Skip to content

Commit c40704d

Browse files
committed
Prototype new test runner
Follows up on #994 and replaces the jsRunner with a new page.navigation-based test runner. Currently only implemented for the Window tests, looking for feedback and converting every existing test will take time - so for a while, newRunner (to be renamed) will sit side-by-side with jsRunner. In addition to the benefits outlined in 994, largely around code simplicity and putting more of the actual code under tests, I think our WebAPI tests particularly benefit from: 1 - No need to recompile when modifying the html tests 2 - Much better assertions, e.g. you can assert that something is actually an array, not just a string representation of an array 3 - Ability to test some edge cases (e.g. dynamic script loading) I've put some effort into testing.js to make sure that, if the encapsulating zig test passes, it's because it actually passed, not because it didn't run. For the time being, console tests are removed. I think it's more useful to have access to the console within tests, than it is to test the console (which is just a wrapper around log, which is both tested and heavily used).
1 parent c0f0630 commit c40704d

File tree

8 files changed

+411
-312
lines changed

8 files changed

+411
-312
lines changed

src/browser/console/console.zig

Lines changed: 72 additions & 161 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,12 @@
1818

1919
const std = @import("std");
2020
const builtin = @import("builtin");
21+
const log = @import("../../log.zig");
2122

2223
const Allocator = std.mem.Allocator;
2324
const Page = @import("../page.zig").Page;
2425
const JsObject = @import("../env.zig").Env.JsObject;
2526

26-
const log = if (builtin.is_test) &test_capture else @import("../../log.zig");
27-
2827
pub const Console = struct {
2928
// TODO: configurable writer
3029
timers: std.StringHashMapUnmanaged(u32) = .{},
@@ -67,7 +66,7 @@ pub const Console = struct {
6766
return;
6867
}
6968

70-
log.info(.console, "error", .{
69+
log.warn(.console, "error", .{
7170
.args = try serializeValues(values, page),
7271
.stack = page.stackTrace() catch "???",
7372
});
@@ -168,161 +167,73 @@ fn timestamp() u32 {
168167
return @import("../../datetime.zig").timestamp();
169168
}
170169

171-
var test_capture = TestCapture{};
172-
const testing = @import("../../testing.zig");
173-
test "Browser.Console" {
174-
defer testing.reset();
175-
176-
var runner = try testing.jsRunner(testing.tracking_allocator, .{});
177-
defer runner.deinit();
178-
179-
{
180-
try runner.testCases(&.{
181-
.{ "console.log('a')", "undefined" },
182-
.{ "console.warn('hello world', 23, true, new Object())", "undefined" },
183-
}, .{});
184-
185-
const captured = test_capture.captured.items;
186-
try testing.expectEqual("[info] args= 1: a", captured[0]);
187-
try testing.expectEqual("[warn] args= 1: hello world 2: 23 3: true 4: #<Object>", captured[1]);
188-
}
189-
190-
{
191-
test_capture.reset();
192-
try runner.testCases(&.{
193-
.{ "console.countReset()", "undefined" },
194-
.{ "console.count()", "undefined" },
195-
.{ "console.count('teg')", "undefined" },
196-
.{ "console.count('teg')", "undefined" },
197-
.{ "console.count('teg')", "undefined" },
198-
.{ "console.count()", "undefined" },
199-
.{ "console.countReset('teg')", "undefined" },
200-
.{ "console.countReset()", "undefined" },
201-
.{ "console.count()", "undefined" },
202-
}, .{});
203-
204-
const captured = test_capture.captured.items;
205-
try testing.expectEqual("[invalid counter] label=default", captured[0]);
206-
try testing.expectEqual("[count] label=default count=1", captured[1]);
207-
try testing.expectEqual("[count] label=teg count=1", captured[2]);
208-
try testing.expectEqual("[count] label=teg count=2", captured[3]);
209-
try testing.expectEqual("[count] label=teg count=3", captured[4]);
210-
try testing.expectEqual("[count] label=default count=2", captured[5]);
211-
try testing.expectEqual("[count reset] label=teg count=3", captured[6]);
212-
try testing.expectEqual("[count reset] label=default count=2", captured[7]);
213-
try testing.expectEqual("[count] label=default count=1", captured[8]);
214-
}
215-
216-
{
217-
test_capture.reset();
218-
try runner.testCases(&.{
219-
.{ "console.assert(true)", "undefined" },
220-
.{ "console.assert('a', 2, 3, 4)", "undefined" },
221-
.{ "console.assert('')", "undefined" },
222-
.{ "console.assert('', 'x', true)", "undefined" },
223-
.{ "console.assert(false, 'x')", "undefined" },
224-
}, .{});
225-
226-
const captured = test_capture.captured.items;
227-
try testing.expectEqual("[assertion failed] values=", captured[0]);
228-
try testing.expectEqual("[assertion failed] values= 1: x 2: true", captured[1]);
229-
try testing.expectEqual("[assertion failed] values= 1: x", captured[2]);
230-
}
231-
232-
{
233-
test_capture.reset();
234-
try runner.testCases(&.{
235-
.{ "[1].forEach(console.log)", null },
236-
}, .{});
237-
238-
const captured = test_capture.captured.items;
239-
try testing.expectEqual("[info] args= 1: 1 2: 0 3: [1]", captured[0]);
240-
}
241-
}
242-
243-
const TestCapture = struct {
244-
captured: std.ArrayListUnmanaged([]const u8) = .{},
245-
246-
fn separator(_: *const TestCapture) []const u8 {
247-
return " ";
248-
}
249-
250-
fn reset(self: *TestCapture) void {
251-
self.captured = .{};
252-
}
253-
254-
fn debug(
255-
self: *TestCapture,
256-
comptime scope: @Type(.enum_literal),
257-
comptime msg: []const u8,
258-
args: anytype,
259-
) void {
260-
self.capture(scope, msg, args);
261-
}
262-
263-
fn info(
264-
self: *TestCapture,
265-
comptime scope: @Type(.enum_literal),
266-
comptime msg: []const u8,
267-
args: anytype,
268-
) void {
269-
self.capture(scope, msg, args);
270-
}
271-
272-
fn warn(
273-
self: *TestCapture,
274-
comptime scope: @Type(.enum_literal),
275-
comptime msg: []const u8,
276-
args: anytype,
277-
) void {
278-
self.capture(scope, msg, args);
279-
}
280-
281-
fn err(
282-
self: *TestCapture,
283-
comptime scope: @Type(.enum_literal),
284-
comptime msg: []const u8,
285-
args: anytype,
286-
) void {
287-
self.capture(scope, msg, args);
288-
}
289-
290-
fn fatal(
291-
self: *TestCapture,
292-
comptime scope: @Type(.enum_literal),
293-
comptime msg: []const u8,
294-
args: anytype,
295-
) void {
296-
self.capture(scope, msg, args);
297-
}
298-
299-
fn capture(
300-
self: *TestCapture,
301-
comptime scope: @Type(.enum_literal),
302-
comptime msg: []const u8,
303-
args: anytype,
304-
) void {
305-
self._capture(scope, msg, args) catch unreachable;
306-
}
307-
308-
fn _capture(
309-
self: *TestCapture,
310-
comptime scope: @Type(.enum_literal),
311-
comptime msg: []const u8,
312-
args: anytype,
313-
) !void {
314-
std.debug.assert(scope == .console);
315-
316-
const allocator = testing.arena_allocator;
317-
var buf: std.ArrayListUnmanaged(u8) = .empty;
318-
try buf.appendSlice(allocator, "[" ++ msg ++ "] ");
319-
320-
inline for (@typeInfo(@TypeOf(args)).@"struct".fields) |f| {
321-
try buf.appendSlice(allocator, f.name);
322-
try buf.append(allocator, '=');
323-
try @import("../../log.zig").writeValue(.pretty, @field(args, f.name), buf.writer(allocator));
324-
try buf.append(allocator, ' ');
325-
}
326-
self.captured.append(testing.arena_allocator, std.mem.trimRight(u8, buf.items, " ")) catch unreachable;
327-
}
328-
};
170+
// const testing = @import("../../testing.zig");
171+
// test "Browser.Console" {
172+
// defer testing.reset();
173+
174+
// var runner = try testing.jsRunner(testing.tracking_allocator, .{});
175+
// defer runner.deinit();
176+
177+
// {
178+
// try runner.testCases(&.{
179+
// .{ "console.log('a')", "undefined" },
180+
// .{ "console.warn('hello world', 23, true, new Object())", "undefined" },
181+
// }, .{});
182+
183+
// const captured = test_capture.captured.items;
184+
// try testing.expectEqual("[info] args= 1: a", captured[0]);
185+
// try testing.expectEqual("[warn] args= 1: hello world 2: 23 3: true 4: #<Object>", captured[1]);
186+
// }
187+
188+
// {
189+
// test_capture.reset();
190+
// try runner.testCases(&.{
191+
// .{ "console.countReset()", "undefined" },
192+
// .{ "console.count()", "undefined" },
193+
// .{ "console.count('teg')", "undefined" },
194+
// .{ "console.count('teg')", "undefined" },
195+
// .{ "console.count('teg')", "undefined" },
196+
// .{ "console.count()", "undefined" },
197+
// .{ "console.countReset('teg')", "undefined" },
198+
// .{ "console.countReset()", "undefined" },
199+
// .{ "console.count()", "undefined" },
200+
// }, .{});
201+
202+
// const captured = test_capture.captured.items;
203+
// try testing.expectEqual("[invalid counter] label=default", captured[0]);
204+
// try testing.expectEqual("[count] label=default count=1", captured[1]);
205+
// try testing.expectEqual("[count] label=teg count=1", captured[2]);
206+
// try testing.expectEqual("[count] label=teg count=2", captured[3]);
207+
// try testing.expectEqual("[count] label=teg count=3", captured[4]);
208+
// try testing.expectEqual("[count] label=default count=2", captured[5]);
209+
// try testing.expectEqual("[count reset] label=teg count=3", captured[6]);
210+
// try testing.expectEqual("[count reset] label=default count=2", captured[7]);
211+
// try testing.expectEqual("[count] label=default count=1", captured[8]);
212+
// }
213+
214+
// {
215+
// test_capture.reset();
216+
// try runner.testCases(&.{
217+
// .{ "console.assert(true)", "undefined" },
218+
// .{ "console.assert('a', 2, 3, 4)", "undefined" },
219+
// .{ "console.assert('')", "undefined" },
220+
// .{ "console.assert('', 'x', true)", "undefined" },
221+
// .{ "console.assert(false, 'x')", "undefined" },
222+
// }, .{});
223+
224+
// const captured = test_capture.captured.items;
225+
// try testing.expectEqual("[assertion failed] values=", captured[0]);
226+
// try testing.expectEqual("[assertion failed] values= 1: x 2: true", captured[1]);
227+
// try testing.expectEqual("[assertion failed] values= 1: x", captured[2]);
228+
// }
229+
230+
// {
231+
// test_capture.reset();
232+
// try runner.testCases(&.{
233+
// .{ "[1].forEach(console.log)", null },
234+
// }, .{});
235+
236+
// const captured = test_capture.captured.items;
237+
// try testing.expectEqual("[info] args= 1: 1 2: 0 3: [1]", captured[0]);
238+
// }
239+
// }

0 commit comments

Comments
 (0)