v / vlib / orm / orm_embed_test.v
442 lines · 361 sloc · 8.07 KB · f479e989063bc4b09e150bd891e5cf4be152d9d6
Raw
1// vtest retry: 3
2// vtest build: present_sqlite3? && !windows && !sanitize-memory-clang
3import db.sqlite
4
5// Basic embedded struct
6struct Coordinates {
7 latitude f64
8 longitude f64
9}
10
11// Struct with embedded Coordinates
12struct Location {
13 Coordinates
14 id int @[primary; sql: serial]
15 name string
16}
17
18// Another embedded struct with different types
19struct Metadata {
20 created_by string
21 version int
22 is_active bool
23}
24
25// Struct with multiple fields and embedded struct
26struct Document {
27 Metadata
28 id int @[primary; sql: serial]
29 title string
30 content string
31}
32
33// Struct embedding another struct that has various field types
34struct PersonInfo {
35 first_name string
36 last_name string
37 age int
38}
39
40struct Employee {
41 PersonInfo
42 id int @[primary; sql: serial]
43 department string
44 salary f64
45}
46
47// Test basic embedded struct insert and select
48fn test_embedded_struct_insert_and_select() {
49 db := sqlite.connect(':memory:')!
50
51 sql db {
52 create table Location
53 }!
54
55 loc := Location{
56 name: 'Paris'
57 latitude: 48.8566
58 longitude: 2.3522
59 }
60
61 sql db {
62 insert loc into Location
63 }!
64
65 locations := sql db {
66 select from Location
67 }!
68
69 assert locations.len == 1
70 fetched := locations.first()
71 assert fetched.name == 'Paris'
72 assert fetched.latitude == 48.8566
73 assert fetched.longitude == 2.3522
74}
75
76// Test multiple inserts with embedded struct
77fn test_embedded_struct_multiple_inserts() {
78 db := sqlite.connect(':memory:')!
79
80 sql db {
81 create table Location
82 }!
83
84 locations_to_insert := [
85 Location{
86 name: 'New York'
87 latitude: 40.7128
88 longitude: -74.0060
89 },
90 Location{
91 name: 'Tokyo'
92 latitude: 35.6762
93 longitude: 139.6503
94 },
95 Location{
96 name: 'Sydney'
97 latitude: -33.8688
98 longitude: 151.2093
99 },
100 ]
101
102 for loc in locations_to_insert {
103 sql db {
104 insert loc into Location
105 }!
106 }
107
108 locations := sql db {
109 select from Location
110 }!
111
112 assert locations.len == 3
113
114 // Verify each location
115 assert locations[0].name == 'New York'
116 assert locations[0].latitude == 40.7128
117 assert locations[0].longitude == -74.0060
118
119 assert locations[1].name == 'Tokyo'
120 assert locations[1].latitude == 35.6762
121 assert locations[1].longitude == 139.6503
122
123 assert locations[2].name == 'Sydney'
124 assert locations[2].latitude == -33.8688
125 assert locations[2].longitude == 151.2093
126}
127
128// Test embedded struct with different field types (string, int, bool)
129fn test_embedded_struct_various_types() {
130 db := sqlite.connect(':memory:')!
131
132 sql db {
133 create table Document
134 }!
135
136 doc := Document{
137 title: 'Test Document'
138 content: 'This is the content'
139 created_by: 'admin'
140 version: 1
141 is_active: true
142 }
143
144 sql db {
145 insert doc into Document
146 }!
147
148 docs := sql db {
149 select from Document
150 }!
151
152 assert docs.len == 1
153 fetched := docs.first()
154 assert fetched.title == 'Test Document'
155 assert fetched.content == 'This is the content'
156 assert fetched.created_by == 'admin'
157 assert fetched.version == 1
158 assert fetched.is_active == true
159}
160
161// Test embedded struct with bool false value
162fn test_embedded_struct_bool_false() {
163 db := sqlite.connect(':memory:')!
164
165 sql db {
166 create table Document
167 }!
168
169 doc := Document{
170 title: 'Inactive Doc'
171 content: 'Content here'
172 created_by: 'user'
173 version: 2
174 is_active: false
175 }
176
177 sql db {
178 insert doc into Document
179 }!
180
181 docs := sql db {
182 select from Document
183 }!
184
185 assert docs.len == 1
186 assert docs.first().is_active == false
187}
188
189// Test employee with person info embedded
190fn test_employee_with_embedded_person_info() {
191 db := sqlite.connect(':memory:')!
192
193 sql db {
194 create table Employee
195 }!
196
197 emp := Employee{
198 first_name: 'John'
199 last_name: 'Doe'
200 age: 30
201 department: 'Engineering'
202 salary: 75000.50
203 }
204
205 sql db {
206 insert emp into Employee
207 }!
208
209 employees := sql db {
210 select from Employee
211 }!
212
213 assert employees.len == 1
214 fetched := employees.first()
215 assert fetched.first_name == 'John'
216 assert fetched.last_name == 'Doe'
217 assert fetched.age == 30
218 assert fetched.department == 'Engineering'
219 assert fetched.salary == 75000.50
220}
221
222// Test selecting specific records with where clause on non-embedded field
223fn test_embedded_struct_select_with_where() {
224 db := sqlite.connect(':memory:')!
225
226 sql db {
227 create table Employee
228 }!
229
230 employees_to_insert := [
231 Employee{
232 first_name: 'Alice'
233 last_name: 'Smith'
234 age: 25
235 department: 'HR'
236 salary: 50000.0
237 },
238 Employee{
239 first_name: 'Bob'
240 last_name: 'Jones'
241 age: 35
242 department: 'Engineering'
243 salary: 80000.0
244 },
245 Employee{
246 first_name: 'Carol'
247 last_name: 'Williams'
248 age: 28
249 department: 'Engineering'
250 salary: 70000.0
251 },
252 ]
253
254 for emp in employees_to_insert {
255 sql db {
256 insert emp into Employee
257 }!
258 }
259
260 // Select by department
261 engineers := sql db {
262 select from Employee where department == 'Engineering'
263 }!
264
265 assert engineers.len == 2
266 assert engineers[0].first_name == 'Bob'
267 assert engineers[1].first_name == 'Carol'
268
269 // Verify all embedded fields are correctly fetched
270 for eng in engineers {
271 assert eng.last_name.len > 0
272 assert eng.age > 0
273 assert eng.salary > 0
274 }
275}
276
277// Test that embedded struct fields are stored with correct column names
278fn test_embedded_struct_field_values_integrity() {
279 db := sqlite.connect(':memory:')!
280
281 sql db {
282 create table Location
283 }!
284
285 // Insert with specific values that could be confused
286 loc := Location{
287 name: 'Test'
288 latitude: 12.345
289 longitude: 67.890
290 }
291
292 sql db {
293 insert loc into Location
294 }!
295
296 locations := sql db {
297 select from Location
298 }!
299
300 fetched := locations.first()
301
302 // Ensure latitude and longitude are not swapped
303 assert fetched.latitude == 12.345
304 assert fetched.longitude == 67.890
305 // Ensure they're not equal (which would indicate a bug)
306 assert fetched.latitude != fetched.longitude
307}
308
309// Test update on non-embedded fields preserves embedded field values
310fn test_update_preserves_embedded_fields() {
311 db := sqlite.connect(':memory:')!
312
313 sql db {
314 create table Location
315 }!
316
317 loc := Location{
318 name: 'Original'
319 latitude: 10.0
320 longitude: 20.0
321 }
322
323 sql db {
324 insert loc into Location
325 }!
326
327 // Update only the name
328 sql db {
329 update Location set name = 'Updated' where id == 1
330 }!
331
332 locations := sql db {
333 select from Location where id == 1
334 }!
335
336 fetched := locations.first()
337 assert fetched.name == 'Updated'
338 // Embedded fields should be preserved
339 assert fetched.latitude == 10.0
340 assert fetched.longitude == 20.0
341}
342
343// Test delete with embedded struct
344fn test_delete_with_embedded_struct() {
345 db := sqlite.connect(':memory:')!
346
347 sql db {
348 create table Location
349 }!
350
351 loc1 := Location{
352 name: 'ToDelete'
353 latitude: 1.0
354 longitude: 2.0
355 }
356
357 loc2 := Location{
358 name: 'ToKeep'
359 latitude: 3.0
360 longitude: 4.0
361 }
362
363 sql db {
364 insert loc1 into Location
365 insert loc2 into Location
366 }!
367
368 sql db {
369 delete from Location where name == 'ToDelete'
370 }!
371
372 locations := sql db {
373 select from Location
374 }!
375
376 assert locations.len == 1
377 assert locations.first().name == 'ToKeep'
378 assert locations.first().latitude == 3.0
379 assert locations.first().longitude == 4.0
380}
381
382// Test empty/zero values in embedded struct
383fn test_embedded_struct_zero_values() {
384 db := sqlite.connect(':memory:')!
385
386 sql db {
387 create table Employee
388 }!
389
390 emp := Employee{
391 first_name: ''
392 last_name: ''
393 age: 0
394 department: 'Test'
395 salary: 0.0
396 }
397
398 sql db {
399 insert emp into Employee
400 }!
401
402 employees := sql db {
403 select from Employee
404 }!
405
406 assert employees.len == 1
407 fetched := employees.first()
408 assert fetched.first_name == ''
409 assert fetched.last_name == ''
410 assert fetched.age == 0
411 assert fetched.salary == 0.0
412}
413
414// Test that the struct equality works correctly with embedded fields
415fn test_embedded_struct_equality() {
416 db := sqlite.connect(':memory:')!
417
418 sql db {
419 create table Location
420 }!
421
422 original := Location{
423 name: 'TestCity'
424 latitude: 45.0
425 longitude: 90.0
426 }
427
428 sql db {
429 insert original into Location
430 }!
431
432 locations := sql db {
433 select from Location
434 }!
435
436 fetched := locations.first()
437
438 // Compare all fields individually
439 assert fetched.name == original.name
440 assert fetched.latitude == original.latitude
441 assert fetched.longitude == original.longitude
442}
443