Skip to content

Commit 1d97203

Browse files
committed
feat: classification of cnahges of OAS extension for Path Item object
enable corresponding tests in classification suite
1 parent 98b136e commit 1d97203

File tree

2 files changed

+67
-54
lines changed

2 files changed

+67
-54
lines changed

src/openapi/openapi3.rules.ts

Lines changed: 60 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,20 @@ import { encodingParamsCalculator } from './openapi3.description.encoding'
7474
const documentAnnotationRule: CompareRules = { $: allAnnotation }
7575
const operationAnnotationRule: CompareRules = { $: allAnnotation }
7676

77+
const openApiExtensionRulesFunction: (fallbackRules: CompareRules | (() => CompareRules)) => CompareRules = (fallbackRules) => ({
78+
'/*': (ctx) => {
79+
const { key } = ctx
80+
return typeof key === 'string' && key.startsWith('x-')
81+
? {
82+
$: allUnclassified,
83+
'/**': {
84+
$: allUnclassified,
85+
},
86+
}
87+
: typeof fallbackRules === 'function' ? fallbackRules() : fallbackRules
88+
},
89+
})
90+
7791
export const openApi3Rules = (options: OpenApi3RulesOptions): CompareRules => {
7892
const requestSchemaRules = openApiSchemaRules(options)
7993
const responseSchemaRules = openApiSchemaRules({ ...options, response: true })
@@ -331,6 +345,51 @@ export const openApi3Rules = (options: OpenApi3RulesOptions): CompareRules => {
331345
},
332346
}
333347

348+
const operationCompareRules:CompareRules = {
349+
$: [nonBreaking, breaking, unclassified],
350+
'/*': operationAnnotationRule,
351+
'/tags': {
352+
...operationAnnotationRule,
353+
mapping: deepEqualsUniqueItemsArrayMappingResolver,
354+
'/*': {
355+
...operationAnnotationRule,
356+
[IGNORE_DIFFERENCE_IN_KEYS_RULE]: true,
357+
},
358+
},
359+
'/parameters': {
360+
...parametersRules,
361+
$: [nonBreaking, apihubParametersRemovalClassifyRule, breaking],
362+
mapping: paramMappingResolver(2),
363+
},
364+
'/requestBody': requestBodiesRules,
365+
'/callbacks': {
366+
'/*': {
367+
//no support?
368+
},
369+
},
370+
'/responses': responsesRules,
371+
'/deprecated': { $: allDeprecated },
372+
'/security': {
373+
$: operationSecurityClassifyRule,
374+
'/*': {
375+
$: operationSecurityItemClassifyRule,
376+
'/*': {
377+
$: allBreaking,
378+
mapping: deepEqualsUniqueItemsArrayMappingResolver,
379+
'/*': {
380+
$: [breaking, nonBreaking, breaking],
381+
ignoreKeyDifference: true,
382+
},
383+
},
384+
},
385+
},
386+
'/servers': serversRules,
387+
'/externalDocs': {
388+
$: allAnnotation,
389+
'/*': { $: allAnnotation },
390+
},
391+
}
392+
334393
return {
335394
'/openapi': documentAnnotationRule,
336395
'/info': {
@@ -346,50 +405,7 @@ export const openApi3Rules = (options: OpenApi3RulesOptions): CompareRules => {
346405
mapping: options.mode === COMPARE_MODE_OPERATION ? singleOperationPathMappingResolver : pathMappingResolver,
347406
'/summary': { $: allAnnotation },
348407
'/description': { $: allAnnotation },
349-
'/*': {
350-
$: [nonBreaking, breaking, unclassified],
351-
'/*': operationAnnotationRule,
352-
'/tags': {
353-
...operationAnnotationRule,
354-
mapping: deepEqualsUniqueItemsArrayMappingResolver,
355-
'/*': {
356-
...operationAnnotationRule,
357-
[IGNORE_DIFFERENCE_IN_KEYS_RULE]: true,
358-
},
359-
},
360-
'/parameters': {
361-
...parametersRules,
362-
$: [nonBreaking, apihubParametersRemovalClassifyRule, breaking],
363-
mapping: paramMappingResolver(2),
364-
},
365-
'/requestBody': requestBodiesRules,
366-
'/callbacks': {
367-
'/*': {
368-
//no support?
369-
},
370-
},
371-
'/responses': responsesRules,
372-
'/deprecated': { $: allDeprecated },
373-
'/security': {
374-
$: operationSecurityClassifyRule,
375-
'/*': {
376-
$: operationSecurityItemClassifyRule,
377-
'/*': {
378-
$: allBreaking,
379-
mapping: deepEqualsUniqueItemsArrayMappingResolver,
380-
'/*': {
381-
$: [breaking, nonBreaking, breaking],
382-
ignoreKeyDifference: true,
383-
},
384-
},
385-
},
386-
},
387-
'/servers': serversRules,
388-
'/externalDocs': {
389-
$: allAnnotation,
390-
'/*': { $: allAnnotation },
391-
},
392-
},
408+
...openApiExtensionRulesFunction(operationCompareRules),
393409
'/servers': serversRules,
394410
'/parameters': {
395411
...parametersRules,

test/compatibility-suites/openapi/general-operation-parameters.test.ts

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { compareFiles, TEST_DEFAULTS_DECLARATION_PATHS } from '../utils'
22
import { diffsMatcher } from '../../helper/matchers'
3-
import { annotation, breaking, deprecated, DiffAction, nonBreaking } from '../../../src'
3+
import { annotation, breaking, deprecated, DiffAction, nonBreaking, unclassified } from '../../../src'
44

55
const SUITE_ID = 'general-operation-parameters'
66
const COMMON_PATH1_GET = ['paths', '/path1', 'get']
@@ -595,42 +595,39 @@ describe('Openapi3 General Operation Parameters', () => {
595595
]))
596596
})
597597

598-
// No changes
599-
test.skip('Add custom property in path', async () => {
598+
test('Add custom property in path', async () => {
600599
const testId = 'add-custom-property-in-path'
601600
const result = await compareFiles(SUITE_ID, testId)
602601
expect(result).toEqual(diffsMatcher([
603602
expect.objectContaining({
604603
action: DiffAction.add,
605604
afterDeclarationPaths: [['paths', '/pets', 'x-feature-flag']],
606-
type: nonBreaking,
605+
type: unclassified,
607606
}),
608607
]))
609608
})
610609

611-
// No changes
612-
test.skip('Update custom property in path', async () => {
610+
test('Update custom property in path', async () => {
613611
const testId = 'update-custom-property-value-in-path'
614612
const result = await compareFiles(SUITE_ID, testId)
615613
expect(result).toEqual(diffsMatcher([
616614
expect.objectContaining({
617615
action: DiffAction.replace,
618616
beforeDeclarationPaths: [['paths', '/pets', 'x-feature-flag']],
619617
afterDeclarationPaths: [['paths', '/pets', 'x-feature-flag']],
620-
type: nonBreaking,
618+
type: unclassified,
621619
}),
622620
]))
623621
})
624622

625-
// No changes
626-
test.skip('Remove custom property in path', async () => {
623+
test('Remove custom property in path', async () => {
627624
const testId = 'remove-custom-property-in-path'
628625
const result = await compareFiles(SUITE_ID, testId)
629626
expect(result).toEqual(diffsMatcher([
630627
expect.objectContaining({
631628
action: DiffAction.remove,
632629
beforeDeclarationPaths: [['paths', '/pets', 'x-feature-flag']],
633-
type: nonBreaking,
630+
type: unclassified,
634631
}),
635632
]))
636633
})

0 commit comments

Comments
 (0)