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
86#[driver_test(scenario(crate::scenarios::character_creature))]
89pub async fn shared_column_roundtrip(t: &mut Test) -> Result<()> {
90 let mut db = setup(t).await;
91
92 let human = Character::create()
93 .creature(Creature::Human {
94 name: "Alice".to_string(),
95 profession: "engineer".to_string(),
96 })
97 .exec(&mut db)
98 .await?;
99
100 let animal = Character::create()
101 .creature(Creature::Animal {
102 name: "Rex".to_string(),
103 species: "dog".to_string(),
104 })
105 .exec(&mut db)
106 .await?;
107
108 assert_eq!(
109 Character::get_by_id(&mut db, &human.id).await?.creature,
110 Creature::Human {
111 name: "Alice".to_string(),
112 profession: "engineer".to_string(),
113 }
114 );
115 assert_eq!(
116 Character::get_by_id(&mut db, &animal.id).await?.creature,
117 Creature::Animal {
118 name: "Rex".to_string(),
119 species: "dog".to_string(),
120 }
121 );
122
123 Ok(())
124}
125
126#[driver_test(scenario(crate::scenarios::character_creature))]
131pub async fn shared_column_update(t: &mut Test) -> Result<()> {
132 let mut db = setup(t).await;
133
134 let mut character = Character::create()
135 .creature(Creature::Human {
136 name: "Bob".to_string(),
137 profession: "builder".to_string(),
138 })
139 .exec(&mut db)
140 .await?;
141
142 character
145 .update()
146 .creature(Creature::Human {
147 name: "Bobby".to_string(),
148 profession: "architect".to_string(),
149 })
150 .exec(&mut db)
151 .await?;
152
153 assert_eq!(
154 Character::get_by_id(&mut db, &character.id).await?.creature,
155 Creature::Human {
156 name: "Bobby".to_string(),
157 profession: "architect".to_string(),
158 }
159 );
160
161 character
164 .update()
165 .creature(Creature::Animal {
166 name: "Whiskers".to_string(),
167 species: "cat".to_string(),
168 })
169 .exec(&mut db)
170 .await?;
171
172 assert_eq!(
173 Character::get_by_id(&mut db, &character.id).await?.creature,
174 Creature::Animal {
175 name: "Whiskers".to_string(),
176 species: "cat".to_string(),
177 }
178 );
179
180 Ok(())
181}
182
183#[driver_test(requires(scan), scenario(crate::scenarios::character_creature))]
193pub async fn shared_column_variant_gated_filter(t: &mut Test) -> Result<()> {
194 let mut db = setup(t).await;
195
196 for (name, profession) in [("Bob", "builder"), ("Alice", "artist")] {
197 Character::create()
198 .creature(Creature::Human {
199 name: name.to_string(),
200 profession: profession.to_string(),
201 })
202 .exec(&mut db)
203 .await?;
204 }
205
206 for (name, species) in [("Bob", "dog"), ("Rex", "cat")] {
207 Character::create()
208 .creature(Creature::Animal {
209 name: name.to_string(),
210 species: species.to_string(),
211 })
212 .exec(&mut db)
213 .await?;
214 }
215
216 let human_bobs = Character::filter(Character::fields().creature().human().name().eq("Bob"))
220 .exec(&mut db)
221 .await?;
222 assert_eq!(human_bobs.len(), 1);
223 assert!(matches!(human_bobs[0].creature, Creature::Human { .. }));
224
225 let animal_bobs = Character::filter(Character::fields().creature().animal().name().eq("Bob"))
228 .exec(&mut db)
229 .await?;
230 assert_eq!(animal_bobs.len(), 1);
231 assert!(matches!(animal_bobs[0].creature, Creature::Animal { .. }));
232
233 let humans_named_alice =
235 Character::filter(Character::fields().creature().human().name().eq("Alice"))
236 .exec(&mut db)
237 .await?;
238 assert_eq!(humans_named_alice.len(), 1);
239
240 Ok(())
241}
242
243#[driver_test(requires(scan), scenario(crate::scenarios::character_creature))]
250pub async fn shared_column_cross_variant_or(t: &mut Test) -> Result<()> {
251 let mut db = setup(t).await;
252
253 Character::create()
254 .creature(Creature::Human {
255 name: "Bob".to_string(),
256 profession: "builder".to_string(),
257 })
258 .exec(&mut db)
259 .await?;
260 Character::create()
261 .creature(Creature::Animal {
262 name: "Bob".to_string(),
263 species: "dog".to_string(),
264 })
265 .exec(&mut db)
266 .await?;
267 Character::create()
268 .creature(Creature::Animal {
269 name: "Rex".to_string(),
270 species: "cat".to_string(),
271 })
272 .exec(&mut db)
273 .await?;
274
275 let bobs = Character::filter(
278 Character::fields()
279 .creature()
280 .human()
281 .name()
282 .eq("Bob")
283 .or(Character::fields().creature().animal().name().eq("Bob")),
284 )
285 .exec(&mut db)
286 .await?;
287 assert_eq!(bobs.len(), 2);
288
289 Ok(())
290}