180 lines
5.7 KiB
Python
180 lines
5.7 KiB
Python
from dataclasses import dataclass
|
|
from enum import Enum
|
|
|
|
import pytest
|
|
|
|
from common.utils import decode_enum, dict_product, get_class, get_text_from_tokens, str_concept, to_dict, unstr_concept
|
|
from helpers import get_concept
|
|
from parsers.tokenizer import Token, TokenKind, Tokenizer
|
|
|
|
|
|
@dataclass
|
|
class Obj:
|
|
prop1: str
|
|
prop2: str
|
|
|
|
def __hash__(self):
|
|
return hash((self.prop1, self.prop1))
|
|
|
|
def __eq__(self, other):
|
|
if not isinstance(other, Obj):
|
|
return False
|
|
|
|
return self.prop1 == other.prop1 and self.prop2 == other.prop2
|
|
|
|
|
|
@dataclass
|
|
class Obj2:
|
|
prop1: object
|
|
prop2: object
|
|
|
|
|
|
class MyEnum(Enum):
|
|
CONCEPT = "concept"
|
|
|
|
|
|
def get_tokens(lst):
|
|
res = []
|
|
for e in lst:
|
|
if e == " ":
|
|
res.append(Token(TokenKind.WHITESPACE, " ", 0, 0, 0))
|
|
elif e == "\n":
|
|
res.append(Token(TokenKind.NEWLINE, "\n", 0, 0, 0))
|
|
elif e == "<EOF>":
|
|
res.append(Token(TokenKind.EOF, "\n", 0, 0, 0))
|
|
else:
|
|
res.append(Token(TokenKind.IDENTIFIER, e, 0, 0, 0))
|
|
|
|
return res
|
|
|
|
|
|
def test_i_can_get_class():
|
|
# example of classes that should be in the result
|
|
create_parser_input = get_class("evaluators.CreateParserInput.CreateParserInput")
|
|
|
|
assert isinstance(create_parser_input, type)
|
|
|
|
|
|
@pytest.mark.parametrize("text, expected_key, expected_id", [
|
|
(None, None, None),
|
|
(10, None, None),
|
|
("", None, None),
|
|
("xxx", None, None),
|
|
("c:", None, None),
|
|
("c:key", None, None),
|
|
("c:key:", "key", None),
|
|
("c:key#id", None, None),
|
|
("c:key#id:", "key", "id"),
|
|
("c:#id:", None, "id"),
|
|
("c:key#:", "key", None),
|
|
("c:key#id:x", None, None),
|
|
("c:one: plus c:two:", None, None),
|
|
("c:one#id: plus c:two:", None, None),
|
|
])
|
|
def test_i_can_unstr_concept(text, expected_key, expected_id):
|
|
k, i = unstr_concept(text)
|
|
assert k == expected_key
|
|
assert i == expected_id
|
|
|
|
|
|
@pytest.mark.parametrize("text, expected_key, expected_id", [
|
|
("r:key:", "key", None),
|
|
("r:key#id:", "key", "id"),
|
|
])
|
|
def test_i_can_unstr_concept_rules(text, expected_key, expected_id):
|
|
k, i = unstr_concept(text, prefix="r:")
|
|
assert k == expected_key
|
|
assert i == expected_id
|
|
|
|
|
|
def test_i_can_str_concept():
|
|
assert str_concept(("key", "id")) == "c:key#id:"
|
|
assert str_concept((None, "id")) == "c:#id:"
|
|
assert str_concept(("key", None)) == "c:key:"
|
|
assert str_concept((None, None)) == ""
|
|
assert str_concept(("key", "id"), drop_name=True) == "c:#id:"
|
|
|
|
concept = get_concept("foo")
|
|
assert str_concept(concept) == "c:foo:"
|
|
|
|
concept.get_metadata().id = "1001"
|
|
assert str_concept(concept) == "c:foo#1001:"
|
|
assert str_concept(concept, drop_name=True) == "c:#1001:"
|
|
|
|
assert str_concept(("key", "id"), prefix='r:') == "r:key#id:"
|
|
|
|
|
|
@pytest.mark.parametrize("text, expected", [
|
|
(None, None),
|
|
(10, None),
|
|
("", None),
|
|
("xxx", None),
|
|
("xxx.", None),
|
|
("xxx.yyy", None),
|
|
("tests.common.test_utils.MyEnum.CONCEPT", MyEnum.CONCEPT),
|
|
])
|
|
def test_i_can_decode_enum(text, expected):
|
|
actual = decode_enum(text)
|
|
assert actual == expected
|
|
|
|
|
|
@pytest.mark.parametrize("items, expected", [
|
|
([], {}),
|
|
([Obj("a", "1"), Obj("a", "2"), Obj("b", "3")], {"a": [Obj("a", "1"), Obj("a", "2")],
|
|
"b": [Obj("b", "3")]}),
|
|
])
|
|
def test_i_can_to_dict(items, expected):
|
|
assert to_dict(items, lambda obj: obj.prop1) == expected
|
|
|
|
|
|
@pytest.mark.parametrize("text, expected_text", [
|
|
("hello world", "hello world"),
|
|
("'hello' 'world'", "'hello' 'world'"),
|
|
("def concept a from", "def concept a from"),
|
|
("()[]{}1=1.5+-/*><&é", "()[]{}1=1.5+-/*><&é"),
|
|
("execute(c:concept_name:)", "execute(c:concept_name:)")
|
|
|
|
])
|
|
def test_i_can_get_text_from_tokens(text, expected_text):
|
|
tokens = list(Tokenizer(text))
|
|
assert get_text_from_tokens(tokens) == expected_text
|
|
|
|
|
|
@pytest.mark.parametrize("text, custom, expected_text", [
|
|
("execute(c:concept_name:)", {TokenKind.CONCEPT: lambda t: f"__C__{t.value[0]}"}, "execute(__C__concept_name)")
|
|
])
|
|
def test_i_can_get_text_from_tokens_with_custom_switcher(text, custom, expected_text):
|
|
tokens = list(Tokenizer(text))
|
|
assert get_text_from_tokens(tokens, custom) == expected_text
|
|
|
|
|
|
def test_i_can_track_tokens():
|
|
text = "execute(c:name1: if r:#id: else c:name2:)"
|
|
switcher = {TokenKind.CONCEPT: lambda t: f"__CONCEPT__{t.value[0]}",
|
|
TokenKind.RULE: lambda t: f"__RULE__{t.value[1]}"}
|
|
tracker = {}
|
|
tokens = list(Tokenizer(text))
|
|
get_text_from_tokens(tokens, switcher, tracker)
|
|
assert len(tracker) == 3
|
|
assert tracker["__CONCEPT__name1"] == tokens[2]
|
|
assert tracker["__RULE__id"] == tokens[6]
|
|
assert tracker["__CONCEPT__name2"] == tokens[10]
|
|
|
|
|
|
@pytest.mark.parametrize("a,b,expected", [
|
|
([], [], []),
|
|
([{"a": "a", "b": "b"}], [], [{"a": "a", "b": "b"}]),
|
|
([], [{"a": "a", "b": "b"}], [{"a": "a", "b": "b"}]),
|
|
([{"a": "a", "b": "b"}], [{"d": "d1"}, {"d": "d2"}], [{"a": "a", "b": "b", "d": "d1"},
|
|
{"a": "a", "b": "b", "d": "d2"}]),
|
|
([{"d": "d1"}, {"d": "d2"}], [{"a": "a", "b": "b"}], [{"a": "a", "b": "b", "d": "d1"},
|
|
{"a": "a", "b": "b", "d": "d2"}]),
|
|
([{"a": "a", "b": "b"}], [{"d": "d", "e": "e"}], [{"a": "a", "b": "b", "d": "d", "e": "e"}]),
|
|
([{"a": "a"}, {"b": "b"}], [{"d": "d"}, {"e": "e"}], [{"a": "a", "d": "d"},
|
|
{"a": "a", "e": "e"},
|
|
{"b": "b", "d": "d"},
|
|
{"b": "b", "e": "e"}])
|
|
])
|
|
def test_dict_product(a, b, expected):
|
|
assert dict_product(a, b) == expected
|