Skip to content

Commit

Permalink
feat: implement support for merge-keys (#20)
Browse files Browse the repository at this point in the history
BREAKING CHANGE: data is no longer an empty object literal by default

BREAKING CHANGE: scripts were updated to 7.x

* feat: loose support for merge-keys

* feat: json option

* feat: handle merge keys properly

* test: add extra test covering duplicate merge keys

* feat: addressing PR comments

* chore: improve typings

* fix: use correct import path

* chore: lint and test scripts

* build: remove docs scripts
  • Loading branch information
P0lip committed Jul 31, 2019
1 parent a10d450 commit cc00861
Show file tree
Hide file tree
Showing 17 changed files with 489 additions and 139 deletions.
2 changes: 0 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,7 @@ jobs:
- checkout
- run: yarn
- run: yarn build
- run: yarn build.docs
- run: yarn release
- run: yarn release.docs

workflows:
version: 2
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ yarn add @stoplight/yaml

### Usage

- **[getJsonPathForPosition](https://stoplightio.github.io/yaml/globals.html#getjsonpathforposition)**: Computes JSON path for given position.
- **[getLocationForJsonPath](https://stoplightio.github.io/yaml/globals.html#getlocationforjsonpath)**: Retrieves location of node matching given JSON path.
- **[parseWithPointers](https://stoplightio.github.io/yaml/globals.html#parsewithpointers)**: Parses YAML into JSON and also returns diagnostics as well as full ast with line information.
- **[getJsonPathForPosition](./src/getJsonPathForPosition.ts)**: Computes JSON path for given position.
- **[getLocationForJsonPath](./src/getLocationForJsonPath.ts)**: Retrieves location of node matching given JSON path.
- **[parseWithPointers](./src/parseWithPointers.ts)**: Parses YAML into JSON and also returns diagnostics as well as full ast with line information.

```ts
// basic example of parseWithPointers
Expand Down
11 changes: 5 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,27 +27,26 @@
},
"scripts": {
"build": "sl-scripts build",
"build.docs": "sl-scripts build:typedoc",
"commit": "git-cz",
"lint": "sl-scripts lint",
"lint": "tslint -c tslint.json 'src/**/*.ts'",
"lint.fix": "yarn lint --fix",
"release": "sl-scripts release",
"release.docs": "sl-scripts release:docs",
"release.dryRun": "sl-scripts release --dry-run --debug",
"test": "sl-scripts test",
"test": "jest",
"test.prod": "yarn lint && yarn test --coverage --no-cache",
"test.update": "yarn test --updateSnapshot",
"test.watch": "yarn test --watch"
},
"dependencies": {
"@stoplight/types": "^9.1.2",
"@stoplight/types": "^10.0.1",
"@types/js-yaml": "3.12.1",
"lodash": "^4.17.5",
"lodash": "^4.17.15",
"yaml-ast-parser": "~0.0.43"
},
"devDependencies": {
"@stoplight/scripts": "3.1.0",
"typescript": "3.5.2"
"typescript": "3.5.3"
},
"lint-staged": {
"*.{ts,tsx}$": [
Expand Down
1 change: 1 addition & 0 deletions src/__tests__/__snapshots__/parseWithPointers.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -514,5 +514,6 @@ paragraph breaks
442,
443,
],
"metadata": undefined,
}
`;
5 changes: 5 additions & 0 deletions src/__tests__/fixtures/duplicate-merge-keys.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# https://github.com/nodeca/js-yaml/blob/master/test/samples-common/duplicate-merge-key.yml
---
<<: {x: 1, y: 2}
foo: bar
<<: {z: 3, t: 4}
56 changes: 56 additions & 0 deletions src/__tests__/fixtures/spectral-spec-merge-keys.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
openapi: '3.0.0'
info:
description: foo
version: 1.0.0
title: Swagger Petstore
license:
name: MIT
contact:
url: https://example.com
servers:
- url: http://petstore.swagger.io/v1
paths:
/pets:
get:
description: get
summary: List all pets
operationId: listPets
tags:
- pets
responses:
'200':
description: A paged array of pets
content:
application/json:
schema:
$ref: '#/components/schemas/Pets'
default: &default
description: unexpected error
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
post:
description: get
summary: Create a pet
operationId: createPets
tags:
- pets
responses:
'201':
description: Null response
default:
<<: [*default]
components:
schemas:
Pet:
description: foo
type: string
Pets:
description: get
type: array
items:
$ref: '#/components/schemas/Pet'
Error:
description: doo
type: string
112 changes: 112 additions & 0 deletions src/__tests__/getLocationForJsonPath.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ const petStore = fs.readFileSync(join(__dirname, './fixtures/petstore.oas2.yaml'
const spectral170 = fs.readFileSync(join(__dirname, './fixtures/spectral-170.yaml'), 'utf-8');
const spectralCRLF = fs.readFileSync(join(__dirname, './fixtures/spectral-crlf.yaml'), 'utf-8');
const spectralLF = fs.readFileSync(join(__dirname, './fixtures/spectral-lf.yaml'), 'utf-8');
const spectralSpecMergeKeys = fs.readFileSync(join(__dirname, './fixtures/spectral-spec-merge-keys.yaml'), 'utf-8');
const duplicateMergeKeys = fs.readFileSync(join(__dirname, './fixtures/duplicate-merge-keys.yaml'), 'utf-8');
const simple = `hello: world
address:
street: 123`;
Expand Down Expand Up @@ -76,6 +78,116 @@ describe('getLocationForJsonPath', () => {
});
});

describe('merge keys fixture', () => {
const result = parseWithPointers(spectralSpecMergeKeys, { mergeKeys: true });

test.each`
start | end | path
${[27, 23]} | ${[27, 39]} | ${['paths', '/pets', 'post', 'responses', 'default', 'description']}
${[28, 18]} | ${[31, 50]} | ${['paths', '/pets', 'post', 'responses', 'default', 'content']}
`('should return proper location for given JSONPath $path', ({ start, end, path }) => {
expect(getLocationForJsonPath(result, path)).toEqual({
range: {
start: {
character: start[1],
line: start[0],
},
end: {
character: end[1],
line: end[0],
},
},
});
});
});

describe('duplicate keys fixture', () => {
const result = parseWithPointers(
`foo: 2
foo: 4`
);

test.each`
start | end | path
${[1, 5]} | ${[1, 6]} | ${['foo']}
`('should return proper location for given JSONPath $path', ({ start, end, path }) => {
expect(getLocationForJsonPath(result, path)).toEqual({
range: {
start: {
character: start[1],
line: start[0],
},
end: {
character: end[1],
line: end[0],
},
},
});
});
});

describe('duplicate merge keys fixture', () => {
const result = parseWithPointers(duplicateMergeKeys, { mergeKeys: true });

test.each`
start | end | path
${[2, 8]} | ${[2, 9]} | ${['x']}
${[2, 14]} | ${[2, 15]} | ${['y']}
${[3, 5]} | ${[3, 8]} | ${['foo']}
${[4, 8]} | ${[4, 9]} | ${['z']}
${[4, 14]} | ${[4, 15]} | ${['t']}
`('should return proper location for given JSONPath $path', ({ start, end, path }) => {
expect(getLocationForJsonPath(result, path)).toEqual({
range: {
start: {
character: start[1],
line: start[0],
},
end: {
character: end[1],
line: end[0],
},
},
});
});
});

describe('merge keys with overrides fixture', () => {
const result = parseWithPointers(
`---
- &CENTER { x: 1, y: 2 }
- &LEFT { x: 0, y: 2 }
- &BIG { r: 10 }
- &SMALL { r: 1 }
- # Override
<< : [ *BIG, *LEFT, *SMALL ]
x: 1
label: center/big`,
{ mergeKeys: true }
);

test.each`
start | end | path
${[2, 19]} | ${[2, 20]} | ${[4, 'y']}
${[3, 12]} | ${[3, 14]} | ${[4, 'r']}
${[8, 5]} | ${[8, 6]} | ${[4, 'x']}
`('should return proper location for given JSONPath $path', ({ start, end, path }) => {
expect(getLocationForJsonPath(result, path)).toEqual({
range: {
start: {
character: start[1],
line: start[0],
},
end: {
character: end[1],
line: end[0],
},
},
});
});
});

describe('spectral bug #170 fixture', () => {
const result = parseWithPointers(spectral170);

Expand Down
Loading

0 comments on commit cc00861

Please sign in to comment.