Merge branch 'issue/11' of https://github.com/vitch/grunt-contrib-jasmine
This commit is contained in:
commit
81d45689d0
@ -62,6 +62,14 @@ Default: `{}`
|
||||
|
||||
These options will be passed to your template as an 'options' hash so that you can provide settings to your template.
|
||||
|
||||
## options.junit
|
||||
Type: `Object`
|
||||
Default: `{}`
|
||||
|
||||
Set `options.junit.path` to generate JUnit compatible XML from the task (for use in a CI system such as Jenkins).
|
||||
|
||||
Set `options.junit.consolidate` to consolidate the generated XML files so that there is one file per top level suite.
|
||||
|
||||
# Flags
|
||||
|
||||
Name: `build`
|
||||
|
@ -32,7 +32,8 @@ module.exports = function(grunt) {
|
||||
|
||||
var runners = {
|
||||
default : __dirname + '/jasmine/templates/DefaultRunner.tmpl',
|
||||
requirejs : __dirname + '/jasmine/templates/RequireJSRunner.tmpl'
|
||||
requirejs : __dirname + '/jasmine/templates/RequireJSRunner.tmpl',
|
||||
junit : __dirname + '/jasmine/templates/JUnit.tmpl'
|
||||
};
|
||||
|
||||
var runnerOptions = {
|
||||
@ -53,7 +54,8 @@ module.exports = function(grunt) {
|
||||
host : '',
|
||||
template: 'default',
|
||||
templateOptions : {},
|
||||
phantomjs : {}
|
||||
phantomjs : {},
|
||||
junit: {}
|
||||
});
|
||||
|
||||
grunt.util._.defaults(options.templateOptions, runnerOptions[options.template] || {});
|
||||
@ -143,13 +145,14 @@ module.exports = function(grunt) {
|
||||
grunt.event.emit.apply(grunt.event, args);
|
||||
});
|
||||
|
||||
phantomjs.on('jasmine.writeFile',function(type,filename, xml){
|
||||
var dir = options[type] && options[type].output;
|
||||
if (dir) {
|
||||
grunt.file.mkdir(dir);
|
||||
grunt.file.write(path.join(dir, filename), xml);
|
||||
}
|
||||
});
|
||||
// Not used?
|
||||
// phantomjs.on('jasmine.writeFile',function(type,filename, xml){
|
||||
// var dir = options[type] && options[type].output;
|
||||
// if (dir) {
|
||||
// grunt.file.mkdir(dir);
|
||||
// grunt.file.write(path.join(dir, filename), xml);
|
||||
// }
|
||||
// });
|
||||
|
||||
|
||||
phantomjs.on('jasmine.reportRunnerStarting',function(suites) {
|
||||
@ -203,6 +206,46 @@ module.exports = function(grunt) {
|
||||
status.skipped += skippedAssertions;
|
||||
});
|
||||
|
||||
phantomjs.on('jasmine.reportJUnitResults',function(junitData){
|
||||
if (options.junit && options.junit.path) {
|
||||
|
||||
if (options.junit.consolidate) {
|
||||
|
||||
grunt.util._(junitData.consolidatedSuites).each(
|
||||
function(suites)
|
||||
{
|
||||
grunt.file.copy(runners.junit, path.join(options.junit.path, 'TEST-' + suites[0].name.replace(/[^\w]/g, '') + '.xml'), {
|
||||
process: function(src) {
|
||||
return grunt.util._.template(
|
||||
src,
|
||||
{
|
||||
testsuites: suites
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
} else {
|
||||
junitData.suites.forEach(
|
||||
function(suiteData)
|
||||
{
|
||||
grunt.file.copy(runners.junit, path.join(options.junit.path, 'TEST-' + suiteData.name.replace(/[^\w]/g, '') + '.xml'), {
|
||||
process: function(src) {
|
||||
return grunt.util._.template(
|
||||
src,
|
||||
{
|
||||
testsuites: [suiteData]
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
phantomjs.on('jasmine.done',function(elapsed){
|
||||
phantomjs.halt();
|
||||
status.duration = elapsed;
|
||||
@ -218,7 +261,4 @@ module.exports = function(grunt) {
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
};
|
94
tasks/jasmine/reporters/JUnitDataReporter.js
Normal file
94
tasks/jasmine/reporters/JUnitDataReporter.js
Normal file
@ -0,0 +1,94 @@
|
||||
/*global jasmine */
|
||||
(function()
|
||||
{
|
||||
'use strict';
|
||||
|
||||
function getNestedSuiteName(suite)
|
||||
{
|
||||
var names = [];
|
||||
while (suite) {
|
||||
names.unshift(suite.description);
|
||||
suite = suite.parentSuite;
|
||||
}
|
||||
return names.join(' ');
|
||||
}
|
||||
|
||||
function getTopLevelSuiteId(suite)
|
||||
{
|
||||
var id;
|
||||
while (suite) {
|
||||
id = suite.id;
|
||||
suite = suite.parentSuite;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
jasmine.JUnitDataReporter = function()
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
jasmine.JUnitDataReporter.prototype = {
|
||||
reportRunnerStarting: function(runner) {
|
||||
},
|
||||
reportRunnerResults: function(runner) {
|
||||
var suitesById = {},
|
||||
suites = runner.suites().map(
|
||||
function(suite)
|
||||
{
|
||||
var failures = 0,
|
||||
data = {
|
||||
topLevelSuiteId: getTopLevelSuiteId(suite),
|
||||
name: getNestedSuiteName(suite),
|
||||
time: suite.duration / 1000,
|
||||
timestamp: suite.timestamp,
|
||||
tests: suite.specs().length,
|
||||
errors: 0, // TODO: These exist in the JUnit XML but not sure how they map to jasmine things
|
||||
testcases: suite.specs().map(
|
||||
function(spec)
|
||||
{
|
||||
var failureMessages = [];
|
||||
if (spec.results().failedCount) {
|
||||
failures ++;
|
||||
spec.results().items_.forEach(
|
||||
function(expectation)
|
||||
{
|
||||
if (!expectation.passed()) {
|
||||
failureMessages.push(expectation.message);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
return {
|
||||
assertions: spec.results().items_.length,
|
||||
className: getNestedSuiteName(spec.suite),
|
||||
name: spec.description,
|
||||
time: spec.duration / 1000,
|
||||
failureMessages: failureMessages
|
||||
};
|
||||
}
|
||||
)
|
||||
};
|
||||
data.failures = failures;
|
||||
suitesById[suite.id] = data;
|
||||
return data;
|
||||
}
|
||||
);
|
||||
console.log('Suites:', suites);
|
||||
},
|
||||
reportSuiteResults: function(suite) {
|
||||
suite.timestamp = new Date();
|
||||
suite.duration = suite.timestamp.getTime() - suite.specs()[0].startTime;
|
||||
},
|
||||
reportSpecStarting: function(spec) {
|
||||
spec.startTime = (new Date()).getTime();
|
||||
},
|
||||
reportSpecResults: function(spec) {
|
||||
spec.duration = (new Date()).getTime() - spec.startTime;
|
||||
},
|
||||
log: function(str) {
|
||||
console.log(str);
|
||||
}
|
||||
};
|
||||
|
||||
}());
|
@ -40,6 +40,7 @@
|
||||
};
|
||||
|
||||
PhantomReporter.prototype.reportSpecStarting = function(spec) {
|
||||
spec.startTime = (new Date()).getTime();
|
||||
var message = {
|
||||
suite : {
|
||||
description : spec.suite.description
|
||||
@ -84,14 +85,19 @@
|
||||
var specIds = runner.specs().map(function(a){return a.id;});
|
||||
var summary = this.resultsForSpecs(specIds);
|
||||
phantom.sendMessage('jasmine.reportRunnerResults',summary);
|
||||
phantom.sendMessage('jasmine.reportJUnitResults', this.generateJUnitSummary_(runner));
|
||||
phantom.sendMessage('jasmine.done.PhantomReporter');
|
||||
};
|
||||
|
||||
PhantomReporter.prototype.reportSuiteResults = function(suite) {
|
||||
phantom.sendMessage('jasmine.reportSuiteResults',{
|
||||
description : suite.description,
|
||||
results : suite.results()
|
||||
});
|
||||
if (suite.specs().length) {
|
||||
suite.timestamp = new Date();
|
||||
suite.duration = suite.timestamp.getTime() - suite.specs()[0].startTime;
|
||||
phantom.sendMessage('jasmine.reportSuiteResults',{
|
||||
description : suite.description,
|
||||
results : suite.results()
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function stringify(obj) {
|
||||
@ -130,6 +136,7 @@
|
||||
}
|
||||
|
||||
PhantomReporter.prototype.reportSpecResults = function(spec) {
|
||||
spec.duration = (new Date()).getTime() - spec.startTime;
|
||||
var _results = spec.results();
|
||||
var results = {
|
||||
description : _results.description,
|
||||
@ -189,5 +196,78 @@
|
||||
};
|
||||
};
|
||||
|
||||
function getNestedSuiteName(suite)
|
||||
{
|
||||
var names = [];
|
||||
while (suite) {
|
||||
names.unshift(suite.description);
|
||||
suite = suite.parentSuite;
|
||||
}
|
||||
return names.join(' ');
|
||||
}
|
||||
|
||||
function getTopLevelSuiteId(suite)
|
||||
{
|
||||
var id;
|
||||
while (suite) {
|
||||
id = suite.id;
|
||||
suite = suite.parentSuite;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
PhantomReporter.prototype.generateJUnitSummary_ = function(runner) {
|
||||
var consolidatedSuites = {},
|
||||
suites = runner.suites().map(
|
||||
function(suite)
|
||||
{
|
||||
var failures = 0,
|
||||
data = {
|
||||
name: getNestedSuiteName(suite),
|
||||
time: suite.duration / 1000,
|
||||
timestamp: suite.timestamp,
|
||||
tests: suite.specs().length,
|
||||
errors: 0, // TODO: These exist in the JUnit XML but not sure how they map to jasmine things
|
||||
testcases: suite.specs().map(
|
||||
function(spec)
|
||||
{
|
||||
var failureMessages = [];
|
||||
if (spec.results().failedCount) {
|
||||
failures ++;
|
||||
spec.results().items_.forEach(
|
||||
function(expectation)
|
||||
{
|
||||
if (!expectation.passed()) {
|
||||
failureMessages.push(expectation.message);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
return {
|
||||
assertions: spec.results().items_.length,
|
||||
className: getNestedSuiteName(spec.suite),
|
||||
name: spec.description,
|
||||
time: spec.duration / 1000,
|
||||
failureMessages: failureMessages
|
||||
};
|
||||
}
|
||||
)
|
||||
};
|
||||
data.failures = failures;
|
||||
if (suite.parentSuite) {
|
||||
consolidatedSuites[getTopLevelSuiteId(suite)].push(data);
|
||||
} else {
|
||||
consolidatedSuites[suite.id] = [data];
|
||||
}
|
||||
return data;
|
||||
}
|
||||
);
|
||||
|
||||
return {
|
||||
suites: suites,
|
||||
consolidatedSuites: consolidatedSuites
|
||||
};
|
||||
};
|
||||
|
||||
jasmine.getEnv().addReporter( new PhantomReporter() );
|
||||
}());
|
||||
|
14
tasks/jasmine/templates/JUnit.tmpl
Normal file
14
tasks/jasmine/templates/JUnit.tmpl
Normal file
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<testsuites>
|
||||
<% testsuites.forEach(function(testsuite) { %>
|
||||
<testsuite name="<%- testsuite.name %>" errors="<%= testsuite.errors %>" tests="<%= testsuite.tests %>" failures="<%= testsuite.failures %>" time="<%= testsuite.time %>" timestamp="<%= testsuite.timestamp %>">
|
||||
<% testsuite.testcases.forEach(function(testcase) { %>
|
||||
<testcase assertions="<%= testcase.assertions %>" classname="<%- testcase.className %>" name="<%- testcase.name %>" time="<%= testcase.time %>">
|
||||
<% testcase.failureMessages.forEach(function(message) { %>
|
||||
<failure><%= message %></failure>
|
||||
<% }) %>
|
||||
</testcase>
|
||||
<% }) %>
|
||||
</testsuite>
|
||||
<% }) %>
|
||||
</testsuites>
|
Loading…
Reference in New Issue
Block a user