mirror of
https://github.com/denoland/std.git
synced 2024-11-21 20:50:22 +00:00
refactor(yaml): align additional error messages (#5806)
Co-authored-by: Yoshiya Hinosawa <stibium121@gmail.com>
This commit is contained in:
parent
4ab37ea779
commit
64d80042b1
@ -565,7 +565,9 @@ export class DumperState {
|
||||
case STYLE_DOUBLE:
|
||||
return `"${escapeString(string)}"`;
|
||||
default:
|
||||
throw new TypeError("impossible error: invalid scalar style");
|
||||
throw new TypeError(
|
||||
"Invalid scalar style should be unreachable: please file a bug report against Deno at https://github.com/denoland/std/issues",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -663,7 +665,9 @@ export class DumperState {
|
||||
objectKeyList.sort(this.sortKeys);
|
||||
} else if (this.sortKeys) {
|
||||
// Something is wrong
|
||||
throw new TypeError("sortKeys must be a boolean or a function");
|
||||
throw new TypeError(
|
||||
'"sortKeys" must be a boolean or a function: received ${typeof this.sortKeys}',
|
||||
);
|
||||
}
|
||||
|
||||
for (const [index, objectKey] of objectKeyList.entries()) {
|
||||
@ -835,9 +839,7 @@ export class DumperState {
|
||||
} else {
|
||||
if (this.skipInvalid) return null;
|
||||
throw new TypeError(
|
||||
`unacceptable kind of an object to dump ${
|
||||
getObjectTypeString(value)
|
||||
}`,
|
||||
`Cannot stringify object of type: ${getObjectTypeString(value)}`,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -258,33 +258,45 @@ export class LoaderState {
|
||||
|
||||
yamlDirectiveHandler(...args: string[]) {
|
||||
if (this.version !== null) {
|
||||
return this.throwError("duplication of %YAML directive");
|
||||
return this.throwError(
|
||||
"Cannot handle YAML directive: duplication of %YAML directive",
|
||||
);
|
||||
}
|
||||
|
||||
if (args.length !== 1) {
|
||||
return this.throwError("YAML directive accepts exactly one argument");
|
||||
return this.throwError(
|
||||
"Cannot handle YAML directive: YAML directive accepts exactly one argument",
|
||||
);
|
||||
}
|
||||
|
||||
const match = /^([0-9]+)\.([0-9]+)$/.exec(args[0]!);
|
||||
if (match === null) {
|
||||
return this.throwError("ill-formed argument of the YAML directive");
|
||||
return this.throwError(
|
||||
"Cannot handle YAML directive: ill-formed argument",
|
||||
);
|
||||
}
|
||||
|
||||
const major = parseInt(match[1]!, 10);
|
||||
const minor = parseInt(match[2]!, 10);
|
||||
if (major !== 1) {
|
||||
return this.throwError("unacceptable YAML version of the document");
|
||||
return this.throwError(
|
||||
"Cannot handle YAML directive: unacceptable YAML version",
|
||||
);
|
||||
}
|
||||
|
||||
this.version = args[0] ?? null;
|
||||
this.checkLineBreaks = minor < 2;
|
||||
if (minor !== 1 && minor !== 2) {
|
||||
return this.dispatchWarning("unsupported YAML version of the document");
|
||||
return this.dispatchWarning(
|
||||
"Cannot handle YAML directive: unsupported YAML version",
|
||||
);
|
||||
}
|
||||
}
|
||||
tagDirectiveHandler(...args: string[]) {
|
||||
if (args.length !== 2) {
|
||||
return this.throwError("TAG directive accepts exactly two arguments");
|
||||
return this.throwError(
|
||||
`Cannot handle tag directive: directive accepts exactly two arguments, received ${args.length}`,
|
||||
);
|
||||
}
|
||||
|
||||
const handle = args[0]!;
|
||||
@ -292,19 +304,19 @@ export class LoaderState {
|
||||
|
||||
if (!PATTERN_TAG_HANDLE.test(handle)) {
|
||||
return this.throwError(
|
||||
"ill-formed tag handle (first argument) of the TAG directive",
|
||||
`Cannot handle tag directive: ill-formed handle (first argument) in "${handle}"`,
|
||||
);
|
||||
}
|
||||
|
||||
if (this.tagMap.has(handle)) {
|
||||
return this.throwError(
|
||||
`there is a previously declared suffix for "${handle}" tag handle`,
|
||||
`Cannot handle tag directive: previously declared suffix for "${handle}" tag handle`,
|
||||
);
|
||||
}
|
||||
|
||||
if (!PATTERN_TAG_URI.test(prefix)) {
|
||||
return this.throwError(
|
||||
"ill-formed tag prefix (second argument) of the TAG directive",
|
||||
"Cannot handle tag directive: ill-formed tag prefix (second argument) of the TAG directive",
|
||||
);
|
||||
}
|
||||
|
||||
@ -326,11 +338,13 @@ export class LoaderState {
|
||||
!(character === 0x09 ||
|
||||
(0x20 <= character && character <= 0x10ffff))
|
||||
) {
|
||||
return this.throwError("expected valid JSON character");
|
||||
return this.throwError(
|
||||
`Expected valid JSON character: received "${character}"`,
|
||||
);
|
||||
}
|
||||
}
|
||||
} else if (PATTERN_NON_PRINTABLE.test(result)) {
|
||||
return this.throwError("the stream contains non-printable characters");
|
||||
return this.throwError("Stream contains non-printable characters");
|
||||
}
|
||||
|
||||
this.result += result;
|
||||
@ -381,7 +395,9 @@ export class LoaderState {
|
||||
ch = this.peek();
|
||||
|
||||
if ((this.line === line || this.lineIndent > nodeIndent) && ch !== 0) {
|
||||
return this.throwError("bad indentation of a sequence entry");
|
||||
return this.throwError(
|
||||
"Cannot read block sequence: bad indentation of a sequence entry",
|
||||
);
|
||||
} else if (this.lineIndent < nodeIndent) {
|
||||
break;
|
||||
}
|
||||
@ -403,7 +419,7 @@ export class LoaderState {
|
||||
) {
|
||||
if (!isObject(source)) {
|
||||
return this.throwError(
|
||||
"cannot merge mappings; the provided source object is unacceptable",
|
||||
"Cannot merge mappings: the provided source object is unacceptable",
|
||||
);
|
||||
}
|
||||
|
||||
@ -436,7 +452,7 @@ export class LoaderState {
|
||||
for (let index = 0; index < keyNode.length; index++) {
|
||||
if (Array.isArray(keyNode[index])) {
|
||||
return this.throwError(
|
||||
"nested arrays are not supported inside keys",
|
||||
"Cannot store mapping pair: nested arrays are not supported inside keys",
|
||||
);
|
||||
}
|
||||
|
||||
@ -485,7 +501,7 @@ export class LoaderState {
|
||||
) {
|
||||
this.line = startLine || this.line;
|
||||
this.position = startPos || this.position;
|
||||
return this.throwError("duplicated mapping key");
|
||||
return this.throwError("Cannot store mapping pair: duplicated key");
|
||||
}
|
||||
Object.defineProperty(result, keyNode, {
|
||||
value: valueNode,
|
||||
@ -509,7 +525,7 @@ export class LoaderState {
|
||||
this.position++;
|
||||
}
|
||||
} else {
|
||||
return this.throwError("a line break is expected");
|
||||
return this.throwError("Cannot read line: line break not found");
|
||||
}
|
||||
|
||||
this.line += 1;
|
||||
@ -722,7 +738,7 @@ export class LoaderState {
|
||||
this.testDocumentSeparator()
|
||||
) {
|
||||
return this.throwError(
|
||||
"unexpected end of the document within a single quoted scalar",
|
||||
"Unexpected end of the document within a single quoted scalar",
|
||||
);
|
||||
} else {
|
||||
this.position++;
|
||||
@ -731,7 +747,7 @@ export class LoaderState {
|
||||
}
|
||||
|
||||
return this.throwError(
|
||||
"unexpected end of the stream within a single quoted scalar",
|
||||
"Unexpected end of the stream within a single quoted scalar",
|
||||
);
|
||||
}
|
||||
|
||||
@ -770,7 +786,7 @@ export class LoaderState {
|
||||
|
||||
if (directiveName.length < 1) {
|
||||
return this.throwError(
|
||||
"directive name must not be less than one character in length",
|
||||
"Cannot read document: directive name length must be greater than zero",
|
||||
);
|
||||
}
|
||||
|
||||
@ -825,7 +841,9 @@ export class LoaderState {
|
||||
this.position += 3;
|
||||
this.skipSeparationSpace(true, -1);
|
||||
} else if (hasDirectives) {
|
||||
return this.throwError("directives end mark is expected");
|
||||
return this.throwError(
|
||||
"Cannot read document: directives end mark is expected",
|
||||
);
|
||||
}
|
||||
|
||||
composeNode(this, this.lineIndent - 1, CONTEXT_BLOCK_OUT, false, true);
|
||||
@ -847,7 +865,7 @@ export class LoaderState {
|
||||
}
|
||||
} else if (this.position < this.length - 1) {
|
||||
return this.throwError(
|
||||
"end of the stream or a document separator is expected",
|
||||
"Cannot read document: end of the stream or a document separator is expected",
|
||||
);
|
||||
}
|
||||
|
||||
@ -902,7 +920,9 @@ function readDoubleQuotedScalar(
|
||||
if ((tmp = hexCharCodeToNumber(ch)) >= 0) {
|
||||
hexResult = (hexResult << 4) + tmp;
|
||||
} else {
|
||||
return state.throwError("expected hexadecimal character");
|
||||
return state.throwError(
|
||||
"Cannot read double quoted scalar: expected hexadecimal character",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -910,7 +930,9 @@ function readDoubleQuotedScalar(
|
||||
|
||||
state.position++;
|
||||
} else {
|
||||
return state.throwError("unknown escape sequence");
|
||||
return state.throwError(
|
||||
"Cannot read double quoted scalar: unknown escape sequence",
|
||||
);
|
||||
}
|
||||
|
||||
captureStart = captureEnd = state.position;
|
||||
@ -923,7 +945,7 @@ function readDoubleQuotedScalar(
|
||||
state.testDocumentSeparator()
|
||||
) {
|
||||
return state.throwError(
|
||||
"unexpected end of the document within a double quoted scalar",
|
||||
"Unexpected end of the document within a double quoted scalar",
|
||||
);
|
||||
} else {
|
||||
state.position++;
|
||||
@ -932,7 +954,7 @@ function readDoubleQuotedScalar(
|
||||
}
|
||||
|
||||
return state.throwError(
|
||||
"unexpected end of the stream within a double quoted scalar",
|
||||
"Unexpected end of the stream within a double quoted scalar",
|
||||
);
|
||||
}
|
||||
|
||||
@ -982,7 +1004,9 @@ function readFlowCollection(state: LoaderState, nodeIndent: number): boolean {
|
||||
return true;
|
||||
}
|
||||
if (!readNext) {
|
||||
return state.throwError("missed comma between flow collection entries");
|
||||
return state.throwError(
|
||||
"Cannot read flow collection: missing comma between flow collection entries",
|
||||
);
|
||||
}
|
||||
|
||||
keyTag = keyNode = valueNode = null;
|
||||
@ -1049,7 +1073,7 @@ function readFlowCollection(state: LoaderState, nodeIndent: number): boolean {
|
||||
}
|
||||
|
||||
return state.throwError(
|
||||
"unexpected end of the stream within a flow collection",
|
||||
"Cannot read flow collection: unexpected end of the stream within a flow collection",
|
||||
);
|
||||
}
|
||||
|
||||
@ -1085,18 +1109,22 @@ function readBlockScalar(state: LoaderState, nodeIndent: number): boolean {
|
||||
if (CHOMPING_CLIP === chomping) {
|
||||
chomping = ch === PLUS ? CHOMPING_KEEP : CHOMPING_STRIP;
|
||||
} else {
|
||||
return state.throwError("repeat of a chomping mode identifier");
|
||||
return state.throwError(
|
||||
"Cannot read block: chomping mode identifier repeated",
|
||||
);
|
||||
}
|
||||
} else if ((tmp = decimalCharCodeToNumber(ch)) >= 0) {
|
||||
if (tmp === 0) {
|
||||
return state.throwError(
|
||||
"bad explicit indentation width of a block scalar; it cannot be less than one",
|
||||
"Cannot read block: indentation width must be greater than 0",
|
||||
);
|
||||
} else if (!detectedIndent) {
|
||||
textIndent = nodeIndent + tmp - 1;
|
||||
detectedIndent = true;
|
||||
} else {
|
||||
return state.throwError("repeat of an indentation width identifier");
|
||||
return state.throwError(
|
||||
"Cannot read block: indentation width identifier repeated",
|
||||
);
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
@ -1261,7 +1289,7 @@ function readBlockMapping(
|
||||
allowCompact = true;
|
||||
} else {
|
||||
return state.throwError(
|
||||
"incomplete explicit mapping pair; a key node is missed; or followed by a non-tabulated empty line",
|
||||
"Cannot read block as explicit mapping pair is incomplete: a key node is missed or followed by a non-tabulated empty line",
|
||||
);
|
||||
}
|
||||
|
||||
@ -1284,7 +1312,7 @@ function readBlockMapping(
|
||||
|
||||
if (!isWhiteSpaceOrEOL(ch)) {
|
||||
return state.throwError(
|
||||
"a whitespace character is expected after the key-value separator within a block mapping",
|
||||
"Cannot read block: a whitespace character is expected after the key-value separator within a block mapping",
|
||||
);
|
||||
}
|
||||
|
||||
@ -1306,7 +1334,7 @@ function readBlockMapping(
|
||||
keyNode = state.result;
|
||||
} else if (detected) {
|
||||
return state.throwError(
|
||||
"can not read an implicit mapping pair; a colon is missed",
|
||||
"Cannot read an implicit mapping pair: missing colon",
|
||||
);
|
||||
} else {
|
||||
state.tag = tag;
|
||||
@ -1315,7 +1343,7 @@ function readBlockMapping(
|
||||
}
|
||||
} else if (detected) {
|
||||
return state.throwError(
|
||||
"can not read a block mapping entry; a multiline key may not be an implicit key",
|
||||
"Cannot read a block mapping entry: a multiline key may not be an implicit key",
|
||||
);
|
||||
} else {
|
||||
state.tag = tag;
|
||||
@ -1358,7 +1386,9 @@ function readBlockMapping(
|
||||
}
|
||||
|
||||
if (state.lineIndent > nodeIndent && ch !== 0) {
|
||||
return state.throwError("bad indentation of a mapping entry");
|
||||
return state.throwError(
|
||||
"Cannot read block: bad indentation of a mapping entry",
|
||||
);
|
||||
} else if (state.lineIndent < nodeIndent) {
|
||||
break;
|
||||
}
|
||||
@ -1403,7 +1433,9 @@ function readTagProperty(state: LoaderState): boolean {
|
||||
if (ch !== EXCLAMATION) return false;
|
||||
|
||||
if (state.tag !== null) {
|
||||
return state.throwError("duplication of a tag property");
|
||||
return state.throwError(
|
||||
"Cannot read tag property: duplication of a tag property",
|
||||
);
|
||||
}
|
||||
|
||||
ch = state.next();
|
||||
@ -1431,7 +1463,7 @@ function readTagProperty(state: LoaderState): boolean {
|
||||
ch = state.next();
|
||||
} else {
|
||||
return state.throwError(
|
||||
"unexpected end of the stream within a verbatim tag",
|
||||
"Cannot read tag property: unexpected end of stream",
|
||||
);
|
||||
}
|
||||
} else {
|
||||
@ -1442,7 +1474,7 @@ function readTagProperty(state: LoaderState): boolean {
|
||||
|
||||
if (!PATTERN_TAG_HANDLE.test(tagHandle)) {
|
||||
return state.throwError(
|
||||
"named tag handle cannot contain such characters",
|
||||
"Cannot read tag property: named tag handle contains invalid characters",
|
||||
);
|
||||
}
|
||||
|
||||
@ -1450,7 +1482,7 @@ function readTagProperty(state: LoaderState): boolean {
|
||||
position = state.position + 1;
|
||||
} else {
|
||||
return state.throwError(
|
||||
"tag suffix cannot contain exclamation marks",
|
||||
"Cannot read tag property: tag suffix cannot contain an exclamation mark",
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1462,14 +1494,14 @@ function readTagProperty(state: LoaderState): boolean {
|
||||
|
||||
if (PATTERN_FLOW_INDICATORS.test(tagName)) {
|
||||
return state.throwError(
|
||||
"tag suffix cannot contain flow indicator characters",
|
||||
"Cannot read tag property: tag suffix cannot contain flow indicator characters",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (tagName && !PATTERN_TAG_URI.test(tagName)) {
|
||||
return state.throwError(
|
||||
`tag name cannot contain such characters: ${tagName}`,
|
||||
`Cannot read tag property: invalid characters in tag name "${tagName}"`,
|
||||
);
|
||||
}
|
||||
|
||||
@ -1482,7 +1514,9 @@ function readTagProperty(state: LoaderState): boolean {
|
||||
} else if (tagHandle === "!!") {
|
||||
state.tag = `tag:yaml.org,2002:${tagName}`;
|
||||
} else {
|
||||
return state.throwError(`undeclared tag handle "${tagHandle}"`);
|
||||
return state.throwError(
|
||||
`Cannot read tag property: undeclared tag handle "${tagHandle}"`,
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -1493,7 +1527,9 @@ function readAnchorProperty(state: LoaderState): boolean {
|
||||
if (ch !== AMPERSAND) return false;
|
||||
|
||||
if (state.anchor !== null) {
|
||||
return state.throwError("duplication of an anchor property");
|
||||
return state.throwError(
|
||||
"Cannot read anchor property: duplicate anchor property",
|
||||
);
|
||||
}
|
||||
ch = state.next();
|
||||
|
||||
@ -1504,7 +1540,7 @@ function readAnchorProperty(state: LoaderState): boolean {
|
||||
|
||||
if (state.position === position) {
|
||||
return state.throwError(
|
||||
"name of an anchor node must contain at least one character",
|
||||
"Cannot read anchor property: name of an anchor node must contain at least one character",
|
||||
);
|
||||
}
|
||||
|
||||
@ -1525,13 +1561,13 @@ function readAlias(state: LoaderState): boolean {
|
||||
|
||||
if (state.position === position) {
|
||||
return state.throwError(
|
||||
"name of an alias node must contain at least one character",
|
||||
"Cannot read alias: alias name must contain at least one character",
|
||||
);
|
||||
}
|
||||
|
||||
const alias = state.input.slice(position, state.position);
|
||||
if (!state.anchorMap.has(alias)) {
|
||||
return state.throwError(`unidentified alias "${alias}"`);
|
||||
return state.throwError(`Cannot read alias: unidentified alias "${alias}"`);
|
||||
}
|
||||
|
||||
state.result = state.anchorMap.get(alias);
|
||||
@ -1628,7 +1664,7 @@ function composeNode(
|
||||
|
||||
if (state.tag !== null || state.anchor !== null) {
|
||||
return state.throwError(
|
||||
"alias node should not have Any properties",
|
||||
"Cannot compose node: alias node should not have any properties",
|
||||
);
|
||||
}
|
||||
} else if (
|
||||
@ -1682,14 +1718,14 @@ function composeNode(
|
||||
|
||||
if (state.result !== null && type.kind !== state.kind) {
|
||||
return state.throwError(
|
||||
`unacceptable node kind for !<${state.tag}> tag; it should be "${type.kind}", not "${state.kind}"`,
|
||||
`Unacceptable node kind for !<${state.tag}> tag: it should be "${type.kind}", not "${state.kind}"`,
|
||||
);
|
||||
}
|
||||
|
||||
if (!type.resolve(state.result)) {
|
||||
// `state.result` updated in resolver if matched
|
||||
return state.throwError(
|
||||
`cannot resolve a node with !<${state.tag}> explicit tag`,
|
||||
`Cannot resolve a node with !<${state.tag}> explicit tag`,
|
||||
);
|
||||
} else {
|
||||
state.result = type.construct(state.result);
|
||||
@ -1698,7 +1734,7 @@ function composeNode(
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return state.throwError(`unknown tag !<${state.tag}>`);
|
||||
return state.throwError(`Cannot resolve unknown tag !<${state.tag}>`);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,9 @@ function constructYamlTimestamp(data: string): Date {
|
||||
let match = YAML_DATE_REGEXP.exec(data);
|
||||
if (match === null) match = YAML_TIMESTAMP_REGEXP.exec(data);
|
||||
|
||||
if (match === null) throw new Error("Date resolve error");
|
||||
if (match === null) {
|
||||
throw new Error("Cannot construct YAML timestamp: date resolve error");
|
||||
}
|
||||
|
||||
// match: [1] year [2] month [3] day
|
||||
|
||||
|
@ -85,7 +85,7 @@ export function parse(
|
||||
const document = documentGenerator.next().value;
|
||||
if (!documentGenerator.next().done) {
|
||||
throw new SyntaxError(
|
||||
"expected a single document in the stream, but found more",
|
||||
"Found more than 1 document in the stream: expected a single document",
|
||||
);
|
||||
}
|
||||
return document ?? null;
|
||||
|
@ -65,7 +65,11 @@ Deno.test({
|
||||
name: "parse() throws with `!!js/*` yaml types with default schemas",
|
||||
fn() {
|
||||
const yaml = `undefined: !!js/undefined ~`;
|
||||
assertThrows(() => parse(yaml), SyntaxError, "unknown tag !");
|
||||
assertThrows(
|
||||
() => parse(yaml),
|
||||
SyntaxError,
|
||||
"Cannot resolve unknown tag !",
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
@ -238,14 +242,14 @@ Deno.test({
|
||||
assertThrows(
|
||||
() => parse("message: !!binary <>"),
|
||||
SyntaxError,
|
||||
"cannot resolve a node with !<tag:yaml.org,2002:binary> explicit tag at line 1, column 21:\n message: !!binary <>\n ^",
|
||||
"Cannot resolve a node with !<tag:yaml.org,2002:binary> explicit tag at line 1, column 21:\n message: !!binary <>\n ^",
|
||||
);
|
||||
|
||||
// empty base64 string is error
|
||||
assertThrows(
|
||||
() => parse("message: !!binary"),
|
||||
SyntaxError,
|
||||
"cannot resolve a node with !<tag:yaml.org,2002:binary> explicit tag at line 2, column 1:\n \n ^",
|
||||
"Cannot resolve a node with !<tag:yaml.org,2002:binary> explicit tag at line 2, column 1:\n \n ^",
|
||||
);
|
||||
},
|
||||
});
|
||||
@ -371,39 +375,39 @@ Deno.test({
|
||||
assertThrows(
|
||||
() => parse('!!int ""'),
|
||||
SyntaxError,
|
||||
'cannot resolve a node with !<tag:yaml.org,2002:int> explicit tag at line 1, column 9:\n !!int ""\n ^',
|
||||
'Cannot resolve a node with !<tag:yaml.org,2002:int> explicit tag at line 1, column 9:\n !!int ""\n ^',
|
||||
);
|
||||
|
||||
// number can't start with _
|
||||
assertThrows(
|
||||
() => parse("!!int _42"),
|
||||
SyntaxError,
|
||||
"cannot resolve a node with !<tag:yaml.org,2002:int> explicit tag at line 2, column 1:\n \n ^",
|
||||
"Cannot resolve a node with !<tag:yaml.org,2002:int> explicit tag at line 2, column 1:\n \n ^",
|
||||
);
|
||||
// number can't end with _
|
||||
assertThrows(
|
||||
() => parse("!!int 42_"),
|
||||
SyntaxError,
|
||||
"cannot resolve a node with !<tag:yaml.org,2002:int> explicit tag at line 2, column 1:\n \n ^",
|
||||
"Cannot resolve a node with !<tag:yaml.org,2002:int> explicit tag at line 2, column 1:\n \n ^",
|
||||
);
|
||||
|
||||
// invalid binary number
|
||||
assertThrows(
|
||||
() => parse("!!int 0b102"),
|
||||
SyntaxError,
|
||||
"cannot resolve a node with !<tag:yaml.org,2002:int> explicit tag at line 2, column 1:\n \n ^",
|
||||
"Cannot resolve a node with !<tag:yaml.org,2002:int> explicit tag at line 2, column 1:\n \n ^",
|
||||
);
|
||||
// invalid octal number
|
||||
assertThrows(
|
||||
() => parse("!!int 09"),
|
||||
SyntaxError,
|
||||
"cannot resolve a node with !<tag:yaml.org,2002:int> explicit tag at line 2, column 1:\n \n ^",
|
||||
"Cannot resolve a node with !<tag:yaml.org,2002:int> explicit tag at line 2, column 1:\n \n ^",
|
||||
);
|
||||
// invalid hexadecimal number
|
||||
assertThrows(
|
||||
() => parse("!!int 0x1G"),
|
||||
SyntaxError,
|
||||
"cannot resolve a node with !<tag:yaml.org,2002:int> explicit tag at line 2, column 1:\n \n ^",
|
||||
"Cannot resolve a node with !<tag:yaml.org,2002:int> explicit tag at line 2, column 1:\n \n ^",
|
||||
);
|
||||
},
|
||||
});
|
||||
@ -428,13 +432,13 @@ Deno.test({
|
||||
assertThrows(
|
||||
() => parse("- !!timestamp"),
|
||||
SyntaxError,
|
||||
"cannot resolve a node with !<tag:yaml.org,2002:timestamp> explicit tag at line 2, column 1:\n \n ^",
|
||||
"Cannot resolve a node with !<tag:yaml.org,2002:timestamp> explicit tag at line 2, column 1:\n \n ^",
|
||||
);
|
||||
|
||||
assertThrows(
|
||||
() => parse("- !!timestamp 1"),
|
||||
SyntaxError,
|
||||
"cannot resolve a node with !<tag:yaml.org,2002:timestamp> explicit tag at line 1, column 16:\n - !!timestamp 1\n ^",
|
||||
"Cannot resolve a node with !<tag:yaml.org,2002:timestamp> explicit tag at line 1, column 16:\n - !!timestamp 1\n ^",
|
||||
);
|
||||
},
|
||||
});
|
||||
@ -458,25 +462,25 @@ Deno.test({
|
||||
assertThrows(
|
||||
() => parse("--- !!omap\n- 1"),
|
||||
SyntaxError,
|
||||
"cannot resolve a node with !<tag:yaml.org,2002:omap> explicit tag",
|
||||
"Cannot resolve a node with !<tag:yaml.org,2002:omap> explicit tag",
|
||||
);
|
||||
// map entry is empty object
|
||||
assertThrows(
|
||||
() => parse("--- !!omap\n- {}"),
|
||||
SyntaxError,
|
||||
"cannot resolve a node with !<tag:yaml.org,2002:omap> explicit tag",
|
||||
"Cannot resolve a node with !<tag:yaml.org,2002:omap> explicit tag",
|
||||
);
|
||||
// map entry is an object with multiple keys
|
||||
assertThrows(
|
||||
() => parse("--- !!omap\n- foo: 1\n bar: 2"),
|
||||
SyntaxError,
|
||||
"cannot resolve a node with !<tag:yaml.org,2002:omap> explicit tag",
|
||||
"Cannot resolve a node with !<tag:yaml.org,2002:omap> explicit tag",
|
||||
);
|
||||
// 2 map entries have the same key
|
||||
assertThrows(
|
||||
() => parse("--- !!omap\n- foo: 1\n- foo: 2"),
|
||||
SyntaxError,
|
||||
"cannot resolve a node with !<tag:yaml.org,2002:omap> explicit tag",
|
||||
"Cannot resolve a node with !<tag:yaml.org,2002:omap> explicit tag",
|
||||
);
|
||||
},
|
||||
});
|
||||
@ -501,13 +505,13 @@ Deno.test("parse() handles !!pairs type", () => {
|
||||
// pair is not an object
|
||||
() => parse(`!!pairs\n- 1`),
|
||||
SyntaxError,
|
||||
"cannot resolve a node with !<tag:yaml.org,2002:pairs> explicit tag",
|
||||
"Cannot resolve a node with !<tag:yaml.org,2002:pairs> explicit tag",
|
||||
);
|
||||
assertThrows(
|
||||
// pair is object with multiple keys
|
||||
() => parse(`!!pairs\n- { Monday: 3, Tuesday: 4 }`),
|
||||
SyntaxError,
|
||||
"cannot resolve a node with !<tag:yaml.org,2002:pairs> explicit tag",
|
||||
"Cannot resolve a node with !<tag:yaml.org,2002:pairs> explicit tag",
|
||||
);
|
||||
});
|
||||
|
||||
@ -558,7 +562,7 @@ Deno.test("parse() handles anchors and aliases", () => {
|
||||
parse(`- &anchor Foo
|
||||
- *`),
|
||||
SyntaxError,
|
||||
"name of an alias node must contain at least one character at line 2, column 4:\n - *\n ^",
|
||||
"Cannot read alias: alias name must contain at least one character at line 2, column 4:\n - *\n ^",
|
||||
);
|
||||
});
|
||||
|
||||
@ -596,14 +600,14 @@ Deno.test("parse() handles single quoted scalar", () => {
|
||||
// document end in single quoted scalar
|
||||
() => parse("'bar\n"),
|
||||
SyntaxError,
|
||||
"unexpected end of the stream within a single quoted scalar at line 2, column 1:\n \n ^",
|
||||
"Unexpected end of the stream within a single quoted scalar at line 2, column 1:\n \n ^",
|
||||
);
|
||||
|
||||
assertThrows(
|
||||
// document separator appears in single quoted scalar
|
||||
() => parse("'bar\n..."),
|
||||
SyntaxError,
|
||||
"unexpected end of the document within a single quoted scalar at line 2, column 1:\n ...\n ^",
|
||||
"Unexpected end of the document within a single quoted scalar at line 2, column 1:\n ...\n ^",
|
||||
);
|
||||
});
|
||||
|
||||
@ -637,7 +641,7 @@ hello: world`),
|
||||
---
|
||||
hello: world`),
|
||||
SyntaxError,
|
||||
"YAML directive accepts exactly one argument at line 2, column 1:\n ---\n ^",
|
||||
"Cannot handle YAML directive: YAML directive accepts exactly one argument at line 2, column 1:\n ---\n ^",
|
||||
);
|
||||
assertThrows(
|
||||
() =>
|
||||
@ -645,7 +649,7 @@ hello: world`),
|
||||
---
|
||||
hello: world`),
|
||||
SyntaxError,
|
||||
"ill-formed argument of the YAML directive at line 2, column 1:\n ---\n ^",
|
||||
"Cannot handle YAML directive: ill-formed argument at line 2, column 1:\n ---\n ^",
|
||||
);
|
||||
assertThrows(
|
||||
() =>
|
||||
@ -653,7 +657,7 @@ hello: world`),
|
||||
---
|
||||
hello: world`),
|
||||
SyntaxError,
|
||||
"unacceptable YAML version of the document at line 2, column 1:\n ---\n ^",
|
||||
"Cannot handle YAML directive: unacceptable YAML version at line 2, column 1:\n ---\n ^",
|
||||
);
|
||||
assertEquals(
|
||||
// The future 1.x version is acceptable
|
||||
@ -678,7 +682,7 @@ hello: world`,
|
||||
const warning = warningSpy.calls[0]?.args[0];
|
||||
assertEquals(
|
||||
warning.message,
|
||||
"unsupported YAML version of the document at line 2, column 1:\n ---\n ^",
|
||||
"Cannot handle YAML directive: unsupported YAML version at line 2, column 1:\n ---\n ^",
|
||||
);
|
||||
assertInstanceOf(warning, SyntaxError);
|
||||
}
|
||||
@ -698,7 +702,7 @@ hello: world`),
|
||||
---
|
||||
hello: world`),
|
||||
SyntaxError,
|
||||
"TAG directive accepts exactly two arguments at line 2, column 1:\n ---\n ^",
|
||||
"Cannot handle tag directive: directive accepts exactly two arguments, received 1 at line 2, column 1:\n ---\n ^",
|
||||
);
|
||||
|
||||
assertThrows(
|
||||
@ -707,7 +711,7 @@ hello: world`),
|
||||
---
|
||||
hello: world`),
|
||||
SyntaxError,
|
||||
"ill-formed tag handle (first argument) of the TAG directive at line 2, column 1:\n ---\n ^",
|
||||
'Cannot handle tag directive: ill-formed handle (first argument) in "abc" at line 2, column 1:\n ---\n ^',
|
||||
);
|
||||
|
||||
assertThrows(
|
||||
@ -717,7 +721,7 @@ hello: world`),
|
||||
---
|
||||
hello: world`),
|
||||
SyntaxError,
|
||||
'there is a previously declared suffix for "!" tag handle at line 3, column 1:\n ---\n ^',
|
||||
'Cannot handle tag directive: previously declared suffix for "!" tag handle at line 3, column 1:\n ---\n ^',
|
||||
);
|
||||
|
||||
assertThrows(
|
||||
@ -731,17 +735,17 @@ hello: world`),
|
||||
});
|
||||
|
||||
Deno.test("parse() throws with invalid strings", () => {
|
||||
assertThrows(() => parse(`"`), SyntaxError, "unexpected end of the stream");
|
||||
assertThrows(() => parse(`"`), SyntaxError, "Unexpected end of the stream");
|
||||
assertThrows(
|
||||
() => parse(`"\x08"`),
|
||||
SyntaxError,
|
||||
'expected valid JSON character at line 1, column 3:\n "\b"\n ^',
|
||||
'Expected valid JSON character: received "8" at line 1, column 3:\n "\b"\n ^',
|
||||
);
|
||||
// non-printable char in block scalar
|
||||
assertThrows(
|
||||
() => parse(`foo: |\n \x08`),
|
||||
SyntaxError,
|
||||
"the stream contains non-printable characters at line 2, column 4:\n \b\n ^",
|
||||
"Stream contains non-printable characters at line 2, column 4:\n \b\n ^",
|
||||
);
|
||||
});
|
||||
|
||||
@ -764,7 +768,7 @@ c: 1`),
|
||||
parse(`<<: 1
|
||||
c: 3`),
|
||||
SyntaxError,
|
||||
"cannot merge mappings; the provided source object is unacceptable at line 1, column 6:\n <<: 1\n ^",
|
||||
"Cannot merge mappings: the provided source object is unacceptable at line 1, column 6:\n <<: 1\n ^",
|
||||
);
|
||||
});
|
||||
|
||||
@ -801,7 +805,7 @@ bar: baz`),
|
||||
assertThrows(
|
||||
() => parse(`foo: |++\n bar`),
|
||||
SyntaxError,
|
||||
"repeat of a chomping mode identifier at line 1, column 8:\n foo: |++\n ^",
|
||||
"Cannot read block: chomping mode identifier repeated at line 1, column 8:\n foo: |++\n ^",
|
||||
);
|
||||
assertEquals(
|
||||
parse(`foo: |1
|
||||
@ -825,12 +829,12 @@ bar: baz`),
|
||||
assertThrows(
|
||||
() => parse(`foo: |0\n bar`),
|
||||
SyntaxError,
|
||||
"bad explicit indentation width of a block scalar; it cannot be less than one at line 1, column 7:\n foo: |0\n ^",
|
||||
"Cannot read block: indentation width must be greater than 0 at line 1, column 7:\n foo: |0\n ^",
|
||||
);
|
||||
assertThrows(
|
||||
() => parse(`foo: |11\n bar`),
|
||||
SyntaxError,
|
||||
"repeat of an indentation width identifier at line 1, column 8:\n foo: |11\n ^",
|
||||
"Cannot read block: indentation width identifier repeated at line 1, column 8:\n foo: |11\n ^",
|
||||
);
|
||||
|
||||
// folding style (>)
|
||||
@ -862,7 +866,7 @@ Deno.test("parse() throws if there are more than one document in the yaml", () =
|
||||
assertThrows(
|
||||
() => parse("hello: world\n---\nfoo: bar"),
|
||||
SyntaxError,
|
||||
"expected a single document in the stream, but found more",
|
||||
"Found more than 1 document in the stream: expected a single document",
|
||||
);
|
||||
});
|
||||
|
||||
@ -873,7 +877,7 @@ Deno.test("parse() throws when the directive name is empty", () => {
|
||||
---
|
||||
hello: world`),
|
||||
SyntaxError,
|
||||
"directive name must not be less than one character in length at line 1, column 2:\n % 1.2\n ^",
|
||||
"Cannot read document: directive name length must be greater than zero at line 1, column 2:\n % 1.2\n ^",
|
||||
);
|
||||
});
|
||||
|
||||
@ -986,7 +990,7 @@ Deno.test("parse() throws with empty mapping key", () => {
|
||||
assertThrows(
|
||||
() => parse(`? : 1`),
|
||||
SyntaxError,
|
||||
"incomplete explicit mapping pair; a key node is missed; or followed by a non-tabulated empty line at line 1, column 3:\n ? : 1\n ^",
|
||||
"Cannot read block as explicit mapping pair is incomplete: a key node is missed or followed by a non-tabulated empty line at line 1, column 3:\n ? : 1\n ^",
|
||||
);
|
||||
});
|
||||
|
||||
@ -999,7 +1003,7 @@ age: 30
|
||||
name: Jane Doe`,
|
||||
),
|
||||
SyntaxError,
|
||||
"duplicated mapping key at line 3, column 1:\n name: Jane Doe\n ^",
|
||||
"Cannot store mapping pair: duplicated key at line 3, column 1:\n name: Jane Doe\n ^",
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -144,7 +144,7 @@ Deno.test({
|
||||
assertThrows(
|
||||
() => stringify(object),
|
||||
TypeError,
|
||||
"unacceptable kind of an object to dump",
|
||||
"Cannot stringify object of type: [object Undefined]",
|
||||
);
|
||||
},
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user