From 85039b485b0ba40e01ed78bda99ff4dc761c28ec Mon Sep 17 00:00:00 2001 From: jpinkney Date: Thu, 27 Sep 2018 12:23:36 -0400 Subject: [PATCH] Fix for redhat-developer/vscode-yaml#116 --- src/languageservice/parser/scalar-type.ts | 16 +++++++++ src/languageservice/parser/yamlParser.ts | 5 +-- test/schemaValidation.test.ts | 41 +++++++++++++++++++++++ 3 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 src/languageservice/parser/scalar-type.ts diff --git a/src/languageservice/parser/scalar-type.ts b/src/languageservice/parser/scalar-type.ts new file mode 100644 index 00000000..87b99de1 --- /dev/null +++ b/src/languageservice/parser/scalar-type.ts @@ -0,0 +1,16 @@ +/** + * Parse a boolean according to the specification + * + * Return: + * true if its a true value + * false if its a false value + */ +export function parseYamlBoolean(input: string): boolean { + if (["true", "True", "TRUE", 'y', 'Y', 'yes', 'Yes', 'YES', 'on', 'On', 'ON'].lastIndexOf(input) >= 0) { + return true; + } + else if (["false", "False", "FALSE", 'n', 'N', 'no', 'No', 'NO', 'off', 'Off', 'OFF'].lastIndexOf(input) >= 0) { + return false; + } + throw `Invalid boolean "${input}"` +} diff --git a/src/languageservice/parser/yamlParser.ts b/src/languageservice/parser/yamlParser.ts index 040ef760..3f30848f 100644 --- a/src/languageservice/parser/yamlParser.ts +++ b/src/languageservice/parser/yamlParser.ts @@ -15,6 +15,7 @@ import { Kind } from 'yaml-ast-parser' import { Schema, Type } from 'js-yaml'; import { getLineStartPositions, getPosition } from '../utils/documentPositionCalculator' +import { parseYamlBoolean } from './scalar-type'; export class SingleYAMLDocument extends JSONDocument { private lines; @@ -152,8 +153,8 @@ function recursivelyBuildAst(parent: ASTNode, node: Yaml.YAMLNode): ASTNode { //This is a patch for redirecting values with these strings to be boolean nodes because its not supported in the parser. let possibleBooleanValues = ['y', 'Y', 'yes', 'Yes', 'YES', 'n', 'N', 'no', 'No', 'NO', 'on', 'On', 'ON', 'off', 'Off', 'OFF']; - if (possibleBooleanValues.indexOf(value.toString()) !== -1) { - return new BooleanASTNode(parent, name, value, node.startPosition, node.endPosition) + if (instance.plainScalar && possibleBooleanValues.indexOf(value.toString()) !== -1) { + return new BooleanASTNode(parent, name, parseYamlBoolean(value), node.startPosition, node.endPosition) } switch (type) { diff --git a/test/schemaValidation.test.ts b/test/schemaValidation.test.ts index 650327a3..5fc79ab6 100644 --- a/test/schemaValidation.test.ts +++ b/test/schemaValidation.test.ts @@ -63,6 +63,47 @@ suite("Validation Tests", () => { }).then(done, done); }); + it('Test that boolean value in quotations is not interpreted as boolean i.e. it errors', (done) => { + let content = `analytics: "no"`; + let validator = parseSetup(content); + validator.then(function(result){ + assert.notEqual(result.length, 0); + }).then(done, done); + }); + + it('Test that boolean value without quotations is valid', (done) => { + let content = `analytics: no`; + let validator = parseSetup(content); + validator.then(function(result){ + assert.equal(result.length, 0); + }).then(done, done); + }); + + it('Test that boolean is valid when inside strings', (done) => { + let content = `cwd: "no"`; + let validator = parseSetup(content); + validator.then(function(result){ + assert.equal(result.length, 0); + }).then(done, done); + }); + + it('Test that boolean is invalid when no strings present and schema wants string', (done) => { + let content = `cwd: no`; + let validator = parseSetup(content); + validator.then(function(result){ + assert.notEqual(result.length, 0); + }).then(done, done); + }); + + it('Basic test', (done) => { + let content = `analytics: true`; + let validator = parseSetup(content); + validator.then(function(result){ + assert.equal(result.length, 0); + }).then(done, done); + }); + + it('Basic test on nodes with children', (done) => { let content = `scripts:\n preinstall: test1\n postinstall: test2`; let validator = parseSetup(content);