summaryrefslogtreecommitdiff
path: root/deps/npm/node_modules/json-stringify-safe/test/stringify_test.js
diff options
context:
space:
mode:
Diffstat (limited to 'deps/npm/node_modules/json-stringify-safe/test/stringify_test.js')
-rw-r--r--deps/npm/node_modules/json-stringify-safe/test/stringify_test.js246
1 files changed, 246 insertions, 0 deletions
diff --git a/deps/npm/node_modules/json-stringify-safe/test/stringify_test.js b/deps/npm/node_modules/json-stringify-safe/test/stringify_test.js
new file mode 100644
index 0000000000..5b32583176
--- /dev/null
+++ b/deps/npm/node_modules/json-stringify-safe/test/stringify_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
+}