OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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_test; | 5 library json_test; |
6 | 6 |
7 import "package:expect/expect.dart"; | 7 import "package:expect/expect.dart"; |
8 import "dart:convert"; | 8 import "dart:convert"; |
9 | 9 |
10 bool badFormat(e) => e is FormatException; | 10 bool badFormat(e) => e is FormatException; |
11 | 11 |
12 void testJson(json, expected) { | 12 void testJson(json, expected) { |
13 compare(expected, actual, path) { | 13 compare(expected, actual, path) { |
14 if (expected is List) { | 14 if (expected is List) { |
15 Expect.isTrue(actual is List); | 15 Expect.isTrue(actual is List); |
16 Expect.equals(expected.length, actual.length, "$path: List length"); | 16 Expect.equals(expected.length, actual.length, "$path: List length"); |
17 for (int i = 0; i < expected.length; i++) { | 17 for (int i = 0; i < expected.length; i++) { |
18 compare(expected[i], actual[i], "$path[$i]"); | 18 compare(expected[i], actual[i], "$path[$i]"); |
19 } | 19 } |
20 } else if (expected is Map) { | 20 } else if (expected is Map) { |
21 Expect.isTrue(actual is Map); | 21 Expect.isTrue(actual is Map); |
22 Expect.equals(expected.length, actual.length, "$path: Map size"); | 22 Expect.equals(expected.length, actual.length, "$path: Map size"); |
23 expected.forEach((key, value) { | 23 expected.forEach((key, value) { |
24 Expect.isTrue(actual.containsKey(key)); | 24 Expect.isTrue(actual.containsKey(key)); |
25 compare(value, actual[key], "$path[$key]"); | 25 compare(value, actual[key], "$path[$key]"); |
26 }); | 26 }); |
27 } else if (expected is num) { | 27 } else if (expected is num) { |
28 Expect.equals(expected is int, actual is int, "$path: same number type"); | 28 Expect.equals(expected is int, actual is int, "$path: same number type"); |
29 Expect.isTrue(expected.compareTo(actual) == 0, | 29 Expect.isTrue(expected.compareTo(actual) == 0, |
30 "$path: $expected vs. $actual"); | 30 "$path: Expected: $expected, was: $actual"); |
31 } else { | 31 } else { |
32 // String, bool, null. | 32 // String, bool, null. |
33 Expect.equals(expected, actual, path); | 33 Expect.equals(expected, actual, path); |
34 } | 34 } |
35 } | 35 } |
36 for (var reviver in [null, (k, v) => v]) { | 36 for (var reviver in [null, (k, v) => v]) { |
37 var name = (reviver == null) ? "" : "reviver:"; | 37 for (var split in [0, 1, 2, 3]) { |
38 var value = JSON.decode(json, reviver: reviver); | 38 var name = (reviver == null) ? "" : "reviver:"; |
39 compare(expected, value, "$name$value"); | 39 var sink = new ChunkedConversionSink.withCallback((values) { |
40 value = JSON.decode(" $json ", reviver: reviver); | 40 var value = values[0]; |
41 compare(expected, value, "$name-$value-"); | 41 compare(expected, value, "$name$value"); |
42 value = JSON.decode("[$json]", reviver: reviver); | 42 }); |
43 compare([expected], value, "$name[$value]"); | 43 var decoderSink = JSON.decoder.startChunkedConversion(sink); |
44 value = JSON.decode('{"x":$json}', reviver: reviver); | 44 switch (split) { |
45 compare({"x":expected}, value, "$name{x:$value}"); | 45 case 0: |
| 46 // Split after first char. |
| 47 decoderSink.add(json.substring(0, 1)); |
| 48 decoderSink.add(json.substring(1)); |
| 49 decoderSink.close(); |
| 50 break; |
| 51 case 1: |
| 52 // Split before last char. |
| 53 int length = json.length; |
| 54 decoderSink.add(json.substring(0, length - 1)); |
| 55 decoderSink.add(json.substring(length - 1)); |
| 56 decoderSink.close(); |
| 57 break; |
| 58 case 2: |
| 59 // Split in middle. |
| 60 int half = json.length ~/ 2; |
| 61 decoderSink.add(json.substring(0, half)); |
| 62 decoderSink.add(json.substring(half)); |
| 63 decoderSink.close(); |
| 64 break; |
| 65 case 3: |
| 66 // Split in three chunks. |
| 67 int length = json.length; |
| 68 int third = length ~/ 3; |
| 69 decoderSink.add(json.substring(0, third)); |
| 70 decoderSink.add(json.substring(third, 2 * third)); |
| 71 decoderSink.add(json.substring(2 * third)); |
| 72 decoderSink.close(); |
| 73 break; |
| 74 } |
| 75 } |
46 } | 76 } |
47 } | 77 } |
48 | 78 |
49 String escape(String s) { | 79 String escape(String s) { |
50 var sb = new StringBuffer(); | 80 var sb = new StringBuffer(); |
51 for (int i = 0; i < s.length; i++) { | 81 for (int i = 0; i < s.length; i++) { |
52 int code = s.codeUnitAt(i); | 82 int code = s.codeUnitAt(i); |
53 if (code == '\\'.codeUnitAt(0)) sb.write(r'\\'); | 83 if (code == '\\'.codeUnitAt(0)) sb.write(r'\\'); |
54 else if (code == '\"'.codeUnitAt(0)) sb.write(r'\"'); | 84 else if (code == '\"'.codeUnitAt(0)) sb.write(r'\"'); |
55 else if (code >= 32 && code < 127) sb.writeCharCode(code); | 85 else if (code >= 32 && code < 127) sb.writeCharCode(code); |
(...skipping 18 matching lines...) Expand all Loading... |
74 for (var exphead in ["e", "E", "e-", "E-", "e+", "E+"]) { | 104 for (var exphead in ["e", "E", "e-", "E-", "e+", "E+"]) { |
75 for (var expval in ["0", "1", "200"]) { | 105 for (var expval in ["0", "1", "200"]) { |
76 exponentList.add("$exphead$expval"); | 106 exponentList.add("$exphead$expval"); |
77 } | 107 } |
78 } | 108 } |
79 | 109 |
80 for (var integer in integerList) { | 110 for (var integer in integerList) { |
81 for (var sign in signList) { | 111 for (var sign in signList) { |
82 for (var fraction in fractionList) { | 112 for (var fraction in fractionList) { |
83 for (var exp in exponentList) { | 113 for (var exp in exponentList) { |
84 var literal = "$sign$integer$fraction$exp"; | 114 for (var ws in ["", " ", "\t"]) { |
85 var expectedValue = num.parse(literal); | 115 var literal = "$ws$sign$integer$fraction$exp$ws"; |
86 testJson(literal, expectedValue); | 116 var expectedValue = num.parse(literal); |
| 117 testJson(literal, expectedValue); |
| 118 } |
87 } | 119 } |
88 } | 120 } |
89 } | 121 } |
90 } | 122 } |
91 | 123 |
92 // Negative tests (syntax error). | 124 // Negative tests (syntax error). |
93 // testError thoroughly tests the given parts with a lot of valid | 125 // testError thoroughly tests the given parts with a lot of valid |
94 // values for the other parts. | 126 // values for the other parts. |
95 testError({signs, integers, fractions, exponents}) { | 127 testError({signs, integers, fractions, exponents}) { |
96 def(value, defaultValue) { | 128 def(value, defaultValue) { |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
285 } | 317 } |
286 | 318 |
287 main() { | 319 main() { |
288 testNumbers(); | 320 testNumbers(); |
289 testStrings(); | 321 testStrings(); |
290 testWords(); | 322 testWords(); |
291 testObjects(); | 323 testObjects(); |
292 testArrays(); | 324 testArrays(); |
293 testWhitespace(); | 325 testWhitespace(); |
294 } | 326 } |
OLD | NEW |