@expressive/mvc 0.53.6 → 0.54.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/context.js +130 -126
- package/dist/esm/control.js +165 -158
- package/dist/esm/index.js +22 -8
- package/dist/esm/instruction/get.js +84 -84
- package/dist/esm/instruction/has.js +73 -70
- package/dist/esm/instruction/ref.js +58 -55
- package/dist/esm/instruction/set.js +77 -80
- package/dist/esm/instruction/use.js +60 -55
- package/dist/esm/model.js +247 -251
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -0
- package/package.json +4 -4
- package/dist/esm/context.test.js +0 -211
- package/dist/esm/control.test.js +0 -183
- package/dist/esm/instruction/get.test.js +0 -645
- package/dist/esm/instruction/has.test.js +0 -354
- package/dist/esm/instruction/ref.test.js +0 -281
- package/dist/esm/instruction/set.test.js +0 -527
- package/dist/esm/instruction/use.test.js +0 -305
- package/dist/esm/mocks.js +0 -20
- package/dist/esm/model.test.js +0 -1541
|
@@ -1,354 +0,0 @@
|
|
|
1
|
-
import { Context } from '../context';
|
|
2
|
-
import { Model } from '../model';
|
|
3
|
-
import { has } from './has';
|
|
4
|
-
describe("recipient", () => {
|
|
5
|
-
it("will register child", () => {
|
|
6
|
-
class Child extends Model {
|
|
7
|
-
}
|
|
8
|
-
class Parent extends Model {
|
|
9
|
-
constructor() {
|
|
10
|
-
super(...arguments);
|
|
11
|
-
this.children = has(Child);
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
const parent = Parent.new();
|
|
15
|
-
const child = Child.new();
|
|
16
|
-
new Context({ parent }).push({ child });
|
|
17
|
-
expect(parent.children).toEqual([child]);
|
|
18
|
-
});
|
|
19
|
-
it("will register a subclass", () => {
|
|
20
|
-
class Child extends Model {
|
|
21
|
-
}
|
|
22
|
-
class Child2 extends Child {
|
|
23
|
-
}
|
|
24
|
-
class Parent extends Model {
|
|
25
|
-
constructor() {
|
|
26
|
-
super(...arguments);
|
|
27
|
-
this.children = has(Child);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
const parent = Parent.new();
|
|
31
|
-
const child = Child2.new();
|
|
32
|
-
new Context({ parent }).push({ child });
|
|
33
|
-
expect(parent.children).toEqual([child]);
|
|
34
|
-
});
|
|
35
|
-
it("will not register superclass", () => {
|
|
36
|
-
class Child extends Model {
|
|
37
|
-
}
|
|
38
|
-
class Child2 extends Child {
|
|
39
|
-
}
|
|
40
|
-
class Parent extends Model {
|
|
41
|
-
constructor() {
|
|
42
|
-
super(...arguments);
|
|
43
|
-
this.children = has(Child2);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
const parent = Parent.new();
|
|
47
|
-
new Context({ parent }).push({ Child });
|
|
48
|
-
expect(parent.children.length).toBe(0);
|
|
49
|
-
});
|
|
50
|
-
it("will run callback on register", () => {
|
|
51
|
-
class Child extends Model {
|
|
52
|
-
}
|
|
53
|
-
class Parent extends Model {
|
|
54
|
-
constructor() {
|
|
55
|
-
super(...arguments);
|
|
56
|
-
this.children = has(Child, gotChild);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
const gotChild = jest.fn();
|
|
60
|
-
const parent = Parent.new();
|
|
61
|
-
const child = Child.new();
|
|
62
|
-
new Context({ parent }).push({ child });
|
|
63
|
-
expect(gotChild).toHaveBeenCalledWith(child, parent);
|
|
64
|
-
});
|
|
65
|
-
it("will register multiple children", () => {
|
|
66
|
-
class Child extends Model {
|
|
67
|
-
}
|
|
68
|
-
class Parent extends Model {
|
|
69
|
-
constructor() {
|
|
70
|
-
super(...arguments);
|
|
71
|
-
this.children = has(Child, hasChild);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
const hasChild = jest.fn();
|
|
75
|
-
const parent = Parent.new();
|
|
76
|
-
const child1 = Child.new();
|
|
77
|
-
const child2 = Child.new();
|
|
78
|
-
new Context({ parent }).push({ child1, child2 });
|
|
79
|
-
expect(hasChild).toHaveBeenCalledTimes(2);
|
|
80
|
-
expect(parent.children).toEqual([child1, child2]);
|
|
81
|
-
});
|
|
82
|
-
it("will remove children which unmount", async () => {
|
|
83
|
-
const didRemove = jest.fn();
|
|
84
|
-
const didAdd = jest.fn(() => didRemove);
|
|
85
|
-
class Child extends Model {
|
|
86
|
-
constructor() {
|
|
87
|
-
super(...arguments);
|
|
88
|
-
this.value = 0;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
class Parent extends Model {
|
|
92
|
-
constructor() {
|
|
93
|
-
super(...arguments);
|
|
94
|
-
this.children = has(Child, didAdd);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
const parent = Parent.new();
|
|
98
|
-
const child1 = Child.new();
|
|
99
|
-
const child2 = Child.new();
|
|
100
|
-
const context = new Context({ parent });
|
|
101
|
-
const context2 = context.push({ child1, child2 });
|
|
102
|
-
expect(didAdd).toHaveBeenCalledTimes(2);
|
|
103
|
-
expect(parent.children).toEqual([child1, child2]);
|
|
104
|
-
context2.pop();
|
|
105
|
-
await expect(parent).toHaveUpdated();
|
|
106
|
-
expect(didRemove).toHaveBeenCalledTimes(2);
|
|
107
|
-
const child3 = Child.new();
|
|
108
|
-
const context2b = context.push({ child3 });
|
|
109
|
-
expect(parent.children).toEqual([child3]);
|
|
110
|
-
context2b.pop();
|
|
111
|
-
await expect(parent).toHaveUpdated();
|
|
112
|
-
expect(didRemove).toHaveBeenCalledTimes(3);
|
|
113
|
-
expect(parent.children.length).toBe(0);
|
|
114
|
-
});
|
|
115
|
-
it("will not register if returns false", async () => {
|
|
116
|
-
class Child extends Model {
|
|
117
|
-
}
|
|
118
|
-
class Parent extends Model {
|
|
119
|
-
constructor() {
|
|
120
|
-
super(...arguments);
|
|
121
|
-
this.children = has(Child, hasChild);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
const hasChild = jest.fn(() => false);
|
|
125
|
-
const parent = Parent.new();
|
|
126
|
-
const context = new Context({ parent });
|
|
127
|
-
context.push({
|
|
128
|
-
child: Child.new(),
|
|
129
|
-
child2: Child.new()
|
|
130
|
-
});
|
|
131
|
-
expect(hasChild).toHaveBeenCalledTimes(2);
|
|
132
|
-
expect(parent.children.length).toBe(0);
|
|
133
|
-
context.push({ child: Child.new() });
|
|
134
|
-
await expect(parent).not.toUpdate();
|
|
135
|
-
expect(hasChild).toHaveBeenCalledTimes(3);
|
|
136
|
-
expect(parent.children.length).toBe(0);
|
|
137
|
-
});
|
|
138
|
-
it("will ignore redundant child", async () => {
|
|
139
|
-
class Child extends Model {
|
|
140
|
-
}
|
|
141
|
-
class Parent extends Model {
|
|
142
|
-
constructor() {
|
|
143
|
-
super(...arguments);
|
|
144
|
-
this.child = has(Child, gotChild);
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
const gotChild = jest.fn();
|
|
148
|
-
const parent = Parent.new();
|
|
149
|
-
const child = Child.new();
|
|
150
|
-
new Context({ parent })
|
|
151
|
-
.push({ child })
|
|
152
|
-
.push({ child });
|
|
153
|
-
expect(gotChild).toHaveBeenCalledTimes(1);
|
|
154
|
-
});
|
|
155
|
-
it("will register own type", async () => {
|
|
156
|
-
class Test extends Model {
|
|
157
|
-
constructor() {
|
|
158
|
-
super(...arguments);
|
|
159
|
-
this.tests = has(Test, (got, self) => {
|
|
160
|
-
gotTest(got.toString(), self.toString());
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
const gotTest = jest.fn();
|
|
165
|
-
const test = Test.new("1");
|
|
166
|
-
const test2 = Test.new("2");
|
|
167
|
-
const test3 = Test.new("3");
|
|
168
|
-
new Context({ test }).push({ test2 }).push({ test3 });
|
|
169
|
-
expect(gotTest).toBeCalledWith("2", "1");
|
|
170
|
-
expect(gotTest).toBeCalledWith("3", "2");
|
|
171
|
-
expect(gotTest).toBeCalledTimes(2);
|
|
172
|
-
});
|
|
173
|
-
it("will register implicit", () => {
|
|
174
|
-
class Baz extends Model {
|
|
175
|
-
}
|
|
176
|
-
class Foo extends Model {
|
|
177
|
-
constructor() {
|
|
178
|
-
super(...arguments);
|
|
179
|
-
this.bar = new Bar();
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
class Bar extends Model {
|
|
183
|
-
constructor() {
|
|
184
|
-
super(...arguments);
|
|
185
|
-
this.baz = has(Baz, gotBaz);
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
const gotBaz = jest.fn();
|
|
189
|
-
const foo = Foo.new();
|
|
190
|
-
const baz = Baz.new();
|
|
191
|
-
new Context({ foo }).push({ baz });
|
|
192
|
-
expect(gotBaz).toBeCalledWith(baz, foo.bar);
|
|
193
|
-
});
|
|
194
|
-
it("will register for implicit", () => {
|
|
195
|
-
class Baz extends Model {
|
|
196
|
-
}
|
|
197
|
-
class Foo extends Model {
|
|
198
|
-
constructor() {
|
|
199
|
-
super(...arguments);
|
|
200
|
-
this.baz = has(Baz);
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
class Bar extends Model {
|
|
204
|
-
constructor() {
|
|
205
|
-
super(...arguments);
|
|
206
|
-
this.baz = new Baz();
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
const foo = Foo.new();
|
|
210
|
-
const bar = Bar.new();
|
|
211
|
-
new Context({ foo }).push({ bar });
|
|
212
|
-
expect(foo.baz).toEqual([bar.baz]);
|
|
213
|
-
});
|
|
214
|
-
it.todo("will unwrap children on export");
|
|
215
|
-
});
|
|
216
|
-
describe("target", () => {
|
|
217
|
-
it("will register recipients", () => {
|
|
218
|
-
class Child extends Model {
|
|
219
|
-
constructor() {
|
|
220
|
-
super(...arguments);
|
|
221
|
-
this.parents = has();
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
class Parent extends Model {
|
|
225
|
-
constructor() {
|
|
226
|
-
super(...arguments);
|
|
227
|
-
this.child = has(Child);
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
const parent = Parent.new();
|
|
231
|
-
const child = Child.new();
|
|
232
|
-
const context = new Context({ parent }).push({ child });
|
|
233
|
-
expect(child.parents).toEqual([parent]);
|
|
234
|
-
context.pop();
|
|
235
|
-
});
|
|
236
|
-
it("will register multiple", () => {
|
|
237
|
-
class Child extends Model {
|
|
238
|
-
constructor() {
|
|
239
|
-
super(...arguments);
|
|
240
|
-
this.parents = has();
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
class Parent extends Model {
|
|
244
|
-
constructor() {
|
|
245
|
-
super(...arguments);
|
|
246
|
-
this.child = has(Child);
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
const child = Child.new();
|
|
250
|
-
const parent = Parent.new();
|
|
251
|
-
const parent2 = Parent.new();
|
|
252
|
-
const context = new Context({ parent }).push({ child });
|
|
253
|
-
const context2 = new Context({ parent2 }).push({ child });
|
|
254
|
-
expect(child.parents).toEqual([parent, parent2]);
|
|
255
|
-
context.pop();
|
|
256
|
-
context2.pop();
|
|
257
|
-
});
|
|
258
|
-
it("will callback on register", () => {
|
|
259
|
-
class Child extends Model {
|
|
260
|
-
constructor() {
|
|
261
|
-
super(...arguments);
|
|
262
|
-
this.parents = has(gotParent);
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
class Parent extends Model {
|
|
266
|
-
constructor() {
|
|
267
|
-
super(...arguments);
|
|
268
|
-
this.child = has(Child);
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
const gotParent = jest.fn();
|
|
272
|
-
const parent = Parent.new();
|
|
273
|
-
const child = Child.new();
|
|
274
|
-
new Context({ parent }).push({ child });
|
|
275
|
-
expect(gotParent).toHaveBeenCalledWith(parent, child);
|
|
276
|
-
});
|
|
277
|
-
it("will callback before recipient does", () => {
|
|
278
|
-
class Child extends Model {
|
|
279
|
-
constructor() {
|
|
280
|
-
super(...arguments);
|
|
281
|
-
this.parents = has(gotParent);
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
class Parent extends Model {
|
|
285
|
-
constructor() {
|
|
286
|
-
super(...arguments);
|
|
287
|
-
this.children = has(Child, gotChild);
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
const gotChild = jest.fn();
|
|
291
|
-
const gotParent = jest.fn(() => {
|
|
292
|
-
expect(gotChild).not.toHaveBeenCalled();
|
|
293
|
-
});
|
|
294
|
-
const parent = Parent.new();
|
|
295
|
-
const child = Child.new();
|
|
296
|
-
new Context({ parent }).push({ child });
|
|
297
|
-
expect(gotChild).toHaveBeenCalled();
|
|
298
|
-
expect(gotParent).toHaveBeenCalled();
|
|
299
|
-
});
|
|
300
|
-
it("will prevent register", () => {
|
|
301
|
-
class Child extends Model {
|
|
302
|
-
constructor() {
|
|
303
|
-
super(...arguments);
|
|
304
|
-
this.parents = has(gotParent);
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
class Parent extends Model {
|
|
308
|
-
constructor() {
|
|
309
|
-
super(...arguments);
|
|
310
|
-
this.children = has(Child, gotChild);
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
const gotChild = jest.fn();
|
|
314
|
-
const gotParent = jest.fn(() => false);
|
|
315
|
-
const parent = Parent.new();
|
|
316
|
-
const child = Child.new();
|
|
317
|
-
new Context({ parent }).push({ child });
|
|
318
|
-
expect(gotParent).toHaveBeenCalled();
|
|
319
|
-
expect(gotChild).not.toHaveBeenCalled();
|
|
320
|
-
});
|
|
321
|
-
it("will callback on removal", async () => {
|
|
322
|
-
class Child extends Model {
|
|
323
|
-
constructor() {
|
|
324
|
-
super(...arguments);
|
|
325
|
-
this.parents = has(() => {
|
|
326
|
-
return removedParent;
|
|
327
|
-
});
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
class Parent extends Model {
|
|
331
|
-
constructor() {
|
|
332
|
-
super(...arguments);
|
|
333
|
-
this.children = has(Child);
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
const removedParent = jest.fn();
|
|
337
|
-
const parent = Parent.new();
|
|
338
|
-
const child = Child.new();
|
|
339
|
-
const context = new Context({ parent }).push({ child });
|
|
340
|
-
context.pop();
|
|
341
|
-
expect(removedParent).toHaveBeenCalledTimes(1);
|
|
342
|
-
});
|
|
343
|
-
it("will complain if used more than once", () => {
|
|
344
|
-
class Child extends Model {
|
|
345
|
-
constructor() {
|
|
346
|
-
super(...arguments);
|
|
347
|
-
this.parents = has();
|
|
348
|
-
this.parents2 = has();
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
expect(() => Child.new()).toThrowError(`'has' callback can only be used once per model.`);
|
|
352
|
-
});
|
|
353
|
-
});
|
|
354
|
-
it.todo("will require values as props if has-instruction");
|
|
@@ -1,281 +0,0 @@
|
|
|
1
|
-
import { Model } from '../model';
|
|
2
|
-
import { ref } from './ref';
|
|
3
|
-
describe("property", () => {
|
|
4
|
-
it('will contain value from ref-object', async () => {
|
|
5
|
-
class Subject extends Model {
|
|
6
|
-
constructor() {
|
|
7
|
-
super(...arguments);
|
|
8
|
-
this.ref = ref();
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
const state = Subject.new();
|
|
12
|
-
state.ref.current = "foobar";
|
|
13
|
-
await expect(state).toHaveUpdated();
|
|
14
|
-
expect(state.ref.current).toBe("foobar");
|
|
15
|
-
});
|
|
16
|
-
it('will get value from ref-object', async () => {
|
|
17
|
-
class Subject extends Model {
|
|
18
|
-
constructor() {
|
|
19
|
-
super(...arguments);
|
|
20
|
-
this.ref = ref();
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
const state = Subject.new();
|
|
24
|
-
expect(state.ref.get()).toBeNull();
|
|
25
|
-
state.ref.current = "foobar";
|
|
26
|
-
expect(state.ref.get()).toBe("foobar");
|
|
27
|
-
});
|
|
28
|
-
it('will watch "current" of property', async () => {
|
|
29
|
-
class Subject extends Model {
|
|
30
|
-
constructor() {
|
|
31
|
-
super(...arguments);
|
|
32
|
-
this.ref = ref();
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
const state = Subject.new();
|
|
36
|
-
const didCallback = jest.fn();
|
|
37
|
-
state.set((key) => {
|
|
38
|
-
if (key == "ref")
|
|
39
|
-
didCallback();
|
|
40
|
-
});
|
|
41
|
-
state.ref.current = "foobar";
|
|
42
|
-
await expect(state).toHaveUpdated();
|
|
43
|
-
expect(didCallback).toBeCalledWith();
|
|
44
|
-
});
|
|
45
|
-
it('will update "current" when property invoked', async () => {
|
|
46
|
-
class Subject extends Model {
|
|
47
|
-
constructor() {
|
|
48
|
-
super(...arguments);
|
|
49
|
-
this.ref = ref();
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
const state = Subject.new();
|
|
53
|
-
const didUpdate = jest.fn();
|
|
54
|
-
state.set((key) => {
|
|
55
|
-
if (key == "ref")
|
|
56
|
-
didUpdate();
|
|
57
|
-
});
|
|
58
|
-
state.ref("foobar");
|
|
59
|
-
await expect(state).toHaveUpdated();
|
|
60
|
-
expect(didUpdate).toBeCalledWith();
|
|
61
|
-
});
|
|
62
|
-
it('will invoke callback', async () => {
|
|
63
|
-
const didTrigger = jest.fn();
|
|
64
|
-
const didUpdate = jest.fn();
|
|
65
|
-
class Subject extends Model {
|
|
66
|
-
constructor() {
|
|
67
|
-
super(...arguments);
|
|
68
|
-
this.ref = ref(didTrigger);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
const state = Subject.new();
|
|
72
|
-
expect(didTrigger).not.toBeCalled();
|
|
73
|
-
state.set(key => {
|
|
74
|
-
if (key == "ref")
|
|
75
|
-
didUpdate();
|
|
76
|
-
});
|
|
77
|
-
state.ref.current = "foobar";
|
|
78
|
-
expect(didTrigger).toBeCalledWith("foobar");
|
|
79
|
-
await expect(state).toHaveUpdated();
|
|
80
|
-
expect(didUpdate).toBeCalledWith();
|
|
81
|
-
});
|
|
82
|
-
it('will invoke return-callback on overwrite', async () => {
|
|
83
|
-
class Subject extends Model {
|
|
84
|
-
constructor() {
|
|
85
|
-
super(...arguments);
|
|
86
|
-
this.ref = ref(() => didTrigger);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
const state = Subject.new();
|
|
90
|
-
const didTrigger = jest.fn();
|
|
91
|
-
state.ref.current = 1;
|
|
92
|
-
await expect(state).toHaveUpdated();
|
|
93
|
-
expect(didTrigger).not.toBeCalled();
|
|
94
|
-
state.ref.current = 2;
|
|
95
|
-
await expect(state).toHaveUpdated();
|
|
96
|
-
expect(didTrigger).toBeCalled();
|
|
97
|
-
});
|
|
98
|
-
it('will not callback when gets null', async () => {
|
|
99
|
-
const callback = jest.fn();
|
|
100
|
-
class Subject extends Model {
|
|
101
|
-
constructor() {
|
|
102
|
-
super(...arguments);
|
|
103
|
-
this.ref = ref(callback);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
const state = Subject.new();
|
|
107
|
-
state.ref("hello");
|
|
108
|
-
expect(callback).toBeCalledWith("hello");
|
|
109
|
-
state.ref(null);
|
|
110
|
-
expect(callback).not.toBeCalledWith(null);
|
|
111
|
-
});
|
|
112
|
-
it('will callback when on null if ignore false', async () => {
|
|
113
|
-
const callback = jest.fn();
|
|
114
|
-
class Subject extends Model {
|
|
115
|
-
constructor() {
|
|
116
|
-
super(...arguments);
|
|
117
|
-
this.ref = ref(callback, false);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
const state = Subject.new();
|
|
121
|
-
state.ref("hello");
|
|
122
|
-
expect(callback).toBeCalledWith("hello");
|
|
123
|
-
state.ref(null);
|
|
124
|
-
expect(callback).toBeCalledWith(null);
|
|
125
|
-
});
|
|
126
|
-
it('will reset nested effects', async () => {
|
|
127
|
-
class Subject extends Model {
|
|
128
|
-
constructor() {
|
|
129
|
-
super(...arguments);
|
|
130
|
-
this.name = "World";
|
|
131
|
-
this.hello = ref((value) => {
|
|
132
|
-
this.get(({ name }) => {
|
|
133
|
-
effect(`${value} ${name}!`);
|
|
134
|
-
});
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
const effect = jest.fn();
|
|
139
|
-
const state = Subject.new();
|
|
140
|
-
state.hello("Hola");
|
|
141
|
-
await expect(state).toHaveUpdated();
|
|
142
|
-
expect(effect).toBeCalledWith("Hola World!");
|
|
143
|
-
state.hello("Bonjour");
|
|
144
|
-
await expect(state).toHaveUpdated();
|
|
145
|
-
expect(effect).toBeCalledWith("Bonjour World!");
|
|
146
|
-
state.name = "Earth";
|
|
147
|
-
await expect(state).toHaveUpdated();
|
|
148
|
-
expect(effect).toBeCalledWith("Bonjour Earth!");
|
|
149
|
-
expect(effect).not.toBeCalledWith("Hola Earth!");
|
|
150
|
-
});
|
|
151
|
-
it('will export value of ref-properties', () => {
|
|
152
|
-
class Subject extends Model {
|
|
153
|
-
constructor() {
|
|
154
|
-
super(...arguments);
|
|
155
|
-
this.ref = ref();
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
const test = Subject.new();
|
|
159
|
-
const values = { ref: "foobar" };
|
|
160
|
-
test.ref(values.ref);
|
|
161
|
-
expect(test.get()).toMatchObject(values);
|
|
162
|
-
});
|
|
163
|
-
it('will be accessible from a proxy', () => {
|
|
164
|
-
class Subject extends Model {
|
|
165
|
-
constructor() {
|
|
166
|
-
super(...arguments);
|
|
167
|
-
this.ref = ref();
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
const test = Subject.new();
|
|
171
|
-
test.get(state => {
|
|
172
|
-
expect(state.ref).not.toBeUndefined();
|
|
173
|
-
});
|
|
174
|
-
});
|
|
175
|
-
it.skip('will subscribe if current accessed', async () => {
|
|
176
|
-
class Subject extends Model {
|
|
177
|
-
constructor() {
|
|
178
|
-
super(...arguments);
|
|
179
|
-
this.ref = ref();
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
const test = Subject.new();
|
|
183
|
-
const effect = jest.fn(($) => {
|
|
184
|
-
void $.ref.current;
|
|
185
|
-
});
|
|
186
|
-
test.get(effect);
|
|
187
|
-
expect(effect).toBeCalledTimes(1);
|
|
188
|
-
test.ref("foobar");
|
|
189
|
-
await expect(test).toHaveUpdated();
|
|
190
|
-
expect(effect).toBeCalledTimes(2);
|
|
191
|
-
});
|
|
192
|
-
});
|
|
193
|
-
describe("proxy", () => {
|
|
194
|
-
class Subject extends Model {
|
|
195
|
-
constructor() {
|
|
196
|
-
super(...arguments);
|
|
197
|
-
this.foo = "foo";
|
|
198
|
-
this.bar = "bar";
|
|
199
|
-
this.refs = ref(this);
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
it("will match properties", () => {
|
|
203
|
-
const test = Subject.new();
|
|
204
|
-
for (const key in test)
|
|
205
|
-
expect(test.refs).toHaveProperty(key);
|
|
206
|
-
});
|
|
207
|
-
it("will match values via current", () => {
|
|
208
|
-
const test = Subject.new();
|
|
209
|
-
const { refs } = test;
|
|
210
|
-
for (const key in test) {
|
|
211
|
-
const value = test[key];
|
|
212
|
-
const { current } = refs[key];
|
|
213
|
-
expect(current).toBe(value);
|
|
214
|
-
}
|
|
215
|
-
});
|
|
216
|
-
it("will update values", async () => {
|
|
217
|
-
const test = Subject.new();
|
|
218
|
-
expect(test.foo).toBe("foo");
|
|
219
|
-
expect(test.bar).toBe("bar");
|
|
220
|
-
test.refs.foo("bar");
|
|
221
|
-
test.refs.bar("foo");
|
|
222
|
-
await expect(test).toHaveUpdated();
|
|
223
|
-
expect(test.foo).toBe("bar");
|
|
224
|
-
expect(test.bar).toBe("foo");
|
|
225
|
-
});
|
|
226
|
-
});
|
|
227
|
-
describe("mapped", () => {
|
|
228
|
-
const generateRef = jest.fn((key) => key);
|
|
229
|
-
class Test extends Model {
|
|
230
|
-
constructor() {
|
|
231
|
-
super(...arguments);
|
|
232
|
-
this.foo = "foo";
|
|
233
|
-
this.bar = "bar";
|
|
234
|
-
this.fields = ref(this, generateRef);
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
afterEach(() => {
|
|
238
|
-
generateRef.mockClear();
|
|
239
|
-
});
|
|
240
|
-
it("will run function for accessed keys", () => {
|
|
241
|
-
const { fields } = Test.new();
|
|
242
|
-
expect(fields.foo).toBe("foo");
|
|
243
|
-
expect(fields.bar).toBe("bar");
|
|
244
|
-
expect(generateRef).toBeCalledWith("foo");
|
|
245
|
-
expect(generateRef).toBeCalledWith("bar");
|
|
246
|
-
});
|
|
247
|
-
it("will run function only for accessed property", () => {
|
|
248
|
-
const { fields } = Test.new();
|
|
249
|
-
expect(fields.foo).toBe("foo");
|
|
250
|
-
expect(generateRef).toBeCalledWith("foo");
|
|
251
|
-
expect(generateRef).not.toBeCalledWith("bar");
|
|
252
|
-
});
|
|
253
|
-
it("will run function only once per property", () => {
|
|
254
|
-
const { fields } = Test.new();
|
|
255
|
-
expect(fields.foo).toBe("foo");
|
|
256
|
-
expect(fields.foo).toBe("foo");
|
|
257
|
-
expect(generateRef).toBeCalledTimes(1);
|
|
258
|
-
});
|
|
259
|
-
it("will throw if object is not this", () => {
|
|
260
|
-
class Test extends Model {
|
|
261
|
-
constructor() {
|
|
262
|
-
super(...arguments);
|
|
263
|
-
this.foo = "foo";
|
|
264
|
-
this.bar = "bar";
|
|
265
|
-
// @ts-expect-error
|
|
266
|
-
this.fields = ref({});
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
expect(() => Test.new()).toThrowError(`ref instruction does not support object which is not 'this'`);
|
|
270
|
-
});
|
|
271
|
-
it.skip("will not break on recursive", () => {
|
|
272
|
-
class Test extends Model {
|
|
273
|
-
constructor() {
|
|
274
|
-
super(...arguments);
|
|
275
|
-
this.foo = ref();
|
|
276
|
-
this.bar = ref(this);
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
Test.new();
|
|
280
|
-
});
|
|
281
|
-
});
|