toasty_driver_integration_suite/tests/
embed_enum_string_discriminant.rs1use crate::prelude::*;
2
3#[driver_test(id(ID), scenario(crate::scenarios::task_with_string_status))]
5pub async fn string_discriminant_unit_enum(t: &mut Test) -> Result<()> {
6 let mut db = setup(t).await;
7
8 let task = toasty::create!(Task {
9 title: "Ship it",
10 status: Status::Pending,
11 })
12 .exec(&mut db)
13 .await?;
14 assert_eq!(task.status, Status::Pending);
15
16 let found = Task::get_by_id(&mut db, &task.id).await?;
17 assert_eq!(found.status, Status::Pending);
18
19 let mut task = found;
21 task.update().status(Status::Active).exec(&mut db).await?;
22 let found = Task::get_by_id(&mut db, &task.id).await?;
23 assert_eq!(found.status, Status::Active);
24
25 Ok(())
26}
27
28#[driver_test(id(ID))]
30pub async fn default_string_labels(t: &mut Test) -> Result<()> {
31 #[derive(Debug, PartialEq, toasty::Embed)]
32 enum Priority {
33 Low,
34 Medium,
35 High,
36 }
37
38 #[derive(Debug, toasty::Model)]
39 struct Task {
40 #[key]
41 #[auto]
42 id: ID,
43 title: String,
44 priority: Priority,
45 }
46
47 let mut db = t.setup_db(models!(Task)).await;
48
49 let task = toasty::create!(Task {
50 title: "Fix bug",
51 priority: Priority::High,
52 })
53 .exec(&mut db)
54 .await?;
55 assert_eq!(task.priority, Priority::High);
56
57 let found = Task::get_by_id(&mut db, &task.id).await?;
58 assert_eq!(found.priority, Priority::High);
59
60 Ok(())
61}
62
63#[driver_test(id(ID))]
65pub async fn mixed_explicit_and_default_labels(t: &mut Test) -> Result<()> {
66 #[derive(Debug, PartialEq, toasty::Embed)]
67 enum Status {
68 #[column(variant = "waiting")]
69 Pending,
70 Active,
71 Done,
72 }
73
74 #[derive(Debug, toasty::Model)]
75 struct Task {
76 #[key]
77 #[auto]
78 id: ID,
79 status: Status,
80 }
81
82 let mut db = t.setup_db(models!(Task)).await;
83
84 let t1 = toasty::create!(Task {
86 status: Status::Pending
87 })
88 .exec(&mut db)
89 .await?;
90 assert_eq!(t1.status, Status::Pending);
91
92 let t2 = toasty::create!(Task {
94 status: Status::Active
95 })
96 .exec(&mut db)
97 .await?;
98
99 let found1 = Task::get_by_id(&mut db, &t1.id).await?;
100 let found2 = Task::get_by_id(&mut db, &t2.id).await?;
101 assert_eq!(found1.status, Status::Pending);
102 assert_eq!(found2.status, Status::Active);
103
104 Ok(())
105}
106
107#[driver_test(id(ID))]
109pub async fn string_discriminant_data_enum(t: &mut Test) -> Result<()> {
110 #[derive(Debug, PartialEq, toasty::Embed)]
111 enum ContactMethod {
112 #[column(variant = "email")]
113 Email { address: String },
114 #[column(variant = "phone")]
115 Phone { number: String },
116 }
117
118 #[derive(Debug, toasty::Model)]
119 #[allow(dead_code)]
120 struct User {
121 #[key]
122 #[auto]
123 id: ID,
124 name: String,
125 contact: ContactMethod,
126 }
127
128 let mut db = t.setup_db(models!(User)).await;
129
130 let user = toasty::create!(User {
131 name: "Alice",
132 contact: ContactMethod::Email {
133 address: "alice@example.com".into(),
134 },
135 })
136 .exec(&mut db)
137 .await?;
138
139 let found = User::get_by_id(&mut db, &user.id).await?;
140 assert_eq!(
141 found.contact,
142 ContactMethod::Email {
143 address: "alice@example.com".into()
144 }
145 );
146
147 let mut user = found;
149 user.update()
150 .contact(ContactMethod::Phone {
151 number: "555-0100".into(),
152 })
153 .exec(&mut db)
154 .await?;
155
156 let found = User::get_by_id(&mut db, &user.id).await?;
157 assert_eq!(
158 found.contact,
159 ContactMethod::Phone {
160 number: "555-0100".into()
161 }
162 );
163
164 Ok(())
165}
166
167#[driver_test(id(ID))]
169pub async fn default_string_labels_data_enum(t: &mut Test) -> Result<()> {
170 #[derive(Debug, PartialEq, toasty::Embed)]
171 enum ContactMethod {
172 Email { address: String },
173 Phone { number: String },
174 }
175
176 #[derive(Debug, toasty::Model)]
177 #[allow(dead_code)]
178 struct User {
179 #[key]
180 #[auto]
181 id: ID,
182 name: String,
183 contact: ContactMethod,
184 }
185
186 let mut db = t.setup_db(models!(User)).await;
187
188 let user = toasty::create!(User {
189 name: "Alice",
190 contact: ContactMethod::Email {
191 address: "alice@example.com".into(),
192 },
193 })
194 .exec(&mut db)
195 .await?;
196
197 let found = User::get_by_id(&mut db, &user.id).await?;
198 assert_eq!(
199 found.contact,
200 ContactMethod::Email {
201 address: "alice@example.com".into()
202 }
203 );
204
205 let mut user = found;
207 user.update()
208 .contact(ContactMethod::Phone {
209 number: "555-0100".into(),
210 })
211 .exec(&mut db)
212 .await?;
213
214 let found = User::get_by_id(&mut db, &user.id).await?;
215 assert_eq!(
216 found.contact,
217 ContactMethod::Phone {
218 number: "555-0100".into()
219 }
220 );
221
222 Ok(())
223}
224
225#[driver_test(id(ID))]
227pub async fn mixed_string_labels_data_enum(t: &mut Test) -> Result<()> {
228 #[derive(Debug, PartialEq, toasty::Embed)]
229 enum ContactMethod {
230 #[column(variant = "mail")]
231 Email {
232 address: String,
233 },
234 Phone {
235 number: String,
236 },
237 }
238
239 #[derive(Debug, toasty::Model)]
240 #[allow(dead_code)]
241 struct User {
242 #[key]
243 #[auto]
244 id: ID,
245 name: String,
246 contact: ContactMethod,
247 }
248
249 let mut db = t.setup_db(models!(User)).await;
250
251 let u1 = toasty::create!(User {
253 name: "Alice",
254 contact: ContactMethod::Email {
255 address: "alice@example.com".into(),
256 },
257 })
258 .exec(&mut db)
259 .await?;
260
261 let u2 = toasty::create!(User {
263 name: "Bob",
264 contact: ContactMethod::Phone {
265 number: "555-0200".into(),
266 },
267 })
268 .exec(&mut db)
269 .await?;
270
271 let found1 = User::get_by_id(&mut db, &u1.id).await?;
272 assert_eq!(
273 found1.contact,
274 ContactMethod::Email {
275 address: "alice@example.com".into()
276 }
277 );
278
279 let found2 = User::get_by_id(&mut db, &u2.id).await?;
280 assert_eq!(
281 found2.contact,
282 ContactMethod::Phone {
283 number: "555-0200".into()
284 }
285 );
286
287 let mut user = found1;
289 user.update()
290 .contact(ContactMethod::Phone {
291 number: "555-0300".into(),
292 })
293 .exec(&mut db)
294 .await?;
295
296 let found = User::get_by_id(&mut db, &user.id).await?;
297 assert_eq!(
298 found.contact,
299 ContactMethod::Phone {
300 number: "555-0300".into()
301 }
302 );
303
304 Ok(())
305}
306
307#[driver_test(
309 requires(scan),
310 scenario(crate::scenarios::task_with_string_status::id_uuid)
311)]
312pub async fn filter_by_string_variant(t: &mut Test) -> Result<()> {
313 let mut db = setup(t).await;
314
315 toasty::create!(Task {
316 title: "A",
317 status: Status::Pending
318 })
319 .exec(&mut db)
320 .await?;
321
322 toasty::create!(Task {
323 title: "B",
324 status: Status::Active
325 })
326 .exec(&mut db)
327 .await?;
328
329 let pending = Task::filter(Task::fields().status().is_pending())
330 .exec(&mut db)
331 .await?;
332 assert_eq!(pending.len(), 1);
333 assert_eq!(pending[0].title, "A");
334
335 Ok(())
336}
337
338#[driver_test(scenario(crate::scenarios::task_with_string_status::id_uuid))]
340pub async fn string_discriminant_schema_registration(t: &mut Test) {
341 let db = setup(t).await;
342 let schema = db.schema();
343
344 let status_model = schema.app.model(Status::id()).as_embedded_enum_unwrap();
345 assert_eq!(
346 status_model.discriminant.ty,
347 toasty_core::stmt::Type::String
348 );
349 assert_eq!(status_model.variants.len(), 3);
350 assert_eq!(
351 status_model.variants[0].discriminant,
352 toasty_core::stmt::Value::String("pending".to_string())
353 );
354 assert_eq!(
355 status_model.variants[1].discriminant,
356 toasty_core::stmt::Value::String("active".to_string())
357 );
358 assert_eq!(
359 status_model.variants[2].discriminant,
360 toasty_core::stmt::Value::String("done".to_string())
361 );
362}