kernal/collections/partial_eq/
btree.rs

1//! Contains equality-based assertions for [Collection]s with items that implement [Eq] and [Ord],
2//! using the additional constraints to optimize runtime. See [CollectionEqOrdAssertions] for more
3//! details.
4
5use std::borrow::Borrow;
6use std::collections::BTreeSet;
7use std::fmt::Debug;
8
9use crate::AssertThat;
10use crate::collections::Collection;
11use crate::collections::partial_eq::{
12    check_contains_all_of,
13    check_contains_exactly_in_any_order,
14    check_contains_none_of
15};
16use crate::util::borrow_all;
17use crate::util::multiset::btree::BTreeMultiset;
18
19/// An extension trait to be used on the output of [assert_that](crate::assert_that) with an
20/// argument that implements the [Collection] trait where the [Collection::Item] type implements
21/// [Eq] and [Ord] in addition to the required [Debug] trait. It offers optimized assertions which
22/// benefit from the additional [Ord] constraint in terms of runtime.
23///
24/// Examples:
25///
26/// ```
27/// use kernal::prelude::*;
28/// use kernal::fast_prelude::*;
29///
30/// assert_that!(&[2, 3, 5, 7, 11])
31///     .contains_exactly_in_any_order_using_ord([3, 7, 2, 11, 5])
32///     .contains_none_of_using_ord([4, 6, 8, 10, 12]);
33/// ```
34pub trait CollectionEqOrdAssertions<'collection, C>
35where
36    C: Collection<'collection>
37{
38    /// Asserts that for each of the given `items`, the tested collection contains an equal element
39    /// according to [Eq] and [Ord]. If the provided iterator contains multiple equal elements, this
40    /// function asserts that the tested collection contains at least that number of equal elements,
41    /// so `[1, 1, 2]` contains all of `[1, 1]`, but not all of `[1, 1, 1]`.
42    ///
43    /// This can be considered a faster alternative to
44    /// [CollectionPartialEqAssertions::contains_all_of](crate::collections::partial_eq::CollectionPartialEqAssertions::contains_all_of)
45    /// with the trade-off of additional trait bounds.
46    fn contains_all_of_using_ord<E, I>(self, items: I) -> Self
47    where
48        E: Borrow<C::Item>,
49        I: IntoIterator<Item = E>;
50
51    /// Asserts that the tested collection contains no element which is equal to one the given
52    /// `items` according to [Eq] and [Ord].
53    ///
54    /// This can be considered a faster alternative to
55    /// [CollectionPartialEqAssertions::contains_none_of](crate::collections::partial_eq::CollectionPartialEqAssertions::contains_none_of)
56    /// with the trade-off of additional trait bounds.
57    fn contains_none_of_using_ord<E, I>(self, items: I) -> Self
58    where
59        E: Borrow<C::Item>,
60        I: IntoIterator<Item = E>;
61
62    /// Asserts that there is a one-to-one matching of the given `items` and the elements of the
63    /// tested collection such that matched elements are equal according to [Eq] and [Ord].
64    ///
65    /// This can be considered a faster alternative to
66    /// [CollectionPartialEqAssertions::contains_exactly_in_any_order](crate::collections::partial_eq::CollectionPartialEqAssertions::contains_exactly_in_any_order)
67    /// with the trade-off of additional trait bounds.
68    fn contains_exactly_in_any_order_using_ord<E, I>(self, items: I) -> Self
69    where
70        E: Borrow<C::Item>,
71        I: IntoIterator<Item = E>;
72}
73
74impl<'collection, C> CollectionEqOrdAssertions<'collection, C> for AssertThat<C>
75where
76    C: Collection<'collection>,
77    C::Item: Debug + Eq + Ord
78{
79    fn contains_all_of_using_ord<E, I>(self, items: I) -> Self
80    where
81        E: Borrow<C::Item>,
82        I: IntoIterator<Item = E>
83    {
84        let expected_items_unborrowed = items.into_iter().collect::<Vec<_>>();
85        let expected_items: Vec<&C::Item> = borrow_all(&expected_items_unborrowed);
86
87        check_contains_all_of::<_, _, BTreeMultiset<_>>(&self, self.data.iterator(), &expected_items);
88
89        self
90    }
91
92    fn contains_none_of_using_ord<E, I>(self, items: I) -> Self
93    where
94        E: Borrow<C::Item>,
95        I: IntoIterator<Item = E>
96    {
97        let unexpected_items_unborrowed = items.into_iter().collect::<Vec<_>>();
98        let unexpected_items: Vec<&C::Item> = borrow_all(&unexpected_items_unborrowed);
99
100        check_contains_none_of::<_, _, BTreeSet<_>>(&self, self.data.iterator(), unexpected_items);
101
102        self
103    }
104
105    fn contains_exactly_in_any_order_using_ord<E, I>(self, items: I) -> Self
106    where
107        E: Borrow<C::Item>,
108        I: IntoIterator<Item = E>
109    {
110        let expected_items_unborrowed = items.into_iter().collect::<Vec<_>>();
111        let expected_items: Vec<&C::Item> = borrow_all(&expected_items_unborrowed);
112
113        check_contains_exactly_in_any_order::<_, _, BTreeMultiset<_>>(
114            &self, self.data.iterator(), &expected_items);
115
116        self
117    }
118}
119
120#[cfg(test)]
121mod tests {
122
123    use crate::{
124        assert_fails,
125        test_contains_all_of,
126        test_contains_exactly_in_any_order,
127        test_contains_none_of
128    };
129    use crate::prelude::*;
130
131    use super::*;
132
133    test_contains_all_of!(contains_all_of_using_ord);
134
135    test_contains_none_of!(contains_none_of_using_ord);
136
137    test_contains_exactly_in_any_order!(contains_exactly_in_any_order_using_ord);
138}