Skip to content
Closed

ai slop #30018

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 22 additions & 2 deletions src/jsc/ConsoleObject.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3623,6 +3623,18 @@ const PendingTimers = std.AutoHashMap(u64, ?std.time.Timer);
threadlocal var pending_time_logs: PendingTimers = undefined;
threadlocal var pending_time_logs_loaded = false;

/// Writes `indent` levels (2 spaces each) to the same stderr stream used by
/// Output.printElapsed, so timer output nests inside the active console.group().
fn printTimerIndent(indent: u16) void {
const spaces_chunk = " " ** 64;
var remaining: usize = @as(usize, indent) * 2;
while (remaining > 0) {
const n = @min(spaces_chunk.len, remaining);
Output.printError("{s}", .{spaces_chunk[0..n]});
remaining -= n;
}
}
Comment thread
robobun marked this conversation as resolved.

pub fn time(
// console
_: *ConsoleObject,
Expand All @@ -3647,7 +3659,7 @@ pub fn timeEnd(
// console
_: *ConsoleObject,
// global
_: *JSGlobalObject,
global: *JSGlobalObject,
chars: [*]const u8,
len: usize,
) callconv(jsc.conv) void {
Expand All @@ -3658,6 +3670,9 @@ pub fn timeEnd(
const id = bun.hash(chars[0..len]);
const result = (pending_time_logs.fetchPut(id, null) catch null) orelse return;
var value: std.time.Timer = result.value orelse return;
// Match console.group() indentation so output nests inside the active group,
// per the WHATWG Console spec.
printTimerIndent(global.bunVM().console.default_indent);
// get the duration in microseconds
// then display it in milliseconds
Output.printElapsed(@as(f64, @floatFromInt(value.read() / std.time.ns_per_us)) / std.time.us_per_ms);
Expand Down Expand Up @@ -3688,6 +3703,9 @@ pub fn timeLog(

const id = bun.hash(chars[0..len]);
var value: std.time.Timer = (pending_time_logs.get(id) orelse return) orelse return;
// Match console.group() indentation so output nests inside the active group,
// per the WHATWG Console spec.
printTimerIndent(global.bunVM().console.default_indent);
// get the duration in microseconds
// then display it in milliseconds
Output.printElapsed(@as(f64, @floatFromInt(value.read() / std.time.ns_per_us)) / std.time.us_per_ms);
Expand All @@ -3697,6 +3715,7 @@ pub fn timeLog(
}
Output.flush();

const console = global.bunVM().console;
// print the arguments
var fmt = ConsoleObject.Formatter{
.remaining_values = &[_]JSValue{},
Expand All @@ -3707,10 +3726,11 @@ pub fn timeLog(
const cli_context = CLI.get();
break :blk cli_context.runtime_options.console_depth orelse DEFAULT_CONSOLE_LOG_DEPTH;
},
.indent = console.default_indent,
.stack_check = bun.StackCheck.init(),
.can_throw_stack_overflow = true,
};
Comment thread
robobun marked this conversation as resolved.
Comment thread
robobun marked this conversation as resolved.
const console = global.bunVM().console;
defer fmt.deinit();
const writer = console.error_writer;
const Writer = @TypeOf(writer);
for (args[0..args_len]) |arg| {
Expand Down
47 changes: 47 additions & 0 deletions test/js/web/console/console-timeLog.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,50 @@ it("should log to console correctly", async () => {

expect(outText.replace(/^\[.+?s\] /gm, "")).toBe(expectedText.replace(/^\[.+?s\] /gm, ""));
});

// https://github.com/oven-sh/bun/issues/30017 — console.timeEnd()/timeLog()
// must apply console.group() indentation per the WHATWG Console spec.
it("console.timeEnd / timeLog respect console.group indentation", async () => {
const src = `
console.time("top");
console.timeEnd("top");

console.group("a");
console.time("t1");
console.timeEnd("t1");
console.group("b");
console.time("t2");
console.timeLog("t2", "msg");
console.timeLog("t2", { x: 1, y: 2 });
console.timeEnd("t2");
console.groupEnd();
console.groupEnd();
`;
await using proc = Bun.spawn({
cmd: [bunExe(), "-e", src],
env: bunEnv,
stdin: "ignore",
stdout: "pipe",
stderr: "pipe",
});
const [stdout, stderr, exitCode] = await Promise.all([proc.stdout.text(), proc.stderr.text(), proc.exited]);
// Group labels go to stdout; timer output goes to stderr.
expect(stdout.replaceAll("\r\n", "\n")).toBe("a\n b\n");
// Strip the elapsed-time prefix so the stderr check focuses on indentation.
const normalized = stderr.replaceAll("\r\n", "\n").replace(/\[.+?m?s\] /g, "");
expect(normalized).toBe(
[
"top", // no group → no indent
" t1", // inside one group → 2 spaces
" t2 msg", // inside nested group → 4 spaces
" t2 {", // multi-line object opens at nested indent
" x: 1,", // inner fields indented by group depth + object depth
" y: 2,",
" }",
" t2",
"",
].join("\n"),
);
// Assert the exit code last for more useful failure diagnostics.
expect(exitCode).toBe(0);
});
Loading