From 399171c02745d21d9ac14d358b7be6495cb9ebaa Mon Sep 17 00:00:00 2001 From: Lewis Ellis Date: Wed, 8 Mar 2017 13:44:15 -0800 Subject: [PATCH 1/7] Add vendored json-stringify-safe --- vendor/json-stringify-safe/stringify.js | 27 +++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 vendor/json-stringify-safe/stringify.js diff --git a/vendor/json-stringify-safe/stringify.js b/vendor/json-stringify-safe/stringify.js new file mode 100644 index 000000000000..bb032fcd55fe --- /dev/null +++ b/vendor/json-stringify-safe/stringify.js @@ -0,0 +1,27 @@ +exports = module.exports = stringify +exports.getSerialize = serializer + +function stringify(obj, replacer, spaces, cycleReplacer) { + return JSON.stringify(obj, serializer(replacer, cycleReplacer), spaces) +} + +function serializer(replacer, cycleReplacer) { + var stack = [], keys = [] + + if (cycleReplacer == null) cycleReplacer = function(key, value) { + if (stack[0] === value) return "[Circular ~]" + return "[Circular ~." + keys.slice(0, stack.indexOf(value)).join(".") + "]" + } + + return function(key, value) { + if (stack.length > 0) { + var thisPos = stack.indexOf(this) + ~thisPos ? stack.splice(thisPos + 1) : stack.push(this) + ~thisPos ? keys.splice(thisPos, Infinity, key) : keys.push(key) + if (~stack.indexOf(value)) value = cycleReplacer.call(this, key, value) + } + else stack.push(value) + + return replacer == null ? value : replacer.call(this, key, value) + } +} \ No newline at end of file From bfa162679360c085bb3319b81380e1ffabdbac0a Mon Sep 17 00:00:00 2001 From: Lewis Ellis Date: Thu, 9 Mar 2017 12:48:56 -0800 Subject: [PATCH 2/7] Make json-stringify-safe IE8 compatible --- vendor/json-stringify-safe/stringify.js | 30 ++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/vendor/json-stringify-safe/stringify.js b/vendor/json-stringify-safe/stringify.js index bb032fcd55fe..57c3de7a8e0c 100644 --- a/vendor/json-stringify-safe/stringify.js +++ b/vendor/json-stringify-safe/stringify.js @@ -1,6 +1,26 @@ +'use strict'; + +/* + json-stringify-safe + Like JSON.stringify, but doesn't throw on circular references. + + Originally forked from https://github.com/isaacs/json-stringify-safe + version 5.0.1 on 3/8/2017 and modified for IE8 compatibility. + Tests for this are in test/vendor. + + ISC license: https://github.com/isaacs/json-stringify-safe/blob/master/LICENSE +*/ + exports = module.exports = stringify exports.getSerialize = serializer +function indexOf(haystack, needle) { + for (var i = 0; i < haystack.length; ++i) { + if (haystack[i] === needle) return i; + } + return -1; +} + function stringify(obj, replacer, spaces, cycleReplacer) { return JSON.stringify(obj, serializer(replacer, cycleReplacer), spaces) } @@ -9,19 +29,19 @@ function serializer(replacer, cycleReplacer) { var stack = [], keys = [] if (cycleReplacer == null) cycleReplacer = function(key, value) { - if (stack[0] === value) return "[Circular ~]" - return "[Circular ~." + keys.slice(0, stack.indexOf(value)).join(".") + "]" + if (stack[0] === value) return '[Circular ~]' + return '[Circular ~.' + keys.slice(0, indexOf(stack, value)).join('.') + ']' } return function(key, value) { if (stack.length > 0) { - var thisPos = stack.indexOf(this) + var thisPos = indexOf(stack, this); ~thisPos ? stack.splice(thisPos + 1) : stack.push(this) ~thisPos ? keys.splice(thisPos, Infinity, key) : keys.push(key) - if (~stack.indexOf(value)) value = cycleReplacer.call(this, key, value) + if (~indexOf(stack, value)) value = cycleReplacer.call(this, key, value) } else stack.push(value) return replacer == null ? value : replacer.call(this, key, value) } -} \ No newline at end of file +} From 062618075ccbc309fe92d92c00d4765ccd2e9d40 Mon Sep 17 00:00:00 2001 From: Lewis Ellis Date: Thu, 9 Mar 2017 12:49:59 -0800 Subject: [PATCH 3/7] Add captureMessage/captureException to scratch example --- example/index.html | 2 ++ example/scratch.js | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/example/index.html b/example/index.html index 0051b996991a..b9dff45eae46 100644 --- a/example/index.html +++ b/example/index.html @@ -36,6 +36,8 @@ + + diff --git a/example/scratch.js b/example/scratch.js index 48507f9c5d1f..9d164ac9bf14 100644 --- a/example/scratch.js +++ b/example/scratch.js @@ -68,6 +68,14 @@ function blobExample() { xhr.send(); } +function captureMessage() { + Raven.captureMessage('lol did it broke'); +} + +function captureException() { + Raven.captureException(new Error('lol did it broke')); +} + function a() { b(); } function b() { c(); } function c() { d(); } From e19a1b2514046c9a799345ec151d3eea91919c5c Mon Sep 17 00:00:00 2001 From: Lewis Ellis Date: Thu, 9 Mar 2017 12:52:03 -0800 Subject: [PATCH 4/7] Use vendored json-stringify-safe in raven.js --- src/raven.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/raven.js b/src/raven.js index f0991d9c0967..aed68b1ecdbb 100644 --- a/src/raven.js +++ b/src/raven.js @@ -2,14 +2,13 @@ 'use strict'; var TraceKit = require('../vendor/TraceKit/tracekit'); +var stringify = require('../vendor/json-stringify-safe/stringify'); var RavenConfigError = require('./configError'); var utils = require('./utils'); var isError = utils.isError, isObject = utils.isObject; -var stringify = require('json-stringify-safe'); - var wrapConsoleMethod = require('./console').wrapMethod; var dsnKeys = 'source protocol user pass host port path'.split(' '), From b7ce7e0a23803e044d7a95b86ad53f148c4ee144 Mon Sep 17 00:00:00 2001 From: Lewis Ellis Date: Thu, 9 Mar 2017 12:53:40 -0800 Subject: [PATCH 5/7] Make request handler work properly with XDomainRequest --- src/raven.js | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/raven.js b/src/raven.js index aed68b1ecdbb..f30c1383c516 100644 --- a/src/raven.js +++ b/src/raven.js @@ -1584,24 +1584,18 @@ Raven.prototype = { if (!hasCORS) return; var url = opts.url; - function handler() { - if (request.status === 200) { - if (opts.onSuccess) { - opts.onSuccess(); - } - } else if (opts.onError) { - var err = new Error('Sentry error code: ' + request.status); - err.request = request; - opts.onError(err); - } - } if ('withCredentials' in request) { request.onreadystatechange = function () { if (request.readyState !== 4) { return; + } else if (request.status === 200) { + opts.onSuccess && opts.onSuccess(); + } else if (opts.onError) { + var err = new Error('Sentry error code: ' + request.status); + err.request = request; + opts.onError(err); } - handler(); }; } else { request = new XDomainRequest(); @@ -1610,7 +1604,16 @@ Raven.prototype = { url = url.replace(/^https?:/, ''); // onreadystatechange not supported by XDomainRequest - request.onload = handler; + if (opts.onSuccess) { + request.onload = opts.onSuccess; + } + if (opts.onError) { + request.onerror = function () { + var err = new Error('Sentry error code: XDomainRequest'); + err.request = request; + opts.onError(err); + } + } } // NOTE: auth is intentionally sent as part of query string (NOT as custom From 8df19632684aa3eb6df9231ba20a169e3f6982c3 Mon Sep 17 00:00:00 2001 From: Lewis Ellis Date: Thu, 9 Mar 2017 13:53:39 -0800 Subject: [PATCH 6/7] Add vendored json-stringify-safe tests --- test/vendor/json-stringify-safe.test.js | 246 ++++++++++++++++++++++++ 1 file changed, 246 insertions(+) create mode 100644 test/vendor/json-stringify-safe.test.js diff --git a/test/vendor/json-stringify-safe.test.js b/test/vendor/json-stringify-safe.test.js new file mode 100644 index 000000000000..5b3258317687 --- /dev/null +++ b/test/vendor/json-stringify-safe.test.js @@ -0,0 +1,246 @@ +var Sinon = require("sinon") +var stringify = require("..") +function jsonify(obj) { return JSON.stringify(obj, null, 2) } + +describe("Stringify", function() { + it("must stringify circular objects", function() { + var obj = {name: "Alice"} + obj.self = obj + var json = stringify(obj, null, 2) + json.must.eql(jsonify({name: "Alice", self: "[Circular ~]"})) + }) + + it("must stringify circular objects with intermediaries", function() { + var obj = {name: "Alice"} + obj.identity = {self: obj} + var json = stringify(obj, null, 2) + json.must.eql(jsonify({name: "Alice", identity: {self: "[Circular ~]"}})) + }) + + it("must stringify circular objects deeper", function() { + var obj = {name: "Alice", child: {name: "Bob"}} + obj.child.self = obj.child + + stringify(obj, null, 2).must.eql(jsonify({ + name: "Alice", + child: {name: "Bob", self: "[Circular ~.child]"} + })) + }) + + it("must stringify circular objects deeper with intermediaries", function() { + var obj = {name: "Alice", child: {name: "Bob"}} + obj.child.identity = {self: obj.child} + + stringify(obj, null, 2).must.eql(jsonify({ + name: "Alice", + child: {name: "Bob", identity: {self: "[Circular ~.child]"}} + })) + }) + + it("must stringify circular objects in an array", function() { + var obj = {name: "Alice"} + obj.self = [obj, obj] + + stringify(obj, null, 2).must.eql(jsonify({ + name: "Alice", self: ["[Circular ~]", "[Circular ~]"] + })) + }) + + it("must stringify circular objects deeper in an array", function() { + var obj = {name: "Alice", children: [{name: "Bob"}, {name: "Eve"}]} + obj.children[0].self = obj.children[0] + obj.children[1].self = obj.children[1] + + stringify(obj, null, 2).must.eql(jsonify({ + name: "Alice", + children: [ + {name: "Bob", self: "[Circular ~.children.0]"}, + {name: "Eve", self: "[Circular ~.children.1]"} + ] + })) + }) + + it("must stringify circular arrays", function() { + var obj = [] + obj.push(obj) + obj.push(obj) + var json = stringify(obj, null, 2) + json.must.eql(jsonify(["[Circular ~]", "[Circular ~]"])) + }) + + it("must stringify circular arrays with intermediaries", function() { + var obj = [] + obj.push({name: "Alice", self: obj}) + obj.push({name: "Bob", self: obj}) + + stringify(obj, null, 2).must.eql(jsonify([ + {name: "Alice", self: "[Circular ~]"}, + {name: "Bob", self: "[Circular ~]"} + ])) + }) + + it("must stringify repeated objects in objects", function() { + var obj = {} + var alice = {name: "Alice"} + obj.alice1 = alice + obj.alice2 = alice + + stringify(obj, null, 2).must.eql(jsonify({ + alice1: {name: "Alice"}, + alice2: {name: "Alice"} + })) + }) + + it("must stringify repeated objects in arrays", function() { + var alice = {name: "Alice"} + var obj = [alice, alice] + var json = stringify(obj, null, 2) + json.must.eql(jsonify([{name: "Alice"}, {name: "Alice"}])) + }) + + it("must call given decycler and use its output", function() { + var obj = {} + obj.a = obj + obj.b = obj + + var decycle = Sinon.spy(function() { return decycle.callCount }) + var json = stringify(obj, null, 2, decycle) + json.must.eql(jsonify({a: 1, b: 2}, null, 2)) + + decycle.callCount.must.equal(2) + decycle.thisValues[0].must.equal(obj) + decycle.args[0][0].must.equal("a") + decycle.args[0][1].must.equal(obj) + decycle.thisValues[1].must.equal(obj) + decycle.args[1][0].must.equal("b") + decycle.args[1][1].must.equal(obj) + }) + + it("must call replacer and use its output", function() { + var obj = {name: "Alice", child: {name: "Bob"}} + + var replacer = Sinon.spy(bangString) + var json = stringify(obj, replacer, 2) + json.must.eql(jsonify({name: "Alice!", child: {name: "Bob!"}})) + + replacer.callCount.must.equal(4) + replacer.args[0][0].must.equal("") + replacer.args[0][1].must.equal(obj) + replacer.thisValues[1].must.equal(obj) + replacer.args[1][0].must.equal("name") + replacer.args[1][1].must.equal("Alice") + replacer.thisValues[2].must.equal(obj) + replacer.args[2][0].must.equal("child") + replacer.args[2][1].must.equal(obj.child) + replacer.thisValues[3].must.equal(obj.child) + replacer.args[3][0].must.equal("name") + replacer.args[3][1].must.equal("Bob") + }) + + it("must call replacer after describing circular references", function() { + var obj = {name: "Alice"} + obj.self = obj + + var replacer = Sinon.spy(bangString) + var json = stringify(obj, replacer, 2) + json.must.eql(jsonify({name: "Alice!", self: "[Circular ~]!"})) + + replacer.callCount.must.equal(3) + replacer.args[0][0].must.equal("") + replacer.args[0][1].must.equal(obj) + replacer.thisValues[1].must.equal(obj) + replacer.args[1][0].must.equal("name") + replacer.args[1][1].must.equal("Alice") + replacer.thisValues[2].must.equal(obj) + replacer.args[2][0].must.equal("self") + replacer.args[2][1].must.equal("[Circular ~]") + }) + + it("must call given decycler and use its output for nested objects", + function() { + var obj = {} + obj.a = obj + obj.b = {self: obj} + + var decycle = Sinon.spy(function() { return decycle.callCount }) + var json = stringify(obj, null, 2, decycle) + json.must.eql(jsonify({a: 1, b: {self: 2}})) + + decycle.callCount.must.equal(2) + decycle.args[0][0].must.equal("a") + decycle.args[0][1].must.equal(obj) + decycle.args[1][0].must.equal("self") + decycle.args[1][1].must.equal(obj) + }) + + it("must use decycler's output when it returned null", function() { + var obj = {a: "b"} + obj.self = obj + obj.selves = [obj, obj] + + function decycle() { return null } + stringify(obj, null, 2, decycle).must.eql(jsonify({ + a: "b", + self: null, + selves: [null, null] + })) + }) + + it("must use decycler's output when it returned undefined", function() { + var obj = {a: "b"} + obj.self = obj + obj.selves = [obj, obj] + + function decycle() {} + stringify(obj, null, 2, decycle).must.eql(jsonify({ + a: "b", + selves: [null, null] + })) + }) + + it("must throw given a decycler that returns a cycle", function() { + var obj = {} + obj.self = obj + var err + function identity(key, value) { return value } + try { stringify(obj, null, 2, identity) } catch (ex) { err = ex } + err.must.be.an.instanceof(TypeError) + }) + + describe(".getSerialize", function() { + it("must stringify circular objects", function() { + var obj = {a: "b"} + obj.circularRef = obj + obj.list = [obj, obj] + + var json = JSON.stringify(obj, stringify.getSerialize(), 2) + json.must.eql(jsonify({ + "a": "b", + "circularRef": "[Circular ~]", + "list": ["[Circular ~]", "[Circular ~]"] + })) + }) + + // This is the behavior as of Mar 3, 2015. + // The serializer function keeps state inside the returned function and + // so far I'm not sure how to not do that. JSON.stringify's replacer is not + // called _after_ serialization. + xit("must return a function that could be called twice", function() { + var obj = {name: "Alice"} + obj.self = obj + + var json + var serializer = stringify.getSerialize() + + json = JSON.stringify(obj, serializer, 2) + json.must.eql(jsonify({name: "Alice", self: "[Circular ~]"})) + + json = JSON.stringify(obj, serializer, 2) + json.must.eql(jsonify({name: "Alice", self: "[Circular ~]"})) + }) + }) +}) + +function bangString(key, value) { + return typeof value == "string" ? value + "!" : value +} From d911cb76ece76139cb1a15b7abc0c1e5e52d38b3 Mon Sep 17 00:00:00 2001 From: Lewis Ellis Date: Thu, 9 Mar 2017 14:06:16 -0800 Subject: [PATCH 7/7] Make vendored json-stringify-safe tests use assert instead of must --- test/vendor/json-stringify-safe.test.js | 112 ++++++++++++------------ 1 file changed, 57 insertions(+), 55 deletions(-) diff --git a/test/vendor/json-stringify-safe.test.js b/test/vendor/json-stringify-safe.test.js index 5b3258317687..626efbdad5fe 100644 --- a/test/vendor/json-stringify-safe.test.js +++ b/test/vendor/json-stringify-safe.test.js @@ -1,5 +1,7 @@ +/*global Mocha, assert*/ var Sinon = require("sinon") -var stringify = require("..") +var stringify = require('../../vendor/json-stringify-safe/stringify'); + function jsonify(obj) { return JSON.stringify(obj, null, 2) } describe("Stringify", function() { @@ -7,21 +9,21 @@ describe("Stringify", function() { var obj = {name: "Alice"} obj.self = obj var json = stringify(obj, null, 2) - json.must.eql(jsonify({name: "Alice", self: "[Circular ~]"})) + assert.deepEqual(json, jsonify({name: "Alice", self: "[Circular ~]"})) }) it("must stringify circular objects with intermediaries", function() { var obj = {name: "Alice"} obj.identity = {self: obj} var json = stringify(obj, null, 2) - json.must.eql(jsonify({name: "Alice", identity: {self: "[Circular ~]"}})) + assert.deepEqual(json, jsonify({name: "Alice", identity: {self: "[Circular ~]"}})) }) it("must stringify circular objects deeper", function() { var obj = {name: "Alice", child: {name: "Bob"}} obj.child.self = obj.child - stringify(obj, null, 2).must.eql(jsonify({ + assert.deepEqual(stringify(obj, null, 2), jsonify({ name: "Alice", child: {name: "Bob", self: "[Circular ~.child]"} })) @@ -31,7 +33,7 @@ describe("Stringify", function() { var obj = {name: "Alice", child: {name: "Bob"}} obj.child.identity = {self: obj.child} - stringify(obj, null, 2).must.eql(jsonify({ + assert.deepEqual(stringify(obj, null, 2), jsonify({ name: "Alice", child: {name: "Bob", identity: {self: "[Circular ~.child]"}} })) @@ -41,7 +43,7 @@ describe("Stringify", function() { var obj = {name: "Alice"} obj.self = [obj, obj] - stringify(obj, null, 2).must.eql(jsonify({ + assert.deepEqual(stringify(obj, null, 2), jsonify({ name: "Alice", self: ["[Circular ~]", "[Circular ~]"] })) }) @@ -51,7 +53,7 @@ describe("Stringify", function() { obj.children[0].self = obj.children[0] obj.children[1].self = obj.children[1] - stringify(obj, null, 2).must.eql(jsonify({ + assert.deepEqual(stringify(obj, null, 2), jsonify({ name: "Alice", children: [ {name: "Bob", self: "[Circular ~.children.0]"}, @@ -65,7 +67,7 @@ describe("Stringify", function() { obj.push(obj) obj.push(obj) var json = stringify(obj, null, 2) - json.must.eql(jsonify(["[Circular ~]", "[Circular ~]"])) + assert.deepEqual(json, jsonify(["[Circular ~]", "[Circular ~]"])) }) it("must stringify circular arrays with intermediaries", function() { @@ -73,7 +75,7 @@ describe("Stringify", function() { obj.push({name: "Alice", self: obj}) obj.push({name: "Bob", self: obj}) - stringify(obj, null, 2).must.eql(jsonify([ + assert.deepEqual(stringify(obj, null, 2), jsonify([ {name: "Alice", self: "[Circular ~]"}, {name: "Bob", self: "[Circular ~]"} ])) @@ -85,7 +87,7 @@ describe("Stringify", function() { obj.alice1 = alice obj.alice2 = alice - stringify(obj, null, 2).must.eql(jsonify({ + assert.deepEqual(stringify(obj, null, 2), jsonify({ alice1: {name: "Alice"}, alice2: {name: "Alice"} })) @@ -95,7 +97,7 @@ describe("Stringify", function() { var alice = {name: "Alice"} var obj = [alice, alice] var json = stringify(obj, null, 2) - json.must.eql(jsonify([{name: "Alice"}, {name: "Alice"}])) + assert.deepEqual(json, jsonify([{name: "Alice"}, {name: "Alice"}])) }) it("must call given decycler and use its output", function() { @@ -105,15 +107,15 @@ describe("Stringify", function() { var decycle = Sinon.spy(function() { return decycle.callCount }) var json = stringify(obj, null, 2, decycle) - json.must.eql(jsonify({a: 1, b: 2}, null, 2)) + assert.deepEqual(json, jsonify({a: 1, b: 2}, null, 2)) - decycle.callCount.must.equal(2) - decycle.thisValues[0].must.equal(obj) - decycle.args[0][0].must.equal("a") - decycle.args[0][1].must.equal(obj) - decycle.thisValues[1].must.equal(obj) - decycle.args[1][0].must.equal("b") - decycle.args[1][1].must.equal(obj) + assert.strictEqual(decycle.callCount, 2) + assert.strictEqual(decycle.thisValues[0], obj) + assert.strictEqual(decycle.args[0][0], "a") + assert.strictEqual(decycle.args[0][1], obj) + assert.strictEqual(decycle.thisValues[1], obj) + assert.strictEqual(decycle.args[1][0], "b") + assert.strictEqual(decycle.args[1][1], obj) }) it("must call replacer and use its output", function() { @@ -121,20 +123,20 @@ describe("Stringify", function() { var replacer = Sinon.spy(bangString) var json = stringify(obj, replacer, 2) - json.must.eql(jsonify({name: "Alice!", child: {name: "Bob!"}})) - - replacer.callCount.must.equal(4) - replacer.args[0][0].must.equal("") - replacer.args[0][1].must.equal(obj) - replacer.thisValues[1].must.equal(obj) - replacer.args[1][0].must.equal("name") - replacer.args[1][1].must.equal("Alice") - replacer.thisValues[2].must.equal(obj) - replacer.args[2][0].must.equal("child") - replacer.args[2][1].must.equal(obj.child) - replacer.thisValues[3].must.equal(obj.child) - replacer.args[3][0].must.equal("name") - replacer.args[3][1].must.equal("Bob") + assert.deepEqual(json, jsonify({name: "Alice!", child: {name: "Bob!"}})) + + assert.strictEqual(replacer.callCount, 4) + assert.strictEqual(replacer.args[0][0], "") + assert.strictEqual(replacer.args[0][1], obj) + assert.strictEqual(replacer.thisValues[1], obj) + assert.strictEqual(replacer.args[1][0], "name") + assert.strictEqual(replacer.args[1][1], "Alice") + assert.strictEqual(replacer.thisValues[2], obj) + assert.strictEqual(replacer.args[2][0], "child") + assert.strictEqual(replacer.args[2][1], obj.child) + assert.strictEqual(replacer.thisValues[3], obj.child) + assert.strictEqual(replacer.args[3][0], "name") + assert.strictEqual(replacer.args[3][1], "Bob") }) it("must call replacer after describing circular references", function() { @@ -143,17 +145,17 @@ describe("Stringify", function() { var replacer = Sinon.spy(bangString) var json = stringify(obj, replacer, 2) - json.must.eql(jsonify({name: "Alice!", self: "[Circular ~]!"})) + assert.deepEqual(json, jsonify({name: "Alice!", self: "[Circular ~]!"})) - replacer.callCount.must.equal(3) - replacer.args[0][0].must.equal("") - replacer.args[0][1].must.equal(obj) - replacer.thisValues[1].must.equal(obj) - replacer.args[1][0].must.equal("name") - replacer.args[1][1].must.equal("Alice") - replacer.thisValues[2].must.equal(obj) - replacer.args[2][0].must.equal("self") - replacer.args[2][1].must.equal("[Circular ~]") + assert.strictEqual(replacer.callCount, 3) + assert.strictEqual(replacer.args[0][0], "") + assert.strictEqual(replacer.args[0][1], obj) + assert.strictEqual(replacer.thisValues[1], obj) + assert.strictEqual(replacer.args[1][0], "name") + assert.strictEqual(replacer.args[1][1], "Alice") + assert.strictEqual(replacer.thisValues[2], obj) + assert.strictEqual(replacer.args[2][0], "self") + assert.strictEqual(replacer.args[2][1], "[Circular ~]") }) it("must call given decycler and use its output for nested objects", @@ -164,13 +166,13 @@ describe("Stringify", function() { var decycle = Sinon.spy(function() { return decycle.callCount }) var json = stringify(obj, null, 2, decycle) - json.must.eql(jsonify({a: 1, b: {self: 2}})) + assert.deepEqual(json, jsonify({a: 1, b: {self: 2}})) - decycle.callCount.must.equal(2) - decycle.args[0][0].must.equal("a") - decycle.args[0][1].must.equal(obj) - decycle.args[1][0].must.equal("self") - decycle.args[1][1].must.equal(obj) + assert.strictEqual(decycle.callCount, 2) + assert.strictEqual(decycle.args[0][0], "a") + assert.strictEqual(decycle.args[0][1], obj) + assert.strictEqual(decycle.args[1][0], "self") + assert.strictEqual(decycle.args[1][1], obj) }) it("must use decycler's output when it returned null", function() { @@ -179,7 +181,7 @@ describe("Stringify", function() { obj.selves = [obj, obj] function decycle() { return null } - stringify(obj, null, 2, decycle).must.eql(jsonify({ + assert.deepEqual(stringify(obj, null, 2, decycle), jsonify({ a: "b", self: null, selves: [null, null] @@ -192,7 +194,7 @@ describe("Stringify", function() { obj.selves = [obj, obj] function decycle() {} - stringify(obj, null, 2, decycle).must.eql(jsonify({ + assert.deepEqual(stringify(obj, null, 2, decycle), jsonify({ a: "b", selves: [null, null] })) @@ -204,7 +206,7 @@ describe("Stringify", function() { var err function identity(key, value) { return value } try { stringify(obj, null, 2, identity) } catch (ex) { err = ex } - err.must.be.an.instanceof(TypeError) + assert.ok(err instanceof TypeError) }) describe(".getSerialize", function() { @@ -214,7 +216,7 @@ describe("Stringify", function() { obj.list = [obj, obj] var json = JSON.stringify(obj, stringify.getSerialize(), 2) - json.must.eql(jsonify({ + assert.deepEqual(json, jsonify({ "a": "b", "circularRef": "[Circular ~]", "list": ["[Circular ~]", "[Circular ~]"] @@ -233,10 +235,10 @@ describe("Stringify", function() { var serializer = stringify.getSerialize() json = JSON.stringify(obj, serializer, 2) - json.must.eql(jsonify({name: "Alice", self: "[Circular ~]"})) + assert.deepEqual(json, jsonify({name: "Alice", self: "[Circular ~]"})) json = JSON.stringify(obj, serializer, 2) - json.must.eql(jsonify({name: "Alice", self: "[Circular ~]"})) + assert.deepEqual(json, jsonify({name: "Alice", self: "[Circular ~]"})) }) }) })