src/url_test.c
author Tero Marttila <terom@fixme.fi>
Sat, 13 Dec 2008 20:58:27 +0200
branchnew-evsql
changeset 55 0b92d553400a
parent 17 0a024b29b16d
permissions -rw-r--r--
evsql: more improvements
     1 #include <stdlib.h>
     2 #include <stdio.h>
     3 #include <string.h>
     4 
     5 #include "lib/url.h"
     6 
     7 #define FAIL(...) do { printf("FAIL: "); printf(__VA_ARGS__); printf("\n"); return -1; } while (0)
     8 
     9 struct url_schema
    10     basic_http = { 1, { "http" } },
    11     svn_ssh = { 2, { "svn", "ssh" } },
    12     schema_unix = { 1, { "unix" } }
    13     ;
    14 
    15 struct url_opts
    16     opts_single = { 1, { { "key0", "val0" } } },
    17     opts_multi = { 2, { { "key0", "val0" }, { "key1", "val1" } } },
    18     opts_nullval = { 1, { { "keyN", NULL } } }
    19     ;
    20 
    21 struct url_test {
    22     const char *url;
    23     const struct url expected;
    24 } url_tests[] = {
    25     {   "localhost:http",   {
    26         NULL, NULL, NULL, "localhost", "http", NULL, NULL
    27     } },
    28 
    29     {   "http://example.com/path",  {
    30         &basic_http, NULL, NULL, "example.com", NULL, "path", NULL 
    31     } },
    32 
    33     {   "svn+ssh://user:passwd@someplace:someport/something",   {
    34         &svn_ssh, "user", "passwd", "someplace", "someport", "something"
    35     } },
    36 
    37     {   "user@:service/",   {
    38         NULL, "user", NULL, NULL, "service", NULL
    39     } },
    40 
    41     {   "unix:////tmp/foo.sock",    {
    42         &schema_unix, NULL, NULL, NULL, NULL, "/tmp/foo.sock"
    43     } },
    44 
    45     {   "unix:///tmp/foo.sock", {
    46         &schema_unix, NULL, NULL, NULL, NULL, "tmp/foo.sock"
    47     } },
    48 
    49     {   "/tmp/foo.sock",    {
    50         NULL, NULL, NULL, NULL, NULL, "tmp/foo.sock"
    51     } },
    52 
    53     {   "?key0=val0",   {
    54         NULL, NULL, NULL, NULL, NULL, NULL, &opts_single
    55     } },
    56 
    57     {   "http://foo.com/index.php?key0=val0&key1=val1",  {
    58         &basic_http, NULL, NULL, "foo.com", NULL, "index.php", &opts_multi
    59     } },
    60 
    61     {   "example.org:81/?keyN", {
    62         NULL, NULL, NULL, "example.org", "81", NULL, &opts_nullval
    63     } },
    64 
    65     {   NULL,               {   } },
    66 };
    67 
    68 int cmp_url_str (const char *field, const char *test, const char *real) {
    69     if (!test) {
    70         if (real)
    71             FAIL("%s shouldn't be present", field);
    72 
    73     } else if (!real) {
    74         FAIL("%s is missing", field);
    75 
    76     } else {
    77         if (strcmp(test, real) != 0)
    78             FAIL("%s differs: %s -> %s", field, test, real);
    79     }
    80 
    81     // ok
    82     return 0;
    83 }
    84 
    85 int cmp_url (const struct url *test, const struct url *real) {
    86     int i;
    87 
    88     // test schema
    89     if (!test->schema) {
    90         if (real->schema)
    91             FAIL("test has no schema, but real does");
    92 
    93     } else if (!real->schema) {
    94         FAIL("test has a schema, but real doesn't");
    95 
    96     } else {
    97         if (test->schema->count != test->schema->count)
    98             FAIL("inconsistent scheme count");
    99         
   100         for (i = 0; i < test->schema->count; i++) {
   101             if (strcmp(test->schema->list[i], real->schema->list[i]) != 0)
   102                 FAIL("differing scheme #%d", i);
   103         }
   104     }
   105     
   106     // test username
   107     if (cmp_url_str("username", test->username, real->username))
   108         goto error;
   109 
   110     // test password
   111     if (cmp_url_str("password", test->password, real->password))
   112         goto error;
   113 
   114     // test hostname
   115     if (cmp_url_str("hostname", test->hostname, real->hostname))
   116         goto error;
   117 
   118     // test service
   119     if (cmp_url_str("service", test->service, real->service))
   120         goto error;
   121 
   122     // test path
   123     if (cmp_url_str("path", test->path, real->path))
   124         goto error;
   125 
   126     // test query
   127     if (!test->opts) {
   128         if (real->opts)
   129             FAIL("test has no opts, but real does");
   130 
   131     } else if (!real->opts) {
   132         FAIL("test has opts, but real doesn't");
   133 
   134     } else {
   135         if (test->opts->count != test->opts->count)
   136             FAIL("inconsistent opts count");
   137         
   138         for (i = 0; i < test->opts->count; i++) {
   139             if (cmp_url_str("opt key", test->opts->list[i].key, real->opts->list[i].key))
   140                 FAIL("differing opt key #%d", i);
   141             
   142             if (cmp_url_str("opt value", test->opts->list[i].value, real->opts->list[i].value))
   143                 FAIL("differing opt value #%d", i);
   144         }
   145     }
   146 
   147     // ok
   148     return 0;
   149 
   150 error:
   151     return -1;
   152 }
   153 
   154 void usage (const char *exec_name) {
   155     printf("Usage: %s\n\n\tNo arguments are accepted\n", exec_name);
   156 
   157     exit(EXIT_FAILURE);
   158 }
   159 
   160 int main (int argc, char **argv) {
   161     const struct url_test *test;
   162     struct url url;
   163 
   164     if (argc > 1)
   165         usage(argv[0]);
   166 
   167     // run the tests
   168     for (test = url_tests; test->url; test++) {
   169         // first output the URL we are handling...
   170         printf("%-80s - ", test->url);
   171         fflush(stdout);
   172         
   173         // parse the URL
   174         memset(&url, 0, sizeof(url));
   175 
   176         if (url_parse(&url, test->url)) {
   177             printf("FATAL: url_parse failed\n");
   178             return EXIT_FAILURE;
   179         }
   180         
   181         // compare it
   182         if (cmp_url(&test->expected, &url)) {
   183             printf("\texpected: ");
   184             url_dump(&test->expected, stdout);
   185 
   186             printf("\tresult:   ");
   187             url_dump(&url, stdout);
   188 
   189         } else {
   190             printf("OK\n\t");
   191             url_dump(&url, stdout);
   192         }
   193 
   194         printf("\n");
   195     }
   196 }
   197