From fb168745043194cb9594dc320639c0c6731cea6b Mon Sep 17 00:00:00 2001 From: Muthu Kumar Date: Tue, 18 Sep 2018 01:44:14 +0530 Subject: [PATCH] [reporter] Better xUnit reporter! * Needs moar escaping --- sample/sample7.test.js | 4 +-- src/gunner.js | 5 ++++ src/reporters/xunit.js | 75 ++++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 67 insertions(+), 17 deletions(-) diff --git a/sample/sample7.test.js b/sample/sample7.test.js index 2a36757..c561477 100644 --- a/sample/sample7.test.js +++ b/sample/sample7.test.js @@ -3,7 +3,7 @@ * used during development */ -const Gunner = require('../es5/dist.js'); +const Gunner = require('../es6'); const expect = Gunner.expect; const expectMany = Gunner.expectMany; const gunner = new Gunner({ name: 'sample tests' }); @@ -99,4 +99,4 @@ gunner.test('(should fail) should not resolve to 5', () => const trace = process.argv.slice(2).indexOf('--trace') !== -1; const reporter = process.argv.slice(2).indexOf('--log') !== -1; -gunner.run({ trace, reporter }); +gunner.run({ trace, reporter: 'xunit' }); diff --git a/src/gunner.js b/src/gunner.js index d8bd263..24399cf 100644 --- a/src/gunner.js +++ b/src/gunner.js @@ -80,11 +80,16 @@ class Gunner { emitter.emit('start'); return testrunner(this, options) .then(results => { + results.count = results.length; results.success = results.filter(r => r.status === 'ok'); + results.failures = results.filter(r => r.status === 'notOk'); + results.skipped = results.filter(r => r.status === 'skip'); results.successPercent = Math.floor( results.success.length/results.length * 100 ); + results.name = this.name; + if((results.successPercent !== 100) && typeof process !== 'undefined') process.exitCode = 1; diff --git a/src/reporters/xunit.js b/src/reporters/xunit.js index d57328e..322e753 100644 --- a/src/reporters/xunit.js +++ b/src/reporters/xunit.js @@ -1,22 +1,67 @@ -const Readable = require('stream').Readable; -const TAP = require('./tap'); -const xUnitConverter = require('tap-xunit'); - -const streamify = text => { - const s = new Readable(); - s._read = () => {}; - s.push(text); - s.push(null); - return s; +const tag = (name, attrs, close, content) => { + const end = close ? "/>" : ">"; + const pairs = []; + let tag; + + Object.keys(attrs).forEach(key => { + if (Object.prototype.hasOwnProperty.call(attrs, key)) { + pairs.push(key + '="' + (attrs[key]) + '"'); + } + }); + + tag = "<" + name + (pairs.length ? " " + pairs.join(" ") : "") + end; + if (content) { + // content = content instanceof String ? content : escape(content); + tag += content + " { + + const { count, success, failures, skipped } = results; + + return '' + tag( + 'testsuites', + {}, + false, + tag( + 'testsuite', + { + tests: count, + success: success.length, + failures: failures.length, + skipped: skipped.length + }, + false, + results.reduce((acc, r) => { + const close = r.status === 'ok'; + const content = r.status !== 'ok' && + (r.status === 'skip' + ? tag('skipped', {}, true) + : tag( + 'failure', {}, + !r.reason, r.reason ? escape(r.reason) : '')); + acc += tag( + 'testcase', + { name: escape(r.description) }, + close, + content || '' + ); + return acc; + }, '') + ) + ); + }; -const xunit = (runner) => { +const xunit = runner => { + runner.on("end", results => { - runner.on('end', results => - streamify(TAP.convert(results, { trace: false })) - .pipe(xUnitConverter()) - .pipe(process.stdout)); + console.log(convert(results)); + }); }; module.exports = xunit; +module.exports.convert = convert;