UNPKG

4.12 kBPlain TextView Raw
1import {print, isPresent, isBlank, NumberWrapper} from 'angular2/src/facade/lang';
2import {StringMapWrapper, ListWrapper} from 'angular2/src/facade/collection';
3import {PromiseWrapper} from 'angular2/src/facade/async';
4import {Math} from 'angular2/src/facade/math';
5import {bind, provide, Provider, OpaqueToken} from 'angular2/src/core/di';
6
7import {Statistic} from '../statistic';
8import {Reporter} from '../reporter';
9import {SampleDescription} from '../sample_description';
10import {MeasureValues} from '../measure_values';
11
12/**
13 * A reporter for the console
14 */
15export class ConsoleReporter extends Reporter {
16 // TODO(tbosch): use static values when our transpiler supports them
17 static get PRINT(): OpaqueToken { return _PRINT; }
18 // TODO(tbosch): use static values when our transpiler supports them
19 static get COLUMN_WIDTH(): OpaqueToken { return _COLUMN_WIDTH; }
20 // TODO(tbosch): use static values when our transpiler supports them
21 static get BINDINGS(): Provider[] { return _PROVIDERS; }
22
23
24 static _lpad(value, columnWidth, fill = ' ') {
25 var result = '';
26 for (var i = 0; i < columnWidth - value.length; i++) {
27 result += fill;
28 }
29 return result + value;
30 }
31
32 static _formatNum(n) { return NumberWrapper.toFixed(n, 2); }
33
34 static _sortedProps(obj) {
35 var props = [];
36 StringMapWrapper.forEach(obj, (value, prop) => props.push(prop));
37 props.sort();
38 return props;
39 }
40
41 private _metricNames: string[];
42
43 constructor(private _columnWidth: number, sampleDescription, private _print: Function) {
44 super();
45 this._metricNames = ConsoleReporter._sortedProps(sampleDescription.metrics);
46 this._printDescription(sampleDescription);
47 }
48
49 _printDescription(sampleDescription) {
50 this._print(`BENCHMARK ${sampleDescription.id}`);
51 this._print('Description:');
52 var props = ConsoleReporter._sortedProps(sampleDescription.description);
53 props.forEach((prop) => { this._print(`- ${prop}: ${sampleDescription.description[prop]}`); });
54 this._print('Metrics:');
55 this._metricNames.forEach((metricName) => {
56 this._print(`- ${metricName}: ${sampleDescription.metrics[metricName]}`);
57 });
58 this._print('');
59 this._printStringRow(this._metricNames);
60 this._printStringRow(this._metricNames.map((_) => ''), '-');
61 }
62
63 reportMeasureValues(measureValues: MeasureValues): Promise<any> {
64 var formattedValues = this._metricNames.map(metricName => {
65 var value = measureValues.values[metricName];
66 return ConsoleReporter._formatNum(value);
67 });
68 this._printStringRow(formattedValues);
69 return PromiseWrapper.resolve(null);
70 }
71
72 reportSample(completeSample: MeasureValues[], validSamples: MeasureValues[]): Promise<any> {
73 this._printStringRow(this._metricNames.map((_) => ''), '=');
74 this._printStringRow(this._metricNames.map(metricName => {
75 var samples = validSamples.map(measureValues => measureValues.values[metricName]);
76 var mean = Statistic.calculateMean(samples);
77 var cv = Statistic.calculateCoefficientOfVariation(samples, mean);
78 var formattedMean = ConsoleReporter._formatNum(mean)
79 // Note: Don't use the unicode character for +- as it might cause
80 // hickups for consoles...
81 return NumberWrapper.isNaN(cv) ?
82 formattedMean :
83 `${formattedMean}+-${Math.floor(cv)}%`;
84 }));
85 return PromiseWrapper.resolve(null);
86 }
87
88 _printStringRow(parts: any[], fill = ' ') {
89 this._print(
90 parts.map(part => ConsoleReporter._lpad(part, this._columnWidth, fill)).join(' | '));
91 }
92}
93
94var _PRINT = new OpaqueToken('ConsoleReporter.print');
95var _COLUMN_WIDTH = new OpaqueToken('ConsoleReporter.columnWidth');
96var _PROVIDERS = [
97 bind(ConsoleReporter)
98 .toFactory((columnWidth, sampleDescription, print) =>
99 new ConsoleReporter(columnWidth, sampleDescription, print),
100 [_COLUMN_WIDTH, SampleDescription, _PRINT]),
101 provide(_COLUMN_WIDTH, {useValue: 18}),
102 provide(_PRINT, {useValue: print})
103];