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:
committed by
Commit Queue
parent
f94efba51e
commit
bf13a576fd
@@ -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.
|
||||
|
||||
@@ -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,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -10,7 +10,8 @@ const _NOOP = 'Nothing_to_escape';
|
||||
|
||||
const _TEST_INPUT = """<A </test> of \xA0 "double" & 'single' values>""";
|
||||
|
||||
const _OUTPUT_UNKNOWN = '<A </test> of \xA0 "double" '
|
||||
const _OUTPUT_UNKNOWN =
|
||||
'<A </test> of \xA0 "double" '
|
||||
'& 'single' values>';
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -39,8 +39,8 @@ _expandUnicodeTests() {
|
||||
// For example: 'abcd' -> '[[["abcd"]]]'.
|
||||
var listExpected = [
|
||||
[
|
||||
[string]
|
||||
]
|
||||
[string],
|
||||
],
|
||||
];
|
||||
var inListBytes = <int>[];
|
||||
inListBytes.addAll([_bracketOpen, _bracketOpen, _bracketOpen]);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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]]);
|
||||
}
|
||||
|
||||
@@ -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\\".'),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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
@@ -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",
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -17,7 +17,7 @@ final protectedStreams = [
|
||||
'Logging',
|
||||
'Timeline',
|
||||
'Profiler',
|
||||
'_aStreamThatStartsWithAnUnderScore'
|
||||
'_aStreamThatStartsWithAnUnderScore',
|
||||
];
|
||||
|
||||
main() {
|
||||
|
||||
Reference in New Issue
Block a user