From df2634b1c283678db43a75fedd0fabdf5ab1169b Mon Sep 17 00:00:00 2001 From: richerfu Date: Thu, 7 May 2026 10:17:33 +0800 Subject: [PATCH 1/3] Add lint & format code --- examples/allocator-builtin/index.d.ts | 10 +- examples/allocator-custom/index.d.ts | 21 +- examples/basic/index.d.ts | 292 +++++++++++++++----------- examples/init/index.d.ts | 26 +-- justfile | 32 +++ memory-testing/assert.ts | 6 +- memory-testing/async.ts | 36 +++- memory-testing/binary.ts | 78 +++++-- memory-testing/finalizers.ts | 7 +- memory-testing/native.ts | 11 +- memory-testing/sync.ts | 40 +++- prek.toml | 15 ++ test/assert.ts | 19 +- test/async.spec.ts | 36 +++- test/binary.spec.ts | 12 +- test/errors-tsfn.spec.ts | 6 +- test/functions-classes.spec.ts | 24 ++- test/init.ts | 6 +- test/objects-arrays.spec.ts | 12 +- test/unions-enums.spec.ts | 77 +++++-- 20 files changed, 547 insertions(+), 219 deletions(-) create mode 100644 justfile create mode 100644 prek.toml diff --git a/examples/allocator-builtin/index.d.ts b/examples/allocator-builtin/index.d.ts index 1d4988f..bc8d017 100644 --- a/examples/allocator-builtin/index.d.ts +++ b/examples/allocator-builtin/index.d.ts @@ -1,7 +1,7 @@ /* auto-generated by zig-addon */ /* eslint-disable */ -export declare function allocator_kind(): string -export declare function manual_allocation_roundtrip(len: number): boolean -export declare function make_js_owned_buffer(len: number): Buffer -export declare function make_copied_buffer(): Buffer -export declare function input_sum(input: Buffer): number +export declare function allocator_kind(): string; +export declare function manual_allocation_roundtrip(len: number): boolean; +export declare function make_js_owned_buffer(len: number): Buffer; +export declare function make_copied_buffer(): Buffer; +export declare function input_sum(input: Buffer): number; diff --git a/examples/allocator-custom/index.d.ts b/examples/allocator-custom/index.d.ts index cd609cd..502ae1b 100644 --- a/examples/allocator-custom/index.d.ts +++ b/examples/allocator-custom/index.d.ts @@ -2,16 +2,15 @@ /* eslint-disable */ export interface Stats { - alloc_calls: number - free_calls: number - active_allocations: number - active_bytes: number + alloc_calls: number; + free_calls: number; + active_allocations: number; + active_bytes: number; } - -export declare function allocator_kind(): string -export declare function allocator_stats(): Stats -export declare function custom_allocation_roundtrip(len: number): boolean -export declare function make_js_owned_buffer(len: number): Buffer -export declare function make_copied_buffer(): Buffer -export declare function input_sum(input: Buffer): number +export declare function allocator_kind(): string; +export declare function allocator_stats(): Stats; +export declare function custom_allocation_roundtrip(len: number): boolean; +export declare function make_js_owned_buffer(len: number): Buffer; +export declare function make_copied_buffer(): Buffer; +export declare function input_sum(input: Buffer): number; diff --git a/examples/basic/index.d.ts b/examples/basic/index.d.ts index c9bbb22..9d90764 100644 --- a/examples/basic/index.d.ts +++ b/examples/basic/index.d.ts @@ -2,102 +2,102 @@ /* eslint-disable */ export interface FibProgress { - current: number - total: number + current: number; + total: number; } export interface FileReadSummary { - path: string - bytes: number - text: string + path: string; + bytes: number; + text: string; } export interface ParallelReadInput { - first_path: string - second_path: string - preview_bytes: number + first_path: string; + second_path: string; + preview_bytes: number; } export interface ParallelReadSummary { - first_bytes: number - second_bytes: number - total_bytes: number - preview: string + first_bytes: number; + second_bytes: number; + total_bytes: number; + preview: string; } export interface AsyncMathInput { - left: number - right: number - scale: number + left: number; + right: number; + scale: number; } export interface AsyncMathResult { - sum: number - product: number - scaled_sum: number + sum: number; + product: number; + scaled_sum: number; } export interface CountProgress { - current: number - total: number + current: number; + total: number; } export interface AbortSignal { - aborted: boolean - reason?: any - onabort: null | ((this: AbortSignal, event: any) => void) - addEventListener(name: string, listener: (this: AbortSignal, event: any) => any): void - removeEventListener(name: string, listener: (this: AbortSignal, event: any) => any): void - throwIfAborted?(): void + aborted: boolean; + reason?: any; + onabort: null | ((this: AbortSignal, event: any) => void); + addEventListener(name: string, listener: (this: AbortSignal, event: any) => any): void; + removeEventListener(name: string, listener: (this: AbortSignal, event: any) => any): void; + throwIfAborted?(): void; } export interface FullField { - name: string - age: number - is_student: boolean + name: string; + age: number; + is_student: boolean; } export interface OptionalField { - name: string - age?: number - is_student?: boolean + name: string; + age?: number; + is_student?: boolean; } export interface NullableField { - name?: string + name?: string; } export declare class TestClass { - constructor(name: string, age: number) - name: string - age: number + constructor(name: string, age: number); + name: string; + age: number; } export declare class TestWithInitClass { - constructor(age: number, name: string) - name: string - age: number - static readonly hello: string + constructor(age: number, name: string); + name: string; + age: number; + static readonly hello: string; } export declare class TestWithoutInitClass { - private constructor() - name: string - age: number - static readonly hello: string + private constructor(); + name: string; + age: number; + static readonly hello: string; } export declare class TestFactoryClass { - constructor(name: string, age: number) - name: string - age: number - static initWithFactory(age: number, name: string): TestFactoryClass - format(): string + constructor(name: string, age: number); + name: string; + age: number; + static initWithFactory(age: number, name: string): TestFactoryClass; + format(): string; } export interface MessagePayload { - title: string - count: number + title: string; + count: number; } export declare const enum Color { @@ -107,79 +107,117 @@ export declare const enum Color { } export declare const enum StringColor { - Red = 'Red', - Green = 'Green', - Blue = 'Blue', -} - - -export declare function test_i32(left: number, right: number): number -export declare function test_f32(left: number, right: number): number -export declare function test_u32(left: number, right: number): number -export declare function hello(name: string): string -export declare const text: string -export declare function throw_error(): void -export declare function fib(n: number): void -export declare function fib_async(n: number): Promise -export declare function fib_async_progress(n: number, onEvent?: (event: FibProgress) => void): Promise -export declare function read_file_async(path: string): Promise -export declare function read_file_summary_async(path: string): Promise -export declare function parallel_read_files_async(input: ParallelReadInput): Promise -export declare function async_math_single(input: AsyncMathInput): Promise -export declare function async_void_thread(): Promise -export declare function async_fail_thread(message: string): Promise -export declare function count_async_progress_thread(total: number, onEvent?: (event: CountProgress) => void): Promise -export declare function event_mode_progress_async(total: number, onEvent?: (event: CountProgress) => void): Promise -export declare function abortable_count_async(total: number, signal: AbortSignal): Promise -export declare function get_and_return_array(array: Array): Array -export declare function get_named_array(array: [number, boolean, string]): [number, boolean, string] -export declare function get_arraylist(array: Array): Array -export declare function get_object(config: FullField): FullField -export declare function get_object_optional(config: OptionalField): OptionalField -export declare function get_optional_object_and_return_optional(config: OptionalField): OptionalField -export declare function get_nullable_object(config: NullableField): NullableField -export declare function return_nullable(): NullableField -export declare function call_function(cb: (arg0: number, arg1: number) => number): number -export declare function basic_function(left: number, right: number): number -export declare function create_function(): (left: number, right: number) => number -export declare function call_function_with_reference(cb: (arg0: number, arg1: number) => number): number -export declare function call_thread_safe_function(tsfn: (err: Error | null, arg0: number, arg1: number) => void): void -export declare function test_hilog(): void -export declare function create_buffer(): Buffer -export declare function get_buffer(buf: Buffer): number -export declare function get_buffer_as_string(buf: Buffer): string -export declare function create_arraybuffer(): ArrayBuffer -export declare function get_arraybuffer(buf: ArrayBuffer): number -export declare function get_arraybuffer_as_string(buf: ArrayBuffer): string -export declare function create_uint8_typedarray(): Uint8Array -export declare function get_uint8_typedarray_length(array: Uint8Array): number -export declare function sum_float32_typedarray(array: Float32Array): number -export declare function create_dataview(): DataView -export declare function get_dataview_length(view: DataView): number -export declare function get_dataview_first_byte(view: DataView): number -export declare function get_dataview_uint32_le(view: DataView): number -export declare function union_identity(value: number | string): number | string -export declare function make_union(is_number: boolean): number | string -export declare function union_kind(value: number | string): string -export declare function object_or_text_identity(value: MessagePayload | string): MessagePayload | string -export declare function make_object_or_text(as_object: boolean): MessagePayload | string -export declare function object_or_array_identity(value: MessagePayload | Array): MessagePayload | Array -export declare function tuple_or_text_identity(value: [number, boolean, string] | string): [number, boolean, string] | string -export declare function flip_flag_or_increment(value: boolean | number): boolean | number -export declare function color_or_text_identity(value: Color | string): Color | string -export declare function favorite_color_or_text(use_color: boolean): Color | string -export declare function maybe_text_or_count_identity(value: string | undefined | null | number): string | undefined | null | number -export declare function make_maybe_text_or_count(as_text: boolean): string | undefined | null | number -export declare function buffer_or_text_identity(value: Buffer | string): Buffer | string -export declare function make_buffer_or_text(use_buffer: boolean): Buffer | string -export declare function arraybuffer_or_array_identity(value: ArrayBuffer | Array): ArrayBuffer | Array -export declare function make_arraybuffer_or_array(use_arraybuffer: boolean): ArrayBuffer | Array -export declare function payload_or_color_identity(value: MessagePayload | Color): MessagePayload | Color -export declare function make_payload_or_color(use_payload: boolean): MessagePayload | Color -export declare function payload_or_string_color_identity(value: MessagePayload | StringColor): MessagePayload | StringColor -export declare function make_payload_or_string_color(use_payload: boolean): MessagePayload | StringColor -export declare function enum_identity(color: Color): Color -export declare function favorite_color(): Color -export declare function is_primary(color: Color): boolean -export declare function string_enum_identity(color: StringColor): StringColor -export declare function favorite_string_color(): StringColor + Red = "Red", + Green = "Green", + Blue = "Blue", +} + +export declare function test_i32(left: number, right: number): number; +export declare function test_f32(left: number, right: number): number; +export declare function test_u32(left: number, right: number): number; +export declare function hello(name: string): string; +export declare const text: string; +export declare function throw_error(): void; +export declare function fib(n: number): void; +export declare function fib_async(n: number): Promise; +export declare function fib_async_progress( + n: number, + onEvent?: (event: FibProgress) => void, +): Promise; +export declare function read_file_async(path: string): Promise; +export declare function read_file_summary_async(path: string): Promise; +export declare function parallel_read_files_async( + input: ParallelReadInput, +): Promise; +export declare function async_math_single(input: AsyncMathInput): Promise; +export declare function async_void_thread(): Promise; +export declare function async_fail_thread(message: string): Promise; +export declare function count_async_progress_thread( + total: number, + onEvent?: (event: CountProgress) => void, +): Promise; +export declare function event_mode_progress_async( + total: number, + onEvent?: (event: CountProgress) => void, +): Promise; +export declare function abortable_count_async(total: number, signal: AbortSignal): Promise; +export declare function get_and_return_array(array: Array): Array; +export declare function get_named_array( + array: [number, boolean, string], +): [number, boolean, string]; +export declare function get_arraylist(array: Array): Array; +export declare function get_object(config: FullField): FullField; +export declare function get_object_optional(config: OptionalField): OptionalField; +export declare function get_optional_object_and_return_optional( + config: OptionalField, +): OptionalField; +export declare function get_nullable_object(config: NullableField): NullableField; +export declare function return_nullable(): NullableField; +export declare function call_function(cb: (arg0: number, arg1: number) => number): number; +export declare function basic_function(left: number, right: number): number; +export declare function create_function(): (left: number, right: number) => number; +export declare function call_function_with_reference( + cb: (arg0: number, arg1: number) => number, +): number; +export declare function call_thread_safe_function( + tsfn: (err: Error | null, arg0: number, arg1: number) => void, +): void; +export declare function test_hilog(): void; +export declare function create_buffer(): Buffer; +export declare function get_buffer(buf: Buffer): number; +export declare function get_buffer_as_string(buf: Buffer): string; +export declare function create_arraybuffer(): ArrayBuffer; +export declare function get_arraybuffer(buf: ArrayBuffer): number; +export declare function get_arraybuffer_as_string(buf: ArrayBuffer): string; +export declare function create_uint8_typedarray(): Uint8Array; +export declare function get_uint8_typedarray_length(array: Uint8Array): number; +export declare function sum_float32_typedarray(array: Float32Array): number; +export declare function create_dataview(): DataView; +export declare function get_dataview_length(view: DataView): number; +export declare function get_dataview_first_byte(view: DataView): number; +export declare function get_dataview_uint32_le(view: DataView): number; +export declare function union_identity(value: number | string): number | string; +export declare function make_union(is_number: boolean): number | string; +export declare function union_kind(value: number | string): string; +export declare function object_or_text_identity( + value: MessagePayload | string, +): MessagePayload | string; +export declare function make_object_or_text(as_object: boolean): MessagePayload | string; +export declare function object_or_array_identity( + value: MessagePayload | Array, +): MessagePayload | Array; +export declare function tuple_or_text_identity( + value: [number, boolean, string] | string, +): [number, boolean, string] | string; +export declare function flip_flag_or_increment(value: boolean | number): boolean | number; +export declare function color_or_text_identity(value: Color | string): Color | string; +export declare function favorite_color_or_text(use_color: boolean): Color | string; +export declare function maybe_text_or_count_identity( + value: string | undefined | null | number, +): string | undefined | null | number; +export declare function make_maybe_text_or_count( + as_text: boolean, +): string | undefined | null | number; +export declare function buffer_or_text_identity(value: Buffer | string): Buffer | string; +export declare function make_buffer_or_text(use_buffer: boolean): Buffer | string; +export declare function arraybuffer_or_array_identity( + value: ArrayBuffer | Array, +): ArrayBuffer | Array; +export declare function make_arraybuffer_or_array( + use_arraybuffer: boolean, +): ArrayBuffer | Array; +export declare function payload_or_color_identity( + value: MessagePayload | Color, +): MessagePayload | Color; +export declare function make_payload_or_color(use_payload: boolean): MessagePayload | Color; +export declare function payload_or_string_color_identity( + value: MessagePayload | StringColor, +): MessagePayload | StringColor; +export declare function make_payload_or_string_color( + use_payload: boolean, +): MessagePayload | StringColor; +export declare function enum_identity(color: Color): Color; +export declare function favorite_color(): Color; +export declare function is_primary(color: Color): boolean; +export declare function string_enum_identity(color: StringColor): StringColor; +export declare function favorite_string_color(): StringColor; diff --git a/examples/init/index.d.ts b/examples/init/index.d.ts index 0ed5ba8..1d7fe65 100644 --- a/examples/init/index.d.ts +++ b/examples/init/index.d.ts @@ -1,14 +1,16 @@ /* auto-generated by zig-addon */ /* eslint-disable */ -export declare function test_i32(left: number, right: number): number -export declare function test_f32(left: number, right: number): number -export declare function test_u32(left: number, right: number): number -export declare function add(left: number, right: number): number -export declare function hello(name: string): string -export declare const text: string -export declare function fib(n: number): void -export declare function fib_async(n: number): Promise -export declare function get_and_return_array(array: Array): Array -export declare function get_named_array(array: [number, boolean, string]): [number, boolean, string] -export declare function get_arraylist(array: Array): Array -export declare function throw_error(): void +export declare function test_i32(left: number, right: number): number; +export declare function test_f32(left: number, right: number): number; +export declare function test_u32(left: number, right: number): number; +export declare function add(left: number, right: number): number; +export declare function hello(name: string): string; +export declare const text: string; +export declare function fib(n: number): void; +export declare function fib_async(n: number): Promise; +export declare function get_and_return_array(array: Array): Array; +export declare function get_named_array( + array: [number, boolean, string], +): [number, boolean, string]; +export declare function get_arraylist(array: Array): Array; +export declare function throw_error(): void; diff --git a/justfile b/justfile new file mode 100644 index 0000000..34edbfd --- /dev/null +++ b/justfile @@ -0,0 +1,32 @@ +set shell := ["bash", "-euo", "pipefail", "-c"] + +default: + @just --list + +init: + npm install --global @ohos-rs/oxk @j178/prek + prek validate-config prek.toml + prek install --config prek.toml --hook-type pre-commit --prepare-hooks --overwrite + +build-example: + #!/usr/bin/env bash + set -euo pipefail + + targets=( + aarch64-linux-ohos + arm-linux-ohoseabi + x86_64-linux-ohos + ) + + for example in examples/*; do + [[ -f "$example/build.zig" ]] || continue + + for target in "${targets[@]}"; do + echo "==> $example ($target)" + (cd "$example" && zig build -Dtarget="$target") + done + done + +format: + zig fmt $(git ls-files '*.zig' '*.zon') + oxk format $(git ls-files '*.js' '*.jsx' '*.ts' '*.tsx' '*.ets') diff --git a/memory-testing/assert.ts b/memory-testing/assert.ts index 27342ec..8173238 100644 --- a/memory-testing/assert.ts +++ b/memory-testing/assert.ts @@ -14,7 +14,11 @@ export function assertEqual(actual: ESObject, expected: ESObject, message: strin } } -export function assertArrayEqual(actual: Array, expected: Array, message: string) { +export function assertArrayEqual( + actual: Array, + expected: Array, + message: string, +) { assertEqual(actual.length, expected.length, `${message}.length`); for (let i = 0; i < expected.length; i++) { assertEqual(actual[i], expected[i], `${message}[${i}]`); diff --git a/memory-testing/async.ts b/memory-testing/async.ts index e1bd475..dfa6a56 100644 --- a/memory-testing/async.ts +++ b/memory-testing/async.ts @@ -84,18 +84,42 @@ export async function exerciseAsyncWrappers(native: NativeAddon) { assertEqual(singleSummary.total, 10, "async single total"); await native.memory_async_void("async-void"); - await assertRejects(native.memory_async_fail("async memory failure"), "async memory failure", "async fail"); + await assertRejects( + native.memory_async_fail("async memory failure"), + "async memory failure", + "async fail", + ); assertEqual(await native.manual_resolved_promise(), 42, "manual promise wrapper"); const progressEvents: Array = []; - assertEqual(await native.memory_async_progress(3, (event: ESObject) => progressEvents.push(event)), 3, "async progress result"); - assertArrayEqual(progressEvents.map((event: ESObject) => event.current), [0, 1, 2, 3], "async progress events"); + assertEqual( + await native.memory_async_progress(3, (event: ESObject) => progressEvents.push(event)), + 3, + "async progress result", + ); + assertArrayEqual( + progressEvents.map((event: ESObject) => event.current), + [0, 1, 2, 3], + "async progress events", + ); const eventModeEvents: Array = []; - assertEqual(await native.memory_event_mode_progress(2, (event: ESObject) => eventModeEvents.push(event)), 2, "event progress result"); - assertArrayEqual(eventModeEvents.map((event: ESObject) => event.current), [0, 1, 2], "event progress events"); + assertEqual( + await native.memory_event_mode_progress(2, (event: ESObject) => eventModeEvents.push(event)), + 2, + "event progress result", + ); + assertArrayEqual( + eventModeEvents.map((event: ESObject) => event.current), + [0, 1, 2], + "event progress events", + ); - await assertRejects(native.memory_abortable_count(1024, abortController(true).signal), "AbortError", "abort pre-cancel"); + await assertRejects( + native.memory_abortable_count(1024, abortController(true).signal), + "AbortError", + "abort pre-cancel", + ); const controller = abortController(false); const pending = native.memory_abortable_slow_count(100000, controller.signal); diff --git a/memory-testing/binary.ts b/memory-testing/binary.ts index 0bff81c..63dc884 100644 --- a/memory-testing/binary.ts +++ b/memory-testing/binary.ts @@ -18,27 +18,79 @@ export function exerciseBinaryWrappers(native: NativeAddon) { const newArrayBufferValue = native.create_arraybuffer_new(32); assertEqual(native.arraybuffer_length(newArrayBufferValue), 32, "arraybuffer new length"); - assertEqual(native.arraybuffer_first_byte(newArrayBufferValue), 0x6b, "arraybuffer new first byte"); + assertEqual( + native.arraybuffer_first_byte(newArrayBufferValue), + 0x6b, + "arraybuffer new first byte", + ); const typedArrayValue = native.create_uint8_typedarray_copy(); assertEqual(native.typedarray_sum(typedArrayValue), 10, "typedarray created sum"); assertEqual(native.typedarray_sum(new Uint8Array([1, 2, 3, 4])), 10, "typedarray input sum"); - assertEqual(native.int16_typedarray_sum(native.create_int16_typedarray_copy()), 4, "int16 typedarray created sum"); - assertEqual(native.int16_typedarray_sum(new Int16Array([-1, 2, 3])), 4, "int16 typedarray input sum"); - assertEqual(native.uint16_typedarray_sum(native.create_uint16_typedarray_copy()), 15, "uint16 typedarray created sum"); - assertEqual(native.uint16_typedarray_sum(new Uint16Array([4, 5, 6])), 15, "uint16 typedarray input sum"); - assertEqual(native.int32_typedarray_sum(native.create_int32_typedarray_copy()), 10, "int32 typedarray created sum"); - assertEqual(native.int32_typedarray_sum(new Int32Array([-7, 8, 9])), 10, "int32 typedarray input sum"); - assertEqual(native.uint32_typedarray_sum(native.create_uint32_typedarray_copy()), 33, "uint32 typedarray created sum"); - assertEqual(native.uint32_typedarray_sum(new Uint32Array([10, 11, 12])), 33, "uint32 typedarray input sum"); - assertEqual(native.float32_typedarray_sum(new Float32Array([1.5, 2.5, -1])), 3, "float32 typedarray input sum"); - assertEqual(native.float64_typedarray_sum(native.create_float64_typedarray_copy()), 3, "float64 typedarray created sum"); - assertEqual(native.float64_typedarray_sum(new Float64Array([1.5, 2.25, -0.75])), 3, "float64 typedarray input sum"); + assertEqual( + native.int16_typedarray_sum(native.create_int16_typedarray_copy()), + 4, + "int16 typedarray created sum", + ); + assertEqual( + native.int16_typedarray_sum(new Int16Array([-1, 2, 3])), + 4, + "int16 typedarray input sum", + ); + assertEqual( + native.uint16_typedarray_sum(native.create_uint16_typedarray_copy()), + 15, + "uint16 typedarray created sum", + ); + assertEqual( + native.uint16_typedarray_sum(new Uint16Array([4, 5, 6])), + 15, + "uint16 typedarray input sum", + ); + assertEqual( + native.int32_typedarray_sum(native.create_int32_typedarray_copy()), + 10, + "int32 typedarray created sum", + ); + assertEqual( + native.int32_typedarray_sum(new Int32Array([-7, 8, 9])), + 10, + "int32 typedarray input sum", + ); + assertEqual( + native.uint32_typedarray_sum(native.create_uint32_typedarray_copy()), + 33, + "uint32 typedarray created sum", + ); + assertEqual( + native.uint32_typedarray_sum(new Uint32Array([10, 11, 12])), + 33, + "uint32 typedarray input sum", + ); + assertEqual( + native.float32_typedarray_sum(new Float32Array([1.5, 2.5, -1])), + 3, + "float32 typedarray input sum", + ); + assertEqual( + native.float64_typedarray_sum(native.create_float64_typedarray_copy()), + 3, + "float64 typedarray created sum", + ); + assertEqual( + native.float64_typedarray_sum(new Float64Array([1.5, 2.25, -0.75])), + 3, + "float64 typedarray input sum", + ); const dataViewValue = native.create_dataview_copy(); assertEqual(native.dataview_length(dataViewValue), 4, "dataview copy length"); assertEqual(native.dataview_uint32_le(dataViewValue), 0x12345678, "dataview copy uint32"); - assertEqual(native.dataview_uint32_le(new DataView(new Uint8Array([0x78, 0x56, 0x34, 0x12]).buffer)), 0x12345678, "dataview input uint32"); + assertEqual( + native.dataview_uint32_le(new DataView(new Uint8Array([0x78, 0x56, 0x34, 0x12]).buffer)), + 0x12345678, + "dataview input uint32", + ); const newDataViewValue = native.create_dataview_new(8); assertEqual(native.dataview_length(newDataViewValue), 8, "dataview new length"); diff --git a/memory-testing/finalizers.ts b/memory-testing/finalizers.ts index 2b5f096..673a8cc 100644 --- a/memory-testing/finalizers.ts +++ b/memory-testing/finalizers.ts @@ -31,7 +31,12 @@ export function exerciseFinalizerWrappers(native: NativeAddon) { assertEqual(withoutInit.total(), 0, "class without init method"); withoutInit = null; - let factoryClass: ESObject | null = native.MemoryFactoryClass.initWithFactory(`factory-${i}`, [1, 2, 3, i]); + let factoryClass: ESObject | null = native.MemoryFactoryClass.initWithFactory(`factory-${i}`, [ + 1, + 2, + 3, + i, + ]); assertEqual(factoryClass.name, `factory-${i}`, "factory class name"); assertEqual(factoryClass.total(), i + 6, "factory class method"); factoryClass = null; diff --git a/memory-testing/native.ts b/memory-testing/native.ts index 26bbbfc..10efec6 100644 --- a/memory-testing/native.ts +++ b/memory-testing/native.ts @@ -61,7 +61,11 @@ export async function settleFinalizers(rounds = 8) { } } -export async function withLeakTracking(native: NativeAddon, label: string, run: () => Promise | void) { +export async function withLeakTracking( + native: NativeAddon, + label: string, + run: () => Promise | void, +) { let tracking = false; native.leak_tracker_start(); tracking = true; @@ -85,7 +89,10 @@ function failResult(resultPrefix: string, err: ESObject): never { throw err; } -export function runMemorySuite(resultPrefix: string, run: (native: NativeAddon) => Promise | void) { +export function runMemorySuite( + resultPrefix: string, + run: (native: NativeAddon) => Promise | void, +) { installTimerGlobals(); let finished = false; diff --git a/memory-testing/sync.ts b/memory-testing/sync.ts index d1620ff..11ec00d 100644 --- a/memory-testing/sync.ts +++ b/memory-testing/sync.ts @@ -24,24 +24,44 @@ export function exerciseSyncWrappers(native: NativeAddon) { assertEqual(native.nullable_name_is_null(null), true, "nullable null"); assertEqual(native.nullable_name_is_null(`nullable-${suffix}`), false, "nullable string"); - assertArrayEqual(native.get_named_array([i, i % 2 === 0, `tuple-${suffix}`]), [i, i % 2 === 0, `tuple-${suffix}`], "tuple roundtrip"); + assertArrayEqual( + native.get_named_array([i, i % 2 === 0, `tuple-${suffix}`]), + [i, i % 2 === 0, `tuple-${suffix}`], + "tuple roundtrip", + ); assertEqual(native.array_sum([1, 2, 3, i]), i + 6, "array sum"); assertEqual(native.arraylist_sum([1, 2, 3, i]), i + 6, "arraylist sum"); - assertEqual(native.nested_summary({ - title: `nested-${suffix}`, - values: [1, 2, 3], - tuple: [i, true, `tuple-${suffix}`], - maybe: i % 2 === 0 ? `maybe-${suffix}` : null, - }) > 0, true, "nested summary"); + assertEqual( + native.nested_summary({ + title: `nested-${suffix}`, + values: [1, 2, 3], + tuple: [i, true, `tuple-${suffix}`], + maybe: i % 2 === 0 ? `maybe-${suffix}` : null, + }) > 0, + true, + "nested summary", + ); assertEqual(native.union_kind(`variant-${suffix}`), "text", "union text"); assertEqual(native.union_kind(i), "number", "union number"); const createdFunction = native.create_function(); assertEqual(createdFunction(19, 23), 42, "create function call"); - assertEqual(native.call_function((left: number, right: number) => left + right), 42, "function callback"); - assertEqual(native.call_function_with_reference((left: number, right: number) => left + right), 42, "function reference"); - assertEqual(native.function_reference_ref_count((left: number, right: number) => left + right), 2, "reference ref count"); + assertEqual( + native.call_function((left: number, right: number) => left + right), + 42, + "function callback", + ); + assertEqual( + native.call_function_with_reference((left: number, right: number) => left + right), + 42, + "function reference", + ); + assertEqual( + native.function_reference_ref_count((left: number, right: number) => left + right), + 2, + "reference ref count", + ); assertEqual(String(native.create_bigint_value()), "9007199254740993", "bigint return"); assertEqual(native.bigint_to_i64(native.create_small_bigint_value()), 42, "bigint input"); diff --git a/prek.toml b/prek.toml new file mode 100644 index 0000000..a36ff5c --- /dev/null +++ b/prek.toml @@ -0,0 +1,15 @@ +fail_fast = true +default_install_hook_types = ["pre-commit"] +default_stages = ["pre-commit"] + +[[repos]] +repo = "local" + +[[repos.hooks]] +id = "build-and-format" +name = "build and format" +language = "system" +entry = "sh -c 'just build-example && just format'" +pass_filenames = false +always_run = true +fail_fast = true diff --git a/test/assert.ts b/test/assert.ts index 67ca7fa..a797aa0 100644 --- a/test/assert.ts +++ b/test/assert.ts @@ -20,13 +20,22 @@ export function assertNullish(actual: ESObject, message: string) { } } -export function assertApproxEqual(actual: number, expected: number, message: string, epsilon: number = 0.00001) { +export function assertApproxEqual( + actual: number, + expected: number, + message: string, + epsilon: number = 0.00001, +) { if (Math.abs(actual - expected) > epsilon) { fail(`${message}: expected=${String(expected)} actual=${String(actual)}`); } } -export function assertArrayEqual(actual: Array, expected: Array, message: string) { +export function assertArrayEqual( + actual: Array, + expected: Array, + message: string, +) { assertEqual(actual.length, expected.length, `${message}.length`); for (let i = 0; i < expected.length; i++) { assertEqual(actual[i], expected[i], `${message}[${i}]`); @@ -51,7 +60,11 @@ export function assertThrows(fn: () => void, expectedMessage: string, message: s assert(threw, `${message}: expected throw`); } -export async function assertRejects(promise: Promise, expectedMessage: string, message: string) { +export async function assertRejects( + promise: Promise, + expectedMessage: string, + message: string, +) { let rejected = false; try { await promise; diff --git a/test/async.spec.ts b/test/async.spec.ts index 4f0c50e..dac2199 100644 --- a/test/async.spec.ts +++ b/test/async.spec.ts @@ -21,7 +21,11 @@ export async function testAsync(native: NativeAddon) { assertEqual(await native.fib_async(10), 55, "fib_async"); const progressEvents: Array = []; - assertEqual(await native.fib_async_progress(8, (event: ESObject) => progressEvents.push(event)), 21, "fib_async_progress"); + assertEqual( + await native.fib_async_progress(8, (event: ESObject) => progressEvents.push(event)), + 21, + "fib_async_progress", + ); assertEqual(progressEvents.length, 2, "fib_async_progress events"); assertEqual(progressEvents[0].current, 0, "fib_async_progress first event"); assertEqual(progressEvents[1].current, 8, "fib_async_progress last event"); @@ -54,12 +58,32 @@ export async function testAsync(native: NativeAddon) { await assertRejects(native.async_fail_thread("async boom"), "async boom", "async_fail_thread"); const countEvents: Array = []; - assertEqual(await native.count_async_progress_thread(3, (event: ESObject) => countEvents.push(event)), 3, "count_async_progress_thread result"); - assertArrayEqual(countEvents.map((event: ESObject) => event.current), [0, 1, 2, 3], "count_async_progress_thread current events"); + assertEqual( + await native.count_async_progress_thread(3, (event: ESObject) => countEvents.push(event)), + 3, + "count_async_progress_thread result", + ); + assertArrayEqual( + countEvents.map((event: ESObject) => event.current), + [0, 1, 2, 3], + "count_async_progress_thread current events", + ); const eventModeEvents: Array = []; - assertEqual(await native.event_mode_progress_async(2, (event: ESObject) => eventModeEvents.push(event)), 2, "event_mode_progress_async result"); - assertArrayEqual(eventModeEvents.map((event: ESObject) => event.current), [0, 1, 2], "event_mode_progress_async current events"); + assertEqual( + await native.event_mode_progress_async(2, (event: ESObject) => eventModeEvents.push(event)), + 2, + "event_mode_progress_async result", + ); + assertArrayEqual( + eventModeEvents.map((event: ESObject) => event.current), + [0, 1, 2], + "event_mode_progress_async current events", + ); - await assertRejects(native.abortable_count_async(4096, abortSignal(true)), "AbortError", "abortable_count_async pre-aborted"); + await assertRejects( + native.abortable_count_async(4096, abortSignal(true)), + "AbortError", + "abortable_count_async pre-aborted", + ); } diff --git a/test/binary.spec.ts b/test/binary.spec.ts index 120f333..f122f86 100644 --- a/test/binary.spec.ts +++ b/test/binary.spec.ts @@ -9,12 +9,20 @@ export function testBinary(native: NativeAddon) { const arrayBufferValue = native.create_arraybuffer(); assertEqual(native.get_arraybuffer(arrayBufferValue), 1024, "arraybuffer length"); - assertEqual(native.get_arraybuffer_as_string(arrayBufferValue).length, 1024, "arraybuffer string length"); + assertEqual( + native.get_arraybuffer_as_string(arrayBufferValue).length, + 1024, + "arraybuffer string length", + ); const typedArrayValue = native.create_uint8_typedarray(); assertEqual(native.get_uint8_typedarray_length(typedArrayValue), 4, "typedarray length"); assertArrayEqual(Array.from(typedArrayValue), [1, 2, 3, 4], "typedarray content"); - assertEqual(native.sum_float32_typedarray(new Float32Array([1.5, 2.5, -1])), 3, "float32 typedarray sum"); + assertEqual( + native.sum_float32_typedarray(new Float32Array([1.5, 2.5, -1])), + 3, + "float32 typedarray sum", + ); const dataViewValue = native.create_dataview(); assertEqual(native.get_dataview_length(dataViewValue), 4, "dataview length"); diff --git a/test/errors-tsfn.spec.ts b/test/errors-tsfn.spec.ts index a74d7aa..ca05433 100644 --- a/test/errors-tsfn.spec.ts +++ b/test/errors-tsfn.spec.ts @@ -18,7 +18,11 @@ async function waitForThreadSafeFunction(native: NativeAddon) { try { if (err) { assert(!sawErr, "thread safe function error callback duplicated"); - assertIncludes(String(err && (err.message || err)), "TSFN Error", "thread safe function error callback"); + assertIncludes( + String(err && (err.message || err)), + "TSFN Error", + "thread safe function error callback", + ); sawErr = true; } else { assert(!sawOk, "thread safe function success callback duplicated"); diff --git a/test/functions-classes.spec.ts b/test/functions-classes.spec.ts index 4a47b04..fee08ea 100644 --- a/test/functions-classes.spec.ts +++ b/test/functions-classes.spec.ts @@ -7,8 +7,16 @@ export function testFunctionsAndClasses(native: NativeAddon) { const createdFunction = native.create_function(); assertEqual(createdFunction(19, 23), 42, "create_function"); - assertEqual(native.call_function((left: number, right: number) => left + right + 1), 4, "call_function"); - assertEqual(native.call_function_with_reference((left: number, right: number) => left * right), 2, "call_function_with_reference"); + assertEqual( + native.call_function((left: number, right: number) => left + right + 1), + 4, + "call_function", + ); + assertEqual( + native.call_function_with_reference((left: number, right: number) => left * right), + 2, + "call_function_with_reference", + ); const classValue = new native.TestClass("Lin", 9); assertEqual(classValue.name, "Lin", "class.name"); @@ -24,10 +32,18 @@ export function testFunctionsAndClasses(native: NativeAddon) { const factoryClassValue = native.TestFactoryClass.initWithFactory(13, "Factory"); assertEqual(factoryClassValue.name, "Factory", "class factory.name"); assertEqual(factoryClassValue.age, 13, "class factory.age"); - assertEqual(factoryClassValue.format(), "TestFactory { name = Factory, age = 13 }", "class factory format"); + assertEqual( + factoryClassValue.format(), + "TestFactory { name = Factory, age = 13 }", + "class factory format", + ); const constructedFactory = new native.TestFactoryClass("Ctor", 14); assertEqual(constructedFactory.name, "Ctor", "class factory constructor.name"); assertEqual(constructedFactory.age, 14, "class factory constructor.age"); - assertEqual(constructedFactory.format(), "TestFactory { name = Ctor, age = 14 }", "class factory constructor format"); + assertEqual( + constructedFactory.format(), + "TestFactory { name = Ctor, age = 14 }", + "class factory constructor format", + ); } diff --git a/test/init.ts b/test/init.ts index 009010e..237a804 100644 --- a/test/init.ts +++ b/test/init.ts @@ -14,7 +14,11 @@ runSuite("__ZIG_NAPI_INIT_TEST_RESULT__", async (native) => { assertArrayEqual(native.get_and_return_array([1, 2, 3]), [1, 2, 3], "init array roundtrip"); assertArrayEqual(native.get_arraylist([3, 2, 1]), [3, 2, 1], "init arraylist roundtrip"); - assertArrayEqual(native.get_named_array([7, true, "tuple"]), [7, true, "tuple"], "init tuple roundtrip"); + assertArrayEqual( + native.get_named_array([7, true, "tuple"]), + [7, true, "tuple"], + "init tuple roundtrip", + ); assertThrows(() => native.throw_error(), "test", "init throw_error"); }); diff --git a/test/objects-arrays.spec.ts b/test/objects-arrays.spec.ts index d88d964..d549769 100644 --- a/test/objects-arrays.spec.ts +++ b/test/objects-arrays.spec.ts @@ -5,7 +5,11 @@ type NativeAddon = ESObject; export function testObjectsAndArrays(native: NativeAddon) { assertArrayEqual(native.get_and_return_array([1, 2, 3]), [1, 2, 3], "array roundtrip"); assertArrayEqual(native.get_arraylist([3, 2, 1]), [3, 2, 1], "arraylist roundtrip"); - assertArrayEqual(native.get_named_array([7, true, "tuple"]), [7, true, "tuple"], "tuple roundtrip"); + assertArrayEqual( + native.get_named_array([7, true, "tuple"]), + [7, true, "tuple"], + "tuple roundtrip", + ); const objectResult = native.get_object({ name: "Ada", @@ -30,7 +34,11 @@ export function testObjectsAndArrays(native: NativeAddon) { assertEqual(optionalRoundtrip.age, 20, "optional roundtrip.age"); assertEqual(optionalRoundtrip.is_student, false, "optional roundtrip.is_student"); - assertEqual(native.get_nullable_object({ name: "Nullable" }).name, "Nullable", "nullable object value"); + assertEqual( + native.get_nullable_object({ name: "Nullable" }).name, + "Nullable", + "nullable object value", + ); assertNullish(native.get_nullable_object({ name: null }).name, "nullable object null"); assertNullish(native.return_nullable().name, "return_nullable"); } diff --git a/test/unions-enums.spec.ts b/test/unions-enums.spec.ts index 28b8945..00a3364 100644 --- a/test/unions-enums.spec.ts +++ b/test/unions-enums.spec.ts @@ -15,14 +15,28 @@ export function testUnionsAndEnums(native: NativeAddon) { assertEqual(native.union_kind(42), "number", "union_kind number"); assertEqual(native.union_kind("forty-two"), "text", "union_kind text"); - assertPayload(native.object_or_text_identity({ title: "payload", count: 5 }), "payload", 5, "object_or_text payload"); + assertPayload( + native.object_or_text_identity({ title: "payload", count: 5 }), + "payload", + 5, + "object_or_text payload", + ); assertEqual(native.object_or_text_identity("plain"), "plain", "object_or_text text"); assertPayload(native.make_object_or_text(true), "hello", 2, "make_object_or_text payload"); assertEqual(native.make_object_or_text(false), "plain", "make_object_or_text text"); - assertPayload(native.object_or_array_identity({ title: "list-payload", count: 6 }), "list-payload", 6, "object_or_array payload"); + assertPayload( + native.object_or_array_identity({ title: "list-payload", count: 6 }), + "list-payload", + 6, + "object_or_array payload", + ); assertArrayEqual(native.object_or_array_identity([1, 2, 3]), [1, 2, 3], "object_or_array list"); - assertArrayEqual(native.tuple_or_text_identity([1, true, "tuple"]), [1, true, "tuple"], "tuple_or_text tuple"); + assertArrayEqual( + native.tuple_or_text_identity([1, true, "tuple"]), + [1, true, "tuple"], + "tuple_or_text tuple", + ); assertEqual(native.tuple_or_text_identity("tuple-text"), "tuple-text", "tuple_or_text text"); assertEqual(native.flip_flag_or_increment(true), false, "flip_flag_or_increment bool"); @@ -47,23 +61,62 @@ export function testUnionsAndEnums(native: NativeAddon) { const madeBuffer = native.make_buffer_or_text(true); assertEqual(native.get_buffer(madeBuffer), 16, "make_buffer_or_text buffer"); - assertEqual(native.get_buffer(native.buffer_or_text_identity(madeBuffer)), 16, "buffer_or_text buffer"); + assertEqual( + native.get_buffer(native.buffer_or_text_identity(madeBuffer)), + 16, + "buffer_or_text buffer", + ); assertEqual(native.buffer_or_text_identity("buffer-text"), "buffer-text", "buffer_or_text text"); assertEqual(native.make_buffer_or_text(false), "buffer-fallback", "make_buffer_or_text text"); const madeArrayBuffer = native.make_arraybuffer_or_array(true); assertEqual(native.get_arraybuffer(madeArrayBuffer), 16, "make_arraybuffer_or_array arraybuffer"); - assertEqual(native.get_arraybuffer(native.arraybuffer_or_array_identity(madeArrayBuffer)), 16, "arraybuffer_or_array arraybuffer"); - assertArrayEqual(native.arraybuffer_or_array_identity([4, 5]), [4, 5], "arraybuffer_or_array list"); - assertArrayEqual(native.make_arraybuffer_or_array(false), [1, 2, 3], "make_arraybuffer_or_array list"); + assertEqual( + native.get_arraybuffer(native.arraybuffer_or_array_identity(madeArrayBuffer)), + 16, + "arraybuffer_or_array arraybuffer", + ); + assertArrayEqual( + native.arraybuffer_or_array_identity([4, 5]), + [4, 5], + "arraybuffer_or_array list", + ); + assertArrayEqual( + native.make_arraybuffer_or_array(false), + [1, 2, 3], + "make_arraybuffer_or_array list", + ); - assertPayload(native.payload_or_color_identity({ title: "mixed", count: 11 }), "mixed", 11, "payload_or_color payload"); + assertPayload( + native.payload_or_color_identity({ title: "mixed", count: 11 }), + "mixed", + 11, + "payload_or_color payload", + ); assertEqual(native.payload_or_color_identity(1), 1, "payload_or_color color"); assertPayload(native.make_payload_or_color(true), "mixed", 9, "make_payload_or_color payload"); assertEqual(native.make_payload_or_color(false), 1, "make_payload_or_color color"); - assertPayload(native.payload_or_string_color_identity({ title: "string-color", count: 12 }), "string-color", 12, "payload_or_string_color payload"); - assertEqual(native.payload_or_string_color_identity("Red"), "Red", "payload_or_string_color color"); - assertPayload(native.make_payload_or_string_color(true), "string-enum", 3, "make_payload_or_string_color payload"); - assertEqual(native.make_payload_or_string_color(false), "Green", "make_payload_or_string_color color"); + assertPayload( + native.payload_or_string_color_identity({ title: "string-color", count: 12 }), + "string-color", + 12, + "payload_or_string_color payload", + ); + assertEqual( + native.payload_or_string_color_identity("Red"), + "Red", + "payload_or_string_color color", + ); + assertPayload( + native.make_payload_or_string_color(true), + "string-enum", + 3, + "make_payload_or_string_color payload", + ); + assertEqual( + native.make_payload_or_string_color(false), + "Green", + "make_payload_or_string_color color", + ); } From 934bcc27f47b43473f10ee57e284198b602425b8 Mon Sep 17 00:00:00 2001 From: richerfu Date: Thu, 7 May 2026 10:29:10 +0800 Subject: [PATCH 2/3] Fix root build.zig error --- build.zig | 7 ++++--- src/build/options.zig | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) create mode 100644 src/build/options.zig diff --git a/build.zig b/build.zig index c743d51..88ae862 100644 --- a/build.zig +++ b/build.zig @@ -10,11 +10,12 @@ pub fn build(b: *std.Build) !void { const napi = b.addModule("napi", .{ .root_source_file = b.path("src/napi.zig"), }); - const build_options = b.addOptions(); - build_options.addOption(bool, "napi_tsgen", false); + const build_options = b.addModule("build_options", .{ + .root_source_file = b.path("src/build/options.zig"), + }); napi.addImport("napi-sys", napi_sys); - napi.addOptions("build_options", build_options); + napi.addImport("build_options", build_options); napi.addIncludePath(b.path("src/sys/header")); napi_sys.addIncludePath(b.path("src/sys/header")); diff --git a/src/build/options.zig b/src/build/options.zig new file mode 100644 index 0000000..dbf72ef --- /dev/null +++ b/src/build/options.zig @@ -0,0 +1 @@ +pub const napi_tsgen = false; From 9b1f648fbff9e5f5a7c7664c612ac7cdbf572257 Mon Sep 17 00:00:00 2001 From: richerfu Date: Thu, 7 May 2026 10:36:05 +0800 Subject: [PATCH 3/3] Add CI config --- .github/workflows/lint-format.yml | 68 +++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 .github/workflows/lint-format.yml diff --git a/.github/workflows/lint-format.yml b/.github/workflows/lint-format.yml new file mode 100644 index 0000000..68d6789 --- /dev/null +++ b/.github/workflows/lint-format.yml @@ -0,0 +1,68 @@ +name: Lint and Format + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + lint: + runs-on: ubuntu-latest + name: Lint + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Zig + uses: openharmony-zig/setup-zig-ohos@v0.1.0 + with: + tag: '0.16.0' + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 22 + + - name: Validate prek config + run: npm exec --yes --package @j178/prek -- prek validate-config prek.toml + + - name: Check Zig syntax + run: | + set -euo pipefail + while IFS= read -r -d '' file; do + zig ast-check "$file" + done < <(git ls-files -z '*.zig') + while IFS= read -r -d '' file; do + zig ast-check --zon "$file" + done < <(git ls-files -z '*.zon') + + - name: Build root package + run: zig build --summary all + + format: + runs-on: ubuntu-latest + name: Format + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Zig + uses: openharmony-zig/setup-zig-ohos@v0.1.0 + with: + tag: '0.16.0' + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 22 + + - name: Check formatting + run: | + set -euo pipefail + git ls-files -z '*.zig' '*.zon' | xargs -0 zig fmt + git ls-files -z '*.js' '*.jsx' '*.ts' '*.tsx' '*.ets' \ + | xargs -0 npm exec --yes --package @ohos-rs/oxk -- oxk format + git diff --exit-code