UNPKG

12.2 kBJavaScriptView Raw
1(function (factory) {
2 if (typeof module === "object" && typeof module.exports === "object") {
3 var v = factory(require, exports);
4 if (v !== undefined) module.exports = v;
5 }
6 else if (typeof define === "function" && define.amd) {
7 define(["require", "exports", "tslib", "fs", "./Reporter"], factory);
8 }
9})(function (require, exports) {
10 "use strict";
11 Object.defineProperty(exports, "__esModule", { value: true });
12 var tslib_1 = require("tslib");
13 var fs_1 = require("fs");
14 var Reporter_1 = tslib_1.__importStar(require("./Reporter"));
15 var BenchmarkReporter = (function (_super) {
16 tslib_1.__extends(BenchmarkReporter, _super);
17 function BenchmarkReporter(executor, options) {
18 if (options === void 0) { options = {}; }
19 var _this = _super.call(this, executor, options) || this;
20 _this.mode = options.mode || 'test';
21 _this.filename = options.filename || '';
22 _this.thresholds = options.thresholds || {};
23 if (_this.mode === 'test') {
24 try {
25 _this.baseline = JSON.parse(fs_1.readFileSync(_this.filename, { encoding: 'utf8' }));
26 }
27 catch (error) {
28 _this.console.warn('Unable to load benchmark baseline data from ' + _this.filename);
29 _this.console.warn('Switching to "baseline" mode');
30 _this.mode = 'baseline';
31 }
32 }
33 if (!_this.baseline) {
34 _this.baseline = {};
35 }
36 _this.sessions = {};
37 return _this;
38 }
39 BenchmarkReporter.prototype._getSession = function (testOrSuite) {
40 var sessionId = testOrSuite.sessionId || 'local';
41 var session = this.sessions[sessionId];
42 if (!session) {
43 var client = void 0;
44 var version = void 0;
45 var platform_1;
46 if (testOrSuite.sessionId) {
47 var environmentType = testOrSuite.remote.environmentType;
48 client = environmentType.browserName;
49 version = environmentType.version;
50 platform_1 = environmentType.platform;
51 }
52 else {
53 client = process.title;
54 version = process.version;
55 platform_1 = process.platform;
56 }
57 session = this.sessions[sessionId] = {
58 suites: {},
59 environment: {
60 client: client,
61 version: version,
62 platform: platform_1,
63 id: client + ':' + version + ':' + platform_1
64 }
65 };
66 }
67 return session;
68 };
69 BenchmarkReporter.prototype.runEnd = function () {
70 if (this.mode === 'baseline') {
71 var existingBaseline_1;
72 try {
73 existingBaseline_1 = JSON.parse(fs_1.readFileSync(this.filename, { encoding: 'utf8' }));
74 }
75 catch (error) {
76 existingBaseline_1 = {};
77 }
78 var baseline_1 = this.baseline;
79 Object.keys(baseline_1).forEach(function (environmentId) {
80 existingBaseline_1[environmentId] = baseline_1[environmentId];
81 });
82 fs_1.writeFileSync(this.filename, JSON.stringify(existingBaseline_1, null, ' '));
83 }
84 };
85 BenchmarkReporter.prototype.suiteEnd = function (suite) {
86 var session = this._getSession(suite);
87 if (!suite.hasParent) {
88 var environment = session.environment;
89 this.console.log('Finished benchmarking ' +
90 environment.client +
91 ' ' +
92 environment.version +
93 ' on ' +
94 environment.platform);
95 }
96 else if (this.mode === 'test') {
97 var suiteInfo = session.suites[suite.id];
98 var numTests = suiteInfo.numBenchmarks;
99 if (numTests > 0) {
100 var numFailedTests = suiteInfo.numFailedBenchmarks;
101 var message = numFailedTests + '/' + numTests + ' benchmarks failed in ' + suite.id;
102 if (numFailedTests > 0) {
103 this.console.warn(message);
104 }
105 else {
106 this.console.log(message);
107 }
108 }
109 }
110 };
111 BenchmarkReporter.prototype.suiteStart = function (suite) {
112 var session = this._getSession(suite);
113 if (!suite.hasParent) {
114 var environment = session.environment;
115 var environmentName = environment.client +
116 ' ' +
117 environment.version +
118 ' on ' +
119 environment.platform;
120 var baselineEnvironments = this.baseline;
121 this.console.log((this.mode === 'baseline' ? 'Baselining' : 'Benchmarking') +
122 ' ' +
123 environmentName);
124 if (this.mode === 'baseline') {
125 baselineEnvironments[environment.id] = {
126 client: environment.client,
127 version: environment.version,
128 platform: environment.platform,
129 tests: {}
130 };
131 }
132 else if (!baselineEnvironments[environment.id]) {
133 this.console.warn('No baseline data for ' + environmentName + '!');
134 }
135 }
136 else {
137 session.suites[suite.id] = {
138 numBenchmarks: 0,
139 numFailedBenchmarks: 0
140 };
141 }
142 };
143 BenchmarkReporter.prototype.testEnd = function (test) {
144 var _this = this;
145 var benchmarkTest = test;
146 if (benchmarkTest.benchmark == null) {
147 return;
148 }
149 if (benchmarkTest.error) {
150 var session = this._getSession(benchmarkTest);
151 var suiteInfo = session.suites[benchmarkTest.parentId];
152 suiteInfo.numBenchmarks++;
153 suiteInfo.numFailedBenchmarks++;
154 this.console.error('FAIL: ' + benchmarkTest.id);
155 this.console.error(this.executor.formatError(benchmarkTest.error, { space: ' ' }));
156 }
157 else {
158 var checkTest = function (baseline, benchmark) {
159 var warn = [];
160 var fail = [];
161 var list;
162 var baselineMean = baseline.stats.mean;
163 var thresholds = _this.thresholds || {};
164 var percentDifference = (100 * (benchmark.stats.mean - baselineMean)) / baselineMean;
165 if (thresholds.warn &&
166 thresholds.warn.mean &&
167 Math.abs(percentDifference) > thresholds.warn.mean) {
168 list = warn;
169 if (thresholds.fail &&
170 thresholds.fail.mean &&
171 Math.abs(percentDifference) > thresholds.fail.mean) {
172 list = fail;
173 }
174 list.push('Execution time is ' + percentDifference.toFixed(1) + '% off');
175 }
176 var baselineRme = baseline.stats.rme;
177 percentDifference = benchmark.stats.rme - baselineRme;
178 if (thresholds.warn &&
179 thresholds.warn.rme &&
180 Math.abs(percentDifference) > thresholds.warn.rme) {
181 list = warn;
182 if (thresholds.fail &&
183 thresholds.fail.rme &&
184 Math.abs(percentDifference) > thresholds.fail.rme) {
185 list = fail;
186 }
187 list.push('RME is ' + percentDifference.toFixed(1) + '% off');
188 }
189 if (fail.length) {
190 _this.console.error('FAIL ' + benchmarkTest.id + ' (' + fail.join(', ') + ')');
191 return false;
192 }
193 else if (warn.length) {
194 _this.console.warn('WARN ' + benchmarkTest.id + ' (' + warn.join(', ') + ')');
195 }
196 else {
197 _this.console.log('PASS ' + benchmarkTest.id);
198 }
199 return true;
200 };
201 var benchmark = benchmarkTest.benchmark;
202 var session = this._getSession(benchmarkTest);
203 var environment = session.environment;
204 var suiteInfo = session.suites[benchmarkTest.parentId];
205 suiteInfo.numBenchmarks++;
206 var baseline = this.baseline[environment.id];
207 if (this.mode === 'baseline') {
208 baseline.tests[benchmarkTest.id] = {
209 hz: benchmark.hz,
210 times: benchmark.times,
211 stats: {
212 rme: benchmark.stats.rme,
213 moe: benchmark.stats.moe,
214 mean: benchmark.stats.mean
215 }
216 };
217 this.console.log('Baselined ' + benchmarkTest.name);
218 this.executor.log('Time per run:', formatSeconds(benchmark.stats.mean), '\xb1', benchmark.stats.rme.toFixed(2), '%');
219 }
220 else {
221 if (baseline) {
222 var testData = baseline.tests[benchmarkTest.id];
223 var result = checkTest(testData, benchmark);
224 var baselineStats = testData.stats;
225 var benchmarkStats = benchmark.stats;
226 this.executor.log('Expected time per run:', formatSeconds(baselineStats.mean), '\xb1', baselineStats.rme.toFixed(2), '%');
227 this.executor.log('Actual time per run:', formatSeconds(benchmarkStats.mean), '\xb1', benchmarkStats.rme.toFixed(2), '%');
228 if (!result) {
229 suiteInfo.numFailedBenchmarks++;
230 }
231 }
232 }
233 }
234 };
235 tslib_1.__decorate([
236 Reporter_1.eventHandler()
237 ], BenchmarkReporter.prototype, "runEnd", null);
238 tslib_1.__decorate([
239 Reporter_1.eventHandler()
240 ], BenchmarkReporter.prototype, "suiteEnd", null);
241 tslib_1.__decorate([
242 Reporter_1.eventHandler()
243 ], BenchmarkReporter.prototype, "suiteStart", null);
244 tslib_1.__decorate([
245 Reporter_1.eventHandler()
246 ], BenchmarkReporter.prototype, "testEnd", null);
247 return BenchmarkReporter;
248 }(Reporter_1.default));
249 exports.default = BenchmarkReporter;
250 function formatSeconds(value) {
251 if (value == null) {
252 return null;
253 }
254 var units = 's';
255 if (value < 1) {
256 var places = Math.ceil(Math.log(value) / Math.log(10)) - 1;
257 if (places < -9) {
258 value *= Math.pow(10, 12);
259 units = 'ps';
260 }
261 else if (places < -6) {
262 value *= Math.pow(10, 9);
263 units = 'ns';
264 }
265 else if (places < -3) {
266 value *= Math.pow(10, 6);
267 units = 'µs';
268 }
269 else if (places < 0) {
270 value *= Math.pow(10, 3);
271 units = 'ms';
272 }
273 }
274 return value.toFixed(3) + units;
275 }
276});
277//# sourceMappingURL=Benchmark.js.map
\No newline at end of file