aboutsummaryrefslogtreecommitdiff
path: root/src/cli/test_command.zig
diff options
context:
space:
mode:
authorGravatar Ashcon Partovi <ashcon@partovi.net> 2023-05-31 23:12:04 -0700
committerGravatar GitHub <noreply@github.com> 2023-05-31 23:12:04 -0700
commite632941c520e9346fc706bb12d0434974c3f5a98 (patch)
treed80b1895cd920d45d0e74bff11ca90fc4ff2dfcd /src/cli/test_command.zig
parent176fade220ccc254e5ad822c3bd211023e961074 (diff)
downloadbun-e632941c520e9346fc706bb12d0434974c3f5a98.tar.gz
bun-e632941c520e9346fc706bb12d0434974c3f5a98.tar.zst
bun-e632941c520e9346fc706bb12d0434974c3f5a98.zip
Small improvements to `bun test` (#3071)
* Change status icon for skipped tests from "-" to "»" * Show file path instead of filename in `bun test` * Emit collapsable logs when running `bun test` in Github Actions https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#grouping-log-lines * Add fallback for test icons when emojis are not available * Only check for GITHUB_ACTIONS when running `bun test` * Emit error annotations when running `bun test` in Github Actions https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-error-message * Remove ANSI output from Github annotation, it doesn't work * Remove outdated code from internal test runner * Add GithubActionFormatter to handle cases where error name or message is already ANSI * Fix formatting of test * Fix #3070 * Implement `bun test --run-todo` By default, `test.todo()` is no longer run, unless `--run-todo` is specified. * Fix test that relies on test.todo() being run * Support vitest-style test options * Disable GITHUB_ACTION in test harness * Add types for TestOptions * Fix bug where test.skip() actually ran * Implement `test.skipIf()` and `describe.skipIf()` * Implement `test.runIf()` * Move DiffFormatter to its own file * Fix bug where Bun.inspect() would emit a Github annotation * Introduce `bun test --only`, rename `--run-todo` to `--todo` * Implement `test.if()`, `describe.if()`, and other test fixes * Remove unwanted files from last commit * Fix last reference to --run-todo * Fix memory issues with printing github actions text * Update bindings.zig * Fix bug with `test.only()` * Remove debug test * Make the github annotations better * Improve .vscode/launch.json * Implement `expect().toBeNil()` * Remove .only() from test * Implement toBeBoolean(), toBeTrue(), toBeFalse() * Add lots of matchers * toBeNil() * toBeBoolean() * toBeTrue() * toBeFalse() * toBeNumber() * toBeInteger() * toBeFinite() * toBePositive() * toBeNegative() * toBeWithin() * toBeSymbol() * toBeFunction() * toBeDate() * toBeString() * toInclude() * toStartWith() * toEndWith() * Fix #3135 * Reduce verbosity of test * Fix snapshot bug --------- Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
Diffstat (limited to 'src/cli/test_command.zig')
-rw-r--r--src/cli/test_command.zig78
1 files changed, 58 insertions, 20 deletions
diff --git a/src/cli/test_command.zig b/src/cli/test_command.zig
index 0e337ebf0..b7712c0de 100644
--- a/src/cli/test_command.zig
+++ b/src/cli/test_command.zig
@@ -48,12 +48,21 @@ const uws = @import("root").bun.uws;
fn fmtStatusTextLine(comptime status: @Type(.EnumLiteral), comptime emoji: bool) []const u8 {
comptime {
- return switch (status) {
- .pass => Output.prettyFmt("<r><green>✓<r>", emoji),
- .fail => Output.prettyFmt("<r><red>✗<r>", emoji),
- .skip => Output.prettyFmt("<r><yellow>-<d>", emoji),
- .todo => Output.prettyFmt("<r><magenta>✎<r>", emoji),
- else => @compileError("Invalid status " ++ @tagName(status)),
+ return switch (emoji) {
+ true => switch (status) {
+ .pass => Output.prettyFmt("<r><green>✓<r>", true),
+ .fail => Output.prettyFmt("<r><red>✗<r>", true),
+ .skip => Output.prettyFmt("<r><yellow>»<d>", true),
+ .todo => Output.prettyFmt("<r><magenta>✎<r>", true),
+ else => @compileError("Invalid status " ++ @tagName(status)),
+ },
+ else => switch (status) {
+ .pass => Output.prettyFmt("<r><green>(pass)<r>", true),
+ .fail => Output.prettyFmt("<r><red>(fail)<r>", true),
+ .skip => Output.prettyFmt("<r><yellow>(skip)<d>", true),
+ .todo => Output.prettyFmt("<r><magenta>(todo)<r>", true),
+ else => @compileError("Invalid status " ++ @tagName(status)),
+ },
};
}
}
@@ -94,13 +103,9 @@ pub const CommandLineReporter = struct {
break :brk map;
};
- pub fn handleUpdateCount(cb: *TestRunner.Callback, _: u32, _: u32) void {
- _ = cb;
- }
+ pub fn handleUpdateCount(_: *TestRunner.Callback, _: u32, _: u32) void {}
- pub fn handleTestStart(_: *TestRunner.Callback, _: Test.ID) void {
- // var this: *CommandLineReporter = @fieldParentPtr(CommandLineReporter, "callback", cb);
- }
+ pub fn handleTestStart(_: *TestRunner.Callback, _: Test.ID) void {}
fn printTestLine(label: string, elapsed_ns: u64, parent: ?*jest.DescribeScope, comptime skip: bool, writer: anytype) void {
var scopes_stack = std.BoundedArray(*jest.DescribeScope, 64).init(0) catch unreachable;
@@ -329,6 +334,16 @@ const Scanner = struct {
if (this.filter_names.len == 0) return true;
for (this.filter_names) |filter_name| {
+ if (strings.startsWith(name, filter_name)) return true;
+ }
+
+ return false;
+ }
+
+ pub fn doesPathMatchFilter(this: *Scanner, name: string) bool {
+ if (this.filter_names.len == 0) return true;
+
+ for (this.filter_names) |filter_name| {
if (strings.contains(name, filter_name)) return true;
}
@@ -336,7 +351,7 @@ const Scanner = struct {
}
pub fn isTestFile(this: *Scanner, name: string) bool {
- return this.couldBeTestFile(name) and this.doesAbsolutePathMatchFilter(name);
+ return this.couldBeTestFile(name) and this.doesPathMatchFilter(name);
}
pub fn next(this: *Scanner, entry: *FileSystem.Entry, fd: bun.StoredFileDescriptorType) void {
@@ -370,7 +385,10 @@ const Scanner = struct {
var parts = &[_]string{ entry.dir, entry.base() };
const path = this.fs.absBuf(parts, &this.open_dir_buf);
- if (!this.doesAbsolutePathMatchFilter(path)) return;
+ if (!this.doesAbsolutePathMatchFilter(path)) {
+ const rel_path = bun.path.relative(this.fs.top_level_dir, path);
+ if (!this.doesPathMatchFilter(rel_path)) return;
+ }
entry.abs_path = bun.PathString.init(this.fs.filename_store.append(@TypeOf(path), path) catch unreachable);
this.results.append(entry.abs_path) catch unreachable;
@@ -385,6 +403,9 @@ pub const TestCommand = struct {
pub fn exec(ctx: Command.Context) !void {
if (comptime is_bindgen) unreachable;
+
+ Output.is_github_action = Output.isGithubAction();
+
// print the version so you know its doing stuff if it takes a sec
if (strings.eqlComptime(ctx.positionals[0], old_name)) {
Output.prettyErrorln("<r><b>bun wiptest <r><d>v" ++ Global.package_json_version_with_sha ++ "<r>", .{});
@@ -415,6 +436,8 @@ pub const TestCommand = struct {
.log = ctx.log,
.callback = undefined,
.default_timeout_ms = ctx.test_options.default_timeout_ms,
+ .run_todo = ctx.test_options.run_todo,
+ .only = ctx.test_options.only,
.snapshots = Snapshots{
.allocator = ctx.allocator,
.update_snapshots = ctx.test_options.update_snapshots,
@@ -717,14 +740,26 @@ pub const TestCommand = struct {
var resolution = try vm.bundler.resolveEntryPoint(file_name);
vm.clearEntryPoint();
- Output.prettyErrorln("<r>\n{s}:\n", .{resolution.path_pair.primary.name.filename});
- Output.flush();
+ const file_path = resolution.path_pair.primary.text;
+ const file_title = bun.path.relative(FileSystem.instance.top_level_dir, file_path);
+
+ // In Github Actions, append a special prefix that will group
+ // subsequent log lines into a collapsable group.
+ // https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#grouping-log-lines
+ const file_prefix = if (Output.is_github_action) "::group::" else "";
- vm.main_hash = @truncate(u32, bun.hash(resolution.path_pair.primary.text));
+ vm.main_hash = @truncate(u32, bun.hash(file_path));
var repeat_count = reporter.repeat_count;
var repeat_index: u32 = 0;
while (repeat_index < repeat_count) : (repeat_index += 1) {
- var promise = try vm.loadEntryPoint(resolution.path_pair.primary.text);
+ if (repeat_count > 1) {
+ Output.prettyErrorln("<r>\n{s}{s}: <d>(run #{d})<r>\n", .{ file_prefix, file_title, repeat_index + 1 });
+ } else {
+ Output.prettyErrorln("<r>\n{s}{s}:\n", .{ file_prefix, file_title });
+ }
+ Output.flush();
+
+ var promise = try vm.loadEntryPoint(file_path);
switch (promise.status(vm.global.vm())) {
.Rejected => {
@@ -789,9 +824,12 @@ pub const TestCommand = struct {
vm.global.handleRejectedPromises();
if (repeat_index > 0) {
vm.clearEntryPoint();
- var entry = JSC.ZigString.init(resolution.path_pair.primary.text);
+ var entry = JSC.ZigString.init(file_path);
vm.global.deleteModuleRegistryEntry(&entry);
- Output.prettyErrorln("<r>{s} <d>[RUN {d:0>4}]:<r>\n", .{ resolution.path_pair.primary.name.filename, repeat_index + 1 });
+ }
+
+ if (Output.is_github_action) {
+ Output.prettyErrorln("<r>\n::endgroup::\n", .{});
Output.flush();
}
}