Part of bug 382647 (move xpfe bookmarks to suite) - do the xpfe removals. r=KaiRo...
[mozilla-central.git] / netwerk / test / urltest.cpp
blob7646256e490113a34fc55f43cd7023a73e569ee9
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
22 * Contributor(s):
23 * Pierre Phaneuf <pp@ludusdesign.com>
25 * Alternatively, the contents of this file may be used under the terms of
26 * either the GNU General Public License Version 2 or later (the "GPL"), or
27 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 * in which case the provisions of the GPL or the LGPL are applicable instead
29 * of those above. If you wish to allow use of your version of this file only
30 * under the terms of either the GPL or the LGPL, and not to allow others to
31 * use your version of this file under the terms of the MPL, indicate your
32 * decision by deleting the provisions above and replace them with the notice
33 * and other provisions required by the GPL or the LGPL. If you do not delete
34 * the provisions above, a recipient may use your version of this file under
35 * the terms of any one of the MPL, the GPL or the LGPL.
37 * ***** END LICENSE BLOCK ***** */
40 A test file to check default URL parsing.
41 -Gagan Saksena 03/25/99
44 #include <stdio.h>
46 #include "TestCommon.h"
47 #include "plstr.h"
48 #include "nsIServiceManager.h"
49 #include "nsIIOService.h"
50 #include "nsIURL.h"
51 #include "nsCOMPtr.h"
52 #include "nsStringAPI.h"
53 #include "nsNetCID.h"
54 #include "nsIComponentRegistrar.h"
55 #include "nsComponentManagerUtils.h"
56 #include "nsServiceManagerUtils.h"
57 #include "nsXPCOM.h"
58 #include "prprf.h"
60 // Define CIDs...
61 static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
62 static NS_DEFINE_CID(kStdURLCID, NS_STANDARDURL_CID);
64 char* gFileIO = 0;
66 enum {
67 URL_FACTORY_DEFAULT,
68 URL_FACTORY_STDURL
71 nsresult writeoutto(const char* i_pURL, char** o_Result, PRInt32 urlFactory = URL_FACTORY_DEFAULT)
73 if (!o_Result || !i_pURL)
74 return NS_ERROR_FAILURE;
75 *o_Result = 0;
76 nsCOMPtr<nsIURI> pURL;
77 nsresult result = NS_OK;
79 switch (urlFactory) {
80 case URL_FACTORY_STDURL: {
81 nsIURI* url;
82 result = CallCreateInstance(kStdURLCID, &url);
83 if (NS_FAILED(result))
85 printf("CreateInstance failed\n");
86 return NS_ERROR_FAILURE;
88 pURL = url;
89 pURL->SetSpec(nsDependentCString(i_pURL));
90 break;
92 case URL_FACTORY_DEFAULT: {
93 nsCOMPtr<nsIIOService> pService =
94 do_GetService(kIOServiceCID, &result);
95 if (NS_FAILED(result))
97 printf("Service failed!\n");
98 return NS_ERROR_FAILURE;
100 result = pService->NewURI(nsDependentCString(i_pURL), nsnull, nsnull, getter_AddRefs(pURL));
104 nsCString output;
105 if (NS_SUCCEEDED(result))
107 nsCOMPtr<nsIURL> tURL = do_QueryInterface(pURL);
108 nsCAutoString temp;
109 PRInt32 port;
110 nsresult rv;
112 #define RESULT() NS_SUCCEEDED(rv) ? temp.get() : ""
114 rv = tURL->GetScheme(temp);
115 output += RESULT();
116 output += ',';
117 rv = tURL->GetUsername(temp);
118 output += RESULT();
119 output += ',';
120 rv = tURL->GetPassword(temp);
121 output += RESULT();
122 output += ',';
123 rv = tURL->GetHost(temp);
124 output += RESULT();
125 output += ',';
126 rv = tURL->GetPort(&port);
127 char portbuffer[40];
128 PR_snprintf(portbuffer, sizeof(portbuffer), "%d", port);
129 output.Append(portbuffer);
130 output += ',';
131 rv = tURL->GetDirectory(temp);
132 output += RESULT();
133 output += ',';
134 rv = tURL->GetFileBaseName(temp);
135 output += RESULT();
136 output += ',';
137 rv = tURL->GetFileExtension(temp);
138 output += RESULT();
139 output += ',';
140 rv = tURL->GetParam(temp);
141 output += RESULT();
142 output += ',';
143 rv = tURL->GetQuery(temp);
144 output += RESULT();
145 output += ',';
146 rv = tURL->GetRef(temp);
147 output += RESULT();
148 output += ',';
149 rv = tURL->GetSpec(temp);
150 output += RESULT();
151 *o_Result = ToNewCString(output);
152 } else {
153 output = "Can not create URL";
154 *o_Result = ToNewCString(output);
156 return NS_OK;
159 nsresult writeout(const char* i_pURL, PRInt32 urlFactory = URL_FACTORY_DEFAULT)
161 char* temp = 0;
162 if (!i_pURL) return NS_ERROR_FAILURE;
163 int rv = writeoutto(i_pURL, &temp, urlFactory);
164 printf("%s\n%s\n", i_pURL, temp);
165 delete[] temp;
166 return rv;
169 /* construct a url and print out its elements separated by commas and
170 the whole spec */
171 nsresult testURL(const char* i_pURL, PRInt32 urlFactory = URL_FACTORY_DEFAULT)
174 if (i_pURL)
175 return writeout(i_pURL, urlFactory);
177 if (!gFileIO)
178 return NS_ERROR_FAILURE;
180 FILE *testfile = fopen(gFileIO, "rt");
181 if (!testfile)
183 fprintf(stderr, "Cannot open testfile: %s\n", gFileIO);
184 return NS_ERROR_FAILURE;
187 char temp[512];
188 int count=0;
189 int failed=0;
190 char* prevResult = nsnull;
191 char* tempurl = nsnull;
193 while (fgets(temp,512,testfile))
195 if (*temp == '#' || !*temp)
196 continue;
198 if (0 == count%3)
200 if (prevResult) delete[] prevResult;
201 printf("Testing: %s\n", temp);
202 writeoutto(temp, &prevResult, urlFactory);
204 else if (1 == count%3) {
205 if (tempurl) delete[] tempurl;
206 tempurl = strdup(temp);
207 } else {
208 if (!prevResult)
209 printf("no results to compare to!\n");
210 else
212 PRInt32 res;
213 printf("Result: %s\n", prevResult);
214 if (urlFactory != URL_FACTORY_DEFAULT) {
215 printf("Expected: %s\n", tempurl);
216 res = PL_strcmp(tempurl, prevResult);
217 } else {
218 printf("Expected: %s\n", temp);
219 res = PL_strcmp(temp, prevResult);
222 if (res == 0)
223 printf("\tPASSED\n\n");
224 else
226 printf("\tFAILED\n\n");
227 failed++;
231 count++;
233 if (failed>0) {
234 printf("%d tests FAILED out of %d\n", failed, count/3);
235 return NS_ERROR_FAILURE;
236 } else {
237 printf("All %d tests PASSED.\n", count/3);
238 return NS_OK;
242 nsresult makeAbsTest(const char* i_BaseURI, const char* relativePortion,
243 const char* expectedResult)
245 if (!i_BaseURI)
246 return NS_ERROR_FAILURE;
248 // build up the base URL
249 nsresult status;
250 nsCOMPtr<nsIURI> baseURL = do_CreateInstance(kStdURLCID, &status);
251 if (NS_FAILED(status))
253 printf("CreateInstance failed\n");
254 return status;
256 status = baseURL->SetSpec(nsDependentCString(i_BaseURI));
257 if (NS_FAILED(status)) return status;
260 // get the new spec
261 nsCAutoString newURL;
262 status = baseURL->Resolve(nsDependentCString(relativePortion), newURL);
263 if (NS_FAILED(status)) return status;
265 nsCAutoString temp;
266 baseURL->GetSpec(temp);
268 printf("Analyzing %s\n", temp.get());
269 printf("With %s\n", relativePortion);
271 printf("Got %s\n", newURL.get());
272 if (expectedResult) {
273 printf("Expect %s\n", expectedResult);
274 int res = PL_strcmp(newURL.get(), expectedResult);
275 if (res == 0) {
276 printf("\tPASSED\n\n");
277 return NS_OK;
278 } else {
279 printf("\tFAILED\n\n");
280 return NS_ERROR_FAILURE;
283 return NS_OK;
286 int doMakeAbsTest(const char* i_URL = 0, const char* i_relativePortion=0)
288 if (i_URL && i_relativePortion)
290 return makeAbsTest(i_URL, i_relativePortion, nsnull);
293 // Run standard tests. These tests are based on the ones described in
294 // rfc2396 with the exception of the handling of ?y which is wrong as
295 // notified by on of the RFC authors.
297 /* Section C.1. Normal Examples
299 g:h = <URL:g:h>
300 g = <URL:http://a/b/c/g>
301 ./g = <URL:http://a/b/c/g>
302 g/ = <URL:http://a/b/c/g/>
303 /g = <URL:http://a/g>
304 //g = <URL:http://g>
305 ?y = <URL:http://a/b/c/d;p?y>
306 g?y = <URL:http://a/b/c/g?y>
307 g?y/./x = <URL:http://a/b/c/g?y/./x>
308 #s = <URL:http://a/b/c/d;p?q#s>
309 g#s = <URL:http://a/b/c/g#s>
310 g#s/./x = <URL:http://a/b/c/g#s/./x>
311 g?y#s = <URL:http://a/b/c/g?y#s>
312 ;x = <URL:http://a/b/c/;x>
313 g;x = <URL:http://a/b/c/g;x>
314 g;x?y#s = <URL:http://a/b/c/g;x?y#s>
315 . = <URL:http://a/b/c/>
316 ./ = <URL:http://a/b/c/>
317 .. = <URL:http://a/b/>
318 ../ = <URL:http://a/b/>
319 ../g = <URL:http://a/b/g>
320 ../.. = <URL:http://a/>
321 ../../ = <URL:http://a/>
322 ../../g = <URL:http://a/g>
325 struct test {
326 const char* baseURL;
327 const char* relativeURL;
328 const char* expectedResult;
331 test tests[] = {
332 // Tests from rfc2396, section C.1 with the exception of the
333 // handling of ?y
334 { "http://a/b/c/d;p?q#f", "g:h", "g:h" },
335 { "http://a/b/c/d;p?q#f", "g", "http://a/b/c/g" },
336 { "http://a/b/c/d;p?q#f", "./g", "http://a/b/c/g" },
337 { "http://a/b/c/d;p?q#f", "g/", "http://a/b/c/g/" },
338 { "http://a/b/c/d;p?q#f", "/g", "http://a/g" },
339 { "http://a/b/c/d;p?q#f", "//g", "http://g" },
340 { "http://a/b/c/d;p?q#f", "?y", "http://a/b/c/d;p?y" },
341 { "http://a/b/c/d;p?q#f", "g?y", "http://a/b/c/g?y" },
342 { "http://a/b/c/d;p?q#f", "g?y/./x", "http://a/b/c/g?y/./x" },
343 { "http://a/b/c/d;p?q#f", "#s", "http://a/b/c/d;p?q#s" },
344 { "http://a/b/c/d;p?q#f", "g#s", "http://a/b/c/g#s" },
345 { "http://a/b/c/d;p?q#f", "g#s/./x", "http://a/b/c/g#s/./x" },
346 { "http://a/b/c/d;p?q#f", "g?y#s", "http://a/b/c/g?y#s" },
347 { "http://a/b/c/d;p?q#f", ";x", "http://a/b/c/;x" },
348 { "http://a/b/c/d;p?q#f", "g;x", "http://a/b/c/g;x" },
349 { "http://a/b/c/d;p?q#f", "g;x?y#s", "http://a/b/c/g;x?y#s" },
350 { "http://a/b/c/d;p?q#f", ".", "http://a/b/c/" },
351 { "http://a/b/c/d;p?q#f", "./", "http://a/b/c/" },
352 { "http://a/b/c/d;p?q#f", "..", "http://a/b/" },
353 { "http://a/b/c/d;p?q#f", "../", "http://a/b/" },
354 { "http://a/b/c/d;p?q#f", "../g", "http://a/b/g" },
355 { "http://a/b/c/d;p?q#f", "../..", "http://a/" },
356 { "http://a/b/c/d;p?q#f", "../../", "http://a/" },
357 { "http://a/b/c/d;p?q#f", "../../g", "http://a/g" },
359 // Our additional tests...
360 { "http://a/b/c/d;p?q#f", "#my::anchor", "http://a/b/c/d;p?q#my::anchor" },
361 { "http://a/b/c/d;p?q#f", "get?baseRef=viewcert.jpg", "http://a/b/c/get?baseRef=viewcert.jpg" },
363 // Make sure relative query's work right even if the query
364 // string contains absolute urls or other junk.
365 { "http://a/b/c/d;p?q#f", "?http://foo", "http://a/b/c/d;p?http://foo" },
366 { "http://a/b/c/d;p?q#f", "g?http://foo", "http://a/b/c/g?http://foo" },
367 {"http://a/b/c/d;p?q#f", "g/h?http://foo", "http://a/b/c/g/h?http://foo" },
368 { "http://a/b/c/d;p?q#f", "g/h/../H?http://foo","http://a/b/c/g/H?http://foo" },
369 { "http://a/b/c/d;p?q#f", "g/h/../H?http://foo?baz", "http://a/b/c/g/H?http://foo?baz" },
370 { "http://a/b/c/d;p?q#f", "g/h/../H?http://foo;baz", "http://a/b/c/g/H?http://foo;baz" },
371 { "http://a/b/c/d;p?q#f", "g/h/../H?http://foo#bar", "http://a/b/c/g/H?http://foo#bar" },
372 { "http://a/b/c/d;p?q#f", "g/h/../H;baz?http://foo", "http://a/b/c/g/H;baz?http://foo" },
373 { "http://a/b/c/d;p?q#f", "g/h/../H;baz?http://foo#bar", "http://a/b/c/g/H;baz?http://foo#bar" },
374 { "http://a/b/c/d;p?q#f", "g/h/../H;baz?C:\\temp", "http://a/b/c/g/H;baz?C:\\temp" },
375 { "http://a/b/c/d;p?q#f", "", "http://a/b/c/d;p?q" },
376 { "http://a/b/c/d;p?q#f", "#", "http://a/b/c/d;p?q#" },
377 { "http://a/b/c;p/d;p?q#f", "../g;p" , "http://a/b/g;p" },
381 const int numTests = sizeof(tests) / sizeof(tests[0]);
382 int failed = 0;
383 nsresult rv;
384 for (int i = 0 ; i<numTests ; ++i)
386 rv = makeAbsTest(tests[i].baseURL, tests[i].relativeURL,
387 tests[i].expectedResult);
388 if (NS_FAILED(rv))
389 failed++;
391 if (failed>0) {
392 printf("%d tests FAILED out of %d\n", failed, numTests);
393 return NS_ERROR_FAILURE;
394 } else {
395 printf("All %d tests PASSED.\n", numTests);
396 return NS_OK;
400 void printusage(void)
402 printf("urltest [-std] [-file <filename>] <URL> "
403 " [-abs <relative>]\n\n"
404 "\t-std : Generate results using nsStdURL.\n"
405 "\t-file : Read URLs from file.\n"
406 "\t-abs : Make an absolute URL from the base (<URL>) and the\n"
407 "\t\trelative path specified. If -abs is given without\n"
408 "\t\ta base URI standard RFC 2396 relative URL tests\n"
409 "\t\tare performed. Implies -std.\n"
410 "\t<URL> : The string representing the URL.\n");
413 int main(int argc, char **argv)
415 if (test_common_init(&argc, &argv) != 0)
416 return -1;
418 int rv = -1;
420 if (argc < 2) {
421 printusage();
422 return NS_OK;
425 nsCOMPtr<nsIServiceManager> servMan;
426 NS_InitXPCOM2(getter_AddRefs(servMan), nsnull, nsnull);
427 nsCOMPtr<nsIComponentRegistrar> registrar = do_QueryInterface(servMan);
428 NS_ASSERTION(registrar, "Null nsIComponentRegistrar");
429 if (registrar)
430 registrar->AutoRegister(nsnull);
432 // end of all messages from register components...
433 printf("------------------\n\n");
435 PRInt32 urlFactory = URL_FACTORY_DEFAULT;
436 PRBool bMakeAbs= PR_FALSE;
437 char* relativePath = 0;
438 char* url = 0;
439 for (int i=1; i<argc; i++) {
440 if (PL_strcasecmp(argv[i], "-std") == 0)
442 urlFactory = URL_FACTORY_STDURL;
443 if (i+1 >= argc)
445 printusage();
446 return NS_OK;
449 else if (PL_strcasecmp(argv[i], "-abs") == 0)
451 if (!gFileIO)
453 relativePath = argv[i+1];
454 i++;
456 bMakeAbs = PR_TRUE;
458 else if (PL_strcasecmp(argv[i], "-file") == 0)
460 if (i+1 >= argc)
462 printusage();
463 return NS_OK;
465 gFileIO = argv[i+1];
466 i++;
468 else
470 url = argv[i];
473 PRTime startTime = PR_Now();
474 if (bMakeAbs)
476 rv = (url && relativePath)
477 ? doMakeAbsTest(url, relativePath)
478 : doMakeAbsTest();
480 else
482 rv = gFileIO ? testURL(0, urlFactory) : testURL(url, urlFactory);
484 if (gFileIO)
486 PRTime endTime = PR_Now();
487 printf("Elapsed time: %d micros.\n", (PRInt32)
488 (endTime - startTime));
490 } // this scopes the nsCOMPtrs
491 // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM
492 rv = NS_ShutdownXPCOM(nsnull);
493 return rv;