Skip to content

Commit

Permalink
fix: calculate location for a mapping with no value (#11)
Browse files Browse the repository at this point in the history
* fix: introduce YamlParserResult type

* fix: calculate location for a mapping with no value

* chore: remove test.each
  • Loading branch information
P0lip authored May 1, 2019
1 parent a5b87e8 commit 82c0c07
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 6 deletions.
36 changes: 36 additions & 0 deletions src/__tests__/fixtures/spectral-170.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
swagger: '2.0'

info:
title: Repro two
description: Endpoint definition
version: "1.0.0"
contact:
name: toto
host: not-example.com
schemes:
- https
basePath: /repro/two

paths:
/quotes_requests:
post:
summary: Gets nothing either.
operationId: "12"
description: Cf. summary
tags: [yep]
parameters:
- name: body
description: Content.
in: body
schema:
$ref: '#/definitions/AnotherDefinition'
responses:
204:
description: Zip

definitions:
AnotherDefinition:
type: object
properties:
special:
description:
22 changes: 22 additions & 0 deletions src/__tests__/getLocationForJsonPath.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { getLocationForJsonPath } from '../getLocationForJsonPath';
import { parseWithPointers } from '../parseWithPointers';

const petStore = fs.readFileSync(join(__dirname, './fixtures/petstore.oas2.yaml'), 'utf-8');
const spectral170 = fs.readFileSync(join(__dirname, './fixtures/spectral-170.yaml'), 'utf-8');
const simple = `hello: world
address:
street: 123`;
Expand Down Expand Up @@ -63,4 +64,25 @@ describe('getLocationForJsonPath', () => {
});
});
});

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

test('should return proper location for empty mapping value', () => {
expect(
getLocationForJsonPath(result, ['definitions', 'AnotherDefinition', 'properties', 'special', 'description'])
).toEqual({
range: {
start: {
character: 20,
line: 35,
},
end: {
character: 20,
line: 35,
},
},
});
});
});
});
24 changes: 21 additions & 3 deletions src/getLocationForJsonPath.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,15 @@ export const getLocationForJsonPath: GetLocationForJsonPath<YAMLNode, number[]>
};

function getStartPosition(node: YAMLNode): number {
if (node.parent && node.parent.kind === Kind.MAPPING && node.kind !== Kind.SCALAR) {
return node.parent.key.endPosition + 1; // offset for colon
if (node.parent && node.parent.kind === Kind.MAPPING) {
// the parent is a mapping with no value, let's default to the end of node
if (node.parent.value === null) {
return node.parent.endPosition;
}

if (node.kind !== Kind.SCALAR) {
return node.parent.key.endPosition + 1; // offset for colon
}
}

return node.startPosition;
Expand All @@ -35,6 +42,13 @@ function getEndPosition(node: YAMLNode): number {
if (node.value !== null && node.mappings.length !== 0) {
return getEndPosition(node.mappings[node.mappings.length - 1]);
}
break;
case Kind.SCALAR:
// the parent is a mapping with no value, let's default to the end of node
if (node.parent.kind === Kind.MAPPING && node.parent.value === null) {
return node.parent.endPosition;
}

break;
}

Expand All @@ -47,7 +61,11 @@ function findNodeAtPath(node: YAMLNode, path: JsonPath) {
case Kind.MAP:
for (const item of node.mappings) {
if (item.key.value === segment) {
node = item.value;
if (item.value === null) {
node = item.key;
} else {
node = item.value;
}
continue pathLoop;
}
}
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export * from './getJsonPathForPosition';
export * from './getLocationForJsonPath';
export * from './parseWithPointers';
export * from './safeStringify';
export * from './types';
7 changes: 4 additions & 3 deletions src/parseWithPointers.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DiagnosticSeverity, IDiagnostic, IParserResult } from '@stoplight/types';
import { DiagnosticSeverity, IDiagnostic } from '@stoplight/types';
import {
Kind,
load as loadAST,
Expand All @@ -8,12 +8,13 @@ import {
YAMLNode,
YAMLSequence,
} from 'yaml-ast-parser';
import { YamlParserResult } from './types';

export const parseWithPointers = <T>(value: string): IParserResult<T, YAMLNode, number[]> => {
export const parseWithPointers = <T>(value: string): YamlParserResult<T> => {
const lineMap = computeLineMap(value);
const ast = loadAST(value);

const parsed: IParserResult<T, YAMLNode, number[]> = {
const parsed: YamlParserResult<T> = {
ast,
lineMap,
data: {} as T, // fixme: we most likely should have undefined here, but this might be breaking
Expand Down
4 changes: 4 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { IParserResult } from '@stoplight/types';
import { YAMLNode } from 'yaml-ast-parser';

export type YamlParserResult<T> = IParserResult<T, YAMLNode, number[]>;

0 comments on commit 82c0c07

Please sign in to comment.