@toa.io/core 1.0.0-alpha.273 → 1.0.0-alpha.277

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 (93) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/package.json +8 -7
  3. package/src/assignment.js +2 -6
  4. package/src/call.js +5 -7
  5. package/src/cascade.js +2 -6
  6. package/src/component.js +4 -8
  7. package/src/composition.js +3 -7
  8. package/src/connector.js +2 -6
  9. package/src/context.js +2 -6
  10. package/src/contract/contract.js +2 -6
  11. package/src/contract/index.js +2 -7
  12. package/src/contract/reply.js +4 -8
  13. package/src/contract/request.js +4 -8
  14. package/src/contract/schemas/index.js +7 -9
  15. package/src/discovery.js +3 -7
  16. package/src/effect.js +2 -6
  17. package/src/emission.js +2 -6
  18. package/src/entities/changeset.js +2 -6
  19. package/src/entities/entity.js +3 -7
  20. package/src/entities/factory.js +5 -9
  21. package/src/entities/index.js +1 -5
  22. package/src/entities/newid.js +2 -4
  23. package/src/entities/set.js +2 -6
  24. package/src/event.js +3 -7
  25. package/src/exceptions.js +37 -30
  26. package/src/exposition.js +2 -6
  27. package/src/guard.js +1 -5
  28. package/src/index.js +28 -55
  29. package/src/locator.js +2 -6
  30. package/src/observation.js +2 -6
  31. package/src/operation.js +4 -8
  32. package/src/outbox/index.js +1 -6
  33. package/src/outbox/outbox.js +5 -10
  34. package/src/query/criteria.js +3 -7
  35. package/src/query/options.js +2 -6
  36. package/src/query.js +5 -6
  37. package/src/receiver.js +4 -8
  38. package/src/reflection.js +2 -6
  39. package/src/remote.js +3 -7
  40. package/src/state.js +2 -6
  41. package/src/transition.js +4 -8
  42. package/src/transmission.js +3 -7
  43. package/src/unmanaged.js +2 -6
  44. package/test/call.fixtures.js +8 -12
  45. package/test/call.test.js +21 -9
  46. package/test/component.fixtures.js +5 -8
  47. package/test/component.test.js +22 -11
  48. package/test/connector.fixtures.js +5 -11
  49. package/test/connector.test.js +42 -41
  50. package/test/context.fixtures.js +8 -12
  51. package/test/context.test.js +18 -7
  52. package/test/contract/conditions.test.js +8 -6
  53. package/test/contract/contract.fixtures.js +12 -17
  54. package/test/contract/request.test.js +51 -40
  55. package/test/discovery.test.js +25 -17
  56. package/test/emission.fixtures.js +5 -8
  57. package/test/emission.test.js +29 -12
  58. package/test/entities/entity.fixtures.js +7 -11
  59. package/test/entities/entity.test.js +30 -19
  60. package/test/entities/factory.fixtures.js +22 -10
  61. package/test/entities/factory.test.js +29 -17
  62. package/test/entities/set.fixtures.js +6 -8
  63. package/test/entities/set.test.js +6 -5
  64. package/test/event.fixtures.js +9 -14
  65. package/test/event.test.js +57 -31
  66. package/test/locator.test.js +25 -24
  67. package/test/outbox.test.js +44 -37
  68. package/test/query.fixtures.js +1 -5
  69. package/test/query.test.js +28 -17
  70. package/test/receiver.fixtures.js +8 -12
  71. package/test/receiver.test.js +45 -22
  72. package/test/reflection.test.js +7 -6
  73. package/test/state.fixtures.js +24 -32
  74. package/test/state.test.js +35 -30
  75. package/test/transmission.fixtures.js +4 -6
  76. package/test/transmission.test.js +33 -15
  77. package/types/atomicity.d.ts +1 -1
  78. package/types/bindings.d.ts +1 -1
  79. package/types/bridges.ts +3 -3
  80. package/types/component.d.ts +4 -4
  81. package/types/context.d.ts +4 -4
  82. package/types/entity.d.ts +2 -2
  83. package/types/event.d.ts +1 -1
  84. package/types/extensions.d.ts +8 -7
  85. package/types/index.ts +16 -16
  86. package/types/operations.d.ts +1 -1
  87. package/types/outbox.d.ts +2 -2
  88. package/types/receiver.d.ts +2 -2
  89. package/types/reflection.d.ts +1 -1
  90. package/types/remote.d.ts +1 -1
  91. package/types/request.d.ts +1 -1
  92. package/types/state.d.ts +2 -2
  93. package/types/storages.d.ts +3 -3
@@ -1,8 +1,9 @@
1
- 'use strict'
1
+ import { describe, it, beforeEach } from 'node:test'
2
+ import assert from 'node:assert/strict'
2
3
 
3
- const { timeout } = require('@toa.io/generic')
4
+ import { timeout } from '@toa.io/generic'
4
5
 
5
- const fixtures = require('./connector.fixtures')
6
+ import * as fixtures from './connector.fixtures.js'
6
7
 
7
8
  let sequence
8
9
 
@@ -19,14 +20,14 @@ describe('callbacks', () => {
19
20
 
20
21
  it('should call connection', async () => {
21
22
  await a.connect()
22
- expect(sequence).toEqual(['+a'])
23
+ assert.deepStrictEqual(sequence, ['+a'])
23
24
  })
24
25
 
25
26
  it('should call disconnection', async () => {
26
27
  await a.connect()
27
28
  await a.disconnect()
28
29
 
29
- expect(sequence.indexOf('+a')).toBeLessThan(sequence.indexOf('-a'))
30
+ assert.ok(sequence.indexOf('+a') < sequence.indexOf('-a'))
30
31
  })
31
32
 
32
33
  it('should reconnect', async () => {
@@ -34,7 +35,7 @@ describe('callbacks', () => {
34
35
  await a.reconnect()
35
36
  await a.reconnect()
36
37
 
37
- expect(sequence).toEqual(['+a', '-a', '*a', '+a', '-a', '*a', '+a'])
38
+ assert.deepStrictEqual(sequence, ['+a', '-a', '*a', '+a', '-a', '*a', '+a'])
38
39
  })
39
40
  })
40
41
 
@@ -57,9 +58,9 @@ describe('dependencies', () => {
57
58
 
58
59
  await a.connect()
59
60
 
60
- expect(sequence.indexOf('+c')).toBeLessThan(sequence.indexOf('+b'))
61
- expect(sequence.indexOf('+b')).toBeLessThan(sequence.indexOf('+a'))
62
- expect(sequence.indexOf('+d')).toBeLessThan(sequence.indexOf('+a'))
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'))
63
64
  })
64
65
 
65
66
  it('should wait array of connectors', async () => {
@@ -69,10 +70,10 @@ describe('dependencies', () => {
69
70
 
70
71
  await a.connect()
71
72
 
72
- expect(sequence.indexOf('+c')).toBeLessThan(sequence.indexOf('+b'))
73
- expect(sequence.indexOf('+c')).toBeLessThan(sequence.indexOf('+d'))
74
- expect(sequence.indexOf('+b')).toBeLessThan(sequence.indexOf('+a'))
75
- expect(sequence.indexOf('+d')).toBeLessThan(sequence.indexOf('+a'))
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'))
76
77
  })
77
78
 
78
79
  it('should wait array(1) of connectors', async () => {
@@ -81,12 +82,12 @@ describe('dependencies', () => {
81
82
 
82
83
  await a.connect()
83
84
 
84
- expect(sequence.indexOf('+c')).toBeLessThan(sequence.indexOf('+b'))
85
- expect(sequence.indexOf('+b')).toBeLessThan(sequence.indexOf('+a'))
85
+ assert.ok(sequence.indexOf('+c') < sequence.indexOf('+b'))
86
+ assert.ok(sequence.indexOf('+b') < sequence.indexOf('+a'))
86
87
  })
87
88
 
88
89
  it('should throw on empty array', async () => {
89
- expect(() => a.depends([])).toThrow(/must not be empty/)
90
+ assert.throws(() => a.depends([]), (error) => /must not be empty/.test(error.message))
90
91
  })
91
92
 
92
93
  it('should await 2-way dependencies', async () => {
@@ -95,12 +96,12 @@ describe('dependencies', () => {
95
96
 
96
97
  await a.connect()
97
98
 
98
- expect(sequence.indexOf('+b')).toBeLessThan(sequence.indexOf('+a'))
99
- expect(sequence.indexOf('+c')).toBeLessThan(sequence.indexOf('+a'))
100
- expect(sequence.indexOf('+d')).toBeLessThan(sequence.indexOf('+a'))
99
+ assert.ok(sequence.indexOf('+b') < sequence.indexOf('+a'))
100
+ assert.ok(sequence.indexOf('+c') < sequence.indexOf('+a'))
101
+ assert.ok(sequence.indexOf('+d') < sequence.indexOf('+a'))
101
102
 
102
- expect(sequence.indexOf('+b')).toBeLessThan(sequence.indexOf('+d'))
103
- expect(sequence.indexOf('+c')).toBeLessThan(sequence.indexOf('+d'))
103
+ assert.ok(sequence.indexOf('+b') < sequence.indexOf('+d'))
104
+ assert.ok(sequence.indexOf('+c') < sequence.indexOf('+d'))
104
105
  })
105
106
 
106
107
  it('should disconnect before dependencies', async () => {
@@ -110,9 +111,9 @@ describe('dependencies', () => {
110
111
  await a.connect()
111
112
  await a.disconnect()
112
113
 
113
- expect(sequence.indexOf('-a')).toBeLessThan(sequence.indexOf('-b'))
114
- expect(sequence.indexOf('-b')).toBeLessThan(sequence.indexOf('-c'))
115
- expect(sequence.indexOf('-b')).toBeLessThan(sequence.indexOf('-d'))
114
+ assert.ok(sequence.indexOf('-a') < sequence.indexOf('-b'))
115
+ assert.ok(sequence.indexOf('-b') < sequence.indexOf('-c'))
116
+ assert.ok(sequence.indexOf('-b') < sequence.indexOf('-d'))
116
117
  })
117
118
 
118
119
  it('should call disconnected', async () => {
@@ -121,10 +122,10 @@ describe('dependencies', () => {
121
122
 
122
123
  await a.disconnect()
123
124
 
124
- expect(sequence.indexOf('*c')).toBeLessThan(sequence.indexOf('*b'))
125
- expect(sequence.indexOf('*b')).toBeLessThan(sequence.indexOf('*a'))
126
- expect(sequence.indexOf('*d')).toBeLessThan(sequence.indexOf('*b'))
127
- expect(sequence.indexOf('*a')).toBe(sequence.length - 1)
125
+ assert.ok(sequence.indexOf('*c') < sequence.indexOf('*b'))
126
+ assert.ok(sequence.indexOf('*b') < sequence.indexOf('*a'))
127
+ assert.ok(sequence.indexOf('*d') < sequence.indexOf('*b'))
128
+ assert.strictEqual(sequence.indexOf('*a'), sequence.length - 1)
128
129
  })
129
130
 
130
131
  it('should disconnect if no parents left', async () => {
@@ -134,19 +135,19 @@ describe('dependencies', () => {
134
135
  await a.connect()
135
136
  await b.connect()
136
137
 
137
- expect(sequence).toEqual(['+c', '+a', '+b'])
138
+ assert.deepStrictEqual(sequence, ['+c', '+a', '+b'])
138
139
 
139
140
  await a.disconnect()
140
141
 
141
- expect(sequence).toEqual(['+c', '+a', '+b', '-a', '*a'])
142
+ assert.deepStrictEqual(sequence, ['+c', '+a', '+b', '-a', '*a'])
142
143
 
143
144
  await b.disconnect()
144
145
 
145
- expect(sequence).toEqual(['+c', '+a', '+b', '-a', '*a', '-b', '-c', '*c', '*b'])
146
+ assert.deepStrictEqual(sequence, ['+c', '+a', '+b', '-a', '*a', '-b', '-c', '*c', '*b'])
146
147
  })
147
148
 
148
149
  it('should throw if depends not on Connector', async () => {
149
- expect(() => a.depends({})).toThrow()
150
+ assert.throws(() => a.depends({}))
150
151
  })
151
152
 
152
153
  it('should disconnect while still connecting', async () => {
@@ -159,11 +160,11 @@ describe('dependencies', () => {
159
160
  while (b.connected !== true) await timeout(1)
160
161
 
161
162
  // `a` never connects, and disconnecting must not wait for it to
162
- expect(a.connected).toStrictEqual(false)
163
+ assert.deepStrictEqual(a.connected, false)
163
164
 
164
165
  await a.disconnect()
165
166
 
166
- expect(sequence).toEqual(['+b', '-b', '*b', '*a'])
167
+ assert.deepStrictEqual(sequence, ['+b', '-b', '*b', '*a'])
167
168
  })
168
169
 
169
170
  describe('errors', () => {
@@ -176,21 +177,21 @@ describe('dependencies', () => {
176
177
  it('should disconnect on fail', async () => {
177
178
  f.depends(b).depends(c)
178
179
 
179
- await expect(f.connect()).rejects.toThrow('FailingConnector')
180
- expect(sequence).toEqual(['+c', '+b', '-b', '-c', '*c', '*b'])
180
+ await assert.rejects(f.connect(), (error) => /FailingConnector/.test(error.message))
181
+ assert.deepStrictEqual(sequence, ['+c', '+b', '-b', '-c', '*c', '*b'])
181
182
  })
182
183
 
183
184
  it('should interrupt connection chain', async () => {
184
185
  a.depends(f).depends(c)
185
186
  f.depends(d)
186
187
 
187
- await expect(a.connect()).rejects.toThrow('FailingConnector')
188
+ await assert.rejects(a.connect(), (error) => /FailingConnector/.test(error.message))
188
189
 
189
- expect(sequence.indexOf('+c')).toBeLessThan(sequence.indexOf('-c'))
190
- expect(sequence.indexOf('+d')).toBeLessThan(sequence.indexOf('-d'))
190
+ assert.ok(sequence.indexOf('+c') < sequence.indexOf('-c'))
191
+ assert.ok(sequence.indexOf('+d') < sequence.indexOf('-d'))
191
192
 
192
- expect(sequence.indexOf('+a')).toBe(-1)
193
- expect(sequence.indexOf('-a')).toBe(-1)
193
+ assert.strictEqual(sequence.indexOf('+a'), -1)
194
+ assert.strictEqual(sequence.indexOf('-a'), -1)
194
195
  })
195
196
  })
196
197
  })
@@ -1,18 +1,14 @@
1
- 'use strict'
1
+ import { mock } from 'node:test'
2
2
 
3
- const { Connector } = require('../src/connector')
3
+ import { Connector } from '../src/connector.js'
4
4
 
5
- const local = {
6
- link: jest.fn()
5
+ export const local = {
6
+ link: mock.fn()
7
7
  }
8
8
 
9
- const discover = jest.fn(() => ({
10
- invoke: jest.fn(),
11
- link: jest.fn()
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()]
@@ -1,20 +1,21 @@
1
- 'use strict'
1
+ import { describe, it, beforeEach, mock } from 'node:test'
2
+ import assert from 'node:assert/strict'
2
3
 
3
- const fixtures = require('./context.fixtures')
4
- const { Context } = require('../src/context')
4
+ import * as fixtures from './context.fixtures.js'
5
+ import { Context } from '../src/context.js'
5
6
 
6
7
  /** @type {toa.core.Context} */
7
8
  let context
8
9
 
9
10
  beforeEach(() => {
10
- jest.clearAllMocks()
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
- expect(context.aspects).toBeDefined()
17
- expect(context.aspects).toStrictEqual(fixtures.aspects)
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
- expect(fixtures.discover).toHaveBeenCalledTimes(1)
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,9 +1,11 @@
1
- 'use strict'
1
+ import { it, beforeEach } from 'node:test'
2
+ import assert from 'node:assert/strict'
3
+ import { isDeepStrictEqual } from 'node:util'
2
4
 
3
- const { generate } = require('randomstring')
5
+ import { generate } from 'randomstring'
4
6
 
5
- const { Contract } = require('../../src/contract/contract')
6
- const fixtures = require('./contract.fixtures')
7
+ import { Contract } from '../../src/contract/contract.js'
8
+ import * as fixtures from './contract.fixtures.js'
7
9
 
8
10
  let contract
9
11
 
@@ -16,11 +18,11 @@ it('should fit value', () => {
16
18
 
17
19
  contract.fit(value)
18
20
 
19
- expect(fixtures.schema.fit).toHaveBeenCalledWith(value)
21
+ assert.ok(fixtures.schema.fit.mock.calls.some((call) => call.arguments.length === 1 && isDeepStrictEqual(call.arguments[0], value)))
20
22
  })
21
23
 
22
24
  it('should throw on invalid value', () => {
23
25
  const value = { invalid: true }
24
26
 
25
- expect(() => contract.fit(value)).toThrow()
27
+ assert.throws(() => contract.fit(value))
26
28
  })
@@ -1,34 +1,29 @@
1
- 'use strict'
1
+ import { mock } from 'node:test'
2
2
 
3
- const { generate } = require('randomstring')
4
- const { readFileSync } = require('node:fs')
5
- const { load: parseYAML } = require('js-yaml')
6
- const { resolve } = require('path')
3
+ import { generate } from 'randomstring'
4
+ import { readFileSync } from 'node:fs'
5
+ import { load as parseYAML } from 'js-yaml'
6
+ import { resolve } from 'path'
7
7
 
8
8
  // noinspection JSCheckFunctionSignatures
9
- const schema = {
10
- fit: jest.fn((input) => (input.invalid ? { message: generate() } : null))
9
+ export const schema = {
10
+ fit: mock.fn((input) => (input.invalid ? { message: generate() } : null))
11
11
  }
12
12
 
13
- const query = {
14
- parse: jest.fn(() => ({ [generate()]: generate() }))
13
+ export const query = {
14
+ parse: mock.fn(() => ({ [generate()]: generate() }))
15
15
  }
16
16
 
17
- const declaration = {}
17
+ export const declaration = {}
18
18
 
19
- const schemas = {
19
+ export const schemas = {
20
20
  request: {
21
21
  type: 'object',
22
22
  properties: {
23
23
  input: { type: 'null' },
24
- query: parseYAML(readFileSync(resolve(__dirname, '../../src/contract/schemas/query.yaml'), 'utf8')),
24
+ query: parseYAML(readFileSync(resolve(import.meta.dirname, '../../src/contract/schemas/query.yaml'), 'utf8')),
25
25
  authentic: { type: 'boolean' }
26
26
  },
27
27
  additionalProperties: true
28
28
  }
29
29
  }
30
-
31
- exports.schema = schema
32
- exports.query = query
33
- exports.declaration = declaration
34
- exports.schemas = schemas
@@ -1,18 +1,23 @@
1
- 'use strict'
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
- const clone = require('clone-deep')
4
- const { generate } = require('randomstring')
6
+ import clone from 'clone-deep'
7
+ import { generate } from 'randomstring'
5
8
 
6
- jest.mock('../../src/contract/contract')
9
+ import { Request } from '../../src/contract/request.js'
10
+ import { Contract } from '../../src/contract/contract.js'
11
+ import * as fixtures from './contract.fixtures.js'
7
12
 
8
- const { Request } = require('../../src/contract/request')
9
- const { Contract } = require('../../src/contract/contract')
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
- jest.clearAllMocks()
19
+ resetCalls()
20
+ fit.mock.resetCalls()
16
21
 
17
22
  contract = new Request(fixtures.schema, {})
18
23
  })
@@ -20,8 +25,8 @@ beforeEach(() => {
20
25
  const dummy = { schema: { properties: {} } }
21
26
 
22
27
  it('should extend Conditions', () => {
23
- expect(contract).toBeInstanceOf(Contract)
24
- expect(Contract).toHaveBeenCalledWith(fixtures.schema)
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,8 @@ it('should fit request', () => {
29
34
 
30
35
  contract.fit(request)
31
36
 
32
- expect(Contract.mock.instances[0].fit).toHaveBeenCalledWith(request)
37
+ assert.ok(fit.mock.calls.some((call) =>
38
+ call.this === contract && isDeepStrictEqual(call.arguments[0], request)))
33
39
  })
34
40
 
35
41
  describe('schema', () => {
@@ -40,79 +46,74 @@ describe('schema', () => {
40
46
  })
41
47
 
42
48
  it('should provide schema', () => {
43
- expect(Request.schema({}, dummy)).toBeDefined()
49
+ assert.notStrictEqual(Request.schema({}, dummy), undefined)
44
50
  })
45
51
 
46
52
  it('should add required input if defined', () => {
47
53
  const input = { type: 'number' }
48
54
 
49
- expect(Request.schema({ input }, dummy).properties.input).toStrictEqual(input)
55
+ assert.deepStrictEqual(Request.schema({ input }, dummy).properties.input, input)
50
56
  })
51
57
 
52
58
  it('should set input as null if undefined', async () => {
53
- expect(Request.schema({}, dummy).properties.input).toStrictEqual({ type: 'null' })
59
+ assert.deepStrictEqual(Request.schema({}, dummy).properties.input, { type: 'null' })
54
60
  })
55
61
 
56
62
  it('should contain query if declaration.query is not defined', () => {
57
- expect(Request.schema({}, dummy).properties.query).toBeDefined()
63
+ assert.notStrictEqual(Request.schema({}, dummy).properties.query, undefined)
58
64
  })
59
65
 
60
66
  it('should not contain query if declaration.query is false', () => {
61
67
  schema.properties.query = { type: 'null' }
62
- expect(Request.schema({ query: false }, dummy)).toMatchObject(schema)
68
+ assert.partialDeepStrictEqual(Request.schema({ query: false }, dummy), schema)
63
69
  })
64
70
 
65
71
  it('should require query if declaration.query is true', () => {
66
72
  schema.required = ['query']
67
- expect(Request.schema({ query: true }, dummy).required).toStrictEqual(expect.arrayContaining(['query']))
73
+ assert.ok(['query'].every((item) => Request.schema({ query: true }, dummy).required.some((candidate) => isDeepStrictEqual(candidate, item))))
68
74
  })
69
75
 
70
76
  it('should forbid projection for non observations', () => {
71
- expect(Request.schema({ type: 'transition' }, dummy).properties.query.properties.projection)
72
- .toBe(undefined)
77
+ assert.strictEqual(Request.schema({ type: 'transition' }, dummy).properties.query.properties.projection, undefined)
73
78
 
74
- expect(Request.schema({ type: 'assignment' }, dummy).properties.query.properties.projection)
75
- .toBe(undefined)
79
+ assert.strictEqual(Request.schema({ type: 'assignment' }, dummy).properties.query.properties.projection, undefined)
76
80
 
77
- expect(Request.schema({ type: 'observation' }, dummy).properties.query.properties.projection)
78
- .toBeDefined()
81
+ assert.notStrictEqual(Request.schema({ type: 'observation' }, dummy).properties.query.properties.projection, undefined)
79
82
  })
80
83
 
81
84
  it('should forbid version for observations', () => {
82
- expect(Request.schema({ type: 'transition' }, dummy).properties.query.properties.version)
83
- .toBeDefined()
85
+ assert.notStrictEqual(Request.schema({ type: 'transition' }, dummy).properties.query.properties.version, undefined)
84
86
 
85
- expect(Request.schema({ type: 'observation' }, dummy).properties.query.properties.version)
86
- .toBe(undefined)
87
+ assert.strictEqual(Request.schema({ type: 'observation' }, dummy).properties.query.properties.version, undefined)
87
88
  })
88
89
 
89
90
  it('should allow omit, limit only for set observations', () => {
90
91
  const schema = Request.schema({ type: 'transition' }, dummy)
91
92
  const transition = schema.properties.query.properties
92
93
 
93
- expect(transition.omit).toBeUndefined()
94
- expect(transition.limit).toBeUndefined()
94
+ assert.strictEqual(transition.omit, undefined)
95
+ assert.strictEqual(transition.limit, undefined)
95
96
 
96
97
  const object = Request.schema({
97
98
  type: 'observation',
98
99
  scope: 'object'
99
100
  }, dummy).properties.query.properties
100
101
 
101
- expect(object.omit).toBeUndefined()
102
- expect(object.limit).toBeUndefined()
102
+ assert.strictEqual(object.omit, undefined)
103
+ assert.strictEqual(object.limit, undefined)
103
104
 
104
105
  const objects = Request.schema({
105
106
  type: 'observation',
106
107
  scope: 'objects'
107
108
  }, dummy).properties.query.properties
108
109
 
109
- expect(objects.omit).toBeDefined()
110
- expect(objects.limit).toBeDefined()
110
+ assert.notStrictEqual(objects.omit, undefined)
111
+ assert.notStrictEqual(objects.limit, undefined)
111
112
  })
112
113
  })
113
114
 
114
115
  describe('source', () => {
115
- const schemas = require('@toa.io/schemas')
116
+
116
117
 
117
118
  const compile = (definition, entity) =>
118
119
  schemas.schema(Request.schema(definition, entity), { removeAdditional: true })
@@ -120,8 +121,8 @@ describe('source', () => {
120
121
  it('should declare source', () => {
121
122
  const schema = Request.schema({}, dummy)
122
123
 
123
- expect(schema.properties.source).toBeDefined()
124
- expect(schema.properties.source.additionalProperties).toStrictEqual(false)
124
+ assert.notStrictEqual(schema.properties.source, undefined)
125
+ assert.deepStrictEqual(schema.properties.source.additionalProperties, false)
125
126
  })
126
127
 
127
128
  it('should pass known source variants', () => {
@@ -134,8 +135,8 @@ describe('source', () => {
134
135
  ]) {
135
136
  const request = { input: null, query: null, source }
136
137
 
137
- expect(schema.fit(request)).toStrictEqual(null)
138
- expect(request.source).toStrictEqual(source)
138
+ assert.deepStrictEqual(schema.fit(request), null)
139
+ assert.deepStrictEqual(request.source, source)
139
140
  }
140
141
  })
141
142
 
@@ -145,7 +146,17 @@ describe('source', () => {
145
146
  const schema = compile({}, undefined)
146
147
  const request = { input: null, query: null, source: { service: 'exposition', evil: 'x' } }
147
148
 
148
- expect(schema.fit(request)).toStrictEqual(null)
149
- expect(request.source).toStrictEqual({ service: 'exposition' })
149
+ assert.deepStrictEqual(schema.fit(request), null)
150
+ assert.deepStrictEqual(request.source, { service: 'exposition' })
150
151
  })
151
152
  })
153
+
154
+ function resetCalls (target = [assert, clone, fixtures, dummy], seen = new Set()) {
155
+ if (target === null || typeof target !== 'object' || seen.has(target)) return
156
+
157
+ seen.add(target)
158
+
159
+ for (const value of Object.values(target))
160
+ if (typeof value === 'function' && value.mock !== undefined) value.mock.resetCalls()
161
+ else resetCalls(value, seen)
162
+ }
@@ -1,11 +1,13 @@
1
- 'use strict'
1
+ import { it, beforeEach, afterEach, mock } from 'node:test'
2
+ import assert from 'node:assert/strict'
3
+ import { isDeepStrictEqual } from 'node:util'
2
4
 
3
- const { console } = require('openspan')
4
- const { Connector } = require('../src/connector')
5
- const { Discovery } = require('../src/discovery')
5
+ import { console } from 'openspan'
6
+ import { Connector } from '../src/connector.js'
7
+ import { Discovery } from '../src/discovery.js'
6
8
 
7
9
  class Lookup extends Connector {
8
- invoke = jest.fn(async () => ({ operations: {} }))
10
+ invoke = mock.fn(async () => ({ operations: {} }))
9
11
  }
10
12
 
11
13
  /** @type {Lookup} */
@@ -14,15 +16,15 @@ let lookup
14
16
  /** @type {Discovery} */
15
17
  let discovery
16
18
 
17
- /** @type {jest.SpyInstance} */
19
+ /** @type {import('node:test').Mock<any>} */
18
20
  let warn
19
21
 
20
22
  const locator = { id: 'dummies.one' }
21
23
 
22
24
  beforeEach(async () => {
23
- jest.useFakeTimers()
25
+ mock.timers.enable()
24
26
 
25
- warn = jest.spyOn(console, 'warn').mockImplementation(() => undefined)
27
+ warn = mock.method(console, 'warn', () => undefined)
26
28
  lookup = new Lookup()
27
29
  discovery = new Discovery(async () => lookup)
28
30
 
@@ -30,27 +32,33 @@ beforeEach(async () => {
30
32
  })
31
33
 
32
34
  afterEach(() => {
33
- warn.mockRestore()
34
- jest.useRealTimers()
35
+ warn.mock.restore()
36
+ mock.timers.reset()
35
37
  })
36
38
 
37
39
  it('should not warn if a lookup is answered', async () => {
38
40
  await discovery.lookup(locator)
39
41
 
40
- jest.advanceTimersByTime(60_000)
42
+ mock.timers.tick(60_000)
41
43
 
42
- expect(warn).not.toHaveBeenCalled()
44
+ assert.strictEqual(warn.mock.callCount(), 0)
43
45
  })
44
46
 
45
47
  it('should keep warning while a lookup is unanswered', async () => {
46
- lookup.invoke.mockImplementation(() => new Promise(() => undefined))
48
+ lookup.invoke.mock.mockImplementation(() => new Promise(() => undefined))
47
49
 
48
50
  void discovery.lookup(locator)
49
51
 
50
- await jest.advanceTimersByTimeAsync(12_000)
52
+ // the interval is set after the lookup is resolved, so it has to exist
53
+ // before time is advanced
54
+ await new Promise((resolve) => process.nextTick(resolve))
51
55
 
52
- expect(warn).toHaveBeenCalledTimes(2)
56
+ // node:test moves the clock before running the callbacks it releases, so the
57
+ // elapsed time each warning reports is only right when time advances by steps
58
+ mock.timers.tick(5_000)
59
+ mock.timers.tick(5_000)
53
60
 
54
- expect(warn).toHaveBeenLastCalledWith('Waiting for lookup response',
55
- { component: locator.id, waiting: 10 })
61
+ assert.strictEqual(warn.mock.callCount(), 2)
62
+
63
+ assert.ok(((call) => call.arguments.length === 2 && isDeepStrictEqual(call.arguments[0], 'Waiting for lookup response') && isDeepStrictEqual(call.arguments[1], { component: locator.id, waiting: 10 }))(warn.mock.calls.at(-1) ?? { arguments: [] }))
56
64
  })
@@ -1,16 +1,13 @@
1
- 'use strict'
1
+ import { mock } from 'node:test'
2
2
 
3
- const { generate } = require('randomstring')
3
+ import { generate } from 'randomstring'
4
4
 
5
5
  // noinspection JSCheckFunctionSignatures
6
- const events = [0, 1, 2].map((index) => ({
7
- emit: jest.fn(async (state) => ({ ...state, event: index }))
6
+ export const events = [0, 1, 2].map((index) => ({
7
+ emit: mock.fn(async (state) => ({ ...state, event: index }))
8
8
  }))
9
9
 
10
- const event = {
10
+ export const event = {
11
11
  origin: { [generate()]: generate() },
12
12
  state: { [generate()]: generate() }
13
13
  }
14
-
15
- exports.events = events
16
- exports.event = event