Example #1
0
def _generate_state_machine(rules_object: type) -> type:

    bases = (_BrownieStateMachine, rules_object, sf.RuleBasedStateMachine)
    machine = type("BrownieStateMachine", bases, {})
    strategies = {
        k: v
        for k, v in getmembers(rules_object) if isinstance(v, SearchStrategy)
    }

    for attr, fn in filter(_member_filter, getmembers(machine)):
        varnames = [[i]
                    for i in fn.__code__.co_varnames[1:fn.__code__.co_argcount]
                    ]
        if fn.__defaults__:
            for i in range(-1, -1 - len(fn.__defaults__), -1):
                varnames[i].append(fn.__defaults__[i])

        if _attr_filter(attr, "initialize"):
            wrapped = sf.initialize(
                **{key[0]: strategies[key[-1]]
                   for key in varnames})
            setattr(machine, attr, wrapped(fn))
        elif _attr_filter(attr, "invariant"):
            setattr(machine, attr, sf.invariant()(fn))
        elif _attr_filter(attr, "rule"):
            wrapped = sf.rule(
                **{key[0]: strategies[key[-1]]
                   for key in varnames})
            setattr(machine, attr, wrapped(fn))

    return machine
Example #2
0
        def another_invariant(self):
            raise ValueError()

        @rule()
        def do_stuff(self):
            pass

    run_state_machine_as_test(Invariant)


@pytest.mark.parametrize(
    "decorators",
    [
        (invariant(), rule()),
        (rule(), invariant()),
        (invariant(), initialize()),
        (initialize(), invariant()),
        (invariant(), precondition(lambda self: True), rule()),
        (rule(), precondition(lambda self: True), invariant()),
        (precondition(lambda self: True), invariant(), rule()),
        (precondition(lambda self: True), rule(), invariant()),
    ],
    ids=lambda x: "-".join(f.__qualname__.split(".")[0] for f in x),
)
def test_invariant_and_rule_are_incompatible(decorators):
    """It's an error to apply @invariant and @rule to the same method."""

    def method(self):
        pass

    for d in decorators[:-1]: