toasty_driver_integration_suite/tests/
embed_enum_shared_column.rs1use crate::prelude::*;
2
3#[driver_test(scenario(crate::scenarios::character_creature))]
8pub async fn shared_column_db_schema(t: &mut Test) {
9 let db = setup(t).await;
10 let schema = db.schema();
11
12 assert_struct!(schema.db.tables, [
13 {
14 name: =~ r"characters$",
15 columns: [
16 { name: "id" },
17 { name: "creature", nullable: false },
18 { name: "creature_name", nullable: true },
20 { name: "creature_profession", nullable: true },
21 { name: "creature_species", nullable: true },
22 ],
23 },
24 ]);
25}
26
27#[driver_test(scenario(crate::scenarios::character_creature))]
31pub async fn shared_column_schema_fields(t: &mut Test) {
32 let db = setup(t).await;
33 let schema = db.schema();
34
35 let creature = &schema.app.models[&Creature::id()];
36 assert_struct!(creature, toasty::schema::app::Model::EmbeddedEnum({
37 fields: [
38 { name.app: Some("name"), shared: Some({ parts: ["name"] }) },
39 { name.app: Some("profession"), shared: None },
40 { name.app: Some("name"), shared: Some({ parts: ["name"] }) },
41 { name.app: Some("species"), shared: None },
42 ],
43 }));
44}
45
46#[driver_test]
47pub async fn raw_shared_identifier_uses_bare_name(t: &mut Test) {
48 #[derive(Debug, toasty::Embed)]
49 enum Value {
50 Text {
51 #[shared(r#type)]
52 kind: String,
53 },
54 Number {
55 #[shared(r#type)]
56 kind: String,
57 },
58 }
59
60 #[derive(Debug, toasty::Model)]
61 struct Record {
62 #[key]
63 id: String,
64 value: Value,
65 }
66
67 let db = t.setup_db(models!(Record)).await;
68 let schema = db.schema();
69
70 assert_struct!(schema.app.models[&Value::id()], toasty::schema::app::Model::EmbeddedEnum({
71 fields: [
72 { shared: Some({ parts: ["type"] }) },
73 { shared: Some({ parts: ["type"] }) },
74 ],
75 }));
76 assert_struct!(schema.db.tables, [{
77 columns: [
78 { name: "id" },
79 { name: "value" },
80 { name: "value_type" },
81 ],
82 }]);
83}
84
85#[driver_test(scenario(crate::scenarios::character_creature))]
88pub async fn shared_column_roundtrip(t: &mut Test) -> Result<()> {
89 let mut db = setup(t).await;
90
91 let human = Character::create()
92 .creature(Creature::Human {
93 name: "Alice".to_string(),
94 profession: "engineer".to_string(),
95 })
96 .exec(&mut db)
97 .await?;
98
99 let animal = Character::create()
100 .creature(Creature::Animal {
101 name: "Rex".to_string(),
102 species: "dog".to_string(),
103 })
104 .exec(&mut db)
105 .await?;
106
107 assert_eq!(
108 Character::get_by_id(&mut db, &human.id).await?.creature,
109 Creature::Human {
110 name: "Alice".to_string(),
111 profession: "engineer".to_string(),
112 }
113 );
114 assert_eq!(
115 Character::get_by_id(&mut db, &animal.id).await?.creature,
116 Creature::Animal {
117 name: "Rex".to_string(),
118 species: "dog".to_string(),
119 }
120 );
121
122 Ok(())
123}
124
125#[driver_test(scenario(crate::scenarios::character_creature))]
130pub async fn shared_column_update(t: &mut Test) -> Result<()> {
131 let mut db = setup(t).await;
132
133 let mut character = Character::create()
134 .creature(Creature::Human {
135 name: "Bob".to_string(),
136 profession: "builder".to_string(),
137 })
138 .exec(&mut db)
139 .await?;
140
141 character
144 .update()
145 .creature(Creature::Human {
146 name: "Bobby".to_string(),
147 profession: "architect".to_string(),
148 })
149 .exec(&mut db)
150 .await?;
151
152 assert_eq!(
153 Character::get_by_id(&mut db, &character.id).await?.creature,
154 Creature::Human {
155 name: "Bobby".to_string(),
156 profession: "architect".to_string(),
157 }
158 );
159
160 character
163 .update()
164 .creature(Creature::Animal {
165 name: "Whiskers".to_string(),
166 species: "cat".to_string(),
167 })
168 .exec(&mut db)
169 .await?;
170
171 assert_eq!(
172 Character::get_by_id(&mut db, &character.id).await?.creature,
173 Creature::Animal {
174 name: "Whiskers".to_string(),
175 species: "cat".to_string(),
176 }
177 );
178
179 Ok(())
180}
181
182#[driver_test(requires(scan), scenario(crate::scenarios::character_creature))]
192pub async fn shared_column_variant_gated_filter(t: &mut Test) -> Result<()> {
193 let mut db = setup(t).await;
194
195 for (name, profession) in [("Bob", "builder"), ("Alice", "artist")] {
196 Character::create()
197 .creature(Creature::Human {
198 name: name.to_string(),
199 profession: profession.to_string(),
200 })
201 .exec(&mut db)
202 .await?;
203 }
204
205 for (name, species) in [("Bob", "dog"), ("Rex", "cat")] {
206 Character::create()
207 .creature(Creature::Animal {
208 name: name.to_string(),
209 species: species.to_string(),
210 })
211 .exec(&mut db)
212 .await?;
213 }
214
215 let human_bobs = Character::filter(Character::fields().creature().human().name().eq("Bob"))
219 .exec(&mut db)
220 .await?;
221 assert_eq!(human_bobs.len(), 1);
222 assert!(matches!(human_bobs[0].creature, Creature::Human { .. }));
223
224 let animal_bobs = Character::filter(Character::fields().creature().animal().name().eq("Bob"))
227 .exec(&mut db)
228 .await?;
229 assert_eq!(animal_bobs.len(), 1);
230 assert!(matches!(animal_bobs[0].creature, Creature::Animal { .. }));
231
232 let humans_named_alice =
234 Character::filter(Character::fields().creature().human().name().eq("Alice"))
235 .exec(&mut db)
236 .await?;
237 assert_eq!(humans_named_alice.len(), 1);
238
239 Ok(())
240}
241
242#[driver_test(requires(scan), scenario(crate::scenarios::character_creature))]
249pub async fn shared_column_cross_variant_or(t: &mut Test) -> Result<()> {
250 let mut db = setup(t).await;
251
252 Character::create()
253 .creature(Creature::Human {
254 name: "Bob".to_string(),
255 profession: "builder".to_string(),
256 })
257 .exec(&mut db)
258 .await?;
259 Character::create()
260 .creature(Creature::Animal {
261 name: "Bob".to_string(),
262 species: "dog".to_string(),
263 })
264 .exec(&mut db)
265 .await?;
266 Character::create()
267 .creature(Creature::Animal {
268 name: "Rex".to_string(),
269 species: "cat".to_string(),
270 })
271 .exec(&mut db)
272 .await?;
273
274 let bobs = Character::filter(
277 Character::fields()
278 .creature()
279 .human()
280 .name()
281 .eq("Bob")
282 .or(Character::fields().creature().animal().name().eq("Bob")),
283 )
284 .exec(&mut db)
285 .await?;
286 assert_eq!(bobs.len(), 2);
287
288 Ok(())
289}