diff --git a/src/bun.js/api/bun/ms.zig b/src/bun.js/api/bun/ms.zig index 6274c665ac..f4ae3a39cc 100644 --- a/src/bun.js/api/bun/ms.zig +++ b/src/bun.js/api/bun/ms.zig @@ -4,20 +4,6 @@ const jsc = bun.jsc; const JSValue = jsc.JSValue; const JSGlobalObject = jsc.JSGlobalObject; -const ns_per_ms = std.time.ns_per_ms; -const ns_per_s = std.time.ns_per_s; -const ns_per_min = std.time.ns_per_min; -const ns_per_hour = std.time.ns_per_hour; -const ns_per_day = std.time.ns_per_day; -const ns_per_week = std.time.ns_per_week; - -const MS_PER_SECOND = @as(f64, ns_per_s) / @as(f64, ns_per_ms); -const MS_PER_MINUTE = @as(f64, ns_per_min) / @as(f64, ns_per_ms); -const MS_PER_HOUR = @as(f64, ns_per_hour) / @as(f64, ns_per_ms); -const MS_PER_DAY = @as(f64, ns_per_day) / @as(f64, ns_per_ms); -const MS_PER_WEEK = @as(f64, ns_per_week) / @as(f64, ns_per_ms); -const MS_PER_YEAR = MS_PER_DAY * 365.25; - /// Parse a time string like "2d", "1.5h", "5m" to milliseconds pub fn parse(input: []const u8) ?f64 { if (input.len == 0 or input.len > 100) return null; @@ -78,26 +64,26 @@ pub fn parse(input: []const u8) ?f64 { } fn getMultiplier(unit: []const u8) ?f64 { - // Years + // Years (365.25 days to account for leap years) if (std.ascii.eqlIgnoreCase(unit, "years") or std.ascii.eqlIgnoreCase(unit, "year") or std.ascii.eqlIgnoreCase(unit, "yrs") or std.ascii.eqlIgnoreCase(unit, "yr") or std.ascii.eqlIgnoreCase(unit, "y")) { - return MS_PER_YEAR; + return std.time.ms_per_day * 365.25; } // Weeks if (std.ascii.eqlIgnoreCase(unit, "weeks") or std.ascii.eqlIgnoreCase(unit, "week") or std.ascii.eqlIgnoreCase(unit, "w")) { - return MS_PER_WEEK; + return std.time.ms_per_week; } // Days if (std.ascii.eqlIgnoreCase(unit, "days") or std.ascii.eqlIgnoreCase(unit, "day") or std.ascii.eqlIgnoreCase(unit, "d")) { - return MS_PER_DAY; + return std.time.ms_per_day; } // Hours @@ -105,7 +91,7 @@ fn getMultiplier(unit: []const u8) ?f64 { std.ascii.eqlIgnoreCase(unit, "hrs") or std.ascii.eqlIgnoreCase(unit, "hr") or std.ascii.eqlIgnoreCase(unit, "h")) { - return MS_PER_HOUR; + return std.time.ms_per_hour; } // Minutes @@ -113,7 +99,7 @@ fn getMultiplier(unit: []const u8) ?f64 { std.ascii.eqlIgnoreCase(unit, "mins") or std.ascii.eqlIgnoreCase(unit, "min") or std.ascii.eqlIgnoreCase(unit, "m")) { - return MS_PER_MINUTE; + return std.time.ms_per_min; } // Seconds @@ -121,7 +107,7 @@ fn getMultiplier(unit: []const u8) ?f64 { std.ascii.eqlIgnoreCase(unit, "secs") or std.ascii.eqlIgnoreCase(unit, "sec") or std.ascii.eqlIgnoreCase(unit, "s")) { - return MS_PER_SECOND; + return std.time.ms_per_s; } // Milliseconds @@ -140,41 +126,41 @@ fn getMultiplier(unit: []const u8) ?f64 { pub fn format(allocator: std.mem.Allocator, ms: f64, long: bool) ![]const u8 { const abs_ms = @abs(ms); - if (abs_ms >= MS_PER_DAY) { - const days = @round(ms / MS_PER_DAY); + if (abs_ms >= std.time.ms_per_day) { + const days = @round(ms / std.time.ms_per_day); const days_int = @as(i64, @intFromFloat(days)); if (long) { - const plural = abs_ms >= MS_PER_DAY * 1.5; + const plural = abs_ms >= std.time.ms_per_day * 1.5; return std.fmt.allocPrint(allocator, "{d} day{s}", .{ days_int, if (plural) "s" else "" }); } return std.fmt.allocPrint(allocator, "{d}d", .{days_int}); } - if (abs_ms >= MS_PER_HOUR) { - const hours = @round(ms / MS_PER_HOUR); + if (abs_ms >= std.time.ms_per_hour) { + const hours = @round(ms / std.time.ms_per_hour); const hours_int = @as(i64, @intFromFloat(hours)); if (long) { - const plural = abs_ms >= MS_PER_HOUR * 1.5; + const plural = abs_ms >= std.time.ms_per_hour * 1.5; return std.fmt.allocPrint(allocator, "{d} hour{s}", .{ hours_int, if (plural) "s" else "" }); } return std.fmt.allocPrint(allocator, "{d}h", .{hours_int}); } - if (abs_ms >= MS_PER_MINUTE) { - const minutes = @round(ms / MS_PER_MINUTE); + if (abs_ms >= std.time.ms_per_min) { + const minutes = @round(ms / std.time.ms_per_min); const minutes_int = @as(i64, @intFromFloat(minutes)); if (long) { - const plural = abs_ms >= MS_PER_MINUTE * 1.5; + const plural = abs_ms >= std.time.ms_per_min * 1.5; return std.fmt.allocPrint(allocator, "{d} minute{s}", .{ minutes_int, if (plural) "s" else "" }); } return std.fmt.allocPrint(allocator, "{d}m", .{minutes_int}); } - if (abs_ms >= MS_PER_SECOND) { - const seconds = @round(ms / MS_PER_SECOND); + if (abs_ms >= std.time.ms_per_s) { + const seconds = @round(ms / std.time.ms_per_s); const seconds_int = @as(i64, @intFromFloat(seconds)); if (long) { - const plural = abs_ms >= MS_PER_SECOND * 1.5; + const plural = abs_ms >= std.time.ms_per_s * 1.5; return std.fmt.allocPrint(allocator, "{d} second{s}", .{ seconds_int, if (plural) "s" else "" }); } return std.fmt.allocPrint(allocator, "{d}s", .{seconds_int}); diff --git a/test/js/bun/util/__snapshots__/ms-bundler.test.ts.snap b/test/js/bun/util/__snapshots__/ms-bundler.test.ts.snap deleted file mode 100644 index f5b46ff892..0000000000 --- a/test/js/bun/util/__snapshots__/ms-bundler.test.ts.snap +++ /dev/null @@ -1,24 +0,0 @@ -// Bun Snapshot v1, https://bun.sh/docs/test/snapshots - -exports[`Bun.ms bundler output 1`] = ` -"// entry.ts -var values = { - oneSecond: Bun.ms("1s"), - oneMinute: Bun.ms("1m"), - oneHour: Bun.ms("1h"), - oneDay: Bun.ms("1d"), - twoWeeks: Bun.ms("2w"), - halfYear: Bun.ms("0.5y"), - withSpaces: Bun.ms("5 minutes"), - negative: Bun.ms("-10s"), - decimal: Bun.ms("1.5h"), - justNumber: Bun.ms("100"), - caseInsensitive: Bun.ms("2D"), - formatShort: Bun.ms(1000), - formatLong: Bun.ms(60000, { long: true }) -}; -export { - values -}; -" -`; diff --git a/test/js/bun/util/ms-bundler.test.ts b/test/js/bun/util/ms-bundler.test.ts index b3dddf94a0..ae3d26eb8d 100644 --- a/test/js/bun/util/ms-bundler.test.ts +++ b/test/js/bun/util/ms-bundler.test.ts @@ -1,10 +1,9 @@ import { test, expect } from "bun:test"; import { bunEnv, bunExe, tempDirWithFiles } from "harness"; -import { readFileSync } from "fs"; import { join } from "path"; -// Test that Bun.ms bundler output is correct -// TODO: In the future, string literals like Bun.ms("2d") should be inlined to numbers at compile time +// Test that Bun.ms works in bundled output +// TODO: Implement compile-time inlining so Bun.ms("2d") becomes 172800000 test("Bun.ms bundler output", async () => { const dir = tempDirWithFiles("ms-bundler", { "entry.ts": ` @@ -26,19 +25,34 @@ export const values = { `, }); - // Bundle the code - const proc = Bun.spawn({ - cmd: [bunExe(), "build", "entry.ts", "--outfile", "out.js"], - cwd: dir, - env: bunEnv, - stderr: "inherit", - stdout: "inherit", + const result = await Bun.build({ + entrypoints: [join(dir, "entry.ts")], }); - const exitCode = await proc.exited; - expect(exitCode).toBe(0); + expect(result.success).toBe(true); + expect(result.outputs).toHaveLength(1); - // Read and snapshot the bundled output - const bundled = readFileSync(join(dir, "out.js"), "utf-8"); - expect(bundled).toMatchSnapshot(); + const output = await result.outputs[0].text(); + expect(output).toMatchInlineSnapshot(` + "// ../../tmp/ms-bundler_2IefkN/entry.ts + var values = { + oneSecond: Bun.ms("1s"), + oneMinute: Bun.ms("1m"), + oneHour: Bun.ms("1h"), + oneDay: Bun.ms("1d"), + twoWeeks: Bun.ms("2w"), + halfYear: Bun.ms("0.5y"), + withSpaces: Bun.ms("5 minutes"), + negative: Bun.ms("-10s"), + decimal: Bun.ms("1.5h"), + justNumber: Bun.ms("100"), + caseInsensitive: Bun.ms("2D"), + formatShort: Bun.ms(1000), + formatLong: Bun.ms(60000, { long: true }) + }; + export { + values + }; + " + `); });