Skip to main content

toasty_driver_integration_suite/tests/
select_projection.rs

1use crate::prelude::*;
2
3/// `.select(field)` on a `Query<List<Item>>` returns a `Query<List<String>>`
4/// whose `.exec()` produces a `Vec<String>` of the projected column.
5#[driver_test(scenario(crate::scenarios::fixed_item_name_quantity))]
6pub async fn select_single_field(test: &mut Test) -> Result<()> {
7    let mut db = setup(test).await;
8
9    toasty::create!(Item::[
10        { id: 1_i64, name: "Alice",   quantity: 7_i64  },
11        { id: 2_i64, name: "Bob",     quantity: 3_i64  },
12        { id: 3_i64, name: "Charlie", quantity: 11_i64 },
13    ])
14    .exec(&mut db)
15    .await
16    .unwrap();
17
18    let mut names: Vec<String> = Item::all()
19        .select(Item::fields().name())
20        .exec(&mut db)
21        .await?;
22
23    names.sort();
24
25    assert_eq!(
26        names,
27        vec![
28            "Alice".to_string(),
29            "Bob".to_string(),
30            "Charlie".to_string()
31        ]
32    );
33
34    Ok(())
35}
36
37/// `.select((f1, f2))` returns a `Query<List<(T1, T2)>>` whose `.exec()`
38/// produces a `Vec` of tuples.
39#[driver_test(scenario(crate::scenarios::fixed_item_name_quantity))]
40pub async fn select_tuple(test: &mut Test) -> Result<()> {
41    let mut db = setup(test).await;
42
43    toasty::create!(Item::[
44        { id: 1_i64, name: "Alice",   quantity: 7_i64  },
45        { id: 2_i64, name: "Bob",     quantity: 3_i64  },
46        { id: 3_i64, name: "Charlie", quantity: 11_i64 },
47    ])
48    .exec(&mut db)
49    .await
50    .unwrap();
51
52    let mut pairs: Vec<(i64, String)> = Item::all()
53        .select((Item::fields().id(), Item::fields().name()))
54        .exec(&mut db)
55        .await?;
56
57    pairs.sort_by_key(|(id, _)| *id);
58
59    assert_eq!(
60        pairs,
61        vec![
62            (1_i64, "Alice".to_string()),
63            (2_i64, "Bob".to_string()),
64            (3_i64, "Charlie".to_string()),
65        ]
66    );
67
68    Ok(())
69}
70
71/// `.select(...)` composes with `.filter(...)`: the projection sees only rows
72/// matching the filter expression.
73#[driver_test(scenario(crate::scenarios::fixed_item_name_quantity))]
74pub async fn select_with_filter(test: &mut Test) -> Result<()> {
75    let mut db = setup(test).await;
76
77    toasty::create!(Item::[
78        { id: 1_i64, name: "Alice",   quantity: 7_i64  },
79        { id: 2_i64, name: "Bob",     quantity: 3_i64  },
80        { id: 3_i64, name: "Charlie", quantity: 11_i64 },
81    ])
82    .exec(&mut db)
83    .await
84    .unwrap();
85
86    let mut names: Vec<String> = Item::filter(Item::fields().quantity().gt(5_i64))
87        .select(Item::fields().name())
88        .exec(&mut db)
89        .await?;
90
91    names.sort();
92
93    assert_eq!(names, vec!["Alice".to_string(), "Charlie".to_string()]);
94
95    Ok(())
96}
97
98/// `.select(...).first()` lifts the outer container to `Option<T>`.
99#[driver_test(scenario(crate::scenarios::fixed_item_name_quantity))]
100pub async fn select_first(test: &mut Test) -> Result<()> {
101    let mut db = setup(test).await;
102
103    toasty::create!(Item::[
104        { id: 1_i64, name: "Alice",   quantity: 7_i64  },
105        { id: 2_i64, name: "Bob",     quantity: 3_i64  },
106        { id: 3_i64, name: "Charlie", quantity: 11_i64 },
107    ])
108    .exec(&mut db)
109    .await
110    .unwrap();
111
112    let name: Option<String> = Item::filter(Item::fields().id().eq(2_i64))
113        .select(Item::fields().name())
114        .first()
115        .exec(&mut db)
116        .await?;
117
118    assert_eq!(name.as_deref(), Some("Bob"));
119
120    Ok(())
121}
122
123/// `.select(...).first()` returns `None` when no rows match.
124#[driver_test(scenario(crate::scenarios::fixed_item_name_quantity))]
125pub async fn select_first_no_match(test: &mut Test) -> Result<()> {
126    let mut db = setup(test).await;
127
128    toasty::create!(Item::[
129        { id: 1_i64, name: "Alice",   quantity: 7_i64  },
130        { id: 2_i64, name: "Bob",     quantity: 3_i64  },
131        { id: 3_i64, name: "Charlie", quantity: 11_i64 },
132    ])
133    .exec(&mut db)
134    .await
135    .unwrap();
136
137    let name: Option<String> = Item::filter(Item::fields().id().eq(999_i64))
138        .select(Item::fields().name())
139        .first()
140        .exec(&mut db)
141        .await?;
142
143    assert_eq!(name, None);
144
145    Ok(())
146}