ink/src/error_tests.zig
2026-03-30 05:44:35 -06:00

152 lines
3.3 KiB
Zig

const std = @import("std");
const compile = @import("compile.zig");
const Module = compile.Module;
test "compiler: unknown global variable" {
try testEqual(
\\{a}
,
\\<STDIN>:1:2: error: unknown identifier
\\1 | {a}
\\ | ^
\\
,
);
}
test "compiler: duplicate variable declarations" {
try testEqual(
\\VAR a = 0
\\VAR b = 2
\\VAR a = 1
,
\\<STDIN>:3:1: error: duplicate identifier
\\3 | VAR a = 1
\\ | ^
\\
,
);
}
test "compiler: duplicate knot declarations" {
try testEqual(
\\== a
\\== a
,
\\<STDIN>:2:1: error: duplicate identifier
\\2 | == a
\\ | ^
\\
,
);
}
test "compiler: duplicate mixed declarations" {
try testEqual(
\\VAR a = 1
\\== a
\\Hello, world!
,
\\<STDIN>:1:1: error: duplicate identifier
\\1 | VAR a = 1
\\ | ^
\\
,
);
}
test "compiler: invalid divert target" {
try testEqual(
\\-> foo
\\
\\VAR foo = 123
,
\\<STDIN>:1:4: error: invalid divert target
\\1 | -> foo
\\ | ^
\\
);
}
test "compiler: global variable restrictions" {
try testEqual(
\\VAR a = b
\\VAR b = a
,
\\<STDIN>:1:9: error: global variable assignments cannot refer to other variables
\\1 | VAR a = b
\\ | ^
\\
);
}
test "compiler: constant cycle detection" {
try testEqual(
\\CONST a = a
,
\\<STDIN>:1:11: error: cycle detected in constant initializer
\\1 | CONST a = a
\\ | ^
\\
);
}
test "compiler: final else case" {
try testEqual(
\\{true:
\\- else:
\\ False
\\- 1 == 1:
\\ Woops!
\\}
,
\\<STDIN>:2:3: error: 'else' case should always be the final case in conditional
\\2 | - else:
\\ | ^
\\
);
}
test "compiler: final else case 2" {
try testEqual(
\\{
\\- true:
\\ True
\\- else:
\\ False
\\- else:
\\ False
\\}
,
\\<STDIN>:4:3: error: 'else' case should always be the final case in conditional
\\4 | - else:
\\ | ^
\\
);
}
fn testEqual(source_bytes: [:0]const u8, expected_error: []const u8) !void {
const gpa = std.testing.allocator;
var arena_allocator = std.heap.ArenaAllocator.init(gpa);
defer arena_allocator.deinit();
var allocating = std.io.Writer.Allocating.init(gpa);
defer allocating.deinit();
const io_w = &allocating.writer;
const arena = arena_allocator.allocator();
var c = try Module.compile(gpa, arena, .{
.source_bytes = source_bytes,
.filename = "<STDIN>",
.dump_writer = null,
.dump_use_color = false,
.dump_ast = false,
.dump_ir = false,
});
defer c.deinit();
try std.testing.expect(c.errors.items.len > 0);
for (c.errors.items) |err| try c.renderError(io_w, err);
return std.testing.expectEqualSlices(u8, expected_error, allocating.written());
}