Skip to content

Commit 741b0bd

Browse files
authored
fix circular objects in json reporter; closes #2433 (#3318)
original work by @jeversmann; continuation of PR #2559 Signed-off-by: Christopher Hiller <[email protected]>
1 parent 8010501 commit 741b0bd

File tree

2 files changed

+56
-2
lines changed

2 files changed

+56
-2
lines changed

lib/reporters/json.js

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,17 +67,44 @@ function JSONReporter (runner) {
6767
* @return {Object}
6868
*/
6969
function clean (test) {
70+
var err = test.err || {};
71+
if (err instanceof Error) {
72+
err = errorJSON(err);
73+
}
74+
7075
return {
7176
title: test.title,
7277
fullTitle: test.fullTitle(),
7378
duration: test.duration,
7479
currentRetry: test.currentRetry(),
75-
err: errorJSON(test.err || {})
80+
err: cleanCycles(err)
7681
};
7782
}
7883

7984
/**
80-
* Transform `error` into a JSON object.
85+
* Replaces any circular references inside `obj` with '[object Object]'
86+
*
87+
* @api private
88+
* @param {Object} obj
89+
* @return {Object}
90+
*/
91+
function cleanCycles (obj) {
92+
var cache = [];
93+
return JSON.parse(JSON.stringify(obj, function (key, value) {
94+
if (typeof value === 'object' && value !== null) {
95+
if (cache.indexOf(value) !== -1) {
96+
// Instead of going in a circle, we'll print [object Object]
97+
return '' + value;
98+
}
99+
cache.push(value);
100+
}
101+
102+
return value;
103+
}));
104+
}
105+
106+
/**
107+
* Transform an Error object into a JSON object.
81108
*
82109
* @api private
83110
* @param {Error} err

test/reporters/json.spec.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,31 @@ describe('json reporter', function () {
5858
done();
5959
});
6060
});
61+
62+
it('should handle circular objects in errors', function (done) {
63+
var testTitle = 'json test 1';
64+
function CircleError () {
65+
this.message = 'oh shit';
66+
this.circular = this;
67+
}
68+
var error = new CircleError();
69+
70+
suite.addTest(new Test(testTitle, function (done) {
71+
throw error;
72+
}));
73+
74+
runner.run(function (failureCount) {
75+
expect(failureCount).to.equal(1);
76+
expect(runner).to.have.property('testResults');
77+
expect(runner.testResults).to.have.property('failures');
78+
expect(runner.testResults.failures).to.be.an(Array);
79+
expect(runner.testResults.failures).to.have.length(1);
80+
81+
var failure = runner.testResults.failures[0];
82+
expect(failure).to.have.property('title', testTitle);
83+
expect(failure).to.have.property('err');
84+
85+
done();
86+
});
87+
});
6188
});

0 commit comments

Comments
 (0)