Ejemplo n.º 1
0
    def accept(f):
        parent_rule = getattr(f, RULE_MARKER, None)
        if parent_rule is not None:
            raise InvalidDefinition(
                'A function cannot be used for two distinct rules. ',
                Settings.default,
            )
        precondition = getattr(f, PRECONDITION_MARKER, None)
        rule = Rule(targets=tuple(converted_targets),
                    arguments=kwargs,
                    function=f,
                    precondition=precondition,
                    parent_rule=parent_rule)

        @proxies(f)
        def rule_wrapper(*args, **kwargs):
            return f(*args, **kwargs)

        setattr(rule_wrapper, RULE_MARKER, rule)
        return rule_wrapper
Ejemplo n.º 2
0
    def accept(f):
        existing_rule = getattr(f, RULE_MARKER, None)
        existing_initialize_rule = getattr(f, INITIALIZE_RULE_MARKER, None)
        if existing_rule is not None or existing_initialize_rule is not None:
            raise InvalidDefinition(
                'A function cannot be used for two distinct rules. ',
                Settings.default,
            )
        precondition = getattr(f, PRECONDITION_MARKER, None)
        rule = Rule(targets=converted_targets,
                    arguments=kwargs,
                    function=f,
                    precondition=precondition)

        @proxies(f)
        def rule_wrapper(*args, **kwargs):
            return f(*args, **kwargs)

        setattr(rule_wrapper, RULE_MARKER, rule)
        return rule_wrapper
Ejemplo n.º 3
0
    def do_draw(self, data):
        if not any(self.is_valid(rule) for rule in self.rules):
            msg = u"No progress can be made from state %r" % (self.machine,)
            quiet_raise(InvalidDefinition(msg))

        feature_flags = data.draw(self.enabled_rules_strategy)

        # Note: The order of the filters here is actually quite important,
        # because checking is_enabled makes choices, so increases the size of
        # the choice sequence. This means that if we are in a case where many
        # rules are invalid we will make a lot more choices if we ask if they
        # are enabled before we ask if they are valid, so our test cases will
        # be artificially large.
        rule = data.draw(
            st.sampled_from(self.rules)
            .filter(self.is_valid)
            .filter(lambda r: feature_flags.is_enabled(r.function.__name__))
        )

        return (rule, data.draw(rule.arguments_strategy))
Ejemplo n.º 4
0
 def do_draw(self, data):
     # This strategy is slightly strange in its implementation.
     # We don't want the interpretation of the rule we draw to change based
     # on whether other rules satisfy their preconditions or have data in
     # their bundles. Therefore the index into the rule list needs to stay
     # stable. BUT we don't want to draw invalid rules. So what we do is we
     # draw an index. We *could* just loop until it's valid, but if most
     # rules are invalid then that could result in a very long loop.
     # So what we do is the following:
     #
     #   1. We first draw a rule unconditionally, and check if it's valid.
     #      If it is, great. Nothing more to do, that's our rule.
     #   2. If it is invalid, we now calculate the list of valid rules and
     #      draw from that list (if there are none, that's an error in the
     #      definition of the machine and we complain to the user about it).
     #   3. Once we've drawn a valid rule, we write that back to the byte
     #      stream. As a result, when shrinking runs the shrinker can delete
     #      the initial failed draw + the draw that lead to us finding an
     #      index into valid_rules, leaving just the written value of i.
     #      When this is run, it will look as we got lucky and just happened
     #      to pick a valid rule.
     #
     # Easy, right?
     n = len(self.rules)
     i = cu.integer_range(data, 0, n - 1)
     u, v = data.blocks[-1]
     block_length = v - u
     rule = self.rules[i]
     if not self.is_valid(rule):
         valid_rules = [
             j for j, r in enumerate(self.rules) if self.is_valid(r)
         ]
         if not valid_rules:
             raise InvalidDefinition(
                 u'No progress can be made from state %r' %
                 (self.machine, ))
         i = valid_rules[cu.integer_range(data, 0, len(valid_rules) - 1)]
         data.write(int_to_bytes(i, block_length))
         rule = self.rules[i]
     return (rule, data.draw(rule.arguments_strategy))
Ejemplo n.º 5
0
 def steps(self):
     strategies = []
     for rule in self.rules():
         converted_arguments = {}
         valid = True
         for k, v in rule.arguments.items():
             if isinstance(v, Bundle):
                 bundle = self.bundle(v.name)
                 if not bundle:
                     valid = False
                     break
                 else:
                     v = SimpleSampledFromStrategy(bundle)
             converted_arguments[k] = v
         if valid:
             strategies.append(
                 TupleStrategy((JustStrategy(rule),
                                FixedKeysDictStrategy(converted_arguments)),
                               tuple))
     if not strategies:
         raise InvalidDefinition('No progress can be made from state %r' %
                                 (self, ))
     return one_of_strategies(strategies)
Ejemplo n.º 6
0
    def steps(self):
        strategies = []
        for rule in self.rules():
            converted_arguments = {}
            valid = True
            if rule.precondition and not rule.precondition(self):
                continue
            for k, v in sorted(rule.arguments.items()):
                if isinstance(v, Bundle):
                    bundle = self.bundle(v.name)
                    if not bundle:
                        valid = False
                        break
                    v = BundleReferenceStrategy(v.name)
                converted_arguments[k] = v
            if valid:
                strategies.append(
                    tuples(just(rule),
                           fixed_dictionaries(converted_arguments)))
        if not strategies:
            raise InvalidDefinition(u'No progress can be made from state %r' %
                                    (self, ))

        return one_of(strategies)
Ejemplo n.º 7
0
 def do_draw(self, data):
     if not any(self.is_valid(rule) for rule in self.rules):
         msg = u"No progress can be made from state %r" % (self.machine,)
         quiet_raise(InvalidDefinition(msg))
     rule = data.draw(st.sampled_from(self.rules).filter(self.is_valid))
     return (rule, data.draw(rule.arguments_strategy))