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