OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library uriTest; | 5 library uriTest; |
6 | 6 |
7 import "package:expect/expect.dart"; | 7 import "package:expect/expect.dart"; |
8 import 'dart:convert'; | 8 import 'dart:convert'; |
9 | 9 |
10 testUri(String uriText, bool isAbsolute) { | 10 testUri(String uriText, bool isAbsolute) { |
11 var uri = Uri.parse(uriText); | 11 var uri = Uri.parse(uriText); |
12 | 12 |
13 Expect.equals(isAbsolute, uri.isAbsolute); | 13 Expect.equals(isAbsolute, uri.isAbsolute); |
14 Expect.stringEquals(uriText, uri.toString()); | 14 Expect.stringEquals(uriText, uri.toString()); |
15 | 15 |
16 // Test equals and hashCode members. | 16 // Test equals and hashCode members. |
17 var uri2 = Uri.parse(uriText); | 17 var uri2 = Uri.parse(uriText); |
18 Expect.equals(uri, uri2); | 18 Expect.equals(uri, uri2); |
19 Expect.equals(uri.hashCode, uri2.hashCode); | 19 Expect.equals(uri.hashCode, uri2.hashCode); |
20 | 20 |
21 // Test that removeFragment doesn't change anything else. | 21 // Test that removeFragment doesn't change anything else. |
22 if (uri.hasFragment) { | 22 if (uri.hasFragment) { |
23 Expect.equals(Uri.parse(uriText.substring(0, uriText.indexOf('#'))), | 23 Expect.equals(Uri.parse(uriText.substring(0, uriText.indexOf('#'))), |
24 uri.removeFragment()); | 24 uri.removeFragment()); |
25 } else { | 25 } else { |
26 Expect.equals(uri, | 26 Expect.equals(uri, Uri.parse(uriText + "#fragment").removeFragment()); |
27 Uri.parse(uriText + "#fragment").removeFragment()); | |
28 } | 27 } |
29 } | 28 } |
30 | 29 |
31 testEncodeDecode(String orig, String encoded) { | 30 testEncodeDecode(String orig, String encoded) { |
32 var e = Uri.encodeFull(orig); | 31 var e = Uri.encodeFull(orig); |
33 Expect.stringEquals(encoded, e); | 32 Expect.stringEquals(encoded, e); |
34 var d = Uri.decodeFull(encoded); | 33 var d = Uri.decodeFull(encoded); |
35 Expect.stringEquals(orig, d); | 34 Expect.stringEquals(orig, d); |
36 } | 35 } |
37 | 36 |
38 testEncodeDecodeComponent(String orig, String encoded) { | 37 testEncodeDecodeComponent(String orig, String encoded) { |
39 var e = Uri.encodeComponent(orig); | 38 var e = Uri.encodeComponent(orig); |
40 Expect.stringEquals(encoded, e); | 39 Expect.stringEquals(encoded, e); |
41 var d = Uri.decodeComponent(encoded); | 40 var d = Uri.decodeComponent(encoded); |
42 Expect.stringEquals(orig, d); | 41 Expect.stringEquals(orig, d); |
43 } | 42 } |
44 | 43 |
45 testEncodeDecodeQueryComponent(String orig, | 44 testEncodeDecodeQueryComponent(String orig, String encodedUTF8, |
46 String encodedUTF8, | 45 String encodedLatin1, String encodedAscii) { |
47 String encodedLatin1, | |
48 String encodedAscii) { | |
49 var e, d; | 46 var e, d; |
50 e = Uri.encodeQueryComponent(orig); | 47 e = Uri.encodeQueryComponent(orig); |
51 Expect.stringEquals(encodedUTF8, e); | 48 Expect.stringEquals(encodedUTF8, e); |
52 d = Uri.decodeQueryComponent(encodedUTF8); | 49 d = Uri.decodeQueryComponent(encodedUTF8); |
53 Expect.stringEquals(orig, d); | 50 Expect.stringEquals(orig, d); |
54 | 51 |
55 e = Uri.encodeQueryComponent(orig, encoding: UTF8); | 52 e = Uri.encodeQueryComponent(orig, encoding: UTF8); |
56 Expect.stringEquals(encodedUTF8, e); | 53 Expect.stringEquals(encodedUTF8, e); |
57 d = Uri.decodeQueryComponent(encodedUTF8, encoding: UTF8); | 54 d = Uri.decodeQueryComponent(encodedUTF8, encoding: UTF8); |
58 Expect.stringEquals(orig, d); | 55 Expect.stringEquals(orig, d); |
59 | 56 |
60 e = Uri.encodeQueryComponent(orig, encoding: LATIN1); | 57 e = Uri.encodeQueryComponent(orig, encoding: LATIN1); |
61 Expect.stringEquals(encodedLatin1, e); | 58 Expect.stringEquals(encodedLatin1, e); |
62 d = Uri.decodeQueryComponent(encodedLatin1, encoding: LATIN1); | 59 d = Uri.decodeQueryComponent(encodedLatin1, encoding: LATIN1); |
63 Expect.stringEquals(orig, d); | 60 Expect.stringEquals(orig, d); |
64 | 61 |
65 if (encodedAscii != null) { | 62 if (encodedAscii != null) { |
66 e = Uri.encodeQueryComponent(orig, encoding: ASCII); | 63 e = Uri.encodeQueryComponent(orig, encoding: ASCII); |
67 Expect.stringEquals(encodedAscii, e); | 64 Expect.stringEquals(encodedAscii, e); |
68 d = Uri.decodeQueryComponent(encodedAscii, encoding: ASCII); | 65 d = Uri.decodeQueryComponent(encodedAscii, encoding: ASCII); |
69 Expect.stringEquals(orig, d); | 66 Expect.stringEquals(orig, d); |
70 } else { | 67 } else { |
71 Expect.throws(() => Uri.encodeQueryComponent(orig, encoding: ASCII), | 68 Expect.throws(() => Uri.encodeQueryComponent(orig, encoding: ASCII), |
72 (e) => e is ArgumentError); | 69 (e) => e is ArgumentError); |
73 } | 70 } |
74 } | 71 } |
75 | 72 |
76 testUriPerRFCs() { | 73 testUriPerRFCs() { |
77 final urisSample = "http://a/b/c/d;p?q"; | 74 final urisSample = "http://a/b/c/d;p?q"; |
78 Uri base = Uri.parse(urisSample); | 75 Uri base = Uri.parse(urisSample); |
79 testResolve(expect, relative) { | 76 testResolve(expect, relative) { |
80 Expect.stringEquals(expect, base.resolve(relative).toString()); | 77 Expect.stringEquals(expect, base.resolve(relative).toString()); |
81 } | 78 } |
82 | 79 |
83 // From RFC 3986. | 80 // From RFC 3986. |
84 testResolve("g:h", "g:h"); | 81 testResolve("g:h", "g:h"); |
85 testResolve("http://a/b/c/g", "g"); | 82 testResolve("http://a/b/c/g", "g"); |
86 testResolve("http://a/b/c/g", "./g"); | 83 testResolve("http://a/b/c/g", "./g"); |
87 testResolve("http://a/b/c/g/", "g/"); | 84 testResolve("http://a/b/c/g/", "g/"); |
88 testResolve("http://a/g", "/g"); | 85 testResolve("http://a/g", "/g"); |
89 testResolve("http://g", "//g"); | 86 testResolve("http://g", "//g"); |
90 testResolve("http://a/b/c/d;p?y", "?y"); | 87 testResolve("http://a/b/c/d;p?y", "?y"); |
91 testResolve("http://a/b/c/g?y", "g?y"); | 88 testResolve("http://a/b/c/g?y", "g?y"); |
92 testResolve("http://a/b/c/d;p?q#s", "#s"); | 89 testResolve("http://a/b/c/d;p?q#s", "#s"); |
93 testResolve("http://a/b/c/g#s", "g#s"); | 90 testResolve("http://a/b/c/g#s", "g#s"); |
94 testResolve("http://a/b/c/g?y#s", "g?y#s"); | 91 testResolve("http://a/b/c/g?y#s", "g?y#s"); |
95 testResolve("http://a/b/c/;x", ";x"); | 92 testResolve("http://a/b/c/;x", ";x"); |
96 testResolve("http://a/b/c/g;x", "g;x"); | 93 testResolve("http://a/b/c/g;x", "g;x"); |
97 testResolve("http://a/b/c/g;x?y#s", "g;x?y#s"); | 94 testResolve("http://a/b/c/g;x?y#s", "g;x?y#s"); |
98 testResolve("http://a/b/c/d;p?q", ""); | 95 testResolve("http://a/b/c/d;p?q", ""); |
99 testResolve("http://a/b/c/", "."); | 96 testResolve("http://a/b/c/", "."); |
100 testResolve("http://a/b/c/", "./"); | 97 testResolve("http://a/b/c/", "./"); |
101 testResolve("http://a/b/", ".."); | 98 testResolve("http://a/b/", ".."); |
102 testResolve("http://a/b/", "../"); | 99 testResolve("http://a/b/", "../"); |
103 testResolve("http://a/b/g", "../g"); | 100 testResolve("http://a/b/g", "../g"); |
104 testResolve("http://a/", "../.."); | 101 testResolve("http://a/", "../.."); |
105 testResolve("http://a/", "../../"); | 102 testResolve("http://a/", "../../"); |
106 testResolve("http://a/g", "../../g"); | 103 testResolve("http://a/g", "../../g"); |
107 testResolve("http://a/g", "../../../g"); | 104 testResolve("http://a/g", "../../../g"); |
108 testResolve("http://a/g", "../../../../g"); | 105 testResolve("http://a/g", "../../../../g"); |
109 testResolve("http://a/g", "/./g"); | 106 testResolve("http://a/g", "/./g"); |
110 testResolve("http://a/g", "/../g"); | 107 testResolve("http://a/g", "/../g"); |
111 testResolve("http://a/b/c/g.", "g."); | 108 testResolve("http://a/b/c/g.", "g."); |
112 testResolve("http://a/b/c/.g", ".g"); | 109 testResolve("http://a/b/c/.g", ".g"); |
113 testResolve("http://a/b/c/g..", "g.."); | 110 testResolve("http://a/b/c/g..", "g.."); |
114 testResolve("http://a/b/c/..g", "..g"); | 111 testResolve("http://a/b/c/..g", "..g"); |
115 testResolve("http://a/b/g", "./../g"); | 112 testResolve("http://a/b/g", "./../g"); |
116 testResolve("http://a/b/c/g/", "./g/."); | 113 testResolve("http://a/b/c/g/", "./g/."); |
117 testResolve("http://a/b/c/g/h", "g/./h"); | 114 testResolve("http://a/b/c/g/h", "g/./h"); |
118 testResolve("http://a/b/c/h", "g/../h"); | 115 testResolve("http://a/b/c/h", "g/../h"); |
119 testResolve("http://a/b/c/g;x=1/y", "g;x=1/./y"); | 116 testResolve("http://a/b/c/g;x=1/y", "g;x=1/./y"); |
120 testResolve("http://a/b/c/y", "g;x=1/../y"); | 117 testResolve("http://a/b/c/y", "g;x=1/../y"); |
121 testResolve("http://a/b/c/g?y/./x", "g?y/./x"); | 118 testResolve("http://a/b/c/g?y/./x", "g?y/./x"); |
122 testResolve("http://a/b/c/g?y/../x", "g?y/../x"); | 119 testResolve("http://a/b/c/g?y/../x", "g?y/../x"); |
123 testResolve("http://a/b/c/g#s/./x", "g#s/./x"); | 120 testResolve("http://a/b/c/g#s/./x", "g#s/./x"); |
124 testResolve("http://a/b/c/g#s/../x", "g#s/../x"); | 121 testResolve("http://a/b/c/g#s/../x", "g#s/../x"); |
125 testResolve("http:g", "http:g"); | 122 testResolve("http:g", "http:g"); |
126 | 123 |
127 // Additional tests (not from RFC 3986). | 124 // Additional tests (not from RFC 3986). |
128 testResolve("http://a/b/g;p/h;s", "../g;p/h;s"); | 125 testResolve("http://a/b/g;p/h;s", "../g;p/h;s"); |
129 | 126 |
130 // Test non-URI base (no scheme, no authority, relative path). | 127 // Test non-URI base (no scheme, no authority, relative path). |
131 base = Uri.parse("a/b/c?_#_"); | 128 base = Uri.parse("a/b/c?_#_"); |
132 testResolve("a/b/g?q#f", "g?q#f"); | 129 testResolve("a/b/g?q#f", "g?q#f"); |
133 testResolve("../", "../../.."); | 130 testResolve("../", "../../.."); |
134 testResolve("a/b/", "."); | 131 testResolve("a/b/", "."); |
135 testResolve("c", "../../c"); | 132 testResolve("c", "../../c"); |
136 | 133 |
137 base = Uri.parse("s:a/b"); | 134 base = Uri.parse("s:a/b"); |
138 testResolve("s:/c", "../c"); | 135 testResolve("s:/c", "../c"); |
139 } | 136 } |
140 | 137 |
141 void testResolvePath(String expected, String path) { | 138 void testResolvePath(String expected, String path) { |
142 Expect.equals(expected, | |
143 new Uri(path: '/').resolveUri(new Uri(path: path)).path); | |
144 Expect.equals( | 139 Expect.equals( |
145 "http://localhost$expected", | 140 expected, new Uri(path: '/').resolveUri(new Uri(path: path)).path); |
| 141 Expect.equals("http://localhost$expected", |
146 Uri.parse("http://localhost").resolveUri(new Uri(path: path)).toString()); | 142 Uri.parse("http://localhost").resolveUri(new Uri(path: path)).toString()); |
147 } | 143 } |
148 | 144 |
149 const ALPHA = r"abcdefghijklmnopqrstuvwxuzABCDEFGHIJKLMNOPQRSTUVWXUZ"; | 145 const ALPHA = r"abcdefghijklmnopqrstuvwxuzABCDEFGHIJKLMNOPQRSTUVWXUZ"; |
150 const DIGIT = r"0123456789"; | 146 const DIGIT = r"0123456789"; |
151 const PERCENT_ENCODED = "%00%ff"; | 147 const PERCENT_ENCODED = "%00%ff"; |
152 const SUBDELIM = r"!$&'()*+,;="; | 148 const SUBDELIM = r"!$&'()*+,;="; |
153 | 149 |
154 const SCHEMECHAR = "$ALPHA$DIGIT+-."; | 150 const SCHEMECHAR = "$ALPHA$DIGIT+-."; |
155 const UNRESERVED = "$ALPHA$DIGIT-._~"; | 151 const UNRESERVED = "$ALPHA$DIGIT-._~"; |
156 const REGNAMECHAR = "$UNRESERVED$SUBDELIM$PERCENT_ENCODED"; | 152 const REGNAMECHAR = "$UNRESERVED$SUBDELIM$PERCENT_ENCODED"; |
157 const USERINFOCHAR = "$REGNAMECHAR:"; | 153 const USERINFOCHAR = "$REGNAMECHAR:"; |
158 | 154 |
159 const PCHAR_NC = "$UNRESERVED$SUBDELIM$PERCENT_ENCODED@"; | 155 const PCHAR_NC = "$UNRESERVED$SUBDELIM$PERCENT_ENCODED@"; |
160 const PCHAR = "$PCHAR_NC:"; | 156 const PCHAR = "$PCHAR_NC:"; |
161 const QUERYCHAR = "$PCHAR/?"; | 157 const QUERYCHAR = "$PCHAR/?"; |
162 | 158 |
163 void testValidCharacters() { | 159 void testValidCharacters() { |
164 // test that all valid characters are accepted. | 160 // test that all valid characters are accepted. |
165 | 161 |
166 for (var scheme in ["", "$SCHEMECHAR$SCHEMECHAR:"]) { | 162 for (var scheme in ["", "$SCHEMECHAR$SCHEMECHAR:"]) { |
167 for (var userinfo in ["", "@", "$USERINFOCHAR$USERINFOCHAR@", | 163 for (var userinfo in [ |
168 "$USERINFOCHAR:$DIGIT@"]) { | 164 "", |
169 for (var host in ["", "$REGNAMECHAR$REGNAMECHAR", | 165 "@", |
170 "255.255.255.256", // valid reg-name. | 166 "$USERINFOCHAR$USERINFOCHAR@", |
171 "[ffff::ffff:ffff]", "[ffff::255.255.255.255]"]) { | 167 "$USERINFOCHAR:$DIGIT@" |
| 168 ]) { |
| 169 for (var host in [ |
| 170 "", "$REGNAMECHAR$REGNAMECHAR", |
| 171 "255.255.255.256", // valid reg-name. |
| 172 "[ffff::ffff:ffff]", "[ffff::255.255.255.255]" |
| 173 ]) { |
172 for (var port in ["", ":", ":$DIGIT$DIGIT"]) { | 174 for (var port in ["", ":", ":$DIGIT$DIGIT"]) { |
173 var auth = "$userinfo$host$port"; | 175 var auth = "$userinfo$host$port"; |
174 if (auth.isNotEmpty) auth = "//$auth"; | 176 if (auth.isNotEmpty) auth = "//$auth"; |
175 var paths = ["", "/", "/$PCHAR", "/$PCHAR/"]; // Absolute or empty. | 177 var paths = ["", "/", "/$PCHAR", "/$PCHAR/"]; // Absolute or empty. |
176 if (auth.isNotEmpty) { | 178 if (auth.isNotEmpty) { |
177 // Initial segment may be empty. | 179 // Initial segment may be empty. |
178 paths..add("//$PCHAR"); | 180 paths..add("//$PCHAR"); |
179 } else { | 181 } else { |
180 // Path may begin with non-slash. | 182 // Path may begin with non-slash. |
181 if (scheme.isEmpty) { | 183 if (scheme.isEmpty) { |
182 // Initial segment must not contain colon. | 184 // Initial segment must not contain colon. |
183 paths..add(PCHAR_NC) | 185 paths |
184 ..add("$PCHAR_NC/$PCHAR") | 186 ..add(PCHAR_NC) |
185 ..add("$PCHAR_NC/$PCHAR/"); | 187 ..add("$PCHAR_NC/$PCHAR") |
| 188 ..add("$PCHAR_NC/$PCHAR/"); |
186 } else { | 189 } else { |
187 paths..add(PCHAR) | 190 paths..add(PCHAR)..add("$PCHAR/$PCHAR")..add("$PCHAR/$PCHAR/"); |
188 ..add("$PCHAR/$PCHAR") | |
189 ..add("$PCHAR/$PCHAR/"); | |
190 } | 191 } |
191 } | 192 } |
192 for (var path in paths) { | 193 for (var path in paths) { |
193 for (var query in ["", "?", "?$QUERYCHAR"]) { | 194 for (var query in ["", "?", "?$QUERYCHAR"]) { |
194 for (var fragment in ["", "#", "#$QUERYCHAR"]) { | 195 for (var fragment in ["", "#", "#$QUERYCHAR"]) { |
195 var uri = "$scheme$auth$path$query$fragment"; | 196 var uri = "$scheme$auth$path$query$fragment"; |
196 // Should not throw. | 197 // Should not throw. |
197 var result = Uri.parse(uri); | 198 var result = Uri.parse(uri); |
198 } | 199 } |
199 } | 200 } |
200 } | 201 } |
201 } | 202 } |
202 } | 203 } |
203 } | 204 } |
204 } | 205 } |
205 } | 206 } |
206 | 207 |
207 void testInvalidUrls() { | 208 void testInvalidUrls() { |
208 void checkInvalid(uri) { | 209 void checkInvalid(uri) { |
209 try { | 210 try { |
210 var result = Uri.parse(uri); | 211 var result = Uri.parse(uri); |
211 Expect.fail("Invalid URI `$uri` parsed to $result\n" + dump(result)); | 212 Expect.fail("Invalid URI `$uri` parsed to $result\n" + dump(result)); |
212 } on FormatException { | 213 } on FormatException { |
213 // Success. | 214 // Success. |
214 } | 215 } |
215 } | 216 } |
| 217 |
216 checkInvalid("s%41://x.x/"); // No escapes in scheme, | 218 checkInvalid("s%41://x.x/"); // No escapes in scheme, |
217 // and no colon before slash in path. | 219 // and no colon before slash in path. |
218 checkInvalid("1a://x.x/"); // Scheme must start with letter, | 220 checkInvalid("1a://x.x/"); // Scheme must start with letter, |
219 // and no colon before slash in path. | 221 // and no colon before slash in path. |
220 checkInvalid(".a://x.x/"); // Scheme must start with letter, | 222 checkInvalid(".a://x.x/"); // Scheme must start with letter, |
221 // and no colon before slash in path. | 223 // and no colon before slash in path. |
222 checkInvalid("_:"); // Character not valid in scheme, | 224 checkInvalid("_:"); // Character not valid in scheme, |
223 // and no colon before slash in path. | 225 // and no colon before slash in path. |
224 checkInvalid(":"); // Scheme must start with letter, | 226 checkInvalid(":"); // Scheme must start with letter, |
225 // and no colon before slash in path. | 227 // and no colon before slash in path. |
226 | 228 |
227 void checkInvalidReplaced(uri, invalid, replacement) { | 229 void checkInvalidReplaced(uri, invalid, replacement) { |
228 var source = uri.replaceAll('{}', invalid); | 230 var source = uri.replaceAll('{}', invalid); |
229 var expected = uri.replaceAll('{}', replacement); | 231 var expected = uri.replaceAll('{}', replacement); |
230 var result = Uri.parse(source); | 232 var result = Uri.parse(source); |
231 Expect.equals(expected, "$result", "Source: $source\n${dump(result)}"); | 233 Expect.equals(expected, "$result", "Source: $source\n${dump(result)}"); |
232 } | 234 } |
233 | 235 |
234 // Regression test for http://dartbug.com/16081 | 236 // Regression test for http://dartbug.com/16081 |
235 checkInvalidReplaced("http://www.example.org/red%09ros{}#red)", | 237 checkInvalidReplaced( |
236 "\u00e9", "%C3%A9"); | 238 "http://www.example.org/red%09ros{}#red)", "\u00e9", "%C3%A9"); |
237 checkInvalidReplaced("http://r{}sum\{}.example.org", "\u00E9", "%C3%A9"); | 239 checkInvalidReplaced("http://r{}sum\{}.example.org", "\u00E9", "%C3%A9"); |
238 | 240 |
239 // Invalid characters. The characters must be rejected, even if normalizing | 241 // Invalid characters. The characters must be rejected, even if normalizing |
240 // the input would cause them to be valid (normalization happens after | 242 // the input would cause them to be valid (normalization happens after |
241 // validation). | 243 // validation). |
242 var invalidCharsAndReplacements = [ | 244 var invalidCharsAndReplacements = [ |
243 "\xe7", "%C3%A7", // Arbitrary non-ASCII letter | 245 "\xe7", "%C3%A7", // Arbitrary non-ASCII letter |
244 " ", "%20", // Space, not allowed anywhere. | 246 " ", "%20", // Space, not allowed anywhere. |
245 '"', "%22", // Quote, not allowed anywhere | 247 '"', "%22", // Quote, not allowed anywhere |
246 "<>", "%3C%3E", // Less/greater-than, not allowed anywhere. | 248 "<>", "%3C%3E", // Less/greater-than, not allowed anywhere. |
247 "\x7f", "%7F", // DEL, not allowed anywhere | 249 "\x7f", "%7F", // DEL, not allowed anywhere |
248 "\xdf", "%C3%9F", // German lower-case scharf-S. | 250 "\xdf", "%C3%9F", // German lower-case scharf-S. |
249 // Becomes ASCII when upper-cased. | 251 // Becomes ASCII when upper-cased. |
250 "\u0130", "%C4%B0", // Latin capital dotted I, | 252 "\u0130", "%C4%B0", // Latin capital dotted I, |
251 // becomes ASCII lower-case in Turkish. | 253 // becomes ASCII lower-case in Turkish. |
252 "%\uFB03", "%25%EF%AC%83", // % + Ligature ffi, | 254 "%\uFB03", "%25%EF%AC%83", // % + Ligature ffi, |
253 // becomes ASCII when upper-cased, | 255 // becomes ASCII when upper-cased, |
254 // should not be read as "%FFI". | 256 // should not be read as "%FFI". |
255 "\u212a", "%E2%84%AA", // Kelvin sign. Becomes ASCII when lower-cased. | 257 "\u212a", "%E2%84%AA", // Kelvin sign. Becomes ASCII when lower-cased. |
256 "%1g", "%251g", // Invalid escape. | 258 "%1g", "%251g", // Invalid escape. |
257 "\u{10000}", "%F0%90%80%80", // Non-BMP character as surrogate pair. | 259 "\u{10000}", "%F0%90%80%80", // Non-BMP character as surrogate pair. |
258 ]; | 260 ]; |
259 for (int i = 0; i < invalidCharsAndReplacements.length; i += 2) { | 261 for (int i = 0; i < invalidCharsAndReplacements.length; i += 2) { |
260 var invalid = invalidCharsAndReplacements[i]; | 262 var invalid = invalidCharsAndReplacements[i]; |
261 var valid = invalidCharsAndReplacements[i + 1]; | 263 var valid = invalidCharsAndReplacements[i + 1]; |
262 checkInvalid("A{}b:///".replaceAll('{}', invalid)); | 264 checkInvalid("A{}b:///".replaceAll('{}', invalid)); |
263 checkInvalid("{}b:///".replaceAll('{}', invalid)); | 265 checkInvalid("{}b:///".replaceAll('{}', invalid)); |
264 checkInvalidReplaced("s://user{}info@x.x/", invalid, valid); | 266 checkInvalidReplaced("s://user{}info@x.x/", invalid, valid); |
265 checkInvalidReplaced("s://reg{}name/", invalid, valid); | 267 checkInvalidReplaced("s://reg{}name/", invalid, valid); |
266 checkInvalid("s://regname:12{}45/".replaceAll("{}", invalid)); | 268 checkInvalid("s://regname:12{}45/".replaceAll("{}", invalid)); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
309 uri = Uri.parse("Z:"); | 311 uri = Uri.parse("Z:"); |
310 Expect.equals("z", uri.scheme); | 312 Expect.equals("z", uri.scheme); |
311 uri = Uri.parse("$SCHEMECHAR:"); | 313 uri = Uri.parse("$SCHEMECHAR:"); |
312 Expect.equals(SCHEMECHAR.toLowerCase(), uri.scheme); | 314 Expect.equals(SCHEMECHAR.toLowerCase(), uri.scheme); |
313 | 315 |
314 // Percent escape normalization. | 316 // Percent escape normalization. |
315 // Escapes of unreserved characters are converted to the character, | 317 // Escapes of unreserved characters are converted to the character, |
316 // subject to case normalization in reg-name. | 318 // subject to case normalization in reg-name. |
317 for (var i = 0; i < UNRESERVED.length; i++) { | 319 for (var i = 0; i < UNRESERVED.length; i++) { |
318 var char = UNRESERVED[i]; | 320 var char = UNRESERVED[i]; |
319 var escape = "%" + char.codeUnitAt(0).toRadixString(16); // all > 0xf. | 321 var escape = "%" + char.codeUnitAt(0).toRadixString(16); // all > 0xf. |
320 | 322 |
321 uri = Uri.parse("s://xX${escape}xX@yY${escape}yY/zZ${escape}zZ" | 323 uri = Uri.parse("s://xX${escape}xX@yY${escape}yY/zZ${escape}zZ" |
322 "?vV${escape}vV#wW${escape}wW"); | 324 "?vV${escape}vV#wW${escape}wW"); |
323 Expect.equals("xX${char}xX", uri.userInfo); | 325 Expect.equals("xX${char}xX", uri.userInfo); |
324 Expect.equals("yY${char}yY".toLowerCase(), uri.host); | 326 Expect.equals("yY${char}yY".toLowerCase(), uri.host); |
325 Expect.equals("/zZ${char}zZ", uri.path); | 327 Expect.equals("/zZ${char}zZ", uri.path); |
326 Expect.equals("vV${char}vV", uri.query); | 328 Expect.equals("vV${char}vV", uri.query); |
327 Expect.equals("wW${char}wW", uri.fragment); | 329 Expect.equals("wW${char}wW", uri.fragment); |
328 } | 330 } |
329 | 331 |
330 // Escapes of reserved characters are kept, but upper-cased. | 332 // Escapes of reserved characters are kept, but upper-cased. |
331 for (var escape in ["%00", "%1f", "%7F", "%fF"]) { | 333 for (var escape in ["%00", "%1f", "%7F", "%fF"]) { |
332 uri = Uri.parse("s://xX${escape}xX@yY${escape}yY/zZ${escape}zZ" | 334 uri = Uri.parse("s://xX${escape}xX@yY${escape}yY/zZ${escape}zZ" |
333 "?vV${escape}vV#wW${escape}wW"); | 335 "?vV${escape}vV#wW${escape}wW"); |
334 var normalizedEscape = escape.toUpperCase(); | 336 var normalizedEscape = escape.toUpperCase(); |
335 Expect.equals("xX${normalizedEscape}xX", uri.userInfo); | 337 Expect.equals("xX${normalizedEscape}xX", uri.userInfo); |
336 Expect.equals("yy${normalizedEscape}yy", uri.host); | 338 Expect.equals("yy${normalizedEscape}yy", uri.host); |
337 Expect.equals("/zZ${normalizedEscape}zZ", uri.path); | 339 Expect.equals("/zZ${normalizedEscape}zZ", uri.path); |
338 Expect.equals("vV${normalizedEscape}vV", uri.query); | 340 Expect.equals("vV${normalizedEscape}vV", uri.query); |
339 Expect.equals("wW${normalizedEscape}wW", uri.fragment); | 341 Expect.equals("wW${normalizedEscape}wW", uri.fragment); |
340 } | 342 } |
341 | 343 |
342 // Some host normalization edge cases. | 344 // Some host normalization edge cases. |
343 uri = Uri.parse("x://x%61X%41x%41X%61x/"); | 345 uri = Uri.parse("x://x%61X%41x%41X%61x/"); |
(...skipping 27 matching lines...) Expand all Loading... |
371 | 373 |
372 // File scheme noralizes to always showing authority, even if empty. | 374 // File scheme noralizes to always showing authority, even if empty. |
373 uri = new Uri(scheme: "file", path: "/y"); | 375 uri = new Uri(scheme: "file", path: "/y"); |
374 Expect.equals("file:///y", uri.toString()); | 376 Expect.equals("file:///y", uri.toString()); |
375 uri = new Uri(scheme: "file", path: "y"); | 377 uri = new Uri(scheme: "file", path: "y"); |
376 Expect.equals("file:///y", uri.toString()); | 378 Expect.equals("file:///y", uri.toString()); |
377 | 379 |
378 // Empty host/query/fragment ensures the delimiter is there. | 380 // Empty host/query/fragment ensures the delimiter is there. |
379 // Different from not being there. | 381 // Different from not being there. |
380 Expect.equals("scheme:/", Uri.parse("scheme:/").toString()); | 382 Expect.equals("scheme:/", Uri.parse("scheme:/").toString()); |
381 Expect.equals("scheme:/", | 383 Expect.equals("scheme:/", new Uri(scheme: "scheme", path: "/").toString()); |
382 new Uri(scheme: "scheme", path: "/").toString()); | |
383 | 384 |
384 Expect.equals("scheme:///?#", Uri.parse("scheme:///?#").toString()); | 385 Expect.equals("scheme:///?#", Uri.parse("scheme:///?#").toString()); |
385 Expect.equals("scheme:///#", | 386 Expect.equals( |
386 new Uri(scheme: "scheme", host: "", path: "/", | 387 "scheme:///#", |
387 query: "", fragment: "").toString()); | 388 new Uri(scheme: "scheme", host: "", path: "/", query: "", fragment: "") |
| 389 .toString()); |
388 } | 390 } |
389 | 391 |
390 void testReplace() { | 392 void testReplace() { |
391 var uris = [ | 393 var uris = [ |
392 Uri.parse(""), | 394 Uri.parse(""), |
393 Uri.parse("a://@:/?#"), | 395 Uri.parse("a://@:/?#"), |
394 Uri.parse("a://b@c:4/e/f?g#h"), | 396 Uri.parse("a://b@c:4/e/f?g#h"), |
395 Uri.parse("$SCHEMECHAR://$USERINFOCHAR@$REGNAMECHAR:$DIGIT/$PCHAR/$PCHAR" | 397 Uri.parse("$SCHEMECHAR://$USERINFOCHAR@$REGNAMECHAR:$DIGIT/$PCHAR/$PCHAR" |
396 "?$QUERYCHAR#$QUERYCHAR"), | 398 "?$QUERYCHAR#$QUERYCHAR"), |
397 ]; | 399 ]; |
398 for (var uri1 in uris) { | 400 for (var uri1 in uris) { |
399 for (var uri2 in uris) { | 401 for (var uri2 in uris) { |
400 if (identical(uri1, uri2)) continue; | 402 if (identical(uri1, uri2)) continue; |
401 var scheme = uri1.scheme; | 403 var scheme = uri1.scheme; |
402 var userInfo = uri1.hasAuthority ? uri1.userInfo : ""; | 404 var userInfo = uri1.hasAuthority ? uri1.userInfo : ""; |
403 var host = uri1.hasAuthority ? uri1.host : null; | 405 var host = uri1.hasAuthority ? uri1.host : null; |
404 var port = uri1.hasAuthority ? uri1.port : 0; | 406 var port = uri1.hasAuthority ? uri1.port : 0; |
405 var path = uri1.path; | 407 var path = uri1.path; |
406 var query = uri1.hasQuery ? uri1.query : null; | 408 var query = uri1.hasQuery ? uri1.query : null; |
407 var fragment = uri1.hasFragment ? uri1.fragment : null; | 409 var fragment = uri1.hasFragment ? uri1.fragment : null; |
408 | 410 |
409 var tmp1 = uri1; | 411 var tmp1 = uri1; |
410 | 412 |
411 void test() { | 413 void test() { |
412 var tmp2 = new Uri(scheme: scheme, userInfo: userInfo, host: host, | 414 var tmp2 = new Uri( |
413 port: port, path: path, | 415 scheme: scheme, |
414 query: query == "" ? null : query, | 416 userInfo: userInfo, |
415 queryParameters: query == "" ? {} : null, | 417 host: host, |
416 fragment: fragment); | 418 port: port, |
| 419 path: path, |
| 420 query: query == "" ? null : query, |
| 421 queryParameters: query == "" ? {} : null, |
| 422 fragment: fragment); |
417 Expect.equals(tmp1, tmp2); | 423 Expect.equals(tmp1, tmp2); |
418 } | 424 } |
419 | 425 |
420 test(); | 426 test(); |
421 | 427 |
422 scheme = uri2.scheme; | 428 scheme = uri2.scheme; |
423 tmp1 = tmp1.replace(scheme: scheme); | 429 tmp1 = tmp1.replace(scheme: scheme); |
424 test(); | 430 test(); |
425 | 431 |
426 if (uri2.hasAuthority) { | 432 if (uri2.hasAuthority) { |
(...skipping 21 matching lines...) Expand all Loading... |
448 } | 454 } |
449 } | 455 } |
450 } | 456 } |
451 | 457 |
452 // Regression test, http://dartbug.com/20814 | 458 // Regression test, http://dartbug.com/20814 |
453 var uri = Uri.parse("/no-authorty/"); | 459 var uri = Uri.parse("/no-authorty/"); |
454 uri = uri.replace(fragment: "fragment"); | 460 uri = uri.replace(fragment: "fragment"); |
455 Expect.isFalse(uri.hasAuthority); | 461 Expect.isFalse(uri.hasAuthority); |
456 | 462 |
457 uri = new Uri(scheme: "foo", path: "bar"); | 463 uri = new Uri(scheme: "foo", path: "bar"); |
458 uri = uri.replace( | 464 uri = uri.replace(queryParameters: { |
459 queryParameters: {"x": ["42", "37"], "y": ["43", "38"]}); | 465 "x": ["42", "37"], |
| 466 "y": ["43", "38"] |
| 467 }); |
460 var params = uri.queryParametersAll; | 468 var params = uri.queryParametersAll; |
461 Expect.equals(2, params.length); | 469 Expect.equals(2, params.length); |
462 Expect.listEquals(["42", "37"], params["x"]); | 470 Expect.listEquals(["42", "37"], params["x"]); |
463 Expect.listEquals(["43", "38"], params["y"]); | 471 Expect.listEquals(["43", "38"], params["y"]); |
464 } | 472 } |
465 | 473 |
466 main() { | 474 main() { |
467 testUri("http:", true); | 475 testUri("http:", true); |
468 testUri("file:///", true); | 476 testUri("file:///", true); |
469 testUri("file", false); | 477 testUri("file", false); |
470 testUri("http://user@example.com:8080/fisk?query=89&hest=silas", true); | 478 testUri("http://user@example.com:8080/fisk?query=89&hest=silas", true); |
471 testUri("http://user@example.com:8080/fisk?query=89&hest=silas#fragment", | 479 testUri( |
472 false); | 480 "http://user@example.com:8080/fisk?query=89&hest=silas#fragment", false); |
473 Expect.stringEquals("http://user@example.com/a/b/c?query#fragment", | 481 Expect.stringEquals( |
474 new Uri( | 482 "http://user@example.com/a/b/c?query#fragment", |
475 scheme: "http", | 483 new Uri( |
476 userInfo: "user", | 484 scheme: "http", |
477 host: "example.com", | 485 userInfo: "user", |
478 port: 80, | 486 host: "example.com", |
479 path: "/a/b/c", | 487 port: 80, |
480 query: "query", | 488 path: "/a/b/c", |
481 fragment: "fragment").toString()); | 489 query: "query", |
482 Expect.stringEquals("/a/b/c/", | 490 fragment: "fragment") |
483 new Uri( | 491 .toString()); |
484 scheme: null, | 492 Expect.stringEquals( |
485 userInfo: null, | 493 "/a/b/c/", |
486 host: null, | 494 new Uri( |
487 port: 0, | 495 scheme: null, |
488 path: "/a/b/c/", | 496 userInfo: null, |
489 query: null, | 497 host: null, |
490 fragment: null).toString()); | 498 port: 0, |
| 499 path: "/a/b/c/", |
| 500 query: null, |
| 501 fragment: null) |
| 502 .toString()); |
491 Expect.stringEquals("file:///", Uri.parse("file:").toString()); | 503 Expect.stringEquals("file:///", Uri.parse("file:").toString()); |
492 | 504 |
493 testResolvePath("/a/g", "/a/b/c/./../../g"); | 505 testResolvePath("/a/g", "/a/b/c/./../../g"); |
494 testResolvePath("/a/g", "/a/b/c/./../../g"); | 506 testResolvePath("/a/g", "/a/b/c/./../../g"); |
495 testResolvePath("/mid/6", "mid/content=5/../6"); | 507 testResolvePath("/mid/6", "mid/content=5/../6"); |
496 testResolvePath("/a/b/e", "a/b/c/d/../../e"); | 508 testResolvePath("/a/b/e", "a/b/c/d/../../e"); |
497 testResolvePath("/a/b/e", "../a/b/c/d/../../e"); | 509 testResolvePath("/a/b/e", "../a/b/c/d/../../e"); |
498 testResolvePath("/a/b/e", "./a/b/c/d/../../e"); | 510 testResolvePath("/a/b/e", "./a/b/c/d/../../e"); |
499 testResolvePath("/a/b/e", "../a/b/./c/d/../../e"); | 511 testResolvePath("/a/b/e", "../a/b/./c/d/../../e"); |
500 testResolvePath("/a/b/e", "./a/b/./c/d/../../e"); | 512 testResolvePath("/a/b/e", "./a/b/./c/d/../../e"); |
501 testResolvePath("/a/b/e/", "./a/b/./c/d/../../e/."); | 513 testResolvePath("/a/b/e/", "./a/b/./c/d/../../e/."); |
502 testResolvePath("/a/b/e/", "./a/b/./c/d/../../e/./."); | 514 testResolvePath("/a/b/e/", "./a/b/./c/d/../../e/./."); |
503 testResolvePath("/a/b/e/", "./a/b/./c/d/../../e/././."); | 515 testResolvePath("/a/b/e/", "./a/b/./c/d/../../e/././."); |
504 | 516 |
505 testUriPerRFCs(); | 517 testUriPerRFCs(); |
506 | 518 |
507 Expect.stringEquals( | 519 Expect.stringEquals( |
508 "http://example.com", | 520 "http://example.com", Uri.parse("http://example.com/a/b/c").origin); |
509 Uri.parse("http://example.com/a/b/c").origin); | |
510 Expect.stringEquals( | 521 Expect.stringEquals( |
511 "https://example.com", | 522 "https://example.com", Uri.parse("https://example.com/a/b/c").origin); |
512 Uri.parse("https://example.com/a/b/c").origin); | 523 Expect.stringEquals("http://example.com:1234", |
513 Expect.stringEquals( | |
514 "http://example.com:1234", | |
515 Uri.parse("http://example.com:1234/a/b/c").origin); | 524 Uri.parse("http://example.com:1234/a/b/c").origin); |
516 Expect.stringEquals( | 525 Expect.stringEquals("https://example.com:1234", |
517 "https://example.com:1234", | |
518 Uri.parse("https://example.com:1234/a/b/c").origin); | 526 Uri.parse("https://example.com:1234/a/b/c").origin); |
519 Expect.throws( | 527 Expect.throws(() => Uri.parse("http:").origin, (e) { |
520 () => Uri.parse("http:").origin, | 528 return e is StateError; |
521 (e) { return e is StateError; }, | 529 }, "origin for uri with empty host should fail"); |
522 "origin for uri with empty host should fail"); | |
523 Expect.throws( | 530 Expect.throws( |
524 () => new Uri( | 531 () => new Uri( |
525 scheme: "http", | 532 scheme: "http", |
526 userInfo: null, | 533 userInfo: null, |
527 host: "", | 534 host: "", |
528 port: 80, | 535 port: 80, |
529 path: "/a/b/c", | 536 path: "/a/b/c", |
530 query: "query", | 537 query: "query", |
531 fragment: "fragment").origin, | 538 fragment: "fragment") |
532 (e) { return e is StateError; }, | 539 .origin, (e) { |
533 "origin for uri with empty host should fail"); | 540 return e is StateError; |
| 541 }, "origin for uri with empty host should fail"); |
534 Expect.throws( | 542 Expect.throws( |
535 () => new Uri( | 543 () => new Uri( |
536 scheme: null, | 544 scheme: null, |
537 userInfo: null, | 545 userInfo: null, |
538 host: "", | 546 host: "", |
539 port: 80, | 547 port: 80, |
540 path: "/a/b/c", | 548 path: "/a/b/c", |
541 query: "query", | 549 query: "query", |
542 fragment: "fragment").origin, | 550 fragment: "fragment") |
543 (e) { return e is StateError; }, | 551 .origin, (e) { |
544 "origin for uri with empty scheme should fail"); | 552 return e is StateError; |
| 553 }, "origin for uri with empty scheme should fail"); |
545 Expect.throws( | 554 Expect.throws( |
546 () => new Uri( | 555 () => new Uri( |
547 scheme: "http", | 556 scheme: "http", |
548 userInfo: null, | 557 userInfo: null, |
549 host: null, | 558 host: null, |
550 port: 80, | 559 port: 80, |
551 path: "/a/b/c", | 560 path: "/a/b/c", |
552 query: "query", | 561 query: "query", |
553 fragment: "fragment").origin, | 562 fragment: "fragment") |
554 (e) { return e is StateError; }, | 563 .origin, (e) { |
555 "origin for uri with empty host should fail"); | 564 return e is StateError; |
556 Expect.throws( | 565 }, "origin for uri with empty host should fail"); |
557 () => Uri.parse("http://:80").origin, | 566 Expect.throws(() => Uri.parse("http://:80").origin, (e) { |
558 (e) { return e is StateError; }, | 567 return e is StateError; |
559 "origin for uri with empty host should fail"); | 568 }, "origin for uri with empty host should fail"); |
560 Expect.throws( | 569 Expect.throws(() => Uri.parse("file://localhost/test.txt").origin, (e) { |
561 () => Uri.parse("file://localhost/test.txt").origin, | 570 return e is StateError; |
562 (e) { return e is StateError; }, | 571 }, "origin for non-http/https uri should fail"); |
563 "origin for non-http/https uri should fail"); | |
564 | 572 |
565 // URI encode tests | 573 // URI encode tests |
566 // Create a string with code point 0x10000 encoded as a surrogate pair. | 574 // Create a string with code point 0x10000 encoded as a surrogate pair. |
567 var s = UTF8.decode([0xf0, 0x90, 0x80, 0x80]); | 575 var s = UTF8.decode([0xf0, 0x90, 0x80, 0x80]); |
568 | 576 |
569 Expect.stringEquals("\u{10000}", s); | 577 Expect.stringEquals("\u{10000}", s); |
570 | 578 |
571 testEncodeDecode("A + B", "A%20+%20B"); | 579 testEncodeDecode("A + B", "A%20+%20B"); |
572 testEncodeDecode("\uFFFE", "%EF%BF%BE"); | 580 testEncodeDecode("\uFFFE", "%EF%BF%BE"); |
573 testEncodeDecode("\uFFFF", "%EF%BF%BF"); | 581 testEncodeDecode("\uFFFF", "%EF%BF%BF"); |
574 testEncodeDecode("\uFFFE", "%EF%BF%BE"); | 582 testEncodeDecode("\uFFFE", "%EF%BF%BE"); |
575 testEncodeDecode("\uFFFF", "%EF%BF%BF"); | 583 testEncodeDecode("\uFFFF", "%EF%BF%BF"); |
576 testEncodeDecode("\x7f", "%7F"); | 584 testEncodeDecode("\x7f", "%7F"); |
577 testEncodeDecode("\x80", "%C2%80"); | 585 testEncodeDecode("\x80", "%C2%80"); |
578 testEncodeDecode("\u0800", "%E0%A0%80"); | 586 testEncodeDecode("\u0800", "%E0%A0%80"); |
579 // All characters not escaped by encodeFull. | 587 // All characters not escaped by encodeFull. |
580 var unescapedFull = | 588 var unescapedFull = r"abcdefghijklmnopqrstuvwxyz" |
581 r"abcdefghijklmnopqrstuvwxyz" | |
582 r"ABCDEFGHIJKLMNOPQRSTUVWXYZ" | 589 r"ABCDEFGHIJKLMNOPQRSTUVWXYZ" |
583 r"0123456789!#$&'()*+,-./:;=?@_~"; | 590 r"0123456789!#$&'()*+,-./:;=?@_~"; |
584 // ASCII characters escaped by encodeFull: | 591 // ASCII characters escaped by encodeFull: |
585 var escapedFull = | 592 var escapedFull = |
586 "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" | 593 "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" |
587 "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" | 594 "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" |
588 r' "%<>[\]^`{|}' | 595 r' "%<>[\]^`{|}' |
589 "\x7f"; | 596 "\x7f"; |
590 var escapedTo = | 597 var escapedTo = "%00%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F" |
591 "%00%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F" | |
592 "%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F" | 598 "%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F" |
593 "%20%22%25%3C%3E%5B%5C%5D%5E%60%7B%7C%7D%7F"; | 599 "%20%22%25%3C%3E%5B%5C%5D%5E%60%7B%7C%7D%7F"; |
594 testEncodeDecode(unescapedFull, unescapedFull); | 600 testEncodeDecode(unescapedFull, unescapedFull); |
595 testEncodeDecode(escapedFull, escapedTo); | 601 testEncodeDecode(escapedFull, escapedTo); |
596 var nonAscii = | 602 var nonAscii = |
597 "\x80-\xff-\u{100}-\u{7ff}-\u{800}-\u{ffff}-\u{10000}-\u{10ffff}"; | 603 "\x80-\xff-\u{100}-\u{7ff}-\u{800}-\u{ffff}-\u{10000}-\u{10ffff}"; |
598 var nonAsciiEncoding = | 604 var nonAsciiEncoding = "%C2%80-%C3%BF-%C4%80-%DF%BF-%E0%A0%80-%EF%BF%BF-" |
599 "%C2%80-%C3%BF-%C4%80-%DF%BF-%E0%A0%80-%EF%BF%BF-" | |
600 "%F0%90%80%80-%F4%8F%BF%BF"; | 605 "%F0%90%80%80-%F4%8F%BF%BF"; |
601 testEncodeDecode(nonAscii, nonAsciiEncoding); | 606 testEncodeDecode(nonAscii, nonAsciiEncoding); |
602 testEncodeDecode(s, "%F0%90%80%80"); | 607 testEncodeDecode(s, "%F0%90%80%80"); |
603 testEncodeDecodeComponent("A + B", "A%20%2B%20B"); | 608 testEncodeDecodeComponent("A + B", "A%20%2B%20B"); |
604 testEncodeDecodeComponent("\uFFFE", "%EF%BF%BE"); | 609 testEncodeDecodeComponent("\uFFFE", "%EF%BF%BE"); |
605 testEncodeDecodeComponent("\uFFFF", "%EF%BF%BF"); | 610 testEncodeDecodeComponent("\uFFFF", "%EF%BF%BF"); |
606 testEncodeDecodeComponent("\uFFFE", "%EF%BF%BE"); | 611 testEncodeDecodeComponent("\uFFFE", "%EF%BF%BE"); |
607 testEncodeDecodeComponent("\uFFFF", "%EF%BF%BF"); | 612 testEncodeDecodeComponent("\uFFFF", "%EF%BF%BF"); |
608 testEncodeDecodeComponent("\x7f", "%7F"); | 613 testEncodeDecodeComponent("\x7f", "%7F"); |
609 testEncodeDecodeComponent("\x80", "%C2%80"); | 614 testEncodeDecodeComponent("\x80", "%C2%80"); |
610 testEncodeDecodeComponent("\u0800", "%E0%A0%80"); | 615 testEncodeDecodeComponent("\u0800", "%E0%A0%80"); |
611 testEncodeDecodeComponent(":/@',;?&=+\$", "%3A%2F%40'%2C%3B%3F%26%3D%2B%24"); | 616 testEncodeDecodeComponent(":/@',;?&=+\$", "%3A%2F%40'%2C%3B%3F%26%3D%2B%24"); |
612 testEncodeDecodeComponent(s, "%F0%90%80%80"); | 617 testEncodeDecodeComponent(s, "%F0%90%80%80"); |
613 testEncodeDecodeQueryComponent("A + B", "A+%2B+B", "A+%2B+B", "A+%2B+B"); | 618 testEncodeDecodeQueryComponent("A + B", "A+%2B+B", "A+%2B+B", "A+%2B+B"); |
614 testEncodeDecodeQueryComponent( | 619 testEncodeDecodeQueryComponent( |
615 "æ ø å", "%C3%A6+%C3%B8+%C3%A5", "%E6+%F8+%E5", null); | 620 "æ ø å", "%C3%A6+%C3%B8+%C3%A5", "%E6+%F8+%E5", null); |
616 testEncodeDecodeComponent(nonAscii, nonAsciiEncoding); | 621 testEncodeDecodeComponent(nonAscii, nonAsciiEncoding); |
617 | 622 |
618 // Invalid URI - : and @ is swapped, port ("host") should be numeric. | 623 // Invalid URI - : and @ is swapped, port ("host") should be numeric. |
619 Expect.throws( | 624 Expect.throws(() => Uri.parse("file://user@password:host/path"), |
620 () => Uri.parse("file://user@password:host/path"), | |
621 (e) => e is FormatException); | 625 (e) => e is FormatException); |
622 | 626 |
623 testValidCharacters(); | 627 testValidCharacters(); |
624 testInvalidUrls(); | 628 testInvalidUrls(); |
625 testNormalization(); | 629 testNormalization(); |
626 testReplace(); | 630 testReplace(); |
627 } | 631 } |
628 | 632 |
629 String dump(Uri uri) { | 633 String dump(Uri uri) { |
630 return "URI: $uri\n" | 634 return "URI: $uri\n" |
631 " Scheme: ${uri.scheme} #${uri.scheme.length}\n" | 635 " Scheme: ${uri.scheme} #${uri.scheme.length}\n" |
632 " User-info: ${uri.userInfo} #${uri.userInfo.length}\n" | 636 " User-info: ${uri.userInfo} #${uri.userInfo.length}\n" |
633 " Host: ${uri.host} #${uri.host.length}\n" | 637 " Host: ${uri.host} #${uri.host.length}\n" |
634 " Port: ${uri.port}\n" | 638 " Port: ${uri.port}\n" |
635 " Path: ${uri.path} #${uri.path.length}\n" | 639 " Path: ${uri.path} #${uri.path.length}\n" |
636 " Query: ${uri.query} #${uri.query.length}\n" | 640 " Query: ${uri.query} #${uri.query.length}\n" |
637 " Fragment: ${uri.fragment} #${uri.fragment.length}\n"; | 641 " Fragment: ${uri.fragment} #${uri.fragment.length}\n"; |
638 } | 642 } |
OLD | NEW |