1 | import {print, isPresent, isBlank, NumberWrapper} from 'angular2/src/facade/lang';
|
2 | import {StringMapWrapper, ListWrapper} from 'angular2/src/facade/collection';
|
3 | import {PromiseWrapper} from 'angular2/src/facade/async';
|
4 | import {Math} from 'angular2/src/facade/math';
|
5 | import {bind, provide, Provider, OpaqueToken} from 'angular2/src/core/di';
|
6 |
|
7 | import {Statistic} from '../statistic';
|
8 | import {Reporter} from '../reporter';
|
9 | import {SampleDescription} from '../sample_description';
|
10 | import {MeasureValues} from '../measure_values';
|
11 |
|
12 |
|
13 |
|
14 |
|
15 | export class ConsoleReporter extends Reporter {
|
16 |
|
17 | static get PRINT(): OpaqueToken { return _PRINT; }
|
18 |
|
19 | static get COLUMN_WIDTH(): OpaqueToken { return _COLUMN_WIDTH; }
|
20 |
|
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 |
|
80 |
|
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 |
|
94 | var _PRINT = new OpaqueToken('ConsoleReporter.print');
|
95 | var _COLUMN_WIDTH = new OpaqueToken('ConsoleReporter.columnWidth');
|
96 | var _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 | ];
|