OLD | NEW |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #library('json_tests'); | 5 #library('json_tests'); |
6 | 6 |
7 #import('dart:json'); | 7 #import('dart:json'); |
8 #import('dart:html'); | 8 #import('dart:html'); |
9 #import('../../lib/unittest/unittest.dart'); | 9 #import('../../lib/unittest/unittest.dart'); |
10 #import('../../lib/unittest/html_config.dart'); | 10 #import('../../lib/unittest/html_config.dart'); |
11 | 11 |
12 main() { | 12 main() { |
13 useHtmlConfiguration(); | 13 useHtmlConfiguration(); |
14 test('Parse', () { | 14 test('Parse', () { |
15 // Scalars. | 15 // Scalars. |
16 expect(JSON.parse(' 5 ')).equals(5); | 16 expect(JSON.parse(' 5 '), equals(5)); |
17 expect(JSON.parse(' -42 ')).equals(-42); | 17 expect(JSON.parse(' -42 '), equals(-42)); |
18 expect(JSON.parse(' 3e0 ')).equals(3); | 18 expect(JSON.parse(' 3e0 '), equals(3)); |
19 expect(JSON.parse(' 3.14 ')).equals(3.14); | 19 expect(JSON.parse(' 3.14 '), equals(3.14)); |
20 expect(JSON.parse('true ')).equals(true); | 20 expect(JSON.parse('true '), isTrue); |
21 expect(JSON.parse(' false')).equals(false); | 21 expect(JSON.parse(' false'), isFalse); |
22 expect(JSON.parse(' null ')).equals(null); | 22 expect(JSON.parse(' null '), isNull); |
23 expect(JSON.parse('\n\rnull\t')).equals(null); | 23 expect(JSON.parse('\n\rnull\t'), isNull); |
24 expect(JSON.parse(' "hi there\\" bob" ')).equals('hi there" bob'); | 24 expect(JSON.parse(' "hi there\\" bob" '), equals('hi there" bob')); |
25 expect(JSON.parse(' "" ')).equals(''); | 25 expect(JSON.parse(' "" '), isEmpty); |
26 | 26 |
27 // Lists. | 27 // Lists. |
28 expectValueEquals([], JSON.parse(' [] ')); | 28 expect(JSON.parse(' [] '), isEmpty); |
29 expectValueEquals([], JSON.parse('[ ]')); | 29 expect(JSON.parse('[ ]'), isEmpty); |
30 expectValueEquals([3, -4.5, true, 'hi', false], | 30 expect(JSON.parse(' [3, -4.5, true, "hi", false] '), |
31 JSON.parse(' [3, -4.5, true, "hi", false] ')); | 31 orderedEquals([3, -4.5, true, 'hi', false])); |
32 // Nulls are tricky. | 32 // Nulls are tricky. |
33 expectValueEquals([null], JSON.parse('[null]')); | 33 expect(JSON.parse('[null]'), orderedEquals([null])); |
34 expectValueEquals([3, -4.5, null, true, 'hi', false], | 34 expect(JSON.parse(' [3, -4.5, null, true, "hi", false] '), |
35 JSON.parse(' [3, -4.5, null, true, "hi", false] ')); | 35 orderedEquals([3, -4.5, null, true, 'hi', false])); |
36 expectValueEquals([[null]], JSON.parse('[[null]]')); | 36 expect(JSON.parse('[[null]]'), |
37 expectValueEquals([[3], [], [null], ['hi', true]], | 37 recursivelyMatches([[null]])); |
38 JSON.parse(' [ [3], [], [null], ["hi", true]] ')); | 38 expect(JSON.parse(' [ [3], [], [null], ["hi", true]] '), |
| 39 recursivelyMatches([[3], [], [null], ['hi', true]])); |
39 | 40 |
40 // Maps. | 41 // Maps. |
41 expectValueEquals({}, JSON.parse(' {} ')); | 42 expect(JSON.parse(' {} '), isEmpty); |
42 expectValueEquals({}, JSON.parse('{ }')); | 43 expect(JSON.parse('{ }'), isEmpty); |
43 | 44 |
44 expectValueEquals( | 45 expect(JSON.parse( |
45 {'x':3, 'y':-4.5, 'z':'hi', 'u':true, 'v':false}, | 46 ' {"x":3, "y": -4.5, "z" : "hi","u" : true, "v": false } '), |
46 JSON.parse(' {"x":3, "y": -4.5, "z" : "hi","u" : true, "v": false } ')); | 47 recursivelyMatches({"x":3, "y": -4.5, "z" : "hi", |
47 expectValueEquals({"x":3, "y":-4.5, "z":'hi'}, | 48 "u" : true, "v": false })); |
48 JSON.parse(' {"x":3, "y": -4.5, "z" : "hi" } ')); | |
49 expectValueEquals({"z":'hi', "x":3, "y":-4.5}, | |
50 JSON.parse(' {"y": -4.5, "z" : "hi" ,"x":3 } ')); | |
51 | 49 |
52 expectValueEquals({' hi bob ':3, '':4.5}, | 50 expect(JSON.parse(' {"x":3, "y": -4.5, "z" : "hi" } '), |
53 JSON.parse('{ " hi bob " :3, "": 4.5}')); | 51 recursivelyMatches({"x":3, "y": -4.5, "z" : "hi" })); |
54 | 52 |
55 expectValueEquals({'x':{}}, JSON.parse(' { "x" : { } } ')); | 53 expect(JSON.parse(' {"y": -4.5, "z" : "hi" ,"x":3 } '), |
56 expectValueEquals({'x':{}}, JSON.parse('{"x":{}}')); | 54 recursivelyMatches({"y": -4.5, "z" : "hi" ,"x":3 })); |
| 55 |
| 56 expect(JSON.parse('{ " hi bob " :3, "": 4.5}'), |
| 57 recursivelyMatches({ " hi bob " :3, "": 4.5})); |
| 58 |
| 59 expect(JSON.parse(' { "x" : { } } '), |
| 60 recursivelyMatches({ 'x' : {}})); |
| 61 expect(JSON.parse('{"x":{}}'), |
| 62 recursivelyMatches({ 'x' : {}})); |
57 | 63 |
58 // Nulls are tricky. | 64 // Nulls are tricky. |
59 expectValueEquals({'w':null}, JSON.parse('{"w":null}')); | 65 expect(JSON.parse('{"w":null}'), |
60 expectValueEquals({'x':{'w':null}}, JSON.parse('{"x":{"w":null}}')); | 66 recursivelyMatches({ 'w' : null})); |
61 expectValueEquals( | 67 |
62 {'x':3, 'y':-4.5, 'z':'hi', 'w':null, 'u':true, 'v':false}, | 68 expect(JSON.parse('{"x":{"w":null}}'), |
63 JSON.parse(' {"x":3, "y": -4.5, "z" : "hi",' | 69 recursivelyMatches({"x":{"w":null}})); |
64 '"w":null, "u" : true, "v": false } ')); | 70 |
65 expectValueEquals( | 71 expect(JSON.parse(' {"x":3, "y": -4.5, "z" : "hi",' |
66 {'x':{'a':3, 'b':-4.5}, 'y':[{}], 'z':'hi', 'w':{'c':null, 'd':true}, | 72 '"w":null, "u" : true, "v": false } '), |
67 'v':null}, | 73 recursivelyMatches({"x":3, "y": -4.5, "z" : "hi", |
68 JSON.parse('{"x": {"a":3, "b": -4.5}, "y":[{}], ' | 74 "w":null, "u" : true, "v": false })); |
69 '"z":"hi","w":{"c":null,"d":true}, "v":null}')); | 75 |
70 }); | 76 expect(JSON.parse('{"x": {"a":3, "b": -4.5}, "y":[{}], ' |
| 77 '"z":"hi","w":{"c":null,"d":true}, "v":null}'), |
| 78 recursivelyMatches({"x": {"a":3, "b": -4.5}, "y":[{}], |
| 79 "z":"hi","w":{"c":null,"d":true}, "v":null})); |
71 | 80 |
72 test('stringify', () { | 81 test('stringify', () { |
73 // Scalars. | 82 // Scalars. |
74 expect(JSON.stringify(5)).equals('5'); | 83 expect(JSON.stringify(5), equals('5')); |
75 expect(JSON.stringify(-42)).equals('-42'); | 84 expect(JSON.stringify(-42), equals('-42')); |
76 // Dart does not guarantee a formatting for doubles, | 85 // Dart does not guarantee a formatting for doubles, |
77 // so reparse and compare to the original. | 86 // so reparse and compare to the original. |
78 validateRoundTrip(3.14); | 87 validateRoundTrip(3.14); |
79 expect(JSON.stringify(true)).equals('true'); | 88 expect(JSON.stringify(true), equals('true')); |
80 expect(JSON.stringify(false)).equals('false'); | 89 expect(JSON.stringify(false), equals('false')); |
81 expect(JSON.stringify(null)).equals('null'); | 90 expect(JSON.stringify(null), equals('null')); |
82 expect(JSON.stringify(' hi there" bob ')).equals('" hi there\\" bob "'); | 91 expect(JSON.stringify(' hi there" bob '), equals('" hi there\\" bob "')); |
83 expect(JSON.stringify('hi\\there')).equals('"hi\\\\there"'); | 92 expect(JSON.stringify('hi\\there'), equals('"hi\\\\there"')); |
84 // TODO(devoncarew): these tests break the dartium build | 93 // TODO(devoncarew): these tests break the dartium build |
85 //expect(JSON.stringify('hi\nthere')).equals('"hi\\nthere"'); | 94 //expect(JSON.stringify('hi\nthere'), equals('"hi\\nthere"')); |
86 //expect(JSON.stringify('hi\r\nthere')).equals('"hi\\r\\nthere"'); | 95 //expect(JSON.stringify('hi\r\nthere'), equals('"hi\\r\\nthere"')); |
87 expect(JSON.stringify('')).equals('""'); | 96 expect(JSON.stringify(''), equals('""')); |
88 | 97 |
89 // Lists. | 98 // Lists. |
90 expect(JSON.stringify([])).equals('[]'); | 99 expect(JSON.stringify([]), equals('[]')); |
91 expect(JSON.stringify(new List(0))).equals('[]'); | 100 expect(JSON.stringify(new List(0)), equals('[]')); |
92 expect(JSON.stringify(new List(3))).equals('[null,null,null]'); | 101 expect(JSON.stringify(new List(3)), equals('[null,null,null]')); |
93 validateRoundTrip([3, -4.5, null, true, 'hi', false]); | 102 validateRoundTrip([3, -4.5, null, true, 'hi', false]); |
94 Expect.equals('[[3],[],[null],["hi",true]]', | 103 expect(JSON.stringify([[3], [], [null], ['hi', true]]), |
95 JSON.stringify([[3], [], [null], ['hi', true]])); | 104 equals('[[3],[],[null],["hi",true]]')); |
96 | 105 |
97 // Maps. | 106 // Maps. |
98 expect(JSON.stringify({})).equals('{}'); | 107 expect(JSON.stringify({}), equals('{}')); |
99 expect(JSON.stringify(new Map())).equals('{}'); | 108 expect(JSON.stringify(new Map()), equals('{}')); |
100 expect(JSON.stringify({'x':{}})).equals('{"x":{}}'); | 109 expect(JSON.stringify({'x':{}}), equals('{"x":{}}')); |
101 expect(JSON.stringify({'x':{'a':3}})).equals('{"x":{"a":3}}'); | 110 expect(JSON.stringify({'x':{'a':3}}), equals('{"x":{"a":3}}')); |
102 | 111 |
103 // Dart does not guarantee an order on the keys | 112 // Dart does not guarantee an order on the keys |
104 // of a map literal, so reparse and compare to the original Map. | 113 // of a map literal, so reparse and compare to the original Map. |
105 validateRoundTrip( | 114 validateRoundTrip( |
106 {'x':3, 'y':-4.5, 'z':'hi', 'w':null, 'u':true, 'v':false}); | 115 {'x':3, 'y':-4.5, 'z':'hi', 'w':null, 'u':true, 'v':false}); |
107 validateRoundTrip({"x":3, "y":-4.5, "z":'hi'}); | 116 validateRoundTrip({"x":3, "y":-4.5, "z":'hi'}); |
108 validateRoundTrip({' hi bob ':3, '':4.5}); | 117 validateRoundTrip({' hi bob ':3, '':4.5}); |
109 validateRoundTrip( | 118 validateRoundTrip( |
110 {'x':{'a':3, 'b':-4.5}, 'y':[{}], 'z':'hi', 'w':{'c':null, 'd':true}, | 119 {'x':{'a':3, 'b':-4.5}, 'y':[{}], 'z':'hi', 'w':{'c':null, 'd':true}, |
111 'v':null}); | 120 'v':null}); |
112 }); | 121 }); |
113 | 122 |
114 test('stringify throws if argument cannot be converted', () { | 123 test('stringify throws if argument cannot be converted', () { |
115 /** | 124 /** |
116 * Checks that we get an exception (rather than silently returning null) if | 125 * Checks that we get an exception (rather than silently returning null) if |
117 * we try to stringify something that cannot be converted to json. | 126 * we try to stringify something that cannot be converted to json. |
118 */ | 127 */ |
119 expectThrow(() { | 128 expect(() => JSON.stringify(new TestClass()), throws); |
120 JSON.stringify(new TestClass()); | |
121 }); | 129 }); |
122 }); | 130 }); |
123 } | 131 } |
124 | 132 |
125 class TestClass { | 133 class TestClass { |
126 int x; | 134 int x; |
127 String y; | 135 String y; |
128 | 136 |
129 TestClass() : x = 3, y = 'joe' { } | 137 TestClass() : x = 3, y = 'joe' { } |
130 } | 138 } |
131 | 139 |
132 /** | 140 /** |
133 * Checks that the argument can be converted to a JSON string and | 141 * Checks that the argument can be converted to a JSON string and |
134 * back, and produce something equivalent to the argument. | 142 * back, and produce something equivalent to the argument. |
135 */ | 143 */ |
136 validateRoundTrip(expected) { | 144 validateRoundTrip(expected) { |
137 expectValueEquals(expected, JSON.parse(JSON.stringify(expected))); | 145 expect(JSON.parse(JSON.stringify(expected)), recursivelyMatches(expected)); |
138 } | 146 } |
139 | 147 |
140 /** | |
141 * Checks that expected value-equals actual, where value-equals is | |
142 * the same as == except for Lists and Maps where it's recursive | |
143 * value-equals. | |
144 */ | |
145 // TODO(chambers): Move into Expect class. | |
146 expectValueEquals(expected, actual, [String message = '']) { | |
147 if (expected is List && actual is List) { | |
148 int n = Math.min(expected.length, actual.length); | |
149 for (int i = 0; i < n; i++) { | |
150 expectValueEquals(expected[i], actual[i], 'at index ${i} ${message}'); | |
151 } | |
152 // We check on length at the end in order to provide better error | |
153 // messages when an unexpected item is inserted in a list. | |
154 expect(actual.length).equals(expected.length); | |
155 } else if (expected is Map && actual is Map) { | |
156 expectIsContained(expected, actual, 'in actual ${message}'); | |
157 expectIsContained(actual, expected, 'in expected ${message}', false); | |
158 } else { | |
159 expect(actual).equals(expected); | |
160 } | |
161 } | |
162 | 148 |
163 expectIsContained(Map expected, Map actual, | |
164 [String message = '', bool checkValues = true]) { | |
165 for (final key in expected.getKeys()) { | |
166 expect(actual.containsKey(key)).equals(true); | |
167 if (checkValues) { | |
168 expectValueEquals(expected[key], actual[key],'at key ${key} ${message}'); | |
169 } | |
170 } | |
171 } | |
OLD | NEW |