@adaas/a-concept 0.1.41 → 0.1.43
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 +8 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/global/A-Error/A_Error.class.ts +28 -6
- package/src/global/A-Feature/A-Feature.class.ts +2 -1
- package/src/helpers/A_TypeGuards.helper.ts +9 -2
- package/tests/A-Feature.test.ts +369 -367
package/tests/A-Feature.test.ts
CHANGED
|
@@ -10,414 +10,414 @@ import { A_TYPES__FeatureState } from "../src";
|
|
|
10
10
|
jest.retryTimes(0);
|
|
11
11
|
|
|
12
12
|
describe('A-Feature tests', () => {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
-
// }
|
|
13
|
+
it('Should Allow to create a feature from component', async () => {
|
|
14
|
+
const testComponent = new A_Component()
|
|
15
|
+
A_Context.root.register(testComponent);
|
|
258
16
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
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
|
+
});
|
|
265
231
|
|
|
266
|
-
|
|
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
|
+
}
|
|
258
|
+
|
|
259
|
+
@A_Feature.Extend({
|
|
260
|
+
name: 'feature2',
|
|
261
|
+
})
|
|
262
|
+
async feature2Extension() {
|
|
263
|
+
executionOrder.push('stepTwo');
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
}
|
|
267
267
|
|
|
268
268
|
|
|
269
|
-
|
|
270
|
-
|
|
269
|
+
// 2) create a running scope
|
|
270
|
+
const scope = new A_Scope({ name: 'TestScope', components: [My_Component] });
|
|
271
271
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
272
|
+
// 3) create an instance of the component from the scope
|
|
273
|
+
const myComponent = scope.resolve(My_Component)!;
|
|
274
|
+
expect(myComponent).toBeInstanceOf(My_Component);
|
|
275
275
|
|
|
276
|
-
|
|
277
|
-
|
|
276
|
+
// 4) call the feature caller to execute the feature
|
|
277
|
+
await myComponent.feature1(new A_Component());
|
|
278
278
|
|
|
279
|
-
|
|
279
|
+
await myComponent.feature2();
|
|
280
280
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
281
|
+
// 5) check the results
|
|
282
|
+
expect(executionOrder).toEqual(['stepOne', 'stepTwo']);
|
|
283
|
+
});
|
|
284
|
+
it('Should inherit feature definitions & extensions', async () => {
|
|
285
|
+
const executionOrder: string[] = [];
|
|
286
286
|
|
|
287
|
-
|
|
288
|
-
|
|
287
|
+
// 1) create a base component with some feature
|
|
288
|
+
class My_Component extends A_Component {
|
|
289
289
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
290
|
+
@A_Feature.Define({ invoke: false })
|
|
291
|
+
async feature1() {
|
|
292
|
+
executionOrder.push('stepOne');
|
|
293
293
|
|
|
294
|
-
|
|
295
|
-
|
|
294
|
+
await this.call('feature1');
|
|
295
|
+
}
|
|
296
296
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
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
|
+
}
|
|
306
306
|
|
|
307
307
|
|
|
308
|
-
|
|
308
|
+
class My_Child_Component extends My_Component { }
|
|
309
309
|
|
|
310
310
|
|
|
311
|
-
|
|
312
|
-
|
|
311
|
+
// 2) create a running scope
|
|
312
|
+
const scope = new A_Scope({ name: 'TestScope', components: [My_Child_Component] });
|
|
313
313
|
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
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);
|
|
317
317
|
|
|
318
|
-
|
|
318
|
+
await myComponent.feature1();
|
|
319
319
|
|
|
320
|
-
|
|
321
|
-
|
|
320
|
+
expect(executionOrder).toEqual(['stepOne', 'stepTwo']);
|
|
321
|
+
});
|
|
322
322
|
|
|
323
|
-
|
|
324
|
-
|
|
323
|
+
it('Should allow override feature extension', async () => {
|
|
324
|
+
const executionOrder: string[] = [];
|
|
325
325
|
|
|
326
|
-
|
|
327
|
-
|
|
326
|
+
// 1) create a base component with some feature
|
|
327
|
+
class My_Component extends A_Component {
|
|
328
328
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
329
|
+
@A_Feature.Define({ invoke: true })
|
|
330
|
+
async feature1() {
|
|
331
|
+
executionOrder.push('stepOne');
|
|
332
|
+
}
|
|
333
333
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
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
|
+
}
|
|
343
343
|
|
|
344
344
|
|
|
345
|
-
|
|
345
|
+
class My_Child_Component extends My_Component {
|
|
346
346
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
347
|
+
async feature1Extension(
|
|
348
|
+
@A_Inject(A_Scope) scope: A_Scope
|
|
349
|
+
) {
|
|
350
|
+
executionOrder.push('stepThree');
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
353
|
|
|
354
354
|
|
|
355
|
-
|
|
356
|
-
|
|
355
|
+
// 2) create a running scope
|
|
356
|
+
const scope = new A_Scope({ name: 'TestScope', components: [My_Child_Component] });
|
|
357
357
|
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
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);
|
|
361
361
|
|
|
362
|
-
|
|
362
|
+
await myComponent.feature1();
|
|
363
363
|
|
|
364
|
-
|
|
365
|
-
|
|
364
|
+
expect(executionOrder).toEqual(['stepOne', 'stepThree']);
|
|
365
|
+
});
|
|
366
366
|
|
|
367
|
-
|
|
368
|
-
|
|
367
|
+
it('Should allow proceed with external scope', async () => {
|
|
368
|
+
const executionOrder: string[] = [];
|
|
369
369
|
|
|
370
|
-
|
|
370
|
+
class CustomComponent extends A_Component {
|
|
371
371
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
372
|
+
doSomething() {
|
|
373
|
+
executionOrder.push('customComponentAction');
|
|
374
|
+
}
|
|
375
375
|
|
|
376
|
-
|
|
376
|
+
}
|
|
377
377
|
|
|
378
|
-
|
|
379
|
-
|
|
378
|
+
// 1) create a base component with some feature
|
|
379
|
+
class ComponentA extends A_Component {
|
|
380
380
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
381
|
+
@A_Feature.Define({ invoke: false })
|
|
382
|
+
async feature1() {
|
|
383
|
+
const scope = new A_Scope({ name: 'ExternalScopeCaller', components: [CustomComponent] });
|
|
384
384
|
|
|
385
|
-
|
|
385
|
+
executionOrder.push('stepOne');
|
|
386
386
|
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
387
|
+
await this.call('feature1', scope);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
390
|
|
|
391
391
|
|
|
392
|
-
|
|
392
|
+
class ComponentB extends A_Component {
|
|
393
393
|
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
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);
|
|
403
403
|
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
404
|
+
executionOrder.push('stepThree');
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
407
|
|
|
408
408
|
|
|
409
|
-
|
|
410
|
-
|
|
409
|
+
// 2) create a running scope
|
|
410
|
+
const scope = new A_Scope({ name: 'TestScope' , components: [ComponentA, ComponentB] });
|
|
411
411
|
|
|
412
412
|
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
413
|
+
// 3) create an instance of the component from the scope
|
|
414
|
+
const myComponent = scope.resolve(ComponentA)!;
|
|
415
|
+
expect(myComponent).toBeInstanceOf(ComponentA);
|
|
416
416
|
|
|
417
|
-
|
|
417
|
+
await myComponent.feature1();
|
|
418
418
|
|
|
419
|
-
|
|
420
|
-
|
|
419
|
+
expect(executionOrder).toEqual(['stepOne', 'stepThree']);
|
|
420
|
+
});
|
|
421
421
|
it('Should allow to interrupt a new feature', async () => {
|
|
422
422
|
const feature = new A_Feature({
|
|
423
423
|
name: 'testFeature',
|
|
@@ -448,7 +448,7 @@ describe('A-Feature tests', () => {
|
|
|
448
448
|
setTimeout(() => {
|
|
449
449
|
executionOrder.push('feature1');
|
|
450
450
|
resolve();
|
|
451
|
-
},
|
|
451
|
+
}, 500);
|
|
452
452
|
});
|
|
453
453
|
}
|
|
454
454
|
|
|
@@ -457,7 +457,7 @@ describe('A-Feature tests', () => {
|
|
|
457
457
|
setTimeout(() => {
|
|
458
458
|
executionOrder.push('feature2');
|
|
459
459
|
resolve();
|
|
460
|
-
},
|
|
460
|
+
}, 500);
|
|
461
461
|
});
|
|
462
462
|
}
|
|
463
463
|
|
|
@@ -466,7 +466,7 @@ describe('A-Feature tests', () => {
|
|
|
466
466
|
setTimeout(() => {
|
|
467
467
|
executionOrder.push('feature3');
|
|
468
468
|
resolve();
|
|
469
|
-
},
|
|
469
|
+
}, 500);
|
|
470
470
|
});
|
|
471
471
|
}
|
|
472
472
|
}
|
|
@@ -499,19 +499,21 @@ describe('A-Feature tests', () => {
|
|
|
499
499
|
});
|
|
500
500
|
|
|
501
501
|
feature.process();
|
|
502
|
-
|
|
503
|
-
await new Promise<void>(async (resolve) => {
|
|
504
502
|
|
|
503
|
+
await new Promise<void>(async (resolve) => {
|
|
505
504
|
setTimeout(() => {
|
|
506
505
|
feature.interrupt();
|
|
506
|
+
}, 1000);
|
|
507
|
+
|
|
507
508
|
|
|
509
|
+
setTimeout(() => {
|
|
508
510
|
expect(feature.state).toBe(A_TYPES__FeatureState.INTERRUPTED);
|
|
509
|
-
expect(executionOrder).toEqual(['feature1']);
|
|
511
|
+
expect(executionOrder).toEqual(['feature1', 'feature2']);
|
|
510
512
|
|
|
511
513
|
resolve();
|
|
512
514
|
|
|
513
|
-
},
|
|
515
|
+
}, 3000);
|
|
514
516
|
});
|
|
515
517
|
|
|
516
|
-
});
|
|
518
|
+
}, 5000);
|
|
517
519
|
});
|