1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 | var nodeunit = require('../nodeunit'),
|
12 | utils = require('../utils'),
|
13 | fs = require('fs'),
|
14 | path = require('path'),
|
15 | async = require('../../deps/async'),
|
16 | AssertionError = require('../assert').AssertionError,
|
17 | child_process = require('child_process'),
|
18 | ejs = require('ejs');
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 | exports.info = "jUnit XML test reports";
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 | var ensureDir = function (path, callback) {
|
37 | var mkdir = child_process.spawn('mkdir', ['-p', path]);
|
38 | mkdir.on('error', function (err) {
|
39 | callback(err);
|
40 | callback = function(){};
|
41 | });
|
42 | mkdir.on('exit', function (code) {
|
43 | if (code === 0) callback();
|
44 | else callback(new Error('mkdir exited with code: ' + code));
|
45 | });
|
46 | };
|
47 |
|
48 |
|
49 |
|
50 |
|
51 |
|
52 |
|
53 |
|
54 |
|
55 |
|
56 |
|
57 |
|
58 |
|
59 |
|
60 | var abspath = function (p, /*optional*/cwd) {
|
61 | if (p[0] === '/') return p;
|
62 | cwd = cwd || process.cwd();
|
63 | return path.normalize(path.resolve(p));
|
64 | };
|
65 |
|
66 |
|
67 |
|
68 |
|
69 |
|
70 |
|
71 |
|
72 |
|
73 |
|
74 |
|
75 | exports.run = function (files, opts, callback) {
|
76 | if (!opts.output) {
|
77 | console.error(
|
78 | 'Error: No output directory defined.\n' +
|
79 | '\tEither add an "output" property to your nodeunit.json config ' +
|
80 | 'file, or\n\tuse the --output command line option.'
|
81 | );
|
82 | return;
|
83 | }
|
84 | opts.output = abspath(opts.output);
|
85 | var error = function (str) {
|
86 | return opts.error_prefix + str + opts.error_suffix;
|
87 | };
|
88 | var ok = function (str) {
|
89 | return opts.ok_prefix + str + opts.ok_suffix;
|
90 | };
|
91 | var bold = function (str) {
|
92 | return opts.bold_prefix + str + opts.bold_suffix;
|
93 | };
|
94 |
|
95 | var start = new Date().getTime();
|
96 | var paths = files.map(function (p) {
|
97 | return path.resolve(p);
|
98 | });
|
99 |
|
100 | var modules = {};
|
101 | var curModule;
|
102 |
|
103 | nodeunit.runFiles(paths, {
|
104 | testspec: opts.testspec,
|
105 | testFullSpec: opts.testFullSpec,
|
106 | moduleStart: function (name) {
|
107 | curModule = {
|
108 | errorCount: 0,
|
109 | failureCount: 0,
|
110 | tests: 0,
|
111 | testcases: {},
|
112 | name: name,
|
113 | start: new Date().getTime()
|
114 | };
|
115 | modules[name] = curModule;
|
116 | },
|
117 | testStart: function(name) {
|
118 | curModule.testcases[name] = {name: name, start : new Date().getTime()};
|
119 | },
|
120 | moduleDone: function(name) {
|
121 | curModule.end = new Date().getTime();
|
122 | },
|
123 | testDone: function (name, assertions) {
|
124 | var testcase = curModule.testcases[name];
|
125 | testcase.end = new Date().getTime();
|
126 | for (var i=0; i<assertions.length; i++) {
|
127 | var a = assertions[i];
|
128 | if (a.failed()) {
|
129 | a = utils.betterErrors(a);
|
130 | testcase.failure = {
|
131 | message: a.message,
|
132 | backtrace: a.error.stack
|
133 | };
|
134 |
|
135 | if (a.error instanceof AssertionError) {
|
136 | curModule.failureCount++;
|
137 | }
|
138 | else {
|
139 | curModule.errorCount++;
|
140 | }
|
141 | break;
|
142 | }
|
143 | }
|
144 | curModule.tests++;
|
145 | curModule.testcases[name] = testcase;;
|
146 | },
|
147 | done: function (assertions) {
|
148 | var end = new Date().getTime();
|
149 | var duration = end - start;
|
150 |
|
151 | ensureDir(opts.output, function (err) {
|
152 | var tmpl = __dirname + "/../../share/junit.xml.ejs";
|
153 | fs.readFile(tmpl, function (err, data) {
|
154 | if (err) throw err;
|
155 | var tmpl = data.toString();
|
156 | for(var k in modules) {
|
157 | var module = modules[k];
|
158 | var rendered = ejs.render(tmpl, {
|
159 | suites: [module]
|
160 | });
|
161 | var filename = path.resolve(
|
162 | opts.output,
|
163 | module.name + '.xml'
|
164 | );
|
165 | console.log('Writing ' + filename);
|
166 | fs.writeFileSync(filename, rendered, 'utf8');
|
167 | }
|
168 | if (assertions.failures()) {
|
169 | console.log(
|
170 | '\n' + bold(error('FAILURES: ')) +
|
171 | assertions.failures() + '/' +
|
172 | assertions.length + ' assertions failed (' +
|
173 | assertions.duration + 'ms)'
|
174 | );
|
175 | }
|
176 | else {
|
177 | console.log(
|
178 | '\n' + bold(ok('OK: ')) + assertions.length +
|
179 | ' assertions (' + assertions.duration + 'ms)'
|
180 | );
|
181 | }
|
182 |
|
183 | if (callback) callback(assertions.failures() ? new Error('We have got test failures.') : undefined);
|
184 | });
|
185 | });
|
186 | }
|
187 | });
|
188 | }
|