-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathintegration.test.ts
More file actions
117 lines (105 loc) · 4.15 KB
/
Copy pathintegration.test.ts
File metadata and controls
117 lines (105 loc) · 4.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import { Container, inject, injectable, multiInject } from 'inversify'
import { setTimeout } from 'timers/promises'
import { describe, expect, it, vi } from 'vitest'
import { MetaKey } from './common'
import DependsOn from './decorators/DependsOn'
import destroy from './destroy'
import getDeps from './helpers/inversify/getDeps'
import get from './helpers/metadata/get'
describe.concurrent('Integration with Inversify', () => {
it('should work', { repeats: 10 }, async () => {
const logs: string[] = []
async function dispose(this: NewableFunction) {
const className = this.constructor.name
logs.push(`pre disposing ${className}`)
await setTimeout(Math.random() * 200)
logs.push(`post disposing ${className}`)
}
function checkOrder(first: string, second: string) {
expect(logs.indexOf(`post disposing ${first}`))
.toBeLessThan(logs.indexOf(`pre disposing ${second}`))
}
class Service {
public [Symbol.asyncDispose] = dispose
}
const container = new Container()
@injectable()
class RemoteConfigService extends Service {}
container.bind(RemoteConfigService).toSelf().inSingletonScope()
@DependsOn(getDeps(DatabaseService))
@injectable()
class DatabaseService extends Service {
@inject(RemoteConfigService)
public remoteConfigService?: RemoteConfigService
}
container.bind(DatabaseService).toSelf().inSingletonScope()
class Gadget extends Service {}
@injectable()
class Gadget0 extends Gadget {}
@injectable()
class Gadget1 extends Gadget {}
container.bind(Gadget).to(Gadget0).inSingletonScope()
container.bind(Gadget).to(Gadget1).inSingletonScope()
@DependsOn(getDeps(UserService))
@injectable()
class UserService extends Service {
@inject(RemoteConfigService)
public remoteConfigService?: RemoteConfigService
@inject(DatabaseService)
public databaseService?: DatabaseService
public constructor(
@multiInject(Gadget)
public gadgets: Gadget[],
) {
super()
}
}
container.bind(UserService).toSelf().inSingletonScope()
@DependsOn(getDeps(TeamService))
@injectable()
class TeamService extends Service {
@inject(DatabaseService)
public databaseService?: DatabaseService
}
container.bind(TeamService).toSelf().inSingletonScope()
expect(get(MetaKey.DependsOnProps, UserService))
.toEqual(['remoteConfigService', 'databaseService'])
expect(get(MetaKey.DependsOnProps, TeamService))
.toEqual(['databaseService'])
expect(get(MetaKey.DependsOnProps, DatabaseService))
.toEqual(['remoteConfigService'])
expect(get(MetaKey.DependsOnProps, RemoteConfigService)).toBeUndefined()
const [userSerivce, teamService] = await Promise.all([
container.getAsync(UserService),
container.getAsync(TeamService),
])
const remoteConfigService = container.get(RemoteConfigService)
const databaseService = container.get(DatabaseService)
expect(userSerivce.remoteConfigService).toBe(remoteConfigService)
expect(userSerivce.databaseService).toBe(databaseService)
expect(userSerivce.gadgets[0]).toBeInstanceOf(Gadget0)
expect(userSerivce.gadgets[1]).toBeInstanceOf(Gadget1)
expect(teamService.databaseService).toBe(databaseService)
expect(databaseService.remoteConfigService).toBe(remoteConfigService)
const onCircularDependencyDetected = vi.fn()
await expect(
destroy({
instances: [
...container.getAll(Gadget),
container.get(RemoteConfigService),
container.get(DatabaseService),
container.get(UserService),
container.get(TeamService),
],
onCircularDependencyDetected,
})).resolves.toBeUndefined()
console.debug(logs)
expect(onCircularDependencyDetected).not.toHaveBeenCalled()
checkOrder(UserService.name, Gadget0.name)
checkOrder(UserService.name, Gadget1.name)
checkOrder(UserService.name, RemoteConfigService.name)
checkOrder(UserService.name, DatabaseService.name)
checkOrder(TeamService.name, DatabaseService.name)
checkOrder(DatabaseService.name, RemoteConfigService.name)
})
})