1078c1fdbff63af8c6338a7c74349196fbfdd6b7
[poolifier.git] / tests / utils.test.mjs
1 import os from 'node:os'
2 import { randomInt } from 'node:crypto'
3 import { expect } from 'expect'
4 import {
5 DEFAULT_TASK_NAME,
6 EMPTY_FUNCTION,
7 availableParallelism,
8 average,
9 exponentialDelay,
10 isAsyncFunction,
11 isKillBehavior,
12 isPlainObject,
13 max,
14 median,
15 min,
16 // once,
17 round,
18 secureRandom,
19 sleep
20 } from '../lib/utils.cjs'
21 import { KillBehaviors } from '../lib/index.cjs'
22
23 describe('Utils test suite', () => {
24 it('Verify DEFAULT_TASK_NAME value', () => {
25 expect(DEFAULT_TASK_NAME).toBe('default')
26 })
27
28 it('Verify EMPTY_FUNCTION value', () => {
29 expect(EMPTY_FUNCTION).toStrictEqual(expect.any(Function))
30 })
31
32 it('Verify availableParallelism() behavior', () => {
33 const parallelism = availableParallelism()
34 expect(typeof parallelism === 'number').toBe(true)
35 expect(Number.isSafeInteger(parallelism)).toBe(true)
36 let expectedParallelism = 1
37 try {
38 expectedParallelism = os.availableParallelism()
39 } catch {
40 expectedParallelism = os.cpus().length
41 }
42 expect(parallelism).toBe(expectedParallelism)
43 })
44
45 it('Verify sleep() behavior', async () => {
46 const start = performance.now()
47 const sleepMs = 1000
48 await sleep(sleepMs)
49 const elapsed = performance.now() - start
50 expect(elapsed).toBeGreaterThanOrEqual(sleepMs - 1)
51 })
52
53 it('Verify exponentialDelay() behavior', () => {
54 const delay = exponentialDelay(randomInt(1000))
55 expect(typeof delay === 'number').toBe(true)
56 expect(delay).toBeGreaterThanOrEqual(Number.MIN_VALUE)
57 expect(delay).toBeLessThanOrEqual(Number.MAX_VALUE)
58 })
59
60 it('Verify average() computation', () => {
61 expect(average([])).toBe(0)
62 expect(average([0.08])).toBe(0.08)
63 expect(average([0.25, 4.75, 3.05, 6.04, 1.01, 2.02, 5.03])).toBe(
64 3.1642857142857146
65 )
66 expect(average([0.25, 4.75, 3.05, 6.04, 1.01, 2.02])).toBe(
67 2.8533333333333335
68 )
69 })
70
71 it('Verify median() computation', () => {
72 expect(median([])).toBe(0)
73 expect(median([0.08])).toBe(0.08)
74 expect(median([0.25, 4.75, 3.05, 6.04, 1.01, 2.02, 5.03])).toBe(3.05)
75 expect(median([0.25, 4.75, 3.05, 6.04, 1.01, 2.02])).toBe(2.535)
76 })
77
78 it('Verify round() behavior', () => {
79 expect(round(0)).toBe(0)
80 expect(round(0.5, 0)).toBe(1)
81 expect(round(0.5)).toBe(0.5)
82 expect(round(-0.5, 0)).toBe(-1)
83 expect(round(-0.5)).toBe(-0.5)
84 expect(round(1.005)).toBe(1.01)
85 expect(round(2.175)).toBe(2.18)
86 expect(round(5.015)).toBe(5.02)
87 expect(round(-1.005)).toBe(-1.01)
88 expect(round(-2.175)).toBe(-2.18)
89 expect(round(-5.015)).toBe(-5.02)
90 })
91
92 it('Verify isPlainObject() behavior', () => {
93 expect(isPlainObject(null)).toBe(false)
94 expect(isPlainObject(undefined)).toBe(false)
95 expect(isPlainObject(true)).toBe(false)
96 expect(isPlainObject(false)).toBe(false)
97 expect(isPlainObject(0)).toBe(false)
98 expect(isPlainObject('')).toBe(false)
99 expect(isPlainObject([])).toBe(false)
100 expect(isPlainObject(() => {})).toBe(false)
101 expect(isPlainObject(new Date())).toBe(false)
102 expect(isPlainObject(new RegExp())).toBe(false)
103 expect(isPlainObject(new Error())).toBe(false)
104 expect(isPlainObject(new Map())).toBe(false)
105 expect(isPlainObject(new Set())).toBe(false)
106 expect(isPlainObject(new WeakMap())).toBe(false)
107 expect(isPlainObject(new WeakSet())).toBe(false)
108 expect(isPlainObject(new Int8Array())).toBe(false)
109 expect(isPlainObject(new Uint8Array())).toBe(false)
110 expect(isPlainObject(new Uint8ClampedArray())).toBe(false)
111 expect(isPlainObject(new Int16Array())).toBe(false)
112 expect(isPlainObject(new Uint16Array())).toBe(false)
113 expect(isPlainObject(new Int32Array())).toBe(false)
114 expect(isPlainObject(new Uint32Array())).toBe(false)
115 expect(isPlainObject(new Float32Array())).toBe(false)
116 expect(isPlainObject(new Float64Array())).toBe(false)
117 expect(isPlainObject(new BigInt64Array())).toBe(false)
118 expect(isPlainObject(new BigUint64Array())).toBe(false)
119 expect(isPlainObject(new Promise(() => {}))).toBe(false)
120 expect(isPlainObject(new WeakRef({}))).toBe(false)
121 expect(isPlainObject(new FinalizationRegistry(() => {}))).toBe(false)
122 expect(isPlainObject(new ArrayBuffer())).toBe(false)
123 expect(isPlainObject(new SharedArrayBuffer())).toBe(false)
124 expect(isPlainObject(new DataView(new ArrayBuffer()))).toBe(false)
125 expect(isPlainObject({})).toBe(true)
126 expect(isPlainObject({ a: 1 })).toBe(true)
127 })
128
129 it('Verify isKillBehavior() behavior', () => {
130 expect(isKillBehavior(KillBehaviors.SOFT, KillBehaviors.SOFT)).toBe(true)
131 expect(isKillBehavior(KillBehaviors.SOFT, KillBehaviors.HARD)).toBe(false)
132 expect(isKillBehavior(KillBehaviors.HARD, KillBehaviors.HARD)).toBe(true)
133 expect(isKillBehavior(KillBehaviors.HARD, KillBehaviors.SOFT)).toBe(false)
134 expect(isKillBehavior(KillBehaviors.SOFT)).toBe(false)
135 expect(isKillBehavior(KillBehaviors.HARD)).toBe(false)
136 expect(isKillBehavior(KillBehaviors.HARD, null)).toBe(false)
137 expect(isKillBehavior(KillBehaviors.HARD, undefined)).toBe(false)
138 expect(isKillBehavior(KillBehaviors.SOFT, 'unknown')).toBe(false)
139 })
140
141 it('Verify isAsyncFunction() behavior', () => {
142 expect(isAsyncFunction(null)).toBe(false)
143 expect(isAsyncFunction(undefined)).toBe(false)
144 expect(isAsyncFunction(true)).toBe(false)
145 expect(isAsyncFunction(false)).toBe(false)
146 expect(isAsyncFunction(0)).toBe(false)
147 expect(isAsyncFunction('')).toBe(false)
148 expect(isAsyncFunction([])).toBe(false)
149 expect(isAsyncFunction(new Date())).toBe(false)
150 expect(isAsyncFunction(new RegExp())).toBe(false)
151 expect(isAsyncFunction(new Error())).toBe(false)
152 expect(isAsyncFunction(new Map())).toBe(false)
153 expect(isAsyncFunction(new Set())).toBe(false)
154 expect(isAsyncFunction(new WeakMap())).toBe(false)
155 expect(isAsyncFunction(new WeakSet())).toBe(false)
156 expect(isAsyncFunction(new Int8Array())).toBe(false)
157 expect(isAsyncFunction(new Uint8Array())).toBe(false)
158 expect(isAsyncFunction(new Uint8ClampedArray())).toBe(false)
159 expect(isAsyncFunction(new Int16Array())).toBe(false)
160 expect(isAsyncFunction(new Uint16Array())).toBe(false)
161 expect(isAsyncFunction(new Int32Array())).toBe(false)
162 expect(isAsyncFunction(new Uint32Array())).toBe(false)
163 expect(isAsyncFunction(new Float32Array())).toBe(false)
164 expect(isAsyncFunction(new Float64Array())).toBe(false)
165 expect(isAsyncFunction(new BigInt64Array())).toBe(false)
166 expect(isAsyncFunction(new BigUint64Array())).toBe(false)
167 expect(isAsyncFunction(new Promise(() => {}))).toBe(false)
168 expect(isAsyncFunction(new WeakRef({}))).toBe(false)
169 expect(isAsyncFunction(new FinalizationRegistry(() => {}))).toBe(false)
170 expect(isAsyncFunction(new ArrayBuffer())).toBe(false)
171 expect(isAsyncFunction(new SharedArrayBuffer())).toBe(false)
172 expect(isAsyncFunction(new DataView(new ArrayBuffer()))).toBe(false)
173 expect(isAsyncFunction({})).toBe(false)
174 expect(isAsyncFunction({ a: 1 })).toBe(false)
175 expect(isAsyncFunction(() => {})).toBe(false)
176 expect(isAsyncFunction(function () {})).toBe(false)
177 expect(isAsyncFunction(function named () {})).toBe(false)
178 expect(isAsyncFunction(async () => {})).toBe(true)
179 expect(isAsyncFunction(async function () {})).toBe(true)
180 expect(isAsyncFunction(async function named () {})).toBe(true)
181 })
182
183 it('Verify secureRandom() behavior', () => {
184 const randomNumber = secureRandom()
185 expect(typeof randomNumber === 'number').toBe(true)
186 expect(randomNumber).toBeGreaterThanOrEqual(0)
187 expect(randomNumber).toBeLessThan(1)
188 })
189
190 it('Verify min() behavior', () => {
191 expect(min()).toBe(Infinity)
192 expect(min(1, 2)).toBe(1)
193 expect(min(2, 1)).toBe(1)
194 expect(min(1, 1)).toBe(1)
195 })
196
197 it('Verify max() behavior', () => {
198 expect(max()).toBe(-Infinity)
199 expect(max(1, 2)).toBe(2)
200 expect(max(2, 1)).toBe(2)
201 expect(max(1, 1)).toBe(1)
202 })
203
204 // it('Verify once()', () => {
205 // let called = 0
206 // const fn = () => ++called
207 // const onceFn = once(fn, this)
208 // const result1 = onceFn()
209 // expect(called).toBe(1)
210 // expect(result1).toBe(1)
211 // const result2 = onceFn()
212 // expect(called).toBe(1)
213 // expect(result2).toBe(1)
214 // const result3 = onceFn()
215 // expect(called).toBe(1)
216 // expect(result3).toBe(1)
217 // })
218 })