UNPKG

benchpress

Version:

Benchpress - a framework for e2e performance tests

88 lines 15 kB
import { print, NumberWrapper } from 'angular2/src/facade/lang'; import { StringMapWrapper } from 'angular2/src/facade/collection'; import { PromiseWrapper } from 'angular2/src/facade/async'; import { Math } from 'angular2/src/facade/math'; import { bind, provide, OpaqueToken } from 'angular2/src/core/di'; import { Statistic } from '../statistic'; import { Reporter } from '../reporter'; import { SampleDescription } from '../sample_description'; /** * A reporter for the console */ export class ConsoleReporter extends Reporter { constructor(_columnWidth, sampleDescription, _print) { super(); this._columnWidth = _columnWidth; this._print = _print; this._metricNames = ConsoleReporter._sortedProps(sampleDescription.metrics); this._printDescription(sampleDescription); } // TODO(tbosch): use static values when our transpiler supports them static get PRINT() { return _PRINT; } // TODO(tbosch): use static values when our transpiler supports them static get COLUMN_WIDTH() { return _COLUMN_WIDTH; } // TODO(tbosch): use static values when our transpiler supports them static get BINDINGS() { return _PROVIDERS; } static _lpad(value, columnWidth, fill = ' ') { var result = ''; for (var i = 0; i < columnWidth - value.length; i++) { result += fill; } return result + value; } static _formatNum(n) { return NumberWrapper.toFixed(n, 2); } static _sortedProps(obj) { var props = []; StringMapWrapper.forEach(obj, (value, prop) => props.push(prop)); props.sort(); return props; } _printDescription(sampleDescription) { this._print(`BENCHMARK ${sampleDescription.id}`); this._print('Description:'); var props = ConsoleReporter._sortedProps(sampleDescription.description); props.forEach((prop) => { this._print(`- ${prop}: ${sampleDescription.description[prop]}`); }); this._print('Metrics:'); this._metricNames.forEach((metricName) => { this._print(`- ${metricName}: ${sampleDescription.metrics[metricName]}`); }); this._print(''); this._printStringRow(this._metricNames); this._printStringRow(this._metricNames.map((_) => ''), '-'); } reportMeasureValues(measureValues) { var formattedValues = this._metricNames.map(metricName => { var value = measureValues.values[metricName]; return ConsoleReporter._formatNum(value); }); this._printStringRow(formattedValues); return PromiseWrapper.resolve(null); } reportSample(completeSample, validSamples) { this._printStringRow(this._metricNames.map((_) => ''), '='); this._printStringRow(this._metricNames.map(metricName => { var samples = validSamples.map(measureValues => measureValues.values[metricName]); var mean = Statistic.calculateMean(samples); var cv = Statistic.calculateCoefficientOfVariation(samples, mean); var formattedMean = ConsoleReporter._formatNum(mean); // Note: Don't use the unicode character for +- as it might cause // hickups for consoles... return NumberWrapper.isNaN(cv) ? formattedMean : `${formattedMean}+-${Math.floor(cv)}%`; })); return PromiseWrapper.resolve(null); } _printStringRow(parts, fill = ' ') { this._print(parts.map(part => ConsoleReporter._lpad(part, this._columnWidth, fill)).join(' | ')); } } var _PRINT = new OpaqueToken('ConsoleReporter.print'); var _COLUMN_WIDTH = new OpaqueToken('ConsoleReporter.columnWidth'); var _PROVIDERS = [ bind(ConsoleReporter) .toFactory((columnWidth, sampleDescription, print) => new ConsoleReporter(columnWidth, sampleDescription, print), [_COLUMN_WIDTH, SampleDescription, _PRINT]), provide(_COLUMN_WIDTH, { useValue: 18 }), provide(_PRINT, { useValue: print }) ]; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uc29sZV9yZXBvcnRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImRpZmZpbmdfcGx1Z2luX3dyYXBwZXItb3V0cHV0X3BhdGgteEJMSUJyVlIudG1wL2JlbmNocHJlc3Mvc3JjL3JlcG9ydGVyL2NvbnNvbGVfcmVwb3J0ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ik9BQU8sRUFBQyxLQUFLLEVBQXNCLGFBQWEsRUFBQyxNQUFNLDBCQUEwQjtPQUMxRSxFQUFDLGdCQUFnQixFQUFjLE1BQU0sZ0NBQWdDO09BQ3JFLEVBQUMsY0FBYyxFQUFDLE1BQU0sMkJBQTJCO09BQ2pELEVBQUMsSUFBSSxFQUFDLE1BQU0sMEJBQTBCO09BQ3RDLEVBQUMsSUFBSSxFQUFFLE9BQU8sRUFBWSxXQUFXLEVBQUMsTUFBTSxzQkFBc0I7T0FFbEUsRUFBQyxTQUFTLEVBQUMsTUFBTSxjQUFjO09BQy9CLEVBQUMsUUFBUSxFQUFDLE1BQU0sYUFBYTtPQUM3QixFQUFDLGlCQUFpQixFQUFDLE1BQU0sdUJBQXVCO0FBR3ZEOztHQUVHO0FBQ0gscUNBQXFDLFFBQVE7SUE0QjNDLFlBQW9CLFlBQW9CLEVBQUUsaUJBQWlCLEVBQVUsTUFBZ0I7UUFDbkYsT0FBTyxDQUFDO1FBRFUsaUJBQVksR0FBWixZQUFZLENBQVE7UUFBNkIsV0FBTSxHQUFOLE1BQU0sQ0FBVTtRQUVuRixJQUFJLENBQUMsWUFBWSxHQUFHLGVBQWUsQ0FBQyxZQUFZLENBQUMsaUJBQWlCLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDNUUsSUFBSSxDQUFDLGlCQUFpQixDQUFDLGlCQUFpQixDQUFDLENBQUM7SUFDNUMsQ0FBQztJQS9CRCxvRUFBb0U7SUFDcEUsV0FBVyxLQUFLLEtBQWtCLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO0lBQ2xELG9FQUFvRTtJQUNwRSxXQUFXLFlBQVksS0FBa0IsTUFBTSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUM7SUFDaEUsb0VBQW9FO0lBQ3BFLFdB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LENBQUM7QUFDbkUsSUFBSSxVQUFVLEdBQUc7SUFDZixJQUFJLENBQUMsZUFBZSxDQUFDO1NBQ2hCLFNBQVMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxpQkFBaUIsRUFBRSxLQUFLLEtBQ2xDLElBQUksZUFBZSxDQUFDLFdBQVcsRUFBRSxpQkFBaUIsRUFBRSxLQUFLLENBQUMsRUFDOUQsQ0FBQyxhQUFhLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDMUQsT0FBTyxDQUFDLGFBQWEsRUFBRSxFQUFDLFFBQVEsRUFBRSxFQUFFLEVBQUMsQ0FBQztJQUN0QyxPQUFPLENBQUMsTUFBTSxFQUFFLEVBQUMsUUFBUSxFQUFFLEtBQUssRUFBQyxDQUFDO0NBQ25DLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge3ByaW50LCBpc1ByZXNlbnQsIGlzQmxhbmssIE51bWJlcldyYXBwZXJ9IGZyb20gJ2FuZ3VsYXIyL3NyYy9mYWNhZGUvbGFuZyc7XG5pbXBvcnQge1N0cmluZ01hcFdyYXBwZXIsIExpc3RXcmFwcGVyfSBmcm9tICdhbmd1bGFyMi9zcmMvZmFjYWRlL2NvbGxlY3Rpb24nO1xuaW1wb3J0IHtQcm9taXNlV3JhcHBlcn0gZnJvbSAnYW5ndWxhcjIvc3JjL2ZhY2FkZS9hc3luYyc7XG5pbXBvcnQge01hdGh9IGZyb20gJ2FuZ3VsYXIyL3NyYy9mYWNhZGUvbWF0aCc7XG5pbXBvcnQge2JpbmQsIHByb3ZpZGUsIFByb3ZpZGVyLCBPcGFxdWVUb2tlbn0gZnJvbSAnYW5ndWxhcjIvc3JjL2NvcmUvZGknO1xuXG5pbXBvcnQge1N0YXRpc3RpY30gZnJvbSAnLi4vc3RhdGlzdGljJztcbmltcG9ydCB7UmVwb3J0ZXJ9IGZyb20gJy4uL3JlcG9ydGVyJztcbmltcG9ydCB7U2FtcGxlRGVzY3JpcHRpb259IGZyb20gJy4uL3NhbXBsZV9kZXNjcmlwdGlvbic7XG5pbXBvcnQge01lYXN1cmVWYWx1ZXN9IGZyb20gJy4uL21lYXN1cmVfdmFsdWVzJztcblxuLyoqXG4gKiBBIHJlcG9ydGVyIGZvciB0aGUgY29uc29sZVxuICovXG5leHBvcnQgY2xhc3MgQ29uc29sZVJlcG9ydGVyIGV4dGVuZHMgUmVwb3J0ZXIge1xuICAvLyBUT0RPKHRib3NjaCk6IHVzZSBzdGF0aWMgdmFsdWVzIHdoZW4gb3VyIHRyYW5zcGlsZXIgc3VwcG9ydHMgdGhlbVxuICBzdGF0aWMgZ2V0IFBSSU5UKCk6IE9wYXF1ZVRva2VuIHsgcmV0dXJuIF9QUklOVDsgfVxuICAvLyBUT0RPKHRib3NjaCk6IHVzZSBzdGF0aWMgdmFsdWVzIHdoZW4gb3VyIHRyYW5zcGlsZXIgc3VwcG9ydHMgdGhlbVxuICBzdGF0aWMgZ2V0IENPTFVNTl9XSURUSCgpOiBPcGFxdWVUb2tlbiB7IHJldHVybiBfQ09MVU1OX1dJRFRIOyB9XG4gIC8vIFRPRE8odGJvc2NoKTogdXNlIHN0YXRpYyB2YWx1ZXMgd2hlbiBvdXIgdHJhbnNwaWxlciBzdXBwb3J0cyB0aGVtXG4gIHN0YXRpYyBnZXQgQklORElOR1MoKTogUHJvdmlkZXJbXSB7IHJldHVybiBfUFJPVklERVJTOyB9XG5cblxuICBzdGF0aWMgX2xwYWQodmFsdWUsIGNvbHVtbldpZHRoLCBmaWxsID0gJyAnKSB7XG4gICAgdmFyIHJlc3VsdCA9ICcnO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY29sdW1uV2lkdGggLSB2YWx1ZS5sZW5ndGg7IGkrKykge1xuICAgICAgcmVzdWx0ICs9IGZpbGw7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQgKyB2YWx1ZTtcbiAgfVxuXG4gIHN0YXRpYyBfZm9ybWF0TnVtKG4pIHsgcmV0dXJuIE51bWJlcldyYXBwZXIudG9GaXhlZChuLCAyKTsgfVxuXG4gIHN0YXRpYyBfc29ydGVkUHJvcHMob2JqKSB7XG4gICAgdmFyIHByb3BzID0gW107XG4gICAgU3RyaW5nTWFwV3JhcHBlci5mb3JFYWNoKG9iaiwgKHZhbHVlLCBwcm9wKSA9PiBwcm9wcy5wdXNoKHByb3ApKTtcbiAgICBwcm9wcy5zb3J0KCk7XG4gICAgcmV0dXJuIHByb3BzO1xuICB9XG5cbiAgcHJpdmF0ZSBfbWV0cmljTmFtZXM6IHN0cmluZ1tdO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgX2NvbHVtbldpZHRoOiBudW1iZXIsIHNhbXBsZURlc2NyaXB0aW9uLCBwcml2YXRlIF9wcmludDogRnVuY3Rpb24pIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMuX21ldHJpY05hbWVzID0gQ29uc29sZVJlcG9ydGVyLl9zb3J0ZWRQcm9wcyhzYW1wbGVEZXNjcmlwdGlvbi5tZXRyaWNzKTtcbiAgICB0aGlzLl9wcmludERlc2NyaXB0aW9uKHNhbXBsZURlc2NyaXB0aW9uKTtcbiAgfVxuXG4gIF9wcmludERlc2NyaXB0aW9uKHNhbXBsZURlc2NyaXB0aW9uKSB7XG4gICAgdGhpcy5fcHJpbnQoYEJFTkNITUFSSyAke3NhbXBsZURlc2NyaXB0aW9uLmlkfWApO1xuICAgIHRoaXMuX3ByaW50KCdEZXNjcmlwdGlvbjonKTtcbiAgICB2YXIgcHJvcHMgPSBDb25zb2xlUmVwb3J0ZXIuX3NvcnRlZFByb3BzKHNhbXBsZURlc2NyaXB0aW9uLmRlc2NyaXB0aW9uKTtcbiAgICBwcm9wcy5mb3JFYWNoKChwcm9wKSA9PiB7IHRoaXMuX3ByaW50KGAtICR7cHJvcH06ICR7c2FtcGxlRGVzY3JpcHRpb24uZGVzY3JpcHRpb25bcHJvcF19YCk7IH0pO1xuICAgIHRoaXMuX3ByaW50KCdNZXRyaWNzOicpO1xuICAgIHRoaXMuX21ldHJpY05hbWVzLmZvckVhY2goKG1ldHJpY05hbWUpID0+IHtcbiAgICAgIHRoaXMuX3ByaW50KGAtICR7bWV0cmljTmFtZX06ICR7c2FtcGxlRGVzY3JpcHRpb24ubWV0cmljc1ttZXRyaWNOYW1lXX1gKTtcbiAgICB9KTtcbiAgICB0aGlzLl9wcmludCgnJyk7XG4gICAgdGhpcy5fcHJpbnRTdHJpbmdSb3codGhpcy5fbWV0cmljTmFtZXMpO1xuICAgIHRoaXMuX3ByaW50U3RyaW5nUm93KHRoaXMuX21ldHJpY05hbWVzLm1hcCgoXykgPT4gJycpLCAnLScpO1xuICB9XG5cbiAgcmVwb3J0TWVhc3VyZVZhbHVlcyhtZWFzdXJlVmFsdWVzOiBNZWFzdXJlVmFsdWVzKTogUHJvbWlzZTxhbnk+IHtcbiAgICB2YXIgZm9ybWF0dGVkVmFsdWVzID0gdGhpcy5fbWV0cmljTmFtZXMubWFwKG1ldHJpY05hbWUgPT4ge1xuICAgICAgdmFyIHZhbHVlID0gbWVhc3VyZVZhbHVlcy52YWx1ZXNbbWV0cmljTmFtZV07XG4gICAgICByZXR1cm4gQ29uc29sZVJlcG9ydGVyLl9mb3JtYXROdW0odmFsdWUpO1xuICAgIH0pO1xuICAgIHRoaXMuX3ByaW50U3RyaW5nUm93KGZvcm1hdHRlZFZhbHVlcyk7XG4gICAgcmV0dXJuIFByb21pc2VXcmFwcGVyLnJlc29sdmUobnVsbCk7XG4gIH1cblxuICByZXBvcnRTYW1wbGUoY29tcGxldGVTYW1wbGU6IE1lYXN1cmVWYWx1ZXNbXSwgdmFsaWRTYW1wbGVzOiBNZWFzdXJlVmFsdWVzW10pOiBQcm9taXNlPGFueT4ge1xuICAgIHRoaXMuX3ByaW50U3RyaW5nUm93KHRoaXMuX21ldHJpY05hbWVzLm1hcCgoXykgPT4gJycpLCAnPScpO1xuICAgIHRoaXMuX3ByaW50U3RyaW5nUm93KHRoaXMuX21ldHJpY05hbWVzLm1hcChtZXRyaWNOYW1lID0+IHtcbiAgICAgIHZhciBzYW1wbGVzID0gdmFsaWRTYW1wbGVzLm1hcChtZWFzdXJlVmFsdWVzID0+IG1lYXN1cmVWYWx1ZXMudmFsdWVzW21ldHJpY05hbWVdKTtcbiAgICAgIHZhciBtZWFuID0gU3RhdGlzdGljLmNhbGN1bGF0ZU1lYW4oc2FtcGxlcyk7XG4gICAgICB2YXIgY3YgPSBTdGF0aXN0aWMuY2FsY3VsYXRlQ29lZmZpY2llbnRPZlZhcmlhdGlvbihzYW1wbGVzLCBtZWFuKTtcbiAgICAgIHZhciBmb3JtYXR0ZWRNZWFuID0gQ29uc29sZVJlcG9ydGVyLl9mb3JtYXROdW0obWVhbilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5vdGU6IERvbid0IHVzZSB0aGUgdW5pY29kZSBjaGFyYWN0ZXIgZm9yICstIGFzIGl0IG1pZ2h0IGNhdXNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBoaWNrdXBzIGZvciBjb25zb2xlcy4uLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE51bWJlcldyYXBwZXIuaXNOYU4oY3YpID9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1hdHRlZE1lYW4gOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYCR7Zm9ybWF0dGVkTWVhbn0rLSR7TWF0aC5mbG9vcihjdil9JWA7XG4gICAgfSkpO1xuICAgIHJldHVybiBQcm9taXNlV3JhcHBlci5yZXNvbHZlKG51bGwpO1xuICB9XG5cbiAgX3ByaW50U3RyaW5nUm93KHBhcnRzOiBhbnlbXSwgZmlsbCA9ICcgJykge1xuICAgIHRoaXMuX3ByaW50KFxuICAgICAgICBwYXJ0cy5tYXAocGFydCA9PiBDb25zb2xlUmVwb3J0ZXIuX2xwYWQocGFydCwgdGhpcy5fY29sdW1uV2lkdGgsIGZpbGwpKS5qb2luKCcgfCAnKSk7XG4gIH1cbn1cblxudmFyIF9QUklOVCA9IG5ldyBPcGFxdWVUb2tlbignQ29uc29sZVJlcG9ydGVyLnByaW50Jyk7XG52YXIgX0NPTFVNTl9XSURUSCA9IG5ldyBPcGFxdWVUb2tlbignQ29uc29sZVJlcG9ydGVyLmNvbHVtbldpZHRoJyk7XG52YXIgX1BST1ZJREVSUyA9IFtcbiAgYmluZChDb25zb2xlUmVwb3J0ZXIpXG4gICAgICAudG9GYWN0b3J5KChjb2x1bW5XaWR0aCwgc2FtcGxlRGVzY3JpcHRpb24sIHByaW50KSA9PlxuICAgICAgICAgICAgICAgICAgICAgbmV3IENvbnNvbGVSZXBvcnRlcihjb2x1bW5XaWR0aCwgc2FtcGxlRGVzY3JpcHRpb24sIHByaW50KSxcbiAgICAgICAgICAgICAgICAgW19DT0xVTU5fV0lEVEgsIFNhbXBsZURlc2NyaXB0aW9uLCBfUFJJTlRdKSxcbiAgcHJvdmlkZShfQ09MVU1OX1dJRFRILCB7dXNlVmFsdWU6IDE4fSksXG4gIHByb3ZpZGUoX1BSSU5ULCB7dXNlVmFsdWU6IHByaW50fSlcbl07XG4iXX0=