performance-helpers 1.0.0 → 1.0.1
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/README.md +12 -2
- package/package.json +146 -1
- package/src/index.js +1 -0
- package/.eslintrc.cjs +0 -22
- package/.nojekyll +0 -0
- package/.prettierrc +0 -6
- package/CONTRIBUTING.md +0 -178
- package/assets/1_Caching.md +0 -4
- package/assets/2_Parallelizing.md +0 -18
- package/assets/3_Logging.md +0 -3
- package/assets/404.md +0 -3
- package/assets/4_Utils.md +0 -10
- package/assets/logo.png +0 -0
- package/assets/navigation.md +0 -10
- package/bench/README.md +0 -97
- package/bench/results.json +0 -94
- package/bench/results.md +0 -233
- package/bench/run.js +0 -2639
- package/bench/worker.js +0 -43
- package/docs/README.md +0 -38
- package/docs/docs-typedoc.json +0 -38714
- package/docs/helpers/constants/README.md +0 -34
- package/docs/helpers/constants/variables/DEFAULT_AUTOSCALE_BACKOFF_MAX_MULTIPLIER.md +0 -9
- package/docs/helpers/constants/variables/DEFAULT_AUTOSCALE_COOLDOWN_MS.md +0 -9
- package/docs/helpers/constants/variables/DEFAULT_AUTOSCALE_INTERVAL_MS.md +0 -9
- package/docs/helpers/constants/variables/DEFAULT_AUTOSCALE_MIN_INTERVAL_MS.md +0 -9
- package/docs/helpers/constants/variables/DEFAULT_BACKPRESSURE_QUEUE_CAPACITY.md +0 -9
- package/docs/helpers/constants/variables/DEFAULT_BACKPRESSURE_REFILL_INTERVAL_MS.md +0 -9
- package/docs/helpers/constants/variables/DEFAULT_BATCH_MAX_SIZE.md +0 -9
- package/docs/helpers/constants/variables/DEFAULT_CACHE_DEFAULT_TTL_MS.md +0 -9
- package/docs/helpers/constants/variables/DEFAULT_CACHE_MAX_POOL_SIZE.md +0 -9
- package/docs/helpers/constants/variables/DEFAULT_CACHE_MAX_WEIGHT_BYTES.md +0 -9
- package/docs/helpers/constants/variables/DEFAULT_HISTOGRAM_BUCKET_COUNT.md +0 -9
- package/docs/helpers/constants/variables/DEFAULT_HISTOGRAM_MAX_VALUE.md +0 -9
- package/docs/helpers/constants/variables/DEFAULT_MAX_CLEANUP_PER_TICK.md +0 -9
- package/docs/helpers/constants/variables/DEFAULT_QUEUE_CAPACITY.md +0 -9
- package/docs/helpers/constants/variables/DEFAULT_REAPER_MIN_INTERVAL_MS.md +0 -9
- package/docs/helpers/constants/variables/DEFAULT_REFILL_INTERVAL_MS.md +0 -9
- package/docs/helpers/constants/variables/DEFAULT_RETRY_BASE_DELAY_MS.md +0 -9
- package/docs/helpers/constants/variables/DEFAULT_RETRY_MAX_DELAY_MS.md +0 -9
- package/docs/helpers/constants/variables/DEFAULT_TIMEOUT_MS.md +0 -9
- package/docs/helpers/constants/variables/ENCODE_CACHE_LARGE_KEY_LENGTH.md +0 -9
- package/docs/helpers/constants/variables/MAX_DEEP_EQUAL_DEPTH.md +0 -9
- package/docs/helpers/constants/variables/MS_PER_MIN.md +0 -9
- package/docs/helpers/constants/variables/MS_PER_SEC.md +0 -9
- package/docs/helpers/constants/variables/default.md +0 -103
- package/docs/helpers/jsdoc-types/README.md +0 -33
- package/docs/helpers/jsdoc-types/interfaces/BufferDecoder.md +0 -23
- package/docs/helpers/jsdoc-types/interfaces/BufferEncoder.md +0 -23
- package/docs/helpers/jsdoc-types/interfaces/CacheNode.md +0 -43
- package/docs/helpers/jsdoc-types/interfaces/CommonPoolOptions.md +0 -31
- package/docs/helpers/jsdoc-types/interfaces/PendingResponseEntry.md +0 -51
- package/docs/helpers/jsdoc-types/interfaces/PostMessageOptions.md +0 -39
- package/docs/helpers/jsdoc-types/interfaces/PowerBatchOptions.md +0 -13
- package/docs/helpers/jsdoc-types/interfaces/PowerCacheOptions.md +0 -115
- package/docs/helpers/jsdoc-types/interfaces/PowerChunkingOptions.md +0 -31
- package/docs/helpers/jsdoc-types/interfaces/PowerCircuitOptions.md +0 -45
- package/docs/helpers/jsdoc-types/interfaces/PowerDeadlineOptions.md +0 -101
- package/docs/helpers/jsdoc-types/interfaces/PowerDeferOptions.md +0 -13
- package/docs/helpers/jsdoc-types/interfaces/PowerEventBusOptions.md +0 -19
- package/docs/helpers/jsdoc-types/interfaces/PowerLatchOptions.md +0 -23
- package/docs/helpers/jsdoc-types/interfaces/PowerLoggerOptions.md +0 -51
- package/docs/helpers/jsdoc-types/interfaces/PowerObserverOptions.md +0 -25
- package/docs/helpers/jsdoc-types/interfaces/PowerPoolOptions.md +0 -85
- package/docs/helpers/jsdoc-types/interfaces/PowerQueueOptions.md +0 -13
- package/docs/helpers/jsdoc-types/interfaces/PowerRetryOptions.md +0 -83
- package/docs/helpers/jsdoc-types/interfaces/PowerSlidingWindowOptions.md +0 -19
- package/docs/helpers/jsdoc-types/interfaces/PowerTTLMapOptions.md +0 -27
- package/docs/helpers/jsdoc-types/interfaces/PowerThrottleOptions.md +0 -31
- package/docs/helpers/jsdoc-types/interfaces/WorkerObj.md +0 -55
- package/docs/helpers/powerBackpressure/README.md +0 -17
- package/docs/helpers/powerBackpressure/classes/PowerBackpressure.md +0 -368
- package/docs/helpers/powerBatch/README.md +0 -17
- package/docs/helpers/powerBatch/classes/PowerBatch.md +0 -139
- package/docs/helpers/powerBuffer/README.md +0 -26
- package/docs/helpers/powerBuffer/functions/b2o.md +0 -25
- package/docs/helpers/powerBuffer/functions/o2b.md +0 -23
- package/docs/helpers/powerBuffer/functions/o2u8.md +0 -33
- package/docs/helpers/powerBuffer/functions/u82o.md +0 -30
- package/docs/helpers/powerBulkhead/README.md +0 -17
- package/docs/helpers/powerBulkhead/classes/PowerBulkhead.md +0 -302
- package/docs/helpers/powerCache/README.md +0 -29
- package/docs/helpers/powerCache/classes/PowerCache.md +0 -933
- package/docs/helpers/powerCache/classes/PowerMemoizer.md +0 -244
- package/docs/helpers/powerCache/classes/PowerTimedCache.md +0 -302
- package/docs/helpers/powerCache/functions/simpleArgsKey.md +0 -31
- package/docs/helpers/powerChunking/README.md +0 -17
- package/docs/helpers/powerChunking/classes/PowerChunker.md +0 -78
- package/docs/helpers/powerCircuit/README.md +0 -23
- package/docs/helpers/powerCircuit/classes/PowerCircuit.md +0 -167
- package/docs/helpers/powerDeadline/README.md +0 -23
- package/docs/helpers/powerDeadline/classes/PowerDeadline.md +0 -88
- package/docs/helpers/powerDefer/README.md +0 -17
- package/docs/helpers/powerDefer/classes/PowerDefer.md +0 -134
- package/docs/helpers/powerEventBus/README.md +0 -23
- package/docs/helpers/powerEventBus/classes/PowerEventBus.md +0 -330
- package/docs/helpers/powerHistogram/README.md +0 -17
- package/docs/helpers/powerHistogram/classes/PowerHistogram.md +0 -285
- package/docs/helpers/powerLatch/README.md +0 -17
- package/docs/helpers/powerLatch/classes/PowerLatch.md +0 -264
- package/docs/helpers/powerLogger/README.md +0 -17
- package/docs/helpers/powerLogger/classes/PowerLogger.md +0 -290
- package/docs/helpers/powerObserver/README.md +0 -23
- package/docs/helpers/powerObserver/classes/PowerObserver.md +0 -213
- package/docs/helpers/powerPermitGate/README.md +0 -11
- package/docs/helpers/powerPermitGate/classes/PowerPermitGate.md +0 -248
- package/docs/helpers/powerPool/README.md +0 -36
- package/docs/helpers/powerPool/classes/PowerPool.md +0 -973
- package/docs/helpers/powerPool/classes/PowerPoolShutdownError.md +0 -67
- package/docs/helpers/powerQueue/README.md +0 -11
- package/docs/helpers/powerQueue/classes/PowerQueue.md +0 -302
- package/docs/helpers/powerRateLimit/README.md +0 -17
- package/docs/helpers/powerRateLimit/classes/PowerRateLimit.md +0 -187
- package/docs/helpers/powerRetry/README.md +0 -23
- package/docs/helpers/powerRetry/classes/PowerRetry.md +0 -106
- package/docs/helpers/powerScheduler/README.md +0 -11
- package/docs/helpers/powerScheduler/classes/PowerScheduler.md +0 -135
- package/docs/helpers/powerSemaphore/README.md +0 -17
- package/docs/helpers/powerSemaphore/classes/PowerSemaphore.md +0 -173
- package/docs/helpers/powerSlidingWindow/README.md +0 -11
- package/docs/helpers/powerSlidingWindow/classes/PowerSlidingWindow.md +0 -83
- package/docs/helpers/powerSubscriberSet/README.md +0 -15
- package/docs/helpers/powerSubscriberSet/classes/PowerSubscriberSet.md +0 -251
- package/docs/helpers/powerSubscriberSet/functions/cleanupWeakRefs.md +0 -21
- package/docs/helpers/powerTTLMap/README.md +0 -17
- package/docs/helpers/powerTTLMap/classes/PowerTTLMap.md +0 -326
- package/docs/helpers/powerThrottle/README.md +0 -17
- package/docs/helpers/powerThrottle/classes/PowerThrottle.md +0 -216
- package/docs/index/README.md +0 -205
- package/docs/utils/errors/README.md +0 -12
- package/docs/utils/errors/functions/formatErrorObj.md +0 -30
- package/docs/utils/errors/functions/normalizeError.md +0 -50
- package/docs/utils/now/README.md +0 -19
- package/docs/utils/now/functions/measureAsync.md +0 -37
- package/docs/utils/now/functions/measureSync.md +0 -54
- package/docs/utils/now/functions/nowMs.md +0 -24
- package/guides/autoscale.md +0 -80
- package/guides/errors.md +0 -41
- package/guides/metaGuide.md +0 -440
- package/guides/now.md +0 -56
- package/guides/powerBackpressure.md +0 -110
- package/guides/powerBatch.md +0 -82
- package/guides/powerBuffer.md +0 -86
- package/guides/powerBulkhead.md +0 -61
- package/guides/powerCache.md +0 -269
- package/guides/powerChunking.md +0 -130
- package/guides/powerCircuit.md +0 -84
- package/guides/powerDeadline.md +0 -99
- package/guides/powerDefer.md +0 -56
- package/guides/powerEventBus.md +0 -89
- package/guides/powerHistogram.md +0 -71
- package/guides/powerLatch.md +0 -94
- package/guides/powerLogger.md +0 -129
- package/guides/powerObserver.md +0 -65
- package/guides/powerPermitGate.md +0 -52
- package/guides/powerPool.md +0 -321
- package/guides/powerQueue.md +0 -112
- package/guides/powerRateLimit.md +0 -37
- package/guides/powerRetry.md +0 -54
- package/guides/powerScheduler.md +0 -41
- package/guides/powerSemaphore.md +0 -65
- package/guides/powerSlidingWindow.md +0 -63
- package/guides/powerSubscriberSet.md +0 -48
- package/guides/powerTTLMap.md +0 -58
- package/guides/powerThrottle.md +0 -152
- package/index.html +0 -57
- package/results.json +0 -6692
- package/scripts/find-missing-jsdoc.js +0 -62
- package/scripts/modernize-optional-chaining.cjs +0 -36
- package/scripts/pool-debug.mjs +0 -29
- package/scripts/repro_powercache.js +0 -14
- package/scripts/static-audit-exports.cjs +0 -93
- package/scripts/static-audit-exports.json +0 -518
- package/test/powerBackpressure.test.js +0 -114
- package/test/powerBatch.branches.extra.test.js +0 -122
- package/test/powerBatch.test.js +0 -79
- package/test/powerBuffer.test.js +0 -125
- package/test/powerBulkhead.test.js +0 -210
- package/test/powerCache.branches.test.js +0 -233
- package/test/powerCache.bulk.test.js +0 -31
- package/test/powerCache.getorset.test.js +0 -110
- package/test/powerCache.hitRate.test.js +0 -35
- package/test/powerCache.inflight.test.js +0 -24
- package/test/powerCache.iterator.test.js +0 -18
- package/test/powerCache.misses.test.js +0 -52
- package/test/powerCache.more.test.js +0 -118
- package/test/powerCache.test.js +0 -37
- package/test/powerCache.timeout.test.js +0 -25
- package/test/powerCache.touch.test.js +0 -46
- package/test/powerChunking.branches.extra.test.js +0 -155
- package/test/powerChunking.errors.test.js +0 -177
- package/test/powerChunking.test.js +0 -39
- package/test/powerCircuit.observability.test.js +0 -71
- package/test/powerCircuit.test.js +0 -74
- package/test/powerDeadline.test.js +0 -140
- package/test/powerDefer.test.js +0 -55
- package/test/powerErrors.test.js +0 -32
- package/test/powerEventBus.branches.extra.test.js +0 -70
- package/test/powerEventBus.extra.test.js +0 -72
- package/test/powerEventBus.max.test.js +0 -43
- package/test/powerEventBus.more.test.js +0 -121
- package/test/powerEventBus.once_off.test.js +0 -17
- package/test/powerEventBus.test.js +0 -74
- package/test/powerEventBus.uncovered.test.js +0 -57
- package/test/powerEventBus.weak.test.js +0 -18
- package/test/powerHistogram.test.js +0 -73
- package/test/powerLatch.branches.extra.test.js +0 -115
- package/test/powerLatch.test.js +0 -57
- package/test/powerLogger.branches.test.js +0 -98
- package/test/powerLogger.formatter.name.test.js +0 -58
- package/test/powerLogger.json.test.js +0 -88
- package/test/powerLogger.output.test.js +0 -81
- package/test/powerLogger.table.debug.test.js +0 -77
- package/test/powerLogger.test.js +0 -59
- package/test/powerMemoizer.memoize.test.js +0 -100
- package/test/powerMemoizer.test.js +0 -85
- package/test/powerObserver.test.js +0 -129
- package/test/powerPermitGate.test.js +0 -66
- package/test/powerPool.autoTransfer.test.js +0 -100
- package/test/powerPool.autoscale.extra.test.js +0 -88
- package/test/powerPool.autoscale.test.js +0 -136
- package/test/powerPool.awaitDefaultTimeout.test.js +0 -52
- package/test/powerPool.awaitTimeout.test.js +0 -22
- package/test/powerPool.batch.test.js +0 -170
- package/test/powerPool.branches.extra2.test.js +0 -42
- package/test/powerPool.branches.test.js +0 -102
- package/test/powerPool.browser.messageerror.test.js +0 -45
- package/test/powerPool.correlation.test.js +0 -26
- package/test/powerPool.correlationId.test.js +0 -63
- package/test/powerPool.dispose.test.js +0 -49
- package/test/powerPool.drain.test.js +0 -57
- package/test/powerPool.events.test.js +0 -131
- package/test/powerPool.more.extra.test.js +0 -99
- package/test/powerPool.more.test.js +0 -283
- package/test/powerPool.node.messageerror.test.js +0 -46
- package/test/powerPool.postMessage.promise.test.js +0 -83
- package/test/powerPool.queueHigh.test.js +0 -55
- package/test/powerPool.queueSaturation.test.js +0 -51
- package/test/powerPool.rapidResize.test.js +0 -55
- package/test/powerPool.resize.overload.test.js +0 -65
- package/test/powerPool.resize.test.js +0 -70
- package/test/powerPool.shutdown.test.js +0 -38
- package/test/powerPool.stats.test.js +0 -40
- package/test/powerPool.stopThePress.test.js +0 -94
- package/test/powerPool.terminateShutdown.test.js +0 -22
- package/test/powerPool.test.js +0 -525
- package/test/powerPool.timers.test.js +0 -55
- package/test/powerPool.uncovered.test.js +0 -407
- package/test/powerPool.workerId.test.js +0 -47
- package/test/powerQueue.iterators.test.js +0 -67
- package/test/powerQueue.saturation.test.js +0 -18
- package/test/powerQueue.test.js +0 -48
- package/test/powerQueue.unshiftMany.test.js +0 -49
- package/test/powerRateLimit.atomic.test.js +0 -80
- package/test/powerRateLimit.extra.test.js +0 -145
- package/test/powerRateLimit.functions.test.js +0 -106
- package/test/powerRateLimit.test.js +0 -38
- package/test/powerRetry.attemptTimeout.test.js +0 -51
- package/test/powerRetry.test.js +0 -121
- package/test/powerScheduler.test.js +0 -126
- package/test/powerSemaphore.test.js +0 -108
- package/test/powerSlidingWindow.pool.test.js +0 -55
- package/test/powerSlidingWindow.test.js +0 -25
- package/test/powerSubscriberSet.test.js +0 -125
- package/test/powerTTLMap.test.js +0 -125
- package/test/powerThrottle.pool.test.js +0 -54
- package/test/powerThrottle.refill.test.js +0 -22
- package/test/powerThrottle.reserve.test.js +0 -46
- package/test/powerThrottle.test.js +0 -45
- package/test/powerTimedCache.test.js +0 -73
- package/test/umd.bundle.branches.test.js +0 -100
- package/test/umd.bundle.cache-timers.test.js +0 -48
- package/test/umd.bundle.exhaustive.test.js +0 -158
- package/test/umd.bundle.fuzz.test.js +0 -86
- package/test/umd.bundle.hasEqual.more.test.js +0 -68
- package/test/umd.bundle.hasEqual.test.js +0 -104
- package/test/umd.bundle.logger-extra.test.js +0 -48
- package/test/umd.bundle.more-coverage-2.test.js +0 -67
- package/test/umd.bundle.pool.test.js +0 -134
- package/test/umd.bundle.test.js +0 -265
- package/test/utils.measure.test.js +0 -49
- package/test/utils.now.extra.test.js +0 -30
- package/test/utils.now.more.test.js +0 -57
- package/tsconfig.json +0 -16
- package/typedoc.json +0 -25
- package/vite.config.js +0 -31
- package/vitest.config.js +0 -17
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi } from 'vitest';
|
|
2
|
-
import { PowerLatch } from '../src/helpers/powerLatch.js';
|
|
3
|
-
|
|
4
|
-
describe('PowerLatch branches extra', () => {
|
|
5
|
-
it('decrementUnlessZero returns 0 when already zero', () => {
|
|
6
|
-
const l = new PowerLatch(0);
|
|
7
|
-
expect(l.decrementUnlessZero()).toBe(0);
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
it('countDown with zero returns without changing', () => {
|
|
11
|
-
const l = new PowerLatch(2);
|
|
12
|
-
expect(l.countDown(0)).toBe(2);
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
it('wait with timeout rejects with ETIMEOUT', async () => {
|
|
16
|
-
const l = new PowerLatch(1);
|
|
17
|
-
await expect(l.wait(5)).rejects.toHaveProperty('code', 'ETIMEOUT');
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
it('abort rejects waiters and calls onAbort', async () => {
|
|
21
|
-
const onAbort = jestFn();
|
|
22
|
-
const l = new PowerLatch(1, { onAbort });
|
|
23
|
-
const p = l.wait();
|
|
24
|
-
l.abort(new Error('fail'));
|
|
25
|
-
await expect(p).rejects.toBeTruthy();
|
|
26
|
-
expect(onAbort.called).toBe(true);
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
it('wait with signal rejects when signal aborted', async () => {
|
|
30
|
-
const l = new PowerLatch(1);
|
|
31
|
-
const ac = new AbortController();
|
|
32
|
-
const p = l.wait({ signal: ac.signal });
|
|
33
|
-
ac.abort();
|
|
34
|
-
await expect(p).rejects.toSatisfy((err) => {
|
|
35
|
-
if (!err) return false;
|
|
36
|
-
if (err && err.code === 'EABORT') return true;
|
|
37
|
-
if (err && (err.name === 'AbortError' || /abort/i.test(String(err.message)))) return true;
|
|
38
|
-
return false;
|
|
39
|
-
});
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
it('wait rejects immediately when provided signal is already aborted', async () => {
|
|
43
|
-
const l = new PowerLatch(1);
|
|
44
|
-
const ac = new AbortController();
|
|
45
|
-
ac.abort(new Error('already aborted'));
|
|
46
|
-
|
|
47
|
-
await expect(l.wait({ signal: ac.signal, timeout: 30 })).rejects.toSatisfy((err) => {
|
|
48
|
-
if (!err) return false;
|
|
49
|
-
if (err && (err.code === 'EABORT' || /abort/i.test(String(err.message)))) return true;
|
|
50
|
-
return false;
|
|
51
|
-
});
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
it('reset clears aborted state and resolves when count set to zero', async () => {
|
|
55
|
-
const l = new PowerLatch(1);
|
|
56
|
-
const p = l.wait();
|
|
57
|
-
l.abort(new Error('x'));
|
|
58
|
-
await expect(p).rejects.toBeTruthy();
|
|
59
|
-
// reset to zero should resolve new waiters
|
|
60
|
-
l.reset(0);
|
|
61
|
-
await expect(l.wait()).resolves.toBeUndefined();
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
it('wait rejects immediately after abort with default abort error and reset restores normal waiting', async () => {
|
|
65
|
-
const l = new PowerLatch(2);
|
|
66
|
-
l.abort();
|
|
67
|
-
|
|
68
|
-
await expect(l.wait()).rejects.toMatchObject({ code: 'EABORT' });
|
|
69
|
-
|
|
70
|
-
l.reset(1);
|
|
71
|
-
const waiter = l.wait();
|
|
72
|
-
l.countDown();
|
|
73
|
-
await expect(waiter).resolves.toBeUndefined();
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
it('removes abort listeners when a waiter resolves normally', async () => {
|
|
77
|
-
const addEventListener = vi.fn();
|
|
78
|
-
const removeEventListener = vi.fn();
|
|
79
|
-
const signal = {
|
|
80
|
-
aborted: false,
|
|
81
|
-
reason: undefined,
|
|
82
|
-
addEventListener,
|
|
83
|
-
removeEventListener,
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
const l = new PowerLatch(1);
|
|
87
|
-
const waiter = l.wait({ signal, timeout: 50 });
|
|
88
|
-
l.countDown();
|
|
89
|
-
await waiter;
|
|
90
|
-
|
|
91
|
-
expect(addEventListener).toHaveBeenCalledWith('abort', expect.any(Function), { once: true });
|
|
92
|
-
expect(removeEventListener).toHaveBeenCalledWith('abort', expect.any(Function));
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
it('swallows errors from onAbort callbacks', () => {
|
|
96
|
-
const l = new PowerLatch(1, {
|
|
97
|
-
onAbort() {
|
|
98
|
-
throw new Error('abort hook failed');
|
|
99
|
-
},
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
expect(() => l.abort(new Error('stop'))).not.toThrow();
|
|
103
|
-
});
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
// small helper to simulate jest-like spy without adding deps
|
|
107
|
-
function jestFn() {
|
|
108
|
-
const fn = function (reason) {
|
|
109
|
-
fn.called = true;
|
|
110
|
-
fn.last = reason;
|
|
111
|
-
};
|
|
112
|
-
fn.called = false;
|
|
113
|
-
fn.last = undefined;
|
|
114
|
-
return fn;
|
|
115
|
-
}
|
package/test/powerLatch.test.js
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { PowerLatch } from '../src/helpers/powerLatch.js';
|
|
3
|
-
|
|
4
|
-
describe('PowerLatch', () => {
|
|
5
|
-
it('resolves wait when countDown called enough times', async () => {
|
|
6
|
-
const latch = new PowerLatch(2);
|
|
7
|
-
let done = false;
|
|
8
|
-
const p = latch.wait().then(() => {
|
|
9
|
-
done = true;
|
|
10
|
-
});
|
|
11
|
-
latch.countDown();
|
|
12
|
-
expect(done).toBe(false);
|
|
13
|
-
latch.countDown();
|
|
14
|
-
await p;
|
|
15
|
-
expect(done).toBe(true);
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
it('wait resolves immediately when count is zero', async () => {
|
|
19
|
-
const latch = new PowerLatch(0);
|
|
20
|
-
await expect(latch.wait()).resolves.toBeUndefined();
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
it('reset to zero resolves pending waiters', async () => {
|
|
24
|
-
const latch = new PowerLatch(2);
|
|
25
|
-
const p = latch.wait();
|
|
26
|
-
latch.reset(0);
|
|
27
|
-
await expect(p).resolves.toBeUndefined();
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
it('wait rejects on timeout', async () => {
|
|
31
|
-
const latch = new PowerLatch(1);
|
|
32
|
-
const p = latch.wait(10);
|
|
33
|
-
// do not count down
|
|
34
|
-
await expect(p).rejects.toHaveProperty('code', 'ETIMEOUT');
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
it('abort rejects pending waiters', async () => {
|
|
38
|
-
const latch = new PowerLatch(1);
|
|
39
|
-
const p = latch.wait();
|
|
40
|
-
latch.abort(new Error('bye'));
|
|
41
|
-
await expect(p).rejects.toThrow('bye');
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
it('static one factory works', async () => {
|
|
45
|
-
const l = PowerLatch.one();
|
|
46
|
-
expect(l.remaining).toBe(1);
|
|
47
|
-
l.countDown();
|
|
48
|
-
await expect(l.wait()).resolves.toBeUndefined();
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
it('decrementUnlessZero avoids negative', () => {
|
|
52
|
-
const l = new PowerLatch(0);
|
|
53
|
-
expect(l.decrementUnlessZero()).toBe(0);
|
|
54
|
-
const l2 = new PowerLatch(2);
|
|
55
|
-
expect(l2.decrementUnlessZero()).toBe(1);
|
|
56
|
-
});
|
|
57
|
-
});
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi } from 'vitest';
|
|
2
|
-
import * as PowerLoggerModule from '../src/helpers/powerLogger.js';
|
|
3
|
-
|
|
4
|
-
const getCtor = (mod) => {
|
|
5
|
-
if (typeof mod === 'function') return mod;
|
|
6
|
-
if (mod && typeof mod.default === 'function') return mod.default;
|
|
7
|
-
if (mod && typeof mod.PowerLogger === 'function') return mod.PowerLogger;
|
|
8
|
-
throw new Error('PowerLogger constructor not found');
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
describe('PowerLogger branch coverage', () => {
|
|
12
|
-
it('does not expose legacy global helpers', () => {
|
|
13
|
-
const Ctor = getCtor(PowerLoggerModule);
|
|
14
|
-
const logger = new Ctor(0);
|
|
15
|
-
expect(typeof logger.hasLegacyDebug).toBe('undefined');
|
|
16
|
-
expect(typeof logger.syncLegacyCounter).toBe('undefined');
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
it('debug helpers accept function args (lazy evaluation)', () => {
|
|
20
|
-
const Ctor = getCtor(PowerLoggerModule);
|
|
21
|
-
const logger = new Ctor(0);
|
|
22
|
-
const side = { called: false };
|
|
23
|
-
const fn = () => {
|
|
24
|
-
side.called = true;
|
|
25
|
-
return 'ok';
|
|
26
|
-
};
|
|
27
|
-
const spy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
28
|
-
logger.setDebugLevel(1);
|
|
29
|
-
logger.error(fn);
|
|
30
|
-
expect(side.called).toBe(true);
|
|
31
|
-
spy.mockRestore();
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
it('setDebugLevel handles thrown-toString gracefully', () => {
|
|
35
|
-
const Ctor = getCtor(PowerLoggerModule);
|
|
36
|
-
const logger = new Ctor(0);
|
|
37
|
-
// craft an object that throws when coerced
|
|
38
|
-
const bad = {
|
|
39
|
-
toString() {
|
|
40
|
-
throw new Error('bad');
|
|
41
|
-
},
|
|
42
|
-
};
|
|
43
|
-
logger.setDebugLevel(bad);
|
|
44
|
-
expect(logger.getDebugLevel()).toBe(0);
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it('debug methods swallow exceptions thrown by lazy args and handle missing console methods', () => {
|
|
48
|
-
const Ctor = getCtor(PowerLoggerModule);
|
|
49
|
-
const logger = new Ctor(3);
|
|
50
|
-
|
|
51
|
-
// lazy arg that throws should be swallowed
|
|
52
|
-
const badFn = () => {
|
|
53
|
-
throw new Error('boom');
|
|
54
|
-
};
|
|
55
|
-
// spy console methods so we don't clutter output
|
|
56
|
-
const spyErr = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
57
|
-
const spyWarn = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
58
|
-
const spyInfo = vi.spyOn(console, 'info').mockImplementation(() => {});
|
|
59
|
-
const spyLog = vi.spyOn(console, 'log').mockImplementation(() => {});
|
|
60
|
-
|
|
61
|
-
expect(() => logger.error(badFn)).not.toThrow();
|
|
62
|
-
expect(() => logger.warn(badFn)).not.toThrow();
|
|
63
|
-
expect(() => logger.info(badFn)).not.toThrow();
|
|
64
|
-
expect(() => logger.log(badFn)).not.toThrow();
|
|
65
|
-
|
|
66
|
-
spyErr.mockRestore();
|
|
67
|
-
spyWarn.mockRestore();
|
|
68
|
-
spyInfo.mockRestore();
|
|
69
|
-
spyLog.mockRestore();
|
|
70
|
-
|
|
71
|
-
// simulate missing console method (warn) - should simply return
|
|
72
|
-
const origWarn = console.warn;
|
|
73
|
-
try {
|
|
74
|
-
// @ts-ignore
|
|
75
|
-
console.warn = undefined;
|
|
76
|
-
expect(() => logger.warn('x')).not.toThrow();
|
|
77
|
-
} finally {
|
|
78
|
-
console.warn = origWarn;
|
|
79
|
-
}
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
it('setDebugLevel coerces boxed primitives and incrementCounter ignores empty names when disabled', () => {
|
|
83
|
-
const Ctor = getCtor(PowerLoggerModule);
|
|
84
|
-
const logger = new Ctor(0);
|
|
85
|
-
|
|
86
|
-
logger.setDebugLevel(new String('3'));
|
|
87
|
-
expect(logger.getDebugLevel()).toBe(3);
|
|
88
|
-
|
|
89
|
-
logger.setDebugLevel(new Boolean(false));
|
|
90
|
-
expect(logger.getDebugLevel()).toBe(0);
|
|
91
|
-
|
|
92
|
-
logger.incrementCounter('ignored');
|
|
93
|
-
logger.setDebugLevel(3);
|
|
94
|
-
logger.incrementCounter('');
|
|
95
|
-
logger.incrementCounter(null);
|
|
96
|
-
expect(logger.getDebugCounters()).toEqual({});
|
|
97
|
-
});
|
|
98
|
-
});
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi } from 'vitest';
|
|
2
|
-
import { PowerLogger } from '../src/helpers/powerLogger.js';
|
|
3
|
-
|
|
4
|
-
describe('PowerLogger formatter and name option', () => {
|
|
5
|
-
it('includes name in JSON payload when provided', () => {
|
|
6
|
-
const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
|
7
|
-
try {
|
|
8
|
-
const logger = new PowerLogger(3, { format: 'json', name: 'my-logger' });
|
|
9
|
-
logger.log('hello');
|
|
10
|
-
expect(logSpy).toHaveBeenCalled();
|
|
11
|
-
const parsed = JSON.parse(logSpy.mock.calls[0][0]);
|
|
12
|
-
expect(parsed.level).toBe('log');
|
|
13
|
-
expect(parsed.name).toBe('my-logger');
|
|
14
|
-
expect(parsed.msg).toBe('hello');
|
|
15
|
-
} finally {
|
|
16
|
-
logSpy.mockRestore();
|
|
17
|
-
}
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
it('calls formatter when provided and uses its return value as payload', () => {
|
|
21
|
-
const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
|
22
|
-
try {
|
|
23
|
-
const formatter = (payload) => ({
|
|
24
|
-
l: payload.level,
|
|
25
|
-
n: payload.name || null,
|
|
26
|
-
m: payload.msg,
|
|
27
|
-
});
|
|
28
|
-
const logger = new PowerLogger(3, { format: 'json', name: 'x', formatter });
|
|
29
|
-
const infoSpy = vi.spyOn(console, 'info').mockImplementation(() => {});
|
|
30
|
-
try {
|
|
31
|
-
logger.info('y');
|
|
32
|
-
expect(infoSpy).toHaveBeenCalled();
|
|
33
|
-
const parsed = JSON.parse(infoSpy.mock.calls[0][0]);
|
|
34
|
-
expect(parsed.l).toBe('info');
|
|
35
|
-
expect(parsed.n).toBe('x');
|
|
36
|
-
expect(parsed.m).toBe('y');
|
|
37
|
-
} finally {
|
|
38
|
-
infoSpy.mockRestore();
|
|
39
|
-
}
|
|
40
|
-
} finally {
|
|
41
|
-
logSpy.mockRestore();
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
it('allows formatter to return a string directly', () => {
|
|
46
|
-
const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
|
47
|
-
try {
|
|
48
|
-
const formatter = (payload) => `${payload.level}:${payload.msg}`;
|
|
49
|
-
const logger = new PowerLogger(3, { format: 'json', name: 'x', formatter });
|
|
50
|
-
logger.log('z');
|
|
51
|
-
expect(logSpy).toHaveBeenCalled();
|
|
52
|
-
const emitted = logSpy.mock.calls[0][0];
|
|
53
|
-
expect(emitted).toBe('log:z');
|
|
54
|
-
} finally {
|
|
55
|
-
logSpy.mockRestore();
|
|
56
|
-
}
|
|
57
|
-
});
|
|
58
|
-
});
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi } from 'vitest';
|
|
2
|
-
import { PowerLogger } from '../src/helpers/powerLogger.js';
|
|
3
|
-
|
|
4
|
-
describe('PowerLogger JSON output mode', () => {
|
|
5
|
-
it('emits JSON on error/warn/info/log when format=json', () => {
|
|
6
|
-
const errSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
7
|
-
const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
8
|
-
const infoSpy = vi.spyOn(console, 'info').mockImplementation(() => {});
|
|
9
|
-
const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
|
10
|
-
|
|
11
|
-
try {
|
|
12
|
-
const logger = new PowerLogger(3, { format: 'json' });
|
|
13
|
-
logger.error('err-msg');
|
|
14
|
-
logger.warn({ a: 1 });
|
|
15
|
-
logger.info(() => 'info-msg');
|
|
16
|
-
logger.log('one', 'two');
|
|
17
|
-
|
|
18
|
-
expect(errSpy).toHaveBeenCalled();
|
|
19
|
-
expect(warnSpy).toHaveBeenCalled();
|
|
20
|
-
expect(infoSpy).toHaveBeenCalled();
|
|
21
|
-
expect(logSpy).toHaveBeenCalled();
|
|
22
|
-
|
|
23
|
-
const parsed = JSON.parse(errSpy.mock.calls[0][0]);
|
|
24
|
-
expect(parsed.level).toBe('error');
|
|
25
|
-
expect(parsed.msg).toBe('err-msg');
|
|
26
|
-
expect(typeof parsed.ts).toBe('number');
|
|
27
|
-
|
|
28
|
-
const parsedWarn = JSON.parse(warnSpy.mock.calls[0][0]);
|
|
29
|
-
expect(parsedWarn.level).toBe('warn');
|
|
30
|
-
expect(parsedWarn.msg).toEqual({ a: 1 });
|
|
31
|
-
|
|
32
|
-
const parsedInfo = JSON.parse(infoSpy.mock.calls[0][0]);
|
|
33
|
-
expect(parsedInfo.level).toBe('info');
|
|
34
|
-
expect(parsedInfo.msg).toBe('info-msg');
|
|
35
|
-
|
|
36
|
-
const parsedLog = JSON.parse(logSpy.mock.calls[0][0]);
|
|
37
|
-
expect(parsedLog.level).toBe('log');
|
|
38
|
-
expect(Array.isArray(parsedLog.msg)).toBe(true);
|
|
39
|
-
expect(parsedLog.msg).toEqual(['one', 'two']);
|
|
40
|
-
} finally {
|
|
41
|
-
errSpy.mockRestore();
|
|
42
|
-
warnSpy.mockRestore();
|
|
43
|
-
infoSpy.mockRestore();
|
|
44
|
-
logSpy.mockRestore();
|
|
45
|
-
}
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
it('falls back to plain console arguments when JSON serialization fails', () => {
|
|
49
|
-
const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
|
50
|
-
|
|
51
|
-
try {
|
|
52
|
-
const circular = {};
|
|
53
|
-
circular.self = circular;
|
|
54
|
-
const logger = new PowerLogger(3, { format: 'json' });
|
|
55
|
-
|
|
56
|
-
logger.log(circular, 'tail');
|
|
57
|
-
|
|
58
|
-
expect(logSpy).toHaveBeenCalled();
|
|
59
|
-
// When JSON serialization contains circular references we now
|
|
60
|
-
// emit a safe JSON string (circulars replaced) instead of passing
|
|
61
|
-
// original args to the console. Verify the emitted JSON contains
|
|
62
|
-
// the safe representation and preserves additional args.
|
|
63
|
-
const out = logSpy.mock.calls[0][0];
|
|
64
|
-
const parsed = JSON.parse(out);
|
|
65
|
-
expect(parsed.level).toBe('log');
|
|
66
|
-
expect(parsed.msg[0]).toEqual({ self: '[Circular]' });
|
|
67
|
-
expect(parsed.msg[1]).toBe('tail');
|
|
68
|
-
} finally {
|
|
69
|
-
logSpy.mockRestore();
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
it('normalizes error-like payloads in error()', () => {
|
|
74
|
-
const errSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
75
|
-
|
|
76
|
-
try {
|
|
77
|
-
const logger = new PowerLogger(1, { format: 'json' });
|
|
78
|
-
logger.error({ error: true, code: 'E_TEST', message: 'broken' });
|
|
79
|
-
|
|
80
|
-
expect(errSpy).toHaveBeenCalled();
|
|
81
|
-
const parsed = JSON.parse(errSpy.mock.calls[0][0]);
|
|
82
|
-
expect(parsed.level).toBe('error');
|
|
83
|
-
expect(parsed.msg).toBe('E_TEST: broken');
|
|
84
|
-
} finally {
|
|
85
|
-
errSpy.mockRestore();
|
|
86
|
-
}
|
|
87
|
-
});
|
|
88
|
-
});
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi } from 'vitest';
|
|
2
|
-
import { PowerLogger } from '../src/helpers/powerLogger.js';
|
|
3
|
-
|
|
4
|
-
describe('PowerLogger output transport', () => {
|
|
5
|
-
it('calls provided output(payload) instead of console', () => {
|
|
6
|
-
const out = vi.fn();
|
|
7
|
-
const logger = new PowerLogger(3, { format: 'json', name: 't1', output: out });
|
|
8
|
-
logger.info('hello', { a: 1 });
|
|
9
|
-
expect(out).toHaveBeenCalled();
|
|
10
|
-
const payload = out.mock.calls[0][0];
|
|
11
|
-
expect(payload).toHaveProperty('level', 'info');
|
|
12
|
-
expect(payload).toHaveProperty('msg');
|
|
13
|
-
expect(payload).toHaveProperty('ts');
|
|
14
|
-
expect(payload).toHaveProperty('name', 't1');
|
|
15
|
-
expect(payload).toHaveProperty('format', 'json');
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
it('formatter can modify payload passed to output', () => {
|
|
19
|
-
const out = vi.fn();
|
|
20
|
-
const logger = new PowerLogger(3, {
|
|
21
|
-
format: 'json',
|
|
22
|
-
name: 't2',
|
|
23
|
-
output: out,
|
|
24
|
-
formatter: (p) => ({ lvl: p.level, m: p.msg, t: p.ts, nm: p.name }),
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
logger.error('oops');
|
|
28
|
-
expect(out).toHaveBeenCalled();
|
|
29
|
-
const payload = out.mock.calls[0][0];
|
|
30
|
-
expect(payload).toHaveProperty('lvl', 'error');
|
|
31
|
-
expect(payload).toHaveProperty('m');
|
|
32
|
-
expect(payload).toHaveProperty('t');
|
|
33
|
-
expect(payload).toHaveProperty('nm', 't2');
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
it('swallows output transport errors', () => {
|
|
37
|
-
const logger = new PowerLogger(3, {
|
|
38
|
-
format: 'json',
|
|
39
|
-
output() {
|
|
40
|
-
throw new Error('transport failed');
|
|
41
|
-
},
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
expect(() => logger.info('safe')).not.toThrow();
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it('falls back to the original payload when formatter throws', () => {
|
|
48
|
-
const out = vi.fn();
|
|
49
|
-
const logger = new PowerLogger(3, {
|
|
50
|
-
format: 'json',
|
|
51
|
-
name: 'fallback',
|
|
52
|
-
output: out,
|
|
53
|
-
formatter() {
|
|
54
|
-
throw new Error('formatter failed');
|
|
55
|
-
},
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
logger.warn('hello');
|
|
59
|
-
|
|
60
|
-
expect(out).toHaveBeenCalled();
|
|
61
|
-
expect(out.mock.calls[0][0]).toMatchObject({
|
|
62
|
-
level: 'warn',
|
|
63
|
-
msg: 'hello',
|
|
64
|
-
format: 'json',
|
|
65
|
-
name: 'fallback',
|
|
66
|
-
});
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
it('passes formatter strings directly to output transports', () => {
|
|
70
|
-
const out = vi.fn();
|
|
71
|
-
const logger = new PowerLogger(3, {
|
|
72
|
-
format: 'json',
|
|
73
|
-
output: out,
|
|
74
|
-
formatter: (payload) => `${payload.level}:${payload.msg}`,
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
logger.info('transport-string');
|
|
78
|
-
|
|
79
|
-
expect(out).toHaveBeenCalledWith('info:transport-string');
|
|
80
|
-
});
|
|
81
|
-
});
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi } from 'vitest';
|
|
2
|
-
import { PowerLogger } from '../src/helpers/powerLogger.js';
|
|
3
|
-
|
|
4
|
-
describe('PowerLogger table and debug methods', () => {
|
|
5
|
-
it('calls console.debug when debug() invoked and level>=3', () => {
|
|
6
|
-
const debugSpy = vi.spyOn(console, 'debug').mockImplementation(() => {});
|
|
7
|
-
try {
|
|
8
|
-
const logger = new PowerLogger(3);
|
|
9
|
-
logger.debug('x', 1);
|
|
10
|
-
expect(debugSpy).toHaveBeenCalled();
|
|
11
|
-
const callArgs = debugSpy.mock.calls[0];
|
|
12
|
-
expect(callArgs[0]).toBe('x');
|
|
13
|
-
expect(callArgs[1]).toBe(1);
|
|
14
|
-
} finally {
|
|
15
|
-
debugSpy.mockRestore();
|
|
16
|
-
}
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
it('emits JSON for debug() when format=json', () => {
|
|
20
|
-
const debugSpy = vi.spyOn(console, 'debug').mockImplementation(() => {});
|
|
21
|
-
try {
|
|
22
|
-
const logger = new PowerLogger(3, { format: 'json' });
|
|
23
|
-
logger.debug({ a: 1 });
|
|
24
|
-
expect(debugSpy).toHaveBeenCalled();
|
|
25
|
-
const parsed = JSON.parse(debugSpy.mock.calls[0][0]);
|
|
26
|
-
expect(parsed.level).toBe('debug');
|
|
27
|
-
expect(parsed.msg).toEqual({ a: 1 });
|
|
28
|
-
expect(typeof parsed.ts).toBe('number');
|
|
29
|
-
} finally {
|
|
30
|
-
debugSpy.mockRestore();
|
|
31
|
-
}
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
it('uses console.table when available for table()', () => {
|
|
35
|
-
const tableSpy = vi.spyOn(console, 'table').mockImplementation(() => {});
|
|
36
|
-
try {
|
|
37
|
-
const logger = new PowerLogger(3);
|
|
38
|
-
const data = [{ a: 1 }, { a: 2 }];
|
|
39
|
-
logger.table(data);
|
|
40
|
-
expect(tableSpy).toHaveBeenCalled();
|
|
41
|
-
expect(tableSpy.mock.calls[0][0]).toBe(data);
|
|
42
|
-
} finally {
|
|
43
|
-
tableSpy.mockRestore();
|
|
44
|
-
}
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it('emits JSON for table() when format=json', () => {
|
|
48
|
-
const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
|
49
|
-
try {
|
|
50
|
-
const logger = new PowerLogger(3, { format: 'json' });
|
|
51
|
-
const data = [{ a: 1 }, { a: 2 }];
|
|
52
|
-
logger.table(data);
|
|
53
|
-
expect(logSpy).toHaveBeenCalled();
|
|
54
|
-
const parsed = JSON.parse(logSpy.mock.calls[0][0]);
|
|
55
|
-
expect(parsed.level).toBe('table');
|
|
56
|
-
expect(Array.isArray(parsed.msg)).toBe(true);
|
|
57
|
-
expect(parsed.msg[0]).toEqual(data);
|
|
58
|
-
} finally {
|
|
59
|
-
logSpy.mockRestore();
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
it('falls back to console.log when console.table is unavailable', () => {
|
|
64
|
-
const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
|
65
|
-
const originalTable = console.table;
|
|
66
|
-
try {
|
|
67
|
-
// @ts-ignore
|
|
68
|
-
console.table = undefined;
|
|
69
|
-
const logger = new PowerLogger(3);
|
|
70
|
-
logger.table('fallback-table');
|
|
71
|
-
expect(logSpy).toHaveBeenCalledWith('fallback-table');
|
|
72
|
-
} finally {
|
|
73
|
-
console.table = originalTable;
|
|
74
|
-
logSpy.mockRestore();
|
|
75
|
-
}
|
|
76
|
-
});
|
|
77
|
-
});
|
package/test/powerLogger.test.js
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
2
|
-
import * as PowerLoggerModule from '../src/helpers/powerLogger.js';
|
|
3
|
-
|
|
4
|
-
const getCtor = (mod) => {
|
|
5
|
-
if (typeof mod === 'function') return mod;
|
|
6
|
-
if (mod && typeof mod.default === 'function') return mod.default;
|
|
7
|
-
if (mod && typeof mod.PowerLogger === 'function') return mod.PowerLogger;
|
|
8
|
-
throw new Error('PowerLogger constructor not found');
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
describe('PowerLogger', () => {
|
|
12
|
-
let logger;
|
|
13
|
-
beforeEach(() => {
|
|
14
|
-
const Ctor = getCtor(PowerLoggerModule);
|
|
15
|
-
logger = new Ctor(0);
|
|
16
|
-
});
|
|
17
|
-
afterEach(() => {
|
|
18
|
-
// nothing for now
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
it('sets and gets debug level', () => {
|
|
22
|
-
logger.setDebugLevel(2);
|
|
23
|
-
expect(logger.getDebugLevel()).toBe(2);
|
|
24
|
-
expect(logger.isDebugLevel(1)).toBe(true);
|
|
25
|
-
expect(logger.isDebugLevel(3)).toBe(false);
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
it('logs only when level permits', () => {
|
|
29
|
-
const spyError = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
30
|
-
const spyWarn = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
31
|
-
const spyInfo = vi.spyOn(console, 'info').mockImplementation(() => {});
|
|
32
|
-
const spyLog = vi.spyOn(console, 'log').mockImplementation(() => {});
|
|
33
|
-
|
|
34
|
-
logger.setDebugLevel(1);
|
|
35
|
-
logger.error('e');
|
|
36
|
-
logger.warn('w');
|
|
37
|
-
expect(spyError).toHaveBeenCalled();
|
|
38
|
-
expect(spyWarn).not.toHaveBeenCalled();
|
|
39
|
-
|
|
40
|
-
logger.setDebugLevel(3);
|
|
41
|
-
logger.info('i');
|
|
42
|
-
logger.log('l');
|
|
43
|
-
expect(spyInfo).toHaveBeenCalled();
|
|
44
|
-
expect(spyLog).toHaveBeenCalled();
|
|
45
|
-
|
|
46
|
-
spyError.mockRestore();
|
|
47
|
-
spyWarn.mockRestore();
|
|
48
|
-
spyInfo.mockRestore();
|
|
49
|
-
spyLog.mockRestore();
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
it('increments counters when debug enabled', () => {
|
|
53
|
-
logger.setDebugLevel(3);
|
|
54
|
-
logger.incrementCounter('x');
|
|
55
|
-
expect(logger.getDebugCounters()).toEqual({ x: 1 });
|
|
56
|
-
logger.resetDebugCounters();
|
|
57
|
-
expect(logger.getDebugCounters()).toEqual({});
|
|
58
|
-
});
|
|
59
|
-
});
|