xunit.js 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. /**
  2. * Module dependencies.
  3. */
  4. var Base = require('./base')
  5. , utils = require('../utils')
  6. , escape = utils.escape;
  7. /**
  8. * Save timer references to avoid Sinon interfering (see GH-237).
  9. */
  10. var Date = global.Date
  11. , setTimeout = global.setTimeout
  12. , setInterval = global.setInterval
  13. , clearTimeout = global.clearTimeout
  14. , clearInterval = global.clearInterval;
  15. /**
  16. * Expose `XUnit`.
  17. */
  18. exports = module.exports = XUnit;
  19. /**
  20. * Initialize a new `XUnit` reporter.
  21. *
  22. * @param {Runner} runner
  23. * @api public
  24. */
  25. function XUnit(runner) {
  26. Base.call(this, runner);
  27. var stats = this.stats
  28. , tests = []
  29. , self = this;
  30. runner.on('pass', function(test){
  31. tests.push(test);
  32. });
  33. runner.on('fail', function(test){
  34. tests.push(test);
  35. });
  36. runner.on('end', function(){
  37. console.log(tag('testsuite', {
  38. name: 'Mocha Tests'
  39. , tests: stats.tests
  40. , failures: stats.failures
  41. , errors: stats.failures
  42. , skipped: stats.tests - stats.failures - stats.passes
  43. , timestamp: (new Date).toUTCString()
  44. , time: (stats.duration / 1000) || 0
  45. }, false));
  46. tests.forEach(test);
  47. console.log('</testsuite>');
  48. });
  49. }
  50. /**
  51. * Inherit from `Base.prototype`.
  52. */
  53. XUnit.prototype.__proto__ = Base.prototype;
  54. /**
  55. * Output tag for the given `test.`
  56. */
  57. function test(test) {
  58. var attrs = {
  59. classname: test.parent.fullTitle()
  60. , name: test.title
  61. , time: test.duration / 1000
  62. };
  63. if ('failed' == test.state) {
  64. var err = test.err;
  65. attrs.message = escape(err.message);
  66. console.log(tag('testcase', attrs, false, tag('failure', attrs, false, cdata(err.stack))));
  67. } else if (test.pending) {
  68. console.log(tag('testcase', attrs, false, tag('skipped', {}, true)));
  69. } else {
  70. console.log(tag('testcase', attrs, true) );
  71. }
  72. }
  73. /**
  74. * HTML tag helper.
  75. */
  76. function tag(name, attrs, close, content) {
  77. var end = close ? '/>' : '>'
  78. , pairs = []
  79. , tag;
  80. for (var key in attrs) {
  81. pairs.push(key + '="' + escape(attrs[key]) + '"');
  82. }
  83. tag = '<' + name + (pairs.length ? ' ' + pairs.join(' ') : '') + end;
  84. if (content) tag += content + '</' + name + end;
  85. return tag;
  86. }
  87. /**
  88. * Return cdata escaped CDATA `str`.
  89. */
  90. function cdata(str) {
  91. return '<![CDATA[' + escape(str) + ']]>';
  92. }