1use crate::prelude::*;
9
10#[driver_test(
13 id(ID),
14 requires(sql),
15 scenario(crate::scenarios::user_comment_article)
16)]
17pub async fn query_returns_distinct_targets(test: &mut Test) -> Result<()> {
18 let mut db = setup(test).await;
19
20 let users = toasty::create!(User::[
21 { name: "Alice" },
22 { name: "Bob" },
23 ])
24 .exec(&mut db)
25 .await?;
26 let (alice, bob) = (&users[0], &users[1]);
27
28 let articles = toasty::create!(Article::[
29 { title: "Rust" },
30 { title: "Toasty" },
31 { title: "SQL" },
32 ])
33 .exec(&mut db)
34 .await?;
35 let (rust, toasty_article, sql) = (&articles[0], &articles[1], &articles[2]);
36
37 toasty::create!(Comment::[
39 { body: "a1", user: alice, article: rust },
40 { body: "a2", user: alice, article: rust },
41 { body: "a3", user: alice, article: toasty_article },
42 { body: "b1", user: bob, article: sql },
43 ])
44 .exec(&mut db)
45 .await?;
46
47 let commented = alice.commented_articles().exec(&mut db).await?;
50 assert_eq_unordered!(commented.iter().map(|a| &a.title[..]), ["Rust", "Toasty"]);
51
52 let commented = bob.commented_articles().exec(&mut db).await?;
54 assert_eq_unordered!(commented.iter().map(|a| &a.title[..]), ["SQL"]);
55
56 Ok(())
57}
58
59#[driver_test(
61 id(ID),
62 requires(sql),
63 scenario(crate::scenarios::user_comment_article)
64)]
65pub async fn query_with_no_intermediates_is_empty(test: &mut Test) -> Result<()> {
66 let mut db = setup(test).await;
67
68 let user = toasty::create!(User { name: "Alice" })
69 .exec(&mut db)
70 .await?;
71 toasty::create!(Article { title: "Rust" })
72 .exec(&mut db)
73 .await?;
74
75 let commented = user.commented_articles().exec(&mut db).await?;
76 assert!(commented.is_empty());
77
78 Ok(())
79}
80
81#[driver_test(
84 id(ID),
85 requires(sql),
86 scenario(crate::scenarios::user_comment_article)
87)]
88pub async fn via_relation_query_can_be_filtered(test: &mut Test) -> Result<()> {
89 let mut db = setup(test).await;
90
91 let alice = toasty::create!(User { name: "Alice" })
92 .exec(&mut db)
93 .await?;
94
95 let articles = toasty::create!(Article::[
96 { title: "Rust" },
97 { title: "Toasty" },
98 { title: "SQL" },
99 ])
100 .exec(&mut db)
101 .await?;
102 let (rust, toasty_article, sql) = (&articles[0], &articles[1], &articles[2]);
103
104 toasty::create!(Comment::[
105 { body: "a1", user: &alice, article: rust },
106 { body: "a2", user: &alice, article: toasty_article },
107 { body: "a3", user: &alice, article: sql },
108 ])
109 .exec(&mut db)
110 .await?;
111
112 let filtered: Vec<_> = alice
113 .commented_articles()
114 .filter(Article::fields().title().eq("Toasty"))
115 .exec(&mut db)
116 .await?;
117 assert_eq_unordered!(filtered.iter().map(|a| &a.title[..]), ["Toasty"]);
118
119 Ok(())
120}
121
122#[driver_test(
142 id(ID),
143 requires(sql),
144 scenario(crate::scenarios::user_comment_article)
145)]
146pub async fn include_via_two_step(test: &mut Test) -> Result<()> {
147 let mut db = setup(test).await;
148
149 let users = toasty::create!(User::[
150 { name: "Alice" },
151 { name: "Bob" },
152 { name: "Charlie" },
153 ])
154 .exec(&mut db)
155 .await?;
156 let (alice, bob, _charlie) = (&users[0], &users[1], &users[2]);
157
158 let articles = toasty::create!(Article::[
159 { title: "Rust" },
160 { title: "Toasty" },
161 { title: "SQL" },
162 ])
163 .exec(&mut db)
164 .await?;
165 let (rust, toasty_article, sql) = (&articles[0], &articles[1], &articles[2]);
166
167 toasty::create!(Comment::[
169 { body: "a1", user: alice, article: rust },
170 { body: "a2", user: alice, article: rust },
171 { body: "a3", user: alice, article: toasty_article },
172 { body: "b1", user: bob, article: sql },
173 ])
174 .exec(&mut db)
175 .await?;
176
177 let loaded: Vec<User> = User::all()
178 .include(User::fields().commented_articles())
179 .exec(&mut db)
180 .await?;
181 assert_eq!(3, loaded.len());
182
183 for user in &loaded {
184 let titles: Vec<&str> = user
185 .commented_articles
186 .get()
187 .iter()
188 .map(|a| &a.title[..])
189 .collect();
190 match &user.name[..] {
191 "Alice" => {
194 assert_eq_unordered!(titles, ["Rust", "Toasty"]);
195 }
196 "Bob" => {
197 assert_eq_unordered!(titles, ["SQL"]);
198 }
199 "Charlie" => assert!(titles.is_empty(), "Charlie has no comments; got {titles:?}"),
200 other => panic!("unexpected user {other}"),
201 }
202 }
203
204 Ok(())
205}
206
207#[driver_test(
217 id(ID),
218 requires(sql),
219 scenario(crate::scenarios::user_org_project_todo)
220)]
221pub async fn include_via_three_step(test: &mut Test) -> Result<()> {
222 let mut db = setup(test).await;
223
224 let users = toasty::create!(User::[
225 { name: "Alice" },
226 { name: "Bob" },
227 ])
228 .exec(&mut db)
229 .await?;
230 let (alice, bob) = (&users[0], &users[1]);
231
232 let alice_org_a = toasty::create!(Organization {
233 name: "A-Co",
234 user: alice
235 })
236 .exec(&mut db)
237 .await?;
238 let alice_org_b = toasty::create!(Organization {
239 name: "B-Co",
240 user: alice
241 })
242 .exec(&mut db)
243 .await?;
244 let bob_org = toasty::create!(Organization {
245 name: "Bob-Inc",
246 user: bob
247 })
248 .exec(&mut db)
249 .await?;
250
251 let alice_proj_1 = toasty::create!(Project {
252 name: "p1",
253 organization: &alice_org_a
254 })
255 .exec(&mut db)
256 .await?;
257 let alice_proj_2 = toasty::create!(Project {
258 name: "p2",
259 organization: &alice_org_a
260 })
261 .exec(&mut db)
262 .await?;
263 let alice_proj_3 = toasty::create!(Project {
264 name: "p3",
265 organization: &alice_org_b
266 })
267 .exec(&mut db)
268 .await?;
269 let bob_proj = toasty::create!(Project {
270 name: "bp",
271 organization: &bob_org
272 })
273 .exec(&mut db)
274 .await?;
275
276 toasty::create!(Todo::[
277 { title: "a-1", project: &alice_proj_1 },
278 { title: "a-2", project: &alice_proj_1 },
279 { title: "a-3", project: &alice_proj_2 },
280 { title: "a-4", project: &alice_proj_3 },
281 { title: "b-1", project: &bob_proj },
282 { title: "b-2", project: &bob_proj },
283 ])
284 .exec(&mut db)
285 .await?;
286
287 let loaded: Vec<User> = User::all()
288 .include(User::fields().todos())
289 .exec(&mut db)
290 .await?;
291 assert_eq!(2, loaded.len());
292
293 for user in &loaded {
294 let titles: Vec<&str> = user.todos.get().iter().map(|t| &t.title[..]).collect();
295 match &user.name[..] {
296 "Alice" => {
297 assert_eq_unordered!(titles, ["a-1", "a-2", "a-3", "a-4"]);
298 }
299 "Bob" => {
300 assert_eq_unordered!(titles, ["b-1", "b-2"]);
301 }
302 other => panic!("unexpected user {other}"),
303 }
304 }
305
306 Ok(())
307}
308
309#[driver_test(
316 id(ID),
317 requires(sql),
318 scenario(crate::scenarios::user_org_project_todo)
319)]
320pub async fn include_via_nested_via(test: &mut Test) -> Result<()> {
321 let mut db = setup(test).await;
322
323 let users = toasty::create!(User::[
324 { name: "Alice" },
325 { name: "Bob" },
326 ])
327 .exec(&mut db)
328 .await?;
329 let (alice, bob) = (&users[0], &users[1]);
330
331 let alice_org_a = toasty::create!(Organization {
332 name: "A-Co",
333 user: alice
334 })
335 .exec(&mut db)
336 .await?;
337 let alice_org_b = toasty::create!(Organization {
338 name: "B-Co",
339 user: alice
340 })
341 .exec(&mut db)
342 .await?;
343 let bob_org = toasty::create!(Organization {
344 name: "Bob-Inc",
345 user: bob
346 })
347 .exec(&mut db)
348 .await?;
349
350 let alice_proj_1 = toasty::create!(Project {
351 name: "p1",
352 organization: &alice_org_a
353 })
354 .exec(&mut db)
355 .await?;
356 let alice_proj_2 = toasty::create!(Project {
357 name: "p2",
358 organization: &alice_org_a
359 })
360 .exec(&mut db)
361 .await?;
362 let alice_proj_3 = toasty::create!(Project {
363 name: "p3",
364 organization: &alice_org_b
365 })
366 .exec(&mut db)
367 .await?;
368 let bob_proj = toasty::create!(Project {
369 name: "bp",
370 organization: &bob_org
371 })
372 .exec(&mut db)
373 .await?;
374
375 toasty::create!(Todo::[
376 { title: "a-1", project: &alice_proj_1 },
377 { title: "a-2", project: &alice_proj_1 },
378 { title: "a-3", project: &alice_proj_2 },
379 { title: "a-4", project: &alice_proj_3 },
380 { title: "b-1", project: &bob_proj },
381 { title: "b-2", project: &bob_proj },
382 ])
383 .exec(&mut db)
384 .await?;
385
386 let loaded: Vec<User> = User::all()
387 .include(User::fields().nested_todos())
388 .exec(&mut db)
389 .await?;
390 assert_eq!(2, loaded.len());
391
392 for user in &loaded {
393 let titles: Vec<&str> = user
394 .nested_todos
395 .get()
396 .iter()
397 .map(|t| &t.title[..])
398 .collect();
399 match &user.name[..] {
400 "Alice" => {
401 assert_eq_unordered!(titles, ["a-1", "a-2", "a-3", "a-4"]);
402 }
403 "Bob" => {
404 assert_eq_unordered!(titles, ["b-1", "b-2"]);
405 }
406 other => panic!("unexpected user {other}"),
407 }
408 }
409
410 Ok(())
411}
412
413#[driver_test(
421 id(ID),
422 requires(sql),
423 scenario(crate::scenarios::user_org_project_todo)
424)]
425pub async fn scalar_via_of_via(test: &mut Test) -> Result<()> {
426 let mut db = setup(test).await;
427
428 let alice = toasty::create!(User { name: "Alice" })
429 .exec(&mut db)
430 .await?;
431 let org_a = toasty::create!(Organization {
432 name: "A-Co",
433 user: &alice
434 })
435 .exec(&mut db)
436 .await?;
437 let org_b = toasty::create!(Organization {
438 name: "B-Co",
439 user: &alice
440 })
441 .exec(&mut db)
442 .await?;
443 let proj_a = toasty::create!(Project {
444 name: "p-a",
445 organization: &org_a
446 })
447 .exec(&mut db)
448 .await?;
449 let proj_b = toasty::create!(Project {
450 name: "p-b",
451 organization: &org_b
452 })
453 .exec(&mut db)
454 .await?;
455
456 toasty::create!(Todo::[
458 { title: "x", project: &proj_a },
459 { title: "y", project: &proj_a },
460 { title: "y", project: &proj_b },
461 { title: "z", project: &proj_b },
462 ])
463 .exec(&mut db)
464 .await?;
465
466 let titles = alice.nested_todo_titles().exec(&mut db).await?;
468 assert_eq_unordered!(titles.iter().map(|t| &t[..]), ["x", "y", "z"]);
469
470 let loaded = User::filter_by_id(alice.id)
472 .include(User::fields().nested_todo_titles())
473 .get(&mut db)
474 .await?;
475 let titles: Vec<&str> = loaded
476 .nested_todo_titles
477 .get()
478 .iter()
479 .map(|t| &t[..])
480 .collect();
481 assert_eq_unordered!(titles, ["x", "y", "z"]);
482
483 Ok(())
484}
485
486#[driver_test(
489 id(ID),
490 requires(sql),
491 scenario(crate::scenarios::user_org_project_todo)
492)]
493pub async fn include_via_three_step_no_intermediates(test: &mut Test) -> Result<()> {
494 let mut db = setup(test).await;
495
496 let alice = toasty::create!(User { name: "Alice" })
497 .exec(&mut db)
498 .await?;
499
500 let loaded = User::filter_by_id(alice.id)
501 .include(User::fields().todos())
502 .get(&mut db)
503 .await?;
504 assert!(loaded.todos.get().is_empty());
505
506 Ok(())
507}
508
509#[driver_test(
516 id(ID),
517 requires(sql),
518 scenario(crate::scenarios::user_comment_article)
519)]
520pub async fn select_via_two_step(test: &mut Test) -> Result<()> {
521 let mut db = setup(test).await;
522
523 let alice = toasty::create!(User { name: "Alice" })
524 .exec(&mut db)
525 .await?;
526
527 let articles = toasty::create!(Article::[
528 { title: "Rust" },
529 { title: "Toasty" },
530 ])
531 .exec(&mut db)
532 .await?;
533 let (rust, toasty_article) = (&articles[0], &articles[1]);
534
535 toasty::create!(Comment::[
536 { body: "a1", user: &alice, article: rust },
537 { body: "a2", user: &alice, article: rust },
538 { body: "a3", user: &alice, article: toasty_article },
539 ])
540 .exec(&mut db)
541 .await?;
542
543 let articles_per_user: Vec<Vec<Article>> = User::all()
544 .select(User::fields().commented_articles())
545 .exec(&mut db)
546 .await?;
547
548 assert_eq!(1, articles_per_user.len());
549 let titles: Vec<&str> = articles_per_user[0].iter().map(|a| &a.title[..]).collect();
550 assert_eq_unordered!(titles, ["Rust", "Toasty"]);
551
552 Ok(())
553}
554
555#[driver_test(
562 id(ID),
563 requires(sql),
564 scenario(crate::scenarios::user_account_subscription)
565)]
566pub async fn include_via_has_one(test: &mut Test) -> Result<()> {
567 let mut db = setup(test).await;
568
569 toasty::create!(User {
572 name: "Alice",
573 account: Account::create().subscription(Subscription::create().plan("pro")),
574 })
575 .exec(&mut db)
576 .await?;
577 toasty::create!(User {
578 name: "Bob",
579 account: Account::create(),
580 })
581 .exec(&mut db)
582 .await?;
583 toasty::create!(User { name: "Carol" })
584 .exec(&mut db)
585 .await?;
586
587 let loaded: Vec<User> = User::all()
588 .include(User::fields().subscription())
589 .exec(&mut db)
590 .await?;
591 assert_eq!(3, loaded.len());
592
593 for user in &loaded {
594 let plan = user.subscription.get().as_ref().map(|s| &s.plan[..]);
595 match &user.name[..] {
596 "Alice" => assert_eq!(plan, Some("pro")),
597 "Bob" => assert_eq!(plan, None, "Bob has an account but no subscription"),
598 "Carol" => assert_eq!(plan, None, "Carol has no account"),
599 other => panic!("unexpected user {other}"),
600 }
601 }
602
603 Ok(())
604}
605
606#[driver_test(
612 id(ID),
613 requires(sql),
614 scenario(crate::scenarios::user_account_subscription)
615)]
616pub async fn select_via_has_one(test: &mut Test) -> Result<()> {
617 let mut db = setup(test).await;
618
619 toasty::create!(User {
620 name: "Alice",
621 account: Account::create().subscription(Subscription::create().plan("pro")),
622 })
623 .exec(&mut db)
624 .await?;
625
626 let subscriptions: Vec<Subscription> = User::filter(User::fields().name().eq("Alice"))
627 .select(User::fields().subscription())
628 .exec(&mut db)
629 .await?;
630
631 assert_eq!(1, subscriptions.len());
632 assert_eq!(subscriptions[0].plan, "pro");
633
634 Ok(())
635}
636
637#[driver_test(
648 id(ID),
649 requires(sql),
650 scenario(crate::scenarios::user_comment_article)
651)]
652pub async fn query_scalar_via_returns_distinct_titles(test: &mut Test) -> Result<()> {
653 let mut db = setup(test).await;
654
655 let users = toasty::create!(User::[{ name: "Alice" }, { name: "Bob" }])
656 .exec(&mut db)
657 .await?;
658 let (alice, bob) = (&users[0], &users[1]);
659
660 let articles = toasty::create!(Article::[
661 { title: "Rust" },
662 { title: "Toasty" },
663 { title: "SQL" },
664 ])
665 .exec(&mut db)
666 .await?;
667 let (rust, toasty_article, sql) = (&articles[0], &articles[1], &articles[2]);
668
669 toasty::create!(Comment::[
671 { body: "a1", user: alice, article: rust },
672 { body: "a2", user: alice, article: rust },
673 { body: "a3", user: alice, article: toasty_article },
674 { body: "b1", user: bob, article: sql },
675 ])
676 .exec(&mut db)
677 .await?;
678
679 let titles = alice.commented_article_titles().exec(&mut db).await?;
681 assert_eq_unordered!(titles.iter().map(|t| &t[..]), ["Rust", "Toasty"]);
682
683 let titles = bob.commented_article_titles().exec(&mut db).await?;
684 assert_eq_unordered!(titles.iter().map(|t| &t[..]), ["SQL"]);
685
686 Ok(())
687}
688
689#[driver_test(
699 id(ID),
700 requires(sql),
701 scenario(crate::scenarios::user_comment_article)
702)]
703pub async fn scalar_via_distinct_values_across_distinct_targets(test: &mut Test) -> Result<()> {
704 let mut db = setup(test).await;
705
706 let alice = toasty::create!(User { name: "Alice" })
707 .exec(&mut db)
708 .await?;
709
710 let articles = toasty::create!(Article::[{ title: "Rust" }, { title: "Rust" }])
712 .exec(&mut db)
713 .await?;
714 let (rust_a, rust_b) = (&articles[0], &articles[1]);
715
716 toasty::create!(Comment::[
717 { body: "a1", user: &alice, article: rust_a },
718 { body: "a2", user: &alice, article: rust_b },
719 ])
720 .exec(&mut db)
721 .await?;
722
723 let commented = alice.commented_articles().exec(&mut db).await?;
725 assert_eq!(commented.len(), 2);
726
727 let titles = alice.commented_article_titles().exec(&mut db).await?;
730 assert_eq_unordered!(titles.iter().map(|t| &t[..]), ["Rust"]);
731
732 let loaded = User::filter_by_id(alice.id)
734 .include(User::fields().commented_article_titles())
735 .get(&mut db)
736 .await?;
737 let titles: Vec<&str> = loaded
738 .commented_article_titles
739 .get()
740 .iter()
741 .map(|t| &t[..])
742 .collect();
743 assert_eq_unordered!(titles, ["Rust"]);
744
745 Ok(())
746}
747
748#[driver_test(
754 id(ID),
755 requires(sql),
756 scenario(crate::scenarios::user_comment_article)
757)]
758pub async fn query_scalar_via_two_step(test: &mut Test) -> Result<()> {
759 let mut db = setup(test).await;
760
761 let alice = toasty::create!(User { name: "Alice" })
762 .exec(&mut db)
763 .await?;
764 let article = toasty::create!(Article { title: "Rust" })
765 .exec(&mut db)
766 .await?;
767
768 toasty::create!(Comment::[
770 { body: "a1", user: &alice, article: &article },
771 { body: "a1", user: &alice, article: &article },
772 { body: "a2", user: &alice, article: &article },
773 ])
774 .exec(&mut db)
775 .await?;
776
777 let bodies = alice.comment_bodies().exec(&mut db).await?;
778 assert_eq_unordered!(bodies.iter().map(|b| &b[..]), ["a1", "a2"]);
779
780 let loaded = User::filter_by_id(alice.id)
781 .include(User::fields().comment_bodies())
782 .get(&mut db)
783 .await?;
784 let bodies: Vec<&str> = loaded.comment_bodies.get().iter().map(|b| &b[..]).collect();
785 assert_eq_unordered!(bodies, ["a1", "a2"]);
786
787 Ok(())
788}
789
790#[driver_test(
793 id(ID),
794 requires(sql),
795 scenario(crate::scenarios::user_comment_article)
796)]
797pub async fn include_scalar_via(test: &mut Test) -> Result<()> {
798 let mut db = setup(test).await;
799
800 let users = toasty::create!(User::[
801 { name: "Alice" },
802 { name: "Bob" },
803 { name: "Charlie" },
804 ])
805 .exec(&mut db)
806 .await?;
807 let (alice, bob) = (&users[0], &users[1]);
808
809 let articles = toasty::create!(Article::[
810 { title: "Rust" },
811 { title: "Toasty" },
812 { title: "SQL" },
813 ])
814 .exec(&mut db)
815 .await?;
816 let (rust, toasty_article, sql) = (&articles[0], &articles[1], &articles[2]);
817
818 toasty::create!(Comment::[
819 { body: "a1", user: alice, article: rust },
820 { body: "a2", user: alice, article: rust },
821 { body: "a3", user: alice, article: toasty_article },
822 { body: "b1", user: bob, article: sql },
823 ])
824 .exec(&mut db)
825 .await?;
826
827 let loaded: Vec<User> = User::all()
828 .include(User::fields().commented_article_titles())
829 .exec(&mut db)
830 .await?;
831 assert_eq!(3, loaded.len());
832
833 for user in &loaded {
834 let titles: Vec<&str> = user
835 .commented_article_titles
836 .get()
837 .iter()
838 .map(|t| &t[..])
839 .collect();
840 match &user.name[..] {
841 "Alice" => {
842 assert_eq_unordered!(titles, ["Rust", "Toasty"]);
843 }
844 "Bob" => {
845 assert_eq_unordered!(titles, ["SQL"]);
846 }
847 "Charlie" => assert!(titles.is_empty(), "Charlie has no comments; got {titles:?}"),
848 other => panic!("unexpected user {other}"),
849 }
850 }
851
852 Ok(())
853}
854
855#[driver_test(
859 id(ID),
860 requires(sql),
861 scenario(crate::scenarios::user_comment_article)
862)]
863pub async fn query_chain_scalar_via(test: &mut Test) -> Result<()> {
864 let mut db = setup(test).await;
865
866 let alice = toasty::create!(User { name: "Alice" })
867 .exec(&mut db)
868 .await?;
869
870 let articles = toasty::create!(Article::[{ title: "Rust" }, { title: "Toasty" }])
871 .exec(&mut db)
872 .await?;
873 let (rust, toasty_article) = (&articles[0], &articles[1]);
874
875 toasty::create!(Comment::[
876 { body: "a1", user: &alice, article: rust },
877 { body: "a2", user: &alice, article: rust },
878 { body: "a3", user: &alice, article: toasty_article },
879 ])
880 .exec(&mut db)
881 .await?;
882
883 let titles = User::filter(User::fields().name().eq("Alice"))
884 .commented_article_titles()
885 .exec(&mut db)
886 .await?;
887 assert_eq_unordered!(titles.iter().map(|t| &t[..]), ["Rust", "Toasty"]);
888
889 Ok(())
890}
891
892#[driver_test(
895 id(ID),
896 requires(sql),
897 scenario(crate::scenarios::user_comment_article)
898)]
899pub async fn select_scalar_via(test: &mut Test) -> Result<()> {
900 let mut db = setup(test).await;
901
902 let alice = toasty::create!(User { name: "Alice" })
903 .exec(&mut db)
904 .await?;
905
906 let articles = toasty::create!(Article::[{ title: "Rust" }, { title: "Toasty" }])
907 .exec(&mut db)
908 .await?;
909 let (rust, toasty_article) = (&articles[0], &articles[1]);
910
911 toasty::create!(Comment::[
912 { body: "a1", user: &alice, article: rust },
913 { body: "a2", user: &alice, article: rust },
914 { body: "a3", user: &alice, article: toasty_article },
915 ])
916 .exec(&mut db)
917 .await?;
918
919 let titles_per_user: Vec<Vec<String>> = User::all()
920 .select(User::fields().commented_article_titles())
921 .exec(&mut db)
922 .await?;
923
924 assert_eq!(1, titles_per_user.len());
925 let titles: Vec<&str> = titles_per_user[0].iter().map(|t| &t[..]).collect();
926 assert_eq_unordered!(titles, ["Rust", "Toasty"]);
927
928 Ok(())
929}
930
931#[driver_test(id(ID), requires(sql), scenario(crate::scenarios::user_tag_names))]
939pub async fn eager_scalar_via_auto_loads(test: &mut Test) -> Result<()> {
940 let mut db = setup(test).await;
941
942 let users = toasty::create!(User::[{ name: "Alice" }, { name: "Bob" }])
943 .exec(&mut db)
944 .await?;
945 let (alice, bob) = (&users[0], &users[1]);
946
947 toasty::create!(Tag::[
948 { name: "rust", user: alice },
949 { name: "rust", user: alice },
950 { name: "db", user: alice },
951 { name: "sql", user: bob },
952 ])
953 .exec(&mut db)
954 .await?;
955
956 let loaded: Vec<User> = User::all().exec(&mut db).await?;
958 assert_eq!(2, loaded.len());
959
960 for user in &loaded {
961 let names: Vec<&str> = user.tag_names.iter().map(|n| &n[..]).collect();
962 match &user.name[..] {
963 "Alice" => {
965 assert_eq_unordered!(names, ["rust", "db"]);
966 }
967 "Bob" => {
968 assert_eq_unordered!(names, ["sql"]);
969 }
970 other => panic!("unexpected user {other}"),
971 }
972 }
973
974 Ok(())
975}