Rule contract kit

Checks for rule plug-ins.

handoverlab.testing

Contract test kit for handover-rule plug-ins.

check_rule runs a rule on the smoke scenario and checks that it keeps the contract of the rule interface:

construct the rule can be built from the given parameters; params() is a dictionary that can be written to JSON and reports the given values; the family is baseline, conditional, daps or ltm recreate a rule built from params() reports the same parameters (stored results can be repeated) debug run a run in debug mode raises nothing: every hook returns a number or an array of the right shape without NaN, the rule does not write into the observation, all engine invariants hold deterministic two runs give identical event-log fingerprints and metrics, with and without debug mode global random state the run leaves NumPy's and Python's global random state untouched (use ctx.rng) independent next to another rule on the same world the rule gives the same event log as alone reduces_to (optional) with given parameters the rule gives the same event log as a built-in rule

Use it in the tests of a plug-in package::

from handoverlab.testing import check_rule
from my_rules import SpeedScaledA3

def test_contract():
    check_rule(SpeedScaledA3, params={"off_db": 3.0, "ttt_s": 0.32, "v_ref": 8.0},
               reduces_to=("a3", {"off_db": 3.0, "ttt_s": 0.32}, {"v_ref": 1e9}))

reduces_to is (key, built-in parameters, own parameter changes): the rule with params updated by the changes must reproduce the built-in rule key. check_rule raises AssertionError naming every failed check, or returns a ContractReport with raise_on_failure=False.

ScaledA3

Bases: BaselineRule

Example plug-in: Event A3 whose time-to-trigger shrinks with the reported speed.

ttt = ttt_s * min(1, v_ref / speed). With an infinite v_ref it is A3.

check_rule(rule: Union[type, str], params: Optional[Dict[str, Any]] = None, reduces_to: Optional[Tuple[str, Dict[str, Any], Dict[str, Any]]] = None, scenario: Union[str, Scenario] = 'smoke', seed: int = 1, raise_on_failure: bool = True) -> ContractReport

Check the rule class rule (or registry key) with constructor arguments params.