@@ -85,14 +85,42 @@ testEncodeDecodeQueryComponent(String orig,
85
85
}
86
86
87
87
testUriPerRFCs () {
88
- final urisSample = "http://a/b/c/d;p?q" ;
89
- Uri base = Uri .parse (urisSample);
88
+ // Convert a Uri to a guaranteed "non simple" URI with the same content.
89
+ toComplex (Uri uri) {
90
+ Uri complex = new Uri (
91
+ scheme: uri.scheme,
92
+ userInfo: uri.hasAuthority ? uri.userInfo : null ,
93
+ host: uri.hasAuthority ? uri.host : null ,
94
+ port: uri.hasAuthority ? uri.port : null ,
95
+ path: uri.path,
96
+ query: uri.hasQuery ? uri.query : null ,
97
+ fragment: uri.hasFragment ? uri.fragment : null ,
98
+ );
99
+ assert (complex.toString () == uri.toString ());
100
+ return complex;
101
+ }
102
+
103
+ Uri base ;
104
+ Uri complexBase;
105
+ // Sets the [base] and [complexBase] to the parse of the URI and a
106
+ // guaranteed non-simple version of the same URI.
107
+ setBase (String uri) {
108
+ base = Uri .parse (uri);
109
+ complexBase = toComplex (base );
110
+ }
111
+
90
112
testResolve (expect, relative) {
91
113
String name = "$base << $relative " ;
92
114
Expect .stringEquals (expect, base .resolve (relative).toString (), name);
115
+
116
+ Expect .stringEquals (expect, complexBase.resolve (relative).toString (),
117
+ name + " (complex base)" );
93
118
}
94
119
95
120
// From RFC 3986.
121
+ final urisSample = "http://a/b/c/d;p?q" ;
122
+ setBase (urisSample);
123
+
96
124
testResolve ("g:h" , "g:h" );
97
125
testResolve ("http://a/b/c/g" , "g" );
98
126
testResolve ("http://a/b/c/g" , "./g" );
@@ -139,47 +167,66 @@ testUriPerRFCs() {
139
167
// Additional tests (not from RFC 3986).
140
168
testResolve ("http://a/b/g;p/h;s" , "../g;p/h;s" );
141
169
142
- base = Uri . parse ("s:a/b" );
170
+ setBase ("s:a/b" );
143
171
testResolve ("s:a/c" , "c" );
144
172
testResolve ("s:/c" , "../c" );
145
173
146
- base = Uri . parse ("S:a/b" );
174
+ setBase ("S:a/b" );
147
175
testResolve ("s:a/c" , "c" );
148
176
testResolve ("s:/c" , "../c" );
149
177
150
- base = Uri . parse ("s:foo" );
178
+ setBase ("s:foo" );
151
179
testResolve ("s:bar" , "bar" );
152
180
testResolve ("s:bar" , "../bar" );
153
181
154
- base = Uri . parse ("S:foo" );
182
+ setBase ("S:foo" );
155
183
testResolve ("s:bar" , "bar" );
156
184
testResolve ("s:bar" , "../bar" );
157
185
158
186
// Special-case (deliberate non-RFC behavior).
159
- base = Uri . parse ("foo/bar" );
187
+ setBase ("foo/bar" );
160
188
testResolve ("foo/baz" , "baz" );
161
189
testResolve ("baz" , "../baz" );
162
190
163
- base = Uri . parse ("s:/foo" );
191
+ setBase ("s:/foo" );
164
192
testResolve ("s:/bar" , "bar" );
165
193
testResolve ("s:/bar" , "../bar" );
166
194
167
- base = Uri . parse ("S:/foo" );
195
+ setBase ("S:/foo" );
168
196
testResolve ("s:/bar" , "bar" );
169
197
testResolve ("s:/bar" , "../bar" );
170
198
171
199
// Test non-URI base (no scheme, no authority, relative path).
172
- base = Uri . parse ("a/b/c?_#_" );
200
+ setBase ("a/b/c?_#_" );
173
201
testResolve ("a/b/g?q#f" , "g?q#f" );
174
202
testResolve ("./" , "../.." );
175
203
testResolve ("../" , "../../.." );
176
204
testResolve ("a/b/" , "." );
177
205
testResolve ("c" , "../../c" ); // Deliberate non-RFC behavior.
178
- base = Uri . parse ("../../a/b/c?_#_" ); // Initial ".." in base url.
206
+ setBase ("../../a/b/c?_#_" ); // Initial ".." in base url.
179
207
testResolve ("../../a/d" , "../d" );
208
+ testResolve ("../../d" , "../../d" );
180
209
testResolve ("../../../d" , "../../../d" );
181
-
182
- base = Uri .parse ("s://h/p?q#f" ); // A simple base.
210
+ setBase ("../../a/b" );
211
+ testResolve ("../../a/d" , "d" );
212
+ testResolve ("../../d" , "../d" );
213
+ testResolve ("../../../d" , "../../d" );
214
+ setBase ("../../a" );
215
+ testResolve ("../../d" , "d" );
216
+ testResolve ("../../../d" , "../d" );
217
+ testResolve ("../../../../d" , "../../d" );
218
+
219
+ // Absoluyte path, not scheme or authority.
220
+ setBase ("/a" );
221
+ testResolve ("/b" , "b" );
222
+ testResolve ("/b" , "../b" );
223
+ testResolve ("/b" , "../../b" );
224
+ setBase ("/a/b" );
225
+ testResolve ("/a/c" , "c" );
226
+ testResolve ("/c" , "../c" );
227
+ testResolve ("/c" , "../../c" );
228
+
229
+ setBase ("s://h/p?q#f" ); // A simple base.
183
230
// Simple references:
184
231
testResolve ("s2://h2/P?Q#F" , "s2://h2/P?Q#F" );
185
232
testResolve ("s://h2/P?Q#F" , "//h2/P?Q#F" );
@@ -195,7 +242,7 @@ testUriPerRFCs() {
195
242
testResolve ("s://h/p?Q#F%20" , "?Q#F%20" );
196
243
testResolve ("s://h/p?q#F%20" , "#F%20" );
197
244
198
- base = Uri . parse ("s://h/p1/p2/p3" ); // A simple base with a path.
245
+ setBase ("s://h/p1/p2/p3" ); // A simple base with a path.
199
246
testResolve ("s://h/p1/p2/" , "." );
200
247
testResolve ("s://h/p1/p2/" , "./" );
201
248
testResolve ("s://h/p1/" , ".." );
@@ -206,7 +253,7 @@ testUriPerRFCs() {
206
253
testResolve ("s://h/" , "../../../.." );
207
254
testResolve ("s://h/" , "../../../../" );
208
255
209
- base = Uri . parse ("s://h/p?q#f%20" ); // A non-simpe base.
256
+ setBase ("s://h/p?q#f%20" ); // A non-simpe base.
210
257
// Simple references:
211
258
testResolve ("s2://h2/P?Q#F" , "s2://h2/P?Q#F" );
212
259
testResolve ("s://h2/P?Q#F" , "//h2/P?Q#F" );
@@ -222,7 +269,7 @@ testUriPerRFCs() {
222
269
testResolve ("s://h/p?Q#F%20" , "?Q#F%20" );
223
270
testResolve ("s://h/p?q#F%20" , "#F%20" );
224
271
225
- base = Uri . parse ("S://h/p1/p2/p3" ); // A non-simple base with a path.
272
+ setBase ("S://h/p1/p2/p3" ); // A non-simple base with a path.
226
273
testResolve ("s://h/p1/p2/" , "." );
227
274
testResolve ("s://h/p1/p2/" , "./" );
228
275
testResolve ("s://h/p1/" , ".." );
@@ -233,7 +280,7 @@ testUriPerRFCs() {
233
280
testResolve ("s://h/" , "../../../.." );
234
281
testResolve ("s://h/" , "../../../../" );
235
282
236
- base = Uri . parse ("../../../" ); // A simple relative path.
283
+ setBase ("../../../" ); // A simple relative path.
237
284
testResolve ("../../../a" , "a" );
238
285
testResolve ("../../../../a" , "../a" );
239
286
testResolve ("../../../a%20" , "a%20" );
@@ -242,8 +289,7 @@ testUriPerRFCs() {
242
289
// Tests covering the branches of the merge algorithm in RFC 3986
243
290
// with both simple and complex base URIs.
244
291
for (var b in ["s://a/pa/pb?q#f" , "s://a/pa/pb?q#f%20" ]) {
245
- var origBase = Uri .parse (b);
246
- base = origBase;
292
+ setBase (b);
247
293
248
294
// if defined(R.scheme) then ...
249
295
testResolve ("s2://a2/p2?q2#f2" , "s2://a2/p2?q2#f2" );
@@ -271,40 +317,40 @@ testUriPerRFCs() {
271
317
// (Cover the merge function and the remove-dot-fragments functions too).
272
318
273
319
// If base has authority and empty path ...
274
- var emptyPathBase = Uri . parse ( b.replaceFirst ("/pa/pb" , "" ) );
275
- base = emptyPathBase;
320
+ var emptyPathBase = b.replaceFirst ("/pa/pb" , "" );
321
+ setBase ( emptyPathBase) ;
276
322
testResolve ("s://a/p2?q2#f2" , "p2?q2#f2" );
277
323
testResolve ("s://a/p2#f2" , "p2#f2" );
278
324
testResolve ("s://a/p2" , "p2" );
279
325
280
- base = origBase ;
326
+ setBase (b) ;
281
327
// otherwise
282
328
// (Cover both no authority and non-empty path and both).
283
- var noAuthEmptyPathBase = Uri . parse ( b.replaceFirst ("//a/pa/pb" , "" ) );
284
- var noAuthAbsPathBase = Uri . parse ( b.replaceFirst ("//a" , "" ) );
285
- var noAuthRelPathBase = Uri . parse ( b.replaceFirst ("//a/" , "" ) );
286
- var noAuthRelSinglePathBase = Uri . parse ( b.replaceFirst ("//a/pa/" , "" ) );
329
+ var noAuthEmptyPathBase = b.replaceFirst ("//a/pa/pb" , "" );
330
+ var noAuthAbsPathBase = b.replaceFirst ("//a" , "" );
331
+ var noAuthRelPathBase = b.replaceFirst ("//a/" , "" );
332
+ var noAuthRelSinglePathBase = b.replaceFirst ("//a/pa/" , "" );
287
333
288
334
testResolve ("s://a/pa/p2?q2#f2" , "p2?q2#f2" );
289
335
testResolve ("s://a/pa/p2#f2" , "p2#f2" );
290
336
testResolve ("s://a/pa/p2" , "p2" );
291
337
292
- base = noAuthEmptyPathBase;
338
+ setBase ( noAuthEmptyPathBase) ;
293
339
testResolve ("s:p2?q2#f2" , "p2?q2#f2" );
294
340
testResolve ("s:p2#f2" , "p2#f2" );
295
341
testResolve ("s:p2" , "p2" );
296
342
297
- base = noAuthAbsPathBase;
343
+ setBase ( noAuthAbsPathBase) ;
298
344
testResolve ("s:/pa/p2?q2#f2" , "p2?q2#f2" );
299
345
testResolve ("s:/pa/p2#f2" , "p2#f2" );
300
346
testResolve ("s:/pa/p2" , "p2" );
301
347
302
- base = noAuthRelPathBase;
348
+ setBase ( noAuthRelPathBase) ;
303
349
testResolve ("s:pa/p2?q2#f2" , "p2?q2#f2" );
304
350
testResolve ("s:pa/p2#f2" , "p2#f2" );
305
351
testResolve ("s:pa/p2" , "p2" );
306
352
307
- base = noAuthRelSinglePathBase;
353
+ setBase ( noAuthRelSinglePathBase) ;
308
354
testResolve ("s:p2?q2#f2" , "p2?q2#f2" );
309
355
testResolve ("s:p2#f2" , "p2#f2" );
310
356
testResolve ("s:p2" , "p2" );
@@ -314,7 +360,7 @@ testUriPerRFCs() {
314
360
// A. if input buffer starts with "../" or "./".
315
361
// This only happens if base has only a single (may be empty) segment and
316
362
// no slash.
317
- base = emptyPathBase;
363
+ setBase ( emptyPathBase) ;
318
364
testResolve ("s://a/p2" , "../p2" );
319
365
testResolve ("s://a/" , "../" );
320
366
testResolve ("s://a/" , ".." );
@@ -324,7 +370,7 @@ testUriPerRFCs() {
324
370
testResolve ("s://a/p2" , "../../p2" );
325
371
testResolve ("s://a/p2" , "../../././p2" );
326
372
327
- base = noAuthRelSinglePathBase;
373
+ setBase ( noAuthRelSinglePathBase) ;
328
374
testResolve ("s:p2" , "../p2" );
329
375
testResolve ("s:" , "../" );
330
376
testResolve ("s:" , ".." );
@@ -337,31 +383,30 @@ testUriPerRFCs() {
337
383
// B. if input buffer starts with "/./" or is "/.". replace with "/".
338
384
// (The URI implementation removes the "." path segments when parsing,
339
385
// so this case isn't handled by merge).
340
- base = origBase ;
386
+ setBase (b) ;
341
387
testResolve ("s://a/pa/p2" , "./p2" );
342
388
343
389
// C. if input buffer starts with "/../" or is "/..", replace with "/"
344
390
// and remove preceeding segment.
345
391
testResolve ("s://a/p2" , "../p2" );
346
- var longPathBase = Uri . parse ( b.replaceFirst ("/pb" , "/pb/pc/pd" ) );
347
- base = longPathBase;
392
+ var longPathBase = b.replaceFirst ("/pb" , "/pb/pc/pd" );
393
+ setBase ( longPathBase) ;
348
394
testResolve ("s://a/pa/pb/p2" , "../p2" );
349
395
testResolve ("s://a/pa/p2" , "../../p2" );
350
396
testResolve ("s://a/p2" , "../../../p2" );
351
397
testResolve ("s://a/p2" , "../../../../p2" );
352
- var noAuthRelLongPathBase =
353
- Uri .parse (b.replaceFirst ("//a/pa/pb" , "pa/pb/pc/pd" ));
354
- base = noAuthRelLongPathBase;
398
+ var noAuthRelLongPathBase = b.replaceFirst ("//a/pa/pb" , "pa/pb/pc/pd" );
399
+ setBase (noAuthRelLongPathBase);
355
400
testResolve ("s:pa/pb/p2" , "../p2" );
356
401
testResolve ("s:pa/p2" , "../../p2" );
357
402
testResolve ("s:/p2" , "../../../p2" );
358
403
testResolve ("s:/p2" , "../../../../p2" );
359
404
360
405
// D. if the input buffer contains only ".." or ".", remove it.
361
- base = noAuthEmptyPathBase;
406
+ setBase ( noAuthEmptyPathBase) ;
362
407
testResolve ("s:" , ".." );
363
408
testResolve ("s:" , "." );
364
- base = noAuthRelSinglePathBase;
409
+ setBase ( noAuthRelSinglePathBase) ;
365
410
testResolve ("s:" , ".." );
366
411
testResolve ("s:" , "." );
367
412
}
0 commit comments