@fuzdev/fuz_util 0.54.0 → 0.56.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/args.d.ts +12 -12
- package/dist/args.js +11 -11
- package/dist/async.d.ts +12 -12
- package/dist/async.js +12 -12
- package/dist/benchmark.d.ts +24 -24
- package/dist/benchmark.js +26 -26
- package/dist/benchmark_baseline.d.ts +17 -11
- package/dist/benchmark_baseline.d.ts.map +1 -1
- package/dist/benchmark_baseline.js +26 -19
- package/dist/benchmark_format.d.ts +15 -15
- package/dist/benchmark_format.js +15 -15
- package/dist/benchmark_stats.d.ts +30 -10
- package/dist/benchmark_stats.d.ts.map +1 -1
- package/dist/benchmark_stats.js +48 -40
- package/dist/benchmark_types.d.ts +7 -7
- package/dist/bytes.d.ts +4 -4
- package/dist/bytes.js +4 -4
- package/dist/dag.d.ts +2 -2
- package/dist/dag.js +2 -2
- package/dist/deep_equal.d.ts +2 -2
- package/dist/deep_equal.js +2 -2
- package/dist/diff.d.ts +17 -17
- package/dist/diff.js +17 -17
- package/dist/dom.d.ts +4 -4
- package/dist/dom.js +4 -4
- package/dist/fetch.d.ts +1 -1
- package/dist/fetch.js +1 -1
- package/dist/git.d.ts +1 -1
- package/dist/git.js +1 -1
- package/dist/hash.d.ts +6 -6
- package/dist/hash.js +8 -8
- package/dist/hash_blake3.d.ts +1 -1
- package/dist/hash_blake3.js +1 -1
- package/dist/hex.d.ts +4 -4
- package/dist/hex.js +4 -4
- package/dist/json.d.ts +2 -2
- package/dist/json.js +2 -2
- package/dist/log.d.ts +12 -12
- package/dist/log.js +11 -11
- package/dist/map.d.ts +1 -1
- package/dist/map.js +1 -1
- package/dist/object.d.ts +1 -1
- package/dist/object.js +1 -1
- package/dist/package_json.d.ts +1 -1
- package/dist/package_json.js +1 -1
- package/dist/path.d.ts +5 -5
- package/dist/path.js +5 -5
- package/dist/process.d.ts +22 -22
- package/dist/process.js +22 -22
- package/dist/random.d.ts +2 -2
- package/dist/random.js +2 -2
- package/dist/result.d.ts +6 -6
- package/dist/result.js +6 -6
- package/dist/sort.d.ts +3 -3
- package/dist/sort.js +3 -3
- package/dist/source_json.d.ts +3 -3
- package/dist/source_json.js +3 -3
- package/dist/stats.d.ts +17 -17
- package/dist/stats.js +17 -17
- package/dist/string.d.ts +6 -6
- package/dist/string.js +6 -6
- package/dist/svelte_preprocess_helpers.d.ts +42 -42
- package/dist/svelte_preprocess_helpers.js +42 -42
- package/dist/testing.d.ts +44 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +59 -0
- package/dist/time.d.ts +19 -19
- package/dist/time.js +19 -19
- package/dist/zod.d.ts +16 -16
- package/dist/zod.d.ts.map +1 -1
- package/dist/zod.js +24 -24
- package/package.json +6 -6
- package/src/lib/args.ts +12 -12
- package/src/lib/async.ts +12 -12
- package/src/lib/benchmark.ts +28 -28
- package/src/lib/benchmark_baseline.ts +37 -20
- package/src/lib/benchmark_format.ts +15 -15
- package/src/lib/benchmark_stats.ts +66 -44
- package/src/lib/benchmark_types.ts +7 -7
- package/src/lib/bytes.ts +4 -4
- package/src/lib/dag.ts +2 -2
- package/src/lib/deep_equal.ts +2 -2
- package/src/lib/diff.ts +17 -17
- package/src/lib/dom.ts +4 -4
- package/src/lib/fetch.ts +1 -1
- package/src/lib/git.ts +1 -1
- package/src/lib/hash.ts +8 -8
- package/src/lib/hash_blake3.ts +1 -1
- package/src/lib/hex.ts +4 -4
- package/src/lib/json.ts +2 -2
- package/src/lib/log.ts +12 -12
- package/src/lib/map.ts +1 -1
- package/src/lib/object.ts +1 -1
- package/src/lib/package_json.ts +1 -1
- package/src/lib/path.ts +5 -5
- package/src/lib/process.ts +22 -22
- package/src/lib/random.ts +2 -2
- package/src/lib/result.ts +6 -6
- package/src/lib/sort.ts +3 -3
- package/src/lib/source_json.ts +3 -3
- package/src/lib/stats.ts +17 -17
- package/src/lib/string.ts +6 -6
- package/src/lib/svelte_preprocess_helpers.ts +42 -42
- package/src/lib/testing.ts +80 -0
- package/src/lib/time.ts +19 -19
- package/src/lib/zod.ts +24 -24
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared test assertions for the `@fuzdev` ecosystem.
|
|
3
|
+
*
|
|
4
|
+
* Extends the fuz-stack testing conventions (`assert` from vitest, tests in `src/test/`,
|
|
5
|
+
* plain object mocks) with reusable helpers for patterns that appear across multiple repos.
|
|
6
|
+
* Only depends on vitest — safe for fuz_util's zero-runtime-deps constraint.
|
|
7
|
+
*
|
|
8
|
+
* @module
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import {assert, vi} from 'vitest';
|
|
12
|
+
|
|
13
|
+
import type {Logger} from './log.js';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Asserts that `fn` rejects with an `Error`.
|
|
17
|
+
* Optionally matches the error message against `pattern`.
|
|
18
|
+
* Returns the caught `Error` for further assertions by the caller.
|
|
19
|
+
*
|
|
20
|
+
* `assert.fail` is placed after the catch block so that assertion failures
|
|
21
|
+
* from the test itself are not swallowed by the catch.
|
|
22
|
+
*
|
|
23
|
+
* @param fn - async function expected to reject
|
|
24
|
+
* @param pattern - optional regex to match against the error message
|
|
25
|
+
* @returns the caught `Error`
|
|
26
|
+
*/
|
|
27
|
+
export const assert_rejects = async (
|
|
28
|
+
fn: () => Promise<unknown>,
|
|
29
|
+
pattern?: RegExp,
|
|
30
|
+
): Promise<Error> => {
|
|
31
|
+
try {
|
|
32
|
+
await fn();
|
|
33
|
+
} catch (err) {
|
|
34
|
+
assert(err instanceof Error, 'Expected rejection to be an Error');
|
|
35
|
+
if (pattern) {
|
|
36
|
+
assert.match(err.message, pattern);
|
|
37
|
+
}
|
|
38
|
+
return err;
|
|
39
|
+
}
|
|
40
|
+
assert.fail('Expected to throw');
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* A mock `Logger` with `vi.fn()` methods and call tracking arrays.
|
|
45
|
+
* Assignable to `Logger` for use in code under test.
|
|
46
|
+
* Each tracking array captures the first argument of each call.
|
|
47
|
+
* For full call details, use `vi.fn()` introspection on the methods directly.
|
|
48
|
+
*/
|
|
49
|
+
export type MockLogger = Logger & {
|
|
50
|
+
error_calls: Array<unknown>;
|
|
51
|
+
warn_calls: Array<unknown>;
|
|
52
|
+
info_calls: Array<unknown>;
|
|
53
|
+
debug_calls: Array<unknown>;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Creates a mock `Logger` with `vi.fn()` on each logging method
|
|
58
|
+
* and tracking arrays for inspecting logged messages.
|
|
59
|
+
* Follows the fuz-stack convention of plain object mocks over mocking libraries.
|
|
60
|
+
*
|
|
61
|
+
* @returns a `MockLogger` assignable to `Logger`
|
|
62
|
+
*/
|
|
63
|
+
export const create_mock_logger = (): MockLogger => {
|
|
64
|
+
const error_calls: Array<unknown> = [];
|
|
65
|
+
const warn_calls: Array<unknown> = [];
|
|
66
|
+
const info_calls: Array<unknown> = [];
|
|
67
|
+
const debug_calls: Array<unknown> = [];
|
|
68
|
+
|
|
69
|
+
return {
|
|
70
|
+
error: vi.fn((msg: unknown) => error_calls.push(msg)),
|
|
71
|
+
warn: vi.fn((msg: unknown) => warn_calls.push(msg)),
|
|
72
|
+
info: vi.fn((msg: unknown) => info_calls.push(msg)),
|
|
73
|
+
debug: vi.fn((msg: unknown) => debug_calls.push(msg)),
|
|
74
|
+
raw: vi.fn(),
|
|
75
|
+
error_calls,
|
|
76
|
+
warn_calls,
|
|
77
|
+
info_calls,
|
|
78
|
+
debug_calls,
|
|
79
|
+
} as unknown as MockLogger;
|
|
80
|
+
};
|
package/src/lib/time.ts
CHANGED
|
@@ -120,8 +120,8 @@ export const TIME_UNIT_DISPLAY: Record<TimeUnit, string> = {ns: 'ns', us: 'μs',
|
|
|
120
120
|
/**
|
|
121
121
|
* Detect the best time unit for a set of nanosecond values.
|
|
122
122
|
* Chooses the unit where most values fall in the range 1-9999.
|
|
123
|
-
* @param values_ns -
|
|
124
|
-
* @returns
|
|
123
|
+
* @param values_ns - array of times in nanoseconds
|
|
124
|
+
* @returns best unit to use for all values
|
|
125
125
|
*/
|
|
126
126
|
export const time_unit_detect_best = (values_ns: Array<number>): TimeUnit => {
|
|
127
127
|
if (values_ns.length === 0) return 'ms';
|
|
@@ -148,10 +148,10 @@ export const time_unit_detect_best = (values_ns: Array<number>): TimeUnit => {
|
|
|
148
148
|
|
|
149
149
|
/**
|
|
150
150
|
* Format time with a specific unit.
|
|
151
|
-
* @param ns -
|
|
152
|
-
* @param unit -
|
|
153
|
-
* @param decimals -
|
|
154
|
-
* @returns
|
|
151
|
+
* @param ns - time in nanoseconds
|
|
152
|
+
* @param unit - unit to use ('ns', 'us', 'ms', 's')
|
|
153
|
+
* @param decimals - number of decimal places (default: 2)
|
|
154
|
+
* @returns formatted string like "3.87μs"
|
|
155
155
|
*/
|
|
156
156
|
export const time_format = (ns: number, unit: TimeUnit, decimals: number = 2): string => {
|
|
157
157
|
if (!isFinite(ns)) return String(ns);
|
|
@@ -170,9 +170,9 @@ export const time_format = (ns: number, unit: TimeUnit, decimals: number = 2): s
|
|
|
170
170
|
|
|
171
171
|
/**
|
|
172
172
|
* Format time with adaptive units (ns/μs/ms/s) based on magnitude.
|
|
173
|
-
* @param ns -
|
|
174
|
-
* @param decimals -
|
|
175
|
-
* @returns
|
|
173
|
+
* @param ns - time in nanoseconds
|
|
174
|
+
* @param decimals - number of decimal places (default: 2)
|
|
175
|
+
* @returns formatted string like "3.87μs" or "1.23ms"
|
|
176
176
|
*
|
|
177
177
|
* @example
|
|
178
178
|
* ```ts
|
|
@@ -216,9 +216,9 @@ export interface TimeResult {
|
|
|
216
216
|
|
|
217
217
|
/**
|
|
218
218
|
* Time an asynchronous function execution.
|
|
219
|
-
* @param fn -
|
|
220
|
-
* @param timer -
|
|
221
|
-
* @returns
|
|
219
|
+
* @param fn - async function to time
|
|
220
|
+
* @param timer - timer to use (defaults to `timer_default`)
|
|
221
|
+
* @returns object containing the function result and timing information
|
|
222
222
|
*
|
|
223
223
|
* @example
|
|
224
224
|
* ```ts
|
|
@@ -252,9 +252,9 @@ export const time_async = async <T>(
|
|
|
252
252
|
|
|
253
253
|
/**
|
|
254
254
|
* Time a synchronous function execution.
|
|
255
|
-
* @param fn -
|
|
256
|
-
* @param timer -
|
|
257
|
-
* @returns
|
|
255
|
+
* @param fn - sync function to time
|
|
256
|
+
* @param timer - timer to use (defaults to `timer_default`)
|
|
257
|
+
* @returns object containing the function result and timing information
|
|
258
258
|
*
|
|
259
259
|
* @example
|
|
260
260
|
* ```ts
|
|
@@ -287,10 +287,10 @@ export const time_sync = <T>(
|
|
|
287
287
|
|
|
288
288
|
/**
|
|
289
289
|
* Measure multiple executions of a function and return all timings.
|
|
290
|
-
* @param fn -
|
|
291
|
-
* @param iterations -
|
|
292
|
-
* @param timer -
|
|
293
|
-
* @returns
|
|
290
|
+
* @param fn - function to measure (sync or async)
|
|
291
|
+
* @param iterations - number of times to execute
|
|
292
|
+
* @param timer - timer to use (defaults to `timer_default`)
|
|
293
|
+
* @returns array of elapsed times in nanoseconds
|
|
294
294
|
*
|
|
295
295
|
* @example
|
|
296
296
|
* ```ts
|
package/src/lib/zod.ts
CHANGED
|
@@ -16,8 +16,8 @@ import type {z} from 'zod';
|
|
|
16
16
|
/**
|
|
17
17
|
* Unwrap nested schema types (optional, default, nullable, etc).
|
|
18
18
|
*
|
|
19
|
-
* @param def - Zod type definition to unwrap
|
|
20
|
-
* @returns
|
|
19
|
+
* @param def - Zod type definition to unwrap
|
|
20
|
+
* @returns inner schema if wrapped, undefined otherwise
|
|
21
21
|
*/
|
|
22
22
|
export const zod_to_subschema = (def: z.core.$ZodTypeDef): z.ZodType | undefined => {
|
|
23
23
|
if ('innerType' in def) {
|
|
@@ -48,7 +48,7 @@ export const ZOD_WRAPPER_TYPES = new Set([
|
|
|
48
48
|
* @returns the innermost non-wrapper type definition
|
|
49
49
|
*/
|
|
50
50
|
export const zod_unwrap_def = (schema: z.ZodType): z.core.$ZodTypeDef => {
|
|
51
|
-
const def = schema
|
|
51
|
+
const {def} = schema;
|
|
52
52
|
if (ZOD_WRAPPER_TYPES.has(def.type)) {
|
|
53
53
|
const sub = zod_to_subschema(def);
|
|
54
54
|
if (sub) return zod_unwrap_def(sub);
|
|
@@ -69,7 +69,7 @@ export const zod_get_base_type = (schema: z.ZodType): string => zod_unwrap_def(s
|
|
|
69
69
|
*
|
|
70
70
|
* @param schema - Zod schema to check
|
|
71
71
|
*/
|
|
72
|
-
export const zod_is_optional = (schema: z.ZodType): boolean => schema.
|
|
72
|
+
export const zod_is_optional = (schema: z.ZodType): boolean => schema.def.type === 'optional';
|
|
73
73
|
|
|
74
74
|
/**
|
|
75
75
|
* Check if a schema accepts null at any wrapping level.
|
|
@@ -77,7 +77,7 @@ export const zod_is_optional = (schema: z.ZodType): boolean => schema._zod.def.t
|
|
|
77
77
|
* @param schema - Zod schema to check
|
|
78
78
|
*/
|
|
79
79
|
export const zod_is_nullable = (schema: z.ZodType): boolean => {
|
|
80
|
-
const def = schema
|
|
80
|
+
const {def} = schema;
|
|
81
81
|
if (def.type === 'nullable') return true;
|
|
82
82
|
if (ZOD_WRAPPER_TYPES.has(def.type)) {
|
|
83
83
|
const sub = zod_to_subschema(def);
|
|
@@ -95,7 +95,7 @@ export const zod_is_nullable = (schema: z.ZodType): boolean => {
|
|
|
95
95
|
* @param schema - Zod schema to check
|
|
96
96
|
*/
|
|
97
97
|
export const zod_has_default = (schema: z.ZodType): boolean => {
|
|
98
|
-
const def = schema
|
|
98
|
+
const {def} = schema;
|
|
99
99
|
if ('defaultValue' in def) return true;
|
|
100
100
|
const sub = zod_to_subschema(def);
|
|
101
101
|
if (sub) return zod_has_default(sub);
|
|
@@ -113,8 +113,8 @@ export const zod_unwrap_to_object = (schema: z.ZodType): z.ZodObject | null => {
|
|
|
113
113
|
const def = zod_unwrap_def(schema);
|
|
114
114
|
if (def.type !== 'object') return null;
|
|
115
115
|
let s: z.ZodType = schema;
|
|
116
|
-
while (s.
|
|
117
|
-
const sub = zod_to_subschema(s.
|
|
116
|
+
while (s.def.type !== 'object') {
|
|
117
|
+
const sub = zod_to_subschema(s.def);
|
|
118
118
|
if (!sub) return null;
|
|
119
119
|
s = sub;
|
|
120
120
|
}
|
|
@@ -158,8 +158,8 @@ export const zod_extract_fields = (schema: z.ZodObject): Array<ZodFieldInfo> =>
|
|
|
158
158
|
/**
|
|
159
159
|
* Get the description from a schema's metadata, unwrapping if needed.
|
|
160
160
|
*
|
|
161
|
-
* @param schema - Zod schema to extract description from
|
|
162
|
-
* @returns
|
|
161
|
+
* @param schema - Zod schema to extract description from
|
|
162
|
+
* @returns description string or null if not found
|
|
163
163
|
*/
|
|
164
164
|
export const zod_to_schema_description = (schema: z.ZodType): string | null => {
|
|
165
165
|
const meta = schema.meta();
|
|
@@ -176,11 +176,11 @@ export const zod_to_schema_description = (schema: z.ZodType): string | null => {
|
|
|
176
176
|
/**
|
|
177
177
|
* Get the default value from a schema, unwrapping if needed.
|
|
178
178
|
*
|
|
179
|
-
* @param schema - Zod schema to extract default from
|
|
180
|
-
* @returns
|
|
179
|
+
* @param schema - Zod schema to extract default from
|
|
180
|
+
* @returns default value or undefined
|
|
181
181
|
*/
|
|
182
182
|
export const zod_to_schema_default = (schema: z.ZodType): unknown => {
|
|
183
|
-
const {def} = schema
|
|
183
|
+
const {def} = schema;
|
|
184
184
|
if ('defaultValue' in def) {
|
|
185
185
|
return def.defaultValue;
|
|
186
186
|
}
|
|
@@ -194,8 +194,8 @@ export const zod_to_schema_default = (schema: z.ZodType): unknown => {
|
|
|
194
194
|
/**
|
|
195
195
|
* Get aliases from a schema's metadata, unwrapping if needed.
|
|
196
196
|
*
|
|
197
|
-
* @param schema - Zod schema to extract aliases from
|
|
198
|
-
* @returns
|
|
197
|
+
* @param schema - Zod schema to extract aliases from
|
|
198
|
+
* @returns array of alias strings
|
|
199
199
|
*/
|
|
200
200
|
export const zod_to_schema_aliases = (schema: z.ZodType): Array<string> => {
|
|
201
201
|
const meta = schema.meta();
|
|
@@ -212,11 +212,11 @@ export const zod_to_schema_aliases = (schema: z.ZodType): Array<string> => {
|
|
|
212
212
|
/**
|
|
213
213
|
* Get the type string for a schema, suitable for display.
|
|
214
214
|
*
|
|
215
|
-
* @param schema - Zod schema to get type string for
|
|
216
|
-
* @returns
|
|
215
|
+
* @param schema - Zod schema to get type string for
|
|
216
|
+
* @returns human-readable type string
|
|
217
217
|
*/
|
|
218
218
|
export const zod_to_schema_type_string = (schema: z.ZodType): string => {
|
|
219
|
-
const {def} = schema
|
|
219
|
+
const {def} = schema;
|
|
220
220
|
switch (def.type) {
|
|
221
221
|
case 'string':
|
|
222
222
|
return 'string';
|
|
@@ -264,8 +264,8 @@ export const zod_to_schema_type_string = (schema: z.ZodType): string => {
|
|
|
264
264
|
/**
|
|
265
265
|
* Format a value for display in help text.
|
|
266
266
|
*
|
|
267
|
-
* @param value -
|
|
268
|
-
* @returns
|
|
267
|
+
* @param value - value to format
|
|
268
|
+
* @returns formatted string representation
|
|
269
269
|
*/
|
|
270
270
|
export const zod_format_value = (value: unknown): string => {
|
|
271
271
|
if (value === undefined) return '';
|
|
@@ -295,8 +295,8 @@ export interface ZodSchemaProperty {
|
|
|
295
295
|
/**
|
|
296
296
|
* Extract properties from a Zod object schema.
|
|
297
297
|
*
|
|
298
|
-
* @param schema - Zod object schema to extract from
|
|
299
|
-
* @returns
|
|
298
|
+
* @param schema - Zod object schema to extract from
|
|
299
|
+
* @returns array of property definitions
|
|
300
300
|
*/
|
|
301
301
|
export const zod_to_schema_properties = (schema: z.ZodType): Array<ZodSchemaProperty> => {
|
|
302
302
|
const {def} = schema;
|
|
@@ -326,8 +326,8 @@ export const zod_to_schema_properties = (schema: z.ZodType): Array<ZodSchemaProp
|
|
|
326
326
|
/**
|
|
327
327
|
* Get all property names and their aliases from an object schema.
|
|
328
328
|
*
|
|
329
|
-
* @param schema - Zod object schema
|
|
330
|
-
* @returns
|
|
329
|
+
* @param schema - Zod object schema
|
|
330
|
+
* @returns set of all names and aliases
|
|
331
331
|
*/
|
|
332
332
|
export const zod_to_schema_names_with_aliases = (schema: z.ZodType): Set<string> => {
|
|
333
333
|
const names: Set<string> = new Set();
|