From 5feced3da63eaa85f55649a4916c528417dc234e Mon Sep 17 00:00:00 2001 From: Tobias Reiher Date: Tue, 25 Aug 2020 12:20:48 +0200 Subject: [PATCH] Extend property tests for parser by new expressions Ref. #291 --- tests/property/strategies.py | 29 ++++++++++++++-- tests/property/test_parser.py | 63 +++++++++++++++++++++++++++++++---- 2 files changed, 84 insertions(+), 8 deletions(-) diff --git a/tests/property/strategies.py b/tests/property/strategies.py index 6230e88bf..faf061157 100644 --- a/tests/property/strategies.py +++ b/tests/property/strategies.py @@ -348,15 +348,31 @@ def variables(draw: Callable, elements: st.SearchStrategy[str]) -> expr.Variable @st.composite def attributes(draw: Callable, elements: st.SearchStrategy[expr.Expr]) -> expr.Expr: - attribute = draw(st.sampled_from([expr.Length, expr.First, expr.Length])) + attribute = draw(st.sampled_from([expr.Length, expr.First, expr.Last])) return attribute(draw(elements)) +@st.composite +def calls(draw: Callable, elements: st.SearchStrategy[expr.Expr]) -> expr.Call: + return draw(st.builds(expr.Call, identifiers(), st.lists(elements, min_size=1))) + + @st.composite def aggregates(draw: Callable, elements: st.SearchStrategy[str]) -> expr.Aggregate: return expr.Aggregate(*draw(st.lists(elements, min_size=1))) +@st.composite +def strings(draw: Callable) -> expr.String: + return expr.String(draw(st.text(string.ascii_letters + string.digits, min_size=1))) + + +@st.composite +def quantified_expressions(draw: Callable, elements: st.SearchStrategy[expr.Expr]) -> expr.Expr: + operation = draw(st.sampled_from([expr.ForAllIn, expr.ForSomeIn])) + return draw(st.builds(operation, identifiers(), elements, elements)) + + @st.composite def mathematical_expressions(draw: Callable, elements: st.SearchStrategy[expr.Expr]) -> expr.Expr: operation = draw(st.sampled_from([expr.Add, expr.Mul, expr.Sub, expr.Div, expr.Pow])) @@ -367,7 +383,16 @@ def mathematical_expressions(draw: Callable, elements: st.SearchStrategy[expr.Ex def relations(draw: Callable, elements: st.SearchStrategy[expr.Expr]) -> expr.Relation: relation = draw( st.sampled_from( - [expr.Less, expr.LessEqual, expr.Equal, expr.GreaterEqual, expr.Greater, expr.NotEqual] + [ + expr.Less, + expr.LessEqual, + expr.Equal, + expr.GreaterEqual, + expr.Greater, + expr.NotEqual, + expr.In, + expr.NotIn, + ] ) ) return relation(*draw(st.lists(elements, min_size=2, max_size=2))) diff --git a/tests/property/test_parser.py b/tests/property/test_parser.py index 91e827c0b..e57061a18 100644 --- a/tests/property/test_parser.py +++ b/tests/property/test_parser.py @@ -19,23 +19,74 @@ ) @settings(deadline=None, suppress_health_check=[HealthCheck.filter_too_much, HealthCheck.too_slow]) def test_parsing_mathematical_expressions(expression: expr.Expr) -> None: - parsed_expression = grammar.mathematical_expression().parseString(str(expression))[0] + parsed_expression = grammar.mathematical_expression().parseString( + str(expression), parseAll=True + )[0] assert parsed_expression == expression @given( strategies.boolean_expressions( st.one_of( - strategies.numbers() - | strategies.variables(strategies.identifiers()) - | strategies.attributes(strategies.identifiers()) - | strategies.aggregates(strategies.numbers()) + strategies.aggregates(strategies.numbers()) + | strategies.strings() + | strategies.mathematical_expressions( + st.one_of( + strategies.numbers() + | strategies.variables(strategies.identifiers()) + | strategies.attributes(strategies.identifiers()) + ) + ) ) ) ) @settings(deadline=None, suppress_health_check=[HealthCheck.filter_too_much, HealthCheck.too_slow]) def test_parsing_boolean_expressions(expression: expr.Expr) -> None: - parsed_expression = grammar.boolean_expression().parseString(str(expression))[0] + parsed_expression = grammar.boolean_expression().parseString(str(expression), parseAll=True)[0] + assert parsed_expression == expression + + +@given( + st.one_of( + strategies.mathematical_expressions( + st.one_of( + strategies.numbers() + | strategies.variables(strategies.identifiers()) + | strategies.attributes(strategies.identifiers()) + ) + ), + strategies.boolean_expressions( + st.one_of( + strategies.aggregates(strategies.numbers()) + | strategies.strings() + | strategies.mathematical_expressions( + st.one_of( + strategies.numbers() + | strategies.variables(strategies.identifiers()) + | strategies.attributes(strategies.identifiers()) + ) + ) + ) + ), + strategies.calls( + st.one_of( + strategies.numbers() + | strategies.variables(strategies.identifiers()) + | strategies.attributes(strategies.identifiers()) + ) + ), + strategies.quantified_expressions( + st.one_of( + strategies.numbers() + | strategies.variables(strategies.identifiers()) + | strategies.attributes(strategies.identifiers()) + ) + ), + ) +) +@settings(deadline=None, suppress_health_check=[HealthCheck.filter_too_much, HealthCheck.too_slow]) +def test_parsing_expressions(expression: expr.Expr) -> None: + parsed_expression = grammar.expression().parseString(str(expression), parseAll=True)[0] assert parsed_expression == expression