Python hypothesis.strategies.recursive() Examples

The following are 16 code examples of hypothesis.strategies.recursive(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module hypothesis.strategies , or try the search function .
Example #1
Source File: strategies-and-tactics.py    From escape-from-automanual-testing with GNU Affero General Public License v3.0 6 votes vote down vote up
def test_json_dumps(value):
    """Checks that value is serialisable as JSON."""
    # We expect this test to always pass - the point of this exercise is
    # to define a recursive strategy, and then investigate the values it
    # generates for a *passing* test.
    hypothesis.note("type: {}".format(type(value)))
    hypothesis.event("type: {}".format(type(value)))
    json.dumps(value)


# Takeaway: you've seen and played with a few ways to see what a
# passing test is doing, without having to inject a failure.


##############################################################################
# `@st.composite` exercise

# This goal of this exercise is to play with a contrived data dependency,
# using a composite strategy to generate inputs.  You can use the same tricks
# as above to check what's being generated, so try to keep the test passing! 
Example #2
Source File: test_parse.py    From eliot with Apache License 2.0 6 votes vote down vote up
def action_structures(draw):
    """
    A Hypothesis strategy that creates a tree of L{ActionStructure} and
    L{unicode}.
    """
    tree = draw(st.recursive(labels, st.lists, max_leaves=20))

    def to_structure(tree_or_message):
        if isinstance(tree_or_message, list):
            return ActionStructure(
                type=draw(labels),
                failed=draw(st.booleans()),
                children=[to_structure(o) for o in tree_or_message],
            )
        else:
            return tree_or_message

    return to_structure(tree) 
Example #3
Source File: test_pencode.py    From chopsticks with Apache License 2.0 6 votes vote down vote up
def assert_roundtrip(obj):
    """Assert that we can successfully round-trip the given object."""
    buf = pencode(obj)
    assert isinstance(buf, bytes)
    obj2 = pdecode(buf)

    assert type(obj) == type(obj2)

    # By definition NaN does not equal anything, even itself
    if isinstance(obj2, float) and math.isnan(obj2):
        return obj2

    try:
        assert obj == obj2
    except RuntimeError as e:
        if 'maximum recursion depth exceeded' not in e.args[0]:
            raise
        # If we hit a RecursionError, we correctly decoded a recursive
        # structure, so test passes :)
    except RecursionError:
        pass

    return obj2 
Example #4
Source File: __init__.py    From cattrs with MIT License 6 votes vote down vote up
def _create_hyp_nested_strategy(simple_class_strategy):
    """
    Create a recursive attrs class.
    Given a strategy for building (simpler) classes, create and return
    a strategy for building classes that have as an attribute:
        * just the simpler class
        * a list of simpler classes
        * a dict mapping the string "cls" to a simpler class.
    """
    # A strategy producing tuples of the form ([list of attributes], <given
    # class strategy>).
    attrs_and_classes = st.tuples(
        lists_of_attrs(defaults=True), simple_class_strategy
    )

    return (
        attrs_and_classes.flatmap(just_class)
        | attrs_and_classes.flatmap(just_class_with_type)
        | attrs_and_classes.flatmap(list_of_class)
        | attrs_and_classes.flatmap(list_of_class_with_type)
        | attrs_and_classes.flatmap(dict_of_class)
    ) 
Example #5
Source File: _from_schema.py    From hypothesis-jsonschema with Mozilla Public License 2.0 6 votes vote down vote up
def regex_patterns(draw: Any) -> str:
    """Return a recursive strategy for simple regular expression patterns."""
    fragments = st.one_of(
        st.just("."),
        st.from_regex(r"\[\^?[A-Za-z0-9]+\]"),
        REGEX_PATTERNS.map("{}+".format),
        REGEX_PATTERNS.map("{}?".format),
        REGEX_PATTERNS.map("{}*".format),
    )
    result = draw(st.lists(fragments, min_size=1, max_size=3).map("".join))
    assert isinstance(result, str)
    try:
        re.compile(result)
    except re.error:
        assume(False)
    return result 
Example #6
Source File: test_mdk.py    From mdk with Apache License 2.0 5 votes vote down vote up
def add_bools(list_of_lists):
    """
    Given recursive list that can contain other lists, return tuple of that plus
    a booleans strategy for each list.
    """
    l = []
    def count(recursive):
        l.append(1)
        for child in recursive:
            if isinstance(child, list):
                count(child)
    count(list_of_lists)
    return st.tuples(st.just(list_of_lists), st.tuples(*[st.sampled_from([True, False]) for i in l])) 
Example #7
Source File: pbt-101.py    From escape-from-automanual-testing with GNU Affero General Public License v3.0 5 votes vote down vote up
def from_json(cls, string):
        """Decodes a JSON-string back into a `Record` instance

        This is a *bad* method. This needs to be fixed
        """
        value = string
        return cls(value)


# We can define recursive strategies like so: 
Example #8
Source File: strategies-and-tactics.py    From escape-from-automanual-testing with GNU Affero General Public License v3.0 5 votes vote down vote up
def test_map_odd_numbers(x):
    assert x[-1] in "13579"


# Takeaway
# --------
# `.map` permits us to extend Hypothesis' core strategies in powerful
# ways. See that it can be used to affect the individual values being
# produced by a strategy (e.g. mapping integers to even-valued
# integers), as well as to cast the values to a different type (e.g.
# mapping an integer to a string.
#
# If it seems like a data-type is missing from Hypothesis'
# strategies, then it is likely that a simple application of `.map`
# will suffice. E.g. suppose you want a strategy that generate deques,
# then
#     `deque_strat = st.lists(...).map(deque)`
# will serve nicely - we don't even need a lambda!


##############################################################################
# Defining recursive data.

# There are a couple of ways to define recursive data with Hypothesis,
# leaning on the fact that strategies are lazily instantiated.
#
# `st.recursive` takes a base strategy, and a function that takes a strategy
# and returns an extended strategy.  All good if we want that structure!
# If you want mutual recursion though, or have a complicated kind of data
# (or just limited time in a tutorial), `st.deferred` is the way to go.
#
# The `Record` exercise in pbt-101.py defined JSON using `st.recursive`,
# if you want to compare them, and has some extension problems that you
# could write as tests here instead.


# JSON values are defined as one of null, false, true, a finite number,
# a string, an array of json values, or a dict of string to json values. 
Example #9
Source File: test_prettyprinter.py    From prettyprinter with MIT License 5 votes vote down vote up
def hashable_containers(primitives):
    def extend(base):
        return st.one_of(
            st.frozensets(base, max_size=50),
            st.lists(base, max_size=50).map(tuple),
        )
    return st.recursive(primitives, extend) 
Example #10
Source File: test_prettyprinter.py    From prettyprinter with MIT License 5 votes vote down vote up
def containers(primitives):
    def extend(base):
        return st.one_of(
            st.lists(base, max_size=50),
            st.lists(base, max_size=50).map(tuple),
            st.dictionaries(
                keys=hashable_containers(primitives),
                values=base,
                max_size=10
            ),
        )

    return st.recursive(primitives, extend, max_leaves=50) 
Example #11
Source File: test_prettyprinter.py    From prettyprinter with MIT License 5 votes vote down vote up
def nested_dictionaries():
    simple_strings_alphabet = 'abcdefghijklmnopqrstuvwxyz\'"\r\n '
    simple_text = st.text(alphabet=simple_strings_alphabet, min_size=5)

    def extend(base):
        return st.one_of(
            st.lists(base, min_size=5),
            st.dictionaries(keys=simple_text, values=base, min_size=1)
        )

    return st.recursive(simple_text, extend, max_leaves=50) 
Example #12
Source File: basestrategies.py    From swagger-conformance with MIT License 5 votes vote down vote up
def json(value_limit=5):
    """Hypothesis strategy for generating values that can be passed to
    `json.dumps` to produce valid JSON data.

    :param value_limit: A limit on the number of values in the JSON data -
                        setting this too high can cause value generation to
                        time out.
    :type value_limit: int
    """
    return hy_st.recursive(
        hy_st.floats() | hy_st.booleans() | hy_st.text() | hy_st.none(),
        lambda children: hy_st.dictionaries(hy_st.text(), children),
        max_leaves=value_limit) 
Example #13
Source File: __init__.py    From cattrs with MIT License 5 votes vote down vote up
def simple_classes(defaults=None, min_attrs=0):
    """
    Return a strategy that yields tuples of simple classes and values to
    instantiate them.
    """
    return lists_of_attrs(defaults, min_size=min_attrs).flatmap(
        _create_hyp_class
    )


# Ok, so st.recursive works by taking a base strategy (in this case,
# simple_classes) and a special function. This function receives a strategy,
# and returns another strategy (building on top of the base strategy). 
Example #14
Source File: test_mdk.py    From mdk with Apache License 2.0 4 votes vote down vote up
def test_nestedInteractions(self, values):
        """
        Nested interactions operate independently of parent interactions.

        :param values: a two-tuple composed of:
           - a recursive list of unicode and other recursive lists - list start
             means begin interaction, string means node resolve, list end means
             finish interaction.
           - list of False/True; True means failed interaction
        """
        requested_interactions, failures = values
        failures = iter(failures)
        assume(not isinstance(requested_interactions, unicode))
        self.init()
        ws_actor = self.connector.expectSocket()
        self.connector.connect(ws_actor)

        failures = iter(failures)
        created_services = {}
        expected_success_nodes = Counter()
        expected_failed_nodes = Counter()

        def run_interaction(children):
            should_fail = next(failures)
            failed = []
            succeeded = []
            self.session.start_interaction()
            for child in children:
                if isinstance(child, unicode):
                    # Make sure disco knows about the node:
                    if child in created_services:
                        node = created_services[child]
                    else:
                        node = create_node(child, child)
                        created_services[child] = node
                    self.disco.onMessage(None, NodeActive(node))
                    # Make sure the child Node is resolved in the interaction
                    self.session.resolve(node.service, "1.0")
                    if should_fail:
                        expected_failed_nodes[node] += 1
                        failed.append(node)
                    else:
                        expected_success_nodes[node] += 1
                        succeeded.append(node)
                else:
                    run_interaction(child)
            if should_fail:
                self.session.fail_interaction("OHNO")
            self.session.finish_interaction()
            self.connector.advance_time(5.0) # Make sure interaction is sent
            ws_actor.swallowLogMessages()
            self.connector.expectInteraction(
                self, ws_actor, self.session, failed, succeeded)

        run_interaction(requested_interactions)
        for node in set(expected_failed_nodes) | set(expected_success_nodes):
            policy = self.disco.failurePolicy(node)
            self.assertEqual((policy.successes, policy.failures),
                             (expected_success_nodes[node],
                              expected_failed_nodes[node])) 
Example #15
Source File: strategies.py    From attrs with MIT License 4 votes vote down vote up
def _create_hyp_nested_strategy(simple_class_strategy):
    """
    Create a recursive attrs class.

    Given a strategy for building (simpler) classes, create and return
    a strategy for building classes that have as an attribute: either just
    the simpler class, a list of simpler classes, a tuple of simpler classes,
    an ordered dict or a dict mapping the string "cls" to a simpler class.
    """
    # Use a tuple strategy to combine simple attributes and an attr class.
    def just_class(tup):
        combined_attrs = list(tup[0])
        combined_attrs.append(attr.ib(default=attr.Factory(tup[1])))
        return _create_hyp_class(combined_attrs)

    def list_of_class(tup):
        default = attr.Factory(lambda: [tup[1]()])
        combined_attrs = list(tup[0])
        combined_attrs.append(attr.ib(default=default))
        return _create_hyp_class(combined_attrs)

    def tuple_of_class(tup):
        default = attr.Factory(lambda: (tup[1](),))
        combined_attrs = list(tup[0])
        combined_attrs.append(attr.ib(default=default))
        return _create_hyp_class(combined_attrs)

    def dict_of_class(tup):
        default = attr.Factory(lambda: {"cls": tup[1]()})
        combined_attrs = list(tup[0])
        combined_attrs.append(attr.ib(default=default))
        return _create_hyp_class(combined_attrs)

    def ordereddict_of_class(tup):
        default = attr.Factory(lambda: OrderedDict([("cls", tup[1]())]))
        combined_attrs = list(tup[0])
        combined_attrs.append(attr.ib(default=default))
        return _create_hyp_class(combined_attrs)

    # A strategy producing tuples of the form ([list of attributes], <given
    # class strategy>).
    attrs_and_classes = st.tuples(list_of_attrs, simple_class_strategy)

    return st.one_of(
        attrs_and_classes.map(just_class),
        attrs_and_classes.map(list_of_class),
        attrs_and_classes.map(tuple_of_class),
        attrs_and_classes.map(dict_of_class),
        attrs_and_classes.map(ordereddict_of_class),
    ) 
Example #16
Source File: strategies.py    From attrs with MIT License 4 votes vote down vote up
def simple_classes(
    draw, slots=None, frozen=None, weakref_slot=None, private_attrs=None
):
    """
    A strategy that generates classes with default non-attr attributes.

    For example, this strategy might generate a class such as:

    @attr.s(slots=True, frozen=True, weakref_slot=True)
    class HypClass:
        a = attr.ib(default=1)
        _b = attr.ib(default=None)
        c = attr.ib(default='text')
        _d = attr.ib(default=1.0)
        c = attr.ib(default={'t': 1})

    By default, all combinations of slots, frozen, and weakref_slot classes
    will be generated.  If `slots=True` is passed in, only slotted classes will
    be generated, and if `slots=False` is passed in, no slotted classes will be
    generated. The same applies to `frozen` and `weakref_slot`.

    By default, some attributes will be private (i.e. prefixed with an
    underscore). If `private_attrs=True` is passed in, all attributes will be
    private, and if `private_attrs=False`, no attributes will be private.
    """
    attrs = draw(list_of_attrs)
    frozen_flag = draw(st.booleans()) if frozen is None else frozen
    slots_flag = draw(st.booleans()) if slots is None else slots
    weakref_slot_flag = (
        draw(st.booleans()) if weakref_slot is None else weakref_slot
    )

    if private_attrs is None:
        attr_names = maybe_underscore_prefix(gen_attr_names())
    elif private_attrs is True:
        attr_names = ("_" + n for n in gen_attr_names())
    elif private_attrs is False:
        attr_names = gen_attr_names()

    cls_dict = dict(zip(attr_names, attrs))
    post_init_flag = draw(st.booleans())
    if post_init_flag:

        def post_init(self):
            pass

        cls_dict["__attrs_post_init__"] = post_init

    return make_class(
        "HypClass",
        cls_dict,
        slots=slots_flag,
        frozen=frozen_flag,
        weakref_slot=weakref_slot_flag,
    )


# st.recursive works by taking a base strategy (in this case, simple_classes)
# and a special function.  This function receives a strategy, and returns
# another strategy (building on top of the base strategy).