Skip to content

Instantly share code, notes, and snippets.

@CaptainJiNX
Created March 5, 2014 13:44
Show Gist options
  • Save CaptainJiNX/9367400 to your computer and use it in GitHub Desktop.
Save CaptainJiNX/9367400 to your computer and use it in GitHub Desktop.
Simple reporter to generate JUnit XML from jasmine 2.0
function getJasmineRequireObj() {
if (typeof module !== "undefined" && module.exports) {
return exports;
} else {
window.jasmineRequire = window.jasmineRequire || {};
return window.jasmineRequire;
}
}
getJasmineRequireObj().junit = function(jRequire, j$) {
j$.JUnitReporter = jRequire.JUnitReporter();
}
getJasmineRequireObj().JUnitReporter = function() {
function JUnitReporter(options) {
var print = options.print,
name = options.name || 'Unnamed',
totalSpecs,
suites = [],
suiteIds = [],
currentSuiteId,
currentClassName,
startTime,
endTime;
var elapsed = function(startTime, endTime) {
return (endTime - startTime) / 1000;
};
var xmlDate = function(d) {
var pad = function(n) {
return n < 10 ? '0' + n : n;
};
return d.getFullYear() + '-' +
pad(d.getMonth() + 1) + '-' +
pad(d.getDate()) + 'T' +
pad(d.getHours()) + ':' +
pad(d.getMinutes()) + ':' +
pad(d.getSeconds());
};
var xmlEscape = function(str) {
return str.replace(/</g, "&lt;")
.replace(/\>/g, "&gt;")
.replace(/\"/g, "&quot;")
.replace(/\'/g, "&apos;")
.replace(/\&/g, "&amp;");
};
var getTestCases = function(suite) {
return suite.testCases;
};
var hasFailures = function(testCase) {
return testCase.failures.length > 0;
};
var isSkipped = function(testCase) {
return testCase.skipped === true;
};
var getTestResultFailureCount = function(testResult) {
return where(selectMany(testResult.suites, getTestCases), hasFailures).length;
};
var getTestSuiteFailureCount = function(suite) {
return where(suite.testCases, hasFailures).length;
};
var getTestSuiteSkippedCount = function(suite) {
return where(suite.testCases, isSkipped).length;
};
var printTestResult = function(testResult) {
print('<?xml version="1.0" encoding="UTF-8"?>');
print('<testsuites errors="0"' +
' failures="' + getTestResultFailureCount(testResult) + '"' +
' name="' + xmlEscape(name) + '"' +
' tests="' + totalSpecs + '"' +
' time="' + elapsed(testResult.startTime, testResult.endTime) + '">');
for (var i = 0; i < testResult.suites.length; i++) {
printTestSuite(testResult.suites[i]);
}
print('</testsuites>');
};
var printTestSuite = function(suite) {
var shouldPrint = function() {
return (suite.testCases.length > 0);
};
if (!shouldPrint()) {
return;
}
print('<testsuite errors="0" failures="' + getTestSuiteFailureCount(suite) + '"' +
' id="' + xmlEscape(suite.id) + '"' +
' name="' + xmlEscape(suite.name) + '"' +
' skipped="' + getTestSuiteSkippedCount(suite) + '"' +
' tests="' + suite.testCases.length + '"' +
' time="' + elapsed(suite.startTime, suite.endTime) + '"' +
' timestamp="' + xmlDate(suite.startTime) + '"' +
'>');
for (var i = 0; i < suite.testCases.length; i++) {
printTestCase(suite.testCases[i]);
}
print('</testsuite>');
};
var printTestCase = function(testCase) {
print('<testcase classname="' + xmlEscape(testCase.className) + '"' +
' name="' + xmlEscape(testCase.name) + '"' +
' time="' + elapsed(testCase.startTime, testCase.endTime) + '"' +
'>');
if (isSkipped(testCase)) {
print('<skipped />');
}
for (var i = 0; i < testCase.failures.length; i++) {
printFailure(testCase.failures[i]);
}
print('</testcase>');
};
var printFailure = function(failure) {
print('<failure message="' + xmlEscape(failure) + '" type="expect"/>');
};
var where = function(arr, predicate) {
var result = [];
for (var i = 0; i < arr.length; i++) {
if (!predicate || predicate(arr[i])) {
result.push(arr[i]);
}
}
return result;
};
var selectMany = function(arr, selector) {
var result = [];
for (var i = 0; i < arr.length; i++) {
result = result.concat(selector(arr[i]))
}
return result;
};
var first = function(arr, predicate) {
for (var i = 0; i < arr.length; i++) {
if (!predicate || predicate(arr[i])) {
return arr[i];
}
}
return null;
};
var findSuite = function(suiteId) {
return first(suites, function(suite) {
return suite.id === suiteId;
});
};
var findTestCase = function(suite, testCaseId) {
return first(suite.testCases, function(testCase) {
return testCase.id === testCaseId;
});
};
var jasmineStarted = function(result) {
startTime = new Date();
totalSpecs = result.totalSpecsDefined;
};
var jasmineDone = function(result) {
endTime = new Date();
var testResult = {
totalSpecs: totalSpecs,
startTime: startTime,
endTime: endTime,
suites: suites
};
printTestResult(testResult);
};
var suiteStarted = function(result) {
if (!currentClassName || result.fullName.indexOf(currentClassName) !== 0) {
currentClassName = result.fullName;
}
suites.push({
id: result.id,
name: result.fullName,
className: currentClassName,
startTime: new Date(),
testCases: []
});
suiteIds.push(result.id);
currentSuiteId = result.id;
};
var getLastSuiteId = function() {
return suiteIds[suiteIds.length - 1];
}
var suiteDone = function(result) {
if (result.id === getLastSuiteId()) {
findSuite(result.id).endTime = new Date();
suiteIds.pop();
currentSuiteId = getLastSuiteId();
}
};
var specStarted = function(result) {
var suite = findSuite(currentSuiteId);
suite.testCases.push({
id: result.id,
name: result.fullName.replace(suite.className, ''),
className: suite.className,
failures: [],
startTime: new Date()
});
};
var specDone = function(result) {
var suite = findSuite(currentSuiteId);
var testCase = findTestCase(suite, result.id);
testCase.endTime = new Date();
if (result.status === "failed") {
for (var i = 0; i < result.failedExpectations.length; i++) {
testCase.failures.push(result.failedExpectations[i].message);
}
}
if (result.status === "pending") {
testCase.skipped = true;
}
};
return {
jasmineStarted: jasmineStarted,
jasmineDone: jasmineDone,
suiteStarted: suiteStarted,
suiteDone: suiteDone,
specStarted: specStarted,
specDone: specDone,
};
}
return JUnitReporter;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment