1use crate::assertions::{
4 AssertIteratorContains, AssertIteratorContainsInAnyOrder, AssertIteratorContainsInOrder,
5};
6use crate::expectations::{
7 IterContains, IterContainsAllInOrder, IterContainsAllOf, IterContainsAnyOf,
8 IterContainsExactly, IterContainsExactlyInAnyOrder, IterContainsOnly, IterContainsOnlyOnce,
9 IterContainsSequence, IterEndsWith, IterStartsWith,
10};
11use crate::properties::DefinedOrderProperty;
12use crate::spec::{Expectation, Expression, FailingStrategy, Spec};
13use crate::std::cmp::Ordering;
14use crate::std::fmt::Debug;
15use crate::std::mem;
16#[cfg(not(feature = "std"))]
17use alloc::{format, string::String, vec, vec::Vec};
18use hashbrown::HashSet;
19
20impl<'a, S, T, E, R> AssertIteratorContains<'a, Vec<T>, E, R> for Spec<'a, S, R>
21where
22 S: IntoIterator<Item = T>,
23 T: PartialEq<E> + Debug,
24 E: Debug,
25 R: FailingStrategy,
26{
27 fn contains(self, expected: E) -> Spec<'a, Vec<T>, R> {
28 self.mapping(Vec::from_iter)
29 .expecting(IterContains { expected })
30 }
31}
32
33impl<T, E> Expectation<Vec<T>> for IterContains<E>
34where
35 T: PartialEq<E> + Debug,
36 E: Debug,
37{
38 fn test(&mut self, subject: &Vec<T>) -> bool {
39 subject.iter().any(|e| e == &self.expected)
40 }
41
42 fn message(&self, expression: Expression<'_>, actual: &Vec<T>) -> String {
43 format!(
44 "expected {expression} to contain {:?}\n but was: {actual:?}\n expected: {:?}",
45 &self.expected, &self.expected
46 )
47 }
48}
49
50impl<'a, S, T, E, R> AssertIteratorContainsInAnyOrder<'a, Vec<T>, E, R> for Spec<'a, S, R>
51where
52 S: IntoIterator<Item = T>,
53 T: PartialEq<<E as IntoIterator>::Item> + Debug,
54 E: IntoIterator,
55 <E as IntoIterator>::Item: Debug,
56 R: FailingStrategy,
57{
58 fn contains_exactly_in_any_order(self, expected: E) -> Spec<'a, Vec<T>, R> {
59 self.mapping(Vec::from_iter)
60 .expecting(IterContainsExactlyInAnyOrder::new(Vec::from_iter(expected)))
61 }
62
63 fn contains_any_of(self, expected: E) -> Spec<'a, Vec<T>, R> {
64 self.mapping(Vec::from_iter).expecting(IterContainsAnyOf {
65 expected: Vec::from_iter(expected),
66 })
67 }
68
69 fn contains_all_of(self, expected: E) -> Spec<'a, Vec<T>, R> {
70 self.mapping(Vec::from_iter)
71 .expecting(IterContainsAllOf::new(Vec::from_iter(expected)))
72 }
73
74 fn contains_only(self, expected: E) -> Spec<'a, Vec<T>, R> {
75 self.mapping(Vec::from_iter)
76 .expecting(IterContainsOnly::new(Vec::from_iter(expected)))
77 }
78
79 fn contains_only_once(self, expected: E) -> Spec<'a, Vec<T>, R> {
80 self.mapping(Vec::from_iter)
81 .expecting(IterContainsOnlyOnce::new(Vec::from_iter(expected)))
82 }
83}
84
85impl<T, E> Expectation<Vec<T>> for IterContainsExactlyInAnyOrder<E>
86where
87 T: PartialEq<E> + Debug,
88 E: Debug,
89{
90 fn test(&mut self, subject: &Vec<T>) -> bool {
91 let missing = &mut self.missing;
92 let extra = &mut self.extra;
93 *extra = (0..subject.len()).collect();
94
95 let mut subject_values = subject.iter().enumerate().collect::<Vec<_>>();
96 for (expected_index, expected) in self.expected.iter().enumerate() {
97 if let Some(index) = subject_values
98 .iter()
99 .position(|(_, value)| *value == expected)
100 {
101 let (subject_index, _) = subject_values.remove(index);
102 extra.remove(&subject_index);
103 } else {
104 missing.insert(expected_index);
105 }
106 }
107
108 extra.is_empty() && missing.is_empty()
109 }
110
111 fn message(&self, expression: Expression<'_>, actual: &Vec<T>) -> String {
112 let missing = collect_values(&self.missing, &self.expected);
113 let extra = collect_values(&self.extra, actual);
114
115 format!(
116 r"expected {expression} contains exactly in any order {:?}
117 but was: {actual:?}
118 expected: {:?}
119 missing: {missing:?}
120 extra: {extra:?}",
121 &self.expected, &self.expected
122 )
123 }
124}
125
126impl<T, E> Expectation<Vec<T>> for IterContainsAnyOf<E>
127where
128 T: PartialEq<E> + Debug,
129 E: Debug,
130{
131 fn test(&mut self, subject: &Vec<T>) -> bool {
132 for expected in &self.expected {
133 if subject.iter().any(|value| value == expected) {
134 return true;
135 }
136 }
137 false
138 }
139
140 fn message(&self, expression: Expression<'_>, actual: &Vec<T>) -> String {
141 format!(
142 r"expected {expression} contains any of {:?}, but contained none of them
143 but was: {actual:?}
144 expected: {:?}",
145 &self.expected, &self.expected
146 )
147 }
148}
149
150impl<T, E> Expectation<Vec<T>> for IterContainsAllOf<E>
151where
152 T: PartialEq<E> + Debug,
153 E: Debug,
154{
155 fn test(&mut self, subject: &Vec<T>) -> bool {
156 let missing = &mut self.missing;
157
158 for (expected_index, expected) in self.expected.iter().enumerate() {
159 if !subject.iter().any(|value| value == expected) {
160 missing.insert(expected_index);
161 }
162 }
163
164 missing.is_empty()
165 }
166
167 fn message(&self, expression: Expression<'_>, actual: &Vec<T>) -> String {
168 let missing = collect_values(&self.missing, &self.expected);
169
170 format!(
171 r"expected {expression} contains all of {:?}
172 but was: {actual:?}
173 expected: {:?}
174 missing: {missing:?}",
175 &self.expected, &self.expected
176 )
177 }
178}
179
180impl<T, E> Expectation<Vec<T>> for IterContainsOnly<E>
181where
182 T: PartialEq<E> + Debug,
183 E: Debug,
184{
185 fn test(&mut self, subject: &Vec<T>) -> bool {
186 let extra = &mut self.extra;
187
188 for (actual_index, value) in subject.iter().enumerate() {
189 if !self.expected.iter().any(|expected| value == expected) {
190 extra.insert(actual_index);
191 }
192 }
193
194 extra.is_empty()
195 }
196
197 fn message(&self, expression: Expression<'_>, actual: &Vec<T>) -> String {
198 let extra = collect_values(&self.extra, actual);
199
200 format!(
201 r"expected {expression} contains only {:?}
202 but was: {actual:?}
203 expected: {:?}
204 extra: {extra:?}",
205 &self.expected, &self.expected
206 )
207 }
208}
209
210impl<T, E> Expectation<Vec<T>> for IterContainsOnlyOnce<E>
211where
212 T: PartialEq<E> + Debug,
213 E: Debug,
214{
215 fn test(&mut self, subject: &Vec<T>) -> bool {
216 let extra = &mut self.extra;
217 let duplicates = &mut self.duplicates;
218
219 for (actual_index, value) in subject.iter().enumerate() {
220 if let Some(expected) = self.expected.iter().find(|expected| value == *expected) {
221 if subject.iter().filter(|actual| *actual == expected).count() > 1 {
222 duplicates.insert(actual_index);
223 }
224 } else {
225 extra.insert(actual_index);
226 }
227 }
228
229 duplicates.is_empty() && extra.is_empty()
230 }
231
232 fn message(&self, expression: Expression<'_>, actual: &Vec<T>) -> String {
233 let extra = collect_values(&self.extra, actual);
234 let duplicates = collect_values(&self.duplicates, actual);
235
236 format!(
237 r"expected {expression} contains only once {:?}
238 but was: {actual:?}
239 expected: {:?}
240 extra: {extra:?}
241 duplicates: {duplicates:?}",
242 &self.expected, &self.expected
243 )
244 }
245}
246
247impl<'a, S, T, E, R> AssertIteratorContainsInOrder<'a, Vec<T>, E, R> for Spec<'a, S, R>
248where
249 S: IntoIterator<Item = T>,
250 <S as IntoIterator>::IntoIter: DefinedOrderProperty,
251 E: IntoIterator,
252 <E as IntoIterator>::IntoIter: DefinedOrderProperty,
253 <E as IntoIterator>::Item: Debug,
254 T: PartialEq<<E as IntoIterator>::Item> + Debug,
255 R: FailingStrategy,
256{
257 fn contains_exactly(self, expected: E) -> Spec<'a, Vec<T>, R> {
258 self.mapping(Vec::from_iter)
259 .expecting(IterContainsExactly::new(Vec::from_iter(expected)))
260 }
261
262 fn contains_sequence(self, expected: E) -> Spec<'a, Vec<T>, R> {
263 self.mapping(Vec::from_iter)
264 .expecting(IterContainsSequence::new(Vec::from_iter(expected)))
265 }
266
267 fn contains_all_in_order(self, expected: E) -> Spec<'a, Vec<T>, R> {
268 self.mapping(Vec::from_iter)
269 .expecting(IterContainsAllInOrder::new(Vec::from_iter(expected)))
270 }
271
272 fn starts_with(self, expected: E) -> Spec<'a, Vec<T>, R> {
273 self.mapping(Vec::from_iter)
274 .expecting(IterStartsWith::new(Vec::from_iter(expected)))
275 }
276
277 fn ends_with(self, expected: E) -> Spec<'a, Vec<T>, R> {
278 self.mapping(Vec::from_iter)
279 .expecting(IterEndsWith::new(Vec::from_iter(expected)))
280 }
281}
282
283impl<T, E> Expectation<Vec<T>> for IterContainsExactly<E>
284where
285 T: PartialEq<E> + Debug,
286 E: Debug,
287{
288 fn test(&mut self, subject: &Vec<T>) -> bool {
289 let mut maybe_extras = Vec::new();
290 let mut maybe_missing = Vec::new();
291 let mut expected_iter = self.expected.iter().enumerate();
292 let mut subject_iter = subject.iter().enumerate();
293 loop {
294 match (expected_iter.next(), subject_iter.next()) {
295 (Some((expected_index, expected_value)), Some((subject_index, actual_value))) => {
296 if actual_value == expected_value {
297 continue;
298 }
299 maybe_missing.push((expected_index, expected_value));
300 maybe_extras.push((subject_index, actual_value));
301 },
302 (Some(expected), None) => maybe_missing.push(expected),
303 (None, Some(actual)) => maybe_extras.push(actual),
304 (None, None) => break,
305 }
306 }
307
308 let missing = &mut self.missing;
309 let extra = &mut self.extra;
310 let out_of_order = &mut self.out_of_order;
311
312 for (expected_index, expected_value) in maybe_missing {
313 if let Some(index) = maybe_extras
314 .iter()
315 .position(|(_, value)| *value == expected_value)
316 {
317 let (subject_index, _) = maybe_extras.remove(index);
318 out_of_order.insert(subject_index);
319 } else {
320 missing.insert(expected_index);
321 }
322 }
323 for (subject_index, _) in maybe_extras {
324 extra.insert(subject_index);
325 }
326
327 out_of_order.is_empty() && extra.is_empty() && missing.is_empty()
328 }
329
330 fn message(&self, expression: Expression<'_>, actual: &Vec<T>) -> String {
331 let missing = collect_values(&self.missing, &self.expected);
332 let extra = collect_values(&self.extra, actual);
333 let out_of_order = collect_values(&self.out_of_order, actual);
334
335 format!(
336 r"expected {expression} contains exactly in order {:?}
337 but was: {actual:?}
338 expected: {:?}
339 missing: {missing:?}
340 extra: {extra:?}
341 out-of-order: {out_of_order:?}",
342 &self.expected, &self.expected
343 )
344 }
345}
346
347impl<T, E> Expectation<Vec<T>> for IterContainsSequence<E>
348where
349 T: PartialEq<E> + Debug,
350 E: Debug,
351{
352 fn test(&mut self, subject: &Vec<T>) -> bool {
353 let subject_length = subject.len();
354 let sequence_length = self.expected.len();
355 let possible_sequence_starts = if sequence_length >= subject_length {
356 vec![0]
357 } else {
358 (0..=subject_length - sequence_length).collect()
359 };
360 let best_missing = &mut self.missing;
361 let best_extra = &mut self.extra;
362 let mut best_match_count = 0;
363 let mut missing = HashSet::new();
364 let mut extra = HashSet::new();
365 let mut match_count = 0;
366 for start_index in possible_sequence_starts {
367 let mut expected_iter = self.expected.iter().enumerate();
368 let mut subject_iter = subject.iter().enumerate().skip(start_index);
369 loop {
370 match (expected_iter.next(), subject_iter.next()) {
371 (
372 Some((expected_index, expected_value)),
373 Some((subject_index, actual_value)),
374 ) => {
375 if actual_value == expected_value {
376 match_count += 1;
377 continue;
378 }
379 missing.insert(expected_index);
380 extra.insert(subject_index);
381 },
382 (Some((expected_index, _)), None) => {
383 missing.insert(expected_index);
384 },
385 (None, _) => break,
386 }
387 }
388 if missing.is_empty() && extra.is_empty() {
389 *best_missing = HashSet::new();
390 *best_extra = HashSet::new();
391 return true;
392 }
393 match match_count.cmp(&best_match_count) {
394 Ordering::Less => {
395 missing.clear();
396 extra.clear();
397 },
398 Ordering::Equal => {
399 best_missing.extend(mem::replace(&mut missing, HashSet::new()));
400 best_extra.extend(mem::replace(&mut extra, HashSet::new()));
401 },
402 Ordering::Greater => {
403 best_match_count = match_count;
404 *best_missing = mem::replace(&mut missing, HashSet::new());
405 *best_extra = mem::replace(&mut extra, HashSet::new());
406 },
407 }
408 match_count = 0;
409 }
410 false
411 }
412
413 fn message(&self, expression: Expression<'_>, actual: &Vec<T>) -> String {
414 let missing = collect_values(&self.missing, &self.expected);
415 let extra = collect_values(&self.extra, actual);
416
417 format!(
418 r"expected {expression} contains sequence {:?}
419 but was: {actual:?}
420 expected: {:?}
421 missing: {missing:?}
422 extra: {extra:?}",
423 &self.expected, &self.expected
424 )
425 }
426}
427
428impl<T, E> Expectation<Vec<T>> for IterContainsAllInOrder<E>
429where
430 T: PartialEq<E> + Debug,
431 E: Debug,
432{
433 fn test(&mut self, subject: &Vec<T>) -> bool {
434 let missing = &mut self.missing;
435 let mut last_match_index = 0;
436 for (expected_index, expected) in self.expected.iter().enumerate() {
437 if let Some((subject_index, _)) = subject
438 .iter()
439 .enumerate()
440 .skip(last_match_index)
441 .find(|(_, actual)| *actual == expected)
442 {
443 last_match_index = subject_index + 1;
444 } else {
445 missing.insert(expected_index);
446 }
447 }
448 missing.is_empty()
449 }
450
451 fn message(&self, expression: Expression<'_>, actual: &Vec<T>) -> String {
452 let missing = collect_values(&self.missing, &self.expected);
453
454 format!(
455 r"expected {expression} contains all of {:?} in order
456 but was: {actual:?}
457 expected: {:?}
458 missing: {missing:?}",
459 &self.expected, &self.expected
460 )
461 }
462}
463
464impl<T, E> Expectation<Vec<T>> for IterStartsWith<E>
465where
466 T: PartialEq<E> + Debug,
467 E: Debug,
468{
469 fn test(&mut self, subject: &Vec<T>) -> bool {
470 let missing = &mut self.missing;
471 let extra = &mut self.extra;
472 let mut expected_iter = self.expected.iter().enumerate();
473 let mut subject_iter = subject.iter().enumerate();
474 loop {
475 match (expected_iter.next(), subject_iter.next()) {
476 (Some((expected_index, expected)), Some((subject_index, actual))) => {
477 if actual == expected {
478 continue;
479 }
480 missing.insert(expected_index);
481 extra.insert(subject_index);
482 },
483 (Some((expected_index, _)), None) => {
484 missing.insert(expected_index);
485 },
486 (None, _) => break,
487 }
488 }
489 extra.is_empty() && missing.is_empty()
490 }
491
492 fn message(&self, expression: Expression<'_>, actual: &Vec<T>) -> String {
493 let missing = collect_values(&self.missing, &self.expected);
494 let extra = collect_values(&self.extra, actual);
495
496 format!(
497 r"expected {expression} starts with {:?}
498 but was: {actual:?}
499 expected: {:?}
500 missing: {missing:?}
501 extra: {extra:?}",
502 &self.expected, &self.expected
503 )
504 }
505}
506
507impl<T, E> Expectation<Vec<T>> for IterEndsWith<E>
508where
509 T: PartialEq<E> + Debug,
510 E: Debug,
511{
512 fn test(&mut self, subject: &Vec<T>) -> bool {
513 let missing = &mut self.missing;
514 let extra = &mut self.extra;
515 let mut expected_iter = self.expected.iter().enumerate().rev();
516 let mut subject_iter = subject.iter().enumerate().rev();
517 loop {
518 match (expected_iter.next(), subject_iter.next()) {
519 (Some((expected_index, expected)), Some((subject_index, actual))) => {
520 if actual == expected {
521 continue;
522 }
523 missing.insert(expected_index);
524 extra.insert(subject_index);
525 },
526 (Some((expected_index, _)), None) => {
527 missing.insert(expected_index);
528 },
529 (None, _) => break,
530 }
531 }
532 extra.is_empty() && missing.is_empty()
533 }
534
535 fn message(&self, expression: Expression<'_>, actual: &Vec<T>) -> String {
536 let missing = collect_values(&self.missing, &self.expected);
537 let extra = collect_values(&self.extra, actual);
538
539 format!(
540 r"expected {expression} ends with {:?}
541 but was: {actual:?}
542 expected: {:?}
543 missing: {missing:?}
544 extra: {extra:?}",
545 &self.expected, &self.expected
546 )
547 }
548}
549
550fn collect_values<'a, T>(indices: &HashSet<usize>, collection: &'a [T]) -> Vec<&'a T> {
551 collection
552 .iter()
553 .enumerate()
554 .filter_map(|(idx, value)| {
555 if indices.contains(&idx) {
556 Some(value)
557 } else {
558 None
559 }
560 })
561 .collect()
562}
563
564#[cfg(test)]
565mod tests;