data-structure-typed 2.2.0 → 2.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/CHANGELOG.md +3 -1
  2. package/README.md +1511 -840
  3. package/benchmark/report.html +1 -1
  4. package/benchmark/report.json +145 -169
  5. package/dist/cjs/index.cjs +20 -20
  6. package/dist/cjs/index.cjs.map +1 -1
  7. package/dist/cjs-legacy/index.cjs +20 -20
  8. package/dist/cjs-legacy/index.cjs.map +1 -1
  9. package/dist/esm/index.mjs +20 -20
  10. package/dist/esm/index.mjs.map +1 -1
  11. package/dist/esm-legacy/index.mjs +20 -20
  12. package/dist/esm-legacy/index.mjs.map +1 -1
  13. package/dist/types/data-structures/binary-tree/avl-tree.d.ts +3 -1
  14. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +1 -0
  15. package/dist/types/data-structures/binary-tree/bst.d.ts +1 -0
  16. package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +1 -0
  17. package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +1 -0
  18. package/dist/types/types/data-structures/base/base.d.ts +1 -1
  19. package/dist/umd/data-structure-typed.js +20 -20
  20. package/dist/umd/data-structure-typed.js.map +1 -1
  21. package/dist/umd/data-structure-typed.min.js +2 -2
  22. package/dist/umd/data-structure-typed.min.js.map +1 -1
  23. package/package.json +2 -2
  24. package/src/data-structures/base/iterable-entry-base.ts +4 -4
  25. package/src/data-structures/binary-tree/avl-tree-counter.ts +1 -1
  26. package/src/data-structures/binary-tree/avl-tree-multi-map.ts +1 -1
  27. package/src/data-structures/binary-tree/avl-tree.ts +4 -2
  28. package/src/data-structures/binary-tree/binary-tree.ts +3 -2
  29. package/src/data-structures/binary-tree/bst.ts +2 -1
  30. package/src/data-structures/binary-tree/red-black-tree.ts +2 -1
  31. package/src/data-structures/binary-tree/tree-counter.ts +1 -1
  32. package/src/data-structures/binary-tree/tree-multi-map.ts +2 -1
  33. package/src/data-structures/graph/abstract-graph.ts +3 -3
  34. package/src/data-structures/hash/hash-map.ts +4 -4
  35. package/src/types/data-structures/base/base.ts +1 -1
  36. package/test/performance/data-structures/binary-tree/red-black-tree.test.ts +39 -36
  37. package/test/performance/runner-config.json +4 -4
  38. package/test/unit/data-structures/binary-tree/avl-tree-counter.test.ts +3 -3
  39. package/test/unit/data-structures/binary-tree/avl-tree-multi-map.test.ts +3 -3
  40. package/test/unit/data-structures/binary-tree/avl-tree.test.ts +3 -3
  41. package/test/unit/data-structures/binary-tree/binary-tree.test.ts +4 -4
  42. package/test/unit/data-structures/binary-tree/bst.test.ts +3 -3
  43. package/test/unit/data-structures/binary-tree/red-black-tree.test.ts +3 -3
  44. package/test/unit/data-structures/binary-tree/tree-counter.test.ts +3 -3
  45. package/test/unit/data-structures/binary-tree/tree-multi-map.test.ts +3 -3
  46. package/test/unit/data-structures/graph/directed-graph.test.ts +3 -3
  47. package/test/unit/data-structures/hash/hash-map.test.ts +14 -14
  48. package/test/performance/reportor.mjs +0 -505
@@ -328,7 +328,7 @@ describe('HashMap', () => {
328
328
  });
329
329
 
330
330
  it('some() returns true if any element matches the condition', () => {
331
- expect(hashMap.some(key => key === 'key1')).toBe(true);
331
+ expect(hashMap.some((_value, key) => key === 'key1')).toBe(true);
332
332
  });
333
333
 
334
334
  it('forEach() should execute a function for each element', () => {
@@ -338,12 +338,12 @@ describe('HashMap', () => {
338
338
  });
339
339
 
340
340
  it('map() should transform each element', () => {
341
- const newHashMap = hashMap.map((key, value) => value.toUpperCase());
341
+ const newHashMap = hashMap.map(value => value.toUpperCase());
342
342
  expect(newHashMap.get('key1')).toBe('VALUE1');
343
343
  });
344
344
 
345
345
  it('filter() should remove elements that do not match the condition', () => {
346
- const filteredHashMap = hashMap.filter(key => key !== 'key1');
346
+ const filteredHashMap = hashMap.filter((_, key) => key !== 'key1');
347
347
  expect(filteredHashMap.has('key1')).toBe(false);
348
348
  });
349
349
 
@@ -361,28 +361,28 @@ describe('HashMap', () => {
361
361
  });
362
362
 
363
363
  it('should find', () => {
364
- const found = hashMap.find((key, value) => value === 'value1');
364
+ const found = hashMap.find(value => value === 'value1');
365
365
  expect(found).toEqual(['key1', 'value1']);
366
366
  const notFound = hashMap.find(value => value === 'value6');
367
367
  expect(notFound).toEqual(undefined);
368
368
  });
369
369
 
370
370
  it('should every', () => {
371
- const isEvery = hashMap.every((key, value) => value.substring(0, 5) === 'value');
371
+ const isEvery = hashMap.every(value => value.substring(0, 5) === 'value');
372
372
  expect(isEvery).toEqual(true);
373
- const isEvery4 = hashMap.every((key, value) => value.substring(0, 4) === 'value');
373
+ const isEvery4 = hashMap.every(value => value.substring(0, 4) === 'value');
374
374
  expect(isEvery4).toEqual(false);
375
375
  });
376
376
 
377
377
  it('should some', () => {
378
- const isSome = hashMap.some((key, value) => value.substring(5, 6) === '2');
378
+ const isSome = hashMap.some(value => value.substring(5, 6) === '2');
379
379
  expect(isSome).toEqual(true);
380
- const isSome4 = hashMap.some((key, value) => value.substring(0, 5) === 'value');
380
+ const isSome4 = hashMap.some(value => value.substring(0, 5) === 'value');
381
381
  expect(isSome4).toEqual(true);
382
382
  });
383
383
 
384
384
  it('should forEach', () => {
385
- hashMap.forEach((key, value, index) => expect(value.substring(5, 6)).toBe(String(index + 1)));
385
+ hashMap.forEach((value, key, index) => expect(value.substring(5, 6)).toBe(String(index + 1)));
386
386
  });
387
387
 
388
388
  it('should entries', () => {
@@ -817,7 +817,7 @@ describe('LinkedHashMap', () => {
817
817
  });
818
818
 
819
819
  it('some() returns true if any element matches the condition', () => {
820
- expect(hashMap.some(key => key === 'key1')).toBe(true);
820
+ expect(hashMap.some((_value, key) => key === 'key1')).toBe(true);
821
821
  });
822
822
 
823
823
  it('forEach() should execute a function for each element', () => {
@@ -827,12 +827,12 @@ describe('LinkedHashMap', () => {
827
827
  });
828
828
 
829
829
  it('map() should transform each element', () => {
830
- const newHashMap = hashMap.map((key, value) => [key, value.toUpperCase()]);
830
+ const newHashMap = hashMap.map((value, key) => [key, value.toUpperCase()]);
831
831
  expect(newHashMap.get('key1')).toBe('VALUE1');
832
832
  });
833
833
 
834
834
  it('filter() should remove elements that do not match the condition', () => {
835
- const filteredHashMap = hashMap.filter(key => key !== 'key1');
835
+ const filteredHashMap = hashMap.filter((_v, key) => key !== 'key1');
836
836
  expect(filteredHashMap.has('key1')).toBe(false);
837
837
  });
838
838
 
@@ -893,7 +893,7 @@ describe('classic uses', () => {
893
893
  linkedHashMap.set(2, 'B');
894
894
  linkedHashMap.set(3, 'C');
895
895
 
896
- const filteredMap = linkedHashMap.filter((key, value) => value !== 'B');
896
+ const filteredMap = linkedHashMap.filter(value => value !== 'B');
897
897
 
898
898
  const result = Array.from(filteredMap);
899
899
  expect(result).toEqual([
@@ -907,7 +907,7 @@ describe('classic uses', () => {
907
907
  linkedHashMap.set(1, 'A');
908
908
  linkedHashMap.set(2, 'B');
909
909
 
910
- const mappedMap = linkedHashMap.map((key, value) => [value, key]);
910
+ const mappedMap = linkedHashMap.map((value, key) => [value, key]);
911
911
 
912
912
  const result = Array.from(mappedMap);
913
913
  expect(result).toEqual([
@@ -1,505 +0,0 @@
1
- import * as path from 'path';
2
- import * as fs from 'fs';
3
- import fastGlob from 'fast-glob';
4
- import { fileURLToPath } from 'url';
5
-
6
- const isNumber = value => {
7
- return typeof value === 'number';
8
- };
9
- const isString = value => {
10
- return typeof value === 'string';
11
- };
12
- const isBoolean = value => {
13
- return typeof value === 'boolean';
14
- };
15
- const isDate = value => {
16
- return value instanceof Date;
17
- };
18
- const isNull = value => {
19
- return value === null;
20
- };
21
- const isUndefined = value => {
22
- return typeof value === 'undefined';
23
- };
24
- const isFunction = value => {
25
- return typeof value === 'function';
26
- };
27
- const isObject = value => {
28
- return typeof value === 'object';
29
- };
30
- const isArray = value => {
31
- return Array.isArray(value);
32
- };
33
- const isEqual = (objA, objB) => {
34
- if (objA === objB) {
35
- return true;
36
- }
37
- if (typeof objA !== 'object' || typeof objB !== 'object' || objA === null || objB === null) {
38
- return false;
39
- }
40
- const keysA = Object.keys(objA);
41
- const keysB = Object.keys(objB);
42
- if (keysA.length !== keysB.length) {
43
- return false;
44
- }
45
- for (const key of keysA) {
46
- if (!keysB.includes(key)) {
47
- return false;
48
- }
49
- if (!isEqual(objA[key], objB[key])) {
50
- return false;
51
- }
52
- }
53
- return true;
54
- };
55
-
56
- function toggleJS(options) {
57
- if (options === null || options === void 0 ? void 0 : options.plainHtml) {
58
- return '';
59
- } else {
60
- return 'onclick="json-to-html.toggleVisibility(this);return false"';
61
- }
62
- }
63
-
64
- function makeLabelDiv(options, level, keyName, datatype) {
65
- if (typeof keyName === 'number') {
66
- return `<div class='index'><span class='json-to-html-label'>${keyName}&nbsp;</span></div>`;
67
- } else if (typeof keyName === 'string') {
68
- if (datatype === 'array') {
69
- return `<div class='collapsible level${level}' ${toggleJS(options)}><span class='json-to-html-label'>${keyName}</span></div>`;
70
- } else if (datatype === 'object') {
71
- return `<div class='attribute collapsible level${level}' ${toggleJS(options)}><span class='json-to-html-label'>${keyName}:</span></div>`;
72
- } else {
73
- return `<div class='leaf level${level}'><span class='json-to-html-label'>${keyName}:</span></div>`;
74
- }
75
- } else {
76
- return '';
77
- }
78
- }
79
-
80
- function getContentClass(keyName) {
81
- if (typeof keyName === 'string') {
82
- return 'content';
83
- } else {
84
- return '';
85
- }
86
- }
87
-
88
- function isPlainObject(val) {
89
- let lastKey;
90
- let lastOwnKey;
91
- for (const key in val) {
92
- if (val.hasOwnProperty(key)) {
93
- lastOwnKey = key;
94
- }
95
- }
96
- for (const key in val) {
97
- lastKey = key;
98
- }
99
- return lastOwnKey === lastKey;
100
- }
101
-
102
- function isLeafValue(val) {
103
- return (
104
- isNumber(val) ||
105
- isString(val) ||
106
- isBoolean(val) ||
107
- isDate(val) ||
108
- isNull(val) ||
109
- isUndefined(val) ||
110
- isNaN(val) ||
111
- isFunction(val) ||
112
- !isPlainObject(val)
113
- );
114
- }
115
-
116
- function isLeafObject(obj) {
117
- if (!isObject(obj)) {
118
- return false;
119
- }
120
- for (const key in obj) {
121
- const val = obj[key];
122
- if (!isLeafValue(val)) {
123
- return false;
124
- }
125
- }
126
- return true;
127
- }
128
-
129
- function isTable(arr) {
130
- if (!isArray(arr)) {
131
- return false;
132
- }
133
- if (arr.length === 0 || !isObject(arr[0])) {
134
- return false;
135
- } else {
136
- let nonCompliant = arr.find(row => !isLeafObject(row));
137
- if (nonCompliant) {
138
- return false;
139
- } else {
140
- const cols = Object.keys(arr[0]);
141
- nonCompliant = arr.find(row => !isEqual(cols, Object.keys(row)));
142
- return !nonCompliant;
143
- }
144
- }
145
- }
146
-
147
- function drawTable(arr) {
148
- function drawRow(headers, rowObj) {
149
- return '<td>' + headers.map(header => rowObj[header]).join('</td><td>') + '</td>';
150
- }
151
-
152
- const cols = Object.keys(arr[0]);
153
- const content = arr.map(rowObj => drawRow(cols, rowObj));
154
- const headingHtml = '<tr><th>' + cols.join('</th><th>') + '</th></tr>';
155
- const contentHtml = '<tr>' + content.join('</tr><tr>') + '</tr>';
156
- return '<table style="display: table; width:100%; table-layout: fixed;">' + headingHtml + contentHtml + '</table>';
157
- }
158
-
159
- function _render(name, data, options, level, altRow) {
160
- const contentClass = getContentClass(name);
161
- if (isArray(data)) {
162
- const title = makeLabelDiv(options, level, `${name}`, 'array');
163
- let subs;
164
- if (isTable(data)) {
165
- subs = drawTable(data);
166
- } else {
167
- subs =
168
- "<div class='altRows'>" +
169
- data
170
- .map((val, idx) => _render(idx.toString(), val, options, level + 1, idx % 2))
171
- .join("</div><div class='altRows'>") +
172
- '</div>';
173
- }
174
- return `<div class="json-to-html-collapse clearfix ${altRow}">
175
- ${title}
176
- <div class="${contentClass}">${subs}</div>
177
- </div>`;
178
- } else if (isLeafValue(data)) {
179
- const title = makeLabelDiv(options, level, name);
180
- if (isFunction(data)) {
181
- return `${title}<span class='json-to-html-value'>&nbsp;&nbsp;-function() can't _render-</span>`;
182
- } else if (!isPlainObject(data)) {
183
- if (isFunction(data.toString)) {
184
- return `${title}<span class='json-to-html-value'>&nbsp;&nbsp;${data.toString()}</span>`;
185
- } else {
186
- return `${title}<span class='json-to-html-value'>&nbsp;&nbsp;-instance object, can't render-</span>`;
187
- }
188
- } else {
189
- return `${title}<span class='json-to-html-value'>&nbsp;&nbsp;${data}</span>`;
190
- }
191
- } else {
192
- const title = makeLabelDiv(options, level, name, 'object');
193
- let count = 0;
194
- const subs =
195
- '<div>' +
196
- Object.entries(data)
197
- .map(([key, val]) => _render(key, val, options, level + 1, count++ % 2))
198
- .join('</div><div>') +
199
- '</div>';
200
- const inner = `<div class="json-to-html-expand clearfix ${altRow}">
201
- ${title}
202
- <div class="${contentClass}">${subs}</div>
203
- </div>`;
204
- return `${level === 0 ? "<div id='json-to-html'>" : ''}
205
- ${inner}
206
- ${level === 0 ? '</div>' : ''}`;
207
- }
208
- }
209
-
210
- export function render(name, json, options) {
211
- return `${_render(name, json, options, 0, 0)}`;
212
- }
213
-
214
- const __filename = fileURLToPath(import.meta.url);
215
- const __dirname = path.dirname(__filename);
216
-
217
- function numberFix(num, decimalPlaces) {
218
- if (num > 10000 || num < 0.001) {
219
- const [mantissa, exponent] = num.toExponential().split('e');
220
- const formattedMantissa = Number(mantissa).toFixed(decimalPlaces);
221
- return `${formattedMantissa}e${exponent}`;
222
- } else {
223
- return num.toFixed(decimalPlaces);
224
- }
225
- }
226
-
227
- const ConsoleColor = {
228
- END: '\x1b[0m',
229
- BOLD: '\x1b[1m',
230
- DIM: '\x1b[2m',
231
- ITALIC: '\x1b[3m',
232
- UNDERLINE: '\x1b[4m',
233
- INVERSE: '\x1b[7m',
234
- STRIKETHROUGH: '\x1b[9m',
235
- NO_BOLD: '\x1b[22m',
236
- NO_ITALIC: '\x1b[23m',
237
- NO_UNDERLINE: '\x1b[24m',
238
- NO_INVERSE: '\x1b[27m',
239
- NO_STRIKETHROUGH: '\x1b[29m',
240
- BLACK: '\x1b[30m',
241
- RED: '\x1b[31m',
242
- GREEN: '\x1b[32m',
243
- YELLOW: '\x1b[33m',
244
- BLUE: '\x1b[34m',
245
- MAGENTA: '\x1b[35m',
246
- GRAY: '\x1b[90m',
247
- CYAN: '\x1b[36m',
248
- WHITE: '\x1b[37m',
249
- BG_BLACK: '\x1b[40m',
250
- BG_RED: '\x1b[41m',
251
- BG_GREEN: '\x1b[42m',
252
- BG_YELLOW: '\x1b[43m',
253
- BG_BLUE: '\x1b[44m',
254
- BG_MAGENTA: '\x1b[45m',
255
- BG_CYAN: '\x1b[46m',
256
- BG_WHITE: '\x1b[47m'
257
- };
258
- const args = process.argv.slice(2);
259
- const { GREEN, BOLD, END, YELLOW, GRAY, CYAN, BG_YELLOW } = ConsoleColor;
260
- const isOnlyOrdered = true;
261
- const runOrder = [
262
- 'heap',
263
- 'avl-tree',
264
- 'red-black-tree',
265
- 'doubly-linked-list',
266
- 'directed-graph',
267
- 'queue',
268
- 'deque',
269
- 'hash-map',
270
- 'trie',
271
- 'stack'
272
- // 'singly-linked-list',
273
- // 'priority-queue',
274
- // 'binary-tree-overall'
275
- ];
276
- const getRelativePath = file => {
277
- return path.relative(__dirname, file);
278
- };
279
- const coloredLabeled = (label, file) => {
280
- const relativeFilePath = getRelativePath(file);
281
- const directory = path.dirname(relativeFilePath);
282
- const fileName = path.basename(relativeFilePath);
283
- return `${BG_YELLOW} ${label} ${END} ${GRAY}${directory}/${END}${CYAN}${fileName}${END}`;
284
- };
285
- const parentDirectory = path.resolve(__dirname, '../..');
286
- const reportDistPath = path.join(parentDirectory, 'benchmark');
287
- const testDir = path.join(__dirname, 'data-structures');
288
- let allFiles = fastGlob.sync(path.join(testDir, '**', '*.test.mjs'));
289
-
290
- let testFiles;
291
- let isIndividual = false;
292
- if (args.length > 0) {
293
- console.log(`arguments: ${args.join(' ')}`);
294
- testFiles = allFiles.filter(file => args.every(word => file.includes(word)));
295
- isIndividual = true;
296
- console.log(
297
- `${testFiles.map(file => coloredLabeled('Found', file)).join(`
298
- `)}`
299
- );
300
- } else {
301
- isIndividual = false;
302
- testFiles = allFiles;
303
- }
304
- const report = {};
305
- let completedCount = 0;
306
- const performanceTests = [];
307
- for (const file of testFiles) {
308
- const testName = path.basename(file, '.test.mjs');
309
- const testFunction = await import(file);
310
- const { suite } = testFunction;
311
- if (suite)
312
- performanceTests.push({
313
- testName,
314
- suite,
315
- file
316
- });
317
- }
318
-
319
- const composeReport = () => {
320
- if (!fs.existsSync(reportDistPath))
321
- fs.mkdirSync(reportDistPath, {
322
- recursive: true
323
- });
324
- const filePath = path.join(reportDistPath, 'report.json');
325
- const htmlFilePath = path.join(reportDistPath, 'report.html');
326
- fs.writeFileSync(filePath, JSON.stringify(report, null, 2));
327
- let html = `<!DOCTYPE html>
328
- <html lang="en">
329
- <head>
330
- <meta charset="UTF-8">
331
- <title>performance of data-structure-typed</title>
332
- <style>
333
- *{
334
- box-sizing: border-box;
335
- }
336
- #json-to-html {
337
- padding: 0 10px 20px;
338
- }
339
-
340
- .json-to-html-label {
341
- font-size: 2rem;
342
- margin: 2rem 0 0 3px;
343
- }
344
- .content table {
345
- width: 100%;
346
- table-layout: fixed;
347
- border-collapse: collapse;
348
- margin-top: 10px;
349
- font-size: 16px;
350
- }
351
-
352
- .content table th,
353
- .content table td {
354
- padding: 8px 12px;
355
- text-align: left;
356
- border: 1px solid #ddd;
357
- }
358
-
359
- .content table th {
360
- background-color: #f2f2f2;
361
- font-weight: bold;
362
- }
363
-
364
- .content table tr:nth-child(odd) {
365
- background-color: #ffffff;
366
- }
367
- </style>
368
- </head>
369
- <body>
370
- <div id="json-to-html">`;
371
- let htmlTables = '';
372
- for (const r in report) {
373
- if (report.hasOwnProperty(r)) {
374
- htmlTables += render(report[r].testName, report[r].benchmarks, {
375
- plainHtml: true,
376
- '<>': 'table',
377
- html: [
378
- {
379
- '<>': 'tr',
380
- html: [
381
- {
382
- '<>': 'td',
383
- html: '${name}'
384
- },
385
- {
386
- '<>': 'td',
387
- html: '${periodMS}'
388
- },
389
- {
390
- '<>': 'td',
391
- html: '${mean}'
392
- }
393
- ]
394
- }
395
- ]
396
- });
397
- }
398
- }
399
- htmlTables += `
400
-
401
- `;
402
- html += htmlTables;
403
- html += `</div>
404
- </body>
405
- </html>`;
406
- if (!isIndividual)
407
- replaceMarkdownContent(
408
- '[//]: # (No deletion!!! Start of Replace Section)', // Start tag
409
- '[//]: # (No deletion!!! End of Replace Section)', // end identifier
410
- htmlTables // New content to be inserted
411
- );
412
- fs.writeFileSync(htmlFilePath, html);
413
- console.log(`Performance ${BOLD}${GREEN}report${END} file generated in file://${BOLD}${GREEN}${htmlFilePath}${END}`);
414
- };
415
-
416
- function replaceMarkdownContent(startMarker, endMarker, newText) {
417
- const filePath = path.join(parentDirectory, 'README.md'); // Path to README.md file
418
- fs.readFile(filePath, 'utf8', (err, data) => {
419
- if (err) {
420
- console.error(`Unable to read ${filePath}:`, err);
421
- return;
422
- }
423
- // Find the start and end markers in the content
424
- const startIndex = data.indexOf(startMarker);
425
- const endIndex = data.indexOf(endMarker, startIndex + 1);
426
- if (startIndex === -1 || endIndex === -1) {
427
- console.error('Unable to find start or end marker');
428
- return;
429
- }
430
- // Replace the old content with the new text
431
- const updatedMarkdown = data.slice(0, startIndex + startMarker.length) + '\n' + newText + data.slice(endIndex);
432
- // Try writing the modified content back to the file
433
- fs.writeFile(filePath, updatedMarkdown, 'utf8', err => {
434
- if (err) {
435
- console.error(`Unable to write to ${filePath}:`, err);
436
- } else {
437
- console.log(`The content has been successfully replaced in file://${BOLD}${GREEN}${filePath}${END}`);
438
- }
439
- });
440
- });
441
- }
442
-
443
- const sortedPerformanceTests = (
444
- isOnlyOrdered ? [...performanceTests].filter(test => runOrder.includes(test.testName)) : [...performanceTests]
445
- ).sort((a, b) => {
446
- const indexA = runOrder.indexOf(a.testName);
447
- const indexB = runOrder.indexOf(b.testName);
448
- // If both a and b are in the runOrder, sort them according to their indices in the runOrder.
449
- if (indexA !== -1 && indexB !== -1) {
450
- return indexA - indexB;
451
- }
452
- // If there is only 'a' in the runOrder, then place 'b' in front.
453
- if (indexA !== -1) {
454
- return 1;
455
- }
456
- // If only b is in the runOrder, then a should be placed before it.
457
- if (indexB !== -1) {
458
- return -1;
459
- }
460
- // If neither a nor b are in runOrder, keep their original runOrder
461
- return 0;
462
- });
463
- console.log(
464
- `${GREEN} Matched Suites (${performanceTests.length})${END}: ${performanceTests.map(test => test.testName)}`
465
- );
466
- console.log(
467
- `${GREEN} Running Suites (${sortedPerformanceTests.length})${END}: ${sortedPerformanceTests.map(test => test.testName)}`
468
- );
469
- sortedPerformanceTests.forEach(item => {
470
- const { suite, testName, file } = item;
471
- console.log(coloredLabeled('Running', file));
472
- if (suite) {
473
- let runTime = 0;
474
- suite
475
- .on('complete', function () {
476
- completedCount++;
477
- report[testName] = {};
478
- report[testName].benchmarks = this.map(benchmark => {
479
- runTime += benchmark.times.elapsed;
480
- return {
481
- 'test name': benchmark.name,
482
- 'time taken (ms)': numberFix(benchmark.times.period * 1000, 2),
483
- // 'executions per sec': numberFix(benchmark.hz, 2),
484
- // 'executed times': numberFix(benchmark.count, 0),
485
- 'sample mean (secs)': numberFix(benchmark.stats.mean, 2),
486
- 'sample deviation': numberFix(benchmark.stats.deviation, 2)
487
- };
488
- });
489
- report[testName].testName = testName;
490
- const isDone = completedCount === sortedPerformanceTests.length;
491
- runTime = Number(runTime.toFixed(2));
492
- const isTimeWarn = runTime > 120;
493
- console.log(
494
- // `Files: ${GREEN}${testFileCount}${END} `,
495
- // `Suites: ${GREEN}${performanceTests.length}${END} `,
496
- `Suites Progress: ${isDone ? GREEN : YELLOW}${completedCount}${END}/${isDone ? GREEN : YELLOW}${sortedPerformanceTests.length}${END}`,
497
- `Time Costs: ${isTimeWarn ? YELLOW : GREEN}${runTime}s${END}`
498
- );
499
- if (isDone) {
500
- composeReport();
501
- }
502
- })
503
- .run({ async: false });
504
- }
505
- });