diff --git a/src/__tests__/fixtures/spectral-481.yaml b/src/__tests__/fixtures/spectral-481.yaml new file mode 100644 index 0000000..032699d --- /dev/null +++ b/src/__tests__/fixtures/spectral-481.yaml @@ -0,0 +1,30 @@ +%YAML 1.2 +--- +openapi: 3.0.0 +info: + title: Random title + description: Random description + version: 0.0.1 + contact: + email: random@random.com +paths: {} +servers: + - url: https://www.random.com +components: + schemas: + RandomRequest: + description: A random request + type: object + properties: + implicit_string_date: + description: Some YAML 1.2 implicit string. + type: string + example: 2012-10-12 + another_implicit_string_date: + description: Some string. + type: string + example: x20121012 + explicit_string_date: + description: Explicit string. + type: string + example: "2012-10-12" diff --git a/src/__tests__/parseWithPointers.spec.ts b/src/__tests__/parseWithPointers.spec.ts index f47a486..3fe80cd 100644 --- a/src/__tests__/parseWithPointers.spec.ts +++ b/src/__tests__/parseWithPointers.spec.ts @@ -7,6 +7,7 @@ import { HugeYAML } from './fixtures/huge-yaml'; const diverse = fs.readFileSync(path.join(__dirname, './fixtures/diverse.yaml'), 'utf-8'); const duplicateMergeKeys = fs.readFileSync(path.join(__dirname, './fixtures/duplicate-merge-keys.yaml'), 'utf-8'); +const spectral481 = fs.readFileSync(path.join(__dirname, './fixtures/spectral-481.yaml'), 'utf-8'); describe('yaml parser', () => { test.each(['test', 1])('parse scalar $s', val => { @@ -29,6 +30,22 @@ describe('yaml parser', () => { expect(result.data).toEqual(HugeJSON); }); + it('parses string according to YAML 1.2 spec', () => { + const { data } = parseWithPointers(spectral481); + expect(data).toHaveProperty( + 'components.schemas.RandomRequest.properties.implicit_string_date.example', + '2012-10-12' + ); + expect(data).toHaveProperty( + 'components.schemas.RandomRequest.properties.another_implicit_string_date.example', + 'x20121012' + ); + expect(data).toHaveProperty( + 'components.schemas.RandomRequest.properties.explicit_string_date.example', + '2012-10-12' + ); + }); + describe('report errors', () => { test('unknown tags', () => { const result = parseWithPointers(`function: !!js/function > diff --git a/src/parseWithPointers.ts b/src/parseWithPointers.ts index 2a1356b..657fb7d 100644 --- a/src/parseWithPointers.ts +++ b/src/parseWithPointers.ts @@ -1,11 +1,17 @@ import { DiagnosticSeverity, IDiagnostic } from '@stoplight/types'; import { + determineScalarType, Kind, load as loadAST, + parseYamlBoolean, + parseYamlFloat, + parseYamlInteger, + ScalarType, YAMLAnchorReference, YAMLException, YamlMap, YAMLNode, + YAMLScalar, YAMLSequence, } from 'yaml-ast-parser'; import { buildJsonPath } from './buildJsonPath'; @@ -92,7 +98,7 @@ export const walkAST = ( case Kind.SEQ: return (node as YAMLSequence).items.map(item => walkAST(item, options, duplicatedMappingKeys)); case Kind.SCALAR: - return 'valueObject' in node ? node.valueObject : node.value; + return getScalarValue(node as YAMLScalar); case Kind.ANCHOR_REF: if (node.value !== void 0 && isCircularAnchorRef(node as YAMLAnchorReference)) { node.value = dereferenceAnchor(node.value, (node as YAMLAnchorReference).referencesAnchor); @@ -150,6 +156,21 @@ const dereferenceAnchor = (node: YAMLNode, anchorId: string): YAMLNode | YAMLNod } }; +function getScalarValue(node: YAMLScalar): number | null | boolean | string | void { + switch (determineScalarType(node)) { + case ScalarType.null: + return null; + case ScalarType.string: + return String(node.value); + case ScalarType.bool: + return parseYamlBoolean(node.value); + case ScalarType.int: + return parseYamlInteger(node.value); + case ScalarType.float: + return parseYamlFloat(node.value); + } +} + // builds up the line map, for use by linesForPosition const computeLineMap = (input: string) => { const lineMap: number[] = [];