And fmt
This commit is contained in:
parent
debc7996ee
commit
bbae5ef63f
34 changed files with 956 additions and 886 deletions
projects/calf/tests/python
|
@ -8,23 +8,24 @@ from calf import grammar as cg
|
|||
from conftest import parametrize
|
||||
|
||||
|
||||
@parametrize('ex', [
|
||||
# Proper strings
|
||||
'""',
|
||||
'"foo bar"',
|
||||
'"foo\n bar\n\r qux"',
|
||||
'"foo\\"bar"',
|
||||
|
||||
'""""""',
|
||||
'"""foo bar baz"""',
|
||||
'"""foo "" "" "" bar baz"""',
|
||||
|
||||
# Unterminated string cases
|
||||
'"',
|
||||
'"f',
|
||||
'"foo bar',
|
||||
'"foo\\" bar',
|
||||
'"""foo bar baz',
|
||||
])
|
||||
@parametrize(
|
||||
"ex",
|
||||
[
|
||||
# Proper strings
|
||||
'""',
|
||||
'"foo bar"',
|
||||
'"foo\n bar\n\r qux"',
|
||||
'"foo\\"bar"',
|
||||
'""""""',
|
||||
'"""foo bar baz"""',
|
||||
'"""foo "" "" "" bar baz"""',
|
||||
# Unterminated string cases
|
||||
'"',
|
||||
'"f',
|
||||
'"foo bar',
|
||||
'"foo\\" bar',
|
||||
'"""foo bar baz',
|
||||
],
|
||||
)
|
||||
def test_match_string(ex):
|
||||
assert re.fullmatch(cg.STRING_PATTERN, ex)
|
||||
|
|
|
@ -20,23 +20,62 @@ def lex_single_token(buffer):
|
|||
@parametrize(
|
||||
"text,token_type",
|
||||
[
|
||||
("(", "PAREN_LEFT",),
|
||||
(")", "PAREN_RIGHT",),
|
||||
("[", "BRACKET_LEFT",),
|
||||
("]", "BRACKET_RIGHT",),
|
||||
("{", "BRACE_LEFT",),
|
||||
("}", "BRACE_RIGHT",),
|
||||
("^", "META",),
|
||||
("#", "MACRO_DISPATCH",),
|
||||
(
|
||||
"(",
|
||||
"PAREN_LEFT",
|
||||
),
|
||||
(
|
||||
")",
|
||||
"PAREN_RIGHT",
|
||||
),
|
||||
(
|
||||
"[",
|
||||
"BRACKET_LEFT",
|
||||
),
|
||||
(
|
||||
"]",
|
||||
"BRACKET_RIGHT",
|
||||
),
|
||||
(
|
||||
"{",
|
||||
"BRACE_LEFT",
|
||||
),
|
||||
(
|
||||
"}",
|
||||
"BRACE_RIGHT",
|
||||
),
|
||||
(
|
||||
"^",
|
||||
"META",
|
||||
),
|
||||
(
|
||||
"#",
|
||||
"MACRO_DISPATCH",
|
||||
),
|
||||
("'", "SINGLE_QUOTE"),
|
||||
("foo", "SYMBOL",),
|
||||
(
|
||||
"foo",
|
||||
"SYMBOL",
|
||||
),
|
||||
("foo/bar", "SYMBOL"),
|
||||
(":foo", "KEYWORD",),
|
||||
(":foo/bar", "KEYWORD",),
|
||||
(" ,,\t ,, \t", "WHITESPACE",),
|
||||
(
|
||||
":foo",
|
||||
"KEYWORD",
|
||||
),
|
||||
(
|
||||
":foo/bar",
|
||||
"KEYWORD",
|
||||
),
|
||||
(
|
||||
" ,,\t ,, \t",
|
||||
"WHITESPACE",
|
||||
),
|
||||
("\n\r", "WHITESPACE"),
|
||||
("\n", "WHITESPACE"),
|
||||
(" , ", "WHITESPACE",),
|
||||
(
|
||||
" , ",
|
||||
"WHITESPACE",
|
||||
),
|
||||
("; this is a sample comment\n", "COMMENT"),
|
||||
('"foo"', "STRING"),
|
||||
('"foo bar baz"', "STRING"),
|
||||
|
|
|
@ -8,12 +8,15 @@ from conftest import parametrize
|
|||
import pytest
|
||||
|
||||
|
||||
@parametrize("text", [
|
||||
'"',
|
||||
'"foo bar',
|
||||
'"""foo bar',
|
||||
'"""foo bar"',
|
||||
])
|
||||
@parametrize(
|
||||
"text",
|
||||
[
|
||||
'"',
|
||||
'"foo bar',
|
||||
'"""foo bar',
|
||||
'"""foo bar"',
|
||||
],
|
||||
)
|
||||
def test_bad_strings_raise(text):
|
||||
"""Tests asserting we won't let obviously bad strings fly."""
|
||||
# FIXME (arrdem 2021-03-13):
|
||||
|
@ -22,81 +25,89 @@ def test_bad_strings_raise(text):
|
|||
next(cp.parse_buffer(text))
|
||||
|
||||
|
||||
@parametrize("text", [
|
||||
"[1.0",
|
||||
"(1.0",
|
||||
"{1.0",
|
||||
])
|
||||
@parametrize(
|
||||
"text",
|
||||
[
|
||||
"[1.0",
|
||||
"(1.0",
|
||||
"{1.0",
|
||||
],
|
||||
)
|
||||
def test_unterminated_raises(text):
|
||||
"""Tests asserting that we don't let unterminated collections parse."""
|
||||
with pytest.raises(cp.CalfMissingCloseParseError):
|
||||
next(cp.parse_buffer(text))
|
||||
|
||||
|
||||
@parametrize("text", [
|
||||
"[{]",
|
||||
"[(]",
|
||||
"({)",
|
||||
"([)",
|
||||
"{(}",
|
||||
"{[}",
|
||||
])
|
||||
@parametrize(
|
||||
"text",
|
||||
[
|
||||
"[{]",
|
||||
"[(]",
|
||||
"({)",
|
||||
"([)",
|
||||
"{(}",
|
||||
"{[}",
|
||||
],
|
||||
)
|
||||
def test_unbalanced_raises(text):
|
||||
"""Tests asserting that we don't let missmatched collections parse."""
|
||||
with pytest.raises(cp.CalfUnexpectedCloseParseError):
|
||||
next(cp.parse_buffer(text))
|
||||
|
||||
|
||||
@parametrize("buff, value", [
|
||||
('"foo"', "foo"),
|
||||
('"foo\tbar"', "foo\tbar"),
|
||||
('"foo\n\rbar"', "foo\n\rbar"),
|
||||
('"foo\\"bar\\""', "foo\"bar\""),
|
||||
('"""foo"""', 'foo'),
|
||||
('"""foo"bar"baz"""', 'foo"bar"baz'),
|
||||
])
|
||||
@parametrize(
|
||||
"buff, value",
|
||||
[
|
||||
('"foo"', "foo"),
|
||||
('"foo\tbar"', "foo\tbar"),
|
||||
('"foo\n\rbar"', "foo\n\rbar"),
|
||||
('"foo\\"bar\\""', 'foo"bar"'),
|
||||
('"""foo"""', "foo"),
|
||||
('"""foo"bar"baz"""', 'foo"bar"baz'),
|
||||
],
|
||||
)
|
||||
def test_strings_round_trip(buff, value):
|
||||
assert next(cp.parse_buffer(buff)) == value
|
||||
|
||||
@parametrize('text, element_types', [
|
||||
# Integers
|
||||
("(1)", ["INTEGER"]),
|
||||
("( 1 )", ["INTEGER"]),
|
||||
("(,1,)", ["INTEGER"]),
|
||||
("(1\n)", ["INTEGER"]),
|
||||
("(\n1\n)", ["INTEGER"]),
|
||||
("(1, 2, 3, 4)", ["INTEGER", "INTEGER", "INTEGER", "INTEGER"]),
|
||||
|
||||
# Floats
|
||||
("(1.0)", ["FLOAT"]),
|
||||
("(1.0e0)", ["FLOAT"]),
|
||||
("(1e0)", ["FLOAT"]),
|
||||
("(1e0)", ["FLOAT"]),
|
||||
|
||||
# Symbols
|
||||
("(foo)", ["SYMBOL"]),
|
||||
("(+)", ["SYMBOL"]),
|
||||
("(-)", ["SYMBOL"]),
|
||||
("(*)", ["SYMBOL"]),
|
||||
("(foo-bar)", ["SYMBOL"]),
|
||||
("(+foo-bar+)", ["SYMBOL"]),
|
||||
("(+foo-bar+)", ["SYMBOL"]),
|
||||
("( foo bar )", ["SYMBOL", "SYMBOL"]),
|
||||
|
||||
# Keywords
|
||||
("(:foo)", ["KEYWORD"]),
|
||||
("( :foo )", ["KEYWORD"]),
|
||||
("(\n:foo\n)", ["KEYWORD"]),
|
||||
("(,:foo,)", ["KEYWORD"]),
|
||||
("(:foo :bar)", ["KEYWORD", "KEYWORD"]),
|
||||
("(:foo :bar 1)", ["KEYWORD", "KEYWORD", "INTEGER"]),
|
||||
|
||||
# Strings
|
||||
('("foo", "bar", "baz")', ["STRING", "STRING", "STRING"]),
|
||||
|
||||
# Lists
|
||||
('([] [] ())', ["SQLIST", "SQLIST", "LIST"]),
|
||||
])
|
||||
@parametrize(
|
||||
"text, element_types",
|
||||
[
|
||||
# Integers
|
||||
("(1)", ["INTEGER"]),
|
||||
("( 1 )", ["INTEGER"]),
|
||||
("(,1,)", ["INTEGER"]),
|
||||
("(1\n)", ["INTEGER"]),
|
||||
("(\n1\n)", ["INTEGER"]),
|
||||
("(1, 2, 3, 4)", ["INTEGER", "INTEGER", "INTEGER", "INTEGER"]),
|
||||
# Floats
|
||||
("(1.0)", ["FLOAT"]),
|
||||
("(1.0e0)", ["FLOAT"]),
|
||||
("(1e0)", ["FLOAT"]),
|
||||
("(1e0)", ["FLOAT"]),
|
||||
# Symbols
|
||||
("(foo)", ["SYMBOL"]),
|
||||
("(+)", ["SYMBOL"]),
|
||||
("(-)", ["SYMBOL"]),
|
||||
("(*)", ["SYMBOL"]),
|
||||
("(foo-bar)", ["SYMBOL"]),
|
||||
("(+foo-bar+)", ["SYMBOL"]),
|
||||
("(+foo-bar+)", ["SYMBOL"]),
|
||||
("( foo bar )", ["SYMBOL", "SYMBOL"]),
|
||||
# Keywords
|
||||
("(:foo)", ["KEYWORD"]),
|
||||
("( :foo )", ["KEYWORD"]),
|
||||
("(\n:foo\n)", ["KEYWORD"]),
|
||||
("(,:foo,)", ["KEYWORD"]),
|
||||
("(:foo :bar)", ["KEYWORD", "KEYWORD"]),
|
||||
("(:foo :bar 1)", ["KEYWORD", "KEYWORD", "INTEGER"]),
|
||||
# Strings
|
||||
('("foo", "bar", "baz")', ["STRING", "STRING", "STRING"]),
|
||||
# Lists
|
||||
("([] [] ())", ["SQLIST", "SQLIST", "LIST"]),
|
||||
],
|
||||
)
|
||||
def test_parse_list(text, element_types):
|
||||
"""Test we can parse various lists of contents."""
|
||||
l_t = next(cp.parse_buffer(text, discard_whitespace=True))
|
||||
|
@ -104,45 +115,43 @@ def test_parse_list(text, element_types):
|
|||
assert [t.type for t in l_t] == element_types
|
||||
|
||||
|
||||
@parametrize('text, element_types', [
|
||||
# Integers
|
||||
("[1]", ["INTEGER"]),
|
||||
("[ 1 ]", ["INTEGER"]),
|
||||
("[,1,]", ["INTEGER"]),
|
||||
("[1\n]", ["INTEGER"]),
|
||||
("[\n1\n]", ["INTEGER"]),
|
||||
("[1, 2, 3, 4]", ["INTEGER", "INTEGER", "INTEGER", "INTEGER"]),
|
||||
|
||||
# Floats
|
||||
("[1.0]", ["FLOAT"]),
|
||||
("[1.0e0]", ["FLOAT"]),
|
||||
("[1e0]", ["FLOAT"]),
|
||||
("[1e0]", ["FLOAT"]),
|
||||
|
||||
# Symbols
|
||||
("[foo]", ["SYMBOL"]),
|
||||
("[+]", ["SYMBOL"]),
|
||||
("[-]", ["SYMBOL"]),
|
||||
("[*]", ["SYMBOL"]),
|
||||
("[foo-bar]", ["SYMBOL"]),
|
||||
("[+foo-bar+]", ["SYMBOL"]),
|
||||
("[+foo-bar+]", ["SYMBOL"]),
|
||||
("[ foo bar ]", ["SYMBOL", "SYMBOL"]),
|
||||
|
||||
# Keywords
|
||||
("[:foo]", ["KEYWORD"]),
|
||||
("[ :foo ]", ["KEYWORD"]),
|
||||
("[\n:foo\n]", ["KEYWORD"]),
|
||||
("[,:foo,]", ["KEYWORD"]),
|
||||
("[:foo :bar]", ["KEYWORD", "KEYWORD"]),
|
||||
("[:foo :bar 1]", ["KEYWORD", "KEYWORD", "INTEGER"]),
|
||||
|
||||
# Strings
|
||||
('["foo", "bar", "baz"]', ["STRING", "STRING", "STRING"]),
|
||||
|
||||
# Lists
|
||||
('[[] [] ()]', ["SQLIST", "SQLIST", "LIST"]),
|
||||
])
|
||||
@parametrize(
|
||||
"text, element_types",
|
||||
[
|
||||
# Integers
|
||||
("[1]", ["INTEGER"]),
|
||||
("[ 1 ]", ["INTEGER"]),
|
||||
("[,1,]", ["INTEGER"]),
|
||||
("[1\n]", ["INTEGER"]),
|
||||
("[\n1\n]", ["INTEGER"]),
|
||||
("[1, 2, 3, 4]", ["INTEGER", "INTEGER", "INTEGER", "INTEGER"]),
|
||||
# Floats
|
||||
("[1.0]", ["FLOAT"]),
|
||||
("[1.0e0]", ["FLOAT"]),
|
||||
("[1e0]", ["FLOAT"]),
|
||||
("[1e0]", ["FLOAT"]),
|
||||
# Symbols
|
||||
("[foo]", ["SYMBOL"]),
|
||||
("[+]", ["SYMBOL"]),
|
||||
("[-]", ["SYMBOL"]),
|
||||
("[*]", ["SYMBOL"]),
|
||||
("[foo-bar]", ["SYMBOL"]),
|
||||
("[+foo-bar+]", ["SYMBOL"]),
|
||||
("[+foo-bar+]", ["SYMBOL"]),
|
||||
("[ foo bar ]", ["SYMBOL", "SYMBOL"]),
|
||||
# Keywords
|
||||
("[:foo]", ["KEYWORD"]),
|
||||
("[ :foo ]", ["KEYWORD"]),
|
||||
("[\n:foo\n]", ["KEYWORD"]),
|
||||
("[,:foo,]", ["KEYWORD"]),
|
||||
("[:foo :bar]", ["KEYWORD", "KEYWORD"]),
|
||||
("[:foo :bar 1]", ["KEYWORD", "KEYWORD", "INTEGER"]),
|
||||
# Strings
|
||||
('["foo", "bar", "baz"]', ["STRING", "STRING", "STRING"]),
|
||||
# Lists
|
||||
("[[] [] ()]", ["SQLIST", "SQLIST", "LIST"]),
|
||||
],
|
||||
)
|
||||
def test_parse_sqlist(text, element_types):
|
||||
"""Test we can parse various 'square' lists of contents."""
|
||||
l_t = next(cp.parse_buffer(text, discard_whitespace=True))
|
||||
|
@ -150,41 +159,21 @@ def test_parse_sqlist(text, element_types):
|
|||
assert [t.type for t in l_t] == element_types
|
||||
|
||||
|
||||
@parametrize('text, element_pairs', [
|
||||
("{}",
|
||||
[]),
|
||||
|
||||
("{:foo 1}",
|
||||
[["KEYWORD", "INTEGER"]]),
|
||||
|
||||
("{:foo 1, :bar 2}",
|
||||
[["KEYWORD", "INTEGER"],
|
||||
["KEYWORD", "INTEGER"]]),
|
||||
|
||||
("{foo 1, bar 2}",
|
||||
[["SYMBOL", "INTEGER"],
|
||||
["SYMBOL", "INTEGER"]]),
|
||||
|
||||
("{foo 1, bar -2}",
|
||||
[["SYMBOL", "INTEGER"],
|
||||
["SYMBOL", "INTEGER"]]),
|
||||
|
||||
("{foo 1, bar -2e0}",
|
||||
[["SYMBOL", "INTEGER"],
|
||||
["SYMBOL", "FLOAT"]]),
|
||||
|
||||
("{foo ()}",
|
||||
[["SYMBOL", "LIST"]]),
|
||||
|
||||
("{foo []}",
|
||||
[["SYMBOL", "SQLIST"]]),
|
||||
|
||||
("{foo {}}",
|
||||
[["SYMBOL", "DICT"]]),
|
||||
|
||||
('{"foo" {}}',
|
||||
[["STRING", "DICT"]])
|
||||
])
|
||||
@parametrize(
|
||||
"text, element_pairs",
|
||||
[
|
||||
("{}", []),
|
||||
("{:foo 1}", [["KEYWORD", "INTEGER"]]),
|
||||
("{:foo 1, :bar 2}", [["KEYWORD", "INTEGER"], ["KEYWORD", "INTEGER"]]),
|
||||
("{foo 1, bar 2}", [["SYMBOL", "INTEGER"], ["SYMBOL", "INTEGER"]]),
|
||||
("{foo 1, bar -2}", [["SYMBOL", "INTEGER"], ["SYMBOL", "INTEGER"]]),
|
||||
("{foo 1, bar -2e0}", [["SYMBOL", "INTEGER"], ["SYMBOL", "FLOAT"]]),
|
||||
("{foo ()}", [["SYMBOL", "LIST"]]),
|
||||
("{foo []}", [["SYMBOL", "SQLIST"]]),
|
||||
("{foo {}}", [["SYMBOL", "DICT"]]),
|
||||
('{"foo" {}}', [["STRING", "DICT"]]),
|
||||
],
|
||||
)
|
||||
def test_parse_dict(text, element_pairs):
|
||||
"""Test we can parse various mappings."""
|
||||
d_t = next(cp.parse_buffer(text, discard_whitespace=True))
|
||||
|
@ -192,27 +181,25 @@ def test_parse_dict(text, element_pairs):
|
|||
assert [[t.type for t in pair] for pair in d_t.value] == element_pairs
|
||||
|
||||
|
||||
@parametrize("text", [
|
||||
"{1}",
|
||||
"{1, 2, 3}",
|
||||
"{:foo}",
|
||||
"{:foo :bar :baz}"
|
||||
])
|
||||
@parametrize("text", ["{1}", "{1, 2, 3}", "{:foo}", "{:foo :bar :baz}"])
|
||||
def test_parse_bad_dict(text):
|
||||
"""Assert that dicts with missmatched pairs don't parse."""
|
||||
with pytest.raises(Exception):
|
||||
next(cp.parse_buffer(text))
|
||||
|
||||
|
||||
@parametrize("text", [
|
||||
"()",
|
||||
"(1 1.1 1e2 -2 foo :foo foo/bar :foo/bar [{},])",
|
||||
"{:foo bar, :baz [:qux]}",
|
||||
"'foo",
|
||||
"'[foo bar :baz 'qux, {}]",
|
||||
"#foo []",
|
||||
"^{} bar",
|
||||
])
|
||||
@parametrize(
|
||||
"text",
|
||||
[
|
||||
"()",
|
||||
"(1 1.1 1e2 -2 foo :foo foo/bar :foo/bar [{},])",
|
||||
"{:foo bar, :baz [:qux]}",
|
||||
"'foo",
|
||||
"'[foo bar :baz 'qux, {}]",
|
||||
"#foo []",
|
||||
"^{} bar",
|
||||
],
|
||||
)
|
||||
def test_examples(text):
|
||||
"""Shotgun examples showing we can parse some stuff."""
|
||||
|
||||
|
|
|
@ -5,18 +5,22 @@ from conftest import parametrize
|
|||
|
||||
from calf.reader import read_buffer
|
||||
|
||||
@parametrize('text', [
|
||||
"()",
|
||||
"[]",
|
||||
"[[[[[[[[[]]]]]]]]]",
|
||||
"{1 {2 {}}}",
|
||||
'"foo"',
|
||||
"foo",
|
||||
"'foo",
|
||||
"^foo bar",
|
||||
"^:foo bar",
|
||||
"{\"foo\" '([:bar ^:foo 'baz 3.14159e0])}",
|
||||
"[:foo bar 'baz lo/l, 1, 1.2. 1e-5 -1e2]",
|
||||
])
|
||||
|
||||
@parametrize(
|
||||
"text",
|
||||
[
|
||||
"()",
|
||||
"[]",
|
||||
"[[[[[[[[[]]]]]]]]]",
|
||||
"{1 {2 {}}}",
|
||||
'"foo"',
|
||||
"foo",
|
||||
"'foo",
|
||||
"^foo bar",
|
||||
"^:foo bar",
|
||||
"{\"foo\" '([:bar ^:foo 'baz 3.14159e0])}",
|
||||
"[:foo bar 'baz lo/l, 1, 1.2. 1e-5 -1e2]",
|
||||
],
|
||||
)
|
||||
def test_read(text):
|
||||
assert list(read_buffer(text))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue