@adaas/a-concept 0.1.38 → 0.1.41

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.
@@ -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
- const testComponent = new A_Component()
14
- A_Context.root.register(testComponent);
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
- const feature = new A_Feature({
17
- name: 'testFeature',
18
- component: testComponent,
19
- });
259
+ // @A_Feature.Extend({
260
+ // name: 'feature2',
261
+ // })
262
+ // async feature2Extension() {
263
+ // executionOrder.push('stepTwo');
264
+ // }
20
265
 
21
- expect(feature).toBeInstanceOf(A_Feature);
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
- const feature = new A_Feature({
35
- name: 'testFeature',
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
- async testHandler(
99
- @A_Inject(A_Caller) caller: MyComponent2
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
- // 2) create a custom component with a defined template feature
106
- class MyComponent2 extends A_Component {
107
- sum: number = 0;
276
+ // // 4) call the feature caller to execute the feature
277
+ // await myComponent.feature1(new A_Component());
108
278
 
109
- @A_Feature.Define({
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
- // 3) create a running scope
125
- const scope = new A_Scope({ name: 'TestScope' });
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
- // 4) create an instance of the component from the scope
130
- const myComponent = scope.resolve(MyComponent2)!;
131
- expect(myComponent).toBeInstanceOf(MyComponent2);
132
- expect(myComponent.sum).toBe(0);
290
+ // @A_Feature.Define({ invoke: false })
291
+ // async feature1() {
292
+ // executionOrder.push('stepOne');
133
293
 
134
- // 5) call the feature caller to execute the feature
135
- await myComponent.testHandler();
294
+ // await this.call('feature1');
295
+ // }
136
296
 
137
- // 6) check the results
138
- expect(myComponent.sum).toBe(2);
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
- // 1) create a base component with some feature
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
- @A_Feature.Extend({
159
- name: 'myFeature',
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
- @A_Feature.Extend({
167
- name: 'myFeature',
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
- // 2) create a running scope
177
- const scope = new A_Scope({ name: 'TestScope', components: [My_Component] });
320
+ // expect(executionOrder).toEqual(['stepOne', 'stepTwo']);
321
+ // });
178
322
 
179
- // 3) create an instance of the component from the scope
180
- const myComponent = scope.resolve(My_Component)!;
181
- expect(myComponent).toBeInstanceOf(My_Component);
323
+ // it('Should allow override feature extension', async () => {
324
+ // const executionOrder: string[] = [];
182
325
 
183
- // 4) call the feature caller to execute the feature
184
- await myComponent.methodA();
326
+ // // 1) create a base component with some feature
327
+ // class My_Component extends A_Component {
185
328
 
186
- // 5) check the results
187
- expect(executionOrder).toEqual(['stepOne', 'stepTwo', 'stepThree']);
188
- });
189
- it('Should execute feature steps in proper order', async () => {
190
- const executionOrder: string[] = [];
329
+ // @A_Feature.Define({ invoke: true })
330
+ // async feature1() {
331
+ // executionOrder.push('stepOne');
332
+ // }
191
333
 
192
- // 1) create a base component with some feature
193
- class My_Component extends A_Component {
194
- async methodA() {
195
- await this.call('myFeature')
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
- @A_Feature.Extend({
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
- // 3) create an instance of the component from the scope
221
- const myComponent = scope.resolve(My_Component)!;
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
- // 4) call the feature caller to execute the feature
225
- await myComponent.methodA();
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
- // 5) check the results
228
- expect(executionOrder).toEqual(['stepTwo', 'stepOne']);
229
- });
362
+ // await myComponent.feature1();
230
363
 
231
- it('Should allow to define a feature', async () => {
232
- const executionOrder: string[] = [];
364
+ // expect(executionOrder).toEqual(['stepOne', 'stepThree']);
365
+ // });
233
366
 
234
- // 1) create a base component with some feature
235
- class My_Component extends A_Component {
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
- @A_Feature.Define()
254
- async feature2() {
255
- await this.call('feature2');
256
- }
370
+ // class CustomComponent extends A_Component {
257
371
 
258
- @A_Feature.Extend({
259
- name: 'feature2',
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
- // 2) create a running scope
269
- const scope = new A_Scope({ name: 'TestScope', components: [My_Component] });
381
+ // @A_Feature.Define({ invoke: false })
382
+ // async feature1() {
383
+ // const scope = new A_Scope({ name: 'ExternalScopeCaller', components: [CustomComponent] });
270
384
 
271
- // 3) create an instance of the component from the scope
272
- const myComponent = scope.resolve(My_Component)!;
273
- expect(myComponent).toBeInstanceOf(My_Component);
385
+ // executionOrder.push('stepOne');
274
386
 
275
- // 4) call the feature caller to execute the feature
276
- await myComponent.feature1(new A_Component());
387
+ // await this.call('feature1', scope);
388
+ // }
389
+ // }
277
390
 
278
- await myComponent.feature2();
279
391
 
280
- // 5) check the results
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
- // 1) create a base component with some feature
287
- class My_Component extends A_Component {
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
- @A_Feature.Define({ invoke: false })
290
- async feature1() {
291
- executionOrder.push('stepOne');
404
+ // executionOrder.push('stepThree');
405
+ // }
406
+ // }
292
407
 
293
- await this.call('feature1');
294
- }
295
408
 
296
- @A_Feature.Extend({
297
- name: 'feature1',
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
- class My_Child_Component extends My_Component { }
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
- // 2) create a running scope
311
- const scope = new A_Scope({ name: 'TestScope', components: [My_Child_Component] });
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
- await myComponent.feature1();
435
+ feature.interrupt();
318
436
 
319
- expect(executionOrder).toEqual(['stepOne', 'stepTwo']);
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 My_Component extends A_Component {
444
+ class ComponentA extends A_Component {
327
445
 
328
- @A_Feature.Define({ invoke: true })
329
446
  async feature1() {
330
- executionOrder.push('stepOne');
447
+ await new Promise<void>(async (resolve) => {
448
+ setTimeout(() => {
449
+ executionOrder.push('feature1');
450
+ resolve();
451
+ }, 2000);
452
+ });
331
453
  }
332
454
 
333
- @A_Feature.Extend({
334
- name: 'feature1',
335
- })
336
- async feature1Extension(
337
- @A_Inject(A_Scope) scope: A_Scope
338
- ) {
339
- executionOrder.push('stepTwo');
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 feature1Extension(
347
- @A_Inject(A_Scope) scope: A_Scope
348
- ) {
349
- executionOrder.push('stepThree');
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: [My_Child_Component] });
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
- executionOrder.push('stepThree');
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
- // 2) create a running scope
409
- const scope = new A_Scope({ name: 'TestScope' , components: [ComponentA, ComponentB] });
505
+ setTimeout(() => {
506
+ feature.interrupt();
410
507
 
508
+ expect(feature.state).toBe(A_TYPES__FeatureState.INTERRUPTED);
509
+ expect(executionOrder).toEqual(['feature1']);
411
510
 
412
- // 3) create an instance of the component from the scope
413
- const myComponent = scope.resolve(ComponentA)!;
414
- expect(myComponent).toBeInstanceOf(ComponentA);
511
+ resolve();
415
512
 
416
- await myComponent.feature1();
513
+ }, 2500);
514
+ });
417
515
 
418
- expect(executionOrder).toEqual(['stepOne', 'stepThree']);
419
516
  });
420
-
421
-
422
517
  });