pub mod common;
use common::*;
use std::{
collections::{HashSet, LinkedList, VecDeque},
rc::Rc,
sync::Arc,
};
#[test]
fn empty_range() {
assert!(
char::generator()
.flat_map(|value| value..value)
.check(|_| true)
.is_none()
);
}
#[test]
fn is_same() {
assert!(
char::generator()
.flat_map(|value| (value, same(value)))
.check(|(left, right)| left == right)
.is_none()
);
}
#[test]
fn is_ascii() {
assert!(ascii().check(|value| value.is_ascii()).is_none());
}
#[test]
fn is_digit() {
assert!(digit().check(|value| value.is_ascii_digit()).is_none());
}
#[test]
fn is_alphabetic() {
assert!(
letter()
.check(|value| value.is_ascii_alphabetic())
.is_none()
);
}
#[test]
fn full_does_not_panic() {
assert!(char::generator().check(|_| true).is_none());
}
#[test]
fn exclusive_range_past_surrogate_start_skips_surrogates() {
for c in ('\u{D7FF}'..'\u{E010}').samples(1000) {
let code = c as u32;
assert!(
!(0xD800..0xE000).contains(&code),
"surrogate U+{:04X} generated",
code
);
}
}
#[test]
fn exclusive_range_end_at_e000_skips_surrogates() {
for c in ('a'..'\u{E000}').samples(1000) {
let code = c as u32;
assert!(
code < 0xD800,
"surrogate or post-surrogate U+{:04X} generated",
code
);
}
}
#[test]
fn collects_exhaustively() {
let range = 'a'..='Z';
let set = range
.clone()
.checks(Ok::<_, ()>)
.map(|result| result.into_item())
.collect::<HashSet<_>>();
for letter in range {
assert!(set.contains(&letter));
}
}
macro_rules! collection {
($m:ident, $t:ty, $i:ident) => {
mod $m {
use super::*;
#[test]
fn has_same_count() {
assert!(
Generate::flat_map(0..100usize, |count| (
count,
char::generator().collect_with::<_, $t>(count)
))
.check(|(count, value)| value.$i().count() == count)
.is_none()
);
}
#[test]
fn is_ascii() {
assert!(
ascii()
.collect::<$t>()
.check(|value| value.$i().all(|value| value.is_ascii()))
.is_none()
);
}
#[test]
fn is_digit() {
assert!(
digit()
.collect::<$t>()
.check(|value| value.$i().all(|value| value.is_ascii_digit()))
.is_none()
);
}
#[test]
fn is_alphabetic() {
assert!(
letter()
.collect::<$t>()
.check(|value| value.$i().all(|value| value.is_ascii_alphabetic()))
.is_none()
);
}
#[cfg(feature = "check")]
#[allow(clippy::boxed_local)]
mod check {
use super::*;
#[check(ascii().collect())]
fn is_ascii(value: $t) {
assert!(value.$i().all(|value| value.is_ascii()));
}
#[check(digit().collect())]
fn is_digit(value: $t) {
assert!(value.$i().all(|value| value.is_ascii_digit()));
}
#[check(letter().collect())]
fn is_alphabetic(value: $t) {
assert!(value.$i().all(|value| value.is_ascii_alphabetic()));
}
}
}
};
}
collection!(string, String, chars);
collection!(vec_char, Vec<char>, iter);
collection!(vecdeque_char, VecDeque<char>, iter);
collection!(linked_list, LinkedList<char>, iter);
collection!(box_char, Box<[char]>, iter);
collection!(rc_char, Rc<[char]>, iter);
collection!(arc_char, Arc<[char]>, iter);
#[cfg(feature = "check")]
mod check {
use super::*;
#[check(char::generator().flat_map(|value| value..value))]
fn empty_range(_: char) {}
#[check(char::generator().flat_map(|value| (value, same(value))))]
fn is_same(pair: (char, char)) {
assert_eq!(pair.0, pair.1);
}
#[check(ascii())]
fn is_ascii(value: char) {
assert!(value.is_ascii());
}
#[check(digit())]
fn is_digit(value: char) {
assert!(value.is_ascii_digit());
}
#[check(letter())]
fn is_alphabetic(value: char) {
assert!(value.is_ascii_alphabetic());
}
#[check(_)]
fn full_does_not_panic(_: char) {}
#[check(10usize..=2000)]
fn surrogate_start_skips_surrogates_for_arbitrary_count(count: usize) {
for c in ('\u{D7FF}'..'\u{E010}').samples(count) {
let code = c as u32;
assert!(
!(0xD800..0xE000).contains(&code),
"surrogate U+{:04X} generated",
code
);
}
}
#[check(10usize..=2000)]
fn range_end_at_e000_skips_surrogates_for_arbitrary_count(count: usize) {
for c in ('a'..'\u{E000}').samples(count) {
let code = c as u32;
assert!(
code < 0xD800,
"surrogate or post-surrogate U+{:04X} generated",
code
);
}
}
#[check(0usize..=100)]
fn collect_with_arbitrary_count_has_requested_length(count: usize) {
let value = char::generator()
.collect_with::<_, Vec<char>>(count)
.sample(1.0);
assert_eq!(value.len(), count);
}
}