@toa.io/core 1.0.0-alpha.29 → 1.0.0-alpha.292
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/CHANGELOG.md +43 -0
- package/package.json +22 -12
- package/source/assignment.ts +27 -0
- package/source/call.ts +63 -0
- package/source/cascade.ts +32 -0
- package/source/component.ts +83 -0
- package/source/composition.ts +27 -0
- package/source/connector.ts +217 -0
- package/source/context.ts +68 -0
- package/source/contract/contract.ts +23 -0
- package/source/contract/index.ts +2 -0
- package/source/contract/reply.ts +56 -0
- package/source/contract/request.ts +140 -0
- package/source/contract/schemas.ts +39 -0
- package/source/discovery.ts +53 -0
- package/source/effect.ts +14 -0
- package/source/emission.ts +21 -0
- package/source/entities/changeset.ts +37 -0
- package/source/entities/entity.ts +137 -0
- package/source/entities/factory.ts +52 -0
- package/source/entities/index.ts +4 -0
- package/source/entities/newid.ts +9 -0
- package/source/entities/set.ts +27 -0
- package/source/event.ts +57 -0
- package/source/exceptions.ts +133 -0
- package/source/exposition.ts +33 -0
- package/source/guard.ts +16 -0
- package/source/index.ts +36 -0
- package/source/locator.ts +37 -0
- package/source/observation.ts +16 -0
- package/source/operation.ts +139 -0
- package/source/outbox/index.ts +1 -0
- package/source/outbox/outbox.ts +341 -0
- package/source/query/criteria.ts +90 -0
- package/source/query/options.ts +35 -0
- package/source/query.ts +67 -0
- package/source/receiver.ts +120 -0
- package/source/reflection.ts +20 -0
- package/source/remote.ts +20 -0
- package/source/state.ts +179 -0
- package/source/transition.ts +79 -0
- package/source/transmission.ts +38 -0
- package/source/types/atomicity.ts +63 -0
- package/source/types/bindings.ts +59 -0
- package/source/types/bridges.ts +54 -0
- package/source/types/extensions.ts +89 -0
- package/source/types/index.ts +14 -0
- package/{types/message.d.ts → source/types/message.ts} +2 -0
- package/source/types/operations.ts +31 -0
- package/source/types/outbox.ts +35 -0
- package/source/types/receiver.ts +10 -0
- package/source/types/request.ts +54 -0
- package/source/types/state.ts +9 -0
- package/source/types/storages.ts +134 -0
- package/source/unmanaged.ts +8 -0
- package/test/call.fixtures.js +10 -12
- package/test/call.test.js +42 -9
- package/test/component.fixtures.js +5 -8
- package/test/component.test.js +27 -10
- package/test/connector.fixtures.js +29 -13
- package/test/connector.test.js +128 -38
- package/test/context.fixtures.js +8 -12
- package/test/context.test.js +19 -8
- package/test/contract/conditions.test.js +15 -9
- package/test/contract/contract.fixtures.js +11 -16
- package/test/contract/request.test.js +130 -46
- package/test/discovery.test.js +71 -0
- package/test/emission.fixtures.js +6 -10
- package/test/emission.test.js +37 -12
- package/test/entities/entity.fixtures.js +11 -16
- package/test/entities/entity.test.js +105 -50
- package/test/entities/factory.fixtures.js +26 -13
- package/test/entities/factory.test.js +68 -17
- package/test/entities/set.fixtures.js +6 -8
- package/test/entities/set.test.js +6 -5
- package/test/event.fixtures.js +9 -14
- package/test/event.test.js +78 -34
- package/test/locator.test.js +32 -25
- package/test/outbox.test.js +202 -0
- package/test/query.fixtures.js +1 -5
- package/test/query.test.js +111 -14
- package/test/receiver.fixtures.js +9 -12
- package/test/receiver.test.js +80 -31
- package/test/reflection.test.js +9 -8
- package/test/state.fixtures.js +33 -31
- package/test/state.test.js +135 -19
- package/test/transmission.fixtures.js +4 -6
- package/test/transmission.test.js +47 -16
- package/transpiled/assignment.d.ts +6 -0
- package/transpiled/assignment.js +20 -0
- package/transpiled/assignment.js.map +1 -0
- package/transpiled/call.d.ts +10 -0
- package/transpiled/call.js +52 -0
- package/transpiled/call.js.map +1 -0
- package/transpiled/cascade.d.ts +7 -0
- package/transpiled/cascade.js +28 -0
- package/transpiled/cascade.js.map +1 -0
- package/transpiled/component.d.ts +15 -0
- package/transpiled/component.js +61 -0
- package/transpiled/component.js.map +1 -0
- package/transpiled/composition.d.ts +6 -0
- package/transpiled/composition.js +23 -0
- package/transpiled/composition.js.map +1 -0
- package/transpiled/connector.d.ts +47 -0
- package/transpiled/connector.js +185 -0
- package/transpiled/connector.js.map +1 -0
- package/transpiled/context.d.ts +18 -0
- package/transpiled/context.js +42 -0
- package/transpiled/context.js.map +1 -0
- package/transpiled/contract/contract.d.ts +10 -0
- package/transpiled/contract/contract.js +14 -0
- package/transpiled/contract/contract.js.map +1 -0
- package/transpiled/contract/index.d.ts +2 -0
- package/transpiled/contract/index.js +3 -0
- package/transpiled/contract/index.js.map +1 -0
- package/transpiled/contract/reply.d.ts +7 -0
- package/transpiled/contract/reply.js +48 -0
- package/transpiled/contract/reply.js.map +1 -0
- package/transpiled/contract/request.d.ts +29 -0
- package/transpiled/contract/request.js +103 -0
- package/transpiled/contract/request.js.map +1 -0
- package/transpiled/contract/schemas.d.ts +4 -0
- package/transpiled/contract/schemas.js +36 -0
- package/transpiled/contract/schemas.js.map +1 -0
- package/transpiled/discovery.d.ts +12 -0
- package/transpiled/discovery.js +34 -0
- package/transpiled/discovery.js.map +1 -0
- package/transpiled/effect.d.ts +5 -0
- package/transpiled/effect.js +11 -0
- package/transpiled/effect.js.map +1 -0
- package/transpiled/emission.d.ts +8 -0
- package/transpiled/emission.js +14 -0
- package/transpiled/emission.js.map +1 -0
- package/transpiled/entities/changeset.d.ts +10 -0
- package/transpiled/entities/changeset.js +27 -0
- package/transpiled/entities/changeset.js.map +1 -0
- package/transpiled/entities/entity.d.ts +19 -0
- package/transpiled/entities/entity.js +109 -0
- package/transpiled/entities/entity.js.map +1 -0
- package/transpiled/entities/factory.d.ts +22 -0
- package/transpiled/entities/factory.js +34 -0
- package/transpiled/entities/factory.js.map +1 -0
- package/transpiled/entities/index.d.ts +4 -0
- package/transpiled/entities/index.js +5 -0
- package/transpiled/entities/index.js.map +1 -0
- package/transpiled/entities/newid.d.ts +1 -0
- package/transpiled/entities/newid.js +7 -0
- package/transpiled/entities/newid.js.map +1 -0
- package/transpiled/entities/set.d.ts +10 -0
- package/transpiled/entities/set.js +19 -0
- package/transpiled/entities/set.js.map +1 -0
- package/transpiled/event.d.ts +14 -0
- package/transpiled/event.js +38 -0
- package/transpiled/event.js.map +1 -0
- package/transpiled/exceptions.d.ts +61 -0
- package/transpiled/exceptions.js +93 -0
- package/transpiled/exceptions.js.map +1 -0
- package/transpiled/exposition.d.ts +18 -0
- package/transpiled/exposition.js +18 -0
- package/transpiled/exposition.js.map +1 -0
- package/transpiled/guard.d.ts +7 -0
- package/transpiled/guard.js +12 -0
- package/transpiled/guard.js.map +1 -0
- package/transpiled/index.d.ts +35 -0
- package/transpiled/index.js +29 -0
- package/transpiled/index.js.map +1 -0
- package/transpiled/locator.d.ts +12 -0
- package/transpiled/locator.js +32 -0
- package/transpiled/locator.js.map +1 -0
- package/transpiled/observation.d.ts +5 -0
- package/transpiled/observation.js +12 -0
- package/transpiled/observation.js.map +1 -0
- package/transpiled/operation.d.ts +49 -0
- package/transpiled/operation.js +78 -0
- package/transpiled/operation.js.map +1 -0
- package/transpiled/outbox/index.d.ts +1 -0
- package/transpiled/outbox/index.js +2 -0
- package/transpiled/outbox/index.js.map +1 -0
- package/transpiled/outbox/outbox.d.ts +46 -0
- package/transpiled/outbox/outbox.js +268 -0
- package/transpiled/outbox/outbox.js.map +1 -0
- package/transpiled/query/criteria.d.ts +6 -0
- package/transpiled/query/criteria.js +74 -0
- package/transpiled/query/criteria.js.map +1 -0
- package/transpiled/query/options.d.ts +3 -0
- package/transpiled/query/options.js +27 -0
- package/transpiled/query/options.js.map +1 -0
- package/transpiled/query.d.ts +9 -0
- package/transpiled/query.js +57 -0
- package/transpiled/query.js.map +1 -0
- package/transpiled/receiver.d.ts +20 -0
- package/transpiled/receiver.js +92 -0
- package/transpiled/receiver.js.map +1 -0
- package/transpiled/reflection.d.ts +9 -0
- package/transpiled/reflection.js +13 -0
- package/transpiled/reflection.js.map +1 -0
- package/transpiled/remote.d.ts +10 -0
- package/transpiled/remote.js +12 -0
- package/transpiled/remote.js.map +1 -0
- package/transpiled/state.d.ts +33 -0
- package/transpiled/state.js +126 -0
- package/transpiled/state.js.map +1 -0
- package/transpiled/transition.d.ts +14 -0
- package/transpiled/transition.js +51 -0
- package/transpiled/transition.js.map +1 -0
- package/transpiled/transmission.d.ts +8 -0
- package/transpiled/transmission.js +30 -0
- package/transpiled/transmission.js.map +1 -0
- package/transpiled/types/atomicity.d.ts +56 -0
- package/transpiled/types/atomicity.js +2 -0
- package/transpiled/types/atomicity.js.map +1 -0
- package/transpiled/types/bindings.d.ts +42 -0
- package/transpiled/types/bindings.js +2 -0
- package/transpiled/types/bindings.js.map +1 -0
- package/transpiled/types/bridges.d.ts +38 -0
- package/transpiled/types/bridges.js +2 -0
- package/transpiled/types/bridges.js.map +1 -0
- package/transpiled/types/extensions.d.ts +62 -0
- package/transpiled/types/extensions.js +2 -0
- package/transpiled/types/extensions.js.map +1 -0
- package/transpiled/types/index.d.ts +13 -0
- package/transpiled/types/index.js +8 -0
- package/transpiled/types/index.js.map +1 -0
- package/transpiled/types/message.d.ts +5 -0
- package/transpiled/types/message.js +2 -0
- package/transpiled/types/message.js.map +1 -0
- package/transpiled/types/operations.d.ts +15 -0
- package/transpiled/types/operations.js +2 -0
- package/transpiled/types/operations.js.map +1 -0
- package/transpiled/types/outbox.d.ts +28 -0
- package/transpiled/types/outbox.js +2 -0
- package/transpiled/types/outbox.js.map +1 -0
- package/transpiled/types/receiver.d.ts +9 -0
- package/transpiled/types/receiver.js +2 -0
- package/transpiled/types/receiver.js.map +1 -0
- package/transpiled/types/request.d.ts +55 -0
- package/transpiled/types/request.js +2 -0
- package/transpiled/types/request.js.map +1 -0
- package/transpiled/types/state.d.ts +9 -0
- package/transpiled/types/state.js +2 -0
- package/transpiled/types/state.js.map +1 -0
- package/transpiled/types/storages.d.ts +111 -0
- package/transpiled/types/storages.js +2 -0
- package/transpiled/types/storages.js.map +1 -0
- package/transpiled/unmanaged.d.ts +5 -0
- package/transpiled/unmanaged.js +7 -0
- package/transpiled/unmanaged.js.map +1 -0
- package/tsconfig.json +10 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/src/assignment.js +0 -31
- package/src/call.js +0 -42
- package/src/cascade.js +0 -36
- package/src/component.js +0 -41
- package/src/composition.js +0 -25
- package/src/connector.js +0 -183
- package/src/context.js +0 -55
- package/src/contract/conditions.js +0 -21
- package/src/contract/index.js +0 -7
- package/src/contract/reply.js +0 -25
- package/src/contract/request.js +0 -67
- package/src/contract/schemas/error.yaml +0 -9
- package/src/contract/schemas/index.js +0 -7
- package/src/contract/schemas/query.yaml +0 -30
- package/src/discovery.js +0 -44
- package/src/emission.js +0 -23
- package/src/entities/changeset.js +0 -43
- package/src/entities/entity.js +0 -73
- package/src/entities/factory.js +0 -33
- package/src/entities/index.js +0 -5
- package/src/entities/set.js +0 -15
- package/src/event.js +0 -40
- package/src/exceptions.js +0 -100
- package/src/exposition.js +0 -27
- package/src/index.js +0 -47
- package/src/locator.js +0 -54
- package/src/observation.js +0 -20
- package/src/operation.js +0 -69
- package/src/query/criteria.js +0 -41
- package/src/query/options.js +0 -40
- package/src/query.js +0 -41
- package/src/receiver.js +0 -65
- package/src/reflection.js +0 -28
- package/src/remote.js +0 -17
- package/src/state.js +0 -99
- package/src/transition.js +0 -73
- package/src/transmission.js +0 -33
- package/types/bindings.d.ts +0 -40
- package/types/bridges.ts +0 -30
- package/types/component.d.ts +0 -9
- package/types/connector.d.ts +0 -18
- package/types/context.d.ts +0 -21
- package/types/entity.d.ts +0 -46
- package/types/event.d.ts +0 -11
- package/types/exception.d.ts +0 -4
- package/types/extensions.d.ts +0 -29
- package/types/index.ts +0 -14
- package/types/locator.d.ts +0 -13
- package/types/operations.d.ts +0 -2
- package/types/query.d.ts +0 -15
- package/types/receiver.d.ts +0 -12
- package/types/reflection.d.ts +0 -14
- package/types/request.d.ts +0 -23
- package/types/state.d.ts +0 -35
- package/types/storages.d.ts +0 -71
package/test/connector.test.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
import { describe, it, beforeEach } from 'node:test'
|
|
2
|
+
import assert from 'node:assert/strict'
|
|
2
3
|
|
|
3
|
-
|
|
4
|
+
import { timeout } from '@toa.io/generic'
|
|
5
|
+
|
|
6
|
+
import * as fixtures from './connector.fixtures.js'
|
|
4
7
|
|
|
5
8
|
let sequence
|
|
6
9
|
|
|
@@ -17,14 +20,14 @@ describe('callbacks', () => {
|
|
|
17
20
|
|
|
18
21
|
it('should call connection', async () => {
|
|
19
22
|
await a.connect()
|
|
20
|
-
|
|
23
|
+
assert.deepStrictEqual(sequence, ['+a'])
|
|
21
24
|
})
|
|
22
25
|
|
|
23
26
|
it('should call disconnection', async () => {
|
|
24
27
|
await a.connect()
|
|
25
28
|
await a.disconnect()
|
|
26
29
|
|
|
27
|
-
|
|
30
|
+
assert.ok(sequence.indexOf('+a') < sequence.indexOf('-a'))
|
|
28
31
|
})
|
|
29
32
|
|
|
30
33
|
it('should reconnect', async () => {
|
|
@@ -32,7 +35,7 @@ describe('callbacks', () => {
|
|
|
32
35
|
await a.reconnect()
|
|
33
36
|
await a.reconnect()
|
|
34
37
|
|
|
35
|
-
|
|
38
|
+
assert.deepStrictEqual(sequence, ['+a', '-a', '*a', '+a', '-a', '*a', '+a'])
|
|
36
39
|
})
|
|
37
40
|
})
|
|
38
41
|
|
|
@@ -55,9 +58,9 @@ describe('dependencies', () => {
|
|
|
55
58
|
|
|
56
59
|
await a.connect()
|
|
57
60
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
+
assert.ok(sequence.indexOf('+c') < sequence.indexOf('+b'))
|
|
62
|
+
assert.ok(sequence.indexOf('+b') < sequence.indexOf('+a'))
|
|
63
|
+
assert.ok(sequence.indexOf('+d') < sequence.indexOf('+a'))
|
|
61
64
|
})
|
|
62
65
|
|
|
63
66
|
it('should wait array of connectors', async () => {
|
|
@@ -67,10 +70,10 @@ describe('dependencies', () => {
|
|
|
67
70
|
|
|
68
71
|
await a.connect()
|
|
69
72
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
73
|
+
assert.ok(sequence.indexOf('+c') < sequence.indexOf('+b'))
|
|
74
|
+
assert.ok(sequence.indexOf('+c') < sequence.indexOf('+d'))
|
|
75
|
+
assert.ok(sequence.indexOf('+b') < sequence.indexOf('+a'))
|
|
76
|
+
assert.ok(sequence.indexOf('+d') < sequence.indexOf('+a'))
|
|
74
77
|
})
|
|
75
78
|
|
|
76
79
|
it('should wait array(1) of connectors', async () => {
|
|
@@ -79,12 +82,15 @@ describe('dependencies', () => {
|
|
|
79
82
|
|
|
80
83
|
await a.connect()
|
|
81
84
|
|
|
82
|
-
|
|
83
|
-
|
|
85
|
+
assert.ok(sequence.indexOf('+c') < sequence.indexOf('+b'))
|
|
86
|
+
assert.ok(sequence.indexOf('+b') < sequence.indexOf('+a'))
|
|
84
87
|
})
|
|
85
88
|
|
|
86
89
|
it('should throw on empty array', async () => {
|
|
87
|
-
|
|
90
|
+
assert.throws(
|
|
91
|
+
() => a.depends([]),
|
|
92
|
+
(error) => /must not be empty/.test(error.message)
|
|
93
|
+
)
|
|
88
94
|
})
|
|
89
95
|
|
|
90
96
|
it('should await 2-way dependencies', async () => {
|
|
@@ -93,23 +99,24 @@ describe('dependencies', () => {
|
|
|
93
99
|
|
|
94
100
|
await a.connect()
|
|
95
101
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
102
|
+
assert.ok(sequence.indexOf('+b') < sequence.indexOf('+a'))
|
|
103
|
+
assert.ok(sequence.indexOf('+c') < sequence.indexOf('+a'))
|
|
104
|
+
assert.ok(sequence.indexOf('+d') < sequence.indexOf('+a'))
|
|
99
105
|
|
|
100
|
-
|
|
101
|
-
|
|
106
|
+
assert.ok(sequence.indexOf('+b') < sequence.indexOf('+d'))
|
|
107
|
+
assert.ok(sequence.indexOf('+c') < sequence.indexOf('+d'))
|
|
102
108
|
})
|
|
103
109
|
|
|
104
110
|
it('should disconnect before dependencies', async () => {
|
|
105
111
|
a.depends(b).depends(c)
|
|
106
112
|
b.depends(d)
|
|
107
113
|
|
|
114
|
+
await a.connect()
|
|
108
115
|
await a.disconnect()
|
|
109
116
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
117
|
+
assert.ok(sequence.indexOf('-a') < sequence.indexOf('-b'))
|
|
118
|
+
assert.ok(sequence.indexOf('-b') < sequence.indexOf('-c'))
|
|
119
|
+
assert.ok(sequence.indexOf('-b') < sequence.indexOf('-d'))
|
|
113
120
|
})
|
|
114
121
|
|
|
115
122
|
it('should call disconnected', async () => {
|
|
@@ -118,10 +125,10 @@ describe('dependencies', () => {
|
|
|
118
125
|
|
|
119
126
|
await a.disconnect()
|
|
120
127
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
128
|
+
assert.ok(sequence.indexOf('*c') < sequence.indexOf('*b'))
|
|
129
|
+
assert.ok(sequence.indexOf('*b') < sequence.indexOf('*a'))
|
|
130
|
+
assert.ok(sequence.indexOf('*d') < sequence.indexOf('*b'))
|
|
131
|
+
assert.strictEqual(sequence.indexOf('*a'), sequence.length - 1)
|
|
125
132
|
})
|
|
126
133
|
|
|
127
134
|
it('should disconnect if no parents left', async () => {
|
|
@@ -131,19 +138,102 @@ describe('dependencies', () => {
|
|
|
131
138
|
await a.connect()
|
|
132
139
|
await b.connect()
|
|
133
140
|
|
|
134
|
-
|
|
141
|
+
assert.deepStrictEqual(sequence, ['+c', '+a', '+b'])
|
|
135
142
|
|
|
136
143
|
await a.disconnect()
|
|
137
144
|
|
|
138
|
-
|
|
145
|
+
assert.deepStrictEqual(sequence, ['+c', '+a', '+b', '-a', '*a'])
|
|
139
146
|
|
|
140
147
|
await b.disconnect()
|
|
141
148
|
|
|
142
|
-
|
|
149
|
+
assert.deepStrictEqual(sequence, [
|
|
150
|
+
'+c',
|
|
151
|
+
'+a',
|
|
152
|
+
'+b',
|
|
153
|
+
'-a',
|
|
154
|
+
'*a',
|
|
155
|
+
'-b',
|
|
156
|
+
'-c',
|
|
157
|
+
'*c',
|
|
158
|
+
'*b'
|
|
159
|
+
])
|
|
143
160
|
})
|
|
144
161
|
|
|
145
162
|
it('should throw if depends not on Connector', async () => {
|
|
146
|
-
|
|
163
|
+
assert.throws(() => a.depends({}))
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
it('should disconnect while still connecting', async () => {
|
|
167
|
+
const stuck = new fixtures.StuckConnector()
|
|
168
|
+
|
|
169
|
+
a.depends(stuck).depends(b)
|
|
170
|
+
|
|
171
|
+
void a.connect()
|
|
172
|
+
|
|
173
|
+
while (b.connected !== true) await timeout(1)
|
|
174
|
+
|
|
175
|
+
// `a` never connects, and disconnecting must not wait for it to
|
|
176
|
+
assert.deepStrictEqual(a.connected, false)
|
|
177
|
+
|
|
178
|
+
await a.disconnect()
|
|
179
|
+
|
|
180
|
+
assert.deepStrictEqual(sequence, ['+b', '-b', '*b', '*a'])
|
|
181
|
+
})
|
|
182
|
+
|
|
183
|
+
it('should disconnect a dependency taken on after disconnection', async () => {
|
|
184
|
+
a.depends(b)
|
|
185
|
+
|
|
186
|
+
await a.connect()
|
|
187
|
+
await a.disconnect()
|
|
188
|
+
|
|
189
|
+
// what a lookup that returns once the teardown walk has gone by amounts to
|
|
190
|
+
a.depends(c)
|
|
191
|
+
|
|
192
|
+
await c.connect()
|
|
193
|
+
|
|
194
|
+
assert.strictEqual(c.connected, false)
|
|
195
|
+
assert.ok(sequence.indexOf('*c') > sequence.indexOf('*a'))
|
|
196
|
+
})
|
|
197
|
+
|
|
198
|
+
it('should disconnect a connected dependency taken on after disconnection', async () => {
|
|
199
|
+
a.depends(b)
|
|
200
|
+
|
|
201
|
+
await a.connect()
|
|
202
|
+
await a.disconnect()
|
|
203
|
+
await c.connect()
|
|
204
|
+
|
|
205
|
+
a.depends(c)
|
|
206
|
+
|
|
207
|
+
// the discarding is not something the caller waits for
|
|
208
|
+
for (let i = 0; c.connected && i < 100; i++) await timeout(1)
|
|
209
|
+
|
|
210
|
+
assert.strictEqual(c.connected, false)
|
|
211
|
+
assert.ok(sequence.includes('*c'))
|
|
212
|
+
})
|
|
213
|
+
|
|
214
|
+
it('should not connect what was disconnected while connecting', async () => {
|
|
215
|
+
const late = new fixtures.LateConnector()
|
|
216
|
+
|
|
217
|
+
late.depends(c)
|
|
218
|
+
b.depends(c)
|
|
219
|
+
|
|
220
|
+
await b.connect()
|
|
221
|
+
|
|
222
|
+
const connecting = late.connect()
|
|
223
|
+
|
|
224
|
+
await late.disconnect()
|
|
225
|
+
|
|
226
|
+
late.arrive()
|
|
227
|
+
|
|
228
|
+
await connecting
|
|
229
|
+
|
|
230
|
+
// the connection landed after the disconnection, and nothing is left to say it again
|
|
231
|
+
assert.strictEqual(late.connected, false)
|
|
232
|
+
|
|
233
|
+
await b.disconnect()
|
|
234
|
+
|
|
235
|
+
assert.strictEqual(c.connected, false)
|
|
236
|
+
assert.ok(sequence.includes('*c'))
|
|
147
237
|
})
|
|
148
238
|
|
|
149
239
|
describe('errors', () => {
|
|
@@ -156,21 +246,21 @@ describe('dependencies', () => {
|
|
|
156
246
|
it('should disconnect on fail', async () => {
|
|
157
247
|
f.depends(b).depends(c)
|
|
158
248
|
|
|
159
|
-
await
|
|
160
|
-
|
|
249
|
+
await assert.rejects(f.connect(), (error) => /FailingConnector/.test(error.message))
|
|
250
|
+
assert.deepStrictEqual(sequence, ['+c', '+b', '-b', '-c', '*c', '*b'])
|
|
161
251
|
})
|
|
162
252
|
|
|
163
253
|
it('should interrupt connection chain', async () => {
|
|
164
254
|
a.depends(f).depends(c)
|
|
165
255
|
f.depends(d)
|
|
166
256
|
|
|
167
|
-
await
|
|
257
|
+
await assert.rejects(a.connect(), (error) => /FailingConnector/.test(error.message))
|
|
168
258
|
|
|
169
|
-
|
|
170
|
-
|
|
259
|
+
assert.ok(sequence.indexOf('+c') < sequence.indexOf('-c'))
|
|
260
|
+
assert.ok(sequence.indexOf('+d') < sequence.indexOf('-d'))
|
|
171
261
|
|
|
172
|
-
|
|
173
|
-
|
|
262
|
+
assert.strictEqual(sequence.indexOf('+a'), -1)
|
|
263
|
+
assert.strictEqual(sequence.indexOf('-a'), -1)
|
|
174
264
|
})
|
|
175
265
|
})
|
|
176
266
|
})
|
package/test/context.fixtures.js
CHANGED
|
@@ -1,18 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
import { mock } from 'node:test'
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
import { Connector } from '../source/connector.js'
|
|
4
4
|
|
|
5
|
-
const local = {
|
|
6
|
-
link:
|
|
5
|
+
export const local = {
|
|
6
|
+
link: mock.fn()
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
const discover =
|
|
10
|
-
invoke:
|
|
11
|
-
link:
|
|
9
|
+
export const discover = mock.fn(() => ({
|
|
10
|
+
invoke: mock.fn(),
|
|
11
|
+
link: mock.fn()
|
|
12
12
|
}))
|
|
13
13
|
|
|
14
|
-
const aspects = [new Connector(), new Connector()]
|
|
15
|
-
|
|
16
|
-
exports.local = local
|
|
17
|
-
exports.discover = discover
|
|
18
|
-
exports.aspects = aspects
|
|
14
|
+
export const aspects = [new Connector(), new Connector()]
|
package/test/context.test.js
CHANGED
|
@@ -1,20 +1,21 @@
|
|
|
1
|
-
|
|
1
|
+
import { describe, it, beforeEach } from 'node:test'
|
|
2
|
+
import assert from 'node:assert/strict'
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
4
|
+
import * as fixtures from './context.fixtures.js'
|
|
5
|
+
import { Context } from '../source/context.js'
|
|
5
6
|
|
|
6
|
-
/** @type {toa.core.Context} */
|
|
7
|
+
/** @type {import('@toa.io/core').Context} */
|
|
7
8
|
let context
|
|
8
9
|
|
|
9
10
|
beforeEach(() => {
|
|
10
|
-
|
|
11
|
+
resetCalls()
|
|
11
12
|
|
|
12
13
|
context = new Context(fixtures.local, fixtures.discover, fixtures.aspects)
|
|
13
14
|
})
|
|
14
15
|
|
|
15
16
|
it('should expose aspects', () => {
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
assert.notStrictEqual(context.aspects, undefined)
|
|
18
|
+
assert.deepStrictEqual(context.aspects, fixtures.aspects)
|
|
18
19
|
})
|
|
19
20
|
|
|
20
21
|
describe('call', () => {
|
|
@@ -24,6 +25,16 @@ describe('call', () => {
|
|
|
24
25
|
await context.call('a', 'b', 'c', request)
|
|
25
26
|
await context.call('a', 'b', 'c', request)
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
assert.strictEqual(fixtures.discover.mock.callCount(), 1)
|
|
28
29
|
})
|
|
29
30
|
})
|
|
31
|
+
|
|
32
|
+
function resetCalls(target = [assert, fixtures], seen = new Set()) {
|
|
33
|
+
if (target === null || typeof target !== 'object' || seen.has(target)) return
|
|
34
|
+
|
|
35
|
+
seen.add(target)
|
|
36
|
+
|
|
37
|
+
for (const value of Object.values(target))
|
|
38
|
+
if (typeof value === 'function' && value.mock !== undefined) value.mock.resetCalls()
|
|
39
|
+
else resetCalls(value, seen)
|
|
40
|
+
}
|
|
@@ -1,26 +1,32 @@
|
|
|
1
|
-
|
|
1
|
+
import { it, beforeEach } from 'node:test'
|
|
2
|
+
import assert from 'node:assert/strict'
|
|
3
|
+
import { isDeepStrictEqual } from 'node:util'
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
import { generate } from 'randomstring'
|
|
4
6
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
+
import { Contract } from '../../source/contract/contract.js'
|
|
8
|
+
import * as fixtures from './contract.fixtures.js'
|
|
7
9
|
|
|
8
|
-
let
|
|
10
|
+
let contract
|
|
9
11
|
|
|
10
12
|
beforeEach(() => {
|
|
11
|
-
|
|
13
|
+
contract = new Contract(fixtures.schema)
|
|
12
14
|
})
|
|
13
15
|
|
|
14
16
|
it('should fit value', () => {
|
|
15
17
|
const value = { foo: generate() }
|
|
16
18
|
|
|
17
|
-
|
|
19
|
+
contract.fit(value)
|
|
18
20
|
|
|
19
|
-
|
|
21
|
+
assert.ok(
|
|
22
|
+
fixtures.schema.fit.mock.calls.some(
|
|
23
|
+
(call) => call.arguments.length === 1 && isDeepStrictEqual(call.arguments[0], value)
|
|
24
|
+
)
|
|
25
|
+
)
|
|
20
26
|
})
|
|
21
27
|
|
|
22
28
|
it('should throw on invalid value', () => {
|
|
23
29
|
const value = { invalid: true }
|
|
24
30
|
|
|
25
|
-
|
|
31
|
+
assert.throws(() => contract.fit(value))
|
|
26
32
|
})
|
|
@@ -1,33 +1,28 @@
|
|
|
1
|
-
|
|
1
|
+
import { mock } from 'node:test'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
import { generate } from 'randomstring'
|
|
4
|
+
|
|
5
|
+
import { query as querySchema } from '../../source/contract/schemas.js'
|
|
6
6
|
|
|
7
7
|
// noinspection JSCheckFunctionSignatures
|
|
8
|
-
const schema = {
|
|
9
|
-
fit:
|
|
8
|
+
export const schema = {
|
|
9
|
+
fit: mock.fn((input) => (input.invalid ? { message: generate() } : null))
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
const query = {
|
|
13
|
-
parse:
|
|
12
|
+
export const query = {
|
|
13
|
+
parse: mock.fn(() => ({ [generate()]: generate() }))
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
const declaration = {}
|
|
16
|
+
export const declaration = {}
|
|
17
17
|
|
|
18
|
-
const schemas = {
|
|
18
|
+
export const schemas = {
|
|
19
19
|
request: {
|
|
20
20
|
type: 'object',
|
|
21
21
|
properties: {
|
|
22
22
|
input: { type: 'null' },
|
|
23
|
-
query:
|
|
23
|
+
query: querySchema,
|
|
24
24
|
authentic: { type: 'boolean' }
|
|
25
25
|
},
|
|
26
26
|
additionalProperties: true
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
|
-
|
|
30
|
-
exports.schema = schema
|
|
31
|
-
exports.query = query
|
|
32
|
-
exports.declaration = declaration
|
|
33
|
-
exports.schemas = schemas
|
|
@@ -1,27 +1,32 @@
|
|
|
1
|
-
|
|
1
|
+
import * as schemas from '@toa.io/schemas'
|
|
2
|
+
import { describe, it, beforeEach, mock } from 'node:test'
|
|
3
|
+
import assert from 'node:assert/strict'
|
|
4
|
+
import { isDeepStrictEqual } from 'node:util'
|
|
2
5
|
|
|
3
|
-
|
|
4
|
-
|
|
6
|
+
import clone from 'clone-deep'
|
|
7
|
+
import { generate } from 'randomstring'
|
|
5
8
|
|
|
6
|
-
|
|
9
|
+
import { Request } from '../../source/contract/request.js'
|
|
10
|
+
import { Contract } from '../../source/contract/contract.js'
|
|
11
|
+
import * as fixtures from './contract.fixtures.js'
|
|
7
12
|
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
const fixtures = require('./contract.fixtures')
|
|
13
|
+
// the base is real; what it was constructed with and told to fit is observable
|
|
14
|
+
const fit = mock.method(Contract.prototype, 'fit', () => undefined)
|
|
11
15
|
|
|
12
16
|
let contract
|
|
13
17
|
|
|
14
18
|
beforeEach(() => {
|
|
15
|
-
|
|
19
|
+
resetCalls()
|
|
20
|
+
fit.mock.resetCalls()
|
|
16
21
|
|
|
17
|
-
contract = new Request(fixtures.schema)
|
|
22
|
+
contract = new Request(fixtures.schema, {})
|
|
18
23
|
})
|
|
19
24
|
|
|
20
|
-
const dummy = {
|
|
25
|
+
const dummy = { properties: {} }
|
|
21
26
|
|
|
22
27
|
it('should extend Conditions', () => {
|
|
23
|
-
|
|
24
|
-
|
|
28
|
+
assert.ok(contract instanceof Contract)
|
|
29
|
+
assert.strictEqual(contract.schema, fixtures.schema)
|
|
25
30
|
})
|
|
26
31
|
|
|
27
32
|
it('should fit request', () => {
|
|
@@ -29,7 +34,11 @@ it('should fit request', () => {
|
|
|
29
34
|
|
|
30
35
|
contract.fit(request)
|
|
31
36
|
|
|
32
|
-
|
|
37
|
+
assert.ok(
|
|
38
|
+
fit.mock.calls.some(
|
|
39
|
+
(call) => call.this === contract && isDeepStrictEqual(call.arguments[0], request)
|
|
40
|
+
)
|
|
41
|
+
)
|
|
33
42
|
})
|
|
34
43
|
|
|
35
44
|
describe('schema', () => {
|
|
@@ -40,73 +49,148 @@ describe('schema', () => {
|
|
|
40
49
|
})
|
|
41
50
|
|
|
42
51
|
it('should provide schema', () => {
|
|
43
|
-
|
|
52
|
+
assert.notStrictEqual(Request.schema({}, dummy), undefined)
|
|
44
53
|
})
|
|
45
54
|
|
|
46
55
|
it('should add required input if defined', () => {
|
|
47
56
|
const input = { type: 'number' }
|
|
48
57
|
|
|
49
|
-
|
|
58
|
+
assert.deepStrictEqual(Request.schema({ input }, dummy).properties.input, input)
|
|
50
59
|
})
|
|
51
60
|
|
|
52
61
|
it('should set input as null if undefined', async () => {
|
|
53
|
-
|
|
62
|
+
assert.deepStrictEqual(Request.schema({}, dummy).properties.input, { type: 'null' })
|
|
54
63
|
})
|
|
55
64
|
|
|
56
65
|
it('should contain query if declaration.query is not defined', () => {
|
|
57
|
-
|
|
66
|
+
assert.notStrictEqual(Request.schema({}, dummy).properties.query, undefined)
|
|
58
67
|
})
|
|
59
68
|
|
|
60
69
|
it('should not contain query if declaration.query is false', () => {
|
|
61
70
|
schema.properties.query = { type: 'null' }
|
|
62
|
-
|
|
71
|
+
assert.partialDeepStrictEqual(Request.schema({ query: false }, dummy), schema)
|
|
63
72
|
})
|
|
64
73
|
|
|
65
74
|
it('should require query if declaration.query is true', () => {
|
|
66
75
|
schema.required = ['query']
|
|
67
|
-
|
|
76
|
+
assert.ok(
|
|
77
|
+
['query'].every((item) =>
|
|
78
|
+
Request.schema({ query: true }, dummy).required.some((candidate) =>
|
|
79
|
+
isDeepStrictEqual(candidate, item)
|
|
80
|
+
)
|
|
81
|
+
)
|
|
82
|
+
)
|
|
68
83
|
})
|
|
69
84
|
|
|
70
85
|
it('should forbid projection for non observations', () => {
|
|
71
|
-
|
|
72
|
-
.
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
.
|
|
86
|
+
assert.strictEqual(
|
|
87
|
+
Request.schema({ type: 'transition' }, dummy).properties.query.properties
|
|
88
|
+
.projection,
|
|
89
|
+
undefined
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
assert.strictEqual(
|
|
93
|
+
Request.schema({ type: 'assignment' }, dummy).properties.query.properties
|
|
94
|
+
.projection,
|
|
95
|
+
undefined
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
assert.notStrictEqual(
|
|
99
|
+
Request.schema({ type: 'observation' }, dummy).properties.query.properties
|
|
100
|
+
.projection,
|
|
101
|
+
undefined
|
|
102
|
+
)
|
|
79
103
|
})
|
|
80
104
|
|
|
81
105
|
it('should forbid version for observations', () => {
|
|
82
|
-
|
|
83
|
-
.
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
106
|
+
assert.notStrictEqual(
|
|
107
|
+
Request.schema({ type: 'transition' }, dummy).properties.query.properties.version,
|
|
108
|
+
undefined
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
assert.strictEqual(
|
|
112
|
+
Request.schema({ type: 'observation' }, dummy).properties.query.properties.version,
|
|
113
|
+
undefined
|
|
114
|
+
)
|
|
87
115
|
})
|
|
88
116
|
|
|
89
117
|
it('should allow omit, limit only for set observations', () => {
|
|
90
118
|
const schema = Request.schema({ type: 'transition' }, dummy)
|
|
91
119
|
const transition = schema.properties.query.properties
|
|
92
120
|
|
|
93
|
-
|
|
94
|
-
|
|
121
|
+
assert.strictEqual(transition.omit, undefined)
|
|
122
|
+
assert.strictEqual(transition.limit, undefined)
|
|
123
|
+
|
|
124
|
+
const object = Request.schema(
|
|
125
|
+
{
|
|
126
|
+
type: 'observation',
|
|
127
|
+
scope: 'object'
|
|
128
|
+
},
|
|
129
|
+
dummy
|
|
130
|
+
).properties.query.properties
|
|
131
|
+
|
|
132
|
+
assert.strictEqual(object.omit, undefined)
|
|
133
|
+
assert.strictEqual(object.limit, undefined)
|
|
134
|
+
|
|
135
|
+
const objects = Request.schema(
|
|
136
|
+
{
|
|
137
|
+
type: 'observation',
|
|
138
|
+
scope: 'objects'
|
|
139
|
+
},
|
|
140
|
+
dummy
|
|
141
|
+
).properties.query.properties
|
|
142
|
+
|
|
143
|
+
assert.notStrictEqual(objects.omit, undefined)
|
|
144
|
+
assert.notStrictEqual(objects.limit, undefined)
|
|
145
|
+
})
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
describe('source', () => {
|
|
149
|
+
const compile = (definition, entity) =>
|
|
150
|
+
schemas.schema(Request.schema(definition, entity))
|
|
95
151
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
scope: 'object'
|
|
99
|
-
}, dummy).properties.query.properties
|
|
152
|
+
it('should not hold source to a schema', () => {
|
|
153
|
+
const schema = Request.schema({}, dummy)
|
|
100
154
|
|
|
101
|
-
|
|
102
|
-
|
|
155
|
+
assert.strictEqual(schema.properties.source, undefined)
|
|
156
|
+
})
|
|
103
157
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
scope: 'objects'
|
|
107
|
-
}, dummy).properties.query.properties
|
|
158
|
+
it('should pass known source variants', () => {
|
|
159
|
+
const schema = compile({}, undefined)
|
|
108
160
|
|
|
109
|
-
|
|
110
|
-
|
|
161
|
+
for (const source of [
|
|
162
|
+
{ namespace: 'a', component: 'b', operation: 'c' },
|
|
163
|
+
{ namespace: 'a', component: 'b', event: 'c' },
|
|
164
|
+
{ service: 'exposition' }
|
|
165
|
+
]) {
|
|
166
|
+
const request = { input: null, query: null, source }
|
|
167
|
+
|
|
168
|
+
assert.deepStrictEqual(schema.fit(request), null)
|
|
169
|
+
assert.deepStrictEqual(request.source, source)
|
|
170
|
+
}
|
|
171
|
+
})
|
|
172
|
+
|
|
173
|
+
// whatever a peer puts beside the keys this release knows travels through: what reads
|
|
174
|
+
// `source` takes the keys it knows, and the contract does not fail a call over the rest
|
|
175
|
+
it('should pass a source a peer added to', () => {
|
|
176
|
+
const schema = compile({}, undefined)
|
|
177
|
+
const request = {
|
|
178
|
+
input: null,
|
|
179
|
+
query: null,
|
|
180
|
+
source: { service: 'exposition', mystery: 'x' }
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
assert.deepStrictEqual(schema.fit(request), null)
|
|
184
|
+
assert.deepStrictEqual(request.source, { service: 'exposition', mystery: 'x' })
|
|
111
185
|
})
|
|
112
186
|
})
|
|
187
|
+
|
|
188
|
+
function resetCalls(target = [assert, clone, fixtures, dummy], seen = new Set()) {
|
|
189
|
+
if (target === null || typeof target !== 'object' || seen.has(target)) return
|
|
190
|
+
|
|
191
|
+
seen.add(target)
|
|
192
|
+
|
|
193
|
+
for (const value of Object.values(target))
|
|
194
|
+
if (typeof value === 'function' && value.mock !== undefined) value.mock.resetCalls()
|
|
195
|
+
else resetCalls(value, seen)
|
|
196
|
+
}
|