LCOV - code coverage report
Current view: top level - glib/glib/tests - markup-collect.c (source / functions) Hit Total Coverage
Test: unnamed Lines: 54 55 98.2 %
Date: 2024-04-23 05:16:05 Functions: 5 5 100.0 %
Branches: 20 24 83.3 %

           Branch data     Line data    Source code
       1                 :            : /* 
       2                 :            :  * Copyright © 2007 Ryan Lortie
       3                 :            :  * 
       4                 :            :  * SPDX-License-Identifier: LGPL-2.1-or-later
       5                 :            :  *
       6                 :            :  * This program is free software; you can redistribute it and/or
       7                 :            :  * modify it under the terms of the GNU Lesser General Public
       8                 :            :  * License as published by the Free Software Foundation; either
       9                 :            :  * version 2.1 of the License, or (at your option) any later version.
      10                 :            :  * 
      11                 :            :  * See the included COPYING file for more information.
      12                 :            :  */
      13                 :            : 
      14                 :            : #include <stdlib.h>
      15                 :            : #include <string.h>
      16                 :            : #include <glib.h>
      17                 :            : 
      18                 :            : static void
      19                 :         20 : start (GMarkupParseContext  *context,
      20                 :            :        const char           *element_name,
      21                 :            :        const char          **attribute_names,
      22                 :            :        const char          **attribute_values,
      23                 :            :        gpointer              user_data,
      24                 :            :        GError              **error)
      25                 :            : {
      26                 :         20 :   GString *string = user_data;
      27                 :            :   gboolean result;
      28                 :            : 
      29                 :            : #define collect(...) \
      30                 :            :   g_markup_collect_attributes (element_name, attribute_names, \
      31                 :            :                                attribute_values, error, __VA_ARGS__, \
      32                 :            :                                G_MARKUP_COLLECT_INVALID)
      33                 :            : #define BOOL    G_MARKUP_COLLECT_BOOLEAN
      34                 :            : #define OPTBOOL G_MARKUP_COLLECT_BOOLEAN | G_MARKUP_COLLECT_OPTIONAL
      35                 :            : #define TRI     G_MARKUP_COLLECT_TRISTATE
      36                 :            : #define STR     G_MARKUP_COLLECT_STRING
      37                 :            : #define STRDUP  G_MARKUP_COLLECT_STRDUP
      38                 :            : #define OPTSTR  G_MARKUP_COLLECT_STRING | G_MARKUP_COLLECT_OPTIONAL
      39                 :            : #define OPTDUP  G_MARKUP_COLLECT_STRDUP | G_MARKUP_COLLECT_OPTIONAL
      40                 :            : #define n(x)    ((x)?(x):"(null)")
      41                 :            : 
      42         [ +  + ]:         20 :   if (strcmp (element_name, "bool") == 0)
      43                 :            :     {
      44                 :         12 :       gboolean mb = 2, ob = 2, tri = 2;
      45                 :            : 
      46                 :         12 :       result = collect (BOOL,    "mb", &mb,
      47                 :            :                         OPTBOOL, "ob", &ob,
      48                 :            :                         TRI,     "tri", &tri);
      49                 :            : 
      50                 :         12 :       g_assert (result ||
      51                 :            :                 (mb == FALSE && ob == FALSE && tri != TRUE && tri != FALSE));
      52                 :            : 
      53   [ +  +  +  + ]:         12 :       if (tri != FALSE && tri != TRUE)
      54                 :         10 :         tri = -1;
      55                 :            : 
      56                 :         12 :       g_string_append_printf (string, "<bool(%d) %d %d %d>",
      57                 :            :                               result, mb, ob, tri);
      58                 :            :     }
      59                 :            : 
      60         [ +  - ]:          8 :   else if (strcmp (element_name, "str") == 0)
      61                 :            :     {
      62                 :            :       const char *cm, *co;
      63                 :            :       char *am, *ao;
      64                 :            : 
      65                 :          8 :       result = collect (STR,    "cm", &cm,
      66                 :            :                         STRDUP, "am", &am,
      67                 :            :                         OPTDUP, "ao", &ao,
      68                 :            :                         OPTSTR, "co", &co);
      69                 :            : 
      70                 :          8 :       g_assert (result ||
      71                 :            :                 (cm == NULL && am == NULL && ao == NULL && co == NULL));
      72                 :            : 
      73                 :         32 :       g_string_append_printf (string, "<str(%d) %s %s %s %s>",
      74   [ -  +  -  +  :         32 :                               result, n (cm), n (am), n (ao), n (co));
             +  +  +  + ]
      75                 :            : 
      76                 :          8 :       g_free (am);
      77                 :          8 :       g_free (ao);
      78                 :            :     }
      79                 :         20 : }
      80                 :            : 
      81                 :            : static GMarkupParser parser = { start, NULL, NULL, NULL, NULL };
      82                 :            : 
      83                 :            : struct test
      84                 :            : {
      85                 :            :   const char   *document;
      86                 :            :   const char   *result;
      87                 :            :   GMarkupError  error_code;
      88                 :            :   const char   *error_info;
      89                 :            : };
      90                 :            : 
      91                 :            : static struct test tests[] =
      92                 :            : {
      93                 :            :   { "<bool mb='y'>", "<bool(1) 1 0 -1>",
      94                 :            :     G_MARKUP_ERROR_PARSE, "'bool'" },
      95                 :            : 
      96                 :            :   { "<bool mb='false'/>", "<bool(1) 0 0 -1>", 0, NULL },
      97                 :            :   { "<bool mb='true'/>", "<bool(1) 1 0 -1>", 0, NULL },
      98                 :            :   { "<bool mb='t' ob='f' tri='1'/>", "<bool(1) 1 0 1>", 0, NULL },
      99                 :            :   { "<bool mb='y' ob='n' tri='0'/>", "<bool(1) 1 0 0>", 0, NULL },
     100                 :            : 
     101                 :            :   { "<bool mb='y' my:attr='q'><my:tag/></bool>", "<bool(1) 1 0 -1>", 0, NULL },
     102                 :            :   { "<bool mb='y' my:attr='q'><my:tag>some <b>text</b> is in here</my:tag></bool>",
     103                 :            :     "<bool(1) 1 0 -1>", 0, NULL },
     104                 :            : 
     105                 :            :   { "<bool ob='y'/>", "<bool(0) 0 0 -1>",
     106                 :            :     G_MARKUP_ERROR_MISSING_ATTRIBUTE, "'mb'" },
     107                 :            : 
     108                 :            :   { "<bool mb='y' mb='y'/>", "<bool(0) 0 0 -1>",
     109                 :            :     G_MARKUP_ERROR_INVALID_CONTENT, "'mb'" },
     110                 :            : 
     111                 :            :   { "<bool mb='y' tri='y' tri='n'/>", "<bool(0) 0 0 -1>",
     112                 :            :     G_MARKUP_ERROR_INVALID_CONTENT, "'tri'" },
     113                 :            : 
     114                 :            :   { "<str cm='x' am='y'/>", "<str(1) x y (null) (null)>", 0, NULL },
     115                 :            : 
     116                 :            :   { "<str am='x' co='y'/>", "<str(0) (null) (null) (null) (null)>",
     117                 :            :     G_MARKUP_ERROR_MISSING_ATTRIBUTE, "'cm'" },
     118                 :            : 
     119                 :            :   { "<str am='x'/>", "<str(0) (null) (null) (null) (null)>",
     120                 :            :     G_MARKUP_ERROR_MISSING_ATTRIBUTE, "'cm'" },
     121                 :            : 
     122                 :            :   { "<str am='x' cm='x' am='y'/>", "<str(0) (null) (null) (null) (null)>",
     123                 :            :     G_MARKUP_ERROR_INVALID_CONTENT, "'am'" },
     124                 :            : 
     125                 :            :   { "<str am='x' qm='y' cm='x'/>", "<str(0) (null) (null) (null) (null)>",
     126                 :            :     G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE, "'qm'" },
     127                 :            : 
     128                 :            :   { "<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)>",
     129                 :            :     G_MARKUP_ERROR_INVALID_CONTENT, "'am'" },
     130                 :            : 
     131                 :            :   { "<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)>",
     132                 :            :     G_MARKUP_ERROR_INVALID_CONTENT, "'am'" },
     133                 :            : 
     134                 :            :   { "<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'/>",
     135                 :            :     "<str(0) (null) (null) (null) (null)>",
     136                 :            :     G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE, "'a'" },
     137                 :            : 
     138                 :            :   { "<bool mb='ja'/>", "<bool(0) 0 0 -1>",
     139                 :            :     G_MARKUP_ERROR_INVALID_CONTENT, "'mb'" },
     140                 :            : 
     141                 :            :   { "<bool mb='nein'/>", "<bool(0) 0 0 -1>",
     142                 :            :     G_MARKUP_ERROR_INVALID_CONTENT, "'mb'" }
     143                 :            : };
     144                 :            : 
     145                 :            : static void
     146                 :         20 : test_collect (gconstpointer d)
     147                 :            : {
     148                 :         20 :   const struct test *test = d;
     149                 :            : 
     150                 :            :   GMarkupParseContext *ctx;
     151                 :         20 :   GError *error = NULL;
     152                 :            :   GString *string;
     153                 :            :   gboolean result;
     154                 :            : 
     155                 :         20 :   string = g_string_new ("");
     156                 :         20 :   ctx = g_markup_parse_context_new (&parser, G_MARKUP_IGNORE_QUALIFIED, string, NULL);
     157                 :         20 :   result = g_markup_parse_context_parse (ctx,
     158                 :         20 :                                          test->document,
     159                 :            :                                          -1, &error);
     160         [ +  + ]:         20 :   if (result)
     161                 :          8 :     result = g_markup_parse_context_end_parse (ctx, &error);
     162                 :            : 
     163         [ +  + ]:         20 :   if (result)
     164                 :            :     {
     165                 :          7 :       g_assert_no_error (error);
     166                 :          7 :       g_assert_cmpint (test->error_code, ==, 0);
     167                 :          7 :       g_assert_cmpstr (test->result, ==, string->str);
     168                 :            :     }
     169                 :            :   else
     170                 :            :     {
     171                 :         13 :       g_assert_error (error, G_MARKUP_ERROR, (gint) test->error_code);
     172                 :            :     }
     173                 :            : 
     174                 :         20 :   g_markup_parse_context_free (ctx);
     175                 :         20 :   g_string_free (string, TRUE);
     176                 :         20 :   g_clear_error (&error);
     177                 :         20 : }
     178                 :            : 
     179                 :            : #define XML "<element a='1' b='2' c='3'/>"
     180                 :            : 
     181                 :            : static void
     182                 :          1 : start_element (GMarkupParseContext  *context,
     183                 :            :                const gchar          *element_name,
     184                 :            :                const gchar         **attribute_names,
     185                 :            :                const gchar         **attribute_values,
     186                 :            :                gpointer              user_data,
     187                 :            :                GError              **error)
     188                 :            : {
     189                 :            :   /* Omitting "c" attribute intentionally to trigger crash. */
     190                 :          1 :   g_markup_collect_attributes (element_name,
     191                 :            :                                attribute_names,
     192                 :            :                                attribute_values,
     193                 :            :                                error,
     194                 :            :                                G_MARKUP_COLLECT_STRING, "a", NULL,
     195                 :            :                                G_MARKUP_COLLECT_STRING, "b", NULL,
     196                 :            :                                G_MARKUP_COLLECT_INVALID);
     197                 :          1 : }
     198                 :            : 
     199                 :            : static GMarkupParser cleanup_parser = {
     200                 :            :   start_element, NULL, NULL, NULL, NULL
     201                 :            : };
     202                 :            : 
     203                 :            : static void
     204                 :          1 : test_cleanup (void)
     205                 :            : {
     206                 :            :   GMarkupParseContext *context;
     207                 :            : 
     208         [ -  + ]:          1 :   if (!g_test_undefined ())
     209                 :          0 :     return;
     210                 :            : 
     211                 :          1 :   context = g_markup_parse_context_new (&cleanup_parser,
     212                 :            :                                         G_MARKUP_DEFAULT_FLAGS, NULL,
     213                 :            :                                         NULL);
     214                 :          1 :   g_markup_parse_context_parse (context, XML, -1, NULL);
     215                 :            : 
     216                 :          1 :   g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
     217                 :            :                          "g_markup_parse_context_end_parse: assertion 'context->state != STATE_ERROR' failed");
     218                 :          1 :   g_markup_parse_context_end_parse (context, NULL);
     219                 :          1 :   g_test_assert_expected_messages ();
     220                 :            : 
     221                 :          1 :   g_markup_parse_context_free (context);
     222                 :            : }
     223                 :            : 
     224                 :            : int
     225                 :          1 : main (int argc, char **argv)
     226                 :            : {
     227                 :            :   gsize i;
     228                 :            :   gchar *path;
     229                 :            : 
     230                 :          1 :   g_test_init (&argc, &argv, NULL);
     231                 :            : 
     232         [ +  + ]:         21 :   for (i = 0; i < G_N_ELEMENTS (tests); i++)
     233                 :            :     {
     234                 :         20 :       path = g_strdup_printf ("/markup/collect/%" G_GSIZE_FORMAT, i);
     235                 :         20 :       g_test_add_data_func (path, &tests[i], test_collect);
     236                 :         20 :       g_free (path);
     237                 :            :     }
     238                 :            : 
     239                 :          1 :   g_test_add_func ("/markup/collect/cleanup", test_cleanup);
     240                 :            : 
     241                 :          1 :   return g_test_run ();
     242                 :            : }

Generated by: LCOV version 1.14