Skip to content

Commit 68b756b

Browse files
test: add tests for string primitive (#2121)
1 parent 417dcc0 commit 68b756b

File tree

2 files changed

+319
-1
lines changed

2 files changed

+319
-1
lines changed

__tests__/core/string.test.ts

+319
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,319 @@
1+
import { types } from "../../src"
2+
import { Hook, NodeLifeCycle } from "../../src/internal"
3+
4+
describe("types.string", () => {
5+
describe("methods", () => {
6+
describe("create", () => {
7+
describe("with no arguments", () => {
8+
if (process.env.NODE_ENV !== "production") {
9+
it("should throw an error in development", () => {
10+
expect(() => {
11+
types.string.create()
12+
}).toThrow()
13+
})
14+
}
15+
})
16+
describe("with a string argument", () => {
17+
it("should return a string", () => {
18+
const s = types.string.create("foo")
19+
expect(typeof s).toBe("string")
20+
})
21+
})
22+
describe("with argument of different types", () => {
23+
const testCases = [
24+
null,
25+
undefined,
26+
1,
27+
true,
28+
[],
29+
function () {},
30+
new Date(),
31+
/a/,
32+
new Map(),
33+
new Set(),
34+
Symbol(),
35+
new Error(),
36+
NaN,
37+
Infinity
38+
]
39+
40+
if (process.env.NODE_ENV !== "production") {
41+
testCases.forEach((testCase) => {
42+
it(`should throw an error when passed ${JSON.stringify(testCase)}`, () => {
43+
expect(() => {
44+
types.string.create(testCase as any)
45+
}).toThrow()
46+
})
47+
})
48+
}
49+
})
50+
})
51+
describe("describe", () => {
52+
it("should return the value 'string'", () => {
53+
const description = types.string.describe()
54+
expect(description).toBe("string")
55+
})
56+
})
57+
describe("getSnapshot", () => {
58+
it("should return the value passed in", () => {
59+
const s = types.string.instantiate(null, "", {}, "foo")
60+
const snapshot = types.string.getSnapshot(s)
61+
expect(snapshot).toBe("foo")
62+
})
63+
})
64+
describe("getSubtype", () => {
65+
it("should return null", () => {
66+
const subtype = types.string.getSubTypes()
67+
expect(subtype).toBe(null)
68+
})
69+
})
70+
describe("instantiate", () => {
71+
if (process.env.NODE_ENV !== "production") {
72+
describe("with invalid arguments", () => {
73+
it("should not throw an error", () => {
74+
expect(() => {
75+
// @ts-ignore
76+
types.string.instantiate()
77+
}).not.toThrow()
78+
})
79+
})
80+
}
81+
describe("with a string argument", () => {
82+
it("should return an object", () => {
83+
const s = types.string.instantiate(null, "", {}, "foo")
84+
expect(typeof s).toBe("object")
85+
})
86+
})
87+
})
88+
describe("is", () => {
89+
describe("with a string argument", () => {
90+
it("should return true", () => {
91+
const result = types.string.is("foo")
92+
expect(result).toBe(true)
93+
})
94+
})
95+
describe("with argument of different types", () => {
96+
const testCases = [
97+
null,
98+
undefined,
99+
1,
100+
true,
101+
[],
102+
function () {},
103+
new Date(),
104+
/a/,
105+
new Map(),
106+
new Set(),
107+
Symbol(),
108+
new Error(),
109+
NaN,
110+
Infinity
111+
]
112+
113+
testCases.forEach((testCase) => {
114+
it(`should return false when passed ${JSON.stringify(testCase)}`, () => {
115+
const result = types.string.is(testCase as any)
116+
expect(result).toBe(false)
117+
})
118+
})
119+
})
120+
})
121+
describe("isAssignableFrom", () => {
122+
describe("with a string argument", () => {
123+
it("should return true", () => {
124+
const result = types.string.isAssignableFrom(types.string)
125+
expect(result).toBe(true)
126+
})
127+
})
128+
describe("with argument of different types", () => {
129+
const testCases = [
130+
types.Date,
131+
types.boolean,
132+
types.finite,
133+
types.float,
134+
types.identifier,
135+
types.identifierNumber,
136+
types.integer,
137+
types.null,
138+
types.number,
139+
types.undefined
140+
]
141+
142+
testCases.forEach((testCase) => {
143+
it(`should return false when passed ${JSON.stringify(testCase)}`, () => {
144+
const result = types.string.isAssignableFrom(testCase as any)
145+
expect(result).toBe(false)
146+
})
147+
})
148+
})
149+
})
150+
// TODO: we need to test this, but to be honest I'm not sure what the expected behavior is on single string nodes.
151+
describe.skip("reconcile", () => {})
152+
describe("validate", () => {
153+
describe("with a string argument", () => {
154+
it("should return with no validation errors", () => {
155+
const result = types.string.validate("foo", [])
156+
expect(result).toEqual([])
157+
})
158+
})
159+
describe("with argument of different types", () => {
160+
const testCases = [
161+
null,
162+
undefined,
163+
1,
164+
true,
165+
[],
166+
function () {},
167+
new Date(),
168+
/a/,
169+
new Map(),
170+
new Set(),
171+
Symbol(),
172+
new Error(),
173+
NaN,
174+
Infinity
175+
]
176+
177+
testCases.forEach((testCase) => {
178+
it(`should return with a validation error when passed ${JSON.stringify(
179+
testCase
180+
)}`, () => {
181+
const result = types.string.validate(testCase as any, [])
182+
expect(result).toEqual([
183+
{
184+
context: [],
185+
message: "Value is not a string",
186+
value: testCase
187+
}
188+
])
189+
})
190+
})
191+
})
192+
})
193+
})
194+
describe("properties", () => {
195+
describe("flags", () => {
196+
test("return the correct value", () => {
197+
const flags = types.string.flags
198+
expect(flags).toBe(1)
199+
})
200+
})
201+
describe("identifierAttribute", () => {
202+
// We don't have a way to set the identifierAttribute on a primitive type, so this should return undefined.
203+
test("returns undefined", () => {
204+
const identifierAttribute = types.string.identifierAttribute
205+
expect(identifierAttribute).toBe(undefined)
206+
})
207+
})
208+
describe("isType", () => {
209+
test("returns true", () => {
210+
const isType = types.string.isType
211+
expect(isType).toBe(true)
212+
})
213+
})
214+
describe("name", () => {
215+
test('returns "string"', () => {
216+
const name = types.string.name
217+
expect(name).toBe("string")
218+
})
219+
})
220+
})
221+
describe("instance", () => {
222+
describe("methods", () => {
223+
describe("aboutToDie", () => {
224+
it("calls the beforeDetach hook", () => {
225+
const s = types.string.instantiate(null, "", {}, "foo")
226+
let called = false
227+
s.registerHook(Hook.beforeDestroy, () => {
228+
called = true
229+
})
230+
s.aboutToDie()
231+
expect(called).toBe(true)
232+
})
233+
})
234+
describe("die", () => {
235+
it("kills the node", () => {
236+
const s = types.string.instantiate(null, "", {}, "foo")
237+
s.die()
238+
expect(s.isAlive).toBe(false)
239+
})
240+
it("should mark the node as dead", () => {
241+
const s = types.string.instantiate(null, "", {}, "foo")
242+
s.die()
243+
expect(s.state).toBe(NodeLifeCycle.DEAD)
244+
})
245+
})
246+
describe("finalizeCreation", () => {
247+
it("should mark the node as finalized", () => {
248+
const s = types.string.instantiate(null, "", {}, "foo")
249+
s.finalizeCreation()
250+
expect(s.state).toBe(NodeLifeCycle.FINALIZED)
251+
})
252+
})
253+
describe("finalizeDeath", () => {
254+
it("should mark the node as dead", () => {
255+
const s = types.string.instantiate(null, "", {}, "foo")
256+
s.finalizeDeath()
257+
expect(s.state).toBe(NodeLifeCycle.DEAD)
258+
})
259+
})
260+
describe("getReconciliationType", () => {
261+
it("should return the correct type", () => {
262+
const s = types.string.instantiate(null, "", {}, "foo")
263+
const type = s.getReconciliationType()
264+
expect(type).toBe(types.string)
265+
})
266+
})
267+
describe("getSnapshot", () => {
268+
it("should return the value passed in", () => {
269+
const s = types.string.instantiate(null, "", {}, "foo")
270+
const snapshot = s.getSnapshot()
271+
expect(snapshot).toBe("foo")
272+
})
273+
})
274+
describe("registerHook", () => {
275+
it("should register a hook and call it", () => {
276+
const s = types.string.instantiate(null, "", {}, "foo")
277+
let called = false
278+
s.registerHook(Hook.beforeDestroy, () => {
279+
called = true
280+
})
281+
282+
s.die()
283+
284+
expect(called).toBe(true)
285+
})
286+
})
287+
describe("setParent", () => {
288+
if (process.env.NODE_ENV !== "production") {
289+
describe("with null", () => {
290+
it("should throw an error", () => {
291+
const s = types.string.instantiate(null, "", {}, "foo")
292+
expect(() => {
293+
s.setParent(null, "foo")
294+
}).toThrow()
295+
})
296+
})
297+
describe("with a parent object", () => {
298+
it("should throw an error", () => {
299+
const Parent = types.model({
300+
child: types.string
301+
})
302+
303+
const parent = Parent.create({ child: "foo" })
304+
305+
const s = types.string.instantiate(null, "", {}, "bar")
306+
307+
expect(() => {
308+
// @ts-ignore
309+
s.setParent(parent, "bar")
310+
}).toThrow(
311+
"[mobx-state-tree] assertion failed: scalar nodes cannot change their parent"
312+
)
313+
})
314+
})
315+
}
316+
})
317+
})
318+
})
319+
})

package.json

-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
"scripts": {
1818
"clean": "shx rm -rf dist && shx rm -rf lib",
1919
"build": "yarn clean && tsc && cpr lib dist --filter=\\.js$ && rollup -c",
20-
"jest": "jest --testPathPattern=/__tests__/core/",
2120
"jest:perf": "jest --testPathPattern=/__tests__/perf/",
2221
"test:perf": "yarn build && yarn jest:perf && TS_NODE_COMPILER_OPTIONS='{\"module\": \"commonjs\"}' /usr/bin/time node --expose-gc --require ts-node/register __tests__/perf/report.ts",
2322
"test": "yarn test:dev && yarn test:prod",

0 commit comments

Comments
 (0)