@toa.io/userland 0.10.1-dev.0 → 0.20.0-alpha.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.
- package/example/.env +9 -0
- package/example/components/echo/manifest.toa.yaml +7 -0
- package/example/components/echo/operations/get.js +7 -0
- package/example/components/echo/operations/resolve.js +7 -0
- package/example/components/echo/operations/signal.js +11 -3
- package/example/components/echo/samples/get.yaml +12 -0
- package/example/components/echo/samples/signal.yaml +0 -3
- package/example/components/math.calculations/operations/increment.js +1 -3
- package/example/components/math.calculations/samples/add.yaml +1 -2
- package/example/components/math.calculations/samples/assets/ab.yaml +2 -0
- package/example/components/math.calculations/samples/increment.yaml +3 -6
- package/example/components/tea.pots/manifest.toa.yaml +2 -2
- package/example/components/web/manifest.toa.yaml +8 -0
- package/example/components/web/operations/get.js +14 -0
- package/example/components/web/samples/get.yaml +8 -0
- package/example/context.toa.yaml +7 -0
- package/example/stage/call.test.js +5 -4
- package/example/stage/events.test.js +6 -3
- package/example/stage/invoke.test.js +4 -0
- package/package.json +10 -9
- package/samples/notes.md +2 -2
- package/samples/readme.md +74 -8
- package/samples/src/.replay/.suite/component.js +3 -8
- package/samples/src/.replay/.suite/operation.js +1 -1
- package/samples/src/.replay/.suite/operations.js +5 -3
- package/samples/src/.replay/.suite/translate/.operation/.prepare/cast.js +20 -0
- package/samples/src/.replay/.suite/translate/.operation/.prepare/cast.test.js +94 -0
- package/samples/src/.replay/.suite/translate/.operation/.prepare/expand.js +14 -0
- package/samples/src/.replay/.suite/translate/.operation/.prepare/index.js +7 -0
- package/samples/src/.replay/.suite/translate/.operation/.prepare/shortcuts/.aspect.js +26 -0
- package/samples/src/.replay/.suite/translate/.operation/.prepare/shortcuts/configuration.js +5 -0
- package/samples/src/.replay/.suite/translate/.operation/.prepare/shortcuts/http.js +5 -0
- package/samples/src/.replay/.suite/translate/.operation/.prepare/shortcuts/index.js +9 -0
- package/samples/src/.replay/.suite/translate/.operation/.prepare/shortcuts/state.js +5 -0
- package/samples/src/.replay/.suite/translate/.operation/.prepare/types/async.js +3 -0
- package/samples/src/.replay/.suite/translate/.operation/.prepare/types/cast.js +26 -0
- package/samples/src/.replay/.suite/translate/.operation/.prepare/types/index.js +5 -0
- package/samples/src/.replay/.suite/translate/.operation/.prepare/types/map.js +3 -0
- package/samples/src/.replay/.suite/translate/.operation/.prepare/types/set.js +3 -0
- package/samples/src/.replay/.suite/translate/.operation/.prepare/types/sync.js +3 -0
- package/samples/src/.replay/.suite/translate/.operation/prepare.js +4 -4
- package/samples/src/.replay/index.js +2 -0
- package/samples/src/.replay/stage.js +60 -0
- package/samples/src/.replay/suite.js +3 -2
- package/samples/src/.replay/test.js +5 -3
- package/samples/src/components.js +1 -1
- package/samples/src/context.js +2 -2
- package/samples/src/replay.js +4 -5
- package/samples/src/suite/components.js +3 -3
- package/samples/test/components.test.js +2 -2
- package/samples/test/context.test.js +2 -2
- package/samples/test/replay.test.js +108 -72
- package/samples/test/replay.translate.message.test.js +2 -6
- package/samples/test/replay.translate.operation.test.js +1 -1
- package/samples/test/stage.mock.js +10 -14
- package/samples/test/suite.components.test.js +5 -31
- package/samples/types/operation.d.ts +2 -2
- package/samples/types/replay.d.ts +3 -3
- package/samples/types/suite.d.ts +5 -2
- package/stage/src/binding/binding.js +14 -13
- package/stage/src/component.js +7 -2
- package/stage/src/index.js +0 -3
- package/stage/test/component.test.js +1 -1
- package/stage/types/index.d.ts +2 -1
- package/example/components/tea.pots/samples/messages/store.orders.created.yaml +0 -37
- package/samples/src/.replay/.suite/translate/.operation/specials/configuration.js +0 -26
- package/samples/src/.replay/.suite/translate/.operation/specials/index.js +0 -5
- package/samples/test/replay.fixtures.js +0 -72
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { map } = require('@toa.io/generic')
|
|
4
|
+
|
|
5
|
+
const types = {
|
|
6
|
+
Map: require('./map'),
|
|
7
|
+
Set: require('./set'),
|
|
8
|
+
sync: require('./sync'),
|
|
9
|
+
async: require('./async')
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function cast (value) {
|
|
13
|
+
return map(value, replace)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function replace (key, value) {
|
|
17
|
+
const [name, type] = key.split(':')
|
|
18
|
+
|
|
19
|
+
if (!(type in types)) return
|
|
20
|
+
|
|
21
|
+
const typed = types[type](value)
|
|
22
|
+
|
|
23
|
+
return [name, typed]
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
exports.cast = cast
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const { cast, expand } = require('./.prepare')
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* @param {toa.samples.Operation & Object} declaration
|
|
7
7
|
*/
|
|
8
8
|
const prepare = (declaration) => {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
expand(declaration)
|
|
10
|
+
|
|
11
|
+
if ('extensions' in declaration) cast(declaration.extensions)
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
exports.prepare = prepare
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const stage = require('@toa.io/userland/stage')
|
|
4
|
+
const storage = require.resolve('@toa.io/storages.null')
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @param {string[]} paths
|
|
8
|
+
* @param {boolean} autonomous
|
|
9
|
+
* @return {Promise<Record<string, toa.core.Component>>}
|
|
10
|
+
*/
|
|
11
|
+
async function setup (paths, autonomous) {
|
|
12
|
+
if (!autonomous) return remotes(paths)
|
|
13
|
+
else return components(paths)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async function remotes (paths) {
|
|
17
|
+
await stage.composition(paths)
|
|
18
|
+
|
|
19
|
+
const remotes = {}
|
|
20
|
+
|
|
21
|
+
for (const path of paths) {
|
|
22
|
+
const id = await getId(path)
|
|
23
|
+
|
|
24
|
+
remotes[id] = await stage.remote(id)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return remotes
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async function components (paths) {
|
|
31
|
+
const components = {}
|
|
32
|
+
|
|
33
|
+
process.env.TOA_SAMPLING_AUTONOMOUS = '1'
|
|
34
|
+
|
|
35
|
+
for (const path of paths) {
|
|
36
|
+
const id = await getId(path)
|
|
37
|
+
|
|
38
|
+
components[id] = await stage.component(path, { storage })
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
delete process.env.TOA_SAMPLING_AUTONOMOUS
|
|
42
|
+
|
|
43
|
+
return components
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async function getId (path) {
|
|
47
|
+
const manifest = await stage.manifest(path)
|
|
48
|
+
|
|
49
|
+
return manifest.locator.id
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* @return {Promise<void>}
|
|
54
|
+
*/
|
|
55
|
+
async function shutdown () {
|
|
56
|
+
await stage.shutdown()
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
exports.setup = setup
|
|
60
|
+
exports.shutdown = shutdown
|
|
@@ -4,12 +4,13 @@ const replay = require('./.suite')
|
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* @param {toa.samples.Suite} suite
|
|
7
|
+
* @param {Record<string, toa.core.Component>} components
|
|
7
8
|
* @returns {Function}
|
|
8
9
|
*/
|
|
9
|
-
const suite = (suite) =>
|
|
10
|
+
const suite = (suite, components) =>
|
|
10
11
|
async (test) => {
|
|
11
12
|
if ('operations' in suite) {
|
|
12
|
-
await test.test('Operations', replay.operations(suite.operations, suite.autonomous))
|
|
13
|
+
await test.test('Operations', replay.operations(suite.operations, components, suite.autonomous))
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
if ('messages' in suite) {
|
|
@@ -6,12 +6,14 @@ const replay = require('./suite')
|
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* @param {toa.samples.Suite} suite
|
|
9
|
+
* @param {Record<string, toa.core.Component>} components
|
|
10
|
+
* @param {object} options
|
|
9
11
|
* @return {Promise<boolean>}
|
|
10
12
|
*/
|
|
11
|
-
const test = async (suite) => {
|
|
12
|
-
const
|
|
13
|
+
const test = async (suite, components, options) => {
|
|
14
|
+
const result = await tap.test(suite.title, options, replay.suite(suite, components))
|
|
13
15
|
|
|
14
|
-
return ok
|
|
16
|
+
return result === null ? false : result.ok
|
|
15
17
|
}
|
|
16
18
|
|
|
17
19
|
exports.test = test
|
|
@@ -7,7 +7,7 @@ const { replay } = require('./replay')
|
|
|
7
7
|
const components = async (paths, options = {}) => {
|
|
8
8
|
const suite = await load(paths, options)
|
|
9
9
|
|
|
10
|
-
return await replay(suite, paths)
|
|
10
|
+
return await replay(suite, paths, options.runner)
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
exports.components = components
|
package/samples/src/context.js
CHANGED
|
@@ -9,13 +9,13 @@ const { replay } = require('./replay')
|
|
|
9
9
|
/** @type {toa.samples.replay.context} */
|
|
10
10
|
const context = async (path, options = {}) => {
|
|
11
11
|
const context = await norm.context(path)
|
|
12
|
-
const paths = context.components.map((component) => component.path)
|
|
13
12
|
const suite = await load(path, options)
|
|
13
|
+
const paths = context.components.map((component) => component.path)
|
|
14
14
|
|
|
15
15
|
let ok = true
|
|
16
16
|
|
|
17
17
|
if (options.integration !== true) ok = await test.components(paths, options)
|
|
18
|
-
if (ok) ok = await replay(suite, paths)
|
|
18
|
+
if (ok && options.autonomous !== true) ok = await replay(suite, paths, options.runner)
|
|
19
19
|
|
|
20
20
|
return ok
|
|
21
21
|
}
|
package/samples/src/replay.js
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const stage = require('
|
|
4
|
-
const { test } = require('./.replay')
|
|
3
|
+
const { test, stage } = require('./.replay')
|
|
5
4
|
|
|
6
5
|
/** @type {toa.samples.replay.replay} */
|
|
7
|
-
const replay = async (suite, paths) => {
|
|
8
|
-
await stage.
|
|
6
|
+
const replay = async (suite, paths, options = undefined) => {
|
|
7
|
+
const components = await stage.setup(paths, suite.autonomous)
|
|
9
8
|
|
|
10
|
-
const ok = await test(suite)
|
|
9
|
+
const ok = await test(suite, components, options)
|
|
11
10
|
|
|
12
11
|
await stage.shutdown()
|
|
13
12
|
|
|
@@ -12,7 +12,7 @@ const read = require('./.read')
|
|
|
12
12
|
*/
|
|
13
13
|
const components = async (paths, options = {}) => {
|
|
14
14
|
/** @type {toa.samples.Suite} */
|
|
15
|
-
const suite = { title: 'Component samples', autonomous: true, operations: {}
|
|
15
|
+
const suite = { title: 'Component samples', autonomous: true, operations: {} }
|
|
16
16
|
|
|
17
17
|
for (const path of paths) {
|
|
18
18
|
const manifest = await norm.component(path)
|
|
@@ -20,9 +20,9 @@ const components = async (paths, options = {}) => {
|
|
|
20
20
|
options.id = manifest.locator.id
|
|
21
21
|
|
|
22
22
|
const operations = await read.operations(path, options)
|
|
23
|
-
const messages = await read.messages(path, options)
|
|
23
|
+
// const messages = await read.messages(path, options)
|
|
24
24
|
|
|
25
|
-
merge(suite, { operations
|
|
25
|
+
merge(suite, { operations })
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
return suite
|
|
@@ -18,7 +18,7 @@ it('should be', () => {
|
|
|
18
18
|
const paths = [generate()]
|
|
19
19
|
|
|
20
20
|
/** @type {toa.samples.suite.Options} */
|
|
21
|
-
const options = { component: generate() }
|
|
21
|
+
const options = { component: generate(), runner: { [generate()]: generate() } }
|
|
22
22
|
|
|
23
23
|
/** @type {boolean} */
|
|
24
24
|
let result
|
|
@@ -34,7 +34,7 @@ it('should load suite', async () => {
|
|
|
34
34
|
it('should replay suite', async () => {
|
|
35
35
|
const suite = await mock.suite.components.mock.results[0].value
|
|
36
36
|
|
|
37
|
-
expect(mock.replay.replay).toHaveBeenCalledWith(suite, paths)
|
|
37
|
+
expect(mock.replay.replay).toHaveBeenCalledWith(suite, paths, options.runner)
|
|
38
38
|
})
|
|
39
39
|
|
|
40
40
|
it('should return result', async () => {
|
|
@@ -27,7 +27,7 @@ const COMPONENTS = resolve(CONTEXT, 'components/*')
|
|
|
27
27
|
let paths
|
|
28
28
|
|
|
29
29
|
/** @type {toa.samples.suite.Options} */
|
|
30
|
-
const options = { component: generate() }
|
|
30
|
+
const options = { component: generate(), runner: { [generate()]: generate() } }
|
|
31
31
|
|
|
32
32
|
/** @type {boolean} */
|
|
33
33
|
let ok
|
|
@@ -55,7 +55,7 @@ it('should load integration suite', async () => {
|
|
|
55
55
|
it('should replay integration suite', async () => {
|
|
56
56
|
const suite = await mock.suite.context.mock.results[0].value
|
|
57
57
|
|
|
58
|
-
expect(replay.replay).toHaveBeenCalledWith(suite, paths)
|
|
58
|
+
expect(replay.replay).toHaveBeenCalledWith(suite, paths, options.runner)
|
|
59
59
|
})
|
|
60
60
|
|
|
61
61
|
it('should return false if components replay failed', async () => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const { resolve } = require('node:path')
|
|
4
|
-
const
|
|
4
|
+
const { directory } = require('@toa.io/filesystem')
|
|
5
5
|
|
|
6
6
|
const { stage } = require('./stage.mock')
|
|
7
7
|
const { translate } = require('./replay.translate.mock')
|
|
@@ -10,7 +10,8 @@ const mock = { stage, translate }
|
|
|
10
10
|
jest.mock('@toa.io/userland/stage', () => mock.stage)
|
|
11
11
|
jest.mock('../src/.replay/.suite/translate', () => mock.translate)
|
|
12
12
|
|
|
13
|
-
const
|
|
13
|
+
const load = require('../src/suite')
|
|
14
|
+
|
|
14
15
|
const { replay } = require('../src')
|
|
15
16
|
|
|
16
17
|
it('should be', () => {
|
|
@@ -22,95 +23,130 @@ let ok
|
|
|
22
23
|
/** @type {toa.samples.Suite} */
|
|
23
24
|
let suite
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
const paths = [path]
|
|
27
|
-
|
|
28
|
-
beforeEach(async () => {
|
|
26
|
+
beforeEach(() => {
|
|
29
27
|
jest.clearAllMocks()
|
|
30
|
-
|
|
31
|
-
suite = clone(fixtures.suite)
|
|
32
|
-
ok = await replay(suite, paths)
|
|
33
28
|
})
|
|
34
29
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
expect(stage.composition).toHaveBeenCalledWith(paths)
|
|
38
|
-
})
|
|
30
|
+
describe('autonomous', () => {
|
|
31
|
+
let paths
|
|
39
32
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
const find = (call) => call[0].input === declaration.input
|
|
43
|
-
const index = mock.translate.operation.mock.calls.findIndex(find)
|
|
33
|
+
beforeEach(async () => {
|
|
34
|
+
const path = resolve(__dirname, '../../example/components/tea.pots')
|
|
44
35
|
|
|
45
|
-
|
|
46
|
-
|
|
36
|
+
paths = [path]
|
|
37
|
+
suite = await load.components(paths)
|
|
38
|
+
ok = await replay(suite, paths)
|
|
39
|
+
})
|
|
47
40
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
*/
|
|
52
|
-
const find = async (component) => {
|
|
53
|
-
for (let n = 0; n < stage.remote.mock.calls.length; n++) {
|
|
54
|
-
const call = stage.remote.mock.calls[n]
|
|
41
|
+
it('should not boot composition for autonomous suite', async () => {
|
|
42
|
+
expect(stage.composition).not.toHaveBeenCalled()
|
|
43
|
+
})
|
|
55
44
|
|
|
56
|
-
|
|
45
|
+
it('should invoke operations with translated samples', async () => {
|
|
46
|
+
const component = await stage.component.mock.results[0].value
|
|
47
|
+
|
|
48
|
+
for (const set of Object.values(suite.operations)) {
|
|
49
|
+
for (const [endpoint, samples] of Object.entries(set)) {
|
|
50
|
+
for (const sample of samples) {
|
|
51
|
+
const request = translation(sample)
|
|
52
|
+
|
|
53
|
+
expect(component.invoke).toHaveBeenCalledWith(endpoint, request)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
57
56
|
}
|
|
57
|
+
})
|
|
58
|
+
})
|
|
58
59
|
|
|
59
|
-
|
|
60
|
-
|
|
60
|
+
describe('integration', () => {
|
|
61
|
+
let paths
|
|
61
62
|
|
|
62
|
-
|
|
63
|
-
const
|
|
63
|
+
beforeEach(async () => {
|
|
64
|
+
const path = resolve(__dirname, '../../example')
|
|
64
65
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
paths = await directory.directories(resolve(path, 'components'))
|
|
67
|
+
suite = await load.context(path)
|
|
68
|
+
ok = await replay(suite, paths)
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
it('should boot composition', () => {
|
|
72
|
+
expect(stage.composition).toHaveBeenCalled()
|
|
73
|
+
expect(stage.composition).toHaveBeenCalledWith(paths)
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
it('should invoke operations with translated samples', async () => {
|
|
77
|
+
/**
|
|
78
|
+
* @param {string} component
|
|
79
|
+
* @return {jest.MockedObject<toa.core.Component>}
|
|
80
|
+
*/
|
|
81
|
+
const getRemote = (component) => {
|
|
82
|
+
for (let n = 0; n < stage.remote.mock.calls.length; n++) {
|
|
83
|
+
const call = stage.remote.mock.calls[n]
|
|
68
84
|
|
|
69
|
-
|
|
85
|
+
if (call[0] === component) return stage.remote.mock.results[n].value
|
|
70
86
|
}
|
|
87
|
+
|
|
88
|
+
throw new Error(`Remote ${component} hasn't been connected`)
|
|
71
89
|
}
|
|
72
|
-
}
|
|
73
|
-
})
|
|
74
90
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
91
|
+
for (const [id, set] of Object.entries(suite.operations)) {
|
|
92
|
+
const remote = await getRemote(id)
|
|
93
|
+
|
|
94
|
+
for (const [endpoint, samples] of Object.entries(set)) {
|
|
95
|
+
for (const sample of samples) {
|
|
96
|
+
const request = translation(sample)
|
|
97
|
+
|
|
98
|
+
expect(remote.invoke).toHaveBeenCalledWith(endpoint, request)
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
it('should emit translated messages', async () => {
|
|
105
|
+
/**
|
|
106
|
+
* @param {toa.samples.Message} declaration
|
|
107
|
+
* @returns {{index: number, message: toa.sampling.Message}}
|
|
108
|
+
*/
|
|
109
|
+
const translation = (declaration) => {
|
|
110
|
+
const find = (call) => call[0].payload === declaration.payload
|
|
111
|
+
const index = mock.translate.message.mock.calls.findIndex(find)
|
|
112
|
+
const message = mock.translate.message.mock.results[index].value
|
|
113
|
+
const call = mock.translate.message.mock.calls[index]
|
|
114
|
+
|
|
115
|
+
expect(call[1]).toStrictEqual(suite.autonomous)
|
|
116
|
+
|
|
117
|
+
return { index, message }
|
|
98
118
|
}
|
|
99
|
-
}
|
|
100
|
-
})
|
|
101
119
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
})
|
|
120
|
+
for (const [label, samples] of Object.entries(suite.messages)) {
|
|
121
|
+
for (const sample of samples) {
|
|
122
|
+
const { index, message } = translation(sample)
|
|
105
123
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
}
|
|
124
|
+
expect(stage.binding.binding.emit)
|
|
125
|
+
.toHaveBeenNthCalledWith(index + 1, label, message)
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
it('should shutdown stage', () => {
|
|
131
|
+
expect(stage.shutdown).toHaveBeenCalled()
|
|
132
|
+
})
|
|
109
133
|
|
|
110
|
-
it
|
|
111
|
-
|
|
134
|
+
it('should return results', () => {
|
|
135
|
+
expect(ok).toStrictEqual(true)
|
|
136
|
+
})
|
|
112
137
|
|
|
113
|
-
|
|
138
|
+
it.each(['messages', 'operations'])('should not throw if no %s defined', async (key) => {
|
|
139
|
+
delete suite[key]
|
|
114
140
|
|
|
115
|
-
|
|
141
|
+
ok = await replay(suite, paths)
|
|
142
|
+
|
|
143
|
+
expect(ok).toStrictEqual(true)
|
|
144
|
+
})
|
|
116
145
|
})
|
|
146
|
+
|
|
147
|
+
const translation = (declaration) => {
|
|
148
|
+
const find = (call) => call[0].input === declaration.input
|
|
149
|
+
const index = mock.translate.operation.mock.calls.findIndex(find)
|
|
150
|
+
|
|
151
|
+
return mock.translate.operation.mock.results[index].value
|
|
152
|
+
}
|
|
@@ -108,16 +108,12 @@ describe('validation', () => {
|
|
|
108
108
|
expect(check).toThrow('must be string')
|
|
109
109
|
})
|
|
110
110
|
|
|
111
|
-
it.each(['input', 'query'])('should throw if request.%s is defined', async (key) => {
|
|
111
|
+
it.each([['input', 'query']])('should throw if request.%s is defined', async (key) => {
|
|
112
112
|
expect.assertions(1)
|
|
113
113
|
|
|
114
114
|
declaration[key] = { id: generate() }
|
|
115
115
|
declaration.request = /** @type {toa.samples.Operation} */ { [key]: { id: generate() } }
|
|
116
116
|
|
|
117
|
-
|
|
118
|
-
check()
|
|
119
|
-
} catch (exception) {
|
|
120
|
-
expect(exception).toMatchObject({ path: '/request' })
|
|
121
|
-
}
|
|
117
|
+
expect(() => check()).toThrow('/request')
|
|
122
118
|
})
|
|
123
119
|
})
|
|
@@ -35,7 +35,7 @@ describe('validation', () => {
|
|
|
35
35
|
it('should not allow additional properties', () => {
|
|
36
36
|
declaration.foo = generate()
|
|
37
37
|
|
|
38
|
-
expect(() => translate(declaration, true)).toThrow('
|
|
38
|
+
expect(() => translate(declaration, true)).toThrow('not expected')
|
|
39
39
|
})
|
|
40
40
|
})
|
|
41
41
|
|
|
@@ -2,33 +2,29 @@
|
|
|
2
2
|
|
|
3
3
|
'use strict'
|
|
4
4
|
|
|
5
|
-
const { generate } = require('randomstring')
|
|
6
5
|
const { Locator } = require('@toa.io/core')
|
|
6
|
+
const stage = jest.requireActual('@toa.io/userland/stage')
|
|
7
7
|
|
|
8
|
-
const
|
|
9
|
-
const name = generate()
|
|
10
|
-
const namespace = generate()
|
|
11
|
-
|
|
12
|
-
return new Locator(name, namespace)
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
// stage
|
|
16
|
-
const manifest = jest.fn(async (path) => ({ path, locator: locator() }))
|
|
8
|
+
const manifest = jest.fn(async (path) => stage.manifest(path))
|
|
17
9
|
const composition = jest.fn()
|
|
18
10
|
const shutdown = jest.fn()
|
|
19
11
|
|
|
20
12
|
const remote = jest.fn(async (id) => {
|
|
21
13
|
const [namespace, name] = id.split('.')
|
|
22
14
|
const locator = new Locator(name, namespace)
|
|
23
|
-
const invoke = jest.fn(async (
|
|
15
|
+
const invoke = jest.fn(async (endpoint, request) => request.reply)
|
|
24
16
|
const disconnect = jest.fn(async () => undefined)
|
|
25
17
|
|
|
26
18
|
return { locator, invoke, disconnect }
|
|
27
19
|
})
|
|
28
20
|
|
|
21
|
+
const component = jest.fn(async () => {
|
|
22
|
+
const invoke = jest.fn(async (endpoint, request) => request.reply)
|
|
23
|
+
|
|
24
|
+
return { invoke }
|
|
25
|
+
})
|
|
26
|
+
|
|
29
27
|
const emit = jest.fn()
|
|
30
28
|
const binding = { binding: { emit } }
|
|
31
29
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
exports.stage = stage
|
|
30
|
+
exports.stage = { manifest, composition, component, remote, shutdown, binding }
|