1#[macro_export]
72macro_rules! assert_contains_as_result {
73 ($container:expr, $containee:expr $(,)?) => {
74 match (&$container, &$containee) {
75 (container, containee) => {
76 if (container).contains(*containee) {
77 Ok(())
78 } else {
79 Err(format!(
80 concat!(
81 "assertion failed: `assert_contains!(container, containee)`\n",
82 "https://docs.rs/assertables/9.8.2/assertables/macro.assert_contains.html\n",
83 " container label: `{}`,\n",
84 " container debug: `{:?}`,\n",
85 " containee label: `{}`,\n",
86 " containee debug: `{:?}`",
87 ),
88 stringify!($container),
89 container,
90 stringify!($containee),
91 containee,
92 ))
93 }
94 }
95 }
96 };
97}
98
99#[cfg(test)]
100mod test_assert_contains_as_result {
101 use std::panic;
102 use std::sync::Once;
103
104 mod str {
105 use super::*;
106
107 #[test]
108 fn success() {
109 let a: &'static str = "alfa";
110 let b: &'static str = "lf";
111 for _ in 0..1 {
112 let actual = assert_contains_as_result!(a, b);
113 assert_eq!(actual.unwrap(), ());
114 }
115 }
116
117 #[test]
118 fn success_once() {
119 static A: Once = Once::new();
120 fn a() -> &'static str {
121 if A.is_completed() {
122 panic!("A.is_completed()")
123 } else {
124 A.call_once(|| {})
125 }
126 "alfa"
127 }
128
129 static B: Once = Once::new();
130 fn b() -> &'static str {
131 if B.is_completed() {
132 panic!("B.is_completed()")
133 } else {
134 B.call_once(|| {})
135 }
136 "lf"
137 }
138
139 assert_eq!(A.is_completed(), false);
140 assert_eq!(B.is_completed(), false);
141 let result = assert_contains_as_result!(a(), b());
142 assert!(result.is_ok());
143 assert_eq!(A.is_completed(), true);
144 assert_eq!(B.is_completed(), true);
145 }
146
147 #[test]
148 fn failure() {
149 let a: &'static str = "alfa";
150 let b: &'static str = "xx";
151 let actual = assert_contains_as_result!(a, b);
152 let message = concat!(
153 "assertion failed: `assert_contains!(container, containee)`\n",
154 "https://docs.rs/assertables/9.8.2/assertables/macro.assert_contains.html\n",
155 " container label: `a`,\n",
156 " container debug: `\"alfa\"`,\n",
157 " containee label: `b`,\n",
158 " containee debug: `\"xx\"`"
159 );
160 assert_eq!(actual.unwrap_err(), message);
161 }
162 }
163
164 mod range_i32 {
165 use super::*;
166 use std::ops::Range;
167
168 #[test]
169 fn success() {
170 let a: Range<i32> = 1..3;
171 let b: i32 = 2;
172 for _ in 0..1 {
173 let actual = assert_contains_as_result!(a, &b);
174 assert_eq!(actual.unwrap(), ());
175 }
176 }
177
178 #[test]
179 fn success_once() {
180 static A: Once = Once::new();
181 fn a() -> Range<i32> {
182 if A.is_completed() {
183 panic!("A.is_completed()")
184 } else {
185 A.call_once(|| {})
186 }
187 1..3
188 }
189
190 static B: Once = Once::new();
191 fn b() -> i32 {
192 if B.is_completed() {
193 panic!("B.is_completed()")
194 } else {
195 B.call_once(|| {})
196 }
197 2
198 }
199
200 assert_eq!(A.is_completed(), false);
201 assert_eq!(B.is_completed(), false);
202 let result = assert_contains_as_result!(a(), &b());
203 assert!(result.is_ok());
204 assert_eq!(A.is_completed(), true);
205 assert_eq!(B.is_completed(), true);
206 }
207
208 #[test]
209 fn failure() {
210 let a: Range<i32> = 1..3;
211 let b: i32 = 4;
212 let actual = assert_contains_as_result!(a, &b);
213 let message = concat!(
214 "assertion failed: `assert_contains!(container, containee)`\n",
215 "https://docs.rs/assertables/9.8.2/assertables/macro.assert_contains.html\n",
216 " container label: `a`,\n",
217 " container debug: `1..3`,\n",
218 " containee label: `&b`,\n",
219 " containee debug: `4`"
220 );
221 assert_eq!(actual.unwrap_err(), message);
222 }
223 }
224
225 mod range_string {
226 use super::*;
227 use std::ops::Range;
228
229 #[test]
230 fn success() {
231 let a: Range<String> = String::from("1")..String::from("3");
232 let b: String = String::from("2");
233 for _ in 0..1 {
234 let actual = assert_contains_as_result!(a, &b);
235 assert_eq!(actual.unwrap(), ());
236 }
237 }
238
239 #[test]
240 fn success_once() {
241 static A: Once = Once::new();
242 fn a() -> Range<String> {
243 if A.is_completed() {
244 panic!("A.is_completed()")
245 } else {
246 A.call_once(|| {})
247 }
248 String::from("1")..String::from("3")
249 }
250
251 static B: Once = Once::new();
252 fn b() -> String {
253 if B.is_completed() {
254 panic!("B.is_completed()")
255 } else {
256 B.call_once(|| {})
257 }
258 String::from("2")
259 }
260
261 assert_eq!(A.is_completed(), false);
262 assert_eq!(B.is_completed(), false);
263 let result = assert_contains_as_result!(a(), &b());
264 assert!(result.is_ok());
265 assert_eq!(A.is_completed(), true);
266 assert_eq!(B.is_completed(), true);
267 }
268
269 #[test]
270 fn failure() {
271 let a: Range<String> = String::from("1")..String::from("3");
272 let b: String = String::from("4");
273 let actual = assert_contains_as_result!(a, &b);
274 let message = concat!(
275 "assertion failed: `assert_contains!(container, containee)`\n",
276 "https://docs.rs/assertables/9.8.2/assertables/macro.assert_contains.html\n",
277 " container label: `a`,\n",
278 " container debug: `\"1\"..\"3\"`,\n",
279 " containee label: `&b`,\n",
280 " containee debug: `\"4\"`"
281 );
282 assert_eq!(actual.unwrap_err(), message);
283 }
284 }
285
286 mod vec_i32 {
287 use super::*;
288
289 #[test]
290 fn success() {
291 let a: Vec<i32> = vec![1, 2, 3];
292 let b: i32 = 2;
293 for _ in 0..1 {
294 let actual = assert_contains_as_result!(a, &b);
295 assert_eq!(actual.unwrap(), ());
296 }
297 }
298
299 #[test]
300 fn success_once() {
301 static A: Once = Once::new();
302 fn a() -> Vec<i32> {
303 if A.is_completed() {
304 panic!("A.is_completed()")
305 } else {
306 A.call_once(|| {})
307 }
308 vec![1, 2, 3]
309 }
310
311 static B: Once = Once::new();
312 fn b() -> i32 {
313 if B.is_completed() {
314 panic!("B.is_completed()")
315 } else {
316 B.call_once(|| {})
317 }
318 2
319 }
320
321 assert_eq!(A.is_completed(), false);
322 assert_eq!(B.is_completed(), false);
323 let result = assert_contains_as_result!(a(), &b());
324 assert!(result.is_ok());
325 assert_eq!(A.is_completed(), true);
326 assert_eq!(B.is_completed(), true);
327 }
328
329 #[test]
330 fn failure() {
331 let a: Vec<i32> = vec![1, 2, 3];
332 let b: i32 = 4;
333 let actual = assert_contains_as_result!(a, &b);
334 let message = concat!(
335 "assertion failed: `assert_contains!(container, containee)`\n",
336 "https://docs.rs/assertables/9.8.2/assertables/macro.assert_contains.html\n",
337 " container label: `a`,\n",
338 " container debug: `[1, 2, 3]`,\n",
339 " containee label: `&b`,\n",
340 " containee debug: `4`"
341 );
342 assert_eq!(actual.unwrap_err(), message);
343 }
344 }
345
346 mod vec_string {
347 use super::*;
348
349 #[test]
350 fn success() {
351 let a: Vec<String> = vec![String::from("1"), String::from("2"), String::from("3")];
352 let b: String = String::from("2");
353
354 for _ in 0..1 {
355 let actual = assert_contains_as_result!(a, &b);
356 assert_eq!(actual.unwrap(), ());
357 }
358 }
359
360 #[test]
361 fn success_once() {
362 static A: Once = Once::new();
363 fn a() -> Vec<String> {
364 if A.is_completed() {
365 panic!("A.is_completed()")
366 } else {
367 A.call_once(|| {})
368 }
369 vec![String::from("1"), String::from("2"), String::from("3")]
370 }
371
372 static B: Once = Once::new();
373 fn b() -> String {
374 if B.is_completed() {
375 panic!("B.is_completed()")
376 } else {
377 B.call_once(|| {})
378 }
379 String::from("2")
380 }
381
382 assert_eq!(A.is_completed(), false);
383 assert_eq!(B.is_completed(), false);
384 let result = assert_contains_as_result!(a(), &b());
385 assert!(result.is_ok());
386 assert_eq!(A.is_completed(), true);
387 assert_eq!(B.is_completed(), true);
388 }
389
390 #[test]
391 fn failure() {
392 let a: Vec<String> = vec![String::from("1"), String::from("2"), String::from("3")];
393 let b: String = String::from("4");
394 let actual = assert_contains_as_result!(a, &b);
395 let message = concat!(
396 "assertion failed: `assert_contains!(container, containee)`\n",
397 "https://docs.rs/assertables/9.8.2/assertables/macro.assert_contains.html\n",
398 " container label: `a`,\n",
399 " container debug: `[\"1\", \"2\", \"3\"]`,\n",
400 " containee label: `&b`,\n",
401 " containee debug: `\"4\"`"
402 );
403 assert_eq!(actual.unwrap_err(), message);
404 }
405 }
406
407 mod hashset_string {
408 use super::*;
409 use std::collections::HashSet;
410
411 #[test]
412 fn success() {
413 let a: HashSet<String> = [String::from("1")].into();
414 let b: String = String::from("1");
415 for _ in 0..1 {
416 let actual = assert_contains_as_result!(a, &b);
417 assert_eq!(actual.unwrap(), ());
418 }
419 }
420
421 #[test]
422 fn success_once() {
423 static A: Once = Once::new();
424 fn a() -> HashSet<String> {
425 if A.is_completed() {
426 panic!("A.is_completed()")
427 } else {
428 A.call_once(|| {})
429 }
430 [String::from("1")].into()
431 }
432
433 static B: Once = Once::new();
434 fn b() -> String {
435 if B.is_completed() {
436 panic!("B.is_completed()")
437 } else {
438 B.call_once(|| {})
439 }
440 String::from("1")
441 }
442
443 assert_eq!(A.is_completed(), false);
444 assert_eq!(B.is_completed(), false);
445 let result = assert_contains_as_result!(a(), &b());
446 assert!(result.is_ok());
447 assert_eq!(A.is_completed(), true);
448 assert_eq!(B.is_completed(), true);
449 }
450
451 #[test]
452 fn failure() {
453 let a: HashSet<String> = [String::from("1")].into();
454 let b: String = String::from("2");
455 let actual = assert_contains_as_result!(a, &b);
456 let message = concat!(
457 "assertion failed: `assert_contains!(container, containee)`\n",
458 "https://docs.rs/assertables/9.8.2/assertables/macro.assert_contains.html\n",
459 " container label: `a`,\n",
460 " container debug: `{\"1\"}`,\n",
461 " containee label: `&b`,\n",
462 " containee debug: `\"2\"`"
463 );
464 assert_eq!(actual.unwrap_err(), message);
465 }
466 }
467
468 mod hashset_string_with_str_automatic_borrow_optimization {
469 use super::*;
470 use std::collections::HashSet;
471
472 #[test]
473 fn success() {
474 let a: HashSet<String> = [String::from("1")].into();
475 let b: &'static str = "1";
476 for _ in 0..1 {
477 let actual = assert_contains_as_result!(a, b);
478 assert_eq!(actual.unwrap(), ());
479 }
480 }
481
482 #[test]
483 fn success_once() {
484 static A: Once = Once::new();
485 fn a() -> HashSet<String> {
486 if A.is_completed() {
487 panic!("A.is_completed()")
488 } else {
489 A.call_once(|| {})
490 }
491 [String::from("1")].into()
492 }
493
494 static B: Once = Once::new();
495 fn b() -> &'static str {
496 if B.is_completed() {
497 panic!("B.is_completed()")
498 } else {
499 B.call_once(|| {})
500 }
501 "1"
502 }
503
504 assert_eq!(A.is_completed(), false);
505 assert_eq!(B.is_completed(), false);
506 let result = assert_contains_as_result!(a(), b());
507 assert!(result.is_ok());
508 assert_eq!(A.is_completed(), true);
509 assert_eq!(B.is_completed(), true);
510 }
511
512 #[test]
513 fn failure() {
514 let a: HashSet<String> = [String::from("1")].into();
515 let b: &'static str = "2";
516 let actual = assert_contains_as_result!(a, b);
517 let message = concat!(
518 "assertion failed: `assert_contains!(container, containee)`\n",
519 "https://docs.rs/assertables/9.8.2/assertables/macro.assert_contains.html\n",
520 " container label: `a`,\n",
521 " container debug: `{\"1\"}`,\n",
522 " containee label: `b`,\n",
523 " containee debug: `\"2\"`"
524 );
525 assert_eq!(actual.unwrap_err(), message);
526 }
527 }
528}
529
530#[macro_export]
606macro_rules! assert_contains {
607 ($container:expr, $containee:expr $(,)?) => {
608 match $crate::assert_contains_as_result!($container, $containee) {
609 Ok(()) => (),
610 Err(err) => panic!("{}", err),
611 }
612 };
613 ($container:expr, $containee:expr, $($message:tt)+) => {
614 match $crate::assert_contains_as_result!($container, $containee) {
615 Ok(()) => (),
616 Err(err) => panic!("{}\n{}", format_args!($($message)+), err),
617 }
618 };
619}
620
621#[cfg(test)]
622mod test_assert_contains {
623 use std::panic;
624
625 mod str {
626 use super::*;
627
628 #[test]
629 fn success() {
630 let a: &'static str = "alfa";
631 let b: &'static str = "lf";
632 for _ in 0..1 {
633 let actual = assert_contains!(a, b);
634 assert_eq!(actual, ());
635 }
636 }
637
638 #[test]
639 fn failure() {
640 let a: &'static str = "alfa";
641 let b: &'static str = "xx";
642 let result = panic::catch_unwind(|| {
643 let _actual = assert_contains!(a, b);
644 });
645 let message = concat!(
646 "assertion failed: `assert_contains!(container, containee)`\n",
647 "https://docs.rs/assertables/9.8.2/assertables/macro.assert_contains.html\n",
648 " container label: `a`,\n",
649 " container debug: `\"alfa\"`,\n",
650 " containee label: `b`,\n",
651 " containee debug: `\"xx\"`"
652 );
653 assert_eq!(
654 result
655 .unwrap_err()
656 .downcast::<String>()
657 .unwrap()
658 .to_string(),
659 message
660 );
661 }
662 }
663
664 mod range_i32 {
665 use super::*;
666 use std::ops::Range;
667
668 #[test]
669 fn success() {
670 let a: Range<i32> = 1..3;
671 let b: i32 = 2;
672 for _ in 0..1 {
673 let actual = assert_contains!(a, &b);
674 assert_eq!(actual, ());
675 }
676 }
677
678 #[test]
679 fn failure() {
680 let a: Range<i32> = 1..3;
681 let b: i32 = 4;
682 let result = panic::catch_unwind(|| {
683 let _actual = assert_contains!(a, &b);
684 });
685 let message = concat!(
686 "assertion failed: `assert_contains!(container, containee)`\n",
687 "https://docs.rs/assertables/9.8.2/assertables/macro.assert_contains.html\n",
688 " container label: `a`,\n",
689 " container debug: `1..3`,\n",
690 " containee label: `&b`,\n",
691 " containee debug: `4`"
692 );
693 assert_eq!(
694 result
695 .unwrap_err()
696 .downcast::<String>()
697 .unwrap()
698 .to_string(),
699 message
700 );
701 }
702 }
703
704 mod range_string {
705 use super::*;
706 use std::ops::Range;
707
708 #[test]
709 fn success() {
710 let a: Range<String> = String::from("1")..String::from("3");
711 let b: String = String::from("2");
712 for _ in 0..1 {
713 let actual = assert_contains!(a, &b);
714 assert_eq!(actual, ());
715 }
716 }
717
718 #[test]
719 fn failure() {
720 let a: Range<String> = String::from("1")..String::from("3");
721 let b: String = String::from("4");
722 let result = panic::catch_unwind(|| {
723 let _actual = assert_contains!(a, &b);
724 });
725 let message = concat!(
726 "assertion failed: `assert_contains!(container, containee)`\n",
727 "https://docs.rs/assertables/9.8.2/assertables/macro.assert_contains.html\n",
728 " container label: `a`,\n",
729 " container debug: `\"1\"..\"3\"`,\n",
730 " containee label: `&b`,\n",
731 " containee debug: `\"4\"`"
732 );
733 assert_eq!(
734 result
735 .unwrap_err()
736 .downcast::<String>()
737 .unwrap()
738 .to_string(),
739 message
740 );
741 }
742 }
743
744 mod vec_i32 {
745 use super::*;
746
747 #[test]
748 fn success() {
749 let a: Vec<i32> = vec![1, 2, 3];
750 let b: i32 = 2;
751 for _ in 0..1 {
752 let actual = assert_contains!(a, &b);
753 assert_eq!(actual, ());
754 }
755 }
756
757 #[test]
758 fn failure() {
759 let a: Vec<i32> = vec![1, 2, 3];
760 let b: i32 = 4;
761 let result = panic::catch_unwind(|| {
762 let _actual = assert_contains!(a, &b);
763 });
764 let message = concat!(
765 "assertion failed: `assert_contains!(container, containee)`\n",
766 "https://docs.rs/assertables/9.8.2/assertables/macro.assert_contains.html\n",
767 " container label: `a`,\n",
768 " container debug: `[1, 2, 3]`,\n",
769 " containee label: `&b`,\n",
770 " containee debug: `4`"
771 );
772 assert_eq!(
773 result
774 .unwrap_err()
775 .downcast::<String>()
776 .unwrap()
777 .to_string(),
778 message
779 );
780 }
781 }
782
783 mod vec_string {
784 use super::*;
785
786 #[test]
787 fn success() {
788 let a: Vec<String> = vec![String::from("1"), String::from("2"), String::from("3")];
789 let b: String = String::from("2");
790 for _ in 0..1 {
791 let actual = assert_contains!(a, &b);
792 assert_eq!(actual, ());
793 }
794 }
795
796 #[test]
797 fn failure() {
798 let a = vec![String::from("1"), String::from("2"), String::from("3")];
799 let b: String = String::from("4");
800 let result = panic::catch_unwind(|| {
801 let _actual = assert_contains!(a, &b);
802 });
803 let message = concat!(
804 "assertion failed: `assert_contains!(container, containee)`\n",
805 "https://docs.rs/assertables/9.8.2/assertables/macro.assert_contains.html\n",
806 " container label: `a`,\n",
807 " container debug: `[\"1\", \"2\", \"3\"]`,\n",
808 " containee label: `&b`,\n",
809 " containee debug: `\"4\"`"
810 );
811 assert_eq!(
812 result
813 .unwrap_err()
814 .downcast::<String>()
815 .unwrap()
816 .to_string(),
817 message
818 );
819 }
820 }
821
822 mod hashset_string {
823 use super::*;
824 use std::collections::HashSet;
825
826 #[test]
827 fn success() {
828 let a: HashSet<String> = [String::from("1")].into();
829 let b: String = String::from("1");
830 for _ in 0..1 {
831 let actual = assert_contains!(a, &b);
832 assert_eq!(actual, ());
833 }
834 }
835
836 #[test]
837 fn failure() {
838 let a: HashSet<String> = [String::from("1")].into();
839 let b: String = String::from("2");
840 let result = panic::catch_unwind(|| {
841 let _actual = assert_contains!(a, &b);
842 });
843 let message = concat!(
844 "assertion failed: `assert_contains!(container, containee)`\n",
845 "https://docs.rs/assertables/9.8.2/assertables/macro.assert_contains.html\n",
846 " container label: `a`,\n",
847 " container debug: `{\"1\"}`,\n",
848 " containee label: `&b`,\n",
849 " containee debug: `\"2\"`"
850 );
851 assert_eq!(
852 result
853 .unwrap_err()
854 .downcast::<String>()
855 .unwrap()
856 .to_string(),
857 message
858 );
859 }
860 }
861
862 mod hashset_string_with_str_automatic_borrow_optimization {
863 use super::*;
864 use std::collections::HashSet;
865
866 #[test]
867 fn success() {
868 let a: HashSet<String> = [String::from("1")].into();
869 let b: &'static str = "1";
870 for _ in 0..1 {
871 let actual = assert_contains!(a, b);
872 assert_eq!(actual, ());
873 }
874 }
875
876 #[test]
877 fn failure() {
878 let a: HashSet<String> = [String::from("1")].into();
879 let b: &'static str = "2";
880 let result = panic::catch_unwind(|| {
881 let _actual = assert_contains!(a, b);
882 });
883 let message = concat!(
884 "assertion failed: `assert_contains!(container, containee)`\n",
885 "https://docs.rs/assertables/9.8.2/assertables/macro.assert_contains.html\n",
886 " container label: `a`,\n",
887 " container debug: `{\"1\"}`,\n",
888 " containee label: `b`,\n",
889 " containee debug: `\"2\"`"
890 );
891 assert_eq!(
892 result
893 .unwrap_err()
894 .downcast::<String>()
895 .unwrap()
896 .to_string(),
897 message
898 );
899 }
900 }
901}
902
903#[macro_export]
935macro_rules! debug_assert_contains {
936 ($($arg:tt)*) => {
937 if $crate::cfg!(debug_assertions) {
938 $crate::assert_contains!($($arg)*);
939 }
940 };
941}