Skip to content

Commit

Permalink
Test laziness
Browse files Browse the repository at this point in the history
  • Loading branch information
Philippe-Cholet committed Jan 25, 2024
1 parent b785403 commit 7500f83
Showing 1 changed file with 262 additions and 0 deletions.
262 changes: 262 additions & 0 deletions tests/laziness.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,262 @@
#![allow(unstable_name_collisions, deprecated)]

use itertools::Itertools;

#[derive(Debug, Clone)]
#[must_use = "iterators are lazy and do nothing unless consumed"]
struct Panicking;

impl Iterator for Panicking {
type Item = u8;

fn next(&mut self) -> Option<u8> {
panic!("iterator adaptor is not lazy")
}

fn size_hint(&self) -> (usize, Option<usize>) {
(0, Some(0))
}
}

impl ExactSizeIterator for Panicking {}

/// ## Usage example
/// ```compile_fail
/// must_use_tests! {
/// name {
/// Panicking.name(); // Add `let _ =` only if required (encountered error).
/// }
/// // ...
/// }
/// ```
///
/// **TODO:** test missing `must_use` attributes better.
macro_rules! must_use_tests {
($($name:ident $body:block)*) => {
$(
/// `#[deny(unused_must_use)]` should force us to ignore the resulting iterators
/// by adding `let _ = ...;` on every iterator.
/// If it does not, then a `must_use` attribute is missing on the associated struct.
///
/// However, it's only helpful if we don't add `let _ =` before seeing if there is an error or not.
/// And it does not protect us against removed `must_use` attributes.
/// There is no simple way to test this yet.
#[deny(unused_must_use)]
#[test]
fn $name() $body
)*
};
}

must_use_tests! {
// Itertools trait:
interleave {
let _ = Panicking.interleave(Panicking);
}
interleave_shortest {
let _ = Panicking.interleave_shortest(Panicking);
}
intersperse {
let _ = Panicking.intersperse(0);
}
intersperse_with {
let _ = Panicking.intersperse_with(|| 0);
}
zip_longest {
let _ = Panicking.zip_longest(Panicking);
}
zip_eq {
let _ = Panicking.zip_eq(Panicking);
}
batching {
let _ = Panicking.batching(Iterator::next);
}
group_by {
let _ = Panicking.group_by(|x| *x);
}
chunks {
let _ = Panicking.chunks(1);
let _ = Panicking.chunks(2);
}
tuple_windows {
let _ = Panicking.tuple_windows::<(_,)>();
let _ = Panicking.tuple_windows::<(_, _)>();
let _ = Panicking.tuple_windows::<(_, _, _)>();
}
circular_tuple_windows {
let _ = Panicking.circular_tuple_windows::<(_,)>();
let _ = Panicking.circular_tuple_windows::<(_, _)>();
let _ = Panicking.circular_tuple_windows::<(_, _, _)>();
}
tuples {
let _ = Panicking.tuples::<(_,)>();
let _ = Panicking.tuples::<(_, _)>();
let _ = Panicking.tuples::<(_, _, _)>();
}
tee {
let _ = Panicking.tee();
}
step {
let _ = Panicking.step(2);
}
map_into {
let _ = Panicking.map_into::<u16>();
}
map_ok {
let _ = Panicking.map(Ok::<u8, ()>).map_ok(|x| x + 1);
}
filter_ok {
let _ = Panicking.map(Ok::<u8, ()>).filter_ok(|x| x % 2 == 0);
}
filter_map_ok {
let _ = Panicking.map(Ok::<u8, ()>).filter_map_ok(|x| {
if x % 2 == 0 {
Some(x + 1)
} else {
None
}
});
}
flatten_ok {
let _ = Panicking.map(|x| Ok::<_, ()>([x])).flatten_ok();
}
merge {
let _ = Panicking.merge(Panicking);
}
merge_by {
let _ = Panicking.merge_by(Panicking, |_, _| true);
}
merge_join_by {
let _ = Panicking.merge_join_by(Panicking, |_, _| true);
let _ = Panicking.merge_join_by(Panicking, Ord::cmp);
}
kmerge {
let _ = Panicking.map(|_| Panicking).kmerge();
}
kmerge_by {
let _ = Panicking.map(|_| Panicking).kmerge_by(|_, _| true);
}
cartesian_product {
let _ = Panicking.cartesian_product(Panicking);
}
multi_cartesian_product {
let _ = vec![Panicking, Panicking, Panicking].into_iter().multi_cartesian_product();
}
coalesce {
let _ = Panicking.coalesce(|x, y| if x == y { Ok(x) } else { Err((x, y)) });
}
dedup {
let _ = Panicking.dedup();
}
dedup_by {
let _ = Panicking.dedup_by(|_, _| true);
}
dedup_with_count {
let _ = Panicking.dedup_with_count();
}
dedup_by_with_count {
let _ = Panicking.dedup_by_with_count(|_, _| true);
}
duplicates {
let _ = Panicking.duplicates();
}
duplicates_by {
let _ = Panicking.duplicates_by(|x| *x);
}
unique {
let _ = Panicking.unique();
}
unique_by {
let _ = Panicking.unique_by(|x| *x);
}
peeking_take_while {
let _ = Panicking.peekable().peeking_take_while(|x| x % 2 == 0);
}
take_while_ref {
let _ = Panicking.take_while_ref(|x| x % 2 == 0);
}
take_while_inclusive {
let _ = Panicking.take_while_inclusive(|x| x % 2 == 0);
}
while_some {
let _ = Panicking.map(Some).while_some();
}
tuple_combinations {
let _ = Panicking.tuple_combinations::<(_,)>();
let _ = Panicking.tuple_combinations::<(_, _)>();
let _ = Panicking.tuple_combinations::<(_, _, _)>();
}
combinations {
let _ = Panicking.combinations(0);
let _ = Panicking.combinations(1);
let _ = Panicking.combinations(2);
}
combinations_with_replacement {
Panicking.combinations_with_replacement(0);
Panicking.combinations_with_replacement(1);
Panicking.combinations_with_replacement(2);
}
permutations {
let _ = Panicking.permutations(0);
let _ = Panicking.permutations(1);
let _ = Panicking.permutations(2);
}
powerset {
let _ = Panicking.powerset();
}
pad_using {
let _ = Panicking.pad_using(25, |_| 10);
}
with_position {
let _ = Panicking.with_position();
}
positions {
let _ = Panicking.positions(|v| v % 2 == 0);
}
update {
let _ = Panicking.update(|n| *n += 1);
}
multipeek {
Panicking.multipeek();
}
// Not iterator themselves but still lazy.
into_grouping_map {
let _ = Panicking.map(|x| (x, x + 1)).into_grouping_map();
}
into_grouping_map_by {
let _ = Panicking.into_grouping_map_by(|x| *x);
}
// Macros:
iproduct {
let _ = itertools::iproduct!(Panicking);
let _ = itertools::iproduct!(Panicking, Panicking);
let _ = itertools::iproduct!(Panicking, Panicking, Panicking);
}
izip {
let _ = itertools::izip!(Panicking);
let _ = itertools::izip!(Panicking, Panicking);
let _ = itertools::izip!(Panicking, Panicking, Panicking);
}
chain {
let _ = itertools::chain!(Panicking);
let _ = itertools::chain!(Panicking, Panicking);
let _ = itertools::chain!(Panicking, Panicking, Panicking);
}
// Free functions:
multizip {
let _ = itertools::multizip((Panicking, Panicking));
}
put_back {
itertools::put_back(Panicking);
itertools::put_back(Panicking).with_value(15);
}
peek_nth {
itertools::peek_nth(Panicking);
}
put_back_n {
itertools::put_back_n(Panicking);
}
rciter {
itertools::rciter(Panicking);
}
}

0 comments on commit 7500f83

Please sign in to comment.