@toa.io/core 0.2.0-dev.3 → 0.2.1-dev.0

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 (69) hide show
  1. package/package.json +5 -4
  2. package/src/assignment.js +7 -7
  3. package/src/cascade.js +1 -1
  4. package/src/{runtime.js → component.js} +7 -4
  5. package/src/composition.js +6 -7
  6. package/src/connector.js +89 -24
  7. package/src/context.js +23 -11
  8. package/src/contract/reply.js +4 -1
  9. package/src/contract/request.js +13 -3
  10. package/src/contract/schemas/index.js +4 -3
  11. package/src/discovery.js +11 -0
  12. package/src/entities/changeset.js +4 -3
  13. package/src/entities/entity.js +17 -6
  14. package/src/entities/factory.js +3 -3
  15. package/src/event.js +12 -5
  16. package/src/exceptions.js +9 -1
  17. package/src/exposition.js +12 -9
  18. package/src/index.js +4 -2
  19. package/src/locator.js +21 -35
  20. package/src/observation.js +6 -6
  21. package/src/operation.js +20 -13
  22. package/src/query/options.js +4 -7
  23. package/src/query.js +6 -1
  24. package/src/receiver.js +36 -7
  25. package/src/reflection.js +28 -0
  26. package/src/remote.js +3 -3
  27. package/src/state.js +33 -25
  28. package/src/transition.js +24 -16
  29. package/test/call.fixtures.js +1 -0
  30. package/test/{runtime.fixtures.js → component.fixtures.js} +4 -2
  31. package/test/{runtime.test.js → component.test.js} +7 -7
  32. package/test/connector.fixtures.js +1 -1
  33. package/test/connector.test.js +6 -29
  34. package/test/context.fixtures.js +18 -0
  35. package/test/context.test.js +29 -0
  36. package/test/contract/contract.fixtures.js +8 -3
  37. package/test/contract/request.test.js +14 -3
  38. package/test/emission.fixtures.js +1 -0
  39. package/test/entities/entity.fixtures.js +4 -4
  40. package/test/entities/entity.test.js +22 -10
  41. package/test/entities/factory.test.js +6 -6
  42. package/test/event.fixtures.js +1 -0
  43. package/test/event.test.js +16 -4
  44. package/test/locator.test.js +76 -19
  45. package/test/receiver.fixtures.js +6 -5
  46. package/test/receiver.test.js +36 -7
  47. package/test/reflection.test.js +30 -0
  48. package/test/state.fixtures.js +6 -5
  49. package/test/state.test.js +8 -16
  50. package/types/bindings.d.ts +39 -0
  51. package/types/bridges.d.ts +35 -0
  52. package/types/component.ts +16 -0
  53. package/types/connector.d.ts +22 -0
  54. package/types/context.d.ts +24 -0
  55. package/types/entity.d.ts +46 -0
  56. package/types/event.d.ts +11 -0
  57. package/types/exception.d.ts +10 -0
  58. package/types/extensions.d.ts +36 -0
  59. package/types/index.d.ts +14 -0
  60. package/types/locator.d.ts +16 -0
  61. package/types/message.d.ts +9 -0
  62. package/types/query.d.ts +15 -0
  63. package/types/receiver.d.ts +12 -0
  64. package/types/reflection.d.ts +16 -0
  65. package/types/reply.d.ts +15 -0
  66. package/types/request.d.ts +25 -0
  67. package/types/state.d.ts +35 -0
  68. package/types/storages.d.ts +71 -0
  69. package/LICENSE +0 -22
@@ -1,6 +1,6 @@
1
1
  'use strict'
2
2
 
3
- const { random, timeout } = require('@toa.io/gears')
3
+ const { random, timeout } = require('@toa.io/generic')
4
4
  const { Connector } = require('../src/connector')
5
5
 
6
6
  class TestConnector extends Connector {
@@ -29,10 +29,8 @@ describe('callbacks', () => {
29
29
 
30
30
  it('should reconnect', async () => {
31
31
  await a.connect()
32
- await a.disconnect()
33
- await a.connect()
34
- await a.disconnect()
35
- await a.connect()
32
+ await a.reconnect()
33
+ await a.reconnect()
36
34
 
37
35
  expect(sequence).toEqual(['+a', '-a', '*a', '+a', '-a', '*a', '+a'])
38
36
  })
@@ -85,12 +83,8 @@ describe('dependencies', () => {
85
83
  expect(sequence.indexOf('+b')).toBeLessThan(sequence.indexOf('+a'))
86
84
  })
87
85
 
88
- it('should not throw on empty array', async () => {
89
- a.depends([])
90
-
91
- await a.connect()
92
-
93
- expect(sequence).toStrictEqual(['+a'])
86
+ it('should throw on empty array', async () => {
87
+ expect(() => a.depends([])).toThrow(/must not be empty/)
94
88
  })
95
89
 
96
90
  it('should await 2-way dependencies', async () => {
@@ -148,25 +142,8 @@ describe('dependencies', () => {
148
142
  expect(sequence).toEqual(['+c', '+a', '+b', '-a', '*a', '-b', '-c', '*c', '*b'])
149
143
  })
150
144
 
151
- it('should not throw if depends not on Connector', async () => {
152
- a.depends({})
153
-
154
- await expect((async () => {
155
- await a.connect()
156
- await a.disconnect()
157
- })()).resolves.not.toThrow()
158
-
159
- b.depends([undefined, c, {}])
160
-
161
- await expect((async () => {
162
- await b.connect()
163
- await b.disconnect()
164
- })()).resolves.not.toThrow()
165
-
166
- expect(sequence).toStrictEqual([
167
- '+a', '-a', '*a',
168
- '+c', '+b', '-b', '-c', '*c', '*b'
169
- ])
145
+ it('should throw if depends not on Connector', async () => {
146
+ expect(() => a.depends({})).toThrow()
170
147
  })
171
148
 
172
149
  describe('errors', () => {
@@ -0,0 +1,18 @@
1
+ 'use strict'
2
+
3
+ const { Connector } = require('../src/connector')
4
+
5
+ const local = {
6
+ link: jest.fn()
7
+ }
8
+
9
+ const discover = jest.fn(() => ({
10
+ invoke: jest.fn(),
11
+ link: jest.fn()
12
+ }))
13
+
14
+ const aspects = [new Connector(), new Connector()]
15
+
16
+ exports.local = local
17
+ exports.discover = discover
18
+ exports.aspects = aspects
@@ -0,0 +1,29 @@
1
+ 'use strict'
2
+
3
+ const fixtures = require('./context.fixtures')
4
+ const { Context } = require('../src/context')
5
+
6
+ /** @type {toa.core.Context} */
7
+ let context
8
+
9
+ beforeEach(() => {
10
+ jest.clearAllMocks()
11
+
12
+ context = new Context(fixtures.local, fixtures.discover, fixtures.aspects)
13
+ })
14
+
15
+ it('should expose aspects', () => {
16
+ expect(context.aspects).toBeDefined()
17
+ expect(context.aspects).toStrictEqual(fixtures.aspects)
18
+ })
19
+
20
+ describe('call', () => {
21
+ it('should discover once', async () => {
22
+ const request = {}
23
+
24
+ await context.call('a', 'b', 'c', request)
25
+ await context.call('a', 'b', 'c', request)
26
+
27
+ expect(fixtures.discover).toHaveBeenCalledTimes(1)
28
+ })
29
+ })
@@ -1,9 +1,10 @@
1
1
  'use strict'
2
2
 
3
3
  const { generate } = require('randomstring')
4
- const { yaml } = require('@toa.io/gears')
4
+ const { load } = require('@toa.io/yaml')
5
5
  const { resolve } = require('path')
6
6
 
7
+ // noinspection JSCheckFunctionSignatures
7
8
  const schema = {
8
9
  fit: jest.fn((input) => (input.invalid ? { message: generate() } : null))
9
10
  }
@@ -16,8 +17,12 @@ const declaration = {}
16
17
 
17
18
  const schemas = {
18
19
  request: {
19
- properties: { query: yaml.sync(resolve(__dirname, '../../src/contract/schemas/query.yaml')) },
20
- additionalProperties: false
20
+ type: 'object',
21
+ properties: {
22
+ input: { type: 'null' },
23
+ query: load.sync(resolve(__dirname, '../../src/contract/schemas/query.yaml'))
24
+ },
25
+ additionalProperties: true
21
26
  }
22
27
  }
23
28
 
@@ -41,18 +41,23 @@ describe('schema', () => {
41
41
  expect(Request.schema({})).toBeDefined()
42
42
  })
43
43
 
44
- it('should add required input', () => {
44
+ it('should add required input if defined', () => {
45
45
  const input = { type: 'number' }
46
46
 
47
47
  expect(Request.schema({ input }).properties.input).toStrictEqual(input)
48
48
  })
49
49
 
50
+ it('should set input as null if undefined', async () => {
51
+ expect(Request.schema({}).properties.input).toStrictEqual({ type: 'null' })
52
+ })
53
+
50
54
  it('should contain query if declaration.query is not defined', () => {
51
55
  expect(Request.schema({}).properties.query).toBeDefined()
52
56
  })
53
57
 
54
58
  it('should not contain query if declaration.query is false', () => {
55
59
  delete schema.properties.query
60
+ schema.not = { required: ['query'] }
56
61
  expect(Request.schema({ query: false })).toStrictEqual(schema)
57
62
  })
58
63
 
@@ -86,12 +91,18 @@ describe('schema', () => {
86
91
  expect(transition.omit).toBeUndefined()
87
92
  expect(transition.limit).toBeUndefined()
88
93
 
89
- const entity = Request.schema({ type: 'observation', subject: 'entity' }).properties.query.properties
94
+ const entity = Request.schema({
95
+ type: 'observation',
96
+ scope: 'object'
97
+ }).properties.query.properties
90
98
 
91
99
  expect(entity.omit).toBeUndefined()
92
100
  expect(entity.limit).toBeUndefined()
93
101
 
94
- const set = Request.schema({ type: 'observation', subject: 'set' }).properties.query.properties
102
+ const set = Request.schema({
103
+ type: 'observation',
104
+ scope: 'objects'
105
+ }).properties.query.properties
95
106
 
96
107
  expect(set.omit).toBeDefined()
97
108
  expect(set.limit).toBeDefined()
@@ -2,6 +2,7 @@
2
2
 
3
3
  const { generate } = require('randomstring')
4
4
 
5
+ // noinspection JSCheckFunctionSignatures
5
6
  const events = [0, 1, 2].map((index) => ({
6
7
  emit: jest.fn(async (state) => ({ ...state, event: index }))
7
8
  }))
@@ -1,16 +1,16 @@
1
1
  'use strict'
2
2
 
3
3
  const { generate } = require('randomstring')
4
- const clone = require('clone-deep')
5
4
 
5
+ // noinspection JSCheckFunctionSignatures
6
6
  const schema = {
7
7
  fit: jest.fn((object) =>
8
- (object.fail ? { [generate()]: generate() } : undefined)),
8
+ (object.fail ? { [generate()]: generate() } : null)),
9
9
 
10
10
  defaults: jest.fn(() => ({ [generate()]: generate() }))
11
11
  }
12
12
 
13
- const state = () => clone({
13
+ const state = () => ({
14
14
  id: generate(),
15
15
  foo: generate(),
16
16
  _created: generate(),
@@ -19,7 +19,7 @@ const state = () => clone({
19
19
  _version: generate()
20
20
  })
21
21
 
22
- const failed = () => clone({ ...state(), fail: true })
22
+ const failed = () => ({ ...state(), fail: true })
23
23
 
24
24
  exports.schema = schema
25
25
  exports.state = state
@@ -27,23 +27,18 @@ describe('new', () => {
27
27
  describe('argument', () => {
28
28
  it('should provide initial state if no argument passed', () => {
29
29
  const entity = new Entity(fixtures.schema)
30
+ const defaults = fixtures.schema.defaults.mock.results[0].value
31
+ const expected = { ...defaults, _version: 0 }
30
32
 
31
- expect(entity.get()).toStrictEqual(fixtures.schema.defaults.mock.results[0].value)
33
+ expect(entity.get()).toStrictEqual(expected)
32
34
  })
33
35
 
34
- it('should set provide origin state', () => {
36
+ it('should set state', () => {
35
37
  const state = fixtures.state()
36
38
  const entity = new Entity(fixtures.schema, state)
37
39
 
38
40
  expect(entity.get()).toStrictEqual(state)
39
41
  })
40
-
41
- it('should not validate origin state', () => {
42
- const state = fixtures.failed()
43
- const entity = new Entity(fixtures.schema, state)
44
-
45
- expect(entity.get()).toStrictEqual(state)
46
- })
47
42
  })
48
43
 
49
44
  it('should provide event', () => {
@@ -58,7 +53,24 @@ it('should provide event', () => {
58
53
 
59
54
  expect(event).toStrictEqual({
60
55
  state,
61
- origin: origin,
56
+ origin,
62
57
  changeset: { foo: 'new value' }
63
58
  })
64
59
  })
60
+
61
+ it('should define `id` as readonly', async () => {
62
+ const origin = fixtures.state()
63
+ const entity = new Entity(fixtures.schema, origin)
64
+ const state = entity.get()
65
+
66
+ expect(() => (state.id = 1)).toThrow('assign to read only property')
67
+ })
68
+
69
+ it('should seal id', async () => {
70
+ const origin = fixtures.state()
71
+ const entity = new Entity(fixtures.schema, origin)
72
+ const state = entity.get()
73
+ const redefine = () => Object.defineProperty(state, 'id', { writable: true })
74
+
75
+ expect(redefine).toThrow('redefine property')
76
+ })
@@ -27,16 +27,16 @@ it('should create initial', () => {
27
27
  })
28
28
 
29
29
  it('should create instance', () => {
30
- const entity = factory.entity(fixtures.entity)
30
+ const object = factory.object(fixtures.entity)
31
31
 
32
- expect(entity).toBeInstanceOf(mock.Entity)
33
- expect(entity.constructor).toHaveBeenCalledWith(fixtures.schema, fixtures.entity)
32
+ expect(object).toBeInstanceOf(mock.Entity)
33
+ expect(object.constructor).toHaveBeenCalledWith(fixtures.schema, fixtures.entity)
34
34
  })
35
35
 
36
36
  it('should create set', () => {
37
- const set = factory.set(fixtures.set)
37
+ const objects = factory.objects(fixtures.set)
38
38
 
39
- expect(set).toBeInstanceOf(mock.EntitySet)
39
+ expect(objects).toBeInstanceOf(mock.EntitySet)
40
40
 
41
41
  const instances = fixtures.set.map((entity, index) => {
42
42
  expect(mock.Entity).toHaveBeenNthCalledWith(index + 1, fixtures.schema, entity)
@@ -44,5 +44,5 @@ it('should create set', () => {
44
44
  return mock.Entity.mock.instances[index]
45
45
  })
46
46
 
47
- expect(set.constructor).toHaveBeenCalledWith(instances)
47
+ expect(objects.constructor).toHaveBeenCalledWith(instances)
48
48
  })
@@ -7,6 +7,7 @@ const definition = {
7
7
  subjective: true
8
8
  }
9
9
 
10
+ // noinspection JSCheckFunctionSignatures
10
11
  const bridge = {
11
12
  condition: jest.fn(async (origin) => !origin.falsy),
12
13
  payload: jest.fn(async () => ({ [generate()]: generate() }))
@@ -40,7 +40,9 @@ describe('condition', () => {
40
40
  it('should emit if condition returns true', async () => {
41
41
  await emit()
42
42
 
43
- expect(fixtures.binding.emit).toHaveBeenCalledWith(await fixtures.bridge.payload.mock.results[0].value)
43
+ const payload = await fixtures.bridge.payload.mock.results[0].value
44
+ const message = { payload }
45
+ expect(fixtures.binding.emit).toHaveBeenCalledWith(message)
44
46
  })
45
47
 
46
48
  it('should not emit if condition returns false', async () => {
@@ -67,7 +69,11 @@ describe('condition', () => {
67
69
  await event.emit(fixtures.event.origin, fixtures.event.changeset, fixtures.event.state)
68
70
 
69
71
  expect(fixtures.bridge.condition).not.toHaveBeenCalledWith()
70
- expect(fixtures.binding.emit).toHaveBeenCalledWith(await fixtures.bridge.payload.mock.results[0].value)
72
+
73
+ const payload = await fixtures.bridge.payload.mock.results[0].value
74
+ const message = { payload }
75
+
76
+ expect(fixtures.binding.emit).toHaveBeenCalledWith(message)
71
77
  })
72
78
  })
73
79
  })
@@ -77,7 +83,10 @@ describe('payload', () => {
77
83
  it('should emit payload', async () => {
78
84
  await emit()
79
85
 
80
- expect(fixtures.binding.emit).toHaveBeenCalledWith(await fixtures.bridge.payload.mock.results[0].value)
86
+ const payload = await fixtures.bridge.payload.mock.results[0].value
87
+ const message = { payload }
88
+
89
+ expect(fixtures.binding.emit).toHaveBeenCalledWith(message)
81
90
  })
82
91
  })
83
92
 
@@ -100,7 +109,10 @@ describe('payload', () => {
100
109
  it('should return state as payload', async () => {
101
110
  await emit()
102
111
 
103
- expect(fixtures.binding.emit).toHaveBeenCalledWith(fixtures.event.state)
112
+ const payload = fixtures.event.state
113
+ const message = { payload }
114
+
115
+ expect(fixtures.binding.emit).toHaveBeenCalledWith(message)
104
116
  })
105
117
  })
106
118
  })
@@ -1,24 +1,81 @@
1
1
  'use strict'
2
2
 
3
+ const { generate } = require('randomstring')
3
4
  const { Locator } = require('../src/locator')
4
5
 
5
- const manifest = {
6
- domain: 'foo',
7
- name: 'bar',
8
- entity: { schema: { foo: 'bar' } },
9
- operations: { add: { query: false }, get: { output: null } }
10
- }
11
-
12
- const nameless = {
13
- domain: 'foo',
14
- entity: { schema: { foo: 'bar' } },
15
- operations: [{ name: 'add' }, { name: 'get' }]
16
- }
17
-
18
- it('should provide host', () => {
19
- expect(new Locator(manifest).host('db')).toBe('foo-db')
20
- expect(new Locator(nameless).host('db')).toBe('foo-db')
21
- expect(new Locator(nameless).host('DB')).toBe('foo-db')
22
- expect(new Locator(manifest).host('db', 1)).toBe('foo-bar-db')
23
- expect(new Locator(nameless).host('db', 1)).toBe('foo-db')
6
+ /** @type {string} */
7
+ let name
8
+
9
+ /** @type {string} */
10
+ let namespace
11
+
12
+ /** @type {toa.core.Locator} */
13
+ let locator
14
+
15
+ beforeEach(() => {
16
+ name = generate()
17
+ namespace = generate()
18
+
19
+ locator = new Locator(name, namespace)
20
+ })
21
+
22
+ it('should expose name and namespace', () => {
23
+ expect(locator.name).toStrictEqual(name)
24
+ expect(locator.namespace).toStrictEqual(namespace)
25
+ })
26
+
27
+ it('should expose id, label', () => {
28
+ const id = locator.namespace + '.' + locator.name
29
+ const label = locator.namespace.toLowerCase() + '-' + locator.name.toLowerCase()
30
+
31
+ expect(locator.id).toStrictEqual(id)
32
+ expect(locator.label).toStrictEqual(label)
33
+ })
34
+
35
+ it('should expose uppercase', () => {
36
+ expect(locator.uppercase).toStrictEqual((locator.namespace + '_' + locator.name).toUpperCase())
37
+ })
38
+
39
+ it('should throw if name is undefined', () => {
40
+ expect(() => new Locator(undefined, namespace)).toThrow(TypeError)
41
+
42
+ // noinspection JSCheckFunctionSignatures
43
+ expect(() => new Locator()).toThrow(TypeError)
44
+ })
45
+
46
+ it('should expose host', () => {
47
+ expect(locator.hostname()).toStrictEqual((namespace + '-' + name).toLowerCase())
48
+ })
49
+
50
+ it('should expose host with given prefix', () => {
51
+ const prefix = generate()
52
+
53
+ expect(locator.hostname(prefix)).toStrictEqual((prefix + '-' + namespace + '-' + name).toLowerCase())
54
+ })
55
+
56
+ describe('global', () => {
57
+ beforeEach(() => {
58
+ locator = new Locator(name)
59
+ })
60
+
61
+ it('should not throw', () => undefined)
62
+
63
+ it('should expose id', () => {
64
+ expect(locator.id).toStrictEqual(name)
65
+ })
66
+
67
+ it('should expose label', () => {
68
+ expect(locator.label).toStrictEqual(name.toLowerCase())
69
+ })
70
+
71
+ it('should expose uppercase', () => {
72
+ expect(locator.uppercase).toStrictEqual(name.toUpperCase())
73
+ })
74
+
75
+ it('should expose hostname', () => {
76
+ const type = generate()
77
+
78
+ expect(locator.hostname(type)).toStrictEqual((type + '-' + name).toLowerCase())
79
+ expect(locator.hostname()).toStrictEqual(name.toLowerCase())
80
+ })
24
81
  })
@@ -2,19 +2,20 @@
2
2
 
3
3
  const { generate } = require('randomstring')
4
4
 
5
- const definition = {
5
+ const definition = /** @type {toa.norm.component.Receiver} */ {
6
6
  transition: generate(),
7
7
  conditioned: false,
8
8
  adaptive: false
9
9
  }
10
10
 
11
- const local = {
11
+ const local = /** @type {toa.core.Component} */ {
12
12
  invoke: jest.fn()
13
13
  }
14
14
 
15
- const bridge = {
16
- condition: jest.fn((payload) => !(payload.reject === true)),
17
- request: jest.fn(() => generate())
15
+ // noinspection JSCheckFunctionSignatures
16
+ const bridge = /** @type {toa.core.bridges.Event} */ {
17
+ condition: jest.fn(async (payload) => !(payload.reject === true)),
18
+ request: jest.fn(async () => ({ input: generate() }))
18
19
  }
19
20
 
20
21
  exports.definition = definition
@@ -1,17 +1,25 @@
1
1
  'use strict'
2
2
 
3
3
  const clone = require('clone-deep')
4
+ const { generate } = require('randomstring')
5
+ const { merge } = require('@toa.io/generic')
4
6
 
5
7
  jest.mock('../src/connector')
6
8
 
7
- const { Connector } = require('../src/connector')
9
+ const { Connector } = /** @type {{ Connector: jest.Mock<toa.core.Connector>}} */ require('../src/connector')
8
10
 
9
11
  const { Receiver } = require('../src/receiver')
10
12
  const fixtures = require('./receiver.fixtures')
11
13
 
12
- let receiver, definition
14
+ /** @type {toa.core.Receiver} */
15
+ let receiver
16
+
17
+ /** @type {toa.norm.component.Receiver} */
18
+ let definition
13
19
 
14
20
  beforeEach(() => {
21
+ jest.clearAllMocks()
22
+
15
23
  definition = clone(fixtures.definition)
16
24
  receiver = new Receiver(fixtures.definition, fixtures.local, fixtures.bridge)
17
25
  })
@@ -23,11 +31,32 @@ it('should depend on local, bridge', () => {
23
31
 
24
32
  it('should apply', async () => {
25
33
  const payload = { foo: 'bar' }
26
- await receiver.receive(payload)
34
+
35
+ await receiver.receive({ payload })
27
36
 
28
37
  expect(fixtures.local.invoke).toHaveBeenCalledWith(definition.transition, payload)
29
38
  })
30
39
 
40
+ it.each([[false], [true]])('should pass UI extensions (adaptive: %s)', async (adaptive) => {
41
+ jest.clearAllMocks()
42
+
43
+ definition.adaptive = adaptive
44
+ receiver = new Receiver(definition, fixtures.local, fixtures.bridge)
45
+
46
+ const payload = { foo: generate() }
47
+ const extension = { [generate()]: generate() }
48
+ const message = { payload, ...extension }
49
+
50
+ await receiver.receive(message)
51
+
52
+ const request = adaptive ? await fixtures.bridge.request.mock.results[0].value : payload
53
+ const expected = merge(clone(request), extension)
54
+
55
+ const argument = fixtures.local.invoke.mock.calls[0][1]
56
+
57
+ expect(argument).toStrictEqual(expected)
58
+ })
59
+
31
60
  describe('conditioned', () => {
32
61
  beforeEach(() => {
33
62
  definition.conditioned = true
@@ -36,7 +65,7 @@ describe('conditioned', () => {
36
65
 
37
66
  it('should test condition', async () => {
38
67
  const payload = { foo: 'bar' }
39
- await receiver.receive(payload)
68
+ await receiver.receive({ payload })
40
69
 
41
70
  expect(fixtures.bridge.condition).toHaveBeenCalledWith(payload)
42
71
  expect(fixtures.local.invoke).toHaveBeenCalledWith(definition.transition, payload)
@@ -44,7 +73,7 @@ describe('conditioned', () => {
44
73
 
45
74
  it('should not apply if condition is false', async () => {
46
75
  const payload = { reject: true }
47
- await receiver.receive(payload)
76
+ await receiver.receive({ payload })
48
77
 
49
78
  expect(fixtures.local.invoke).not.toHaveBeenCalled()
50
79
  })
@@ -58,9 +87,9 @@ describe('adaptive', () => {
58
87
 
59
88
  it('should apply', async () => {
60
89
  const payload = { reject: true }
61
- await receiver.receive(payload)
90
+ await receiver.receive({ payload })
62
91
 
63
92
  expect(fixtures.local.invoke)
64
- .toHaveBeenCalledWith(definition.transition, fixtures.bridge.request.mock.results[0].value)
93
+ .toHaveBeenCalledWith(definition.transition, await fixtures.bridge.request.mock.results[0].value)
65
94
  })
66
95
  })
@@ -0,0 +1,30 @@
1
+ 'use strict'
2
+
3
+ const { generate } = require('randomstring')
4
+ const { Reflection, Connector } = require('../')
5
+
6
+ it('should export', () => {
7
+ expect(Reflection).toBeDefined()
8
+ })
9
+
10
+ /** @type {toa.core.Reflection<string>} */
11
+ let reflection
12
+
13
+ const value = generate()
14
+
15
+ /** @type {toa.core.reflection.Source<string>} */
16
+ const source = async () => value
17
+
18
+ beforeEach(() => {
19
+ reflection = new Reflection(source)
20
+ })
21
+
22
+ it('should be a Connector', () => {
23
+ expect(reflection).toBeInstanceOf(Connector)
24
+ })
25
+
26
+ it('should reflect', async () => {
27
+ await reflection.connect()
28
+
29
+ expect(reflection.value).toStrictEqual(value)
30
+ })
@@ -12,20 +12,21 @@ const storage = {
12
12
  }
13
13
 
14
14
  const factory = {
15
- entity: jest.fn(() => ({ [generate()]: generate() })),
16
- set: jest.fn(() => ({ [generate()]: generate() }))
15
+ object: jest.fn(() => ({ [generate()]: generate() })),
16
+ objects: jest.fn(() => ({ [generate()]: generate() }))
17
17
  }
18
18
 
19
19
  const query = generate()
20
20
 
21
21
  const entity = {
22
22
  get: jest.fn(() => ({ [generate()]: generate() })),
23
- event: jest.fn(() => ({ state: { [generate()]: generate() }, changeset: { [generate()]: generate() } }))
23
+ event: jest.fn(() => ({
24
+ state: { [generate()]: generate() }, changeset: { [generate()]: generate() }
25
+ }))
24
26
  }
25
27
 
26
28
  const initial = {
27
- initial: true,
28
- ...entity
29
+ initial: true, ...entity
29
30
  }
30
31
 
31
32
  const unchanged = {