| 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 |