diff options
author | 2023-05-31 23:12:04 -0700 | |
---|---|---|
committer | 2023-05-31 23:12:04 -0700 | |
commit | e632941c520e9346fc706bb12d0434974c3f5a98 (patch) | |
tree | d80b1895cd920d45d0e74bff11ca90fc4ff2dfcd /src/cli/test_command.zig | |
parent | 176fade220ccc254e5ad822c3bd211023e961074 (diff) | |
download | bun-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.zig | 78 |
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(); } } |