mirror of
https://github.com/ziglang/zig.git
synced 2025-02-13 16:10:19 +00:00
Disallow named test decls with duplicate names
This commit is contained in:
parent
bac3a28214
commit
5a3eca5d4c
@ -2244,8 +2244,8 @@ test "struct" {
|
||||
field: u8,
|
||||
};
|
||||
const value = Struct{ .field = 42 };
|
||||
try expectFmt("struct: Struct{ .field = 42 }\n", "struct: {}\n", .{value});
|
||||
try expectFmt("struct: Struct{ .field = 42 }\n", "struct: {}\n", .{&value});
|
||||
try expectFmt("struct: fmt.test.struct.Struct{ .field = 42 }\n", "struct: {}\n", .{value});
|
||||
try expectFmt("struct: fmt.test.struct.Struct{ .field = 42 }\n", "struct: {}\n", .{&value});
|
||||
}
|
||||
{
|
||||
const Struct = struct {
|
||||
@ -2253,8 +2253,24 @@ test "struct" {
|
||||
b: u1,
|
||||
};
|
||||
const value = Struct{ .a = 0, .b = 1 };
|
||||
try expectFmt("struct: Struct{ .a = 0, .b = 1 }\n", "struct: {}\n", .{value});
|
||||
try expectFmt("struct: fmt.test.struct.Struct{ .a = 0, .b = 1 }\n", "struct: {}\n", .{value});
|
||||
}
|
||||
|
||||
const S = struct {
|
||||
a: u32,
|
||||
b: anyerror,
|
||||
};
|
||||
|
||||
const inst = S{
|
||||
.a = 456,
|
||||
.b = error.Unused,
|
||||
};
|
||||
|
||||
try expectFmt("fmt.test.struct.S{ .a = 456, .b = error.Unused }", "{}", .{inst});
|
||||
// Tuples
|
||||
try expectFmt("{ }", "{}", .{.{}});
|
||||
try expectFmt("{ -1 }", "{}", .{.{-1}});
|
||||
try expectFmt("{ -1, 42, 2.5e+04 }", "{}", .{.{ -1, 42, 0.25e5 }});
|
||||
}
|
||||
|
||||
test "enum" {
|
||||
@ -2263,13 +2279,26 @@ test "enum" {
|
||||
Two,
|
||||
};
|
||||
const value = Enum.Two;
|
||||
try expectFmt("enum: Enum.Two\n", "enum: {}\n", .{value});
|
||||
try expectFmt("enum: Enum.Two\n", "enum: {}\n", .{&value});
|
||||
try expectFmt("enum: Enum.One\n", "enum: {}\n", .{Enum.One});
|
||||
try expectFmt("enum: Enum.Two\n", "enum: {}\n", .{Enum.Two});
|
||||
try expectFmt("enum: fmt.test.enum.Enum.Two\n", "enum: {}\n", .{value});
|
||||
try expectFmt("enum: fmt.test.enum.Enum.Two\n", "enum: {}\n", .{&value});
|
||||
try expectFmt("enum: fmt.test.enum.Enum.One\n", "enum: {}\n", .{Enum.One});
|
||||
try expectFmt("enum: fmt.test.enum.Enum.Two\n", "enum: {}\n", .{Enum.Two});
|
||||
|
||||
// test very large enum to verify ct branch quota is large enough
|
||||
try expectFmt("enum: os.windows.win32error.Win32Error.INVALID_FUNCTION\n", "enum: {}\n", .{std.os.windows.Win32Error.INVALID_FUNCTION});
|
||||
// TODO: https://github.com/ziglang/zig/issues/15609
|
||||
if (!((builtin.cpu.arch == .wasm32) and builtin.mode == .Debug)) {
|
||||
try expectFmt("enum: os.windows.win32error.Win32Error.INVALID_FUNCTION\n", "enum: {}\n", .{std.os.windows.Win32Error.INVALID_FUNCTION});
|
||||
}
|
||||
|
||||
const E = enum {
|
||||
One,
|
||||
Two,
|
||||
Three,
|
||||
};
|
||||
|
||||
const inst = E.Two;
|
||||
|
||||
try expectFmt("fmt.test.enum.E.Two", "{}", .{inst});
|
||||
}
|
||||
|
||||
test "non-exhaustive enum" {
|
||||
@ -2445,24 +2474,6 @@ test "custom" {
|
||||
try expectFmt("dim: 10.200x2.220\n", "dim: {d}\n", .{value});
|
||||
}
|
||||
|
||||
test "struct" {
|
||||
const S = struct {
|
||||
a: u32,
|
||||
b: anyerror,
|
||||
};
|
||||
|
||||
const inst = S{
|
||||
.a = 456,
|
||||
.b = error.Unused,
|
||||
};
|
||||
|
||||
try expectFmt("fmt.test.struct.S{ .a = 456, .b = error.Unused }", "{}", .{inst});
|
||||
// Tuples
|
||||
try expectFmt("{ }", "{}", .{.{}});
|
||||
try expectFmt("{ -1 }", "{}", .{.{-1}});
|
||||
try expectFmt("{ -1, 42, 2.5e+04 }", "{}", .{.{ -1, 42, 0.25e5 }});
|
||||
}
|
||||
|
||||
test "union" {
|
||||
const TU = union(enum) {
|
||||
float: f32,
|
||||
@ -2493,18 +2504,6 @@ test "union" {
|
||||
try std.testing.expect(mem.eql(u8, eu_result[0..18], "fmt.test.union.EU@"));
|
||||
}
|
||||
|
||||
test "enum" {
|
||||
const E = enum {
|
||||
One,
|
||||
Two,
|
||||
Three,
|
||||
};
|
||||
|
||||
const inst = E.Two;
|
||||
|
||||
try expectFmt("fmt.test.enum.E.Two", "{}", .{inst});
|
||||
}
|
||||
|
||||
test "struct.self-referential" {
|
||||
const S = struct {
|
||||
const SelfType = @This();
|
||||
|
@ -1741,6 +1741,22 @@ test "std.hash_map clone" {
|
||||
try expectEqual(b.get(1).?, 1);
|
||||
try expectEqual(b.get(2).?, 2);
|
||||
try expectEqual(b.get(3).?, 3);
|
||||
|
||||
var original = AutoHashMap(i32, i32).init(std.testing.allocator);
|
||||
defer original.deinit();
|
||||
|
||||
var i: u8 = 0;
|
||||
while (i < 10) : (i += 1) {
|
||||
try original.putNoClobber(i, i * 10);
|
||||
}
|
||||
|
||||
var copy = try original.clone();
|
||||
defer copy.deinit();
|
||||
|
||||
i = 0;
|
||||
while (i < 10) : (i += 1) {
|
||||
try testing.expect(copy.get(i).? == i * 10);
|
||||
}
|
||||
}
|
||||
|
||||
test "std.hash_map ensureTotalCapacity with existing elements" {
|
||||
@ -2072,24 +2088,6 @@ test "std.hash_map basic hash map usage" {
|
||||
try testing.expect(map.remove(3) == true);
|
||||
}
|
||||
|
||||
test "std.hash_map clone" {
|
||||
var original = AutoHashMap(i32, i32).init(std.testing.allocator);
|
||||
defer original.deinit();
|
||||
|
||||
var i: u8 = 0;
|
||||
while (i < 10) : (i += 1) {
|
||||
try original.putNoClobber(i, i * 10);
|
||||
}
|
||||
|
||||
var copy = try original.clone();
|
||||
defer copy.deinit();
|
||||
|
||||
i = 0;
|
||||
while (i < 10) : (i += 1) {
|
||||
try testing.expect(copy.get(i).? == i * 10);
|
||||
}
|
||||
}
|
||||
|
||||
test "std.hash_map getOrPutAdapted" {
|
||||
const AdaptedContext = struct {
|
||||
fn eql(self: @This(), adapted_key: []const u8, test_key: u64) bool {
|
||||
|
@ -553,10 +553,18 @@ test "Reader.readUntilDelimiter returns StreamTooLong, then bytes read until the
|
||||
}
|
||||
|
||||
test "Reader.readUntilDelimiter returns EndOfStream" {
|
||||
var buf: [5]u8 = undefined;
|
||||
var fis = std.io.fixedBufferStream("");
|
||||
const reader = fis.reader();
|
||||
try std.testing.expectError(error.EndOfStream, reader.readUntilDelimiter(&buf, '\n'));
|
||||
{
|
||||
var buf: [5]u8 = undefined;
|
||||
var fis = std.io.fixedBufferStream("");
|
||||
const reader = fis.reader();
|
||||
try std.testing.expectError(error.EndOfStream, reader.readUntilDelimiter(&buf, '\n'));
|
||||
}
|
||||
{
|
||||
var buf: [5]u8 = undefined;
|
||||
var fis = std.io.fixedBufferStream("1234");
|
||||
const reader = fis.reader();
|
||||
try std.testing.expectError(error.EndOfStream, reader.readUntilDelimiter(&buf, '\n'));
|
||||
}
|
||||
}
|
||||
|
||||
test "Reader.readUntilDelimiter returns bytes read until delimiter, then EndOfStream" {
|
||||
@ -567,13 +575,6 @@ test "Reader.readUntilDelimiter returns bytes read until delimiter, then EndOfSt
|
||||
try std.testing.expectError(error.EndOfStream, reader.readUntilDelimiter(&buf, '\n'));
|
||||
}
|
||||
|
||||
test "Reader.readUntilDelimiter returns EndOfStream" {
|
||||
var buf: [5]u8 = undefined;
|
||||
var fis = std.io.fixedBufferStream("1234");
|
||||
const reader = fis.reader();
|
||||
try std.testing.expectError(error.EndOfStream, reader.readUntilDelimiter(&buf, '\n'));
|
||||
}
|
||||
|
||||
test "Reader.readUntilDelimiter returns StreamTooLong, then EndOfStream" {
|
||||
var buf: [5]u8 = undefined;
|
||||
var fis = std.io.fixedBufferStream("12345");
|
||||
|
@ -2012,15 +2012,10 @@ test "big.int shift-right negative" {
|
||||
defer arg2.deinit();
|
||||
try a.shiftRight(&arg2, 10);
|
||||
try testing.expect((try a.to(i32)) == -1); // -5 >> 10 == -1
|
||||
}
|
||||
|
||||
test "big.int shift-right negative" {
|
||||
var a = try Managed.init(testing.allocator);
|
||||
defer a.deinit();
|
||||
|
||||
var arg = try Managed.initSet(testing.allocator, -10);
|
||||
defer arg.deinit();
|
||||
try a.shiftRight(&arg, 1232);
|
||||
var arg3 = try Managed.initSet(testing.allocator, -10);
|
||||
defer arg3.deinit();
|
||||
try a.shiftRight(&arg3, 1232);
|
||||
try testing.expect((try a.to(i32)) == -1); // -10 >> 1232 == -1
|
||||
}
|
||||
|
||||
@ -2483,7 +2478,7 @@ test "big.int gcd non-one small" {
|
||||
try testing.expect((try r.to(u32)) == 1);
|
||||
}
|
||||
|
||||
test "big.int gcd non-one small" {
|
||||
test "big.int gcd non-one medium" {
|
||||
var a = try Managed.initSet(testing.allocator, 4864);
|
||||
defer a.deinit();
|
||||
var b = try Managed.initSet(testing.allocator, 3458);
|
||||
|
@ -782,36 +782,38 @@ test "big.rational mul" {
|
||||
}
|
||||
|
||||
test "big.rational div" {
|
||||
var a = try Rational.init(testing.allocator);
|
||||
defer a.deinit();
|
||||
var b = try Rational.init(testing.allocator);
|
||||
defer b.deinit();
|
||||
var r = try Rational.init(testing.allocator);
|
||||
defer r.deinit();
|
||||
{
|
||||
var a = try Rational.init(testing.allocator);
|
||||
defer a.deinit();
|
||||
var b = try Rational.init(testing.allocator);
|
||||
defer b.deinit();
|
||||
var r = try Rational.init(testing.allocator);
|
||||
defer r.deinit();
|
||||
|
||||
try a.setRatio(78923, 23341);
|
||||
try b.setRatio(123097, 12441414);
|
||||
try a.div(a, b);
|
||||
try a.setRatio(78923, 23341);
|
||||
try b.setRatio(123097, 12441414);
|
||||
try a.div(a, b);
|
||||
|
||||
try r.setRatio(75531824394, 221015929);
|
||||
try testing.expect((try a.order(r)) == .eq);
|
||||
}
|
||||
|
||||
test "big.rational div" {
|
||||
var a = try Rational.init(testing.allocator);
|
||||
defer a.deinit();
|
||||
var r = try Rational.init(testing.allocator);
|
||||
defer r.deinit();
|
||||
|
||||
try a.setRatio(78923, 23341);
|
||||
a.invert();
|
||||
|
||||
try r.setRatio(23341, 78923);
|
||||
try testing.expect((try a.order(r)) == .eq);
|
||||
|
||||
try a.setRatio(-78923, 23341);
|
||||
a.invert();
|
||||
|
||||
try r.setRatio(-23341, 78923);
|
||||
try testing.expect((try a.order(r)) == .eq);
|
||||
try r.setRatio(75531824394, 221015929);
|
||||
try testing.expect((try a.order(r)) == .eq);
|
||||
}
|
||||
|
||||
{
|
||||
var a = try Rational.init(testing.allocator);
|
||||
defer a.deinit();
|
||||
var r = try Rational.init(testing.allocator);
|
||||
defer r.deinit();
|
||||
|
||||
try a.setRatio(78923, 23341);
|
||||
a.invert();
|
||||
|
||||
try r.setRatio(23341, 78923);
|
||||
try testing.expect((try a.order(r)) == .eq);
|
||||
|
||||
try a.setRatio(-78923, 23341);
|
||||
a.invert();
|
||||
|
||||
try r.setRatio(-23341, 78923);
|
||||
try testing.expect((try a.order(r)) == .eq);
|
||||
}
|
||||
}
|
||||
|
@ -182,7 +182,7 @@ test "listen on a port, send bytes, receive bytes" {
|
||||
try testing.expectEqualSlices(u8, "Hello world!", buf[0..n]);
|
||||
}
|
||||
|
||||
test "listen on a port, send bytes, receive bytes" {
|
||||
test "listen on a port, send bytes, receive bytes, async-only" {
|
||||
if (!std.io.is_async) return error.SkipZigTest;
|
||||
|
||||
if (builtin.os.tag != .linux and !builtin.os.tag.isDarwin()) {
|
||||
|
@ -633,7 +633,7 @@ test "std.PriorityDequeue: peekMax" {
|
||||
try expect(queue.peekMax().? == 9);
|
||||
}
|
||||
|
||||
test "std.PriorityDequeue: sift up with odd indices" {
|
||||
test "std.PriorityDequeue: sift up with odd indices, removeMin" {
|
||||
var queue = PDQ.init(testing.allocator, {});
|
||||
defer queue.deinit();
|
||||
const items = [_]u32{ 15, 7, 21, 14, 13, 22, 12, 6, 7, 25, 5, 24, 11, 16, 15, 24, 2, 1 };
|
||||
@ -647,7 +647,7 @@ test "std.PriorityDequeue: sift up with odd indices" {
|
||||
}
|
||||
}
|
||||
|
||||
test "std.PriorityDequeue: sift up with odd indices" {
|
||||
test "std.PriorityDequeue: sift up with odd indices, removeMax" {
|
||||
var queue = PDQ.init(testing.allocator, {});
|
||||
defer queue.deinit();
|
||||
const items = [_]u32{ 15, 7, 21, 14, 13, 22, 12, 6, 7, 25, 5, 24, 11, 16, 15, 24, 2, 1 };
|
||||
|
@ -1240,7 +1240,7 @@ test "zig fmt: infix operator and then multiline string literal" {
|
||||
);
|
||||
}
|
||||
|
||||
test "zig fmt: infix operator and then multiline string literal" {
|
||||
test "zig fmt: infix operator and then multiline string literal over multiple lines" {
|
||||
try testCanonical(
|
||||
\\const x = "" ++
|
||||
\\ \\ hi0
|
||||
@ -4310,7 +4310,7 @@ test "zig fmt: comptime before comptime field" {
|
||||
});
|
||||
}
|
||||
|
||||
test "zig fmt: invalid else branch statement" {
|
||||
test "zig fmt: invalid doc comments on comptime and test blocks" {
|
||||
try testError(
|
||||
\\/// This is a doc comment for a comptime block.
|
||||
\\comptime {}
|
||||
@ -5191,7 +5191,7 @@ test "zig fmt: preserve container doc comment in container without trailing comm
|
||||
);
|
||||
}
|
||||
|
||||
test "zig fmt: make single-line if no trailing comma" {
|
||||
test "zig fmt: make single-line if no trailing comma, fmt: off" {
|
||||
try testCanonical(
|
||||
\\// Test trailing comma syntax
|
||||
\\// zig fmt: off
|
||||
@ -5270,7 +5270,7 @@ test "zig fmt: variable initialized with ==" {
|
||||
, &.{.wrong_equal_var_decl});
|
||||
}
|
||||
|
||||
test "zig fmt: missing const/var before local variable" {
|
||||
test "zig fmt: missing const/var before local variable in comptime block" {
|
||||
try testError(
|
||||
\\comptime {
|
||||
\\ z: u32;
|
||||
|
@ -5280,6 +5280,9 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err
|
||||
}
|
||||
},
|
||||
};
|
||||
var must_free_decl_name = true;
|
||||
defer if (must_free_decl_name) gpa.free(decl_name);
|
||||
|
||||
const is_exported = export_bit and decl_name_index != 0;
|
||||
if (kind == .@"usingnamespace") try namespace.usingnamespace_set.ensureUnusedCapacity(gpa, 1);
|
||||
|
||||
@ -5296,6 +5299,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err
|
||||
const new_decl = mod.declPtr(new_decl_index);
|
||||
new_decl.kind = kind;
|
||||
new_decl.name = decl_name;
|
||||
must_free_decl_name = false;
|
||||
if (kind == .@"usingnamespace") {
|
||||
namespace.usingnamespace_set.putAssumeCapacity(new_decl_index, is_pub);
|
||||
}
|
||||
@ -5339,9 +5343,29 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err
|
||||
new_decl.alive = true; // This Decl corresponds to an AST node and therefore always alive.
|
||||
return;
|
||||
}
|
||||
gpa.free(decl_name);
|
||||
const decl_index = gop.key_ptr.*;
|
||||
const decl = mod.declPtr(decl_index);
|
||||
if (kind == .@"test") {
|
||||
const src_loc = SrcLoc{
|
||||
.file_scope = decl.getFileScope(),
|
||||
.parent_decl_node = decl.src_node,
|
||||
.lazy = .{ .token_offset = 1 },
|
||||
};
|
||||
const msg = try ErrorMsg.create(
|
||||
gpa,
|
||||
src_loc,
|
||||
"found test declaration with duplicate name: {s}",
|
||||
.{decl_name},
|
||||
);
|
||||
errdefer msg.destroy(gpa);
|
||||
try mod.failed_decls.putNoClobber(gpa, decl_index, msg);
|
||||
const other_src_loc = SrcLoc{
|
||||
.file_scope = namespace.file_scope,
|
||||
.parent_decl_node = decl_node,
|
||||
.lazy = .{ .token_offset = 1 },
|
||||
};
|
||||
try mod.errNoteNonLazy(other_src_loc, msg, "other test here", .{});
|
||||
}
|
||||
log.debug("scan existing {*} ({s}) of {*}", .{ decl, decl.name, namespace });
|
||||
// Update the AST node of the decl; even if its contents are unchanged, it may
|
||||
// have been re-ordered.
|
||||
|
@ -150,6 +150,7 @@ test {
|
||||
_ = @import("behavior/comptime_memory.zig");
|
||||
_ = @import("behavior/const_slice_child.zig");
|
||||
_ = @import("behavior/decltest.zig");
|
||||
_ = @import("behavior/duplicated_test_names.zig");
|
||||
_ = @import("behavior/defer.zig");
|
||||
_ = @import("behavior/empty_tuple_fields.zig");
|
||||
_ = @import("behavior/empty_union.zig");
|
||||
|
@ -203,7 +203,7 @@ test "multiline string comments at multiple places" {
|
||||
try expect(mem.eql(u8, s1, s2));
|
||||
}
|
||||
|
||||
test "string concatenation" {
|
||||
test "string concatenation simple" {
|
||||
try expect(mem.eql(u8, "OK" ++ " IT " ++ "WORKED", "OK IT WORKED"));
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@ test "type pun signed and unsigned as offset many pointer" {
|
||||
}
|
||||
}
|
||||
|
||||
test "type pun signed and unsigned as array pointer" {
|
||||
test "type pun signed and unsigned as array pointer with pointer arithemtic" {
|
||||
if (true) {
|
||||
// TODO https://github.com/ziglang/zig/issues/9646
|
||||
return error.SkipZigTest;
|
||||
|
17
test/behavior/duplicated_test_names.zig
Normal file
17
test/behavior/duplicated_test_names.zig
Normal file
@ -0,0 +1,17 @@
|
||||
const Namespace = struct {
|
||||
test "thingy" {}
|
||||
};
|
||||
|
||||
fn thingy(a: usize, b: usize) usize {
|
||||
return a + b;
|
||||
}
|
||||
|
||||
comptime {
|
||||
_ = Namespace;
|
||||
}
|
||||
|
||||
test "thingy" {}
|
||||
|
||||
test thingy {
|
||||
if (thingy(1, 2) != 3) unreachable;
|
||||
}
|
@ -1129,20 +1129,6 @@ test "array of vectors is copied" {
|
||||
try std.testing.expectEqual(points2[6], Vec3{ -345, -311, 381 });
|
||||
}
|
||||
|
||||
test "byte vector initialized in inline function" {
|
||||
const S = struct {
|
||||
inline fn boolx4(e0: bool, e1: bool, e2: bool, e3: bool) @Vector(4, bool) {
|
||||
return .{ e0, e1, e2, e3 };
|
||||
}
|
||||
|
||||
fn all(vb: @Vector(4, bool)) bool {
|
||||
return @reduce(.And, vb);
|
||||
}
|
||||
};
|
||||
|
||||
try expect(S.all(S.boolx4(true, true, true, true)));
|
||||
}
|
||||
|
||||
test "byte vector initialized in inline function" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
|
@ -0,0 +1,10 @@
|
||||
test "thingy" {}
|
||||
test "thingy" {}
|
||||
|
||||
// error
|
||||
// backend=stage2
|
||||
// target=native
|
||||
// is_test=1
|
||||
//
|
||||
// :1:6: error: found test declaration with duplicate name: test.thingy
|
||||
// :2:6: note: other test here
|
Loading…
Reference in New Issue
Block a user