fix missing requirements and add test caller

This commit is contained in:
JOLIMAITRE Matthieu 2024-05-21 05:52:45 +02:00
parent d93ab67edc
commit 78ceb46b2e
8 changed files with 94 additions and 149 deletions

70
tests/cases.py Executable file
View file

@ -0,0 +1,70 @@
#!/bin/env -S python
from typing import TypeVar, Any
from os.path import dirname
import sys
sys.path.append(f"{dirname(__file__)}/../src")
from pyalibert import regex, Parser, just, Declare
from okipy.lib import Suite
# utils
whitespace = just(" ").or_(just("\n")).repeat()
T = TypeVar("T")
def lexeme(p: Parser[T]) -> Parser[T]:
return p << whitespace
suite = Suite("cases")
@suite.test()
def case_json(ctx):
# Punctuation
lbrace = lexeme(just("{"))
rbrace = lexeme(just("}"))
lbrack = lexeme(just("["))
rbrack = lexeme(just("]"))
colon = lexeme(just(":"))
comma = lexeme(just(","))
# Primitives
true = lexeme(just("true")).set(True)
false = lexeme(just("false")).set(False)
null = lexeme(just("null")).set(None)
number = lexeme(regex(r"-?(0|[1-9][0-9]*)([.][0-9]+)?([eE][+-]?[0-9]+)?")).map(float)
just_part = regex(r'[^"\\]+')
just_esc = just("\\") >> ( just("\\") | just("/") | just('"') | just("b").set("\b") | just("f").set("\f") | just("n").set("\n") | just("r").set("\r") | just("t").set("\t") | regex(r"u[0-9a-fA-F]{4}").map(lambda s: chr(int(s[1:], 16))))
quoted = lexeme(just('"') >> (just_part | just_esc).repeat().map(lambda l: "".join(l)) << just('"'))
# Data structures
json = Declare[Any]()
object_pair = (quoted << colon) & json.parser()
json_object = lbrace >> object_pair.sep_by(comma).map(dict) << rbrace
array = lbrack >> json.parser().sep_by(comma) << rbrack
# Everything
json.define(quoted | number | json_object | array | true | false | null)
json = json.parser()
# asserts
assert json.parse("1") == 1
assert json.parse('"1"') == "1"
assert json.parse('["1", 1]') == ["1", 1]
assert json.parse('{"1": 1}') == {"1": 1}
assert json.parse(r"""{
"int": 1,
"just": "hello",
"a list": [1, 2, 3],
"escapes": "\n \u24D2",
"nested": {"x": "y"},
"other": [true, false, null]
}""") == {
"int": 1,
"just": "hello",
"a list": [1, 2, 3],
"escapes": "\n",
"nested": {"x": "y"},
"other": [True, False, None],
}
if __name__ == "__main__": suite.run(sys.argv[1:])