source: trip-planner-front/node_modules/json-stringify-safe/test/stringify_test.js@ 6a80231

Last change on this file since 6a80231 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 7.4 KB
Line 
1var Sinon = require("sinon")
2var stringify = require("..")
3function jsonify(obj) { return JSON.stringify(obj, null, 2) }
4
5describe("Stringify", function() {
6 it("must stringify circular objects", function() {
7 var obj = {name: "Alice"}
8 obj.self = obj
9 var json = stringify(obj, null, 2)
10 json.must.eql(jsonify({name: "Alice", self: "[Circular ~]"}))
11 })
12
13 it("must stringify circular objects with intermediaries", function() {
14 var obj = {name: "Alice"}
15 obj.identity = {self: obj}
16 var json = stringify(obj, null, 2)
17 json.must.eql(jsonify({name: "Alice", identity: {self: "[Circular ~]"}}))
18 })
19
20 it("must stringify circular objects deeper", function() {
21 var obj = {name: "Alice", child: {name: "Bob"}}
22 obj.child.self = obj.child
23
24 stringify(obj, null, 2).must.eql(jsonify({
25 name: "Alice",
26 child: {name: "Bob", self: "[Circular ~.child]"}
27 }))
28 })
29
30 it("must stringify circular objects deeper with intermediaries", function() {
31 var obj = {name: "Alice", child: {name: "Bob"}}
32 obj.child.identity = {self: obj.child}
33
34 stringify(obj, null, 2).must.eql(jsonify({
35 name: "Alice",
36 child: {name: "Bob", identity: {self: "[Circular ~.child]"}}
37 }))
38 })
39
40 it("must stringify circular objects in an array", function() {
41 var obj = {name: "Alice"}
42 obj.self = [obj, obj]
43
44 stringify(obj, null, 2).must.eql(jsonify({
45 name: "Alice", self: ["[Circular ~]", "[Circular ~]"]
46 }))
47 })
48
49 it("must stringify circular objects deeper in an array", function() {
50 var obj = {name: "Alice", children: [{name: "Bob"}, {name: "Eve"}]}
51 obj.children[0].self = obj.children[0]
52 obj.children[1].self = obj.children[1]
53
54 stringify(obj, null, 2).must.eql(jsonify({
55 name: "Alice",
56 children: [
57 {name: "Bob", self: "[Circular ~.children.0]"},
58 {name: "Eve", self: "[Circular ~.children.1]"}
59 ]
60 }))
61 })
62
63 it("must stringify circular arrays", function() {
64 var obj = []
65 obj.push(obj)
66 obj.push(obj)
67 var json = stringify(obj, null, 2)
68 json.must.eql(jsonify(["[Circular ~]", "[Circular ~]"]))
69 })
70
71 it("must stringify circular arrays with intermediaries", function() {
72 var obj = []
73 obj.push({name: "Alice", self: obj})
74 obj.push({name: "Bob", self: obj})
75
76 stringify(obj, null, 2).must.eql(jsonify([
77 {name: "Alice", self: "[Circular ~]"},
78 {name: "Bob", self: "[Circular ~]"}
79 ]))
80 })
81
82 it("must stringify repeated objects in objects", function() {
83 var obj = {}
84 var alice = {name: "Alice"}
85 obj.alice1 = alice
86 obj.alice2 = alice
87
88 stringify(obj, null, 2).must.eql(jsonify({
89 alice1: {name: "Alice"},
90 alice2: {name: "Alice"}
91 }))
92 })
93
94 it("must stringify repeated objects in arrays", function() {
95 var alice = {name: "Alice"}
96 var obj = [alice, alice]
97 var json = stringify(obj, null, 2)
98 json.must.eql(jsonify([{name: "Alice"}, {name: "Alice"}]))
99 })
100
101 it("must call given decycler and use its output", function() {
102 var obj = {}
103 obj.a = obj
104 obj.b = obj
105
106 var decycle = Sinon.spy(function() { return decycle.callCount })
107 var json = stringify(obj, null, 2, decycle)
108 json.must.eql(jsonify({a: 1, b: 2}, null, 2))
109
110 decycle.callCount.must.equal(2)
111 decycle.thisValues[0].must.equal(obj)
112 decycle.args[0][0].must.equal("a")
113 decycle.args[0][1].must.equal(obj)
114 decycle.thisValues[1].must.equal(obj)
115 decycle.args[1][0].must.equal("b")
116 decycle.args[1][1].must.equal(obj)
117 })
118
119 it("must call replacer and use its output", function() {
120 var obj = {name: "Alice", child: {name: "Bob"}}
121
122 var replacer = Sinon.spy(bangString)
123 var json = stringify(obj, replacer, 2)
124 json.must.eql(jsonify({name: "Alice!", child: {name: "Bob!"}}))
125
126 replacer.callCount.must.equal(4)
127 replacer.args[0][0].must.equal("")
128 replacer.args[0][1].must.equal(obj)
129 replacer.thisValues[1].must.equal(obj)
130 replacer.args[1][0].must.equal("name")
131 replacer.args[1][1].must.equal("Alice")
132 replacer.thisValues[2].must.equal(obj)
133 replacer.args[2][0].must.equal("child")
134 replacer.args[2][1].must.equal(obj.child)
135 replacer.thisValues[3].must.equal(obj.child)
136 replacer.args[3][0].must.equal("name")
137 replacer.args[3][1].must.equal("Bob")
138 })
139
140 it("must call replacer after describing circular references", function() {
141 var obj = {name: "Alice"}
142 obj.self = obj
143
144 var replacer = Sinon.spy(bangString)
145 var json = stringify(obj, replacer, 2)
146 json.must.eql(jsonify({name: "Alice!", self: "[Circular ~]!"}))
147
148 replacer.callCount.must.equal(3)
149 replacer.args[0][0].must.equal("")
150 replacer.args[0][1].must.equal(obj)
151 replacer.thisValues[1].must.equal(obj)
152 replacer.args[1][0].must.equal("name")
153 replacer.args[1][1].must.equal("Alice")
154 replacer.thisValues[2].must.equal(obj)
155 replacer.args[2][0].must.equal("self")
156 replacer.args[2][1].must.equal("[Circular ~]")
157 })
158
159 it("must call given decycler and use its output for nested objects",
160 function() {
161 var obj = {}
162 obj.a = obj
163 obj.b = {self: obj}
164
165 var decycle = Sinon.spy(function() { return decycle.callCount })
166 var json = stringify(obj, null, 2, decycle)
167 json.must.eql(jsonify({a: 1, b: {self: 2}}))
168
169 decycle.callCount.must.equal(2)
170 decycle.args[0][0].must.equal("a")
171 decycle.args[0][1].must.equal(obj)
172 decycle.args[1][0].must.equal("self")
173 decycle.args[1][1].must.equal(obj)
174 })
175
176 it("must use decycler's output when it returned null", function() {
177 var obj = {a: "b"}
178 obj.self = obj
179 obj.selves = [obj, obj]
180
181 function decycle() { return null }
182 stringify(obj, null, 2, decycle).must.eql(jsonify({
183 a: "b",
184 self: null,
185 selves: [null, null]
186 }))
187 })
188
189 it("must use decycler's output when it returned undefined", function() {
190 var obj = {a: "b"}
191 obj.self = obj
192 obj.selves = [obj, obj]
193
194 function decycle() {}
195 stringify(obj, null, 2, decycle).must.eql(jsonify({
196 a: "b",
197 selves: [null, null]
198 }))
199 })
200
201 it("must throw given a decycler that returns a cycle", function() {
202 var obj = {}
203 obj.self = obj
204 var err
205 function identity(key, value) { return value }
206 try { stringify(obj, null, 2, identity) } catch (ex) { err = ex }
207 err.must.be.an.instanceof(TypeError)
208 })
209
210 describe(".getSerialize", function() {
211 it("must stringify circular objects", function() {
212 var obj = {a: "b"}
213 obj.circularRef = obj
214 obj.list = [obj, obj]
215
216 var json = JSON.stringify(obj, stringify.getSerialize(), 2)
217 json.must.eql(jsonify({
218 "a": "b",
219 "circularRef": "[Circular ~]",
220 "list": ["[Circular ~]", "[Circular ~]"]
221 }))
222 })
223
224 // This is the behavior as of Mar 3, 2015.
225 // The serializer function keeps state inside the returned function and
226 // so far I'm not sure how to not do that. JSON.stringify's replacer is not
227 // called _after_ serialization.
228 xit("must return a function that could be called twice", function() {
229 var obj = {name: "Alice"}
230 obj.self = obj
231
232 var json
233 var serializer = stringify.getSerialize()
234
235 json = JSON.stringify(obj, serializer, 2)
236 json.must.eql(jsonify({name: "Alice", self: "[Circular ~]"}))
237
238 json = JSON.stringify(obj, serializer, 2)
239 json.must.eql(jsonify({name: "Alice", self: "[Circular ~]"}))
240 })
241 })
242})
243
244function bangString(key, value) {
245 return typeof value == "string" ? value + "!" : value
246}
Note: See TracBrowser for help on using the repository browser.