Add tests for constant unions

This commit is contained in:
korvahkh
2026-08-08 20:19:18 -05:00
parent f97274fd0a
commit feb008ab6e

View File

@@ -52,3 +52,195 @@ union_constant_as_a_global_initializer :: proc(t: ^testing.T) {
if v, ok := G.(int); testing.expect(t, ok, "global lost its variant") { testing.expect_value(t, v, 3) }
if v, ok := GS.(string); testing.expect(t, ok, "string global lost its variant") { testing.expect_value(t, v, "hello") }
}
A :: union {B, bool}
B :: union {C, int }
C :: struct{}
@(test)
union_const_access :: proc(t: ^testing.T) {
X :: struct{x: A}{B(C{})}
testing.expect_value(t, X.x, A(B(C{})))
E :: enum {y}
Y : [E]A : {.y = true}
testing.expect_value(t, Y[.y], A(true))
}
@(test)
nested_union_implicit_cast :: proc(t: ^testing.T) {
Av: A: Bv
Bv: B: Cv
Cv: C: {}
testing.expect_value(t, Av, A(B(C{})))
}
@(test)
union_ternary :: proc(t: ^testing.T) {
E0 : A = B(C{}) if true else B(C{})
E1 : A = true if true else true
E2 := A(B(C{}) if true else B(C{}))
E3 := A(true if true else true)
testing.expect_value(t, E0, A(B(C{})))
testing.expect_value(t, E1, A(true))
testing.expect_value(t, E2, A(B(C{})))
testing.expect_value(t, E3, A(true))
}
@(test)
union_array :: proc(t: ^testing.T) {
C0: [2][2]A: B(C{})
C1: struct {x: [2][2]A} : {B(C{})}
testing.expect_value(t, C0, [2][2]A{0..<2 = B(C{})})
}
@(test)
union_multi_level_cast :: proc(t: ^testing.T) {
UI :: union {int, bool}
foo: Maybe(UI): 1
bar: union{UI}: 2
baz: UI: 3
qux: struct{ui: UI}: {4}
testing.expect_value(t, foo, 1)
testing.expect_value(t, bar, 2)
testing.expect_value(t, baz, 3)
testing.expect_value(t, qux.ui, 4)
}
@(test)
union_args :: proc(t: ^testing.T) {
implicit_bool :: proc(a: A = true ) -> A { return a.(bool) }
explicit_bool :: proc(a: A = A(true)) -> A { return a.(bool) }
nil_union :: proc(a: A = B{} ) -> A { return a.(B ) }
struct_union :: proc(a: A = B(C{}) ) -> A { return a.(B ) }
testing.expect_value(t, implicit_bool(), true)
testing.expect_value(t, explicit_bool(), true)
testing.expect_value(t, nil_union (), B{})
testing.expect_value(t, struct_union (), B(C{}))
testing.expect_value(t, implicit_bool(true ), true)
testing.expect_value(t, explicit_bool(A(true)), true)
testing.expect_value(t, nil_union (B{} ), B{})
testing.expect_value(t, struct_union (B(C{}) ), B(C{}))
testing.expect_value(t, implicit_bool(a=true ), true)
testing.expect_value(t, explicit_bool(a=A(true)), true)
testing.expect_value(t, nil_union (a=B{} ), B{})
testing.expect_value(t, struct_union (a=B(C{}) ), B(C{}))
}
@(test)
union_in_aggregates :: proc(t: ^testing.T) {
S :: struct {
x : union { int, string },
y : u128,
}
U :: struct #packed {v: [2]S, n: i64}
V :: struct {x: [dynamic; 2]S}
s := [dynamic; 2]S { {x=1} }
u := U { {{x=1}, {x=2}}, 2 }
v := V{x = { {x=1} }}
testing.expect_value(t, s [0], S{x=1})
testing.expect_value(t, u.v[1], S{x=2})
testing.expect_value(t, v.x[0], S{x=1})
}
@(test)
union_named_constants :: proc(t: ^testing.T) {
Inner_Left :: enum {
a,
b,
}
Inner_Right :: enum {
c,
d,
}
Inner :: union {
Inner_Left,
Inner_Right,
}
Outer :: union {
Inner,
int,
}
Atom :: struct {
token: Outer,
}
Promoted_Value :: union {
int,
f32,
string,
}
Promoted_Inner :: struct {
value: Promoted_Value,
padding0: int,
padding1: int,
}
Promoted_Outer :: struct {
using inner: Promoted_Inner,
}
NAMED_INNER :: Inner(Inner_Left.a)
DIRECT_ATOMS :: [?]Atom{{token = Inner(Inner_Left.a)}}
NAMED_ATOMS :: [?]Atom{{token = NAMED_INNER}}
INDEXED_OUTERS :: [1]Outer {
0 = Inner(Inner_Left.a),
}
RANGED_OUTERS :: [1]Outer {
0..=0 = Inner(Inner_Left.a),
}
Outer_Index :: enum {first}
ENUMERATED_OUTERS :: [Outer_Index]Outer {
.first = Inner(Inner_Left.a),
}
RANGED_ENUMERATED_OUTERS :: [Outer_Index]Outer {
.first..=.first = Inner(Inner_Left.a),
}
FIXED_CAPACITY_OUTERS :: [dynamic; 1]Outer{
0 = Inner(Inner_Left.a),
}
RANGED_FIXED_CAPACITY_OUTERS :: [dynamic; 1]Outer{
0..=0 = Inner(Inner_Left.a),
}
POSITIONAL_FIXED_CAPACITY_OUTERS :: [dynamic; 1]Outer{
Inner(Inner_Left.a),
}
testing.expect_value(t, DIRECT_ATOMS[0], Atom{token = Inner(.a)})
testing.expect_value(t, NAMED_ATOMS[0], Atom{token = NAMED_INNER})
testing.expect_value(t, INDEXED_OUTERS[0], Inner(.a))
testing.expect_value(t, RANGED_OUTERS[0], Inner(.a))
testing.expect_value(t, ENUMERATED_OUTERS[.first], Inner(.a))
testing.expect_value(t, RANGED_ENUMERATED_OUTERS[.first], Inner(.a))
fco := FIXED_CAPACITY_OUTERS
rfco := RANGED_FIXED_CAPACITY_OUTERS
testing.expect_value(t, fco[0], Inner(.a))
testing.expect_value(t, rfco[0], Inner(.a))
testing.expect_value(t, POSITIONAL_FIXED_CAPACITY_OUTERS[0], Inner(.a))
testing.expect_value(t, Promoted_Outer {
value = Promoted_Value(int(1)),
}, Promoted_Outer {
inner = {Promoted_Value(int(1)), 0, 0},
})
}