Skip to content

Commit

Permalink
Hypothesis rule based state machine test case for testing strategies …
Browse files Browse the repository at this point in the history
…behavior. Fix #10.
  • Loading branch information
nilp0inter committed Nov 16, 2019
1 parent a14de22 commit 1dac991
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 6 deletions.
17 changes: 11 additions & 6 deletions experta/strategies.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,17 @@ def get_key(self, activation):
def _update_agenda(self, agenda, added, removed):
for act in removed:
act.key = self.get_key(act)
try:
idx = bisect.bisect_left(agenda.activations, act)
if agenda.activations[idx] == act:
del agenda.activations[idx]
except IndexError:
pass
idx = bisect.bisect_left(agenda.activations, act)
for o in (0, 1, -1):
try:
if agenda.activations[idx+o] == act:
del agenda.activations[idx+o]
else:
continue
except IndexError:
pass
else:
break

for act in added:
act.key = self.get_key(act)
Expand Down
61 changes: 61 additions & 0 deletions tests/unit/test_strategy_statemachine.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import pytest

from hypothesis import strategies as st
from hypothesis import assume, settings
from hypothesis.database import DirectoryBasedExampleDatabase
from hypothesis.stateful import Bundle, RuleBasedStateMachine, rule, invariant, consumes

from experta.activation import Activation
from experta.agenda import Agenda
from experta.engine import KnowledgeEngine
from experta.fact import Fact
from experta.factlist import FactList
from experta.rule import Rule
from experta.strategies import DepthStrategy


def get_rule_stm(strategy):
class StrategyStateMachine(RuleBasedStateMachine):
def __init__(self):
super(StrategyStateMachine, self).__init__()
self.model = set()
self.agenda = Agenda()
self.strategy = strategy()
self.fss = set()

activations = Bundle("activations")

@rule(target=activations,
r=st.integers(min_value=0),
fs=st.sets(st.integers(min_value=0), min_size=1))
def declare(self, r, fs):
assume((r, frozenset(fs)) not in self.fss)
self.fss.add((r, frozenset(fs)))

fs = [Fact(i, __factid__=i) for i in fs]
act = Activation(Rule(Fact(r)), facts=tuple(fs))

# Update agenda
self.strategy.update_agenda(self.agenda, [act], [])

# Update model
self.model |= set([act])

return act

@rule(act=consumes(activations))
def retract(self, act):
# Update agenda
self.strategy.update_agenda(self.agenda, [], [act])

# Update model
self.model -= set([act])

@invariant()
def values_agree(self):
assert set(self.agenda.activations) == self.model

return StrategyStateMachine


test_depthstrategy_state_machine = get_rule_stm(DepthStrategy).TestCase

0 comments on commit 1dac991

Please sign in to comment.