Skip to content

Commit

Permalink
test(yaml): improve parse() testing (#5182)
Browse files Browse the repository at this point in the history
  • Loading branch information
kt3k authored Jun 28, 2024
1 parent 4052256 commit de998e7
Showing 1 changed file with 155 additions and 1 deletion.
156 changes: 155 additions & 1 deletion yaml/parse_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,16 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.

import { parse, parseAll } from "./parse.ts";
import { assert, assertEquals, assertThrows } from "@std/assert";
import {
assert,
assertEquals,
assertInstanceOf,
assertThrows,
} from "@std/assert";
import { DEFAULT_SCHEMA, EXTENDED_SCHEMA } from "./schema/mod.ts";
import { YamlError } from "./_error.ts";
import { Type } from "./type.ts";
import { assertSpyCall, spy } from "@std/testing/mock";

Deno.test({
name: "parse() handles single document yaml string",
Expand Down Expand Up @@ -294,3 +300,151 @@ Deno.test({
);
},
});

Deno.test("parse() handles escaped strings in double quotes", () => {
assertEquals(parse('"\\"bar\\""'), '"bar"');
assertEquals(parse('"\\x30\\x31"'), "01");
assertEquals(parse('"\\\na"'), "a");
assertEquals(parse('"\\x4a"'), "J");
assertEquals(parse('"\\u0041"'), "A");
assertEquals(parse('"\\U00000041"'), "A");
assertEquals(parse('"\\U0001F431"'), "🐱");

assertThrows(
// invalid hex character
() => parse('"\\xyz"'),
YamlError,
'expected hexadecimal character at line 1, column 4:\n "\\xyz"\n ^',
);
assertThrows(
// invalid escape sequence
() => parse('"\\X30"'),
YamlError,
'unknown escape sequence at line 1, column 3:\n "\\X30"\n ^',
);
});

Deno.test("parse() handles %YAML directive", () => {
assertEquals(
parse(`%YAML 1.2
---
hello: world`),
{ hello: "world" },
);

assertThrows(
() =>
parse(`%YAML 1.2
%YAML 1.2
---
hello: world`),
YamlError,
"duplication of %YAML directive at line 3, column 1:\n ---\n ^",
);
assertThrows(
() =>
parse(`%YAML 1.2 1.1
---
hello: world`),
YamlError,
"YAML directive accepts exactly one argument at line 2, column 1:\n ---\n ^",
);
assertThrows(
() =>
parse(`%YAML 1.2.3
---
hello: world`),
YamlError,
"ill-formed argument of the YAML directive at line 2, column 1:\n ---\n ^",
);
assertThrows(
() =>
parse(`%YAML 2.0
---
hello: world`),
YamlError,
"unacceptable YAML version of the document at line 2, column 1:\n ---\n ^",
);
assertEquals(
// The future 1.x version is acceptable
parse(`%YAML 1.3
---
hello: world`),
{ hello: "world" },
);

{
const warningSpy = spy();
assertEquals(
parse(
`%YAML 1.3
---
hello: world`,
{ onWarning: warningSpy },
),
{ hello: "world" },
);
assertSpyCall(warningSpy, 0);
const warning = warningSpy.calls[0]?.args[0];
assertEquals(
warning.message,
"unsupported YAML version of the document at line 2, column 1:\n ---\n ^",
);
assertInstanceOf(warning, YamlError);
}
});

Deno.test("parse() handles %TAG directive", () => {
assertEquals(
parse(`%TAG ! tag:example.com,2000:
---
hello: world`),
{ hello: "world" },
);

assertThrows(
() =>
parse(`%TAG !
---
hello: world`),
YamlError,
"TAG directive accepts exactly two arguments at line 2, column 1:\n ---\n ^",
);

assertThrows(
() =>
parse(`%TAG abc tag:example.com,2000:
---
hello: world`),
YamlError,
"ill-formed tag handle (first argument) of the TAG directive at line 2, column 1:\n ---\n ^",
);

assertThrows(
() =>
parse(`%TAG ! tag:example.com,2000:
%TAG ! tag:example.com,2000:
---
hello: world`),
YamlError,
'there is a previously declared suffix for "!" tag handle at line 3, column 1:\n ---\n ^',
);

assertThrows(
() =>
parse(`%TAG ! ,:
---
hello: world`),
YamlError,
"ill-formed tag prefix (second argument) of the TAG directive at line 2, column 1:\n ---\n ^",
);
});

Deno.test("parse() throws with invalid strings", () => {
assertThrows(() => parse(`"`), YamlError, "unexpected end of the stream");
assertThrows(
() => parse(`"\x08"`),
YamlError,
'expected valid JSON character at line 1, column 3:\n "\b"\n ^',
);
});

0 comments on commit de998e7

Please sign in to comment.