From 4f33300d1c31c2447e2b04301b52c951a62b3461 Mon Sep 17 00:00:00 2001 From: Anand Balakrishnan Date: Thu, 12 Oct 2023 16:22:03 -0700 Subject: [PATCH] test(pyargus): add better testing for parsing expressions - Limit the size of the identifiers, and prevent ambiguity in the identifiers. --- noxfile.py | 2 +- .../{tests => argus/test_utils}/__init__.py | 0 .../utils => argus/test_utils}/expr_gen.py | 36 +++++++++++++------ .../utils => argus/test_utils}/signals_gen.py | 0 pyargus/tests/test_expr.py | 6 ++-- pyargus/tests/test_signals.py | 3 +- pyargus/tests/utils/__init__.py | 0 7 files changed, 31 insertions(+), 16 deletions(-) rename pyargus/{tests => argus/test_utils}/__init__.py (100%) rename pyargus/{tests/utils => argus/test_utils}/expr_gen.py (66%) rename pyargus/{tests/utils => argus/test_utils}/signals_gen.py (100%) delete mode 100644 pyargus/tests/utils/__init__.py diff --git a/noxfile.py b/noxfile.py index 3b0f14f..3266603 100644 --- a/noxfile.py +++ b/noxfile.py @@ -101,7 +101,7 @@ def ruff(session: nox.Session): @nox.session(tags=["lint", "python"]) def mypy(session: nox.Session): - session.conda_install("mypy", "typing-extensions", "pytest", "hypothesis") + session.conda_install("mypy", "typing-extensions", "pytest", "hypothesis", "lark") session.env.update(ENV) with session.chdir(CURRENT_DIR / "pyargus"): diff --git a/pyargus/tests/__init__.py b/pyargus/argus/test_utils/__init__.py similarity index 100% rename from pyargus/tests/__init__.py rename to pyargus/argus/test_utils/__init__.py diff --git a/pyargus/tests/utils/expr_gen.py b/pyargus/argus/test_utils/expr_gen.py similarity index 66% rename from pyargus/tests/utils/expr_gen.py rename to pyargus/argus/test_utils/expr_gen.py index a04a977..a765104 100644 --- a/pyargus/tests/utils/expr_gen.py +++ b/pyargus/argus/test_utils/expr_gen.py @@ -1,24 +1,34 @@ """Hypothesis strategies to generate Argus expressions """ + import hypothesis.strategies as st +import lark from hypothesis.extra.lark import from_lark -from lark import Lark, Transformer -class T(Transformer): - def INT(self, tok): # noqa: N802,ANN # type: ignore - "Convert the value of `tok` from string to int, while maintaining line number & column." +class Transformer(lark.Transformer): + def INT(self, tok: lark.Token) -> lark.Token: # noqa: N802 + """Convert the value of `tok` from string to int, while maintaining line number & column. + + Performs wrapping conversion for 64-bit integers + """ return tok.update(value=int(tok) // 2**64) -ARGUS_EXPR_GRAMMAR = Lark( +ARGUS_EXPR_GRAMMAR = lark.Lark( r""" TRUE: "true" | "TRUE" FALSE: "false" | "FALSE" BOOLEAN: TRUE | FALSE -IDENT: ESCAPED_STRING | CNAME +KEYWORD: "X" | "G" | "F" | "U" | BOOLEAN + +ESCAPED_STRING: "\"" /(\w|[\t ]){1,20}/ "\"" +NUM_IDENT: ESCAPED_STRING + | "num_" CNAME +BOOL_IDENT: ESCAPED_STRING + | "bool_" CNAME num_expr: num_expr "*" num_expr | num_expr "/" num_expr @@ -26,7 +36,7 @@ num_expr: num_expr "*" num_expr | num_expr "-" num_expr | "-" num_expr | NUMBER - | IDENT + | NUM_IDENT | "(" num_expr ")" cmp_expr: num_expr ">=" num_expr @@ -49,12 +59,11 @@ bool_expr: bool_expr "&&" bool_expr | "F" WS_INLINE INTERVAL? bool_expr | cmp_expr | BOOLEAN - | IDENT + | BOOL_IDENT | "(" bool_expr ")" phi: bool_expr -%import common.ESCAPED_STRING %import common.CNAME %import common.NUMBER %import common.INT @@ -64,10 +73,17 @@ phi: bool_expr """, start="phi", + parser="lalr", + transformer=Transformer(), ) @st.composite def argus_expr(draw: st.DrawFn) -> str: """Strategy to generate an Argus STL expression from a pre-defined grammar""" - return draw(from_lark(ARGUS_EXPR_GRAMMAR, start="phi")) + return draw( + from_lark( + ARGUS_EXPR_GRAMMAR, + start="phi", + ) + ) diff --git a/pyargus/tests/utils/signals_gen.py b/pyargus/argus/test_utils/signals_gen.py similarity index 100% rename from pyargus/tests/utils/signals_gen.py rename to pyargus/argus/test_utils/signals_gen.py diff --git a/pyargus/tests/test_expr.py b/pyargus/tests/test_expr.py index 4105780..3ee432c 100644 --- a/pyargus/tests/test_expr.py +++ b/pyargus/tests/test_expr.py @@ -1,13 +1,13 @@ import logging -from hypothesis import given +from hypothesis import HealthCheck, given, settings import argus - -from .utils.expr_gen import argus_expr +from argus.test_utils.expr_gen import argus_expr @given(spec=argus_expr()) +@settings(suppress_health_check=[HealthCheck.too_slow]) def test_correct_expr(spec: str) -> None: try: _ = argus.parse_expr(spec) diff --git a/pyargus/tests/test_signals.py b/pyargus/tests/test_signals.py index 7ecb739..2f39a13 100644 --- a/pyargus/tests/test_signals.py +++ b/pyargus/tests/test_signals.py @@ -3,8 +3,7 @@ from hypothesis import assume, given from hypothesis import strategies as st import argus - -from .utils.signals_gen import ( +from argus.test_utils.signals_gen import ( constant_signal, draw_index, empty_signal, diff --git a/pyargus/tests/utils/__init__.py b/pyargus/tests/utils/__init__.py deleted file mode 100644 index e69de29..0000000