test(pyargus): add better testing for parsing expressions

- Limit the size of the identifiers, and prevent ambiguity in the
identifiers.
This commit is contained in:
Anand Balakrishnan 2023-10-12 16:22:03 -07:00
parent 5da441db42
commit 4f33300d1c
No known key found for this signature in database
7 changed files with 31 additions and 16 deletions

View file

@ -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"):

View file

@ -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",
)
)

View file

@ -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)

View file

@ -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,