@fuzdev/fuz_util 0.55.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.
Files changed (104) hide show
  1. package/dist/args.d.ts +12 -12
  2. package/dist/args.js +11 -11
  3. package/dist/async.d.ts +12 -12
  4. package/dist/async.js +12 -12
  5. package/dist/benchmark.d.ts +24 -24
  6. package/dist/benchmark.js +26 -26
  7. package/dist/benchmark_baseline.d.ts +11 -11
  8. package/dist/benchmark_baseline.js +11 -11
  9. package/dist/benchmark_format.d.ts +15 -15
  10. package/dist/benchmark_format.js +15 -15
  11. package/dist/benchmark_stats.d.ts +5 -5
  12. package/dist/benchmark_stats.js +5 -5
  13. package/dist/benchmark_types.d.ts +7 -7
  14. package/dist/bytes.d.ts +4 -4
  15. package/dist/bytes.js +4 -4
  16. package/dist/dag.d.ts +2 -2
  17. package/dist/dag.js +2 -2
  18. package/dist/deep_equal.d.ts +2 -2
  19. package/dist/deep_equal.js +2 -2
  20. package/dist/diff.d.ts +17 -17
  21. package/dist/diff.js +17 -17
  22. package/dist/dom.d.ts +4 -4
  23. package/dist/dom.js +4 -4
  24. package/dist/fetch.d.ts +1 -1
  25. package/dist/fetch.js +1 -1
  26. package/dist/git.d.ts +1 -1
  27. package/dist/git.js +1 -1
  28. package/dist/hash.d.ts +6 -6
  29. package/dist/hash.js +8 -8
  30. package/dist/hash_blake3.d.ts +1 -1
  31. package/dist/hash_blake3.js +1 -1
  32. package/dist/hex.d.ts +4 -4
  33. package/dist/hex.js +4 -4
  34. package/dist/json.d.ts +2 -2
  35. package/dist/json.js +2 -2
  36. package/dist/log.d.ts +12 -12
  37. package/dist/log.js +11 -11
  38. package/dist/map.d.ts +1 -1
  39. package/dist/map.js +1 -1
  40. package/dist/object.d.ts +1 -1
  41. package/dist/object.js +1 -1
  42. package/dist/package_json.d.ts +1 -1
  43. package/dist/package_json.js +1 -1
  44. package/dist/path.d.ts +5 -5
  45. package/dist/path.js +5 -5
  46. package/dist/process.d.ts +22 -22
  47. package/dist/process.js +22 -22
  48. package/dist/random.d.ts +2 -2
  49. package/dist/random.js +2 -2
  50. package/dist/result.d.ts +6 -6
  51. package/dist/result.js +6 -6
  52. package/dist/sort.d.ts +3 -3
  53. package/dist/sort.js +3 -3
  54. package/dist/source_json.d.ts +3 -3
  55. package/dist/source_json.js +3 -3
  56. package/dist/stats.d.ts +17 -17
  57. package/dist/stats.js +17 -17
  58. package/dist/string.d.ts +6 -6
  59. package/dist/string.js +6 -6
  60. package/dist/svelte_preprocess_helpers.d.ts +42 -42
  61. package/dist/svelte_preprocess_helpers.js +42 -42
  62. package/dist/testing.d.ts +44 -0
  63. package/dist/testing.d.ts.map +1 -0
  64. package/dist/testing.js +59 -0
  65. package/dist/time.d.ts +19 -19
  66. package/dist/time.js +19 -19
  67. package/dist/zod.d.ts +16 -16
  68. package/dist/zod.d.ts.map +1 -1
  69. package/dist/zod.js +24 -24
  70. package/package.json +6 -6
  71. package/src/lib/args.ts +12 -12
  72. package/src/lib/async.ts +12 -12
  73. package/src/lib/benchmark.ts +28 -28
  74. package/src/lib/benchmark_baseline.ts +11 -11
  75. package/src/lib/benchmark_format.ts +15 -15
  76. package/src/lib/benchmark_stats.ts +5 -5
  77. package/src/lib/benchmark_types.ts +7 -7
  78. package/src/lib/bytes.ts +4 -4
  79. package/src/lib/dag.ts +2 -2
  80. package/src/lib/deep_equal.ts +2 -2
  81. package/src/lib/diff.ts +17 -17
  82. package/src/lib/dom.ts +4 -4
  83. package/src/lib/fetch.ts +1 -1
  84. package/src/lib/git.ts +1 -1
  85. package/src/lib/hash.ts +8 -8
  86. package/src/lib/hash_blake3.ts +1 -1
  87. package/src/lib/hex.ts +4 -4
  88. package/src/lib/json.ts +2 -2
  89. package/src/lib/log.ts +12 -12
  90. package/src/lib/map.ts +1 -1
  91. package/src/lib/object.ts +1 -1
  92. package/src/lib/package_json.ts +1 -1
  93. package/src/lib/path.ts +5 -5
  94. package/src/lib/process.ts +22 -22
  95. package/src/lib/random.ts +2 -2
  96. package/src/lib/result.ts +6 -6
  97. package/src/lib/sort.ts +3 -3
  98. package/src/lib/source_json.ts +3 -3
  99. package/src/lib/stats.ts +17 -17
  100. package/src/lib/string.ts +6 -6
  101. package/src/lib/svelte_preprocess_helpers.ts +42 -42
  102. package/src/lib/testing.ts +80 -0
  103. package/src/lib/time.ts +19 -19
  104. 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 - Array of times in nanoseconds
124
- * @returns Best unit to use for all values
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 - 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"
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 - Time in nanoseconds
174
- * @param decimals - Number of decimal places (default: 2)
175
- * @returns Formatted string like "3.87μs" or "1.23ms"
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 - Async function to time
220
- * @param timer - Timer to use (defaults to timer_default)
221
- * @returns Object containing the function result and timing information
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 - Sync function to time
256
- * @param timer - Timer to use (defaults to timer_default)
257
- * @returns Object containing the function result and timing information
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 - 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
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 Inner schema if wrapped, undefined otherwise.
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._zod.def;
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._zod.def.type === 'optional';
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._zod.def;
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._zod.def;
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._zod.def.type !== 'object') {
117
- const sub = zod_to_subschema(s._zod.def);
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 Description string or null if not found.
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 Default value or undefined.
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._zod;
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 Array of alias strings.
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 Human-readable type string.
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._zod;
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 - Value to format.
268
- * @returns Formatted string representation.
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 Array of property definitions.
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 Set of all names and aliases.
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();