Commit a021c7b1b2
Changed files (4)
lib
lib/std/zig/fmt.zig
@@ -60,12 +60,13 @@ pub fn fmtEscapes(bytes: []const u8) std.fmt.Formatter(formatEscapes) {
}
test "escape invalid identifiers" {
- try std.fmt.testFmt("@\"while\"", "{}", .{fmtId("while")});
- try std.fmt.testFmt("hello", "{}", .{fmtId("hello")});
- try std.fmt.testFmt("@\"11\\\"23\"", "{}", .{fmtId("11\"23")});
- try std.fmt.testFmt("@\"11\\x0f23\"", "{}", .{fmtId("11\x0F23")});
- try std.fmt.testFmt("\\x0f", "{}", .{fmtEscapes("\x0f")});
- try std.fmt.testFmt(
+ const expectFmt = std.testing.expectFmt;
+ try expectFmt("@\"while\"", "{}", .{fmtId("while")});
+ try expectFmt("hello", "{}", .{fmtId("hello")});
+ try expectFmt("@\"11\\\"23\"", "{}", .{fmtId("11\"23")});
+ try expectFmt("@\"11\\x0f23\"", "{}", .{fmtId("11\x0F23")});
+ try expectFmt("\\x0f", "{}", .{fmtEscapes("\x0f")});
+ try expectFmt(
\\" \\ hi \x07 \x11 \" derp \'"
, "\"{}\"", .{fmtEscapes(" \\ hi \x07 \x11 \" derp '")});
}
lib/std/fmt.zig
@@ -12,6 +12,7 @@ const meta = std.meta;
const builtin = @import("builtin");
const errol = @import("fmt/errol.zig");
const lossyCast = std.math.lossyCast;
+const expectFmt = std.testing.expectFmt;
pub const default_max_depth = 3;
@@ -1531,91 +1532,91 @@ test "parse unsigned comptime" {
}
test "escaped braces" {
- try testFmt("escaped: {{foo}}\n", "escaped: {{{{foo}}}}\n", .{});
- try testFmt("escaped: {foo}\n", "escaped: {{foo}}\n", .{});
+ try expectFmt("escaped: {{foo}}\n", "escaped: {{{{foo}}}}\n", .{});
+ try expectFmt("escaped: {foo}\n", "escaped: {{foo}}\n", .{});
}
test "optional" {
{
const value: ?i32 = 1234;
- try testFmt("optional: 1234\n", "optional: {}\n", .{value});
+ try expectFmt("optional: 1234\n", "optional: {}\n", .{value});
}
{
const value: ?i32 = null;
- try testFmt("optional: null\n", "optional: {}\n", .{value});
+ try expectFmt("optional: null\n", "optional: {}\n", .{value});
}
{
const value = @intToPtr(?*i32, 0xf000d000);
- try testFmt("optional: *i32@f000d000\n", "optional: {*}\n", .{value});
+ try expectFmt("optional: *i32@f000d000\n", "optional: {*}\n", .{value});
}
}
test "error" {
{
const value: anyerror!i32 = 1234;
- try testFmt("error union: 1234\n", "error union: {}\n", .{value});
+ try expectFmt("error union: 1234\n", "error union: {}\n", .{value});
}
{
const value: anyerror!i32 = error.InvalidChar;
- try testFmt("error union: error.InvalidChar\n", "error union: {}\n", .{value});
+ try expectFmt("error union: error.InvalidChar\n", "error union: {}\n", .{value});
}
}
test "int.small" {
{
const value: u3 = 0b101;
- try testFmt("u3: 5\n", "u3: {}\n", .{value});
+ try expectFmt("u3: 5\n", "u3: {}\n", .{value});
}
}
test "int.specifier" {
{
const value: u8 = 'a';
- try testFmt("u8: a\n", "u8: {c}\n", .{value});
+ try expectFmt("u8: a\n", "u8: {c}\n", .{value});
}
{
const value: u8 = 0b1100;
- try testFmt("u8: 0b1100\n", "u8: 0b{b}\n", .{value});
+ try expectFmt("u8: 0b1100\n", "u8: 0b{b}\n", .{value});
}
{
const value: u16 = 0o1234;
- try testFmt("u16: 0o1234\n", "u16: 0o{o}\n", .{value});
+ try expectFmt("u16: 0o1234\n", "u16: 0o{o}\n", .{value});
}
{
const value: u8 = 'a';
- try testFmt("UTF-8: a\n", "UTF-8: {u}\n", .{value});
+ try expectFmt("UTF-8: a\n", "UTF-8: {u}\n", .{value});
}
{
const value: u21 = 0x1F310;
- try testFmt("UTF-8: 🌐\n", "UTF-8: {u}\n", .{value});
+ try expectFmt("UTF-8: 🌐\n", "UTF-8: {u}\n", .{value});
}
{
const value: u21 = 0xD800;
- try testFmt("UTF-8: �\n", "UTF-8: {u}\n", .{value});
+ try expectFmt("UTF-8: �\n", "UTF-8: {u}\n", .{value});
}
{
const value: u21 = 0x110001;
- try testFmt("UTF-8: �\n", "UTF-8: {u}\n", .{value});
+ try expectFmt("UTF-8: �\n", "UTF-8: {u}\n", .{value});
}
}
test "int.padded" {
- try testFmt("u8: ' 1'", "u8: '{:4}'", .{@as(u8, 1)});
- try testFmt("u8: '1000'", "u8: '{:0<4}'", .{@as(u8, 1)});
- try testFmt("u8: '0001'", "u8: '{:0>4}'", .{@as(u8, 1)});
- try testFmt("u8: '0100'", "u8: '{:0^4}'", .{@as(u8, 1)});
- try testFmt("i8: '-1 '", "i8: '{:<4}'", .{@as(i8, -1)});
- try testFmt("i8: ' -1'", "i8: '{:>4}'", .{@as(i8, -1)});
- try testFmt("i8: ' -1 '", "i8: '{:^4}'", .{@as(i8, -1)});
- try testFmt("i16: '-1234'", "i16: '{:4}'", .{@as(i16, -1234)});
- try testFmt("i16: '+1234'", "i16: '{:4}'", .{@as(i16, 1234)});
- try testFmt("i16: '-12345'", "i16: '{:4}'", .{@as(i16, -12345)});
- try testFmt("i16: '+12345'", "i16: '{:4}'", .{@as(i16, 12345)});
- try testFmt("u16: '12345'", "u16: '{:4}'", .{@as(u16, 12345)});
-
- try testFmt("UTF-8: 'ü '", "UTF-8: '{u:<4}'", .{'ü'});
- try testFmt("UTF-8: ' ü'", "UTF-8: '{u:>4}'", .{'ü'});
- try testFmt("UTF-8: ' ü '", "UTF-8: '{u:^4}'", .{'ü'});
+ try expectFmt("u8: ' 1'", "u8: '{:4}'", .{@as(u8, 1)});
+ try expectFmt("u8: '1000'", "u8: '{:0<4}'", .{@as(u8, 1)});
+ try expectFmt("u8: '0001'", "u8: '{:0>4}'", .{@as(u8, 1)});
+ try expectFmt("u8: '0100'", "u8: '{:0^4}'", .{@as(u8, 1)});
+ try expectFmt("i8: '-1 '", "i8: '{:<4}'", .{@as(i8, -1)});
+ try expectFmt("i8: ' -1'", "i8: '{:>4}'", .{@as(i8, -1)});
+ try expectFmt("i8: ' -1 '", "i8: '{:^4}'", .{@as(i8, -1)});
+ try expectFmt("i16: '-1234'", "i16: '{:4}'", .{@as(i16, -1234)});
+ try expectFmt("i16: '+1234'", "i16: '{:4}'", .{@as(i16, 1234)});
+ try expectFmt("i16: '-12345'", "i16: '{:4}'", .{@as(i16, -12345)});
+ try expectFmt("i16: '+12345'", "i16: '{:4}'", .{@as(i16, 12345)});
+ try expectFmt("u16: '12345'", "u16: '{:4}'", .{@as(u16, 12345)});
+
+ try expectFmt("UTF-8: 'ü '", "UTF-8: '{u:<4}'", .{'ü'});
+ try expectFmt("UTF-8: ' ü'", "UTF-8: '{u:>4}'", .{'ü'});
+ try expectFmt("UTF-8: ' ü '", "UTF-8: '{u:^4}'", .{'ü'});
}
test "buffer" {
@@ -1638,12 +1639,12 @@ test "buffer" {
test "array" {
{
const value: [3]u8 = "abc".*;
- try testFmt("array: abc\n", "array: {s}\n", .{value});
- try testFmt("array: abc\n", "array: {s}\n", .{&value});
- try testFmt("array: { 97, 98, 99 }\n", "array: {d}\n", .{value});
+ try expectFmt("array: abc\n", "array: {s}\n", .{value});
+ try expectFmt("array: abc\n", "array: {s}\n", .{&value});
+ try expectFmt("array: { 97, 98, 99 }\n", "array: {d}\n", .{value});
var buf: [100]u8 = undefined;
- try testFmt(
+ try expectFmt(
try bufPrint(buf[0..], "array: [3]u8@{x}\n", .{@ptrToInt(&value)}),
"array: {*}\n",
.{&value},
@@ -1654,60 +1655,60 @@ test "array" {
test "slice" {
{
const value: []const u8 = "abc";
- try testFmt("slice: abc\n", "slice: {s}\n", .{value});
+ try expectFmt("slice: abc\n", "slice: {s}\n", .{value});
}
{
var runtime_zero: usize = 0;
const value = @intToPtr([*]align(1) const []const u8, 0xdeadbeef)[runtime_zero..runtime_zero];
- try testFmt("slice: []const u8@deadbeef\n", "slice: {*}\n", .{value});
+ try expectFmt("slice: []const u8@deadbeef\n", "slice: {*}\n", .{value});
}
{
const null_term_slice: [:0]const u8 = "\x00hello\x00";
- try testFmt("buf: \x00hello\x00\n", "buf: {s}\n", .{null_term_slice});
+ try expectFmt("buf: \x00hello\x00\n", "buf: {s}\n", .{null_term_slice});
}
- try testFmt("buf: Test\n", "buf: {s:5}\n", .{"Test"});
- try testFmt("buf: Test\n Other text", "buf: {s}\n Other text", .{"Test"});
+ try expectFmt("buf: Test\n", "buf: {s:5}\n", .{"Test"});
+ try expectFmt("buf: Test\n Other text", "buf: {s}\n Other text", .{"Test"});
{
var int_slice = [_]u32{ 1, 4096, 391891, 1111111111 };
var runtime_zero: usize = 0;
- try testFmt("int: { 1, 4096, 391891, 1111111111 }", "int: {}", .{int_slice[runtime_zero..]});
- try testFmt("int: { 1, 4096, 391891, 1111111111 }", "int: {d}", .{int_slice[runtime_zero..]});
- try testFmt("int: { 1, 1000, 5fad3, 423a35c7 }", "int: {x}", .{int_slice[runtime_zero..]});
- try testFmt("int: { 00001, 01000, 5fad3, 423a35c7 }", "int: {x:0>5}", .{int_slice[runtime_zero..]});
+ try expectFmt("int: { 1, 4096, 391891, 1111111111 }", "int: {}", .{int_slice[runtime_zero..]});
+ try expectFmt("int: { 1, 4096, 391891, 1111111111 }", "int: {d}", .{int_slice[runtime_zero..]});
+ try expectFmt("int: { 1, 1000, 5fad3, 423a35c7 }", "int: {x}", .{int_slice[runtime_zero..]});
+ try expectFmt("int: { 00001, 01000, 5fad3, 423a35c7 }", "int: {x:0>5}", .{int_slice[runtime_zero..]});
}
}
test "escape non-printable" {
- try testFmt("abc", "{e}", .{"abc"});
- try testFmt("ab\\xffc", "{e}", .{"ab\xffc"});
- try testFmt("ab\\xFFc", "{E}", .{"ab\xffc"});
+ try expectFmt("abc", "{e}", .{"abc"});
+ try expectFmt("ab\\xffc", "{e}", .{"ab\xffc"});
+ try expectFmt("ab\\xFFc", "{E}", .{"ab\xffc"});
}
test "pointer" {
{
const value = @intToPtr(*align(1) i32, 0xdeadbeef);
- try testFmt("pointer: i32@deadbeef\n", "pointer: {}\n", .{value});
- try testFmt("pointer: i32@deadbeef\n", "pointer: {*}\n", .{value});
+ try expectFmt("pointer: i32@deadbeef\n", "pointer: {}\n", .{value});
+ try expectFmt("pointer: i32@deadbeef\n", "pointer: {*}\n", .{value});
}
{
const value = @intToPtr(fn () void, 0xdeadbeef);
- try testFmt("pointer: fn() void@deadbeef\n", "pointer: {}\n", .{value});
+ try expectFmt("pointer: fn() void@deadbeef\n", "pointer: {}\n", .{value});
}
{
const value = @intToPtr(fn () void, 0xdeadbeef);
- try testFmt("pointer: fn() void@deadbeef\n", "pointer: {}\n", .{value});
+ try expectFmt("pointer: fn() void@deadbeef\n", "pointer: {}\n", .{value});
}
}
test "cstr" {
- try testFmt(
+ try expectFmt(
"cstr: Test C\n",
"cstr: {s}\n",
.{@ptrCast([*c]const u8, "Test C")},
);
- try testFmt(
+ try expectFmt(
"cstr: Test C\n",
"cstr: {s:10}\n",
.{@ptrCast([*c]const u8, "Test C")},
@@ -1715,8 +1716,8 @@ test "cstr" {
}
test "filesize" {
- try testFmt("file size: 63MiB\n", "file size: {Bi}\n", .{@as(usize, 63 * 1024 * 1024)});
- try testFmt("file size: 66.06MB\n", "file size: {B:.2}\n", .{@as(usize, 63 * 1024 * 1024)});
+ try expectFmt("file size: 63MiB\n", "file size: {Bi}\n", .{@as(usize, 63 * 1024 * 1024)});
+ try expectFmt("file size: 66.06MB\n", "file size: {B:.2}\n", .{@as(usize, 63 * 1024 * 1024)});
}
test "struct" {
@@ -1725,8 +1726,8 @@ test "struct" {
field: u8,
};
const value = Struct{ .field = 42 };
- try testFmt("struct: Struct{ .field = 42 }\n", "struct: {}\n", .{value});
- try testFmt("struct: Struct{ .field = 42 }\n", "struct: {}\n", .{&value});
+ try expectFmt("struct: Struct{ .field = 42 }\n", "struct: {}\n", .{value});
+ try expectFmt("struct: Struct{ .field = 42 }\n", "struct: {}\n", .{&value});
}
{
const Struct = struct {
@@ -1734,7 +1735,7 @@ test "struct" {
b: u1,
};
const value = Struct{ .a = 0, .b = 1 };
- try testFmt("struct: Struct{ .a = 0, .b = 1 }\n", "struct: {}\n", .{value});
+ try expectFmt("struct: Struct{ .a = 0, .b = 1 }\n", "struct: {}\n", .{value});
}
}
@@ -1744,13 +1745,13 @@ test "enum" {
Two,
};
const value = Enum.Two;
- try testFmt("enum: Enum.Two\n", "enum: {}\n", .{value});
- try testFmt("enum: Enum.Two\n", "enum: {}\n", .{&value});
- try testFmt("enum: Enum.One\n", "enum: {x}\n", .{Enum.One});
- try testFmt("enum: Enum.Two\n", "enum: {X}\n", .{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: {x}\n", .{Enum.One});
+ try expectFmt("enum: Enum.Two\n", "enum: {X}\n", .{Enum.Two});
// test very large enum to verify ct branch quota is large enough
- try testFmt("enum: Win32Error.INVALID_FUNCTION\n", "enum: {}\n", .{std.os.windows.Win32Error.INVALID_FUNCTION});
+ try expectFmt("enum: Win32Error.INVALID_FUNCTION\n", "enum: {}\n", .{std.os.windows.Win32Error.INVALID_FUNCTION});
}
test "non-exhaustive enum" {
@@ -1759,78 +1760,78 @@ test "non-exhaustive enum" {
Two = 0xbeef,
_,
};
- try testFmt("enum: Enum.One\n", "enum: {}\n", .{Enum.One});
- try testFmt("enum: Enum.Two\n", "enum: {}\n", .{Enum.Two});
- try testFmt("enum: Enum(4660)\n", "enum: {}\n", .{@intToEnum(Enum, 0x1234)});
- try testFmt("enum: Enum.One\n", "enum: {x}\n", .{Enum.One});
- try testFmt("enum: Enum.Two\n", "enum: {x}\n", .{Enum.Two});
- try testFmt("enum: Enum.Two\n", "enum: {X}\n", .{Enum.Two});
- try testFmt("enum: Enum(1234)\n", "enum: {x}\n", .{@intToEnum(Enum, 0x1234)});
+ try expectFmt("enum: Enum.One\n", "enum: {}\n", .{Enum.One});
+ try expectFmt("enum: Enum.Two\n", "enum: {}\n", .{Enum.Two});
+ try expectFmt("enum: Enum(4660)\n", "enum: {}\n", .{@intToEnum(Enum, 0x1234)});
+ try expectFmt("enum: Enum.One\n", "enum: {x}\n", .{Enum.One});
+ try expectFmt("enum: Enum.Two\n", "enum: {x}\n", .{Enum.Two});
+ try expectFmt("enum: Enum.Two\n", "enum: {X}\n", .{Enum.Two});
+ try expectFmt("enum: Enum(1234)\n", "enum: {x}\n", .{@intToEnum(Enum, 0x1234)});
}
test "float.scientific" {
- try testFmt("f32: 1.34000003e+00", "f32: {e}", .{@as(f32, 1.34)});
- try testFmt("f32: 1.23400001e+01", "f32: {e}", .{@as(f32, 12.34)});
- try testFmt("f64: -1.234e+11", "f64: {e}", .{@as(f64, -12.34e10)});
- try testFmt("f64: 9.99996e-40", "f64: {e}", .{@as(f64, 9.999960e-40)});
+ try expectFmt("f32: 1.34000003e+00", "f32: {e}", .{@as(f32, 1.34)});
+ try expectFmt("f32: 1.23400001e+01", "f32: {e}", .{@as(f32, 12.34)});
+ try expectFmt("f64: -1.234e+11", "f64: {e}", .{@as(f64, -12.34e10)});
+ try expectFmt("f64: 9.99996e-40", "f64: {e}", .{@as(f64, 9.999960e-40)});
}
test "float.scientific.precision" {
- try testFmt("f64: 1.40971e-42", "f64: {e:.5}", .{@as(f64, 1.409706e-42)});
- try testFmt("f64: 1.00000e-09", "f64: {e:.5}", .{@as(f64, @bitCast(f32, @as(u32, 814313563)))});
- try testFmt("f64: 7.81250e-03", "f64: {e:.5}", .{@as(f64, @bitCast(f32, @as(u32, 1006632960)))});
+ try expectFmt("f64: 1.40971e-42", "f64: {e:.5}", .{@as(f64, 1.409706e-42)});
+ try expectFmt("f64: 1.00000e-09", "f64: {e:.5}", .{@as(f64, @bitCast(f32, @as(u32, 814313563)))});
+ try expectFmt("f64: 7.81250e-03", "f64: {e:.5}", .{@as(f64, @bitCast(f32, @as(u32, 1006632960)))});
// libc rounds 1.000005e+05 to 1.00000e+05 but zig does 1.00001e+05.
// In fact, libc doesn't round a lot of 5 cases up when one past the precision point.
- try testFmt("f64: 1.00001e+05", "f64: {e:.5}", .{@as(f64, @bitCast(f32, @as(u32, 1203982400)))});
+ try expectFmt("f64: 1.00001e+05", "f64: {e:.5}", .{@as(f64, @bitCast(f32, @as(u32, 1203982400)))});
}
test "float.special" {
- try testFmt("f64: nan", "f64: {}", .{math.nan_f64});
+ try expectFmt("f64: nan", "f64: {}", .{math.nan_f64});
// negative nan is not defined by IEE 754,
// and ARM thus normalizes it to positive nan
if (builtin.arch != builtin.Arch.arm) {
- try testFmt("f64: -nan", "f64: {}", .{-math.nan_f64});
+ try expectFmt("f64: -nan", "f64: {}", .{-math.nan_f64});
}
- try testFmt("f64: inf", "f64: {}", .{math.inf_f64});
- try testFmt("f64: -inf", "f64: {}", .{-math.inf_f64});
+ try expectFmt("f64: inf", "f64: {}", .{math.inf_f64});
+ try expectFmt("f64: -inf", "f64: {}", .{-math.inf_f64});
}
test "float.decimal" {
- try testFmt("f64: 152314000000000000000000000000", "f64: {d}", .{@as(f64, 1.52314e+29)});
- try testFmt("f32: 0", "f32: {d}", .{@as(f32, 0.0)});
- try testFmt("f32: 1.1", "f32: {d:.1}", .{@as(f32, 1.1234)});
- try testFmt("f32: 1234.57", "f32: {d:.2}", .{@as(f32, 1234.567)});
+ try expectFmt("f64: 152314000000000000000000000000", "f64: {d}", .{@as(f64, 1.52314e+29)});
+ try expectFmt("f32: 0", "f32: {d}", .{@as(f32, 0.0)});
+ try expectFmt("f32: 1.1", "f32: {d:.1}", .{@as(f32, 1.1234)});
+ try expectFmt("f32: 1234.57", "f32: {d:.2}", .{@as(f32, 1234.567)});
// -11.1234 is converted to f64 -11.12339... internally (errol3() function takes f64).
// -11.12339... is rounded back up to -11.1234
- try testFmt("f32: -11.1234", "f32: {d:.4}", .{@as(f32, -11.1234)});
- try testFmt("f32: 91.12345", "f32: {d:.5}", .{@as(f32, 91.12345)});
- try testFmt("f64: 91.1234567890", "f64: {d:.10}", .{@as(f64, 91.12345678901235)});
- try testFmt("f64: 0.00000", "f64: {d:.5}", .{@as(f64, 0.0)});
- try testFmt("f64: 6", "f64: {d:.0}", .{@as(f64, 5.700)});
- try testFmt("f64: 10.0", "f64: {d:.1}", .{@as(f64, 9.999)});
- try testFmt("f64: 1.000", "f64: {d:.3}", .{@as(f64, 1.0)});
- try testFmt("f64: 0.00030000", "f64: {d:.8}", .{@as(f64, 0.0003)});
- try testFmt("f64: 0.00000", "f64: {d:.5}", .{@as(f64, 1.40130e-45)});
- try testFmt("f64: 0.00000", "f64: {d:.5}", .{@as(f64, 9.999960e-40)});
+ try expectFmt("f32: -11.1234", "f32: {d:.4}", .{@as(f32, -11.1234)});
+ try expectFmt("f32: 91.12345", "f32: {d:.5}", .{@as(f32, 91.12345)});
+ try expectFmt("f64: 91.1234567890", "f64: {d:.10}", .{@as(f64, 91.12345678901235)});
+ try expectFmt("f64: 0.00000", "f64: {d:.5}", .{@as(f64, 0.0)});
+ try expectFmt("f64: 6", "f64: {d:.0}", .{@as(f64, 5.700)});
+ try expectFmt("f64: 10.0", "f64: {d:.1}", .{@as(f64, 9.999)});
+ try expectFmt("f64: 1.000", "f64: {d:.3}", .{@as(f64, 1.0)});
+ try expectFmt("f64: 0.00030000", "f64: {d:.8}", .{@as(f64, 0.0003)});
+ try expectFmt("f64: 0.00000", "f64: {d:.5}", .{@as(f64, 1.40130e-45)});
+ try expectFmt("f64: 0.00000", "f64: {d:.5}", .{@as(f64, 9.999960e-40)});
}
test "float.libc.sanity" {
- try testFmt("f64: 0.00001", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 916964781)))});
- try testFmt("f64: 0.00001", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 925353389)))});
- try testFmt("f64: 0.10000", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 1036831278)))});
- try testFmt("f64: 1.00000", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 1065353133)))});
- try testFmt("f64: 10.00000", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 1092616192)))});
+ try expectFmt("f64: 0.00001", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 916964781)))});
+ try expectFmt("f64: 0.00001", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 925353389)))});
+ try expectFmt("f64: 0.10000", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 1036831278)))});
+ try expectFmt("f64: 1.00000", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 1065353133)))});
+ try expectFmt("f64: 10.00000", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 1092616192)))});
// libc differences
//
// This is 0.015625 exactly according to gdb. We thus round down,
// however glibc rounds up for some reason. This occurs for all
// floats of the form x.yyyy25 on a precision point.
- try testFmt("f64: 0.01563", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 1015021568)))});
+ try expectFmt("f64: 0.01563", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 1015021568)))});
// errol3 rounds to ... 630 but libc rounds to ...632. Grisu3
// also rounds to 630 so I'm inclined to believe libc is not
// optimal here.
- try testFmt("f64: 18014400656965630.00000", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 1518338049)))});
+ try expectFmt("f64: 18014400656965630.00000", "f64: {d:.5}", .{@as(f64, @bitCast(f32, @as(u32, 1518338049)))});
}
test "custom" {
@@ -1860,12 +1861,12 @@ test "custom" {
.x = 10.2,
.y = 2.22,
};
- try testFmt("point: (10.200,2.220)\n", "point: {}\n", .{&value});
- try testFmt("dim: 10.200x2.220\n", "dim: {d}\n", .{&value});
+ try expectFmt("point: (10.200,2.220)\n", "point: {}\n", .{&value});
+ try expectFmt("dim: 10.200x2.220\n", "dim: {d}\n", .{&value});
// same thing but not passing a pointer
- try testFmt("point: (10.200,2.220)\n", "point: {}\n", .{value});
- try testFmt("dim: 10.200x2.220\n", "dim: {d}\n", .{value});
+ try expectFmt("point: (10.200,2.220)\n", "point: {}\n", .{value});
+ try expectFmt("dim: 10.200x2.220\n", "dim: {d}\n", .{value});
}
test "struct" {
@@ -1879,7 +1880,7 @@ test "struct" {
.b = error.Unused,
};
- try testFmt("S{ .a = 456, .b = error.Unused }", "{}", .{inst});
+ try expectFmt("S{ .a = 456, .b = error.Unused }", "{}", .{inst});
}
test "union" {
@@ -1902,7 +1903,7 @@ test "union" {
const uu_inst = UU{ .int = 456 };
const eu_inst = EU{ .float = 321.123 };
- try testFmt("TU{ .int = 123 }", "{}", .{tu_inst});
+ try expectFmt("TU{ .int = 123 }", "{}", .{tu_inst});
var buf: [100]u8 = undefined;
const uu_result = try bufPrint(buf[0..], "{}", .{uu_inst});
@@ -1921,7 +1922,7 @@ test "enum" {
const inst = E.Two;
- try testFmt("E.Two", "{}", .{inst});
+ try expectFmt("E.Two", "{}", .{inst});
}
test "struct.self-referential" {
@@ -1935,7 +1936,7 @@ test "struct.self-referential" {
};
inst.a = &inst;
- try testFmt("S{ .a = S{ .a = S{ .a = S{ ... } } } }", "{}", .{inst});
+ try expectFmt("S{ .a = S{ .a = S{ .a = S{ ... } } } }", "{}", .{inst});
}
test "struct.zero-size" {
@@ -1950,31 +1951,18 @@ test "struct.zero-size" {
const a = A{};
const b = B{ .a = a, .c = 0 };
- try testFmt("B{ .a = A{ }, .c = 0 }", "{}", .{b});
+ try expectFmt("B{ .a = A{ }, .c = 0 }", "{}", .{b});
}
test "bytes.hex" {
const some_bytes = "\xCA\xFE\xBA\xBE";
- try testFmt("lowercase: cafebabe\n", "lowercase: {x}\n", .{some_bytes});
- try testFmt("uppercase: CAFEBABE\n", "uppercase: {X}\n", .{some_bytes});
+ try expectFmt("lowercase: cafebabe\n", "lowercase: {x}\n", .{some_bytes});
+ try expectFmt("uppercase: CAFEBABE\n", "uppercase: {X}\n", .{some_bytes});
//Test Slices
- try testFmt("uppercase: CAFE\n", "uppercase: {X}\n", .{some_bytes[0..2]});
- try testFmt("lowercase: babe\n", "lowercase: {x}\n", .{some_bytes[2..]});
+ try expectFmt("uppercase: CAFE\n", "uppercase: {X}\n", .{some_bytes[0..2]});
+ try expectFmt("lowercase: babe\n", "lowercase: {x}\n", .{some_bytes[2..]});
const bytes_with_zeros = "\x00\x0E\xBA\xBE";
- try testFmt("lowercase: 000ebabe\n", "lowercase: {x}\n", .{bytes_with_zeros});
-}
-
-pub fn testFmt(expected: []const u8, comptime template: []const u8, args: anytype) !void {
- var buf: [100]u8 = undefined;
- const result = try bufPrint(buf[0..], template, args);
- if (mem.eql(u8, result, expected)) return;
-
- std.debug.warn("\n====== expected this output: =========\n", .{});
- std.debug.warn("{s}", .{expected});
- std.debug.warn("\n======== instead found this: =========\n", .{});
- std.debug.warn("{s}", .{result});
- std.debug.warn("\n======================================\n", .{});
- return error.TestFailed;
+ try expectFmt("lowercase: 000ebabe\n", "lowercase: {x}\n", .{bytes_with_zeros});
}
pub const trim = @compileError("deprecated; use std.mem.trim with std.ascii.spaces instead");
@@ -1996,7 +1984,7 @@ test "hexToBytes" {
const test_hex_str = "909A312BB12ED1F819B3521AC4C1E896F2160507FFC1C8381E3B07BB16BD1706";
var pb: [32]u8 = undefined;
try hexToBytes(pb[0..], test_hex_str);
- try testFmt(test_hex_str, "{X}", .{pb});
+ try expectFmt(test_hex_str, "{X}", .{pb});
}
test "formatIntValue with comptime_int" {
@@ -2016,8 +2004,8 @@ test "formatFloatValue with comptime_float" {
try formatFloatValue(value, "", FormatOptions{}, fbs.writer());
std.testing.expect(mem.eql(u8, fbs.getWritten(), "1.0e+00"));
- try testFmt("1.0e+00", "{}", .{value});
- try testFmt("1.0e+00", "{}", .{1.0});
+ try expectFmt("1.0e+00", "{}", .{value});
+ try expectFmt("1.0e+00", "{}", .{1.0});
}
test "formatType max_depth" {
@@ -2086,19 +2074,19 @@ test "formatType max_depth" {
}
test "positional" {
- try testFmt("2 1 0", "{2} {1} {0}", .{ @as(usize, 0), @as(usize, 1), @as(usize, 2) });
- try testFmt("2 1 0", "{2} {1} {}", .{ @as(usize, 0), @as(usize, 1), @as(usize, 2) });
- try testFmt("0 0", "{0} {0}", .{@as(usize, 0)});
- try testFmt("0 1", "{} {1}", .{ @as(usize, 0), @as(usize, 1) });
- try testFmt("1 0 0 1", "{1} {} {0} {}", .{ @as(usize, 0), @as(usize, 1) });
+ try expectFmt("2 1 0", "{2} {1} {0}", .{ @as(usize, 0), @as(usize, 1), @as(usize, 2) });
+ try expectFmt("2 1 0", "{2} {1} {}", .{ @as(usize, 0), @as(usize, 1), @as(usize, 2) });
+ try expectFmt("0 0", "{0} {0}", .{@as(usize, 0)});
+ try expectFmt("0 1", "{} {1}", .{ @as(usize, 0), @as(usize, 1) });
+ try expectFmt("1 0 0 1", "{1} {} {0} {}", .{ @as(usize, 0), @as(usize, 1) });
}
test "positional with specifier" {
- try testFmt("10.0", "{0d:.1}", .{@as(f64, 9.999)});
+ try expectFmt("10.0", "{0d:.1}", .{@as(f64, 9.999)});
}
test "positional/alignment/width/precision" {
- try testFmt("10.0", "{0d: >3.1}", .{@as(f64, 9.999)});
+ try expectFmt("10.0", "{0d: >3.1}", .{@as(f64, 9.999)});
}
test "vector" {
@@ -2119,76 +2107,76 @@ test "vector" {
const vi64: std.meta.Vector(4, i64) = [_]i64{ -2, -1, 0, 1 };
const vu64: std.meta.Vector(4, u64) = [_]u64{ 1000, 2000, 3000, 4000 };
- try testFmt("{ true, false, true, false }", "{}", .{vbool});
- try testFmt("{ -2, -1, 0, 1 }", "{}", .{vi64});
- try testFmt("{ -2, -1, +0, +1 }", "{d:5}", .{vi64});
- try testFmt("{ 1000, 2000, 3000, 4000 }", "{}", .{vu64});
- try testFmt("{ 3e8, 7d0, bb8, fa0 }", "{x}", .{vu64});
- try testFmt("{ 1kB, 2kB, 3kB, 4kB }", "{B}", .{vu64});
- try testFmt("{ 1000B, 1.953125KiB, 2.9296875KiB, 3.90625KiB }", "{Bi}", .{vu64});
+ try expectFmt("{ true, false, true, false }", "{}", .{vbool});
+ try expectFmt("{ -2, -1, 0, 1 }", "{}", .{vi64});
+ try expectFmt("{ -2, -1, +0, +1 }", "{d:5}", .{vi64});
+ try expectFmt("{ 1000, 2000, 3000, 4000 }", "{}", .{vu64});
+ try expectFmt("{ 3e8, 7d0, bb8, fa0 }", "{x}", .{vu64});
+ try expectFmt("{ 1kB, 2kB, 3kB, 4kB }", "{B}", .{vu64});
+ try expectFmt("{ 1000B, 1.953125KiB, 2.9296875KiB, 3.90625KiB }", "{Bi}", .{vu64});
}
test "enum-literal" {
- try testFmt(".hello_world", "{s}", .{.hello_world});
+ try expectFmt(".hello_world", "{s}", .{.hello_world});
}
test "padding" {
- try testFmt("Simple", "{s}", .{"Simple"});
- try testFmt(" true", "{:10}", .{true});
- try testFmt(" true", "{:>10}", .{true});
- try testFmt("======true", "{:=>10}", .{true});
- try testFmt("true======", "{:=<10}", .{true});
- try testFmt(" true ", "{:^10}", .{true});
- try testFmt("===true===", "{:=^10}", .{true});
- try testFmt(" Minimum width", "{s:18} width", .{"Minimum"});
- try testFmt("==================Filled", "{s:=>24}", .{"Filled"});
- try testFmt(" Centered ", "{s:^24}", .{"Centered"});
- try testFmt("-", "{s:-^1}", .{""});
- try testFmt("==crêpe===", "{s:=^10}", .{"crêpe"});
- try testFmt("=====crêpe", "{s:=>10}", .{"crêpe"});
- try testFmt("crêpe=====", "{s:=<10}", .{"crêpe"});
+ try expectFmt("Simple", "{s}", .{"Simple"});
+ try expectFmt(" true", "{:10}", .{true});
+ try expectFmt(" true", "{:>10}", .{true});
+ try expectFmt("======true", "{:=>10}", .{true});
+ try expectFmt("true======", "{:=<10}", .{true});
+ try expectFmt(" true ", "{:^10}", .{true});
+ try expectFmt("===true===", "{:=^10}", .{true});
+ try expectFmt(" Minimum width", "{s:18} width", .{"Minimum"});
+ try expectFmt("==================Filled", "{s:=>24}", .{"Filled"});
+ try expectFmt(" Centered ", "{s:^24}", .{"Centered"});
+ try expectFmt("-", "{s:-^1}", .{""});
+ try expectFmt("==crêpe===", "{s:=^10}", .{"crêpe"});
+ try expectFmt("=====crêpe", "{s:=>10}", .{"crêpe"});
+ try expectFmt("crêpe=====", "{s:=<10}", .{"crêpe"});
}
test "decimal float padding" {
var number: f32 = 3.1415;
- try testFmt("left-pad: **3.141\n", "left-pad: {d:*>7.3}\n", .{number});
- try testFmt("center-pad: *3.141*\n", "center-pad: {d:*^7.3}\n", .{number});
- try testFmt("right-pad: 3.141**\n", "right-pad: {d:*<7.3}\n", .{number});
+ try expectFmt("left-pad: **3.141\n", "left-pad: {d:*>7.3}\n", .{number});
+ try expectFmt("center-pad: *3.141*\n", "center-pad: {d:*^7.3}\n", .{number});
+ try expectFmt("right-pad: 3.141**\n", "right-pad: {d:*<7.3}\n", .{number});
}
test "sci float padding" {
var number: f32 = 3.1415;
- try testFmt("left-pad: **3.141e+00\n", "left-pad: {e:*>11.3}\n", .{number});
- try testFmt("center-pad: *3.141e+00*\n", "center-pad: {e:*^11.3}\n", .{number});
- try testFmt("right-pad: 3.141e+00**\n", "right-pad: {e:*<11.3}\n", .{number});
+ try expectFmt("left-pad: **3.141e+00\n", "left-pad: {e:*>11.3}\n", .{number});
+ try expectFmt("center-pad: *3.141e+00*\n", "center-pad: {e:*^11.3}\n", .{number});
+ try expectFmt("right-pad: 3.141e+00**\n", "right-pad: {e:*<11.3}\n", .{number});
}
test "null" {
const inst = null;
- try testFmt("null", "{}", .{inst});
+ try expectFmt("null", "{}", .{inst});
}
test "type" {
- try testFmt("u8", "{}", .{u8});
- try testFmt("?f32", "{}", .{?f32});
- try testFmt("[]const u8", "{}", .{[]const u8});
+ try expectFmt("u8", "{}", .{u8});
+ try expectFmt("?f32", "{}", .{?f32});
+ try expectFmt("[]const u8", "{}", .{[]const u8});
}
test "named arguments" {
- try testFmt("hello world!", "{s} world{c}", .{ "hello", '!' });
- try testFmt("hello world!", "{[greeting]s} world{[punctuation]c}", .{ .punctuation = '!', .greeting = "hello" });
- try testFmt("hello world!", "{[1]s} world{[0]c}", .{ '!', "hello" });
+ try expectFmt("hello world!", "{s} world{c}", .{ "hello", '!' });
+ try expectFmt("hello world!", "{[greeting]s} world{[punctuation]c}", .{ .punctuation = '!', .greeting = "hello" });
+ try expectFmt("hello world!", "{[1]s} world{[0]c}", .{ '!', "hello" });
}
test "runtime width specifier" {
var width: usize = 9;
- try testFmt("~~hello~~", "{s:~^[1]}", .{ "hello", width });
- try testFmt("~~hello~~", "{s:~^[width]}", .{ .string = "hello", .width = width });
+ try expectFmt("~~hello~~", "{s:~^[1]}", .{ "hello", width });
+ try expectFmt("~~hello~~", "{s:~^[width]}", .{ .string = "hello", .width = width });
}
test "runtime precision specifier" {
var number: f32 = 3.1415;
var precision: usize = 2;
- try testFmt("3.14e+00", "{:1.[1]}", .{ number, precision });
- try testFmt("3.14e+00", "{:1.[precision]}", .{ .number = number, .precision = precision });
+ try expectFmt("3.14e+00", "{:1.[1]}", .{ number, precision });
+ try expectFmt("3.14e+00", "{:1.[precision]}", .{ .number = number, .precision = precision });
}
lib/std/SemanticVersion.zig
@@ -205,7 +205,7 @@ test "SemanticVersion format" {
"1.2.3----R-S.12.9.1--.12+meta",
"1.2.3----RC-SNAPSHOT.12.9.1--.12",
"1.0.0+0.build.1-rc.10000aaa-kk-0.1",
- }) |valid| try testFmt(valid, "{}", .{try parse(valid)});
+ }) |valid| try std.testing.expectFmt(valid, "{}", .{try parse(valid)});
// Invalid version strings should be rejected.
for ([_][]const u8{
@@ -253,7 +253,9 @@ test "SemanticVersion format" {
// Valid version string that may overflow.
const big_valid = "99999999999999999999999.999999999999999999.99999999999999999";
- if (parse(big_valid)) |ver| try testFmt(big_valid, "{}", .{ver}) else |err| expect(err == error.Overflow);
+ if (parse(big_valid)) |ver| {
+ try std.testing.expectFmt(big_valid, "{}", .{ver});
+ } else |err| expect(err == error.Overflow);
// Invalid version string that may overflow.
const big_invalid = "99999999999999999999999.999999999999999999.99999999999999999----RC-SNAPSHOT.12.09.1--------------------------------..12";
@@ -280,20 +282,6 @@ test "SemanticVersion precedence" {
expect(order(try parse("1.0.0-rc.1"), try parse("1.0.0")) == .lt);
}
-// This is copy-pasted from fmt.zig since it is not public.
-fn testFmt(expected: []const u8, comptime template: []const u8, args: anytype) !void {
- var buf: [100]u8 = undefined;
- const result = try std.fmt.bufPrint(buf[0..], template, args);
- if (std.mem.eql(u8, result, expected)) return;
-
- std.debug.warn("\n====== expected this output: =========\n", .{});
- std.debug.warn("{s}", .{expected});
- std.debug.warn("\n======== instead found this: =========\n", .{});
- std.debug.warn("{s}", .{result});
- std.debug.warn("\n======================================\n", .{});
- return error.TestFailed;
-}
-
test "zig_version" {
// An approximate Zig build that predates this test.
const older_version = .{ .major = 0, .minor = 8, .patch = 0, .pre = "dev.874" };
lib/std/testing.zig
@@ -184,6 +184,22 @@ test "expectEqual.union(enum)" {
expectEqual(a10, a10);
}
+/// This function is intended to be used only in tests. When the formatted result of the template
+/// and its arguments does not equal the expected text, it prints diagnostics to stderr to show how
+/// they are not equal, then returns an error.
+pub fn expectFmt(expected: []const u8, comptime template: []const u8, args: anytype) !void {
+ const result = try std.fmt.allocPrint(allocator, template, args);
+ defer allocator.free(result);
+ if (std.mem.eql(u8, result, expected)) return;
+
+ print("\n====== expected this output: =========\n", .{});
+ print("{s}", .{expected});
+ print("\n======== instead found this: =========\n", .{});
+ print("{s}", .{result});
+ print("\n======================================\n", .{});
+ return error.TestFailed;
+}
+
/// This function is intended to be used only in tests. When the actual value is not
/// within the margin of the expected value,
/// prints diagnostics to stderr to show exactly how they are not equal, then aborts.