json.js 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. 'use strict';
  2. /**
  3. * @module JSON
  4. */
  5. /**
  6. * Module dependencies.
  7. */
  8. var Base = require('./base');
  9. /**
  10. * Expose `JSON`.
  11. */
  12. exports = module.exports = JSONReporter;
  13. /**
  14. * Initialize a new `JSON` reporter.
  15. *
  16. * @public
  17. * @class JSON
  18. * @memberof Mocha.reporters
  19. * @extends Mocha.reporters.Base
  20. * @api public
  21. * @param {Runner} runner
  22. */
  23. function JSONReporter(runner) {
  24. Base.call(this, runner);
  25. var self = this;
  26. var tests = [];
  27. var pending = [];
  28. var failures = [];
  29. var passes = [];
  30. runner.on('test end', function(test) {
  31. tests.push(test);
  32. });
  33. runner.on('pass', function(test) {
  34. passes.push(test);
  35. });
  36. runner.on('fail', function(test) {
  37. failures.push(test);
  38. });
  39. runner.on('pending', function(test) {
  40. pending.push(test);
  41. });
  42. runner.once('end', function() {
  43. var obj = {
  44. stats: self.stats,
  45. tests: tests.map(clean),
  46. pending: pending.map(clean),
  47. failures: failures.map(clean),
  48. passes: passes.map(clean)
  49. };
  50. runner.testResults = obj;
  51. process.stdout.write(JSON.stringify(obj, null, 2));
  52. });
  53. }
  54. /**
  55. * Return a plain-object representation of `test`
  56. * free of cyclic properties etc.
  57. *
  58. * @api private
  59. * @param {Object} test
  60. * @return {Object}
  61. */
  62. function clean(test) {
  63. var err = test.err || {};
  64. if (err instanceof Error) {
  65. err = errorJSON(err);
  66. }
  67. return {
  68. title: test.title,
  69. fullTitle: test.fullTitle(),
  70. duration: test.duration,
  71. currentRetry: test.currentRetry(),
  72. err: cleanCycles(err)
  73. };
  74. }
  75. /**
  76. * Replaces any circular references inside `obj` with '[object Object]'
  77. *
  78. * @api private
  79. * @param {Object} obj
  80. * @return {Object}
  81. */
  82. function cleanCycles(obj) {
  83. var cache = [];
  84. return JSON.parse(
  85. JSON.stringify(obj, function(key, value) {
  86. if (typeof value === 'object' && value !== null) {
  87. if (cache.indexOf(value) !== -1) {
  88. // Instead of going in a circle, we'll print [object Object]
  89. return '' + value;
  90. }
  91. cache.push(value);
  92. }
  93. return value;
  94. })
  95. );
  96. }
  97. /**
  98. * Transform an Error object into a JSON object.
  99. *
  100. * @api private
  101. * @param {Error} err
  102. * @return {Object}
  103. */
  104. function errorJSON(err) {
  105. var res = {};
  106. Object.getOwnPropertyNames(err).forEach(function(key) {
  107. res[key] = err[key];
  108. }, err);
  109. return res;
  110. }