def test_consistent_decimal_error(): bad = "invalid argument to Decimal" with pytest.raises(InvalidArgument) as excinfo: decimals(bad).example() with pytest.raises(InvalidArgument) as excinfo2: with decimal.localcontext(decimal.Context(traps=[])): decimals(bad).example() assert str(excinfo.value) == str(excinfo2.value)
def test_non_reversible_decimals(): def not_reversible(xs): assume(all(x.is_finite() for x in xs)) return sum(xs) != sum(reversed(xs)) sigh = minimal(lists(decimals()), not_reversible, timeout_after=30) assert len(sigh) < 10
def _get_strategy_for_field(f): if f.choices: choices = [] for value, name_or_optgroup in f.choices: if isinstance(name_or_optgroup, (list, tuple)): choices.extend(key for key, _ in name_or_optgroup) else: choices.append(value) if isinstance(f, (dm.CharField, dm.TextField)) and f.blank: choices.insert(0, u'') strategy = st.sampled_from(choices) elif type(f) == dm.SlugField: strategy = st.text(alphabet=string.ascii_letters + string.digits, min_size=(None if f.blank else 1), max_size=f.max_length) elif type(f) == dm.GenericIPAddressField: lookup = {'both': ip4_addr_strings() | ip6_addr_strings(), 'ipv4': ip4_addr_strings(), 'ipv6': ip6_addr_strings()} strategy = lookup[f.protocol.lower()] elif type(f) in (dm.TextField, dm.CharField): strategy = st.text(min_size=(None if f.blank else 1), max_size=f.max_length) elif type(f) == dm.DecimalField: bound = Decimal(10 ** f.max_digits - 1) / (10 ** f.decimal_places) strategy = st.decimals(min_value=-bound, max_value=bound, places=f.decimal_places) else: strategy = field_mappings().get(type(f), st.nothing()) if f.validators: strategy = strategy.filter(validator_to_filter(f)) if f.null: strategy = st.one_of(st.none(), strategy) return strategy
def _get_strategy_for_field(f): # type: (Type[dm.Field]) -> st.SearchStrategy[Any] if f.choices: choices = [] # type: list for value, name_or_optgroup in f.choices: if isinstance(name_or_optgroup, (list, tuple)): choices.extend(key for key, _ in name_or_optgroup) else: choices.append(value) if isinstance(f, (dm.CharField, dm.TextField)) and f.blank: choices.insert(0, u'') strategy = st.sampled_from(choices) elif type(f) == dm.SlugField: strategy = st.text(alphabet=string.ascii_letters + string.digits, min_size=(0 if f.blank else 1), max_size=f.max_length) elif type(f) == dm.GenericIPAddressField: lookup = {'both': ip4_addr_strings() | ip6_addr_strings(), 'ipv4': ip4_addr_strings(), 'ipv6': ip6_addr_strings()} strategy = lookup[f.protocol.lower()] elif type(f) in (dm.TextField, dm.CharField): strategy = st.text( alphabet=st.characters(blacklist_characters=u'\x00', blacklist_categories=('Cs',)), min_size=(0 if f.blank else 1), max_size=f.max_length, ) # We can infer a vastly more precise strategy by considering the # validators as well as the field type. This is a minimal proof of # concept, but we intend to leverage the idea much more heavily soon. # See https://github.com/HypothesisWorks/hypothesis-python/issues/1116 re_validators = [ v for v in f.validators if isinstance(v, validators.RegexValidator) and not v.inverse_match ] if re_validators: regexes = [re.compile(v.regex, v.flags) if isinstance(v.regex, str) else v.regex for v in re_validators] # This strategy generates according to one of the regexes, and # filters using the others. It can therefore learn to generate # from the most restrictive and filter with permissive patterns. # Not maximally efficient, but it makes pathological cases rarer. # If you want a challenge: extend https://qntm.org/greenery to # compute intersections of the full Python regex language. strategy = st.one_of(*[st.from_regex(r) for r in regexes]) elif type(f) == dm.DecimalField: bound = Decimal(10 ** f.max_digits - 1) / (10 ** f.decimal_places) strategy = st.decimals(min_value=-bound, max_value=bound, places=f.decimal_places) else: strategy = field_mappings().get(type(f), st.nothing()) if f.validators: strategy = strategy.filter(validator_to_filter(f)) if f.null: strategy = st.one_of(st.none(), strategy) return strategy
def test_fuzz_decimals_bounds(data): places = data.draw(none() | integers(0, 20), label='places') finite_decs = decimals(allow_nan=False, allow_infinity=False, places=places) | none() low, high = data.draw(tuples(finite_decs, finite_decs), label='low, high') if low is not None and high is not None and low > high: low, high = high, low ctx = decimal.Context(prec=data.draw(integers(1, 100), label='precision')) try: with decimal.localcontext(ctx): strat = decimals(low, high, allow_nan=False, allow_infinity=False, places=places) val = data.draw(strat, label='value') except InvalidArgument: reject() # decimals too close for given places if low is not None: assert low <= val if high is not None: assert val <= high if places is not None: assert val.as_tuple().exponent == -places
def test_non_float_decimal(): minimal(ds.decimals(), lambda d: d.is_finite() and decimal.Decimal(float(d)) != d)
@given(ds.fractions(min_value=-1, max_value=1, max_denominator=1000)) def test_fraction_is_in_bounds(x): assert -1 <= x <= 1 and abs(x.denominator) <= 1000 @given(ds.fractions(min_value=fractions.Fraction(1, 2))) def test_fraction_gt_positive(x): assert fractions.Fraction(1, 2) <= x @given(ds.fractions(max_value=fractions.Fraction(-1, 2))) def test_fraction_lt_negative(x): assert x <= fractions.Fraction(-1, 2) @given(ds.decimals(min_value=-1.5, max_value=1.5, allow_nan=False)) def test_decimal_is_in_bounds(x): # decimal.Decimal("-1.5") == -1.5 (not explicitly testable in py2.6) assert decimal.Decimal("-1.5") <= x <= decimal.Decimal("1.5") def test_float_can_find_max_value_inf(): assert minimal(ds.floats(max_value=float("inf")), lambda x: math.isinf(x)) == float("inf") assert minimal(ds.floats(min_value=0.0), lambda x: math.isinf(x)) == float("inf") def test_float_can_find_min_value_inf(): minimal(ds.floats(), lambda x: x < 0 and math.isinf(x)) minimal(ds.floats(min_value=float("-inf"), max_value=0.0),
zpad_right( string_value_as_bytes, ceil32(len(string_value_as_bytes)), ) if string_value else b'\x00' * 32 ) ) encoded_value = encoder(string_value) assert encoded_value == expected_value @settings(max_examples=250) @given( value=st.one_of(st.integers(), st.decimals(), st.none()), value_bit_size=st.integers(min_value=1, max_value=32).map(lambda v: v * 8), frac_places=st.integers(min_value=1, max_value=80), data_byte_size=st.integers(min_value=0, max_value=32), ) @example(value=decimal.Decimal('5.33'), value_bit_size=8, frac_places=1, data_byte_size=1) def test_encode_unsigned_fixed(value, value_bit_size, frac_places, data_byte_size): if value_bit_size > data_byte_size * 8: pattern = r'Value byte size exceeds data size' with pytest.raises(ValueError, match=pattern): UnsignedFixedEncoder( value_bit_size=value_bit_size, frac_places=frac_places,
def test_decimals(): assert minimal(ds.decimals(), lambda f: f.is_finite() and f >= 1) == 1
if empty or not strategies: # pragma: no cover raise ResolutionFailed( 'Could not resolve %s to a strategy; consider using ' 'register_type_strategy' % (empty or thing,)) return st.one_of(strategies) _global_type_lookup = { # Types with core Hypothesis strategies type(None): st.none(), bool: st.booleans(), int: st.integers(), float: st.floats(), complex: st.complex_numbers(), fractions.Fraction: st.fractions(), decimal.Decimal: st.decimals(), text_type: st.text(), bytes: st.binary(), datetime.datetime: st.datetimes(), datetime.date: st.dates(), datetime.time: st.times(), datetime.timedelta: st.timedeltas(), uuid.UUID: st.uuids(), tuple: st.builds(tuple), list: st.builds(list), set: st.builds(set), frozenset: st.builds(frozenset), dict: st.builds(dict), # Built-in types type: st.sampled_from([type(None), bool, int, str, list, set, dict]), type(Ellipsis): st.just(Ellipsis),
def techproducts_id(): return st.builds(u'{}-{}-{}'.format, st.integers(min_value=0), solr_text(), st.integers(min_value=0)) @given(id=techproducts_id(), name=solr_text(), manu=solr_text(), manu_id_s=techproducts_id(), cat=solr_text(), features=solr_text(), weight=st.floats(min_value=1, max_value=100), price=st.decimals(), popularity=st.integers(min_value=1, max_value=10000), inStock=st.booleans(), store=lat_long(), manufacturedate_dt=solr_date()) def generate_documents(use_doc, **kwargs): use_doc(kwargs) def main(*args, **kwargs): run.main(generate_documents=generate_documents, *args, **kwargs) if __name__ == '__main__': main()
def test_decimals_include_nan(): find_any(decimals(), lambda x: x.is_nan())
min_value=0, max_value=2**n - 1, )) int_total_bits = st.shared(total_bits, key='int_total_bits') int_strs = int_total_bits.map('int{}'.format) int_values = int_total_bits.flatmap(lambda n: st.integers( min_value=-2**(n - 1), max_value=2**(n - 1) - 1, )) ufixed_size_tuples = st.shared(fixed_sizes, key='ufixed_size_tuples') ufixed_strs = ufixed_size_tuples.map(join_with_x).map('ufixed{}'.format) ufixed_values = ufixed_size_tuples.flatmap(lambda sz: st.decimals( min_value=0, max_value=2**sz[0] - 1, places=0, ).map(scale_places(sz[1]))) fixed_size_tuples = st.shared(fixed_sizes, key='fixed_size_tuples') fixed_strs = fixed_size_tuples.map(join_with_x).map('fixed{}'.format) fixed_values = fixed_size_tuples.flatmap(lambda sz: st.decimals( min_value=-2**(sz[0] - 1), max_value=2**(sz[0] - 1) - 1, places=0, ).map(scale_places(sz[1]))) fixed_bytes_sizes = st.shared(bytes_sizes, key='fixed_bytes_sizes') fixed_bytes_strs = fixed_bytes_sizes.map('bytes{}'.format) fixed_bytes_values = fixed_bytes_sizes.flatmap(lambda n: st.binary( min_size=n,
assert list_add(L) == list_add(reversed(L)) # Test commutativity using a property-based tests from hypothesis import given import hypothesis.strategies as st # EXERCISE 1: Test with a list of whole numbers @given(st.lists(st.integers())) def test_list_add_whole_numbers_pbt(L): assert list_add(L) == list_add(reversed(L)) # EXERCISE 2: Test with a list of real numbers (floats or decimals) @given( st.lists( st.decimals( allow_nan=False, allow_infinity=False, places=2, min_value=-999999, max_value=999999, ))) def test_list_add_real_numbers_pbt(L): assert list_add(L) == list_add(reversed(L)) # Documentation on the different strategies: # http://hypothesis.readthedocs.io/en/latest/data.html
# Copyright (C) 2013-2015 David R. MacIver ([email protected]) # This file is part of Hypothesis (https://github.com/DRMacIver/hypothesis) # This Source Code Form is subject to the terms of the Mozilla Public License, # v. 2.0. If a copy of the MPL was not distributed with this file, You can # obtain one at http://mozilla.org/MPL/2.0/. # END HEADER from __future__ import division, print_function, absolute_import, \ unicode_literals from decimal import Decimal from hypothesis import given, assume from tests.common.utils import fails from hypothesis.strategies import decimals, fractions @fails @given(decimals()) def test_all_decimals_can_be_exact_floats(x): assume(x.is_finite()) assert Decimal(float(x)) == x @given(fractions(), fractions(), fractions()) def test_fraction_addition_is_well_behaved(x, y, z): assert x + y + z == y + x + z
from datetime import timedelta from hypothesis import given from hypothesis.strategies import SearchStrategy, builds, datetimes, decimals from isoduration.formatter import format_duration from isoduration.parser import parse_duration from isoduration.types import DateDuration, Duration, TimeDuration item_st = decimals(min_value=-1_000_000_000_000, max_value=+1_000_000_000_000, places=0) seconds_st = decimals( min_value=-1_000_000_000_000, max_value=+1_000_000_000_000, places=10 ) """ Fractional numbers are only allowed by the standard in the lest significant component. It's a bit difficult to have a strategy modelling this, so we have opted to include fractional numbers just as part of the seconds component. """ date_duration_st: SearchStrategy[DateDuration] = builds( DateDuration, years=item_st, months=item_st, days=item_st ) time_duration_st: SearchStrategy[TimeDuration] = builds( TimeDuration, hours=item_st, minutes=item_st, seconds=seconds_st ) @given(date_duration=date_duration_st, time_duration=time_duration_st) def test_parse_inverse_of_format(date_duration, time_duration): duration = Duration(date_duration, time_duration) assert parse_duration(format_duration(duration)) == duration
from hypothesis import strategies as st from decimal import Decimal import datetime as dt from enum import Enum from . import _strategies as _st # Tests often want to compare for equality, and there's no good way to do this with NaNs breaking it. :-( st.register_type_strategy(Decimal, st.decimals(allow_nan=False)) st.register_type_strategy(float, st.floats(allow_nan=False)) def type_value_pairs(base): @st.composite def tv_pairs(draw): typ = draw(base) try: val = draw(st.from_type(typ)) except Exception as exc: exc.args += (typ, ) raise return (typ, val) return tv_pairs() atoms = st.sampled_from([ type(None), bool, int,
class HypothesisSpec(RuleBasedStateMachine): def __init__(self): super(HypothesisSpec, self).__init__() self.database = None strategies = Bundle(u'strategy') strategy_tuples = Bundle(u'tuples') objects = Bundle(u'objects') streaming_strategies = Bundle(u'streams') basic_data = Bundle(u'basic') varied_floats = Bundle(u'varied_floats') strats_with_parameters = Bundle(u'strats_with_parameters') strats_with_templates = Bundle(u'strats_with_templates') strats_with_2_templates = Bundle(u'strats_with_2_templates') def teardown(self): self.clear_database() @timeout(60, catchable=True) def execute_step(self, step): return super(HypothesisSpec, self).execute_step(step) @rule(target=basic_data, st=strats_with_templates) def to_basic(self, st): return st[0].to_basic(st[1]) @rule(data=basic_data, strat=strategies) def from_basic(self, data, strat): try: template = strat.from_basic(data) except BadData: return strat.reify(template) @rule(target=basic_data, data=basic_data, r=randoms()) def mess_with_basic(self, data, r): return mutate_basic(data, r) @rule() def clear_database(self): if self.database is not None: self.database.close() self.database = None @rule() def set_database(self): self.teardown() self.database = ExampleDatabase() @rule(st=strats_with_templates) def reify(self, st): strat, temp = st strat.reify(temp) @rule(target=strats_with_templates, st=strats_with_templates) def via_basic(self, st): strat, temp = st temp = strat.from_basic(strat.to_basic(temp)) return (strat, temp) @rule(targets=(strategies, streaming_strategies), strat=strategies) def build_stream(self, strat): return streaming(strat) @rule(targets=(strategies, streaming_strategies), strat=strategies, i=integers(1, 10)) def evalled_stream(self, strat, i): return streaming(strat).map(lambda x: list(x[:i]) and x) @rule(stream_strat=streaming_strategies, index=integers(0, 50)) def eval_stream(self, stream_strat, index): try: stream = stream_strat.example() list(stream[:index]) except NoExamples: pass @rule(target=strats_with_templates, st=strats_with_templates, r=randoms()) def simplify(self, st, r): strat, temp = st for temp in strat.full_simplify(r, temp): break return (strat, temp) @rule(strat=strategies, r=randoms(), mshr=integers(0, 100)) def find_constant_failure(self, strat, r, mshr): with Settings( verbosity=Verbosity.quiet, max_examples=1, min_satisfying_examples=0, database=self.database, max_shrinks=mshr, ): @given( strat, random=r, ) def test(x): assert False try: test() except AssertionError: pass @rule(strat=strategies, r=randoms(), p=floats(0, 1), mex=integers(1, 10), mshr=integers(1, 100)) def find_weird_failure(self, strat, r, mex, p, mshr): with Settings( verbosity=Verbosity.quiet, max_examples=mex, min_satisfying_examples=0, database=self.database, max_shrinks=mshr, ): @given( strat, random=r, ) def test(x): assert Random(hashlib.md5( show(x).encode(u'utf-8')).digest()).random() <= p try: test() except AssertionError: pass @rule(target=strats_with_parameters, strat=strategies, r=randoms()) def draw_parameter(self, strat, r): return (strat, strat.draw_parameter(r)) @rule(target=strats_with_templates, sp=strats_with_parameters, r=randoms()) def draw_template(self, sp, r): strat, param = sp return (strat, strat.draw_template(r, param)) @rule(target=strats_with_2_templates, sp=strats_with_parameters, r=randoms()) def draw_templates(self, sp, r): strat, param = sp return ( strat, strat.draw_template(r, param), strat.draw_template(r, param), ) @rule(st=strats_with_templates) def check_serialization(self, st): strat, template = st as_basic = strat.to_basic(template) assert show(strat.reify(template)) == show( strat.reify(strat.from_basic(as_basic))) assert as_basic == strat.to_basic(strat.from_basic(as_basic)) @rule(target=strategies, spec=sampled_from(( integers(), booleans(), floats(), complex_numbers(), fractions(), decimals(), text(), binary(), none(), StateMachineSearchStrategy(), tuples(), ))) def strategy(self, spec): return spec @rule(target=strategies, values=lists(integers() | text(), min_size=1)) def sampled_from_strategy(self, values): return sampled_from(values) @rule(target=strategies, spec=strategy_tuples) def strategy_for_tupes(self, spec): return tuples(*spec) @rule(target=strategies, source=strategies, level=integers(1, 10), mixer=text()) def filtered_strategy(s, source, level, mixer): def is_good(x): return bool( Random( hashlib.md5( (mixer + show(x)).encode(u'utf-8')).digest()).randint( 0, level)) return source.filter(is_good) @rule(target=strategies, elements=strategies) def list_strategy(self, elements): return lists(elements, average_size=AVERAGE_LIST_LENGTH) @rule(target=strategies, l=strategies, r=strategies) def or_strategy(self, l, r): return l | r @rule(target=strategies, source=strategies, result=strategies, mixer=text()) def mapped_strategy(self, source, result, mixer): cache = {} def do_map(value): rep = show(value) try: return deepcopy(cache[rep]) except KeyError: pass random = Random( hashlib.md5((mixer + rep).encode(u'utf-8')).digest()) outcome_template = result.draw_and_produce(random) cache[rep] = result.reify(outcome_template) return deepcopy(cache[rep]) return source.map(do_map) @rule(target=varied_floats, source=floats()) def float(self, source): return source @rule(target=varied_floats, source=varied_floats, offset=integers(-100, 100)) def adjust_float(self, source, offset): return int_to_float(clamp(0, float_to_int(source) + offset, 2**64 - 1)) @rule(target=strategies, left=varied_floats, right=varied_floats) 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 floats(left, right) @rule(target=strategies, source=strategies, result1=strategies, result2=strategies, mixer=text(), p=floats(0, 1)) def flatmapped_strategy(self, source, result1, result2, mixer, p): assume(result1 is not result2) def do_map(value): rep = show(value) random = Random( hashlib.md5((mixer + rep).encode(u'utf-8')).digest()) if random.random() <= p: return result1 else: return result2 return source.flatmap(do_map) @rule(target=strategies, value=objects) def just_strategy(self, value): return just(value) @rule(target=strategy_tuples, source=strategies) def single_tuple(self, source): return (source, ) @rule(target=strategy_tuples, l=strategy_tuples, r=strategy_tuples) def cat_tuples(self, l, r): return l + r @rule(target=objects, strat=strategies) def get_example(self, strat): try: strat.example() except NoExamples: # Because of filtering some strategies we look for don't actually # have any examples. pass @rule(target=strategies, left=integers(), right=integers()) def integer_range(self, left, right): left, right = sorted((left, right)) return integers(left, right) @rule(strat=strategies) def repr_is_good(self, strat): assert u' at 0x' not in repr(strat) @rule(strat=strategies) def template_upper_bound_is_valid(self, strat): ub = strat.template_upper_bound assert ub >= 0 if isinstance(ub, float): assert math.isinf(ub) else: assert isinstance(ub, int) @rule(strat=strategies, r=randoms()) def can_find_as_many_templates_as_size(self, strat, r): tempstrat = templates_for(strat) n = min(10, strat.template_upper_bound) found = [] with Settings(verbosity=Verbosity.quiet, timeout=2.0): for i in range(n): try: x = find( tempstrat, lambda t: t not in found, random=r, ) except: print(u'Exception at %d/%d. template_upper_bound=%r' % (i, n, strat.template_upper_bound)) raise found.append(x)
@given(fractions(), fractions(), fractions()) def test_fraction_addition_is_well_behaved(x, y, z): assert x + y + z == y + x + z def test_decimals_include_nan(): find_any(decimals(), lambda x: x.is_nan()) def test_decimals_include_inf(): find_any(decimals(), lambda x: x.is_infinite()) @given(decimals(allow_nan=False)) def test_decimals_can_disallow_nan(x): assert not x.is_nan() @given(decimals(allow_infinity=False)) def test_decimals_can_disallow_inf(x): assert not x.is_infinite() @pytest.mark.parametrize("places", range(10)) def test_decimals_have_correct_places(places): @given(decimals(0, 10, allow_nan=False, places=places)) def inner_tst(n): assert n.as_tuple().exponent == -places
from numpy.testing import assert_allclose def unary_func(x): return x**2 def binary_func(x, y): return x * y**2 def ternary_func(x, y, z): return z * x * y**2 @given(x=st.decimals(-100, 100)) def test_numerical_derivative(x): num_der = numerical_derivative(unary_func, x) assert np.isclose(float(num_der), float(x) * 2.) @given(st.data()) def test_numerical_gradient_no_broadcast(data): x = data.draw( hnp.arrays(shape=hnp.array_shapes(max_side=3, max_dims=3), dtype=float, elements=st.floats(-100, 100))) y = data.draw( hnp.arrays(shape=x.shape, dtype=float, elements=st.floats(-100, 100)))
class HypothesisSpec(RuleBasedStateMachine): def __init__(self): super(HypothesisSpec, self).__init__() self.database = None strategies = Bundle(u'strategy') strategy_tuples = Bundle(u'tuples') objects = Bundle(u'objects') basic_data = Bundle(u'basic') varied_floats = Bundle(u'varied_floats') def teardown(self): self.clear_database() @rule() def clear_database(self): if self.database is not None: self.database.close() self.database = None @rule() def set_database(self): self.teardown() self.database = ExampleDatabase() @rule(strat=strategies, r=integers(), max_shrinks=integers(0, 100)) def find_constant_failure(self, strat, r, max_shrinks): with settings( verbosity=Verbosity.quiet, max_examples=1, min_satisfying_examples=0, database=self.database, max_shrinks=max_shrinks, ): @given(strat) @seed(r) def test(x): assert False try: test() except (AssertionError, FailedHealthCheck): pass @rule(strat=strategies, r=integers(), p=floats(0, 1), max_examples=integers(1, 10), max_shrinks=integers(1, 100)) def find_weird_failure(self, strat, r, max_examples, p, max_shrinks): with settings( verbosity=Verbosity.quiet, max_examples=max_examples, min_satisfying_examples=0, database=self.database, max_shrinks=max_shrinks, ): @given(strat) @seed(r) def test(x): assert Random(hashlib.md5( repr(x).encode(u'utf-8')).digest()).random() <= p try: test() except (AssertionError, FailedHealthCheck): pass @rule(target=strategies, spec=sampled_from(( integers(), booleans(), floats(), complex_numbers(), fractions(), decimals(), text(), binary(), none(), tuples(), ))) def strategy(self, spec): return spec @rule(target=strategies, values=lists(integers() | text(), min_size=1)) def sampled_from_strategy(self, values): return sampled_from(values) @rule(target=strategies, spec=strategy_tuples) def strategy_for_tupes(self, spec): return tuples(*spec) @rule(target=strategies, source=strategies, level=integers(1, 10), mixer=text()) def filtered_strategy(s, source, level, mixer): def is_good(x): return bool( Random( hashlib.md5( (mixer + repr(x)).encode(u'utf-8')).digest()).randint( 0, level)) return source.filter(is_good) @rule(target=strategies, elements=strategies) def list_strategy(self, elements): return lists(elements, average_size=AVERAGE_LIST_LENGTH) @rule(target=strategies, l=strategies, r=strategies) def or_strategy(self, l, r): return l | r @rule(target=varied_floats, source=floats()) def float(self, source): return source @rule(target=varied_floats, source=varied_floats, offset=integers(-100, 100)) def adjust_float(self, source, offset): return int_to_float(clamp(0, float_to_int(source) + offset, 2**64 - 1)) @rule(target=strategies, left=varied_floats, right=varied_floats) 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 floats(left, right) @rule(target=strategies, source=strategies, result1=strategies, result2=strategies, mixer=text(), p=floats(0, 1)) def flatmapped_strategy(self, source, result1, result2, mixer, p): assume(result1 is not result2) def do_map(value): rep = repr(value) random = Random( hashlib.md5((mixer + rep).encode(u'utf-8')).digest()) if random.random() <= p: return result1 else: return result2 return source.flatmap(do_map) @rule(target=strategies, value=objects) def just_strategy(self, value): return just(value) @rule(target=strategy_tuples, source=strategies) def single_tuple(self, source): return (source, ) @rule(target=strategy_tuples, l=strategy_tuples, r=strategy_tuples) def cat_tuples(self, l, r): return l + r @rule(target=objects, strat=strategies) def get_example(self, strat): try: strat.example() except NoExamples: # Because of filtering some strategies we look for don't actually # have any examples. pass @rule(target=strategies, left=integers(), right=integers()) def integer_range(self, left, right): left, right = sorted((left, right)) return integers(left, right) @rule(strat=strategies) def repr_is_good(self, strat): assert u' at 0x' not in repr(strat)
@given(ds.fractions(min_value=-1, max_value=1, max_denominator=1000)) def test_fraction_is_in_bounds(x): assert -1 <= x <= 1 and abs(x.denominator) <= 1000 @given(ds.fractions(min_value=fractions.Fraction(1, 2))) def test_fraction_gt_positive(x): assert fractions.Fraction(1, 2) <= x @given(ds.fractions(max_value=fractions.Fraction(-1, 2))) def test_fraction_lt_negative(x): assert x <= fractions.Fraction(-1, 2) @given(ds.decimals(min_value=-1.5, max_value=1.5)) def test_decimal_is_in_bounds(x): # decimal.Decimal("-1.5") == -1.5 (not explicitly testable in py2.6) assert decimal.Decimal('-1.5') <= x <= decimal.Decimal('1.5') def test_float_can_find_max_value_inf(): assert find( ds.floats(max_value=float('inf')), lambda x: math.isinf(x) ) == float('inf') assert find( ds.floats(min_value=0.0), lambda x: math.isinf(x)) == float('inf') def test_float_can_find_min_value_inf(): find(ds.floats(), lambda x: x < 0 and math.isinf(x))
def _decimal_strategy(min_value: NumberType = None, max_value: NumberType = None, places: int = 10) -> SearchStrategy: min_value, max_value = _check_numeric_bounds("int128", min_value, max_value, Fixed) return st.decimals(min_value=min_value, max_value=max_value, places=places)
class TransactionTestCase(unittest.TestCase): @given(st.decimals(), datetimes(), st.dictionaries(keys=st.text(), values=st.uuids())) def test_get_transaction_value(self, value, timestamp, metadata): transaction = cashflow.Transaction(value, timestamp, metadata) if math.isnan(value): assert math.isnan(transaction.value) else: assert transaction.value == value @given(st.decimals(), datetimes(), st.dictionaries(keys=st.text(), values=st.uuids())) def test_get_transaction_timestamp(self, value, timestamp, metadata): transaction = cashflow.Transaction(value, timestamp, metadata) assert transaction.timestamp == timestamp @given(st.decimals(), datetimes(), st.dictionaries(keys=st.text(), values=st.uuids())) def test_get_transaction_metadata(self, value, timestamp, metadata): transaction = cashflow.Transaction(value, timestamp, metadata) assert transaction.metadata == metadata @given(st.decimals(), datetimes(), st.dictionaries(keys=st.text(), values=st.uuids())) def test_transaction_serialization(self, value, timestamp, metadata): transaction = cashflow.Transaction(value, timestamp, metadata) serialized_data = transaction.serialize() expected_data = { 'value': transaction.value, 'timestamp': transaction.timestamp, 'metadata': transaction.metadata } assert expected_data == serialized_data @given(st.decimals(), st.dictionaries(keys=st.text(), values=st.uuids())) def test_compare_two_transactions(self, value, metadata): # The difference is the timestamp... transaction1 = cashflow.Transaction( value, datetime.datetime.now(), metadata ) transaction2 = cashflow.Transaction( value, datetime.datetime.now(), metadata ) assert transaction1 == transaction1 assert transaction1 != transaction2 # Using date instead datetime to ensure different objects with the same # data will be considered as equal. transaction1 = cashflow.Transaction( value, datetime.date.today(), metadata ) transaction2 = cashflow.Transaction( value, datetime.date.today(), metadata ) assert transaction1 == transaction1 assert transaction1 == transaction2 @given(st.decimals(), datetimes(), st.dictionaries(keys=st.text(), values=st.uuids())) def test_compare_transaction_to_other_object(self, value, timestamp, metadata): # noqa transaction = cashflow.Transaction(value, timestamp, metadata) with pytest.raises(RuntimeError) as cm: transaction == 'foo bar baz' expected_message = '{!r} is not an instance of Transaction'.format( 'foo bar baz' ) assert str(cm.value) == expected_message
@given(ds.fractions(min_value=-1, max_value=1, max_denominator=1000)) def test_fraction_is_in_bounds(x): assert -1 <= x <= 1 and abs(x.denominator) <= 1000 @given(ds.fractions(min_value=fractions.Fraction(1, 2))) def test_fraction_gt_positive(x): assert fractions.Fraction(1, 2) <= x @given(ds.fractions(max_value=fractions.Fraction(-1, 2))) def test_fraction_lt_negative(x): assert x <= fractions.Fraction(-1, 2) @given(ds.decimals(min_value=-1.5, max_value=1.5)) def test_decimal_is_in_bounds(x): assert decimal.Decimal("-1.5") <= x <= decimal.Decimal("1.5") def test_float_can_find_max_value_inf(): assert minimal(ds.floats(max_value=math.inf), lambda x: math.isinf(x)) == float( "inf" ) assert minimal(ds.floats(min_value=0.0), lambda x: math.isinf(x)) == math.inf def test_float_can_find_min_value_inf(): minimal(ds.floats(), lambda x: x < 0 and math.isinf(x)) minimal(ds.floats(min_value=-math.inf, max_value=0.0), lambda x: math.isinf(x))
floats(), floats(min_value=-2.0), floats(), floats(max_value=-0.0), floats(), floats(min_value=0.0), floats(min_value=3.14, max_value=3.14), text(), binary(), booleans(), tuples(booleans(), booleans()), frozensets(integers()), sets(frozensets(booleans())), complex_numbers(), fractions(), decimals(), lists(lists(booleans())), lists(lists(booleans(), average_size=100)), lists(floats(0.0, 0.0), average_size=1.0), ordered_pair, constant_list(integers()), streaming(integers()).map(lambda x: list(x[:2]) and x), integers().filter(lambda x: abs(x) > 100), floats(min_value=-sys.float_info.max, max_value=sys.float_info.max), none(), randoms(), tuples().flatmap(lambda x: EvalledIntStream), templates_for(integers(min_value=0, max_value=0).flatmap(lambda x: integers(min_value=0, max_value=0))), booleans().flatmap(lambda x: booleans() if x else complex_numbers()), recursive(base=booleans(), extend=lambda x: lists(x, max_size=3), max_leaves=10), ]
string_value_as_bytes = codecs.encode(string_value, 'utf8') expected_value = (encode_uint_256(len(string_value_as_bytes)) + (zpad_right( string_value_as_bytes, ceil32(len(string_value_as_bytes)), ) if string_value else b'')) encoded_value = encoder(string_value) assert encoded_value == expected_value @settings(max_examples=250) @given( value=st.one_of(st.integers(), st.decimals(), st.none()), value_bit_size=st.integers(min_value=1, max_value=32).map(lambda v: v * 8), frac_places=st.integers(min_value=1, max_value=80), data_byte_size=st.integers(min_value=0, max_value=32), ) @example(value=decimal.Decimal('5.33'), value_bit_size=8, frac_places=1, data_byte_size=1) def test_encode_unsigned_fixed(value, value_bit_size, frac_places, data_byte_size): if value_bit_size > data_byte_size * 8: pattern = r'Value byte size exceeds data size' with pytest.raises(ValueError, match=pattern): UnsignedFixedEncoder( value_bit_size=value_bit_size,
# # Most of this work is copyright (C) 2013-2015 David R. MacIver # ([email protected]), but it contains contributions by others. See # https://github.com/DRMacIver/hypothesis/blob/master/CONTRIBUTING.rst for a # full list of people who may hold copyright, and consult the git log if you # need to determine who owns an individual contribution. # # This Source Code Form is subject to the terms of the Mozilla Public License, # v. 2.0. If a copy of the MPL was not distributed with this file, You can # obtain one at http://mozilla.org/MPL/2.0/. # # END HEADER from __future__ import division, print_function, absolute_import from hypothesis import given, assume from tests.common.utils import fails from hypothesis.strategies import decimals, fractions, float_to_decimal @fails @given(decimals()) def test_all_decimals_can_be_exact_floats(x): assume(x.is_finite()) assert float_to_decimal(float(x)) == x @given(fractions(), fractions(), fractions()) def test_fraction_addition_is_well_behaved(x, y, z): assert x + y + z == y + x + z
@given(fractions(), fractions(), fractions()) def test_fraction_addition_is_well_behaved(x, y, z): assert x + y + z == y + x + z def test_decimals_include_nan(): find_any(decimals(), lambda x: x.is_nan()) def test_decimals_include_inf(): find_any(decimals(), lambda x: x.is_infinite()) @given(decimals(allow_nan=False)) def test_decimals_can_disallow_nan(x): assert not x.is_nan() @given(decimals(allow_infinity=False)) def test_decimals_can_disallow_inf(x): assert not x.is_infinite() @pytest.mark.parametrize('places', range(10)) def test_decimals_have_correct_places(places): @given(decimals(0, 10, allow_nan=False, places=places)) def inner_tst(n): assert n.as_tuple().exponent == -places inner_tst()
raise ResolutionFailed( "Could not resolve %s to a strategy; consider using " "register_type_strategy" % (empty or thing,) ) return st.one_of(strategies) _global_type_lookup = { # Types with core Hypothesis strategies type(None): st.none(), bool: st.booleans(), int: st.integers(), float: st.floats(), complex: st.complex_numbers(), fractions.Fraction: st.fractions(), decimal.Decimal: st.decimals(), text_type: st.text(), binary_type: st.binary(), datetime.datetime: st.datetimes(), datetime.date: st.dates(), datetime.time: st.times(), datetime.timedelta: st.timedeltas(), uuid.UUID: st.uuids(), tuple: st.builds(tuple), list: st.builds(list), set: st.builds(set), frozenset: st.builds(frozenset), dict: st.builds(dict), type(lambda: None): st.functions(), # Built-in types type(Ellipsis): st.just(Ellipsis),
one_of(integers(), tuples(booleans())), sampled_from(range(10)), one_of(just('a'), just('b'), just('c')), sampled_from(('a', 'b', 'c')), integers(), integers(min_value=3), integers(min_value=(-2 ** 32), max_value=(2 ** 64)), floats(), floats(min_value=-2.0, max_value=3.0), floats(min_value=3.14, max_value=3.14), text(), binary(), booleans(), tuples(booleans(), booleans()), frozensets(integers()), complex_numbers(), fractions(), decimals(), lists(lists(booleans())), lists(lists(booleans(), average_size=100)), lists(floats(0.0, 0.0), average_size=1.0), ordered_pair, constant_list(integers()), streaming(integers()).map(lambda x: list(x[:2]) and x), integers().filter(lambda x: abs(x) > 100), floats(min_value=-sys.float_info.max, max_value=sys.float_info.max), none(), randoms(), tuples().flatmap(lambda x: EvalledIntStream), templates_for(integers(min_value=0, max_value=0).flatmap( lambda x: integers(min_value=0, max_value=0))), booleans().flatmap(lambda x: booleans() if x else complex_numbers()), ]
@given(fractions(), fractions(), fractions()) def test_fraction_addition_is_well_behaved(x, y, z): assert x + y + z == y + x + z def test_decimals_include_nan(): find_any(decimals(), lambda x: x.is_nan()) def test_decimals_include_inf(): find_any(decimals(), lambda x: x.is_infinite(), settings(max_examples=10**6)) @given(decimals(allow_nan=False)) def test_decimals_can_disallow_nan(x): assert not x.is_nan() @given(decimals(allow_infinity=False)) def test_decimals_can_disallow_inf(x): assert not x.is_infinite() @pytest.mark.parametrize("places", range(10)) def test_decimals_have_correct_places(places): @given(decimals(0, 10, allow_nan=False, places=places)) def inner_tst(n): assert n.as_tuple().exponent == -places
def _for_decimal(field): bound = Decimal(10**field.max_digits - 1) / (10**field.decimal_places) return st.decimals(min_value=-bound, max_value=bound, places=field.decimal_places)
def test_all_decimals_can_be_exact_floats(): find_any( decimals(), lambda x: assume(x.is_finite()) and decimal.Decimal(float(x)) == x)
def test_decimals_have_correct_places(places): @given(decimals(0, 10, allow_nan=False, places=places)) def inner_tst(n): assert n.as_tuple().exponent == -places inner_tst()
def test_all_decimals_can_be_exact_floats(): find_any( decimals(), lambda x: assume(x.is_finite()) and decimal.Decimal(float(x)) == x )
encsiopacket, ) import tests # pylint: disable=unused-import #---- Constants ---------------------------------------------------------- __all__ = () _LOGGER = logging.getLogger(__name__) # We keep out NaN because NaN == NaN is False, which frustrates our # comparisons of deep JSON-ified objects; also, we don't allow numbers or # nulls in the top level because the Socket.IO packet encoding does not # contemplate such things (of course we needed another data encoding # format, didn't we?) _JSON_CHILDREN = strategies.recursive(strategies.decimals().filter(lambda x: not x.is_nan()) | strategies.booleans() | strategies.text() | strategies.none(), lambda children: strategies.lists(children) | strategies.dictionaries(strategies.text(), children), max_leaves=5) _JSON = strategies.one_of(strategies.booleans(), strategies.text(), strategies.lists(_JSON_CHILDREN), strategies.dictionaries(strategies.text(), _JSON_CHILDREN)) #---- Classes ------------------------------------------------------------ #========================================================================= class PacketsTestCase(t_unittest.TestCase): longMessage = True #---- Public constants ----------------------------------------------- BAD_TRUNC_PACKET = '' BAD_TYPE = bytes(b'\x2a') BAD_TYPE_STR_PACKET = BAD_TYPE.decode('latin_1') BAD_PACKET_STR_BIN_ACK = SIO_TYPE_BIN_ACK.decode('utf_8')
def test_decimals_include_inf(): find_any(decimals(), lambda x: x.is_infinite())
def test_non_float_decimal(): find( ds.decimals(), lambda d: d.is_finite() and float_to_decimal(float(d)) != d)
# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the # source code or documentation are not subject to the GNU General Public # License and may only be used or replicated with the express permission of # Red Hat, Inc. # # Red Hat Author(s): Anne Mulhern <*****@*****.**> """ Utilities for testing. """ from hypothesis import strategies from justbytes import Size from justbytes import UNITS NUMBERS_STRATEGY = strategies.one_of( strategies.integers(), strategies.fractions(), strategies.decimals().filter(lambda x: x.is_finite()), ) SIZE_STRATEGY = strategies.builds( Size, strategies.one_of( NUMBERS_STRATEGY, strategies.builds( str, NUMBERS_STRATEGY ) ), strategies.sampled_from(UNITS()) )
def test_non_float_decimal(): find(ds.decimals(), lambda d: ds.float_to_decimal(float(d)) != d)
def test_decimals_include_inf(): find_any(decimals(), lambda x: x.is_infinite(), settings(max_examples=10**6))
TestNestedSets = strategy_test_suite( frozensets(frozensets(integers(), max_size=2))) TestMisc1 = strategy_test_suite( fixed_dictionaries({(2, -374): frozensets(none())})) TestMisc2 = strategy_test_suite( fixed_dictionaries({b'': frozensets(integers())})) TestMisc3 = strategy_test_suite(tuples(sets(none() | text()))) TestEmptyTuple = strategy_test_suite(tuples()) TestEmptyList = strategy_test_suite(lists(max_size=0)) TestEmptySet = strategy_test_suite(sets(max_size=0)) TestEmptyFrozenSet = strategy_test_suite(frozensets(max_size=0)) TestEmptyDict = strategy_test_suite(fixed_dictionaries({})) TestDecimal = strategy_test_suite(decimals()) TestFraction = strategy_test_suite(fractions()) TestNonEmptyLists = strategy_test_suite(lists(integers()).filter(bool)) TestNoneLists = strategy_test_suite(lists(none())) TestConstantLists = strategy_test_suite( integers().flatmap(lambda i: lists(just(i)))) TestListsWithUniqueness = strategy_test_suite( lists(lists(integers()), unique_by=lambda x: tuple(sorted(x)))) TestOrderedPairs = strategy_test_suite( integers(min_value=1, max_value=200).flatmap( lambda e: tuples(integers(min_value=0, max_value=e - 1), just(e))))
def define_decimal_strategy(specifier, settings): return st.decimals()
def _for_decimal(field): bound = Decimal(10 ** field.max_digits - 1) / (10 ** field.decimal_places) return st.decimals(min_value=-bound, max_value=bound, places=field.decimal_places)
# v. 2.0. If a copy of the MPL was not distributed with this file, You can # obtain one at http://mozilla.org/MPL/2.0/. # # END HEADER from __future__ import division, print_function, absolute_import import math from hypothesis import given, assume from tests.common.utils import fails, fails_with from hypothesis.strategies import decimals, fractions, float_to_decimal @fails @given(decimals()) def test_all_decimals_can_be_exact_floats(x): assume(x.is_finite()) assert float_to_decimal(float(x)) == x @given(fractions(), fractions(), fractions()) def test_fraction_addition_is_well_behaved(x, y, z): assert x + y + z == y + x + z @fails_with(AssertionError) @given(decimals()) def test_decimals_include_nan(x): assert not math.isnan(x)
TestNestedSets = strategy_test_suite( frozensets(frozensets(integers(), max_size=2))) TestMisc1 = strategy_test_suite(fixed_dictionaries( {(2, -374): frozensets(none())})) TestMisc2 = strategy_test_suite(fixed_dictionaries( {b'': frozensets(integers())})) TestMisc3 = strategy_test_suite(tuples(sets(none() | text()))) TestEmptyTuple = strategy_test_suite(tuples()) TestEmptyList = strategy_test_suite(lists(max_size=0)) TestEmptySet = strategy_test_suite(sets(max_size=0)) TestEmptyFrozenSet = strategy_test_suite(frozensets(max_size=0)) TestEmptyDict = strategy_test_suite(fixed_dictionaries({})) TestDecimal = strategy_test_suite(decimals()) TestFraction = strategy_test_suite(fractions()) TestNonEmptyLists = strategy_test_suite( lists(integers(), average_size=5.0).filter(bool) ) TestNoneLists = strategy_test_suite(lists(none(), average_size=5.0)) TestConstantLists = strategy_test_suite( integers().flatmap(lambda i: lists(just(i), average_size=5.0)) ) TestListsWithUniqueness = strategy_test_suite( lists( lists(integers(), average_size=5.0),
jsontype = hs.sampled_from([ "null", "boolean", "number", "integer", "string", "array", "object", ]) jsontypes = hs.lists(jsontype, unique=True) jsonnull = hs.none() jsonboolean = hs.booleans() jsonnumber = hs.integers() | \ hs.floats(allow_nan=False, allow_infinity=False) | \ hs.decimals(allow_nan=False, allow_infinity=False) jsonnumber_nodecimal = hs.integers() | \ hs.floats(allow_nan=False, allow_infinity=False) jsoninteger = hs.integers() jsonstring = hs.text() jsonleaf = jsonnull | jsonboolean | jsonnumber | jsonstring jsonleaf_nodecimal = jsonnull | jsonboolean | jsonnumber_nodecimal | jsonstring json = hs.recursive( base=jsonleaf, extend=lambda children: hs.lists(children) | hs.dictionaries( jsonstring, children), max_leaves=10, ) json_nodecimal = hs.recursive( base=jsonleaf_nodecimal,
def scale_places(places): """ Scaling must happen with adequate precision. Otherwise, we get bounds checking errors. """ def f(x): with decimal.localcontext(abi_decimal_context): return x / 10 ** places return f ufixed_size_tuples = st.shared(fixed_sizes, key='ufixed_size_tuples') ufixed_strs = ufixed_size_tuples.map(join_with_x).map('ufixed{}'.format) ufixed_values = ufixed_size_tuples.flatmap(lambda sz: st.decimals( min_value=0, max_value=2 ** sz[0] - 1, places=0, ).map(scale_places(sz[1]))) fixed_size_tuples = st.shared(fixed_sizes, key='fixed_size_tuples') fixed_strs = fixed_size_tuples.map(join_with_x).map('fixed{}'.format) fixed_values = fixed_size_tuples.flatmap(lambda sz: st.decimals( min_value=-2 ** (sz[0] - 1), max_value=2 ** (sz[0] - 1) - 1, places=0, ).map(scale_places(sz[1]))) fixed_bytes_sizes = st.shared(bytes_sizes, key='fixed_bytes_sizes') fixed_bytes_strs = fixed_bytes_sizes.map('bytes{}'.format) fixed_bytes_values = fixed_bytes_sizes.flatmap(lambda n: st.binary( min_size=n,
class UtilsTestCase(TestCase): @classmethod def setUpTestData(cls): cls.factory = RequestFactory() def test_get_client_ip(self): request = self.factory.get('/some/route', REMOTE_ADDR="1.2.3.4") self.assertEqual(get_client_ip(request), "1.2.3.4") # communicate with perma payments @patch('perma.utils.encrypt_for_perma_payments', autospec=True) @patch('perma.utils.stringify_data', autospec=True) def test_prep_for_perma_payments(self, stringify, encrypt): stringify.return_value = sentinel.stringified encrypt.return_value = sentinel.encrypted assert prep_for_perma_payments({}) == sentinel.encrypted stringify.assert_called_once_with({}) encrypt.assert_called_once_with(sentinel.stringified) def test_process_perma_payments_transmission_encrypted_data_not_in_post(self): with self.assertRaises(InvalidTransmissionException) as excinfo: assert process_perma_payments_transmission({}, []) assert 'No encrypted_data in POST.' in str(excinfo.exception) def test_process_perma_payments_transmission_encrypted_data_none(self): with self.assertRaises(InvalidTransmissionException) as excinfo: assert process_perma_payments_transmission({'encrypted_data': None}, []) assert 'No encrypted_data in POST.' in str(excinfo.exception) def test_process_perma_payments_transmission_encrypted_data_empty(self): with self.assertRaises(InvalidTransmissionException) as excinfo: assert process_perma_payments_transmission({'encrypted_data': ''}, []) assert 'No encrypted_data in POST.' in str(excinfo.exception) @patch('perma.utils.decrypt_from_perma_payments', autospec=True) def test_process_perma_payments_transmission_encryption_problem(self, decrypt): decrypt.side_effect = SentinelException with self.assertRaises(InvalidTransmissionException) as excinfo: process_perma_payments_transmission(spoof_perma_payments_post(), []) assert 'SentinelException' in str(excinfo.exception) assert decrypt.call_count == 1 @patch('perma.utils.unstringify_data', autospec=True) @patch('perma.utils.decrypt_from_perma_payments', autospec=True) def test_process_perma_payments_transmission_not_valid_json(self, decrypt, unstringify): unstringify.side_effect = SentinelException with self.assertRaises(InvalidTransmissionException) as excinfo: process_perma_payments_transmission(spoof_perma_payments_post(), []) assert 'SentinelException' in str(excinfo.exception) assert unstringify.call_count == 1 @patch('perma.utils.unstringify_data', autospec=True) @patch('perma.utils.decrypt_from_perma_payments', autospec=True) def test_process_perma_payments_transmission_missing_timestamp(self, decrypt, unstringify): post = spoof_perma_payments_post() del post['encrypted_data']['timestamp'] unstringify.return_value = post['encrypted_data'] with self.assertRaises(InvalidTransmissionException) as excinfo: process_perma_payments_transmission(post, []) assert 'Missing timestamp in data.' in str(excinfo.exception) @patch('perma.utils.is_valid_timestamp', autospec=True) @patch('perma.utils.unstringify_data', autospec=True) @patch('perma.utils.decrypt_from_perma_payments', autospec=True) def test_process_perma_payments_transmission_expired_timestamp(self, decrypt, unstringify, timestamp): post = spoof_perma_payments_post() unstringify_data.return_value = post['encrypted_data'] timestamp.return_value = False with self.assertRaises(InvalidTransmissionException) as excinfo: process_perma_payments_transmission(post, []) assert 'Expired timestamp in data.' in str(excinfo.exception) @patch('perma.utils.is_valid_timestamp', autospec=True) @patch('perma.utils.unstringify_data', autospec=True) @patch('perma.utils.decrypt_from_perma_payments', autospec=True) def test_process_perma_payments_transmission_happy_path(self, decrypt, unstringify, timestamp): post = spoof_perma_payments_post() decrypt.return_value = sentinel.decrypted unstringify.return_value = post['encrypted_data'] timestamp.return_value = True assert process_perma_payments_transmission(post, ['desired_field']) == {'desired_field': 'desired_field'} decrypt.assert_called_once_with(post['encrypted_data']) unstringify.assert_called_once_with(sentinel.decrypted) timestamp.assert_called_once_with(post['encrypted_data']['timestamp'], settings.PERMA_PAYMENTS_TIMESTAMP_MAX_AGE_SECONDS) # perma-payments helpers def test_retrieve_fields_returns_only_specified_fields(self): one_two_three = one_two_three_dict() assert retrieve_fields(one_two_three, ['one']) == {'one': 'one'} assert retrieve_fields(one_two_three, ['two']) == {'two': 'two'} assert retrieve_fields(one_two_three, ['one', 'three']) == {'one': 'one', 'three': 'three'} def test_retrieve_fields_raises_if_field_absent(self): one_two_three = one_two_three_dict() with self.assertRaises(InvalidTransmissionException): retrieve_fields(one_two_three, ['four']) def test_is_valid_timestamp(self): max_age = 60 now = datetime.utcnow().timestamp() still_valid = (datetime.utcnow() + timedelta(seconds=max_age)).timestamp() invalid = (datetime.utcnow() + timedelta(seconds=max_age * 2)).timestamp() self.assertTrue(is_valid_timestamp(now, max_age)) self.assertTrue(is_valid_timestamp(still_valid, max_age)) self.assertFalse(is_valid_timestamp(invalid, max_age)) preserved = text(alphabet=characters(min_codepoint=1, blacklist_categories=('Cc', 'Cs'))) | integers() | booleans() @given(preserved | dictionaries(keys=text(alphabet=characters(min_codepoint=1, blacklist_categories=('Cc', 'Cs'))), values=preserved)) def test_stringify_and_unstringify_data_types_preserved(self, data): assert unstringify_data(stringify_data(data)) == data oneway = decimals(places=2, min_value=decimal.Decimal(0.00), allow_nan=False, allow_infinity=False) | datetimes() | dates() | uuids() @given(oneway | dictionaries(keys=text(alphabet=characters(min_codepoint=1, blacklist_categories=('Cc', 'Cs'))), values=oneway)) def test_stringify_types_lost(self, data): # Some types can be serialized, but not recovered from strings by json.loads. # Instead, you have to manually attempt to convert, by field, if you are expecting one of these types. # # If something can't be serialized, or unserialized, # this test will raise an Exception, rather than failing with an assertion error. unstringify_data(stringify_data(data)) @given(binary()) def test_perma_payments_encrypt_and_decrypt(self, b): ci = encrypt_for_perma_payments(b) assert decrypt_from_perma_payments(ci) == b
@given(ds.fractions(min_value=-1, max_value=1, max_denominator=1000)) def test_fraction_is_in_bounds(x): assert -1 <= x <= 1 and abs(x.denominator) <= 1000 @given(ds.fractions(min_value=fractions.Fraction(1, 2))) def test_fraction_gt_positive(x): assert fractions.Fraction(1, 2) <= x @given(ds.fractions(max_value=fractions.Fraction(-1, 2))) def test_fraction_lt_negative(x): assert x <= fractions.Fraction(-1, 2) @given(ds.decimals(min_value=-1.5, max_value=1.5, allow_nan=False)) def test_decimal_is_in_bounds(x): # decimal.Decimal("-1.5") == -1.5 (not explicitly testable in py2.6) assert decimal.Decimal("-1.5") <= x <= decimal.Decimal("1.5") def test_float_can_find_max_value_inf(): assert minimal(ds.floats(max_value=float("inf")), lambda x: math.isinf(x)) == float( "inf" ) assert minimal(ds.floats(min_value=0.0), lambda x: math.isinf(x)) == float("inf") def test_float_can_find_min_value_inf(): minimal(ds.floats(), lambda x: x < 0 and math.isinf(x)) minimal(ds.floats(min_value=float("-inf"), max_value=0.0), lambda x: math.isinf(x))
assert Integer(z).num == z @given(st.floats(allow_nan=False, allow_infinity=False)) def test_init_non_nan_non_inf_float(z): assert Integer(z).num == int(z) @given(st.just(float("nan"))) def test_init_nan_float_raises_value_error(z): with pt.raises(ValueError): Integer(z) @given(st.decimals(allow_nan=False, allow_infinity=False)) def test_init_non_nan_non_inf_decimal(z): assert Integer(z).num == int(z) @given(st.just(Decimal("nan"))) def test_init_nan_decimal_raises_value_error(z): with pt.raises(ValueError): Integer(z) @given(st.text(alphabet=string.digits, min_size=1)) def test_init_numeric_string(z): assert Integer(z).num == int(z)
"min_size": st.integers(min_value=0, max_value=100), "max_size": st.integers(min_value=0, max_value=100) | st.none(), } values = st.integers() | st.text() Strategies = st.recursive( st.one_of( st.sampled_from([ st.none(), st.booleans(), st.randoms(use_true_random=True), st.complex_numbers(), st.randoms(use_true_random=True), st.fractions(), st.decimals(), ]), st.builds(st.just, values), st.builds(st.sampled_from, st.lists(values, min_size=1)), builds_ignoring_invalid(st.floats, st.floats(), st.floats()), ), lambda x: st.one_of( builds_ignoring_invalid(st.lists, x, **size_strategies), builds_ignoring_invalid(st.sets, x, **size_strategies), builds_ignoring_invalid(lambda v: st.tuples(*v), st.lists(x)), builds_ignoring_invalid(lambda v: st.one_of(*v), st.lists(x, min_size=1)), builds_ignoring_invalid( st.dictionaries, x, x,
size_strategies = dict( min_size=st.integers(min_value=0, max_value=100) | st.none(), max_size=st.integers(min_value=0, max_value=100) | st.none(), average_size=st.floats(min_value=0.0, max_value=100.0) | st.none() ) values = st.integers() | st.text(average_size=2.0) Strategies = st.recursive( st.one_of( st.sampled_from([ st.none(), st.booleans(), st.randoms(), st.complex_numbers(), st.randoms(), st.fractions(), st.decimals(), ]), st.builds(st.just, values), st.builds(st.sampled_from, st.lists(values, min_size=1)), builds_ignoring_invalid(st.floats, st.floats(), st.floats()), ), lambda x: st.one_of( builds_ignoring_invalid(st.lists, x, **size_strategies), builds_ignoring_invalid(st.sets, x, **size_strategies), builds_ignoring_invalid( lambda v: st.tuples(*v), st.lists(x, average_size=2.0)), builds_ignoring_invalid( lambda v: st.one_of(*v), st.lists(x, average_size=2.0, min_size=1)), builds_ignoring_invalid( st.dictionaries, x, x,
import pytest from hypothesis import given, settings from hypothesis import strategies as st from vyper import ast as vy_ast from vyper import functions as vy_fn denoms = [x for k in vy_fn.AsWeiValue.wei_denoms.keys() for x in k] st_decimals = st.decimals( min_value=0, max_value=2 ** 32, allow_nan=False, allow_infinity=False, places=10, ) @pytest.mark.fuzzing @settings(max_examples=10, deadline=1000) @given(value=st_decimals) @pytest.mark.parametrize("denom", denoms) def test_decimal(get_contract, value, denom): source = f""" @external def foo(a: decimal) -> uint256: return as_wei_value(a, '{denom}') """ contract = get_contract(source) vyper_ast = vy_ast.parse_to_ast(f"as_wei_value({value:.10f}, '{denom}')") old_node = vyper_ast.body[0].value new_node = vy_fn.AsWeiValue().evaluate(old_node)