diff --git a/package.json b/package.json index 14a9332..099d437 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "fast-equals": "6.0.0" }, "devDependencies": { - "@netcracker/qubership-apihub-compatibility-suites": "2.4.0", + "@netcracker/qubership-apihub-compatibility-suites": "dev", "@netcracker/qubership-apihub-graphapi": "1.0.9", "@netcracker/qubership-apihub-npm-gitflow": "3.1.0", "@types/jest": "30.0.0", diff --git a/test/compatibility-suites/openapi/general-operation-parameters.test.ts b/test/compatibility-suites/openapi/general-operation-parameters.test.ts index c488f36..a278e7a 100644 --- a/test/compatibility-suites/openapi/general-operation-parameters.test.ts +++ b/test/compatibility-suites/openapi/general-operation-parameters.test.ts @@ -1,3 +1,4 @@ +import { TEST_SPEC_TYPE_OPEN_API } from '@netcracker/qubership-apihub-compatibility-suites' import { compareFiles, TEST_DEFAULTS_DECLARATION_PATHS } from '../utils' import { diffsMatcher, expectOpenApiVersionChange } from '../../helper/matchers' import { annotation, breaking, deprecated, DiffAction, nonBreaking } from '../../../src' @@ -775,7 +776,7 @@ const PATH_ITEM_PATH = [ ] describe('Openapi3.1 PathItems', () => { - test.caseForOpenApiVersionPairs('add-method-in-path-item', SUITE_ID, async ({ beforeVersion, afterVersion, diffs }) => { + test.caseForSpecVersionPairs(TEST_SPEC_TYPE_OPEN_API, 'add-method-in-path-item', SUITE_ID, async ({ beforeVersion, afterVersion, diffs }) => { expect(diffs).toEqual(diffsMatcher([ expectOpenApiVersionChange(beforeVersion, afterVersion), expect.objectContaining({ @@ -786,19 +787,19 @@ describe('Openapi3.1 PathItems', () => { ])) }) - test.caseForOpenApiVersionPairs('remove-unused-method-in-path-item', SUITE_ID, async ({ beforeVersion, afterVersion, diffs }) => { + test.caseForSpecVersionPairs(TEST_SPEC_TYPE_OPEN_API, 'remove-unused-method-in-path-item', SUITE_ID, async ({ beforeVersion, afterVersion, diffs }) => { expect(diffs).toEqual(diffsMatcher([ expectOpenApiVersionChange(beforeVersion, afterVersion), ])) }) - test.caseForOpenApiVersionPairs('add-unused-method-in-path-item', SUITE_ID, async ({ beforeVersion, afterVersion, diffs }) => { + test.caseForSpecVersionPairs(TEST_SPEC_TYPE_OPEN_API, 'add-unused-method-in-path-item', SUITE_ID, async ({ beforeVersion, afterVersion, diffs }) => { expect(diffs).toEqual(diffsMatcher([ expectOpenApiVersionChange(beforeVersion, afterVersion), ])) }) - test.caseForOpenApiVersionPairs('remove-method-in-path-item', SUITE_ID, async ({ beforeVersion, afterVersion, diffs }) => { + test.caseForSpecVersionPairs(TEST_SPEC_TYPE_OPEN_API, 'remove-method-in-path-item', SUITE_ID, async ({ beforeVersion, afterVersion, diffs }) => { expect(diffs).toEqual(diffsMatcher([ expectOpenApiVersionChange(beforeVersion, afterVersion), expect.objectContaining({ @@ -809,13 +810,13 @@ describe('Openapi3.1 PathItems', () => { ])) }) - test.caseForOpenApiVersionPairs('replace-inline-path-item-to-ref', SUITE_ID, async ({ beforeVersion, afterVersion, diffs }) => { + test.caseForSpecVersionPairs(TEST_SPEC_TYPE_OPEN_API, 'replace-inline-path-item-to-ref', SUITE_ID, async ({ beforeVersion, afterVersion, diffs }) => { expect(diffs).toEqual(diffsMatcher([ expectOpenApiVersionChange(beforeVersion, afterVersion), ])) }) - test.caseForOpenApiVersionPairs('replace-ref-path-item-to-inline', SUITE_ID, async ({ beforeVersion, afterVersion, diffs }) => { + test.caseForSpecVersionPairs(TEST_SPEC_TYPE_OPEN_API, 'replace-ref-path-item-to-inline', SUITE_ID, async ({ beforeVersion, afterVersion, diffs }) => { expect(diffs).toEqual(diffsMatcher([ expectOpenApiVersionChange(beforeVersion, afterVersion), ])) diff --git a/test/compatibility-suites/openapi/parameters-schema.test.ts b/test/compatibility-suites/openapi/parameters-schema.test.ts index 3a5d5bf..be868b8 100644 --- a/test/compatibility-suites/openapi/parameters-schema.test.ts +++ b/test/compatibility-suites/openapi/parameters-schema.test.ts @@ -1,5 +1,7 @@ -import { runAddRemoveDefaultValuesSchemaTests, runCommonSchemaTests } from './templates/schema' -import { runCommonSchema31Tests } from './templates/schema31' +import { TEST_SPEC_TYPE_OPEN_API } from '@netcracker/qubership-apihub-compatibility-suites' +import { runGeneralSchemaTests } from '../schemas/schema-test-runner-general' +import { runOpenApiOnlySchemaTests } from '../schemas/schema-test-runner-openapi-only' +import { DATA_FLOW_DIRECTION_SEND } from '../utils' const SUITE_ID = 'parameters-schema' @@ -12,12 +14,7 @@ const PARAMETERS_SCHEMA_PATH = [ 'schema', ] -describe('Openapi3 Parameters Schema', () => { - runCommonSchemaTests(SUITE_ID, PARAMETERS_SCHEMA_PATH) - - runAddRemoveDefaultValuesSchemaTests(SUITE_ID) -}) - -describe('Openapi31 Parameters Schema', () => { - runCommonSchema31Tests(SUITE_ID, PARAMETERS_SCHEMA_PATH) +describe('Parameters Schema', () => { + runGeneralSchemaTests(TEST_SPEC_TYPE_OPEN_API, SUITE_ID, PARAMETERS_SCHEMA_PATH, DATA_FLOW_DIRECTION_SEND) + runOpenApiOnlySchemaTests(TEST_SPEC_TYPE_OPEN_API, SUITE_ID, PARAMETERS_SCHEMA_PATH, DATA_FLOW_DIRECTION_SEND) }) diff --git a/test/compatibility-suites/openapi/request-body-schema.test.ts b/test/compatibility-suites/openapi/request-body-schema.test.ts index 29e1f5b..39ef02a 100644 --- a/test/compatibility-suites/openapi/request-body-schema.test.ts +++ b/test/compatibility-suites/openapi/request-body-schema.test.ts @@ -1,5 +1,7 @@ -import { runAddRemoveDefaultValuesSchemaTests, runCommonSchemaTests } from './templates/schema' -import { runCommonSchema31Tests } from './templates/schema31' +import { TEST_SPEC_TYPE_OPEN_API } from '@netcracker/qubership-apihub-compatibility-suites' +import { runGeneralSchemaTests } from '../schemas/schema-test-runner-general' +import { runOpenApiOnlySchemaTests } from '../schemas/schema-test-runner-openapi-only' +import { DATA_FLOW_DIRECTION_SEND } from '../utils' const SUITE_ID = 'request-body-schema' @@ -13,12 +15,7 @@ const REQUEST_SCHEMA_PATH = [ 'schema', ] -describe('Openapi3 Request Body Schema', () => { - runCommonSchemaTests(SUITE_ID, REQUEST_SCHEMA_PATH) - - runAddRemoveDefaultValuesSchemaTests(SUITE_ID) -}) - -describe('Openapi31 Request Body Schema', () => { - runCommonSchema31Tests(SUITE_ID, REQUEST_SCHEMA_PATH) +describe('Request Body Schema', () => { + runGeneralSchemaTests(TEST_SPEC_TYPE_OPEN_API, SUITE_ID, REQUEST_SCHEMA_PATH, DATA_FLOW_DIRECTION_SEND) + runOpenApiOnlySchemaTests(TEST_SPEC_TYPE_OPEN_API, SUITE_ID, REQUEST_SCHEMA_PATH, DATA_FLOW_DIRECTION_SEND) }) diff --git a/test/compatibility-suites/openapi/response-body-schema.test.ts b/test/compatibility-suites/openapi/response-body-schema.test.ts index 6ecba81..4dd1f0a 100644 --- a/test/compatibility-suites/openapi/response-body-schema.test.ts +++ b/test/compatibility-suites/openapi/response-body-schema.test.ts @@ -1,9 +1,7 @@ -import { compareFiles, compareFilesWithMerge, TEST_DEFAULTS_DECLARATION_PATHS } from '../utils' -import { diffsMatcher, expectOpenApiVersionChange } from '../../helper/matchers' -import { annotation, breaking, DiffAction, nonBreaking, risky } from '../../../src' -import { JSON_SCHEMA_NODE_SYNTHETIC_TYPE_ANY } from '@netcracker/qubership-apihub-api-unifier' -import { runAddRemoveDefaultValuesSchemaTests } from './templates/schema' -import { runCommonResponseSchema31Tests } from './templates/response-schema31' +import { TEST_SPEC_TYPE_OPEN_API } from '@netcracker/qubership-apihub-compatibility-suites' +import { runGeneralSchemaTests } from '../schemas/schema-test-runner-general' +import { runOpenApiOnlySchemaTests } from '../schemas/schema-test-runner-openapi-only' +import { DATA_FLOW_DIRECTION_RECEIVE } from '../utils' const SUITE_ID = 'response-body-schema' @@ -18,1616 +16,7 @@ const RESPONSE_SCHEMA_PATH = [ 'schema', ] -describe('Openapi3 ResponseBody.Schema ', () => { - - test('Add schema title', async () => { - const testId = 'add-schema-title' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'title']], - type: annotation, - }), - ])) - }) - - test('Update schema title', async () => { - const testId = 'update-schema-title' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'title']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'title']], - type: annotation, - }), - ])) - }) - - test('Remove schema title', async () => { - const testId = 'remove-schema-title' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'title']], - type: annotation, - }), - ])) - }) - - test('Update schema type', async () => { - const testId = 'update-schema-type' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'type']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'type']], - type: breaking, - }), - ])) - }) - - test('Update schema type from specific type to any type', async () => { - const testId = 'update-schema-type-from-specific-type-to-any-type' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher( - [ - expect.objectContaining({ - action: DiffAction.replace, - beforeValue: 'string', - afterValue: JSON_SCHEMA_NODE_SYNTHETIC_TYPE_ANY, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option1', 'type']], - afterDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, - type: breaking, - }), - expect.objectContaining({ - action: DiffAction.replace, - beforeValue: 'string', - afterValue: JSON_SCHEMA_NODE_SYNTHETIC_TYPE_ANY, - afterDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option2', 'type']], - type: breaking, - }), - ], - )) - }) - - test('Update schema type to an equivalent value', async () => { - const testId = 'update-schema-type-to-an-equivalent-value' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual([]) - }) - - test.caseForOpenApiVersionPairs('mark-schema-value-as-nullable', SUITE_ID, async ({ beforeVersion, afterVersion, diffs }) => { - expect(diffs).toEqual(diffsMatcher([ - expectOpenApiVersionChange(beforeVersion, afterVersion), - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option1', 'nullable']], - type: breaking, - }), - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option2', 'nullable']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option2', 'nullable']], - type: breaking, - }), - ])) - }) - - test.caseForOpenApiVersionPairs('mark-schema-value-as-non-nullable', SUITE_ID, async ({ beforeVersion, afterVersion, diffs }) => { - expect(diffs).toEqual(diffsMatcher([ - expectOpenApiVersionChange(beforeVersion, afterVersion), - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option1', 'nullable']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option1', 'nullable']], - type: nonBreaking, - }), - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option2', 'nullable']], - afterDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, - type: nonBreaking, - }), - ])) - }) - - test('Add enum', async () => { - const testId = 'add-enum' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'enum']], - type: nonBreaking, - }), - ])) - }) - - test('Remove enum', async () => { - const testId = 'remove-enum' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'enum']], - type: risky, - }), - ])) - }) - - test('Add enum value', async () => { - const testId = 'add-enum-value' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'enum', 2]], - type: risky, - }), - ])) - }) - - test('Update enum value', async () => { - const testId = 'update-enum-value' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'enum', 1]], - type: nonBreaking, - }), - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'enum', 1]], - type: risky, - }), - ], - )) - }) - - test('Remove enum value', async () => { - const testId = 'remove-enum-value' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'enum', 2]], - type: nonBreaking, - }), - ])) - }) - - test('Add format for string property', async () => { - const testId = 'add-format-for-string-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'format']], - type: nonBreaking, - }), - ])) - }) - - test('Update format for string property', async () => { - const testId = 'update-format-for-string-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'format']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'format']], - type: breaking, - }), - ])) - }) - - test('Remove format for string property', async () => { - const testId = 'remove-format-for-string-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'format']], - type: breaking, - }), - ])) - }) - - test('Add minLength for string property', async () => { - const testId = 'add-min-length-for-string-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option1', 'minLength']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option1', 'minLength']], - type: nonBreaking, - }), - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option2', 'minLength']], - type: nonBreaking, - }), - ])) - }) - - test('Increase minLength for string property', async () => { - const testId = 'increase-min-length-for-string-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'minLength']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'minLength']], - type: nonBreaking, - }), - ])) - }) - - test('Decrease minLength for string property', async () => { - const testId = 'decrease-min-length-for-string-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'minLength']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'minLength']], - type: breaking, - }), - ])) - }) - - test('Remove minLength for string property', async () => { - const testId = 'remove-min-length-for-string-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option1', 'minLength']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option1', 'minLength']], - type: breaking, - }), - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option2', 'minLength']], - afterDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, - type: breaking, - }), - ])) - }) - - test('Add maxLength for string property', async () => { - const testId = 'add-max-length-for-string-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'maxLength']], - type: nonBreaking, - }), - ])) - }) - - test('Increase maxLength for string property', async () => { - const testId = 'increase-max-length-for-string-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'maxLength']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'maxLength']], - type: breaking, - }), - ])) - }) - - test('Decrease maxLength for string property', async () => { - const testId = 'decrease-max-length-for-string-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'maxLength']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'maxLength']], - type: nonBreaking, - }), - ])) - }) - - test('Remove maxLength for string property', async () => { - const testId = 'remove-max-length-for-string-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'maxLength']], - type: breaking, - }), - ])) - }) - - test('Add pattern for string property', async () => { - const testId = 'add-pattern-for-string-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'pattern']], - type: nonBreaking, - }), - ])) - }) - - test('Update pattern for string property', async () => { - const testId = 'update-pattern-for-string-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'pattern']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'pattern']], - type: breaking, - }), - ])) - }) - - test('Remove pattern for string property', async () => { - const testId = 'remove-pattern-for-string-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'pattern']], - type: breaking, - }), - ])) - }) - - test('Add format for number property', async () => { - const testId = 'add-format-for-number-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'format']], - type: nonBreaking, - }), - ])) - }) - - test('Update format for number property', async () => { - const testId = 'update-format-for-number-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'format']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'format']], - type: breaking, - }), - ])) - }) - - test('Remove format for number property', async () => { - const testId = 'remove-format-for-number-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'format']], - type: breaking, - }), - ])) - }) - - test('Add minimum for number property', async () => { - const testId = 'add-minimum-for-number-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'minimum']], - type: nonBreaking, - }), - ])) - }) - - test('Increase minimum for number property', async () => { - const testId = 'increase-minimum-for-number-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'minimum']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'minimum']], - type: nonBreaking, - }), - ])) - }) - - test('Decrease minimum for number property', async () => { - const testId = 'decrease-minimum-for-number-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'minimum']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'minimum']], - type: breaking, - }), - ])) - }) - - test('Remove minimum for number property', async () => { - const testId = 'remove-minimum-for-number-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'minimum']], - type: breaking, - }), - ])) - }) - - test('Mark minimum value as exclusive for number property', async () => { - const testId = 'mark-minimum-value-as-exclusive-for-number-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher( - [ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option1', 'exclusiveMinimum']], - type: nonBreaking, - }), - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option2', 'exclusiveMinimum']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option2', 'exclusiveMinimum']], - type: nonBreaking, - }), - ], - )) - }) - - test('Mark minimum value as inclusive for number property', async () => { - const testId = 'mark-minimum-value-as-inclusive-for-number-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher( - [ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option1', 'exclusiveMinimum']], - afterDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, - type: breaking, - }), - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option2', 'exclusiveMinimum']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option2', 'exclusiveMinimum']], - type: breaking, - }), - ], - )) - }) - - test('Add maximum for number property', async () => { - const testId = 'add-maximum-for-number-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'maximum']], - type: nonBreaking, - }), - ])) - }) - - test('Increase maximum for number property', async () => { - const testId = 'increase-maximum-for-number-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'maximum']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'maximum']], - type: breaking, - }), - ])) - }) - - test('Decrease maximum for number property', async () => { - const testId = 'decrease-maximum-for-number-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'maximum']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'maximum']], - type: nonBreaking, - }), - ])) - }) - - test('Remove maximum for number property', async () => { - const testId = 'remove-maximum-for-number-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'maximum']], - type: breaking, - }), - ])) - }) - - test('Mark maximum value as exclusive for number property', async () => { - const testId = 'mark-maximum-value-as-exclusive-for-number-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher( - [ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option1', 'exclusiveMaximum']], - type: nonBreaking, - }), - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option2', 'exclusiveMaximum']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option2', 'exclusiveMaximum']], - type: nonBreaking, - }), - ], - )) - }) - - test('Mark maximum value as inclusive for number property', async () => { - const testId = 'mark-maximum-value-as-inclusive-for-number-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher( - [ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option1', 'exclusiveMaximum']], - afterDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, - type: breaking, - }), - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option2', 'exclusiveMaximum']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option2', 'exclusiveMaximum']], - type: breaking, - }), - ], - )) - }) - - test('Update specific type to number with exclusive maximum and exclusive minimum', async () => { - const testId = 'update-specific-type-to-number-with-exclusive-value' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher( - [ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'type']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'type']], - type: breaking, - }), - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'exclusiveMaximum']], - type: nonBreaking, - }), - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'exclusiveMinimum']], - type: nonBreaking, - }), - ], - )) - }) - - test('Add multipleOf for number property', async () => { - const testId = 'add-multiple-of-for-number-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'multipleOf']], - type: nonBreaking, - }), - ])) - }) - - test('Update multipleOf for number property', async () => { - const testId = 'update-multiple-of-for-number-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'multipleOf']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'multipleOf']], - type: breaking, - }), - ])) - }) - - test('Remove multipleOf for number property', async () => { - const testId = 'remove-multiple-of-for-number-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'multipleOf']], - type: breaking, - }), - ])) - }) - - test('Add minItems for array property', async () => { - const testId = 'add-min-items-for-array-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option2', 'minItems']], - type: nonBreaking, - }), - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option1', 'minItems']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option1', 'minItems']], - type: nonBreaking, - }), - ])) - }) - - test('Increase minItems for array property', async () => { - const testId = 'increase-min-items-for-array-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'minItems']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'minItems']], - type: nonBreaking, - }), - ])) - }) - - test('Decrease minItems for array property', async () => { - const testId = 'decrease-min-items-for-array-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'minItems']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'minItems']], - type: breaking, - }), - ])) - }) - - test('Remove minItems for array property', async () => { - const testId = 'remove-min-items-for-array-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option2', 'minItems']], - afterDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, - type: breaking, - }), - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option1', 'minItems']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option1', 'minItems']], - type: breaking, - }), - ])) - }) - - test('Add maxItems for array property', async () => { - const testId = 'add-max-items-for-array-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'maxItems']], - type: nonBreaking, - }), - ])) - }) - - test('Increase maxItems for array property', async () => { - const testId = 'increase-max-items-for-array-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'maxItems']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'maxItems']], - type: breaking, - }), - ])) - }) - - test('Decrease maxItems for array property', async () => { - const testId = 'decrease-max-items-for-array-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'maxItems']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'maxItems']], - type: nonBreaking, - }), - ])) - }) - - test('Remove maxItems for array property', async () => { - const testId = 'remove-max-items-for-array-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'maxItems']], - type: breaking, - }), - ])) - }) - - test('Prohibit non-unique items for array property', async () => { - const testId = 'prohibit-non-unique-items-for-array-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher( - [ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option1', 'uniqueItems']], - type: nonBreaking, - }), - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option2', 'uniqueItems']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option2', 'uniqueItems']], - type: nonBreaking, - }), - ], - )) - }) - - test('Allow non-unique items for array property', async () => { - const testId = 'allow-non-unique-items-for-array-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher( - [ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option1', 'uniqueItems']], - afterDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, - type: breaking, - }), - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option2', 'uniqueItems']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option2', 'uniqueItems']], - type: breaking, - }), - ], - )) - }) - - test('Add new property (compliance)', async () => { - const testId = 'add-new-property-compliance' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'prop2']], - type: nonBreaking, - }), - ])) - }) - - test('Remove property (compliance)', async () => { - const testId = 'remove-property-compliance' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'prop2']], - type: nonBreaking, - }), - ])) - }) - - test('Add required property', async () => { - const testId = 'add-required-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'required', 0]], - type: nonBreaking, - }), - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'required', 1]], - type: nonBreaking, - }), - ])) - }) - - test('Add required property with default', async () => { - const testId = 'add-required-property-with-default' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'required', 0]], - type: nonBreaking, - }), - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'required', 1]], - type: nonBreaking, - }), - ])) - }) - - test('Remove required property', async () => { - const testId = 'remove-required-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'required', 0]], - type: breaking, - }), - ])) - }) - - test('Update required property', async () => { - const testId = 'update-required-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'required', 0]], - type: breaking, - }), - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'required', 0]], - type: nonBreaking, - }), - ])) - }) - - test('Mark object property as readOnly', async () => { - const testId = 'mark-object-property-as-read-only' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher( - [ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option1', 'readOnly']], - type: nonBreaking, - }), - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option2', 'readOnly']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option2', 'readOnly']], - type: nonBreaking, - }), - ], - )) - }) - - test('Mark object property as not readOnly', async () => { - const testId = 'mark-object-property-as-not-read-only' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher( - [ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option1', 'readOnly']], - afterDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, - type: nonBreaking, - }), - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option2', 'readOnly']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option2', 'readOnly']], - type: nonBreaking, - }), - ], - )) - }) - - test('Mark object property as writeOnly', async () => { - const testId = 'mark-object-property-as-write-only' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher( - [ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option1', 'writeOnly']], - type: nonBreaking, - }), - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option2', 'writeOnly']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option2', 'writeOnly']], - type: nonBreaking, - }), - ], - )) - }) - - test('Mark object property as not writeOnly', async () => { - const testId = 'mark-object-property-as-not-write-only' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher( - [ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option1', 'writeOnly']], - afterDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, - type: nonBreaking, - }), - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option2', 'writeOnly']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option2', 'writeOnly']], - type: nonBreaking, - }), - ], - )) - }) - - test('Add minProperties for object property', async () => { - const testId = 'add-min-properties-for-object-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option1', 'minProperties']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option1', 'minProperties']], - type: nonBreaking, - }), - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option2', 'minProperties']], - type: nonBreaking, - }), - ])) - }) - - test('Increase minProperties for object property', async () => { - const testId = 'increase-min-properties-for-object-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'minProperties']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'minProperties']], - type: nonBreaking, - }), - ])) - }) - - test('Decrease minProperties for object property', async () => { - const testId = 'decrease-min-properties-for-object-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'minProperties']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'minProperties']], - type: breaking, - }), - ])) - }) - - test('Remove minProperties for object property', async () => { - const testId = 'remove-min-properties-for-object-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option1', 'minProperties']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option1', 'minProperties']], - type: breaking, - }), - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option2', 'minProperties']], - afterDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, - type: breaking, - }), - ])) - }) - - test('Add maxProperties for object property', async () => { - const testId = 'add-max-properties-for-object-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'maxProperties']], - type: nonBreaking, - }), - ])) - }) - - test('Increase maxProperties for object property', async () => { - const testId = 'increase-max-properties-for-object-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'maxProperties']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'maxProperties']], - type: breaking, - }), - ])) - }) - - test('Decrease maxProperties for object property', async () => { - const testId = 'decrease-max-properties-for-object-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'maxProperties']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'maxProperties']], - type: nonBreaking, - }), - ])) - }) - - test('Remove maxProperties for object property', async () => { - const testId = 'remove-max-properties-for-object-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'maxProperties']], - type: breaking, - }), - ])) - }) - - test('Update definition of free-form object', async () => { - const testId = 'update-definition-of-free-form-object' - const result = await compareFilesWithMerge(SUITE_ID, testId) - expect(result.merged).not.toHaveProperty(['paths', '/path1', 'post', 'responses', 200, 'content', 'application/json', 'schema', 'properties', 'option1', 'additionalProperties']) - expect(result.merged).not.toHaveProperty(['paths', '/path1', 'post', 'responses', 200, 'content', 'application/json', 'schema', 'properties', 'option2', 'additionalProperties']) - expect(result.merged).not.toHaveProperty(['paths', '/path1', 'post', 'responses', 200, 'content', 'application/json', 'schema', 'additionalProperties']) - expect(result.diffs).toEqual([]) - }) - - test('Add non-boolean additionalProperties', async () => { - const testId = 'add-non-boolean-additional-properties' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual( - diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeValue: JSON_SCHEMA_NODE_SYNTHETIC_TYPE_ANY, - afterValue: 'string', - beforeDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'additionalProperties', 'type']], - type: nonBreaking, - }), - ], - ), - ) - }) - - test('Update type of additionalProperties', async () => { - const testId = 'update-type-of-additional-properties' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'additionalProperties', 'type']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'additionalProperties', 'type']], - type: breaking, - }), - ])) - }) - - test('Remove additionalProperties', async () => { - const testId = 'remove-additional-properties' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual( - diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeValue: 'string', - afterValue: JSON_SCHEMA_NODE_SYNTHETIC_TYPE_ANY, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'additionalProperties', 'type']], - afterDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, - type: breaking, - }), - ], - ), - ) - }) - - test('Add oneOf', async () => { - const testId = 'add-one-of' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'oneOf', 1]], - type: breaking, - }), - ])) - }) - - test('Add oneOf option', async () => { - const testId = 'add-one-of-option' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'oneOf', 2]], - type: breaking, - }), - ])) - }) - - test('Remove oneOf option', async () => { - const testId = 'remove-one-of-option' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'oneOf', 2]], - type: nonBreaking, - }), - ])) - }) - - test('Remove oneOf', async () => { - const testId = 'remove-one-of' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'oneOf', 1]], - type: nonBreaking, - }), - ])) - }) - - // TODO: fixme - test.skip('Add discriminator for oneOf', async () => { - const testId = 'add-discriminator-for-one-of' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'discriminator']], - type: breaking, - }), - ])) - }) - - // TODO: fixme - test.skip('Remove discriminator for oneOf', async () => { - const testId = 'remove-discriminator-for-one-of' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'discriminator']], - type: breaking, - }), - ])) - }) - - // TODO: fixme - test.skip('Update discriminator for oneOf', async () => { - const testId = 'update-discriminator-for-one-of' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'discriminator', 'propertyName']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'discriminator', 'propertyName']], - type: breaking, - }), - ])) - }) - - test('Add anyOf', async () => { - const testId = 'add-any-of' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'anyOf', 1]], - type: breaking, - }), - ])) - }) - - test('Add anyOf option', async () => { - const testId = 'add-any-of-option' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'anyOf', 2]], - type: breaking, - }), - ])) - }) - - test('Remove anyOf option', async () => { - const testId = 'remove-any-of-option' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'anyOf', 2]], - type: nonBreaking, - }), - ])) - }) - - test('Remove anyOf', async () => { - const testId = 'remove-any-of' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'anyOf', 1]], - type: nonBreaking, - }), - ])) - }) - - // TODO: fixme - test.skip('Add discriminator for anyOf', async () => { - const testId = 'add-discriminator-for-any-of' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'discriminator']], - type: breaking, - }), - ])) - }) - - // TODO: fixme - test.skip('Remove discriminator for anyOf', async () => { - const testId = 'remove-discriminator-for-any-of' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'discriminator']], - type: breaking, - }), - ])) - }) - - // TODO: fixme - test.skip('Update discriminator for anyOf', async () => { - const testId = 'update-discriminator-for-any-of' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'discriminator', 'propertyName']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'discriminator', 'propertyName']], - type: breaking, - }), - ])) - }) - - test('Add allOf', async () => { - const testId = 'add-all-of' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'allOf', 1, 'properties', 'prop2']], - type: nonBreaking, - }), - ])) - }) - - test('Add allOf option', async () => { - const testId = 'add-all-of-option' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'allOf', 2, 'properties', 'prop3']], - type: nonBreaking, - }), - ])) - }) - - test('Remove allOf option', async () => { - const testId = 'remove-all-of-option' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'allOf', 2, 'properties', 'prop3']], - type: nonBreaking, - }), - ])) - }) - - test('Remove allOf', async () => { - const testId = 'remove-all-of' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'allOf', 1, 'properties', 'prop2']], - type: nonBreaking, - }), - ])) - }) - - // TODO: fixme - test.skip('Add xml name replacement for schema', async () => { - const testId = 'add-xml-name-replacement-for-schema' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'xml']], - type: breaking, - }), - ])) - }) - - // TODO: fixme - test.skip('Update xml name replacement for schema', async () => { - const testId = 'update-xml-name-replacement-for-schema' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'xml', 'name']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'xml', 'name']], - type: breaking, - }), - ])) - }) - - // TODO: fixme - test.skip('Remove xml name replacement for schema', async () => { - const testId = 'remove-xml-name-replacement-for-schema' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'xml']], - type: breaking, - }), - ])) - }) - - // TODO: fixme - test.skip('Add xml name replacement for property', async () => { - const testId = 'add-xml-name-replacement-for-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'id', 'xml']], - type: breaking, - }), - ])) - }) - - // TODO: fixme - test.skip('Update xml name replacement for property', async () => { - const testId = 'update-xml-name-replacement-for-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'id', 'xml', 'name']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'id', 'xml', 'name']], - type: breaking, - }), - ])) - }) - - // TODO: fixme - test.skip('Remove xml name replacement for property', async () => { - const testId = 'remove-xml-name-replacement-for-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'id', 'xml']], - type: breaking, - }), - ])) - }) - - // TODO: fixme - test.skip('Mark property as xml attribute', async () => { - const testId = 'mark-property-as-xml-attribute' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher( - [ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option1', 'xml', 'attribute']], - type: breaking, - }), - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option2', 'xml', 'attribute']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option2', 'xml', 'attribute']], - type: breaking, - }), - ], - )) - }) - - // TODO: fixme - test.skip('Mark property as xml element', async () => { - const testId = 'mark-property-as-xml-element' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher( - [ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option1', 'xml', 'attribute']], - type: breaking, - }), - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option2', 'xml', 'attribute']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'properties', 'option2', 'xml', 'attribute']], - type: breaking, - }), - ], - )) - }) - - // TODO: fixme - test.skip('Add xml prefix and namespace for schema', async () => { - const testId = 'add-xml-prefix-and-namespace-for-schema' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'xml']], - type: breaking, - }), - ])) - }) - - // TODO: fixme - test.skip('Update xml prefix for schema', async () => { - const testId = 'update-xml-prefix-for-schema' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'xml', 'prefix']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'xml', 'prefix']], - type: breaking, - }), - ])) - }) - - // TODO: fixme - test.skip('Remove xml prefix and namespace for schema', async () => { - const testId = 'remove-xml-prefix-and-namespace-for-schema' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'xml']], - type: breaking, - }), - ])) - }) - - // TODO: fixme - test.skip('Add xml:wrapped for array property', async () => { - const testId = 'add-xml-wrapped-for-array-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'xml', 'wrapped']], - type: breaking, - }), - ])) - }) - - // TODO: fixme only for openapi.rules and think about expected with Diana for all xml cases - test.skip('Remove xml:wrapped for array property', async () => { - const testId = 'remove-xml-wrapped-for-array-property' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'xml', 'wrapped']], - type: breaking, - }), - ])) - }) - - test.skip('Update schema type from any type to specific type', async () => { - const testId = 'update-schema-type-from-any-type-to-specific-type' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [TEST_DEFAULTS_DECLARATION_PATHS], //check - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'type']], - type: nonBreaking, - }), - ])) - }) - - test.skip('Update schema type from string type to nothing type', async () => { - const testId = 'update-schema-type-from-string-type-to-nothing-type' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'type']], - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'allOf']], //check - type: breaking, - }), - ])) - }) - - test.skip('Update schema type from nothing type to string type', async () => { - const testId = 'update-schema-type-from-nothing-type-to-string-type' - const result = await compareFiles(SUITE_ID, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'allOf']],//check - afterDeclarationPaths: [[...RESPONSE_SCHEMA_PATH, 'type']], - type: nonBreaking, - }), - ])) - }) - - runAddRemoveDefaultValuesSchemaTests(SUITE_ID) +describe('Response Body Schema', () => { + runGeneralSchemaTests(TEST_SPEC_TYPE_OPEN_API, SUITE_ID, RESPONSE_SCHEMA_PATH, DATA_FLOW_DIRECTION_RECEIVE) + runOpenApiOnlySchemaTests(TEST_SPEC_TYPE_OPEN_API, SUITE_ID, RESPONSE_SCHEMA_PATH, DATA_FLOW_DIRECTION_RECEIVE) }) - -describe('Openapi31 ResponseBody.Schema', () => { - runCommonResponseSchema31Tests(SUITE_ID, RESPONSE_SCHEMA_PATH) -}) - diff --git a/test/compatibility-suites/openapi/response-headers-schema.test.ts b/test/compatibility-suites/openapi/response-headers-schema.test.ts index d3eecf1..1657410 100644 --- a/test/compatibility-suites/openapi/response-headers-schema.test.ts +++ b/test/compatibility-suites/openapi/response-headers-schema.test.ts @@ -1,4 +1,7 @@ -import { runCommonResponseSchema31Tests } from './templates/response-schema31' +import { TEST_SPEC_TYPE_OPEN_API } from '@netcracker/qubership-apihub-compatibility-suites' +import { runGeneralSchemaTests } from '../schemas/schema-test-runner-general' +import { runOpenApiOnlySchemaTests } from '../schemas/schema-test-runner-openapi-only' +import { DATA_FLOW_DIRECTION_RECEIVE } from '../utils' const SUITE_ID = 'response-headers-schema' @@ -13,6 +16,7 @@ const RESPONSE_HEADERS_SCHEMA_PATH = [ 'schema', ] -describe('Openapi31 ResponseHeaders.Schema', () => { - runCommonResponseSchema31Tests(SUITE_ID, RESPONSE_HEADERS_SCHEMA_PATH) +describe('Response Headers Schema', () => { + runGeneralSchemaTests(TEST_SPEC_TYPE_OPEN_API, SUITE_ID, RESPONSE_HEADERS_SCHEMA_PATH, DATA_FLOW_DIRECTION_RECEIVE) + runOpenApiOnlySchemaTests(TEST_SPEC_TYPE_OPEN_API, SUITE_ID, RESPONSE_HEADERS_SCHEMA_PATH, DATA_FLOW_DIRECTION_RECEIVE) }) diff --git a/test/compatibility-suites/openapi/templates/reference-object-31.template.ts b/test/compatibility-suites/openapi/templates/reference-object-31.template.ts index beeb68f..3c66115 100644 --- a/test/compatibility-suites/openapi/templates/reference-object-31.template.ts +++ b/test/compatibility-suites/openapi/templates/reference-object-31.template.ts @@ -1,4 +1,5 @@ import { JsonPath } from '@netcracker/qubership-apihub-json-crawl' +import { TEST_SPEC_TYPE_OPEN_API } from '@netcracker/qubership-apihub-compatibility-suites' import { diffsMatcher, expectOpenApiVersionChange } from '../../../helper/matchers' import { annotation, DiffAction } from '../../../../src' @@ -16,7 +17,7 @@ export function runRefObjectSummaryTests(suiteId: string, refPath: JsonPath, com } export function runReferenceObjectTests(suiteId: string, refPath: JsonPath, componentPath: JsonPath, overridenField: OverridenFields): void { - test.caseForOpenApiVersionPairs(`add-overriden-${overridenField}`, suiteId, async ({ beforeVersion, afterVersion, diffs }) => { + test.caseForSpecVersionPairs(TEST_SPEC_TYPE_OPEN_API, `add-overriden-${overridenField}`, suiteId, async ({ beforeVersion, afterVersion, diffs }) => { expect(diffs).toEqual(diffsMatcher([ expectOpenApiVersionChange(beforeVersion, afterVersion), expect.objectContaining({ @@ -28,7 +29,7 @@ export function runReferenceObjectTests(suiteId: string, refPath: JsonPath, comp ])) }) - test.caseForOpenApiVersionPairs(`remove-overriden-${overridenField}`, suiteId, async ({ beforeVersion, afterVersion, diffs }) => { + test.caseForSpecVersionPairs(TEST_SPEC_TYPE_OPEN_API, `remove-overriden-${overridenField}`, suiteId, async ({ beforeVersion, afterVersion, diffs }) => { expect(diffs).toEqual(diffsMatcher([ expectOpenApiVersionChange(beforeVersion, afterVersion), expect.objectContaining({ @@ -40,7 +41,7 @@ export function runReferenceObjectTests(suiteId: string, refPath: JsonPath, comp ])) }) - test.caseForOpenApiVersionPairs(`change-overriden-${overridenField}`, suiteId, async ({ beforeVersion, afterVersion, diffs }) => { + test.caseForSpecVersionPairs(TEST_SPEC_TYPE_OPEN_API, `change-overriden-${overridenField}`, suiteId, async ({ beforeVersion, afterVersion, diffs }) => { expect(diffs).toEqual(diffsMatcher([ expectOpenApiVersionChange(beforeVersion, afterVersion), expect.objectContaining({ @@ -52,7 +53,7 @@ export function runReferenceObjectTests(suiteId: string, refPath: JsonPath, comp ])) }) - test.caseForOpenApiVersionPairs(`change-referenced-${overridenField}-when-overridden-exists`, suiteId, async ({ beforeVersion, afterVersion, diffs }) => { + test.caseForSpecVersionPairs(TEST_SPEC_TYPE_OPEN_API, `change-referenced-${overridenField}-when-overridden-exists`, suiteId, async ({ beforeVersion, afterVersion, diffs }) => { expect(diffs).toEqual(diffsMatcher([ expectOpenApiVersionChange(beforeVersion, afterVersion), ])) diff --git a/test/compatibility-suites/openapi/templates/response-schema31.ts b/test/compatibility-suites/openapi/templates/response-schema31.ts deleted file mode 100644 index a635460..0000000 --- a/test/compatibility-suites/openapi/templates/response-schema31.ts +++ /dev/null @@ -1,119 +0,0 @@ -import { JsonPath } from '@netcracker/qubership-apihub-json-crawl' -import { annotation, breaking, DiffAction, nonBreaking, risky } from '../../../../src' -import { diffsMatcher, expectOpenApiVersionChange } from '../../../helper/matchers' - -const COMPONENTS_SCHEMAS = ['components', 'schemas'] - -export function runCommonResponseSchema31Tests(suiteId: string, commonPath: JsonPath): void { - describe('Union type', () => { - test.caseForOpenApiVersionPairs('add-union-type', suiteId, async ({ beforeVersion, afterVersion, diffs }) => { - expect(diffs).toEqual(diffsMatcher([ - expectOpenApiVersionChange(beforeVersion, afterVersion), - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...commonPath, 'type', 1]], - type: breaking, - }), - ])) - }) - - test.caseForOpenApiVersionPairs('add-null-to-union-type', suiteId, async ({ beforeVersion, afterVersion, diffs }) => { - expect(diffs).toEqual(diffsMatcher([ - expectOpenApiVersionChange(beforeVersion, afterVersion), - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...commonPath, 'type', 2]], - type: breaking, - }), - ])) - }) - - test.caseForOpenApiVersionPairs('remove-union-type', suiteId, async ({ beforeVersion, afterVersion, diffs }) => { - expect(diffs).toEqual(diffsMatcher([ - expectOpenApiVersionChange(beforeVersion, afterVersion), - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...commonPath, 'type', 1]], - type: nonBreaking, - }), - ])) - }) - - test.caseForOpenApiVersionPairs('remove-null-from-union-type', suiteId, async ({ beforeVersion, afterVersion, diffs }) => { - expect(diffs).toEqual(diffsMatcher([ - expectOpenApiVersionChange(beforeVersion, afterVersion), - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...commonPath, 'type', 2]], - type: nonBreaking, - }), - ])) - }) - - test.caseForOpenApiVersionPairs('reorder-types-in-union-type', suiteId, async ({ beforeVersion, afterVersion, diffs }) => { - expect(diffs).toEqual(diffsMatcher([ - expectOpenApiVersionChange(beforeVersion, afterVersion), - ])) - }) - }) - - describe('$ref sibling properties', () => { - test.caseForOpenApiVersionPairs('add-sibling-description-for-ref', suiteId, async ({ beforeVersion, afterVersion, diffs }) => { - expect(diffs).toEqual(diffsMatcher([ - expectOpenApiVersionChange(beforeVersion, afterVersion), - expect.objectContaining({ - action: DiffAction.replace, - afterDeclarationPaths: [[...commonPath, 'description']], - beforeDeclarationPaths: [[...COMPONENTS_SCHEMAS, 'Pet', 'description']], - type: annotation, - }), - ])) - }) - - test.caseForOpenApiVersionPairs('change-sibling-enum-for-ref', suiteId, async ({ beforeVersion, afterVersion, diffs }) => { - expect(diffs).toEqual(diffsMatcher([ - expectOpenApiVersionChange(beforeVersion, afterVersion), - ])) - }) - - test.caseForOpenApiVersionPairs('change-referenced-enum-when-sibling-exists-for-ref', suiteId, async ({ beforeVersion, afterVersion, diffs }) => { - expect(diffs).toEqual(diffsMatcher([ - expectOpenApiVersionChange(beforeVersion, afterVersion), - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [ - [...COMPONENTS_SCHEMAS, 'Color', 'enum', 1], - [...commonPath, 'enum', 1], - ], - type: risky, - }), - ])) - }) - - test.caseForOpenApiVersionPairs('remove-sibling-maxLength-for-ref', suiteId, async ({ beforeVersion, afterVersion, diffs }) => { - expect(diffs).toEqual(diffsMatcher([ - expectOpenApiVersionChange(beforeVersion, afterVersion), - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'maxLength']], - afterDeclarationPaths: [[...COMPONENTS_SCHEMAS, 'Color', 'maxLength']], - type: breaking, - }), - ])) - }) - }) - - describe('Cross-version equivalency', () => { - test.caseForOpenApiVersionPairs('nullable-equivalent-to-null', suiteId, async ({ beforeVersion, afterVersion, diffs }) => { - expect(diffs).toEqual(diffsMatcher([ - expectOpenApiVersionChange(beforeVersion, afterVersion), - ])) - }) - - test.caseForOpenApiVersionPairs('union-type-equivalent-to-any-of', suiteId, async ({ beforeVersion, afterVersion, diffs }) => { - expect(diffs).toEqual(diffsMatcher([ - expectOpenApiVersionChange(beforeVersion, afterVersion), - ])) - }) - }) -} diff --git a/test/compatibility-suites/openapi/templates/schema.ts b/test/compatibility-suites/openapi/templates/schema.ts deleted file mode 100644 index 5c1b691..0000000 --- a/test/compatibility-suites/openapi/templates/schema.ts +++ /dev/null @@ -1,1672 +0,0 @@ -import { compareFiles, TEST_DEFAULTS_DECLARATION_PATHS } from '../../utils' -import { JsonPath } from '@netcracker/qubership-apihub-json-crawl' -import { annotation, breaking, DiffAction, nonBreaking } from '../../../../src' -import { diffsMatcher, expectOpenApiVersionChange } from '../../../helper/matchers' -import { JSON_SCHEMA_NODE_SYNTHETIC_TYPE_ANY } from '@netcracker/qubership-apihub-api-unifier' - -export function runCommonSchemaTests(suiteId: string, commonPath: JsonPath): void { - describe('Common schema tests', () => { - test('Add schema title', async () => { - const testId = 'add-schema-title' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...commonPath, 'title']], - type: annotation, - }), - ])) - }) - - test('Update schema title', async () => { - const testId = 'update-schema-title' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'title']], - afterDeclarationPaths: [[...commonPath, 'title']], - type: annotation, - }), - ])) - }) - - test('Remove schema title', async () => { - const testId = 'remove-schema-title' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...commonPath, 'title']], - type: annotation, - }), - ])) - }) - - //todo TEMP SKIP where are redundant diffs with exclusiveMin(max) - test('Update schema type', async () => { - const testId = 'update-schema-type' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'type']], - afterDeclarationPaths: [[...commonPath, 'type']], - type: breaking, - }), - ])) - }) - - test('Update schema type from specific type to any type', async () => { - const testId = 'update-schema-type-from-specific-type-to-any-type' - const result = await compareFiles(suiteId, testId) - - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeValue: 'string', - afterValue: JSON_SCHEMA_NODE_SYNTHETIC_TYPE_ANY, - beforeDeclarationPaths: [[...commonPath, 'properties', 'option1', 'type']], - afterDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, - type: nonBreaking, - }), - expect.objectContaining({ - action: DiffAction.replace, - beforeValue: 'string', - afterValue: JSON_SCHEMA_NODE_SYNTHETIC_TYPE_ANY, - afterDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, - beforeDeclarationPaths: [[...commonPath, 'properties', 'option2', 'type']], - type: nonBreaking, - }), - ], - )) - }) - - test('Update schema type to an equivalent value', async () => { - const testId = 'update-schema-type-to-an-equivalent-value' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual([]) - }) - - test.caseForOpenApiVersionPairs('mark-schema-value-as-nullable', suiteId, async ({ beforeVersion, afterVersion, diffs }) => { - expect(diffs).toEqual(diffsMatcher([ - expectOpenApiVersionChange(beforeVersion, afterVersion), - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, - afterDeclarationPaths: [[...commonPath, 'properties', 'option1', 'nullable']], - type: nonBreaking, - }), - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'properties', 'option2', 'nullable']], - afterDeclarationPaths: [[...commonPath, 'properties', 'option2', 'nullable']], - type: nonBreaking, - }), - ])) - }) - - test.caseForOpenApiVersionPairs('mark-schema-value-as-non-nullable', suiteId, async ({ beforeVersion, afterVersion, diffs }) => { - expect(diffs).toEqual(diffsMatcher([ - expectOpenApiVersionChange(beforeVersion, afterVersion), - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'properties', 'option1', 'nullable']], - afterDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, - type: breaking, - }), - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'properties', 'option2', 'nullable']], - afterDeclarationPaths: [[...commonPath, 'properties', 'option2', 'nullable']], - type: breaking, - }), - ])) - }) - - test('Add enum', async () => { - const testId = 'add-enum' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...commonPath, 'enum']], - type: breaking, - }), - ])) - }) - - test('Remove enum', async () => { - const testId = 'remove-enum' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...commonPath, 'enum']], - type: nonBreaking, - }), - ])) - }) - - test('Add enum value', async () => { - const testId = 'add-enum-value' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...commonPath, 'enum', 2]], - type: nonBreaking, - }), - ])) - }) - - test('Update enum value', async () => { - const testId = 'update-enum-value' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...commonPath, 'enum', 1]], - type: breaking, - }), - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...commonPath, 'enum', 1]], - type: nonBreaking, - }), - ], - )) - }) - - test('Remove enum value', async () => { - const testId = 'remove-enum-value' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...commonPath, 'enum', 2]], - type: breaking, - }), - ])) - }) - - test('Add format for string property', async () => { - const testId = 'add-format-for-string-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...commonPath, 'format']], - type: breaking, - }), - ])) - }) - - test('Update format for string property', async () => { - const testId = 'update-format-for-string-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'format']], - afterDeclarationPaths: [[...commonPath, 'format']], - type: breaking, - }), - ])) - }) - - test('Remove format for string property', async () => { - const testId = 'remove-format-for-string-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...commonPath, 'format']], - type: nonBreaking, - }), - ])) - }) - - test('Add minLength for string property', async () => { - const testId = 'add-min-length-for-string-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'properties', 'option1', 'minLength']], - afterDeclarationPaths: [[...commonPath, 'properties', 'option1', 'minLength']], - type: breaking, - }), - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, - afterDeclarationPaths: [[...commonPath, 'properties', 'option2', 'minLength']], - type: breaking, - }), - ])) - }) - - test('Increase minLength for string property', async () => { - const testId = 'increase-min-length-for-string-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'minLength']], - afterDeclarationPaths: [[...commonPath, 'minLength']], - type: breaking, - }), - ])) - }) - - test('Decrease minLength for string property', async () => { - const testId = 'decrease-min-length-for-string-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'minLength']], - afterDeclarationPaths: [[...commonPath, 'minLength']], - type: nonBreaking, - }), - ])) - }) - - test('Remove minLength for string property', async () => { - const testId = 'remove-min-length-for-string-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'properties', 'option1', 'minLength']], - afterDeclarationPaths: [[...commonPath, 'properties', 'option1', 'minLength']], - type: nonBreaking, - }), - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'properties', 'option2', 'minLength']], - afterDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, - type: nonBreaking, - }) - ])) - }) - - test('Add maxLength for string property', async () => { - const testId = 'add-max-length-for-string-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...commonPath, 'maxLength']], - type: breaking, - }), - ])) - }) - - test('Increase maxLength for string property', async () => { - const testId = 'increase-max-length-for-string-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'maxLength']], - afterDeclarationPaths: [[...commonPath, 'maxLength']], - type: nonBreaking, - }), - ])) - }) - - test('Decrease maxLength for string property', async () => { - const testId = 'decrease-max-length-for-string-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'maxLength']], - afterDeclarationPaths: [[...commonPath, 'maxLength']], - type: breaking, - }), - ])) - }) - - test('Remove maxLength for string property', async () => { - const testId = 'remove-max-length-for-string-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...commonPath, 'maxLength']], - type: nonBreaking, - }), - ])) - }) - - test('Add pattern for string property', async () => { - const testId = 'add-pattern-for-string-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...commonPath, 'pattern']], - type: breaking, - }), - ])) - }) - - test('Update pattern for string property', async () => { - const testId = 'update-pattern-for-string-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'pattern']], - afterDeclarationPaths: [[...commonPath, 'pattern']], - type: breaking, - }), - ])) - }) - - test('Remove pattern for string property', async () => { - const testId = 'remove-pattern-for-string-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...commonPath, 'pattern']], - type: nonBreaking, - }), - ])) - }) - - test('Add format for number property', async () => { - const testId = 'add-format-for-number-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...commonPath, 'format']], - type: breaking, - }), - ])) - }) - - test('Update format for number property', async () => { - const testId = 'update-format-for-number-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'format']], - afterDeclarationPaths: [[...commonPath, 'format']], - type: breaking, - }), - ])) - }) - - test('Remove format for number property', async () => { - const testId = 'remove-format-for-number-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...commonPath, 'format']], - type: nonBreaking, - }), - ])) - }) - - test('Add minimum for number property', async () => { - const testId = 'add-minimum-for-number-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...commonPath, 'minimum']], - type: breaking, - }), - ])) - }) - - test('Increase minimum for number property', async () => { - const testId = 'increase-minimum-for-number-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'minimum']], - afterDeclarationPaths: [[...commonPath, 'minimum']], - type: breaking, - }), - ])) - }) - - test('Decrease minimum for number property', async () => { - const testId = 'decrease-minimum-for-number-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'minimum']], - afterDeclarationPaths: [[...commonPath, 'minimum']], - type: nonBreaking, - }), - ])) - }) - - test('Remove minimum for number property', async () => { - const testId = 'remove-minimum-for-number-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...commonPath, 'minimum']], - type: nonBreaking, - }), - ])) - }) - - test('Mark minimum value as exclusive for number property', async () => { - const testId = 'mark-minimum-value-as-exclusive-for-number-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, - afterDeclarationPaths: [[...commonPath, 'properties', 'option1', 'exclusiveMinimum']], - type: breaking, - }), - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'properties', 'option2', 'exclusiveMinimum']], - afterDeclarationPaths: [[...commonPath, 'properties', 'option2', 'exclusiveMinimum']], - type: breaking, - }), - ], - )) - }) - - test('Mark minimum value as inclusive for number property', async () => { - const testId = 'mark-minimum-value-as-inclusive-for-number-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'properties', 'option1', 'exclusiveMinimum']], - afterDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, - type: nonBreaking, - }), - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'properties', 'option2', 'exclusiveMinimum']], - afterDeclarationPaths: [[...commonPath, 'properties', 'option2', 'exclusiveMinimum']], - type: nonBreaking, - }), - ], - )) - }) - - test('Add maximum for number property', async () => { - const testId = 'add-maximum-for-number-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...commonPath, 'maximum']], - type: breaking, - }), - ])) - }) - - test('Increase maximum for number property', async () => { - const testId = 'increase-maximum-for-number-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'maximum']], - afterDeclarationPaths: [[...commonPath, 'maximum']], - type: nonBreaking, - }), - ])) - }) - - test('Decrease maximum for number property', async () => { - const testId = 'decrease-maximum-for-number-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'maximum']], - afterDeclarationPaths: [[...commonPath, 'maximum']], - type: breaking, - }), - ])) - }) - - test('Remove maximum for number property', async () => { - const testId = 'remove-maximum-for-number-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...commonPath, 'maximum']], - type: nonBreaking, - }), - ])) - }) - - test('Mark maximum value as exclusive for number property', async () => { - const testId = 'mark-maximum-value-as-exclusive-for-number-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, - afterDeclarationPaths: [[...commonPath, 'properties', 'option1', 'exclusiveMaximum']], - type: breaking, - }), - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'properties', 'option2', 'exclusiveMaximum']], - afterDeclarationPaths: [[...commonPath, 'properties', 'option2', 'exclusiveMaximum']], - type: breaking, - }), - ], - )) - }) - - test('Mark maximum value as inclusive for number property', async () => { - const testId = 'mark-maximum-value-as-inclusive-for-number-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'properties', 'option1', 'exclusiveMaximum']], - afterDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, - type: nonBreaking, - }), - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'properties', 'option2', 'exclusiveMaximum']], - afterDeclarationPaths: [[...commonPath, 'properties', 'option2', 'exclusiveMaximum']], - type: nonBreaking, - }), - ], - )) - }) - - test('Update specific type to number with exclusive maximum and exclusive minimum', async () => { - const testId = 'update-specific-type-to-number-with-exclusive-value' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher( - [ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'type']], - afterDeclarationPaths: [[...commonPath, 'type']], - type: breaking, - }), - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...commonPath, 'exclusiveMaximum']], - type: breaking, - }), - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...commonPath, 'exclusiveMinimum']], - type: breaking, - }), - ], - )) - }) - - test('Add multipleOf for number property', async () => { - const testId = 'add-multiple-of-for-number-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...commonPath, 'multipleOf']], - type: breaking, - }), - ])) - }) - - test('Update multipleOf for number property', async () => { - const testId = 'update-multiple-of-for-number-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'multipleOf']], - afterDeclarationPaths: [[...commonPath, 'multipleOf']], - type: breaking, - }), - ])) - }) - - test('Remove multipleOf for number property', async () => { - const testId = 'remove-multiple-of-for-number-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...commonPath, 'multipleOf']], - type: nonBreaking, - }), - ])) - }) - - test('Add minItems for array property', async () => { - const testId = 'add-min-items-for-array-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, - afterDeclarationPaths: [[...commonPath, 'properties', 'option2', 'minItems']], - type: breaking, - }), - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'properties', 'option1', 'minItems']], - afterDeclarationPaths: [[...commonPath, 'properties', 'option1', 'minItems']], - type: breaking, - }) - ])) - }) - - test('Increase minItems for array property', async () => { - const testId = 'increase-min-items-for-array-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'minItems']], - afterDeclarationPaths: [[...commonPath, 'minItems']], - type: breaking, - }), - ])) - }) - - test('Decrease minItems for array property', async () => { - const testId = 'decrease-min-items-for-array-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'minItems']], - afterDeclarationPaths: [[...commonPath, 'minItems']], - type: nonBreaking, - }), - ])) - }) - - test('Remove minItems for array property', async () => { - const testId = 'remove-min-items-for-array-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'properties', 'option2', 'minItems']], - afterDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, - type: nonBreaking, - }), - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'properties', 'option1', 'minItems']], - afterDeclarationPaths: [[...commonPath, 'properties', 'option1', 'minItems']], - type: nonBreaking, - }) - ])) - }) - - test('Add maxItems for array property', async () => { - const testId = 'add-max-items-for-array-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...commonPath, 'maxItems']], - type: breaking, - }), - ])) - }) - - test('Increase maxItems for array property', async () => { - const testId = 'increase-max-items-for-array-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'maxItems']], - afterDeclarationPaths: [[...commonPath, 'maxItems']], - type: nonBreaking, - }), - ])) - }) - - test('Decrease maxItems for array property', async () => { - const testId = 'decrease-max-items-for-array-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'maxItems']], - afterDeclarationPaths: [[...commonPath, 'maxItems']], - type: breaking, - }), - ])) - }) - - test('Remove maxItems for array property', async () => { - const testId = 'remove-max-items-for-array-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...commonPath, 'maxItems']], - type: nonBreaking, - }), - ])) - }) - - test('Prohibit non-unique items for array property', async () => { - const testId = 'prohibit-non-unique-items-for-array-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, - afterDeclarationPaths: [[...commonPath, 'properties', 'option1', 'uniqueItems']], - type: breaking, - }), - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'properties', 'option2', 'uniqueItems']], - afterDeclarationPaths: [[...commonPath, 'properties', 'option2', 'uniqueItems']], - type: breaking, - }), - ])) - }) - - test('Allow non-unique items for array property', async () => { - const testId = 'allow-non-unique-items-for-array-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'properties', 'option1', 'uniqueItems']], - afterDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, - type: nonBreaking, - }), - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'properties', 'option2', 'uniqueItems']], - afterDeclarationPaths: [[...commonPath, 'properties', 'option2', 'uniqueItems']], - type: nonBreaking, - }), - ])) - }) - - test('Add new property (compliance)', async () => { - const testId = 'add-new-property-compliance' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...commonPath, 'properties', 'prop2']], - type: nonBreaking, - }), - ])) - }) - - test('Remove property (compliance)', async () => { - const testId = 'remove-property-compliance' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...commonPath, 'properties', 'prop2']], - type: breaking, - }), - ])) - }) - - test('Add required property', async () => { - - const testId = 'add-required-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...commonPath, 'required', 0]], - type: breaking, - }), - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...commonPath, 'required', 1]], - type: breaking, - }), - ])) - }) - - test('Add required property with default', async () => { - const testId = 'add-required-property-with-default' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...commonPath, 'required', 0]], - type: nonBreaking, - }), - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...commonPath, 'required', 1]], - type: nonBreaking, - }), - ])) - }) - - test('Remove required property', async () => { - const testId = 'remove-required-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...commonPath, 'required', 0]], - type: nonBreaking, - }), - ])) - }) - - test('Update required property', async () => { - const testId = 'update-required-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...commonPath, 'required', 0]], - type: nonBreaking, - }), - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...commonPath, 'required', 0]], - type: breaking, - }), - ])) - }) - - test('Mark object property as readOnly', async () => { - - const testId = 'mark-object-property-as-read-only' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'properties', 'option1', 'readOnly']], - afterDeclarationPaths: [[...commonPath, 'properties', 'option1', 'readOnly']], - type: breaking, - }), - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, - afterDeclarationPaths: [[...commonPath, 'properties', 'option2', 'readOnly']], - type: breaking, - }), - ], - )) - }) - - test('Mark object property as not readOnly', async () => { - - const testId = 'mark-object-property-as-not-read-only' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'properties', 'option1', 'readOnly']], - afterDeclarationPaths: [[...commonPath, 'properties', 'option1', 'readOnly']], - type: nonBreaking, - }), - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'properties', 'option2', 'readOnly']], - afterDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, - type: nonBreaking, - }), - ], - )) - }) - - test('Mark object property as writeOnly', async () => { - const testId = 'mark-object-property-as-write-only' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, - afterDeclarationPaths: [[...commonPath, 'properties', 'option1', 'writeOnly']], - type: nonBreaking, - }), - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'properties', 'option2', 'writeOnly']], - afterDeclarationPaths: [[...commonPath, 'properties', 'option2', 'writeOnly']], - type: nonBreaking, - }), - ], - )) - }) - - test('Mark object property as not writeOnly', async () => { - const testId = 'mark-object-property-as-not-write-only' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'properties', 'option1', 'writeOnly']], - afterDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, - type: nonBreaking, - }), - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'properties', 'option2', 'writeOnly']], - afterDeclarationPaths: [[...commonPath, 'properties', 'option2', 'writeOnly']], - type: nonBreaking, - }), - ], - )) - }) - - test('Add minProperties for object property', async () => { - const testId = 'add-min-properties-for-object-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'properties', 'option1', 'minProperties']], - afterDeclarationPaths: [[...commonPath, 'properties', 'option1', 'minProperties']], - type: breaking, - }), - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, - afterDeclarationPaths: [[...commonPath, 'properties', 'option2', 'minProperties']], - type: breaking, - }) - ])) - }) - - test('Increase minProperties for object property', async () => { - const testId = 'increase-min-properties-for-object-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'minProperties']], - afterDeclarationPaths: [[...commonPath, 'minProperties']], - type: breaking, - }), - ])) - }) - - test('Decrease minProperties for object property', async () => { - const testId = 'decrease-min-properties-for-object-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'minProperties']], - afterDeclarationPaths: [[...commonPath, 'minProperties']], - type: nonBreaking, - }), - ])) - }) - - test('Remove minProperties for object property', async () => { - const testId = 'remove-min-properties-for-object-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'properties', 'option1', 'minProperties']], - afterDeclarationPaths: [[...commonPath, 'properties', 'option1', 'minProperties']], - type: nonBreaking, - }), - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'properties', 'option2', 'minProperties']], - afterDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, - type: nonBreaking, - }) - ])) - }) - - test('Add maxProperties for object property', async () => { - const testId = 'add-max-properties-for-object-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...commonPath, 'maxProperties']], - type: breaking, - }), - ])) - }) - - test('Increase maxProperties for object property', async () => { - const testId = 'increase-max-properties-for-object-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'maxProperties']], - afterDeclarationPaths: [[...commonPath, 'maxProperties']], - type: nonBreaking, - }), - ])) - }) - - // TODO: fixme - test('Decrease maxProperties for object property', async () => { - const testId = 'decrease-max-properties-for-object-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'maxProperties']], - afterDeclarationPaths: [[...commonPath, 'maxProperties']], - type: breaking, - }), - ])) - }) - - test('Remove maxProperties for object property', async () => { - const testId = 'remove-max-properties-for-object-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...commonPath, 'maxProperties']], - type: nonBreaking, - }), - ])) - }) - - test('Update definition of free-form object', async () => { - - const testId = 'update-definition-of-free-form-object' - const diffs = await compareFiles(suiteId, testId) - expect(diffs).toBeEmpty() - }) - - test('Add non-boolean additionalProperties', async () => { - - const testId = 'add-non-boolean-additional-properties' - const result = await compareFiles(suiteId, testId) - - expect(result).toEqual( - diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeValue: JSON_SCHEMA_NODE_SYNTHETIC_TYPE_ANY, - afterValue: 'string', - beforeDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, - afterDeclarationPaths: [[...commonPath, 'additionalProperties', 'type']], - type: breaking, - }), - ], - ), - ) - }) - - test('Update type of additionalProperties', async () => { - const testId = 'update-type-of-additional-properties' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'additionalProperties', 'type']], - afterDeclarationPaths: [[...commonPath, 'additionalProperties', 'type']], - type: breaking, - }), - ])) - }) - - test('Remove additionalProperties', async () => { - const testId = 'remove-additional-properties' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual( - diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeValue: 'string', - afterValue: JSON_SCHEMA_NODE_SYNTHETIC_TYPE_ANY, - beforeDeclarationPaths: [[...commonPath, 'additionalProperties', 'type']], - afterDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, - type: nonBreaking, - }), - ], - ), - ) - }) - - test('Add oneOf', async () => { - const testId = 'add-one-of' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...commonPath, 'oneOf', 1]], - type: nonBreaking, - }), - ])) - }) - - test('Add oneOf option', async () => { - const testId = 'add-one-of-option' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...commonPath, 'oneOf', 2]], - type: nonBreaking, - }), - ])) - }) - - test('Remove oneOf option', async () => { - const testId = 'remove-one-of-option' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...commonPath, 'oneOf', 2]], - type: breaking, - }), - ])) - }) - - test('Remove oneOf', async () => { - const testId = 'remove-one-of' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...commonPath, 'oneOf', 1]], - type: breaking, - }), - ])) - }) - - // TODO: fixme - test.skip('Add discriminator for oneOf', async () => { - const testId = 'add-discriminator-for-one-of' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...commonPath, 'discriminator']], - type: nonBreaking, - }), - ])) - }) - - // TODO: fixme - test.skip('Remove discriminator for oneOf', async () => { - const testId = 'remove-discriminator-for-one-of' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...commonPath, 'discriminator']], - type: nonBreaking, - }), - ])) - }) - - // TODO: fixme - test.skip('Update discriminator for oneOf', async () => { - const testId = 'update-discriminator-for-one-of' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'discriminator', 'propertyName']], - afterDeclarationPaths: [[...commonPath, 'discriminator', 'propertyName']], - type: nonBreaking, - }), - ])) - }) - - test('Add anyOf', async () => { - const testId = 'add-any-of' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...commonPath, 'anyOf', 1]], - type: nonBreaking, - }), - ])) - }) - - test('Add anyOf option', async () => { - const testId = 'add-any-of-option' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...commonPath, 'anyOf', 2]], - type: nonBreaking, - }), - ])) - }) - - test('Remove anyOf option', async () => { - const testId = 'remove-any-of-option' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...commonPath, 'anyOf', 2]], - type: breaking, - }), - ])) - }) - - test('Remove anyOf', async () => { - const testId = 'remove-any-of' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...commonPath, 'anyOf', 1]], - type: breaking, - }), - ])) - }) - - // TODO: fixme - test.skip('Add discriminator for anyOf', async () => { - const testId = 'add-discriminator-for-any-of' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...commonPath, 'discriminator']], - type: nonBreaking, - }), - ])) - }) - - // TODO: fixme - test.skip('Remove discriminator for anyOf', async () => { - const testId = 'remove-discriminator-for-any-of' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...commonPath, 'discriminator']], - type: nonBreaking, - }), - ])) - }) - - // TODO: fixme - test.skip('Update discriminator for anyOf', async () => { - const testId = 'update-discriminator-for-any-of' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'discriminator', 'propertyName']], - afterDeclarationPaths: [[...commonPath, 'discriminator', 'propertyName']], - type: nonBreaking, - }), - ])) - }) - - test('Add allOf', async () => { - const testId = 'add-all-of' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...commonPath, 'allOf', 1, 'properties', 'prop2']], - type: nonBreaking, - }), - ])) - }) - - test('Add allOf option', async () => { - const testId = 'add-all-of-option' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...commonPath, 'allOf', 2, 'properties', 'prop3']], - type: nonBreaking, - }), - ])) - }) - - //should be breaking if additionalProperties=true - test('Remove allOf option', async () => { - const testId = 'remove-all-of-option' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...commonPath, 'allOf', 2, 'properties', 'prop3']], - type: breaking, - }), - ])) - }) - - //should be breaking if additionalProperties=true - test('Remove allOf', async () => { - const testId = 'remove-all-of' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...commonPath, 'allOf', 1, 'properties', 'prop2']], - type: breaking, - }), - ])) - }) - - // TODO: fixme - test.skip('Add xml name replacement for schema', async () => { - const testId = 'add-xml-name-replacement-for-schema' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...commonPath, 'xml']], - type: breaking, - }), - ])) - }) - - // TODO: fixme - test.skip('Update xml name replacement for schema', async () => { - const testId = 'update-xml-name-replacement-for-schema' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'xml', 'name']], - afterDeclarationPaths: [[...commonPath, 'xml', 'name']], - type: breaking, - }), - ])) - }) - - // TODO: fixme - test.skip('Remove xml name replacement for schema', async () => { - const testId = 'remove-xml-name-replacement-for-schema' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...commonPath, 'xml']], - type: breaking, - }), - ])) - }) - - // TODO: fixme - test.skip('Add xml name replacement for property', async () => { - const testId = 'add-xml-name-replacement-for-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...commonPath, 'properties', 'id', 'xml']], - type: breaking, - }), - ])) - }) - - // TODO: fixme - test.skip('Update xml name replacement for property', async () => { - const testId = 'update-xml-name-replacement-for-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'properties', 'id', 'xml', 'name']], - afterDeclarationPaths: [[...commonPath, 'properties', 'id', 'xml', 'name']], - type: breaking, - }), - ])) - }) - - // TODO: fixme - test.skip('Remove xml name replacement for property', async () => { - const testId = 'remove-xml-name-replacement-for-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...commonPath, 'properties', 'id', 'xml']], - type: breaking, - }), - ])) - }) - - // TODO: fixme - test.skip('Mark property as xml attribute', async () => { - const testId = 'mark-property-as-xml-attribute' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...commonPath, 'properties', 'option1', 'xml', 'attribute']], - type: breaking, - }), - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'properties', 'option2', 'xml', 'attribute']], - afterDeclarationPaths: [[...commonPath, 'properties', 'option2', 'xml', 'attribute']], - type: breaking, - }), - ])) - }) - - // TODO: fixme - test.skip('Mark property as xml element', async () => { - const testId = 'mark-property-as-xml-element' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...commonPath, 'properties', 'option1', 'xml', 'attribute']], - type: breaking, - }), - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'properties', 'option2', 'xml', 'attribute']], - afterDeclarationPaths: [[...commonPath, 'properties', 'option2', 'xml', 'attribute']], - type: breaking, - }), - ])) - }) - - // TODO: fixme - test.skip('Add xml prefix and namespace for schema', async () => { - const testId = 'add-xml-prefix-and-namespace-for-schema' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...commonPath, 'xml']], - type: breaking, - }), - ])) - }) - - // TODO: fixme - test.skip('Update xml prefix for schema', async () => { - const testId = 'update-xml-prefix-for-schema' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'xml', 'prefix']], - afterDeclarationPaths: [[...commonPath, 'xml', 'prefix']], - type: breaking, - }), - ])) - }) - - // TODO: fixme - test.skip('Remove xml prefix and namespace for schema', async () => { - const testId = 'remove-xml-prefix-and-namespace-for-schema' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...commonPath, 'xml']], - type: breaking, - }), - ])) - }) - - // TODO: fixme - test.skip('Add xml:wrapped for array property', async () => { - const testId = 'add-xml-wrapped-for-array-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...commonPath, 'xml', 'wrapped']], - type: breaking, - }), - ])) - }) - - // TODO: fixme - test.skip('Remove xml:wrapped for array property', async () => { - const testId = 'remove-xml-wrapped-for-array-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...commonPath, 'xml', 'wrapped']], - type: breaking, - }), - ])) - }) - - // TODO: fixme - test.skip('Update schema type from any type to specific type', async () => { - const testId = 'update-schema-type-from-any-type-to-specific-type' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [TEST_DEFAULTS_DECLARATION_PATHS], //check - afterDeclarationPaths: [[...commonPath, 'type']], - type: breaking, - }), - ])) - }) - - // TODO: fixme - test.skip('Update schema type from specific type to nothing', async () => { - const testId = 'update-schema-type-from-specific-type-to-nothing' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'type']], - afterDeclarationPaths: [[...commonPath, 'allOf',]], //check - type: breaking, - }), - ])) - }) - - // TODO: fixme - test.skip('Update schema type from nothing to specific type', async () => { - const testId = 'update-schema-type-from-nothing-to-specific-type' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual(diffsMatcher([ - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'allOf']], //check - afterDeclarationPaths: [[...commonPath, 'type']], - type: nonBreaking, - }), - ])) - }) - }) -} - -export function runAddRemoveDefaultValuesSchemaTests(suiteId: string): void { - describe('Add/remove default values', () => { - - test('Add minItems with default value for array property', async () => { - const testId = 'add-minItems-with-default-value-for-array-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual([]) - }) - - test('Remove minItems with default value for array property', async () => { - const testId = 'remove-minItems-with-default-value-for-array-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual([]) - }) - - test('Add uniqueItems with default value for array property', async () => { - const testId = 'add-uniqueItems-with-default-value-for-array-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual([]) - }) - - test('Remove uniqueItems with default value for array property', async () => { - const testId = 'remove-uniqueItems-with-default-value-for-array-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual([]) - }) - - test('Add minProperties with default value for object property', async () => { - const testId = 'add-minProperties-with-default-value-for-object-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual([]) - }) - - test('Remove minProperties with default value for object property', async () => { - const testId = 'remove-minProperties-with-default-value-for-object-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual([]) - }) - - test('Add attribute with default value for xml', async () => { - const testId = 'add-attribute-with-default-value-for-xml' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual([]) - }) - - test('Remove attribute with default value for xml', async () => { - const testId = 'remove-attribute-with-default-value-for-xml' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual([]) - }) - - test('Add xml:wrapped with default value for array property', async () => { - const testId = 'add-xml-wrapped-with-default-value-for-array-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual([]) - }) - - test('Remove xml:wrapped with default value for array property', async () => { - const testId = 'remove-xml-wrapped-with-default-value-for-array-property' - const result = await compareFiles(suiteId, testId) - expect(result).toEqual([]) - }) - }) -} diff --git a/test/compatibility-suites/openapi/templates/schema31.ts b/test/compatibility-suites/openapi/templates/schema31.ts deleted file mode 100644 index b94fc3c..0000000 --- a/test/compatibility-suites/openapi/templates/schema31.ts +++ /dev/null @@ -1,119 +0,0 @@ -import { JsonPath } from '@netcracker/qubership-apihub-json-crawl' -import { annotation, breaking, DiffAction, nonBreaking } from '../../../../src' -import { diffsMatcher, expectOpenApiVersionChange } from '../../../helper/matchers' - -const COMPONENTS_SCHEMAS = ['components', 'schemas'] - -export function runCommonSchema31Tests(suiteId: string, commonPath: JsonPath): void { - describe('Union type', () => { - test.caseForOpenApiVersionPairs('add-union-type', suiteId, async ({ beforeVersion, afterVersion, diffs }) => { - expect(diffs).toEqual(diffsMatcher([ - expectOpenApiVersionChange(beforeVersion, afterVersion), - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...commonPath, 'type', 1]], - type: nonBreaking, - }), - ])) - }) - - test.caseForOpenApiVersionPairs('add-null-to-union-type', suiteId, async ({ beforeVersion, afterVersion, diffs }) => { - expect(diffs).toEqual(diffsMatcher([ - expectOpenApiVersionChange(beforeVersion, afterVersion), - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [[...commonPath, 'type', 2]], - type: nonBreaking, - }), - ])) - }) - - test.caseForOpenApiVersionPairs('remove-union-type', suiteId, async ({ beforeVersion, afterVersion, diffs }) => { - expect(diffs).toEqual(diffsMatcher([ - expectOpenApiVersionChange(beforeVersion, afterVersion), - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...commonPath, 'type', 1]], - type: breaking, - }), - ])) - }) - - test.caseForOpenApiVersionPairs('remove-null-from-union-type', suiteId, async ({ beforeVersion, afterVersion, diffs }) => { - expect(diffs).toEqual(diffsMatcher([ - expectOpenApiVersionChange(beforeVersion, afterVersion), - expect.objectContaining({ - action: DiffAction.remove, - beforeDeclarationPaths: [[...commonPath, 'type', 2]], - type: breaking, - }), - ])) - }) - - test.caseForOpenApiVersionPairs('reorder-types-in-union-type', suiteId, async ({ beforeVersion, afterVersion, diffs }) => { - expect(diffs).toEqual(diffsMatcher([ - expectOpenApiVersionChange(beforeVersion, afterVersion), - ])) - }) - }) - - describe('$ref sibling properties', () => { - test.caseForOpenApiVersionPairs('add-sibling-description-for-ref', suiteId, async ({ beforeVersion, afterVersion, diffs }) => { - expect(diffs).toEqual(diffsMatcher([ - expectOpenApiVersionChange(beforeVersion, afterVersion), - expect.objectContaining({ - action: DiffAction.replace, - afterDeclarationPaths: [[...commonPath, 'description']], - beforeDeclarationPaths: [[...COMPONENTS_SCHEMAS, 'Pet', 'description']], - type: annotation, - }), - ])) - }) - - test.caseForOpenApiVersionPairs('change-sibling-enum-for-ref', suiteId, async ({ beforeVersion, afterVersion, diffs }) => { - expect(diffs).toEqual(diffsMatcher([ - expectOpenApiVersionChange(beforeVersion, afterVersion), - ])) - }) - - test.caseForOpenApiVersionPairs('change-referenced-enum-when-sibling-exists-for-ref', suiteId, async ({ beforeVersion, afterVersion, diffs }) => { - expect(diffs).toEqual(diffsMatcher([ - expectOpenApiVersionChange(beforeVersion, afterVersion), - expect.objectContaining({ - action: DiffAction.add, - afterDeclarationPaths: [ - [...COMPONENTS_SCHEMAS, 'Color', 'enum', 1], - [...commonPath, 'enum', 1], - ], - type: nonBreaking, - }), - ])) - }) - - test.caseForOpenApiVersionPairs('remove-sibling-maxLength-for-ref', suiteId, async ({ beforeVersion, afterVersion, diffs }) => { - expect(diffs).toEqual(diffsMatcher([ - expectOpenApiVersionChange(beforeVersion, afterVersion), - expect.objectContaining({ - action: DiffAction.replace, - beforeDeclarationPaths: [[...commonPath, 'maxLength']], - afterDeclarationPaths: [[...COMPONENTS_SCHEMAS, 'Color', 'maxLength']], - type: nonBreaking, - }), - ])) - }) - }) - - describe('Cross-version equivalency', () => { - test.caseForOpenApiVersionPairs('nullable-equivalent-to-null', suiteId, async ({ beforeVersion, afterVersion, diffs }) => { - expect(diffs).toEqual(diffsMatcher([ - expectOpenApiVersionChange(beforeVersion, afterVersion), - ])) - }) - - test.caseForOpenApiVersionPairs('union-type-equivalent-to-any-of', suiteId, async ({ beforeVersion, afterVersion, diffs }) => { - expect(diffs).toEqual(diffsMatcher([ - expectOpenApiVersionChange(beforeVersion, afterVersion), - ])) - }) - }) -} diff --git a/test/compatibility-suites/schemas/schema-test-runner-general.ts b/test/compatibility-suites/schemas/schema-test-runner-general.ts new file mode 100644 index 0000000..ba4d007 --- /dev/null +++ b/test/compatibility-suites/schemas/schema-test-runner-general.ts @@ -0,0 +1,1205 @@ +import { JSON_SCHEMA_NODE_SYNTHETIC_TYPE_ANY } from '@netcracker/qubership-apihub-api-unifier' +import { TestSpecType } from '@netcracker/qubership-apihub-compatibility-suites' +import { JsonPath } from '@netcracker/qubership-apihub-json-crawl' +import { annotation, breaking, DiffAction, nonBreaking, risky } from '../../../src' +import { diffsMatcher, expectSpecVersionChange } from '../../helper/matchers' +import { + compareFiles, + compareFilesWithMerge, + createExpectedDiffTypeSelector, + currentTestId, + DataFlowDirection, + TEST_DEFAULTS_DECLARATION_PATHS, +} from '../utils' + +export function runGeneralSchemaTests( + suiteType: TestSpecType, + suiteId: string, + commonPath: JsonPath, + direction: DataFlowDirection, +): void { + const expectedType = createExpectedDiffTypeSelector(direction) + + describe('General', () => { + describe('JSON Schema Keywords', () => { + test('add-schema-title', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.add, + afterDeclarationPaths: [[...commonPath, 'title']], + type: annotation, + }), + ])) + }) + + test('update-schema-title', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'title']], + afterDeclarationPaths: [[...commonPath, 'title']], + type: annotation, + }), + ])) + }) + + test('remove-schema-title', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.remove, + beforeDeclarationPaths: [[...commonPath, 'title']], + type: annotation, + }), + ])) + }) + + test('update-schema-type', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'type']], + afterDeclarationPaths: [[...commonPath, 'type']], + type: breaking, + }), + ])) + }) + + test('update-schema-type-from-specific-type-to-any-type', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeValue: 'string', + afterValue: JSON_SCHEMA_NODE_SYNTHETIC_TYPE_ANY, + beforeDeclarationPaths: [[...commonPath, 'type']], + afterDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, + type: expectedType(nonBreaking, breaking), + }), + ])) + }) + + test('update-schema-type-to-an-equivalent-value', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual([]) + }) + + test('add-enum', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.add, + afterDeclarationPaths: [[...commonPath, 'enum']], + type: expectedType(breaking, nonBreaking), + }), + ])) + }) + + test('remove-enum', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.remove, + beforeDeclarationPaths: [[...commonPath, 'enum']], + type: expectedType(nonBreaking, risky), + }), + ])) + }) + + test('add-enum-value', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.add, + afterDeclarationPaths: [[...commonPath, 'enum', 2]], + type: expectedType(nonBreaking, risky), + }), + ])) + }) + + test('update-enum-value', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.remove, + beforeDeclarationPaths: [[...commonPath, 'enum', 1]], + type: expectedType(breaking, nonBreaking), + }), + expect.objectContaining({ + action: DiffAction.add, + afterDeclarationPaths: [[...commonPath, 'enum', 1]], + type: expectedType(nonBreaking, risky), + }), + ])) + }) + + test('remove-enum-value', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.remove, + beforeDeclarationPaths: [[...commonPath, 'enum', 2]], + type: expectedType(breaking, nonBreaking), + }), + ])) + }) + + test('add-format-for-string-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.add, + afterDeclarationPaths: [[...commonPath, 'format']], + type: expectedType(breaking, nonBreaking), + }), + ])) + }) + + test('update-format-for-string-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'format']], + afterDeclarationPaths: [[...commonPath, 'format']], + type: breaking, + }), + ])) + }) + + test('remove-format-for-string-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.remove, + beforeDeclarationPaths: [[...commonPath, 'format']], + type: expectedType(nonBreaking, breaking), + }), + ])) + }) + + test('add-min-length-for-string-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'properties', 'option1', 'minLength']], + afterDeclarationPaths: [[...commonPath, 'properties', 'option1', 'minLength']], + type: expectedType(breaking, nonBreaking), + }), + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, + afterDeclarationPaths: [[...commonPath, 'properties', 'option2', 'minLength']], + type: expectedType(breaking, nonBreaking), + }), + ])) + }) + + test('increase-min-length-for-string-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'minLength']], + afterDeclarationPaths: [[...commonPath, 'minLength']], + type: expectedType(breaking, nonBreaking), + }), + ])) + }) + + test('decrease-min-length-for-string-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'minLength']], + afterDeclarationPaths: [[...commonPath, 'minLength']], + type: expectedType(nonBreaking, breaking), + }), + ])) + }) + + test('remove-min-length-for-string-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'properties', 'option1', 'minLength']], + afterDeclarationPaths: [[...commonPath, 'properties', 'option1', 'minLength']], + type: expectedType(nonBreaking, breaking), + }), + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'properties', 'option2', 'minLength']], + afterDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, + type: expectedType(nonBreaking, breaking), + }), + ])) + }) + + test('add-max-length-for-string-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.add, + afterDeclarationPaths: [[...commonPath, 'maxLength']], + type: expectedType(breaking, nonBreaking), + }), + ])) + }) + + test('increase-max-length-for-string-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'maxLength']], + afterDeclarationPaths: [[...commonPath, 'maxLength']], + type: expectedType(nonBreaking, breaking), + }), + ])) + }) + + test('decrease-max-length-for-string-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'maxLength']], + afterDeclarationPaths: [[...commonPath, 'maxLength']], + type: expectedType(breaking, nonBreaking), + }), + ])) + }) + + test('remove-max-length-for-string-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.remove, + beforeDeclarationPaths: [[...commonPath, 'maxLength']], + type: expectedType(nonBreaking, breaking), + }), + ])) + }) + + test('add-pattern-for-string-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.add, + afterDeclarationPaths: [[...commonPath, 'pattern']], + type: expectedType(breaking, nonBreaking), + }), + ])) + }) + + test('update-pattern-for-string-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'pattern']], + afterDeclarationPaths: [[...commonPath, 'pattern']], + type: breaking, + }), + ])) + }) + + test('remove-pattern-for-string-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.remove, + beforeDeclarationPaths: [[...commonPath, 'pattern']], + type: expectedType(nonBreaking, breaking), + }), + ])) + }) + + test('add-format-for-number-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.add, + afterDeclarationPaths: [[...commonPath, 'format']], + type: expectedType(breaking, nonBreaking), + }), + ])) + }) + + test('update-format-for-number-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'format']], + afterDeclarationPaths: [[...commonPath, 'format']], + type: breaking, + }), + ])) + }) + + test('remove-format-for-number-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.remove, + beforeDeclarationPaths: [[...commonPath, 'format']], + type: expectedType(nonBreaking, breaking), + }), + ])) + }) + + test('add-minimum-for-number-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.add, + afterDeclarationPaths: [[...commonPath, 'minimum']], + type: expectedType(breaking, nonBreaking), + }), + ])) + }) + + test('increase-minimum-for-number-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'minimum']], + afterDeclarationPaths: [[...commonPath, 'minimum']], + type: expectedType(breaking, nonBreaking), + }), + ])) + }) + + test('decrease-minimum-for-number-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'minimum']], + afterDeclarationPaths: [[...commonPath, 'minimum']], + type: expectedType(nonBreaking, breaking), + }), + ])) + }) + + test('remove-minimum-for-number-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.remove, + beforeDeclarationPaths: [[...commonPath, 'minimum']], + type: expectedType(nonBreaking, breaking), + }), + ])) + }) + + test('add-maximum-for-number-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.add, + afterDeclarationPaths: [[...commonPath, 'maximum']], + type: expectedType(breaking, nonBreaking), + }), + ])) + }) + + test('increase-maximum-for-number-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'maximum']], + afterDeclarationPaths: [[...commonPath, 'maximum']], + type: expectedType(nonBreaking, breaking), + }), + ])) + }) + + test('decrease-maximum-for-number-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'maximum']], + afterDeclarationPaths: [[...commonPath, 'maximum']], + type: expectedType(breaking, nonBreaking), + }), + ])) + }) + + test('remove-maximum-for-number-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.remove, + beforeDeclarationPaths: [[...commonPath, 'maximum']], + type: expectedType(nonBreaking, breaking), + }), + ])) + }) + + test('add-multiple-of-for-number-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.add, + afterDeclarationPaths: [[...commonPath, 'multipleOf']], + type: expectedType(breaking, nonBreaking), + }), + ])) + }) + + test('update-multiple-of-for-number-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'multipleOf']], + afterDeclarationPaths: [[...commonPath, 'multipleOf']], + type: breaking, + }), + ])) + }) + + test('remove-multiple-of-for-number-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.remove, + beforeDeclarationPaths: [[...commonPath, 'multipleOf']], + type: expectedType(nonBreaking, breaking), + }), + ])) + }) + + test('add-min-items-for-array-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, + afterDeclarationPaths: [[...commonPath, 'minItems']], + type: expectedType(breaking, nonBreaking), + }), + ])) + }) + + test('increase-min-items-for-array-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'minItems']], + afterDeclarationPaths: [[...commonPath, 'minItems']], + type: expectedType(breaking, nonBreaking), + }), + ])) + }) + + test('decrease-min-items-for-array-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'minItems']], + afterDeclarationPaths: [[...commonPath, 'minItems']], + type: expectedType(nonBreaking, breaking), + }), + ])) + }) + + test('remove-min-items-for-array-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'minItems']], + afterDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, + type: expectedType(nonBreaking, breaking), + }), + ])) + }) + + test('add-max-items-for-array-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.add, + afterDeclarationPaths: [[...commonPath, 'maxItems']], + type: expectedType(breaking, nonBreaking), + }), + ])) + }) + + test('increase-max-items-for-array-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'maxItems']], + afterDeclarationPaths: [[...commonPath, 'maxItems']], + type: expectedType(nonBreaking, breaking), + }), + ])) + }) + + test('decrease-max-items-for-array-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'maxItems']], + afterDeclarationPaths: [[...commonPath, 'maxItems']], + type: expectedType(breaking, nonBreaking), + }), + ])) + }) + + test('remove-max-items-for-array-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.remove, + beforeDeclarationPaths: [[...commonPath, 'maxItems']], + type: expectedType(nonBreaking, breaking), + }), + ])) + }) + + test('prohibit-non-unique-items-for-array-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, + afterDeclarationPaths: [[...commonPath, 'properties', 'option1', 'uniqueItems']], + type: expectedType(breaking, nonBreaking), + }), + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'properties', 'option2', 'uniqueItems']], + afterDeclarationPaths: [[...commonPath, 'properties', 'option2', 'uniqueItems']], + type: expectedType(breaking, nonBreaking), + }), + ])) + }) + + test('allow-non-unique-items-for-array-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'properties', 'option1', 'uniqueItems']], + afterDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, + type: expectedType(nonBreaking, breaking), + }), + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'properties', 'option2', 'uniqueItems']], + afterDeclarationPaths: [[...commonPath, 'properties', 'option2', 'uniqueItems']], + type: expectedType(nonBreaking, breaking), + }), + ])) + }) + + test('add-new-property-compliance', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.add, + afterDeclarationPaths: [[...commonPath, 'properties', 'prop2']], + type: nonBreaking, + }), + ])) + }) + + test('remove-property-compliance', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.remove, + beforeDeclarationPaths: [[...commonPath, 'properties', 'prop2']], + type: expectedType(breaking, nonBreaking), + }), + ])) + }) + + test('add-required-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.add, + afterDeclarationPaths: [[...commonPath, 'required', 0]], + type: expectedType(breaking, nonBreaking), + }), + expect.objectContaining({ + action: DiffAction.add, + afterDeclarationPaths: [[...commonPath, 'required', 1]], + type: expectedType(breaking, nonBreaking), + }), + ])) + }) + + test('add-required-property-with-default', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.add, + afterDeclarationPaths: [[...commonPath, 'required', 0]], + type: nonBreaking, + }), + expect.objectContaining({ + action: DiffAction.add, + afterDeclarationPaths: [[...commonPath, 'required', 1]], + type: nonBreaking, + }), + ])) + }) + + test('remove-required-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.remove, + beforeDeclarationPaths: [[...commonPath, 'required', 0]], + type: expectedType(nonBreaking, breaking), + }), + ])) + }) + + test('update-required-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.remove, + beforeDeclarationPaths: [[...commonPath, 'required', 0]], + type: expectedType(nonBreaking, breaking), + }), + expect.objectContaining({ + action: DiffAction.add, + afterDeclarationPaths: [[...commonPath, 'required', 0]], + type: expectedType(breaking, nonBreaking), + }), + ])) + }) + + test('mark-object-property-as-read-only', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'properties', 'option1', 'readOnly']], + afterDeclarationPaths: [[...commonPath, 'properties', 'option1', 'readOnly']], + type: expectedType(breaking, nonBreaking), + }), + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, + afterDeclarationPaths: [[...commonPath, 'properties', 'option2', 'readOnly']], + type: expectedType(breaking, nonBreaking), + }), + ])) + }) + + test('mark-object-property-as-not-read-only', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'properties', 'option1', 'readOnly']], + afterDeclarationPaths: [[...commonPath, 'properties', 'option1', 'readOnly']], + type: nonBreaking, + }), + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'properties', 'option2', 'readOnly']], + afterDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, + type: nonBreaking, + }), + ])) + }) + + test('mark-object-property-as-write-only', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, + afterDeclarationPaths: [[...commonPath, 'properties', 'option1', 'writeOnly']], + type: nonBreaking, + }), + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'properties', 'option2', 'writeOnly']], + afterDeclarationPaths: [[...commonPath, 'properties', 'option2', 'writeOnly']], + type: nonBreaking, + }), + ])) + }) + + test('mark-object-property-as-not-write-only', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'properties', 'option1', 'writeOnly']], + afterDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, + type: nonBreaking, + }), + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'properties', 'option2', 'writeOnly']], + afterDeclarationPaths: [[...commonPath, 'properties', 'option2', 'writeOnly']], + type: nonBreaking, + }), + ])) + }) + + test('add-min-properties-for-object-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, + afterDeclarationPaths: [[...commonPath, 'minProperties']], + type: expectedType(breaking, nonBreaking), + }), + ])) + }) + + test('increase-min-properties-for-object-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'minProperties']], + afterDeclarationPaths: [[...commonPath, 'minProperties']], + type: expectedType(breaking, nonBreaking), + }), + ])) + }) + + test('decrease-min-properties-for-object-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'minProperties']], + afterDeclarationPaths: [[...commonPath, 'minProperties']], + type: expectedType(nonBreaking, breaking), + }), + ])) + }) + + test('remove-min-properties-for-object-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'minProperties']], + afterDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, + type: expectedType(nonBreaking, breaking), + }), + ])) + }) + + test('add-max-properties-for-object-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.add, + afterDeclarationPaths: [[...commonPath, 'maxProperties']], + type: expectedType(breaking, nonBreaking), + }), + ])) + }) + + test('increase-max-properties-for-object-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'maxProperties']], + afterDeclarationPaths: [[...commonPath, 'maxProperties']], + type: expectedType(nonBreaking, breaking), + }), + ])) + }) + + test('decrease-max-properties-for-object-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'maxProperties']], + afterDeclarationPaths: [[...commonPath, 'maxProperties']], + type: expectedType(breaking, nonBreaking), + }), + ])) + }) + + test('remove-max-properties-for-object-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.remove, + beforeDeclarationPaths: [[...commonPath, 'maxProperties']], + type: expectedType(nonBreaking, breaking), + }), + ])) + }) + + test('update-definition-of-free-form-object', async () => { + const result = await compareFilesWithMerge(suiteId, currentTestId(), suiteType) + expect(result.merged).not.toHaveProperty([...commonPath, 'properties', 'option1', 'additionalProperties']) + expect(result.merged).not.toHaveProperty([...commonPath, 'properties', 'option2', 'additionalProperties']) + expect(result.merged).not.toHaveProperty([...commonPath, 'additionalProperties']) + expect(result.diffs).toEqual([]) + }) + + test('add-non-boolean-additional-properties', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual( + diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeValue: JSON_SCHEMA_NODE_SYNTHETIC_TYPE_ANY, + afterValue: 'string', + beforeDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, + afterDeclarationPaths: [[...commonPath, 'additionalProperties', 'type']], + type: expectedType(breaking, nonBreaking), + }), + ]), + ) + }) + + test('update-type-of-additional-properties', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'additionalProperties', 'type']], + afterDeclarationPaths: [[...commonPath, 'additionalProperties', 'type']], + type: breaking, + }), + ])) + }) + + test('remove-additional-properties', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual( + diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeValue: 'string', + afterValue: JSON_SCHEMA_NODE_SYNTHETIC_TYPE_ANY, + beforeDeclarationPaths: [[...commonPath, 'additionalProperties', 'type']], + afterDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, + type: expectedType(nonBreaking, breaking), + }), + ]), + ) + }) + + test('add-one-of', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.add, + afterDeclarationPaths: [[...commonPath, 'oneOf', 1]], + type: expectedType(nonBreaking, breaking), + }), + ])) + }) + + test('add-one-of-option', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.add, + afterDeclarationPaths: [[...commonPath, 'oneOf', 2]], + type: expectedType(nonBreaking, breaking), + }), + ])) + }) + + test('remove-one-of-option', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.remove, + beforeDeclarationPaths: [[...commonPath, 'oneOf', 2]], + type: expectedType(breaking, nonBreaking), + }), + ])) + }) + + test('remove-one-of', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.remove, + beforeDeclarationPaths: [[...commonPath, 'oneOf', 1]], + type: expectedType(breaking, nonBreaking), + }), + ])) + }) + + test('add-any-of', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.add, + afterDeclarationPaths: [[...commonPath, 'anyOf', 1]], + type: expectedType(nonBreaking, breaking), + }), + ])) + }) + + test('add-any-of-option', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.add, + afterDeclarationPaths: [[...commonPath, 'anyOf', 2]], + type: expectedType(nonBreaking, breaking), + }), + ])) + }) + + test('remove-any-of-option', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.remove, + beforeDeclarationPaths: [[...commonPath, 'anyOf', 2]], + type: expectedType(breaking, nonBreaking), + }), + ])) + }) + + test('remove-any-of', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.remove, + beforeDeclarationPaths: [[...commonPath, 'anyOf', 1]], + type: expectedType(breaking, nonBreaking), + }), + ])) + }) + + test('add-all-of', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.add, + afterDeclarationPaths: [[...commonPath, 'allOf', 1, 'properties', 'prop2']], + type: nonBreaking, + }), + ])) + }) + + test('add-all-of-option', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.add, + afterDeclarationPaths: [[...commonPath, 'allOf', 2, 'properties', 'prop3']], + type: nonBreaking, + }), + ])) + }) + + test('remove-all-of-option', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.remove, + beforeDeclarationPaths: [[...commonPath, 'allOf', 2, 'properties', 'prop3']], + type: expectedType(breaking, nonBreaking), + }), + ])) + }) + + test('remove-all-of', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.remove, + beforeDeclarationPaths: [[...commonPath, 'allOf', 1, 'properties', 'prop2']], + type: expectedType(breaking, nonBreaking), + }), + ])) + }) + + // TODO: fixme + test.skip('update-schema-type-from-any-type-to-specific-type', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [TEST_DEFAULTS_DECLARATION_PATHS], + afterDeclarationPaths: [[...commonPath, 'type']], + type: expectedType(breaking, nonBreaking), + }), + ])) + }) + + // TODO: fixme + test.skip('update-schema-type-from-specific-type-to-nothing', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'type']], + afterDeclarationPaths: [[...commonPath, 'allOf']], + type: breaking, + }), + ])) + }) + + // TODO: fixme + test.skip('update-schema-type-from-nothing-to-specific-type', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'allOf']], + afterDeclarationPaths: [[...commonPath, 'type']], + type: nonBreaking, + }), + ])) + }) + + // --- General default value tests (no path needed, all expect empty diffs) --- + + test('add-minItems-with-default-value-for-array-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual([]) + }) + + test('remove-minItems-with-default-value-for-array-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual([]) + }) + + test('add-uniqueItems-with-default-value-for-array-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual([]) + }) + + test('remove-uniqueItems-with-default-value-for-array-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual([]) + }) + + test('add-minProperties-with-default-value-for-object-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual([]) + }) + + test('remove-minProperties-with-default-value-for-object-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual([]) + }) + }) + + describe('Union Types', () => { + test.caseForSpecVersionPairs( + suiteType, + 'add-union-type', + suiteId, + async ({ beforeVersion, afterVersion, diffs }) => { + expect(diffs).toEqual(diffsMatcher([ + expectSpecVersionChange(suiteType, beforeVersion, afterVersion), + expect.objectContaining({ + action: DiffAction.add, + afterDeclarationPaths: [[...commonPath, 'type', 1]], + type: expectedType(nonBreaking, breaking), + }), + ])) + }, + ) + + test.caseForSpecVersionPairs( + suiteType, + 'add-null-to-union-type', + suiteId, + async ({ beforeVersion, afterVersion, diffs }) => { + expect(diffs).toEqual(diffsMatcher([ + expectSpecVersionChange(suiteType, beforeVersion, afterVersion), + expect.objectContaining({ + action: DiffAction.add, + afterDeclarationPaths: [[...commonPath, 'type', 2]], + type: expectedType(nonBreaking, breaking), + }), + ])) + }, + ) + + test.caseForSpecVersionPairs( + suiteType, + 'remove-union-type', + suiteId, + async ({ beforeVersion, afterVersion, diffs }) => { + expect(diffs).toEqual(diffsMatcher([ + expectSpecVersionChange(suiteType, beforeVersion, afterVersion), + expect.objectContaining({ + action: DiffAction.remove, + beforeDeclarationPaths: [[...commonPath, 'type', 1]], + type: expectedType(breaking, nonBreaking), + }), + ])) + }, + ) + + test.caseForSpecVersionPairs( + suiteType, + 'remove-null-from-union-type', + suiteId, + async ({ beforeVersion, afterVersion, diffs }) => { + expect(diffs).toEqual(diffsMatcher([ + expectSpecVersionChange(suiteType, beforeVersion, afterVersion), + expect.objectContaining({ + action: DiffAction.remove, + beforeDeclarationPaths: [[...commonPath, 'type', 2]], + type: expectedType(breaking, nonBreaking), + }), + ])) + }, + ) + + test.caseForSpecVersionPairs( + suiteType, + 'reorder-types-in-union-type', + suiteId, + async ({ beforeVersion, afterVersion, diffs }) => { + expect(diffs).toEqual(diffsMatcher([ + expectSpecVersionChange(suiteType, beforeVersion, afterVersion), + ])) + }, + ) + + test.caseForSpecVersionPairs( + suiteType, + 'union-type-equivalent-to-any-of', + suiteId, + async ({ beforeVersion, afterVersion, diffs }) => { + expect(diffs).toEqual(diffsMatcher([ + expectSpecVersionChange(suiteType, beforeVersion, afterVersion), + ])) + }, + ) + }) + }) +} diff --git a/test/compatibility-suites/schemas/schema-test-runner-openapi-only.ts b/test/compatibility-suites/schemas/schema-test-runner-openapi-only.ts new file mode 100644 index 0000000..71fc400 --- /dev/null +++ b/test/compatibility-suites/schemas/schema-test-runner-openapi-only.ts @@ -0,0 +1,465 @@ +import { TestSpecType } from '@netcracker/qubership-apihub-compatibility-suites' +import { JsonPath } from '@netcracker/qubership-apihub-json-crawl' +import { annotation, breaking, DiffAction, nonBreaking, risky } from '../../../src' +import { diffsMatcher, expectSpecVersionChange } from '../../helper/matchers' +import { + compareFiles, + createExpectedDiffTypeSelector, + currentTestId, + DataFlowDirection, + TEST_DEFAULTS_DECLARATION_PATHS, +} from '../utils' + +export function runOpenApiOnlySchemaTests( + suiteType: TestSpecType, + suiteId: string, + commonPath: JsonPath, + direction: DataFlowDirection, +): void { + const expectedType = createExpectedDiffTypeSelector(direction) + + describe('OpenAPI-Only', () => { + describe('OpenAPI Vocabulary', () => { + test.caseForSpecVersionPairs( + suiteType, + 'mark-schema-value-as-nullable', + suiteId, + async ({ beforeVersion, afterVersion, diffs }) => { + expect(diffs).toEqual(diffsMatcher([ + expectSpecVersionChange(suiteType, beforeVersion, afterVersion), + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, + afterDeclarationPaths: [[...commonPath, 'properties', 'option1', 'nullable']], + type: expectedType(nonBreaking, breaking), + }), + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'properties', 'option2', 'nullable']], + afterDeclarationPaths: [[...commonPath, 'properties', 'option2', 'nullable']], + type: expectedType(nonBreaking, breaking), + }), + ])) + }, + ) + + test.caseForSpecVersionPairs( + suiteType, + 'mark-schema-value-as-non-nullable', + suiteId, + async ({ beforeVersion, afterVersion, diffs }) => { + expect(diffs).toEqual(diffsMatcher([ + expectSpecVersionChange(suiteType, beforeVersion, afterVersion), + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'properties', 'option1', 'nullable']], + afterDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, + type: expectedType(breaking, nonBreaking), + }), + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'properties', 'option2', 'nullable']], + afterDeclarationPaths: [[...commonPath, 'properties', 'option2', 'nullable']], + type: expectedType(breaking, nonBreaking), + }), + ])) + }, + ) + + // discriminator tests - all test.skip + test.skip('add-discriminator-for-one-of', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.add, + afterDeclarationPaths: [[...commonPath, 'discriminator']], + type: nonBreaking, + }), + ])) + }) + test.skip('remove-discriminator-for-one-of', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.remove, + beforeDeclarationPaths: [[...commonPath, 'discriminator']], + type: nonBreaking, + }), + ])) + }) + test.skip('update-discriminator-for-one-of', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'discriminator', 'propertyName']], + afterDeclarationPaths: [[...commonPath, 'discriminator', 'propertyName']], + type: nonBreaking, + }), + ])) + }) + test.skip('add-discriminator-for-any-of', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.add, + afterDeclarationPaths: [[...commonPath, 'discriminator']], + type: nonBreaking, + }), + ])) + }) + test.skip('remove-discriminator-for-any-of', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.remove, + beforeDeclarationPaths: [[...commonPath, 'discriminator']], + type: nonBreaking, + }), + ])) + }) + test.skip('update-discriminator-for-any-of', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'discriminator', 'propertyName']], + afterDeclarationPaths: [[...commonPath, 'discriminator', 'propertyName']], + type: nonBreaking, + }), + ])) + }) + + // xml tests - all test.skip + test.skip('add-xml-name-replacement-for-schema', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.add, + afterDeclarationPaths: [[...commonPath, 'xml']], + type: breaking, + }), + ])) + }) + test.skip('update-xml-name-replacement-for-schema', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'xml', 'name']], + afterDeclarationPaths: [[...commonPath, 'xml', 'name']], + type: breaking, + }), + ])) + }) + test.skip('remove-xml-name-replacement-for-schema', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.remove, + beforeDeclarationPaths: [[...commonPath, 'xml']], + type: breaking, + }), + ])) + }) + test.skip('add-xml-name-replacement-for-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.add, + afterDeclarationPaths: [[...commonPath, 'properties', 'id', 'xml']], + type: breaking, + }), + ])) + }) + test.skip('update-xml-name-replacement-for-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'properties', 'id', 'xml', 'name']], + afterDeclarationPaths: [[...commonPath, 'properties', 'id', 'xml', 'name']], + type: breaking, + }), + ])) + }) + test.skip('remove-xml-name-replacement-for-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.remove, + beforeDeclarationPaths: [[...commonPath, 'properties', 'id', 'xml']], + type: breaking, + }), + ])) + }) + test.skip('mark-property-as-xml-attribute', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.add, + afterDeclarationPaths: [[...commonPath, 'properties', 'option1', 'xml', 'attribute']], + type: breaking, + }), + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'properties', 'option2', 'xml', 'attribute']], + afterDeclarationPaths: [[...commonPath, 'properties', 'option2', 'xml', 'attribute']], + type: breaking, + }), + ])) + }) + test.skip('mark-property-as-xml-element', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.remove, + beforeDeclarationPaths: [[...commonPath, 'properties', 'option1', 'xml', 'attribute']], + type: breaking, + }), + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'properties', 'option2', 'xml', 'attribute']], + afterDeclarationPaths: [[...commonPath, 'properties', 'option2', 'xml', 'attribute']], + type: breaking, + }), + ])) + }) + test.skip('add-xml-prefix-and-namespace-for-schema', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.add, + afterDeclarationPaths: [[...commonPath, 'xml']], + type: breaking, + }), + ])) + }) + test.skip('update-xml-prefix-for-schema', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'xml', 'prefix']], + afterDeclarationPaths: [[...commonPath, 'xml', 'prefix']], + type: breaking, + }), + ])) + }) + test.skip('remove-xml-prefix-and-namespace-for-schema', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.remove, + beforeDeclarationPaths: [[...commonPath, 'xml']], + type: breaking, + }), + ])) + }) + test.skip('add-xml-wrapped-for-array-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.add, + afterDeclarationPaths: [[...commonPath, 'xml', 'wrapped']], + type: breaking, + }), + ])) + }) + test.skip('remove-xml-wrapped-for-array-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.remove, + beforeDeclarationPaths: [[...commonPath, 'xml', 'wrapped']], + type: breaking, + }), + ])) + }) + + // nullable cross-version (OpenAPI-only) + test.caseForSpecVersionPairs( + suiteType, + 'nullable-equivalent-to-null', + suiteId, + async ({ beforeVersion, afterVersion, diffs }) => { + expect(diffs).toEqual(diffsMatcher([ + expectSpecVersionChange(suiteType, beforeVersion, afterVersion), + ])) + }, + ) + + // OpenAPI-only default value tests + test('add-attribute-with-default-value-for-xml', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual([]) + }) + test('remove-attribute-with-default-value-for-xml', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual([]) + }) + test('add-xml-wrapped-with-default-value-for-array-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual([]) + }) + test('remove-xml-wrapped-with-default-value-for-array-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual([]) + }) + }) + + describe('OpenAPI 3.0 Exclusive Bounds', () => { + test('mark-minimum-value-as-exclusive-for-number-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, + afterDeclarationPaths: [[...commonPath, 'properties', 'option1', 'exclusiveMinimum']], + type: expectedType(breaking, nonBreaking), + }), + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'properties', 'option2', 'exclusiveMinimum']], + afterDeclarationPaths: [[...commonPath, 'properties', 'option2', 'exclusiveMinimum']], + type: expectedType(breaking, nonBreaking), + }), + ])) + }) + test('mark-minimum-value-as-inclusive-for-number-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'properties', 'option1', 'exclusiveMinimum']], + afterDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, + type: expectedType(nonBreaking, breaking), + }), + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'properties', 'option2', 'exclusiveMinimum']], + afterDeclarationPaths: [[...commonPath, 'properties', 'option2', 'exclusiveMinimum']], + type: expectedType(nonBreaking, breaking), + }), + ])) + }) + test('mark-maximum-value-as-exclusive-for-number-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, + afterDeclarationPaths: [[...commonPath, 'properties', 'option1', 'exclusiveMaximum']], + type: expectedType(breaking, nonBreaking), + }), + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'properties', 'option2', 'exclusiveMaximum']], + afterDeclarationPaths: [[...commonPath, 'properties', 'option2', 'exclusiveMaximum']], + type: expectedType(breaking, nonBreaking), + }), + ])) + }) + test('mark-maximum-value-as-inclusive-for-number-property', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'properties', 'option1', 'exclusiveMaximum']], + afterDeclarationPaths: TEST_DEFAULTS_DECLARATION_PATHS, + type: expectedType(nonBreaking, breaking), + }), + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'properties', 'option2', 'exclusiveMaximum']], + afterDeclarationPaths: [[...commonPath, 'properties', 'option2', 'exclusiveMaximum']], + type: expectedType(nonBreaking, breaking), + }), + ])) + }) + test('update-specific-type-to-number-with-exclusive-value', async () => { + const result = await compareFiles(suiteId, currentTestId(), suiteType) + expect(result).toEqual(diffsMatcher([ + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'type']], + afterDeclarationPaths: [[...commonPath, 'type']], + type: breaking, + }), + expect.objectContaining({ + action: DiffAction.add, + afterDeclarationPaths: [[...commonPath, 'exclusiveMaximum']], + type: expectedType(breaking, nonBreaking), + }), + expect.objectContaining({ + action: DiffAction.add, + afterDeclarationPaths: [[...commonPath, 'exclusiveMinimum']], + type: expectedType(breaking, nonBreaking), + }), + ])) + }) + }) + + describe('Reference Sibling Properties', () => { + const COMPONENTS_SCHEMAS = ['components', 'schemas'] + + test.caseForSpecVersionPairs( + suiteType, + 'add-sibling-description-for-ref', + suiteId, + async ({ beforeVersion, afterVersion, diffs }) => { + expect(diffs).toEqual(diffsMatcher([ + expectSpecVersionChange(suiteType, beforeVersion, afterVersion), + expect.objectContaining({ + action: DiffAction.replace, + afterDeclarationPaths: [[...commonPath, 'description']], + beforeDeclarationPaths: [[...COMPONENTS_SCHEMAS, 'Pet', 'description']], + type: annotation, + }), + ])) + }, + ) + test.caseForSpecVersionPairs( + suiteType, + 'change-sibling-enum-for-ref', + suiteId, + async ({ beforeVersion, afterVersion, diffs }) => { + expect(diffs).toEqual(diffsMatcher([ + expectSpecVersionChange(suiteType, beforeVersion, afterVersion), + ])) + }, + ) + test.caseForSpecVersionPairs( + suiteType, + 'change-referenced-enum-when-sibling-exists-for-ref', + suiteId, + async ({ beforeVersion, afterVersion, diffs }) => { + expect(diffs).toEqual(diffsMatcher([ + expectSpecVersionChange(suiteType, beforeVersion, afterVersion), + expect.objectContaining({ + action: DiffAction.add, + afterDeclarationPaths: [[...COMPONENTS_SCHEMAS, 'Color', 'enum', 1], [...commonPath, 'enum', 1]], + type: expectedType(nonBreaking, risky), + }), + ])) + }, + ) + test.caseForSpecVersionPairs( + suiteType, + 'remove-sibling-maxLength-for-ref', + suiteId, + async ({ beforeVersion, afterVersion, diffs }) => { + expect(diffs).toEqual(diffsMatcher([ + expectSpecVersionChange(suiteType, beforeVersion, afterVersion), + expect.objectContaining({ + action: DiffAction.replace, + beforeDeclarationPaths: [[...commonPath, 'maxLength']], + afterDeclarationPaths: [[...COMPONENTS_SCHEMAS, 'Color', 'maxLength']], + type: expectedType(nonBreaking, breaking), + }), + ])) + }, + ) + }) + }) +} diff --git a/test/compatibility-suites/utils.ts b/test/compatibility-suites/utils.ts index 186f749..248dd0d 100644 --- a/test/compatibility-suites/utils.ts +++ b/test/compatibility-suites/utils.ts @@ -10,15 +10,44 @@ import { import { buildFromSchema, GraphApiDirectiveDefinition } from '@netcracker/qubership-apihub-graphapi' import { isObject } from '@netcracker/qubership-apihub-json-crawl' import { buildSchema } from 'graphql/utilities' -import { apiDiff, CompareOptions, CompareResult, Diff } from '../../src' +import { apiDiff, CompareOptions, CompareResult, Diff, DiffType } from '../../src' import { RUNTIME_DIRECTIVE_LOCATIONS } from '../../src/graphapi' import { TEST_DIFF_FLAG, TEST_ORIGINS_FLAG, TEST_SYNTHETIC_TITLE_FLAG } from '../helper' -const toMajorMinor = (v: string): string => (v.startsWith('3.1') ? '3.1' : '3.0') +export const DATA_FLOW_DIRECTION_SEND = 'send' as const +export const DATA_FLOW_DIRECTION_RECEIVE = 'receive' as const + +export type DataFlowDirection = typeof DATA_FLOW_DIRECTION_SEND | typeof DATA_FLOW_DIRECTION_RECEIVE + +/** + * Returns a selector that picks the expected diff type based on direction. + * First argument is for request, second is for response. + */ +export function createExpectedDiffTypeSelector(direction: DataFlowDirection) { + return (forSend: DiffType, forReceive: DiffType): DiffType => { + return direction === DATA_FLOW_DIRECTION_SEND ? forSend : forReceive + } +} + +/** + * Extracts test ID from the current Jest test name. + * In Jest 30, `currentTestName` joins describe/test names with a space. + * Since all test names in our suites are kebab-case (no spaces), the last word is the test ID. + */ +export const currentTestId = (): string => { + const fullName = expect.getState().currentTestName! + return fullName.split(' ').pop()! +} + +const toMajorMinor = (v: string): string => { + const match = v.match(/^(\d+\.\d+)/) + return match ? match[1] : v +} const pairTag = (pair: SpecificationVersionPair): string => `${toMajorMinor(pair[0])}-${toMajorMinor(pair[1])}` -type OpenApiVersionPairCaseContext = { +type SpecVersionPairCaseContext = { + suiteType: TestSpecType suiteId: string testId: string beforeVersion: string @@ -28,23 +57,26 @@ type OpenApiVersionPairCaseContext = { } /** - * Initializes custom Jest wrapper `caseForOpenApiVersionPairs` on `test`/`it` and their `.only`/`.skip` variants. + * Initializes custom Jest wrapper `caseForSpecVersionPairs` on `test`/`it` and their `.only`/`.skip` variants. * * Why: - * - **Runtime**: makes calls like `test.caseForOpenApiVersionPairs(...)` actually exist (they call into our generator). + * - **Runtime**: makes calls like `test.caseForSpecVersionPairs(...)` actually exist (they call into our generator). * - **IDE/Test Explorer**: many Jest integrations recognize only expressions starting with `test`/`it`, so - * `test.caseForOpenApiVersionPairs(...)` is easier for them to detect than a standalone helper call. + * `test.caseForSpecVersionPairs(...)` is easier for them to detect than a standalone helper call. * * Call this once from Jest `setupFilesAfterEnv` (see `test/setup/jest-wrappers.ts`). */ -export function initCaseForOpenApiVersionPairs(): void { +export function initCaseForSpecVersionPairs(): void { const attach = (jestIt: typeof test): void => { - (jestIt as unknown as Record).caseForOpenApiVersionPairs = ( + const record = jestIt as unknown as Record + + record.caseForSpecVersionPairs = ( + suiteType: TestSpecType, testId: string, suiteId: string, - fn: (ctx: OpenApiVersionPairCaseContext) => Promise | void, + fn: (ctx: SpecVersionPairCaseContext) => Promise | void, ): void => { - runCaseForOpenApiVersionPairs(jestIt, suiteId, testId, fn) + runCaseForSpecVersionPairs(jestIt, suiteType, testId, suiteId, fn) } } @@ -57,17 +89,18 @@ export function initCaseForOpenApiVersionPairs(): void { attach(it.skip) } -function runCaseForOpenApiVersionPairs( +function runCaseForSpecVersionPairs( jestTest: typeof test, - suiteId: string, + suiteType: TestSpecType, testId: string, - fn: (ctx: OpenApiVersionPairCaseContext) => Promise | void, + suiteId: string, + fn: (ctx: SpecVersionPairCaseContext) => Promise | void, ): void { - const pairs = getCompatibilitySuiteSpecificationVersionPairs(TEST_SPEC_TYPE_OPEN_API, suiteId, testId) + const pairs = getCompatibilitySuiteSpecificationVersionPairs(suiteType, suiteId, testId) if (pairs.length === 0) { - jestTest(`${testId} (no OpenAPI version pairs)`, () => { - throw new Error(`No OpenAPI version pairs for ${suiteId}/${testId}`) + jestTest(`${testId} (no version pairs)`, () => { + throw new Error(`No version pairs for (${suiteType}, ${suiteId}, ${testId})`) }) return } @@ -77,8 +110,9 @@ function runCaseForOpenApiVersionPairs( const afterVersion = pair[1] const caseTitle = `${testId} (${pairTag(pair)})` jestTest(caseTitle, async () => { - const { diffs, merged } = await compareFilesWithMerge(suiteId, testId, TEST_SPEC_TYPE_OPEN_API, pair) + const { diffs, merged } = await compareFilesWithMerge(suiteId, testId, suiteType, pair) await fn({ + suiteType, suiteId, testId, beforeVersion, @@ -155,6 +189,9 @@ export async function compareFilesWithMerge( afterObject = buildFromSchema(afterSchema) break } + default: { + throw new Error(`Unsupported spec type for comparison: ${type}`) + } } const beforeSchemaWithoutComponents = removeComponents(beforeObject) const afterSchemaWithoutComponents = removeComponents(afterObject) diff --git a/test/helper/matchers.ts b/test/helper/matchers.ts index 1ff6397..9cef265 100644 --- a/test/helper/matchers.ts +++ b/test/helper/matchers.ts @@ -1,8 +1,11 @@ import { Diff } from '../../src' import 'jest-extended' +import { + TEST_SPEC_TYPE_OPEN_API, + TestSpecType, +} from '@netcracker/qubership-apihub-compatibility-suites' import CustomEqualityTester = jasmine.CustomEqualityTester -import 'jest-extended' type ExpectedRecursive = T | ObjectContaining | AsymmetricMatcher | { [K in keyof T]: ExpectedRecursive | Any; @@ -41,7 +44,6 @@ export type RecursiveMatcher = { T[P]; } - export type DiffMatcher = ArrayContaining & Diff[] const DIFF_MATCHER_SKIP = Symbol('DIFF_MATCHER_SKIP') @@ -65,18 +67,43 @@ export function diffsMatcher( return expect.toIncludeSameMembers(compactExpected) } -export const expectOpenApiVersionChange = (fromVersion: string = '3.0.4', toVersion: string = '3.1.0') => { - if (fromVersion === toVersion) - { +/** + * Generic spec-version-change matcher. Returns a diff matcher for the root version key change, + * or DIFF_MATCHER_SKIP when versions are equal (no version change diff expected). + */ +export const expectSpecVersionChange = ( + suiteType: TestSpecType, + fromVersion: string, + toVersion: string, +) => { + if (fromVersion === toVersion) { + return DIFF_MATCHER_SKIP + } + + let rootKey: string + switch (suiteType) { + case TEST_SPEC_TYPE_OPEN_API: + rootKey = 'openapi' + break + default: + // GraphQL and unknown types have no root version key to match return DIFF_MATCHER_SKIP - } + } return expect.objectContaining({ action: 'replace', - afterDeclarationPaths: [['openapi']], + afterDeclarationPaths: [[rootKey]], afterValue: toVersion, - beforeDeclarationPaths: [['openapi']], + beforeDeclarationPaths: [[rootKey]], beforeValue: fromVersion, type: 'annotation', }) } + +/** + * Backward-compatible thin wrapper for OpenAPI version change matching. + * Non-schema tests can continue using this without changes. + */ +export const expectOpenApiVersionChange = (fromVersion: string = '3.0.4', toVersion: string = '3.1.0') => { + return expectSpecVersionChange(TEST_SPEC_TYPE_OPEN_API, fromVersion, toVersion) +} diff --git a/test/setup/jest-wrappers.ts b/test/setup/jest-wrappers.ts index 725bf5a..da33e2b 100644 --- a/test/setup/jest-wrappers.ts +++ b/test/setup/jest-wrappers.ts @@ -1,3 +1,3 @@ -import { initCaseForOpenApiVersionPairs } from '../compatibility-suites/utils' +import { initCaseForSpecVersionPairs } from '../compatibility-suites/utils' -initCaseForOpenApiVersionPairs() +initCaseForSpecVersionPairs() diff --git a/types/jest-wrappers/index.d.ts b/types/jest-wrappers/index.d.ts index 1bf09ba..cc179c6 100644 --- a/types/jest-wrappers/index.d.ts +++ b/types/jest-wrappers/index.d.ts @@ -1,8 +1,10 @@ +import type { TestSpecType } from '@netcracker/qubership-apihub-compatibility-suites' import type { Diff } from '../../src' declare global { namespace jest { - interface OpenApiVersionPairCaseContext { + interface SpecVersionPairCaseContext { + suiteType: TestSpecType suiteId: string testId: string beforeVersion: string @@ -13,18 +15,20 @@ declare global { interface It { /** - * Jest-runner friendly wrapper: first arg is the test name (used for `-t`), so it can match - * the real generated per-pair tests (`${testId} (${pairTag})`). + * Jest-runner friendly wrapper that iterates over specification version pairs. + * + * For each pair, calls `getCompatibilitySuite(...)` with `specificationVersionPair` and runs `fn`. * * Usage: - * - `test.caseForOpenApiVersionPairs('', '', fn)` - * - `test.only.caseForOpenApiVersionPairs(...)` - * - `test.skip.caseForOpenApiVersionPairs(...)` + * - `test.caseForSpecVersionPairs(suiteType, '', '', fn)` + * - `test.only.caseForSpecVersionPairs(...)` + * - `test.skip.caseForSpecVersionPairs(...)` */ - caseForOpenApiVersionPairs( + caseForSpecVersionPairs( + suiteType: TestSpecType, testId: string, suiteId: string, - fn: (ctx: OpenApiVersionPairCaseContext) => Promise | void, + fn: (ctx: SpecVersionPairCaseContext) => Promise | void, ): void } }