def test_can_extend_strategy(): class Foo(object): pass @strategy.extend(Foo) def s(foo, settings): return st.booleans() @strategy.extend_static(Foo) def t(foo, settings): return st.text() assert isinstance(strategy(Foo()).example(), bool) assert isinstance(strategy(Foo).example(), text_type)
def header(header_class, **kwargs): """Create a strategy for producing headers of a specific class. Args: header_class: The type of header to be produced. This class will be introspected to determine suitable strategies for each named field. **kwargs: Any supplied keyword arguments can be used to fix the value of particular header fields. """ field_strategies = {} for field_name in header_class.ordered_field_names(): if field_name in kwargs: field_strategy = just(kwargs.pop(field_name)) else: value_type = getattr(header_class, field_name).value_type field_strategy = integers_in_range(value_type.MINIMUM, value_type.MAXIMUM) field_strategies[field_name] = field_strategy if len(kwargs) > 0: raise TypeError("Unrecognised binary header field names {} for {}".format( ', '.join(kwargs.keys()), header_class.__name__)) return strategy(field_strategies).map(lambda kw: header_class(**kw))
def test_flatmap_retrieve_from_db(): constant_float_lists = strategy(floats_in_range( 0, 1)).flatmap(lambda x: [just(x)]) track = [] db = ExampleDatabase() @given(constant_float_lists, settings=Settings(database=db)) def record_and_test_size(xs): track.append(xs) assert sum(xs) < 1 with pytest.raises(AssertionError): record_and_test_size() assert track example = track[-1] while track: track.pop() with pytest.raises(AssertionError): record_and_test_size() assert track[0] == example
def url(schemes=[], userpass=False, port=False, url=False, query=False, fragment=False): if schemes: scheme = st.just(random.choice(schemes)) else: scheme = st.text(alphabet=ascii_lowercase+digits, min_size=2) d = {'scheme': scheme, 'domain': st.lists( st.text( alphabet=ascii_lowercase + digits, min_size=1, max_size=63), min_size=1, max_size=3), 'tld': st.text(alphabet=ascii_lowercase, min_size=2, max_size=63)} if userpass: d['user'] = st.text(alphabet=ascii_lowercase + digits) d['passwd'] = st.text(alphabet=ascii_lowercase + digits) if port: d['port'] = st.integers(min_value=0, max_value=65535) if url: d['url'] = st.lists(st.text()) if query: d['query'] = st.lists(st.tuples( st.text(alphabet=ascii_lowercase, min_size=1), st.text(alphabet=ascii_lowercase + digits, min_size=1))) if fragment: d['fragment'] = st.text() urlst = strategy(st.fixed_dictionaries(d)) return urlst.map(to_url).filter(max_len)
def header(header_class, **kwargs): """Create a strategy for producing headers of a specific class. Args: header_class: The type of header to be produced. This class will be introspected to determine suitable strategies for each named field. **kwargs: Any supplied keyword arguments can be used to fix the value of particular header fields. """ field_strategies = {} for field_name in header_class.ordered_field_names(): if field_name in kwargs: field_strategy = just(kwargs.pop(field_name)) else: value_type = getattr(header_class, field_name).value_type field_strategy = integers_in_range(value_type.MINIMUM, value_type.MAXIMUM) field_strategies[field_name] = field_strategy if len(kwargs) > 0: raise TypeError( "Unrecognised binary header field names {} for {}".format( ', '.join(kwargs.keys()), header_class.__name__)) return strategy(field_strategies).map(lambda kw: header_class(**kw))
def test_deeply_nested_sets(): def f(n): if n <= 0: return booleans() return sets(f(n - 1)) assert strategy(f(10)).template_upper_bound == float('inf')
class LocalTest(TestCase): @given(strategy(int).map(break_the_db)) def test_does_not_break_other_things(self, unused): pass def test_normal_test_1(self): Company.objects.create(name='MickeyCo')
def test_flatmap_retrieve_from_db(): constant_float_lists = strategy(floats(0, 1)).flatmap( lambda x: lists(just(x)) ) track = [] db = ExampleDatabase() @given(constant_float_lists, settings=Settings(database=db)) def record_and_test_size(xs): track.append(xs) assert sum(xs) < 1 with pytest.raises(AssertionError): record_and_test_size() assert track example = track[-1] while track: track.pop() with pytest.raises(AssertionError): record_and_test_size() assert track[0] == example
def test_deeply_nested_sets(): def f(n): if n <= 0: return bool return frozenset((f(n - 1), )) assert strategy(f(10)).size_lower_bound == float('inf')
def test_only_raises_bad_data_on_minimal(spec): strat = strategy(spec) for m in minimal_basic(): try: strat.from_basic(m) except BadData: pass
def test_deeply_nested_sets(): def f(n): if n <= 0: return booleans() return sets(f(n - 1)) assert strategy(f(10)).template_upper_bound == float(u'inf')
def test_deeply_nested_sets(): def f(n): if n <= 0: return bool return frozenset((f(n - 1),)) assert strategy(f(10)).size_lower_bound == float('inf')
def float_range(self, left, right): for f in (math.isnan, math.isinf): for x in (left, right): assume(not f(x)) left, right = sorted((left, right)) assert left <= right return strategy(floats(left, right))
def test_all_minimal_elements_reify(spec): random = Random(hashlib.md5(( show(spec) + ':test_all_minimal_elements_round_trip_via_the_database' ).encode('utf-8')).digest()) strat = strategy(spec, Settings(average_list_length=2)) for elt in minimal_elements(strat, random): strat.reify(elt)
def test_streams_copy_as_self(): x = strategy(streaming(bool)).example() assert copy(x) is x assert deepcopy(x) is x y = x.map(lambda x: not x) assert copy(y) is y assert deepcopy(y) is y
def test_round_tripping_lists_via_the_database(spec): random = Random(hashlib.md5( (show(spec) + ':test_round_tripping_via_the_database').encode('utf-8') ).digest()) strat = strategy([spec], Settings(average_list_length=10)) template = some_template(strat, random) template_via_db = via_database(spec, strat, template) assert show(strat.reify(template)) == show(strat.reify(template_via_db))
def via_database(spec, template): strat = strategy(spec) db = ExampleDatabase() s = db.storage_for(strat) s.save(template) results = list(s.fetch()) assert len(results) == 1 return results[0]
def test_check_serialization_preserves_changed_marker(): strat = strategy(streaming(floats(min_value=0.0, max_value=2.2250738585072014e-308))) template = strat.draw_template(Random(0), strat.draw_parameter(Random(0))) strat.reify(template)[0] simpler = next(strat.full_simplify(Random(0), template)) as_basic = strat.to_basic(simpler) assert as_basic == strat.to_basic(strat.from_basic(as_basic))
def test_two_incompatible_unreified_templates(): r = Random(1) strat = strategy(Bitfields).flatmap(lambda x: integers_in_range(0, x)) x = some_template(strat, r) y = some_template(strat, r) assert x.source_template != y.source_template assert not strat.strictly_simpler(x, y) assert not strat.strictly_simpler(y, x)
def test_all_minimal_elements_reify(spec): random = Random( hashlib.md5((show(spec) + ':test_all_minimal_elements_round_trip_via_the_database' ).encode('utf-8')).digest()) strat = strategy(spec, Settings(average_list_length=2)) for elt in minimal_elements(strat, random): strat.reify(elt)
def test_round_tripping_lists_via_the_database(spec): random = Random( hashlib.md5(( show(spec) + ':test_round_tripping_via_the_database').encode('utf-8')).digest()) strat = strategy([spec], Settings(average_list_length=10)) template = some_template(strat, random) template_via_db = via_database(spec, strat, template) assert show(strat.reify(template)) == show(strat.reify(template_via_db))
def test_can_still_simplify_if_not_reified(): strat = strategy(ConstantLists) random = Random(u'test_constant_lists_are_constant') template = some_template(strat, random) try: while True: template = next(strat.full_simplify(random, template)) except StopIteration: pass
def test_check_serialization_preserves_changed_marker(): strat = strategy( streaming(floats(min_value=0.0, max_value=2.2250738585072014e-308))) template = strat.draw_template(Random(0), strat.draw_parameter(Random(0))) strat.reify(template)[0] simpler = next(strat.full_simplify(Random(0), template)) as_basic = strat.to_basic(simpler) assert as_basic == strat.to_basic(strat.from_basic(as_basic))
def test_round_tripping_via_the_database(spec): random = Random(hashlib.md5( (show(spec) + ':test_round_tripping_via_the_database').encode('utf-8') ).digest()) strat = strategy(spec) template = some_template(strat, random) strat.from_basic(strat.to_basic(template)) template_via_db = via_database(spec, strat, template) assert show(strat.reify(template)) == show(strat.reify(template_via_db))
class HasSetupAndTeardown(object): def __init__(self): self.setups = 0 self.teardowns = [] def __repr__(self): return 'HasSetupAndTeardown()' def setup_example(self): self.setups += 1 def teardown_example(self, example): self.teardowns.append(example) def __copy__(self): return self def __deepcopy__(self, mapping): return self @given(int) def give_me_an_int(self, x): pass @given(str) def give_me_a_string(myself, x): pass @given(int) def give_me_a_positive_int(self, x): assert x >= 0 @given(strategy(int).map(lambda x: x.nope)) def fail_in_reify(self, x): pass @given(int) def assume_some_stuff(self, x): assume(x > 0) @given(strategy(int).filter(lambda x: x > 0)) def assume_in_reify(self, x): pass
def test_can_recalculate_shrinks_without_reify_cache(): random = Random('test_can_recalculate_shrinks_without_reify_cache') strat = strategy(Bitfields) template = some_template(strat, random) for shrunk_template in strat.full_simplify(random, template): strat.reify_cache.pop(shrunk_template, None) strat.reify_cache.pop(template, None) assert not (~strat.reify(template) & strat.reify(shrunk_template)) new_template = strat.from_basic(strat.to_basic(template)) assert strat.reify(template) == strat.reify(new_template)
def test_can_apply_simplifiers_to_other_types(): r = Random(0) s = strategy(one_of((bool, [bool]))) template1 = s.draw_and_produce_from_random(r) while True: template2 = s.draw_and_produce_from_random(r) if template2[0] != template1[0]: break for simplify in s.simplifiers(r, template1): assert list(simplify(r, template2)) == []
def test_round_tripping_via_the_database(spec): random = Random( hashlib.md5(( show(spec) + ':test_round_tripping_via_the_database').encode('utf-8')).digest()) strat = strategy(spec) template = some_template(strat, random) strat.from_basic(strat.to_basic(template)) template_via_db = via_database(spec, strat, template) assert show(strat.reify(template)) == show(strat.reify(template_via_db))
def can_find_as_many_templates_as_size(self, strat, r): tempstrat = strategy(TemplatesFor(strat)) n = min(10, strat.size_lower_bound) found = [] with Settings(verbosity=Verbosity.quiet, timeout=2.0): for _ in range(n): x = find( tempstrat, lambda t: t not in found, random=r, ) found.append(x)
def test_all_minimal_elements_round_trip_via_the_database(spec): random = Random(hashlib.md5(( show(spec) + u':test_all_minimal_elements_round_trip_via_the_database' ).encode(u'utf-8')).digest()) strat = strategy(spec, Settings(average_list_length=2)) for elt in minimal_elements(strat, random): elt_via_db = via_database(spec, strat, elt) with BuildContext(): assert show(strat.reify(elt)) == show(strat.reify(elt_via_db)) elt_via_db_2 = via_database(spec, strat, elt_via_db) assert elt_via_db == elt_via_db_2
def test_list_simplicity(): # Testing internal details because this is too damn hard to hit reliably s = strategy([bool]) assert not s.strictly_simpler((), ()) assert s.strictly_simpler((), (False,)) assert not s.strictly_simpler((True,), ()) assert s.strictly_simpler((True,), (False, True)) assert s.strictly_simpler((False,), (True,)) assert not s.strictly_simpler((True,), (False,)) assert s.strictly_simpler((False, False,), (False, True)) assert not s.strictly_simpler((False, True), (False, True))
def test_all_minimal_elements_round_trip_via_the_database(spec): random = Random( hashlib.md5((show(spec) + u':test_all_minimal_elements_round_trip_via_the_database' ).encode(u'utf-8')).digest()) strat = strategy(spec, Settings(average_list_length=2)) for elt in minimal_elements(strat, random): elt_via_db = via_database(spec, strat, elt) with BuildContext(): assert show(strat.reify(elt)) == show(strat.reify(elt_via_db)) elt_via_db_2 = via_database(spec, strat, elt_via_db) assert elt_via_db == elt_via_db_2
def test_can_collectively_minimize(spec): """This should generally exercise strategies' strictly_simpler heuristic by putting us in a state where example cloning is required to get to the answer fast enough.""" if strategy(spec).size_upper_bound < 2: return xs = find([spec], lambda x: len(x) >= 10 and len(set((map(repr, x)))) >= 2, settings=Settings(timeout=1.0, average_list_length=3)) assert len(xs) == 10 assert len(set((map(repr, xs)))) == 2
def some_template(spec, random=None): if random is None: random = Random() strat = strategy(spec) for _ in hrange(10): element = strat.draw_and_produce(random) try: strat.reify(element) return element except UnsatisfiedAssumption: pass else: raise NoExamples('some_template called on strategy with no examples')
def some_template(spec, random=None): if random is None: random = Random() strat = strategy(spec) for _ in hrange(100): element = strat.draw_and_produce(random) try: strat.reify(element) return element except UnsatisfiedAssumption: pass else: raise NoExamples('some_template called on strategy with no examples')
def minimal_basic(): global __minimal_basic if __minimal_basic is None: random = Random('__minimal_templates_as_basic_data') __minimal_basic = [] for typ in standard_types: strat = strategy(typ, Settings(average_list_length=2)) for m in minimal_elements(strat, random): __minimal_basic.append(strat.to_basic(m)) for i in hrange(10): __minimal_basic.append(list(hrange(i))) __minimal_basic.append([None] * i) __minimal_basic.append(None) return __minimal_basic
def test_can_collectively_minimize(spec): """This should generally exercise strategies' strictly_simpler heuristic by putting us in a state where example cloning is required to get to the answer fast enough.""" if strategy(spec).size_upper_bound < 2: return xs = find( [spec], lambda x: len(x) >= 10 and len(set((map(repr, x)))) >= 2, settings=Settings(timeout=1.0, average_list_length=3)) assert len(xs) == 10 assert len(set((map(repr, xs)))) == 2
def test_nested_set_complexity(): strat = strategy(frozenset({frozenset({complex})})) rnd = Random(0) template = ( ((float('inf'), 1.0), (-1.0325215252103651e-149, 1.0)), ((-1.677443578786644e-309, -1.0), (-2.2250738585072014e-308, 0.0)) ) simplifiers = list(strat.simplifiers(rnd, template)) rnd.shuffle(simplifiers) simplifiers = simplifiers[:10] for simplify in simplifiers: for s in islice(simplify(rnd, template), 50): assert not strat.strictly_simpler(template, s)
def minimal_basic(): global __minimal_basic if __minimal_basic is None: random = Random(u'__minimal_templates_as_basic_data') __minimal_basic = [] for typ in standard_types: strat = strategy(typ, Settings(average_list_length=2)) for m in minimal_elements(strat, random): __minimal_basic.append(strat.to_basic(m)) for i in hrange(10): __minimal_basic.append(list(hrange(i))) __minimal_basic.append([None] * i) __minimal_basic.append(None) return __minimal_basic
def spaced_ranges(min_num_ranges, max_num_ranges, min_interval, max_interval): """A Hypothesis strategy to produce separated, non-overlapping ranges. Args: min_num_ranges: The minimum number of ranges to produce. TODO: Correct? max_num_ranges: The maximum number of ranges to produce. min_interval: The minimum interval used for the lengths of the alternating ranges and spaces. max_interval: The maximum interval used for the lengths of the alternating ranges and spaces. """ return strategy(integers_in_range(min_num_ranges, max_num_ranges)) \ .map(lambda n: 2*n) \ .flatmap(lambda n: (integers_in_range(min_interval, max_interval),) * n) \ .map(list).map(lambda lst: list(accumulate(lst))) \ .map(lambda lst: list(batched(lst, 2))) \ .map(lambda pairs: list(starmap(range, pairs)))
def multiline_ascii_encodable_text(min_num_lines, max_num_lines): """A Hypothesis strategy to produce a multiline Unicode string. Args: min_num_lines: The minimum number of lines in the produced strings. max_num_lines: The maximum number of lines in the produced strings. Returns: A strategy for generating Unicode strings containing only newlines and characters which are encodable as printable 7-bit ASCII characters. """ return strategy(integers_in_range(min_num_lines, max_num_lines)) \ .flatmap(lambda n: ([integers_in_range(*PRINTABLE_ASCII_RANGE)],) * n) \ .map(lambda xs: '\n'.join(bytes(x).decode('ascii') for x in xs))
def test_list_simplicity(): # Testing internal details because this is too damn hard to hit reliably s = strategy([bool]) assert not s.strictly_simpler((), ()) assert s.strictly_simpler((), (False, )) assert not s.strictly_simpler((True, ), ()) assert s.strictly_simpler((True, ), (False, True)) assert s.strictly_simpler((False, ), (True, )) assert not s.strictly_simpler((True, ), (False, )) assert s.strictly_simpler(( False, False, ), (False, True)) assert not s.strictly_simpler((False, True), (False, True))
def run_round_trip(specifier, value, format=None, backend=None): if backend is not None: backend = backend() else: backend = SQLiteBackend() db = ExampleDatabase(format=format, backend=backend) strat = strategy(specifier) try: storage = db.storage(u'round trip') storage.save(value, strat) saved = list(storage.fetch(strat)) assert len(saved) == 1 assert strat.to_basic(saved[0]) == strat.to_basic(value) finally: db.close()
class SomeGivens(object): @given(int) def give_me_an_int(self, x): pass @given(str) def give_me_a_string(myself, x): pass @given(int) def give_me_a_positive_int(self, x): assert x >= 0 @given(strategy(int).map(lambda x: x.nope)) def fail_in_reify(self, x): pass @given(int) def assume_some_stuff(self, x): assume(x > 0) @given(strategy(int).filter(lambda x: x > 0)) def assume_in_reify(self, x): pass
def test_minimal_unsorted_strings(string): def dedupe(xs): result = [] for x in xs: if x not in result: result.append(x) return result result = minimal( strategy([string]).map(dedupe), lambda xs: assume(len(xs) >= 10) and sorted(xs) != xs) assert len(result) == 10 for example in result: if len(example) > 1: for i in hrange(len(example)): assert example[:i] in result
def some_template(spec, random=None): if random is None: random = Random() strat = strategy(spec) for _ in hrange(100): try: element = strat.draw_and_produce(random) except BadTemplateDraw: continue try: with BuildContext(): strat.reify(element) return element except UnsatisfiedAssumption: pass else: raise NoExamples(u'some_template called on strategy with no examples')
def test_minimal_unsorted_strings(string): def dedupe(xs): result = [] for x in xs: if x not in result: result.append(x) return result result = minimal( strategy([string]).map(dedupe), lambda xs: assume(len(xs) >= 10) and sorted(xs) != xs ) assert len(result) == 10 for example in result: if len(example) > 1: for i in hrange(len(example)): assert example[:i] in result
def minimal(definition, condition=None, settings=None, timeout_after=10): strat = strategy(definition) condition = condition or (lambda x: True) settings = settings or quality_settings def template_satisfies(x): t = strat.reify(x) return condition(t) @timeout(timeout_after) def run(): return best_satisfying_template( strat, Random(), template_satisfies, settings, None ) return strat.reify(run())
def dtype_strategy(dtype, settings): if dtype.kind == 'b': result = bool elif dtype.kind == 'f': result = float elif dtype.kind == 'c': result = complex elif dtype.kind in ('S', 'a', 'V'): result = binary_type elif dtype.kind == 'u': result = integers_in_range(0, 1 << (4 * dtype.itemsize) - 1) elif dtype.kind == 'i': min_integer = -1 << (4 * dtype.itemsize - 1) result = integers_in_range(min_integer, -min_integer - 1) elif dtype.kind == 'U': result = text_type else: raise NotImplementedError( 'No strategy implementation for %r' % (dtype,) ) return strategy(result, settings).map(dtype.type)
def array_strategy(specifier, settings): dtype = specifier.dtype if isinstance(dtype, (text_type, binary_type)): dtype = np.dtype(dtype) if not isinstance(dtype, np.dtype): if is_scalar(dtype): dtype = np.dtype(dtype) else: dtype = np.dtype('object') if dtype.kind != 'O': typ = dtype else: typ = specifier.dtype return ArrayStrategy( shape=specifier.shape, dtype=dtype, element_strategy=strategy(typ, settings), )
# obtain one at http://mozilla.org/MPL/2.0/. # END HEADER from __future__ import division, print_function, absolute_import, \ unicode_literals from random import Random import pytest from hypothesis import Settings, given, assume, strategy from hypothesis.database import ExampleDatabase from hypothesis.specifiers import just, floats_in_range, integers_in_range from hypothesis.searchstrategy.strategies import BuildContext ConstantLists = strategy(int).flatmap(lambda i: [just(i)]) OrderedPairs = strategy(integers_in_range( 1, 200)).flatmap(lambda e: (integers_in_range(0, e - 1), just(e))) with Settings(max_examples=200): @given(ConstantLists) def test_constant_lists_are_constant(x): assume(len(x) >= 3) assert len(set(x)) == 1 @given(OrderedPairs) def test_in_order(x): assert x[0] < x[1]