vestjs-runtime 1.6.0 → 1.7.0
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/IsolateSerializer/package.json +8 -12
- package/README.md +1 -3
- package/dist/cjs/IsolateSerializer.development.js +135 -0
- package/dist/cjs/IsolateSerializer.development.js.map +1 -0
- package/dist/cjs/IsolateSerializer.js +6 -0
- package/dist/cjs/IsolateSerializer.production.js +2 -0
- package/dist/cjs/IsolateSerializer.production.js.map +1 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/test-utils.development.js +61 -0
- package/dist/cjs/test-utils.development.js.map +1 -0
- package/dist/cjs/test-utils.js +6 -0
- package/dist/cjs/test-utils.production.js +2 -0
- package/dist/cjs/test-utils.production.js.map +1 -0
- package/dist/cjs/vestjs-runtime.development.js +686 -0
- package/dist/cjs/vestjs-runtime.development.js.map +1 -0
- package/dist/cjs/vestjs-runtime.js +6 -0
- package/dist/cjs/vestjs-runtime.production.js +2 -0
- package/dist/cjs/vestjs-runtime.production.js.map +1 -0
- package/dist/es/IsolateSerializer.development.js +133 -0
- package/dist/es/IsolateSerializer.development.js.map +1 -0
- package/dist/es/IsolateSerializer.production.js +2 -0
- package/dist/es/IsolateSerializer.production.js.map +1 -0
- package/dist/es/package.json +1 -0
- package/dist/es/test-utils.development.js +59 -0
- package/dist/es/test-utils.development.js.map +1 -0
- package/dist/es/test-utils.production.js +2 -0
- package/dist/es/test-utils.production.js.map +1 -0
- package/dist/es/vestjs-runtime.development.js +675 -0
- package/dist/es/vestjs-runtime.development.js.map +1 -0
- package/dist/es/vestjs-runtime.production.js +2 -0
- package/dist/es/vestjs-runtime.production.js.map +1 -0
- package/dist/umd/IsolateSerializer.development.js +138 -0
- package/dist/umd/IsolateSerializer.development.js.map +1 -0
- package/dist/umd/IsolateSerializer.production.js +2 -0
- package/dist/umd/IsolateSerializer.production.js.map +1 -0
- package/dist/umd/test-utils.development.js +67 -0
- package/dist/umd/test-utils.development.js.map +1 -0
- package/dist/umd/test-utils.production.js +2 -0
- package/dist/umd/test-utils.production.js.map +1 -0
- package/dist/umd/vestjs-runtime.development.js +688 -0
- package/dist/umd/vestjs-runtime.development.js.map +1 -0
- package/dist/umd/vestjs-runtime.production.js +2 -0
- package/dist/umd/vestjs-runtime.production.js.map +1 -0
- package/package.json +87 -42
- package/test-utils/package.json +8 -12
- package/types/IsolateSerializer.d.ts +42 -0
- package/types/IsolateSerializer.d.ts.map +1 -0
- package/types/test-utils.d.ts +37 -0
- package/types/test-utils.d.ts.map +1 -0
- package/types/vestjs-runtime.d.ts +257 -351
- package/types/vestjs-runtime.d.ts.map +1 -0
- package/vitest.config.ts +17 -9
- package/dist/IsolateKeys-B21aPuBk.mjs +0 -23
- package/dist/IsolateKeys-B21aPuBk.mjs.map +0 -1
- package/dist/IsolateKeys-CCvALpZC.cjs +0 -35
- package/dist/IsolateKeys-CCvALpZC.cjs.map +0 -1
- package/dist/IsolateSerializer-B1hE3gmT.mjs +0 -1004
- package/dist/IsolateSerializer-B1hE3gmT.mjs.map +0 -1
- package/dist/IsolateSerializer-pbEf5gB2.cjs +0 -1121
- package/dist/IsolateSerializer-pbEf5gB2.cjs.map +0 -1
- package/dist/chunk-CLMFDpHK.mjs +0 -18
- package/dist/exports/IsolateSerializer.cjs +0 -4
- package/dist/exports/IsolateSerializer.mjs +0 -4
- package/dist/exports/test-utils.cjs +0 -21
- package/dist/exports/test-utils.cjs.map +0 -1
- package/dist/exports/test-utils.mjs +0 -21
- package/dist/exports/test-utils.mjs.map +0 -1
- package/dist/vestjs-runtime.cjs +0 -153
- package/dist/vestjs-runtime.cjs.map +0 -1
- package/dist/vestjs-runtime.mjs +0 -117
- package/dist/vestjs-runtime.mjs.map +0 -1
- package/docs/IsolateRegistry.docs.md +0 -146
- package/docs/Isolates.md +0 -97
- package/src/Bus.ts +0 -46
- package/src/Isolate/Isolate.ts +0 -163
- package/src/Isolate/IsolateFocused.ts +0 -93
- package/src/Isolate/IsolateIndexer.ts +0 -42
- package/src/Isolate/IsolateInspector.ts +0 -93
- package/src/Isolate/IsolateKeys.ts +0 -18
- package/src/Isolate/IsolateMutator.ts +0 -165
- package/src/Isolate/IsolateRegistry.ts +0 -176
- package/src/Isolate/IsolateReorderable.ts +0 -11
- package/src/Isolate/IsolateSelectors.ts +0 -25
- package/src/Isolate/IsolateStateMachine.ts +0 -30
- package/src/Isolate/IsolateStatus.ts +0 -8
- package/src/Isolate/IsolateTransient.ts +0 -27
- package/src/Isolate/IsolateTypes.ts +0 -33
- package/src/Isolate/__tests__/Isolate.test.ts +0 -123
- package/src/Isolate/__tests__/IsolateFocused.test.ts +0 -199
- package/src/Isolate/__tests__/IsolateInspector.test.ts +0 -136
- package/src/Isolate/__tests__/IsolateMutator.test.ts +0 -164
- package/src/Isolate/__tests__/IsolatePropagation.test.ts +0 -170
- package/src/Isolate/__tests__/IsolateReorderable.test.ts +0 -111
- package/src/Isolate/__tests__/IsolateSelectors.test.ts +0 -72
- package/src/Isolate/__tests__/IsolateStatus.test.ts +0 -44
- package/src/Isolate/__tests__/IsolateTransient.test.ts +0 -58
- package/src/Isolate/__tests__/__snapshots__/asyncIsolate.test.ts.snap +0 -71
- package/src/Isolate/__tests__/asyncIsolate.test.ts +0 -85
- package/src/IsolateWalker.ts +0 -359
- package/src/Orchestrator/RuntimeStates.ts +0 -4
- package/src/Reconciler.ts +0 -178
- package/src/RuntimeEvents.ts +0 -9
- package/src/VestRuntime.ts +0 -421
- package/src/__tests__/Bus.test.ts +0 -57
- package/src/__tests__/IsolateWalker.iterative.test.ts +0 -77
- package/src/__tests__/IsolateWalker.test.ts +0 -418
- package/src/__tests__/Reconciler.test.ts +0 -193
- package/src/__tests__/Reconciler.transient.test.ts +0 -166
- package/src/__tests__/VestRuntime.test.ts +0 -212
- package/src/__tests__/VestRuntimeStateMachine.test.ts +0 -36
- package/src/__tests__/vestjs-runtime.test.ts +0 -19
- package/src/errors/ErrorStrings.ts +0 -6
- package/src/exports/IsolateSerializer.ts +0 -131
- package/src/exports/__tests__/IsolateSerializer.test.ts +0 -334
- package/src/exports/__tests__/IsolateSerializer.transient.test.ts +0 -101
- package/src/exports/__tests__/__snapshots__/IsolateSerializer.test.ts.snap +0 -5
- package/src/exports/test-utils.ts +0 -17
- package/src/vestjs-runtime.ts +0 -28
- package/types/Isolate-DChR7h5K.d.mts +0 -58
- package/types/Isolate-DChR7h5K.d.mts.map +0 -1
- package/types/Isolate-HYIh82M8.d.cts +0 -58
- package/types/Isolate-HYIh82M8.d.cts.map +0 -1
- package/types/IsolateSerializer-BCg01Px5.d.mts +0 -13
- package/types/IsolateSerializer-BCg01Px5.d.mts.map +0 -1
- package/types/IsolateSerializer-CQpP6A4m.d.cts +0 -13
- package/types/IsolateSerializer-CQpP6A4m.d.cts.map +0 -1
- package/types/exports/IsolateSerializer.d.cts +0 -3
- package/types/exports/IsolateSerializer.d.mts +0 -3
- package/types/exports/test-utils.d.cts +0 -7
- package/types/exports/test-utils.d.cts.map +0 -1
- package/types/exports/test-utils.d.mts +0 -7
- package/types/exports/test-utils.d.mts.map +0 -1
- package/types/vestjs-runtime.d.cts +0 -372
- package/types/vestjs-runtime.d.cts.map +0 -1
- package/types/vestjs-runtime.d.mts +0 -370
- package/types/vestjs-runtime.d.mts.map +0 -1
|
@@ -1,199 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { CB } from 'vest-utils';
|
|
3
|
-
|
|
4
|
-
import { IReconciler } from '../../Reconciler';
|
|
5
|
-
import {
|
|
6
|
-
IsolateFocused,
|
|
7
|
-
FocusModes,
|
|
8
|
-
FocusSelectors,
|
|
9
|
-
VestIsolateTypeFocused,
|
|
10
|
-
} from '../IsolateFocused';
|
|
11
|
-
import * as VestRuntime from '../../VestRuntime';
|
|
12
|
-
import { IsolateKeys } from '../IsolateKeys';
|
|
13
|
-
import { Isolate } from '../Isolate';
|
|
14
|
-
|
|
15
|
-
describe('IsolateFocused', () => {
|
|
16
|
-
function withRunTime<T>(fn: CB<T>) {
|
|
17
|
-
return VestRuntime.Run(
|
|
18
|
-
VestRuntime.createRef((() => null) as unknown as IReconciler, v => v),
|
|
19
|
-
() => fn(),
|
|
20
|
-
);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
describe('Focus Modes', () => {
|
|
24
|
-
it('Should expose ONLY and SKIP focus modes', () => {
|
|
25
|
-
expect(FocusModes.ONLY).toBe('only');
|
|
26
|
-
expect(FocusModes.SKIP).toBe('skip');
|
|
27
|
-
});
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
describe('Isolate creation', () => {
|
|
31
|
-
it('Should return undefined if no fields are provided and matchAll is false', () => {
|
|
32
|
-
let node: any;
|
|
33
|
-
withRunTime(() => {
|
|
34
|
-
Isolate.create('Root', () => {
|
|
35
|
-
node = IsolateFocused(FocusModes.ONLY, []);
|
|
36
|
-
});
|
|
37
|
-
});
|
|
38
|
-
expect(node).toBeUndefined();
|
|
39
|
-
|
|
40
|
-
let node2: any;
|
|
41
|
-
withRunTime(() => {
|
|
42
|
-
Isolate.create('Root', () => {
|
|
43
|
-
node2 = IsolateFocused(FocusModes.ONLY);
|
|
44
|
-
});
|
|
45
|
-
});
|
|
46
|
-
expect(node2).toBeUndefined();
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
it('Should create a focused isolate when matchAll is true', () => {
|
|
50
|
-
let node: any;
|
|
51
|
-
withRunTime(() => {
|
|
52
|
-
Isolate.create('Root', () => {
|
|
53
|
-
node = IsolateFocused(FocusModes.SKIP, true);
|
|
54
|
-
});
|
|
55
|
-
});
|
|
56
|
-
expect(node[IsolateKeys.Type]).toBe(VestIsolateTypeFocused);
|
|
57
|
-
expect(node[IsolateKeys.Transient]).toBe(true);
|
|
58
|
-
expect(node.data).toEqual({
|
|
59
|
-
focusMode: FocusModes.SKIP,
|
|
60
|
-
match: [],
|
|
61
|
-
matchAll: true,
|
|
62
|
-
});
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
it('Should create a focused isolate with specified fields', () => {
|
|
66
|
-
let node: any;
|
|
67
|
-
withRunTime(() => {
|
|
68
|
-
Isolate.create('Root', () => {
|
|
69
|
-
node = IsolateFocused(FocusModes.ONLY, ['field1', 'field2']);
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
expect(node[IsolateKeys.Type]).toBe(VestIsolateTypeFocused);
|
|
73
|
-
expect(node[IsolateKeys.Transient]).toBe(true);
|
|
74
|
-
expect(node.data).toEqual({
|
|
75
|
-
focusMode: FocusModes.ONLY,
|
|
76
|
-
match: ['field1', 'field2'],
|
|
77
|
-
matchAll: false,
|
|
78
|
-
});
|
|
79
|
-
});
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
describe('FocusSelectors', () => {
|
|
83
|
-
describe('isIsolateFocused', () => {
|
|
84
|
-
it('Should correctly identify a focused isolate', () => {
|
|
85
|
-
let node: any;
|
|
86
|
-
withRunTime(() => {
|
|
87
|
-
Isolate.create('Root', () => {
|
|
88
|
-
node = IsolateFocused(FocusModes.ONLY, ['field1']);
|
|
89
|
-
});
|
|
90
|
-
});
|
|
91
|
-
expect(FocusSelectors.isIsolateFocused(node)).toBe(true);
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
it('Should return false for non-focused isolates', () => {
|
|
95
|
-
let node: any;
|
|
96
|
-
withRunTime(() => {
|
|
97
|
-
node = Isolate.create('Root', () => {});
|
|
98
|
-
});
|
|
99
|
-
expect(FocusSelectors.isIsolateFocused(node)).toBe(false);
|
|
100
|
-
});
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
describe('isSkipFocused', () => {
|
|
104
|
-
it('Should return false if focus is undefined', () => {
|
|
105
|
-
expect(FocusSelectors.isSkipFocused(undefined, 'field1')).toBe(false);
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
it('Should return false if focus mode is missing or not SKIP', () => {
|
|
109
|
-
let node: any;
|
|
110
|
-
withRunTime(() => {
|
|
111
|
-
Isolate.create('Root', () => {
|
|
112
|
-
node = IsolateFocused(FocusModes.ONLY, ['field1']);
|
|
113
|
-
});
|
|
114
|
-
});
|
|
115
|
-
expect(FocusSelectors.isSkipFocused(node, 'field1')).toBe(false);
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
it('Should return true if focus is SKIP and matchAll is true', () => {
|
|
119
|
-
let node: any;
|
|
120
|
-
withRunTime(() => {
|
|
121
|
-
Isolate.create('Root', () => {
|
|
122
|
-
node = IsolateFocused(FocusModes.SKIP, true);
|
|
123
|
-
});
|
|
124
|
-
});
|
|
125
|
-
expect(FocusSelectors.isSkipFocused(node)).toBe(true);
|
|
126
|
-
expect(FocusSelectors.isSkipFocused(node, 'anyField')).toBe(true);
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
it('Should return true if focus is SKIP and matches the fieldName', () => {
|
|
130
|
-
let node: any;
|
|
131
|
-
withRunTime(() => {
|
|
132
|
-
Isolate.create('Root', () => {
|
|
133
|
-
node = IsolateFocused(FocusModes.SKIP, ['field1']);
|
|
134
|
-
});
|
|
135
|
-
});
|
|
136
|
-
expect(FocusSelectors.isSkipFocused(node, 'field1')).toBe(true);
|
|
137
|
-
expect(FocusSelectors.isSkipFocused(node, 'field2')).toBe(false);
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
it('Should return true if no fieldName is provided but matches exist', () => {
|
|
141
|
-
let node: any;
|
|
142
|
-
withRunTime(() => {
|
|
143
|
-
Isolate.create('Root', () => {
|
|
144
|
-
node = IsolateFocused(FocusModes.SKIP, ['field1']);
|
|
145
|
-
});
|
|
146
|
-
});
|
|
147
|
-
expect(FocusSelectors.isSkipFocused(node)).toBe(true);
|
|
148
|
-
});
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
describe('isOnlyFocused', () => {
|
|
152
|
-
it('Should return false if focus is undefined', () => {
|
|
153
|
-
expect(FocusSelectors.isOnlyFocused(undefined, 'field1')).toBe(false);
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
it('Should return false if focus mode is missing or not ONLY', () => {
|
|
157
|
-
let node: any;
|
|
158
|
-
withRunTime(() => {
|
|
159
|
-
Isolate.create('Root', () => {
|
|
160
|
-
node = IsolateFocused(FocusModes.SKIP, ['field1']);
|
|
161
|
-
});
|
|
162
|
-
});
|
|
163
|
-
expect(FocusSelectors.isOnlyFocused(node, 'field1')).toBe(false);
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
it('Should return true if focus is ONLY and matches the fieldName', () => {
|
|
167
|
-
let node: any;
|
|
168
|
-
withRunTime(() => {
|
|
169
|
-
Isolate.create('Root', () => {
|
|
170
|
-
node = IsolateFocused(FocusModes.ONLY, ['field1', 'field2']);
|
|
171
|
-
});
|
|
172
|
-
});
|
|
173
|
-
expect(FocusSelectors.isOnlyFocused(node, 'field1')).toBe(true);
|
|
174
|
-
expect(FocusSelectors.isOnlyFocused(node, 'field3')).toBe(false);
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
it('Should return true if focus is ONLY and matchAll is true', () => {
|
|
178
|
-
let node: any;
|
|
179
|
-
withRunTime(() => {
|
|
180
|
-
Isolate.create('Root', () => {
|
|
181
|
-
node = IsolateFocused(FocusModes.ONLY, true);
|
|
182
|
-
});
|
|
183
|
-
});
|
|
184
|
-
expect(FocusSelectors.isOnlyFocused(node)).toBe(true);
|
|
185
|
-
expect(FocusSelectors.isOnlyFocused(node, 'anyField')).toBe(true);
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
it('Should return true if no fieldName is provided but matches exist', () => {
|
|
189
|
-
let node: any;
|
|
190
|
-
withRunTime(() => {
|
|
191
|
-
Isolate.create('Root', () => {
|
|
192
|
-
node = IsolateFocused(FocusModes.ONLY, ['field1']);
|
|
193
|
-
});
|
|
194
|
-
});
|
|
195
|
-
expect(FocusSelectors.isOnlyFocused(node)).toBe(true);
|
|
196
|
-
});
|
|
197
|
-
});
|
|
198
|
-
});
|
|
199
|
-
});
|
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
|
|
3
|
-
import { TIsolate } from '../Isolate';
|
|
4
|
-
import { IsolateInspector } from '../IsolateInspector';
|
|
5
|
-
|
|
6
|
-
describe('IsolateInspector', () => {
|
|
7
|
-
describe('at', () => {
|
|
8
|
-
describe('When the isolate is nullish', () => {
|
|
9
|
-
it('Should return null', () => {
|
|
10
|
-
expect(IsolateInspector.at(null, 0)).toBeNull();
|
|
11
|
-
});
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
describe('When the children are nullish', () => {
|
|
15
|
-
it('Should return null', () => {
|
|
16
|
-
const isolate = { children: null } as unknown as TIsolate;
|
|
17
|
-
|
|
18
|
-
expect(IsolateInspector.at(isolate, 0)).toBeNull();
|
|
19
|
-
});
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
describe('When the child does not exist', () => {
|
|
23
|
-
it('Should return null', () => {
|
|
24
|
-
const isolate = { children: [] } as unknown as TIsolate;
|
|
25
|
-
|
|
26
|
-
expect(IsolateInspector.at(isolate, 0)).toBeNull();
|
|
27
|
-
});
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
describe('When the child exists', () => {
|
|
31
|
-
it('Should return the child', () => {
|
|
32
|
-
const child = {} as TIsolate;
|
|
33
|
-
const child1 = {} as TIsolate;
|
|
34
|
-
const isolate = { children: [child, child1] } as unknown as TIsolate;
|
|
35
|
-
|
|
36
|
-
expect(IsolateInspector.at(isolate, 0)).toBe(child);
|
|
37
|
-
expect(IsolateInspector.at(isolate, 1)).toBe(child1);
|
|
38
|
-
});
|
|
39
|
-
});
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
describe('cursor', () => {
|
|
43
|
-
describe('When the isolate is nullish', () => {
|
|
44
|
-
it('Should return 0', () => {
|
|
45
|
-
expect(IsolateInspector.cursor(null)).toBe(0);
|
|
46
|
-
});
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
describe('When the children are nullish', () => {
|
|
50
|
-
it('Should return 0', () => {
|
|
51
|
-
const isolate = { children: null } as unknown as TIsolate;
|
|
52
|
-
|
|
53
|
-
expect(IsolateInspector.cursor(isolate)).toBe(0);
|
|
54
|
-
});
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
describe('When the children exist', () => {
|
|
58
|
-
it('Should return the length of the children', () => {
|
|
59
|
-
const child = {} as TIsolate;
|
|
60
|
-
const child1 = {} as TIsolate;
|
|
61
|
-
const isolate = { children: [child, child1] } as unknown as TIsolate;
|
|
62
|
-
|
|
63
|
-
expect(IsolateInspector.cursor(isolate)).toBe(2);
|
|
64
|
-
});
|
|
65
|
-
});
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
describe('canReorder', () => {
|
|
69
|
-
describe('When the isolate is nullish', () => {
|
|
70
|
-
it('Should return false', () => {
|
|
71
|
-
expect(IsolateInspector.canReorder(null)).toBe(false);
|
|
72
|
-
});
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
describe('When the isolate does not allow reordering', () => {
|
|
76
|
-
it('Should return false', () => {
|
|
77
|
-
const isolate = { allowReorder: false } as unknown as TIsolate;
|
|
78
|
-
|
|
79
|
-
expect(IsolateInspector.canReorder(isolate)).toBe(false);
|
|
80
|
-
});
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
describe('When the isolate does not allow reordering but a parent does', () => {
|
|
84
|
-
it('Should return true', () => {
|
|
85
|
-
const root = { allowReorder: false } as unknown as TIsolate;
|
|
86
|
-
const parent = {
|
|
87
|
-
allowReorder: true,
|
|
88
|
-
parent: root,
|
|
89
|
-
} as unknown as TIsolate;
|
|
90
|
-
const isolate = { allowReorder: false, parent } as unknown as TIsolate;
|
|
91
|
-
|
|
92
|
-
expect(IsolateInspector.canReorder(isolate)).toBe(true);
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
describe('When only the root allows reordering', () => {
|
|
96
|
-
it('Should return false', () => {
|
|
97
|
-
const root = { allowReorder: true } as unknown as TIsolate;
|
|
98
|
-
const parent = {
|
|
99
|
-
allowReorder: false,
|
|
100
|
-
parent: root,
|
|
101
|
-
} as unknown as TIsolate;
|
|
102
|
-
const isolate = {
|
|
103
|
-
allowReorder: false,
|
|
104
|
-
parent,
|
|
105
|
-
} as unknown as TIsolate;
|
|
106
|
-
|
|
107
|
-
expect(IsolateInspector.canReorder(isolate)).toBe(false);
|
|
108
|
-
});
|
|
109
|
-
});
|
|
110
|
-
});
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
describe('usesKey', () => {
|
|
114
|
-
describe('When the node is nullish', () => {
|
|
115
|
-
it('Should return false', () => {
|
|
116
|
-
expect(IsolateInspector.usesKey(null)).toBe(false);
|
|
117
|
-
});
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
describe('When the node does not have a key', () => {
|
|
121
|
-
it('Should return false', () => {
|
|
122
|
-
const isolate = { key: null } as unknown as TIsolate;
|
|
123
|
-
|
|
124
|
-
expect(IsolateInspector.usesKey(isolate)).toBe(false);
|
|
125
|
-
});
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
describe('When the node has a key', () => {
|
|
129
|
-
it('Should return true', () => {
|
|
130
|
-
const isolate = { key: 'key' } as unknown as TIsolate;
|
|
131
|
-
|
|
132
|
-
expect(IsolateInspector.usesKey(isolate)).toBe(true);
|
|
133
|
-
});
|
|
134
|
-
});
|
|
135
|
-
});
|
|
136
|
-
});
|
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
import { TIsolate } from '../Isolate';
|
|
2
|
-
import { IsolateMutator } from '../IsolateMutator';
|
|
3
|
-
import { describe, it, expect, vi } from 'vitest';
|
|
4
|
-
|
|
5
|
-
describe('IsolateMutator', () => {
|
|
6
|
-
describe('setParent', () => {
|
|
7
|
-
it('should set parent', () => {
|
|
8
|
-
const parent = {} as TIsolate;
|
|
9
|
-
const isolate = {} as TIsolate;
|
|
10
|
-
|
|
11
|
-
expect(isolate.parent).toBeUndefined();
|
|
12
|
-
expect(IsolateMutator.setParent(isolate, parent)).toBe(isolate);
|
|
13
|
-
expect(isolate.parent).toBe(parent);
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
describe('When the child already has a parent', () => {
|
|
17
|
-
it('Should set the new parent of the child', () => {
|
|
18
|
-
const parent1 = {} as TIsolate;
|
|
19
|
-
const parent2 = {} as TIsolate;
|
|
20
|
-
const isolate = {} as TIsolate;
|
|
21
|
-
|
|
22
|
-
IsolateMutator.setParent(isolate, parent1);
|
|
23
|
-
expect(isolate.parent).toBe(parent1);
|
|
24
|
-
IsolateMutator.setParent(isolate, parent2);
|
|
25
|
-
expect(isolate.parent).toBe(parent2);
|
|
26
|
-
});
|
|
27
|
-
});
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
describe('saveOutput', () => {
|
|
31
|
-
it('should save output', () => {
|
|
32
|
-
const isolate = {} as TIsolate;
|
|
33
|
-
const output = {};
|
|
34
|
-
|
|
35
|
-
expect(isolate.output).toBeUndefined();
|
|
36
|
-
expect(IsolateMutator.saveOutput(isolate, output)).toBe(isolate);
|
|
37
|
-
expect(isolate.output).toBe(output);
|
|
38
|
-
});
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
describe('setKey', () => {
|
|
42
|
-
it('should set key', () => {
|
|
43
|
-
const isolate = {} as TIsolate;
|
|
44
|
-
const key = 'foo';
|
|
45
|
-
|
|
46
|
-
expect(isolate.key).toBeUndefined();
|
|
47
|
-
expect(IsolateMutator.setKey(isolate, key)).toBe(isolate);
|
|
48
|
-
expect(isolate.key).toBe(key);
|
|
49
|
-
});
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
describe('addChild', () => {
|
|
53
|
-
it('should add child', () => {
|
|
54
|
-
const isolate = { children: [] } as unknown as TIsolate;
|
|
55
|
-
const child1 = {} as TIsolate;
|
|
56
|
-
const child2 = {} as TIsolate;
|
|
57
|
-
|
|
58
|
-
expect(isolate.children).toEqual([]);
|
|
59
|
-
IsolateMutator.addChild(isolate, child1);
|
|
60
|
-
expect(isolate.children).toEqual([child1]);
|
|
61
|
-
IsolateMutator.addChild(isolate, child2);
|
|
62
|
-
expect(isolate.children).toEqual([child1, child2]);
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
it('should set parent of the child', () => {
|
|
66
|
-
const isolate = { children: [] } as unknown as TIsolate;
|
|
67
|
-
const child = {} as TIsolate;
|
|
68
|
-
|
|
69
|
-
expect(child.parent).toBeUndefined();
|
|
70
|
-
IsolateMutator.addChild(isolate, child);
|
|
71
|
-
expect(child.parent).toBe(isolate);
|
|
72
|
-
});
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
describe('removeChild', () => {
|
|
76
|
-
it('Should remove child', () => {
|
|
77
|
-
const child1 = {} as TIsolate;
|
|
78
|
-
const child2 = {} as TIsolate;
|
|
79
|
-
const isolate = { children: [child1, child2] } as unknown as TIsolate;
|
|
80
|
-
|
|
81
|
-
expect(isolate.children).toEqual([child1, child2]);
|
|
82
|
-
IsolateMutator.removeChild(isolate, child1);
|
|
83
|
-
expect(isolate.children).toEqual([child2]);
|
|
84
|
-
IsolateMutator.removeChild(isolate, child2);
|
|
85
|
-
expect(isolate.children).toEqual([]);
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
describe('When the child does not exist', () => {
|
|
89
|
-
it('Should no-op', () => {
|
|
90
|
-
const child = {} as TIsolate;
|
|
91
|
-
const isolate = { children: [] } as unknown as TIsolate;
|
|
92
|
-
|
|
93
|
-
expect(isolate.children).toEqual([]);
|
|
94
|
-
IsolateMutator.removeChild(isolate, child);
|
|
95
|
-
expect(isolate.children).toEqual([]);
|
|
96
|
-
});
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
describe('slice', () => {
|
|
101
|
-
it('Should slice children', () => {
|
|
102
|
-
const child1 = {} as TIsolate;
|
|
103
|
-
const child2 = {} as TIsolate;
|
|
104
|
-
const isolate = { children: [child1, child2] } as unknown as TIsolate;
|
|
105
|
-
|
|
106
|
-
expect(isolate.children).toEqual([child1, child2]);
|
|
107
|
-
IsolateMutator.slice(isolate, 1);
|
|
108
|
-
expect(isolate.children).toEqual([child1]);
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
describe('When children are nullish', () => {
|
|
112
|
-
it('Should no-op', () => {
|
|
113
|
-
const isolate = { children: null } as unknown as TIsolate;
|
|
114
|
-
|
|
115
|
-
expect(isolate.children).toBeNull();
|
|
116
|
-
IsolateMutator.slice(isolate, 1);
|
|
117
|
-
expect(isolate.children).toBeNull();
|
|
118
|
-
});
|
|
119
|
-
});
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
describe('abort', () => {
|
|
123
|
-
it('Should abort the controller', () => {
|
|
124
|
-
const isolate = {
|
|
125
|
-
abortController: { abort: vi.fn() },
|
|
126
|
-
} as unknown as TIsolate;
|
|
127
|
-
|
|
128
|
-
expect(isolate.abortController!.abort).not.toHaveBeenCalled();
|
|
129
|
-
IsolateMutator.abort(isolate);
|
|
130
|
-
expect(isolate.abortController!.abort).toHaveBeenCalled();
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
describe('When the controller is nullish', () => {
|
|
134
|
-
it('Should no-op', () => {
|
|
135
|
-
const isolate = { abortController: null } as unknown as TIsolate;
|
|
136
|
-
|
|
137
|
-
expect(isolate.abortController).toBeNull();
|
|
138
|
-
IsolateMutator.abort(isolate);
|
|
139
|
-
expect(isolate.abortController).toBeNull();
|
|
140
|
-
});
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
it('Should abort the controller with the passed reason', () => {
|
|
144
|
-
const isolate = {
|
|
145
|
-
abortController: { abort: vi.fn() },
|
|
146
|
-
} as unknown as TIsolate;
|
|
147
|
-
|
|
148
|
-
expect(isolate.abortController!.abort).not.toHaveBeenCalled();
|
|
149
|
-
IsolateMutator.abort(isolate, 'foo');
|
|
150
|
-
expect(isolate.abortController!.abort).toHaveBeenCalledWith('foo');
|
|
151
|
-
});
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
describe('setData', () => {
|
|
155
|
-
it('Should set the data', () => {
|
|
156
|
-
const isolate = {} as TIsolate;
|
|
157
|
-
const data = { foo: 'bar' };
|
|
158
|
-
|
|
159
|
-
expect(isolate.data).toBeUndefined();
|
|
160
|
-
IsolateMutator.setData(isolate, data);
|
|
161
|
-
expect(isolate.data).toBe(data);
|
|
162
|
-
});
|
|
163
|
-
});
|
|
164
|
-
});
|
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Isolate,
|
|
3
|
-
IsolateStatus,
|
|
4
|
-
TIsolate,
|
|
5
|
-
VestRuntime,
|
|
6
|
-
IsolateMutator,
|
|
7
|
-
} from 'vestjs-runtime';
|
|
8
|
-
import wait from 'wait';
|
|
9
|
-
import { describe, it, expect, vi } from 'vitest';
|
|
10
|
-
|
|
11
|
-
function mockRunTime(fn: () => void) {
|
|
12
|
-
// We mock a minimal runtime context for the test
|
|
13
|
-
const ref = {
|
|
14
|
-
historyNode: null,
|
|
15
|
-
runtimeNode: null,
|
|
16
|
-
runtimeRoot: null,
|
|
17
|
-
};
|
|
18
|
-
return VestRuntime.Run(VestRuntime.createRef(ref as any, vi.fn()), fn);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
describe('Isolate Status Propagation (HAS_PENDING)', () => {
|
|
22
|
-
it('Should set all ancestors to HAS_PENDING when a child is async', async () => {
|
|
23
|
-
let root!: TIsolate;
|
|
24
|
-
let parent!: TIsolate;
|
|
25
|
-
let child!: TIsolate;
|
|
26
|
-
let resolveChild!: (value?: unknown) => void;
|
|
27
|
-
|
|
28
|
-
mockRunTime(() => {
|
|
29
|
-
root = Isolate.create('Root', () => {
|
|
30
|
-
parent = Isolate.create('Parent', () => {
|
|
31
|
-
child = Isolate.create(
|
|
32
|
-
'Child',
|
|
33
|
-
() =>
|
|
34
|
-
new Promise(r => {
|
|
35
|
-
resolveChild = r;
|
|
36
|
-
}),
|
|
37
|
-
);
|
|
38
|
-
});
|
|
39
|
-
});
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
expect(child.status).toBe(IsolateStatus.PENDING);
|
|
43
|
-
expect(parent.status).toBe(IsolateStatus.HAS_PENDING);
|
|
44
|
-
expect(root.status).toBe(IsolateStatus.HAS_PENDING);
|
|
45
|
-
|
|
46
|
-
// This part tests the 'bubbleUpDone' logic (Phase 2 implementation)
|
|
47
|
-
resolveChild();
|
|
48
|
-
await wait(1); // Wait for microtask queue
|
|
49
|
-
await wait(1); // Ensure all callbacks are resolved
|
|
50
|
-
|
|
51
|
-
expect(child.status).toBe(IsolateStatus.DONE);
|
|
52
|
-
expect(parent.status).toBe(IsolateStatus.DONE);
|
|
53
|
-
expect(root.status).toBe(IsolateStatus.DONE);
|
|
54
|
-
});
|
|
55
|
-
it('Should remain HAS_PENDING if a sibling is still pending', async () => {
|
|
56
|
-
let root!: TIsolate;
|
|
57
|
-
let parent!: TIsolate;
|
|
58
|
-
let child1!: TIsolate;
|
|
59
|
-
let child2!: TIsolate;
|
|
60
|
-
let resolve1!: (value?: unknown) => void;
|
|
61
|
-
let resolve2!: (value?: unknown) => void;
|
|
62
|
-
|
|
63
|
-
mockRunTime(() => {
|
|
64
|
-
root = Isolate.create('Root', () => {
|
|
65
|
-
parent = Isolate.create('Parent', () => {
|
|
66
|
-
child1 = Isolate.create(
|
|
67
|
-
'Child1',
|
|
68
|
-
() =>
|
|
69
|
-
new Promise(r => {
|
|
70
|
-
resolve1 = r;
|
|
71
|
-
}),
|
|
72
|
-
);
|
|
73
|
-
child2 = Isolate.create(
|
|
74
|
-
'Child2',
|
|
75
|
-
() =>
|
|
76
|
-
new Promise(r => {
|
|
77
|
-
resolve2 = r;
|
|
78
|
-
}),
|
|
79
|
-
);
|
|
80
|
-
});
|
|
81
|
-
});
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
expect(child1.status).toBe(IsolateStatus.PENDING);
|
|
85
|
-
expect(child2.status).toBe(IsolateStatus.PENDING);
|
|
86
|
-
expect(parent.status).toBe(IsolateStatus.HAS_PENDING);
|
|
87
|
-
expect(root.status).toBe(IsolateStatus.HAS_PENDING);
|
|
88
|
-
|
|
89
|
-
// Resolve first child
|
|
90
|
-
resolve1();
|
|
91
|
-
await wait(1); // Wait for microtask queue
|
|
92
|
-
await wait(1); // Ensure callbacks
|
|
93
|
-
|
|
94
|
-
// Parent should still be HAS_PENDING because Child2 is pending
|
|
95
|
-
expect(child1.status).toBe(IsolateStatus.DONE);
|
|
96
|
-
expect(child2.status).toBe(IsolateStatus.PENDING);
|
|
97
|
-
expect(parent.status).toBe(IsolateStatus.HAS_PENDING);
|
|
98
|
-
expect(root.status).toBe(IsolateStatus.HAS_PENDING);
|
|
99
|
-
|
|
100
|
-
// Resolve second child
|
|
101
|
-
resolve2();
|
|
102
|
-
await wait(1); // Wait for microtask queue
|
|
103
|
-
await wait(1);
|
|
104
|
-
|
|
105
|
-
// Parent and root should now transition to DONE
|
|
106
|
-
expect(child2.status).toBe(IsolateStatus.DONE);
|
|
107
|
-
expect(parent.status).toBe(IsolateStatus.DONE);
|
|
108
|
-
expect(root.status).toBe(IsolateStatus.DONE);
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
it('Should remain HAS_PENDING if an indirect descendant is pending', async () => {
|
|
112
|
-
let parent!: TIsolate;
|
|
113
|
-
let nestedParent!: TIsolate;
|
|
114
|
-
let leaf!: TIsolate;
|
|
115
|
-
let resolveLeaf!: (value?: unknown) => void;
|
|
116
|
-
|
|
117
|
-
mockRunTime(() => {
|
|
118
|
-
parent = Isolate.create('Parent', () => {
|
|
119
|
-
nestedParent = Isolate.create('NestedParent', () => {
|
|
120
|
-
leaf = Isolate.create(
|
|
121
|
-
'Leaf',
|
|
122
|
-
() =>
|
|
123
|
-
new Promise(r => {
|
|
124
|
-
resolveLeaf = r;
|
|
125
|
-
}),
|
|
126
|
-
);
|
|
127
|
-
});
|
|
128
|
-
});
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
expect(leaf.status).toBe(IsolateStatus.PENDING);
|
|
132
|
-
expect(nestedParent.status).toBe(IsolateStatus.HAS_PENDING);
|
|
133
|
-
expect(parent.status).toBe(IsolateStatus.HAS_PENDING);
|
|
134
|
-
|
|
135
|
-
// Resolve leaf
|
|
136
|
-
resolveLeaf();
|
|
137
|
-
await wait(1); // Wait for microtask queue
|
|
138
|
-
await wait(1);
|
|
139
|
-
|
|
140
|
-
// All should transition to DONE
|
|
141
|
-
expect(leaf.status).toBe(IsolateStatus.DONE);
|
|
142
|
-
expect(nestedParent.status).toBe(IsolateStatus.DONE);
|
|
143
|
-
expect(parent.status).toBe(IsolateStatus.DONE);
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
it('Should prevent manual setDone transition if children are active', async () => {
|
|
147
|
-
let parent!: TIsolate;
|
|
148
|
-
let child!: TIsolate;
|
|
149
|
-
|
|
150
|
-
mockRunTime(() => {
|
|
151
|
-
parent = Isolate.create('Parent', () => {
|
|
152
|
-
child = Isolate.create(
|
|
153
|
-
'Child',
|
|
154
|
-
() => new Promise(() => {}), // Never resolves
|
|
155
|
-
);
|
|
156
|
-
});
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
expect(child.status).toBe(IsolateStatus.PENDING);
|
|
160
|
-
expect(parent.status).toBe(IsolateStatus.HAS_PENDING);
|
|
161
|
-
|
|
162
|
-
// Try to force setDone on parent
|
|
163
|
-
mockRunTime(() => {
|
|
164
|
-
IsolateMutator.setDone(parent);
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
// Should still be HAS_PENDING
|
|
168
|
-
expect(parent.status).toBe(IsolateStatus.HAS_PENDING);
|
|
169
|
-
});
|
|
170
|
-
});
|