@toa.io/core 1.0.0-alpha.292 → 1.0.0-alpha.293

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.
Files changed (90) hide show
  1. package/package.json +10 -4
  2. package/CHANGELOG.md +0 -43
  3. package/source/assignment.ts +0 -27
  4. package/source/call.ts +0 -63
  5. package/source/cascade.ts +0 -32
  6. package/source/component.ts +0 -83
  7. package/source/composition.ts +0 -27
  8. package/source/connector.ts +0 -217
  9. package/source/context.ts +0 -68
  10. package/source/contract/contract.ts +0 -23
  11. package/source/contract/index.ts +0 -2
  12. package/source/contract/reply.ts +0 -56
  13. package/source/contract/request.ts +0 -140
  14. package/source/contract/schemas.ts +0 -39
  15. package/source/discovery.ts +0 -53
  16. package/source/effect.ts +0 -14
  17. package/source/emission.ts +0 -21
  18. package/source/entities/changeset.ts +0 -37
  19. package/source/entities/entity.ts +0 -137
  20. package/source/entities/factory.ts +0 -52
  21. package/source/entities/index.ts +0 -4
  22. package/source/entities/newid.ts +0 -9
  23. package/source/entities/set.ts +0 -27
  24. package/source/event.ts +0 -57
  25. package/source/exceptions.ts +0 -133
  26. package/source/exposition.ts +0 -33
  27. package/source/guard.ts +0 -16
  28. package/source/index.ts +0 -36
  29. package/source/locator.ts +0 -37
  30. package/source/observation.ts +0 -16
  31. package/source/operation.ts +0 -139
  32. package/source/outbox/index.ts +0 -1
  33. package/source/outbox/outbox.ts +0 -341
  34. package/source/query/criteria.ts +0 -90
  35. package/source/query/options.ts +0 -35
  36. package/source/query.ts +0 -67
  37. package/source/receiver.ts +0 -120
  38. package/source/reflection.ts +0 -20
  39. package/source/remote.ts +0 -20
  40. package/source/state.ts +0 -179
  41. package/source/transition.ts +0 -79
  42. package/source/transmission.ts +0 -38
  43. package/source/types/atomicity.ts +0 -63
  44. package/source/types/bindings.ts +0 -59
  45. package/source/types/bridges.ts +0 -54
  46. package/source/types/extensions.ts +0 -89
  47. package/source/types/index.ts +0 -14
  48. package/source/types/message.ts +0 -5
  49. package/source/types/operations.ts +0 -31
  50. package/source/types/outbox.ts +0 -35
  51. package/source/types/receiver.ts +0 -10
  52. package/source/types/request.ts +0 -54
  53. package/source/types/state.ts +0 -9
  54. package/source/types/storages.ts +0 -134
  55. package/source/unmanaged.ts +0 -8
  56. package/test/call.fixtures.js +0 -25
  57. package/test/call.test.js +0 -79
  58. package/test/component.fixtures.js +0 -18
  59. package/test/component.test.js +0 -57
  60. package/test/connector.fixtures.js +0 -56
  61. package/test/connector.test.js +0 -266
  62. package/test/context.fixtures.js +0 -14
  63. package/test/context.test.js +0 -40
  64. package/test/contract/conditions.test.js +0 -32
  65. package/test/contract/contract.fixtures.js +0 -28
  66. package/test/contract/request.test.js +0 -196
  67. package/test/discovery.test.js +0 -71
  68. package/test/emission.fixtures.js +0 -13
  69. package/test/emission.test.js +0 -60
  70. package/test/entities/entity.fixtures.js +0 -24
  71. package/test/entities/entity.test.js +0 -137
  72. package/test/entities/factory.fixtures.js +0 -31
  73. package/test/entities/factory.test.js +0 -99
  74. package/test/entities/set.fixtures.js +0 -9
  75. package/test/entities/set.test.js +0 -13
  76. package/test/event.fixtures.js +0 -24
  77. package/test/event.test.js +0 -162
  78. package/test/locator.test.js +0 -120
  79. package/test/outbox.test.js +0 -202
  80. package/test/query.fixtures.js +0 -96
  81. package/test/query.test.js +0 -183
  82. package/test/receiver.fixtures.js +0 -20
  83. package/test/receiver.test.js +0 -144
  84. package/test/reflection.test.js +0 -31
  85. package/test/state.fixtures.js +0 -49
  86. package/test/state.test.js +0 -162
  87. package/test/transmission.fixtures.js +0 -13
  88. package/test/transmission.test.js +0 -77
  89. package/tsconfig.json +0 -10
  90. package/tsconfig.tsbuildinfo +0 -1
@@ -1,202 +0,0 @@
1
- import { it, beforeEach, afterEach, mock } from 'node:test'
2
- import assert from 'node:assert/strict'
3
-
4
- import { Outbox } from '../source/outbox/index.js'
5
-
6
- let emission, storage, atom, outbox, listeners
7
-
8
- const BATCH = 4
9
-
10
- /** rows as the storage hands them back, ids ascending like the uuid v7 they are */
11
- const page = (from, count) =>
12
- Array.from({ length: count }, (_, i) => ({
13
- id: String(from + i).padStart(4, '0'),
14
- event: { state: {} }
15
- }))
16
-
17
- beforeEach(() => {
18
- resetCalls()
19
- mock.timers.enable()
20
-
21
- emission = { emit: mock.fn(async () => undefined), link: mock.fn() }
22
-
23
- storage = {
24
- link: mock.fn(),
25
- outbox: {
26
- pending: mock.fn(async () => []),
27
- settle: mock.fn(async () => undefined)
28
- }
29
- }
30
-
31
- listeners = []
32
-
33
- atom = {
34
- slots: mock.fn(() => [0]),
35
- onassigned: (listener) => {
36
- listeners.push(listener)
37
- listener({ i: 0, n: 1 })
38
-
39
- return () => {
40
- listeners = listeners.filter((one) => one !== listener)
41
- }
42
- },
43
- link: mock.fn()
44
- }
45
- outbox = new Outbox(emission, storage, atom, { interval: 1000, batch: BATCH })
46
- })
47
-
48
- afterEach(() => {
49
- mock.timers.reset()
50
- })
51
-
52
- /** everything the current turn awaited, without moving the clock */
53
- const settled = async () => {
54
- for (let i = 0; i < 20; i++) await Promise.resolve()
55
- }
56
-
57
- /** one cycle, and everything it awaited */
58
- const cycle = async () => {
59
- mock.timers.tick(1000)
60
-
61
- for (let i = 0; i < 20; i++) await Promise.resolve()
62
- }
63
-
64
- it('should read nothing more when the first page is short', async () => {
65
- storage.outbox.pending.mock.mockImplementationOnce(async () => page(0, 3))
66
-
67
- await outbox.open()
68
- await cycle()
69
-
70
- assert.strictEqual(storage.outbox.pending.mock.callCount(), 1)
71
- assert.strictEqual(emission.emit.mock.callCount(), 3)
72
- })
73
-
74
- it('should keep reading while a page comes back full', async () => {
75
- storage.outbox.pending.mock.mockImplementationOnce(
76
- async () => page(0, BATCH),
77
- storage.outbox.pending.mock.callCount()
78
- )
79
- storage.outbox.pending.mock.mockImplementationOnce(
80
- async () => page(BATCH, BATCH),
81
- storage.outbox.pending.mock.callCount() + 1
82
- )
83
- storage.outbox.pending.mock.mockImplementationOnce(
84
- async () => page(2 * BATCH, 5),
85
- storage.outbox.pending.mock.callCount() + 2
86
- )
87
-
88
- await outbox.open()
89
- await cycle()
90
-
91
- assert.strictEqual(storage.outbox.pending.mock.callCount(), 3)
92
- assert.strictEqual(emission.emit.mock.callCount(), 2 * BATCH + 5)
93
- })
94
-
95
- it('should continue each page from the id the one before ended on', async () => {
96
- storage.outbox.pending.mock.mockImplementationOnce(
97
- async () => page(0, BATCH),
98
- storage.outbox.pending.mock.callCount()
99
- )
100
- storage.outbox.pending.mock.mockImplementationOnce(
101
- async () => page(BATCH, 1),
102
- storage.outbox.pending.mock.callCount() + 1
103
- )
104
-
105
- await outbox.open()
106
- await cycle()
107
-
108
- const [, second] = storage.outbox.pending.mock.calls
109
-
110
- assert.strictEqual(storage.outbox.pending.mock.calls[0].arguments[3], undefined)
111
- assert.deepStrictEqual(second.arguments[3], String(BATCH - 1).padStart(4, '0'))
112
- })
113
-
114
- it('should mark what it published, once, after the last page', async () => {
115
- storage.outbox.pending.mock.mockImplementationOnce(
116
- async () => page(0, BATCH),
117
- storage.outbox.pending.mock.callCount()
118
- )
119
- storage.outbox.pending.mock.mockImplementationOnce(
120
- async () => page(BATCH, 2),
121
- storage.outbox.pending.mock.callCount() + 1
122
- )
123
-
124
- await outbox.open()
125
- await cycle()
126
-
127
- assert.strictEqual(storage.outbox.settle.mock.callCount(), 1)
128
- assert.strictEqual(storage.outbox.settle.mock.calls[0].arguments[0].length, BATCH + 2)
129
- })
130
-
131
- it('should not publish a row it has published and not yet marked', async () => {
132
- storage.outbox.settle.mock.mockImplementationOnce(async () => {
133
- throw new Error('mongo is out')
134
- })
135
- storage.outbox.pending.mock.mockImplementationOnce(
136
- async () => page(0, 2),
137
- storage.outbox.pending.mock.callCount()
138
- )
139
- storage.outbox.pending.mock.mockImplementationOnce(
140
- async () => page(0, 2),
141
- storage.outbox.pending.mock.callCount() + 1
142
- )
143
-
144
- await outbox.open()
145
- await cycle()
146
- await cycle()
147
-
148
- assert.strictEqual(emission.emit.mock.callCount(), 2)
149
- })
150
-
151
- it('should read nothing while it owns no slots', async () => {
152
- atom.slots.mock.mockImplementation(() => null)
153
-
154
- await outbox.open()
155
- await cycle()
156
-
157
- assert.strictEqual(storage.outbox.pending.mock.callCount(), 0)
158
- })
159
-
160
- function resetCalls(target = [assert, BATCH, page, cycle], seen = new Set()) {
161
- if (target === null || typeof target !== 'object' || seen.has(target)) return
162
-
163
- seen.add(target)
164
-
165
- for (const value of Object.values(target))
166
- if (typeof value === 'function' && value.mock !== undefined) value.mock.resetCalls()
167
- else resetCalls(value, seen)
168
- }
169
-
170
- it('should read as soon as a claim arrives, rather than on its next cycle', async () => {
171
- atom.slots.mock.mockImplementation(() => null)
172
-
173
- await outbox.open()
174
- await settled()
175
-
176
- assert.strictEqual(storage.outbox.pending.mock.callCount(), 0, 'nothing is owned yet')
177
-
178
- atom.slots.mock.mockImplementation(() => [0])
179
-
180
- for (const listener of listeners) listener({ i: 0, n: 1 })
181
-
182
- await settled()
183
-
184
- assert.strictEqual(
185
- storage.outbox.pending.mock.callCount(),
186
- 1,
187
- 'the lane is its own now, and the cycle is up to five seconds away'
188
- )
189
- })
190
-
191
- it('should read the lanes it inherits when the group resizes', async () => {
192
- await outbox.open()
193
- await settled()
194
-
195
- const before = storage.outbox.pending.mock.callCount()
196
-
197
- for (const listener of listeners) listener({ i: 0, n: 2 })
198
-
199
- await settled()
200
-
201
- assert.strictEqual(storage.outbox.pending.mock.callCount(), before + 1)
202
- })
@@ -1,96 +0,0 @@
1
- export const samples = {
2
- simple: {
3
- query: {
4
- criteria: 'name==Eddie'
5
- },
6
- parsed: {
7
- criteria: {
8
- type: 'COMPARISON',
9
- left: { type: 'SELECTOR', selector: 'name' },
10
- operator: '==',
11
- right: { type: 'VALUE', value: 'Eddie' }
12
- }
13
- },
14
- properties: {
15
- name: {
16
- type: 'string'
17
- }
18
- }
19
- },
20
-
21
- extended: {
22
- query: {
23
- criteria: 'flag==true;volume>2.1'
24
- },
25
- parsed: {
26
- criteria: {
27
- type: 'LOGIC',
28
- left: {
29
- type: 'COMPARISON',
30
- left: { type: 'SELECTOR', selector: 'flag' },
31
- operator: '==',
32
- right: { type: 'VALUE', value: true }
33
- },
34
- operator: ';',
35
- right: {
36
- type: 'COMPARISON',
37
- left: { type: 'SELECTOR', selector: 'volume' },
38
- operator: '>',
39
- right: { type: 'VALUE', value: 2.1 }
40
- }
41
- }
42
- },
43
- properties: {
44
- flag: {
45
- type: 'boolean'
46
- },
47
- volume: {
48
- type: 'number'
49
- }
50
- }
51
- },
52
-
53
- abc: {
54
- properties: {
55
- a: {
56
- type: 'string'
57
- },
58
- b: {
59
- type: 'string'
60
- },
61
- c: {
62
- type: 'string'
63
- }
64
- }
65
- },
66
-
67
- id: {
68
- properties: {
69
- id: {
70
- type: 'string'
71
- },
72
- name: {
73
- type: 'string'
74
- }
75
- },
76
- query: {
77
- id: '123',
78
- criteria: 'name==Eddie'
79
- },
80
- parsed: {
81
- id: '123',
82
- criteria: {
83
- type: 'COMPARISON',
84
- left: {
85
- type: 'SELECTOR',
86
- selector: 'name'
87
- },
88
- operator: '==',
89
- right: {
90
- type: 'VALUE',
91
- value: 'Eddie'
92
- }
93
- }
94
- }
95
- }
96
- }
@@ -1,183 +0,0 @@
1
- import { describe, it, beforeEach } from 'node:test'
2
- import assert from 'node:assert/strict'
3
-
4
- import { Query } from '../source/query.js'
5
- import * as fixtures from './query.fixtures.js'
6
-
7
- beforeEach(() => {
8
- resetCalls()
9
- })
10
-
11
- describe('criteria', () => {
12
- it('should not throw if no criteria', () => {
13
- const instance = new Query(fixtures.samples.simple.properties)
14
- const query = instance.parse({})
15
-
16
- assert.strictEqual(query.criteria, undefined)
17
- })
18
-
19
- it('should parse criteria', () => {
20
- const instance = new Query(fixtures.samples.simple.properties)
21
- const query = instance.parse(fixtures.samples.simple.query)
22
-
23
- assert.deepStrictEqual(query.criteria, fixtures.samples.simple.parsed.criteria)
24
- })
25
-
26
- it('should coerce every value of a list', () => {
27
- const instance = new Query({ n: { type: 'integer' } })
28
- const query = instance.parse({ criteria: 'n=in=(1,2,3)' })
29
-
30
- assert.deepStrictEqual(query.criteria.right.value, [1, 2, 3])
31
- })
32
-
33
- it('should keep a parsed criteria', () => {
34
- const instance = new Query(fixtures.samples.simple.properties)
35
-
36
- const first = instance.parse(fixtures.samples.simple.query).criteria
37
- const second = instance.parse(fixtures.samples.simple.query).criteria
38
-
39
- assert.strictEqual(second, first)
40
- })
41
-
42
- it('should not keep an invalid criteria', () => {
43
- const instance = new Query(fixtures.samples.simple.properties)
44
- const query = { criteria: 'nonexistent==1' }
45
-
46
- assert.throws(() => instance.parse(query))
47
- assert.throws(() => instance.parse(query))
48
- })
49
-
50
- it('should parse criteria with type coercion', () => {
51
- const instance = new Query(fixtures.samples.extended.properties)
52
- const query = instance.parse(fixtures.samples.extended.query)
53
-
54
- assert.deepStrictEqual(query.criteria, fixtures.samples.extended.parsed.criteria)
55
- })
56
-
57
- it('should refuse a value the property cannot hold', () => {
58
- const strict = new Query({
59
- volume: { type: 'number' },
60
- count: { type: 'integer' },
61
- booked: { type: 'boolean' }
62
- })
63
-
64
- const refused = [
65
- ['volume>abc', /takes a number/],
66
- ['volume==1.5kg', /takes a number/],
67
- ['count==1.5', /takes an integer/],
68
- ['count==12kg', /takes an integer/],
69
- ['booked==yes', /takes a boolean/],
70
- ['booked==TRUE', /takes a boolean/],
71
- ['volume=in=(1,two)', /'two' is not one/]
72
- ]
73
-
74
- for (const [criteria, message] of refused)
75
- assert.throws(
76
- () => strict.parse({ criteria }),
77
- (error) => message.test(error.message),
78
- criteria
79
- )
80
- })
81
-
82
- it('should read a value the property can hold', () => {
83
- const strict = new Query({
84
- volume: { type: 'number' },
85
- count: { type: 'integer' },
86
- booked: { type: 'boolean' },
87
- title: { type: 'string' }
88
- })
89
-
90
- const read = [
91
- ['volume>1.5', 1.5],
92
- ['volume>-1.5', -1.5],
93
- ['count==12', 12],
94
- ['booked==false', false],
95
- ['title==12kg', '12kg']
96
- ]
97
-
98
- for (const [criteria, value] of read)
99
- assert.deepStrictEqual(
100
- strict.parse({ criteria }).criteria.right.value,
101
- value,
102
- criteria
103
- )
104
- })
105
-
106
- it('should throw on unknown properties', () => {
107
- const instance = new Query(fixtures.samples.simple.properties)
108
-
109
- assert.throws(
110
- () => instance.parse({ criteria: 'lastname==Johnson' }),
111
- (error) => /not defined/.test(error.message)
112
- )
113
- })
114
-
115
- it('should parse id', () => {
116
- const instance = new Query(fixtures.samples.id.properties)
117
- const query = instance.parse({ ...fixtures.samples.id.query })
118
-
119
- assert.deepStrictEqual(query, fixtures.samples.id.parsed)
120
- })
121
- })
122
-
123
- describe('options', () => {
124
- const instance = new Query(fixtures.samples.abc.properties)
125
-
126
- it('should not throw if no options', () => {
127
- const query = instance.parse({})
128
-
129
- assert.strictEqual(query.options, undefined)
130
- })
131
-
132
- describe('omit, limit', () => {
133
- it('should pass', () => {
134
- const input = { omit: 1, limit: 1 }
135
- const query = instance.parse(input)
136
-
137
- assert.deepStrictEqual(query.options, input)
138
- })
139
- })
140
-
141
- describe('sort', () => {
142
- it('should set default values', () => {
143
- const sort = ['a', 'b:desc', 'c']
144
- const query = instance.parse({ sort })
145
-
146
- assert.deepStrictEqual(query.options.sort, [
147
- ['a', 'asc'],
148
- ['b', 'desc'],
149
- ['c', 'asc']
150
- ])
151
- })
152
-
153
- it('should throw on unknown properties', () => {
154
- const sort = ['d:asc']
155
-
156
- assert.throws(
157
- () => instance.parse({ sort }),
158
- (error) => /not defined/.test(error.message)
159
- )
160
- })
161
- })
162
-
163
- describe('projection', () => {
164
- it('should throw on unknown properties', () => {
165
- const projection = ['a', 'b', 'c', 'd']
166
-
167
- assert.throws(
168
- () => instance.parse({ projection }),
169
- (error) => /not defined/.test(error.message)
170
- )
171
- })
172
- })
173
- })
174
-
175
- function resetCalls(target = [assert, fixtures], seen = new Set()) {
176
- if (target === null || typeof target !== 'object' || seen.has(target)) return
177
-
178
- seen.add(target)
179
-
180
- for (const value of Object.values(target))
181
- if (typeof value === 'function' && value.mock !== undefined) value.mock.resetCalls()
182
- else resetCalls(value, seen)
183
- }
@@ -1,20 +0,0 @@
1
- import { mock } from 'node:test'
2
-
3
- import { generate } from 'randomstring'
4
-
5
- export const definition = /** @type {toa.norm.component.Receiver} */ {
6
- operation: generate(),
7
- conditioned: false,
8
- adaptive: false
9
- }
10
-
11
- export const local = /** @type {import('@toa.io/core').Component} */ {
12
- locator: { id: 'default.dummy' },
13
- invoke: mock.fn()
14
- }
15
-
16
- // noinspection JSCheckFunctionSignatures
17
- export const bridge = /** @type {import('@toa.io/core/types').bridges.Event} */ {
18
- condition: mock.fn(async (payload) => !(payload.reject === true)),
19
- request: mock.fn(async () => ({ input: generate() }))
20
- }
@@ -1,144 +0,0 @@
1
- import { describe, it, beforeEach, mock } from 'node:test'
2
- import assert from 'node:assert/strict'
3
- import { isDeepStrictEqual } from 'node:util'
4
-
5
- import clone from 'clone-deep'
6
- import { generate } from 'randomstring'
7
- import { merge } from '@toa.io/generic'
8
-
9
- import { Connector } from '../source/connector.js'
10
-
11
- // the fixtures are not connectors, so a dependency is recorded rather than linked
12
- const depends = mock.method(Connector.prototype, 'depends', () => undefined)
13
-
14
- const dependencies = (instance) =>
15
- depends.mock.calls
16
- .filter((call) => call.this === instance)
17
- .map((call) => call.arguments[0])
18
-
19
- import { Receiver } from '../source/receiver.js'
20
- import * as fixtures from './receiver.fixtures.js'
21
-
22
- /** @type {import('@toa.io/core/types').Receiver} */
23
- let receiver
24
-
25
- /** @type {toa.norm.component.Receiver} */
26
- let definition
27
-
28
- beforeEach(() => {
29
- resetCalls()
30
- depends.mock.resetCalls()
31
-
32
- definition = clone(fixtures.definition)
33
- receiver = new Receiver(fixtures.definition, fixtures.local, fixtures.bridge)
34
- })
35
-
36
- it('should depend on local, bridge', () => {
37
- assert.ok(dependencies(receiver).some((one) => isDeepStrictEqual(one, fixtures.local)))
38
- assert.ok(dependencies(receiver).some((one) => isDeepStrictEqual(one, fixtures.bridge)))
39
- })
40
-
41
- it('should apply', async () => {
42
- const payload = { foo: 'bar' }
43
-
44
- await receiver.receive({ payload })
45
-
46
- assert.ok(
47
- fixtures.local.invoke.mock.calls.some(
48
- (call) =>
49
- call.arguments.length === 2 &&
50
- isDeepStrictEqual(call.arguments[0], definition.operation) &&
51
- isDeepStrictEqual(call.arguments[1], { input: payload })
52
- )
53
- )
54
- })
55
-
56
- for (const [adaptive] of [[false], [true]])
57
- it(`should pass UI extensions (adaptive: ${adaptive})`, async () => {
58
- resetCalls()
59
-
60
- definition.adaptive = adaptive
61
- receiver = new Receiver(definition, fixtures.local, fixtures.bridge)
62
-
63
- const payload = { foo: generate() }
64
- const extension = { [generate()]: generate() }
65
- const message = { payload, ...extension }
66
-
67
- await receiver.receive(message)
68
-
69
- const request = adaptive
70
- ? await fixtures.bridge.request.mock.calls[0].result
71
- : { input: payload }
72
- const expected = merge(clone(request), extension)
73
-
74
- const argument = fixtures.local.invoke.mock.calls[0].arguments[1]
75
-
76
- assert.deepStrictEqual(argument, expected)
77
- })
78
-
79
- describe('conditioned', () => {
80
- beforeEach(() => {
81
- definition.conditioned = true
82
- receiver = new Receiver(definition, fixtures.local, fixtures.bridge)
83
- })
84
-
85
- it('should test condition', async () => {
86
- const payload = { foo: 'bar' }
87
- await receiver.receive({ payload })
88
-
89
- assert.ok(
90
- fixtures.bridge.condition.mock.calls.some(
91
- (call) =>
92
- call.arguments.length === 1 && isDeepStrictEqual(call.arguments[0], payload)
93
- )
94
- )
95
- assert.ok(
96
- fixtures.local.invoke.mock.calls.some(
97
- (call) =>
98
- call.arguments.length === 2 &&
99
- isDeepStrictEqual(call.arguments[0], definition.operation) &&
100
- isDeepStrictEqual(call.arguments[1], { input: payload })
101
- )
102
- )
103
- })
104
-
105
- it('should not apply if condition is false', async () => {
106
- const payload = { reject: true }
107
- await receiver.receive({ payload })
108
-
109
- assert.strictEqual(fixtures.local.invoke.mock.callCount(), 0)
110
- })
111
- })
112
-
113
- describe('adaptive', () => {
114
- beforeEach(() => {
115
- definition.adaptive = true
116
- receiver = new Receiver(definition, fixtures.local, fixtures.bridge)
117
- })
118
-
119
- it('should apply', async () => {
120
- const payload = { reject: true }
121
- await receiver.receive({ payload })
122
-
123
- const request = await fixtures.bridge.request.mock.calls[0].result
124
-
125
- assert.ok(
126
- fixtures.local.invoke.mock.calls.some(
127
- (call) =>
128
- call.arguments.length === 2 &&
129
- isDeepStrictEqual(call.arguments[0], definition.operation) &&
130
- isDeepStrictEqual(call.arguments[1], request)
131
- )
132
- )
133
- })
134
- })
135
-
136
- function resetCalls(target = [assert, clone, fixtures], seen = new Set()) {
137
- if (target === null || typeof target !== 'object' || seen.has(target)) return
138
-
139
- seen.add(target)
140
-
141
- for (const value of Object.values(target))
142
- if (typeof value === 'function' && value.mock !== undefined) value.mock.resetCalls()
143
- else resetCalls(value, seen)
144
- }
@@ -1,31 +0,0 @@
1
- import { it, beforeEach } from 'node:test'
2
- import assert from 'node:assert/strict'
3
-
4
- import { generate } from 'randomstring'
5
- import { Reflection, Connector } from '../source/index.js'
6
-
7
- it('should export', () => {
8
- assert.notStrictEqual(Reflection, undefined)
9
- })
10
-
11
- /** @type {import('@toa.io/core').Reflection<string>} */
12
- let reflection
13
-
14
- const value = generate()
15
-
16
- /** @type {import('@toa.io/core').ReflectionSource<string>} */
17
- const source = async () => value
18
-
19
- beforeEach(() => {
20
- reflection = new Reflection(source)
21
- })
22
-
23
- it('should be a Connector', () => {
24
- assert.ok(reflection instanceof Connector)
25
- })
26
-
27
- it('should reflect', async () => {
28
- await reflection.connect()
29
-
30
- assert.deepStrictEqual(reflection.value, value)
31
- })