1use 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;