Skip to main content

asserting/iterator/
mod.rs

1//! Implementations of assertions for `Iterator` values.
2
3use crate::assertions::{
4    AssertElements, AssertIteratorContains, AssertIteratorContainsInAnyOrder,
5    AssertIteratorContainsInOrder, AssertOrderedElements,
6};
7use crate::colored::{
8    mark_all_items_in_collection, mark_missing, mark_missing_string,
9    mark_selected_items_in_collection, mark_unexpected, mark_unexpected_string,
10};
11use crate::expectations::{
12    all_satisfy, any_satisfies, has_at_least_number_of_elements, has_single_element,
13    iterator_contains, iterator_contains_all_in_order, iterator_contains_all_of,
14    iterator_contains_any_of, iterator_contains_exactly, iterator_contains_exactly_in_any_order,
15    iterator_contains_only, iterator_contains_only_once, iterator_contains_sequence,
16    iterator_ends_with, iterator_starts_with, none_satisfies, not, AllSatisfy, AnySatisfies,
17    HasAtLeastNumberOfElements, HasSingleElement, IteratorContains, IteratorContainsAllInOrder,
18    IteratorContainsAllOf, IteratorContainsAnyOf, IteratorContainsExactly,
19    IteratorContainsExactlyInAnyOrder, IteratorContainsOnly, IteratorContainsOnlyOnce,
20    IteratorContainsSequence, IteratorEndsWith, IteratorStartsWith, NoneSatisfies,
21};
22use crate::properties::DefinedOrderProperty;
23use crate::spec::{
24    DiffFormat, Expectation, Expression, FailingStrategy, Invertible, PanicOnFail, Spec,
25};
26use crate::std::cmp::Ordering;
27use crate::std::fmt::Debug;
28use crate::std::mem;
29use crate::std::{format, string::String, vec, vec::Vec};
30use hashbrown::HashSet;
31
32impl<'a, S, T, E, R> AssertIteratorContains<'a, Vec<T>, E, R> for Spec<'a, S, R>
33where
34    S: IntoIterator<Item = T>,
35    T: PartialEq<E> + Debug,
36    E: Debug,
37    R: FailingStrategy,
38{
39    fn contains(self, expected: E) -> Spec<'a, Vec<T>, R> {
40        self.mapping(Vec::from_iter)
41            .expecting(iterator_contains(expected))
42    }
43
44    fn does_not_contain(self, expected: E) -> Spec<'a, Vec<T>, R> {
45        self.mapping(Vec::from_iter)
46            .expecting(not(iterator_contains(expected)))
47    }
48}
49
50impl<T, E> Expectation<Vec<T>> for IteratorContains<E>
51where
52    T: PartialEq<E> + Debug,
53    E: Debug,
54{
55    fn test(&mut self, subject: &Vec<T>) -> bool {
56        subject.iter().any(|e| e == &self.expected)
57    }
58
59    fn message(
60        &self,
61        expression: &Expression<'_>,
62        actual: &Vec<T>,
63        inverted: bool,
64        format: &DiffFormat,
65    ) -> String {
66        let (not, marked_actual) = if inverted {
67            let found_unexpected = actual
68                .iter()
69                .enumerate()
70                .filter_map(|(idx, element)| {
71                    if element == &self.expected {
72                        Some(idx)
73                    } else {
74                        None
75                    }
76                })
77                .collect();
78            let marked_actual = mark_selected_items_in_collection(
79                actual,
80                &found_unexpected,
81                format,
82                mark_unexpected,
83            );
84            ("not ", marked_actual)
85        } else {
86            let marked_actual = mark_all_items_in_collection(actual, format, mark_unexpected);
87            ("", marked_actual)
88        };
89        let marked_expected = mark_missing(&self.expected, format);
90        format!(
91            "expected {expression} to {not}contain {:?}\n   but was: {marked_actual}\n  expected: {not}{marked_expected}",
92            &self.expected,
93        )
94    }
95}
96
97impl<E> Invertible for IteratorContains<E> {}
98
99impl<'a, S, T, E, R> AssertIteratorContainsInAnyOrder<'a, Vec<T>, E, R> for Spec<'a, S, R>
100where
101    S: IntoIterator<Item = T>,
102    T: PartialEq<<E as IntoIterator>::Item> + Debug,
103    E: IntoIterator,
104    <E as IntoIterator>::Item: Debug,
105    R: FailingStrategy,
106{
107    fn contains_exactly_in_any_order(self, expected: E) -> Spec<'a, Vec<T>, R> {
108        self.mapping(Vec::from_iter)
109            .expecting(iterator_contains_exactly_in_any_order(expected))
110    }
111
112    fn contains_any_of(self, expected: E) -> Spec<'a, Vec<T>, R> {
113        self.mapping(Vec::from_iter)
114            .expecting(iterator_contains_any_of(expected))
115    }
116
117    fn does_not_contain_any_of(self, expected: E) -> Spec<'a, Vec<T>, R> {
118        self.mapping(Vec::from_iter)
119            .expecting(not(iterator_contains_any_of(expected)))
120    }
121
122    fn contains_all_of(self, expected: E) -> Spec<'a, Vec<T>, R> {
123        self.mapping(Vec::from_iter)
124            .expecting(iterator_contains_all_of(expected))
125    }
126
127    fn contains_only(self, expected: E) -> Spec<'a, Vec<T>, R> {
128        self.mapping(Vec::from_iter)
129            .expecting(iterator_contains_only(expected))
130    }
131
132    fn contains_only_once(self, expected: E) -> Spec<'a, Vec<T>, R> {
133        self.mapping(Vec::from_iter)
134            .expecting(iterator_contains_only_once(expected))
135    }
136}
137
138impl<T, E> Expectation<Vec<T>> for IteratorContainsExactlyInAnyOrder<E>
139where
140    T: PartialEq<E> + Debug,
141    E: Debug,
142{
143    fn test(&mut self, subject: &Vec<T>) -> bool {
144        let missing = &mut self.missing;
145        let extra = &mut self.extra;
146        *extra = (0..subject.len()).collect();
147
148        let mut subject_values = subject.iter().enumerate().collect::<Vec<_>>();
149        for (expected_index, expected) in self.expected.iter().enumerate() {
150            if let Some(index) = subject_values
151                .iter()
152                .position(|(_, value)| *value == expected)
153            {
154                let (subject_index, _) = subject_values.remove(index);
155                extra.remove(&subject_index);
156            } else {
157                missing.insert(expected_index);
158            }
159        }
160
161        extra.is_empty() && missing.is_empty()
162    }
163
164    fn message(
165        &self,
166        expression: &Expression<'_>,
167        actual: &Vec<T>,
168        _inverted: bool,
169        format: &DiffFormat,
170    ) -> String {
171        let missing = collect_selected_values(&self.missing, &self.expected);
172        let extra = collect_selected_values(&self.extra, actual);
173        let marked_actual =
174            mark_selected_items_in_collection(actual, &self.extra, format, mark_unexpected);
175        let marked_expected =
176            mark_selected_items_in_collection(&self.expected, &self.missing, format, mark_missing);
177
178        format!(
179            r"expected {expression} to contain exactly in any order {:?}
180   but was: {marked_actual}
181  expected: {marked_expected}
182   missing: {missing:?}
183     extra: {extra:?}",
184            &self.expected
185        )
186    }
187}
188
189impl<T, E> Expectation<Vec<T>> for IteratorContainsAnyOf<E>
190where
191    T: PartialEq<E> + Debug,
192    E: Debug,
193{
194    fn test(&mut self, subject: &Vec<T>) -> bool {
195        for expected in &self.expected {
196            if subject.iter().any(|value| value == expected) {
197                return true;
198            }
199        }
200        false
201    }
202
203    fn message(
204        &self,
205        expression: &Expression<'_>,
206        actual: &Vec<T>,
207        inverted: bool,
208        format: &DiffFormat,
209    ) -> String {
210        let (not, marked_actual, marked_expected) = if inverted {
211            let mut found_in_actual = HashSet::new();
212            let mut found_in_expected = HashSet::new();
213            for (exp_idx, expected_item) in self.expected.iter().enumerate() {
214                let found = actual
215                    .iter()
216                    .enumerate()
217                    .filter_map(|(idx, elem)| {
218                        if elem == expected_item {
219                            Some(idx)
220                        } else {
221                            None
222                        }
223                    })
224                    .collect::<Vec<_>>();
225                if !found.is_empty() {
226                    found_in_actual.extend(found);
227                    found_in_expected.insert(exp_idx);
228                }
229            }
230            let marked_actual = mark_selected_items_in_collection(
231                actual,
232                &found_in_actual,
233                format,
234                mark_unexpected,
235            );
236            let marked_expected = mark_selected_items_in_collection(
237                &self.expected,
238                &found_in_expected,
239                format,
240                mark_missing,
241            );
242            ("not ", marked_actual, marked_expected)
243        } else {
244            let marked_actual = mark_all_items_in_collection(actual, format, mark_unexpected);
245            let marked_expected =
246                mark_all_items_in_collection(&self.expected, format, mark_missing);
247            ("", marked_actual, marked_expected)
248        };
249        format!(
250            r"expected {expression} to {not}contain any of {:?}
251   but was: {marked_actual}
252  expected: {not}{marked_expected}",
253            &self.expected,
254        )
255    }
256}
257
258impl<E> Invertible for IteratorContainsAnyOf<E> {}
259
260impl<T, E> Expectation<Vec<T>> for IteratorContainsAllOf<E>
261where
262    T: PartialEq<E> + Debug,
263    E: Debug,
264{
265    fn test(&mut self, subject: &Vec<T>) -> bool {
266        let missing = &mut self.missing;
267
268        for (expected_index, expected) in self.expected.iter().enumerate() {
269            if !subject.iter().any(|value| value == expected) {
270                missing.insert(expected_index);
271            }
272        }
273
274        missing.is_empty()
275    }
276
277    fn message(
278        &self,
279        expression: &Expression<'_>,
280        actual: &Vec<T>,
281        _inverted: bool,
282        format: &DiffFormat,
283    ) -> String {
284        let mut extra = HashSet::new();
285        for (actual_index, actual) in actual.iter().enumerate() {
286            if !self.expected.iter().any(|expected| actual == expected) {
287                extra.insert(actual_index);
288            }
289        }
290        let marked_actual =
291            mark_selected_items_in_collection(actual, &extra, format, mark_unexpected);
292        let marked_expected =
293            mark_selected_items_in_collection(&self.expected, &self.missing, format, mark_missing);
294        let missing = collect_selected_values(&self.missing, &self.expected);
295
296        format!(
297            r"expected {expression} to contain all of {:?}
298   but was: {marked_actual}
299  expected: {marked_expected}
300   missing: {missing:?}",
301            &self.expected,
302        )
303    }
304}
305
306impl<T, E> Expectation<Vec<T>> for IteratorContainsOnly<E>
307where
308    T: PartialEq<E> + Debug,
309    E: Debug,
310{
311    fn test(&mut self, subject: &Vec<T>) -> bool {
312        let extra = &mut self.extra;
313
314        for (actual_index, value) in subject.iter().enumerate() {
315            if !self.expected.iter().any(|expected| value == expected) {
316                extra.insert(actual_index);
317            }
318        }
319
320        extra.is_empty()
321    }
322
323    fn message(
324        &self,
325        expression: &Expression<'_>,
326        actual: &Vec<T>,
327        _inverted: bool,
328        format: &DiffFormat,
329    ) -> String {
330        let mut missing = HashSet::new();
331        for (expected_index, expected) in self.expected.iter().enumerate() {
332            if !actual.iter().any(|value| value == expected) {
333                missing.insert(expected_index);
334            }
335        }
336        let marked_actual =
337            mark_selected_items_in_collection(actual, &self.extra, format, mark_unexpected);
338        let marked_expected =
339            mark_selected_items_in_collection(&self.expected, &missing, format, mark_missing);
340        let extra = collect_selected_values(&self.extra, actual);
341
342        format!(
343            r"expected {expression} to contain only {:?}
344   but was: {marked_actual}
345  expected: {marked_expected}
346     extra: {extra:?}",
347            &self.expected,
348        )
349    }
350}
351
352impl<T, E> Expectation<Vec<T>> for IteratorContainsOnlyOnce<E>
353where
354    T: PartialEq<E> + Debug,
355    E: Debug,
356{
357    fn test(&mut self, subject: &Vec<T>) -> bool {
358        let extra = &mut self.extra;
359        let duplicates = &mut self.duplicates;
360
361        for (actual_index, value) in subject.iter().enumerate() {
362            if let Some(expected) = self.expected.iter().find(|expected| value == *expected) {
363                if subject.iter().filter(|actual| *actual == expected).count() > 1 {
364                    duplicates.insert(actual_index);
365                }
366            } else {
367                extra.insert(actual_index);
368            }
369        }
370
371        duplicates.is_empty() && extra.is_empty()
372    }
373
374    fn message(
375        &self,
376        expression: &Expression<'_>,
377        actual: &Vec<T>,
378        _inverted: bool,
379        format: &DiffFormat,
380    ) -> String {
381        let actual_duplicates_and_extras = self.duplicates.union(&self.extra).copied().collect();
382        let marked_actual = mark_selected_items_in_collection(
383            actual,
384            &actual_duplicates_and_extras,
385            format,
386            mark_unexpected,
387        );
388        let duplicates = collect_selected_values(&self.duplicates, actual);
389        let mut expected_duplicates_and_missing = HashSet::new();
390        for (expected_index, expected) in self.expected.iter().enumerate() {
391            if duplicates.iter().any(|duplicate| *duplicate == expected)
392                || !actual.iter().any(|actual| actual == expected)
393            {
394                expected_duplicates_and_missing.insert(expected_index);
395            }
396        }
397        let marked_expected = mark_selected_items_in_collection(
398            &self.expected,
399            &expected_duplicates_and_missing,
400            format,
401            mark_missing,
402        );
403        let extra = collect_selected_values(&self.extra, actual);
404
405        format!(
406            r"expected {expression} to contain only once {:?}
407     but was: {marked_actual}
408    expected: {marked_expected}
409       extra: {extra:?}
410  duplicates: {duplicates:?}",
411            &self.expected,
412        )
413    }
414}
415
416impl<'a, S, T, E, R> AssertIteratorContainsInOrder<'a, Vec<T>, E, R> for Spec<'a, S, R>
417where
418    S: IntoIterator<Item = T>,
419    <S as IntoIterator>::IntoIter: DefinedOrderProperty,
420    E: IntoIterator,
421    <E as IntoIterator>::IntoIter: DefinedOrderProperty,
422    <E as IntoIterator>::Item: Debug,
423    T: PartialEq<<E as IntoIterator>::Item> + Debug,
424    R: FailingStrategy,
425{
426    fn contains_exactly(self, expected: E) -> Spec<'a, Vec<T>, R> {
427        self.mapping(Vec::from_iter)
428            .expecting(iterator_contains_exactly(expected))
429    }
430
431    fn contains_sequence(self, expected: E) -> Spec<'a, Vec<T>, R> {
432        self.mapping(Vec::from_iter)
433            .expecting(iterator_contains_sequence(expected))
434    }
435
436    fn contains_all_in_order(self, expected: E) -> Spec<'a, Vec<T>, R> {
437        self.mapping(Vec::from_iter)
438            .expecting(iterator_contains_all_in_order(expected))
439    }
440
441    fn starts_with(self, expected: E) -> Spec<'a, Vec<T>, R> {
442        self.mapping(Vec::from_iter)
443            .expecting(iterator_starts_with(expected))
444    }
445
446    fn ends_with(self, expected: E) -> Spec<'a, Vec<T>, R> {
447        self.mapping(Vec::from_iter)
448            .expecting(iterator_ends_with(expected))
449    }
450}
451
452impl<T, E> Expectation<Vec<T>> for IteratorContainsExactly<E>
453where
454    T: PartialEq<E> + Debug,
455    E: Debug,
456{
457    fn test(&mut self, subject: &Vec<T>) -> bool {
458        let mut maybe_extras = Vec::new();
459        let mut maybe_missing = Vec::new();
460        let mut expected_iter = self.expected.iter().enumerate();
461        let mut subject_iter = subject.iter().enumerate();
462        loop {
463            match (expected_iter.next(), subject_iter.next()) {
464                (Some((expected_index, expected_value)), Some((subject_index, actual_value))) => {
465                    if actual_value == expected_value {
466                        continue;
467                    }
468                    maybe_missing.push((expected_index, expected_value));
469                    maybe_extras.push((subject_index, actual_value));
470                },
471                (Some(expected), None) => maybe_missing.push(expected),
472                (None, Some(actual)) => maybe_extras.push(actual),
473                (None, None) => break,
474            }
475        }
476
477        let missing = &mut self.missing;
478        let extra = &mut self.extra;
479        let out_of_order = &mut self.out_of_order;
480
481        for (expected_index, expected_value) in maybe_missing {
482            if let Some(index) = maybe_extras
483                .iter()
484                .position(|(_, value)| *value == expected_value)
485            {
486                let (subject_index, _) = maybe_extras.remove(index);
487                out_of_order.insert(subject_index);
488            } else {
489                missing.insert(expected_index);
490            }
491        }
492        for (subject_index, _) in maybe_extras {
493            extra.insert(subject_index);
494        }
495
496        out_of_order.is_empty() && extra.is_empty() && missing.is_empty()
497    }
498
499    fn message(
500        &self,
501        expression: &Expression<'_>,
502        actual: &Vec<T>,
503        _inverted: bool,
504        format: &DiffFormat,
505    ) -> String {
506        let out_of_order = collect_selected_values(&self.out_of_order, actual);
507        let mut expected_indices = self.missing.clone();
508        for (expected_index, expected) in self.expected.iter().enumerate() {
509            if out_of_order.iter().any(|actual| *actual == expected) {
510                expected_indices.insert(expected_index);
511            }
512        }
513        let marked_expected = mark_selected_items_in_collection(
514            &self.expected,
515            &expected_indices,
516            format,
517            mark_missing,
518        );
519        let actual_indices = self.extra.union(&self.out_of_order).copied().collect();
520        let marked_actual =
521            mark_selected_items_in_collection(actual, &actual_indices, format, mark_unexpected);
522
523        let missing = collect_selected_values(&self.missing, &self.expected);
524        let extra = collect_selected_values(&self.extra, actual);
525
526        format!(
527            r"expected {expression} to contain exactly in order {:?}
528       but was: {marked_actual}
529      expected: {marked_expected}
530       missing: {missing:?}
531         extra: {extra:?}
532  out-of-order: {out_of_order:?}",
533            &self.expected,
534        )
535    }
536}
537
538impl<T, E> Expectation<Vec<T>> for IteratorContainsSequence<E>
539where
540    T: PartialEq<E> + Debug,
541    E: Debug,
542{
543    fn test(&mut self, subject: &Vec<T>) -> bool {
544        let subject_length = subject.len();
545        let sequence_length = self.expected.len();
546        let possible_sequence_starts = if sequence_length >= subject_length {
547            vec![0]
548        } else {
549            (0..=subject_length - sequence_length).collect()
550        };
551        let best_missing = &mut self.missing;
552        let best_extra = &mut self.extra;
553        let mut best_match_count = 0;
554        let mut missing = HashSet::new();
555        let mut extra = HashSet::new();
556        let mut match_count = 0;
557        for start_index in possible_sequence_starts {
558            let mut expected_iter = self.expected.iter().enumerate();
559            let mut subject_iter = subject.iter().enumerate().skip(start_index);
560            loop {
561                match (expected_iter.next(), subject_iter.next()) {
562                    (
563                        Some((expected_index, expected_value)),
564                        Some((subject_index, actual_value)),
565                    ) => {
566                        if actual_value == expected_value {
567                            match_count += 1;
568                            continue;
569                        }
570                        missing.insert(expected_index);
571                        extra.insert(subject_index);
572                    },
573                    (Some((expected_index, _)), None) => {
574                        missing.insert(expected_index);
575                    },
576                    (None, _) => break,
577                }
578            }
579            if missing.is_empty() && extra.is_empty() {
580                *best_missing = HashSet::new();
581                *best_extra = HashSet::new();
582                return true;
583            }
584            match match_count.cmp(&best_match_count) {
585                Ordering::Less => {
586                    missing.clear();
587                    extra.clear();
588                },
589                Ordering::Equal => {
590                    best_missing.extend(mem::replace(&mut missing, HashSet::new()));
591                    best_extra.extend(mem::replace(&mut extra, HashSet::new()));
592                },
593                Ordering::Greater => {
594                    best_match_count = match_count;
595                    *best_missing = mem::replace(&mut missing, HashSet::new());
596                    *best_extra = mem::replace(&mut extra, HashSet::new());
597                },
598            }
599            match_count = 0;
600        }
601        false
602    }
603
604    fn message(
605        &self,
606        expression: &Expression<'_>,
607        actual: &Vec<T>,
608        _inverted: bool,
609        format: &DiffFormat,
610    ) -> String {
611        let marked_actual =
612            mark_selected_items_in_collection(actual, &self.extra, format, mark_unexpected);
613        let marked_expected =
614            mark_selected_items_in_collection(&self.expected, &self.missing, format, mark_missing);
615        let missing = collect_selected_values(&self.missing, &self.expected);
616        let extra = collect_selected_values(&self.extra, actual);
617
618        format!(
619            r"expected {expression} to contain the sequence {:?}
620   but was: {marked_actual}
621  expected: {marked_expected}
622   missing: {missing:?}
623     extra: {extra:?}",
624            &self.expected,
625        )
626    }
627}
628
629impl<T, E> Expectation<Vec<T>> for IteratorContainsAllInOrder<E>
630where
631    T: PartialEq<E> + Debug,
632    E: Debug,
633{
634    fn test(&mut self, subject: &Vec<T>) -> bool {
635        let missing = &mut self.missing;
636        let mut last_match_index = 0;
637        for (expected_index, expected) in self.expected.iter().enumerate() {
638            if let Some((subject_index, _)) = subject
639                .iter()
640                .enumerate()
641                .skip(last_match_index)
642                .find(|(_, actual)| *actual == expected)
643            {
644                last_match_index = subject_index + 1;
645            } else {
646                missing.insert(expected_index);
647            }
648        }
649        missing.is_empty()
650    }
651
652    fn message(
653        &self,
654        expression: &Expression<'_>,
655        actual: &Vec<T>,
656        _inverted: bool,
657        format: &DiffFormat,
658    ) -> String {
659        let marked_expected =
660            mark_selected_items_in_collection(&self.expected, &self.missing, format, mark_missing);
661        let missing = collect_selected_values(&self.missing, &self.expected);
662
663        format!(
664            r"expected {expression} to contain all of {:?} in order
665   but was: {actual:?}
666  expected: {marked_expected}
667   missing: {missing:?}",
668            &self.expected,
669        )
670    }
671}
672
673impl<T, E> Expectation<Vec<T>> for IteratorStartsWith<E>
674where
675    T: PartialEq<E> + Debug,
676    E: Debug,
677{
678    fn test(&mut self, subject: &Vec<T>) -> bool {
679        let missing = &mut self.missing;
680        let extra = &mut self.extra;
681        let mut expected_iter = self.expected.iter().enumerate();
682        let mut subject_iter = subject.iter().enumerate();
683        loop {
684            match (expected_iter.next(), subject_iter.next()) {
685                (Some((expected_index, expected)), Some((subject_index, actual))) => {
686                    if actual == expected {
687                        continue;
688                    }
689                    missing.insert(expected_index);
690                    extra.insert(subject_index);
691                },
692                (Some((expected_index, _)), None) => {
693                    missing.insert(expected_index);
694                },
695                (None, _) => break,
696            }
697        }
698        extra.is_empty() && missing.is_empty()
699    }
700
701    fn message(
702        &self,
703        expression: &Expression<'_>,
704        actual: &Vec<T>,
705        _inverted: bool,
706        format: &DiffFormat,
707    ) -> String {
708        let marked_actual =
709            mark_selected_items_in_collection(actual, &self.extra, format, mark_unexpected);
710        let marked_expected =
711            mark_selected_items_in_collection(&self.expected, &self.missing, format, mark_missing);
712        let missing = collect_selected_values(&self.missing, &self.expected);
713        let extra = collect_selected_values(&self.extra, actual);
714
715        format!(
716            r"expected {expression} to start with {:?}
717   but was: {marked_actual}
718  expected: {marked_expected}
719   missing: {missing:?}
720     extra: {extra:?}",
721            &self.expected,
722        )
723    }
724}
725
726impl<T, E> Expectation<Vec<T>> for IteratorEndsWith<E>
727where
728    T: PartialEq<E> + Debug,
729    E: Debug,
730{
731    fn test(&mut self, subject: &Vec<T>) -> bool {
732        let missing = &mut self.missing;
733        let extra = &mut self.extra;
734        let mut expected_iter = self.expected.iter().enumerate().rev();
735        let mut subject_iter = subject.iter().enumerate().rev();
736        loop {
737            match (expected_iter.next(), subject_iter.next()) {
738                (Some((expected_index, expected)), Some((subject_index, actual))) => {
739                    if actual == expected {
740                        continue;
741                    }
742                    missing.insert(expected_index);
743                    extra.insert(subject_index);
744                },
745                (Some((expected_index, _)), None) => {
746                    missing.insert(expected_index);
747                },
748                (None, _) => break,
749            }
750        }
751        extra.is_empty() && missing.is_empty()
752    }
753
754    fn message(
755        &self,
756        expression: &Expression<'_>,
757        actual: &Vec<T>,
758        _inverted: bool,
759        format: &DiffFormat,
760    ) -> String {
761        let marked_actual =
762            mark_selected_items_in_collection(actual, &self.extra, format, mark_unexpected);
763        let marked_expected =
764            mark_selected_items_in_collection(&self.expected, &self.missing, format, mark_missing);
765        let missing = collect_selected_values(&self.missing, &self.expected);
766        let extra = collect_selected_values(&self.extra, actual);
767
768        format!(
769            r"expected {expression} to end with {:?}
770   but was: {marked_actual}
771  expected: {marked_expected}
772   missing: {missing:?}
773     extra: {extra:?}",
774            &self.expected,
775        )
776    }
777}
778
779impl<'a, S, T, R> AssertElements<'a, T, R> for Spec<'a, S, R>
780where
781    S: IntoIterator<Item = T>,
782    T: Debug,
783    R: FailingStrategy,
784{
785    fn single_element(self) -> Spec<'a, T, R> {
786        let spec = self.mapping(Vec::from_iter).expecting(has_single_element());
787        if spec.has_failures() {
788            PanicOnFail.do_fail_with(&spec.failures());
789            unreachable!("Assertion failed and should have panicked! Please report a bug.")
790        }
791        spec.extracting(|mut collection| {
792            collection.pop().unwrap_or_else(|| {
793                unreachable!("Assertion failed and should have panicked! Please report a bug.")
794            })
795        })
796    }
797
798    fn filtered_on<C>(self, condition: C) -> Spec<'a, Vec<T>, R>
799    where
800        C: FnMut(&T) -> bool,
801    {
802        self.mapping(|subject| subject.into_iter().filter(condition).collect())
803    }
804
805    fn any_satisfies<P>(self, predicate: P) -> Spec<'a, Vec<T>, R>
806    where
807        P: FnMut(&T) -> bool,
808    {
809        self.mapping(Vec::from_iter)
810            .expecting(any_satisfies(predicate))
811    }
812
813    fn all_satisfy<P>(self, predicate: P) -> Spec<'a, Vec<T>, R>
814    where
815        P: FnMut(&T) -> bool,
816    {
817        self.mapping(Vec::from_iter)
818            .expecting(all_satisfy(predicate))
819    }
820
821    fn none_satisfies<P>(self, predicate: P) -> Spec<'a, Vec<T>, R>
822    where
823        P: FnMut(&T) -> bool,
824    {
825        self.mapping(Vec::from_iter)
826            .expecting(none_satisfies(predicate))
827    }
828}
829
830impl<T> Expectation<Vec<T>> for HasSingleElement
831where
832    T: Debug,
833{
834    fn test(&mut self, subject: &Vec<T>) -> bool {
835        subject.len() == 1
836    }
837
838    fn message(
839        &self,
840        expression: &Expression<'_>,
841        actual: &Vec<T>,
842        _inverted: bool,
843        format: &DiffFormat,
844    ) -> String {
845        let actual_length = actual.len();
846        let actual_elements = match actual_length {
847            0 => mark_unexpected_string("no elements", format),
848            1 => mark_unexpected_string("exactly one element", format),
849            _ => mark_unexpected_string(&format!("{actual_length} elements"), format),
850        };
851        let expected_elements = mark_missing_string("exactly one element", format);
852        format!(
853            r"expected {expression} to have {expected_elements}, but has {actual_elements}
854  actual: {actual:?}"
855        )
856    }
857}
858
859impl<T, P> Expectation<Vec<T>> for AnySatisfies<P>
860where
861    T: Debug,
862    P: FnMut(&T) -> bool,
863{
864    fn test(&mut self, subject: &Vec<T>) -> bool {
865        subject.iter().any(|e| (self.predicate)(e))
866    }
867
868    fn message(
869        &self,
870        expression: &Expression<'_>,
871        actual: &Vec<T>,
872        _inverted: bool,
873        _format: &DiffFormat,
874    ) -> String {
875        format!(
876            r"expected any element of {expression} to satisfy the predicate, but none did
877  actual: {actual:?}"
878        )
879    }
880}
881
882impl<T, P> Expectation<Vec<T>> for AllSatisfy<P>
883where
884    T: Debug,
885    P: FnMut(&T) -> bool,
886{
887    fn test(&mut self, subject: &Vec<T>) -> bool {
888        for (i, e) in subject.iter().enumerate() {
889            if !(self.predicate)(e) {
890                self.failing.insert(i);
891            }
892        }
893        self.failing.is_empty()
894    }
895
896    fn message(
897        &self,
898        expression: &Expression<'_>,
899        actual: &Vec<T>,
900        _inverted: bool,
901        format: &DiffFormat,
902    ) -> String {
903        let number_of_failing = self.failing.len();
904        let failing = collect_selected_values(&self.failing, actual);
905        let marked_actual =
906            mark_selected_items_in_collection(actual, &self.failing, format, mark_unexpected);
907        format!(
908            r"expected all elements of {expression} to satisfy the predicate, but {number_of_failing} did not
909   actual: {marked_actual}
910  failing: {failing:?}"
911        )
912    }
913}
914
915impl<T, P> Expectation<Vec<T>> for NoneSatisfies<P>
916where
917    T: Debug,
918    P: FnMut(&T) -> bool,
919{
920    fn test(&mut self, subject: &Vec<T>) -> bool {
921        for (i, e) in subject.iter().enumerate() {
922            if (self.predicate)(e) {
923                self.failing.insert(i);
924            }
925        }
926        self.failing.is_empty()
927    }
928
929    fn message(
930        &self,
931        expression: &Expression<'_>,
932        actual: &Vec<T>,
933        _inverted: bool,
934        format: &DiffFormat,
935    ) -> String {
936        let number_of_failing = self.failing.len();
937        let failing = collect_selected_values(&self.failing, actual);
938        let marked_actual =
939            mark_selected_items_in_collection(actual, &self.failing, format, mark_unexpected);
940        format!(
941            r"expected none of the elements of {expression} to satisfy the predicate, but {number_of_failing} did
942   actual: {marked_actual}
943  failing: {failing:?}"
944        )
945    }
946}
947
948impl<'a, S, T, R> AssertOrderedElements<'a, T, R> for Spec<'a, S, R>
949where
950    S: IntoIterator<Item = T>,
951    <S as IntoIterator>::IntoIter: DefinedOrderProperty,
952    T: Debug,
953    R: FailingStrategy,
954{
955    fn first_element(self) -> Spec<'a, T, R> {
956        let spec = self
957            .mapping(Vec::from_iter)
958            .expecting(has_at_least_number_of_elements(1));
959        if spec.has_failures() {
960            PanicOnFail.do_fail_with(&spec.failures());
961            unreachable!("Assertion failed and should have panicked! Please report a bug.")
962        }
963        spec.extracting(|mut collection| collection.remove(0))
964    }
965
966    fn last_element(self) -> Spec<'a, T, R> {
967        let spec = self
968            .mapping(Vec::from_iter)
969            .expecting(has_at_least_number_of_elements(1));
970        if spec.has_failures() {
971            PanicOnFail.do_fail_with(&spec.failures());
972            unreachable!("Assertion failed and should have panicked! Please report a bug.")
973        }
974        spec.extracting(|mut collection| {
975            collection.pop().unwrap_or_else(|| {
976                unreachable!("Assertion failed and should have panicked! Please report a bug.")
977            })
978        })
979    }
980
981    fn nth_element(self, n: usize) -> Spec<'a, T, R> {
982        let min_len = n + 1;
983        let spec = self
984            .mapping(Vec::from_iter)
985            .expecting(has_at_least_number_of_elements(min_len));
986        if spec.has_failures() {
987            PanicOnFail.do_fail_with(&spec.failures());
988            unreachable!("Assertion failed and should have panicked! Please report a bug.")
989        }
990        spec.extracting(|mut collection| collection.remove(n))
991    }
992
993    fn elements_at(self, indices: impl IntoIterator<Item = usize>) -> Spec<'a, Vec<T>, R> {
994        let indices = HashSet::<_>::from_iter(indices);
995        self.mapping(|subject| {
996            subject
997                .into_iter()
998                .enumerate()
999                .filter_map(|(i, v)| if indices.contains(&i) { Some(v) } else { None })
1000                .collect()
1001        })
1002    }
1003}
1004
1005impl<T> Expectation<Vec<T>> for HasAtLeastNumberOfElements
1006where
1007    T: Debug,
1008{
1009    fn test(&mut self, subject: &Vec<T>) -> bool {
1010        subject.len() >= self.expected_number_of_elements
1011    }
1012
1013    fn message(
1014        &self,
1015        expression: &Expression<'_>,
1016        actual: &Vec<T>,
1017        _inverted: bool,
1018        format: &DiffFormat,
1019    ) -> String {
1020        let actual_length = actual.len();
1021        let actual_elements = match actual_length {
1022            0 => mark_unexpected_string("no elements", format),
1023            1 => mark_unexpected_string("one element", format),
1024            _ => mark_unexpected_string(&format!("{actual_length} elements"), format),
1025        };
1026        let expected_elements = match self.expected_number_of_elements {
1027            0 => mark_missing_string("no elements", format),
1028            1 => mark_missing_string("at least one element", format),
1029            _ => mark_missing_string(
1030                &format!("at least {} elements", self.expected_number_of_elements),
1031                format,
1032            ),
1033        };
1034        format!(
1035            r"expected {expression} to have {expected_elements}, but has {actual_elements}
1036  actual: {actual:?}"
1037        )
1038    }
1039}
1040
1041pub fn collect_selected_values<'a, T>(indices: &HashSet<usize>, collection: &'a [T]) -> Vec<&'a T> {
1042    collection
1043        .iter()
1044        .enumerate()
1045        .filter_map(|(idx, value)| {
1046            if indices.contains(&idx) {
1047                Some(value)
1048            } else {
1049                None
1050            }
1051        })
1052        .collect()
1053}
1054
1055#[cfg(test)]
1056mod tests;