def test_coin_biased_towards_falsehood(): p = 1.0 / 500 for i in range(255): if i != 1: assert not cu.biased_coin(ConjectureData.for_buffer([0, i, 0, 1]), p) assert cu.biased_coin(ConjectureData.for_buffer([0, 1, 0, 0]), p)
def test_coin_biased_towards_truth(): p = 1 - 1.0 / 500 for i in range(1, 255): assert cu.biased_coin(ConjectureData.for_buffer([0, i, 0, 0]), p) assert not cu.biased_coin(ConjectureData.for_buffer([0, 0, 0, 1]), p)
def test_coin_biased_towards_falsehood(): p = 1.0 / 500 for i in range(255): assert not cu.biased_coin(ConjectureData.for_buffer([i]), p) second_order = [ cu.biased_coin(ConjectureData.for_buffer([255, i]), p) for i in range(255) ] assert False in second_order assert True in second_order
def run(self, state_machine, print_steps=None): if print_steps is None: print_steps = current_verbosity() >= Verbosity.debug self.data.hypothesis_runner = state_machine stopping_value = 1 - 1.0 / (1 + self.n_steps * 0.5) try: steps = 0 while True: if steps == self.n_steps: stopping_value = 0 self.data.start_example() if not cu.biased_coin(self.data, stopping_value): self.data.stop_example() break value = self.data.draw(state_machine.steps()) steps += 1 if steps <= self.n_steps: if print_steps: state_machine.print_step(value) state_machine.execute_step(value) self.data.stop_example() finally: state_machine.teardown()
def do_draw(self, data): seen = set() result = [] if self.max_size == self.min_size: while len(result) < self.max_size: v = data.draw(self.element_strategy) k = self.key(v) if k not in seen: result.append(v) seen.add(k) return result stopping_value = 1 - 1.0 / (1 + self.average_size) duplicates = 0 while len(result) < self.max_size: data.start_example() if len(result) >= self.min_size: more = cu.biased_coin(data, stopping_value) else: more = True if not more: data.stop_example() break value = data.draw(self.element_strategy) data.stop_example() k = self.key(value) if k in seen: duplicates += 1 assume(duplicates <= len(result)) continue seen.add(k) result.append(value) assume(len(result) >= self.min_size) return result
def run(self, state_machine, print_steps=None): if print_steps is None: print_steps = current_verbosity() >= Verbosity.debug self.data.hypothesis_runner = state_machine stopping_value = 1 - 1.0 / (1 + self.n_steps * 0.5) try: state_machine.check_invariants() steps = 0 while True: if steps >= self.n_steps: stopping_value = 0 self.data.start_example() if not cu.biased_coin(self.data, stopping_value): self.data.stop_example() break assert steps < self.n_steps value = self.data.draw(state_machine.steps()) steps += 1 if print_steps: state_machine.print_step(value) state_machine.execute_step(value) self.data.stop_example() state_machine.check_invariants() finally: state_machine.teardown()
def is_enabled(self, name): """Tests whether the feature named ``name`` should be enabled on this test run.""" if self.__data is None or self.__data.frozen: # Feature set objects might hang around after data generation has # finished. If this happens then we just report all new features as # enabled, because that's our shrinking direction and they have no # impact on data generation if they weren't used while it was # running. return not self.__is_disabled.get(name, False) data = self.__data data.start_example(label=FEATURE_LABEL) # If we've already decided on this feature then we don't actually # need to draw anything, but we do write the same decision to the # input stream. This allows us to lazily decide whether a feature # is enabled, because it means that if we happen to delete the part # of the test case where we originally decided, the next point at # which we make this decision just makes the decision it previously # made. is_disabled = cu.biased_coin( self.__data, self.__p_disabled, forced=self.__is_disabled.get(name) ) self.__is_disabled[name] = is_disabled data.stop_example() return not is_disabled
def test_unbiased_coin_has_no_second_order(): flips = [ cu.biased_coin(ConjectureData.for_buffer([i]), 0.5) for i in range(256) ] counts = Counter(flips) assert counts[True] == counts[False] == 128
def test_drawing_an_exact_fraction_coin(): count = 0 total = 0 p = Fraction(3, 8) for i in range(4): for j in range(4): total += 1 if cu.biased_coin(ConjectureData.for_buffer([i, j, 0]), p): count += 1 assert p == Fraction(count, total)
def test_unbiased_coin_has_no_second_order(): counts = Counter() for i in range(256): buf = hbytes([i]) data = ConjectureData.for_buffer(buf) result = cu.biased_coin(data, 0.5) if data.buffer == buf: counts[result] += 1 assert counts[False] == counts[True] > 0
def do_draw(self, data): if len(self.intervals) > 256: if biased_coin(data, 0.2): i = integer_range(data, 256, len(self.intervals) - 1) else: i = integer_range(data, 0, 255) else: i = integer_range(data, 0, len(self.intervals) - 1) i = self.rewrite_integer(i) return chr(self.intervals[i])
def do_draw(self, data): if cu.biased_coin(data, self.__p): return data.draw(self) + data.draw(self) else: # We draw n as two separate calls so that it doesn't show up as a # single block. If it did, the heuristics that allow us to move # blocks around would fire and it would move right, which would # then allow us to shrink it more easily. n = (data.draw_bits(16) << 16) | data.draw_bits(16) if n == MAX_INT: return (POISON,) else: return (None,)
def do_draw(self, data): if cu.biased_coin(data, self.__p): return data.draw(self) + data.draw(self) else: # We draw n as two separate calls so that it doesn't show up as a # single block. If it did, the heuristics that allow us to move # blocks around would fire and it would move right, which would # then allow us to shrink it more easily. n = (data.draw_bits(16) << 16) | data.draw_bits(16) if n == MAX_INT: return (POISON, ) else: return (None, )
def do_draw(self, data): if self.max_size == self.min_size: return [ data.draw(self.element_strategy) for _ in range(self.min_size) ] stopping_value = 1 - 1.0 / (1 + self.average_length) result = [] while True: data.start_example() more = cu.biased_coin(data, stopping_value) value = data.draw(self.element_strategy) data.stop_example() if not more: if len(result) < self.min_size: continue else: break result.append(value) if self.max_size < float('inf'): result = result[:self.max_size] return result
def do_draw(self, data): if self.max_size == self.min_size: return [ data.draw(self.element_strategy) for _ in range(self.min_size) ] stopping_value = 1 - 1.0 / (1 + self.average_length) result = [] while len(result) < self.max_size: data.start_example() more = cu.biased_coin(data, stopping_value) if not more: data.stop_example() if len(result) < self.min_size: continue else: break value = data.draw(self.element_strategy) data.stop_example() result.append(value) else: cu.write(data, TERMINATOR) return result
def run(self, state_machine, print_steps=None): if print_steps is None: print_steps = current_verbosity() >= Verbosity.debug stopping_value = 1 - 1.0 / (1 + self.n_steps * 0.5) try: steps = 0 while True: if steps == self.n_steps: stopping_value = 0 self.data.start_example() if not cu.biased_coin(self.data, stopping_value): self.data.stop_example() break value = self.data.draw(state_machine.steps()) steps += 1 if steps <= self.n_steps: if print_steps: state_machine.print_step(value) state_machine.execute_step(value) self.data.stop_example() finally: state_machine.teardown()
def test_drawing_an_exact_fraction_coin(): count = 0 for i in hrange(8): if cu.biased_coin(ConjectureData.for_buffer([i]), Fraction(3, 8)): count += 1 assert count == 3
def test_drawing_impossible_coin_still_writes(): data = ConjectureData.for_buffer([1, 0]) assert not data.buffer assert not cu.biased_coin(data, 0) assert data.buffer
def test_drawing_certain_coin_still_writes(): data = ConjectureData.for_buffer([0, 1]) assert not data.buffer assert cu.biased_coin(data, 1) assert data.buffer
def _draw_loop_dimensions(self, data, use=None): # All shapes are handled in column-major order; i.e. they are reversed base_shape = self.base_shape[::-1] result_shape = list(base_shape) shapes = [[] for _ in range(self.num_shapes)] if use is None: use = [True for _ in range(self.num_shapes)] else: assert len(use) == self.num_shapes assert all(isinstance(x, bool) for x in use) for dim_count in range(1, self.max_dims + 1): dim = dim_count - 1 # We begin by drawing a valid dimension-size for the given # dimension. This restricts the variability across the shapes # at this dimension such that they can only choose between # this size and a singleton dimension. if len(base_shape) < dim_count or base_shape[dim] == 1: # dim is unrestricted by the base-shape: shrink to min_side dim_side = data.draw(self.side_strat) elif base_shape[dim] <= self.max_side: # dim is aligned with non-singleton base-dim dim_side = base_shape[dim] else: # only a singleton is valid in alignment with the base-dim dim_side = 1 for shape_id, shape in enumerate(shapes): # Populating this dimension-size for each shape, either # the drawn size is used or, if permitted, a singleton # dimension. if dim_count <= len(base_shape) and self.size_one_allowed: # aligned: shrink towards size 1 side = data.draw(st.sampled_from([1, dim_side])) else: side = dim_side # Use a trick where where a biased coin is queried to see # if the given shape-tuple will continue to be grown. All # of the relevant draws will still be made for the given # shape-tuple even if it is no longer being added to. # This helps to ensure more stable shrinking behavior. if self.min_dims < dim_count: use[shape_id] &= cu.biased_coin( data, 1 - 1 / (1 + self.max_dims - dim) ) if use[shape_id]: shape.append(side) if len(result_shape) < len(shape): result_shape.append(shape[-1]) elif shape[-1] != 1 and result_shape[dim] == 1: result_shape[dim] = shape[-1] if not any(use): break result_shape = result_shape[: max(map(len, [self.base_shape] + shapes))] assert len(shapes) == self.num_shapes assert all(self.min_dims <= len(s) <= self.max_dims for s in shapes) assert all(self.min_side <= s <= self.max_side for side in shapes for s in side) return BroadcastableShapes( input_shapes=tuple(tuple(reversed(shape)) for shape in shapes), result_shape=tuple(reversed(result_shape)), )
def test_can_draw_arbitrary_fractions(p, b): try: cu.biased_coin(ConjectureData.for_buffer(b), p) except StopTest: reject()
def test_assert_biased_coin_always_treats_one_as_true(): assert cu.biased_coin(ConjectureData.for_buffer([0, 1]), p=1.0 / 257)
def test_biased_coin_can_be_forced(): assert cu.biased_coin(ConjectureData.for_buffer([0]), p=0.5, forced=True) assert not cu.biased_coin( ConjectureData.for_buffer([1]), p=0.5, forced=False)
def test_too_small_to_be_useful_coin(): assert not cu.biased_coin(ConjectureData.for_buffer([1]), 0.5**65)
def do_draw(self, data): if cu.biased_coin(data, self.__poison_chance): return POISON else: return data.draw(self.__ints)