summaryrefslogtreecommitdiffstats
path: root/vendor/proptest/src
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-07 05:48:42 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-07 05:48:42 +0000
commitcec1877e180393eba0f6ddb0cf97bf3a791631c7 (patch)
tree47b4dac2a9dd9a40c30c251b4d4a72d7ccf77e9f /vendor/proptest/src
parentAdding debian version 1.74.1+dfsg1-1. (diff)
downloadrustc-cec1877e180393eba0f6ddb0cf97bf3a791631c7.tar.xz
rustc-cec1877e180393eba0f6ddb0cf97bf3a791631c7.zip
Merging upstream version 1.75.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/proptest/src')
-rw-r--r--vendor/proptest/src/arbitrary/_alloc/char.rs2
-rw-r--r--vendor/proptest/src/arbitrary/_std/path.rs112
-rw-r--r--vendor/proptest/src/bits.rs17
-rw-r--r--vendor/proptest/src/lib.rs7
-rw-r--r--vendor/proptest/src/num.rs15
-rw-r--r--vendor/proptest/src/path.rs55
-rw-r--r--vendor/proptest/src/sample.rs8
-rw-r--r--vendor/proptest/src/string.rs210
-rw-r--r--vendor/proptest/src/sugar.rs52
-rw-r--r--vendor/proptest/src/test_runner/config.rs3
-rw-r--r--vendor/proptest/src/test_runner/failure_persistence/file.rs19
-rw-r--r--vendor/proptest/src/test_runner/rng.rs19
-rw-r--r--vendor/proptest/src/test_runner/runner.rs22
13 files changed, 408 insertions, 133 deletions
diff --git a/vendor/proptest/src/arbitrary/_alloc/char.rs b/vendor/proptest/src/arbitrary/_alloc/char.rs
index fab9dd824..58a261e41 100644
--- a/vendor/proptest/src/arbitrary/_alloc/char.rs
+++ b/vendor/proptest/src/arbitrary/_alloc/char.rs
@@ -43,7 +43,6 @@ impl_wrap_char!(ToLowercase, char::to_lowercase);
#[cfg(feature = "unstable")]
impl_wrap_char!(ToUppercase, char::to_uppercase);
-#[cfg(feature = "break-dead-code")]
arbitrary!(DecodeUtf16<<Vec<u16> as IntoIterator>::IntoIter>,
SMapped<Vec<u16>, Self>;
static_map(vec(any::<u16>(), ..VEC_MAX), decode_utf16)
@@ -75,7 +74,6 @@ mod test {
decode_utf16_error => DecodeUtf16Error
);
- #[cfg(feature = "break-dead-code")]
no_panic_test!(
decode_utf16 => DecodeUtf16<<Vec<u16> as IntoIterator>::IntoIter>
);
diff --git a/vendor/proptest/src/arbitrary/_std/path.rs b/vendor/proptest/src/arbitrary/_std/path.rs
index e7d063c17..2e71b03db 100644
--- a/vendor/proptest/src/arbitrary/_std/path.rs
+++ b/vendor/proptest/src/arbitrary/_std/path.rs
@@ -11,13 +11,121 @@
use std::path::*;
-// TODO: Figure out PathBuf and then Box/Rc/Box<Path>.
+use crate::{
+ arbitrary::{SMapped, StrategyFor},
+ path::PathParams,
+ prelude::{any, any_with, Arbitrary, Strategy},
+ std_facade::{string::ToString, Arc, Box, Rc, String, Vec},
+ strategy::{statics::static_map, MapInto},
+};
arbitrary!(StripPrefixError; Path::new("").strip_prefix("a").unwrap_err());
+/// A private type (not actually pub) representing the output of [`PathParams`] that can't be
+/// referred to by API users.
+///
+/// The goal of this type is to encapsulate the output of `PathParams`. If this layer weren't
+/// present, the type of `<PathBuf as Arbitrary>::Strategy` would be `SMapped<(bool, Vec<String>),
+/// Self>`. This is a problem because it exposes the internal representation of `PathParams` as an
+/// API. For example, if an additional parameter of randomness (e.g. another bool) were added, the
+/// type of `Strategy` would change.
+///
+/// With `PathParamsOutput`, the type of `Strategy` is `SMapped<PathParamsOutput, Self>`, which is a
+/// type that can't be named directly---only via `<PathBuf as Arbitrary>::Strategy`. The internal
+/// representation of `PathParams` can be changed without affecting the API.
+#[derive(Debug)]
+pub struct PathParamsOutput {
+ is_absolute: bool,
+ components: Vec<String>,
+}
+
+impl Arbitrary for PathParamsOutput {
+ type Parameters = PathParams;
+ type Strategy = SMapped<(bool, Vec<String>), Self>;
+
+ fn arbitrary_with(args: Self::Parameters) -> Self::Strategy {
+ static_map(
+ (
+ any::<bool>(),
+ any_with::<Vec<String>>((
+ args.components(),
+ args.component_regex(),
+ )),
+ ),
+ |(is_absolute, components)| Self {
+ is_absolute,
+ components,
+ },
+ )
+ }
+}
+
+/// This implementation accepts as its argument a [`PathParams`] struct. It generates either a
+/// relative or an absolute path with equal probability.
+///
+/// Currently, this implementation does not generate:
+///
+/// * Paths that are not valid UTF-8 (this is unlikely to change)
+/// * Paths with a [`PrefixComponent`](std::path::PrefixComponent) on Windows, e.g. `C:\` (this may
+/// change in the future)
+impl Arbitrary for PathBuf {
+ type Parameters = PathParams;
+ type Strategy = SMapped<PathParamsOutput, Self>;
+
+ fn arbitrary_with(args: Self::Parameters) -> Self::Strategy {
+ static_map(
+ any_with::<PathParamsOutput>(args),
+ |PathParamsOutput {
+ is_absolute,
+ components,
+ }| {
+ let mut out = PathBuf::new();
+ if is_absolute {
+ out.push(&MAIN_SEPARATOR.to_string());
+ }
+
+ for component in components {
+ // If a component has an embedded / (or \ on Windows), remove it from the
+ // string.
+ let component = component
+ .chars()
+ .filter(|&c| !std::path::is_separator(c))
+ .collect::<String>();
+ out.push(&component);
+ }
+
+ out
+ },
+ )
+ }
+}
+
+macro_rules! dst_wrapped {
+ ($($w: ident),*) => {
+ $(
+ /// This implementation is identical to [the `Arbitrary` implementation for
+ /// `PathBuf`](trait.Arbitrary.html#impl-Arbitrary-for-PathBuf).
+ impl Arbitrary for $w<Path> {
+ type Parameters = PathParams;
+ type Strategy = MapInto<StrategyFor<PathBuf>, Self>;
+
+ fn arbitrary_with(args: Self::Parameters) -> Self::Strategy {
+ any_with::<PathBuf>(args).prop_map_into()
+ }
+ }
+ )*
+ }
+}
+
+dst_wrapped!(Box, Rc, Arc);
+
#[cfg(test)]
mod test {
no_panic_test!(
- strip_prefix_error => StripPrefixError
+ strip_prefix_error => StripPrefixError,
+ path_buf => PathBuf,
+ box_path => Box<Path>,
+ rc_path => Rc<Path>,
+ arc_path => Arc<Path>
);
}
diff --git a/vendor/proptest/src/bits.rs b/vendor/proptest/src/bits.rs
index 342eb28b1..89b183ed1 100644
--- a/vendor/proptest/src/bits.rs
+++ b/vendor/proptest/src/bits.rs
@@ -22,6 +22,8 @@ use core::mem;
#[cfg(feature = "bit-set")]
use bit_set::BitSet;
+#[cfg(feature = "bit-set")]
+use bit_vec::BitVec;
use rand::{self, seq::IteratorRandom, Rng};
use crate::collection::SizeRange;
@@ -450,8 +452,15 @@ pub(crate) mod varsize {
impl VarBitSet {
/// Create a bit set of `len` set values.
+ #[cfg(not(feature = "bit-set"))]
+ pub fn saturated(len: usize) -> Self {
+ Self(vec![true; len])
+ }
+
+ /// Create a bit set of `len` set values.
+ #[cfg(feature = "bit-set")]
pub fn saturated(len: usize) -> Self {
- (0..len).collect::<VarBitSet>()
+ Self(BitSet::from_bit_vec(BitVec::from_elem(len, true)))
}
#[cfg(not(feature = "bit-set"))]
@@ -492,8 +501,10 @@ pub(crate) mod varsize {
}
impl FromIterator<usize> for VarBitSet {
- fn from_iter<T: IntoIterator<Item = usize>>(iter: T) -> Self {
- let mut bits = VarBitSet::new_bitset(0);
+ fn from_iter<T: IntoIterator<Item = usize>>(into_iter: T) -> Self {
+ let iter = into_iter.into_iter();
+ let lower_bound = iter.size_hint().0;
+ let mut bits = VarBitSet::new_bitset(lower_bound);
for bit in iter {
bits.set(bit);
}
diff --git a/vendor/proptest/src/lib.rs b/vendor/proptest/src/lib.rs
index 818c32645..72b90ffbf 100644
--- a/vendor/proptest/src/lib.rs
+++ b/vendor/proptest/src/lib.rs
@@ -27,10 +27,6 @@
feature(allocator_api, try_trait_v2, generator_trait, never_type)
)]
#![cfg_attr(all(feature = "std", feature = "unstable"), feature(ip))]
-#![cfg_attr(
- all(feature = "alloc", not(feature = "std")),
- feature(core_intrinsics)
-)]
#![cfg_attr(docsrs, feature(doc_cfg))]
// std_facade is used in a few macros, so it needs to be public.
@@ -90,6 +86,9 @@ pub mod test_runner;
pub mod tuple;
pub mod option;
+#[cfg(feature = "std")]
+#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
+pub mod path;
pub mod result;
pub mod sample;
#[cfg(feature = "std")]
diff --git a/vendor/proptest/src/num.rs b/vendor/proptest/src/num.rs
index 3aa785db4..ebf8593a4 100644
--- a/vendor/proptest/src/num.rs
+++ b/vendor/proptest/src/num.rs
@@ -362,6 +362,7 @@ unsigned_integer_bin_search!(u128);
unsigned_integer_bin_search!(usize);
bitflags! {
+ #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub(crate) struct FloatTypes: u32 {
const POSITIVE = 0b0000_0001;
const NEGATIVE = 0b0000_0010;
@@ -372,13 +373,13 @@ bitflags! {
const QUIET_NAN = 0b0100_0000;
const SIGNALING_NAN = 0b1000_0000;
const ANY =
- Self::POSITIVE.bits |
- Self::NEGATIVE.bits |
- Self::NORMAL.bits |
- Self::SUBNORMAL.bits |
- Self::ZERO.bits |
- Self::INFINITE.bits |
- Self::QUIET_NAN.bits;
+ Self::POSITIVE.bits() |
+ Self::NEGATIVE.bits() |
+ Self::NORMAL.bits() |
+ Self::SUBNORMAL.bits() |
+ Self::ZERO.bits() |
+ Self::INFINITE.bits() |
+ Self::QUIET_NAN.bits();
}
}
diff --git a/vendor/proptest/src/path.rs b/vendor/proptest/src/path.rs
new file mode 100644
index 000000000..76242817d
--- /dev/null
+++ b/vendor/proptest/src/path.rs
@@ -0,0 +1,55 @@
+//! Strategies for generating [`PathBuf`] and related path types.
+//!
+//! [`PathParams`] in this module is used as the argument to the
+//! [`Arbitrary`](crate::arbitrary::Arbitrary) implementation for [`PathBuf`].
+
+use crate::{collection::SizeRange, string::StringParam};
+
+/// Parameters for the [`Arbitrary`] implementation for [`PathBuf`].
+///
+/// By default, this generates paths with 0 to 8 components uniformly at random, each of which is a
+/// default [`StringParam`].
+#[derive(Clone, Debug, PartialEq, Eq, Hash)]
+pub struct PathParams {
+ /// The number of components in the path.
+ components: SizeRange,
+ /// The regular expression to generate individual components.
+ component_regex: StringParam,
+}
+
+impl PathParams {
+ /// Gets the number of components in the path.
+ pub fn components(&self) -> SizeRange {
+ self.components.clone()
+ }
+
+ /// Sets the number of components in the path.
+ pub fn with_components(mut self, components: impl Into<SizeRange>) -> Self {
+ self.components = components.into();
+ self
+ }
+
+ /// Gets the regular expression to generate individual components.
+ pub fn component_regex(&self) -> StringParam {
+ self.component_regex
+ }
+
+ /// Sets the regular expression to generate individual components.
+ pub fn with_component_regex(
+ mut self,
+ component_regex: impl Into<StringParam>,
+ ) -> Self {
+ self.component_regex = component_regex.into();
+ self
+ }
+}
+
+impl Default for PathParams {
+ fn default() -> Self {
+ Self {
+ components: (0..8).into(),
+ // This is the default regex for `any::<String>()`.
+ component_regex: StringParam::default(),
+ }
+ }
+}
diff --git a/vendor/proptest/src/sample.rs b/vendor/proptest/src/sample.rs
index 9c464f132..86ba6818e 100644
--- a/vendor/proptest/src/sample.rs
+++ b/vendor/proptest/src/sample.rs
@@ -245,6 +245,14 @@ impl Index {
}
}
+// This impl is handy for generic code over any type that exposes an internal `Index` -- with it,
+// a plain `Index` can be passed in as well.
+impl AsRef<Index> for Index {
+ fn as_ref(&self) -> &Index {
+ self
+ }
+}
+
mapfn! {
[] fn UsizeToIndex[](raw: usize) -> Index {
Index(raw)
diff --git a/vendor/proptest/src/string.rs b/vendor/proptest/src/string.rs
index 8777388f5..935cb21ca 100644
--- a/vendor/proptest/src/string.rs
+++ b/vendor/proptest/src/string.rs
@@ -16,14 +16,8 @@ use core::mem;
use core::ops::RangeInclusive;
use core::u32;
-use regex_syntax::hir::{
- self, Hir,
- HirKind::*,
- Literal::*,
- RepetitionKind::{self, *},
- RepetitionRange::*,
-};
-use regex_syntax::{Error as ParseError, Parser};
+use regex_syntax::hir::{self, Hir, HirKind::*, Repetition};
+use regex_syntax::{Error as ParseError, ParserBuilder};
use crate::bool;
use crate::char;
@@ -33,7 +27,7 @@ use crate::test_runner::*;
/// Wraps the regex that forms the `Strategy` for `String` so that a sensible
/// `Default` can be given. The default is a string of non-control characters.
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct StringParam(&'static str);
impl From<StringParam> for &'static str {
@@ -150,7 +144,8 @@ impl StrategyFromRegex for Vec<u8> {
/// If you don't need error handling and aren't limited by setup time, it is
/// also possible to directly use a `&str` as a strategy with the same effect.
pub fn string_regex(regex: &str) -> ParseResult<String> {
- string_regex_parsed(&regex_to_hir(regex)?)
+ let hir = ParserBuilder::new().build().parse(regex)?;
+ string_regex_parsed(&hir)
}
/// Like `string_regex()`, but allows providing a pre-parsed expression.
@@ -167,8 +162,20 @@ pub fn string_regex_parsed(expr: &Hir) -> ParseResult<String> {
/// Creates a strategy which generates byte strings matching the given regular
/// expression.
+///
+/// By default, the byte strings generated by this strategy _will_ be valid
+/// UTF-8. If you wish to generate byte strings that aren't (necessarily)
+/// valid UTF-8, wrap your regex (or some subsection of it) in `(?-u: ... )`.
+/// You may want to turn on the `s` flag as well (`(?s-u: ... )`) so that `.`
+/// will generate newline characters (byte value `0x0A`). See the
+/// [`regex` crate's documentation](https://docs.rs/regex/*/regex/#opt-out-of-unicode-support)
+/// for more information.
pub fn bytes_regex(regex: &str) -> ParseResult<Vec<u8>> {
- bytes_regex_parsed(&regex_to_hir(regex)?)
+ let hir = ParserBuilder::new()
+ .utf8(false)
+ .build()
+ .parse(regex)?;
+ bytes_regex_parsed(&hir)
}
/// Like `bytes_regex()`, but allows providing a pre-parsed expression.
@@ -176,11 +183,7 @@ pub fn bytes_regex_parsed(expr: &Hir) -> ParseResult<Vec<u8>> {
match expr.kind() {
Empty => Ok(Just(vec![]).sboxed()),
- Literal(lit) => Ok(Just(match lit {
- Unicode(scalar) => to_bytes(*scalar),
- Byte(byte) => vec![*byte],
- })
- .sboxed()),
+ Literal(lit) => Ok(Just(lit.0.to_vec()).sboxed()),
Class(class) => Ok(match class {
hir::Class::Unicode(class) => {
@@ -192,19 +195,13 @@ pub fn bytes_regex_parsed(expr: &Hir) -> ParseResult<Vec<u8>> {
}
}),
- Repetition(rep) => Ok(vec(
- bytes_regex_parsed(&rep.hir)?,
- to_range(rep.kind.clone())?,
- )
- .prop_map(|parts| {
- parts.into_iter().fold(vec![], |mut acc, child| {
- acc.extend(child);
- acc
- })
- })
- .sboxed()),
+ Repetition(rep) => {
+ Ok(vec(bytes_regex_parsed(&rep.sub)?, to_range(rep)?)
+ .prop_map(|parts| parts.concat())
+ .sboxed())
+ }
- Group(group) => bytes_regex_parsed(&group.hir).map(|v| v.0),
+ Capture(capture) => bytes_regex_parsed(&capture.sub).map(|v| v.0),
Concat(subs) => {
let subs = ConcatIter {
@@ -232,12 +229,8 @@ pub fn bytes_regex_parsed(expr: &Hir) -> ParseResult<Vec<u8>> {
Ok(Union::try_new(subs.iter().map(bytes_regex_parsed))?.sboxed())
}
- Anchor(_) => {
- unsupported("line/text anchors not supported for string generation")
- }
-
- WordBoundary(_) => unsupported(
- "word boundary tests not supported for string generation",
+ Look(_) => unsupported(
+ "anchors/boundaries not supported for string generation",
),
}
.map(RegexGeneratorStrategy)
@@ -298,8 +291,7 @@ impl<'a, I: Iterator<Item = &'a Hir>> Iterator for ConcatIter<'a, I> {
while let Some(next) = self.iter.next() {
match next.kind() {
// A literal. Accumulate:
- Literal(Unicode(scalar)) => self.buf.extend(to_bytes(*scalar)),
- Literal(Byte(byte)) => self.buf.push(*byte),
+ Literal(literal) => self.buf.extend_from_slice(&literal.0),
// Encountered a non-literal.
_ => {
return if !self.buf.is_empty() {
@@ -324,31 +316,35 @@ impl<'a, I: Iterator<Item = &'a Hir>> Iterator for ConcatIter<'a, I> {
}
}
-fn to_range(kind: RepetitionKind) -> Result<SizeRange, Error> {
- Ok(match kind {
- ZeroOrOne => size_range(0..=1),
- ZeroOrMore => size_range(0..=32),
- OneOrMore => size_range(1..=32),
- Range(range) => match range {
- Exactly(count) if u32::MAX == count => {
- return unsupported(
- "Cannot have repetition of exactly u32::MAX",
- )
- }
- Exactly(count) => size_range(count as usize),
- AtLeast(min) => {
- let max = if min < u32::MAX as u32 / 2 {
- min as usize * 2
- } else {
- u32::MAX as usize
- };
- size_range((min as usize)..max)
- }
- Bounded(_, max) if u32::MAX == max => {
- return unsupported("Cannot have repetition max of u32::MAX")
- }
- Bounded(min, max) => size_range((min as usize)..(max as usize + 1)),
- },
+fn to_range(rep: &Repetition) -> Result<SizeRange, Error> {
+ Ok(match (rep.min, rep.max) {
+ // Zero or one
+ (0, Some(1)) => size_range(0..=1),
+ // Zero or more
+ (0, None) => size_range(0..=32),
+ // One or more
+ (1, None) => size_range(1..=32),
+ // Exact count of u32::MAX
+ (u32::MAX, Some(u32::MAX)) => {
+ return unsupported("Cannot have repetition of exactly u32::MAX");
+ }
+ // Exact count
+ (min, Some(max)) if min == max => size_range(min as usize),
+ // At least min
+ (min, None) => {
+ let max = if min < u32::MAX as u32 / 2 {
+ min as usize * 2
+ } else {
+ u32::MAX as usize
+ };
+ size_range((min as usize)..max)
+ }
+ // Bounded range with max of u32::MAX
+ (_, Some(u32::MAX)) => {
+ return unsupported("Cannot have repetition max of u32::MAX")
+ }
+ // Bounded range
+ (min, Some(max)) => size_range((min as usize)..(max as usize + 1)),
})
}
@@ -357,10 +353,6 @@ fn to_bytes(khar: char) -> Vec<u8> {
khar.encode_utf8(&mut buf).as_bytes().to_owned()
}
-fn regex_to_hir(pattern: &str) -> Result<Hir, Error> {
- Ok(Parser::new().parse(pattern)?)
-}
-
fn unsupported<T>(error: &'static str) -> Result<T, Error> {
Err(Error::UnsupportedRegex(error))
}
@@ -370,9 +362,17 @@ mod test {
use std::collections::HashSet;
use regex::Regex;
+ use regex::bytes::Regex as BytesRegex;
use super::*;
+ fn printable_ascii(v: &[u8]) -> String {
+ v.iter()
+ .flat_map(|c| std::ascii::escape_default(*c))
+ .map(|c| char::from_u32(c.into()).unwrap())
+ .collect()
+ }
+
fn do_test(
pattern: &str,
min_distinct: usize,
@@ -396,6 +396,29 @@ mod test {
);
}
+ fn do_test_bytes(
+ pattern: &str,
+ min_distinct: usize,
+ max_distinct: usize,
+ iterations: usize,
+ ) {
+ let generated = generate_byte_values_matching_regex(pattern, iterations);
+ assert!(
+ generated.len() >= min_distinct,
+ "Expected to generate at least {} strings, but only \
+ generated {}",
+ min_distinct,
+ generated.len()
+ );
+ assert!(
+ generated.len() <= max_distinct,
+ "Expected to generate at most {} strings, but \
+ generated {}",
+ max_distinct,
+ generated.len()
+ );
+ }
+
fn generate_values_matching_regex(
pattern: &str,
iterations: usize,
@@ -432,6 +455,42 @@ mod test {
generated
}
+ fn generate_byte_values_matching_regex(
+ pattern: &str,
+ iterations: usize,
+ ) -> HashSet<Vec<u8>> {
+ let rx = BytesRegex::new(pattern).unwrap();
+ let mut generated = HashSet::new();
+
+ let strategy = bytes_regex(pattern).unwrap();
+ let mut runner = TestRunner::deterministic();
+ for _ in 0..iterations {
+ let mut value = strategy.new_tree(&mut runner).unwrap();
+
+ loop {
+ let s = value.current();
+ let ok = if let Some(matsch) = rx.find(&s) {
+ 0 == matsch.start() && s.len() == matsch.end()
+ } else {
+ false
+ };
+ if !ok {
+ panic!(
+ "Generated string {:?} which does not match {:?}",
+ printable_ascii(&s), pattern
+ );
+ }
+
+ generated.insert(s);
+
+ if !value.simplify() {
+ break;
+ }
+ }
+ }
+ generated
+ }
+
#[test]
fn test_case_insensitive_produces_all_available_values() {
let mut expected: HashSet<String> = HashSet::new();
@@ -445,6 +504,7 @@ mod test {
#[test]
fn test_literal() {
do_test("foo", 1, 1, 8);
+ do_test_bytes("foo", 1, 1, 8);
}
#[test]
@@ -455,36 +515,43 @@ mod test {
#[test]
fn test_alternation() {
do_test("foo|bar|baz", 3, 3, 16);
+ do_test_bytes("foo|bar|baz", 3, 3, 16);
}
#[test]
- fn test_repitition() {
+ fn test_repetition() {
do_test("a{0,8}", 9, 9, 64);
+ do_test_bytes("a{0,8}", 9, 9, 64);
}
#[test]
fn test_question() {
do_test("a?", 2, 2, 16);
+ do_test_bytes("a?", 2, 2, 16);
}
#[test]
fn test_star() {
do_test("a*", 33, 33, 256);
+ do_test_bytes("a*", 33, 33, 256);
}
#[test]
fn test_plus() {
do_test("a+", 32, 32, 256);
+ do_test_bytes("a+", 32, 32, 256);
}
#[test]
fn test_n_to_range() {
do_test("a{4,}", 4, 4, 64);
+ do_test_bytes("a{4,}", 4, 4, 64);
}
#[test]
fn test_concatenation() {
do_test("(foo|bar)(xyzzy|plugh)", 4, 4, 32);
+ do_test_bytes("(foo|bar)(xyzzy|plugh)", 4, 4, 32);
}
#[test]
@@ -505,6 +572,7 @@ mod test {
#[test]
fn test_dot_s() {
do_test("(?s).", 200, 65536, 256);
+ do_test_bytes("(?s-u).", 256, 256, 2048);
}
#[test]
@@ -512,6 +580,16 @@ mod test {
do_test("\\d+", 1, 65536, 256);
}
+ #[test]
+ fn test_non_utf8_byte_strings() {
+ do_test_bytes(r"(?-u)[\xC0-\xFF]\x20", 64, 64, 512);
+ do_test_bytes(r"(?-u)\x20[\x80-\xBF]", 64, 64, 512);
+ do_test_bytes(r#"(?x-u)
+ \xed (( ( \xa0\x80 | \xad\xbf | \xae\x80 | \xaf\xbf )
+ ( \xed ( \xb0\x80 | \xbf\xbf ) )? )
+ | \xb0\x80 | \xbe\x80 | \xbf\xbf )"#, 15, 15, 120);
+ }
+
fn assert_send_and_sync<T: Send + Sync>(_: T) {}
#[test]
diff --git a/vendor/proptest/src/sugar.rs b/vendor/proptest/src/sugar.rs
index e16d2dda9..6b76b30cf 100644
--- a/vendor/proptest/src/sugar.rs
+++ b/vendor/proptest/src/sugar.rs
@@ -333,52 +333,64 @@ macro_rules! prop_oneof {
($_weight0:expr => $item0:expr $(,)?) => { $item0 };
+ // NOTE: The clippy::arc_with_non_send_sync lint is disabled here because
+ // the strategies passed into prop_oneof! are often not Send or Sync, such
+ // as BoxedStrategy.
+ //
+ // The double-curly-braces are not strictly required, but allow the expression
+ // to be annotated with an attribute.
+
($weight0:expr => $item0:expr,
- $weight1:expr => $item1:expr $(,)?) => {
+ $weight1:expr => $item1:expr $(,)?) => {{
+ #[allow(clippy::arc_with_non_send_sync)]
$crate::strategy::TupleUnion::new(
(($weight0, $crate::std_facade::Arc::new($item0)),
($weight1, $crate::std_facade::Arc::new($item1))))
- };
+ }};
($weight0:expr => $item0:expr,
$weight1:expr => $item1:expr,
- $weight2:expr => $item2:expr $(,)?) => {
+ $weight2:expr => $item2:expr $(,)?) => {{
+ #[allow(clippy::arc_with_non_send_sync)]
$crate::strategy::TupleUnion::new(
(($weight0, $crate::std_facade::Arc::new($item0)),
($weight1, $crate::std_facade::Arc::new($item1)),
($weight2, $crate::std_facade::Arc::new($item2))))
- };
+ }};
($weight0:expr => $item0:expr,
$weight1:expr => $item1:expr,
$weight2:expr => $item2:expr,
- $weight3:expr => $item3:expr $(,)?) => {
+ $weight3:expr => $item3:expr $(,)?) => {{
+ #[allow(clippy::arc_with_non_send_sync)]
$crate::strategy::TupleUnion::new(
(($weight0, $crate::std_facade::Arc::new($item0)),
($weight1, $crate::std_facade::Arc::new($item1)),
($weight2, $crate::std_facade::Arc::new($item2)),
($weight3, $crate::std_facade::Arc::new($item3))))
- };
+ }};
($weight0:expr => $item0:expr,
$weight1:expr => $item1:expr,
$weight2:expr => $item2:expr,
$weight3:expr => $item3:expr,
- $weight4:expr => $item4:expr $(,)?) => {
+ $weight4:expr => $item4:expr $(,)?) => {{
+ #[allow(clippy::arc_with_non_send_sync)]
$crate::strategy::TupleUnion::new(
(($weight0, $crate::std_facade::Arc::new($item0)),
($weight1, $crate::std_facade::Arc::new($item1)),
($weight2, $crate::std_facade::Arc::new($item2)),
($weight3, $crate::std_facade::Arc::new($item3)),
($weight4, $crate::std_facade::Arc::new($item4))))
- };
+ }};
($weight0:expr => $item0:expr,
$weight1:expr => $item1:expr,
$weight2:expr => $item2:expr,
$weight3:expr => $item3:expr,
$weight4:expr => $item4:expr,
- $weight5:expr => $item5:expr $(,)?) => {
+ $weight5:expr => $item5:expr $(,)?) => {{
+ #[allow(clippy::arc_with_non_send_sync)]
$crate::strategy::TupleUnion::new(
(($weight0, $crate::std_facade::Arc::new($item0)),
($weight1, $crate::std_facade::Arc::new($item1)),
@@ -386,7 +398,7 @@ macro_rules! prop_oneof {
($weight3, $crate::std_facade::Arc::new($item3)),
($weight4, $crate::std_facade::Arc::new($item4)),
($weight5, $crate::std_facade::Arc::new($item5))))
- };
+ }};
($weight0:expr => $item0:expr,
$weight1:expr => $item1:expr,
@@ -394,7 +406,8 @@ macro_rules! prop_oneof {
$weight3:expr => $item3:expr,
$weight4:expr => $item4:expr,
$weight5:expr => $item5:expr,
- $weight6:expr => $item6:expr $(,)?) => {
+ $weight6:expr => $item6:expr $(,)?) => {{
+ #[allow(clippy::arc_with_non_send_sync)]
$crate::strategy::TupleUnion::new(
(($weight0, $crate::std_facade::Arc::new($item0)),
($weight1, $crate::std_facade::Arc::new($item1)),
@@ -403,7 +416,7 @@ macro_rules! prop_oneof {
($weight4, $crate::std_facade::Arc::new($item4)),
($weight5, $crate::std_facade::Arc::new($item5)),
($weight6, $crate::std_facade::Arc::new($item6))))
- };
+ }};
($weight0:expr => $item0:expr,
$weight1:expr => $item1:expr,
@@ -412,7 +425,8 @@ macro_rules! prop_oneof {
$weight4:expr => $item4:expr,
$weight5:expr => $item5:expr,
$weight6:expr => $item6:expr,
- $weight7:expr => $item7:expr $(,)?) => {
+ $weight7:expr => $item7:expr $(,)?) => {{
+ #[allow(clippy::arc_with_non_send_sync)]
$crate::strategy::TupleUnion::new(
(($weight0, $crate::std_facade::Arc::new($item0)),
($weight1, $crate::std_facade::Arc::new($item1)),
@@ -422,7 +436,7 @@ macro_rules! prop_oneof {
($weight5, $crate::std_facade::Arc::new($item5)),
($weight6, $crate::std_facade::Arc::new($item6)),
($weight7, $crate::std_facade::Arc::new($item7))))
- };
+ }};
($weight0:expr => $item0:expr,
$weight1:expr => $item1:expr,
@@ -432,7 +446,8 @@ macro_rules! prop_oneof {
$weight5:expr => $item5:expr,
$weight6:expr => $item6:expr,
$weight7:expr => $item7:expr,
- $weight8:expr => $item8:expr $(,)?) => {
+ $weight8:expr => $item8:expr $(,)?) => {{
+ #[allow(clippy::arc_with_non_send_sync)]
$crate::strategy::TupleUnion::new(
(($weight0, $crate::std_facade::Arc::new($item0)),
($weight1, $crate::std_facade::Arc::new($item1)),
@@ -443,7 +458,7 @@ macro_rules! prop_oneof {
($weight6, $crate::std_facade::Arc::new($item6)),
($weight7, $crate::std_facade::Arc::new($item7)),
($weight8, $crate::std_facade::Arc::new($item8))))
- };
+ }};
($weight0:expr => $item0:expr,
$weight1:expr => $item1:expr,
@@ -454,7 +469,8 @@ macro_rules! prop_oneof {
$weight6:expr => $item6:expr,
$weight7:expr => $item7:expr,
$weight8:expr => $item8:expr,
- $weight9:expr => $item9:expr $(,)?) => {
+ $weight9:expr => $item9:expr $(,)?) => {{
+ #[allow(clippy::arc_with_non_send_sync)]
$crate::strategy::TupleUnion::new(
(($weight0, $crate::std_facade::Arc::new($item0)),
($weight1, $crate::std_facade::Arc::new($item1)),
@@ -466,7 +482,7 @@ macro_rules! prop_oneof {
($weight7, $crate::std_facade::Arc::new($item7)),
($weight8, $crate::std_facade::Arc::new($item8)),
($weight9, $crate::std_facade::Arc::new($item9))))
- };
+ }};
($($weight:expr => $item:expr),+ $(,)?) => {
$crate::strategy::Union::new_weighted(vec![
diff --git a/vendor/proptest/src/test_runner/config.rs b/vendor/proptest/src/test_runner/config.rs
index 04940abc4..232de951b 100644
--- a/vendor/proptest/src/test_runner/config.rs
+++ b/vendor/proptest/src/test_runner/config.rs
@@ -356,7 +356,8 @@ pub struct Config {
/// meaning of certain levels other than 0 is subject to change.
///
/// - 0: No extra output.
- /// - 1: Log test failure messages.
+ /// - 1: Log test failure messages. In state machine tests, this level is
+ /// used to print transitions.
/// - 2: Trace low-level details.
///
/// This is only available with the `std` feature (enabled by default)
diff --git a/vendor/proptest/src/test_runner/failure_persistence/file.rs b/vendor/proptest/src/test_runner/failure_persistence/file.rs
index 61d7dcf6a..21799adb2 100644
--- a/vendor/proptest/src/test_runner/failure_persistence/file.rs
+++ b/vendor/proptest/src/test_runner/failure_persistence/file.rs
@@ -39,12 +39,11 @@ pub enum FileFailurePersistence {
/// `Direct("NUL")` on Windows (though it is internally handled by simply
/// not doing any I/O).
Off,
- /// The path given to `TestRunner::set_source_file()` is parsed. The path
- /// is traversed up the directory tree until a directory containing a file
- /// named `lib.rs` or `main.rs` is found. A sibling to that directory with
- /// the name given by the string in this configuration is created, and a
- /// file with the same name and path relative to the source directory, but
- /// with the extension changed to `.txt`, is used.
+ /// The path of the source file under test is traversed up the directory tree
+ /// until a directory containing a file named `lib.rs` or `main.rs` is found.
+ /// A sibling to that directory with the name given by the string in this
+ /// configuration is created, and a file with the same name and path relative
+ /// to the source directory, but with the extension changed to `.txt`, is used.
///
/// For example, given a source path of
/// `/home/jsmith/code/project/src/foo/bar.rs` and a configuration of
@@ -58,9 +57,9 @@ pub enum FileFailurePersistence {
/// If no source file has been configured, a warning is printed and this
/// behaves like `Off`.
SourceParallel(&'static str),
- /// The path given to `TestRunner::set_source_file()` is parsed. The
- /// extension of the path is changed to the string given in this
- /// configuration, and that filename is used.
+ /// Failures are persisted in a file with the same path as the source file
+ /// under test, but the extension is changed to the string given in this
+ /// configuration.
///
/// For example, given a source path of
/// `/home/jsmith/code/project/src/foo/bar.rs` and a configuration of
@@ -151,7 +150,7 @@ impl FailurePersistence for FileFailurePersistence {
path.display(),
e
);
- } else if is_new {
+ } else {
eprintln!(
"proptest: Saving this and future failures in {}\n\
proptest: If this test was run on a CI system, you may \
diff --git a/vendor/proptest/src/test_runner/rng.rs b/vendor/proptest/src/test_runner/rng.rs
index 78c8d7a75..31dd3a354 100644
--- a/vendor/proptest/src/test_runner/rng.rs
+++ b/vendor/proptest/src/test_runner/rng.rs
@@ -9,9 +9,8 @@
use crate::std_facade::{Arc, String, ToOwned, Vec};
use core::result::Result;
-use core::{fmt, str, u8};
+use core::{fmt, str, u8, convert::TryInto};
-use byteorder::{ByteOrder, LittleEndian};
use rand::{self, Rng, RngCore, SeedableRng};
use rand_chacha::ChaChaRng;
use rand_xorshift::XorShiftRng;
@@ -137,7 +136,7 @@ impl RngCore for TestRng {
&mut TestRngImpl::PassThrough { .. } => {
let mut buf = [0; 4];
self.fill_bytes(&mut buf[..]);
- LittleEndian::read_u32(&buf[..])
+ u32::from_le_bytes(buf)
}
&mut TestRngImpl::Recorder {
@@ -160,7 +159,7 @@ impl RngCore for TestRng {
&mut TestRngImpl::PassThrough { .. } => {
let mut buf = [0; 8];
self.fill_bytes(&mut buf[..]);
- LittleEndian::read_u64(&buf[..])
+ u64::from_le_bytes(buf)
}
&mut TestRngImpl::Recorder {
@@ -302,7 +301,9 @@ impl Seed {
}
let mut seed = [0u8; 16];
- LittleEndian::write_u32_into(&dwords[..], &mut seed[..]);
+ for (chunk, dword) in seed.chunks_mut(4).zip(dwords) {
+ chunk.copy_from_slice(&dword.to_le_bytes());
+ }
Some(Seed::XorShift(seed))
}
@@ -354,8 +355,12 @@ impl Seed {
match *self {
Seed::XorShift(ref seed) => {
- let mut dwords = [0u32; 4];
- LittleEndian::read_u32_into(seed, &mut dwords[..]);
+ let dwords = [
+ u32::from_le_bytes(seed[0..4].try_into().unwrap()),
+ u32::from_le_bytes(seed[4..8].try_into().unwrap()),
+ u32::from_le_bytes(seed[8..12].try_into().unwrap()),
+ u32::from_le_bytes(seed[12..16].try_into().unwrap()),
+ ];
format!(
"{} {} {} {} {}",
RngAlgorithm::XorShift.persistence_key(),
diff --git a/vendor/proptest/src/test_runner/runner.rs b/vendor/proptest/src/test_runner/runner.rs
index ce540499e..27d0ddf82 100644
--- a/vendor/proptest/src/test_runner/runner.rs
+++ b/vendor/proptest/src/test_runner/runner.rs
@@ -39,7 +39,9 @@ use crate::test_runner::rng::TestRng;
const ENV_FORK_FILE: &'static str = "_PROPTEST_FORKFILE";
const ALWAYS: u32 = 0;
-const SHOW_FALURES: u32 = 1;
+/// Verbose level 1 to show failures. In state machine tests this level is used
+/// to print transitions.
+pub const INFO_LOG: u32 = 1;
const TRACE: u32 = 2;
#[cfg(feature = "std")]
@@ -279,18 +281,12 @@ where
match result {
Ok(()) => verbose_message!(runner, TRACE, "Test case passed"),
- Err(TestCaseError::Reject(ref reason)) => verbose_message!(
- runner,
- SHOW_FALURES,
- "Test case rejected: {}",
- reason
- ),
- Err(TestCaseError::Fail(ref reason)) => verbose_message!(
- runner,
- SHOW_FALURES,
- "Test case failed: {}",
- reason
- ),
+ Err(TestCaseError::Reject(ref reason)) => {
+ verbose_message!(runner, INFO_LOG, "Test case rejected: {}", reason)
+ }
+ Err(TestCaseError::Fail(ref reason)) => {
+ verbose_message!(runner, INFO_LOG, "Test case failed: {}", reason)
+ }
}
result.map(|_| {