@redocly/openapi-core 1.0.0-beta.90 → 1.0.0-beta.93
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/__tests__/__snapshots__/bundle.test.ts.snap +15 -13
- package/__tests__/ref-utils.test.ts +23 -1
- package/lib/config/all.js +1 -0
- package/lib/config/config.js +7 -12
- package/lib/config/minimal.js +1 -0
- package/lib/config/recommended.js +1 -0
- package/lib/config/rules.d.ts +1 -1
- package/lib/config/rules.js +10 -2
- package/lib/ref-utils.js +1 -1
- package/lib/rules/common/assertions/asserts.d.ts +5 -0
- package/lib/rules/common/assertions/asserts.js +143 -0
- package/lib/rules/common/assertions/index.d.ts +2 -0
- package/lib/rules/common/assertions/index.js +52 -0
- package/lib/rules/common/assertions/utils.d.ts +20 -0
- package/lib/rules/common/assertions/utils.js +123 -0
- package/lib/rules/oas2/index.d.ts +1 -0
- package/lib/rules/oas2/index.js +2 -0
- package/lib/rules/oas3/index.js +2 -0
- package/lib/visitors.d.ts +2 -2
- package/lib/walk.d.ts +1 -0
- package/lib/walk.js +1 -1
- package/package.json +1 -1
- package/src/bundle.ts +1 -1
- package/src/config/all.ts +1 -0
- package/src/config/config.ts +30 -24
- package/src/config/minimal.ts +1 -0
- package/src/config/recommended.ts +1 -0
- package/src/config/rules.ts +11 -2
- package/src/lint.ts +3 -3
- package/src/ref-utils.ts +1 -1
- package/src/rules/common/assertions/__tests__/asserts.test.ts +231 -0
- package/src/rules/common/assertions/__tests__/index.test.ts +65 -0
- package/src/rules/common/assertions/__tests__/utils.test.ts +89 -0
- package/src/rules/common/assertions/asserts.ts +137 -0
- package/src/rules/common/assertions/index.ts +75 -0
- package/src/rules/common/assertions/utils.ts +164 -0
- package/src/rules/oas2/index.ts +2 -0
- package/src/rules/oas3/index.ts +2 -0
- package/src/visitors.ts +2 -2
- package/src/walk.ts +2 -1
- package/tsconfig.tsbuildinfo +1 -1
package/src/config/config.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as fs from 'fs';
|
|
2
2
|
import * as path from 'path';
|
|
3
3
|
import { dirname } from 'path';
|
|
4
|
-
import { red, blue } from 'colorette';
|
|
4
|
+
import { red, blue, yellow, green } from 'colorette';
|
|
5
5
|
import { parseYaml, stringifyYaml } from '../js-yaml';
|
|
6
6
|
import { notUndefined, slash } from '../utils';
|
|
7
7
|
import {
|
|
@@ -646,19 +646,22 @@ function assignExisting<T>(target: Record<string, T>, obj: Record<string, T>) {
|
|
|
646
646
|
|
|
647
647
|
export function getMergedConfig(config: Config, entrypointAlias?: string): Config {
|
|
648
648
|
return entrypointAlias
|
|
649
|
-
? new Config(
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
649
|
+
? new Config(
|
|
650
|
+
{
|
|
651
|
+
...config.rawConfig,
|
|
652
|
+
lint: getMergedLintConfig(config, entrypointAlias),
|
|
653
|
+
'features.openapi': {
|
|
654
|
+
...config['features.openapi'],
|
|
655
|
+
...config.apis[entrypointAlias]?.['features.openapi'],
|
|
656
|
+
},
|
|
657
|
+
'features.mockServer': {
|
|
658
|
+
...config['features.mockServer'],
|
|
659
|
+
...config.apis[entrypointAlias]?.['features.mockServer'],
|
|
660
|
+
},
|
|
661
|
+
// TODO: merge everything else here
|
|
655
662
|
},
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
...config.apis[entrypointAlias]?.['features.mockServer'],
|
|
659
|
-
},
|
|
660
|
-
// TODO: merge everything else here
|
|
661
|
-
})
|
|
663
|
+
config.configFile,
|
|
664
|
+
)
|
|
662
665
|
: config;
|
|
663
666
|
}
|
|
664
667
|
|
|
@@ -695,17 +698,20 @@ export function transformConfig(rawConfig: DeprecatedRawConfig | RawConfig): Raw
|
|
|
695
698
|
throw new Error("Do not use 'referenceDocs' field. Use 'features.openapi' instead.\n");
|
|
696
699
|
}
|
|
697
700
|
const { apiDefinitions, referenceDocs, ...rest } = rawConfig as DeprecatedRawConfig & RawConfig;
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
701
|
+
if (apiDefinitions) {
|
|
702
|
+
process.stderr.write(
|
|
703
|
+
`The ${yellow('apiDefinitions')} field is deprecated. Use ${green(
|
|
704
|
+
'apis',
|
|
705
|
+
)} instead. Read more about this change: https://redocly.com/docs/api-registry/guides/migration-guide-config-file/#changed-properties\n`,
|
|
706
|
+
);
|
|
707
|
+
}
|
|
708
|
+
if (referenceDocs) {
|
|
709
|
+
process.stderr.write(
|
|
710
|
+
`The ${yellow('referenceDocs')} field is deprecated. Use ${green(
|
|
711
|
+
'features.openapi',
|
|
712
|
+
)} instead. Read more about this change: https://redocly.com/docs/api-registry/guides/migration-guide-config-file/#changed-properties\n`,
|
|
713
|
+
);
|
|
714
|
+
}
|
|
709
715
|
return {
|
|
710
716
|
'features.openapi': referenceDocs,
|
|
711
717
|
apis: transformApiDefinitionsToApis(apiDefinitions),
|
package/src/config/minimal.ts
CHANGED
package/src/config/rules.ts
CHANGED
|
@@ -24,14 +24,23 @@ export function initRules<T extends Function, P extends RuleSet<T>>(
|
|
|
24
24
|
return undefined;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
const
|
|
27
|
+
const visitors = rule(ruleSettings);
|
|
28
|
+
|
|
29
|
+
if (Array.isArray(visitors)) {
|
|
30
|
+
return visitors.map((visitor: any) => ({
|
|
31
|
+
severity: ruleSettings.severity,
|
|
32
|
+
ruleId,
|
|
33
|
+
visitor: visitor,
|
|
34
|
+
}))
|
|
35
|
+
}
|
|
28
36
|
|
|
29
37
|
return {
|
|
30
38
|
severity: ruleSettings.severity,
|
|
31
39
|
ruleId,
|
|
32
|
-
visitor,
|
|
40
|
+
visitor: visitors, // note: actually it is only one visitor object
|
|
33
41
|
};
|
|
34
42
|
}),
|
|
35
43
|
)
|
|
44
|
+
.flatMap(visitor => visitor)
|
|
36
45
|
.filter(notUndefined);
|
|
37
46
|
}
|
package/src/lint.ts
CHANGED
|
@@ -11,7 +11,7 @@ import { LintConfig, Config } from './config/config';
|
|
|
11
11
|
import { normalizeTypes } from './types';
|
|
12
12
|
import { initRules } from './config/rules';
|
|
13
13
|
import { releaseAjvInstance } from './rules/ajv';
|
|
14
|
-
import { detectOpenAPI, OasMajorVersion, OasVersion, openAPIMajor } from './oas-types';
|
|
14
|
+
import { detectOpenAPI, Oas3RuleSet, OasMajorVersion, OasVersion, openAPIMajor } from './oas-types';
|
|
15
15
|
import { ConfigTypes } from './types/redocly-yaml';
|
|
16
16
|
import { OasSpec } from './rules/common/spec';
|
|
17
17
|
import { defaultPlugin } from './config/builtIn';
|
|
@@ -76,8 +76,8 @@ export async function lintDocument(opts: {
|
|
|
76
76
|
};
|
|
77
77
|
|
|
78
78
|
const preprocessors = initRules(rules as any, config, 'preprocessors', oasVersion);
|
|
79
|
-
const regularRules = initRules(rules as
|
|
80
|
-
const normalizedVisitors = normalizeVisitors([...preprocessors, ...regularRules], types);
|
|
79
|
+
const regularRules = initRules(rules as Oas3RuleSet[], config, 'rules', oasVersion);
|
|
80
|
+
const normalizedVisitors = normalizeVisitors([...preprocessors, ...regularRules] as any, types);
|
|
81
81
|
const resolvedRefMap = await resolveDocument({
|
|
82
82
|
rootDocument: document,
|
|
83
83
|
rootType: types.DefinitionRoot,
|
package/src/ref-utils.ts
CHANGED
|
@@ -60,7 +60,7 @@ export function pointerBaseName(pointer: string) {
|
|
|
60
60
|
|
|
61
61
|
export function refBaseName(ref: string) {
|
|
62
62
|
const parts = ref.split(/[\/\\]/); // split by '\' and '/'
|
|
63
|
-
return parts[parts.length - 1].
|
|
63
|
+
return parts[parts.length - 1].replace(/\.[^.]+$/, ''); // replace extension with empty string
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
export function isAbsoluteUrl(ref: string) {
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import { asserts } from '../asserts';
|
|
2
|
+
|
|
3
|
+
describe('oas3 assertions', () => {
|
|
4
|
+
describe('generic rules', () => {
|
|
5
|
+
const fakeNode = {
|
|
6
|
+
foo: '',
|
|
7
|
+
bar: '',
|
|
8
|
+
baz: '',
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
describe('pattern', () => {
|
|
12
|
+
it('value should match regex pattern', () => {
|
|
13
|
+
expect(asserts.pattern('test string', '/test/')).toBeTruthy();
|
|
14
|
+
expect(asserts.pattern('test string', '/test me/')).toBeFalsy();
|
|
15
|
+
expect(asserts.pattern(['test string', 'test me'], '/test/')).toBeTruthy();
|
|
16
|
+
expect(asserts.pattern(['test string', 'test me'], '/test me/')).toBeFalsy();
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
describe('enum', () => {
|
|
21
|
+
it('value should be among predefined keys', () => {
|
|
22
|
+
expect(asserts.enum('test', ['test', 'example'])).toBeTruthy();
|
|
23
|
+
expect(asserts.enum(['test'], ['test', 'example'])).toBeTruthy();
|
|
24
|
+
expect(asserts.enum(['test', 'example'], ['test', 'example'])).toBeTruthy();
|
|
25
|
+
expect(asserts.enum(['test', 'example', 'foo'], ['test', 'example'])).toBeFalsy();
|
|
26
|
+
expect(asserts.enum('test', ['foo', 'example'])).toBeFalsy();
|
|
27
|
+
expect(asserts.enum(['test', 'foo'], ['test', 'example'])).toBeFalsy();
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
describe('defined', () => {
|
|
32
|
+
it('value should be defined', () => {
|
|
33
|
+
expect(asserts.defined('test', true)).toBeTruthy();
|
|
34
|
+
expect(asserts.defined(undefined, true)).toBeFalsy();
|
|
35
|
+
});
|
|
36
|
+
it('value should be undefined', () => {
|
|
37
|
+
expect(asserts.defined(undefined, false)).toBeTruthy();
|
|
38
|
+
expect(asserts.defined('test', false)).toBeFalsy();
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
describe('undefined', () => {
|
|
43
|
+
it('value should be undefined', () => {
|
|
44
|
+
expect(asserts.undefined(undefined, true)).toBeTruthy();
|
|
45
|
+
expect(asserts.undefined('test', true)).toBeFalsy();
|
|
46
|
+
});
|
|
47
|
+
it('value should be defined', () => {
|
|
48
|
+
expect(asserts.undefined('test', false)).toBeTruthy();
|
|
49
|
+
expect(asserts.undefined(undefined, false)).toBeFalsy();
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
describe('required', () => {
|
|
54
|
+
it('values should be required', () => {
|
|
55
|
+
expect(asserts.required(['one', 'two', 'three'], ['one', 'two'])).toBeTruthy();
|
|
56
|
+
expect(asserts.required(['one', 'two'], ['one', 'two', 'three'])).toBeFalsy();
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
describe('nonEmpty', () => {
|
|
61
|
+
it('value should not be empty', () => {
|
|
62
|
+
expect(asserts.nonEmpty('test', true)).toBeTruthy();
|
|
63
|
+
expect(asserts.nonEmpty('', true)).toBeFalsy();
|
|
64
|
+
expect(asserts.nonEmpty(null, true)).toBeFalsy();
|
|
65
|
+
expect(asserts.nonEmpty(undefined, true)).toBeFalsy();
|
|
66
|
+
});
|
|
67
|
+
it('value should be empty', () => {
|
|
68
|
+
expect(asserts.nonEmpty('', false)).toBeTruthy();
|
|
69
|
+
expect(asserts.nonEmpty(null, false)).toBeTruthy();
|
|
70
|
+
expect(asserts.nonEmpty(undefined, false)).toBeTruthy();
|
|
71
|
+
expect(asserts.nonEmpty('test', false)).toBeFalsy();
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
describe('minLength', () => {
|
|
76
|
+
it('value should have less or equal than 5 symbols length', () => {
|
|
77
|
+
expect(asserts.minLength('test', 5)).toBeFalsy();
|
|
78
|
+
expect(asserts.minLength([1, 2, 3, 4], 5)).toBeFalsy();
|
|
79
|
+
expect(asserts.minLength([1, 2, 3, 4, 5], 5)).toBeTruthy();
|
|
80
|
+
expect(asserts.minLength([1, 2, 3, 4, 5, 6], 5)).toBeTruthy();
|
|
81
|
+
expect(asserts.minLength('example', 5)).toBeTruthy();
|
|
82
|
+
expect(asserts.minLength([], 5)).toBeFalsy();
|
|
83
|
+
expect(asserts.minLength('', 5)).toBeFalsy();
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
describe('maxLength', () => {
|
|
88
|
+
it('value should have more or equal than 5 symbols length', () => {
|
|
89
|
+
expect(asserts.maxLength('test', 5)).toBeTruthy();
|
|
90
|
+
expect(asserts.maxLength([1, 2, 3, 4], 5)).toBeTruthy();
|
|
91
|
+
expect(asserts.maxLength([1, 2, 3, 4, 5], 5)).toBeTruthy();
|
|
92
|
+
expect(asserts.maxLength([1, 2, 3, 4, 5, 6], 5)).toBeFalsy();
|
|
93
|
+
expect(asserts.maxLength('example', 5)).toBeFalsy();
|
|
94
|
+
expect(asserts.maxLength([], 5)).toBeTruthy();
|
|
95
|
+
expect(asserts.maxLength('', 5)).toBeTruthy();
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
describe('casing', () => {
|
|
100
|
+
it('value should be camelCase', () => {
|
|
101
|
+
expect(asserts.casing(['testExample', 'fooBar'], 'camelCase')).toBeTruthy();
|
|
102
|
+
expect(asserts.casing(['testExample', 'FooBar'], 'camelCase')).toBeFalsy();
|
|
103
|
+
expect(asserts.casing('testExample', 'camelCase')).toBeTruthy();
|
|
104
|
+
expect(asserts.casing('TestExample', 'camelCase')).toBeFalsy();
|
|
105
|
+
expect(asserts.casing('test-example', 'camelCase')).toBeFalsy();
|
|
106
|
+
expect(asserts.casing('test_example', 'camelCase')).toBeFalsy();
|
|
107
|
+
});
|
|
108
|
+
it('value should be PascalCase', () => {
|
|
109
|
+
expect(asserts.casing('TestExample', 'PascalCase')).toBeTruthy();
|
|
110
|
+
expect(asserts.casing(['TestExample', 'FooBar'], 'PascalCase')).toBeTruthy();
|
|
111
|
+
expect(asserts.casing(['TestExample', 'fooBar'], 'PascalCase')).toBeFalsy();
|
|
112
|
+
expect(asserts.casing('testExample', 'PascalCase')).toBeFalsy();
|
|
113
|
+
expect(asserts.casing('test-example', 'PascalCase')).toBeFalsy();
|
|
114
|
+
expect(asserts.casing('test_example', 'PascalCase')).toBeFalsy();
|
|
115
|
+
});
|
|
116
|
+
it('value should be kebab-case', () => {
|
|
117
|
+
expect(asserts.casing('test-example', 'kebab-case')).toBeTruthy();
|
|
118
|
+
expect(asserts.casing(['test-example', 'foo-bar'], 'kebab-case')).toBeTruthy();
|
|
119
|
+
expect(asserts.casing(['test-example', 'foo_bar'], 'kebab-case')).toBeFalsy();
|
|
120
|
+
expect(asserts.casing('testExample', 'kebab-case')).toBeFalsy();
|
|
121
|
+
expect(asserts.casing('TestExample', 'kebab-case')).toBeFalsy();
|
|
122
|
+
expect(asserts.casing('test_example', 'kebab-case')).toBeFalsy();
|
|
123
|
+
});
|
|
124
|
+
it('value should be snake_case', () => {
|
|
125
|
+
expect(asserts.casing('test_example', 'snake_case')).toBeTruthy();
|
|
126
|
+
expect(asserts.casing(['test_example', 'foo_bar'], 'snake_case')).toBeTruthy();
|
|
127
|
+
expect(asserts.casing(['test_example', 'foo-bar'], 'snake_case')).toBeFalsy();
|
|
128
|
+
expect(asserts.casing('testExample', 'snake_case')).toBeFalsy();
|
|
129
|
+
expect(asserts.casing('TestExample', 'snake_case')).toBeFalsy();
|
|
130
|
+
expect(asserts.casing('test-example', 'snake_case')).toBeFalsy();
|
|
131
|
+
});
|
|
132
|
+
it('value should be MACRO_CASE', () => {
|
|
133
|
+
expect(asserts.casing('TEST_EXAMPLE', 'MACRO_CASE')).toBeTruthy();
|
|
134
|
+
expect(asserts.casing(['TEST_EXAMPLE', 'FOO_BAR'], 'MACRO_CASE')).toBeTruthy();
|
|
135
|
+
expect(asserts.casing(['TEST_EXAMPLE', 'FOO-BAR'], 'MACRO_CASE')).toBeFalsy();
|
|
136
|
+
expect(asserts.casing('TEST_EXAMPLE_', 'MACRO_CASE')).toBeFalsy();
|
|
137
|
+
expect(asserts.casing('_TEST_EXAMPLE', 'MACRO_CASE')).toBeFalsy();
|
|
138
|
+
expect(asserts.casing('TEST__EXAMPLE', 'MACRO_CASE')).toBeFalsy();
|
|
139
|
+
expect(asserts.casing('TEST-EXAMPLE', 'MACRO_CASE')).toBeFalsy();
|
|
140
|
+
expect(asserts.casing('testExample', 'MACRO_CASE')).toBeFalsy();
|
|
141
|
+
expect(asserts.casing('TestExample', 'MACRO_CASE')).toBeFalsy();
|
|
142
|
+
expect(asserts.casing('test-example', 'MACRO_CASE')).toBeFalsy();
|
|
143
|
+
});
|
|
144
|
+
it('value should be COBOL-CASE', () => {
|
|
145
|
+
expect(asserts.casing('TEST-EXAMPLE', 'COBOL-CASE')).toBeTruthy();
|
|
146
|
+
expect(asserts.casing(['TEST-EXAMPLE', 'FOO-BAR'], 'COBOL-CASE')).toBeTruthy();
|
|
147
|
+
expect(asserts.casing(['TEST-EXAMPLE', 'FOO_BAR'], 'COBOL-CASE')).toBeFalsy();
|
|
148
|
+
expect(asserts.casing('TEST-EXAMPLE-', 'COBOL-CASE')).toBeFalsy();
|
|
149
|
+
expect(asserts.casing('0TEST-EXAMPLE', 'COBOL-CASE')).toBeFalsy();
|
|
150
|
+
expect(asserts.casing('-TEST-EXAMPLE', 'COBOL-CASE')).toBeFalsy();
|
|
151
|
+
expect(asserts.casing('TEST--EXAMPLE', 'COBOL-CASE')).toBeFalsy();
|
|
152
|
+
expect(asserts.casing('TEST_EXAMPLE', 'COBOL-CASE')).toBeFalsy();
|
|
153
|
+
expect(asserts.casing('testExample', 'COBOL-CASE')).toBeFalsy();
|
|
154
|
+
expect(asserts.casing('TestExample', 'COBOL-CASE')).toBeFalsy();
|
|
155
|
+
expect(asserts.casing('test-example', 'COBOL-CASE')).toBeFalsy();
|
|
156
|
+
});
|
|
157
|
+
it('value should be flatcase', () => {
|
|
158
|
+
expect(asserts.casing('testexample', 'flatcase')).toBeTruthy();
|
|
159
|
+
expect(asserts.casing(['testexample', 'foobar'], 'flatcase')).toBeTruthy();
|
|
160
|
+
expect(asserts.casing(['testexample', 'foo_bar'], 'flatcase')).toBeFalsy();
|
|
161
|
+
expect(asserts.casing('testexample_', 'flatcase')).toBeFalsy();
|
|
162
|
+
expect(asserts.casing('0testexample', 'flatcase')).toBeFalsy();
|
|
163
|
+
expect(asserts.casing('testExample', 'flatcase')).toBeFalsy();
|
|
164
|
+
expect(asserts.casing('TestExample', 'flatcase')).toBeFalsy();
|
|
165
|
+
expect(asserts.casing('test-example', 'flatcase')).toBeFalsy();
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
describe.skip('sortOrder', () => {
|
|
170
|
+
it('value should be ordered in ASC direction', () => {
|
|
171
|
+
expect(asserts.sortOrder(['example', 'foo', 'test'], 'asc')).toBeTruthy();
|
|
172
|
+
expect(asserts.sortOrder(['example', 'foo', 'test'], { direction: 'asc' })).toBeTruthy();
|
|
173
|
+
expect(asserts.sortOrder(['example'], 'asc')).toBeTruthy();
|
|
174
|
+
expect(asserts.sortOrder(['example', 'test', 'foo'], 'asc')).toBeFalsy();
|
|
175
|
+
expect(asserts.sortOrder(['example', 'foo', 'test'], 'desc')).toBeFalsy();
|
|
176
|
+
expect(
|
|
177
|
+
asserts.sortOrder([{ name: 'bar' }, { name: 'baz' }, { name: 'foo' }], {
|
|
178
|
+
direction: 'asc',
|
|
179
|
+
property: 'name',
|
|
180
|
+
}),
|
|
181
|
+
).toBeTruthy();
|
|
182
|
+
expect(
|
|
183
|
+
asserts.sortOrder([{ name: 'bar' }, { name: 'baz' }, { name: 'foo' }], {
|
|
184
|
+
direction: 'desc',
|
|
185
|
+
property: 'name',
|
|
186
|
+
}),
|
|
187
|
+
).toBeFalsy();
|
|
188
|
+
});
|
|
189
|
+
it('value should be ordered in DESC direction', () => {
|
|
190
|
+
expect(asserts.sortOrder(['test', 'foo', 'example'], 'desc')).toBeTruthy();
|
|
191
|
+
expect(asserts.sortOrder(['test', 'foo', 'example'], { direction: 'desc' })).toBeTruthy();
|
|
192
|
+
expect(asserts.sortOrder(['example'], 'desc')).toBeTruthy();
|
|
193
|
+
expect(asserts.sortOrder(['example', 'test', 'foo'], 'desc')).toBeFalsy();
|
|
194
|
+
expect(asserts.sortOrder(['test', 'foo', 'example'], 'asc')).toBeFalsy();
|
|
195
|
+
expect(
|
|
196
|
+
asserts.sortOrder([{ name: 'foo' }, { name: 'baz' }, { name: 'bar' }], {
|
|
197
|
+
direction: 'desc',
|
|
198
|
+
property: 'name',
|
|
199
|
+
}),
|
|
200
|
+
).toBeTruthy();
|
|
201
|
+
expect(
|
|
202
|
+
asserts.sortOrder([{ name: 'foo' }, { name: 'baz' }, { name: 'bar' }], {
|
|
203
|
+
direction: 'asc',
|
|
204
|
+
property: 'name',
|
|
205
|
+
}),
|
|
206
|
+
).toBeFalsy();
|
|
207
|
+
});
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
describe('mutuallyExclusive', () => {
|
|
211
|
+
it('node should not have more than one property from predefined list', () => {
|
|
212
|
+
expect(asserts.mutuallyExclusive(Object.keys(fakeNode), ['foo', 'test'])).toBeTruthy();
|
|
213
|
+
expect(asserts.mutuallyExclusive(Object.keys(fakeNode), [])).toBeTruthy();
|
|
214
|
+
expect(asserts.mutuallyExclusive(Object.keys(fakeNode), ['foo', 'bar'])).toBeFalsy();
|
|
215
|
+
expect(
|
|
216
|
+
asserts.mutuallyExclusive(Object.keys(fakeNode), ['foo', 'bar', 'test']),
|
|
217
|
+
).toBeFalsy();
|
|
218
|
+
});
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
describe('mutuallyRequired', () => {
|
|
222
|
+
it('node should have all the properties from predefined list', () => {
|
|
223
|
+
expect(asserts.mutuallyRequired(Object.keys(fakeNode), ['foo', 'bar'])).toBeTruthy();
|
|
224
|
+
expect(asserts.mutuallyRequired(Object.keys(fakeNode), ['foo', 'bar', 'baz'])).toBeTruthy();
|
|
225
|
+
expect(asserts.mutuallyRequired(Object.keys(fakeNode), [])).toBeTruthy();
|
|
226
|
+
expect(asserts.mutuallyRequired(Object.keys(fakeNode), ['foo', 'test'])).toBeFalsy();
|
|
227
|
+
expect(asserts.mutuallyRequired(Object.keys(fakeNode), ['foo', 'bar', 'test'])).toBeFalsy();
|
|
228
|
+
});
|
|
229
|
+
});
|
|
230
|
+
});
|
|
231
|
+
});
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { Assertions } from '../.';
|
|
2
|
+
|
|
3
|
+
const opts = {
|
|
4
|
+
'0': {
|
|
5
|
+
subject: 'Operation',
|
|
6
|
+
property: 'summary',
|
|
7
|
+
description: 'example warn text',
|
|
8
|
+
severity: 'warn',
|
|
9
|
+
pattern: '/example/',
|
|
10
|
+
},
|
|
11
|
+
'1': {
|
|
12
|
+
subject: 'PathItem',
|
|
13
|
+
context: [{ type: 'Operation', matchParentKeys: ['post'] }],
|
|
14
|
+
description: 'example warn text',
|
|
15
|
+
severity: 'warn',
|
|
16
|
+
mutuallyExclusive: ['summary', 'security'],
|
|
17
|
+
},
|
|
18
|
+
'2': {
|
|
19
|
+
subject: ['PathItem'],
|
|
20
|
+
context: [{ type: 'Operation' }],
|
|
21
|
+
property: 'tags',
|
|
22
|
+
description: 'example warn text',
|
|
23
|
+
severity: 'warn',
|
|
24
|
+
sortOrder: 'desc',
|
|
25
|
+
},
|
|
26
|
+
'3': {
|
|
27
|
+
subject: ['Foo'],
|
|
28
|
+
context: [{ type: 'Bar' }, { type: 'Baz' }],
|
|
29
|
+
property: 'test',
|
|
30
|
+
description: 'example warn text',
|
|
31
|
+
severity: 'warn',
|
|
32
|
+
sortOrder: 'desc',
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
describe('Oas3 assertions', () => {
|
|
37
|
+
it('should return the right visitor structure', () => {
|
|
38
|
+
const visitors = Assertions(opts) as any;
|
|
39
|
+
expect(visitors).toMatchInlineSnapshot(`
|
|
40
|
+
Array [
|
|
41
|
+
Object {
|
|
42
|
+
"Operation": [Function],
|
|
43
|
+
},
|
|
44
|
+
Object {
|
|
45
|
+
"Operation": Object {
|
|
46
|
+
"PathItem": [Function],
|
|
47
|
+
"skip": [Function],
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
Object {
|
|
51
|
+
"Operation": Object {
|
|
52
|
+
"PathItem": [Function],
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
Object {
|
|
56
|
+
"Bar": Object {
|
|
57
|
+
"Baz": Object {
|
|
58
|
+
"Foo": [Function],
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
]
|
|
63
|
+
`);
|
|
64
|
+
});
|
|
65
|
+
});
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { isOrdered, buildVisitorObject, getIntersectionLength } from '../utils';
|
|
2
|
+
|
|
3
|
+
describe('Oas3 assertions', () => {
|
|
4
|
+
describe('Utils', () => {
|
|
5
|
+
describe('getCounts', () => {
|
|
6
|
+
it('should return the right counts', () => {
|
|
7
|
+
const arr = ['foo', 'bar', 'baz'];
|
|
8
|
+
expect(getIntersectionLength(arr, ['foo'])).toBe(1);
|
|
9
|
+
expect(getIntersectionLength(arr, ['foo', 'bar', 'baz'])).toBe(3);
|
|
10
|
+
expect(getIntersectionLength(arr, ['foo', 'test', 'baz'])).toBe(2);
|
|
11
|
+
expect(getIntersectionLength(arr, ['example', 'test'])).toBe(0);
|
|
12
|
+
});
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
describe('isOrdered', () => {
|
|
16
|
+
it('should say if array is ordered or not in specific direction', () => {
|
|
17
|
+
expect(isOrdered(['example', 'foo', 'test'], 'asc')).toBeTruthy();
|
|
18
|
+
expect(isOrdered(['example'], 'asc')).toBeTruthy();
|
|
19
|
+
expect(isOrdered(['test', 'foo', 'example'], 'desc')).toBeTruthy();
|
|
20
|
+
expect(isOrdered(['example'], 'desc')).toBeTruthy();
|
|
21
|
+
expect(isOrdered(['example', 'test', 'foo'], 'asc')).toBeFalsy();
|
|
22
|
+
expect(isOrdered(['example', 'foo', 'test'], 'desc')).toBeFalsy();
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
describe('buildVisitorObject', () => {
|
|
27
|
+
it('should return a consistent visitor structure', () => {
|
|
28
|
+
const context = [
|
|
29
|
+
{
|
|
30
|
+
type: 'Foo',
|
|
31
|
+
matchParentKeys: ['test'],
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
type: 'Bar',
|
|
35
|
+
matchParentKeys: ['test'],
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
type: 'Roof',
|
|
39
|
+
matchParentKeys: ['test'],
|
|
40
|
+
},
|
|
41
|
+
];
|
|
42
|
+
|
|
43
|
+
const visitors = buildVisitorObject('Bar', context, () => {}) as any;
|
|
44
|
+
|
|
45
|
+
expect(visitors).toMatchInlineSnapshot(`
|
|
46
|
+
Object {
|
|
47
|
+
"Foo": Object {
|
|
48
|
+
"Bar": Object {
|
|
49
|
+
"Roof": Object {
|
|
50
|
+
"Bar": [Function],
|
|
51
|
+
"skip": [Function],
|
|
52
|
+
},
|
|
53
|
+
"skip": [Function],
|
|
54
|
+
},
|
|
55
|
+
"skip": [Function],
|
|
56
|
+
},
|
|
57
|
+
}
|
|
58
|
+
`);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('should return the right visitor structure', () => {
|
|
62
|
+
const context = [
|
|
63
|
+
{
|
|
64
|
+
type: 'Operation',
|
|
65
|
+
matchParentKeys: ['put'],
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
type: 'ResponsesMap',
|
|
69
|
+
matchParentKeys: [201, 200],
|
|
70
|
+
},
|
|
71
|
+
];
|
|
72
|
+
|
|
73
|
+
const visitors = buildVisitorObject('MediaTypeMap', context, () => {}) as any;
|
|
74
|
+
|
|
75
|
+
expect(visitors).toMatchInlineSnapshot(`
|
|
76
|
+
Object {
|
|
77
|
+
"Operation": Object {
|
|
78
|
+
"ResponsesMap": Object {
|
|
79
|
+
"MediaTypeMap": [Function],
|
|
80
|
+
"skip": [Function],
|
|
81
|
+
},
|
|
82
|
+
"skip": [Function],
|
|
83
|
+
},
|
|
84
|
+
}
|
|
85
|
+
`);
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
});
|