Skip to content

Commit ca308b0

Browse files
authored
Merge pull request #462 from mirandaconrado/master
Detect empty ranges during tree creation
2 parents 0a53eda + 1426f0f commit ca308b0

File tree

2 files changed

+78
-0
lines changed

2 files changed

+78
-0
lines changed

proptest/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
- Setting `PROPTEST_MAX_DEFAULT_SIZE_RANGE` now customizes the default `SizeRange`
88
used by the default strategies for collections (like `Vec`). The default remains 100.
9+
- Empty ranges panic during tree creation instead of during sampling.
910

1011
### Documentation
1112
- Reference the derive macro in Arbitrary's documentation

proptest/src/num.rs

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,13 @@ macro_rules! numeric_api {
6969
type Value = $typ;
7070

7171
fn new_tree(&self, runner: &mut TestRunner) -> NewTree<Self> {
72+
if self.is_empty() {
73+
panic!(
74+
"Invalid use of empty range {}..{}.",
75+
self.start, self.end
76+
);
77+
}
78+
7279
Ok(BinarySearch::new_clamped(
7380
self.start,
7481
$crate::num::sample_uniform::<$sample_typ>(
@@ -87,6 +94,14 @@ macro_rules! numeric_api {
8794
type Value = $typ;
8895

8996
fn new_tree(&self, runner: &mut TestRunner) -> NewTree<Self> {
97+
if self.is_empty() {
98+
panic!(
99+
"Invalid use of empty range {}..={}.",
100+
self.start(),
101+
self.end()
102+
);
103+
}
104+
90105
Ok(BinarySearch::new_clamped(
91106
*self.start(),
92107
$crate::num::sample_uniform_incl::<$sample_typ>(
@@ -1390,4 +1405,66 @@ mod test {
13901405
}));
13911406
}
13921407
}
1408+
1409+
mod panic_on_empty {
1410+
macro_rules! panic_on_empty {
1411+
($t:tt) => {
1412+
mod $t {
1413+
use crate::strategy::Strategy;
1414+
use crate::test_runner::TestRunner;
1415+
use std::panic;
1416+
use std::string::String;
1417+
1418+
const ZERO: $t = 0 as $t;
1419+
const ONE: $t = 1 as $t;
1420+
1421+
#[test]
1422+
fn range() {
1423+
assert_eq!(
1424+
panic::catch_unwind(|| {
1425+
let mut runner = TestRunner::deterministic();
1426+
let _ = (ZERO..ZERO).new_tree(&mut runner);
1427+
})
1428+
.err()
1429+
.and_then(|a| a
1430+
.downcast_ref::<String>()
1431+
.map(|s| {
1432+
s == "Invalid use of empty range 0..0."
1433+
})),
1434+
Some(true)
1435+
);
1436+
}
1437+
1438+
#[test]
1439+
fn range_inclusive() {
1440+
assert_eq!(
1441+
panic::catch_unwind(|| {
1442+
let mut runner = TestRunner::deterministic();
1443+
let _ = (ONE..=ZERO).new_tree(&mut runner);
1444+
})
1445+
.err()
1446+
.and_then(|a| a
1447+
.downcast_ref::<String>()
1448+
.map(|s| {
1449+
s == "Invalid use of empty range 1..=0."
1450+
})),
1451+
Some(true)
1452+
);
1453+
}
1454+
}
1455+
};
1456+
}
1457+
panic_on_empty!(u8);
1458+
panic_on_empty!(i8);
1459+
panic_on_empty!(u16);
1460+
panic_on_empty!(i16);
1461+
panic_on_empty!(u32);
1462+
panic_on_empty!(i32);
1463+
panic_on_empty!(u64);
1464+
panic_on_empty!(i64);
1465+
panic_on_empty!(usize);
1466+
panic_on_empty!(isize);
1467+
panic_on_empty!(f32);
1468+
panic_on_empty!(f64);
1469+
}
13931470
}

0 commit comments

Comments
 (0)