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
69 let empty = Account::get_by_id(&mut db, "empty").await?;
70 assert_none!(empty.contact);
71 assert_none!(empty.status);
72
73 Ok(())
74}
75
76#[driver_test(
79 requires(scan),
80 scenario(crate::scenarios::account_optional_contact_status)
81)]
82pub async fn option_enum_filter_presence(test: &mut Test) -> Result<()> {
83 let mut db = setup(test).await;
84
85 toasty::create!(Account {
86 id: "full",
87 contact: Some(Contact::Phone {
88 number: "555".to_string(),
89 }),
90 status: Some(Status::Inactive),
91 })
92 .exec(&mut db)
93 .await?;
94 toasty::create!(Account {
95 id: "empty",
96 contact: None,
97 status: None,
98 })
99 .exec(&mut db)
100 .await?;
101
102 let present = Account::filter(Account::fields().contact().is_some())
104 .exec(&mut db)
105 .await?;
106 assert_struct!(present, [_ { id: "full", .. }]);
107
108 let absent = Account::filter(Account::fields().contact().is_none())
109 .exec(&mut db)
110 .await?;
111 assert_struct!(absent, [_ { id: "empty", .. }]);
112
113 let status_absent = Account::filter(Account::fields().status().is_none())
115 .exec(&mut db)
116 .await?;
117 assert_struct!(status_absent, [_ { id: "empty", .. }]);
118
119 Ok(())
120}
121
122#[driver_test(
125 requires(scan),
126 scenario(crate::scenarios::account_optional_contact_status)
127)]
128pub async fn option_enum_filter_eq(test: &mut Test) -> Result<()> {
129 let mut db = setup(test).await;
130
131 toasty::create!(Account {
132 id: "alice",
133 contact: Some(Contact::Email {
134 address: "alice@x.com".to_string(),
135 }),
136 status: Some(Status::Active),
137 })
138 .exec(&mut db)
139 .await?;
140 toasty::create!(Account {
141 id: "bob",
142 contact: Some(Contact::Phone {
143 number: "555".to_string(),
144 }),
145 status: Some(Status::Inactive),
146 })
147 .exec(&mut db)
148 .await?;
149 toasty::create!(Account {
150 id: "empty",
151 contact: None,
152 status: None,
153 })
154 .exec(&mut db)
155 .await?;
156
157 let email = Account::filter(Account::fields().contact().eq(Some(Contact::Email {
158 address: "alice@x.com".to_string(),
159 })))
160 .exec(&mut db)
161 .await?;
162 assert_struct!(email, [_ { id: "alice", .. }]);
163
164 let active = Account::filter(Account::fields().status().eq(Some(Status::Active)))
165 .exec(&mut db)
166 .await?;
167 assert_struct!(active, [_ { id: "alice", .. }]);
168
169 Ok(())
170}
171
172#[driver_test(scenario(crate::scenarios::account_optional_contact_status))]
174pub async fn option_enum_update(test: &mut Test) -> Result<()> {
175 let mut db = setup(test).await;
176
177 toasty::create!(Account {
178 id: "a",
179 contact: Some(Contact::Email {
180 address: "a@x.com".to_string(),
181 }),
182 status: None,
183 })
184 .exec(&mut db)
185 .await?;
186
187 Account::filter_by_id("a")
189 .update()
190 .contact(None)
191 .exec(&mut db)
192 .await?;
193 assert_none!(Account::get_by_id(&mut db, "a").await?.contact);
194
195 Account::filter_by_id("a")
197 .update()
198 .status(Some(Status::Active))
199 .exec(&mut db)
200 .await?;
201 assert_struct!(
202 Account::get_by_id(&mut db, "a").await?.status,
203 Some(== Status::Active)
204 );
205
206 Ok(())
207}
208
209#[driver_test(scenario(crate::scenarios::account_optional_contact_status))]
214pub async fn option_enum_create_ops(test: &mut Test) -> Result<()> {
215 let mut db = setup(test).await;
216 let contact = column(&db, "accounts", "contact").index;
217 let address = column(&db, "accounts", "contact_address").index;
218 let number = column(&db, "accounts", "contact_number").index;
219 let status = column(&db, "accounts", "status").index;
220 test.log().clear();
221
222 toasty::create!(Account {
225 id: "a",
226 contact: Some(Contact::Email {
227 address: "a@x.com".to_string(),
228 }),
229 status: Some(Status::Active),
230 })
231 .exec(&mut db)
232 .await?;
233 let row = pop_insert(test);
234 assert_eq!(row[&contact], Value::from(1i64));
235 assert_eq!(row[&address], Value::from("a@x.com"));
236 assert_eq!(row[&number], Value::Null);
237 assert_eq!(row[&status], Value::from(1i64));
238
239 toasty::create!(Account {
241 id: "b",
242 contact: None,
243 status: None,
244 })
245 .exec(&mut db)
246 .await?;
247 let row = pop_insert(test);
248 assert_eq!(row[&contact], Value::Null);
249 assert_eq!(row[&address], Value::Null);
250 assert_eq!(row[&number], Value::Null);
251 assert_eq!(row[&status], Value::Null);
252
253 Ok(())
254}
255
256#[driver_test(
260 requires(scan),
261 scenario(crate::scenarios::account_optional_contact_status)
262)]
263pub async fn option_enum_filter_ops(test: &mut Test) -> Result<()> {
264 let mut db = setup(test).await;
265 let contact = column(&db, "accounts", "contact").index;
266 test.log().clear();
267
268 let _ = Account::filter(Account::fields().contact().is_none())
270 .exec(&mut db)
271 .await?;
272 assert_struct!(pop_filter(test), Expr::IsNull({
273 expr.as_expr_column_unwrap().column: == contact,
274 }));
275
276 let _ = Account::filter(Account::fields().contact().is_some())
278 .exec(&mut db)
279 .await?;
280 let Expr::Not(not) = pop_filter(test) else {
281 panic!("expected NOT");
282 };
283 assert_struct!(*not.expr, Expr::IsNull({
284 expr.as_expr_column_unwrap().column: == contact,
285 }));
286
287 Ok(())
288}
289
290#[driver_test(scenario(crate::scenarios::account_optional_contact_status))]
294pub async fn option_enum_update_ops(test: &mut Test) -> Result<()> {
295 let mut db = setup(test).await;
296 let contact = column(&db, "accounts", "contact").index;
297 let address = column(&db, "accounts", "contact_address").index;
298 let number = column(&db, "accounts", "contact_number").index;
299
300 toasty::create!(Account {
301 id: "a",
302 contact: None,
303 status: None,
304 })
305 .exec(&mut db)
306 .await?;
307
308 test.log().clear();
310 Account::filter_by_id("a")
311 .update()
312 .contact(Some(Contact::Phone {
313 number: "555".to_string(),
314 }))
315 .exec(&mut db)
316 .await?;
317 let set = pop_update(test);
318 assert_eq!(set[&contact], Value::from(2i64));
319 assert_eq!(set[&number], Value::from("555"));
320 assert_eq!(set[&address], Value::Null);
321
322 test.log().clear();
324 Account::filter_by_id("a")
325 .update()
326 .contact(None)
327 .exec(&mut db)
328 .await?;
329 let set = pop_update(test);
330 assert_eq!(set[&contact], Value::Null);
331 assert_eq!(set[&address], Value::Null);
332 assert_eq!(set[&number], Value::Null);
333
334 Ok(())
335}