refactor: zig 0.17.0 update and test coverage
This commit is contained in:
parent
ae1fb8a2fb
commit
e12c5ac8f3
14 changed files with 922 additions and 658 deletions
2
.github/workflows/cd.yml
vendored
2
.github/workflows/cd.yml
vendored
|
|
@ -60,7 +60,7 @@ jobs:
|
|||
- name: Setup Zig
|
||||
uses: mlugg/setup-zig@v2
|
||||
with:
|
||||
version: 0.17.0-dev.387+31f157d80
|
||||
version: 0.17.0-dev.639+284ab0ad8
|
||||
|
||||
- name: Setup Rust
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
|
|
|
|||
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
|
|
@ -22,7 +22,7 @@ jobs:
|
|||
- name: Setup Zig
|
||||
uses: mlugg/setup-zig@v2
|
||||
with:
|
||||
version: 0.17.0-dev.387+31f157d80
|
||||
version: 0.17.0-dev.639+284ab0ad8
|
||||
|
||||
- name: Build project
|
||||
run: zig build
|
||||
|
|
@ -55,7 +55,7 @@ jobs:
|
|||
- name: Setup Zig
|
||||
uses: mlugg/setup-zig@v2
|
||||
with:
|
||||
version: 0.17.0-dev.387+31f157d80
|
||||
version: 0.17.0-dev.639+284ab0ad8
|
||||
|
||||
- name: Download build artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ Temporalz provides Zig bindings to the Rust-based [temporal_rs](https://github.c
|
|||
|
||||
#### Prerequisites
|
||||
|
||||
- Zig 0.17.0-dev.387+31f157d80
|
||||
- Zig 0.17.0-dev.639+284ab0ad8
|
||||
- Rust toolchain (only required if [prebuilt staticlibs](#prebuilt) are not available for your platform)
|
||||
|
||||
#### Add as a Dependency
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ pub fn build(b: *std.Build) !void {
|
|||
b.fmt("-Dtarget={s}", .{try target.result.zigTriple(b.allocator)}),
|
||||
});
|
||||
run_cmd.setCwd(b.path("example"));
|
||||
if (b.args) |args| run_cmd.addArgs(args);
|
||||
run_cmd.addPassthruArgs();
|
||||
run_step.dependOn(&run_cmd.step);
|
||||
}
|
||||
|
||||
|
|
@ -89,7 +89,7 @@ pub fn build(b: *std.Build) !void {
|
|||
{
|
||||
const test262_step = b.step("test262", "Run test-262 tests");
|
||||
const run_cmd = b.addSystemCommand(&.{ "node", "test/test262/runner.mjs" });
|
||||
if (b.args) |args| run_cmd.addArgs(args);
|
||||
run_cmd.addPassthruArgs();
|
||||
run_cmd.step.dependOn(b.getInstallStep());
|
||||
test262_step.dependOn(&run_cmd.step);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
.name = .temporalz,
|
||||
.version = "0.2.0",
|
||||
.fingerprint = 0xd8d79d59acc4faae,
|
||||
.minimum_zig_version = "0.17.0-dev.387+31f157d80",
|
||||
.minimum_zig_version = "0.17.0-dev.639+284ab0ad8",
|
||||
.dependencies = .{
|
||||
.temporal = .{
|
||||
.path = "pkg/temporal",
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ pub fn build(b: *std.Build) void {
|
|||
else => {
|
||||
const run_cmd = b.addRunArtifact(exe);
|
||||
run_cmd.step.dependOn(b.getInstallStep());
|
||||
if (b.args) |args| run_cmd.addArgs(args);
|
||||
run_cmd.addPassthruArgs();
|
||||
run_step.dependOn(&run_cmd.step);
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
.name = .temporalz_example,
|
||||
.version = "0.1.2",
|
||||
.fingerprint = 0x686c9dfc777f9593,
|
||||
.minimum_zig_version = "0.17.0-dev.387+31f157d80",
|
||||
.minimum_zig_version = "0.17.0-dev.639+284ab0ad8",
|
||||
.dependencies = .{
|
||||
.temporalz = .{
|
||||
.path = "../",
|
||||
|
|
|
|||
|
|
@ -16,8 +16,11 @@ var instants: std.ArrayList(?Temporal.Instant) = .empty;
|
|||
var durations: std.ArrayList(?Temporal.Duration) = .empty;
|
||||
var plain_dates_init = false;
|
||||
var plain_dates: std.ArrayList(?Temporal.PlainDate) = .empty;
|
||||
var zdts_init = false;
|
||||
var zdts: std.ArrayList(?Temporal.ZonedDateTime) = .empty;
|
||||
|
||||
var last_error: ?[]u8 = null;
|
||||
var last_error_kind: u8 = 0; // 0=unknown,1=Generic,2=Type,3=Range,4=Syntax
|
||||
|
||||
fn ensureInstants() void {
|
||||
if (!instants_init) {
|
||||
|
|
@ -100,26 +103,98 @@ fn removePlainDate(handle: u32) void {
|
|||
}
|
||||
}
|
||||
|
||||
fn ensureZdts() void {
|
||||
if (!zdts_init) {
|
||||
zdts = .empty;
|
||||
zdts_init = true;
|
||||
}
|
||||
}
|
||||
|
||||
fn addZonedDateTime(zdt: Temporal.ZonedDateTime) u32 {
|
||||
ensureZdts();
|
||||
zdts.append(wasm_allocator, zdt) catch return 0;
|
||||
return @intCast(zdts.items.len);
|
||||
}
|
||||
|
||||
fn getZonedDateTime(handle: u32) !Temporal.ZonedDateTime {
|
||||
ensureZdts();
|
||||
if (handle == 0 or handle > zdts.items.len) return PolyfillError.InvalidHandle;
|
||||
return zdts.items[handle - 1] orelse PolyfillError.InvalidHandle;
|
||||
}
|
||||
|
||||
fn removeZonedDateTime(handle: u32) void {
|
||||
if (!zdts_init or handle == 0 or handle > zdts.items.len) return;
|
||||
if (zdts.items[handle - 1]) |zdt| {
|
||||
zdt.deinit();
|
||||
zdts.items[handle - 1] = null;
|
||||
}
|
||||
}
|
||||
|
||||
export fn temporalz_zoned_date_time_destroy(handle: u32) void {
|
||||
removeZonedDateTime(handle);
|
||||
}
|
||||
|
||||
export fn temporalz_zoned_date_time_epoch_nanoseconds_hi(handle: u32) i64 {
|
||||
clearLastError();
|
||||
const z = getZonedDateTime(handle) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
return unpackI128Hi(z.epochNanoseconds());
|
||||
}
|
||||
|
||||
export fn temporalz_zoned_date_time_epoch_nanoseconds_lo(handle: u32) u64 {
|
||||
clearLastError();
|
||||
const z = getZonedDateTime(handle) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
return unpackI128Lo(z.epochNanoseconds());
|
||||
}
|
||||
|
||||
fn clearLastError() void {
|
||||
if (last_error) |msg| {
|
||||
wasm_allocator.free(msg);
|
||||
last_error = null;
|
||||
}
|
||||
last_error_kind = 0;
|
||||
}
|
||||
|
||||
fn errorKind(err: anyerror) u8 {
|
||||
return switch (err) {
|
||||
error.TypeError => 2,
|
||||
error.RangeError => 3,
|
||||
error.SyntaxError => 4,
|
||||
error.InvalidHandle => 2,
|
||||
else => 1,
|
||||
};
|
||||
}
|
||||
|
||||
fn setLastError(err: anyerror) void {
|
||||
clearLastError();
|
||||
const msg = std.fmt.allocPrint(wasm_allocator, "{s}", .{@errorName(err)}) catch return;
|
||||
last_error = msg;
|
||||
last_error_kind = errorKind(err);
|
||||
}
|
||||
|
||||
fn setLastErrorMessage(msg: []const u8) void {
|
||||
fn setLastErrorRange(msg: []const u8) void {
|
||||
clearLastError();
|
||||
const owned = wasm_allocator.alloc(u8, msg.len) catch return;
|
||||
std.mem.copyForwards(u8, owned, msg);
|
||||
last_error = owned;
|
||||
last_error_kind = 3;
|
||||
}
|
||||
|
||||
fn setLastErrorType(msg: []const u8) void {
|
||||
clearLastError();
|
||||
const owned = wasm_allocator.alloc(u8, msg.len) catch return;
|
||||
std.mem.copyForwards(u8, owned, msg);
|
||||
last_error = owned;
|
||||
last_error_kind = 2;
|
||||
}
|
||||
|
||||
const setLastErrorMessage = setLastErrorRange;
|
||||
|
||||
fn packPtrLen(ptr: [*]u8, len: usize) u64 {
|
||||
const ptr_u32: u32 = @intCast(@intFromPtr(ptr));
|
||||
const len_u32: u32 = @intCast(len);
|
||||
|
|
@ -187,6 +262,10 @@ export fn temporalz_last_error_clear() void {
|
|||
clearLastError();
|
||||
}
|
||||
|
||||
export fn temporalz_last_error_kind() u8 {
|
||||
return last_error_kind;
|
||||
}
|
||||
|
||||
export fn temporalz_alloc(len: usize) usize {
|
||||
clearLastError();
|
||||
const buf = wasm_allocator.alloc(u8, len) catch |err| {
|
||||
|
|
@ -371,6 +450,145 @@ export fn temporalz_instant_round(
|
|||
return addInstant(res);
|
||||
}
|
||||
|
||||
export fn temporalz_instant_until(
|
||||
handle_a: u32,
|
||||
handle_b: u32,
|
||||
largest_unit: u8,
|
||||
smallest_unit: u8,
|
||||
rounding_mode: u8,
|
||||
rounding_increment: u32,
|
||||
) u32 {
|
||||
clearLastError();
|
||||
const a = getInstant(handle_a) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
const b = getInstant(handle_b) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
const settings = parseDifferenceSettings(largest_unit, smallest_unit, rounding_mode, rounding_increment) catch return 0;
|
||||
const res = a.until(b, settings) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
return addDuration(res);
|
||||
}
|
||||
|
||||
export fn temporalz_instant_since(
|
||||
handle_a: u32,
|
||||
handle_b: u32,
|
||||
largest_unit: u8,
|
||||
smallest_unit: u8,
|
||||
rounding_mode: u8,
|
||||
rounding_increment: u32,
|
||||
) u32 {
|
||||
clearLastError();
|
||||
const a = getInstant(handle_a) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
const b = getInstant(handle_b) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
const settings = parseDifferenceSettings(largest_unit, smallest_unit, rounding_mode, rounding_increment) catch return 0;
|
||||
const res = a.since(b, settings) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
return addDuration(res);
|
||||
}
|
||||
|
||||
fn parseDifferenceSettings(
|
||||
largest_unit: u8,
|
||||
smallest_unit: u8,
|
||||
rounding_mode: u8,
|
||||
rounding_increment: u32,
|
||||
) !Temporal.Instant.DifferenceSettings {
|
||||
var settings = Temporal.Instant.DifferenceSettings{};
|
||||
if (largest_unit != 255) {
|
||||
settings.largest_unit = unitFromCode(largest_unit) orelse {
|
||||
setLastErrorRange("Invalid largestUnit");
|
||||
return error.RangeError;
|
||||
};
|
||||
}
|
||||
if (smallest_unit != 255) {
|
||||
settings.smallest_unit = unitFromCode(smallest_unit) orelse {
|
||||
setLastErrorRange("Invalid smallestUnit");
|
||||
return error.RangeError;
|
||||
};
|
||||
}
|
||||
if (rounding_mode != 255) {
|
||||
settings.rounding_mode = roundingModeFromCode(rounding_mode) orelse {
|
||||
setLastErrorRange("Invalid roundingMode");
|
||||
return error.RangeError;
|
||||
};
|
||||
}
|
||||
if (rounding_increment != 0) settings.rounding_increment = rounding_increment;
|
||||
return settings;
|
||||
}
|
||||
|
||||
export fn temporalz_instant_to_zoned_date_time_iso(handle: u32, tz_ptr: [*]const u8, tz_len: usize) u32 {
|
||||
clearLastError();
|
||||
const inst = getInstant(handle) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
const tz_id = tz_ptr[0..tz_len];
|
||||
const tz = Temporal.Instant.TimeZone.init(tz_id) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
const zdt = inst.toZonedDateTimeISO(tz) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
return addZonedDateTime(zdt);
|
||||
}
|
||||
|
||||
export fn temporalz_instant_to_string_with(
|
||||
handle: u32,
|
||||
smallest_unit: u8,
|
||||
rounding_mode: u8,
|
||||
fractional_digits: i16,
|
||||
tz_ptr: [*]const u8,
|
||||
tz_len: usize,
|
||||
) u64 {
|
||||
clearLastError();
|
||||
const inst = getInstant(handle) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
var opts = Temporal.Instant.ToStringOptions{};
|
||||
if (smallest_unit != 255) {
|
||||
opts.smallest_unit = unitFromCode(smallest_unit) orelse {
|
||||
setLastErrorRange("Invalid smallestUnit");
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
if (rounding_mode != 255) {
|
||||
opts.rounding_mode = roundingModeFromCode(rounding_mode) orelse {
|
||||
setLastErrorRange("Invalid roundingMode");
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
if (fractional_digits >= 0) opts.fractional_second_digits = @intCast(fractional_digits);
|
||||
if (tz_len > 0) {
|
||||
const tz_id = tz_ptr[0..tz_len];
|
||||
const tz = Temporal.Instant.TimeZone.init(tz_id) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
opts.time_zone = tz;
|
||||
}
|
||||
const text = inst.toString(wasm_allocator, opts) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
return packPtrLen(text.ptr, text.len);
|
||||
}
|
||||
|
||||
export fn temporalz_instant_destroy(handle: u32) void {
|
||||
removeInstant(handle);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ pub fn build(b: *std.Build) !void {
|
|||
const libtemporal_dep = b.lazyDependency("libtemporal", .{});
|
||||
if (libtemporal_dep) |dep| {
|
||||
const lib_file_candidate = dep.path(prebuilt_lib_path);
|
||||
const lib_full_path = lib_file_candidate.getPath(b);
|
||||
const lib_full_path = b.fmt("{f}", .{lib_file_candidate});
|
||||
if (std.Io.Dir.cwd().openFile(b.graph.io, lib_full_path, .{})) |lib_check_file| {
|
||||
lib_check_file.close(b.graph.io);
|
||||
prebuilt_lib_file = lib_file_candidate;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
.name = .temporal,
|
||||
.version = "0.2.0",
|
||||
.fingerprint = 0xd5dcf3f41df6b117,
|
||||
.minimum_zig_version = "0.17.0-dev.387+31f157d80",
|
||||
.minimum_zig_version = "0.17.0-dev.639+284ab0ad8",
|
||||
.dependencies = .{
|
||||
.temporal_rs = .{
|
||||
.url = "git+https://github.com/boa-dev/temporal?ref=v0.2.3#c003cc92325e19b26f8ee2f85e4a47d98cbcc781",
|
||||
|
|
@ -14,8 +14,8 @@
|
|||
.lazy = true,
|
||||
},
|
||||
.build_crab = .{
|
||||
.url = "git+https://github.com/nurulhudaapon/build.crab?ref=zig-dev#48706bf535be39c87df6aeafcc14b946d174bb50",
|
||||
.hash = "build_crab-0.2.1-U0id_ybJAABQczZZ4_zdQnkJuZF9WLQoHkkrY5TTq4bR",
|
||||
.url = "git+https://github.com/nurulhudaapon/build.crab?ref=zig-dev#fd666880b60cd9b209459a6966689113978aaf03",
|
||||
.hash = "build_crab-0.2.1-U0id_xnKAACLofQELmEzeT_mjjbHeCs9SfEoSg6nBBGC",
|
||||
},
|
||||
},
|
||||
.paths = .{
|
||||
|
|
|
|||
|
|
@ -667,7 +667,6 @@ test nanoseconds {
|
|||
const ns = dur.nanoseconds();
|
||||
try std.testing.expect(ns > 499 and ns < 501);
|
||||
}
|
||||
|
||||
test sign {
|
||||
const pos = try Duration.from("P1Y");
|
||||
defer pos.deinit();
|
||||
|
|
|
|||
|
|
@ -100,13 +100,13 @@ pub fn main(init: std.process.Init) !void {
|
|||
|
||||
while (attempt < max_attempts) : (attempt += 1) {
|
||||
current_test = friendly_name;
|
||||
std.testing.allocator_instance = .{};
|
||||
std.testing.allocator_instance = .init(std.heap.page_allocator, .{});
|
||||
final_result = t.func();
|
||||
current_test = null;
|
||||
|
||||
final_ns_taken = slowest.endTiming(allocator, scope_name, friendly_name);
|
||||
|
||||
if (std.testing.allocator_instance.deinit() == .leak) {
|
||||
if (std.testing.allocator_instance.deinit() > 0) {
|
||||
leak += 1;
|
||||
Printer.status(.fail, "\n{s}\n\"{s}\" - Memory Leak\n{s}\n", .{ BORDER, friendly_name, BORDER });
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -14,6 +14,22 @@ const wasmBytes = fs.readFileSync(wasmPath);
|
|||
const polyfillPath = path.resolve(__dirname, "../test262/polyfill.js");
|
||||
let polyfillCode = fs.readFileSync(polyfillPath, "utf-8");
|
||||
|
||||
const EXCLUDE_TESTS = [
|
||||
// JS surface-shape tests are intentionally out of scope for this thin polyfill.
|
||||
"(?:^|/)(?:builtin|name|not-a-constructor|prop-desc)\\.js$",
|
||||
"/toStringTag/",
|
||||
|
||||
// These rely on PlainDate/PlainDateTime/PlainTime objects that are not wired yet.
|
||||
"^built-ins/Temporal/Now/plainDateISO/",
|
||||
"^built-ins/Temporal/Now/plainDateTimeISO/",
|
||||
"^built-ins/Temporal/Now/plainTimeISO/",
|
||||
"^built-ins/Temporal/Now/zonedDateTimeISO/",
|
||||
"^intl402/Temporal/Now/plainDateISO/",
|
||||
"^intl402/Temporal/Now/plainDateTimeISO/",
|
||||
"^intl402/Temporal/Now/plainTimeISO/",
|
||||
"^intl402/Temporal/Now/zonedDateTimeISO/",
|
||||
];
|
||||
|
||||
const bytesArray = JSON.stringify(Array.from(wasmBytes));
|
||||
// TextEncoder/TextDecoder need to be manually constructed and passed via context
|
||||
// Since we can't serialize them, we inject polyfill-compatible shim versions
|
||||
|
|
@ -28,6 +44,7 @@ const result = runTest262({
|
|||
test262Dir: "test/temporal-test262-runner/test262",
|
||||
polyfillCodeFile: tempPolyfillPath,
|
||||
testGlobs: process.argv.slice(2),
|
||||
excludeTests: EXCLUDE_TESTS,
|
||||
});
|
||||
|
||||
fs.unlinkSync(tempPolyfillPath);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue