toasty_driver_integration_suite/tests/
embed_enum_optional.rs1use crate::helpers::column;
14use crate::prelude::*;
15
16use toasty_core::stmt::{Expr, Value};
17
18#[driver_test(scenario(crate::scenarios::account_optional_contact_status))]
21pub async fn option_enum_db_schema(test: &mut Test) {
22 let db = setup(test).await;
23 let schema = db.schema();
24
25 assert_struct!(schema.db.tables, [
26 {
27 name: =~ r"accounts$",
28 columns: [
29 { name: "id" },
30 { name: "contact", nullable: true },
31 { name: "contact_address", nullable: true },
32 { name: "contact_number", nullable: true },
33 { name: "status", nullable: true },
34 ],
35 },
36 ]);
37}
38
39#[driver_test(scenario(crate::scenarios::account_optional_contact_status))]
41pub async fn option_enum_crud(test: &mut Test) -> Result<()> {
42 let mut db = setup(test).await;
43
44 toasty::create!(Account {
45 id: "full",
46 contact: Some(Contact::Email {
47 address: "a@x.com".to_string(),
48 }),
49 status: Some(Status::Active),
50 })
51 .exec(&mut db)
52 .await?;
53
54 toasty::create!(Account {
55 id: "empty",
56 contact: None,
57 status: None,
58 })
59 .exec(&mut db)
60 .await?;
61
62 let full = Account::get_by_id(&mut db, "full").await?;
63 assert_struct!(full, {
64 contact: Some(== Contact::Email { address: "a@x.com".to_string() }),
65 status: Some(== Status::Active),
66 });
67
68 let empty = Account::get_by_id(&mut db, "empty").await?;
69 assert_none!(empty.contact);
70 assert_none!(empty.status);
71
72 Ok(())
73}
74
75#[driver_test(
78 requires(scan),
79 scenario(crate::scenarios::account_optional_contact_status)
80)]
81pub async fn option_enum_filter_presence(test: &mut Test) -> Result<()> {
82 let mut db = setup(test).await;
83
84 toasty::create!(Account {
85 id: "full",
86 contact: Some(Contact::Phone {
87 number: "555".to_string(),
88 }),
89 status: Some(Status::Inactive),
90 })
91 .exec(&mut db)
92 .await?;
93 toasty::create!(Account {
94 id: "empty",
95 contact: None,
96 status: None,
97 })
98 .exec(&mut db)
99 .await?;
100
101 let present = Account::filter(Account::fields().contact().is_some())
103 .exec(&mut db)
104 .await?;
105 assert_struct!(present, [{ id: "full" }]);
106
107 let absent = Account::filter(Account::fields().contact().is_none())
108 .exec(&mut db)
109 .await?;
110 assert_struct!(absent, [{ id: "empty" }]);
111
112 let status_absent = Account::filter(Account::fields().status().is_none())
114 .exec(&mut db)
115 .await?;
116 assert_struct!(status_absent, [{ id: "empty" }]);
117
118 Ok(())
119}
120
121#[driver_test(
124 requires(scan),
125 scenario(crate::scenarios::account_optional_contact_status)
126)]
127pub async fn option_enum_filter_eq(test: &mut Test) -> Result<()> {
128 let mut db = setup(test).await;
129
130 toasty::create!(Account {
131 id: "alice",
132 contact: Some(Contact::Email {
133 address: "alice@x.com".to_string(),
134 }),
135 status: Some(Status::Active),
136 })
137 .exec(&mut db)
138 .await?;
139 toasty::create!(Account {
140 id: "bob",
141 contact: Some(Contact::Phone {
142 number: "555".to_string(),
143 }),
144 status: Some(Status::Inactive),
145 })
146 .exec(&mut db)
147 .await?;
148 toasty::create!(Account {
149 id: "empty",
150 contact: None,
151 status: None,
152 })
153 .exec(&mut db)
154 .await?;
155
156 let email = Account::filter(Account::fields().contact().eq(Some(Contact::Email {
157 address: "alice@x.com".to_string(),
158 })))
159 .exec(&mut db)
160 .await?;
161 assert_struct!(email, [{ id: "alice" }]);
162
163 let active = Account::filter(Account::fields().status().eq(Some(Status::Active)))
164 .exec(&mut db)
165 .await?;
166 assert_struct!(active, [{ id: "alice" }]);
167
168 Ok(())
169}
170
171#[driver_test(scenario(crate::scenarios::account_optional_contact_status))]
173pub async fn option_enum_update(test: &mut Test) -> Result<()> {
174 let mut db = setup(test).await;
175
176 toasty::create!(Account {
177 id: "a",
178 contact: Some(Contact::Email {
179 address: "a@x.com".to_string(),
180 }),
181 status: None,
182 })
183 .exec(&mut db)
184 .await?;
185
186 Account::filter_by_id("a")
188 .update()
189 .contact(None)
190 .exec(&mut db)
191 .await?;
192 assert_none!(Account::get_by_id(&mut db, "a").await?.contact);
193
194 Account::filter_by_id("a")
196 .update()
197 .status(Some(Status::Active))
198 .exec(&mut db)
199 .await?;
200 assert_struct!(
201 Account::get_by_id(&mut db, "a").await?.status,
202 Some(== Status::Active)
203 );
204
205 Ok(())
206}
207
208#[driver_test(scenario(crate::scenarios::account_optional_contact_status))]
213pub async fn option_enum_create_ops(test: &mut Test) -> Result<()> {
214 let mut db = setup(test).await;
215 let contact = column(&db, "accounts", "contact").index;
216 let address = column(&db, "accounts", "contact_address").index;
217 let number = column(&db, "accounts", "contact_number").index;
218 let status = column(&db, "accounts", "status").index;
219 test.log().clear();
220
221 toasty::create!(Account {
224 id: "a",
225 contact: Some(Contact::Email {
226 address: "a@x.com".to_string(),
227 }),
228 status: Some(Status::Active),
229 })
230 .exec(&mut db)
231 .await?;
232 let row = pop_insert(test);
233 assert_eq!(row[&contact], Value::from(1i64));
234 assert_eq!(row[&address], Value::from("a@x.com"));
235 assert_eq!(row[&number], Value::Null);
236 assert_eq!(row[&status], Value::from(1i64));
237
238 toasty::create!(Account {
240 id: "b",
241 contact: None,
242 status: None,
243 })
244 .exec(&mut db)
245 .await?;
246 let row = pop_insert(test);
247 assert_eq!(row[&contact], Value::Null);
248 assert_eq!(row[&address], Value::Null);
249 assert_eq!(row[&number], Value::Null);
250 assert_eq!(row[&status], Value::Null);
251
252 Ok(())
253}
254
255#[driver_test(
259 requires(scan),
260 scenario(crate::scenarios::account_optional_contact_status)
261)]
262pub async fn option_enum_filter_ops(test: &mut Test) -> Result<()> {
263 let mut db = setup(test).await;
264 let contact = column(&db, "accounts", "contact").index;
265 test.log().clear();
266
267 let _ = Account::filter(Account::fields().contact().is_none())
269 .exec(&mut db)
270 .await?;
271 assert_struct!(pop_filter(test), Expr::IsNull({
272 expr.as_expr_column_unwrap().column: == contact,
273 }));
274
275 let _ = Account::filter(Account::fields().contact().is_some())
277 .exec(&mut db)
278 .await?;
279 let Expr::Not(not) = pop_filter(test) else {
280 panic!("expected NOT");
281 };
282 assert_struct!(*not.expr, Expr::IsNull({
283 expr.as_expr_column_unwrap().column: == contact,
284 }));
285
286 Ok(())
287}
288
289#[driver_test(scenario(crate::scenarios::account_optional_contact_status))]
293pub async fn option_enum_update_ops(test: &mut Test) -> Result<()> {
294 let mut db = setup(test).await;
295 let contact = column(&db, "accounts", "contact").index;
296 let address = column(&db, "accounts", "contact_address").index;
297 let number = column(&db, "accounts", "contact_number").index;
298
299 toasty::create!(Account {
300 id: "a",
301 contact: None,
302 status: None,
303 })
304 .exec(&mut db)
305 .await?;
306
307 test.log().clear();
309 Account::filter_by_id("a")
310 .update()
311 .contact(Some(Contact::Phone {
312 number: "555".to_string(),
313 }))
314 .exec(&mut db)
315 .await?;
316 let set = pop_update(test);
317 assert_eq!(set[&contact], Value::from(2i64));
318 assert_eq!(set[&number], Value::from("555"));
319 assert_eq!(set[&address], Value::Null);
320
321 test.log().clear();
323 Account::filter_by_id("a")
324 .update()
325 .contact(None)
326 .exec(&mut db)
327 .await?;
328 let set = pop_update(test);
329 assert_eq!(set[&contact], Value::Null);
330 assert_eq!(set[&address], Value::Null);
331 assert_eq!(set[&number], Value::Null);
332
333 Ok(())
334}