react / wstein / node_modules / jest-cli / node_modules / jsdom / node_modules / request / node_modules / json-stringify-safe / test / stringify_test.js
81146 viewsvar Sinon = require("sinon")1var stringify = require("..")2function jsonify(obj) { return JSON.stringify(obj, null, 2) }34describe("Stringify", function() {5it("must stringify circular objects", function() {6var obj = {name: "Alice"}7obj.self = obj8var json = stringify(obj, null, 2)9json.must.eql(jsonify({name: "Alice", self: "[Circular ~]"}))10})1112it("must stringify circular objects with intermediaries", function() {13var obj = {name: "Alice"}14obj.identity = {self: obj}15var json = stringify(obj, null, 2)16json.must.eql(jsonify({name: "Alice", identity: {self: "[Circular ~]"}}))17})1819it("must stringify circular objects deeper", function() {20var obj = {name: "Alice", child: {name: "Bob"}}21obj.child.self = obj.child2223stringify(obj, null, 2).must.eql(jsonify({24name: "Alice",25child: {name: "Bob", self: "[Circular ~.child]"}26}))27})2829it("must stringify circular objects deeper with intermediaries", function() {30var obj = {name: "Alice", child: {name: "Bob"}}31obj.child.identity = {self: obj.child}3233stringify(obj, null, 2).must.eql(jsonify({34name: "Alice",35child: {name: "Bob", identity: {self: "[Circular ~.child]"}}36}))37})3839it("must stringify circular objects in an array", function() {40var obj = {name: "Alice"}41obj.self = [obj, obj]4243stringify(obj, null, 2).must.eql(jsonify({44name: "Alice", self: ["[Circular ~]", "[Circular ~]"]45}))46})4748it("must stringify circular objects deeper in an array", function() {49var obj = {name: "Alice", children: [{name: "Bob"}, {name: "Eve"}]}50obj.children[0].self = obj.children[0]51obj.children[1].self = obj.children[1]5253stringify(obj, null, 2).must.eql(jsonify({54name: "Alice",55children: [56{name: "Bob", self: "[Circular ~.children.0]"},57{name: "Eve", self: "[Circular ~.children.1]"}58]59}))60})6162it("must stringify circular arrays", function() {63var obj = []64obj.push(obj)65obj.push(obj)66var json = stringify(obj, null, 2)67json.must.eql(jsonify(["[Circular ~]", "[Circular ~]"]))68})6970it("must stringify circular arrays with intermediaries", function() {71var obj = []72obj.push({name: "Alice", self: obj})73obj.push({name: "Bob", self: obj})7475stringify(obj, null, 2).must.eql(jsonify([76{name: "Alice", self: "[Circular ~]"},77{name: "Bob", self: "[Circular ~]"}78]))79})8081it("must stringify repeated objects in objects", function() {82var obj = {}83var alice = {name: "Alice"}84obj.alice1 = alice85obj.alice2 = alice8687stringify(obj, null, 2).must.eql(jsonify({88alice1: {name: "Alice"},89alice2: {name: "Alice"}90}))91})9293it("must stringify repeated objects in arrays", function() {94var alice = {name: "Alice"}95var obj = [alice, alice]96var json = stringify(obj, null, 2)97json.must.eql(jsonify([{name: "Alice"}, {name: "Alice"}]))98})99100it("must call given decycler and use its output", function() {101var obj = {}102obj.a = obj103obj.b = obj104105var decycle = Sinon.spy(function() { return decycle.callCount })106var json = stringify(obj, null, 2, decycle)107json.must.eql(jsonify({a: 1, b: 2}, null, 2))108109decycle.callCount.must.equal(2)110decycle.thisValues[0].must.equal(obj)111decycle.args[0][0].must.equal("a")112decycle.args[0][1].must.equal(obj)113decycle.thisValues[1].must.equal(obj)114decycle.args[1][0].must.equal("b")115decycle.args[1][1].must.equal(obj)116})117118it("must call replacer and use its output", function() {119var obj = {name: "Alice", child: {name: "Bob"}}120121var replacer = Sinon.spy(bangString)122var json = stringify(obj, replacer, 2)123json.must.eql(jsonify({name: "Alice!", child: {name: "Bob!"}}))124125replacer.callCount.must.equal(4)126replacer.args[0][0].must.equal("")127replacer.args[0][1].must.equal(obj)128replacer.thisValues[1].must.equal(obj)129replacer.args[1][0].must.equal("name")130replacer.args[1][1].must.equal("Alice")131replacer.thisValues[2].must.equal(obj)132replacer.args[2][0].must.equal("child")133replacer.args[2][1].must.equal(obj.child)134replacer.thisValues[3].must.equal(obj.child)135replacer.args[3][0].must.equal("name")136replacer.args[3][1].must.equal("Bob")137})138139it("must call replacer after describing circular references", function() {140var obj = {name: "Alice"}141obj.self = obj142143var replacer = Sinon.spy(bangString)144var json = stringify(obj, replacer, 2)145json.must.eql(jsonify({name: "Alice!", self: "[Circular ~]!"}))146147replacer.callCount.must.equal(3)148replacer.args[0][0].must.equal("")149replacer.args[0][1].must.equal(obj)150replacer.thisValues[1].must.equal(obj)151replacer.args[1][0].must.equal("name")152replacer.args[1][1].must.equal("Alice")153replacer.thisValues[2].must.equal(obj)154replacer.args[2][0].must.equal("self")155replacer.args[2][1].must.equal("[Circular ~]")156})157158it("must call given decycler and use its output for nested objects",159function() {160var obj = {}161obj.a = obj162obj.b = {self: obj}163164var decycle = Sinon.spy(function() { return decycle.callCount })165var json = stringify(obj, null, 2, decycle)166json.must.eql(jsonify({a: 1, b: {self: 2}}))167168decycle.callCount.must.equal(2)169decycle.args[0][0].must.equal("a")170decycle.args[0][1].must.equal(obj)171decycle.args[1][0].must.equal("self")172decycle.args[1][1].must.equal(obj)173})174175it("must use decycler's output when it returned null", function() {176var obj = {a: "b"}177obj.self = obj178obj.selves = [obj, obj]179180function decycle() { return null }181stringify(obj, null, 2, decycle).must.eql(jsonify({182a: "b",183self: null,184selves: [null, null]185}))186})187188it("must use decycler's output when it returned undefined", function() {189var obj = {a: "b"}190obj.self = obj191obj.selves = [obj, obj]192193function decycle() {}194stringify(obj, null, 2, decycle).must.eql(jsonify({195a: "b",196selves: [null, null]197}))198})199200it("must throw given a decycler that returns a cycle", function() {201var obj = {}202obj.self = obj203var err204function identity(key, value) { return value }205try { stringify(obj, null, 2, identity) } catch (ex) { err = ex }206err.must.be.an.instanceof(TypeError)207})208209describe(".getSerialize", function() {210it("must stringify circular objects", function() {211var obj = {a: "b"}212obj.circularRef = obj213obj.list = [obj, obj]214215var json = JSON.stringify(obj, stringify.getSerialize(), 2)216json.must.eql(jsonify({217"a": "b",218"circularRef": "[Circular ~]",219"list": ["[Circular ~]", "[Circular ~]"]220}))221})222223// This is the behavior as of Mar 3, 2015.224// The serializer function keeps state inside the returned function and225// so far I'm not sure how to not do that. JSON.stringify's replacer is not226// called _after_ serialization.227xit("must return a function that could be called twice", function() {228var obj = {name: "Alice"}229obj.self = obj230231var json232var serializer = stringify.getSerialize()233234json = JSON.stringify(obj, serializer, 2)235json.must.eql(jsonify({name: "Alice", self: "[Circular ~]"}))236237json = JSON.stringify(obj, serializer, 2)238json.must.eql(jsonify({name: "Alice", self: "[Circular ~]"}))239})240})241})242243function bangString(key, value) {244return typeof value == "string" ? value + "!" : value245}246247248