refactor: add date validation to date convertion helper
[e-mobility-charging-stations-simulator.git] / test / utils / Utils.test.ts
CommitLineData
85cce27f 1import { hoursToMilliseconds, hoursToSeconds } from 'date-fns';
f64ca10c 2import { expect } from 'expect';
a2111e8d 3
878e026c 4import { Constants } from '../../src/utils/Constants';
9bf0ef23
JB
5import {
6 cloneObject,
7 convertToBoolean,
8 convertToDate,
9 convertToFloat,
10 convertToInt,
1553f6df 11 extractTimeSeriesValues,
be4c6702 12 formatDurationMilliSeconds,
8053c842 13 formatDurationSeconds,
9bf0ef23
JB
14 generateUUID,
15 getRandomFloat,
16 getRandomInteger,
17 hasOwnProp,
80c58041 18 isArraySorted,
9bf0ef23
JB
19 isEmptyArray,
20 isEmptyObject,
21 isEmptyString,
22 isIterable,
23 isNotEmptyArray,
24 isNotEmptyString,
25 isNullOrUndefined,
26 isObject,
27 isUndefined,
0bd926c1 28 isValidTime,
9bf0ef23
JB
29 roundTo,
30 secureRandom,
31 sleep,
32 validateUUID,
33} from '../../src/utils/Utils';
a2111e8d 34
878e026c
JB
35describe('Utils test suite', () => {
36 it('Verify generateUUID()/validateUUID()', () => {
9bf0ef23 37 const uuid = generateUUID();
878e026c
JB
38 expect(uuid).toBeDefined();
39 expect(uuid.length).toEqual(36);
9bf0ef23
JB
40 expect(validateUUID(uuid)).toBe(true);
41 expect(validateUUID('abcdef00-0000-4000-0000-000000000000')).toBe(true);
42 expect(validateUUID('')).toBe(false);
878e026c 43 // Shall invalidate Nil UUID
9bf0ef23
JB
44 expect(validateUUID('00000000-0000-0000-0000-000000000000')).toBe(false);
45 expect(validateUUID('987FBC9-4BED-3078-CF07A-9141BA07C9F3')).toBe(false);
878e026c 46 });
8bd02502 47
878e026c 48 it('Verify sleep()', async () => {
f204e9b4 49 const start = performance.now();
9bf0ef23 50 await sleep(1000);
f204e9b4 51 const end = performance.now();
878e026c
JB
52 expect(end - start).toBeGreaterThanOrEqual(1000);
53 });
45999aab 54
be4c6702
JB
55 it('Verify formatDurationMilliSeconds()', () => {
56 expect(formatDurationMilliSeconds(0)).toBe('');
57 expect(formatDurationMilliSeconds(1000)).toBe('1 second');
58 expect(formatDurationMilliSeconds(hoursToMilliseconds(4380))).toBe('182 days 12 hours');
59 });
60
8053c842
JB
61 it('Verify formatDurationSeconds()', () => {
62 expect(formatDurationSeconds(0)).toBe('');
63 expect(formatDurationSeconds(1)).toBe('1 second');
64 expect(formatDurationSeconds(hoursToSeconds(4380))).toBe('182 days 12 hours');
65 });
66
0bd926c1
JB
67 it('Verify isValidTime()', () => {
68 expect(isValidTime(undefined)).toBe(false);
69 expect(isValidTime(null)).toBe(false);
70 expect(isValidTime('')).toBe(false);
71 expect(isValidTime({})).toBe(false);
72 expect(isValidTime([])).toBe(false);
73 expect(isValidTime(new Map())).toBe(false);
74 expect(isValidTime(new Set())).toBe(false);
75 expect(isValidTime(new WeakMap())).toBe(false);
76 expect(isValidTime(new WeakSet())).toBe(false);
77 expect(isValidTime(-1)).toBe(true);
78 expect(isValidTime(0)).toBe(true);
79 expect(isValidTime(1)).toBe(true);
80 expect(isValidTime(-0.5)).toBe(true);
81 expect(isValidTime(0.5)).toBe(true);
82 expect(isValidTime(new Date())).toBe(true);
ac8178a4
JB
83 });
84
878e026c 85 it('Verify convertToDate()', () => {
9bf0ef23 86 expect(convertToDate(undefined)).toBe(undefined);
85cce27f
JB
87 expect(() => convertToDate('')).toThrowError(new Error("Cannot convert to date: ''"));
88 expect(() => convertToDate('00:70:61')).toThrowError(
89 new Error("Cannot convert to date: '00:70:61'"),
90 );
91 expect(convertToDate('0')).toStrictEqual(new Date('1999-12-31T23:00:00.000Z'));
92 expect(convertToDate('-1')).toStrictEqual(new Date('2000-12-31T23:00:00.000Z'));
9bf0ef23 93 expect(convertToDate(0)).toStrictEqual(new Date('1970-01-01T00:00:00.000Z'));
85cce27f 94 expect(convertToDate(-1)).toStrictEqual(new Date('1969-12-31T23:59:59.999Z'));
878e026c 95 const dateStr = '2020-01-01T00:00:00.000Z';
9bf0ef23 96 let date = convertToDate(dateStr);
878e026c
JB
97 expect(date).toBeInstanceOf(Date);
98 expect(date).toStrictEqual(new Date(dateStr));
9bf0ef23 99 date = convertToDate(new Date(dateStr));
878e026c
JB
100 expect(date).toBeInstanceOf(Date);
101 expect(date).toStrictEqual(new Date(dateStr));
102 });
df645d8f 103
878e026c 104 it('Verify convertToInt()', () => {
9bf0ef23
JB
105 expect(convertToInt(undefined)).toBe(0);
106 expect(convertToInt(null)).toBe(0);
107 expect(convertToInt(0)).toBe(0);
108 const randomInteger = getRandomInteger();
109 expect(convertToInt(randomInteger)).toEqual(randomInteger);
110 expect(convertToInt('-1')).toBe(-1);
111 expect(convertToInt('1')).toBe(1);
112 expect(convertToInt('1.1')).toBe(1);
113 expect(convertToInt('1.9')).toBe(1);
114 expect(convertToInt('1.999')).toBe(1);
115 expect(convertToInt(-1)).toBe(-1);
116 expect(convertToInt(1)).toBe(1);
117 expect(convertToInt(1.1)).toBe(1);
118 expect(convertToInt(1.9)).toBe(1);
119 expect(convertToInt(1.999)).toBe(1);
878e026c 120 expect(() => {
9bf0ef23 121 convertToInt('NaN');
85cce27f 122 }).toThrow("Cannot convert to integer: 'NaN'");
878e026c 123 });
df645d8f 124
878e026c 125 it('Verify convertToFloat()', () => {
9bf0ef23
JB
126 expect(convertToFloat(undefined)).toBe(0);
127 expect(convertToFloat(null)).toBe(0);
128 expect(convertToFloat(0)).toBe(0);
129 const randomFloat = getRandomFloat();
130 expect(convertToFloat(randomFloat)).toEqual(randomFloat);
131 expect(convertToFloat('-1')).toBe(-1);
132 expect(convertToFloat('1')).toBe(1);
133 expect(convertToFloat('1.1')).toBe(1.1);
134 expect(convertToFloat('1.9')).toBe(1.9);
135 expect(convertToFloat('1.999')).toBe(1.999);
136 expect(convertToFloat(-1)).toBe(-1);
137 expect(convertToFloat(1)).toBe(1);
138 expect(convertToFloat(1.1)).toBe(1.1);
139 expect(convertToFloat(1.9)).toBe(1.9);
140 expect(convertToFloat(1.999)).toBe(1.999);
878e026c 141 expect(() => {
9bf0ef23 142 convertToFloat('NaN');
85cce27f 143 }).toThrow("Cannot convert to float: 'NaN'");
878e026c 144 });
df645d8f 145
878e026c 146 it('Verify convertToBoolean()', () => {
9bf0ef23
JB
147 expect(convertToBoolean(undefined)).toBe(false);
148 expect(convertToBoolean(null)).toBe(false);
149 expect(convertToBoolean('true')).toBe(true);
150 expect(convertToBoolean('false')).toBe(false);
151 expect(convertToBoolean('TRUE')).toBe(true);
152 expect(convertToBoolean('FALSE')).toBe(false);
153 expect(convertToBoolean('1')).toBe(true);
154 expect(convertToBoolean('0')).toBe(false);
155 expect(convertToBoolean(1)).toBe(true);
156 expect(convertToBoolean(0)).toBe(false);
157 expect(convertToBoolean(true)).toBe(true);
158 expect(convertToBoolean(false)).toBe(false);
159 expect(convertToBoolean('')).toBe(false);
160 expect(convertToBoolean('NoNBoolean')).toBe(false);
878e026c 161 });
df645d8f 162
878e026c 163 it('Verify secureRandom()', () => {
9bf0ef23 164 const random = secureRandom();
878e026c
JB
165 expect(typeof random === 'number').toBe(true);
166 expect(random).toBeGreaterThanOrEqual(0);
167 expect(random).toBeLessThan(1);
168 });
a2111e8d 169
878e026c 170 it('Verify getRandomInteger()', () => {
9bf0ef23 171 let randomInteger = getRandomInteger();
878e026c
JB
172 expect(Number.isSafeInteger(randomInteger)).toBe(true);
173 expect(randomInteger).toBeGreaterThanOrEqual(0);
174 expect(randomInteger).toBeLessThanOrEqual(Constants.MAX_RANDOM_INTEGER);
9bf0ef23
JB
175 expect(randomInteger).not.toEqual(getRandomInteger());
176 randomInteger = getRandomInteger(0, -Constants.MAX_RANDOM_INTEGER);
878e026c
JB
177 expect(randomInteger).toBeGreaterThanOrEqual(-Constants.MAX_RANDOM_INTEGER);
178 expect(randomInteger).toBeLessThanOrEqual(0);
9bf0ef23 179 expect(() => getRandomInteger(0, 1)).toThrowError(
5edd8ba0 180 'The value of "max" is out of range. It must be greater than the value of "min" (1). Received 1',
878e026c 181 );
9bf0ef23 182 expect(() => getRandomInteger(-1)).toThrowError(
5edd8ba0 183 'The value of "max" is out of range. It must be greater than the value of "min" (0). Received 0',
878e026c 184 );
9bf0ef23 185 expect(() => getRandomInteger(Constants.MAX_RANDOM_INTEGER + 1)).toThrowError(
878e026c
JB
186 `The value of "max" is out of range. It must be <= ${
187 Constants.MAX_RANDOM_INTEGER + 1
5edd8ba0 188 }. Received 281_474_976_710_656`,
878e026c 189 );
9bf0ef23 190 randomInteger = getRandomInteger(2, 1);
878e026c
JB
191 expect(randomInteger).toBeGreaterThanOrEqual(1);
192 expect(randomInteger).toBeLessThanOrEqual(2);
193 const max = 2.2,
194 min = 1.1;
9bf0ef23 195 randomInteger = getRandomInteger(max, min);
878e026c
JB
196 expect(randomInteger).toBeGreaterThanOrEqual(Math.ceil(min));
197 expect(randomInteger).toBeLessThanOrEqual(Math.floor(max));
198 });
a2111e8d 199
316d1564 200 it('Verify roundTo()', () => {
9bf0ef23
JB
201 expect(roundTo(0, 2)).toBe(0);
202 expect(roundTo(0.5, 0)).toBe(1);
203 expect(roundTo(0.5, 2)).toBe(0.5);
204 expect(roundTo(-0.5, 0)).toBe(-1);
205 expect(roundTo(-0.5, 2)).toBe(-0.5);
206 expect(roundTo(1.005, 0)).toBe(1);
207 expect(roundTo(1.005, 2)).toBe(1.01);
208 expect(roundTo(2.175, 2)).toBe(2.18);
209 expect(roundTo(5.015, 2)).toBe(5.02);
210 expect(roundTo(-1.005, 2)).toBe(-1.01);
211 expect(roundTo(-2.175, 2)).toBe(-2.18);
212 expect(roundTo(-5.015, 2)).toBe(-5.02);
316d1564
JB
213 });
214
878e026c 215 it('Verify getRandomFloat()', () => {
9bf0ef23 216 let randomFloat = getRandomFloat();
878e026c
JB
217 expect(typeof randomFloat === 'number').toBe(true);
218 expect(randomFloat).toBeGreaterThanOrEqual(0);
219 expect(randomFloat).toBeLessThanOrEqual(Number.MAX_VALUE);
9bf0ef23
JB
220 expect(randomFloat).not.toEqual(getRandomFloat());
221 expect(() => getRandomFloat(0, 1)).toThrowError(new RangeError('Invalid interval'));
222 expect(() => getRandomFloat(Number.MAX_VALUE, -Number.MAX_VALUE)).toThrowError(
5edd8ba0 223 new RangeError('Invalid interval'),
878e026c 224 );
9bf0ef23 225 randomFloat = getRandomFloat(0, -Number.MAX_VALUE);
878e026c
JB
226 expect(randomFloat).toBeGreaterThanOrEqual(-Number.MAX_VALUE);
227 expect(randomFloat).toBeLessThanOrEqual(0);
228 });
a2111e8d 229
1553f6df
JB
230 it('Verify extractTimeSeriesValues()', () => {
231 expect(extractTimeSeriesValues([])).toEqual([]);
232 expect(extractTimeSeriesValues([{ timestamp: Date.now(), value: 1.1 }])).toEqual([1.1]);
233 expect(
234 extractTimeSeriesValues([
235 { timestamp: Date.now(), value: 1.1 },
236 { timestamp: Date.now(), value: 2.2 },
237 ]),
238 ).toEqual([1.1, 2.2]);
239 });
240
878e026c 241 it('Verify isObject()', () => {
9bf0ef23
JB
242 expect(isObject('test')).toBe(false);
243 expect(isObject(undefined)).toBe(false);
244 expect(isObject(null)).toBe(false);
245 expect(isObject(0)).toBe(false);
246 expect(isObject([])).toBe(false);
247 expect(isObject([0, 1])).toBe(false);
248 expect(isObject(['0', '1'])).toBe(false);
249 expect(isObject({})).toBe(true);
250 expect(isObject({ 1: 1 })).toBe(true);
251 expect(isObject({ '1': '1' })).toBe(true);
252 expect(isObject(new Map())).toBe(true);
253 expect(isObject(new Set())).toBe(true);
254 expect(isObject(new WeakMap())).toBe(true);
255 expect(isObject(new WeakSet())).toBe(true);
878e026c 256 });
a2111e8d 257
dd5a1d6c
JB
258 it('Verify cloneObject()', () => {
259 const obj = { 1: 1 };
9bf0ef23
JB
260 expect(cloneObject(obj)).toStrictEqual(obj);
261 expect(cloneObject(obj) === obj).toBe(false);
32f5e42d
JB
262 const nestedObj = { 1: obj, 2: obj };
263 expect(cloneObject(nestedObj)).toStrictEqual(nestedObj);
264 expect(cloneObject(nestedObj) === nestedObj).toBe(false);
dd5a1d6c 265 const array = [1, 2];
9bf0ef23
JB
266 expect(cloneObject(array)).toStrictEqual(array);
267 expect(cloneObject(array) === array).toBe(false);
32f5e42d
JB
268 const objArray = [obj, obj];
269 expect(cloneObject(objArray)).toStrictEqual(objArray);
270 expect(cloneObject(objArray) === objArray).toBe(false);
dd5a1d6c 271 const date = new Date();
9bf0ef23
JB
272 expect(cloneObject(date)).toStrictEqual(date);
273 expect(cloneObject(date) === date).toBe(false);
dd5a1d6c 274 const map = new Map([['1', '2']]);
32f5e42d 275 expect(cloneObject(map)).toStrictEqual({});
dd5a1d6c 276 const set = new Set(['1']);
32f5e42d 277 expect(cloneObject(set)).toStrictEqual({});
dd5a1d6c
JB
278 // The URL object seems to have not enumerable properties
279 const url = new URL('https://domain.tld');
32f5e42d 280 expect(cloneObject(url)).toStrictEqual({});
dd5a1d6c 281 const weakMap = new WeakMap([[{ 1: 1 }, { 2: 2 }]]);
32f5e42d 282 expect(cloneObject(weakMap)).toStrictEqual({});
dd5a1d6c 283 const weakSet = new WeakSet([{ 1: 1 }, { 2: 2 }]);
32f5e42d 284 expect(cloneObject(weakSet)).toStrictEqual({});
dd5a1d6c
JB
285 });
286
af29b598 287 it('Verify hasOwnProp()', () => {
9bf0ef23
JB
288 expect(hasOwnProp('test', '')).toBe(false);
289 expect(hasOwnProp(undefined, '')).toBe(false);
290 expect(hasOwnProp(null, '')).toBe(false);
291 expect(hasOwnProp([], '')).toBe(false);
292 expect(hasOwnProp({}, '')).toBe(false);
293 expect(hasOwnProp({ 1: 1 }, 1)).toBe(true);
294 expect(hasOwnProp({ 1: 1 }, '1')).toBe(true);
295 expect(hasOwnProp({ 1: 1 }, 2)).toBe(false);
296 expect(hasOwnProp({ 1: 1 }, '2')).toBe(false);
297 expect(hasOwnProp({ '1': '1' }, '1')).toBe(true);
298 expect(hasOwnProp({ '1': '1' }, 1)).toBe(true);
299 expect(hasOwnProp({ '1': '1' }, '2')).toBe(false);
300 expect(hasOwnProp({ '1': '1' }, 2)).toBe(false);
af29b598
JB
301 });
302
878e026c 303 it('Verify isIterable()', () => {
9bf0ef23
JB
304 expect(isIterable('')).toBe(true);
305 expect(isIterable(' ')).toBe(true);
306 expect(isIterable('test')).toBe(true);
307 expect(isIterable(undefined)).toBe(false);
308 expect(isIterable(null)).toBe(false);
309 expect(isIterable(0)).toBe(false);
310 expect(isIterable([0, 1])).toBe(true);
311 expect(isIterable({ 1: 1 })).toBe(false);
312 expect(isIterable(new Map())).toBe(true);
313 expect(isIterable(new Set())).toBe(true);
314 expect(isIterable(new WeakMap())).toBe(false);
315 expect(isIterable(new WeakSet())).toBe(false);
878e026c 316 });
a2111e8d 317
878e026c 318 it('Verify isEmptyString()', () => {
9bf0ef23
JB
319 expect(isEmptyString('')).toBe(true);
320 expect(isEmptyString(' ')).toBe(true);
321 expect(isEmptyString(' ')).toBe(true);
322 expect(isEmptyString('test')).toBe(false);
323 expect(isEmptyString(' test')).toBe(false);
324 expect(isEmptyString('test ')).toBe(false);
325 expect(isEmptyString(undefined)).toBe(true);
326 expect(isEmptyString(null)).toBe(true);
327 expect(isEmptyString(0)).toBe(false);
328 expect(isEmptyString({})).toBe(false);
329 expect(isEmptyString([])).toBe(false);
330 expect(isEmptyString(new Map())).toBe(false);
331 expect(isEmptyString(new Set())).toBe(false);
332 expect(isEmptyString(new WeakMap())).toBe(false);
333 expect(isEmptyString(new WeakSet())).toBe(false);
878e026c 334 });
5a2a53cf 335
878e026c 336 it('Verify isNotEmptyString()', () => {
9bf0ef23
JB
337 expect(isNotEmptyString('')).toBe(false);
338 expect(isNotEmptyString(' ')).toBe(false);
339 expect(isNotEmptyString(' ')).toBe(false);
340 expect(isNotEmptyString('test')).toBe(true);
341 expect(isNotEmptyString(' test')).toBe(true);
342 expect(isNotEmptyString('test ')).toBe(true);
343 expect(isNotEmptyString(undefined)).toBe(false);
344 expect(isNotEmptyString(null)).toBe(false);
345 expect(isNotEmptyString(0)).toBe(false);
346 expect(isNotEmptyString({})).toBe(false);
347 expect(isNotEmptyString([])).toBe(false);
348 expect(isNotEmptyString(new Map())).toBe(false);
349 expect(isNotEmptyString(new Set())).toBe(false);
350 expect(isNotEmptyString(new WeakMap())).toBe(false);
351 expect(isNotEmptyString(new WeakSet())).toBe(false);
878e026c 352 });
429f8c9d 353
878e026c 354 it('Verify isUndefined()', () => {
9bf0ef23
JB
355 expect(isUndefined(undefined)).toBe(true);
356 expect(isUndefined(null)).toBe(false);
357 expect(isUndefined('')).toBe(false);
358 expect(isUndefined(0)).toBe(false);
359 expect(isUndefined({})).toBe(false);
360 expect(isUndefined([])).toBe(false);
361 expect(isUndefined(new Map())).toBe(false);
362 expect(isUndefined(new Set())).toBe(false);
363 expect(isUndefined(new WeakMap())).toBe(false);
364 expect(isUndefined(new WeakSet())).toBe(false);
878e026c 365 });
a2111e8d 366
878e026c 367 it('Verify isNullOrUndefined()', () => {
9bf0ef23
JB
368 expect(isNullOrUndefined(undefined)).toBe(true);
369 expect(isNullOrUndefined(null)).toBe(true);
370 expect(isNullOrUndefined('')).toBe(false);
371 expect(isNullOrUndefined(0)).toBe(false);
372 expect(isNullOrUndefined({})).toBe(false);
373 expect(isNullOrUndefined([])).toBe(false);
374 expect(isNullOrUndefined(new Map())).toBe(false);
375 expect(isNullOrUndefined(new Set())).toBe(false);
376 expect(isNullOrUndefined(new WeakMap())).toBe(false);
377 expect(isNullOrUndefined(new WeakSet())).toBe(false);
878e026c 378 });
53ac516c 379
878e026c 380 it('Verify isEmptyArray()', () => {
9bf0ef23
JB
381 expect(isEmptyArray([])).toBe(true);
382 expect(isEmptyArray([1, 2])).toBe(false);
383 expect(isEmptyArray(['1', '2'])).toBe(false);
384 expect(isEmptyArray(undefined)).toBe(false);
385 expect(isEmptyArray(null)).toBe(false);
386 expect(isEmptyArray('')).toBe(false);
387 expect(isEmptyArray('test')).toBe(false);
388 expect(isEmptyArray(0)).toBe(false);
389 expect(isEmptyArray({})).toBe(false);
390 expect(isEmptyArray(new Map())).toBe(false);
391 expect(isEmptyArray(new Set())).toBe(false);
392 expect(isEmptyArray(new WeakMap())).toBe(false);
393 expect(isEmptyArray(new WeakSet())).toBe(false);
878e026c 394 });
a2111e8d 395
878e026c 396 it('Verify isNotEmptyArray()', () => {
9bf0ef23
JB
397 expect(isNotEmptyArray([])).toBe(false);
398 expect(isNotEmptyArray([1, 2])).toBe(true);
399 expect(isNotEmptyArray(['1', '2'])).toBe(true);
400 expect(isNotEmptyArray(undefined)).toBe(false);
401 expect(isNotEmptyArray(null)).toBe(false);
402 expect(isNotEmptyArray('')).toBe(false);
403 expect(isNotEmptyArray('test')).toBe(false);
404 expect(isNotEmptyArray(0)).toBe(false);
405 expect(isNotEmptyArray({})).toBe(false);
406 expect(isNotEmptyArray(new Map())).toBe(false);
407 expect(isNotEmptyArray(new Set())).toBe(false);
408 expect(isNotEmptyArray(new WeakMap())).toBe(false);
409 expect(isNotEmptyArray(new WeakSet())).toBe(false);
878e026c
JB
410 });
411
412 it('Verify isEmptyObject()', () => {
9bf0ef23
JB
413 expect(isEmptyObject({})).toBe(true);
414 expect(isEmptyObject({ 1: 1, 2: 2 })).toBe(false);
9bf0ef23
JB
415 expect(isEmptyObject(new Map())).toBe(false);
416 expect(isEmptyObject(new Set())).toBe(false);
417 expect(isEmptyObject(new WeakMap())).toBe(false);
418 expect(isEmptyObject(new WeakSet())).toBe(false);
878e026c 419 });
80c58041
JB
420
421 it('Verify isArraySorted()', () => {
422 expect(
423 isArraySorted([], (a, b) => {
424 return a - b;
425 }),
426 ).toBe(true);
427 expect(
428 isArraySorted([1], (a, b) => {
429 return a - b;
430 }),
431 ).toBe(true);
432 expect(isArraySorted<number>([1, 2, 3, 4, 5], (a, b) => a - b)).toBe(true);
433 expect(isArraySorted<number>([1, 2, 3, 5, 4], (a, b) => a - b)).toBe(false);
479200ff 434 expect(isArraySorted<number>([2, 1, 3, 4, 5], (a, b) => a - b)).toBe(false);
80c58041 435 });
878e026c 436});