Created
May 2, 2021 07:54
-
-
Save Jarred-Sumner/be47a4a01f473b00745660f26178c81b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fn expectPrinted(t: *Tester, contents: string, expected: string, src: anytype) !void { | |
// ... | |
_ = t.expect(contents, copied, src); | |
} | |
test "test name" { | |
var t_ = Tester.t(std.heap.page_allocator); | |
var t = &t_; | |
try expectPrinted(t, "(-x) ** 2", "(-x) ** 2;\n", @src()); | |
try expectPrinted(t, "(+x) ** 2", "(+x) ** 2;\n", @src()); | |
try expectPrinted(t, "(~x) ** 2", "(~x) ** 2;\n", @src()); | |
try expectPrinted(t, "(!x) ** 2", "(!x) ** 2;\n", @src()); | |
try expectPrinted(t, "(-1) ** 2", "(-1) ** 2;\n", @src()); | |
try expectPrinted(t, "(+1) ** 2", "1 ** 2;\n", @src()); | |
try expectPrinted(t, "(~1) ** 2", "(~1) ** 2;\n", @src()); | |
try expectPrinted(t, "(!1) ** 2", "false ** 2;\n", @src()); | |
try expectPrinted(t, "(void x) ** 2", "(void x) ** 2;\n", @src()); | |
try expectPrinted(t, "(delete x) ** 2", "(delete x) ** 2;\n", @src()); | |
try expectPrinted(t, "(typeof x) ** 2", "(typeof x) ** 2;\n", @src()); | |
try expectPrinted(t, "undefined ** 2", "(void 0) ** 2;\n", @src()); | |
try expectPrinted(t, "class Foo { foo() {} }", "class Foo {\n foo() {\n }\n}\n", @src()); | |
try expectPrinted(t, "class Foo { *foo() {} }", "class Foo {\n *foo() {\n }\n}\n", @src()); | |
try expectPrinted(t, "class Foo { get foo() {} }", "class Foo {\n get foo() {\n }\n}\n", @src()); | |
try expectPrinted(t, "class Foo { set foo(x) {} }", "class Foo {\n set foo(x) {\n }\n}\n", @src()); | |
try expectPrinted(t, "class Foo { static foo() {} }", "class Foo {\n static foo() {\n }\n}\n", @src()); | |
try expectPrinted(t, "class Foo { static *foo() {} }", "class Foo {\n static *foo() {\n }\n}\n", @src()); | |
try expectPrinted(t, "class Foo { static get foo() {} }", "class Foo {\n static get foo() {\n }\n}\n", @src()); | |
try expectPrinted(t, "class Foo { static set foo(x) {} }", "class Foo {\n static set foo(x) {\n }\n}\n", @src()); | |
try expectPrinted(t, "class Foo { async foo() {} }", "class Foo {\n async foo() {\n }\n}\n", @src()); | |
try expectPrinted(t, "class Foo { static async foo() {} }", "class Foo {\n static async foo() {\n }\n}\n", @src()); | |
try expectPrinted(t, "class Foo { static async *foo() {} }", "class Foo {\n static async *foo() {\n }\n}\n", @src()); | |
try expectPrinted(t, "({foo})", "({foo});\n", @src()); | |
try expectPrinted(t, "({foo:0})", "({foo: 0});\n", @src()); | |
try expectPrinted(t, "({1e9:0})", "({1e9: 0});\n", @src()); | |
try expectPrinted(t, "({1_2_3n:0})", "({123n: 0});\n", @src()); | |
try expectPrinted(t, "({0x1_2_3n:0})", "({0x123n: 0});\n", @src()); | |
try expectPrinted(t, "({foo() {}})", "({foo() {\n}});\n", @src()); | |
try expectPrinted(t, "({*foo() {}})", "({*foo() {\n}});\n", @src()); | |
try expectPrinted(t, "({get foo() {}})", "({get foo() {\n}});\n", @src()); | |
try expectPrinted(t, "({set foo(x) {}})", "({set foo(x) {\n}});\n", @src()); | |
try expectPrinted(t, "({if:0})", "({if: 0});\n", @src()); | |
try expectPrinted(t, "({if() {}})", "({if() {\n}});\n", @src()); | |
try expectPrinted(t, "({*if() {}})", "({*if() {\n}});\n", @src()); | |
try expectPrinted(t, "({get if() {}})", "({get if() {\n}});\n", @src()); | |
try expectPrinted(t, "({set if(x) {}})", "({set if(x) {\n}});\n", @src()); | |
try expectPrinted(t, "await x", "await x;\n", @src()); | |
try expectPrinted(t, "await +x", "await +x;\n", @src()); | |
try expectPrinted(t, "await -x", "await -x;\n", @src()); | |
try expectPrinted(t, "await ~x", "await ~x;\n", @src()); | |
try expectPrinted(t, "await !x", "await !x;\n", @src()); | |
try expectPrinted(t, "await --x", "await --x;\n", @src()); | |
try expectPrinted(t, "await ++x", "await ++x;\n", @src()); | |
try expectPrinted(t, "await x--", "await x--;\n", @src()); | |
try expectPrinted(t, "await x++", "await x++;\n", @src()); | |
try expectPrinted(t, "await void x", "await void x;\n", @src()); | |
try expectPrinted(t, "await typeof x", "await typeof x;\n", @src()); | |
try expectPrinted(t, "await (x * y)", "await (x * y);\n", @src()); | |
try expectPrinted(t, "await (x ** y)", "await (x ** y);\n", @src()); | |
t.report(@src()); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const RED = "\x1b[31;1m"; | |
const GREEN = "\x1b[32;1m"; | |
const CYAN = "\x1b[36;1m"; | |
const WHITE = "\x1b[37;1m"; | |
const DIM = "\x1b[2m"; | |
const RESET = "\x1b[0m"; | |
pub const Tester = struct { | |
pass: std.ArrayList(Expectation), | |
fail: std.ArrayList(Expectation), | |
allocator: *std.mem.Allocator, | |
pub fn t(allocator: *std.mem.Allocator) Tester { | |
return Tester{ | |
.allocator = allocator, | |
.pass = std.ArrayList(Expectation).init(allocator), | |
.fail = std.ArrayList(Expectation).init(allocator), | |
}; | |
} | |
pub const Expectation = struct { | |
expected: string, | |
result: string, | |
source: std.builtin.SourceLocation, | |
pub fn init(expected: string, result: string, src: std.builtin.SourceLocation) Expectation { | |
return Expectation{ | |
.expected = expected, | |
.result = result, | |
.source = src, | |
}; | |
} | |
const PADDING = 0; | |
pub fn print(self: *const @This()) void { | |
var pad = &([_]u8{' '} ** PADDING); | |
var stderr = std.io.getStdErr(); | |
stderr.writeAll(RESET) catch unreachable; | |
stderr.writeAll(pad) catch unreachable; | |
stderr.writeAll(DIM) catch unreachable; | |
std.fmt.format(stderr.writer(), "{s}:{d}:{d}", .{ self.source.file, self.source.line, self.source.column }) catch unreachable; | |
stderr.writeAll(RESET) catch unreachable; | |
stderr.writeAll("\n") catch unreachable; | |
stderr.writeAll(pad) catch unreachable; | |
stderr.writeAll("Expected: ") catch unreachable; | |
stderr.writeAll(RESET) catch unreachable; | |
stderr.writeAll(GREEN) catch unreachable; | |
std.fmt.format(stderr.writer(), "\"{s}\"", .{self.expected}) catch unreachable; | |
stderr.writeAll(GREEN) catch unreachable; | |
stderr.writeAll(RESET) catch unreachable; | |
stderr.writeAll("\n") catch unreachable; | |
stderr.writeAll(pad) catch unreachable; | |
stderr.writeAll("Received: ") catch unreachable; | |
stderr.writeAll(RESET) catch unreachable; | |
stderr.writeAll(RED) catch unreachable; | |
std.fmt.format(stderr.writer(), "\"{s}\"", .{self.result}) catch unreachable; | |
stderr.writeAll(RED) catch unreachable; | |
stderr.writeAll(RESET) catch unreachable; | |
stderr.writeAll("\n") catch unreachable; | |
} | |
pub fn evaluate_outcome(self: *const @This()) Outcome { | |
for (self.expected) |char, i| { | |
if (char != self.result[i]) { | |
return Outcome.fail; | |
} | |
} | |
return Outcome.pass; | |
} | |
}; | |
pub const Outcome = enum { | |
pass, | |
fail, | |
}; | |
pub fn expect(tester: *Tester, expected: string, result: string, src: std.builtin.SourceLocation) callconv(.Inline) bool { | |
var expectation = Expectation.init(expected, result, src); | |
switch (expectation.evaluate_outcome()) { | |
.pass => { | |
tester.pass.append(expectation) catch unreachable; | |
return true; | |
}, | |
.fail => { | |
tester.fail.append(expectation) catch unreachable; | |
return false; | |
}, | |
} | |
} | |
const ReportType = enum { | |
none, | |
pass, | |
fail, | |
some_fail, | |
pub fn init(tester: *Tester) ReportType { | |
if (tester.fail.items.len == 0 and tester.pass.items.len == 0) { | |
return .none; | |
} else if (tester.fail.items.len == 0) { | |
return .pass; | |
} else if (tester.pass.items.len == 0) { | |
return .fail; | |
} else { | |
return .some_fail; | |
} | |
} | |
}; | |
pub fn report(tester: *Tester, src: std.builtin.SourceLocation) void { | |
var stderr = std.io.getStdErr(); | |
if (tester.fail.items.len > 0) { | |
std.fmt.format(stderr.writer(), "\n\n", .{}) catch unreachable; | |
} | |
for (tester.fail.items) |item| { | |
item.print(); | |
std.fmt.format(stderr.writer(), "\n", .{}) catch unreachable; | |
} | |
switch (ReportType.init(tester)) { | |
.none => { | |
std.log.info("No expectations.\n\n", .{}); | |
}, | |
.pass => { | |
std.fmt.format(stderr.writer(), "{s}All {d} expectations passed.{s}\n", .{ GREEN, tester.pass.items.len, GREEN }) catch unreachable; | |
std.fmt.format(stderr.writer(), RESET, .{}) catch unreachable; | |
std.testing.expect(true); | |
}, | |
.fail => { | |
std.fmt.format(stderr.writer(), "{s}All {d} expectations failed.{s}\n\n", .{ RED, tester.fail.items.len, RED }) catch unreachable; | |
std.fmt.format(stderr.writer(), RESET, .{}) catch unreachable; | |
std.testing.expect(false); | |
}, | |
.some_fail => { | |
std.fmt.format(stderr.writer(), "{s}{d} failed{s} and {s}{d} passed{s} of {d} expectations{s}\n\n", .{ | |
RED, | |
tester.fail.items.len, | |
RED ++ RESET, | |
GREEN, | |
tester.pass.items.len, | |
GREEN ++ RESET, | |
tester.fail.items.len + tester.pass.items.len, | |
RESET, | |
}) catch unreachable; | |
std.fmt.format(stderr.writer(), RESET, .{}) catch unreachable; | |
std.testing.expect(false); | |
}, | |
} | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment