@toa.io/core 0.2.0-dev.3 → 0.2.1-dev.1
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/package.json +5 -4
- package/src/assignment.js +7 -7
- package/src/cascade.js +1 -1
- package/src/{runtime.js → component.js} +7 -4
- package/src/composition.js +6 -7
- package/src/connector.js +89 -24
- package/src/context.js +23 -11
- package/src/contract/reply.js +4 -1
- package/src/contract/request.js +13 -3
- package/src/contract/schemas/index.js +4 -3
- package/src/discovery.js +11 -0
- package/src/entities/changeset.js +4 -3
- package/src/entities/entity.js +17 -6
- package/src/entities/factory.js +3 -3
- package/src/event.js +12 -5
- package/src/exceptions.js +9 -1
- package/src/exposition.js +12 -9
- package/src/index.js +4 -2
- package/src/locator.js +21 -35
- package/src/observation.js +6 -6
- package/src/operation.js +20 -13
- package/src/query/options.js +4 -7
- package/src/query.js +6 -1
- package/src/receiver.js +36 -7
- package/src/reflection.js +28 -0
- package/src/remote.js +3 -3
- package/src/state.js +33 -25
- package/src/transition.js +24 -16
- package/test/call.fixtures.js +1 -0
- package/test/{runtime.fixtures.js → component.fixtures.js} +4 -2
- package/test/{runtime.test.js → component.test.js} +7 -7
- package/test/connector.fixtures.js +1 -1
- package/test/connector.test.js +6 -29
- package/test/context.fixtures.js +18 -0
- package/test/context.test.js +29 -0
- package/test/contract/contract.fixtures.js +8 -3
- package/test/contract/request.test.js +14 -3
- package/test/emission.fixtures.js +1 -0
- package/test/entities/entity.fixtures.js +4 -4
- package/test/entities/entity.test.js +22 -10
- package/test/entities/factory.test.js +6 -6
- package/test/event.fixtures.js +1 -0
- package/test/event.test.js +16 -4
- package/test/locator.test.js +76 -19
- package/test/receiver.fixtures.js +6 -5
- package/test/receiver.test.js +36 -7
- package/test/reflection.test.js +30 -0
- package/test/state.fixtures.js +6 -5
- package/test/state.test.js +8 -16
- package/types/bindings.d.ts +39 -0
- package/types/bridges.d.ts +35 -0
- package/types/component.ts +16 -0
- package/types/connector.d.ts +22 -0
- package/types/context.d.ts +24 -0
- package/types/entity.d.ts +46 -0
- package/types/event.d.ts +11 -0
- package/types/exception.d.ts +10 -0
- package/types/extensions.d.ts +36 -0
- package/types/index.d.ts +14 -0
- package/types/locator.d.ts +16 -0
- package/types/message.d.ts +9 -0
- package/types/query.d.ts +15 -0
- package/types/receiver.d.ts +12 -0
- package/types/reflection.d.ts +16 -0
- package/types/reply.d.ts +15 -0
- package/types/request.d.ts +25 -0
- package/types/state.d.ts +35 -0
- package/types/storages.d.ts +71 -0
- package/LICENSE +0 -22
package/test/connector.test.js
CHANGED
|
@@ -29,10 +29,8 @@ describe('callbacks', () => {
|
|
|
29
29
|
|
|
30
30
|
it('should reconnect', async () => {
|
|
31
31
|
await a.connect()
|
|
32
|
-
await a.
|
|
33
|
-
await a.
|
|
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
|
|
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
|
|
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 {
|
|
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
|
-
|
|
20
|
-
|
|
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({
|
|
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({
|
|
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()
|
|
@@ -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() } :
|
|
8
|
+
(object.fail ? { [generate()]: generate() } : null)),
|
|
9
9
|
|
|
10
10
|
defaults: jest.fn(() => ({ [generate()]: generate() }))
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
const state = () =>
|
|
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 = () =>
|
|
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(
|
|
33
|
+
expect(entity.get()).toStrictEqual(expected)
|
|
32
34
|
})
|
|
33
35
|
|
|
34
|
-
it('should set
|
|
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
|
|
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
|
|
30
|
+
const object = factory.object(fixtures.entity)
|
|
31
31
|
|
|
32
|
-
expect(
|
|
33
|
-
expect(
|
|
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
|
|
37
|
+
const objects = factory.objects(fixtures.set)
|
|
38
38
|
|
|
39
|
-
expect(
|
|
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(
|
|
47
|
+
expect(objects.constructor).toHaveBeenCalledWith(instances)
|
|
48
48
|
})
|
package/test/event.fixtures.js
CHANGED
package/test/event.test.js
CHANGED
|
@@ -40,7 +40,9 @@ describe('condition', () => {
|
|
|
40
40
|
it('should emit if condition returns true', async () => {
|
|
41
41
|
await emit()
|
|
42
42
|
|
|
43
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
112
|
+
const payload = fixtures.event.state
|
|
113
|
+
const message = { payload }
|
|
114
|
+
|
|
115
|
+
expect(fixtures.binding.emit).toHaveBeenCalledWith(message)
|
|
104
116
|
})
|
|
105
117
|
})
|
|
106
118
|
})
|
package/test/locator.test.js
CHANGED
|
@@ -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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
expect(
|
|
23
|
-
expect(
|
|
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
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
|
package/test/receiver.test.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
+
})
|
package/test/state.fixtures.js
CHANGED
|
@@ -12,20 +12,21 @@ const storage = {
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
const factory = {
|
|
15
|
-
|
|
16
|
-
|
|
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(() => ({
|
|
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 = {
|