OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 import 'dart:async'; |
| 6 |
| 7 import 'package:charcode/ascii.dart'; |
| 8 import 'package:convert/convert.dart'; |
| 9 import 'package:test/test.dart'; |
| 10 |
| 11 void main() { |
| 12 group("encoder", () { |
| 13 test("doesn't percent-encode unreserved characters", () { |
| 14 expect(percent.encode([ |
| 15 $a, $b, $c, $d, $e, $f, $g, $h, $i, $j, $k, $l, $m, $n, $o, $p, $q, $r, |
| 16 $s, $t, $u, $v, $w, $x, $y, $z, $A, $B, $C, $D, $E, $F, $G, $H, $I, $J, |
| 17 $K, $L, $M, $N, $O, $P, $Q, $R, $S, $T, $U, $V, $W, $X, $Y, $Z, $dash, |
| 18 $dot, $underscore, $tilde |
| 19 ]), equals("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-._~")); |
| 20 }); |
| 21 |
| 22 test("percent-encodes reserved ASCII characters", () { |
| 23 expect(percent.encode([ |
| 24 $space, $backquote, $open_brace, $at, $open_bracket, $comma, |
| 25 $division, $caret, $close_brace, $del, $nul, $percent |
| 26 ]), equals("%20%60%7B%40%5B%2C%2F%5E%7D%7F%00%25")); |
| 27 }); |
| 28 |
| 29 test("percent-encodes non-ASCII characters", () { |
| 30 expect(percent.encode([0x80, 0xFF]), equals("%80%FF")); |
| 31 }); |
| 32 |
| 33 test("mixes encoded and unencoded characters", () { |
| 34 expect(percent.encode([$a, $plus, $b, $equal, 0x80]), |
| 35 equals("a%2Bb%3D%80")); |
| 36 }); |
| 37 |
| 38 group("with chunked conversion", () { |
| 39 test("percent-encodes byte arrays", () { |
| 40 var results = []; |
| 41 var controller = new StreamController(sync: true); |
| 42 controller.stream.listen(results.add); |
| 43 var sink = percent.encoder.startChunkedConversion(controller.sink); |
| 44 |
| 45 sink.add([$a, $plus, $b, $equal, 0x80]); |
| 46 expect(results, equals(["a%2Bb%3D%80"])); |
| 47 |
| 48 sink.add([0x00, 0x01, 0xfe, 0xff]); |
| 49 expect(results, equals(["a%2Bb%3D%80", "%00%01%FE%FF"])); |
| 50 }); |
| 51 |
| 52 test("handles empty and single-byte lists", () { |
| 53 var results = []; |
| 54 var controller = new StreamController(sync: true); |
| 55 controller.stream.listen(results.add); |
| 56 var sink = percent.encoder.startChunkedConversion(controller.sink); |
| 57 |
| 58 sink.add([]); |
| 59 expect(results, equals([""])); |
| 60 |
| 61 sink.add([0x00]); |
| 62 expect(results, equals(["", "%00"])); |
| 63 |
| 64 sink.add([]); |
| 65 expect(results, equals(["", "%00", ""])); |
| 66 }); |
| 67 }); |
| 68 |
| 69 test("rejects non-bytes", () { |
| 70 expect(() => percent.encode([0x100]), throwsFormatException); |
| 71 |
| 72 var sink = percent.encoder.startChunkedConversion( |
| 73 new StreamController(sync: true)); |
| 74 expect(() => sink.add([0x100]), throwsFormatException); |
| 75 }); |
| 76 }); |
| 77 |
| 78 group("decoder", () { |
| 79 test("converts percent-encoded strings to byte arrays", () { |
| 80 expect(percent.decode("a%2Bb%3D%80"), |
| 81 equals([$a, $plus, $b, $equal, 0x80])); |
| 82 }); |
| 83 |
| 84 test("supports lowercase letters", () { |
| 85 expect(percent.decode("a%2bb%3d%80"), |
| 86 equals([$a, $plus, $b, $equal, 0x80])); |
| 87 }); |
| 88 |
| 89 test("supports more aggressive encoding", () { |
| 90 expect(percent.decode("%61%2E%5A"), equals([$a, $dot, $Z])); |
| 91 }); |
| 92 |
| 93 test("supports less aggressive encoding", () { |
| 94 expect(percent.decode(" `{@[,/^}\x7F\x00"), equals([ |
| 95 $space, $backquote, $open_brace, $at, $open_bracket, $comma, |
| 96 $division, $caret, $close_brace, $del, $nul |
| 97 ])); |
| 98 }); |
| 99 |
| 100 group("with chunked conversion", () { |
| 101 var results; |
| 102 var sink; |
| 103 setUp(() { |
| 104 results = []; |
| 105 var controller = new StreamController(sync: true); |
| 106 controller.stream.listen(results.add); |
| 107 sink = percent.decoder.startChunkedConversion(controller.sink); |
| 108 }); |
| 109 |
| 110 test("converts percent to byte arrays", () { |
| 111 sink.add("a%2Bb%3D%80"); |
| 112 expect(results, equals([[$a, $plus, $b, $equal, 0x80]])); |
| 113 |
| 114 sink.add("%00%01%FE%FF"); |
| 115 expect(results, |
| 116 equals([[$a, $plus, $b, $equal, 0x80], [0x00, 0x01, 0xfe, 0xff]])); |
| 117 }); |
| 118 |
| 119 test("supports trailing percents and digits split across chunks", () { |
| 120 sink.add("ab%"); |
| 121 expect(results, equals([[$a, $b]])); |
| 122 |
| 123 sink.add("2"); |
| 124 expect(results, equals([[$a, $b]])); |
| 125 |
| 126 sink.add("0cd%2"); |
| 127 expect(results, equals([[$a, $b], [$space, $c, $d]])); |
| 128 |
| 129 sink.add("0"); |
| 130 expect(results, equals(([[$a, $b], [$space, $c, $d], [$space]]))); |
| 131 }); |
| 132 |
| 133 test("supports empty strings", () { |
| 134 sink.add(""); |
| 135 expect(results, isEmpty); |
| 136 |
| 137 sink.add("%"); |
| 138 expect(results, equals([[]])); |
| 139 |
| 140 sink.add(""); |
| 141 expect(results, equals([[]])); |
| 142 |
| 143 sink.add("2"); |
| 144 expect(results, equals([[]])); |
| 145 |
| 146 sink.add(""); |
| 147 expect(results, equals([[]])); |
| 148 |
| 149 sink.add("0"); |
| 150 expect(results, equals([[], [0x20]])); |
| 151 }); |
| 152 |
| 153 test("rejects dangling % detected in close()", () { |
| 154 sink.add("ab%"); |
| 155 expect(results, equals([[$a, $b]])); |
| 156 expect(() => sink.close(), throwsFormatException); |
| 157 }); |
| 158 |
| 159 test("rejects dangling digit detected in close()", () { |
| 160 sink.add("ab%2"); |
| 161 expect(results, equals([[$a, $b]])); |
| 162 expect(() => sink.close(), throwsFormatException); |
| 163 }); |
| 164 |
| 165 test("rejects danging % detected in addSlice()", () { |
| 166 sink.addSlice("ab%", 0, 3, false); |
| 167 expect(results, equals([[$a, $b]])); |
| 168 |
| 169 expect(() => sink.addSlice("ab%", 0, 3, true), |
| 170 throwsFormatException); |
| 171 }); |
| 172 |
| 173 test("rejects danging digit detected in addSlice()", () { |
| 174 sink.addSlice("ab%2", 0, 3, false); |
| 175 expect(results, equals([[$a, $b]])); |
| 176 |
| 177 expect(() => sink.addSlice("ab%2", 0, 3, true), |
| 178 throwsFormatException); |
| 179 }); |
| 180 }); |
| 181 |
| 182 group("rejects non-ASCII character", () { |
| 183 for (var char in ["\u0141", "\u{10041}"]) { |
| 184 test('"$char"', () { |
| 185 expect(() => percent.decode("a$char"), throwsFormatException); |
| 186 expect(() => percent.decode("${char}a"), throwsFormatException); |
| 187 |
| 188 var sink = percent.decoder.startChunkedConversion( |
| 189 new StreamController(sync: true)); |
| 190 expect(() => sink.add(char), throwsFormatException); |
| 191 }); |
| 192 } |
| 193 }); |
| 194 |
| 195 test("rejects % followed by non-hex", () { |
| 196 expect(() => percent.decode("%z2"), throwsFormatException); |
| 197 expect(() => percent.decode("%2z"), throwsFormatException); |
| 198 }); |
| 199 |
| 200 test("rejects dangling % detected in convert()", () { |
| 201 expect(() => percent.decode("ab%"), throwsFormatException); |
| 202 }); |
| 203 |
| 204 test("rejects dangling digit detected in convert()", () { |
| 205 expect(() => percent.decode("ab%2"), throwsFormatException); |
| 206 }); |
| 207 }); |
| 208 } |
OLD | NEW |