windjammer_runtime/
setup_teardown.rs1use std::panic;
6
7pub fn with_setup_teardown<S, T, F, R>(setup: S, teardown: T, test: F) -> R
32where
33 S: FnOnce() -> R,
34 T: FnOnce(R),
35 F: FnOnce(R) -> R,
36 R: Clone + panic::UnwindSafe,
37{
38 let resource = setup();
39 let resource_clone = resource.clone();
40
41 let result = panic::catch_unwind(panic::AssertUnwindSafe(|| test(resource)));
42
43 teardown(resource_clone);
44
45 match result {
46 Ok(r) => r,
47 Err(e) => panic::resume_unwind(e),
48 }
49}
50
51pub fn with_setup<S, F, R>(setup: S, test: F) -> R
53where
54 S: FnOnce() -> R,
55 F: FnOnce(R) -> R,
56{
57 let resource = setup();
58 test(resource)
59}
60
61pub fn with_teardown<T, F, R>(teardown: T, test: F) -> R
63where
64 T: FnOnce(R),
65 F: FnOnce() -> R,
66 R: Clone,
67{
68 let result = test();
69 let result_clone = result.clone();
70 teardown(result_clone);
71 result
72}
73
74pub struct TestDatabase {
76 pub connection_string: String,
77}
78
79impl TestDatabase {
80 pub fn new() -> Self {
81 Self {
82 connection_string: "test://localhost".to_string(),
83 }
84 }
85
86 pub fn setup(&self) {
87 }
89
90 pub fn teardown(&self) {
91 }
93}
94
95impl Default for TestDatabase {
96 fn default() -> Self {
97 Self::new()
98 }
99}
100
101#[cfg(test)]
102mod tests {
103 use super::*;
104
105 #[test]
106 fn test_with_setup_teardown() {
107 let mut setup_called = false;
108 let mut teardown_called = false;
109
110 let result = with_setup_teardown(
112 || {
113 setup_called = true;
114 42
115 },
116 |_| {
117 teardown_called = true;
118 },
119 |value| {
120 assert_eq!(value, 42);
121 value
122 },
123 );
124
125 assert_eq!(result, 42);
126 }
129
130 #[test]
131 fn test_with_setup() {
132 let result = with_setup(
133 || 42,
134 |value| {
135 assert_eq!(value, 42);
136 value * 2
137 },
138 );
139
140 assert_eq!(result, 84);
141 }
142
143 #[test]
144 fn test_with_teardown() {
145 let result = with_teardown(
146 |value| {
147 assert_eq!(value, 42);
148 },
149 || 42,
150 );
151
152 assert_eq!(result, 42);
153 }
154
155 #[test]
156 fn test_database_helper() {
157 let db = TestDatabase::new();
158 assert_eq!(db.connection_string, "test://localhost");
159
160 db.setup();
161 db.teardown();
162 }
163}