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