Files
Sheerka-Old/tests/parsers/test_ExplainParser.py
T

206 lines
8.1 KiB
Python

import pytest
from core.builtin_concepts import BuiltinConcepts
from parsers.BaseParser import UnexpectedTokenErrorNode, UnexpectedEof
from parsers.ExplainParser import ExplainParser, ExplanationNode, MultipleDigestError, ValueErrorNode, \
RecurseDefNode, FormatLNode, UnionNode, FilterNode, FormatDNode
from parsers.ExpressionParser import PropertyContainsNode, PropertyEqualsNode, TrueNode, AndNode, OrNode
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
class TestExplainParser(TestUsingMemoryBasedSheerka):
def init_parser(self, **kwargs):
sheerka = self.get_sheerka(singleton=True, **kwargs)
context = self.get_context(sheerka)
parser = ExplainParser()
return sheerka, context, parser
def test_i_cannot_parse_empty_string(self):
sheerka, context, parser = self.init_parser()
res = parser.parse(context, "")
assert not res.status
assert sheerka.isinstance(res.body, BuiltinConcepts.NOT_FOR_ME)
def test_i_cannot_parse_if_not_for_me(self):
sheerka, context, parser = self.init_parser()
text = "foo"
res = parser.parse(context, text)
not_for_me = res.body
assert not res.status
assert sheerka.isinstance(not_for_me, BuiltinConcepts.NOT_FOR_ME)
assert not_for_me.body == text
assert isinstance(not_for_me.reason[0], UnexpectedTokenErrorNode)
@pytest.mark.parametrize("text, digest, command, directives", [
# ("explain", "", "explain", []),
("explain digest", "digest", "explain digest", []),
("explain -r 3", "", "explain -r 3", [RecurseDefNode(3)]),
("explain digest -r 3", "digest", "explain digest -r 3", [RecurseDefNode(3)]),
])
def test_i_can_parse_explain_without_filter(self, text, digest, command, directives):
sheerka, context, parser = self.init_parser()
res = parser.parse(context, text)
parser_result = res.body
explanation_node = res.body.body
assert res.status
assert sheerka.isinstance(parser_result, BuiltinConcepts.PARSER_RESULT)
assert parser_result.parser.name == "parsers.Explain"
assert parser_result.source == text
assert explanation_node.digest == digest
assert explanation_node.command == command
assert explanation_node.expr == UnionNode([FilterNode(TrueNode(), directives)])
def test_i_can_parse_using_filter(self):
sheerka, context, parser = self.init_parser()
text = "explain -f a=b"
res = parser.parse(context, text)
parser_result = res.body
explanation_node = res.body.body
assert res.status
assert sheerka.isinstance(parser_result, BuiltinConcepts.PARSER_RESULT)
assert parser_result.parser.name == "parsers.Explain"
assert parser_result.source == text
assert explanation_node.expr == UnionNode([
FilterNode(TrueNode()),
FilterNode(PropertyContainsNode("a", "b"))])
@pytest.mark.parametrize("text, expected", [
("-f a==b", PropertyEqualsNode("a", "b")),
("--filter a==b", PropertyEqualsNode("a", "b")),
("-f a==b and c=d", AndNode(PropertyEqualsNode("a", "b"), PropertyContainsNode("c", "d"))),
("-f a==b or c=d", OrNode(PropertyEqualsNode("a", "b"), PropertyContainsNode("c", "d"))),
("-f a==b or c==d and e==f", OrNode(
PropertyEqualsNode("a", "b"),
AndNode(PropertyEqualsNode("c", "d"), PropertyEqualsNode("e", "f")))),
("-f a==b and c==d or e==f", OrNode(
AndNode(PropertyEqualsNode("a", "b"), PropertyEqualsNode("c", "d")),
PropertyEqualsNode("e", "f"))),
("-f (a==b or c==d) and e==f", AndNode(
OrNode(PropertyEqualsNode("a", "b"), PropertyEqualsNode("c", "d")),
PropertyEqualsNode("e", "f"))),
])
def test_i_can_parse_filter_expressions(self, text, expected):
sheerka, context, parser = self.init_parser()
res = parser.parse(context, "explain " + text)
parser_result = res.body
explanation_node = res.body.body
expr_node = explanation_node.expr.filters[-1].expr
assert res.status
assert sheerka.isinstance(parser_result, BuiltinConcepts.PARSER_RESULT)
assert isinstance(explanation_node, ExplanationNode)
assert expr_node == expected
@pytest.mark.parametrize("text, expected", [
("-r 2", [
FilterNode(TrueNode(), [RecurseDefNode(2)])
]),
("--format_l 'abc'", [
FilterNode(TrueNode(), [FormatLNode('abc')])
]),
("--format_d 'abc'", [
FilterNode(TrueNode(), [FormatDNode({"abc": "{abc}"})])
]),
("--format_d a,b,c", [
FilterNode(TrueNode(), [FormatDNode({"a": "{a}", "b": "{b}", "c": "{c}"})])
]),
("--format_d a , b , c", [
FilterNode(TrueNode(), [FormatDNode({"a": "{a}", "b": "{b}", "c": "{c}"})])
]),
("-r 2 --format_l 'abc'", [
FilterNode(TrueNode(), [RecurseDefNode(2), FormatLNode('abc')])
]),
("--format_d a, b -r 2", [
FilterNode(TrueNode(), [FormatDNode({"a": "{a}", "b": "{b}"}), RecurseDefNode(2)])
]),
("-f a==b -r 3", [
FilterNode(TrueNode()),
FilterNode(PropertyEqualsNode("a", "b"), [RecurseDefNode(3)]),
]),
("-f a==b --format_l 'abc'", [
FilterNode(TrueNode()),
FilterNode(PropertyEqualsNode("a", "b"), [FormatLNode("abc")]),
]),
("-r 3 -f a==b", [
FilterNode(TrueNode(), [RecurseDefNode(3)]),
FilterNode(PropertyEqualsNode("a", "b"), []),
]),
("--format_l 'abc' -f a==b", [
FilterNode(TrueNode(), [FormatLNode("abc")]),
FilterNode(PropertyEqualsNode("a", "b"), []),
]),
("-f a==b -f c==d", [
FilterNode(TrueNode()),
FilterNode(PropertyEqualsNode("a", "b")),
FilterNode(PropertyEqualsNode("c", "d"))
]),
("-r 1 -f a==b -r 2 -f c==d -r 3", [
FilterNode(TrueNode(), [RecurseDefNode(1)]),
FilterNode(PropertyEqualsNode("a", "b"), [RecurseDefNode(2)]),
FilterNode(PropertyEqualsNode("c", "d"), [RecurseDefNode(3)])
]),
])
def test_i_can_parse_other_directives(self, text, expected):
sheerka, context, parser = self.init_parser()
res = parser.parse(context, "explain " + text)
parser_result = res.body
explanation_node = res.body.body
expr_node = explanation_node.expr
assert res.status
assert sheerka.isinstance(parser_result, BuiltinConcepts.PARSER_RESULT)
assert isinstance(explanation_node, ExplanationNode)
assert expr_node.filters == expected
@pytest.mark.parametrize("text, expected", [
("explain -d digest", "digest"),
("explain -d", ""),
("explain -d -f a=b", "")
])
def test_i_can_parse_record_digest(self, text, expected):
sheerka, context, parser = self.init_parser()
res = parser.parse(context, text)
explanation_node = res.body.body
assert explanation_node.digest == expected
assert explanation_node.record_digest
@pytest.mark.parametrize("text, expected_error_type", [
("explain digest1 digest2", MultipleDigestError),
("explain -r", UnexpectedEof),
("explain -r foo", ValueErrorNode),
("explain -r 1.2", ValueErrorNode),
("explain -f -r 1.2", UnexpectedTokenErrorNode),
("explain -f", UnexpectedEof),
("explain --format_d", UnexpectedEof),
("explain --format_l", UnexpectedEof),
("explain --format_l -r foo", UnexpectedTokenErrorNode),
("explain --format_d -r foo", UnexpectedTokenErrorNode),
])
def test_i_cannot_parse(self, text, expected_error_type):
sheerka, context, parser = self.init_parser()
res = parser.parse(context, text)
error = res.body
errors = res.body.body
assert not res.status
assert sheerka.isinstance(error, BuiltinConcepts.ERROR)
assert len(errors) == 1
assert isinstance(errors[0], expected_error_type)