Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright  2007 Ryan Lortie
      3  *
      4  * This program is free software: you can redistribute it and/or modify
      5  * it under the terms of the GNU Lesser General Public License as
      6  * published by the Free Software Foundation; either version 2 of the
      7  * License, or (at your option) any later version.
      8  *
      9  * See the included COPYING file for more information.
     10  */
     11 
     12 #include <string.h>
     13 #include <glib.h>
     14 
     15 static void
     16 start (GMarkupParseContext  *context,
     17        const char           *element_name,
     18        const char          **attribute_names,
     19        const char          **attribute_values,
     20        gpointer              user_data,
     21        GError              **error)
     22 {
     23   GString *string = user_data;
     24   gboolean result;
     25 
     26 #define collect(...) \
     27   g_markup_collect_attributes (element_name, attribute_names, \
     28                                attribute_values, error, __VA_ARGS__, \
     29                                G_MARKUP_COLLECT_INVALID)
     30 #define BOOL    G_MARKUP_COLLECT_BOOLEAN
     31 #define OPTBOOL G_MARKUP_COLLECT_BOOLEAN | G_MARKUP_COLLECT_OPTIONAL
     32 #define TRI     G_MARKUP_COLLECT_TRISTATE
     33 #define STR     G_MARKUP_COLLECT_STRING
     34 #define STRDUP  G_MARKUP_COLLECT_STRDUP
     35 #define OPTSTR  G_MARKUP_COLLECT_STRING | G_MARKUP_COLLECT_OPTIONAL
     36 #define OPTDUP  G_MARKUP_COLLECT_STRDUP | G_MARKUP_COLLECT_OPTIONAL
     37 #define n(x)    ((x)?(x):"(null)")
     38 
     39   if (strcmp (element_name, "bool") == 0)
     40     {
     41       gboolean mb = 2, ob = 2, tri = 2;
     42 
     43       result = collect (BOOL,    "mb", &mb,
     44                         OPTBOOL, "ob", &ob,
     45                         TRI,     "tri", &tri);
     46 
     47       g_assert (result ||
     48                 (mb == FALSE && ob == FALSE && tri != TRUE && tri != FALSE));
     49 
     50       if (tri != FALSE && tri != TRUE)
     51         tri = -1;
     52 
     53       g_string_append_printf (string, "<bool(%d) %d %d %d>",
     54                               result, mb, ob, tri);
     55     }
     56 
     57   else if (strcmp (element_name, "str") == 0)
     58     {
     59       const char *cm, *co;
     60       char *am, *ao;
     61 
     62       result = collect (STR,    "cm", &cm,
     63                         STRDUP, "am", &am,
     64                         OPTDUP, "ao", &ao,
     65                         OPTSTR, "co", &co);
     66 
     67       g_assert (result ||
     68                 (cm == NULL && am == NULL && ao == NULL && co == NULL));
     69 
     70       g_string_append_printf (string, "<str(%d) %s %s %s %s>",
     71                               result, n (cm), n (am), n (ao), n (co));
     72 
     73       g_free (am);
     74       g_free (ao);
     75     }
     76 }
     77 
     78 static GMarkupParser parser = { start };
     79 
     80 struct test
     81 {
     82   const char   *document;
     83   const char   *result;
     84   GMarkupError  error_code;
     85   const char   *error_info;
     86 };
     87 
     88 static struct test tests[] =
     89 {
     90   { "<bool mb='y'>", "<bool(1) 1 0 -1>",
     91     G_MARKUP_ERROR_PARSE, "'bool'" },
     92 
     93   { "<bool mb='false'/>", "<bool(1) 0 0 -1>" },
     94   { "<bool mb='true'/>", "<bool(1) 1 0 -1>" },
     95   { "<bool mb='t' ob='f' tri='1'/>", "<bool(1) 1 0 1>" },
     96   { "<bool mb='y' ob='n' tri='0'/>", "<bool(1) 1 0 0>" },
     97 
     98   { "<bool ob='y'/>", "<bool(0) 0 0 -1>",
     99     G_MARKUP_ERROR_MISSING_ATTRIBUTE, "'mb'" },
    100 
    101   { "<bool mb='y' mb='y'/>", "<bool(0) 0 0 -1>",
    102     G_MARKUP_ERROR_INVALID_CONTENT, "'mb'" },
    103 
    104   { "<bool mb='y' tri='y' tri='n'/>", "<bool(0) 0 0 -1>",
    105     G_MARKUP_ERROR_INVALID_CONTENT, "'tri'" },
    106 
    107   { "<str cm='x' am='y'/>", "<str(1) x y (null) (null)>" },
    108 
    109   { "<str am='x' co='y'/>", "<str(0) (null) (null) (null) (null)>",
    110     G_MARKUP_ERROR_MISSING_ATTRIBUTE, "'cm'" },
    111 
    112   { "<str am='x'/>", "<str(0) (null) (null) (null) (null)>",
    113     G_MARKUP_ERROR_MISSING_ATTRIBUTE, "'cm'" },
    114 
    115   { "<str am='x' cm='x' am='y'/>", "<str(0) (null) (null) (null) (null)>",
    116     G_MARKUP_ERROR_INVALID_CONTENT, "'am'" },
    117 
    118   { "<str am='x' qm='y' cm='x'/>", "<str(0) (null) (null) (null) (null)>",
    119     G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE, "'qm'" },
    120 
    121   { "<str am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' cm='x'/>", "<str(0) (null) (null) (null) (null)>",
    122     G_MARKUP_ERROR_INVALID_CONTENT, "'am'" },
    123 
    124   { "<str cm='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x' am='x'/>", "<str(0) (null) (null) (null) (null)>",
    125     G_MARKUP_ERROR_INVALID_CONTENT, "'am'" },
    126 
    127   { "<str a='x' b='x' c='x' d='x' e='x' f='x' g='x' h='x' i='x' j='x' k='x' l='x' m='x' n='x' o='x' p='x' q='x' r='x' s='x' t='x' u='x' v='x' w='x' x='x' y='x' z='x' aa='x' bb='x' cc='x' dd='x' ee='x' ff='x' gg='x' hh='x' ii='x' jj='x' kk='x' ll='x' mm='x' nn='x' oo='x' pp='x' qq='x' rr='x' ss='x' tt='x' uu='x' vv='x' ww='x' xx='x' yy='x' zz='x' am='x' cm='x'/>",
    128     "<str(0) (null) (null) (null) (null)>",
    129     G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE, "'a'" },
    130 
    131   { "<bool mb='ja'/>", "<bool(0) 0 0 -1>",
    132     G_MARKUP_ERROR_INVALID_CONTENT, "'mb'" },
    133 
    134   { "<bool mb='nein'/>", "<bool(0) 0 0 -1>",
    135     G_MARKUP_ERROR_INVALID_CONTENT, "'mb'" }
    136 };
    137 
    138 int
    139 main (int argc, char **argv)
    140 {
    141   gboolean verbose = FALSE;
    142   int i;
    143 
    144   if (argc > 1)
    145     {
    146       if (argc != 2 || strcmp (argv[1], "-v") != 0)
    147         {
    148           g_print ("error: call with no arguments or '-v' for verbose\n");
    149           return 1;
    150         }
    151 
    152       verbose = TRUE;
    153     }
    154 
    155   for (i = 0; i < G_N_ELEMENTS (tests); i++)
    156     {
    157       GMarkupParseContext *ctx;
    158       GError *error = NULL;
    159       GString *string;
    160       gboolean result;
    161 
    162       string = g_string_new ("");
    163       ctx = g_markup_parse_context_new (&parser, 0, string, NULL);
    164       result = g_markup_parse_context_parse (ctx,
    165                                              tests[i].document,
    166                                              -1, &error);
    167       if (result)
    168         result = g_markup_parse_context_end_parse (ctx, &error);
    169 
    170       if (verbose)
    171         g_print ("%d: %s:\n  (error %d, \"%s\")\n  %s\n\n",
    172                  i, tests[i].document,
    173                  error ? error->code : 0,
    174                  error ? error->message : "(no error)",
    175                  string->str);
    176 
    177       if (result)
    178         {
    179           if (error != NULL)
    180             g_error ("parser successful but error is set: "
    181                      "%s(%d) '%s'", g_quark_to_string (error->domain),
    182                      error->code, error->message);
    183 
    184           if (tests[i].error_code != 0)
    185             g_error ("parser succeeded on test %d ('%s') but "
    186                      "we expected a failure with code %d\n", i,
    187                      tests[i].document, tests[i].error_code);
    188         }
    189       else
    190         {
    191           if (error->domain != G_MARKUP_ERROR)
    192             g_error ("error occured on test %d ('%s') but is not in "
    193                      "the GMarkupError domain, but rather '%s'", i,
    194                      tests[i].document, g_quark_to_string (error->domain));
    195 
    196           if (error->code != tests[i].error_code)
    197             g_error ("failure expected with test %d ('%s') but it "
    198                     "has error code %d (we expected code %d)", i,
    199                     tests[i].document, error->code, tests[i].error_code);
    200 
    201           if (strstr (error->message, tests[i].error_info) == NULL)
    202             g_error ("failure message on test %d ('%s') fails "
    203                      "to mention '%s' in the error message", i,
    204                      tests[i].document, tests[i].error_info);
    205         }
    206 
    207       if (strcmp (tests[i].result, string->str) != 0)
    208         g_error ("result on test %d ('%s') expected to be '%s' "
    209                  "but came out as '%s'", i, tests[i].document,
    210                  tests[i].result, string->str);
    211 
    212       g_markup_parse_context_free (ctx);
    213       g_string_free (string, TRUE);
    214       g_clear_error (&error);
    215     }
    216 
    217   if (verbose)
    218     g_print ("\n*** all tests passed ***\n\n");
    219 
    220   return 0;
    221 }
    222