2015-11-29 14:42:41 +00:00
|
|
|
import "../src/yaml/private/lexer"
|
2015-11-29 20:01:22 +00:00
|
|
|
import streams, unicode
|
2015-11-29 14:42:41 +00:00
|
|
|
|
|
|
|
import unittest
|
|
|
|
|
2015-11-30 18:52:01 +00:00
|
|
|
type BasicLexerToken = tuple[kind: YamlLexerTokenKind, content: string]
|
2015-11-29 14:42:41 +00:00
|
|
|
|
2015-11-30 18:52:01 +00:00
|
|
|
template ensure(input: string, expected: openarray[BasicLexerToken]) =
|
2015-11-29 14:42:41 +00:00
|
|
|
var
|
|
|
|
i = 0
|
|
|
|
lex: YamlLexer
|
|
|
|
lex.open(newStringStream(input))
|
|
|
|
for token in lex.tokens:
|
2015-11-29 21:27:05 +00:00
|
|
|
if i >= expected.len:
|
|
|
|
echo "received more tokens than expected (next token = ",
|
|
|
|
token.kind, ")"
|
|
|
|
fail()
|
|
|
|
break
|
2015-11-29 14:42:41 +00:00
|
|
|
if token.kind != expected[i].kind:
|
|
|
|
if token.kind == yamlError:
|
|
|
|
echo "got lexer error: " & lex.content
|
|
|
|
else:
|
|
|
|
echo "wrong token kind (expected ", expected[i].kind, ", got ",
|
|
|
|
token.kind, ")"
|
|
|
|
fail()
|
|
|
|
break
|
|
|
|
if not isNil(expected[i].content):
|
|
|
|
if lex.content != expected[i].content:
|
|
|
|
echo "wrong token content (", token.kind, ": expected \"",
|
|
|
|
expected[i].content, "\", got \"", lex.content, "\")"
|
|
|
|
fail()
|
|
|
|
break
|
|
|
|
inc(i)
|
2015-11-29 21:27:05 +00:00
|
|
|
if i < expected.len:
|
|
|
|
echo "received less tokens than expected (first missing = ",
|
|
|
|
expected[i].kind, ")"
|
2015-11-29 14:42:41 +00:00
|
|
|
|
2015-11-30 18:52:01 +00:00
|
|
|
proc t(kind: YamlLexerTokenKind, content: string): BasicLexerToken =
|
2015-11-29 14:42:41 +00:00
|
|
|
(kind: kind, content: content)
|
|
|
|
|
|
|
|
suite "Lexing":
|
2015-11-29 21:27:05 +00:00
|
|
|
test "YAML Directive":
|
2015-11-29 14:42:41 +00:00
|
|
|
ensure("%YAML 1.2", [t(yamlYamlDirective, nil),
|
|
|
|
t(yamlMajorVersion, "1"),
|
|
|
|
t(yamlMinorVersion, "2"),
|
|
|
|
t(yamlStreamEnd, nil)])
|
|
|
|
|
2015-11-29 21:27:05 +00:00
|
|
|
test "TAG Directive":
|
2015-11-29 14:42:41 +00:00
|
|
|
ensure("%TAG !t! tag:http://example.com/",
|
|
|
|
[t(yamlTagDirective, nil),
|
|
|
|
t(yamlTagHandle, "!t!"),
|
|
|
|
t(yamlTagURI, "tag:http://example.com/"),
|
|
|
|
t(yamlStreamEnd, nil)])
|
|
|
|
|
2015-11-29 21:27:05 +00:00
|
|
|
test "Unknown Directive":
|
2015-11-29 15:50:27 +00:00
|
|
|
ensure("%FOO bar baz", [t(yamlUnknownDirective, "%FOO"),
|
|
|
|
t(yamlUnknownDirectiveParam, "bar"),
|
|
|
|
t(yamlUnknownDirectiveParam, "baz"),
|
|
|
|
t(yamlStreamEnd, nil)])
|
|
|
|
|
2015-11-29 21:27:05 +00:00
|
|
|
test "Comments after Directives":
|
2015-11-29 15:50:27 +00:00
|
|
|
ensure("%YAML 1.2 # version\n# at line start\n # indented\n%FOO",
|
|
|
|
[t(yamlYamlDirective, nil),
|
|
|
|
t(yamlMajorVersion, "1"),
|
|
|
|
t(yamlMinorVersion, "2"),
|
|
|
|
t(yamlComment, " version"),
|
|
|
|
t(yamlComment, " at line start"),
|
|
|
|
t(yamlComment, " indented"),
|
|
|
|
t(yamlUnknownDirective, "%FOO"),
|
|
|
|
t(yamlStreamEnd, nil)])
|
|
|
|
|
2015-11-29 21:27:05 +00:00
|
|
|
test "Directives End":
|
2015-11-29 14:42:41 +00:00
|
|
|
ensure("---", [t(yamlDirectivesEnd, nil),
|
|
|
|
t(yamlStreamEnd, nil)])
|
|
|
|
|
2015-11-29 21:27:05 +00:00
|
|
|
test "Document End":
|
|
|
|
ensure("...", [t(yamlLineStart, nil),
|
|
|
|
t(yamlDocumentEnd, nil),
|
2015-11-29 14:42:41 +00:00
|
|
|
t(yamlStreamEnd, nil)])
|
|
|
|
|
2015-11-29 21:27:05 +00:00
|
|
|
test "Directive after Document End":
|
2015-11-29 20:01:22 +00:00
|
|
|
ensure("content\n...\n%YAML 1.2",
|
2015-11-29 21:27:05 +00:00
|
|
|
[t(yamlLineStart, ""),
|
2015-11-29 20:01:22 +00:00
|
|
|
t(yamlScalar, "content"),
|
2015-11-29 21:27:05 +00:00
|
|
|
t(yamlLineStart, ""),
|
2015-11-29 20:01:22 +00:00
|
|
|
t(yamlDocumentEnd, nil),
|
|
|
|
t(yamlYamlDirective, nil),
|
|
|
|
t(yamlMajorVersion, "1"),
|
|
|
|
t(yamlMinorVersion, "2"),
|
|
|
|
t(yamlStreamEnd, nil)])
|
|
|
|
|
2015-11-29 14:42:41 +00:00
|
|
|
test "Plain Scalar (alphanumeric)":
|
2015-11-29 21:27:05 +00:00
|
|
|
ensure("abA03rel4", [t(yamlLineStart, ""),
|
2015-11-29 14:42:41 +00:00
|
|
|
t(yamlScalar, "abA03rel4"),
|
|
|
|
t(yamlStreamEnd, nil)])
|
|
|
|
|
|
|
|
test "Plain Scalar (with spaces)":
|
2015-11-29 21:27:05 +00:00
|
|
|
ensure("test content", [t(yamlLineStart, ""),
|
2015-11-29 14:42:41 +00:00
|
|
|
t(yamlScalar, "test content"),
|
|
|
|
t(yamlStreamEnd, nil)])
|
|
|
|
|
|
|
|
test "Plain Scalar (with special chars)":
|
|
|
|
ensure(":test ?content -with #special !chars",
|
|
|
|
[t(yamlLineStart, nil),
|
|
|
|
t(yamlScalar, ":test ?content -with #special !chars"),
|
|
|
|
t(yamlStreamEnd, nil)])
|
|
|
|
|
2015-11-29 15:50:27 +00:00
|
|
|
test "Plain Scalar (starting with %)":
|
|
|
|
ensure("---\n%test", [t(yamlDirectivesEnd, nil),
|
|
|
|
t(yamlLineStart, ""),
|
|
|
|
t(yamlScalar, "%test"),
|
|
|
|
t(yamlStreamEnd, nil)])
|
|
|
|
|
2015-11-29 14:42:41 +00:00
|
|
|
test "Single Quoted Scalar":
|
2015-11-29 21:27:05 +00:00
|
|
|
ensure("'? test - content! '", [t(yamlLineStart, ""),
|
2015-11-29 14:42:41 +00:00
|
|
|
t(yamlScalar, "? test - content! "),
|
|
|
|
t(yamlStreamEnd, nil)])
|
|
|
|
|
|
|
|
test "Single Quoted Scalar (escaped single quote inside)":
|
2015-11-29 21:27:05 +00:00
|
|
|
ensure("'test '' content'", [t(yamlLineStart, ""),
|
2015-11-29 14:42:41 +00:00
|
|
|
t(yamlScalar, "test ' content"),
|
2015-11-29 20:01:22 +00:00
|
|
|
t(yamlStreamEnd, nil)])
|
|
|
|
|
|
|
|
test "Doubly Quoted Scalar":
|
2015-11-29 21:27:05 +00:00
|
|
|
ensure("\"test content\"", [t(yamlLineStart, ""),
|
2015-11-29 20:01:22 +00:00
|
|
|
t(yamlScalar, "test content"),
|
|
|
|
t(yamlStreamEnd, nil)])
|
|
|
|
|
|
|
|
test "Doubly Quoted Scalar (escaping)":
|
2015-11-29 21:27:05 +00:00
|
|
|
ensure(""""\t\\\0\""""", [t(yamlLineStart, ""),
|
2015-11-29 20:01:22 +00:00
|
|
|
t(yamlScalar, "\t\\\0\""),
|
|
|
|
t(yamlStreamEnd, nil)])
|
|
|
|
|
|
|
|
test "Doubly Quoted Scalar (unicode escaping)":
|
|
|
|
ensure(""""\x42\u4243\U00424344"""",
|
2015-11-29 21:27:05 +00:00
|
|
|
[t(yamlLineStart, ""),
|
2015-11-29 20:01:22 +00:00
|
|
|
t(yamlScalar, "\x42" & toUTF8(cast[Rune](0x4243)) &
|
|
|
|
toUTF8(cast[Rune](0x424344))),
|
2015-11-29 21:27:05 +00:00
|
|
|
t(yamlStreamEnd, nil)])
|
|
|
|
|
|
|
|
test "Block Array":
|
|
|
|
ensure("""
|
|
|
|
- a
|
|
|
|
- b""", [t(yamlLineStart, ""), t(yamlDash, nil), t(yamlScalar, "a"),
|
|
|
|
t(yamlLineStart, ""), t(yamlDash, nil), t(yamlScalar, "b"),
|
|
|
|
t(yamlStreamEnd, nil)])
|
|
|
|
|
|
|
|
test "Block Map with Implicit Keys":
|
|
|
|
ensure("""
|
|
|
|
foo: bar
|
|
|
|
herp: derp""", [t(yamlLineStart, ""), t(yamlScalar, "foo"), t(yamlColon, nil),
|
|
|
|
t(yamlScalar, "bar"), t(yamlLineStart, ""),
|
|
|
|
t(yamlScalar, "herp"), t(yamlColon, nil), t(yamlScalar, "derp"),
|
|
|
|
t(yamlStreamEnd, nil)])
|
|
|
|
|
|
|
|
test "Block Map with Explicit Keys":
|
|
|
|
ensure("""
|
|
|
|
? foo
|
|
|
|
: bar""", [t(yamlLineStart, ""), t(yamlQuestionmark, nil), t(yamlScalar, "foo"),
|
|
|
|
t(yamlLineStart, ""), t(yamlColon, nil), t(yamlScalar, "bar"),
|
|
|
|
t(yamlStreamEnd, nil)])
|
|
|
|
|
|
|
|
test "Indentation":
|
|
|
|
ensure("""
|
|
|
|
foo:
|
|
|
|
bar:
|
|
|
|
- baz
|
|
|
|
- biz
|
|
|
|
herp: derp""",
|
2015-11-29 21:43:10 +00:00
|
|
|
[t(yamlLineStart, ""), t(yamlScalar, "foo"), t(yamlColon, nil),
|
|
|
|
t(yamlLineStart, " "), t(yamlScalar, "bar"), t(yamlColon, nil),
|
|
|
|
t(yamlLineStart, " "), t(yamlDash, nil), t(yamlScalar, "baz"),
|
|
|
|
t(yamlLineStart, " "), t(yamlDash, nil), t(yamlScalar, "biz"),
|
|
|
|
t(yamlLineStart, " "), t(yamlScalar, "herp"), t(yamlColon, nil),
|
|
|
|
t(yamlScalar, "derp"), t(yamlStreamEnd, nil)])
|
|
|
|
|
|
|
|
test "Anchor":
|
|
|
|
ensure("foo: &bar", [t(yamlLineStart, ""), t(yamlScalar, "foo"),
|
|
|
|
t(yamlColon, nil), t(yamlAnchor, "bar"),
|
|
|
|
t(yamlStreamEnd, nil)])
|
|
|
|
|
|
|
|
test "Alias":
|
|
|
|
ensure("foo: *bar", [t(yamlLineStart, ""), t(yamlScalar, "foo"),
|
|
|
|
t(yamlColon, nil), t(yamlAlias, "bar"),
|
|
|
|
t(yamlStreamEnd, nil)])
|