performance-report.js revision ae090ac5cdb5a6367975f3eae3acdc77433f08dc
// -- Shorthand and Private Variables ------------------------------------------
Obj = Y.Object,
BOUNDING_BOX = 'boundingBox',
CONTENT_BOX = 'contentBox',
PERFORMANCE = 'performance';
function Report() {
}
// -- Public Constants -----------------------------------------------------
// Selectors (relative to contentBox)
SELECTOR_BODY : 'tbody',
SELECTOR_FOOTER: 'tfoot',
SELECTOR_HEADER: 'thead',
SELECTOR_RESULT: 'tbody>tr.result',
// Templates
BODY_TEMPLATE : '<tbody></tbody>',
CONTENT_TEMPLATE: '<table></table>',
FOOTER_TEMPLATE : '<tfoot><tr><td colspan="10"></td></tr></tfoot>',
'<thead>' +
'<tr>' +
'<th class="group">Group</th>' +
'<th class="test">Test</th>' +
'<th class="calls">Calls</th>' +
'<th class="failures">Failures</th>' +
'<th class="mean">Mean</th>' +
'<th class="median">Median</th>' +
'<th class="mediandev"><abbr title="Median Absolute Deviation">Med. Dev.</abbr></th>' +
'<th class="stdev"><abbr title="Sample Standard Deviation">Std. Dev.</abbr></th>' +
'<th class="max">Max</th>' +
'<th class="min">Min</th>' +
'</tr>' +
'</thead>',
'<tr class="{classNames result}">' +
'<td class="group">{groupName}</td>' +
'<td class="test"><div class="bd">{name} <img src="{chartUrl}" style="height:20px;width:100px" alt="Sparkline"></div></td>' +
'<td class="calls">{calls}</td>' +
'<td class="failures">{failures}</td>' +
'<td class="mean">{mean}</td>' +
'<td class="median">{median}</td>' +
'<td class="mediandev">{mediandev}</td>' +
'<td class="stdev">{stdev}</td>' +
'<td class="max">{max}</td>' +
'<td class="min">{min}</td>' +
'</tr>' +
'<tr class="code hidden">' +
'<td colspan="10">' +
'<pre><code>{code}</code></pre>' +
'</td>' +
'</tr>',
// -- Public Methods -------------------------------------------------------
initializer: function () {
if (!this.get(PERFORMANCE)) {
Y.error('No performance instance specified.');
}
},
destructor: function () {
if (this._events) {
var e;
e.detach();
}
}
},
bindUI: function () {
]);
},
renderUI: function () {
this._renderResults();
}
},
// -- Protected Methods ----------------------------------------------------
_clearResults: function () {
});
},
// -- Protected Static Methods ---------------------------------------------
/**
* params.
*
* @method _createQueryString
* @return {String}
* @protected
*/
_createQueryString: function (params) {
var _params = [],
}
});
},
/**
* Replaces special HTML characters in the specified string with their
* entity equivalents.
*
* @method _htmlEntities
* @param {String} string
* @return {String}
* @protected
*/
_htmlEntities: function (string) {
replace(/</g, '<').
replace(/>/g, '>').
replace(/"/g, '"');
},
_renderBody: function (contentBox, suite) {
// Do nothing if BODY_TEMPLATE is empty.
if (!this.BODY_TEMPLATE) {
return;
}
var body = contentBox.one(this.SELECTOR_BODY);
// Remove the body if it already exists.
if (body) {
body.destroy(true);
}
// Render a new body.
contentBox.append(this.BODY_TEMPLATE);
},
_renderFooter: function (contentBox, suite) {
// Do nothing if FOOTER_TEMPLATE is empty.
if (!this.FOOTER_TEMPLATE) {
return;
}
var foot = contentBox.one(this.SELECTOR_FOOTER);
// Remove the footer if it already exists.
if (foot) {
foot.destroy(true);
}
// Render a new footer.
contentBox.append(this.FOOTER_TEMPLATE);
},
_renderHeader: function (contentBox, suite) {
// Do nothing if HEADER_TEMPLATE is empty.
if (!this.HEADER_TEMPLATE) {
return;
}
var head = contentBox.one(this.SELECTOR_HEADER);
// Remove the header if it already exists.
if (head) {
head.destroy(true);
}
// Render a new header.
contentBox.append(this.HEADER_TEMPLATE);
},
_renderResult: function (resultData, test, group) {
var chartParams = {
cht: 'ls',
chd: 't:' + resultData.points.join(','),
chf: 'bg,s,00000000', // transparent background
chs: '100x20'
};
this.get(CONTENT_BOX).one(this.SELECTOR_BODY).append(Y.substitute(
this.RESULT_TEMPLATE,
Y.merge(resultData, {
chartUrl : this.CHART_URL + this._createQueryString(chartParams),
code : this._htmlEntities(test.test.toString()),
groupName: this._htmlEntities(group.name || 'Default'),
mediandev: resultData.mediandev !== '' ? '±' + resultData.mediandev : '',
name : this._htmlEntities(resultData.name),
stdev : resultData.stdev !== '' ? '±' + resultData.stdev : ''
}),
function (key, value, meta) {
if (key === 'classNames') {
return meta + (resultData.failures ? ' fail' : '');
}
return value;
}
));
},
_renderResults: function () {
var perf = this.get(PERFORMANCE),
results = perf.get('results'),
suite = perf.get('activeSuite');
this._clearResults();
if (!results || !suite) {
return;
}
Obj.each(results, function (groupResult, groupName) {
var group = suite.groups[groupName];
Obj.each(groupResult, function (testResult, testName) {
this._renderResult(testResult, group.tests[testName], group);
}, this);
}, this);
},
// -- Protected Event Handlers ---------------------------------------------
_afterClear: function () {
this._clearResults();
},
_afterEnd: function () {
this.get(BOUNDING_BOX).removeClass('running');
},
_afterResultAdd: function (e) {
this._renderResult(e.result, e.test, e.group);
},
_afterStart: function () {
this.get(BOUNDING_BOX).addClass('running');
},
_onResultClick: function (e) {
e.currentTarget.next('tr.code').toggleClass('hidden');
}
}, {
// -- Public Static Constants ----------------------------------------------
NAME: 'performanceReport',
ATTRS: {
performance: {
validator: function (value) {
return value instanceof Y.Performance;
},
writeOnce: 'initOnly'
}
}
});
Y.PerformanceReport = Report;
}, '@VERSION@', {
requires: ['performance', 'substitute', 'widget']
});