Skip to content

Commit

Permalink
Merge commit 'd01fd14dc6ad01a54996a2a31b29bbe97322dd70' into pr20-merged
Browse files Browse the repository at this point in the history
  • Loading branch information
AltSysrq committed Jan 14, 2018
2 parents c27ee24 + d01fd14 commit 07e794d
Show file tree
Hide file tree
Showing 28 changed files with 318 additions and 210 deletions.
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,22 @@
## Unreleased

### Potential Breaking Changes

- Instead of returning `-> Result<Self::Value, String>`, strategies are expected
to return `-> Result<Self::Value, Rejection>` instead. `Rejection` reduces
the amount of heap allocations, especially for `.prop_filter(..)` where
you may now also pass in `&'static str` as well as `Rc<str>`.
You will only experience breaks if you've written your own strategy types
or if you've used `TestCaseError::Reject` or `TestCaseError::Fail` expliclty.

### New Additions

- Added `proptest::strategy::Rejection` which allows you to avoid heap
allocation in some places or share allocation with string-interning.

- Added a type alias `proptest::strategy::NewTree<S>` where `S: Strategy`
defined as: `type NewTree<S> = Result<<S as Strategy>::Value, Rejection>`.

## 0.3.4

### Bug Fixes
Expand Down
4 changes: 2 additions & 2 deletions examples/tutorial-simplify-play.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@

extern crate proptest;

use proptest::test_runner::{Config, TestRunner};
use proptest::test_runner::TestRunner;
use proptest::strategy::{Strategy, ValueTree};

fn main() {
let mut runner = TestRunner::new(Config::default());
let mut runner = TestRunner::default();
let mut str_val = "[a-z]{1,4}\\p{Cyrillic}{1,4}\\p{Greek}{1,4}"
.new_value(&mut runner).unwrap();
println!("str_val = {}", str_val.current());
Expand Down
4 changes: 2 additions & 2 deletions examples/tutorial-strategy-play.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@

extern crate proptest;

use proptest::test_runner::{Config, TestRunner};
use proptest::test_runner::TestRunner;
use proptest::strategy::{Strategy, ValueTree};

fn main() {
let mut runner = TestRunner::new(Config::default());
let mut runner = TestRunner::default();
let int_val = (0..100i32).new_value(&mut runner).unwrap();
let str_val = "[a-z]{1,4}\\p{Cyrillic}{1,4}\\p{Greek}{1,4}"
.new_value(&mut runner).unwrap();
Expand Down
8 changes: 3 additions & 5 deletions src/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,7 @@ macro_rules! small_array {
impl<S : Strategy> Strategy for [S;$n] {
type Value = ArrayValueTree<[S::Value;$n]>;

fn new_value(&self, runner: &mut TestRunner)
-> Result<Self::Value, String> {
fn new_value(&self, runner: &mut TestRunner) -> NewTree<Self> {
Ok(ArrayValueTree {
tree: [$(self[$ix].new_value(runner)?,)*],
shrinker: 0,
Expand All @@ -116,8 +115,7 @@ macro_rules! small_array {
for UniformArrayStrategy<S, [ValueFor<S>; $n]> {
type Value = ArrayValueTree<[S::Value; $n]>;

fn new_value(&self, runner: &mut TestRunner)
-> Result<Self::Value, String> {
fn new_value(&self, runner: &mut TestRunner) -> NewTree<Self> {
Ok(ArrayValueTree {
tree: [$({
let _ = $ix;
Expand Down Expand Up @@ -256,7 +254,7 @@ mod test {
}

let input = [0..32, 0..32];
let mut runner = TestRunner::new(Config::default());
let mut runner = TestRunner::default();

let mut cases_tested = 0;
for _ in 0..256 {
Expand Down
16 changes: 7 additions & 9 deletions src/bits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,7 @@ impl<T : BitSetLike> BitSetStrategy<T> {
impl<T : BitSetLike> Strategy for BitSetStrategy<T> {
type Value = BitSetValueTree<T>;

fn new_value(&self, runner: &mut TestRunner)
-> Result<Self::Value, String> {
fn new_value(&self, runner: &mut TestRunner) -> NewTree<Self> {
let mut inner = T::new_bitset(self.max);
for bit in self.min..self.max {
if self.mask.as_ref().map_or(true, |mask| mask.test(bit)) &&
Expand Down Expand Up @@ -212,8 +211,7 @@ impl<T : BitSetLike> SampledBitSetStrategy<T> {
impl<T : BitSetLike> Strategy for SampledBitSetStrategy<T> {
type Value = BitSetValueTree<T>;

fn new_value(&self, runner: &mut TestRunner)
-> Result<Self::Value, String> {
fn new_value(&self, runner: &mut TestRunner) -> NewTree<Self> {
let mut bits = T::new_bitset(self.bits.end);
let count = runner.rng().gen_range(self.size.start, self.size.end);
for bit in rand::sample(runner.rng(), self.bits.clone(), count) {
Expand Down Expand Up @@ -370,7 +368,7 @@ mod test {
fn generates_values_in_range() {
let input = u32::between(4, 8);

let mut runner = TestRunner::new(Config::default());
let mut runner = TestRunner::default();
for _ in 0..256 {
let value = input.new_value(&mut runner).unwrap().current();
assert!(0 == value & !0xF0u32,
Expand All @@ -382,7 +380,7 @@ mod test {
fn generates_values_in_mask() {
let mut accum = 0;

let mut runner = TestRunner::new(Config::default());
let mut runner = TestRunner::default();
let input = u32::masked(0xdeadbeef);
for _ in 0..1024 {
accum |= input.new_value(&mut runner).unwrap().current();
Expand All @@ -400,7 +398,7 @@ mod test {
mask.insert(0);
mask.insert(2);

let mut runner = TestRunner::new(Config::default());
let mut runner = TestRunner::default();
let input = bitset::masked(mask);
for _ in 0..32 {
let v = input.new_value(&mut runner).unwrap().current();
Expand All @@ -416,7 +414,7 @@ mod test {
fn shrinks_to_zero() {
let input = u32::between(4, 24);

let mut runner = TestRunner::new(Config::default());
let mut runner = TestRunner::default();
for _ in 0..256 {
let mut value = input.new_value(&mut runner).unwrap();
let mut prev = value.current();
Expand All @@ -435,7 +433,7 @@ mod test {
fn complicates_to_previous() {
let input = u32::between(4, 24);

let mut runner = TestRunner::new(Config::default());
let mut runner = TestRunner::default();
for _ in 0..256 {
let mut value = input.new_value(&mut runner).unwrap();
let orig = value.current();
Expand Down
6 changes: 2 additions & 4 deletions src/bool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ pub const ANY: Any = Any(());
impl Strategy for Any {
type Value = BoolValueTree;

fn new_value(&self, runner: &mut TestRunner)
-> Result<BoolValueTree, String> {
fn new_value(&self, runner: &mut TestRunner) -> NewTree<Self> {
Ok(BoolValueTree(runner.rng().gen()))
}
}
Expand All @@ -47,8 +46,7 @@ pub struct Weighted(f64);
impl Strategy for Weighted {
type Value = BoolValueTree;

fn new_value(&self, runner: &mut TestRunner)
-> Result<BoolValueTree, String> {
fn new_value(&self, runner: &mut TestRunner) -> NewTree<Self> {
Ok(BoolValueTree(runner.rng().next_f64() < self.0))
}
}
Expand Down
14 changes: 6 additions & 8 deletions src/char.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,8 +227,7 @@ pub struct CharValueTree {
impl<'a> Strategy for CharStrategy<'a> {
type Value = CharValueTree;

fn new_value(&self, runner: &mut TestRunner)
-> Result<CharValueTree, String> {
fn new_value(&self, runner: &mut TestRunner) -> NewTree<Self> {
let (base, offset) = select_range_index(
runner.rng(), &self.special, &self.preferred, &self.ranges);

Expand Down Expand Up @@ -304,17 +303,16 @@ mod test {
(0..::std::char::MAX as u32,
0..::std::char::MAX as u32),
1..5);
TestRunner::new(Config::default()).run(
TestRunner::default().run(
&meta_input, |input_ranges| {
let input = ranges(Cow::Owned(input_ranges.iter().map(
|&(lo, hi)| ::std::char::from_u32(lo).and_then(
|lo| ::std::char::from_u32(hi).map(
|hi| (min(lo, hi), max(lo, hi))))
.ok_or_else(|| TestCaseError::Reject(
"non-char".to_owned())))
.ok_or_else(|| TestCaseError::reject("non-char")))
.collect::<Result<Vec<CharRange>,_>>()?));

let mut runner = TestRunner::new(Config::default());
let mut runner = TestRunner::default();
for _ in 0..256 {
let mut value = input.new_value(&mut runner).unwrap();
loop {
Expand All @@ -335,7 +333,7 @@ mod test {
fn applies_desired_bias() {
let mut men_in_business_suits_levitating = 0;
let mut ascii_printable = 0;
let mut runner = TestRunner::new(Config::default());
let mut runner = TestRunner::default();

for _ in 0..1024 {
let ch = ANY.new_value(&mut runner).unwrap().current();
Expand All @@ -353,7 +351,7 @@ mod test {
#[test]
fn doesnt_shrink_to_ascii_control() {
let mut accepted = 0;
let mut runner = TestRunner::new(Config::default());
let mut runner = TestRunner::default();

for _ in 0..256 {
let mut value = ANY.new_value(&mut runner).unwrap();
Expand Down
19 changes: 9 additions & 10 deletions src/collection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ where ValueFor<T> : Hash + Eq {
let min_size = size.start;
HashSetStrategy(statics::Filter::new(
statics::Map::new(vec(element, size), VecToHashSet),
"HashSet minimum size".to_owned(),
reject("HashSet minimum size"),
MinSize(min_size)))
}

Expand Down Expand Up @@ -224,7 +224,7 @@ where ValueFor<T> : Ord {

BTreeSetStrategy(statics::Filter::new(
statics::Map::new(vec(element, size), VecToBTreeSet),
"BTreeSet minimum size".to_owned(),
reject("BTreeSet minimum size"),
MinSize(min_size)))
}

Expand Down Expand Up @@ -275,7 +275,7 @@ where ValueFor<K> : Hash + Eq {
let min_size = size.start;
HashMapStrategy(statics::Filter::new(
statics::Map::new(vec((key, value), size), VecToHashMap),
"HashMap minimum size".to_owned(),
reject("HashMap minimum size"),
MinSize(min_size)))
}

Expand Down Expand Up @@ -326,7 +326,7 @@ where ValueFor<K> : Ord {
let min_size = size.start;
BTreeMapStrategy(statics::Filter::new(
statics::Map::new(vec((key, value), size.clone()), VecToBTreeMap),
"BTreeMap minimum size".to_owned(),
reject("BTreeMap minimum size"),
MinSize(min_size)))
}

Expand All @@ -349,8 +349,7 @@ pub struct VecValueTree<T : ValueTree> {
impl<T : Strategy> Strategy for VecStrategy<T> {
type Value = VecValueTree<T::Value>;

fn new_value(&self, runner: &mut TestRunner)
-> Result<Self::Value, String> {
fn new_value(&self, runner: &mut TestRunner) -> NewTree<Self> {
let max_size = rand::distributions::Range::new(
self.size.start, self.size.end).ind_sample(runner.rng());
let mut elements = Vec::with_capacity(max_size);
Expand Down Expand Up @@ -459,7 +458,7 @@ mod test {
let mut num_successes = 0;

for _ in 0..256 {
let mut runner = TestRunner::new(Config::default());
let mut runner = TestRunner::default();
let case = input.new_value(&mut runner).unwrap();
let start = case.current();
// Has correct length
Expand All @@ -471,7 +470,7 @@ mod test {
if v.iter().map(|&v| v).sum::<usize>() < 9 {
Ok(())
} else {
Err(TestCaseError::Fail("greater than 8".to_owned()))
fail_case("greater than 8")
}
});

Expand Down Expand Up @@ -501,7 +500,7 @@ mod test {
fn test_map() {
// Only 8 possible keys
let input = hash_map("[ab]{3}", "a", 2..3);
let mut runner = TestRunner::new(Config::default());
let mut runner = TestRunner::default();

for _ in 0..256 {
let v = input.new_value(&mut runner).unwrap().current();
Expand All @@ -513,7 +512,7 @@ mod test {
fn test_set() {
// Only 8 possible values
let input = hash_set("[ab]{3}", 2..3);
let mut runner = TestRunner::new(Config::default());
let mut runner = TestRunner::default();

for _ in 0..256 {
let v = input.new_value(&mut runner).unwrap().current();
Expand Down
3 changes: 1 addition & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1484,8 +1484,7 @@ macro_rules! opaque_strategy_wrapper {

impl $($sgen)* Strategy for $stratname $($sgen)* $($swhere)* {
type Value = $stratvtty;
fn new_value(&self, runner: &mut TestRunner)
-> Result<Self::Value, String> {
fn new_value(&self, runner: &mut TestRunner) -> NewTree<Self> {
self.0.new_value(runner).map($vtname)
}
}
Expand Down
Loading

0 comments on commit 07e794d

Please sign in to comment.