NimYAML/test/lexing.nim

224 lines
8.8 KiB
Nim
Raw Normal View History

import streams, unicode, lexbase, macros
import unittest
2015-12-23 11:35:07 +00:00
type
YamlTypeHint* = enum
yTypeInteger, yTypeFloat, yTypeFloatInf, yTypeFloatNaN, yTypeBoolTrue,
yTypeBoolFalse, yTypeNull, yTypeString, yTypeUnknown
include "../private/lexer"
2015-12-23 11:35:07 +00:00
2015-12-23 09:28:58 +00:00
type BasicLexerToken = tuple[kind: YamlLexerToken, content: string,
2015-12-23 11:35:07 +00:00
typeHint: YamlTypeHint]
2015-11-30 18:52:01 +00:00
template ensure(input: string, expected: openarray[BasicLexerToken]) =
var
i = 0
lex: YamlLexer
lex.open(newStringStream(input))
for token in lex.tokens:
if i >= expected.len:
echo "received more tokens than expected (next token = ",
2015-12-11 21:55:21 +00:00
token, ")"
fail()
break
2015-12-11 21:55:21 +00:00
if token != expected[i].kind:
2015-12-23 11:35:07 +00:00
if token == tError:
echo "got lexer error: " & lex.content
else:
2015-12-11 21:55:21 +00:00
echo "wrong token kind (expected ", expected[i], ", got ",
token, ")"
fail()
break
if not isNil(expected[i].content):
if lex.content != expected[i].content:
2015-12-11 21:55:21 +00:00
echo "wrong token content (", token, ": expected \"",
expected[i].content, "\", got \"", lex.content, "\")"
fail()
break
inc(i)
if i < expected.len:
echo "received less tokens than expected (first missing = ",
expected[i].kind, ")"
2015-12-23 09:28:58 +00:00
proc t(kind: YamlLexerToken, content: string,
typeHint: YamlTypeHint = yTypeUnknown): BasicLexerToken =
2015-12-23 09:28:58 +00:00
(kind: kind, content: content, typeHint: typeHint)
suite "Lexing":
setup:
discard
teardown:
discard
test "Lexing: YAML Directive":
2015-12-23 11:35:07 +00:00
ensure("%YAML 1.2", [t(tYamlDirective, nil),
t(tVersionPart, "1"),
t(tVersionPart, "2"),
t(tStreamEnd, nil)])
test "Lexing: TAG Directive":
ensure("%TAG !t! tag:http://example.com/",
2015-12-23 11:35:07 +00:00
[t(tTagDirective, nil),
t(tTagHandle, "!t!"),
t(tTagURI, "tag:http://example.com/"),
t(tStreamEnd, nil)])
test "Lexing: Unknown Directive":
2015-12-23 11:35:07 +00:00
ensure("%FOO bar baz", [t(tUnknownDirective, "%FOO"),
t(tUnknownDirectiveParam, "bar"),
t(tUnknownDirectiveParam, "baz"),
t(tStreamEnd, nil)])
2015-11-29 15:50:27 +00:00
test "Lexing: Comments after Directives":
2015-11-29 15:50:27 +00:00
ensure("%YAML 1.2 # version\n# at line start\n # indented\n%FOO",
2015-12-23 11:35:07 +00:00
[t(tYamlDirective, nil),
t(tVersionPart, "1"),
t(tVersionPart, "2"),
t(tComment, " version"),
2016-01-14 23:06:57 +00:00
t(tComment, "# at line start"),
t(tComment, "# indented"),
2015-12-23 11:35:07 +00:00
t(tUnknownDirective, "%FOO"),
t(tStreamEnd, nil)])
2015-11-29 15:50:27 +00:00
test "Lexing: Directives End":
2015-12-23 11:35:07 +00:00
ensure("---", [t(tDirectivesEnd, nil),
t(tStreamEnd, nil)])
test "Lexing: Document End":
2015-12-23 11:35:07 +00:00
ensure("...", [t(tLineStart, nil),
t(tDocumentEnd, nil),
t(tStreamEnd, nil)])
test "Lexing: Directive after Document End":
2015-11-29 20:01:22 +00:00
ensure("content\n...\n%YAML 1.2",
2015-12-23 11:35:07 +00:00
[t(tLineStart, ""),
t(tScalarPart, "content"),
t(tLineStart, ""),
t(tDocumentEnd, nil),
t(tYamlDirective, nil),
t(tVersionPart, "1"),
t(tVersionPart, "2"),
t(tStreamEnd, nil)])
2015-11-29 20:01:22 +00:00
test "Lexing: Plain Scalar (alphanumeric)":
2015-12-23 11:35:07 +00:00
ensure("abA03rel4", [t(tLineStart, ""),
t(tScalarPart, "abA03rel4"),
t(tStreamEnd, nil)])
test "Lexing: Plain Scalar (with spaces)":
2015-12-23 11:35:07 +00:00
ensure("test content", [t(tLineStart, ""),
t(tScalarPart, "test content"),
t(tStreamEnd, nil)])
test "Lexing: Plain Scalar (with special chars)":
ensure(":test ?content -with #special !chars",
2015-12-23 11:35:07 +00:00
[t(tLineStart, nil),
t(tScalarPart, ":test ?content -with #special !chars"),
t(tStreamEnd, nil)])
test "Lexing: Plain Scalar (starting with %)":
2015-12-23 11:35:07 +00:00
ensure("---\n%test", [t(tDirectivesEnd, nil),
t(tLineStart, ""),
t(tScalarPart, "%test"),
t(tStreamEnd, nil)])
2015-11-29 15:50:27 +00:00
test "Lexing: Single Quoted Scalar":
2015-12-23 11:35:07 +00:00
ensure("'? test - content! '", [t(tLineStart, ""),
t(tScalar, "? test - content! "),
t(tStreamEnd, nil)])
test "Lexing: Single Quoted Scalar (escaped single quote inside)":
2015-12-23 11:35:07 +00:00
ensure("'test '' content'", [t(tLineStart, ""),
t(tScalar, "test ' content"),
t(tStreamEnd, nil)])
2015-11-29 20:01:22 +00:00
test "Lexing: Doubly Quoted Scalar":
2015-12-23 11:35:07 +00:00
ensure("\"test content\"", [t(tLineStart, ""),
t(tScalar, "test content"),
t(tStreamEnd, nil)])
2015-11-29 20:01:22 +00:00
test "Lexing: Doubly Quoted Scalar (escaping)":
2015-12-23 11:35:07 +00:00
ensure(""""\t\\\0\""""", [t(tLineStart, ""),
t(tScalar, "\t\\\0\""),
t(tStreamEnd, nil)])
2015-11-29 20:01:22 +00:00
test "Lexing: Doubly Quoted Scalar (unicode escaping)":
2015-11-29 20:01:22 +00:00
ensure(""""\x42\u4243\U00424344"""",
2015-12-23 11:35:07 +00:00
[t(tLineStart, ""),
t(tScalar, "\x42" & toUTF8(cast[Rune](0x4243)) &
2015-11-29 20:01:22 +00:00
toUTF8(cast[Rune](0x424344))),
2015-12-23 11:35:07 +00:00
t(tStreamEnd, nil)])
test "Lexing: Block Array":
ensure("""
- a
2015-12-23 11:35:07 +00:00
- b""", [t(tLineStart, ""), t(tDash, nil), t(tScalarPart, "a"),
t(tLineStart, ""), t(tDash, nil), t(tScalarPart, "b"),
t(tStreamEnd, nil)])
test "Lexing: Block Map with Implicit Keys":
ensure("""
foo: bar
2015-12-23 11:35:07 +00:00
herp: derp""", [t(tLineStart, ""), t(tScalarPart, "foo"),
t(tColon, nil), t(tScalarPart, "bar"),
t(tLineStart, ""), t(tScalarPart, "herp"),
t(tColon, nil), t(tScalarPart, "derp"),
t(tStreamEnd, nil)])
test "Lexing: Block Map with Explicit Keys":
ensure("""
? foo
2015-12-23 11:35:07 +00:00
: bar""", [t(tLineStart, ""), t(tQuestionmark, nil),
t(tScalarPart, "foo"), t(tLineStart, ""), t(tColon, nil),
t(tScalarPart, "bar"), t(tStreamEnd, nil)])
test "Lexing: Indentation":
ensure("""
foo:
bar:
- baz
- biz
herp: derp""",
2015-12-23 11:35:07 +00:00
[t(tLineStart, ""), t(tScalarPart, "foo"), t(tColon, nil),
t(tLineStart, " "), t(tScalarPart, "bar"), t(tColon, nil),
t(tLineStart, " "), t(tDash, nil), t(tScalarPart, "baz"),
t(tLineStart, " "), t(tDash, nil), t(tScalarPart, "biz"),
t(tLineStart, " "), t(tScalarPart, "herp"), t(tColon, nil),
t(tScalarPart, "derp"), t(tStreamEnd, nil)])
2015-11-29 21:43:10 +00:00
test "Lexing: Anchor":
2015-12-23 11:35:07 +00:00
ensure("foo: &bar", [t(tLineStart, ""), t(tScalarPart, "foo"),
t(tColon, nil), t(tAnchor, "bar"),
t(tStreamEnd, nil)])
2015-11-29 21:43:10 +00:00
test "Lexing: Alias":
2015-12-23 11:35:07 +00:00
ensure("foo: *bar", [t(tLineStart, ""), t(tScalarPart, "foo"),
t(tColon, nil), t(tAlias, "bar"),
t(tStreamEnd, nil)])
2015-12-07 18:09:02 +00:00
test "Lexing: Tag handle":
2015-12-23 11:35:07 +00:00
ensure("!t!str tagged", [t(tLineStart, ""), t(tTagHandle, "!t!"),
t(tTagSuffix, "str"),
t(tScalarPart, "tagged"),
t(tStreamEnd, nil)])
2015-12-07 18:09:02 +00:00
test "Lexing: Verbatim tag handle":
2015-12-07 18:09:02 +00:00
ensure("!<tag:http://example.com/str> tagged",
2015-12-23 11:35:07 +00:00
[t(tLineStart, ""),
t(tVerbatimTag, "tag:http://example.com/str"),
t(tScalarPart, "tagged"), t(tStreamEnd, nil)])
2015-12-23 09:28:58 +00:00
test "Lexing: Type hints":
ensure("False\nnull\nYES\nunknown\n\"string\"\n-13\n42.25\n-4e+3\n5.42e78\n-.NaN",
[t(tLineStart, ""), t(tScalarPart, "False", yTypeBoolFalse),
2015-12-23 11:35:07 +00:00
t(tLineStart, ""), t(tScalarPart, "null", yTypeNull),
t(tLineStart, ""), t(tScalarPart, "YES", yTypeBoolTrue),
t(tLineStart, ""), t(tScalarPart, "unknown", yTypeUnknown),
t(tLineStart, ""), t(tScalar, "string", yTypeString),
2015-12-23 11:35:07 +00:00
t(tLineStart, ""), t(tScalarPart, "-13", yTypeInteger),
t(tLineStart, ""), t(tScalarPart, "42.25", yTypeFloat),
t(tLineStart, ""), t(tScalarPart, "-4e+3", yTypeFloat),
t(tLineStart, ""), t(tScalarPart, "5.42e78", yTypeFloat),
t(tLineStart, ""), t(tScalarPart, "-.NaN", yTypeFloatNaN),
2015-12-23 11:35:07 +00:00
t(tStreamEnd, nil)])