Reformat tests/lib/collection, /convert, and /developer using 3.8 style.

Change-Id: I550bb08a2c933799cbaa9586c85869bfc56ce1b0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/425328
Auto-Submit: Bob Nystrom <rnystrom@google.com>
Commit-Queue: Lasse Nielsen <lrn@google.com>
Reviewed-by: Lasse Nielsen <lrn@google.com>
This commit is contained in:
Robert Nystrom
2025-05-02 03:57:54 -07:00
committed by Commit Queue
parent f94efba51e
commit bf13a576fd
40 changed files with 1843 additions and 1039 deletions
+25 -3
View File
@@ -225,9 +225,31 @@ abstract class QueueTest {
queue.retainWhere((x) => x != 3);
testLength(23, queue);
Expect.listEquals(
[6, 8, 9, 1, 2, 4, 5, 6, 8, 9, 10, 1, 2, 4, 5, 6, 8, 9, 10, 1, 2, 4, 5],
queue.toList());
Expect.listEquals([
6,
8,
9,
1,
2,
4,
5,
6,
8,
9,
10,
1,
2,
4,
5,
6,
8,
9,
10,
1,
2,
4,
5,
], queue.toList());
// Regression test: http://dartbug.com/16270
// These should all do nothing, and should not throw.
+18 -8
View File
@@ -14,7 +14,9 @@ void originalError() {
map.putIfAbsent(key, () {
wasAbsent = true;
Expect.isFalse(
map.containsKey(key), 'containsKey should be false in putIfAbsent');
map.containsKey(key),
'containsKey should be false in putIfAbsent',
);
return key;
});
Expect.isTrue(wasAbsent);
@@ -39,7 +41,7 @@ class Dumb {
final keys = [
123,
3.14,
10.0, // int or double depending on platform.
10.0, // int or double depending on platform.
'aString',
#someSymbol,
true,
@@ -66,8 +68,10 @@ void testMap(Map<Object?, Object?> map) {
bool wasAbsent = false;
map.putIfAbsent(key, () {
wasAbsent = true;
Expect.isFalse(map.containsKey(key),
'containsKey should be false in putIfAbsent. key = $key');
Expect.isFalse(
map.containsKey(key),
'containsKey should be false in putIfAbsent. key = $key',
);
return key;
});
Expect.isTrue(wasAbsent);
@@ -88,12 +92,18 @@ void main() {
testMap(LinkedHashMap.identity()); // Should be same as `Map.identity()`.
// Custom maps:
testMap(HashMap(
testMap(
HashMap(
equals: (k1, k2) => k2 == k1,
hashCode: (key) => key.hashCode + 1,
isValidKey: (_) => true));
testMap(LinkedHashMap(
isValidKey: (_) => true,
),
);
testMap(
LinkedHashMap(
equals: (k1, k2) => k2 == k1,
hashCode: (key) => key.hashCode + 1,
isValidKey: (_) => true));
isValidKey: (_) => true,
),
);
}
+19 -9
View File
@@ -8,14 +8,14 @@ import 'dart:convert';
var asciiStrings = [
"pure ascii",
"\x00 with control characters \n",
"\x01 edge cases \x7f"
"\x01 edge cases \x7f",
];
var nonAsciiStrings = [
"\x80 edge case first",
"Edge case ASCII \u{80}",
"Edge case byte \u{ff}",
"Edge case super-BMP \u{10000}"
"Edge case super-BMP \u{10000}",
];
void main() {
@@ -50,9 +50,13 @@ void testDirectConversions() {
}
for (var nonAsciiString in nonAsciiStrings) {
Expect.throws(() {
print(codec.encoder.convert(nonAsciiString));
}, (_) => true, nonAsciiString);
Expect.throws(
() {
print(codec.encoder.convert(nonAsciiString));
},
(_) => true,
nonAsciiString,
);
}
var encode = codec.encoder.convert;
@@ -113,7 +117,10 @@ void testDirectConversions() {
}
List<int> encode(
String str, int chunkSize, Converter<String, List<int>> converter) {
String str,
int chunkSize,
Converter<String, List<int>> converter,
) {
List<int> bytes = <int>[];
var byteSink = new ByteConversionSink.withCallback(bytes.addAll);
var stringConversionSink = converter.startChunkedConversion(byteSink);
@@ -129,7 +136,10 @@ List<int> encode(
}
String decode(
List<int> bytes, int chunkSize, Converter<List<int>, String> converter) {
List<int> bytes,
int chunkSize,
Converter<List<int>, String> converter,
) {
StringBuffer buf = new StringBuffer();
var stringSink = new StringConversionSink.fromStringSink(buf);
var byteConversionSink = converter.startChunkedConversion(stringSink);
@@ -149,7 +159,7 @@ void testChunkedConversions() {
for (var converter in [
ascii.encoder,
new AsciiCodec().encoder,
new AsciiEncoder()
new AsciiEncoder(),
]) {
for (int chunkSize in [1, 2, 5, 50]) {
for (var asciiString in asciiStrings) {
@@ -168,7 +178,7 @@ void testChunkedConversions() {
for (var converter in [
ascii.decoder,
new AsciiCodec().decoder,
new AsciiDecoder()
new AsciiDecoder(),
]) {
for (int chunkSize in [1, 2, 5, 50]) {
for (var asciiString in asciiStrings) {
@@ -127,8 +127,11 @@ main() {
// Test int->bool converter individually.
Converter<int, bool> int2boolConverter = new IntBoolConverter1();
Expect.listEquals(
[true, false, true], [2, -2, 2].map(int2boolConverter.convert).toList());
Expect.listEquals([
true,
false,
true,
], [2, -2, 2].map(int2boolConverter.convert).toList());
var hasExecuted = false;
boolSink = new MyChunkedBoolSink.withCallback((value) {
hasExecuted = true;
@@ -146,8 +149,11 @@ main() {
// Test bool->int converter individually.
Converter<bool, int> bool2intConverter = new BoolIntConverter1();
Expect.listEquals(
[1, 0, 1], [true, false, true].map(bool2intConverter.convert).toList());
Expect.listEquals([
1,
0,
1,
], [true, false, true].map(bool2intConverter.convert).toList());
hasExecuted = false;
intSink = new MyChunkedIntSink.withCallback((value) {
hasExecuted = true;
@@ -237,8 +243,9 @@ main() {
hasExecuted = false;
// With identity between the two converters.
fused =
int2boolConverter.fuse(new IdentityConverter()).fuse(bool2intConverter);
fused = int2boolConverter
.fuse(new IdentityConverter())
.fuse(bool2intConverter);
Expect.listEquals([1, 0, 1], [2, -2, 2].map(fused.convert).toList());
hasExecuted = false;
intSink2 = new MyChunkedIntSink.withCallback((value) {
@@ -17,42 +17,42 @@ final TESTS = [
[[], "[]"],
[
[3, -4.5, true, "hi", false],
'[3,-4.5,true,"hi",false]'
'[3,-4.5,true,"hi",false]',
],
[
[null],
"[null]"
"[null]",
],
[
[
[null]
[null],
],
"[[null]]"
"[[null]]",
],
[
[
[3]
[3],
],
"[[3]]"
"[[3]]",
],
[{}, "{}"],
[
{"x": 3, "y": 4.5, "z": "hi", "u": true, "v": false},
'{"x":3,"y":4.5,"z":"hi","u":true,"v":false}'
'{"x":3,"y":4.5,"z":"hi","u":true,"v":false}',
],
[
{"x": null},
'{"x":null}'
'{"x":null}',
],
[
{"x": {}},
'{"x":{}}'
'{"x":{}}',
],
// Note that -0.0 won't be treated the same in JS. The Json spec seems to
// allow it, though.
[
{"hi there": 499, "'": -0.0},
'{"hi there":499,"\'":-0.0}'
'{"hi there":499,"\'":-0.0}',
],
[r'\foo', r'"\\foo"'],
];
@@ -81,8 +81,9 @@ bool isJsonEqual(o1, o2) {
Object? decode(String str) {
Object? result;
var decoder = new JsonDecoder(null);
ChunkedConversionSink objectSink =
new ChunkedConversionSink.withCallback((x) => result = x.single);
ChunkedConversionSink objectSink = new ChunkedConversionSink.withCallback(
(x) => result = x.single,
);
var stringConversionSink = decoder.startChunkedConversion(objectSink);
stringConversionSink.add(str);
stringConversionSink.close();
@@ -92,8 +93,9 @@ Object? decode(String str) {
Object? decode2(String str) {
Object? result;
var decoder = new JsonDecoder(null);
ChunkedConversionSink objectSink =
new ChunkedConversionSink.withCallback((x) => result = x.single);
ChunkedConversionSink objectSink = new ChunkedConversionSink.withCallback(
(x) => result = x.single,
);
var stringConversionSink = decoder.startChunkedConversion(objectSink);
ClosableStringSink stringSink = stringConversionSink.asStringSink();
stringSink.write(str);
@@ -104,8 +106,9 @@ Object? decode2(String str) {
Object? decode3(String str) {
Object? result;
var decoder = new JsonDecoder(null);
ChunkedConversionSink objectSink =
new ChunkedConversionSink.withCallback((x) => result = x.single);
ChunkedConversionSink objectSink = new ChunkedConversionSink.withCallback(
(x) => result = x.single,
);
var stringConversionSink = decoder.startChunkedConversion(objectSink);
ClosableStringSink stringSink = stringConversionSink.asStringSink();
str.codeUnits.forEach(stringSink.writeCharCode);
@@ -116,8 +119,9 @@ Object? decode3(String str) {
Object? decode4(String str) {
Object? result;
var decoder = new JsonDecoder(null);
ChunkedConversionSink objectSink =
new ChunkedConversionSink.withCallback((x) => result = x.single);
ChunkedConversionSink objectSink = new ChunkedConversionSink.withCallback(
(x) => result = x.single,
);
var stringConversionSink = decoder.startChunkedConversion(objectSink);
ClosableStringSink stringSink = stringConversionSink.asStringSink();
str.runes.forEach(stringSink.writeCharCode);
@@ -128,8 +132,9 @@ Object? decode4(String str) {
Object? decode5(String str) {
Object? result;
var decoder = new JsonDecoder(null);
ChunkedConversionSink objectSink =
new ChunkedConversionSink.withCallback((x) => result = x.single);
ChunkedConversionSink objectSink = new ChunkedConversionSink.withCallback(
(x) => result = x.single,
);
var stringConversionSink = decoder.startChunkedConversion(objectSink);
ByteConversionSink inputByteSink = stringConversionSink.asUtf8Sink(false);
var tmpBytes = utf8.encode(str);
@@ -141,8 +146,9 @@ Object? decode5(String str) {
Object? decode6(String str) {
Object? result;
var decoder = new JsonDecoder(null);
ChunkedConversionSink objectSink =
new ChunkedConversionSink.withCallback((x) => result = x.single);
ChunkedConversionSink objectSink = new ChunkedConversionSink.withCallback(
(x) => result = x.single,
);
var stringConversionSink = decoder.startChunkedConversion(objectSink);
ByteConversionSink inputByteSink = stringConversionSink.asUtf8Sink(false);
var tmpBytes = utf8.encode(str);
@@ -154,8 +160,9 @@ Object? decode6(String str) {
Object? decode7(String str) {
Object? result;
var decoder = new JsonDecoder(null);
ChunkedConversionSink objectSink =
new ChunkedConversionSink.withCallback((x) => result = x.single);
ChunkedConversionSink objectSink = new ChunkedConversionSink.withCallback(
(x) => result = x.single,
);
var stringConversionSink = decoder.startChunkedConversion(objectSink);
stringConversionSink.addSlice("1" + str + "2", 1, str.length + 1, false);
stringConversionSink.close();
@@ -166,14 +173,15 @@ main() {
var tests = TESTS.expand((test) {
var object = test[0];
var string = test[1];
var longString = " "
var longString =
" "
" "
"$string"
" "
" ";
return [
test,
[object, longString]
[object, longString],
];
});
for (var test in tests) {
@@ -17,42 +17,42 @@ final TESTS = [
[[], "[]"],
[
[3, -4.5, true, "hi", false],
'[3,-4.5,true,"hi",false]'
'[3,-4.5,true,"hi",false]',
],
[
[null],
"[null]"
"[null]",
],
[
[
[null]
[null],
],
"[[null]]"
"[[null]]",
],
[
[
[3]
[3],
],
"[[3]]"
"[[3]]",
],
[{}, "{}"],
[
{"x": 3, "y": 4.5, "z": "hi", "u": true, "v": false},
'{"x":3,"y":4.5,"z":"hi","u":true,"v":false}'
'{"x":3,"y":4.5,"z":"hi","u":true,"v":false}',
],
[
{"x": null},
'{"x":null}'
'{"x":null}',
],
[
{"x": {}},
'{"x":{}}'
'{"x":{}}',
],
// Note that -0.0 won't be treated the same in JS. The Json spec seems to
// allow it, though.
[
{"hi there": 499, "'": -0.0},
'{"hi there":499,"\'":-0.0}'
'{"hi there":499,"\'":-0.0}',
],
[r'\foo', r'"\\foo"'],
];
@@ -75,8 +75,9 @@ class MyStringConversionSink extends StringConversionSink {
String encode(Object? o) {
var result;
ChunkedConversionSink<String> stringSink =
new MyStringConversionSink((x) => result = x);
ChunkedConversionSink<String> stringSink = new MyStringConversionSink(
(x) => result = x,
);
var objectSink = new JsonEncoder().startChunkedConversion(stringSink);
objectSink.add(o);
objectSink.close();
@@ -50,7 +50,7 @@ final TESTS0 = [
// Unfinished UTF-8 sequences.
[0xc3],
[0xE2, 0x82],
[0xF0, 0xA4, 0xAD]
[0xF0, 0xA4, 0xAD],
];
final TESTS1 = [
@@ -73,153 +73,153 @@ final TESTS1 = [
[0xC0, 0x80],
[0xC1, 0x80],
// Outside valid range.
[0xF4, 0xBF, 0xBF, 0xBF]
[0xF4, 0xBF, 0xBF, 0xBF],
];
final TESTS2 = [
// Test that 0xC0|1, 0x80 does not eat the next character.
[
[0xC0, 0x80, 0x61],
"XXa"
"XXa",
],
[
[0xC1, 0x80, 0x61],
"XXa"
"XXa",
],
// 0xF5 .. 0xFF never appear in valid UTF-8 sequences.
[
[0xF5, 0x80],
"XX"
"XX",
],
[
[0xF6, 0x80],
"XX"
"XX",
],
[
[0xF7, 0x80],
"XX"
"XX",
],
[
[0xF8, 0x80],
"XX"
"XX",
],
[
[0xF9, 0x80],
"XX"
"XX",
],
[
[0xFA, 0x80],
"XX"
"XX",
],
[
[0xFB, 0x80],
"XX"
"XX",
],
[
[0xFC, 0x80],
"XX"
"XX",
],
[
[0xFD, 0x80],
"XX"
"XX",
],
[
[0xFE, 0x80],
"XX"
"XX",
],
[
[0xFF, 0x80],
"XX"
"XX",
],
[
[0xF5, 0x80, 0x61],
"XXa"
"XXa",
],
[
[0xF6, 0x80, 0x61],
"XXa"
"XXa",
],
[
[0xF7, 0x80, 0x61],
"XXa"
"XXa",
],
[
[0xF8, 0x80, 0x61],
"XXa"
"XXa",
],
[
[0xF9, 0x80, 0x61],
"XXa"
"XXa",
],
[
[0xFA, 0x80, 0x61],
"XXa"
"XXa",
],
[
[0xFB, 0x80, 0x61],
"XXa"
"XXa",
],
[
[0xFC, 0x80, 0x61],
"XXa"
"XXa",
],
[
[0xFD, 0x80, 0x61],
"XXa"
"XXa",
],
[
[0xFE, 0x80, 0x61],
"XXa"
"XXa",
],
[
[0xFF, 0x80, 0x61],
"XXa"
"XXa",
],
// Characters outside the valid range.
[
[0xF5, 0x80, 0x80, 0x61],
"XXXa"
"XXXa",
],
[
[0xF6, 0x80, 0x80, 0x61],
"XXXa"
"XXXa",
],
[
[0xF7, 0x80, 0x80, 0x61],
"XXXa"
"XXXa",
],
[
[0xF8, 0x80, 0x80, 0x61],
"XXXa"
"XXXa",
],
[
[0xF9, 0x80, 0x80, 0x61],
"XXXa"
"XXXa",
],
[
[0xFA, 0x80, 0x80, 0x61],
"XXXa"
"XXXa",
],
[
[0xFB, 0x80, 0x80, 0x61],
"XXXa"
"XXXa",
],
[
[0xFC, 0x80, 0x80, 0x61],
"XXXa"
"XXXa",
],
[
[0xFD, 0x80, 0x80, 0x61],
"XXXa"
"XXXa",
],
[
[0xFE, 0x80, 0x80, 0x61],
"XXXa"
"XXXa",
],
[
[0xFF, 0x80, 0x80, 0x61],
"XXXa"
]
"XXXa",
],
];
main() {
@@ -227,46 +227,47 @@ main() {
// Pairs of test and expected string output when malformed strings are
// allowed. Replacement character: U+FFFD, one per unfinished sequence or
// undecodable byte.
String replacement =
TESTS0.contains(test) ? "\u{FFFD}" : "\u{FFFD}" * test.length;
String replacement = TESTS0.contains(test)
? "\u{FFFD}"
: "\u{FFFD}" * test.length;
return [
[test, "${replacement}"],
[
[0x61, ...test],
"a${replacement}"
"a${replacement}",
],
[
[0x61, ...test, 0x61],
"a${replacement}a"
"a${replacement}a",
],
[
[...test, 0x61],
"${replacement}a"
"${replacement}a",
],
[
[...test, ...test],
"${replacement}${replacement}"
"${replacement}${replacement}",
],
[
[...test, 0x61, ...test],
"${replacement}a${replacement}"
"${replacement}a${replacement}",
],
[
[0xc3, 0xa5, ...test],
"å${replacement}"
"å${replacement}",
],
[
[0xc3, 0xa5, ...test, 0xc3, 0xa5],
"å${replacement}å"
"å${replacement}å",
],
[
[...test, 0xc3, 0xa5],
"${replacement}å"
"${replacement}å",
],
[
[...test, 0xc3, 0xa5, ...test],
"${replacement}å${replacement}"
]
"${replacement}å${replacement}",
],
];
});
@@ -277,7 +278,10 @@ main() {
return [test[0], expected];
});
for (var test in []..addAll(allTests)..addAll(allTests2)) {
for (var test
in []
..addAll(allTests)
..addAll(allTests2)) {
List<int> bytes = test[0];
Expect.throwsFormatException(() => decode(bytes, 1));
Expect.throwsFormatException(() => decode(bytes, 2));
@@ -9,8 +9,9 @@ import 'unicode_tests.dart';
String decode(List<int> bytes, int chunkSize) {
// Use a non-chunked interface.
late String result;
var chunkedSink =
new StringConversionSink.withCallback((decoded) => result = decoded);
var chunkedSink = new StringConversionSink.withCallback(
(decoded) => result = decoded,
);
var byteSink = new Utf8Decoder().startChunkedConversion(chunkedSink);
int i = 0;
while (i < bytes.length) {
@@ -8,8 +8,9 @@ import 'unicode_tests.dart';
List<int> encode(String str) {
late List<int> bytes;
var byteSink =
new ByteConversionSink.withCallback((result) => bytes = result);
var byteSink = new ByteConversionSink.withCallback(
(result) => bytes = result,
);
var stringConversionSink = new Utf8Encoder().startChunkedConversion(byteSink);
stringConversionSink.add(str);
stringConversionSink.close();
@@ -18,8 +19,9 @@ List<int> encode(String str) {
List<int> encode2(String str) {
late List<int> bytes;
var byteSink =
new ByteConversionSink.withCallback((result) => bytes = result);
var byteSink = new ByteConversionSink.withCallback(
(result) => bytes = result,
);
var stringConversionSink = new Utf8Encoder().startChunkedConversion(byteSink);
ClosableStringSink stringSink = stringConversionSink.asStringSink();
stringSink.write(str);
@@ -29,8 +31,9 @@ List<int> encode2(String str) {
List<int> encode3(String str) {
late List<int> bytes;
var byteSink =
new ByteConversionSink.withCallback((result) => bytes = result);
var byteSink = new ByteConversionSink.withCallback(
(result) => bytes = result,
);
var stringConversionSink = new Utf8Encoder().startChunkedConversion(byteSink);
ClosableStringSink stringSink = stringConversionSink.asStringSink();
str.codeUnits.forEach(stringSink.writeCharCode);
@@ -40,8 +43,9 @@ List<int> encode3(String str) {
List<int> encode4(String str) {
late List<int> bytes;
var byteSink =
new ByteConversionSink.withCallback((result) => bytes = result);
var byteSink = new ByteConversionSink.withCallback(
(result) => bytes = result,
);
var stringConversionSink = new Utf8Encoder().startChunkedConversion(byteSink);
ClosableStringSink stringSink = stringConversionSink.asStringSink();
str.runes.forEach(stringSink.writeCharCode);
@@ -51,8 +55,9 @@ List<int> encode4(String str) {
List<int> encode5(String str) {
late List<int> bytes;
var byteSink =
new ByteConversionSink.withCallback((result) => bytes = result);
var byteSink = new ByteConversionSink.withCallback(
(result) => bytes = result,
);
var stringConversionSink = new Utf8Encoder().startChunkedConversion(byteSink);
ByteConversionSink inputByteSink = stringConversionSink.asUtf8Sink(false);
List<int> tmpBytes = utf8.encode(str);
@@ -63,8 +68,9 @@ List<int> encode5(String str) {
List<int> encode6(String str) {
late List<int> bytes;
var byteSink =
new ByteConversionSink.withCallback((result) => bytes = result);
var byteSink = new ByteConversionSink.withCallback(
(result) => bytes = result,
);
var stringConversionSink = new Utf8Encoder().startChunkedConversion(byteSink);
ByteConversionSink inputByteSink = stringConversionSink.asUtf8Sink(false);
List<int> tmpBytes = utf8.encode(str);
@@ -75,8 +81,9 @@ List<int> encode6(String str) {
List<int> encode7(String str) {
late List<int> bytes;
var byteSink =
new ByteConversionSink.withCallback((result) => bytes = result);
var byteSink = new ByteConversionSink.withCallback(
(result) => bytes = result,
);
var stringConversionSink = new Utf8Encoder().startChunkedConversion(byteSink);
stringConversionSink.addSlice("1" + str + "2", 1, str.length + 1, false);
stringConversionSink.close();
@@ -32,7 +32,7 @@ final TESTS0 = [
// Unfinished UTF-8 sequences.
[0xc3],
[0xE2, 0x82],
[0xF0, 0xA4, 0xAD]
[0xF0, 0xA4, 0xAD],
];
final TESTS1 = [
@@ -55,153 +55,153 @@ final TESTS1 = [
[0xC0, 0x80],
[0xC1, 0x80],
// Outside valid range.
[0xF4, 0xBF, 0xBF, 0xBF]
[0xF4, 0xBF, 0xBF, 0xBF],
];
final TESTS2 = [
// Test that 0xC0|1, 0x80 does not eat the next character.
[
[0xC0, 0x80, 0x61],
"XXa"
"XXa",
],
[
[0xC1, 0x80, 0x61],
"XXa"
"XXa",
],
// 0xF5 .. 0xFF never appear in valid UTF-8 sequences.
[
[0xF5, 0x80],
"XX"
"XX",
],
[
[0xF6, 0x80],
"XX"
"XX",
],
[
[0xF7, 0x80],
"XX"
"XX",
],
[
[0xF8, 0x80],
"XX"
"XX",
],
[
[0xF9, 0x80],
"XX"
"XX",
],
[
[0xFA, 0x80],
"XX"
"XX",
],
[
[0xFB, 0x80],
"XX"
"XX",
],
[
[0xFC, 0x80],
"XX"
"XX",
],
[
[0xFD, 0x80],
"XX"
"XX",
],
[
[0xFE, 0x80],
"XX"
"XX",
],
[
[0xFF, 0x80],
"XX"
"XX",
],
[
[0xF5, 0x80, 0x61],
"XXa"
"XXa",
],
[
[0xF6, 0x80, 0x61],
"XXa"
"XXa",
],
[
[0xF7, 0x80, 0x61],
"XXa"
"XXa",
],
[
[0xF8, 0x80, 0x61],
"XXa"
"XXa",
],
[
[0xF9, 0x80, 0x61],
"XXa"
"XXa",
],
[
[0xFA, 0x80, 0x61],
"XXa"
"XXa",
],
[
[0xFB, 0x80, 0x61],
"XXa"
"XXa",
],
[
[0xFC, 0x80, 0x61],
"XXa"
"XXa",
],
[
[0xFD, 0x80, 0x61],
"XXa"
"XXa",
],
[
[0xFE, 0x80, 0x61],
"XXa"
"XXa",
],
[
[0xFF, 0x80, 0x61],
"XXa"
"XXa",
],
// Characters outside the valid range.
[
[0xF5, 0x80, 0x80, 0x61],
"XXXa"
"XXXa",
],
[
[0xF6, 0x80, 0x80, 0x61],
"XXXa"
"XXXa",
],
[
[0xF7, 0x80, 0x80, 0x61],
"XXXa"
"XXXa",
],
[
[0xF8, 0x80, 0x80, 0x61],
"XXXa"
"XXXa",
],
[
[0xF9, 0x80, 0x80, 0x61],
"XXXa"
"XXXa",
],
[
[0xFA, 0x80, 0x80, 0x61],
"XXXa"
"XXXa",
],
[
[0xFB, 0x80, 0x80, 0x61],
"XXXa"
"XXXa",
],
[
[0xFC, 0x80, 0x80, 0x61],
"XXXa"
"XXXa",
],
[
[0xFD, 0x80, 0x80, 0x61],
"XXXa"
"XXXa",
],
[
[0xFE, 0x80, 0x80, 0x61],
"XXXa"
"XXXa",
],
[
[0xFF, 0x80, 0x80, 0x61],
"XXXa"
]
"XXXa",
],
];
main() {
@@ -209,46 +209,47 @@ main() {
// Pairs of test and expected string output when malformed strings are
// allowed. Replacement character: U+FFFD, one per unfinished sequence or
// undecodable byte.
String replacement =
TESTS0.contains(test) ? "\u{FFFD}" : "\u{FFFD}" * test.length;
String replacement = TESTS0.contains(test)
? "\u{FFFD}"
: "\u{FFFD}" * test.length;
return [
[test, "${replacement}"],
[
[0x61, ...test],
"a${replacement}"
"a${replacement}",
],
[
[0x61, ...test, 0x61],
"a${replacement}a"
"a${replacement}a",
],
[
[...test, 0x61],
"${replacement}a"
"${replacement}a",
],
[
[...test, ...test],
"${replacement}${replacement}"
"${replacement}${replacement}",
],
[
[...test, 0x61, ...test],
"${replacement}a${replacement}"
"${replacement}a${replacement}",
],
[
[0xc3, 0xa5, ...test],
"å${replacement}"
"å${replacement}",
],
[
[0xc3, 0xa5, ...test, 0xc3, 0xa5],
"å${replacement}å"
"å${replacement}å",
],
[
[...test, 0xc3, 0xa5],
"${replacement}å"
"${replacement}å",
],
[
[...test, 0xc3, 0xa5, ...test],
"${replacement}å${replacement}"
]
"${replacement}å${replacement}",
],
];
});
@@ -259,7 +260,10 @@ main() {
return [test[0], expected];
});
for (var test in []..addAll(allTests)..addAll(allTests2)) {
for (var test
in []
..addAll(allTests)
..addAll(allTests2)) {
List<int> bytes = test[0];
Expect.throwsFormatException(() => decode(bytes));
@@ -7,8 +7,9 @@ import 'dart:convert';
String decode(List<int> inputBytes) {
late List<int> bytes;
var byteSink =
new ByteConversionSink.withCallback((result) => bytes = result);
var byteSink = new ByteConversionSink.withCallback(
(result) => bytes = result,
);
var stringConversionSink = new Utf8Encoder().startChunkedConversion(byteSink);
ByteConversionSink inputByteSink = stringConversionSink.asUtf8Sink(false);
inputByteSink.add(inputBytes);
@@ -18,8 +19,9 @@ String decode(List<int> inputBytes) {
String decode2(List<int> inputBytes) {
late List<int> bytes;
var byteSink =
new ByteConversionSink.withCallback((result) => bytes = result);
var byteSink = new ByteConversionSink.withCallback(
(result) => bytes = result,
);
var stringConversionSink = new Utf8Encoder().startChunkedConversion(byteSink);
ByteConversionSink inputByteSink = stringConversionSink.asUtf8Sink(false);
inputBytes.forEach((b) => inputByteSink.addSlice([0, b, 1], 1, 2, false));
@@ -29,8 +31,9 @@ String decode2(List<int> inputBytes) {
String decodeAllowMalformed(List<int> inputBytes) {
late List<int> bytes;
var byteSink =
new ByteConversionSink.withCallback((result) => bytes = result);
var byteSink = new ByteConversionSink.withCallback(
(result) => bytes = result,
);
var stringConversionSink = new Utf8Encoder().startChunkedConversion(byteSink);
ByteConversionSink inputByteSink = stringConversionSink.asUtf8Sink(true);
inputByteSink.add(inputBytes);
@@ -40,8 +43,9 @@ String decodeAllowMalformed(List<int> inputBytes) {
String decodeAllowMalformed2(List<int> inputBytes) {
late List<int> bytes;
var byteSink =
new ByteConversionSink.withCallback((result) => bytes = result);
var byteSink = new ByteConversionSink.withCallback(
(result) => bytes = result,
);
var stringConversionSink = new Utf8Encoder().startChunkedConversion(byteSink);
ByteConversionSink inputByteSink = stringConversionSink.asUtf8Sink(true);
inputBytes.forEach((b) => inputByteSink.addSlice([0, b, 1], 1, 2, false));
@@ -53,7 +57,7 @@ final TESTS0 = [
// Unfinished UTF-8 sequences.
[0xc3],
[0xE2, 0x82],
[0xF0, 0xA4, 0xAD]
[0xF0, 0xA4, 0xAD],
];
final TESTS1 = [
@@ -76,153 +80,153 @@ final TESTS1 = [
[0xC0, 0x80],
[0xC1, 0x80],
// Outside valid range.
[0xF4, 0xBF, 0xBF, 0xBF]
[0xF4, 0xBF, 0xBF, 0xBF],
];
final TESTS2 = [
// Test that 0xC0|1, 0x80 does not eat the next character.
[
[0xC0, 0x80, 0x61],
"XXa"
"XXa",
],
[
[0xC1, 0x80, 0x61],
"XXa"
"XXa",
],
// 0xF5 .. 0xFF never appear in valid UTF-8 sequences.
[
[0xF5, 0x80],
"XX"
"XX",
],
[
[0xF6, 0x80],
"XX"
"XX",
],
[
[0xF7, 0x80],
"XX"
"XX",
],
[
[0xF8, 0x80],
"XX"
"XX",
],
[
[0xF9, 0x80],
"XX"
"XX",
],
[
[0xFA, 0x80],
"XX"
"XX",
],
[
[0xFB, 0x80],
"XX"
"XX",
],
[
[0xFC, 0x80],
"XX"
"XX",
],
[
[0xFD, 0x80],
"XX"
"XX",
],
[
[0xFE, 0x80],
"XX"
"XX",
],
[
[0xFF, 0x80],
"XX"
"XX",
],
[
[0xF5, 0x80, 0x61],
"XXa"
"XXa",
],
[
[0xF6, 0x80, 0x61],
"XXa"
"XXa",
],
[
[0xF7, 0x80, 0x61],
"XXa"
"XXa",
],
[
[0xF8, 0x80, 0x61],
"XXa"
"XXa",
],
[
[0xF9, 0x80, 0x61],
"XXa"
"XXa",
],
[
[0xFA, 0x80, 0x61],
"XXa"
"XXa",
],
[
[0xFB, 0x80, 0x61],
"XXa"
"XXa",
],
[
[0xFC, 0x80, 0x61],
"XXa"
"XXa",
],
[
[0xFD, 0x80, 0x61],
"XXa"
"XXa",
],
[
[0xFE, 0x80, 0x61],
"XXa"
"XXa",
],
[
[0xFF, 0x80, 0x61],
"XXa"
"XXa",
],
// Characters outside the valid range.
[
[0xF5, 0x80, 0x80, 0x61],
"XXXa"
"XXXa",
],
[
[0xF6, 0x80, 0x80, 0x61],
"XXXa"
"XXXa",
],
[
[0xF7, 0x80, 0x80, 0x61],
"XXXa"
"XXXa",
],
[
[0xF8, 0x80, 0x80, 0x61],
"XXXa"
"XXXa",
],
[
[0xF9, 0x80, 0x80, 0x61],
"XXXa"
"XXXa",
],
[
[0xFA, 0x80, 0x80, 0x61],
"XXXa"
"XXXa",
],
[
[0xFB, 0x80, 0x80, 0x61],
"XXXa"
"XXXa",
],
[
[0xFC, 0x80, 0x80, 0x61],
"XXXa"
"XXXa",
],
[
[0xFD, 0x80, 0x80, 0x61],
"XXXa"
"XXXa",
],
[
[0xFE, 0x80, 0x80, 0x61],
"XXXa"
"XXXa",
],
[
[0xFF, 0x80, 0x80, 0x61],
"XXXa"
]
"XXXa",
],
];
main() {
@@ -230,46 +234,47 @@ main() {
// Pairs of test and expected string output when malformed strings are
// allowed. Replacement character: U+FFFD, one per unfinished sequence or
// undecodable byte.
String replacement =
TESTS0.contains(test) ? "\u{FFFD}" : "\u{FFFD}" * test.length;
String replacement = TESTS0.contains(test)
? "\u{FFFD}"
: "\u{FFFD}" * test.length;
return [
[test, "${replacement}"],
[
[0x61, ...test],
"a${replacement}"
"a${replacement}",
],
[
[0x61, ...test, 0x61],
"a${replacement}a"
"a${replacement}a",
],
[
[...test, 0x61],
"${replacement}a"
"${replacement}a",
],
[
[...test, ...test],
"${replacement}${replacement}"
"${replacement}${replacement}",
],
[
[...test, 0x61, ...test],
"${replacement}a${replacement}"
"${replacement}a${replacement}",
],
[
[0xc3, 0xa5, ...test],
"å${replacement}"
"å${replacement}",
],
[
[0xc3, 0xa5, ...test, 0xc3, 0xa5],
"å${replacement}å"
"å${replacement}å",
],
[
[...test, 0xc3, 0xa5],
"${replacement}å"
"${replacement}å",
],
[
[...test, 0xc3, 0xa5, ...test],
"${replacement}å${replacement}"
]
"${replacement}å${replacement}",
],
];
});
@@ -280,7 +285,10 @@ main() {
return [test[0], expected];
});
for (var test in []..addAll(allTests)..addAll(allTests2)) {
for (var test
in []
..addAll(allTests)
..addAll(allTests2)) {
List<int> bytes = test[0];
Expect.throwsFormatException(() => decode(bytes));
Expect.throwsFormatException(() => decode2(bytes));
@@ -9,8 +9,9 @@ import 'dart:convert';
List<int> encode(String str) {
late List<int> bytes;
var byteSink =
new ByteConversionSink.withCallback((result) => bytes = result);
var byteSink = new ByteConversionSink.withCallback(
(result) => bytes = result,
);
var stringConversionSink = new Utf8Encoder().startChunkedConversion(byteSink);
stringConversionSink.add(str);
stringConversionSink.close();
@@ -19,8 +20,9 @@ List<int> encode(String str) {
List<int> encode2(String str) {
late List<int> bytes;
var byteSink =
new ByteConversionSink.withCallback((result) => bytes = result);
var byteSink = new ByteConversionSink.withCallback(
(result) => bytes = result,
);
var stringConversionSink = new Utf8Encoder().startChunkedConversion(byteSink);
ClosableStringSink stringSink = stringConversionSink.asStringSink();
stringSink.write(str);
@@ -30,8 +32,9 @@ List<int> encode2(String str) {
List<int> encode3(String str) {
late List<int> bytes;
var byteSink =
new ByteConversionSink.withCallback((result) => bytes = result);
var byteSink = new ByteConversionSink.withCallback(
(result) => bytes = result,
);
var stringConversionSink = new Utf8Encoder().startChunkedConversion(byteSink);
ClosableStringSink stringSink = stringConversionSink.asStringSink();
str.codeUnits.forEach(stringSink.writeCharCode);
@@ -41,8 +44,9 @@ List<int> encode3(String str) {
List<int> encode4(String str) {
late List<int> bytes;
var byteSink =
new ByteConversionSink.withCallback((result) => bytes = result);
var byteSink = new ByteConversionSink.withCallback(
(result) => bytes = result,
);
var stringConversionSink = new Utf8Encoder().startChunkedConversion(byteSink);
ClosableStringSink stringSink = stringConversionSink.asStringSink();
str.runes.forEach(stringSink.writeCharCode);
@@ -52,8 +56,9 @@ List<int> encode4(String str) {
List<int> encode5(String str) {
late List<int> bytes;
var byteSink =
new ByteConversionSink.withCallback((result) => bytes = result);
var byteSink = new ByteConversionSink.withCallback(
(result) => bytes = result,
);
var stringConversionSink = new Utf8Encoder().startChunkedConversion(byteSink);
ByteConversionSink inputByteSink = stringConversionSink.asUtf8Sink(false);
List<int> tmpBytes = utf8.encode(str);
@@ -64,8 +69,9 @@ List<int> encode5(String str) {
List<int> encode6(String str) {
late List<int> bytes;
var byteSink =
new ByteConversionSink.withCallback((result) => bytes = result);
var byteSink = new ByteConversionSink.withCallback(
(result) => bytes = result,
);
var stringConversionSink = new Utf8Encoder().startChunkedConversion(byteSink);
ByteConversionSink inputByteSink = stringConversionSink.asUtf8Sink(false);
List<int> tmpBytes = utf8.encode(str);
@@ -76,8 +82,9 @@ List<int> encode6(String str) {
List<int> encode7(String str) {
late List<int> bytes;
var byteSink =
new ByteConversionSink.withCallback((result) => bytes = result);
var byteSink = new ByteConversionSink.withCallback(
(result) => bytes = result,
);
var stringConversionSink = new Utf8Encoder().startChunkedConversion(byteSink);
stringConversionSink.addSlice("1" + str + "2", 1, str.length + 1, false);
stringConversionSink.close();
+8 -5
View File
@@ -27,7 +27,7 @@ main() {
50,
51,
49,
93
93,
];
Expect.listEquals(ENCODED, utf8.encode(RAW));
Expect.equals(RAW, utf8.decode(ENCODED));
@@ -40,10 +40,13 @@ main() {
Expect.listEquals(["122ç", 50, 50, 231], json.decode(JSON_ENCODED));
// Test that the reviver is passed to the decoder.
var decoded = json.decode('{"p": 5}', reviver: (dynamic k, dynamic v) {
if (k == null) return v;
return v * 2;
});
var decoded = json.decode(
'{"p": 5}',
reviver: (dynamic k, dynamic v) {
if (k == null) return v;
return v * 2;
},
);
Expect.equals(10, decoded["p"]);
var jsonWithReviver = new JsonCodec.withReviver((dynamic k, dynamic v) {
if (k == null) return v;
+20 -7
View File
@@ -10,7 +10,8 @@ const _NOOP = 'Nothing_to_escape';
const _TEST_INPUT = """<A </test> of \xA0 "double" & 'single' values>""";
const _OUTPUT_UNKNOWN = '&lt;A &lt;&#47;test&gt; of \xA0 &quot;double&quot; '
const _OUTPUT_UNKNOWN =
'&lt;A &lt;&#47;test&gt; of \xA0 &quot;double&quot; '
'&amp; &#39;single&#39; values&gt;';
const _OUTPUT_ATTRIBUTE =
@@ -78,12 +79,24 @@ void main() {
_testMode(htmlEscape, _TEST_INPUT, _OUTPUT_UNKNOWN);
_testMode(const HtmlEscape(), _TEST_INPUT, _OUTPUT_UNKNOWN);
_testMode(
const HtmlEscape(HtmlEscapeMode.unknown), _TEST_INPUT, _OUTPUT_UNKNOWN);
_testMode(const HtmlEscape(HtmlEscapeMode.attribute), _TEST_INPUT,
_OUTPUT_ATTRIBUTE);
_testMode(const HtmlEscape(HtmlEscapeMode.sqAttribute), _TEST_INPUT,
_OUTPUT_SQ_ATTRIBUTE);
const HtmlEscape(HtmlEscapeMode.unknown),
_TEST_INPUT,
_OUTPUT_UNKNOWN,
);
_testMode(
const HtmlEscape(HtmlEscapeMode.element), _TEST_INPUT, _OUTPUT_ELEMENT);
const HtmlEscape(HtmlEscapeMode.attribute),
_TEST_INPUT,
_OUTPUT_ATTRIBUTE,
);
_testMode(
const HtmlEscape(HtmlEscapeMode.sqAttribute),
_TEST_INPUT,
_OUTPUT_SQ_ATTRIBUTE,
);
_testMode(
const HtmlEscape(HtmlEscapeMode.element),
_TEST_INPUT,
_OUTPUT_ELEMENT,
);
_testMode(htmlEscape, _NOOP, _NOOP);
}
+88 -50
View File
@@ -27,37 +27,61 @@ void testParsing() {
// Lists.
Expect.deepEquals([], json.decode(' [] '));
Expect.deepEquals([], json.decode('[ ]'));
Expect.deepEquals([3, -4.5, true, 'hi', false],
json.decode(' [3, -4.5, true, "hi", false] '));
Expect.deepEquals([
3,
-4.5,
true,
'hi',
false,
], json.decode(' [3, -4.5, true, "hi", false] '));
// Nulls are tricky.
Expect.deepEquals([null], json.decode('[null]'));
Expect.deepEquals([3, -4.5, null, true, 'hi', false],
json.decode(' [3, -4.5, null, true, "hi", false] '));
Expect.deepEquals([
[null]
3,
-4.5,
null,
true,
'hi',
false,
], json.decode(' [3, -4.5, null, true, "hi", false] '));
Expect.deepEquals([
[null],
], json.decode('[[null]]'));
Expect.deepEquals([
[3],
[],
[null],
['hi', true]
['hi', true],
], json.decode(' [ [3], [], [null], ["hi", true]] '));
// Maps.
Expect.deepEquals({}, json.decode(' {} '));
Expect.deepEquals({}, json.decode('{ }'));
Expect.deepEquals({"x": 3, "y": -4.5, "z": "hi", "u": true, "v": false},
json.decode(' {"x":3, "y": -4.5, "z" : "hi","u" : true, "v": false } '));
Expect.deepEquals({
"x": 3,
"y": -4.5,
"z": "hi",
"u": true,
"v": false,
}, json.decode(' {"x":3, "y": -4.5, "z" : "hi","u" : true, "v": false } '));
Expect.deepEquals({"x": 3, "y": -4.5, "z": "hi"},
json.decode(' {"x":3, "y": -4.5, "z" : "hi" } '));
Expect.deepEquals({
"x": 3,
"y": -4.5,
"z": "hi",
}, json.decode(' {"x":3, "y": -4.5, "z" : "hi" } '));
Expect.deepEquals({"y": -4.5, "z": "hi", "x": 3},
json.decode(' {"y": -4.5, "z" : "hi" ,"x":3 } '));
Expect.deepEquals({
"y": -4.5,
"z": "hi",
"x": 3,
}, json.decode(' {"y": -4.5, "z" : "hi" ,"x":3 } '));
Expect.deepEquals(
{" hi bob ": 3, "": 4.5}, json.decode('{ " hi bob " :3, "": 4.5}'));
Expect.deepEquals({
" hi bob ": 3,
"": 4.5,
}, json.decode('{ " hi bob " :3, "": 4.5}'));
Expect.deepEquals({'x': {}}, json.decode(' { "x" : { } } '));
Expect.deepEquals({'x': {}}, json.decode('{"x":{}}'));
@@ -66,24 +90,30 @@ void testParsing() {
Expect.deepEquals({'w': null}, json.decode('{"w":null}'));
Expect.deepEquals({
"x": {"w": null}
"x": {"w": null},
}, json.decode('{"x":{"w":null}}'));
Expect.deepEquals(
{"x": 3, "y": -4.5, "z": "hi", "w": null, "u": true, "v": false},
json.decode(' {"x":3, "y": -4.5, "z" : "hi",'
'"w":null, "u" : true, "v": false } '));
{"x": 3, "y": -4.5, "z": "hi", "w": null, "u": true, "v": false},
json.decode(
' {"x":3, "y": -4.5, "z" : "hi",'
'"w":null, "u" : true, "v": false } ',
),
);
Expect.deepEquals(
{
"x": {"a": 3, "b": -4.5},
"y": [{}],
"z": "hi",
"w": {"c": null, "d": true},
"v": null
},
json.decode('{"x": {"a":3, "b": -4.5}, "y":[{}], '
'"z":"hi","w":{"c":null,"d":true}, "v":null}'));
{
"x": {"a": 3, "b": -4.5},
"y": [{}],
"z": "hi",
"w": {"c": null, "d": true},
"v": null,
},
json.decode(
'{"x": {"a":3, "b": -4.5}, "y":[{}], '
'"z":"hi","w":{"c":null,"d":true}, "v":null}',
),
);
}
void testStringify() {
@@ -108,28 +138,36 @@ void testStringify() {
Expect.equals('[null,null,null]', json.encode(new List.filled(3, null)));
validateRoundTrip([3, -4.5, null, true, 'hi', false]);
Expect.equals(
'[[3],[],[null],["hi",true]]',
json.encode([
[3],
[],
[null],
['hi', true]
]));
'[[3],[],[null],["hi",true]]',
json.encode([
[3],
[],
[null],
['hi', true],
]),
);
// Maps.
Expect.equals('{}', json.encode({}));
Expect.equals('{}', json.encode(new Map()));
Expect.equals('{"x":{}}', json.encode({'x': {}}));
Expect.equals(
'{"x":{"a":3}}',
json.encode({
'x': {'a': 3}
}));
'{"x":{"a":3}}',
json.encode({
'x': {'a': 3},
}),
);
// Dart does not guarantee an order on the keys
// of a map literal, so reparse and compare to the original Map.
validateRoundTrip(
{'x': 3, 'y': -4.5, 'z': 'hi', 'w': null, 'u': true, 'v': false});
validateRoundTrip({
'x': 3,
'y': -4.5,
'z': 'hi',
'w': null,
'u': true,
'v': false,
});
validateRoundTrip({"x": 3, "y": -4.5, "z": 'hi'});
validateRoundTrip({' hi bob ': 3, '': 4.5});
validateRoundTrip({
@@ -137,17 +175,20 @@ void testStringify() {
'y': [{}],
'z': 'hi',
'w': {'c': null, 'd': true},
'v': null
'v': null,
});
Expect.equals("4", json.encode(new ToJson(4)));
Expect.equals('[4,"a"]', json.encode(new ToJson([4, "a"])));
Expect.equals(
'[4,{"x":42}]',
json.encode(new ToJson([
'[4,{"x":42}]',
json.encode(
new ToJson([
4,
new ToJson({"x": 42})
])));
new ToJson({"x": 42}),
]),
),
);
expectThrowsJsonError(() => json.encode([new ToJson(new ToJson(4))]));
expectThrowsJsonError(() => json.encode([new Object()]));
@@ -161,8 +202,7 @@ void testStringifyErrors() {
expectThrowsJsonError(() => json.encode(new ToJsoner("bad", throws: true)));
// Throws if toJson returns non-serializable value.
expectThrowsJsonError(
() => json.encode(new ToJsoner(new TestClass())));
expectThrowsJsonError(() => json.encode(new ToJsoner(new TestClass())));
// Throws on cyclic values.
var a = [];
@@ -182,9 +222,7 @@ class TestClass {
int x;
String y;
TestClass()
: x = 3,
y = 'joe' {}
TestClass() : x = 3, y = 'joe' {}
}
class ToJsoner {
+47 -32
View File
@@ -15,7 +15,7 @@ void _testIndentWithNullChar() {
var encoder = const JsonEncoder.withIndent('\x00');
var encoded = encoder.convert([
[],
[[]]
[[]],
]);
Expect.equals("[\n\x00[],\n\x00[\n\x00\x00[]\n\x00]\n]", encoded);
}
@@ -25,57 +25,71 @@ void main() {
_expect(null, 'null');
_expect([
[],
[[]]
], '''
_expect(
[
[],
[[]],
],
'''
[
[],
[
[]
]
]''');
]''',
);
_expect([1, 2, 3, 4], '''
_expect(
[1, 2, 3, 4],
'''
[
1,
2,
3,
4
]''');
]''',
);
_expect([true, null, 'hello', 42.42], '''
_expect(
[true, null, 'hello', 42.42],
'''
[
true,
null,
"hello",
42.42
]''');
]''',
);
_expect({"hello": [], "goodbye": {}}, '''{
_expect(
{"hello": [], "goodbye": {}},
'''{
"hello": [],
"goodbye": {}
}''');
}''',
);
_expect([
"test",
1,
2,
33234.324,
true,
false,
null,
{
"test1": "test2",
"test3": "test4",
"grace": 5,
"shanna": [0, 1, 2]
},
{
"lib": "app.dart",
"src": ["foo.dart", "bar.dart"]
}
], '''[
_expect(
[
"test",
1,
2,
33234.324,
true,
false,
null,
{
"test1": "test2",
"test3": "test4",
"grace": 5,
"shanna": [0, 1, 2],
},
{
"lib": "app.dart",
"src": ["foo.dart", "bar.dart"],
},
],
'''[
"test",
1,
2,
@@ -100,7 +114,8 @@ void main() {
"bar.dart"
]
}
]''');
]''',
);
}
void _expect(Object? object, String expected) {
+54 -28
View File
@@ -19,17 +19,25 @@ void testJson(jsonText, expected) {
}
} else if (expected is Map) {
Expect.isTrue(actual is Map);
Expect.equals(expected.length, actual.length,
"$path: Map size in $jsonText");
Expect.equals(
expected.length,
actual.length,
"$path: Map size in $jsonText",
);
expected.forEach((key, value) {
Expect.isTrue(actual.containsKey(key));
compare(value, actual[key], "$path[$key] in $jsonText");
});
} else if (expected is num) {
Expect.equals(expected is int, actual is int,
"$path: not same number type in $jsonText");
Expect.isTrue(expected.compareTo(actual) == 0,
"$path: Expected: $expected, was: $actual in $jsonText");
Expect.equals(
expected is int,
actual is int,
"$path: not same number type in $jsonText",
);
Expect.isTrue(
expected.compareTo(actual) == 0,
"$path: Expected: $expected, was: $actual in $jsonText",
);
} else {
// String, bool, null.
Expect.equals(expected, actual, "$path in $jsonText");
@@ -99,7 +107,10 @@ String escape(String s) {
sb.writeCharCode(code);
else {
String hex = '000${code.toRadixString(16)}';
sb.write(r'\u' '${hex.substring(hex.length - 4)}');
sb.write(
r'\u'
'${hex.substring(hex.length - 4)}',
);
}
}
return '$sb';
@@ -107,15 +118,22 @@ String escape(String s) {
void testThrows(jsonText) {
var message = "json = '${escape(jsonText)}'";
Expect.throwsFormatException(() => json.decode(jsonText),
"json.decode, $message");
Expect.throwsFormatException(() => jsonDecode(jsonText),
"jsonDecode, $message");
Expect.throwsFormatException(() => json.decoder.convert(jsonText),
"json.decoder.convert, $message");
Expect.throwsFormatException(() =>
utf8.decoder.fuse(json.decoder).convert(utf8.encode(jsonText)),
"utf8.decoder.fuse(json.decoder) o utf.encode, $message");
Expect.throwsFormatException(
() => json.decode(jsonText),
"json.decode, $message",
);
Expect.throwsFormatException(
() => jsonDecode(jsonText),
"jsonDecode, $message",
);
Expect.throwsFormatException(
() => json.decoder.convert(jsonText),
"json.decoder.convert, $message",
);
Expect.throwsFormatException(
() => utf8.decoder.fuse(json.decoder).convert(utf8.encode(jsonText)),
"utf8.decoder.fuse(json.decoder) o utf.encode, $message",
);
}
testNumbers() {
@@ -255,7 +273,9 @@ testNumbers() {
testStrings() {
// String parser accepts and understands escapes.
var input = r'"\u0000\uffff\n\r\f\t\b\/\\\"' '\x20\ufffd\uffff"';
var input =
r'"\u0000\uffff\n\r\f\t\b\/\\\"'
'\x20\ufffd\uffff"';
var expected = "\u0000\uffff\n\r\f\t\b\/\\\"\x20\ufffd\uffff";
testJson(input, expected);
// Empty string.
@@ -314,8 +334,8 @@ testObjects() {
testJson(r'{"x":42}', {"x": 42});
testJson(r'{"x":{"x":{"x":42}}}', {
"x": {
"x": {"x": 42}
}
"x": {"x": 42},
},
});
testJson(r'{"x":10,"x":42}', {"x": 42});
testJson(r'{"":42}', {"": 42});
@@ -334,25 +354,31 @@ testObjects() {
testArrays() {
testJson(r'[]', []);
testJson(r'[1.1e1,"string",true,false,null,{}]',
[1.1e1, "string", true, false, null, {}]);
testJson(r'[1.1e1,"string",true,false,null,{}]', [
1.1e1,
"string",
true,
false,
null,
{},
]);
testJson(r'[[[[[[]]]],[[[]]],[[]]]]', [
[
[
[
[[]]
]
[[]],
],
],
[
[[]]
[[]],
],
[[]]
]
[[]],
],
]);
testJson(r'[{},[{}],{"x":[]}]', [
{},
[{}],
{"x": []}
{"x": []},
]);
testThrows(r'[1,,2]');
@@ -389,7 +415,7 @@ testWhitespace() {
testJson('$v[${v}-2.2e2$v,$v{$v"key"$v:${v}true$v}$v,$v"ab"$v]$v', [
-2.2e2,
{"key": true},
"ab"
"ab",
]);
// IE9 accepts invalid characters at the end, so some of these tests have been
@@ -20,13 +20,15 @@ reviver(key, value) {
return value;
}
const extendedJson =
const JsonCodec(toEncodable: toEncodable, reviver: reviver);
const extendedJson = const JsonCodec(
toEncodable: toEncodable,
reviver: reviver,
);
main() {
var encoded = extendedJson.encode([
new A(0),
{"2": new A(1)}
{"2": new A(1)},
]);
Expect.equals('[{"A":0},{"2":{"A":1}}]', encoded);
var decoded = extendedJson.decode(encoded);
+2 -2
View File
@@ -39,8 +39,8 @@ _expandUnicodeTests() {
// For example: 'abcd' -> '[[["abcd"]]]'.
var listExpected = [
[
[string]
]
[string],
],
];
var inListBytes = <int>[];
inListBytes.addAll([_bracketOpen, _bracketOpen, _bracketOpen]);
+354 -88
View File
@@ -20,9 +20,14 @@ main() {
// Create an UTF-8 sink from a chunked JSON decoder, then let [action]
// put data into it, and check that what comes out is equal to [expect].
void jsonTest(testName, expect, action(sink), [bool allowMalformed = false]) {
jsonParse(testName, (value) {
Expect.equals(expect, value, "$testName:$value");
}, action, allowMalformed);
jsonParse(
testName,
(value) {
Expect.equals(expect, value, "$testName:$value");
},
action,
allowMalformed,
);
}
void jsonParse(testName, check, action, [bool allowMalformed = false]) {
@@ -30,8 +35,9 @@ void jsonParse(testName, check, action, [bool allowMalformed = false]) {
var value = values[0];
check(value);
});
var decoderSink =
json.decoder.startChunkedConversion(sink).asUtf8Sink(allowMalformed);
var decoderSink = json.decoder
.startChunkedConversion(sink)
.asUtf8Sink(allowMalformed);
try {
action(decoderSink);
} on FormatException catch (e, s) {
@@ -43,10 +49,12 @@ void jsonParse(testName, check, action, [bool allowMalformed = false]) {
void testStrings() {
// String literal containing characters, all escape types,
// and a number of UTF-8 encoded characters.
var s = r'"abc\f\ndef\r\t\b\"\/\\\u0001\u9999\uffff'
var s =
r'"abc\f\ndef\r\t\b\"\/\\\u0001\u9999\uffff'
'\x7f\xc2\x80\xdf\xbf\xe0\xa0\x80\xef\xbf\xbf'
'\xf0\x90\x80\x80\xf4\x8f\xbf\xbf"'; // UTF-8.
var expected = "abc\f\ndef\r\t\b\"\/\\\u0001\u9999\uffff"
var expected =
"abc\f\ndef\r\t\b\"\/\\\u0001\u9999\uffff"
"\x7f\x80\u07ff\u0800\uffff"
"\u{10000}\u{10ffff}";
for (var i = 1; i < s.length - 1; i++) {
@@ -84,7 +92,7 @@ void testNumbers() {
"9",
"1234.56789123456701418035663664340972900390625",
"1.2345678912345671e-14",
"9223372036854775807"
"9223372036854775807",
]) {
var expected = num.parse(number);
for (int i = 1; i < number.length - 1; i++) {
@@ -200,8 +208,9 @@ void jsonMalformedTest(name, expect, codes) {
var value = values[0];
Expect.equals(expect, value, tag);
});
var decoderSink =
json.decoder.startChunkedConversion(sink).asUtf8Sink(true);
var decoderSink = json.decoder
.startChunkedConversion(sink)
.asUtf8Sink(true);
try {
action(decoderSink);
} catch (e, s) {
@@ -213,11 +222,16 @@ void jsonMalformedTest(name, expect, codes) {
var sink = new ChunkedConversionSink.withCallback((values) {
Expect.fail(tag);
});
var decoderSink =
json.decoder.startChunkedConversion(sink).asUtf8Sink(false);
Expect.throws(() {
action(decoderSink);
}, (_) => true, tag);
var decoderSink = json.decoder
.startChunkedConversion(sink)
.asUtf8Sink(false);
Expect.throws(
() {
action(decoderSink);
},
(_) => true,
tag,
);
}
}
@@ -251,11 +265,16 @@ void jsonThrows(String name, String codeString) {
var sink = new ChunkedConversionSink.withCallback((values) {
Expect.fail(tag);
});
var decoderSink =
json.decoder.startChunkedConversion(sink).asUtf8Sink(true);
Expect.throws(() {
action(decoderSink);
}, (_) => true, tag);
var decoderSink = json.decoder
.startChunkedConversion(sink)
.asUtf8Sink(true);
Expect.throws(
() {
action(decoderSink);
},
(_) => true,
tag,
);
}
var codes = codeString.codeUnits;
@@ -283,103 +302,350 @@ void jsonThrows(String name, String codeString) {
// Malformed UTF-8 encodings.
void testMalformed() {
// Overlong encodings.
jsonMalformedTest(
"overlong-0-2", "@\uFFFD\uFFFD@", [0x22, 0x40, 0xc0, 0x80, 0x40, 0x22]);
jsonMalformedTest("overlong-0-3", "@\uFFFD\uFFFD\uFFFD@",
[0x22, 0x40, 0xe0, 0x80, 0x80, 0x40, 0x22]);
jsonMalformedTest("overlong-0-4", "@\uFFFD\uFFFD\uFFFD\uFFFD@",
[0x22, 0x40, 0xf0, 0x80, 0x80, 0x80, 0x40, 0x22]);
jsonMalformedTest("overlong-0-2", "@\uFFFD\uFFFD@", [
0x22,
0x40,
0xc0,
0x80,
0x40,
0x22,
]);
jsonMalformedTest("overlong-0-3", "@\uFFFD\uFFFD\uFFFD@", [
0x22,
0x40,
0xe0,
0x80,
0x80,
0x40,
0x22,
]);
jsonMalformedTest("overlong-0-4", "@\uFFFD\uFFFD\uFFFD\uFFFD@", [
0x22,
0x40,
0xf0,
0x80,
0x80,
0x80,
0x40,
0x22,
]);
jsonMalformedTest(
"overlong-7f-2", "@\uFFFD\uFFFD@", [0x22, 0x40, 0xc1, 0xbf, 0x40, 0x22]);
jsonMalformedTest("overlong-7f-3", "@\uFFFD\uFFFD\uFFFD@",
[0x22, 0x40, 0xe0, 0x81, 0xbf, 0x40, 0x22]);
jsonMalformedTest("overlong-7f-4", "@\uFFFD\uFFFD\uFFFD\uFFFD@",
[0x22, 0x40, 0xf0, 0x80, 0x81, 0xbf, 0x40, 0x22]);
jsonMalformedTest("overlong-7f-2", "@\uFFFD\uFFFD@", [
0x22,
0x40,
0xc1,
0xbf,
0x40,
0x22,
]);
jsonMalformedTest("overlong-7f-3", "@\uFFFD\uFFFD\uFFFD@", [
0x22,
0x40,
0xe0,
0x81,
0xbf,
0x40,
0x22,
]);
jsonMalformedTest("overlong-7f-4", "@\uFFFD\uFFFD\uFFFD\uFFFD@", [
0x22,
0x40,
0xf0,
0x80,
0x81,
0xbf,
0x40,
0x22,
]);
jsonMalformedTest("overlong-80-3", "@\uFFFD\uFFFD\uFFFD@",
[0x22, 0x40, 0xe0, 0x82, 0x80, 0x40, 0x22]);
jsonMalformedTest("overlong-80-4", "@\uFFFD\uFFFD\uFFFD\uFFFD@",
[0x22, 0x40, 0xf0, 0x80, 0x82, 0x80, 0x40, 0x22]);
jsonMalformedTest("overlong-80-3", "@\uFFFD\uFFFD\uFFFD@", [
0x22,
0x40,
0xe0,
0x82,
0x80,
0x40,
0x22,
]);
jsonMalformedTest("overlong-80-4", "@\uFFFD\uFFFD\uFFFD\uFFFD@", [
0x22,
0x40,
0xf0,
0x80,
0x82,
0x80,
0x40,
0x22,
]);
jsonMalformedTest("overlong-7ff-3", "@\uFFFD\uFFFD\uFFFD@",
[0x22, 0x40, 0xe0, 0x9f, 0xbf, 0x40, 0x22]);
jsonMalformedTest("overlong-7ff-4", "@\uFFFD\uFFFD\uFFFD\uFFFD@",
[0x22, 0x40, 0xf0, 0x80, 0x9f, 0xbf, 0x40, 0x22]);
jsonMalformedTest("overlong-7ff-3", "@\uFFFD\uFFFD\uFFFD@", [
0x22,
0x40,
0xe0,
0x9f,
0xbf,
0x40,
0x22,
]);
jsonMalformedTest("overlong-7ff-4", "@\uFFFD\uFFFD\uFFFD\uFFFD@", [
0x22,
0x40,
0xf0,
0x80,
0x9f,
0xbf,
0x40,
0x22,
]);
jsonMalformedTest("overlong-800-4", "@\uFFFD\uFFFD\uFFFD\uFFFD@",
[0x22, 0x40, 0xf0, 0x80, 0xa0, 0x80, 0x40, 0x22]);
jsonMalformedTest("overlong-ffff-4", "@\uFFFD\uFFFD\uFFFD\uFFFD@",
[0x22, 0x40, 0xf0, 0x8f, 0xbf, 0xbf, 0x40, 0x22]);
jsonMalformedTest("overlong-800-4", "@\uFFFD\uFFFD\uFFFD\uFFFD@", [
0x22,
0x40,
0xf0,
0x80,
0xa0,
0x80,
0x40,
0x22,
]);
jsonMalformedTest("overlong-ffff-4", "@\uFFFD\uFFFD\uFFFD\uFFFD@", [
0x22,
0x40,
0xf0,
0x8f,
0xbf,
0xbf,
0x40,
0x22,
]);
// Unterminated multibyte sequences.
jsonMalformedTest(
"unterminated-2-normal", "@\uFFFD@", [0x22, 0x40, 0xc0, 0x40, 0x22]);
jsonMalformedTest("unterminated-2-normal", "@\uFFFD@", [
0x22,
0x40,
0xc0,
0x40,
0x22,
]);
jsonMalformedTest("unterminated-3-normal", "@\uFFFD\uFFFD@",
[0x22, 0x40, 0xe0, 0x80, 0x40, 0x22]);
jsonMalformedTest("unterminated-3-normal", "@\uFFFD\uFFFD@", [
0x22,
0x40,
0xe0,
0x80,
0x40,
0x22,
]);
jsonMalformedTest("unterminated-4-normal", "@\uFFFD\uFFFD\uFFFD@",
[0x22, 0x40, 0xf0, 0x80, 0x80, 0x40, 0x22]);
jsonMalformedTest("unterminated-4-normal", "@\uFFFD\uFFFD\uFFFD@", [
0x22,
0x40,
0xf0,
0x80,
0x80,
0x40,
0x22,
]);
jsonMalformedTest("unterminated-2-multi", "@\uFFFD\x80@",
[0x22, 0x40, 0xc0, 0xc2, 0x80, 0x40, 0x22]);
jsonMalformedTest("unterminated-2-multi", "@\uFFFD\x80@", [
0x22,
0x40,
0xc0,
0xc2,
0x80,
0x40,
0x22,
]);
jsonMalformedTest("unterminated-3-multi", "@\uFFFD\uFFFD\x80@",
[0x22, 0x40, 0xe0, 0x80, 0xc2, 0x80, 0x40, 0x22]);
jsonMalformedTest("unterminated-3-multi", "@\uFFFD\uFFFD\x80@", [
0x22,
0x40,
0xe0,
0x80,
0xc2,
0x80,
0x40,
0x22,
]);
jsonMalformedTest("unterminated-4-multi", "@\uFFFD\uFFFD\uFFFD\x80@",
[0x22, 0x40, 0xf0, 0x80, 0x80, 0xc2, 0x80, 0x40, 0x22]);
jsonMalformedTest("unterminated-4-multi", "@\uFFFD\uFFFD\uFFFD\x80@", [
0x22,
0x40,
0xf0,
0x80,
0x80,
0xc2,
0x80,
0x40,
0x22,
]);
jsonMalformedTest("unterminated-2-escape", "@\uFFFD\n@",
[0x22, 0x40, 0xc0, 0x5c, 0x6e, 0x40, 0x22]);
jsonMalformedTest("unterminated-2-escape", "@\uFFFD\n@", [
0x22,
0x40,
0xc0,
0x5c,
0x6e,
0x40,
0x22,
]);
jsonMalformedTest("unterminated-3-escape", "@\uFFFD\uFFFD\n@",
[0x22, 0x40, 0xe0, 0x80, 0x5c, 0x6e, 0x40, 0x22]);
jsonMalformedTest("unterminated-3-escape", "@\uFFFD\uFFFD\n@", [
0x22,
0x40,
0xe0,
0x80,
0x5c,
0x6e,
0x40,
0x22,
]);
jsonMalformedTest("unterminated-4-escape", "@\uFFFD\uFFFD\uFFFD\n@",
[0x22, 0x40, 0xf0, 0x80, 0x80, 0x5c, 0x6e, 0x40, 0x22]);
jsonMalformedTest("unterminated-4-escape", "@\uFFFD\uFFFD\uFFFD\n@", [
0x22,
0x40,
0xf0,
0x80,
0x80,
0x5c,
0x6e,
0x40,
0x22,
]);
jsonMalformedTest("unterminated-2-end", "@\uFFFD", [0x22, 0x40, 0xc0, 0x22]);
jsonMalformedTest(
"unterminated-3-end", "@\uFFFD\uFFFD", [0x22, 0x40, 0xe0, 0x80, 0x22]);
jsonMalformedTest("unterminated-3-end", "@\uFFFD\uFFFD", [
0x22,
0x40,
0xe0,
0x80,
0x22,
]);
jsonMalformedTest("unterminated-4-end", "@\uFFFD\uFFFD\uFFFD",
[0x22, 0x40, 0xf0, 0x80, 0x80, 0x22]);
jsonMalformedTest("unterminated-4-end", "@\uFFFD\uFFFD\uFFFD", [
0x22,
0x40,
0xf0,
0x80,
0x80,
0x22,
]);
// Unexpected continuation byte
// - after a normal character.
jsonMalformedTest(
"continuation-normal", "@\uFFFD@", [0x22, 0x40, 0x80, 0x40, 0x22]);
jsonMalformedTest("continuation-normal", "@\uFFFD@", [
0x22,
0x40,
0x80,
0x40,
0x22,
]);
// - after a valid continuation byte.
jsonMalformedTest("continuation-continuation-2", "@\x80\uFFFD@",
[0x22, 0x40, 0xc2, 0x80, 0x80, 0x40, 0x22]);
jsonMalformedTest("continuation-continuation-3", "@\u0800\uFFFD@",
[0x22, 0x40, 0xe0, 0xa0, 0x80, 0x80, 0x40, 0x22]);
jsonMalformedTest("continuation-continuation-4", "@\u{10000}\uFFFD@",
[0x22, 0x40, 0xf0, 0x90, 0x80, 0x80, 0x80, 0x40, 0x22]);
jsonMalformedTest("continuation-continuation-2", "@\x80\uFFFD@", [
0x22,
0x40,
0xc2,
0x80,
0x80,
0x40,
0x22,
]);
jsonMalformedTest("continuation-continuation-3", "@\u0800\uFFFD@", [
0x22,
0x40,
0xe0,
0xa0,
0x80,
0x80,
0x40,
0x22,
]);
jsonMalformedTest("continuation-continuation-4", "@\u{10000}\uFFFD@", [
0x22,
0x40,
0xf0,
0x90,
0x80,
0x80,
0x80,
0x40,
0x22,
]);
// - after another invalid continuation byte
jsonMalformedTest("continuation-twice", "@\uFFFD\uFFFD\uFFFD@",
[0x22, 0x40, 0x80, 0x80, 0x80, 0x40, 0x22]);
jsonMalformedTest("continuation-twice", "@\uFFFD\uFFFD\uFFFD@", [
0x22,
0x40,
0x80,
0x80,
0x80,
0x40,
0x22,
]);
// - at start.
jsonMalformedTest("continuation-start", "\uFFFD@", [0x22, 0x80, 0x40, 0x22]);
// Unexpected leading byte where continuation byte expected.
jsonMalformedTest(
"leading-2", "@\uFFFD\x80@", [0x22, 0x40, 0xc0, 0xc2, 0x80, 0x40, 0x22]);
jsonMalformedTest("leading-3-1", "@\uFFFD\x80@",
[0x22, 0x40, 0xe0, 0xc2, 0x80, 0x40, 0x22]);
jsonMalformedTest("leading-3-2", "@\uFFFD\uFFFD\x80@",
[0x22, 0x40, 0xe0, 0x80, 0xc2, 0x80, 0x40, 0x22]);
jsonMalformedTest("leading-4-1", "@\uFFFD\x80@",
[0x22, 0x40, 0xf0, 0xc2, 0x80, 0x40, 0x22]);
jsonMalformedTest("leading-4-2", "@\uFFFD\uFFFD\x80@",
[0x22, 0x40, 0xf0, 0x80, 0xc2, 0x80, 0x40, 0x22]);
jsonMalformedTest("leading-4-3", "@\uFFFD\uFFFD\uFFFD\x80@",
[0x22, 0x40, 0xf0, 0x80, 0x80, 0xc2, 0x80, 0x40, 0x22]);
jsonMalformedTest("leading-2", "@\uFFFD\x80@", [
0x22,
0x40,
0xc0,
0xc2,
0x80,
0x40,
0x22,
]);
jsonMalformedTest("leading-3-1", "@\uFFFD\x80@", [
0x22,
0x40,
0xe0,
0xc2,
0x80,
0x40,
0x22,
]);
jsonMalformedTest("leading-3-2", "@\uFFFD\uFFFD\x80@", [
0x22,
0x40,
0xe0,
0x80,
0xc2,
0x80,
0x40,
0x22,
]);
jsonMalformedTest("leading-4-1", "@\uFFFD\x80@", [
0x22,
0x40,
0xf0,
0xc2,
0x80,
0x40,
0x22,
]);
jsonMalformedTest("leading-4-2", "@\uFFFD\uFFFD\x80@", [
0x22,
0x40,
0xf0,
0x80,
0xc2,
0x80,
0x40,
0x22,
]);
jsonMalformedTest("leading-4-3", "@\uFFFD\uFFFD\uFFFD\x80@", [
0x22,
0x40,
0xf0,
0x80,
0x80,
0xc2,
0x80,
0x40,
0x22,
]);
// Overlong encodings of ASCII outside of strings always fail.
// Use Latin-1 strings as argument since most chars are correct,
+31 -23
View File
@@ -19,21 +19,22 @@ void main() {
// String (0x22 = ") with UTF-8 encoded Unicode characters.
Expect.equals(
"A\xff\u1234\u{65555}",
parse([
0x22,
0x41,
0xc3,
0xbf,
0xe1,
0x88,
0xb4,
0xf1,
0xa5,
0x95,
0x95,
0x22
]));
"A\xff\u1234\u{65555}",
parse([
0x22,
0x41,
0xc3,
0xbf,
0xe1,
0x88,
0xb4,
0xf1,
0xa5,
0x95,
0x95,
0x22,
]),
);
// BOM followed by true.
Expect.isTrue(parse([0xEF, 0xBB, 0xBF, 0x74, 0x72, 0x75, 0x65]));
@@ -41,18 +42,22 @@ void main() {
// Do not accept BOM in non-UTF-8 decoder.
Expect.throws<FormatException>(
() => new JsonDecoder().convert("\xEF\xBB\xBFtrue"));
() => new JsonDecoder().convert("\xEF\xBB\xBFtrue"),
);
Expect.throws<FormatException>(() => new JsonDecoder().convert("\uFEFFtrue"));
// Only accept BOM first.
Expect.throws<FormatException>(
() => parseFuse(" \xEF\xBB\xBFtrue".codeUnits.toList()));
() => parseFuse(" \xEF\xBB\xBFtrue".codeUnits.toList()),
);
// Only accept BOM first.
Expect.throws<FormatException>(
() => parseFuse(" true\xEF\xBB\xBF".codeUnits.toList()));
() => parseFuse(" true\xEF\xBB\xBF".codeUnits.toList()),
);
Expect.throws<FormatException>(
() => parseFuse(" [\xEF\xBB\xBF]".codeUnits.toList()));
() => parseFuse(" [\xEF\xBB\xBF]".codeUnits.toList()),
);
// Regression test for dartbug.com/46205
// Bug occurs in sound null safe mode only.
@@ -69,10 +74,13 @@ Object? parseSequence(List<int> text) {
Object? parseChunked(List<int> text) {
var result;
var sink = new Utf8Decoder().fuse(new JsonDecoder()).startChunkedConversion(
new ChunkedConversionSink.withCallback((List<Object?> values) {
result = values[0];
}));
var sink = new Utf8Decoder()
.fuse(new JsonDecoder())
.startChunkedConversion(
new ChunkedConversionSink.withCallback((List<Object?> values) {
result = values[0];
}),
);
for (var i = 0; i < text.length; i++) {
sink.add([text[i]]);
}
+12 -6
View File
@@ -82,8 +82,10 @@ void testParse() {
// Maps.
Expect.mapEquals({}, json.decode(' {} '));
Expect.mapEquals({"key": "value"}, json.decode(' {"key": "value" } '));
Expect.mapEquals(
{"key1": 1, "key2": 2}, json.decode(' {"key1": 1, "key2": 2} '));
Expect.mapEquals({
"key1": 1,
"key2": 2,
}, json.decode(' {"key1": 1, "key2": 2} '));
Expect.mapEquals({"key1": 1}, json.decode(' { "key1" : 1 } '));
}
@@ -171,8 +173,12 @@ void testEscaping() {
Expect.stringEquals('"\\u001f"', json.encode('\u001f'));
Expect.stringEquals('"\\\""', json.encode('"'));
Expect.stringEquals('"\\\\"', json.encode('\\'));
Expect.stringEquals('"Got \\b, \\f, \\n, \\r, \\t, \\u0000, \\\\, and \\"."',
json.encode('Got \b, \f, \n, \r, \t, \u0000, \\, and ".'));
Expect.stringEquals('"Got \\b\\f\\n\\r\\t\\u0000\\\\\\"."',
json.encode('Got \b\f\n\r\t\u0000\\".'));
Expect.stringEquals(
'"Got \\b, \\f, \\n, \\r, \\t, \\u0000, \\\\, and \\"."',
json.encode('Got \b, \f, \n, \r, \t, \u0000, \\, and ".'),
);
Expect.stringEquals(
'"Got \\b\\f\\n\\r\\t\\u0000\\\\\\"."',
json.encode('Got \b\f\n\r\t\u0000\\".'),
);
}
+17 -7
View File
@@ -41,9 +41,13 @@ void testDirectConversions() {
}
for (var nonLatin1String in nonLatin1Strings) {
Expect.throws(() {
print(codec.encoder.convert(nonLatin1String));
}, (_) => true, nonLatin1String);
Expect.throws(
() {
print(codec.encoder.convert(nonLatin1String));
},
(_) => true,
nonLatin1String,
);
}
var encode = codec.encoder.convert;
@@ -104,7 +108,10 @@ void testDirectConversions() {
}
List<int> encode(
String str, int chunkSize, Converter<String, List<int>> converter) {
String str,
int chunkSize,
Converter<String, List<int>> converter,
) {
List<int> bytes = <int>[];
var byteSink = new ByteConversionSink.withCallback(bytes.addAll);
var stringConversionSink = converter.startChunkedConversion(byteSink);
@@ -120,7 +127,10 @@ List<int> encode(
}
String decode(
List<int> bytes, int chunkSize, Converter<List<int>, String> converter) {
List<int> bytes,
int chunkSize,
Converter<List<int>, String> converter,
) {
StringBuffer buf = new StringBuffer();
var stringSink = new StringConversionSink.fromStringSink(buf);
var byteConversionSink = converter.startChunkedConversion(stringSink);
@@ -140,7 +150,7 @@ void testChunkedConversions() {
for (var converter in [
latin1.encoder,
new Latin1Codec().encoder,
new Latin1Encoder()
new Latin1Encoder(),
]) {
for (int chunkSize in [1, 2, 5, 50]) {
for (var latin1String in latin1Strings) {
@@ -159,7 +169,7 @@ void testChunkedConversions() {
for (var converter in [
latin1.decoder,
new Latin1Codec().decoder,
new Latin1Decoder()
new Latin1Decoder(),
]) {
for (int chunkSize in [1, 2, 5, 50]) {
for (var latin1String in latin1Strings) {
@@ -22,15 +22,16 @@ void testEfficiency() {
// Before fix, with N = 100000, took 25 seconds.
const N = 1000000;
String result = ""; // Starts empty, set once.
var sink = LineSplitter()
.startChunkedConversion(ChunkedConversionSink.withCallback((lines) {
// Gets called only once with exactly one line.
Expect.equals("", result);
Expect.equals(1, lines.length);
var line = lines.first;
Expect.notEquals("", line);
result = line;
}));
var sink = LineSplitter().startChunkedConversion(
ChunkedConversionSink.withCallback((lines) {
// Gets called only once with exactly one line.
Expect.equals("", result);
Expect.equals(1, lines.length);
var line = lines.first;
Expect.notEquals("", line);
result = line;
}),
);
for (var i = 0; i < N; i++) {
sink.add("xy");
}
+49 -15
View File
@@ -44,8 +44,9 @@ void testManyLines() {
String _getLinesSliced(String str) {
late String lines;
var stringSink =
new StringConversionSink.withCallback((result) => lines = result);
var stringSink = new StringConversionSink.withCallback(
(result) => lines = result,
);
var sink = new LineSplitter().startChunkedConversion(stringSink);
const chunkSize = 3;
@@ -74,14 +75,25 @@ void testSimpleConvert() {
var test = "Line1\nLine2\r\nLine3\rLine4\n\n\n\r\n\r\n\r\r";
var result = decoder.convert(test);
Expect.listEquals(
['Line1', 'Line2', 'Line3', 'Line4', '', '', '', '', '', ''], result);
Expect.listEquals([
'Line1',
'Line2',
'Line3',
'Line4',
'',
'',
'',
'',
'',
'',
], result);
}
void testReadLine1() {
var controller = new StreamController<List<int>>(sync: true);
var stream =
controller.stream.transform(utf8.decoder).transform(const LineSplitter());
var stream = controller.stream
.transform(utf8.decoder)
.transform(const LineSplitter());
var stage = 0;
var done = false;
@@ -108,8 +120,9 @@ void testReadLine1() {
void testReadLine2() {
var controller = new StreamController<List<int>>(sync: true);
var stream =
controller.stream.transform(utf8.decoder).transform(const LineSplitter());
var stream = controller.stream
.transform(utf8.decoder)
.transform(const LineSplitter());
var expectedLines = [
'Line1',
@@ -123,7 +136,7 @@ void testReadLine2() {
'',
'',
'Line5',
'Line6'
'Line6',
];
var index = 0;
@@ -152,8 +165,18 @@ void testSplit() {
var test = "Line1\nLine2\r\nLine3\rLine4\n\n\n\r\n\r\n\r\r";
var result = LineSplitter.split(test).toList();
Expect.listEquals(
['Line1', 'Line2', 'Line3', 'Line4', '', '', '', '', '', ''], result);
Expect.listEquals([
'Line1',
'Line2',
'Line3',
'Line4',
'',
'',
'',
'',
'',
'',
], result);
}
void testSplitWithOffsets() {
@@ -182,8 +205,18 @@ void testSplitWithOffsets() {
var result = LineSplitter.split(test).toList();
Expect.listEquals(
['Line1', 'Line2', 'Line3', 'Line4', '', '', '', '', '', ''], result);
Expect.listEquals([
'Line1',
'Line2',
'Line3',
'Line4',
'',
'',
'',
'',
'',
'',
], result);
test = "a\n\nb\r\nc\n\rd\r\re\r\n\nf\r\n";
result = LineSplitter.split(test).toList();
@@ -210,8 +243,9 @@ void testChunkedConversion() {
for (int j = i; j < test.length; j++) {
var output = [];
var splitter = new LineSplitter();
var outSink =
new ChunkedConversionSink<String>.withCallback(output.addAll);
var outSink = new ChunkedConversionSink<String>.withCallback(
output.addAll,
);
var sink = splitter.startChunkedConversion(outSink);
sink.addSlice(test, 0, i, false);
sink.addSlice(test, i, j, false);
@@ -43,9 +43,10 @@ void main() {
final stringSink = StringSink();
Expect.throwsFormatException(
() => utf8.decoder.startChunkedConversion(stringSink)
..add(bytes)
..close());
() => utf8.decoder.startChunkedConversion(stringSink)
..add(bytes)
..close(),
);
}
}
@@ -19,42 +19,42 @@ final TESTS = [
[[], "[]"],
[
[3, -4.5, true, "hi", false],
'[3,-4.5,true,"hi",false]'
'[3,-4.5,true,"hi",false]',
],
[
[null],
"[null]"
"[null]",
],
[
[
[null]
[null],
],
"[[null]]"
"[[null]]",
],
[
[
[3]
[3],
],
"[[3]]"
"[[3]]",
],
[{}, "{}"],
[
{"x": 3, "y": 4.5, "z": "hi", "u": true, "v": false},
'{"x":3,"y":4.5,"z":"hi","u":true,"v":false}'
'{"x":3,"y":4.5,"z":"hi","u":true,"v":false}',
],
[
{"x": null},
'{"x":null}'
'{"x":null}',
],
[
{"x": {}},
'{"x":{}}'
'{"x":{}}',
],
// Note that -0.0 won't be treated the same in JS. The Json spec seems to
// allow it, though.
[
{"hi there": 499, "'": -0.0},
'{"hi there":499,"\'":-0.0}'
'{"hi there":499,"\'":-0.0}',
],
[r'\foo', r'"\\foo"'],
];
@@ -83,10 +83,12 @@ bool isJsonEqual(o1, o2) {
Stream<Object?> createStream(List<String> chunks) {
var decoder = new JsonDecoder(null);
var controller;
controller = new StreamController<String>(onListen: () {
chunks.forEach(controller.add);
controller.close();
});
controller = new StreamController<String>(
onListen: () {
chunks.forEach(controller.add);
controller.close();
},
);
return controller.stream.transform(decoder);
}
@@ -110,14 +112,15 @@ void main() {
var tests = TESTS.expand((test) {
var object = test[0];
var string = test[1];
var longString = " "
var longString =
" "
" "
"$string"
" "
" ";
return [
test,
[object, longString]
[object, longString],
];
});
for (var test in tests) {
@@ -19,42 +19,42 @@ final TESTS = [
[[], "[]"],
[
[3, -4.5, true, "hi", false],
'[3,-4.5,true,"hi",false]'
'[3,-4.5,true,"hi",false]',
],
[
[null],
"[null]"
"[null]",
],
[
[
[null]
[null],
],
"[[null]]"
"[[null]]",
],
[
[
[3]
[3],
],
"[[3]]"
"[[3]]",
],
[{}, "{}"],
[
{"x": 3, "y": 4.5, "z": "hi", "u": true, "v": false},
'{"x":3,"y":4.5,"z":"hi","u":true,"v":false}'
'{"x":3,"y":4.5,"z":"hi","u":true,"v":false}',
],
[
{"x": null},
'{"x":null}'
'{"x":null}',
],
[
{"x": {}},
'{"x":{}}'
'{"x":{}}',
],
// Note that -0.0 won't be treated the same in JS. The Json spec seems to
// allow it, though.
[
{"hi there": 499, "'": -0.0},
'{"hi there":499,"\'":-0.0}'
'{"hi there":499,"\'":-0.0}',
],
[r'\foo', r'"\\foo"'],
];
@@ -62,10 +62,12 @@ final TESTS = [
Stream<String> encode(Object? o) {
var encoder = new JsonEncoder();
late StreamController controller;
controller = new StreamController(onListen: () {
controller.add(o);
controller.close();
});
controller = new StreamController(
onListen: () {
controller.add(o);
controller.close();
},
);
return controller.stream.transform(encoder);
}
@@ -85,13 +87,16 @@ void testWithPause(String expected, Object? o) {
Stream stream = encode(o);
StringBuffer buffer = new StringBuffer();
var sub;
sub = stream.listen((x) {
buffer.write(x);
sub.pause(new Future.delayed(Duration.zero));
}, onDone: () {
Expect.stringEquals(expected, buffer.toString());
asyncEnd();
});
sub = stream.listen(
(x) {
buffer.write(x);
sub.pause(new Future.delayed(Duration.zero));
},
onDone: () {
Expect.stringEquals(expected, buffer.toString());
asyncEnd();
},
);
}
void main() {
@@ -40,10 +40,12 @@ void expectJsonEquals(o1, o2, [path = "result"]) {
Stream<Object?> createStream(List<List<int>> chunks) {
var controller;
controller = new StreamController<List<int>>(onListen: () {
chunks.forEach(controller.add);
controller.close();
});
controller = new StreamController<List<int>>(
onListen: () {
chunks.forEach(controller.add);
controller.close();
},
);
return controller.stream.transform(jsonUtf8.decoder);
}
@@ -12,10 +12,12 @@ final jsonUtf8 = json.fuse<List<int>>(utf8);
Stream<List<int>> encode(Object o) {
var controller;
controller = new StreamController(onListen: () {
controller.add(o);
controller.close();
});
controller = new StreamController(
onListen: () {
controller.add(o);
controller.close();
},
);
return controller.stream.transform(jsonUtf8.encoder);
}
@@ -33,13 +35,16 @@ void testWithPauses(List<int> expected, Stream<List<int>> stream) {
asyncStart();
var accumulated = <int>[];
var sub;
sub = stream.listen((x) {
accumulated.addAll(x);
sub.pause(new Future.delayed(Duration.zero));
}, onDone: () {
Expect.listEquals(expected, accumulated);
asyncEnd();
});
sub = stream.listen(
(x) {
accumulated.addAll(x);
sub.pause(new Future.delayed(Duration.zero));
},
onDone: () {
Expect.listEquals(expected, accumulated);
asyncEnd();
},
);
}
void main() {
@@ -10,20 +10,22 @@ import "package:expect/async_helper.dart";
Stream<String> decode(List<int> bytes, int chunkSize) {
var controller;
controller = new StreamController<List<int>>(onListen: () {
int i = 0;
while (i < bytes.length) {
List nextChunk = <int>[];
for (int j = 0; j < chunkSize; j++) {
if (i < bytes.length) {
nextChunk.add(bytes[i]);
i++;
controller = new StreamController<List<int>>(
onListen: () {
int i = 0;
while (i < bytes.length) {
List nextChunk = <int>[];
for (int j = 0; j < chunkSize; j++) {
if (i < bytes.length) {
nextChunk.add(bytes[i]);
i++;
}
}
controller.add(nextChunk);
}
controller.add(nextChunk);
}
controller.close();
});
controller.close();
},
);
return controller.stream.transform(utf8.decoder);
}
@@ -41,13 +43,16 @@ testWithPauses(String expected, Stream stream) {
asyncStart();
StringBuffer buffer = new StringBuffer();
var sub;
sub = stream.listen((x) {
buffer.write(x);
sub.pause(new Future.delayed(Duration.zero));
}, onDone: () {
Expect.stringEquals(expected, buffer.toString());
asyncEnd();
});
sub = stream.listen(
(x) {
buffer.write(x);
sub.pause(new Future.delayed(Duration.zero));
},
onDone: () {
Expect.stringEquals(expected, buffer.toString());
asyncEnd();
},
);
}
main() {
@@ -10,18 +10,20 @@ import "package:expect/async_helper.dart";
Stream<List<int>> encode(String string, int chunkSize) {
var controller;
controller = new StreamController<String>(onListen: () {
int i = 0;
while (i < string.length) {
if (i + chunkSize <= string.length) {
controller.add(string.substring(i, i + chunkSize));
} else {
controller.add(string.substring(i));
controller = new StreamController<String>(
onListen: () {
int i = 0;
while (i < string.length) {
if (i + chunkSize <= string.length) {
controller.add(string.substring(i, i + chunkSize));
} else {
controller.add(string.substring(i));
}
i += chunkSize;
}
i += chunkSize;
}
controller.close();
});
controller.close();
},
);
return controller.stream.transform(utf8.encoder);
}
@@ -40,13 +42,16 @@ void testWithPauses(List<int> expected, Stream<List<int>> stream) {
asyncStart();
var combined = <int>[];
var sub;
sub = stream.listen((x) {
combined.addAll(x);
sub.pause(new Future.delayed(Duration.zero));
}, onDone: () {
Expect.listEquals(expected, combined);
asyncEnd();
});
sub = stream.listen(
(x) {
combined.addAll(x);
sub.pause(new Future.delayed(Duration.zero));
},
onDone: () {
Expect.listEquals(expected, combined);
asyncEnd();
},
);
}
main() {
+18 -16
View File
@@ -45,7 +45,7 @@ const INTER_BYTES = const [
0xbb,
0x9d,
0xc3,
0xb1
0xb1,
];
const INTER_STRING = "Îñţérñåţîöñåļîžåţîờñ";
@@ -63,7 +63,7 @@ const BLUEBERRY_BYTES = const [
0x72,
0xc3,
0xb8,
0x64
0x64,
];
const BLUEBERRY_STRING = "blåbærgrød";
@@ -102,7 +102,7 @@ const SIVA_BYTES1 = const [
0x88,
0xe0,
0xae,
0xb2
0xb2,
];
const SIVA_STRING1 = "சிவா அணாமாைல";
@@ -141,7 +141,7 @@ const SIVA_BYTES2 = const [
0xb2,
0xe0,
0xa5,
0x88
0x88,
];
const SIVA_STRING2 = "िसवा अणामालै";
@@ -179,7 +179,7 @@ const ASCII_BYTES = const [
0x77,
0x78,
0x79,
0x7A
0x7A,
];
const ASCII_STRING = "abcdefghijklmnopqrstuvwxyz";
@@ -226,17 +226,19 @@ List<List> _expandTestPairs() {
assert(2 == BEE_STRING.length);
var tests = <List>[];
tests.addAll(_TEST_PAIRS);
tests.addAll(_TEST_PAIRS.map((test) {
var bytes = test[0] as List<int>;
var string = test[1] as String;
var longBytes = <int>[];
var longString = "";
for (int i = 0; i < 100; i++) {
longBytes.addAll(bytes);
longString += string;
}
return [longBytes, longString];
}));
tests.addAll(
_TEST_PAIRS.map((test) {
var bytes = test[0] as List<int>;
var string = test[1] as String;
var longBytes = <int>[];
var longString = "";
for (int i = 0; i < 100; i++) {
longBytes.addAll(bytes);
longString += string;
}
return [longBytes, longString];
}),
);
return tests;
}
+54 -50
View File
@@ -32,7 +32,7 @@ final TESTS0 = [
// Unfinished UTF-8 sequences.
[0xc3],
[0xE2, 0x82],
[0xF0, 0xA4, 0xAD]
[0xF0, 0xA4, 0xAD],
];
final TESTS1 = [
@@ -67,146 +67,146 @@ final TESTS2 = [
// Test that 0xC0|1, 0x80 does not eat the next character.
[
[0xC0, 0x80, 0x61],
"XXa"
"XXa",
],
[
[0xC1, 0x80, 0x61],
"XXa"
"XXa",
],
// 0xF5 .. 0xFF never appear in valid UTF-8 sequences.
[
[0xF5, 0x80],
"XX"
"XX",
],
[
[0xF6, 0x80],
"XX"
"XX",
],
[
[0xF7, 0x80],
"XX"
"XX",
],
[
[0xF8, 0x80],
"XX"
"XX",
],
[
[0xF9, 0x80],
"XX"
"XX",
],
[
[0xFA, 0x80],
"XX"
"XX",
],
[
[0xFB, 0x80],
"XX"
"XX",
],
[
[0xFC, 0x80],
"XX"
"XX",
],
[
[0xFD, 0x80],
"XX"
"XX",
],
[
[0xFE, 0x80],
"XX"
"XX",
],
[
[0xFF, 0x80],
"XX"
"XX",
],
[
[0xF5, 0x80, 0x61],
"XXa"
"XXa",
],
[
[0xF6, 0x80, 0x61],
"XXa"
"XXa",
],
[
[0xF7, 0x80, 0x61],
"XXa"
"XXa",
],
[
[0xF8, 0x80, 0x61],
"XXa"
"XXa",
],
[
[0xF9, 0x80, 0x61],
"XXa"
"XXa",
],
[
[0xFA, 0x80, 0x61],
"XXa"
"XXa",
],
[
[0xFB, 0x80, 0x61],
"XXa"
"XXa",
],
[
[0xFC, 0x80, 0x61],
"XXa"
"XXa",
],
[
[0xFD, 0x80, 0x61],
"XXa"
"XXa",
],
[
[0xFE, 0x80, 0x61],
"XXa"
"XXa",
],
[
[0xFF, 0x80, 0x61],
"XXa"
"XXa",
],
// Characters outside the valid range.
[
[0xF5, 0x80, 0x80, 0x61],
"XXXa"
"XXXa",
],
[
[0xF6, 0x80, 0x80, 0x61],
"XXXa"
"XXXa",
],
[
[0xF7, 0x80, 0x80, 0x61],
"XXXa"
"XXXa",
],
[
[0xF8, 0x80, 0x80, 0x61],
"XXXa"
"XXXa",
],
[
[0xF9, 0x80, 0x80, 0x61],
"XXXa"
"XXXa",
],
[
[0xFA, 0x80, 0x80, 0x61],
"XXXa"
"XXXa",
],
[
[0xFB, 0x80, 0x80, 0x61],
"XXXa"
"XXXa",
],
[
[0xFC, 0x80, 0x80, 0x61],
"XXXa"
"XXXa",
],
[
[0xFD, 0x80, 0x80, 0x61],
"XXXa"
"XXXa",
],
[
[0xFE, 0x80, 0x80, 0x61],
"XXXa"
"XXXa",
],
[
[0xFF, 0x80, 0x80, 0x61],
"XXXa"
]
"XXXa",
],
];
main() {
@@ -214,46 +214,47 @@ main() {
// Pairs of test and expected string output when malformed strings are
// allowed. Replacement character: U+FFFD, one per unfinished sequence or
// undecodable byte.
String replacement =
TESTS0.contains(test) ? "\u{FFFD}" : "\u{FFFD}" * test.length;
String replacement = TESTS0.contains(test)
? "\u{FFFD}"
: "\u{FFFD}" * test.length;
return [
[test, "${replacement}"],
[
[0x61, ...test],
"a${replacement}"
"a${replacement}",
],
[
[0x61, ...test, 0x61],
"a${replacement}a"
"a${replacement}a",
],
[
[...test, 0x61],
"${replacement}a"
"${replacement}a",
],
[
[...test, ...test],
"${replacement}${replacement}"
"${replacement}${replacement}",
],
[
[...test, 0x61, ...test],
"${replacement}a${replacement}"
"${replacement}a${replacement}",
],
[
[0xc3, 0xa5, ...test],
"å${replacement}"
"å${replacement}",
],
[
[0xc3, 0xa5, ...test, 0xc3, 0xa5],
"å${replacement}å"
"å${replacement}å",
],
[
[...test, 0xc3, 0xa5],
"${replacement}å"
"${replacement}å",
],
[
[...test, 0xc3, 0xa5, ...test],
"${replacement}å${replacement}"
]
"${replacement}å${replacement}",
],
];
});
@@ -276,7 +277,10 @@ main() {
Expect.equals(expected, decodeAllowMalformed4(bytes));
}
for (var test in []..addAll(allTests)..addAll(allTests2)) {
for (var test
in []
..addAll(allTests)
..addAll(allTests2)) {
List<int> bytes = test[0];
String expected = test[1];
check(expected, bytes, 'plain list');
+58 -35
View File
@@ -15,56 +15,79 @@ test(List<int> bytes(List<int> input)) {
Expect.equals("a", utf8.decode(bytes([0xEF, 0xBB, 0xBF, 0x61])));
Expect.equals("a", utf8.decoder.convert(bytes([0xEF, 0xBB, 0xBF, 0x61])));
Expect.equals(
"a", new Utf8Decoder().convert(bytes([0xEF, 0xBB, 0xBF, 0x61])));
"a",
new Utf8Decoder().convert(bytes([0xEF, 0xBB, 0xBF, 0x61])),
);
Expect.equals(
"a", utf8.decode(bytes([0xEF, 0xBB, 0xBF, 0x61]), allowMalformed: true));
"a",
utf8.decode(bytes([0xEF, 0xBB, 0xBF, 0x61]), allowMalformed: true),
);
Expect.equals(
"a",
new Utf8Codec(allowMalformed: true)
.decode(bytes([0xEF, 0xBB, 0xBF, 0x61])));
"a",
new Utf8Codec(allowMalformed: true).decode(bytes([0xEF, 0xBB, 0xBF, 0x61])),
);
Expect.equals(
"a",
new Utf8Codec(allowMalformed: true)
.decoder
.convert(bytes([0xEF, 0xBB, 0xBF, 0x61])));
"a",
new Utf8Codec(
allowMalformed: true,
).decoder.convert(bytes([0xEF, 0xBB, 0xBF, 0x61])),
);
Expect.equals(
"a",
new Utf8Decoder(allowMalformed: true)
.convert(bytes([0xEF, 0xBB, 0xBF, 0x61])));
"a",
new Utf8Decoder(
allowMalformed: true,
).convert(bytes([0xEF, 0xBB, 0xBF, 0x61])),
);
Expect.equals("", utf8.decode(bytes([0xEF, 0xBB, 0xBF])));
Expect.equals("", utf8.decoder.convert(bytes([0xEF, 0xBB, 0xBF])));
Expect.equals("", new Utf8Decoder().convert(bytes([0xEF, 0xBB, 0xBF])));
Expect.equals(
"", utf8.decode(bytes([0xEF, 0xBB, 0xBF]), allowMalformed: true));
Expect.equals("",
new Utf8Codec(allowMalformed: true).decode(bytes([0xEF, 0xBB, 0xBF])));
"",
utf8.decode(bytes([0xEF, 0xBB, 0xBF]), allowMalformed: true),
);
Expect.equals(
"",
new Utf8Codec(allowMalformed: true)
.decoder
.convert(bytes([0xEF, 0xBB, 0xBF])));
Expect.equals("",
new Utf8Decoder(allowMalformed: true).convert(bytes([0xEF, 0xBB, 0xBF])));
"",
new Utf8Codec(allowMalformed: true).decode(bytes([0xEF, 0xBB, 0xBF])),
);
Expect.equals(
"",
new Utf8Codec(
allowMalformed: true,
).decoder.convert(bytes([0xEF, 0xBB, 0xBF])),
);
Expect.equals(
"",
new Utf8Decoder(allowMalformed: true).convert(bytes([0xEF, 0xBB, 0xBF])),
);
Expect.equals("a\u{FEFF}", utf8.decode(bytes([0x61, 0xEF, 0xBB, 0xBF])));
Expect.equals(
"a\u{FEFF}", utf8.decoder.convert(bytes([0x61, 0xEF, 0xBB, 0xBF])));
"a\u{FEFF}",
utf8.decoder.convert(bytes([0x61, 0xEF, 0xBB, 0xBF])),
);
Expect.equals(
"a\u{FEFF}", new Utf8Decoder().convert(bytes([0x61, 0xEF, 0xBB, 0xBF])));
Expect.equals("a\u{FEFF}",
utf8.decode(bytes([0x61, 0xEF, 0xBB, 0xBF]), allowMalformed: true));
"a\u{FEFF}",
new Utf8Decoder().convert(bytes([0x61, 0xEF, 0xBB, 0xBF])),
);
Expect.equals(
"a\u{FEFF}",
new Utf8Codec(allowMalformed: true)
.decode(bytes([0x61, 0xEF, 0xBB, 0xBF])));
"a\u{FEFF}",
utf8.decode(bytes([0x61, 0xEF, 0xBB, 0xBF]), allowMalformed: true),
);
Expect.equals(
"a\u{FEFF}",
new Utf8Codec(allowMalformed: true)
.decoder
.convert(bytes([0x61, 0xEF, 0xBB, 0xBF])));
"a\u{FEFF}",
new Utf8Codec(allowMalformed: true).decode(bytes([0x61, 0xEF, 0xBB, 0xBF])),
);
Expect.equals(
"a\u{FEFF}",
new Utf8Decoder(allowMalformed: true)
.convert(bytes([0x61, 0xEF, 0xBB, 0xBF])));
"a\u{FEFF}",
new Utf8Codec(
allowMalformed: true,
).decoder.convert(bytes([0x61, 0xEF, 0xBB, 0xBF])),
);
Expect.equals(
"a\u{FEFF}",
new Utf8Decoder(
allowMalformed: true,
).convert(bytes([0x61, 0xEF, 0xBB, 0xBF])),
);
}
main() {
+469 -292
View File
@@ -52,10 +52,11 @@ const List<int> testEnglishUtf8 = const <int>[
0x64,
0x6f,
0x67,
0x2e
0x2e,
];
const String testDanishPhrase = "Quizdeltagerne spiste jordbær med "
const String testDanishPhrase =
"Quizdeltagerne spiste jordbær med "
"fløde mens cirkusklovnen Wolther spillede på xylofon.";
const List<int> testDanishUtf8 = const <int>[
@@ -148,7 +149,7 @@ const List<int> testDanishUtf8 = const <int>[
0x66,
0x6f,
0x6e,
0x2e
0x2e,
];
// unusual formatting due to strange editor interaction w/ text direction.
@@ -245,10 +246,11 @@ const List<int> testHebrewUtf8 = const <int>[
0xd7,
0x98,
0xd7,
0x94
0x94,
];
const String testRussianPhrase = "Съешь же ещё этих мягких "
const String testRussianPhrase =
"Съешь же ещё этих мягких "
"французских булок да выпей чаю";
const List<int> testRussianUtf8 = const <int>[
@@ -352,10 +354,11 @@ const List<int> testRussianUtf8 = const <int>[
0xd0,
0xb0,
0xd1,
0x8e
0x8e,
];
const String testGreekPhrase = "Γαζέες καὶ μυρτιὲς δὲν θὰ βρῶ πιὰ "
const String testGreekPhrase =
"Γαζέες καὶ μυρτιὲς δὲν θὰ βρῶ πιὰ "
"στὸ χρυσαφὶ ξέφωτο";
const List<int> testGreekUtf8 = const <int>[
@@ -461,10 +464,11 @@ const List<int> testGreekUtf8 = const <int>[
0xcf,
0x84,
0xce,
0xbf
0xbf,
];
const String testKatakanaPhrase = "イロハニホヘト チリヌルヲ ワカヨタレソ "
const String testKatakanaPhrase =
"イロハニホヘト チリヌルヲ ワカヨタレソ "
"ツネナラム ウヰノオクヤマ ケフコエテ アサキユメミシ ヱヒモセスン";
const List<int> testKatakanaUtf8 = const <int>[
@@ -618,7 +622,7 @@ const List<int> testKatakanaUtf8 = const <int>[
0xb9,
0xe3,
0x83,
0xb3
0xb3,
];
void main() {
@@ -650,29 +654,48 @@ void testEncodeToUtf8() {
List<int> encodeUtf8(String str) => utf8.encode(str);
Expect.listEquals(
testEnglishUtf8, encodeUtf8(testEnglishPhrase), "english to utf8");
testEnglishUtf8,
encodeUtf8(testEnglishPhrase),
"english to utf8",
);
Expect.listEquals(
testDanishUtf8, encodeUtf8(testDanishPhrase), "encode danish to utf8");
testDanishUtf8,
encodeUtf8(testDanishPhrase),
"encode danish to utf8",
);
Expect.listEquals(
testHebrewUtf8, encodeUtf8(testHebrewPhrase), "Hebrew to utf8");
testHebrewUtf8,
encodeUtf8(testHebrewPhrase),
"Hebrew to utf8",
);
Expect.listEquals(
testRussianUtf8, encodeUtf8(testRussianPhrase), "Russian to utf8");
testRussianUtf8,
encodeUtf8(testRussianPhrase),
"Russian to utf8",
);
Expect.listEquals(
testGreekUtf8, encodeUtf8(testGreekPhrase), "Greek to utf8");
testGreekUtf8,
encodeUtf8(testGreekPhrase),
"Greek to utf8",
);
Expect.listEquals(
testKatakanaUtf8, encodeUtf8(testKatakanaPhrase), "Katakana to utf8");
testKatakanaUtf8,
encodeUtf8(testKatakanaPhrase),
"Katakana to utf8",
);
}
void testUtf8bytesToCodepoints(List<int> utf8ToRunes(List<int> utf8)) {
Expect.listEquals(
[954, 972, 963, 956, 949],
utf8ToRunes([0xce, 0xba, 0xcf, 0x8c, 0xcf, 0x83, 0xce, 0xbc, 0xce, 0xb5]),
"κόσμε");
[954, 972, 963, 956, 949],
utf8ToRunes([0xce, 0xba, 0xcf, 0x8c, 0xcf, 0x83, 0xce, 0xbc, 0xce, 0xb5]),
"κόσμε",
);
// boundary conditions: First possible sequence of a certain length
Expect.listEquals([], utf8ToRunes([]), "no input");
@@ -680,67 +703,103 @@ void testUtf8bytesToCodepoints(List<int> utf8ToRunes(List<int> utf8)) {
Expect.listEquals([0x80], utf8ToRunes([0xc2, 0x80]), "80");
Expect.listEquals([0x800], utf8ToRunes([0xe0, 0xa0, 0x80]), "800");
Expect.listEquals([0x10000], utf8ToRunes([0xf0, 0x90, 0x80, 0x80]), "10000");
Expect.listEquals([
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune
], utf8ToRunes([0xf8, 0x88, 0x80, 0x80, 0x80]), "200000");
Expect.listEquals([
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune
], utf8ToRunes([0xfc, 0x84, 0x80, 0x80, 0x80, 0x80]), "4000000");
Expect.listEquals(
[
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
],
utf8ToRunes([0xf8, 0x88, 0x80, 0x80, 0x80]),
"200000",
);
Expect.listEquals(
[
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
],
utf8ToRunes([0xfc, 0x84, 0x80, 0x80, 0x80, 0x80]),
"4000000",
);
// boundary conditions: Last possible sequence of a certain length
Expect.listEquals([0x7f], utf8ToRunes([0x7f]), "7f");
Expect.listEquals([0x7ff], utf8ToRunes([0xdf, 0xbf]), "7ff");
Expect.listEquals([0xffff], utf8ToRunes([0xef, 0xbf, 0xbf]), "ffff");
Expect.listEquals([
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune
], utf8ToRunes([0xf7, 0xbf, 0xbf, 0xbf]), "1fffff");
Expect.listEquals([
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune
], utf8ToRunes([0xfb, 0xbf, 0xbf, 0xbf, 0xbf]), "3ffffff");
Expect.listEquals([
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune
], utf8ToRunes([0xfd, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf]), "4000000");
Expect.listEquals(
[
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
],
utf8ToRunes([0xf7, 0xbf, 0xbf, 0xbf]),
"1fffff",
);
Expect.listEquals(
[
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
],
utf8ToRunes([0xfb, 0xbf, 0xbf, 0xbf, 0xbf]),
"3ffffff",
);
Expect.listEquals(
[
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
],
utf8ToRunes([0xfd, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf]),
"4000000",
);
// other boundary conditions
Expect.listEquals([0xd7ff], utf8ToRunes([0xed, 0x9f, 0xbf]), "d7ff");
Expect.listEquals([0xe000], utf8ToRunes([0xee, 0x80, 0x80]), "e000");
Expect.listEquals([unicodeReplacementCharacterRune],
utf8ToRunes([0xef, 0xbf, 0xbd]), "fffd");
Expect.listEquals(
[0x10ffff], utf8ToRunes([0xf4, 0x8f, 0xbf, 0xbf]), "10ffff");
Expect.listEquals([
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune
], utf8ToRunes([0xf4, 0x90, 0x80, 0x80]), "110000");
[unicodeReplacementCharacterRune],
utf8ToRunes([0xef, 0xbf, 0xbd]),
"fffd",
);
Expect.listEquals(
[0x10ffff],
utf8ToRunes([0xf4, 0x8f, 0xbf, 0xbf]),
"10ffff",
);
Expect.listEquals(
[
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
],
utf8ToRunes([0xf4, 0x90, 0x80, 0x80]),
"110000",
);
// unexpected continuation bytes
Expect.listEquals([unicodeReplacementCharacterRune], utf8ToRunes([0x80]),
"80 => replacement character");
Expect.listEquals([unicodeReplacementCharacterRune], utf8ToRunes([0xbf]),
"bf => replacement character");
Expect.listEquals(
[unicodeReplacementCharacterRune],
utf8ToRunes([0x80]),
"80 => replacement character",
);
Expect.listEquals(
[unicodeReplacementCharacterRune],
utf8ToRunes([0xbf]),
"bf => replacement character",
);
List<int> allContinuationBytes = <int>[];
List<int> matchingReplacementChars = <int>[];
@@ -748,8 +807,11 @@ void testUtf8bytesToCodepoints(List<int> utf8ToRunes(List<int> utf8)) {
allContinuationBytes.add(i);
matchingReplacementChars.add(unicodeReplacementCharacterRune);
}
Expect.listEquals(matchingReplacementChars, utf8ToRunes(allContinuationBytes),
"80 - bf => replacement character x 64");
Expect.listEquals(
matchingReplacementChars,
utf8ToRunes(allContinuationBytes),
"80 - bf => replacement character x 64",
);
List<int> allFirstTwoByteSeq = <int>[];
matchingReplacementChars = <int>[];
@@ -757,8 +819,11 @@ void testUtf8bytesToCodepoints(List<int> utf8ToRunes(List<int> utf8)) {
allFirstTwoByteSeq.addAll([i, 0x20]);
matchingReplacementChars.addAll([unicodeReplacementCharacterRune, 0x20]);
}
Expect.listEquals(matchingReplacementChars, utf8ToRunes(allFirstTwoByteSeq),
"c0 - df + space => replacement character + space x 32");
Expect.listEquals(
matchingReplacementChars,
utf8ToRunes(allFirstTwoByteSeq),
"c0 - df + space => replacement character + space x 32",
);
List<int> allFirstThreeByteSeq = <int>[];
matchingReplacementChars = <int>[];
@@ -766,8 +831,11 @@ void testUtf8bytesToCodepoints(List<int> utf8ToRunes(List<int> utf8)) {
allFirstThreeByteSeq.addAll([i, 0x20]);
matchingReplacementChars.addAll([unicodeReplacementCharacterRune, 0x20]);
}
Expect.listEquals(matchingReplacementChars, utf8ToRunes(allFirstThreeByteSeq),
"e0 - ef + space => replacement character x 16");
Expect.listEquals(
matchingReplacementChars,
utf8ToRunes(allFirstThreeByteSeq),
"e0 - ef + space => replacement character x 16",
);
List<int> allFirstFourByteSeq = <int>[];
matchingReplacementChars = <int>[];
@@ -775,8 +843,11 @@ void testUtf8bytesToCodepoints(List<int> utf8ToRunes(List<int> utf8)) {
allFirstFourByteSeq.addAll([i, 0x20]);
matchingReplacementChars.addAll([unicodeReplacementCharacterRune, 0x20]);
}
Expect.listEquals(matchingReplacementChars, utf8ToRunes(allFirstFourByteSeq),
"f0 - f7 + space => replacement character x 8");
Expect.listEquals(
matchingReplacementChars,
utf8ToRunes(allFirstFourByteSeq),
"f0 - f7 + space => replacement character x 8",
);
List<int> allFirstFiveByteSeq = <int>[];
matchingReplacementChars = <int>[];
@@ -784,8 +855,11 @@ void testUtf8bytesToCodepoints(List<int> utf8ToRunes(List<int> utf8)) {
allFirstFiveByteSeq.addAll([i, 0x20]);
matchingReplacementChars.addAll([unicodeReplacementCharacterRune, 0x20]);
}
Expect.listEquals(matchingReplacementChars, utf8ToRunes(allFirstFiveByteSeq),
"f8 - fb + space => replacement character x 4");
Expect.listEquals(
matchingReplacementChars,
utf8ToRunes(allFirstFiveByteSeq),
"f8 - fb + space => replacement character x 4",
);
List<int> allFirstSixByteSeq = <int>[];
matchingReplacementChars = <int>[];
@@ -793,235 +867,329 @@ void testUtf8bytesToCodepoints(List<int> utf8ToRunes(List<int> utf8)) {
allFirstSixByteSeq.addAll([i, 0x20]);
matchingReplacementChars.addAll([unicodeReplacementCharacterRune, 0x20]);
}
Expect.listEquals(matchingReplacementChars, utf8ToRunes(allFirstSixByteSeq),
"fc - fd + space => replacement character x 2");
Expect.listEquals(
matchingReplacementChars,
utf8ToRunes(allFirstSixByteSeq),
"fc - fd + space => replacement character x 2",
);
// Sequences with last continuation byte missing
Expect.listEquals([unicodeReplacementCharacterRune], utf8ToRunes([0xc2]),
"2-byte sequence with last byte missing");
Expect.listEquals(
[unicodeReplacementCharacterRune, unicodeReplacementCharacterRune],
utf8ToRunes([0xe0, 0x80]),
"3-byte sequence with last byte missing");
Expect.listEquals([
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune
], utf8ToRunes([0xf0, 0x80, 0x80]), "4-byte sequence with last byte missing");
Expect.listEquals([
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune
], utf8ToRunes([0xf8, 0x88, 0x80, 0x80]),
"5-byte sequence with last byte missing");
Expect.listEquals([
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune
], utf8ToRunes([0xfc, 0x80, 0x80, 0x80, 0x80]),
"6-byte sequence with last byte missing");
[unicodeReplacementCharacterRune],
utf8ToRunes([0xc2]),
"2-byte sequence with last byte missing",
);
Expect.listEquals(
[unicodeReplacementCharacterRune, unicodeReplacementCharacterRune],
utf8ToRunes([0xe0, 0x80]),
"3-byte sequence with last byte missing",
);
Expect.listEquals(
[
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
],
utf8ToRunes([0xf0, 0x80, 0x80]),
"4-byte sequence with last byte missing",
);
Expect.listEquals(
[
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
],
utf8ToRunes([0xf8, 0x88, 0x80, 0x80]),
"5-byte sequence with last byte missing",
);
Expect.listEquals(
[
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
],
utf8ToRunes([0xfc, 0x80, 0x80, 0x80, 0x80]),
"6-byte sequence with last byte missing",
);
Expect.listEquals([unicodeReplacementCharacterRune], utf8ToRunes([0xdf]),
"2-byte sequence with last byte missing (hi)");
Expect.listEquals([unicodeReplacementCharacterRune],
utf8ToRunes([0xef, 0xbf]), "3-byte sequence with last byte missing (hi)");
Expect.listEquals([
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune
], utf8ToRunes([0xf7, 0xbf, 0xbf]),
"4-byte sequence with last byte missing (hi)");
Expect.listEquals([
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune
], utf8ToRunes([0xfb, 0xbf, 0xbf, 0xbf]),
"5-byte sequence with last byte missing (hi)");
Expect.listEquals([
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune
], utf8ToRunes([0xfd, 0xbf, 0xbf, 0xbf, 0xbf]),
"6-byte sequence with last byte missing (hi)");
Expect.listEquals(
[unicodeReplacementCharacterRune],
utf8ToRunes([0xdf]),
"2-byte sequence with last byte missing (hi)",
);
Expect.listEquals(
[unicodeReplacementCharacterRune],
utf8ToRunes([0xef, 0xbf]),
"3-byte sequence with last byte missing (hi)",
);
Expect.listEquals(
[
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
],
utf8ToRunes([0xf7, 0xbf, 0xbf]),
"4-byte sequence with last byte missing (hi)",
);
Expect.listEquals(
[
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
],
utf8ToRunes([0xfb, 0xbf, 0xbf, 0xbf]),
"5-byte sequence with last byte missing (hi)",
);
Expect.listEquals(
[
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
],
utf8ToRunes([0xfd, 0xbf, 0xbf, 0xbf, 0xbf]),
"6-byte sequence with last byte missing (hi)",
);
// Concatenation of incomplete sequences
Expect.listEquals(
[
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune
],
utf8ToRunes([
0xc2,
0xe0,
0x80,
0xf0,
0x80,
0x80,
0xf8,
0x88,
0x80,
0x80,
0xfc,
0x80,
0x80,
0x80,
0x80,
0xdf,
0xef, // These two bytes form one incomplete sequence.
0xbf, // All others form one per byte.
0xf7,
0xbf,
0xbf,
0xfb,
0xbf,
0xbf,
0xbf,
0xfd,
0xbf,
0xbf,
0xbf,
0xbf
]),
"Concatenation of incomplete sequences");
[
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
],
utf8ToRunes([
0xc2,
0xe0,
0x80,
0xf0,
0x80,
0x80,
0xf8,
0x88,
0x80,
0x80,
0xfc,
0x80,
0x80,
0x80,
0x80,
0xdf,
0xef, // These two bytes form one incomplete sequence.
0xbf, // All others form one per byte.
0xf7,
0xbf,
0xbf,
0xfb,
0xbf,
0xbf,
0xbf,
0xfd,
0xbf,
0xbf,
0xbf,
0xbf,
]),
"Concatenation of incomplete sequences",
);
// Impossible bytes
Expect.listEquals(
[unicodeReplacementCharacterRune], utf8ToRunes([0xfe]), "fe");
[unicodeReplacementCharacterRune],
utf8ToRunes([0xfe]),
"fe",
);
Expect.listEquals(
[unicodeReplacementCharacterRune], utf8ToRunes([0xff]), "ff");
Expect.listEquals([
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune
], utf8ToRunes([0xfe, 0xfe, 0xff, 0xff]), "fe fe ff ff");
[unicodeReplacementCharacterRune],
utf8ToRunes([0xff]),
"ff",
);
Expect.listEquals(
[
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
],
utf8ToRunes([0xfe, 0xfe, 0xff, 0xff]),
"fe fe ff ff",
);
// Overlong sequences
Expect.listEquals(
[unicodeReplacementCharacterRune, unicodeReplacementCharacterRune],
utf8ToRunes([0xc0, 0xaf]),
"c0 af");
Expect.listEquals([
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune
], utf8ToRunes([0xe0, 0x80, 0xaf]), "e0 80 af");
Expect.listEquals([
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune
], utf8ToRunes([0xf0, 0x80, 0x80, 0xaf]), "f0 80 80 af");
Expect.listEquals([
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune
], utf8ToRunes([0xf8, 0x80, 0x80, 0x80, 0xaf]), "f8 80 80 80 af");
Expect.listEquals([
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune
], utf8ToRunes([0xfc, 0x80, 0x80, 0x80, 0x80, 0xaf]), "fc 80 80 80 80 af");
[unicodeReplacementCharacterRune, unicodeReplacementCharacterRune],
utf8ToRunes([0xc0, 0xaf]),
"c0 af",
);
Expect.listEquals(
[
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
],
utf8ToRunes([0xe0, 0x80, 0xaf]),
"e0 80 af",
);
Expect.listEquals(
[
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
],
utf8ToRunes([0xf0, 0x80, 0x80, 0xaf]),
"f0 80 80 af",
);
Expect.listEquals(
[
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
],
utf8ToRunes([0xf8, 0x80, 0x80, 0x80, 0xaf]),
"f8 80 80 80 af",
);
Expect.listEquals(
[
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
],
utf8ToRunes([0xfc, 0x80, 0x80, 0x80, 0x80, 0xaf]),
"fc 80 80 80 80 af",
);
Expect.listEquals(
[unicodeReplacementCharacterRune, unicodeReplacementCharacterRune],
utf8ToRunes([0xc1, 0xbf]),
"c1 bf");
Expect.listEquals([
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune
], utf8ToRunes([0xe0, 0x9f, 0xbf]), "e0 9f bf");
Expect.listEquals([
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune
], utf8ToRunes([0xf0, 0x8f, 0xbf, 0xbf]), "f0 8f bf bf");
Expect.listEquals([
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune
], utf8ToRunes([0xf8, 0x87, 0xbf, 0xbf, 0xbf]), "f8 87 bf bf bf");
Expect.listEquals([
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune
], utf8ToRunes([0xfc, 0x83, 0xbf, 0xbf, 0xbf, 0xbf]), "fc 83 bf bf bf bf");
[unicodeReplacementCharacterRune, unicodeReplacementCharacterRune],
utf8ToRunes([0xc1, 0xbf]),
"c1 bf",
);
Expect.listEquals(
[
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
],
utf8ToRunes([0xe0, 0x9f, 0xbf]),
"e0 9f bf",
);
Expect.listEquals(
[
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
],
utf8ToRunes([0xf0, 0x8f, 0xbf, 0xbf]),
"f0 8f bf bf",
);
Expect.listEquals(
[
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
],
utf8ToRunes([0xf8, 0x87, 0xbf, 0xbf, 0xbf]),
"f8 87 bf bf bf",
);
Expect.listEquals(
[
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
],
utf8ToRunes([0xfc, 0x83, 0xbf, 0xbf, 0xbf, 0xbf]),
"fc 83 bf bf bf bf",
);
Expect.listEquals(
[unicodeReplacementCharacterRune, unicodeReplacementCharacterRune],
utf8ToRunes([0xc0, 0x80]),
"c0 80");
Expect.listEquals([
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune
], utf8ToRunes([0xe0, 0x80, 0x80]), "e0 80 80");
Expect.listEquals([
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune
], utf8ToRunes([0xf0, 0x80, 0x80, 0x80]), "f0 80 80 80");
Expect.listEquals([
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune
], utf8ToRunes([0xf8, 0x80, 0x80, 0x80, 0x80]), "f8 80 80 80 80");
Expect.listEquals([
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune
], utf8ToRunes([0xfc, 0x80, 0x80, 0x80, 0x80, 0x80]), "fc 80 80 80 80 80");
[unicodeReplacementCharacterRune, unicodeReplacementCharacterRune],
utf8ToRunes([0xc0, 0x80]),
"c0 80",
);
Expect.listEquals(
[
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
],
utf8ToRunes([0xe0, 0x80, 0x80]),
"e0 80 80",
);
Expect.listEquals(
[
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
],
utf8ToRunes([0xf0, 0x80, 0x80, 0x80]),
"f0 80 80 80",
);
Expect.listEquals(
[
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
],
utf8ToRunes([0xf8, 0x80, 0x80, 0x80, 0x80]),
"f8 80 80 80 80",
);
Expect.listEquals(
[
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
unicodeReplacementCharacterRune,
],
utf8ToRunes([0xfc, 0x80, 0x80, 0x80, 0x80, 0x80]),
"fc 80 80 80 80 80",
);
// Other illegal code positions (???)
Expect.listEquals([0xfffe], utf8ToRunes([0xef, 0xbf, 0xbe]), "U+FFFE");
@@ -1030,17 +1198,26 @@ void testUtf8bytesToCodepoints(List<int> utf8ToRunes(List<int> utf8)) {
void testUtf8BytesToString(String decodeUtf8(List<int> input)) {
Expect.stringEquals(
testEnglishPhrase, decodeUtf8(testEnglishUtf8), "English");
testEnglishPhrase,
decodeUtf8(testEnglishUtf8),
"English",
);
Expect.stringEquals(testDanishPhrase, decodeUtf8(testDanishUtf8), "Danish");
Expect.stringEquals(testHebrewPhrase, decodeUtf8(testHebrewUtf8), "Hebrew");
Expect.stringEquals(
testRussianPhrase, decodeUtf8(testRussianUtf8), "Russian");
testRussianPhrase,
decodeUtf8(testRussianUtf8),
"Russian",
);
Expect.stringEquals(testGreekPhrase, decodeUtf8(testGreekUtf8), "Greek");
Expect.stringEquals(
testKatakanaPhrase, decodeUtf8(testKatakanaUtf8), "Katakana");
testKatakanaPhrase,
decodeUtf8(testKatakanaUtf8),
"Katakana",
);
}
+3 -1
View File
@@ -11,6 +11,8 @@ main() {
for (int i = 0; i <= 0x10FFFF; i++) {
if (i == unicodeBomCharacterRune || (i & 0x1FF800) == 0xD800) continue;
Expect.equals(
i, utf8.decode(utf8.encode(new String.fromCharCode(i))).runes.first);
i,
utf8.decode(utf8.encode(new String.fromCharCode(i))).runes.first,
);
}
}
+61 -14
View File
@@ -25,8 +25,13 @@ void testEncodeSlice() {
String ascii = "ABCDE";
Expect.listEquals([0x41, 0x42, 0x43, 0x44, 0x45], encoder.convert(ascii));
Expect.listEquals([0x41, 0x42, 0x43, 0x44, 0x45], encoder.convert(ascii, 0));
Expect.listEquals(
[0x41, 0x42, 0x43, 0x44, 0x45], encoder.convert(ascii, 0, 5));
Expect.listEquals([
0x41,
0x42,
0x43,
0x44,
0x45,
], encoder.convert(ascii, 0, 5));
Expect.listEquals([0x42, 0x43, 0x44, 0x45], encoder.convert(ascii, 1));
Expect.listEquals([0x41, 0x42, 0x43, 0x44], encoder.convert(ascii, 0, 4));
Expect.listEquals([0x42, 0x43, 0x44], encoder.convert(ascii, 1, 4));
@@ -39,17 +44,59 @@ void testEncodeSlice() {
var unicode = "\u0081\u0082\u1041\u{10101}";
Expect.listEquals(
[0xc2, 0x81, 0xc2, 0x82, 0xe1, 0x81, 0x81, 0xf0, 0x90, 0x84, 0x81],
encoder.convert(unicode));
Expect.listEquals(
[0xc2, 0x81, 0xc2, 0x82, 0xe1, 0x81, 0x81, 0xf0, 0x90, 0x84, 0x81],
encoder.convert(unicode, 0, unicode.length));
Expect.listEquals([0xc2, 0x82, 0xe1, 0x81, 0x81, 0xf0, 0x90, 0x84, 0x81],
encoder.convert(unicode, 1));
Expect.listEquals(
[0xc2, 0x82, 0xe1, 0x81, 0x81], encoder.convert(unicode, 1, 3));
Expect.listEquals([
0xc2,
0x81,
0xc2,
0x82,
0xe1,
0x81,
0x81,
0xf0,
0x90,
0x84,
0x81,
], encoder.convert(unicode));
Expect.listEquals([
0xc2,
0x81,
0xc2,
0x82,
0xe1,
0x81,
0x81,
0xf0,
0x90,
0x84,
0x81,
], encoder.convert(unicode, 0, unicode.length));
Expect.listEquals([
0xc2,
0x82,
0xe1,
0x81,
0x81,
0xf0,
0x90,
0x84,
0x81,
], encoder.convert(unicode, 1));
Expect.listEquals([
0xc2,
0x82,
0xe1,
0x81,
0x81,
], encoder.convert(unicode, 1, 3));
// Split in the middle of a surrogate pair.
Expect.listEquals([0xc2, 0x82, 0xe1, 0x81, 0x81, 0xef, 0xbf, 0xbd],
encoder.convert(unicode, 1, 4));
Expect.listEquals([
0xc2,
0x82,
0xe1,
0x81,
0x81,
0xef,
0xbf,
0xbd,
], encoder.convert(unicode, 1, 4));
}
+20 -8
View File
@@ -34,12 +34,16 @@ void testDecodeSlice() {
if (ascii is Uint8List) {
Expect.equals("ABCDE", decoder.convert(Uint8List.sublistView(ascii, 0)));
Expect.equals("ABCDE",
decoder.convert(Uint8List.sublistView(ascii, 0, ascii.length)));
Expect.equals(
"ABCDE",
decoder.convert(Uint8List.sublistView(ascii, 0, ascii.length)),
);
Expect.equals("CDE", decoder.convert(Uint8List.sublistView(ascii, 2)));
Expect.equals("BCD", decoder.convert(Uint8List.sublistView(ascii, 1, 4)));
Expect.equals(
"ABCD", decoder.convert(Uint8List.sublistView(ascii, 0, 4)));
"ABCD",
decoder.convert(Uint8List.sublistView(ascii, 0, 4)),
);
}
Expect.throws(() => decoder.convert(ascii, -1)); // start < 0.
@@ -60,14 +64,22 @@ void testDecodeSlice() {
Expect.equals("\u0082", decoder.convert(utf8, 2, 4));
if (utf8 is Uint8List) {
Expect.equals("\u0081\u0082\u1041",
decoder.convert(Uint8List.sublistView(utf8, 0)));
Expect.equals(
"\u0082\u1041", decoder.convert(Uint8List.sublistView(utf8, 2)));
"\u0081\u0082\u1041",
decoder.convert(Uint8List.sublistView(utf8, 0)),
);
Expect.equals(
"\u0081\u0082", decoder.convert(Uint8List.sublistView(utf8, 0, 4)));
"\u0082\u1041",
decoder.convert(Uint8List.sublistView(utf8, 2)),
);
Expect.equals(
"\u0082", decoder.convert(Uint8List.sublistView(utf8, 2, 4)));
"\u0081\u0082",
decoder.convert(Uint8List.sublistView(utf8, 0, 4)),
);
Expect.equals(
"\u0082",
decoder.convert(Uint8List.sublistView(utf8, 2, 4)),
);
}
Expect.throws(() => decoder.convert(utf8, 1));
+1 -1
View File
@@ -17,7 +17,7 @@ final protectedStreams = [
'Logging',
'Timeline',
'Profiler',
'_aStreamThatStartsWithAnUnderScore'
'_aStreamThatStartsWithAnUnderScore',
];
main() {