tizen beta release
[profile/ivi/webkit-efl.git] / LayoutTests / fast / js / script-tests / JSON-parse-reviver.js
1 description("Test behaviour of JSON reviver function.")
2 if (!Array.isArray)
3     Array.isArray = function(o) { return o.constructor === Array; }
4
5 function arrayReviver(i,v) {
6     if (i != "") {
7         currentHolder = this;
8         debug("");
9         debug("Ensure the holder for our array is indeed an array");
10         shouldBeTrue("Array.isArray(currentHolder)");
11         shouldBe("currentHolder.length", "" + expectedLength);
12         if (i > 0) {
13             debug("");
14             debug("Ensure that we always get the same holder");
15             shouldBe("currentHolder", "lastHolder");
16         }
17         switch (Number(i)) {
18         case 0:
19             v = undefined;
20             debug("");
21             debug("Ensure that the holder already has all the properties present at the start of filtering");
22             shouldBe("currentHolder[0]", '"a value"');
23             shouldBe("currentHolder[1]", '"another value"');
24             shouldBe("currentHolder[2]", '"and another value"');
25             shouldBe("currentHolder[3]", '"to delete"');
26             shouldBe("currentHolder[4]", '"extra value"');
27             break;
28
29         case 1:
30             debug("");
31             debug("Ensure that returning undefined has removed the property 0 from the holder during filtering.");
32             shouldBeFalse("currentHolder.hasOwnProperty(0)");
33             currentHolder[2] = "a replaced value";
34             break;
35
36         case 2:
37             debug("");
38             debug("Ensure that changing the value of a property is reflected while filtering.")
39             shouldBe("currentHolder[2]", '"a replaced value"');
40             value = v;
41             debug("");
42             debug("Ensure that the changed value is reflected in the arguments passed to the reviver");
43             shouldBe("value", "currentHolder[2]");
44             delete this[3];
45             break;
46
47         case 3:
48             debug("");
49             debug("Ensure that we visited a value that we have deleted, and that deletion is reflected while filtering.");
50             shouldBeFalse("currentHolder.hasOwnProperty(3)");
51             value = v;
52             debug("");
53             debug("Ensure that when visiting a deleted property value is undefined");
54             shouldBeUndefined("value");
55             v = "undelete the property";
56             expectedLength = this.length = 3;
57             break;
58
59         case 4:
60             if (this.length != 3) {
61                 testFailed("Did not call reviver for deleted property");
62                 expectedLength = this.length = 3;
63                 break;
64             }
65
66         case 5:
67             testPassed("Ensured that property was visited despite Array length being reduced.");
68             value = v;
69             shouldBeUndefined("value");
70             this[10] = "fail";
71             break;
72
73         default:
74             testFailed("Visited unexpected property " + i + " with value " + v);
75         }
76     }
77     lastHolder = this;
78     return v;
79 }
80 expectedLength = 5;
81 var result = JSON.parse('["a value", "another value", "and another value", "to delete", "extra value"]', arrayReviver);
82 debug("");
83 debug("Ensure that we created the root holder as specified in ES5");
84 shouldBeTrue("'' in lastHolder");
85 shouldBe("result", "lastHolder['']");
86 debug("");
87 debug("Ensure that a deleted value is revived if the reviver function returns a value");
88 shouldBeTrue("result.hasOwnProperty(3)");
89
90 function objectReviver(i,v) {
91     if (i != "") {
92         currentHolder = this;
93         shouldBeTrue("currentHolder != globalObject");
94         if (seen) {
95             debug("");
96             debug("Ensure that we get the same holder object for each property");
97             shouldBe("currentHolder", "lastHolder");
98         }
99         seen = true;
100         switch (i) {
101         case "a property":
102             v = undefined;
103             debug("");
104             debug("Ensure that the holder already has all the properties present at the start of filtering");
105             shouldBe("currentHolder['a property']", '"a value"');
106             shouldBe("currentHolder['another property']", '"another value"');
107             shouldBe("currentHolder['and another property']", '"and another value"');
108             shouldBe("currentHolder['to delete']", '"will be deleted"');
109             break;
110
111         case "another property":
112             debug("");
113             debug("Ensure that returning undefined has correctly removed the property 'a property' from the holder object");
114             shouldBeFalse("currentHolder.hasOwnProperty('a property')");
115             currentHolder['and another property'] = "a replaced value";
116             break;
117
118         case "and another property":
119             debug("Ensure that changing the value of a property is reflected while filtering.");
120             shouldBe("currentHolder['and another property']", '"a replaced value"');
121             value = v;
122             debug("");
123             debug("Ensure that the changed value is reflected in the arguments passed to the reviver");
124             shouldBe("value", '"a replaced value"');
125             delete this["to delete"];
126             break;
127
128         case "to delete":
129             debug("");
130             debug("Ensure that we visited a value that we have deleted, and that deletion is reflected while filtering.");
131             shouldBeFalse("currentHolder.hasOwnProperty('to delete')");
132             value = v;
133             debug("");
134             debug("Ensure that when visiting a deleted property value is undefined");
135             shouldBeUndefined("value");
136             v = "undelete the property";
137             this["new property"] = "fail";
138             break;
139         default:
140             testFailed("Visited unexpected property " + i + " with value " + v);
141         }
142     }
143     lastHolder = this;
144     return v;
145 }
146
147 debug("");
148 debug("Test behaviour of revivor used in conjunction with an object");
149 var seen = false;
150 var globalObject = this;
151 var result = JSON.parse('{"a property" : "a value", "another property" : "another value", "and another property" : "and another value", "to delete" : "will be deleted"}', objectReviver);
152 debug("");
153 debug("Ensure that we created the root holder as specified in ES5");
154 shouldBeTrue("lastHolder.hasOwnProperty('')");
155 shouldBeFalse("result.hasOwnProperty('a property')");
156 shouldBeTrue("result.hasOwnProperty('to delete')");
157 shouldBe("result", "lastHolder['']");
158
159 debug("");
160 debug("Test behaviour of revivor that introduces a cycle");
161 function reviveAddsCycle(i, v) {
162     if (i == 0)
163         this[1] = this;
164     return v;
165 }
166
167 shouldThrow('JSON.parse("[0,1]", reviveAddsCycle)');
168
169 debug("");
170 debug("Test behaviour of revivor that introduces a new array classed object (the result of a regex)");
171 var createdBadness = false;
172 function reviveIntroducesNewArrayLikeObject(i, v) {
173     if (i == 0 && !createdBadness) {
174         this[1] = /(a)+/.exec("a");
175         createdBadness = true;
176     }
177     return v;
178 }
179
180 shouldBe('JSON.stringify(JSON.parse("[0,1]", reviveIntroducesNewArrayLikeObject))', '\'[0,["a","a"]]\'');
181
182