1 import { Worker } from 'node:worker_threads'
2 import cluster from 'node:cluster'
3 import os from 'node:os'
4 import { randomInt } from 'node:crypto'
5 import { expect } from 'expect'
7 DEFAULT_MEASUREMENT_STATISTICS_REQUIREMENTS,
12 buildInternalWorkerChoiceStrategyOptions,
26 } from '../lib/utils.js'
27 import { KillBehaviors, WorkerTypes } from '../lib/index.js'
29 describe('Utils test suite', () => {
30 it('Verify DEFAULT_TASK_NAME value', () => {
31 expect(DEFAULT_TASK_NAME).toBe('default')
34 it('Verify EMPTY_FUNCTION value', () => {
35 expect(EMPTY_FUNCTION).toStrictEqual(expect.any(Function))
38 it('Verify DEFAULT_MEASUREMENT_STATISTICS_REQUIREMENTS values', () => {
39 expect(DEFAULT_MEASUREMENT_STATISTICS_REQUIREMENTS).toStrictEqual({
46 it('Verify availableParallelism() behavior', () => {
47 const parallelism = availableParallelism()
48 expect(typeof parallelism === 'number').toBe(true)
49 expect(Number.isSafeInteger(parallelism)).toBe(true)
50 let expectedParallelism = 1
52 expectedParallelism = os.availableParallelism()
54 expectedParallelism = os.cpus().length
56 expect(parallelism).toBe(expectedParallelism)
59 it('Verify getWorkerType() behavior', () => {
61 getWorkerType(new Worker('./tests/worker-files/thread/testWorker.mjs'))
62 ).toBe(WorkerTypes.thread)
63 expect(getWorkerType(cluster.fork())).toBe(WorkerTypes.cluster)
66 it('Verify getWorkerId() behavior', () => {
67 const threadWorker = new Worker(
68 './tests/worker-files/thread/testWorker.mjs'
70 const clusterWorker = cluster.fork()
71 expect(getWorkerId(threadWorker)).toBe(threadWorker.threadId)
72 expect(getWorkerId(clusterWorker)).toBe(clusterWorker.id)
75 it('Verify sleep() behavior', async () => {
76 const start = performance.now()
79 const elapsed = performance.now() - start
80 expect(elapsed).toBeGreaterThanOrEqual(sleepMs - 1)
83 it('Verify exponentialDelay() behavior', () => {
84 const delay = exponentialDelay(randomInt(1000))
85 expect(typeof delay === 'number').toBe(true)
86 expect(delay).toBeGreaterThanOrEqual(Number.MIN_VALUE)
87 expect(delay).toBeLessThanOrEqual(Number.MAX_VALUE)
90 it('Verify average() computation', () => {
91 expect(average([])).toBe(0)
92 expect(average([0.08])).toBe(0.08)
93 expect(average([0.25, 4.75, 3.05, 6.04, 1.01, 2.02, 5.03])).toBe(
96 expect(average([0.25, 4.75, 3.05, 6.04, 1.01, 2.02])).toBe(
101 it('Verify median() computation', () => {
102 expect(median([])).toBe(0)
103 expect(median([0.08])).toBe(0.08)
104 expect(median([0.25, 4.75, 3.05, 6.04, 1.01, 2.02, 5.03])).toBe(3.05)
105 expect(median([0.25, 4.75, 3.05, 6.04, 1.01, 2.02])).toBe(2.535)
108 it('Verify round() behavior', () => {
109 expect(round(0)).toBe(0)
110 expect(round(0.5, 0)).toBe(1)
111 expect(round(0.5)).toBe(0.5)
112 expect(round(-0.5, 0)).toBe(-1)
113 expect(round(-0.5)).toBe(-0.5)
114 expect(round(1.005)).toBe(1.01)
115 expect(round(2.175)).toBe(2.18)
116 expect(round(5.015)).toBe(5.02)
117 expect(round(-1.005)).toBe(-1.01)
118 expect(round(-2.175)).toBe(-2.18)
119 expect(round(-5.015)).toBe(-5.02)
122 it('Verify isPlainObject() behavior', () => {
123 expect(isPlainObject(null)).toBe(false)
124 expect(isPlainObject(undefined)).toBe(false)
125 expect(isPlainObject(true)).toBe(false)
126 expect(isPlainObject(false)).toBe(false)
127 expect(isPlainObject(0)).toBe(false)
128 expect(isPlainObject('')).toBe(false)
129 expect(isPlainObject([])).toBe(false)
130 expect(isPlainObject(() => {})).toBe(false)
131 expect(isPlainObject(new Date())).toBe(false)
132 expect(isPlainObject(new RegExp())).toBe(false)
133 expect(isPlainObject(new Error())).toBe(false)
134 expect(isPlainObject(new Map())).toBe(false)
135 expect(isPlainObject(new Set())).toBe(false)
136 expect(isPlainObject(new WeakMap())).toBe(false)
137 expect(isPlainObject(new WeakSet())).toBe(false)
138 expect(isPlainObject(new Int8Array())).toBe(false)
139 expect(isPlainObject(new Uint8Array())).toBe(false)
140 expect(isPlainObject(new Uint8ClampedArray())).toBe(false)
141 expect(isPlainObject(new Int16Array())).toBe(false)
142 expect(isPlainObject(new Uint16Array())).toBe(false)
143 expect(isPlainObject(new Int32Array())).toBe(false)
144 expect(isPlainObject(new Uint32Array())).toBe(false)
145 expect(isPlainObject(new Float32Array())).toBe(false)
146 expect(isPlainObject(new Float64Array())).toBe(false)
147 expect(isPlainObject(new BigInt64Array())).toBe(false)
148 expect(isPlainObject(new BigUint64Array())).toBe(false)
149 expect(isPlainObject(new Promise(() => {}))).toBe(false)
150 expect(isPlainObject(new WeakRef({}))).toBe(false)
151 expect(isPlainObject(new FinalizationRegistry(() => {}))).toBe(false)
152 expect(isPlainObject(new ArrayBuffer())).toBe(false)
153 expect(isPlainObject(new SharedArrayBuffer())).toBe(false)
154 expect(isPlainObject(new DataView(new ArrayBuffer()))).toBe(false)
155 expect(isPlainObject({})).toBe(true)
156 expect(isPlainObject({ a: 1 })).toBe(true)
159 it('Verify isKillBehavior() behavior', () => {
160 expect(isKillBehavior(KillBehaviors.SOFT, KillBehaviors.SOFT)).toBe(true)
161 expect(isKillBehavior(KillBehaviors.SOFT, KillBehaviors.HARD)).toBe(false)
162 expect(isKillBehavior(KillBehaviors.HARD, KillBehaviors.HARD)).toBe(true)
163 expect(isKillBehavior(KillBehaviors.HARD, KillBehaviors.SOFT)).toBe(false)
164 expect(isKillBehavior(KillBehaviors.SOFT)).toBe(false)
165 expect(isKillBehavior(KillBehaviors.HARD)).toBe(false)
166 expect(isKillBehavior(KillBehaviors.HARD, null)).toBe(false)
167 expect(isKillBehavior(KillBehaviors.HARD, undefined)).toBe(false)
168 expect(isKillBehavior(KillBehaviors.SOFT, 'unknown')).toBe(false)
171 it('Verify isAsyncFunction() behavior', () => {
172 expect(isAsyncFunction(null)).toBe(false)
173 expect(isAsyncFunction(undefined)).toBe(false)
174 expect(isAsyncFunction(true)).toBe(false)
175 expect(isAsyncFunction(false)).toBe(false)
176 expect(isAsyncFunction(0)).toBe(false)
177 expect(isAsyncFunction('')).toBe(false)
178 expect(isAsyncFunction([])).toBe(false)
179 expect(isAsyncFunction(new Date())).toBe(false)
180 expect(isAsyncFunction(new RegExp())).toBe(false)
181 expect(isAsyncFunction(new Error())).toBe(false)
182 expect(isAsyncFunction(new Map())).toBe(false)
183 expect(isAsyncFunction(new Set())).toBe(false)
184 expect(isAsyncFunction(new WeakMap())).toBe(false)
185 expect(isAsyncFunction(new WeakSet())).toBe(false)
186 expect(isAsyncFunction(new Int8Array())).toBe(false)
187 expect(isAsyncFunction(new Uint8Array())).toBe(false)
188 expect(isAsyncFunction(new Uint8ClampedArray())).toBe(false)
189 expect(isAsyncFunction(new Int16Array())).toBe(false)
190 expect(isAsyncFunction(new Uint16Array())).toBe(false)
191 expect(isAsyncFunction(new Int32Array())).toBe(false)
192 expect(isAsyncFunction(new Uint32Array())).toBe(false)
193 expect(isAsyncFunction(new Float32Array())).toBe(false)
194 expect(isAsyncFunction(new Float64Array())).toBe(false)
195 expect(isAsyncFunction(new BigInt64Array())).toBe(false)
196 expect(isAsyncFunction(new BigUint64Array())).toBe(false)
197 expect(isAsyncFunction(new Promise(() => {}))).toBe(false)
198 expect(isAsyncFunction(new WeakRef({}))).toBe(false)
199 expect(isAsyncFunction(new FinalizationRegistry(() => {}))).toBe(false)
200 expect(isAsyncFunction(new ArrayBuffer())).toBe(false)
201 expect(isAsyncFunction(new SharedArrayBuffer())).toBe(false)
202 expect(isAsyncFunction(new DataView(new ArrayBuffer()))).toBe(false)
203 expect(isAsyncFunction({})).toBe(false)
204 expect(isAsyncFunction({ a: 1 })).toBe(false)
205 expect(isAsyncFunction(() => {})).toBe(false)
206 expect(isAsyncFunction(function () {})).toBe(false)
207 expect(isAsyncFunction(function named () {})).toBe(false)
208 expect(isAsyncFunction(async () => {})).toBe(true)
209 expect(isAsyncFunction(async function () {})).toBe(true)
210 expect(isAsyncFunction(async function named () {})).toBe(true)
213 it('Verify secureRandom() behavior', () => {
214 const randomNumber = secureRandom()
215 expect(typeof randomNumber === 'number').toBe(true)
216 expect(randomNumber).toBeGreaterThanOrEqual(0)
217 expect(randomNumber).toBeLessThan(1)
220 it('Verify min() behavior', () => {
221 expect(min()).toBe(Infinity)
222 expect(min(1, 2)).toBe(1)
223 expect(min(2, 1)).toBe(1)
224 expect(min(1, 1)).toBe(1)
227 it('Verify max() behavior', () => {
228 expect(max()).toBe(-Infinity)
229 expect(max(1, 2)).toBe(2)
230 expect(max(2, 1)).toBe(2)
231 expect(max(1, 1)).toBe(1)
234 it('Verify buildInternalWorkerChoiceStrategyOptions() behavior', () => {
235 const poolMaxSize = 10
236 const internalWorkerChoiceStrategyOptions =
237 buildInternalWorkerChoiceStrategyOptions(poolMaxSize)
238 expect(internalWorkerChoiceStrategyOptions).toStrictEqual({
241 Object.keys(internalWorkerChoiceStrategyOptions.weights).length,
242 runTime: { median: false },
243 waitTime: { median: false },
244 elu: { median: false },
245 weights: expect.objectContaining({
246 0: expect.any(Number),
247 [poolMaxSize - 1]: expect.any(Number)
252 // it('Verify once()', () => {
254 // const fn = () => ++called
255 // const onceFn = once(fn, this)
256 // const result1 = onceFn()
257 // expect(called).toBe(1)
258 // expect(result1).toBe(1)
259 // const result2 = onceFn()
260 // expect(called).toBe(1)
261 // expect(result2).toBe(1)
262 // const result3 = onceFn()
263 // expect(called).toBe(1)
264 // expect(result3).toBe(1)