assertr/assertions/std/
mutex.rs1use core::fmt::Debug;
2use core::fmt::Write;
3use indoc::writedoc;
4use std::sync::Mutex;
5
6use crate::{AssertThat, Mode, tracking::AssertionTracking};
7
8#[allow(clippy::return_self_not_must_use)]
9#[cfg_attr(feature = "fluent", assertr_derive::fluent_aliases)]
10pub trait MutexAssertions {
11 fn is_locked(self) -> Self;
14
15 #[cfg_attr(feature = "fluent", fluent_alias("not_be_locked"))]
18 fn is_not_locked(self) -> Self;
19
20 fn is_free(self) -> Self
25 where
26 Self: Sized,
27 {
28 self.is_not_locked()
29 }
30}
31
32impl<T: Debug, M: Mode> MutexAssertions for AssertThat<'_, Mutex<T>, M> {
33 #[track_caller]
34 fn is_locked(self) -> Self {
35 self.track_assertion();
36 let actual = self.actual();
37 if let Ok(guard) = actual.try_lock() {
38 self.fail(|w: &mut String| {
39 writedoc! {w, r"
40 Expected: Mutex {{ data: {guard:#?}, poisoned: {poisoned} }}
41
42 to be locked, but it wasn't!
43 ", poisoned = actual.is_poisoned()}
44 });
45 }
46 self
47 }
48
49 #[track_caller]
50 fn is_not_locked(self) -> Self {
51 self.track_assertion();
52 let actual = self.actual();
53 if let Err(_err) = actual.try_lock() {
54 self.fail(|w: &mut String| {
55 writedoc! {w, r"
56 Expected: Mutex {{ data: <locked>, poisoned: {poisoned} }}
57
58 to not be locked, but it was!
59 ", poisoned = actual.is_poisoned()}
60 });
61 }
62 self
63 }
64}
65
66#[cfg(test)]
67mod tests {
68
69 mod is_locked {
70 use crate::prelude::*;
71 use indoc::formatdoc;
72 use std::sync::Mutex;
73
74 #[test]
75 fn succeeds_when_locked() {
76 let mutex = Mutex::new(42);
77 let guard = mutex.lock();
78 assert_that!(&mutex).is_locked();
79 drop(guard);
80 }
81
82 #[test]
83 fn panics_when_not_locked() {
84 let mutex = Mutex::new(42);
85 assert_that_panic_by(|| assert_that!(mutex).with_location(false).is_locked())
86 .has_type::<String>()
87 .is_equal_to(formatdoc! {"
88 -------- assertr --------
89 Expected: Mutex {{ data: 42, poisoned: false }}
90
91 to be locked, but it wasn't!
92 -------- assertr --------
93 "});
94 }
95 }
96
97 mod is_not_locked {
98 use crate::prelude::*;
99 use indoc::formatdoc;
100 use std::sync::Mutex;
101
102 #[test]
103 fn succeeds_when_not_locked() {
104 let mutex = Mutex::new(42);
105 assert_that!(mutex).is_not_locked();
106 }
107
108 #[test]
109 fn panics_when_locked() {
110 let mutex = Mutex::new(42);
111 let guard = mutex.lock();
112 assert_that_panic_by(|| assert_that!(&mutex).with_location(false).is_not_locked())
113 .has_type::<String>()
114 .is_equal_to(formatdoc! {"
115 -------- assertr --------
116 Expected: Mutex {{ data: <locked>, poisoned: false }}
117
118 to not be locked, but it was!
119 -------- assertr --------
120 "});
121 drop(guard);
122 }
123 }
124
125 mod is_free {
126 use crate::prelude::*;
127 use std::sync::Mutex;
128
129 #[test]
130 fn succeeds_when_not_locked() {
131 let mutex = Mutex::new(42);
132 assert_that!(mutex).is_free();
133 }
134 }
135}