zig/test/behavior/struct.zig
Andrew Kelley be5130ec53 compiler_rt: move more functions to the stage2 section
also move more already-passing behavior tests to the passing section.
2021-12-29 00:39:25 -07:00

229 lines
4.8 KiB
Zig

const std = @import("std");
const builtin = @import("builtin");
const native_endian = builtin.target.cpu.arch.endian();
const expect = std.testing.expect;
const expectEqual = std.testing.expectEqual;
const expectEqualSlices = std.testing.expectEqualSlices;
const maxInt = std.math.maxInt;
top_level_field: i32,
test "top level fields" {
var instance = @This(){
.top_level_field = 1234,
};
instance.top_level_field += 1;
try expect(@as(i32, 1235) == instance.top_level_field);
}
const StructWithNoFields = struct {
fn add(a: i32, b: i32) i32 {
return a + b;
}
};
const StructFoo = struct {
a: i32,
b: bool,
c: f32,
};
test "structs" {
var foo: StructFoo = undefined;
@memset(@ptrCast([*]u8, &foo), 0, @sizeOf(StructFoo));
foo.a += 1;
foo.b = foo.a == 1;
try testFoo(foo);
testMutation(&foo);
try expect(foo.c == 100);
}
fn testFoo(foo: StructFoo) !void {
try expect(foo.b);
}
fn testMutation(foo: *StructFoo) void {
foo.c = 100;
}
test "struct byval assign" {
var foo1: StructFoo = undefined;
var foo2: StructFoo = undefined;
foo1.a = 1234;
foo2.a = 0;
try expect(foo2.a == 0);
foo2 = foo1;
try expect(foo2.a == 1234);
}
test "call struct static method" {
const result = StructWithNoFields.add(3, 4);
try expect(result == 7);
}
const should_be_11 = StructWithNoFields.add(5, 6);
test "invoke static method in global scope" {
try expect(should_be_11 == 11);
}
const empty_global_instance = StructWithNoFields{};
test "return empty struct instance" {
_ = returnEmptyStructInstance();
}
fn returnEmptyStructInstance() StructWithNoFields {
return empty_global_instance;
}
const Node = struct {
val: Val,
next: *Node,
};
const Val = struct {
x: i32,
};
test "fn call of struct field" {
const Foo = struct {
ptr: fn () i32,
};
const S = struct {
fn aFunc() i32 {
return 13;
}
fn callStructField(foo: Foo) i32 {
return foo.ptr();
}
};
try expect(S.callStructField(Foo{ .ptr = S.aFunc }) == 13);
}
test "struct initializer" {
const val = Val{ .x = 42 };
try expect(val.x == 42);
}
const MemberFnTestFoo = struct {
x: i32,
fn member(foo: MemberFnTestFoo) i32 {
return foo.x;
}
};
test "call member function directly" {
const instance = MemberFnTestFoo{ .x = 1234 };
const result = MemberFnTestFoo.member(instance);
try expect(result == 1234);
}
test "store member function in variable" {
const instance = MemberFnTestFoo{ .x = 1234 };
const memberFn = MemberFnTestFoo.member;
const result = memberFn(instance);
try expect(result == 1234);
}
test "member functions" {
const r = MemberFnRand{ .seed = 1234 };
try expect(r.getSeed() == 1234);
}
const MemberFnRand = struct {
seed: u32,
pub fn getSeed(r: *const MemberFnRand) u32 {
return r.seed;
}
};
test "return struct byval from function" {
const bar = makeBar2(1234, 5678);
try expect(bar.y == 5678);
}
const Bar = struct {
x: i32,
y: i32,
};
fn makeBar2(x: i32, y: i32) Bar {
return Bar{
.x = x,
.y = y,
};
}
test "call method with mutable reference to struct with no fields" {
const S = struct {
fn doC(s: *const @This()) bool {
_ = s;
return true;
}
fn do(s: *@This()) bool {
_ = s;
return true;
}
};
var s = S{};
try expect(S.doC(&s));
try expect(s.doC());
try expect(S.do(&s));
try expect(s.do());
}
test "usingnamespace within struct scope" {
const S = struct {
usingnamespace struct {
pub fn inner() i32 {
return 42;
}
};
};
try expect(@as(i32, 42) == S.inner());
}
test "struct field init with catch" {
const S = struct {
fn doTheTest() !void {
var x: anyerror!isize = 1;
var req = Foo{
.field = x catch undefined,
};
try expect(req.field == 1);
}
pub const Foo = extern struct {
field: isize,
};
};
try S.doTheTest();
comptime try S.doTheTest();
}
test "packed struct field alignment" {
const Stage1 = struct {
var baz: packed struct {
a: u32,
b: u32,
} = undefined;
};
const Stage2 = struct {
var baz: packed struct {
a: u32,
b: u32 align(1),
} = undefined;
};
const S = if (builtin.zig_is_stage2) Stage2 else Stage1;
try expect(@TypeOf(&S.baz.b) == *align(1) u32);
}
const blah: packed struct {
a: u3,
b: u3,
c: u2,
} = undefined;
test "bit field alignment" {
try expect(@TypeOf(&blah.b) == *align(1:3:1) const u3);
}