@adaas/a-concept 0.1.38 → 0.1.40
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/index.cjs +2 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/global/A-Context/A-Context.class.ts +10 -13
- package/src/global/A-Error/A_Error.class.ts +14 -1
- package/src/global/A-Feature/A-Feature.class.ts +3 -0
- package/src/global/A-Scope/A-Scope.class.ts +1 -4
- package/tests/A-Feature.test.ts +429 -334
package/tests/A-Feature.test.ts
CHANGED
|
@@ -5,418 +5,513 @@ import { A_Scope } from "@adaas/a-concept/global/A-Scope/A-Scope.class";
|
|
|
5
5
|
import { A_Caller } from '@adaas/a-concept/global/A-Caller/A_Caller.class';
|
|
6
6
|
import { A_Context } from '@adaas/a-concept/global/A-Context/A-Context.class';
|
|
7
7
|
import { A_TYPES__ComponentMetaKey } from '@adaas/a-concept/global/A-Component/A-Component.constants';
|
|
8
|
+
import { A_TYPES__FeatureState } from "../src";
|
|
8
9
|
|
|
9
10
|
jest.retryTimes(0);
|
|
10
11
|
|
|
11
12
|
describe('A-Feature tests', () => {
|
|
12
|
-
it('Should Allow to create a feature from component', async () => {
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
// it('Should Allow to create a feature from component', async () => {
|
|
14
|
+
// const testComponent = new A_Component()
|
|
15
|
+
// A_Context.root.register(testComponent);
|
|
16
|
+
|
|
17
|
+
// const feature = new A_Feature({
|
|
18
|
+
// name: 'testFeature',
|
|
19
|
+
// component: testComponent,
|
|
20
|
+
// });
|
|
21
|
+
|
|
22
|
+
// expect(feature).toBeInstanceOf(A_Feature);
|
|
23
|
+
// expect(feature.scope.parent).toBe(A_Context.root);
|
|
24
|
+
|
|
25
|
+
// });
|
|
26
|
+
// it('Should Allow to create a feature with steps', async () => {
|
|
27
|
+
// const template = [
|
|
28
|
+
// {
|
|
29
|
+
// name: 'A_Component.testHandler',
|
|
30
|
+
// component: A_Component,
|
|
31
|
+
// handler: 'testHandler',
|
|
32
|
+
// }
|
|
33
|
+
// ]
|
|
34
|
+
|
|
35
|
+
// const feature = new A_Feature({
|
|
36
|
+
// name: 'testFeature',
|
|
37
|
+
// scope: new A_Scope(),
|
|
38
|
+
// template
|
|
39
|
+
// });
|
|
40
|
+
|
|
41
|
+
// expect(feature).toBeInstanceOf(A_Feature);
|
|
42
|
+
// });
|
|
43
|
+
// it('Should be possible to execute a feature with steps as a template on the component', async () => {
|
|
44
|
+
// // 1) create a base component with some feature
|
|
45
|
+
// class MyExtendedComponent extends A_Component {
|
|
46
|
+
|
|
47
|
+
// async testHandler(
|
|
48
|
+
// @A_Inject(A_Caller) caller: MyComponent
|
|
49
|
+
// ) {
|
|
50
|
+
// caller.sum = 2;
|
|
51
|
+
// }
|
|
52
|
+
// }
|
|
53
|
+
|
|
54
|
+
// // 2) create a custom component with a defined template feature
|
|
55
|
+
// class MyComponent extends A_Component {
|
|
56
|
+
// sum: number = 0;
|
|
57
|
+
|
|
58
|
+
// @A_Feature.Define({
|
|
59
|
+
// invoke: true,
|
|
60
|
+
// template: [{
|
|
61
|
+
// name: 'MyExtendedComponent.testHandler',
|
|
62
|
+
// component: MyExtendedComponent,
|
|
63
|
+
// handler: 'testHandler',
|
|
64
|
+
// behavior: 'sync',
|
|
65
|
+
// before: '',
|
|
66
|
+
// after: ''
|
|
67
|
+
// },
|
|
68
|
+
// {
|
|
69
|
+
// name: 'MyExtendedComponent.testHandler',
|
|
70
|
+
// component: MyExtendedComponent,
|
|
71
|
+
// handler: 'testHandler'
|
|
72
|
+
// }]
|
|
73
|
+
// })
|
|
74
|
+
// async testHandler() { }
|
|
75
|
+
// }
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
// // 3) create a running scope
|
|
79
|
+
// const scope = new A_Scope({ name: 'TestScope' });
|
|
80
|
+
// scope.register(MyExtendedComponent);
|
|
81
|
+
// scope.register(MyComponent);
|
|
82
|
+
|
|
83
|
+
// // 4) create an instance of the component from the scope
|
|
84
|
+
// const myComponent = scope.resolve(MyComponent)!;
|
|
85
|
+
// expect(myComponent).toBeInstanceOf(MyComponent);
|
|
86
|
+
// expect(myComponent.sum).toBe(0);
|
|
87
|
+
|
|
88
|
+
// // 5) call the feature caller to execute the feature
|
|
89
|
+
// await myComponent.testHandler();
|
|
90
|
+
|
|
91
|
+
// // 6) check the results
|
|
92
|
+
// expect(myComponent.sum).toBe(2);
|
|
93
|
+
|
|
94
|
+
// });
|
|
95
|
+
// it('Should be possible to execute a feature with steps as a template on the component with string component declaration', async () => {
|
|
96
|
+
// // 1) create a base component with some feature
|
|
97
|
+
// class MyExtendedComponent2 extends A_Component {
|
|
98
|
+
|
|
99
|
+
// async testHandler(
|
|
100
|
+
// @A_Inject(A_Caller) caller: MyComponent2
|
|
101
|
+
// ) {
|
|
102
|
+
// caller.sum = 2;
|
|
103
|
+
// }
|
|
104
|
+
// }
|
|
105
|
+
|
|
106
|
+
// // 2) create a custom component with a defined template feature
|
|
107
|
+
// class MyComponent2 extends A_Component {
|
|
108
|
+
// sum: number = 0;
|
|
109
|
+
|
|
110
|
+
// @A_Feature.Define({
|
|
111
|
+
// invoke: true,
|
|
112
|
+
// template: [{
|
|
113
|
+
// name: 'MyExtendedComponent2.testHandler',
|
|
114
|
+
// component: 'MyExtendedComponent2',
|
|
115
|
+
// handler: 'testHandler',
|
|
116
|
+
// behavior: 'sync',
|
|
117
|
+
// before: '',
|
|
118
|
+
// after: ''
|
|
119
|
+
// }]
|
|
120
|
+
// })
|
|
121
|
+
// async testHandler() { }
|
|
122
|
+
// }
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
// // 3) create a running scope
|
|
126
|
+
// const scope = new A_Scope({ name: 'TestScope' });
|
|
127
|
+
// scope.register(MyExtendedComponent2);
|
|
128
|
+
// scope.register(MyComponent2);
|
|
129
|
+
|
|
130
|
+
// // 4) create an instance of the component from the scope
|
|
131
|
+
// const myComponent = scope.resolve(MyComponent2)!;
|
|
132
|
+
// expect(myComponent).toBeInstanceOf(MyComponent2);
|
|
133
|
+
// expect(myComponent.sum).toBe(0);
|
|
134
|
+
|
|
135
|
+
// // 5) call the feature caller to execute the feature
|
|
136
|
+
// await myComponent.testHandler();
|
|
137
|
+
|
|
138
|
+
// // 6) check the results
|
|
139
|
+
// expect(myComponent.sum).toBe(2);
|
|
140
|
+
|
|
141
|
+
// });
|
|
142
|
+
// it('Should execute feature steps in base order', async () => {
|
|
143
|
+
// const executionOrder: string[] = [];
|
|
144
|
+
|
|
145
|
+
// // 1) create a base component with some feature
|
|
146
|
+
// class My_Component extends A_Component {
|
|
147
|
+
// async methodA() {
|
|
148
|
+
// await this.call('myFeature')
|
|
149
|
+
// }
|
|
150
|
+
|
|
151
|
+
// @A_Feature.Extend({
|
|
152
|
+
// name: 'myFeature',
|
|
153
|
+
// })
|
|
154
|
+
// async stepOne(
|
|
155
|
+
// ) {
|
|
156
|
+
// executionOrder.push('stepOne');
|
|
157
|
+
// }
|
|
158
|
+
|
|
159
|
+
// @A_Feature.Extend({
|
|
160
|
+
// name: 'myFeature',
|
|
161
|
+
// })
|
|
162
|
+
// async stepTwo(
|
|
163
|
+
// ) {
|
|
164
|
+
// executionOrder.push('stepTwo');
|
|
165
|
+
// }
|
|
166
|
+
|
|
167
|
+
// @A_Feature.Extend({
|
|
168
|
+
// name: 'myFeature',
|
|
169
|
+
// })
|
|
170
|
+
// async stepThree(
|
|
171
|
+
// ) {
|
|
172
|
+
// executionOrder.push('stepThree');
|
|
173
|
+
// }
|
|
174
|
+
// }
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
// // 2) create a running scope
|
|
178
|
+
// const scope = new A_Scope({ name: 'TestScope', components: [My_Component] });
|
|
179
|
+
|
|
180
|
+
// // 3) create an instance of the component from the scope
|
|
181
|
+
// const myComponent = scope.resolve(My_Component)!;
|
|
182
|
+
// expect(myComponent).toBeInstanceOf(My_Component);
|
|
183
|
+
|
|
184
|
+
// // 4) call the feature caller to execute the feature
|
|
185
|
+
// await myComponent.methodA();
|
|
186
|
+
|
|
187
|
+
// // 5) check the results
|
|
188
|
+
// expect(executionOrder).toEqual(['stepOne', 'stepTwo', 'stepThree']);
|
|
189
|
+
// });
|
|
190
|
+
// it('Should execute feature steps in proper order', async () => {
|
|
191
|
+
// const executionOrder: string[] = [];
|
|
192
|
+
|
|
193
|
+
// // 1) create a base component with some feature
|
|
194
|
+
// class My_Component extends A_Component {
|
|
195
|
+
// async methodA() {
|
|
196
|
+
// await this.call('myFeature')
|
|
197
|
+
// }
|
|
198
|
+
|
|
199
|
+
// @A_Feature.Extend({
|
|
200
|
+
// name: 'myFeature',
|
|
201
|
+
// after: ['My_Component.stepTwo'],
|
|
202
|
+
// })
|
|
203
|
+
// async stepOne(
|
|
204
|
+
// ) {
|
|
205
|
+
// executionOrder.push('stepOne');
|
|
206
|
+
// }
|
|
207
|
+
|
|
208
|
+
// @A_Feature.Extend({
|
|
209
|
+
// name: 'myFeature',
|
|
210
|
+
// })
|
|
211
|
+
// async stepTwo(
|
|
212
|
+
// ) {
|
|
213
|
+
// executionOrder.push('stepTwo');
|
|
214
|
+
// }
|
|
215
|
+
// }
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
// // 2) create a running scope
|
|
219
|
+
// const scope = new A_Scope({ name: 'TestScope', components: [My_Component] });
|
|
220
|
+
|
|
221
|
+
// // 3) create an instance of the component from the scope
|
|
222
|
+
// const myComponent = scope.resolve(My_Component)!;
|
|
223
|
+
// expect(myComponent).toBeInstanceOf(My_Component);
|
|
224
|
+
|
|
225
|
+
// // 4) call the feature caller to execute the feature
|
|
226
|
+
// await myComponent.methodA();
|
|
227
|
+
|
|
228
|
+
// // 5) check the results
|
|
229
|
+
// expect(executionOrder).toEqual(['stepTwo', 'stepOne']);
|
|
230
|
+
// });
|
|
231
|
+
|
|
232
|
+
// it('Should allow to define a feature', async () => {
|
|
233
|
+
// const executionOrder: string[] = [];
|
|
234
|
+
|
|
235
|
+
// // 1) create a base component with some feature
|
|
236
|
+
// class My_Component extends A_Component {
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
// @A_Feature.Define({ invoke: true })
|
|
240
|
+
// @A_Feature.Extend({
|
|
241
|
+
// name: 'myFeature',
|
|
242
|
+
// })
|
|
243
|
+
// async feature1(
|
|
244
|
+
// @A_Inject(A_Component) component: A_Component
|
|
245
|
+
// ) { }
|
|
246
|
+
|
|
247
|
+
// @A_Feature.Extend({
|
|
248
|
+
// name: 'feature1',
|
|
249
|
+
// })
|
|
250
|
+
// async feature1Extension() {
|
|
251
|
+
// executionOrder.push('stepOne');
|
|
252
|
+
// }
|
|
253
|
+
|
|
254
|
+
// @A_Feature.Define()
|
|
255
|
+
// async feature2() {
|
|
256
|
+
// await this.call('feature2');
|
|
257
|
+
// }
|
|
15
258
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
259
|
+
// @A_Feature.Extend({
|
|
260
|
+
// name: 'feature2',
|
|
261
|
+
// })
|
|
262
|
+
// async feature2Extension() {
|
|
263
|
+
// executionOrder.push('stepTwo');
|
|
264
|
+
// }
|
|
20
265
|
|
|
21
|
-
|
|
22
|
-
expect(feature.scope.parent).toBe(A_Context.root);
|
|
266
|
+
// }
|
|
23
267
|
|
|
24
|
-
});
|
|
25
|
-
it('Should Allow to create a feature with steps', async () => {
|
|
26
|
-
const template = [
|
|
27
|
-
{
|
|
28
|
-
name: 'A_Component.testHandler',
|
|
29
|
-
component: A_Component,
|
|
30
|
-
handler: 'testHandler',
|
|
31
|
-
}
|
|
32
|
-
]
|
|
33
268
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
scope: new A_Scope(),
|
|
37
|
-
template
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
expect(feature).toBeInstanceOf(A_Feature);
|
|
41
|
-
});
|
|
42
|
-
it('Should be possible to execute a feature with steps as a template on the component', async () => {
|
|
43
|
-
// 1) create a base component with some feature
|
|
44
|
-
class MyExtendedComponent extends A_Component {
|
|
45
|
-
|
|
46
|
-
async testHandler(
|
|
47
|
-
@A_Inject(A_Caller) caller: MyComponent
|
|
48
|
-
) {
|
|
49
|
-
caller.sum = 2;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// 2) create a custom component with a defined template feature
|
|
54
|
-
class MyComponent extends A_Component {
|
|
55
|
-
sum: number = 0;
|
|
56
|
-
|
|
57
|
-
@A_Feature.Define({
|
|
58
|
-
invoke: true,
|
|
59
|
-
template: [{
|
|
60
|
-
name: 'MyExtendedComponent.testHandler',
|
|
61
|
-
component: MyExtendedComponent,
|
|
62
|
-
handler: 'testHandler',
|
|
63
|
-
behavior: 'sync',
|
|
64
|
-
before: '',
|
|
65
|
-
after: ''
|
|
66
|
-
},
|
|
67
|
-
{
|
|
68
|
-
name: 'MyExtendedComponent.testHandler',
|
|
69
|
-
component: MyExtendedComponent,
|
|
70
|
-
handler: 'testHandler'
|
|
71
|
-
}]
|
|
72
|
-
})
|
|
73
|
-
async testHandler() { }
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
// 3) create a running scope
|
|
78
|
-
const scope = new A_Scope({ name: 'TestScope' });
|
|
79
|
-
scope.register(MyExtendedComponent);
|
|
80
|
-
scope.register(MyComponent);
|
|
81
|
-
|
|
82
|
-
// 4) create an instance of the component from the scope
|
|
83
|
-
const myComponent = scope.resolve(MyComponent)!;
|
|
84
|
-
expect(myComponent).toBeInstanceOf(MyComponent);
|
|
85
|
-
expect(myComponent.sum).toBe(0);
|
|
86
|
-
|
|
87
|
-
// 5) call the feature caller to execute the feature
|
|
88
|
-
await myComponent.testHandler();
|
|
89
|
-
|
|
90
|
-
// 6) check the results
|
|
91
|
-
expect(myComponent.sum).toBe(2);
|
|
92
|
-
|
|
93
|
-
});
|
|
94
|
-
it('Should be possible to execute a feature with steps as a template on the component with string component declaration', async () => {
|
|
95
|
-
// 1) create a base component with some feature
|
|
96
|
-
class MyExtendedComponent2 extends A_Component {
|
|
269
|
+
// // 2) create a running scope
|
|
270
|
+
// const scope = new A_Scope({ name: 'TestScope', components: [My_Component] });
|
|
97
271
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
caller.sum = 2;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
272
|
+
// // 3) create an instance of the component from the scope
|
|
273
|
+
// const myComponent = scope.resolve(My_Component)!;
|
|
274
|
+
// expect(myComponent).toBeInstanceOf(My_Component);
|
|
104
275
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
sum: number = 0;
|
|
276
|
+
// // 4) call the feature caller to execute the feature
|
|
277
|
+
// await myComponent.feature1(new A_Component());
|
|
108
278
|
|
|
109
|
-
|
|
110
|
-
invoke: true,
|
|
111
|
-
template: [{
|
|
112
|
-
name: 'MyExtendedComponent2.testHandler',
|
|
113
|
-
component: 'MyExtendedComponent2',
|
|
114
|
-
handler: 'testHandler',
|
|
115
|
-
behavior: 'sync',
|
|
116
|
-
before: '',
|
|
117
|
-
after: ''
|
|
118
|
-
}]
|
|
119
|
-
})
|
|
120
|
-
async testHandler() { }
|
|
121
|
-
}
|
|
279
|
+
// await myComponent.feature2();
|
|
122
280
|
|
|
281
|
+
// // 5) check the results
|
|
282
|
+
// expect(executionOrder).toEqual(['stepOne', 'stepTwo']);
|
|
283
|
+
// });
|
|
284
|
+
// it('Should inherit feature definitions & extensions', async () => {
|
|
285
|
+
// const executionOrder: string[] = [];
|
|
123
286
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
scope.register(MyExtendedComponent2);
|
|
127
|
-
scope.register(MyComponent2);
|
|
287
|
+
// // 1) create a base component with some feature
|
|
288
|
+
// class My_Component extends A_Component {
|
|
128
289
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
expect(myComponent.sum).toBe(0);
|
|
290
|
+
// @A_Feature.Define({ invoke: false })
|
|
291
|
+
// async feature1() {
|
|
292
|
+
// executionOrder.push('stepOne');
|
|
133
293
|
|
|
134
|
-
|
|
135
|
-
|
|
294
|
+
// await this.call('feature1');
|
|
295
|
+
// }
|
|
136
296
|
|
|
137
|
-
|
|
138
|
-
|
|
297
|
+
// @A_Feature.Extend({
|
|
298
|
+
// name: 'feature1',
|
|
299
|
+
// })
|
|
300
|
+
// async feature1Extension(
|
|
301
|
+
// @A_Inject(A_Scope) scope: A_Scope
|
|
302
|
+
// ) {
|
|
303
|
+
// executionOrder.push('stepTwo');
|
|
304
|
+
// }
|
|
305
|
+
// }
|
|
139
306
|
|
|
140
|
-
});
|
|
141
|
-
it('Should execute feature steps in base order', async () => {
|
|
142
|
-
const executionOrder: string[] = [];
|
|
143
307
|
|
|
144
|
-
|
|
145
|
-
class My_Component extends A_Component {
|
|
146
|
-
async methodA() {
|
|
147
|
-
await this.call('myFeature')
|
|
148
|
-
}
|
|
308
|
+
// class My_Child_Component extends My_Component { }
|
|
149
309
|
|
|
150
|
-
@A_Feature.Extend({
|
|
151
|
-
name: 'myFeature',
|
|
152
|
-
})
|
|
153
|
-
async stepOne(
|
|
154
|
-
) {
|
|
155
|
-
executionOrder.push('stepOne');
|
|
156
|
-
}
|
|
157
310
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
})
|
|
161
|
-
async stepTwo(
|
|
162
|
-
) {
|
|
163
|
-
executionOrder.push('stepTwo');
|
|
164
|
-
}
|
|
311
|
+
// // 2) create a running scope
|
|
312
|
+
// const scope = new A_Scope({ name: 'TestScope', components: [My_Child_Component] });
|
|
165
313
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
async stepThree(
|
|
170
|
-
) {
|
|
171
|
-
executionOrder.push('stepThree');
|
|
172
|
-
}
|
|
173
|
-
}
|
|
314
|
+
// // 3) create an instance of the component from the scope
|
|
315
|
+
// const myComponent = scope.resolve(My_Child_Component)!;
|
|
316
|
+
// expect(myComponent).toBeInstanceOf(My_Child_Component);
|
|
174
317
|
|
|
318
|
+
// await myComponent.feature1();
|
|
175
319
|
|
|
176
|
-
|
|
177
|
-
|
|
320
|
+
// expect(executionOrder).toEqual(['stepOne', 'stepTwo']);
|
|
321
|
+
// });
|
|
178
322
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
expect(myComponent).toBeInstanceOf(My_Component);
|
|
323
|
+
// it('Should allow override feature extension', async () => {
|
|
324
|
+
// const executionOrder: string[] = [];
|
|
182
325
|
|
|
183
|
-
|
|
184
|
-
|
|
326
|
+
// // 1) create a base component with some feature
|
|
327
|
+
// class My_Component extends A_Component {
|
|
185
328
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
const executionOrder: string[] = [];
|
|
329
|
+
// @A_Feature.Define({ invoke: true })
|
|
330
|
+
// async feature1() {
|
|
331
|
+
// executionOrder.push('stepOne');
|
|
332
|
+
// }
|
|
191
333
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
334
|
+
// @A_Feature.Extend({
|
|
335
|
+
// name: 'feature1',
|
|
336
|
+
// })
|
|
337
|
+
// async feature1Extension(
|
|
338
|
+
// @A_Inject(A_Scope) scope: A_Scope
|
|
339
|
+
// ) {
|
|
340
|
+
// executionOrder.push('stepTwo');
|
|
341
|
+
// }
|
|
342
|
+
// }
|
|
197
343
|
|
|
198
|
-
@A_Feature.Extend({
|
|
199
|
-
name: 'myFeature',
|
|
200
|
-
after: ['My_Component.stepTwo'],
|
|
201
|
-
})
|
|
202
|
-
async stepOne(
|
|
203
|
-
) {
|
|
204
|
-
executionOrder.push('stepOne');
|
|
205
|
-
}
|
|
206
344
|
|
|
207
|
-
|
|
208
|
-
name: 'myFeature',
|
|
209
|
-
})
|
|
210
|
-
async stepTwo(
|
|
211
|
-
) {
|
|
212
|
-
executionOrder.push('stepTwo');
|
|
213
|
-
}
|
|
214
|
-
}
|
|
345
|
+
// class My_Child_Component extends My_Component {
|
|
215
346
|
|
|
347
|
+
// async feature1Extension(
|
|
348
|
+
// @A_Inject(A_Scope) scope: A_Scope
|
|
349
|
+
// ) {
|
|
350
|
+
// executionOrder.push('stepThree');
|
|
351
|
+
// }
|
|
352
|
+
// }
|
|
216
353
|
|
|
217
|
-
// 2) create a running scope
|
|
218
|
-
const scope = new A_Scope({ name: 'TestScope', components: [My_Component] });
|
|
219
354
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
expect(myComponent).toBeInstanceOf(My_Component);
|
|
355
|
+
// // 2) create a running scope
|
|
356
|
+
// const scope = new A_Scope({ name: 'TestScope', components: [My_Child_Component] });
|
|
223
357
|
|
|
224
|
-
|
|
225
|
-
|
|
358
|
+
// // 3) create an instance of the component from the scope
|
|
359
|
+
// const myComponent = scope.resolve(My_Child_Component)!;
|
|
360
|
+
// expect(myComponent).toBeInstanceOf(My_Child_Component);
|
|
226
361
|
|
|
227
|
-
|
|
228
|
-
expect(executionOrder).toEqual(['stepTwo', 'stepOne']);
|
|
229
|
-
});
|
|
362
|
+
// await myComponent.feature1();
|
|
230
363
|
|
|
231
|
-
|
|
232
|
-
|
|
364
|
+
// expect(executionOrder).toEqual(['stepOne', 'stepThree']);
|
|
365
|
+
// });
|
|
233
366
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
@A_Feature.Define({ invoke: true })
|
|
239
|
-
@A_Feature.Extend({
|
|
240
|
-
name: 'myFeature',
|
|
241
|
-
})
|
|
242
|
-
async feature1(
|
|
243
|
-
@A_Inject(A_Component) component: A_Component
|
|
244
|
-
) { }
|
|
245
|
-
|
|
246
|
-
@A_Feature.Extend({
|
|
247
|
-
name: 'feature1',
|
|
248
|
-
})
|
|
249
|
-
async feature1Extension() {
|
|
250
|
-
executionOrder.push('stepOne');
|
|
251
|
-
}
|
|
367
|
+
// it('Should allow proceed with external scope', async () => {
|
|
368
|
+
// const executionOrder: string[] = [];
|
|
252
369
|
|
|
253
|
-
|
|
254
|
-
async feature2() {
|
|
255
|
-
await this.call('feature2');
|
|
256
|
-
}
|
|
370
|
+
// class CustomComponent extends A_Component {
|
|
257
371
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
async feature2Extension() {
|
|
262
|
-
executionOrder.push('stepTwo');
|
|
263
|
-
}
|
|
372
|
+
// doSomething() {
|
|
373
|
+
// executionOrder.push('customComponentAction');
|
|
374
|
+
// }
|
|
264
375
|
|
|
265
|
-
|
|
376
|
+
// }
|
|
266
377
|
|
|
378
|
+
// // 1) create a base component with some feature
|
|
379
|
+
// class ComponentA extends A_Component {
|
|
267
380
|
|
|
268
|
-
|
|
269
|
-
|
|
381
|
+
// @A_Feature.Define({ invoke: false })
|
|
382
|
+
// async feature1() {
|
|
383
|
+
// const scope = new A_Scope({ name: 'ExternalScopeCaller', components: [CustomComponent] });
|
|
270
384
|
|
|
271
|
-
|
|
272
|
-
const myComponent = scope.resolve(My_Component)!;
|
|
273
|
-
expect(myComponent).toBeInstanceOf(My_Component);
|
|
385
|
+
// executionOrder.push('stepOne');
|
|
274
386
|
|
|
275
|
-
|
|
276
|
-
|
|
387
|
+
// await this.call('feature1', scope);
|
|
388
|
+
// }
|
|
389
|
+
// }
|
|
277
390
|
|
|
278
|
-
await myComponent.feature2();
|
|
279
391
|
|
|
280
|
-
|
|
281
|
-
expect(executionOrder).toEqual(['stepOne', 'stepTwo']);
|
|
282
|
-
});
|
|
283
|
-
it('Should inherit feature definitions & extensions', async () => {
|
|
284
|
-
const executionOrder: string[] = [];
|
|
392
|
+
// class ComponentB extends A_Component {
|
|
285
393
|
|
|
286
|
-
|
|
287
|
-
|
|
394
|
+
// @A_Feature.Extend({
|
|
395
|
+
// name: 'feature1',
|
|
396
|
+
// })
|
|
397
|
+
// async feature1Extension(
|
|
398
|
+
// @A_Inject(A_Scope) scope: A_Scope,
|
|
399
|
+
// @A_Inject(CustomComponent) customComponent: CustomComponent
|
|
400
|
+
// ) {
|
|
401
|
+
// expect(customComponent).toBeInstanceOf(CustomComponent);
|
|
402
|
+
// expect(customComponent.doSomething).toBeInstanceOf(Function);
|
|
288
403
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
404
|
+
// executionOrder.push('stepThree');
|
|
405
|
+
// }
|
|
406
|
+
// }
|
|
292
407
|
|
|
293
|
-
await this.call('feature1');
|
|
294
|
-
}
|
|
295
408
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
})
|
|
299
|
-
async feature1Extension(
|
|
300
|
-
@A_Inject(A_Scope) scope: A_Scope
|
|
301
|
-
) {
|
|
302
|
-
executionOrder.push('stepTwo');
|
|
303
|
-
}
|
|
304
|
-
}
|
|
409
|
+
// // 2) create a running scope
|
|
410
|
+
// const scope = new A_Scope({ name: 'TestScope' , components: [ComponentA, ComponentB] });
|
|
305
411
|
|
|
306
412
|
|
|
307
|
-
|
|
413
|
+
// // 3) create an instance of the component from the scope
|
|
414
|
+
// const myComponent = scope.resolve(ComponentA)!;
|
|
415
|
+
// expect(myComponent).toBeInstanceOf(ComponentA);
|
|
308
416
|
|
|
417
|
+
// await myComponent.feature1();
|
|
309
418
|
|
|
310
|
-
|
|
311
|
-
|
|
419
|
+
// expect(executionOrder).toEqual(['stepOne', 'stepThree']);
|
|
420
|
+
// });
|
|
421
|
+
it('Should allow to interrupt a new feature', async () => {
|
|
422
|
+
const feature = new A_Feature({
|
|
423
|
+
name: 'testFeature',
|
|
424
|
+
scope: new A_Scope(),
|
|
425
|
+
template: [
|
|
426
|
+
{
|
|
427
|
+
name: 'A_Component.testHandler',
|
|
428
|
+
component: 'A_Component',
|
|
429
|
+
handler: 'testHandler',
|
|
430
|
+
}
|
|
431
|
+
]
|
|
432
|
+
});
|
|
312
433
|
|
|
313
|
-
// 3) create an instance of the component from the scope
|
|
314
|
-
const myComponent = scope.resolve(My_Child_Component)!;
|
|
315
|
-
expect(myComponent).toBeInstanceOf(My_Child_Component);
|
|
316
434
|
|
|
317
|
-
|
|
435
|
+
feature.interrupt();
|
|
318
436
|
|
|
319
|
-
expect(
|
|
437
|
+
expect(feature.state).toBe(A_TYPES__FeatureState.INTERRUPTED);
|
|
320
438
|
});
|
|
321
|
-
|
|
322
|
-
it('Should allow override feature extension', async () => {
|
|
439
|
+
it('Should allow to interrupt feature with async processing', async () => {
|
|
323
440
|
const executionOrder: string[] = [];
|
|
324
441
|
|
|
442
|
+
|
|
325
443
|
// 1) create a base component with some feature
|
|
326
|
-
class
|
|
444
|
+
class ComponentA extends A_Component {
|
|
327
445
|
|
|
328
|
-
@A_Feature.Define({ invoke: true })
|
|
329
446
|
async feature1() {
|
|
330
|
-
|
|
447
|
+
await new Promise<void>(async (resolve) => {
|
|
448
|
+
setTimeout(() => {
|
|
449
|
+
executionOrder.push('feature1');
|
|
450
|
+
resolve();
|
|
451
|
+
}, 2000);
|
|
452
|
+
});
|
|
331
453
|
}
|
|
332
454
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
455
|
+
async feature2() {
|
|
456
|
+
await new Promise<void>(async (resolve) => {
|
|
457
|
+
setTimeout(() => {
|
|
458
|
+
executionOrder.push('feature2');
|
|
459
|
+
resolve();
|
|
460
|
+
}, 1000);
|
|
461
|
+
});
|
|
340
462
|
}
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
class My_Child_Component extends My_Component {
|
|
345
463
|
|
|
346
|
-
async
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
464
|
+
async feature3() {
|
|
465
|
+
await new Promise<void>(async (resolve) => {
|
|
466
|
+
setTimeout(() => {
|
|
467
|
+
executionOrder.push('feature3');
|
|
468
|
+
resolve();
|
|
469
|
+
}, 1000);
|
|
470
|
+
});
|
|
350
471
|
}
|
|
351
472
|
}
|
|
352
473
|
|
|
353
474
|
|
|
354
475
|
// 2) create a running scope
|
|
355
|
-
const scope = new A_Scope({ name: 'TestScope', components: [
|
|
356
|
-
|
|
357
|
-
// 3) create an instance of the component from the scope
|
|
358
|
-
const myComponent = scope.resolve(My_Child_Component)!;
|
|
359
|
-
expect(myComponent).toBeInstanceOf(My_Child_Component);
|
|
360
|
-
|
|
361
|
-
await myComponent.feature1();
|
|
362
|
-
|
|
363
|
-
expect(executionOrder).toEqual(['stepOne', 'stepThree']);
|
|
364
|
-
});
|
|
365
|
-
|
|
366
|
-
it('Should allow proceed with external scope', async () => {
|
|
367
|
-
const executionOrder: string[] = [];
|
|
368
|
-
|
|
369
|
-
class CustomComponent extends A_Component {
|
|
476
|
+
const scope = new A_Scope({ name: 'TestScope', components: [ComponentA] });
|
|
370
477
|
|
|
371
|
-
doSomething() {
|
|
372
|
-
executionOrder.push('customComponentAction');
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
// 1) create a base component with some feature
|
|
378
|
-
class ComponentA extends A_Component {
|
|
379
|
-
|
|
380
|
-
@A_Feature.Define({ invoke: false })
|
|
381
|
-
async feature1() {
|
|
382
|
-
const scope = new A_Scope({ name: 'ExternalScopeCaller', components: [CustomComponent] });
|
|
383
|
-
|
|
384
|
-
executionOrder.push('stepOne');
|
|
385
|
-
|
|
386
|
-
await this.call('feature1', scope);
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
class ComponentB extends A_Component {
|
|
392
|
-
|
|
393
|
-
@A_Feature.Extend({
|
|
394
|
-
name: 'feature1',
|
|
395
|
-
})
|
|
396
|
-
async feature1Extension(
|
|
397
|
-
@A_Inject(A_Scope) scope: A_Scope,
|
|
398
|
-
@A_Inject(CustomComponent) customComponent: CustomComponent
|
|
399
|
-
) {
|
|
400
|
-
expect(customComponent).toBeInstanceOf(CustomComponent);
|
|
401
|
-
expect(customComponent.doSomething).toBeInstanceOf(Function);
|
|
402
478
|
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
479
|
+
const feature = new A_Feature({
|
|
480
|
+
name: 'testFeature',
|
|
481
|
+
scope,
|
|
482
|
+
template: [
|
|
483
|
+
{
|
|
484
|
+
name: 'ComponentA.feature1',
|
|
485
|
+
component: 'ComponentA',
|
|
486
|
+
handler: 'feature1',
|
|
487
|
+
},
|
|
488
|
+
{
|
|
489
|
+
name: 'ComponentA.feature2',
|
|
490
|
+
component: 'ComponentA',
|
|
491
|
+
handler: 'feature2',
|
|
492
|
+
},
|
|
493
|
+
{
|
|
494
|
+
name: 'ComponentA.feature3',
|
|
495
|
+
component: 'ComponentA',
|
|
496
|
+
handler: 'feature3',
|
|
497
|
+
},
|
|
498
|
+
]
|
|
499
|
+
});
|
|
406
500
|
|
|
501
|
+
feature.process();
|
|
502
|
+
|
|
503
|
+
await new Promise<void>(async (resolve) => {
|
|
407
504
|
|
|
408
|
-
|
|
409
|
-
|
|
505
|
+
setTimeout(() => {
|
|
506
|
+
feature.interrupt();
|
|
410
507
|
|
|
508
|
+
expect(feature.state).toBe(A_TYPES__FeatureState.INTERRUPTED);
|
|
509
|
+
expect(executionOrder).toEqual(['feature1']);
|
|
411
510
|
|
|
412
|
-
|
|
413
|
-
const myComponent = scope.resolve(ComponentA)!;
|
|
414
|
-
expect(myComponent).toBeInstanceOf(ComponentA);
|
|
511
|
+
resolve();
|
|
415
512
|
|
|
416
|
-
|
|
513
|
+
}, 2500);
|
|
514
|
+
});
|
|
417
515
|
|
|
418
|
-
expect(executionOrder).toEqual(['stepOne', 'stepThree']);
|
|
419
516
|
});
|
|
420
|
-
|
|
421
|
-
|
|
422
517
|
});
|