mirror of
https://github.com/oven-sh/bun
synced 2026-02-10 19:08:50 +00:00
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>
This commit is contained in:
@@ -38,7 +38,7 @@ pub fn toUTF16Literal(comptime str: []const u8) []const u16 {
|
||||
};
|
||||
}
|
||||
|
||||
const OptionalUsize = std.meta.Int(.unsigned, @bitSizeOf(usize) - 1);
|
||||
pub const OptionalUsize = std.meta.Int(.unsigned, @bitSizeOf(usize) - 1);
|
||||
pub fn indexOfAny(self: string, comptime str: anytype) ?OptionalUsize {
|
||||
inline for (str) |a| {
|
||||
if (indexOfChar(self, a)) |i| {
|
||||
@@ -689,6 +689,63 @@ pub fn endsWithAny(self: string, str: string) bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Formats a string to be safe to output in a Github action.
|
||||
// - Encodes "\n" as "%0A" to support multi-line strings.
|
||||
// https://github.com/actions/toolkit/issues/193#issuecomment-605394935
|
||||
// - Strips ANSI output as it will appear malformed.
|
||||
pub fn githubActionWriter(writer: anytype, self: string) !void {
|
||||
var offset: usize = 0;
|
||||
const end = @truncate(u32, self.len);
|
||||
while (offset < end) {
|
||||
if (indexOfNewlineOrNonASCIIOrANSI(self, @truncate(u32, offset))) |i| {
|
||||
const byte = self[i];
|
||||
if (byte > 0x7F) {
|
||||
offset += @max(wtf8ByteSequenceLength(byte), 1);
|
||||
continue;
|
||||
}
|
||||
if (i > 0) {
|
||||
try writer.writeAll(self[offset..i]);
|
||||
}
|
||||
var n: usize = 1;
|
||||
if (byte == '\n') {
|
||||
try writer.writeAll("%0A");
|
||||
} else if (i + 1 < end) {
|
||||
const next = self[i + 1];
|
||||
if (byte == '\r' and next == '\n') {
|
||||
n += 1;
|
||||
try writer.writeAll("%0A");
|
||||
} else if (byte == '\x1b' and next == '[') {
|
||||
n += 1;
|
||||
if (i + 2 < end) {
|
||||
const remain = self[(i + 2)..@min(i + 5, end)];
|
||||
if (indexOfChar(remain, 'm')) |j| {
|
||||
n += j + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
offset = i + n;
|
||||
} else {
|
||||
try writer.writeAll(self[offset..end]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub const GithubActionFormatter = struct {
|
||||
text: string,
|
||||
|
||||
pub fn format(this: GithubActionFormatter, comptime _: []const u8, _: std.fmt.FormatOptions, writer: anytype) !void {
|
||||
try githubActionWriter(writer, this.text);
|
||||
}
|
||||
};
|
||||
|
||||
pub fn githubAction(self: string) strings.GithubActionFormatter {
|
||||
return GithubActionFormatter{
|
||||
.text = self,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn quotedWriter(writer: anytype, self: string) !void {
|
||||
var remain = self;
|
||||
if (strings.containsNewlineOrNonASCIIOrQuote(remain)) {
|
||||
@@ -3179,6 +3236,44 @@ pub fn firstNonASCIIWithType(comptime Type: type, slice: Type) ?u32 {
|
||||
return null;
|
||||
}
|
||||
|
||||
pub fn indexOfNewlineOrNonASCIIOrANSI(slice_: []const u8, offset: u32) ?u32 {
|
||||
const slice = slice_[offset..];
|
||||
var remaining = slice;
|
||||
|
||||
if (remaining.len == 0)
|
||||
return null;
|
||||
|
||||
if (comptime Environment.enableSIMD) {
|
||||
while (remaining.len >= ascii_vector_size) {
|
||||
const vec: AsciiVector = remaining[0..ascii_vector_size].*;
|
||||
const cmp = @bitCast(AsciiVectorU1, (vec > max_16_ascii)) | @bitCast(AsciiVectorU1, (vec < min_16_ascii)) |
|
||||
@bitCast(AsciiVectorU1, vec == @splat(ascii_vector_size, @as(u8, '\r'))) |
|
||||
@bitCast(AsciiVectorU1, vec == @splat(ascii_vector_size, @as(u8, '\n'))) |
|
||||
@bitCast(AsciiVectorU1, vec == @splat(ascii_vector_size, @as(u8, '\x1b')));
|
||||
|
||||
if (@reduce(.Max, cmp) > 0) {
|
||||
const bitmask = @bitCast(AsciiVectorInt, cmp);
|
||||
const first = @ctz(bitmask);
|
||||
|
||||
return @as(u32, first) + @intCast(u32, slice.len - remaining.len) + offset;
|
||||
}
|
||||
|
||||
remaining = remaining[ascii_vector_size..];
|
||||
}
|
||||
|
||||
if (comptime Environment.allow_assert) std.debug.assert(remaining.len < ascii_vector_size);
|
||||
}
|
||||
|
||||
for (remaining) |*char_| {
|
||||
const char = char_.*;
|
||||
if (char > 127 or char < 0x20 or char == '\n' or char == '\r' or char == '\x1b') {
|
||||
return @truncate(u32, (@ptrToInt(char_) - @ptrToInt(slice.ptr))) + offset;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
pub fn indexOfNewlineOrNonASCII(slice_: []const u8, offset: u32) ?u32 {
|
||||
return indexOfNewlineOrNonASCIICheckStart(slice_, offset, true);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user