1 import { describe
, it
} from
'node:test'
3 import { hoursToMilliseconds
, hoursToSeconds
} from
'date-fns'
4 import { expect
} from
'expect'
6 import { Constants
} from
'../../src/utils/Constants.js'
13 extractTimeSeriesValues
,
14 formatDurationMilliSeconds
,
15 formatDurationSeconds
,
36 } from
'../../src/utils/Utils.js'
38 await describe('Utils test suite', async () => {
39 await it('Verify generateUUID()/validateUUID()', () => {
40 const uuid
= generateUUID()
41 expect(uuid
).toBeDefined()
42 expect(uuid
.length
).toEqual(36)
43 expect(validateUUID(uuid
)).toBe(true)
44 expect(validateUUID('abcdef00-0000-4000-0000-000000000000')).toBe(true)
45 expect(validateUUID('')).toBe(false)
46 // Shall invalidate Nil UUID
47 expect(validateUUID('00000000-0000-0000-0000-000000000000')).toBe(false)
48 expect(validateUUID('987FBC9-4BED-3078-CF07A-9141BA07C9F3')).toBe(false)
51 await it('Verify sleep()', async () => {
52 const start
= performance
.now()
54 const stop
= performance
.now()
55 expect(stop
- start
).toBeGreaterThanOrEqual(1000)
58 await it('Verify formatDurationMilliSeconds()', () => {
59 expect(formatDurationMilliSeconds(0)).toBe('0 seconds')
60 expect(formatDurationMilliSeconds(900)).toBe('0 seconds')
61 expect(formatDurationMilliSeconds(1000)).toBe('1 second')
62 expect(formatDurationMilliSeconds(hoursToMilliseconds(4380))).toBe('182 days 12 hours')
65 await it('Verify formatDurationSeconds()', () => {
66 expect(formatDurationSeconds(0)).toBe('0 seconds')
67 expect(formatDurationSeconds(0.9)).toBe('0 seconds')
68 expect(formatDurationSeconds(1)).toBe('1 second')
69 expect(formatDurationSeconds(hoursToSeconds(4380))).toBe('182 days 12 hours')
72 await it('Verify isValidTime()', () => {
73 expect(isValidTime(undefined)).toBe(false)
74 expect(isValidTime(null)).toBe(false)
75 expect(isValidTime('')).toBe(false)
76 expect(isValidTime({})).toBe(false)
77 expect(isValidTime([])).toBe(false)
78 expect(isValidTime(new Map())).toBe(false)
79 expect(isValidTime(new Set())).toBe(false)
80 expect(isValidTime(new WeakMap())).toBe(false)
81 expect(isValidTime(new WeakSet())).toBe(false)
82 expect(isValidTime(-1)).toBe(true)
83 expect(isValidTime(0)).toBe(true)
84 expect(isValidTime(1)).toBe(true)
85 expect(isValidTime(-0.5)).toBe(true)
86 expect(isValidTime(0.5)).toBe(true)
87 expect(isValidTime(new Date())).toBe(true)
90 await it('Verify convertToDate()', () => {
91 expect(convertToDate(undefined)).toBe(undefined)
92 expect(convertToDate(null)).toBe(null)
93 expect(() => convertToDate('')).toThrow(new Error("Cannot convert to date: ''"))
94 expect(() => convertToDate('00:70:61')).toThrow(new Error("Cannot convert to date: '00:70:61'"))
95 expect(convertToDate(0)).toStrictEqual(new Date('1970-01-01T00:00:00.000Z'))
96 expect(convertToDate(-1)).toStrictEqual(new Date('1969-12-31T23:59:59.999Z'))
97 const dateStr
= '2020-01-01T00:00:00.000Z'
98 let date
= convertToDate(dateStr
)
99 expect(date
).toBeInstanceOf(Date)
100 expect(date
).toStrictEqual(new Date(dateStr
))
101 date
= convertToDate(new Date(dateStr
))
102 expect(date
).toBeInstanceOf(Date)
103 expect(date
).toStrictEqual(new Date(dateStr
))
106 await it('Verify convertToInt()', () => {
107 expect(convertToInt(undefined)).toBe(0)
108 expect(convertToInt(null)).toBe(0)
109 expect(convertToInt(0)).toBe(0)
110 const randomInteger
= getRandomInteger()
111 expect(convertToInt(randomInteger
)).toEqual(randomInteger
)
112 expect(convertToInt('-1')).toBe(-1)
113 expect(convertToInt('1')).toBe(1)
114 expect(convertToInt('1.1')).toBe(1)
115 expect(convertToInt('1.9')).toBe(1)
116 expect(convertToInt('1.999')).toBe(1)
117 expect(convertToInt(-1)).toBe(-1)
118 expect(convertToInt(1)).toBe(1)
119 expect(convertToInt(1.1)).toBe(1)
120 expect(convertToInt(1.9)).toBe(1)
121 expect(convertToInt(1.999)).toBe(1)
124 }).toThrow("Cannot convert to integer: 'NaN'")
127 await it('Verify convertToFloat()', () => {
128 expect(convertToFloat(undefined)).toBe(0)
129 expect(convertToFloat(null)).toBe(0)
130 expect(convertToFloat(0)).toBe(0)
131 const randomFloat
= getRandomFloat()
132 expect(convertToFloat(randomFloat
)).toEqual(randomFloat
)
133 expect(convertToFloat('-1')).toBe(-1)
134 expect(convertToFloat('1')).toBe(1)
135 expect(convertToFloat('1.1')).toBe(1.1)
136 expect(convertToFloat('1.9')).toBe(1.9)
137 expect(convertToFloat('1.999')).toBe(1.999)
138 expect(convertToFloat(-1)).toBe(-1)
139 expect(convertToFloat(1)).toBe(1)
140 expect(convertToFloat(1.1)).toBe(1.1)
141 expect(convertToFloat(1.9)).toBe(1.9)
142 expect(convertToFloat(1.999)).toBe(1.999)
144 convertToFloat('NaN')
145 }).toThrow("Cannot convert to float: 'NaN'")
148 await it('Verify convertToBoolean()', () => {
149 expect(convertToBoolean(undefined)).toBe(false)
150 expect(convertToBoolean(null)).toBe(false)
151 expect(convertToBoolean('true')).toBe(true)
152 expect(convertToBoolean('false')).toBe(false)
153 expect(convertToBoolean('TRUE')).toBe(true)
154 expect(convertToBoolean('FALSE')).toBe(false)
155 expect(convertToBoolean('1')).toBe(true)
156 expect(convertToBoolean('0')).toBe(false)
157 expect(convertToBoolean(1)).toBe(true)
158 expect(convertToBoolean(0)).toBe(false)
159 expect(convertToBoolean(true)).toBe(true)
160 expect(convertToBoolean(false)).toBe(false)
161 expect(convertToBoolean('')).toBe(false)
162 expect(convertToBoolean('NoNBoolean')).toBe(false)
165 await it('Verify secureRandom()', () => {
166 const random
= secureRandom()
167 expect(typeof random
=== 'number').toBe(true)
168 expect(random
).toBeGreaterThanOrEqual(0)
169 expect(random
).toBeLessThan(1)
172 await it('Verify getRandomInteger()', () => {
173 let randomInteger
= getRandomInteger()
174 expect(Number.isSafeInteger(randomInteger
)).toBe(true)
175 expect(randomInteger
).toBeGreaterThanOrEqual(0)
176 expect(randomInteger
).toBeLessThanOrEqual(Constants
.MAX_RANDOM_INTEGER
)
177 expect(randomInteger
).not
.toEqual(getRandomInteger())
178 randomInteger
= getRandomInteger(0, -Constants
.MAX_RANDOM_INTEGER
)
179 expect(randomInteger
).toBeGreaterThanOrEqual(-Constants
.MAX_RANDOM_INTEGER
)
180 expect(randomInteger
).toBeLessThanOrEqual(0)
181 expect(() => getRandomInteger(0, 1)).toThrow(
182 'The value of "max" is out of range. It must be greater than the value of "min" (1). Received 1'
184 expect(() => getRandomInteger(-1)).toThrow(
185 'The value of "max" is out of range. It must be greater than the value of "min" (0). Received 0'
187 expect(() => getRandomInteger(Constants
.MAX_RANDOM_INTEGER
+ 1)).toThrow(
188 `The value of "max" is out of range. It must be <= ${
189 Constants.MAX_RANDOM_INTEGER + 1
190 }. Received 281_474_976_710_656`
192 randomInteger
= getRandomInteger(2, 1)
193 expect(randomInteger
).toBeGreaterThanOrEqual(1)
194 expect(randomInteger
).toBeLessThanOrEqual(2)
197 randomInteger
= getRandomInteger(maximum
, minimum
)
198 expect(randomInteger
).toBeLessThanOrEqual(Math.floor(maximum
))
199 expect(randomInteger
).toBeGreaterThanOrEqual(Math.ceil(minimum
))
202 await it('Verify roundTo()', () => {
203 expect(roundTo(0, 2)).toBe(0)
204 expect(roundTo(0.5, 0)).toBe(1)
205 expect(roundTo(0.5, 2)).toBe(0.5)
206 expect(roundTo(-0.5, 0)).toBe(-1)
207 expect(roundTo(-0.5, 2)).toBe(-0.5)
208 expect(roundTo(1.005, 0)).toBe(1)
209 expect(roundTo(1.005, 2)).toBe(1.01)
210 expect(roundTo(2.175, 2)).toBe(2.18)
211 expect(roundTo(5.015, 2)).toBe(5.02)
212 expect(roundTo(-1.005, 2)).toBe(-1.01)
213 expect(roundTo(-2.175, 2)).toBe(-2.18)
214 expect(roundTo(-5.015, 2)).toBe(-5.02)
217 await it('Verify getRandomFloat()', () => {
218 let randomFloat
= getRandomFloat()
219 expect(typeof randomFloat
=== 'number').toBe(true)
220 expect(randomFloat
).toBeGreaterThanOrEqual(0)
221 expect(randomFloat
).toBeLessThanOrEqual(Number.MAX_VALUE
)
222 expect(randomFloat
).not
.toEqual(getRandomFloat())
223 expect(() => getRandomFloat(0, 1)).toThrow(new RangeError('Invalid interval'))
224 expect(() => getRandomFloat(Number.MAX_VALUE
, -Number.MAX_VALUE
)).toThrow(
225 new RangeError('Invalid interval')
227 randomFloat
= getRandomFloat(0, -Number.MAX_VALUE
)
228 expect(randomFloat
).toBeGreaterThanOrEqual(-Number.MAX_VALUE
)
229 expect(randomFloat
).toBeLessThanOrEqual(0)
232 await it('Verify extractTimeSeriesValues()', () => {
233 expect(extractTimeSeriesValues([])).toEqual([])
234 expect(extractTimeSeriesValues([{ timestamp
: Date.now(), value
: 1.1 }])).toEqual([1.1])
236 extractTimeSeriesValues([
237 { timestamp
: Date.now(), value
: 1.1 },
238 { timestamp
: Date.now(), value
: 2.2 }
240 ).toEqual([1.1, 2.2])
243 await it('Verify isObject()', () => {
244 expect(isObject('test')).toBe(false)
245 expect(isObject(undefined)).toBe(false)
246 expect(isObject(null)).toBe(false)
247 expect(isObject(0)).toBe(false)
248 expect(isObject([])).toBe(false)
249 expect(isObject([0, 1])).toBe(false)
250 expect(isObject(['0', '1'])).toBe(false)
251 expect(isObject({})).toBe(true)
252 expect(isObject({ 1: 1 })).toBe(true)
253 expect(isObject({ 1: '1' })).toBe(true)
254 expect(isObject(new Map())).toBe(true)
255 expect(isObject(new Set())).toBe(true)
256 expect(isObject(new WeakMap())).toBe(true)
257 expect(isObject(new WeakSet())).toBe(true)
260 await it('Verify cloneObject()', () => {
262 expect(cloneObject(obj
)).toStrictEqual(obj
)
263 expect(cloneObject(obj
) === obj
).toBe(false)
264 const nestedObj
= { 1: obj
, 2: obj
}
265 expect(cloneObject(nestedObj
)).toStrictEqual(nestedObj
)
266 expect(cloneObject(nestedObj
) === nestedObj
).toBe(false)
268 expect(cloneObject(array
)).toStrictEqual(array
)
269 expect(cloneObject(array
) === array
).toBe(false)
270 const objArray
= [obj
, obj
]
271 expect(cloneObject(objArray
)).toStrictEqual(objArray
)
272 expect(cloneObject(objArray
) === objArray
).toBe(false)
273 const date
= new Date()
274 expect(cloneObject(date
)).toStrictEqual(date
)
275 expect(cloneObject(date
) === date
).toBe(false)
276 const map
= new Map([['1', '2']])
277 expect(cloneObject(map
)).toStrictEqual({})
278 const set
= new Set(['1'])
279 expect(cloneObject(set
)).toStrictEqual({})
280 // The URL object seems to have not enumerable properties
281 const url
= new URL('https://domain.tld')
282 expect(cloneObject(url
)).toStrictEqual({})
283 const weakMap
= new WeakMap([[{ 1: 1 }, { 2: 2 }]])
284 expect(cloneObject(weakMap
)).toStrictEqual({})
285 const weakSet
= new WeakSet([{ 1: 1 }, { 2: 2 }])
286 expect(cloneObject(weakSet
)).toStrictEqual({})
289 await it('Verify hasOwnProp()', () => {
290 expect(hasOwnProp('test', '')).toBe(false)
291 expect(hasOwnProp(undefined, '')).toBe(false)
292 expect(hasOwnProp(null, '')).toBe(false)
293 expect(hasOwnProp([], '')).toBe(false)
294 expect(hasOwnProp({}, '')).toBe(false)
295 expect(hasOwnProp({ 1: 1 }, 1)).toBe(true)
296 expect(hasOwnProp({ 1: 1 }, '1')).toBe(true)
297 expect(hasOwnProp({ 1: 1 }, 2)).toBe(false)
298 expect(hasOwnProp({ 1: 1 }, '2')).toBe(false)
299 expect(hasOwnProp({ 1: '1' }, '1')).toBe(true)
300 expect(hasOwnProp({ 1: '1' }, 1)).toBe(true)
301 expect(hasOwnProp({ 1: '1' }, '2')).toBe(false)
302 expect(hasOwnProp({ 1: '1' }, 2)).toBe(false)
305 await it('Verify isIterable()', () => {
306 expect(isIterable('')).toBe(true)
307 expect(isIterable(' ')).toBe(true)
308 expect(isIterable('test')).toBe(true)
309 expect(isIterable(undefined)).toBe(false)
310 expect(isIterable(null)).toBe(false)
311 expect(isIterable(0)).toBe(false)
312 expect(isIterable([0, 1])).toBe(true)
313 expect(isIterable({ 1: 1 })).toBe(false)
314 expect(isIterable(new Map())).toBe(true)
315 expect(isIterable(new Set())).toBe(true)
316 expect(isIterable(new WeakMap())).toBe(false)
317 expect(isIterable(new WeakSet())).toBe(false)
320 await it('Verify isEmptyString()', () => {
321 expect(isEmptyString('')).toBe(true)
322 expect(isEmptyString(' ')).toBe(true)
323 expect(isEmptyString(' ')).toBe(true)
324 expect(isEmptyString('test')).toBe(false)
325 expect(isEmptyString(' test')).toBe(false)
326 expect(isEmptyString('test ')).toBe(false)
327 expect(isEmptyString(undefined)).toBe(true)
328 expect(isEmptyString(null)).toBe(true)
329 expect(isEmptyString(0)).toBe(false)
330 expect(isEmptyString({})).toBe(false)
331 expect(isEmptyString([])).toBe(false)
332 expect(isEmptyString(new Map())).toBe(false)
333 expect(isEmptyString(new Set())).toBe(false)
334 expect(isEmptyString(new WeakMap())).toBe(false)
335 expect(isEmptyString(new WeakSet())).toBe(false)
338 await it('Verify isNotEmptyString()', () => {
339 expect(isNotEmptyString('')).toBe(false)
340 expect(isNotEmptyString(' ')).toBe(false)
341 expect(isNotEmptyString(' ')).toBe(false)
342 expect(isNotEmptyString('test')).toBe(true)
343 expect(isNotEmptyString(' test')).toBe(true)
344 expect(isNotEmptyString('test ')).toBe(true)
345 expect(isNotEmptyString(undefined)).toBe(false)
346 expect(isNotEmptyString(null)).toBe(false)
347 expect(isNotEmptyString(0)).toBe(false)
348 expect(isNotEmptyString({})).toBe(false)
349 expect(isNotEmptyString([])).toBe(false)
350 expect(isNotEmptyString(new Map())).toBe(false)
351 expect(isNotEmptyString(new Set())).toBe(false)
352 expect(isNotEmptyString(new WeakMap())).toBe(false)
353 expect(isNotEmptyString(new WeakSet())).toBe(false)
356 await it('Verify isEmptyArray()', () => {
357 expect(isEmptyArray([])).toBe(true)
358 expect(isEmptyArray([1, 2])).toBe(false)
359 expect(isEmptyArray(['1', '2'])).toBe(false)
360 expect(isEmptyArray(undefined)).toBe(false)
361 expect(isEmptyArray(null)).toBe(false)
362 expect(isEmptyArray('')).toBe(false)
363 expect(isEmptyArray('test')).toBe(false)
364 expect(isEmptyArray(0)).toBe(false)
365 expect(isEmptyArray({})).toBe(false)
366 expect(isEmptyArray(new Map())).toBe(false)
367 expect(isEmptyArray(new Set())).toBe(false)
368 expect(isEmptyArray(new WeakMap())).toBe(false)
369 expect(isEmptyArray(new WeakSet())).toBe(false)
372 await it('Verify isNotEmptyArray()', () => {
373 expect(isNotEmptyArray([])).toBe(false)
374 expect(isNotEmptyArray([1, 2])).toBe(true)
375 expect(isNotEmptyArray(['1', '2'])).toBe(true)
376 expect(isNotEmptyArray(undefined)).toBe(false)
377 expect(isNotEmptyArray(null)).toBe(false)
378 expect(isNotEmptyArray('')).toBe(false)
379 expect(isNotEmptyArray('test')).toBe(false)
380 expect(isNotEmptyArray(0)).toBe(false)
381 expect(isNotEmptyArray({})).toBe(false)
382 expect(isNotEmptyArray(new Map())).toBe(false)
383 expect(isNotEmptyArray(new Set())).toBe(false)
384 expect(isNotEmptyArray(new WeakMap())).toBe(false)
385 expect(isNotEmptyArray(new WeakSet())).toBe(false)
388 await it('Verify isEmptyObject()', () => {
389 expect(isEmptyObject({})).toBe(true)
390 expect(isEmptyObject({ 1: 1, 2: 2 })).toBe(false)
391 expect(isEmptyObject(new Map())).toBe(false)
392 expect(isEmptyObject(new Set())).toBe(false)
393 expect(isEmptyObject(new WeakMap())).toBe(false)
394 expect(isEmptyObject(new WeakSet())).toBe(false)
397 await it('Verify isArraySorted()', () => {
399 isArraySorted([], (a
, b
) => {
404 isArraySorted([1], (a
, b
) => {
408 expect(isArraySorted
<number>([1, 2, 3, 4, 5], (a
, b
) => a
- b
)).toBe(true)
409 expect(isArraySorted
<number>([1, 2, 3, 5, 4], (a
, b
) => a
- b
)).toBe(false)
410 expect(isArraySorted
<number>([2, 1, 3, 4, 5], (a
, b
) => a
- b
)).toBe(false)
413 await it('Verify once()', () => {
415 const fn
= (): number => ++called
416 const onceFn
= once(fn
, this)
417 const result1
= onceFn()
418 expect(called
).toBe(1)
419 expect(result1
).toBe(1)
420 const result2
= onceFn()
421 expect(called
).toBe(1)
422 expect(result2
).toBe(1)
423 const result3
= onceFn()
424 expect(called
).toBe(1)
425 expect(result3
).toBe(1)
428 await it('Verify min()', () => {
429 expect(min()).toBe(Infinity)
430 expect(min(0, 1)).toBe(0)
431 expect(min(1, 0)).toBe(0)
432 expect(min(0, -1)).toBe(-1)
433 expect(min(-1, 0)).toBe(-1)
436 await it('Verify max()', () => {
437 expect(max()).toBe(-Infinity)
438 expect(max(0, 1)).toBe(1)
439 expect(max(1, 0)).toBe(1)
440 expect(max(0, -1)).toBe(0)
441 expect(max(-1, 0)).toBe(0)