decorator-dependency-injection 1.0.3 → 1.0.4
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/README.md +68 -16
- package/eslint.config.js +73 -0
- package/index.d.ts +146 -0
- package/index.js +56 -126
- package/package.json +46 -7
- package/src/Container.js +184 -0
- package/src/proxy.js +42 -0
- package/.github/workflows/release.yml +0 -129
- package/babel.config.json +0 -6
- package/test/injection.test.js +0 -309
- package/test/injectionLazy.test.js +0 -249
- package/test/mock.test.js +0 -295
- package/test/proxy.test.js +0 -130
package/test/injection.test.js
DELETED
|
@@ -1,309 +0,0 @@
|
|
|
1
|
-
import {Factory, Inject, resetMocks, Singleton} from '../index.js'
|
|
2
|
-
|
|
3
|
-
describe('Injection via fields', () => {
|
|
4
|
-
@Singleton()
|
|
5
|
-
class TestSingleton {
|
|
6
|
-
static calls = 0
|
|
7
|
-
|
|
8
|
-
constructor() {
|
|
9
|
-
TestSingleton.calls++
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
it('should inject singleton', () => {
|
|
14
|
-
class TestInjection {
|
|
15
|
-
@Inject(TestSingleton) testSingleton
|
|
16
|
-
|
|
17
|
-
constructor() {
|
|
18
|
-
expect(this.testSingleton).toBeInstanceOf(TestSingleton)
|
|
19
|
-
expect(TestSingleton.calls).toBe(1)
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
class TestInjection2 {
|
|
24
|
-
@Inject(TestSingleton) testSingleton
|
|
25
|
-
|
|
26
|
-
constructor() {
|
|
27
|
-
expect(this.testSingleton).toBeInstanceOf(TestSingleton)
|
|
28
|
-
expect(TestSingleton.calls).toBe(1)
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
new TestInjection()
|
|
33
|
-
new TestInjection2()
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
@Factory()
|
|
37
|
-
class TestFactory {
|
|
38
|
-
static calls = 0
|
|
39
|
-
params
|
|
40
|
-
|
|
41
|
-
@Inject(TestSingleton) testSingleton
|
|
42
|
-
|
|
43
|
-
constructor(...params) {
|
|
44
|
-
TestFactory.calls++
|
|
45
|
-
this.params = params
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
afterEach(() => {
|
|
50
|
-
TestFactory.calls = 0
|
|
51
|
-
TestSingleton.calls = 0
|
|
52
|
-
resetMocks()
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
it('should inject factory', () => {
|
|
56
|
-
class TestInjectionFactory {
|
|
57
|
-
@Inject(TestFactory) testFactory
|
|
58
|
-
|
|
59
|
-
constructor() {
|
|
60
|
-
expect(this.testFactory).toBeInstanceOf(TestFactory)
|
|
61
|
-
expect(TestFactory.calls).toBe(1)
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
class TestInjectionFactory2 {
|
|
66
|
-
@Inject(TestFactory) testFactory
|
|
67
|
-
|
|
68
|
-
constructor() {
|
|
69
|
-
expect(this.testFactory).toBeInstanceOf(TestFactory)
|
|
70
|
-
expect(TestFactory.calls).toBe(2)
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
const result = new TestInjectionFactory()
|
|
75
|
-
new TestInjectionFactory2()
|
|
76
|
-
expect(result.testFactory.testSingleton).toBeInstanceOf(TestSingleton)
|
|
77
|
-
})
|
|
78
|
-
|
|
79
|
-
it('should inject factory with parameters', () => {
|
|
80
|
-
class TestInjectionFactoryParams {
|
|
81
|
-
@Inject(TestFactory, 'param1', 'param2') testFactory
|
|
82
|
-
|
|
83
|
-
constructor() {
|
|
84
|
-
expect(this.testFactory).toBeInstanceOf(TestFactory)
|
|
85
|
-
expect(this.testFactory.params).toEqual(['param1', 'param2'])
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
new TestInjectionFactoryParams()
|
|
90
|
-
})
|
|
91
|
-
|
|
92
|
-
it('should cache factory instance on repeated accesses', () => {
|
|
93
|
-
class TestRepeatedFactoryAccess {
|
|
94
|
-
@Inject(TestFactory) testFactory
|
|
95
|
-
|
|
96
|
-
constructor() {
|
|
97
|
-
const instance1 = this.testFactory
|
|
98
|
-
const instance2 = this.testFactory
|
|
99
|
-
expect(instance1).toBe(instance2)
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
new TestRepeatedFactoryAccess()
|
|
104
|
-
})
|
|
105
|
-
|
|
106
|
-
it('should create distinct factory instances for different fields in the same object', () => {
|
|
107
|
-
class TestMultipleFactoryInjection {
|
|
108
|
-
@Inject(TestFactory) testFactory1
|
|
109
|
-
@Inject(TestFactory) testFactory2
|
|
110
|
-
|
|
111
|
-
constructor() {
|
|
112
|
-
// Access both properties to trigger initialization.
|
|
113
|
-
const one = this.testFactory1
|
|
114
|
-
const two = this.testFactory2
|
|
115
|
-
expect(one).not.toBe(two)
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
new TestMultipleFactoryInjection()
|
|
120
|
-
})
|
|
121
|
-
|
|
122
|
-
it('should inject the same singleton instance for different fields in the same object', () => {
|
|
123
|
-
class TestMultipleSingletonInjection {
|
|
124
|
-
@Inject(TestSingleton) testSingleton1
|
|
125
|
-
@Inject(TestSingleton) testSingleton2
|
|
126
|
-
|
|
127
|
-
constructor() {
|
|
128
|
-
// Access both properties to trigger initialization.
|
|
129
|
-
const one = this.testSingleton1
|
|
130
|
-
const two = this.testSingleton2
|
|
131
|
-
expect(one).toBe(two)
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
new TestMultipleSingletonInjection()
|
|
136
|
-
})
|
|
137
|
-
|
|
138
|
-
@Singleton('named')
|
|
139
|
-
class NamedSingleton {
|
|
140
|
-
static calls = 0
|
|
141
|
-
|
|
142
|
-
constructor() {
|
|
143
|
-
NamedSingleton.calls++
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
it('should inject named singleton', () => {
|
|
148
|
-
class TestInjectionNamedSingleton {
|
|
149
|
-
@Inject('named') namedSingleton
|
|
150
|
-
|
|
151
|
-
constructor() {
|
|
152
|
-
expect(this.namedSingleton).toBeInstanceOf(NamedSingleton)
|
|
153
|
-
expect(NamedSingleton.calls).toBe(1)
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
class TestInjectionNamedSingleton2 {
|
|
158
|
-
@Inject('named') namedSingleton
|
|
159
|
-
|
|
160
|
-
constructor() {
|
|
161
|
-
expect(this.namedSingleton).toBeInstanceOf(NamedSingleton)
|
|
162
|
-
expect(NamedSingleton.calls).toBe(1)
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
new TestInjectionNamedSingleton()
|
|
167
|
-
new TestInjectionNamedSingleton2()
|
|
168
|
-
})
|
|
169
|
-
|
|
170
|
-
@Factory('named2')
|
|
171
|
-
class NamedFactory {
|
|
172
|
-
static calls = 0
|
|
173
|
-
params
|
|
174
|
-
|
|
175
|
-
constructor(...params) {
|
|
176
|
-
NamedFactory.calls++
|
|
177
|
-
this.params = params
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
it('should inject named factory', () => {
|
|
182
|
-
class TestInjectionNamedFactory {
|
|
183
|
-
@Inject('named2') namedFactory
|
|
184
|
-
|
|
185
|
-
constructor() {
|
|
186
|
-
expect(this.namedFactory).toBeInstanceOf(NamedFactory)
|
|
187
|
-
expect(NamedFactory.calls).toBe(1)
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
class TestInjectionNamedFactory2 {
|
|
192
|
-
@Inject('named2') namedFactory
|
|
193
|
-
|
|
194
|
-
constructor() {
|
|
195
|
-
expect(this.namedFactory).toBeInstanceOf(NamedFactory)
|
|
196
|
-
expect(NamedFactory.calls).toBe(2)
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
const result = new TestInjectionNamedFactory()
|
|
201
|
-
new TestInjectionNamedFactory2()
|
|
202
|
-
expect(result.namedFactory.params).toEqual([])
|
|
203
|
-
})
|
|
204
|
-
|
|
205
|
-
it('should cache named factory instance on repeated accesses', () => {
|
|
206
|
-
class TestRepeatedNamedFactoryAccess {
|
|
207
|
-
@Inject('named2') namedFactory
|
|
208
|
-
|
|
209
|
-
constructor() {
|
|
210
|
-
const instance1 = this.namedFactory
|
|
211
|
-
const instance2 = this.namedFactory
|
|
212
|
-
expect(instance1).toBe(instance2)
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
new TestRepeatedNamedFactoryAccess()
|
|
217
|
-
})
|
|
218
|
-
|
|
219
|
-
it('should throw if @Inject is applied to a method', () => {
|
|
220
|
-
expect(() => {
|
|
221
|
-
// noinspection JSUnusedLocalSymbols
|
|
222
|
-
class BadInjection {
|
|
223
|
-
@Inject('something')
|
|
224
|
-
someMethod() {
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
}).toThrow()
|
|
228
|
-
})
|
|
229
|
-
|
|
230
|
-
it('should handle circular dependencies gracefully', () => {
|
|
231
|
-
@Singleton()
|
|
232
|
-
class A {
|
|
233
|
-
@Inject('B') b
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
@Singleton('B')
|
|
237
|
-
class B {
|
|
238
|
-
@Inject(A) a
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
expect(() => new A()).toThrow(/Circular dependency detected.*@InjectLazy/)
|
|
242
|
-
})
|
|
243
|
-
|
|
244
|
-
it('should throw if decorator is used on non-class object', () => {
|
|
245
|
-
expect(() => {
|
|
246
|
-
const obj = {}
|
|
247
|
-
Inject('something')(obj, 'field')
|
|
248
|
-
}).toThrow()
|
|
249
|
-
})
|
|
250
|
-
|
|
251
|
-
it('should throw a helpful error for eager circular dependencies', () => {
|
|
252
|
-
@Factory()
|
|
253
|
-
class A2 {
|
|
254
|
-
@Inject('B2') b
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
@Singleton('B2')
|
|
258
|
-
class B2 {
|
|
259
|
-
@Inject(A2) a
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
expect(() => new A2()).toThrow(/Circular dependency detected.*@InjectLazy/)
|
|
263
|
-
})
|
|
264
|
-
|
|
265
|
-
it('should inject into symbol-named fields', () => {
|
|
266
|
-
const sym = Symbol('sym')
|
|
267
|
-
|
|
268
|
-
@Singleton()
|
|
269
|
-
class S {
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
class Test {
|
|
273
|
-
@Inject(S) [sym]
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
const t = new Test()
|
|
277
|
-
expect(t[sym]).toBeInstanceOf(S)
|
|
278
|
-
})
|
|
279
|
-
|
|
280
|
-
it('should not leak injected properties to prototype', () => {
|
|
281
|
-
@Singleton()
|
|
282
|
-
class S {
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
class Test {
|
|
286
|
-
@Inject(S) dep
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
// noinspection JSUnusedLocalSymbols
|
|
290
|
-
const t = new Test()
|
|
291
|
-
expect(Object.prototype.hasOwnProperty.call(Test.prototype, 'dep')).toBe(false)
|
|
292
|
-
})
|
|
293
|
-
|
|
294
|
-
it('should handle undefined/null/complex params in factory', () => {
|
|
295
|
-
@Factory()
|
|
296
|
-
class F {
|
|
297
|
-
constructor(...params) {
|
|
298
|
-
this.params = params
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
class Test {
|
|
303
|
-
@Inject(F, undefined, null, {a: 1}) dep
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
const t = new Test()
|
|
307
|
-
expect(t.dep.params).toEqual([undefined, null, {a: 1}])
|
|
308
|
-
})
|
|
309
|
-
})
|
|
@@ -1,249 +0,0 @@
|
|
|
1
|
-
import {Factory, InjectLazy, resetMocks, Singleton} from '../index.js'
|
|
2
|
-
|
|
3
|
-
describe('Lazy Injection via fields', () => {
|
|
4
|
-
@Singleton()
|
|
5
|
-
class TestLazySingleton {
|
|
6
|
-
static calls = 0
|
|
7
|
-
|
|
8
|
-
constructor() {
|
|
9
|
-
TestLazySingleton.calls++
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
it('should lazily inject singleton', () => {
|
|
14
|
-
class TestLazySingletonInjection {
|
|
15
|
-
@InjectLazy(TestLazySingleton) testSingleton
|
|
16
|
-
|
|
17
|
-
constructor() {
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const instance = new TestLazySingletonInjection()
|
|
22
|
-
expect(TestLazySingleton.calls).toBe(0) // Not constructed until access
|
|
23
|
-
const first = instance.testSingleton
|
|
24
|
-
expect(first).toBeInstanceOf(TestLazySingleton)
|
|
25
|
-
expect(TestLazySingleton.calls).toBe(1)
|
|
26
|
-
// Repeated access returns the same instance.
|
|
27
|
-
const second = instance.testSingleton
|
|
28
|
-
expect(first).toBe(second)
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
@Factory()
|
|
32
|
-
class TestLazyFactory {
|
|
33
|
-
static calls = 0
|
|
34
|
-
params
|
|
35
|
-
|
|
36
|
-
constructor(...params) {
|
|
37
|
-
TestLazyFactory.calls++
|
|
38
|
-
this.params = params
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
afterEach(() => {
|
|
43
|
-
TestLazyFactory.calls = 0
|
|
44
|
-
TestLazySingleton.calls = 0
|
|
45
|
-
resetMocks()
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
it('should lazily inject factory with caching on first access per field', () => {
|
|
49
|
-
class TestLazyFactoryInjection {
|
|
50
|
-
@InjectLazy(TestLazyFactory) testFactory
|
|
51
|
-
|
|
52
|
-
constructor() {
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const inst = new TestLazyFactoryInjection()
|
|
57
|
-
expect(TestLazyFactory.calls).toBe(0)
|
|
58
|
-
const first = inst.testFactory
|
|
59
|
-
expect(first).toBeInstanceOf(TestLazyFactory)
|
|
60
|
-
expect(TestLazyFactory.calls).toBe(1)
|
|
61
|
-
expect(inst.testFactory).toBe(first)
|
|
62
|
-
})
|
|
63
|
-
|
|
64
|
-
it('should create distinct factory instances for different fields', () => {
|
|
65
|
-
class TestMultipleLazyFactoryInjection {
|
|
66
|
-
@InjectLazy(TestLazyFactory) testFactory1
|
|
67
|
-
@InjectLazy(TestLazyFactory) testFactory2
|
|
68
|
-
|
|
69
|
-
constructor() {
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const instance = new TestMultipleLazyFactoryInjection()
|
|
74
|
-
expect(TestLazyFactory.calls).toBe(0)
|
|
75
|
-
const one = instance.testFactory1
|
|
76
|
-
const two = instance.testFactory2
|
|
77
|
-
expect(one).toBeInstanceOf(TestLazyFactory)
|
|
78
|
-
expect(two).toBeInstanceOf(TestLazyFactory)
|
|
79
|
-
expect(one).not.toBe(two)
|
|
80
|
-
})
|
|
81
|
-
|
|
82
|
-
it('should pass constructor parameters when using lazy injection', () => {
|
|
83
|
-
class TestLazyFactoryParamsInjection {
|
|
84
|
-
@InjectLazy(TestLazyFactory, 'param1', 'param2') testFactory
|
|
85
|
-
|
|
86
|
-
constructor() {
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
TestLazyFactory.calls = 0
|
|
91
|
-
const instance = new TestLazyFactoryParamsInjection()
|
|
92
|
-
expect(TestLazyFactory.calls).toBe(0)
|
|
93
|
-
const factoryInst = instance.testFactory
|
|
94
|
-
expect(factoryInst).toBeInstanceOf(TestLazyFactory)
|
|
95
|
-
expect(factoryInst.params).toEqual(['param1', 'param2'])
|
|
96
|
-
})
|
|
97
|
-
|
|
98
|
-
it('should not initialize dependency if property is never accessed', () => {
|
|
99
|
-
class TestNeverAccess {
|
|
100
|
-
@InjectLazy(TestLazySingleton) testSingleton
|
|
101
|
-
|
|
102
|
-
constructor() {
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
TestLazySingleton.calls = 0
|
|
107
|
-
new TestNeverAccess() // Do not access testSingleton.
|
|
108
|
-
expect(TestLazySingleton.calls).toBe(0)
|
|
109
|
-
})
|
|
110
|
-
|
|
111
|
-
@Singleton('lazyNamedSingleton')
|
|
112
|
-
class NamedLazySingleton {
|
|
113
|
-
static calls = 0
|
|
114
|
-
|
|
115
|
-
constructor() {
|
|
116
|
-
NamedLazySingleton.calls++
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
it('should lazily inject named singleton', () => {
|
|
121
|
-
class TestLazyNamedSingletonInjection {
|
|
122
|
-
@InjectLazy('lazyNamedSingleton') namedSingleton
|
|
123
|
-
|
|
124
|
-
constructor() {
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
const instance = new TestLazyNamedSingletonInjection()
|
|
129
|
-
expect(NamedLazySingleton.calls).toBe(0)
|
|
130
|
-
const first = instance.namedSingleton
|
|
131
|
-
expect(first).toBeInstanceOf(NamedLazySingleton)
|
|
132
|
-
expect(NamedLazySingleton.calls).toBe(1)
|
|
133
|
-
expect(instance.namedSingleton).toBe(first)
|
|
134
|
-
})
|
|
135
|
-
|
|
136
|
-
@Factory('lazyNamedFactory')
|
|
137
|
-
class NamedLazyFactory {
|
|
138
|
-
static calls = 0
|
|
139
|
-
params
|
|
140
|
-
|
|
141
|
-
constructor(...params) {
|
|
142
|
-
NamedLazyFactory.calls++
|
|
143
|
-
this.params = params
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
it('should lazily inject named factory', () => {
|
|
148
|
-
class TestLazyNamedFactoryInjection {
|
|
149
|
-
@InjectLazy('lazyNamedFactory') namedFactory
|
|
150
|
-
|
|
151
|
-
constructor() {
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
NamedLazyFactory.calls = 0
|
|
156
|
-
const instance = new TestLazyNamedFactoryInjection()
|
|
157
|
-
expect(NamedLazyFactory.calls).toBe(0)
|
|
158
|
-
const first = instance.namedFactory
|
|
159
|
-
expect(first).toBeInstanceOf(NamedLazyFactory)
|
|
160
|
-
expect(NamedLazyFactory.calls).toBe(1)
|
|
161
|
-
expect(instance.namedFactory).toBe(first)
|
|
162
|
-
})
|
|
163
|
-
|
|
164
|
-
it('should not expose any internal caching artifacts', () => {
|
|
165
|
-
class TestLazyEnum {
|
|
166
|
-
@InjectLazy(TestLazySingleton) lazyProp
|
|
167
|
-
|
|
168
|
-
constructor() {
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
const inst = new TestLazyEnum()
|
|
173
|
-
// noinspection JSUnusedLocalSymbols: Force lazy initialization.
|
|
174
|
-
const _ = inst.lazyProp
|
|
175
|
-
const keys = Object.keys(inst)
|
|
176
|
-
expect(keys).toContain('lazyProp')
|
|
177
|
-
expect(keys.length).toBe(1)
|
|
178
|
-
const symbols = Object.getOwnPropertySymbols(inst)
|
|
179
|
-
expect(symbols.length).toBe(0)
|
|
180
|
-
})
|
|
181
|
-
|
|
182
|
-
it('should throw if @InjectLazy is applied to a method', () => {
|
|
183
|
-
expect(() => {
|
|
184
|
-
// noinspection JSUnusedLocalSymbols
|
|
185
|
-
class BadLazy {
|
|
186
|
-
@InjectLazy('something')
|
|
187
|
-
someMethod() {
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
}).toThrow()
|
|
191
|
-
})
|
|
192
|
-
|
|
193
|
-
it('should handle circular dependencies (lazy)', () => {
|
|
194
|
-
@Singleton()
|
|
195
|
-
class A {
|
|
196
|
-
@InjectLazy('B') b
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
@Singleton('B')
|
|
200
|
-
class B {
|
|
201
|
-
@InjectLazy(A) a
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
expect(() => new A()).not.toThrow()
|
|
205
|
-
})
|
|
206
|
-
|
|
207
|
-
it('should inject into symbol-named fields (lazy)', () => {
|
|
208
|
-
const sym = Symbol('sym')
|
|
209
|
-
|
|
210
|
-
@Singleton()
|
|
211
|
-
class S {
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
class Test {
|
|
215
|
-
@InjectLazy(S) [sym]
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
const t = new Test()
|
|
219
|
-
expect(t[sym]).toBeInstanceOf(S)
|
|
220
|
-
})
|
|
221
|
-
|
|
222
|
-
it('should not leak lazy injected properties to prototype', () => {
|
|
223
|
-
@Singleton()
|
|
224
|
-
class S {
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
class Test {
|
|
228
|
-
@InjectLazy(S) dep
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
// noinspection JSUnusedLocalSymbols
|
|
232
|
-
const t = new Test()
|
|
233
|
-
expect(Object.prototype.hasOwnProperty.call(Test.prototype, 'dep')).toBe(false)
|
|
234
|
-
})
|
|
235
|
-
|
|
236
|
-
it('should allow circular dependencies with lazy injection', () => {
|
|
237
|
-
@Singleton()
|
|
238
|
-
class A1 {
|
|
239
|
-
@InjectLazy('B1') b
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
@Factory('B1')
|
|
243
|
-
class B1 {
|
|
244
|
-
@InjectLazy(A1) a
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
expect(() => new A1()).not.toThrow()
|
|
248
|
-
})
|
|
249
|
-
})
|