Skip to content

Commit ecdf5a0

Browse files
committed
test: add struct deep copy integration test (#1466)
1 parent a366112 commit ecdf5a0

2 files changed

Lines changed: 91 additions & 1 deletion

File tree

TESTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ Integration tests compile and run `.ez` programs end-to-end through the full com
5252

5353
**Structure:**
5454

55-
- `integration-tests/pass/core/`121 core language feature tests (arrays, control flow, structs, enums, maps, typeof, named returns, import variants, C interop, #strict when, or_return, raw strings, bigint arrays, pointer collections, non-standard map key ops, wide numeric map keys, [func] arrays, func var calls, enum map keys, map deep copy, wildcard types, [func] arrays of struct-namespaced refs, nested array deep copy, etc.)
55+
- `integration-tests/pass/core/`122 core language feature tests (arrays, control flow, structs, enums, maps, typeof, named returns, import variants, C interop, #strict when, or_return, raw strings, bigint arrays, pointer collections, non-standard map key ops, wide numeric map keys, [func] arrays, func var calls, enum map keys, map deep copy, wildcard types, [func] arrays of struct-namespaced refs, nested array deep copy, struct deep copy, etc.)
5656
- `integration-tests/pass/stdlib/` — 28 stdlib module tests
5757
- `integration-tests/pass/warnings/` — 22 warning detection tests
5858
- `integration-tests/pass/multi-file/` — 30 multi-file import tests (basic, alias, structs, enums, constants, private visibility, transitive, circular, collision, nested, struct functions)
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
* struct_deep_copy.ez - copy() on structs and struct-containing shapes
3+
* performs a deep copy of collection-typed fields.
4+
*
5+
* Regression for #1466 (commits 9b055bd + a366112):
6+
* - 9b055bd: TK_STRUCT branch in copy() deep-copies direct array/map
7+
* fields instead of falling through to a bitwise C struct copy.
8+
* - a366112: unified recursive deep-copy emitter covers transitive
9+
* struct nesting, arrays of structs with collection fields, and
10+
* maps whose values are structs with collection content.
11+
*
12+
* Three user-observable independence probes. A fourth gap — map[K:Struct]
13+
* where Struct holds a collection — is correct internally (verified by
14+
* reading the generated C during QA) but not observable from EZ user
15+
* code today because map reads return struct copies, so mutations can't
16+
* propagate back to the backing storage for an independence check
17+
* without additional ref semantics.
18+
*/
19+
20+
const Bag struct {
21+
name string
22+
items [int]
23+
}
24+
25+
const Inner struct {
26+
tag string
27+
nums [int]
28+
}
29+
30+
const Outer struct {
31+
id int
32+
inner Inner
33+
}
34+
35+
do main() {
36+
println("=== Struct Deep Copy Test ===")
37+
mut passed int = 0
38+
mut failed int = 0
39+
40+
// -- direct array field (fix in 9b055bd) --
41+
mut bag Bag = Bag{name: "orig", items: {1, 2, 3}}
42+
mut bag_copy Bag = copy(bag)
43+
bag_copy.items[0] = 999
44+
bag_copy.name = "copy"
45+
if bag.name == "orig" && bag.items[0] == 1 &&
46+
bag_copy.name == "copy" && bag_copy.items[0] == 999 {
47+
println(" [PASS] direct array field in struct")
48+
passed += 1
49+
} otherwise {
50+
println(" [FAIL] direct array field in struct")
51+
failed += 1
52+
}
53+
54+
// -- transitive struct-in-struct with inner collection (fix in a366112) --
55+
mut o1 Outer = Outer{id: 1, inner: Inner{tag: "x", nums: {10, 20, 30}}}
56+
mut o2 Outer = copy(o1)
57+
o2.inner.nums[0] = 888
58+
o2.inner.tag = "y"
59+
if o1.inner.nums[0] == 10 && o1.inner.tag == "x" &&
60+
o2.inner.nums[0] == 888 && o2.inner.tag == "y" {
61+
println(" [PASS] transitive struct-in-struct-with-array")
62+
passed += 1
63+
} otherwise {
64+
println(" [FAIL] transitive struct-in-struct-with-array")
65+
failed += 1
66+
}
67+
68+
// -- array of structs with a collection field (fix in a366112) --
69+
mut bags [Bag] = {Bag{name: "a", items: {1, 2}}, Bag{name: "b", items: {3, 4}}}
70+
mut bags_copy [Bag] = copy(bags)
71+
bags_copy[0].items[0] = 777
72+
bags_copy[0].name = "A"
73+
if bags[0].items[0] == 1 && bags[0].name == "a" &&
74+
bags_copy[0].items[0] == 777 && bags_copy[0].name == "A" {
75+
println(" [PASS] array of structs with collection field")
76+
passed += 1
77+
} otherwise {
78+
println(" [FAIL] array of structs with collection field")
79+
failed += 1
80+
}
81+
82+
println("")
83+
println("Results: ${passed} passed, ${failed} failed")
84+
85+
if failed > 0 {
86+
println("SOME TESTS FAILED")
87+
} otherwise {
88+
println("ALL TESTS PASSED")
89+
}
90+
}

0 commit comments

Comments
 (0)