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 == "": 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