@toa.io/norm 1.0.0-alpha.274 → 1.0.0-alpha.278
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/CHANGELOG.md +17 -0
- package/package.json +8 -7
- package/src/.component/.expand/bridge.js +2 -6
- package/src/.component/.expand/entity.js +2 -6
- package/src/.component/.expand/events.js +2 -6
- package/src/.component/.expand/extensions.js +2 -6
- package/src/.component/.expand/index.js +8 -19
- package/src/.component/.expand/operations.js +2 -6
- package/src/.component/.expand/properties.js +2 -6
- package/src/.component/.expand/receivers.js +2 -6
- package/src/.component/.expand/version.js +4 -8
- package/src/.component/.normalize/events.js +12 -5
- package/src/.component/.normalize/index.js +3 -9
- package/src/.component/.normalize/operations.js +1 -5
- package/src/.component/.normalize/receivers.js +1 -5
- package/src/.component/collapse.js +2 -6
- package/src/.component/defaults.js +2 -6
- package/src/.component/dependencies.js +7 -6
- package/src/.component/dereference.js +2 -6
- package/src/.component/expand.js +2 -15
- package/src/.component/extensions.js +6 -9
- package/src/.component/index.js +9 -21
- package/src/.component/merge.js +7 -8
- package/src/.component/normalize.js +3 -7
- package/src/.component/validate.js +11 -13
- package/src/.context/.dependencies/connectors.js +2 -6
- package/src/.context/.dependencies/describe.js +1 -5
- package/src/.context/.dependencies/extensions.js +4 -7
- package/src/.context/.dependencies/index.js +3 -9
- package/src/.context/.dependencies/load.js +14 -13
- package/src/.context/.dependencies/resolve.js +6 -10
- package/src/.context/complete.js +1 -5
- package/src/.context/dependencies.js +2 -6
- package/src/.context/dereference.js +1 -5
- package/src/.context/expand.js +2 -6
- package/src/.context/index.js +6 -15
- package/src/.context/normalize.js +2 -6
- package/src/.context/validate.js +7 -11
- package/src/component.js +14 -25
- package/src/context.js +12 -21
- package/src/index.js +3 -9
- package/src/shortcuts.js +4 -10
- package/test/component/collapse.fixtures.js +2 -5
- package/test/component/collapse.test.js +17 -10
- package/test/component/dependencies.test.js +12 -10
- package/test/component/dereference.fixtures.js +2 -7
- package/test/component/dereference.test.js +9 -8
- package/test/component/dummies/extension/index.js +1 -5
- package/test/component/expand.fixtures.js +3 -8
- package/test/component/expand.test.js +10 -9
- package/test/component/normalize.fixtures.js +3 -7
- package/test/component/normalize.test.js +20 -18
- package/test/component/validate.fixtures.js +1 -5
- package/test/component/validate.test.js +88 -86
- package/test/context/complete.fixtures.js +2 -7
- package/test/context/complete.test.js +10 -8
- package/test/context/dependencies.load.test.js +13 -12
- package/test/context/dereference.fixtures.js +3 -8
- package/test/context/dereference.test.js +8 -7
- package/test/context/expand.fixtures.js +1 -5
- package/test/context/expand.test.js +9 -8
- package/test/context/normalize.fixtures.js +2 -6
- package/test/context/normalize.test.js +10 -8
- package/test/context/validate.fixtures.js +1 -5
- package/test/context/validate.test.js +20 -19
- package/test/shortcuts.fixtures.js +4 -9
- package/test/shortcuts.test.js +16 -15
- package/types/context/declaration.d.ts +1 -1
- package/types/context.d.ts +2 -2
- package/types/index.d.ts +3 -3
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
import { it, beforeEach } from 'node:test'
|
|
2
|
+
import assert from 'node:assert/strict'
|
|
2
3
|
|
|
3
|
-
|
|
4
|
+
import clone from 'clone-deep'
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
import { expand } from '../../src/.component/index.js'
|
|
7
|
+
import * as fixtures from './expand.fixtures.js'
|
|
7
8
|
|
|
8
9
|
let source
|
|
9
10
|
|
|
@@ -13,13 +14,13 @@ beforeEach(() => {
|
|
|
13
14
|
|
|
14
15
|
it('should expand', async () => {
|
|
15
16
|
await expand(source)
|
|
16
|
-
|
|
17
|
+
assert.partialDeepStrictEqual(source, fixtures.target)
|
|
17
18
|
})
|
|
18
19
|
|
|
19
20
|
it('should derive version from the component contents', async () => {
|
|
20
21
|
await expand(source)
|
|
21
22
|
|
|
22
|
-
|
|
23
|
+
assert.match(source.version, /^[0-9a-f]{8}$/)
|
|
23
24
|
})
|
|
24
25
|
|
|
25
26
|
it('should keep declared version', async () => {
|
|
@@ -27,7 +28,7 @@ it('should keep declared version', async () => {
|
|
|
27
28
|
|
|
28
29
|
await expand(source)
|
|
29
30
|
|
|
30
|
-
|
|
31
|
+
assert.deepStrictEqual(source.version, '1.0.0')
|
|
31
32
|
})
|
|
32
33
|
|
|
33
34
|
it('should recognize storages.queues', async () => {
|
|
@@ -37,6 +38,6 @@ it('should recognize storages.queues', async () => {
|
|
|
37
38
|
|
|
38
39
|
await expand(source)
|
|
39
40
|
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
assert.strictEqual(source.queues, undefined)
|
|
42
|
+
assert.partialDeepStrictEqual(source.properties['@toa.io/storages.queues'], queues)
|
|
42
43
|
})
|
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
import { generate } from 'randomstring'
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
const operations = {
|
|
3
|
+
export const operations = {
|
|
6
4
|
namespace: 'dummies',
|
|
7
5
|
name: 'dummy',
|
|
8
|
-
path:
|
|
6
|
+
path: import.meta.dirname,
|
|
9
7
|
bindings: ['foo', 'bar'],
|
|
10
8
|
'bindings@local': ['foo'],
|
|
11
9
|
operations: {
|
|
@@ -22,5 +20,3 @@ const operations = {
|
|
|
22
20
|
}
|
|
23
21
|
}
|
|
24
22
|
}
|
|
25
|
-
|
|
26
|
-
exports.operations = operations
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { describe, it, beforeEach } from 'node:test'
|
|
2
|
+
import assert from 'node:assert/strict'
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
import clone from 'clone-deep'
|
|
5
|
+
|
|
6
|
+
import { normalize, extensions } from '../../src/.component/index.js'
|
|
7
|
+
import * as fixtures from './normalize.fixtures.js'
|
|
6
8
|
|
|
7
9
|
let manifest
|
|
8
10
|
|
|
@@ -11,27 +13,27 @@ beforeEach(() => {
|
|
|
11
13
|
})
|
|
12
14
|
|
|
13
15
|
describe('operations', () => {
|
|
14
|
-
it('should set default bindings', () => {
|
|
15
|
-
normalize(manifest)
|
|
16
|
+
it('should set default bindings', async () => {
|
|
17
|
+
await normalize(manifest)
|
|
16
18
|
|
|
17
|
-
|
|
19
|
+
assert.deepStrictEqual(manifest.operations.add.bindings, manifest.bindings)
|
|
18
20
|
})
|
|
19
21
|
})
|
|
20
22
|
|
|
21
23
|
describe('extensions', () => {
|
|
22
|
-
it('should add predefined extensions', () => {
|
|
23
|
-
extensions(manifest)
|
|
24
|
+
it('should add predefined extensions', async () => {
|
|
25
|
+
await extensions(manifest)
|
|
24
26
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
+
assert.strictEqual(manifest.extensions['@toa.io/extensions.telemetry'], null)
|
|
28
|
+
assert.strictEqual(manifest.extensions['@toa.io/extensions.fetch'], null)
|
|
27
29
|
})
|
|
28
30
|
|
|
29
|
-
it('should add predefined extensions without explicit declarations', () => {
|
|
31
|
+
it('should add predefined extensions without explicit declarations', async () => {
|
|
30
32
|
delete manifest.extensions
|
|
31
33
|
|
|
32
|
-
extensions(manifest)
|
|
34
|
+
await extensions(manifest)
|
|
33
35
|
|
|
34
|
-
|
|
36
|
+
assert.deepStrictEqual(manifest.extensions, {
|
|
35
37
|
'@toa.io/extensions.telemetry': null,
|
|
36
38
|
'@toa.io/extensions.fetch': null,
|
|
37
39
|
'@toa.io/extensions.introspection': {}
|
|
@@ -45,9 +47,9 @@ describe('receivers', () => {
|
|
|
45
47
|
'messages.created': 'add'
|
|
46
48
|
}
|
|
47
49
|
|
|
48
|
-
normalize(manifest)
|
|
50
|
+
await normalize(manifest)
|
|
49
51
|
|
|
50
|
-
|
|
52
|
+
assert.deepStrictEqual(manifest.receivers, {
|
|
51
53
|
'default.messages.created': 'add'
|
|
52
54
|
})
|
|
53
55
|
})
|
|
@@ -62,9 +64,9 @@ describe('receivers', () => {
|
|
|
62
64
|
'messages.created': receiver
|
|
63
65
|
}
|
|
64
66
|
|
|
65
|
-
normalize(manifest)
|
|
67
|
+
await normalize(manifest)
|
|
66
68
|
|
|
67
|
-
|
|
69
|
+
assert.deepStrictEqual(manifest.receivers, {
|
|
68
70
|
'messages.created': receiver
|
|
69
71
|
})
|
|
70
72
|
})
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
import { describe, it, beforeEach } from 'node:test'
|
|
2
|
+
import assert from 'node:assert/strict'
|
|
2
3
|
|
|
3
|
-
|
|
4
|
+
import clone from 'clone-deep'
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
import { validate } from '../../src/.component/index.js'
|
|
7
|
+
import * as fixtures from './validate.fixtures.js'
|
|
7
8
|
|
|
8
9
|
let manifest
|
|
9
10
|
|
|
@@ -11,248 +12,249 @@ beforeEach(() => {
|
|
|
11
12
|
manifest = clone(fixtures.ok)
|
|
12
13
|
})
|
|
13
14
|
|
|
14
|
-
it('should be ok', () => {
|
|
15
|
-
|
|
15
|
+
it('should be ok', async () => {
|
|
16
|
+
await assert.doesNotReject(validate(manifest))
|
|
16
17
|
})
|
|
17
18
|
|
|
18
|
-
it('should provide error', () => {
|
|
19
|
+
it('should provide error', async () => {
|
|
19
20
|
manifest.foo = 'bar'
|
|
20
21
|
|
|
21
|
-
|
|
22
|
+
await assert.rejects(validate(manifest))
|
|
22
23
|
})
|
|
23
24
|
|
|
24
|
-
it('should not have additional properties', () => {
|
|
25
|
+
it('should not have additional properties', async () => {
|
|
25
26
|
manifest.foo = 'bar'
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
await assert.rejects(validate(manifest))
|
|
28
29
|
})
|
|
29
30
|
|
|
30
31
|
describe('namespace', () => {
|
|
31
|
-
it('should match token pattern', () => {
|
|
32
|
+
it('should match token pattern', async () => {
|
|
32
33
|
manifest.namespace = '1'
|
|
33
|
-
|
|
34
|
+
await assert.rejects(validate(manifest), (error) => /must match pattern/.test(error.message))
|
|
34
35
|
|
|
35
36
|
manifest.namespace = 'foo_'
|
|
36
|
-
|
|
37
|
+
await assert.rejects(validate(manifest), (error) => /must match pattern/.test(error.message))
|
|
37
38
|
|
|
38
39
|
manifest.namespace = 'foo_bar'
|
|
39
|
-
|
|
40
|
+
await assert.rejects(validate(manifest), (error) => /must match pattern/.test(error.message))
|
|
40
41
|
|
|
41
42
|
manifest.namespace = 'foo-'
|
|
42
|
-
|
|
43
|
+
await assert.rejects(validate(manifest), (error) => /must match pattern/.test(error.message))
|
|
43
44
|
|
|
44
45
|
manifest.namespace = 'foo-bar'
|
|
45
|
-
|
|
46
|
+
await assert.rejects(validate(manifest), (error) => /must match pattern/.test(error.message))
|
|
46
47
|
|
|
47
48
|
manifest.namespace = 'FooBar12'
|
|
48
|
-
|
|
49
|
+
await assert.doesNotReject(validate(manifest))
|
|
49
50
|
})
|
|
50
51
|
|
|
51
|
-
it('should forbid \'system\' namespace', () => {
|
|
52
|
+
it('should forbid \'system\' namespace', async () => {
|
|
52
53
|
manifest.namespace = 'system'
|
|
53
|
-
|
|
54
|
+
await assert.rejects(validate(manifest), (error) => /must NOT be valid/.test(error.message))
|
|
54
55
|
})
|
|
55
56
|
|
|
56
57
|
it('should set `default` namespace', async () => {
|
|
57
58
|
delete manifest.namespace
|
|
58
59
|
|
|
59
|
-
|
|
60
|
-
|
|
60
|
+
await assert.doesNotReject(validate(manifest))
|
|
61
|
+
assert.deepStrictEqual(manifest.namespace, 'default')
|
|
61
62
|
})
|
|
62
63
|
})
|
|
63
64
|
|
|
64
65
|
describe('name', () => {
|
|
65
|
-
it('should be optional', () => {
|
|
66
|
+
it('should be optional', async () => {
|
|
66
67
|
delete manifest.name
|
|
67
|
-
|
|
68
|
+
await assert.doesNotReject(validate(manifest))
|
|
68
69
|
})
|
|
69
70
|
})
|
|
70
71
|
|
|
71
72
|
describe('entity', () => {
|
|
72
|
-
it('should be optional', () => {
|
|
73
|
+
it('should be optional', async () => {
|
|
73
74
|
delete manifest.entity
|
|
74
|
-
|
|
75
|
+
await assert.doesNotReject(validate(manifest))
|
|
75
76
|
})
|
|
76
77
|
|
|
77
|
-
it('should be object', () => {
|
|
78
|
+
it('should be object', async () => {
|
|
78
79
|
manifest.entity = 'foo'
|
|
79
|
-
|
|
80
|
+
await assert.rejects(validate(manifest), (error) => /must be object/.test(error.message))
|
|
80
81
|
})
|
|
81
82
|
|
|
82
|
-
it('should not have additional properties', () => {
|
|
83
|
+
it('should not have additional properties', async () => {
|
|
83
84
|
manifest.entity.foo = 'bar'
|
|
84
|
-
|
|
85
|
+
await assert.rejects(validate(manifest))
|
|
85
86
|
})
|
|
86
87
|
|
|
87
88
|
describe('schema', () => {
|
|
88
|
-
it('should be required', () => {
|
|
89
|
+
it('should be required', async () => {
|
|
89
90
|
delete manifest.entity.schema
|
|
90
|
-
|
|
91
|
+
await assert.rejects(validate(manifest))
|
|
91
92
|
})
|
|
92
93
|
|
|
93
|
-
it('should be JSON schema object', () => {
|
|
94
|
+
it('should be JSON schema object', async () => {
|
|
94
95
|
manifest.entity.schema = { properties: { foo: 'bar' } }
|
|
95
|
-
|
|
96
|
+
await assert.rejects(validate(manifest))
|
|
96
97
|
})
|
|
97
98
|
|
|
98
|
-
it('should be JSON schema object of type object', () => {
|
|
99
|
+
it('should be JSON schema object of type object', async () => {
|
|
99
100
|
manifest.entity.schema = { type: 'integer' }
|
|
100
|
-
|
|
101
|
+
await assert.rejects(validate(manifest), (error) => /must be equal to constant/.test(error.message))
|
|
101
102
|
|
|
102
103
|
manifest.entity.schema = {}
|
|
103
104
|
validate(manifest)
|
|
104
|
-
|
|
105
|
+
assert.strictEqual(manifest.entity.schema.type, 'object')
|
|
105
106
|
})
|
|
106
107
|
|
|
107
|
-
it('should have property names matching token pattern', () => {
|
|
108
|
+
it('should have property names matching token pattern', async () => {
|
|
108
109
|
manifest.entity.schema.properties._foo = { type: 'string' }
|
|
109
|
-
|
|
110
|
+
await assert.rejects(validate(manifest), (error) => /pattern/.test(error.message))
|
|
110
111
|
})
|
|
111
112
|
|
|
112
|
-
it('should allow default id', () => {
|
|
113
|
+
it('should allow default id', async () => {
|
|
113
114
|
manifest.entity.schema.properties.id = {
|
|
114
115
|
type: 'string',
|
|
115
116
|
pattern: '^[a-fA-F0-9]+$'
|
|
116
117
|
}
|
|
117
|
-
|
|
118
|
+
await assert.doesNotReject(validate(manifest))
|
|
118
119
|
})
|
|
119
120
|
})
|
|
120
121
|
|
|
121
122
|
describe('associated', () => {
|
|
122
|
-
it('should provide default', () => {
|
|
123
|
-
|
|
124
|
-
|
|
123
|
+
it('should provide default', async () => {
|
|
124
|
+
await assert.doesNotReject(validate(manifest))
|
|
125
|
+
assert.strictEqual(manifest.entity.associated, false)
|
|
125
126
|
})
|
|
126
127
|
})
|
|
127
128
|
})
|
|
128
129
|
|
|
129
130
|
describe('bindings', () => {
|
|
130
|
-
it('should be array of unique strings', () => {
|
|
131
|
+
it('should be array of unique strings', async () => {
|
|
131
132
|
manifest.bindings = 'oops'
|
|
132
|
-
|
|
133
|
+
await assert.rejects(validate(manifest), (error) => /must be array/.test(error.message))
|
|
133
134
|
|
|
134
135
|
manifest.bindings = ['oops', 'oops']
|
|
135
|
-
|
|
136
|
+
await assert.rejects(validate(manifest), (error) => /duplicate items/.test(error.message))
|
|
136
137
|
|
|
137
138
|
manifest.bindings = ['oops', {}]
|
|
138
|
-
|
|
139
|
+
await assert.rejects(validate(manifest), (error) => /must be string/.test(error.message))
|
|
139
140
|
})
|
|
140
141
|
|
|
141
|
-
it('should forbid explicit loop', () => {
|
|
142
|
+
it('should forbid explicit loop', async () => {
|
|
142
143
|
manifest.bindings = ['@toa.io/bindings.loop']
|
|
143
|
-
|
|
144
|
+
await assert.rejects(validate(manifest), (error) => /must NOT be valid/.test(error.message))
|
|
144
145
|
})
|
|
145
146
|
})
|
|
146
147
|
|
|
147
148
|
describe('operations', () => {
|
|
148
|
-
it('should be object', () => {
|
|
149
|
+
it('should be object', async () => {
|
|
149
150
|
manifest.operations.get = 'bar'
|
|
150
|
-
|
|
151
|
+
await assert.rejects(validate(manifest), (error) => /must be object/.test(error.message))
|
|
151
152
|
})
|
|
152
153
|
|
|
153
|
-
it('should not have additional properties', () => {
|
|
154
|
+
it('should not have additional properties', async () => {
|
|
154
155
|
manifest.operations.get.foo = 'bar'
|
|
155
|
-
|
|
156
|
+
await assert.rejects(validate(manifest))
|
|
156
157
|
})
|
|
157
158
|
|
|
158
|
-
it('should have type (transition or observation)', () => {
|
|
159
|
+
it('should have type (transition or observation)', async () => {
|
|
159
160
|
delete manifest.operations.get.type
|
|
160
|
-
|
|
161
|
+
await assert.rejects(validate(manifest))
|
|
161
162
|
|
|
162
163
|
manifest.operations.get.type = 'foo'
|
|
163
|
-
|
|
164
|
+
await assert.rejects(validate(manifest), (error) => /one of the allowed values/.test(error.message))
|
|
164
165
|
})
|
|
165
166
|
|
|
166
|
-
it('should forbid explicit loop', () => {
|
|
167
|
+
it('should forbid explicit loop', async () => {
|
|
167
168
|
manifest.operations.get.bindings = ['@toa.io/bindings.loop']
|
|
168
|
-
|
|
169
|
+
await assert.rejects(validate(manifest), (error) => /must NOT be valid/.test(error.message))
|
|
169
170
|
})
|
|
170
171
|
|
|
171
|
-
it('should forbid query: false for observations', () => {
|
|
172
|
+
it('should forbid query: false for observations', async () => {
|
|
172
173
|
manifest.operations.get.query = false
|
|
173
|
-
|
|
174
|
+
await assert.rejects(validate(manifest), (error) => /must NOT be valid/.test(error.message))
|
|
174
175
|
})
|
|
175
176
|
|
|
176
|
-
|
|
177
|
+
for (const [_, operation] of [
|
|
177
178
|
['computation', 'compute']
|
|
178
|
-
])
|
|
179
|
+
])
|
|
180
|
+
it(`should set query: false for ${_}`, async () => {
|
|
179
181
|
validate(manifest)
|
|
180
182
|
|
|
181
|
-
|
|
183
|
+
assert.strictEqual(manifest.operations[operation].query, false)
|
|
182
184
|
})
|
|
183
185
|
|
|
184
186
|
describe('scope', () => {
|
|
185
|
-
it('should have scope', () => {
|
|
187
|
+
it('should have scope', async () => {
|
|
186
188
|
delete manifest.operations.get.scope
|
|
187
|
-
|
|
189
|
+
await assert.rejects(validate(manifest), (error) => /required property/.test(error.message))
|
|
188
190
|
})
|
|
189
191
|
|
|
190
|
-
it('should allow only entity or set for observations', () => {
|
|
192
|
+
it('should allow only entity or set for observations', async () => {
|
|
191
193
|
manifest.operations.get.scope = 'changeset'
|
|
192
|
-
|
|
194
|
+
await assert.rejects(validate(manifest), (error) => /allowed values/.test(error.message))
|
|
193
195
|
})
|
|
194
196
|
|
|
195
|
-
it('should allow only entity for transitions', () => {
|
|
197
|
+
it('should allow only entity for transitions', async () => {
|
|
196
198
|
manifest.operations.add.scope = 'changeset'
|
|
197
|
-
|
|
199
|
+
await assert.rejects(validate(manifest), (error) => /allowed values/.test(error.message))
|
|
198
200
|
|
|
199
201
|
manifest.operations.add.scope = 'set'
|
|
200
|
-
|
|
202
|
+
await assert.rejects(validate(manifest), (error) => /allowed values/.test(error.message))
|
|
201
203
|
})
|
|
202
204
|
|
|
203
|
-
it('should allow only changeset for assignments', () => {
|
|
205
|
+
it('should allow only changeset for assignments', async () => {
|
|
204
206
|
manifest.operations.set.scope = 'changeset'
|
|
205
|
-
|
|
207
|
+
await assert.doesNotReject(validate(manifest))
|
|
206
208
|
|
|
207
209
|
manifest.operations.set.scope = 'set'
|
|
208
|
-
|
|
210
|
+
await assert.rejects(validate(manifest), (error) => /allowed values/.test(error.message))
|
|
209
211
|
})
|
|
210
212
|
})
|
|
211
213
|
|
|
212
214
|
describe('concurrency', () => {
|
|
213
|
-
it('should be required for transitions', () => {
|
|
215
|
+
it('should be required for transitions', async () => {
|
|
214
216
|
delete manifest.operations.add.concurrency
|
|
215
|
-
|
|
217
|
+
await assert.rejects(validate(manifest), (error) => /required property/.test(error.message))
|
|
216
218
|
})
|
|
217
219
|
|
|
218
|
-
it('should throw for observations, assignments', () => {
|
|
220
|
+
it('should throw for observations, assignments', async () => {
|
|
219
221
|
manifest.operations.get.concurrency = 'none'
|
|
220
|
-
|
|
222
|
+
await assert.rejects(validate(manifest))
|
|
221
223
|
delete manifest.operations.get.concurrency
|
|
222
224
|
|
|
223
225
|
manifest.operations.set.concurrency = 'none'
|
|
224
|
-
|
|
226
|
+
await assert.rejects(validate(manifest))
|
|
225
227
|
})
|
|
226
228
|
})
|
|
227
229
|
|
|
228
230
|
describe('input, output', () => {
|
|
229
|
-
it('should be schema', () => {
|
|
231
|
+
it('should be schema', async () => {
|
|
230
232
|
manifest.operations.get.input = { properties: { foo: 'bar' } }
|
|
231
|
-
|
|
233
|
+
await assert.rejects(validate(manifest))
|
|
232
234
|
|
|
233
235
|
delete manifest.operations.get.input
|
|
234
236
|
manifest.operations.get.output = { properties: { foo: 'bar' } }
|
|
235
|
-
|
|
237
|
+
await assert.rejects(validate(manifest))
|
|
236
238
|
})
|
|
237
239
|
})
|
|
238
240
|
})
|
|
239
241
|
|
|
240
242
|
describe('receivers', () => {
|
|
241
|
-
it('should throw if transition points to undefined operation', () => {
|
|
243
|
+
it('should throw if transition points to undefined operation', async () => {
|
|
242
244
|
manifest.receivers['foo.bar.happened'].operation = 'notExists'
|
|
243
245
|
|
|
244
|
-
|
|
246
|
+
await assert.rejects(validate(manifest), (error) => /refers to undefined operation/.test(error.message))
|
|
245
247
|
})
|
|
246
248
|
|
|
247
|
-
it('should throw if transition points to observation', () => {
|
|
249
|
+
it('should throw if transition points to observation', async () => {
|
|
248
250
|
manifest.receivers['foo.bar.happened'].operation = 'get'
|
|
249
251
|
|
|
250
|
-
|
|
252
|
+
await assert.rejects(validate(manifest), (error) => /of the allowed types/.test(error.message))
|
|
251
253
|
})
|
|
252
254
|
|
|
253
255
|
it('should throw if source has a name `context`', async () => {
|
|
254
256
|
manifest.receivers['foo.bar.happened'].source = 'context'
|
|
255
257
|
|
|
256
|
-
|
|
258
|
+
await assert.rejects(validate(manifest), (error) => /must NOT be valid/.test(error.message))
|
|
257
259
|
})
|
|
258
260
|
})
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
1
|
const component = (id) => {
|
|
4
2
|
const [namespace, name] = id.split('.')
|
|
5
3
|
|
|
@@ -16,7 +14,7 @@ const component = (id) => {
|
|
|
16
14
|
}
|
|
17
15
|
}
|
|
18
16
|
|
|
19
|
-
const context = {
|
|
17
|
+
export const context = {
|
|
20
18
|
runtime: '0.0.0',
|
|
21
19
|
name: 'test',
|
|
22
20
|
description: 'context fixture',
|
|
@@ -42,7 +40,7 @@ const context = {
|
|
|
42
40
|
}
|
|
43
41
|
|
|
44
42
|
/** @type {Array<toa.norm.context.Composition>} */
|
|
45
|
-
const compositions = [
|
|
43
|
+
export const compositions = [
|
|
46
44
|
...context.compositions,
|
|
47
45
|
{
|
|
48
46
|
name: 'd-a',
|
|
@@ -53,6 +51,3 @@ const compositions = [
|
|
|
53
51
|
components: [component('d.b')]
|
|
54
52
|
}
|
|
55
53
|
]
|
|
56
|
-
|
|
57
|
-
exports.context = context
|
|
58
|
-
exports.compositions = compositions
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
import { it, beforeEach } from 'node:test'
|
|
2
|
+
import assert from 'node:assert/strict'
|
|
3
|
+
import { isDeepStrictEqual } from 'node:util'
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
import clone from 'clone-deep'
|
|
4
6
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
+
import { complete } from '../../src/.context/index.js'
|
|
8
|
+
import * as fixtures from './complete.fixtures.js'
|
|
7
9
|
|
|
8
10
|
/** @type {toa.norm.Context} */
|
|
9
11
|
let context
|
|
@@ -14,8 +16,8 @@ beforeEach(() => {
|
|
|
14
16
|
})
|
|
15
17
|
|
|
16
18
|
it('should complete compositions', () => {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
+
assert.deepStrictEqual(context.compositions.length, fixtures.compositions.length)
|
|
20
|
+
assert.ok(fixtures.compositions.every((item) => context.compositions.some((candidate) => isDeepStrictEqual(candidate, item))))
|
|
19
21
|
})
|
|
20
22
|
|
|
21
23
|
it('should create if compositions are not set', () => {
|
|
@@ -26,6 +28,6 @@ it('should create if compositions are not set', () => {
|
|
|
26
28
|
components: [component]
|
|
27
29
|
}))
|
|
28
30
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
+
assert.doesNotThrow(() => complete(context))
|
|
32
|
+
assert.deepStrictEqual(context.compositions, compositions)
|
|
31
33
|
})
|
|
@@ -1,24 +1,25 @@
|
|
|
1
|
-
|
|
1
|
+
import { it } from 'node:test'
|
|
2
|
+
import assert from 'node:assert/strict'
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
4
|
+
import { join } from 'node:path'
|
|
5
|
+
import { load } from '../../src/.context/.dependencies/load.js'
|
|
5
6
|
|
|
6
7
|
it('should be', async () => {
|
|
7
|
-
|
|
8
|
+
assert.ok(load instanceof Function)
|
|
8
9
|
})
|
|
9
10
|
|
|
10
11
|
it('should load module', async () => {
|
|
11
|
-
const path = join(
|
|
12
|
-
const { metadata, module } = load(path)
|
|
12
|
+
const path = join(import.meta.dirname, '../../')
|
|
13
|
+
const { metadata, module } = await load(path)
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
assert.deepStrictEqual(metadata.name, '@toa.io/norm')
|
|
16
|
+
assert.ok(module.context instanceof Function)
|
|
16
17
|
})
|
|
17
18
|
|
|
18
19
|
it('should return null metadata if no package.json', async () => {
|
|
19
|
-
const path = join(
|
|
20
|
-
const { metadata, module } = load(path)
|
|
20
|
+
const path = join(import.meta.dirname, '../../src')
|
|
21
|
+
const { metadata, module } = await load(path)
|
|
21
22
|
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
assert.strictEqual(metadata, null)
|
|
24
|
+
assert.ok(module.context instanceof Function)
|
|
24
25
|
})
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const clone = require('clone-deep')
|
|
1
|
+
import clone from 'clone-deep'
|
|
4
2
|
|
|
5
3
|
/**
|
|
6
4
|
* @param id {string}
|
|
@@ -22,7 +20,7 @@ const component = (id) => {
|
|
|
22
20
|
}
|
|
23
21
|
}
|
|
24
22
|
|
|
25
|
-
const context = {
|
|
23
|
+
export const context = {
|
|
26
24
|
name: 'test',
|
|
27
25
|
description: 'context fixture',
|
|
28
26
|
version: '0.0.0',
|
|
@@ -41,7 +39,7 @@ const context = {
|
|
|
41
39
|
]
|
|
42
40
|
}
|
|
43
41
|
|
|
44
|
-
const expected = clone(context)
|
|
42
|
+
export const expected = clone(context)
|
|
45
43
|
|
|
46
44
|
expected.compositions = [
|
|
47
45
|
{
|
|
@@ -53,6 +51,3 @@ expected.compositions = [
|
|
|
53
51
|
components: [component('d.c'), component('a.b')]
|
|
54
52
|
}
|
|
55
53
|
]
|
|
56
|
-
|
|
57
|
-
exports.context = context
|
|
58
|
-
exports.expected = expected
|