Skip to content

Commit

Permalink
Extract delete_matching_keys into a helper.
Browse files Browse the repository at this point in the history
Signed-off-by: dblock <[email protected]>
  • Loading branch information
dblock committed Jul 18, 2024
1 parent 4db9e70 commit 36b5cee
Show file tree
Hide file tree
Showing 7 changed files with 167 additions and 148 deletions.
25 changes: 25 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,27 +30,29 @@
"@types/lodash": "^4.14.202",
"@types/node": "^20.10.3",
"@types/qs": "^6.9.15",
"@types/tmp": "^0.2.6",
"@typescript-eslint/eslint-plugin": "^6.21.0",
"ajv": "^8.13.0",
"ajv-errors": "^3.0.0",
"ajv-formats": "^3.0.1",
"ajv": "^8.13.0",
"axios": "^1.7.1",
"cbor": "^9.0.2",
"commander": "^12.0.0",
"eslint": "^8.57.0",
"eslint-config-standard-with-typescript": "^43.0.1",
"eslint-plugin-eslint-comments": "^3.2.0",
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-license-header": "^0.6.1",
"eslint-plugin-n": "^16.6.2",
"eslint-plugin-promise": "^6.1.1",
"eslint-plugin-yml": "^1.14.0",
"eslint": "^8.57.0",
"globals": "^15.0.0",
"json-diff-ts": "^4.0.1",
"json-schema-to-typescript": "^14.0.4",
"lodash": "^4.17.21",
"qs": "^6.12.1",
"smile-js": "^0.7.0",
"tmp": "^0.2.3",
"ts-jest": "^29.1.2",
"ts-node": "^10.9.1",
"typescript": "<5.4.0",
Expand Down
17 changes: 17 additions & 0 deletions tools/src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,23 @@ export function sort_array_by_keys (values: any[], priorities: string[] = []): s
})
}

export function delete_matching_keys(obj: any, condition: (obj: any) => boolean): string[] {
let removed: string[] = []
for (const key in obj) {
var item = obj[key]
if (_.isObject(item)) {
if (condition(item)) {
removed.push(key)
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
delete obj[key]
} else {
removed = _.concat(removed, delete_matching_keys(item, condition))
}
}
}
return removed
}

export function ensure_parent_dir (file_path: string): void {
fs.mkdirSync(path.dirname(file_path), { recursive: true })
}
Expand Down
28 changes: 7 additions & 21 deletions tools/src/merger/OpenApiMerger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import { type OpenAPIV3 } from 'openapi-types'
import fs from 'fs'
import _, { isEmpty } from 'lodash'
import { read_yaml, write_yaml } from '../helpers'
import { delete_matching_keys, read_yaml, write_yaml } from '../helpers'
import SupersededOpsGenerator from './SupersededOpsGenerator'
import GlobalParamsGenerator from './GlobalParamsGenerator'
import { Logger } from '../Logger'
Expand Down Expand Up @@ -82,10 +82,10 @@ export default class OpenApiMerger {

// Remove any refs that are x-version-added/removed incompatible with the target server version.
#remove_refs_per_semver() : void {
this.#remove_per_semver(this._spec.paths)
this.#remove_keys_not_matching_semver(this._spec.paths)

// parameters
const removed_params = this.#remove_per_semver(this._spec.components.parameters)
const removed_params = this.#remove_keys_not_matching_semver(this._spec.components.parameters)
const removed_parameter_refs = _.map(removed_params, (ref) => `#/components/parameters/${ref}`)
Object.entries(this._spec.paths as Document).forEach(([_path, path_item]) => {
Object.entries(path_item as Document).forEach(([_method, method_item]) => {
Expand All @@ -94,7 +94,7 @@ export default class OpenApiMerger {
})

// responses
const removed_responses = this.#remove_per_semver(this._spec.components.responses)
const removed_responses = this.#remove_keys_not_matching_semver(this._spec.components.responses)
const removed_response_refs = _.map(removed_responses, (ref) => `#/components/responses/${ref}`)
Object.entries(this._spec.paths as Document).forEach(([_path, path_item]) => {
Object.entries(path_item as Document).forEach(([_method, method_item]) => {
Expand All @@ -121,23 +121,9 @@ export default class OpenApiMerger {
}

// Remove any elements that are x-version-added/removed incompatible with the target server version.
#remove_per_semver(obj: any): string[] {
let removed: string[] = []
if (this.target_version === undefined) return removed

for (const key in obj) {
if (_.isObject(obj[key])) {
if (this.#exclude_per_semver(obj[key])) {
removed.push(key)
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
delete obj[key]
} else {
removed = _.concat(removed, this.#remove_per_semver(obj[key]))
}
}
}

return removed
#remove_keys_not_matching_semver(obj: any): string[] {
if (this.target_version === undefined) return []
return delete_matching_keys(obj, this.#exclude_per_semver.bind(this))
}

// Redirect schema references in namespace files to local references in single-file spec.
Expand Down
89 changes: 88 additions & 1 deletion tools/tests/helpers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
* compatible open source license.
*/

import { sort_array_by_keys, to_json, to_ndjson } from '../src/helpers'
import _ from 'lodash'
import { delete_matching_keys, sort_array_by_keys, to_json, to_ndjson } from '../src/helpers'

describe('helpers', () => {
describe('sort_array_by_keys', () => {
Expand Down Expand Up @@ -36,4 +37,90 @@ describe('helpers', () => {
expect(to_ndjson([{ x: 1 }])).toEqual("{\"x\":1}\n")
expect(to_ndjson([{ x: 1 }, { y: 'z' }])).toEqual("{\"x\":1}\n{\"y\":\"z\"}\n")
})

describe('delete_matching_keys', () => {
test('empty collection', () => {
var obj = {}
expect(delete_matching_keys(obj, (_obj) => false)).toEqual([])
expect(obj).toEqual({})
})

describe('an object', () => {
var obj: object

beforeEach(() => {
obj = {
foo: {
bar1: {
x: 1
}
},
zar: {
bar2: {
y: 2
}
}
}
})

test('removes all keys', () => {
expect(delete_matching_keys(obj, (_item) => true)).toEqual(['foo', 'zar'])
expect(obj).toStrictEqual({})
})

test('removes no keys', () => {
const obj2 = _.cloneDeep(obj)
expect(delete_matching_keys(obj, (_item) => false)).toEqual([])
expect(obj).toStrictEqual(obj2)
})

test('removes a value from a key', () => {
expect(delete_matching_keys(obj, (_item: any) => _item.x == 1)).toEqual(['bar1'])
expect(obj).toStrictEqual({ foo: {}, zar: { bar2: { y: 2 } } })
})

test('removes multiple values from a key', () => {
expect(delete_matching_keys(obj, (_item: any) => _item.x == 1 || _item.y == 2)).toEqual(['bar1', 'bar2'])
expect(obj).toStrictEqual({ foo: {}, zar: {} })
})
})

describe('an object with arrays', () => {
var obj: object

beforeEach(() => {
obj = {
foo: [{
bar1: {
x: 1
},
bar2: {
y: 2
}
}],
}
})

test('removes all keys', () => {
expect(delete_matching_keys(obj, (_item) => true)).toEqual(['foo'])
expect(obj).toStrictEqual({})
})

test('removes no keys', () => {
const obj2 = _.cloneDeep(obj)
expect(delete_matching_keys(obj, (_item) => false)).toEqual([])
expect(obj).toStrictEqual(obj2)
})

test('removes a value from a key', () => {
expect(delete_matching_keys(obj, (_item: any) => _item.x == 1)).toEqual(['bar1'])
expect(obj).toStrictEqual({ foo: [{ bar2: { y: 2 } }] })
})

test('removes multiple values from a key', () => {
expect(delete_matching_keys(obj, (_item: any) => _item.x == 1 || _item.y == 2)).toEqual(['bar1', 'bar2'])
expect(obj).toStrictEqual({ foo: [{}] })
})
})
})
})
32 changes: 26 additions & 6 deletions tools/tests/merger/OpenApiMerger.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import OpenApiMerger from 'merger/OpenApiMerger'
import fs from 'fs'
import tmp, { file } from 'tmp'

Check failure on line 12 in tools/tests/merger/OpenApiMerger.test.ts

View workflow job for this annotation

GitHub Actions / lint

'file' is defined but never used

describe('OpenApiMerger', () => {
var merger: OpenApiMerger
Expand All @@ -29,27 +30,46 @@ describe('OpenApiMerger', () => {
})

describe('write_to()', () => {
afterAll(() => {
fs.unlinkSync('./tools/tests/merger/opensearch-openapi.yaml')
var temp: tmp.DirResult
var filename: string

Check failure on line 34 in tools/tests/merger/OpenApiMerger.test.ts

View workflow job for this annotation

GitHub Actions / lint

Trailing spaces not allowed

Check failure on line 35 in tools/tests/merger/OpenApiMerger.test.ts

View workflow job for this annotation

GitHub Actions / lint

Trailing spaces not allowed
beforeEach(() => {
temp = tmp.dirSync()
filename = `${temp.name}/opensearch-openapi.yaml`
})

afterEach(() => {
fs.unlinkSync(filename)
temp.removeCallback()
})

test('writes a spec', () => {
merger.write_to('./tools/tests/merger/opensearch-openapi.yaml')
merger.write_to(filename)
expect(fs.readFileSync('./tools/tests/merger/fixtures/expected_2.0.yaml', 'utf8'))
.toEqual(fs.readFileSync('./tools/tests/merger/opensearch-openapi.yaml', 'utf8'))
.toEqual(fs.readFileSync(filename, 'utf8'))
})
})
})

describe('1.3', () => {
var temp: tmp.DirResult
var filename: string

Check failure on line 56 in tools/tests/merger/OpenApiMerger.test.ts

View workflow job for this annotation

GitHub Actions / lint

Trailing spaces not allowed

Check failure on line 57 in tools/tests/merger/OpenApiMerger.test.ts

View workflow job for this annotation

GitHub Actions / lint

Trailing spaces not allowed
beforeEach(() => {
merger = new OpenApiMerger('./tools/tests/merger/fixtures/spec/', '1.3')
temp = tmp.dirSync()
filename = `${temp.name}/opensearch-openapi.yaml`
})

afterEach(() => {
fs.unlinkSync(filename)
temp.removeCallback()
})

test('writes a spec', () => {
merger.write_to('./tools/tests/merger/opensearch-openapi.yaml')
merger.write_to(filename)
expect(fs.readFileSync('./tools/tests/merger/fixtures/expected_1.3.yaml', 'utf8'))
.toEqual(fs.readFileSync('./tools/tests/merger/opensearch-openapi.yaml', 'utf8'))
.toEqual(fs.readFileSync(filename, 'utf8'))
})
})
})
Loading

0 comments on commit 36b5cee

Please sign in to comment.