UNPKG

3.36 kBJavaScriptView Raw
1/**
2 * @fileoverview Tracks performance of individual rules.
3 * @author Brandon Mills
4 */
5
6"use strict";
7
8//------------------------------------------------------------------------------
9// Helpers
10//------------------------------------------------------------------------------
11
12/* istanbul ignore next */
13/**
14 * Align the string to left
15 * @param {string} str string to evaluate
16 * @param {int} len length of the string
17 * @param {string} ch delimiter character
18 * @returns {string} modified string
19 * @private
20 */
21function alignLeft(str, len, ch) {
22 return str + new Array(len - str.length + 1).join(ch || " ");
23}
24
25/* istanbul ignore next */
26/**
27 * Align the string to right
28 * @param {string} str string to evaluate
29 * @param {int} len length of the string
30 * @param {string} ch delimiter character
31 * @returns {string} modified string
32 * @private
33 */
34function alignRight(str, len, ch) {
35 return new Array(len - str.length + 1).join(ch || " ") + str;
36}
37
38//------------------------------------------------------------------------------
39// Module definition
40//------------------------------------------------------------------------------
41
42const enabled = !!process.env.TIMING;
43
44const HEADERS = ["Rule", "Time (ms)", "Relative"];
45const ALIGN = [alignLeft, alignRight, alignRight];
46
47/* istanbul ignore next */
48/**
49 * display the data
50 * @param {Object} data Data object to be displayed
51 * @returns {string} modified string
52 * @private
53 */
54function display(data) {
55 let total = 0;
56 const rows = Object.keys(data)
57 .map(key => {
58 const time = data[key];
59
60 total += time;
61 return [key, time];
62 })
63 .sort((a, b) => b[1] - a[1])
64 .slice(0, 10);
65
66 rows.forEach(row => {
67 row.push(`${(row[1] * 100 / total).toFixed(1)}%`);
68 row[1] = row[1].toFixed(3);
69 });
70
71 rows.unshift(HEADERS);
72
73 const widths = [];
74
75 rows.forEach(row => {
76 const len = row.length;
77
78 for (let i = 0; i < len; i++) {
79 const n = row[i].length;
80
81 if (!widths[i] || n > widths[i]) {
82 widths[i] = n;
83 }
84 }
85 });
86
87 const table = rows.map(row => (
88 row
89 .map((cell, index) => ALIGN[index](cell, widths[index]))
90 .join(" | ")
91 ));
92
93 table.splice(1, 0, widths.map((width, index) => {
94 const extraAlignment = index !== 0 && index !== widths.length - 1 ? 2 : 1;
95
96 return ALIGN[index](":", width + extraAlignment, "-");
97 }).join("|"));
98
99 console.log(table.join("\n")); // eslint-disable-line no-console
100}
101
102/* istanbul ignore next */
103module.exports = (function() {
104
105 const data = Object.create(null);
106
107 /**
108 * Time the run
109 * @param {*} key key from the data object
110 * @param {Function} fn function to be called
111 * @returns {Function} function to be executed
112 * @private
113 */
114 function time(key, fn) {
115 if (typeof data[key] === "undefined") {
116 data[key] = 0;
117 }
118
119 return function(...args) {
120 let t = process.hrtime();
121
122 fn(...args);
123 t = process.hrtime(t);
124 data[key] += t[0] * 1e3 + t[1] / 1e6;
125 };
126 }
127
128 if (enabled) {
129 process.on("exit", () => {
130 display(data);
131 });
132 }
133
134 return {
135 time,
136 enabled
137 };
138
139}());