cddl2py 0.0.1 → 0.1.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/LICENSE +21 -0
- package/README.md +136 -0
- package/bin/cddl2py.js +0 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +246 -30
- package/package.json +12 -8
- package/.release-it.ts +0 -11
- package/src/cli.ts +0 -42
- package/src/constants.ts +0 -32
- package/src/index.ts +0 -658
- package/src/utils.ts +0 -12
- package/tests/__snapshots__/complex_types.test.ts.snap +0 -81
- package/tests/__snapshots__/group_choice.test.ts.snap +0 -127
- package/tests/__snapshots__/literals.test.ts.snap +0 -15
- package/tests/__snapshots__/mixin_union.test.ts.snap +0 -65
- package/tests/__snapshots__/mod.test.ts.snap +0 -145
- package/tests/__snapshots__/named_group_choice.test.ts.snap +0 -37
- package/tests/__snapshots__/transform.test.ts.snap +0 -137
- package/tests/__snapshots__/webdriver_local.test.ts.snap +0 -921
- package/tests/__snapshots__/webdriver_remote.test.ts.snap +0 -1249
- package/tests/complex_types.test.ts +0 -92
- package/tests/group_choice.test.ts +0 -88
- package/tests/literals.test.ts +0 -63
- package/tests/mixin_union.test.ts +0 -80
- package/tests/mod.test.ts +0 -106
- package/tests/named_group_choice.test.ts +0 -82
- package/tests/transform.test.ts +0 -149
- package/tests/transform_edge_cases.test.ts +0 -265
- package/tests/unknown.test.ts +0 -72
- package/tests/webdriver_local.test.ts +0 -64
- package/tests/webdriver_remote.test.ts +0 -64
- package/tsconfig.json +0 -11
|
@@ -1,265 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest'
|
|
2
|
-
|
|
3
|
-
import type {
|
|
4
|
-
Array as CDDLArray,
|
|
5
|
-
Comment,
|
|
6
|
-
Group,
|
|
7
|
-
Operator,
|
|
8
|
-
Property,
|
|
9
|
-
PropertyReference,
|
|
10
|
-
Tag,
|
|
11
|
-
Variable
|
|
12
|
-
} from 'cddl'
|
|
13
|
-
|
|
14
|
-
import { transform } from '../src/index.js'
|
|
15
|
-
|
|
16
|
-
const COMMENTS: Comment[] = []
|
|
17
|
-
|
|
18
|
-
function comment (content: string, leading = false): Comment {
|
|
19
|
-
return {
|
|
20
|
-
Type: 'comment',
|
|
21
|
-
Content: content,
|
|
22
|
-
Leading: leading
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function groupRef (value: string, operator?: Operator): PropertyReference {
|
|
27
|
-
return {
|
|
28
|
-
Type: 'group',
|
|
29
|
-
Value: value,
|
|
30
|
-
Unwrapped: false,
|
|
31
|
-
Operator: operator
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function rangeRef (): PropertyReference {
|
|
36
|
-
return {
|
|
37
|
-
Type: 'range',
|
|
38
|
-
Value: {
|
|
39
|
-
Min: 0,
|
|
40
|
-
Max: 10,
|
|
41
|
-
Inclusive: true
|
|
42
|
-
},
|
|
43
|
-
Unwrapped: false
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
function tagRef (typePart: string): PropertyReference {
|
|
48
|
-
return {
|
|
49
|
-
Type: 'tag',
|
|
50
|
-
Value: {
|
|
51
|
-
NumericPart: 1,
|
|
52
|
-
TypePart: typePart
|
|
53
|
-
} satisfies Tag,
|
|
54
|
-
Unwrapped: false
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function literal (value: unknown): PropertyReference {
|
|
59
|
-
return {
|
|
60
|
-
Type: 'literal',
|
|
61
|
-
Value: value as any,
|
|
62
|
-
Unwrapped: false
|
|
63
|
-
} as PropertyReference
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
function property (
|
|
67
|
-
name: string,
|
|
68
|
-
type: Property['Type'],
|
|
69
|
-
overrides: Partial<Property> = {}
|
|
70
|
-
): Property {
|
|
71
|
-
return {
|
|
72
|
-
HasCut: false,
|
|
73
|
-
Occurrence: { n: 1, m: 1 },
|
|
74
|
-
Name: name,
|
|
75
|
-
Type: type,
|
|
76
|
-
Comments: COMMENTS,
|
|
77
|
-
...overrides
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
function unnamedProperty (
|
|
82
|
-
type: Property['Type'],
|
|
83
|
-
overrides: Partial<Property> = {}
|
|
84
|
-
): Property {
|
|
85
|
-
return property('', type, overrides)
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
function group (
|
|
89
|
-
name: string,
|
|
90
|
-
properties: Group['Properties'],
|
|
91
|
-
comments: Comment[] = COMMENTS
|
|
92
|
-
): Group {
|
|
93
|
-
return {
|
|
94
|
-
Type: 'group',
|
|
95
|
-
Name: name,
|
|
96
|
-
IsChoiceAddition: false,
|
|
97
|
-
Properties: properties,
|
|
98
|
-
Comments: comments
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
function array (
|
|
103
|
-
name: string,
|
|
104
|
-
values: CDDLArray['Values'],
|
|
105
|
-
comments: Comment[] = COMMENTS
|
|
106
|
-
): CDDLArray {
|
|
107
|
-
return {
|
|
108
|
-
Type: 'array',
|
|
109
|
-
Name: name,
|
|
110
|
-
Values: values,
|
|
111
|
-
Comments: comments
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
function variable (
|
|
116
|
-
name: string,
|
|
117
|
-
propertyType: Variable['PropertyType'],
|
|
118
|
-
comments: Comment[] = COMMENTS
|
|
119
|
-
): Variable {
|
|
120
|
-
return {
|
|
121
|
-
Type: 'variable',
|
|
122
|
-
Name: name,
|
|
123
|
-
PropertyType: propertyType,
|
|
124
|
-
IsChoiceAddition: false,
|
|
125
|
-
Comments: comments
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
describe('transform edge cases', () => {
|
|
130
|
-
it('should generate pydantic variants for union mixins with shared fields', () => {
|
|
131
|
-
const output = transform([
|
|
132
|
-
group('base', [property('kind', 'tstr')]),
|
|
133
|
-
group('mixin-a', [property('a', 'int')]),
|
|
134
|
-
group('mixin-b', [property('b', 'int')]),
|
|
135
|
-
group('combined', [
|
|
136
|
-
unnamedProperty(groupRef('base')),
|
|
137
|
-
unnamedProperty([groupRef('mixin-a'), groupRef('mixin-b')]),
|
|
138
|
-
property('enabled', 'bool', {
|
|
139
|
-
Occurrence: { n: 0, m: 1 },
|
|
140
|
-
Operator: { Type: 'default', Value: literal(true) },
|
|
141
|
-
Comments: [comment('inline docs')]
|
|
142
|
-
})
|
|
143
|
-
], [comment('shared union mixin', true)])
|
|
144
|
-
], { pydantic: true })
|
|
145
|
-
|
|
146
|
-
expect(output).toContain('# shared union mixin')
|
|
147
|
-
expect(output).toContain('class _CombinedFields(BaseModel):')
|
|
148
|
-
expect(output).toContain('enabled: Optional[bool] = Field(default=True) # inline docs')
|
|
149
|
-
expect(output).toContain('class _CombinedVariant0(_CombinedFields, MixinA, Base):')
|
|
150
|
-
expect(output).toContain('class _CombinedVariant1(_CombinedFields, MixinB, Base):')
|
|
151
|
-
expect(output).toContain('Combined = Union[_CombinedVariant0, _CombinedVariant1]')
|
|
152
|
-
})
|
|
153
|
-
|
|
154
|
-
it('should collapse multiple union mixin groups into a single alias', () => {
|
|
155
|
-
const output = transform([
|
|
156
|
-
group('combined', [
|
|
157
|
-
unnamedProperty(groupRef('base')),
|
|
158
|
-
unnamedProperty([groupRef('mixin-a'), groupRef('mixin-b')]),
|
|
159
|
-
unnamedProperty([groupRef('mixin-c'), groupRef('mixin-d')])
|
|
160
|
-
])
|
|
161
|
-
])
|
|
162
|
-
|
|
163
|
-
expect(output).toContain('Combined = Union[Base, MixinA, MixinB, MixinC, MixinD]')
|
|
164
|
-
})
|
|
165
|
-
|
|
166
|
-
it('should handle empty arrays, choice arrays and nested arrays', () => {
|
|
167
|
-
const output = transform([
|
|
168
|
-
array('empty-list', [], [comment('empty array', true)]),
|
|
169
|
-
array('choice-list', [[
|
|
170
|
-
unnamedProperty('int'),
|
|
171
|
-
unnamedProperty('tstr')
|
|
172
|
-
]]),
|
|
173
|
-
array('nested-list', [
|
|
174
|
-
unnamedProperty(array('', [
|
|
175
|
-
unnamedProperty(['int', 'tstr'])
|
|
176
|
-
]))
|
|
177
|
-
])
|
|
178
|
-
])
|
|
179
|
-
|
|
180
|
-
expect(output).toContain('# empty array')
|
|
181
|
-
expect(output).toContain('EmptyList = list[Any]')
|
|
182
|
-
expect(output).toContain('ChoiceList = list[Union[int, str]]')
|
|
183
|
-
expect(output).toContain('NestedList = list[Union[int, str]]')
|
|
184
|
-
})
|
|
185
|
-
|
|
186
|
-
it('should resolve inline groups, refs, tags and ranges into python types', () => {
|
|
187
|
-
const output = transform([
|
|
188
|
-
variable('tuple-type', group('', [
|
|
189
|
-
unnamedProperty('int'),
|
|
190
|
-
unnamedProperty('tstr')
|
|
191
|
-
]) as any),
|
|
192
|
-
variable('choice-type', group('', [
|
|
193
|
-
[unnamedProperty('int'), unnamedProperty('tstr')],
|
|
194
|
-
unnamedProperty('bool')
|
|
195
|
-
]) as any),
|
|
196
|
-
variable('dict-type', group('', [
|
|
197
|
-
property('any', ['tstr'])
|
|
198
|
-
]) as any),
|
|
199
|
-
variable('fallback-dict', group('', [
|
|
200
|
-
property('foo', 'tstr')
|
|
201
|
-
]) as any),
|
|
202
|
-
variable('group-array-type', {
|
|
203
|
-
Type: 'group_array',
|
|
204
|
-
Value: 'item-value',
|
|
205
|
-
Unwrapped: false
|
|
206
|
-
}),
|
|
207
|
-
variable('mapped-tag-type', tagRef('tstr')),
|
|
208
|
-
variable('custom-tag-type', tagRef('custom-tag')),
|
|
209
|
-
variable('range-type', rangeRef()),
|
|
210
|
-
variable('literal-null', literal(null))
|
|
211
|
-
])
|
|
212
|
-
|
|
213
|
-
expect(output).toContain('TupleType = Tuple[int, str]')
|
|
214
|
-
expect(output).toContain('ChoiceType = Union[Tuple[int, str], bool]')
|
|
215
|
-
expect(output).toContain('DictType = dict[Any, str]')
|
|
216
|
-
expect(output).toContain('FallbackDict = dict[str, Any]')
|
|
217
|
-
expect(output).toContain('GroupArrayType = list[ItemValue]')
|
|
218
|
-
expect(output).toContain('MappedTagType = str')
|
|
219
|
-
expect(output).toContain('CustomTagType = CustomTag')
|
|
220
|
-
expect(output).toContain('RangeType = int')
|
|
221
|
-
expect(output).toContain('LiteralNull = None')
|
|
222
|
-
})
|
|
223
|
-
|
|
224
|
-
it('should render property defaults from both property and reference operators', () => {
|
|
225
|
-
const output = transform([
|
|
226
|
-
group('defaults', [
|
|
227
|
-
property('count', 'int', {
|
|
228
|
-
Operator: { Type: 'default', Value: literal(7) }
|
|
229
|
-
}),
|
|
230
|
-
property('status', groupRef('status-value', {
|
|
231
|
-
Type: 'default',
|
|
232
|
-
Value: literal('ready')
|
|
233
|
-
}), {
|
|
234
|
-
Comments: [comment('status docs')]
|
|
235
|
-
}),
|
|
236
|
-
property('maybe_enabled', 'bool', {
|
|
237
|
-
Occurrence: { n: 0, m: 1 },
|
|
238
|
-
Operator: { Type: 'default', Value: literal(false) }
|
|
239
|
-
})
|
|
240
|
-
])
|
|
241
|
-
], { pydantic: true })
|
|
242
|
-
|
|
243
|
-
expect(output).toContain('count: int = Field(default=7)')
|
|
244
|
-
expect(output).toContain('status: StatusValue = Field(default="ready") # status docs')
|
|
245
|
-
expect(output).toContain('maybe_enabled: Optional[bool] = Field(default=False)')
|
|
246
|
-
})
|
|
247
|
-
|
|
248
|
-
it('should raise clear errors for unsupported transform inputs', () => {
|
|
249
|
-
expect(() => transform([
|
|
250
|
-
variable('unknown-native', 'nope')
|
|
251
|
-
])).toThrow('Unknown native type: "nope"')
|
|
252
|
-
|
|
253
|
-
expect(() => transform([
|
|
254
|
-
variable('unsupported-literal', literal({ foo: 'bar' }))
|
|
255
|
-
])).toThrow('Unsupported literal')
|
|
256
|
-
|
|
257
|
-
expect(() => transform([
|
|
258
|
-
variable('bad-group', { Type: 'group', Value: false, Unwrapped: false } as any)
|
|
259
|
-
])).toThrow('Unknown group type')
|
|
260
|
-
|
|
261
|
-
expect(() => transform([
|
|
262
|
-
variable('bad-reference', { Type: 'mystery', Value: 'oops', Unwrapped: false } as any)
|
|
263
|
-
])).toThrow('Unknown type')
|
|
264
|
-
})
|
|
265
|
-
})
|
package/tests/unknown.test.ts
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import url from 'node:url'
|
|
2
|
-
import path from 'node:path'
|
|
3
|
-
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
|
|
4
|
-
|
|
5
|
-
import cli from '../src/cli.js'
|
|
6
|
-
|
|
7
|
-
const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
|
|
8
|
-
const cddlFile = path.join(__dirname, '..', '..', '..', 'examples', 'commons', 'unknown.cddl')
|
|
9
|
-
|
|
10
|
-
vi.mock('../src/constants', () => ({
|
|
11
|
-
pkg: {
|
|
12
|
-
name: 'cddl2py',
|
|
13
|
-
version: '0.1.0',
|
|
14
|
-
author: 'Test Author',
|
|
15
|
-
description: 'Generate Python types from CDDL'
|
|
16
|
-
},
|
|
17
|
-
NATIVE_TYPE_MAP: {
|
|
18
|
-
any: 'Any',
|
|
19
|
-
number: 'Union[int, float]',
|
|
20
|
-
int: 'int',
|
|
21
|
-
uint: 'int',
|
|
22
|
-
nint: 'int',
|
|
23
|
-
float: 'float',
|
|
24
|
-
float16: 'float',
|
|
25
|
-
float32: 'float',
|
|
26
|
-
float64: 'float',
|
|
27
|
-
bool: 'bool',
|
|
28
|
-
bstr: 'bytes',
|
|
29
|
-
bytes: 'bytes',
|
|
30
|
-
tstr: 'str',
|
|
31
|
-
text: 'str',
|
|
32
|
-
str: 'str',
|
|
33
|
-
nil: 'None',
|
|
34
|
-
null: 'None',
|
|
35
|
-
}
|
|
36
|
-
}))
|
|
37
|
-
|
|
38
|
-
describe('any type mapping', () => {
|
|
39
|
-
let exitOrig = process.exit
|
|
40
|
-
let logOrig = console.log
|
|
41
|
-
let errorOrig = console.error
|
|
42
|
-
|
|
43
|
-
beforeEach(() => {
|
|
44
|
-
process.exit = vi.fn() as any
|
|
45
|
-
console.log = vi.fn()
|
|
46
|
-
console.error = vi.fn()
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
afterEach(() => {
|
|
50
|
-
process.exit = exitOrig
|
|
51
|
-
console.log = logOrig
|
|
52
|
-
console.error = errorOrig
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
it('should map CDDL any to Python Any (TypedDict)', async () => {
|
|
56
|
-
await cli([cddlFile])
|
|
57
|
-
|
|
58
|
-
const output = vi.mocked(console.log).mock.calls.flat().join('\n')
|
|
59
|
-
expect(output).toContain('Foo = Any')
|
|
60
|
-
expect(output).toContain('Bar = list[Any]')
|
|
61
|
-
expect(output).toContain('Baz = dict[str, Any]')
|
|
62
|
-
})
|
|
63
|
-
|
|
64
|
-
it('should map CDDL any to Python Any (Pydantic)', async () => {
|
|
65
|
-
await cli([cddlFile, '--pydantic'])
|
|
66
|
-
|
|
67
|
-
const output = vi.mocked(console.log).mock.calls.flat().join('\n')
|
|
68
|
-
expect(output).toContain('Foo = Any')
|
|
69
|
-
expect(output).toContain('Bar = list[Any]')
|
|
70
|
-
expect(output).toContain('Baz = dict[str, Any]')
|
|
71
|
-
})
|
|
72
|
-
})
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import url from 'node:url'
|
|
2
|
-
import path from 'node:path'
|
|
3
|
-
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
|
|
4
|
-
|
|
5
|
-
import cli from '../src/cli.js'
|
|
6
|
-
|
|
7
|
-
const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
|
|
8
|
-
const cddlFile = path.join(__dirname, '..', '..', '..', 'examples', 'webdriver', 'local.cddl')
|
|
9
|
-
|
|
10
|
-
vi.mock('../src/constants', () => ({
|
|
11
|
-
pkg: {
|
|
12
|
-
name: 'cddl2py',
|
|
13
|
-
version: '0.1.0',
|
|
14
|
-
author: 'Test Author',
|
|
15
|
-
description: 'Generate Python types from CDDL'
|
|
16
|
-
},
|
|
17
|
-
NATIVE_TYPE_MAP: {
|
|
18
|
-
any: 'Any',
|
|
19
|
-
number: 'Union[int, float]',
|
|
20
|
-
int: 'int',
|
|
21
|
-
uint: 'int',
|
|
22
|
-
nint: 'int',
|
|
23
|
-
float: 'float',
|
|
24
|
-
float16: 'float',
|
|
25
|
-
float32: 'float',
|
|
26
|
-
float64: 'float',
|
|
27
|
-
bool: 'bool',
|
|
28
|
-
bstr: 'bytes',
|
|
29
|
-
bytes: 'bytes',
|
|
30
|
-
tstr: 'str',
|
|
31
|
-
text: 'str',
|
|
32
|
-
str: 'str',
|
|
33
|
-
nil: 'None',
|
|
34
|
-
null: 'None',
|
|
35
|
-
}
|
|
36
|
-
}))
|
|
37
|
-
|
|
38
|
-
describe('webdriver local spec', () => {
|
|
39
|
-
let exitOrig = process.exit
|
|
40
|
-
let logOrig = console.log
|
|
41
|
-
let errorOrig = console.error
|
|
42
|
-
|
|
43
|
-
beforeEach(() => {
|
|
44
|
-
process.exit = vi.fn() as any
|
|
45
|
-
console.log = vi.fn()
|
|
46
|
-
console.error = vi.fn()
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
afterEach(() => {
|
|
50
|
-
process.exit = exitOrig
|
|
51
|
-
console.log = logOrig
|
|
52
|
-
console.error = errorOrig
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
it('should generate Python types for webdriver local spec', async () => {
|
|
56
|
-
await cli([cddlFile])
|
|
57
|
-
|
|
58
|
-
expect(process.exit).not.toHaveBeenCalledWith(1)
|
|
59
|
-
expect(console.error).not.toHaveBeenCalled()
|
|
60
|
-
expect(console.log).toHaveBeenCalled()
|
|
61
|
-
const output = vi.mocked(console.log).mock.calls.flat().join('\n')
|
|
62
|
-
expect(output).toMatchSnapshot()
|
|
63
|
-
})
|
|
64
|
-
})
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import url from 'node:url'
|
|
2
|
-
import path from 'node:path'
|
|
3
|
-
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
|
|
4
|
-
|
|
5
|
-
import cli from '../src/cli.js'
|
|
6
|
-
|
|
7
|
-
const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
|
|
8
|
-
const cddlFile = path.join(__dirname, '..', '..', '..', 'examples', 'webdriver', 'remote.cddl')
|
|
9
|
-
|
|
10
|
-
vi.mock('../src/constants', () => ({
|
|
11
|
-
pkg: {
|
|
12
|
-
name: 'cddl2py',
|
|
13
|
-
version: '0.1.0',
|
|
14
|
-
author: 'Test Author',
|
|
15
|
-
description: 'Generate Python types from CDDL'
|
|
16
|
-
},
|
|
17
|
-
NATIVE_TYPE_MAP: {
|
|
18
|
-
any: 'Any',
|
|
19
|
-
number: 'Union[int, float]',
|
|
20
|
-
int: 'int',
|
|
21
|
-
uint: 'int',
|
|
22
|
-
nint: 'int',
|
|
23
|
-
float: 'float',
|
|
24
|
-
float16: 'float',
|
|
25
|
-
float32: 'float',
|
|
26
|
-
float64: 'float',
|
|
27
|
-
bool: 'bool',
|
|
28
|
-
bstr: 'bytes',
|
|
29
|
-
bytes: 'bytes',
|
|
30
|
-
tstr: 'str',
|
|
31
|
-
text: 'str',
|
|
32
|
-
str: 'str',
|
|
33
|
-
nil: 'None',
|
|
34
|
-
null: 'None',
|
|
35
|
-
}
|
|
36
|
-
}))
|
|
37
|
-
|
|
38
|
-
describe('webdriver remote spec', () => {
|
|
39
|
-
let exitOrig = process.exit
|
|
40
|
-
let logOrig = console.log
|
|
41
|
-
let errorOrig = console.error
|
|
42
|
-
|
|
43
|
-
beforeEach(() => {
|
|
44
|
-
process.exit = vi.fn() as any
|
|
45
|
-
console.log = vi.fn()
|
|
46
|
-
console.error = vi.fn()
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
afterEach(() => {
|
|
50
|
-
process.exit = exitOrig
|
|
51
|
-
console.log = logOrig
|
|
52
|
-
console.error = errorOrig
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
it('should generate Python types for remote.cddl', async () => {
|
|
56
|
-
await cli([cddlFile])
|
|
57
|
-
|
|
58
|
-
expect(process.exit).not.toHaveBeenCalledWith(1)
|
|
59
|
-
expect(console.error).not.toHaveBeenCalled()
|
|
60
|
-
expect(console.log).toHaveBeenCalled()
|
|
61
|
-
const output = vi.mocked(console.log).mock.calls.flat().join('\n')
|
|
62
|
-
expect(output).toMatchSnapshot()
|
|
63
|
-
})
|
|
64
|
-
})
|