LCOV - code coverage report
Current view: top level - tests - vector-expression.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 472 472 100.0 %
Date: 2024-05-11 21:41:31 Functions: 21 21 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 310 618 50.2 %

           Branch data     Line data    Source code
       1                 :            : #undef G_DISABLE_ASSERT
       2                 :            : 
       3                 :            : #include <gtk/gtk.h>
       4                 :            : #include <shumate/shumate.h>
       5                 :            : #include "shumate/vector/shumate-vector-expression-interpolate-private.h"
       6                 :            : #include "shumate/vector/shumate-vector-expression-filter-private.h"
       7                 :            : 
       8                 :            : static void
       9                 :          3 : test_vector_expression_parse (void)
      10                 :            : {
      11                 :          6 :   g_autoptr(GError) error = NULL;
      12         [ -  + ]:          6 :   g_autoptr(JsonNode) node1 = json_from_string ("{\"stops\": [[12, 1], [13, 2], [14, 5], [16, 9]]}", NULL);
      13         [ +  - ]:          6 :   g_autoptr(JsonNode) node2 = json_from_string ("1.0", NULL);
      14         [ +  - ]:          3 :   g_autoptr(ShumateVectorExpression) expr1 = NULL;
      15         [ +  - ]:          3 :   g_autoptr(ShumateVectorExpression) expr2 = NULL;
      16         [ +  - ]:          3 :   g_autoptr(ShumateVectorExpression) expr3 = NULL;
      17                 :            : 
      18                 :          3 :   expr1 = shumate_vector_expression_from_json (node1, &error);
      19         [ -  + ]:          3 :   g_assert_no_error (error);
      20         [ -  + ]:          3 :   g_assert_true (SHUMATE_IS_VECTOR_EXPRESSION_INTERPOLATE (expr1));
      21                 :            : 
      22                 :          3 :   expr2 = shumate_vector_expression_from_json (node2, &error);
      23         [ -  + ]:          3 :   g_assert_no_error (error);
      24         [ -  + ]:          3 :   g_assert_true (SHUMATE_IS_VECTOR_EXPRESSION_FILTER (expr2));
      25                 :            : 
      26                 :          3 :   expr3 = shumate_vector_expression_from_json (NULL, &error);
      27         [ -  + ]:          3 :   g_assert_no_error (error);
      28   [ -  +  +  - ]:          3 :   g_assert_true (SHUMATE_IS_VECTOR_EXPRESSION_FILTER (expr3));
      29                 :          3 : }
      30                 :            : 
      31                 :            : 
      32                 :            : static void
      33                 :          3 : test_vector_expression_literal (void)
      34                 :            : {
      35                 :          6 :   g_auto(ShumateVectorValue) value = SHUMATE_VECTOR_VALUE_INIT;
      36                 :          3 :   g_autoptr(ShumateVectorExpression) expr = NULL;
      37                 :          3 :   double result;
      38                 :            : 
      39                 :          3 :   shumate_vector_value_set_number (&value, 3.1415);
      40                 :          3 :   expr = shumate_vector_expression_filter_from_literal (&value);
      41                 :            : 
      42                 :          3 :   result = shumate_vector_expression_eval_number (expr, NULL, -10);
      43   [ -  +  +  - ]:          3 :   g_assert_cmpfloat (3.1415, ==, result);
      44                 :          3 : }
      45                 :            : 
      46                 :            : 
      47                 :            : static void
      48                 :          3 : test_vector_expression_number_array (void)
      49                 :            : {
      50                 :          6 :   g_autoptr(GError) error = NULL;
      51         [ -  + ]:          6 :   g_autoptr(JsonNode) node = json_from_string ("[1, 2, 3, 4, 5]", NULL);
      52         [ +  - ]:          3 :   g_autoptr(ShumateVectorExpression) expression;
      53         [ +  - ]:          3 :   g_auto(ShumateVectorValue) value = SHUMATE_VECTOR_VALUE_INIT;
      54                 :          3 :   double num;
      55                 :            : 
      56                 :          3 :   expression = shumate_vector_expression_from_json (node, &error);
      57         [ -  + ]:          3 :   g_assert_no_error (error);
      58                 :            : 
      59         [ -  + ]:          3 :   g_assert_true (shumate_vector_expression_eval (expression, NULL, &value));
      60         [ -  + ]:          3 :   g_assert_cmpint (5, ==, value.array->len);
      61         [ +  + ]:         18 :   for (int i = 0; i < 5; i++)
      62                 :            :     {
      63         [ -  + ]:         15 :       g_assert_true (shumate_vector_value_get_number (value.array->pdata[i], &num));
      64         [ -  + ]:         15 :       g_assert_cmpfloat (i + 1, ==, num);
      65                 :            :     }
      66                 :          3 : }
      67                 :            : 
      68                 :            : 
      69                 :            : static void
      70                 :          3 : test_vector_expression_nested_array_literal (void)
      71                 :            : {
      72                 :          6 :   g_autoptr(GError) error = NULL;
      73         [ +  - ]:          6 :   g_autoptr(JsonNode) node = json_from_string ("[\"in\", 2, [1, 2, 3, 4, 5]]", NULL);
      74         [ +  - ]:          3 :   g_autoptr(ShumateVectorExpression) expression;
      75         [ -  + ]:          3 :   g_auto(ShumateVectorValue) value = SHUMATE_VECTOR_VALUE_INIT;
      76                 :            : 
      77                 :          3 :   expression = shumate_vector_expression_from_json (node, &error);
      78   [ +  -  +  -  :          3 :   g_assert_error (error, SHUMATE_STYLE_ERROR, SHUMATE_STYLE_ERROR_INVALID_EXPRESSION);
                   -  + ]
      79                 :          3 : }
      80                 :            : 
      81                 :            : 
      82                 :            : static void
      83                 :          6 : check_interpolate (ShumateVectorExpression *expression)
      84                 :            : {
      85                 :          6 :   ShumateVectorRenderScope scope;
      86                 :            : 
      87                 :            :   /* Test that exact stop values work */
      88                 :          6 :   scope.zoom_level = 12;
      89         [ -  + ]:          6 :   g_assert_cmpfloat (1.0, ==, shumate_vector_expression_eval_number (expression, &scope, -10000.0));
      90                 :          6 :   scope.zoom_level = 13;
      91         [ -  + ]:          6 :   g_assert_cmpfloat (2.0, ==, shumate_vector_expression_eval_number (expression, &scope, -10000.0));
      92                 :          6 :   scope.zoom_level = 14;
      93         [ -  + ]:          6 :   g_assert_cmpfloat (5.0, ==, shumate_vector_expression_eval_number (expression, &scope, -10000.0));
      94                 :          6 :   scope.zoom_level = 16;
      95         [ -  + ]:          6 :   g_assert_cmpfloat (9.0, ==, shumate_vector_expression_eval_number (expression, &scope, -10000.0));
      96                 :            : 
      97                 :            :   /* Test that outlier values work */
      98                 :          6 :   scope.zoom_level = 1;
      99         [ -  + ]:          6 :   g_assert_cmpfloat (1.0, ==, shumate_vector_expression_eval_number (expression, &scope, -10000.0));
     100                 :          6 :   scope.zoom_level = 100;
     101         [ -  + ]:          6 :   g_assert_cmpfloat (9.0, ==, shumate_vector_expression_eval_number (expression, &scope, -10000.0));
     102                 :            : 
     103                 :            :   /* Test that in-between values work */
     104                 :          6 :   scope.zoom_level = 12.5;
     105         [ -  + ]:          6 :   g_assert_cmpfloat (1.5, ==, shumate_vector_expression_eval_number (expression, &scope, -10000.0));
     106                 :          6 :   scope.zoom_level = 15;
     107         [ -  + ]:          6 :   g_assert_cmpfloat (7.0, ==, shumate_vector_expression_eval_number (expression, &scope, -10000.0));
     108                 :          6 : }
     109                 :            : 
     110                 :            : static void
     111                 :          3 : test_vector_expression_interpolate (void)
     112                 :            : {
     113                 :          6 :   g_autoptr(GError) error = NULL;
     114         [ -  + ]:          6 :   g_autoptr(JsonNode) node = json_from_string ("{\"stops\": [[12, 1], [13, 2], [14, 5], [16, 9]]}", NULL);
     115         [ +  - ]:          3 :   g_autoptr(ShumateVectorExpression) expression;
     116                 :            : 
     117         [ -  + ]:          3 :   g_assert_nonnull (node);
     118                 :            : 
     119                 :          3 :   expression = shumate_vector_expression_from_json (node, &error);
     120         [ -  + ]:          3 :   g_assert_no_error (error);
     121                 :            : 
     122         [ +  - ]:          3 :   check_interpolate (expression);
     123                 :          3 : }
     124                 :            : 
     125                 :            : static void
     126                 :          3 : test_vector_expression_interpolate_filter (void)
     127                 :            : {
     128                 :          6 :   g_autoptr(GError) error = NULL;
     129         [ -  + ]:          6 :   g_autoptr(JsonNode) node = json_from_string ("[\"interpolate\", [\"linear\"], [\"zoom\"], 12, 1, 13, 2, 14, 5, 16, 9]", NULL);
     130         [ +  - ]:          3 :   g_autoptr(ShumateVectorExpression) expression;
     131                 :            : 
     132         [ -  + ]:          3 :   g_assert_nonnull (node);
     133                 :            : 
     134                 :          3 :   expression = shumate_vector_expression_from_json (node, &error);
     135         [ -  + ]:          3 :   g_assert_no_error (error);
     136                 :            : 
     137         [ +  - ]:          3 :   check_interpolate (expression);
     138                 :          3 : }
     139                 :            : 
     140                 :            : 
     141                 :            : static void
     142                 :          6 : check_interpolate_color (ShumateVectorExpression *expression)
     143                 :            : {
     144                 :          6 :   ShumateVectorRenderScope scope;
     145                 :          6 :   GdkRGBA color, correct_color;
     146                 :            : 
     147                 :            :   /* Test that exact stop values work */
     148                 :          6 :   scope.zoom_level = 12;
     149                 :          6 :   shumate_vector_expression_eval_color (expression, &scope, &color);
     150                 :          6 :   gdk_rgba_parse (&correct_color, "#00224466");
     151         [ -  + ]:          6 :   g_assert_true (gdk_rgba_equal (&color, &correct_color));
     152                 :            : 
     153                 :          6 :   scope.zoom_level = 12.5;
     154                 :          6 :   shumate_vector_expression_eval_color (expression, &scope, &color);
     155                 :          6 :   gdk_rgba_parse (&correct_color, "#446688AA");
     156         [ -  + ]:          6 :   g_assert_true (gdk_rgba_equal (&color, &correct_color));
     157                 :            : 
     158                 :          6 :   scope.zoom_level = 13;
     159                 :          6 :   shumate_vector_expression_eval_color (expression, &scope, &color);
     160                 :          6 :   gdk_rgba_parse (&correct_color, "#88AACCEE");
     161         [ -  + ]:          6 :   g_assert_true (gdk_rgba_equal (&color, &correct_color));
     162                 :          6 : }
     163                 :            : 
     164                 :            : static void
     165                 :          3 : test_vector_expression_interpolate_color (void)
     166                 :            : {
     167                 :          6 :   g_autoptr(GError) error = NULL;
     168         [ -  + ]:          6 :   g_autoptr(JsonNode) node = json_from_string ("{\"stops\": [[12, \"#00224466\"], [13, \"#88AACCEE\"]]}", NULL);
     169         [ +  - ]:          3 :   g_autoptr(ShumateVectorExpression) expression;
     170                 :            : 
     171         [ -  + ]:          3 :   g_assert_nonnull (node);
     172                 :            : 
     173                 :          3 :   expression = shumate_vector_expression_from_json (node, &error);
     174         [ -  + ]:          3 :   g_assert_no_error (error);
     175                 :            : 
     176         [ +  - ]:          3 :   check_interpolate_color (expression);
     177                 :          3 : }
     178                 :            : 
     179                 :            : static void
     180                 :          3 : test_vector_expression_interpolate_color_filter (void)
     181                 :            : {
     182                 :          6 :   g_autoptr(GError) error = NULL;
     183         [ -  + ]:          6 :   g_autoptr(JsonNode) node = json_from_string ("[\"interpolate\", [\"linear\"], [\"zoom\"], 12, \"#00224466\", 13, \"#88AACCEE\"]", NULL);
     184         [ +  - ]:          3 :   g_autoptr(ShumateVectorExpression) expression;
     185                 :            : 
     186         [ -  + ]:          3 :   g_assert_nonnull (node);
     187                 :            : 
     188                 :          3 :   expression = shumate_vector_expression_from_json (node, &error);
     189         [ -  + ]:          3 :   g_assert_no_error (error);
     190                 :            : 
     191         [ +  - ]:          3 :   check_interpolate_color (expression);
     192                 :          3 : }
     193                 :            : 
     194                 :            : 
     195                 :            : static gboolean
     196                 :        540 : filter_with_scope (ShumateVectorRenderScope *scope, const char *filter)
     197                 :            : {
     198                 :       1080 :   g_autoptr(GError) error = NULL;
     199         [ -  + ]:        540 :   g_autoptr(JsonNode) node = NULL;
     200         [ +  - ]:        540 :   g_autoptr(ShumateVectorExpression) expression = NULL;
     201                 :            : 
     202                 :        540 :   node = json_from_string (filter, &error);
     203         [ -  + ]:        540 :   g_assert_no_error (error);
     204                 :            : 
     205                 :        540 :   expression = shumate_vector_expression_from_json (node, &error);
     206         [ -  + ]:        540 :   g_assert_no_error (error);
     207                 :            : 
     208         [ +  - ]:        540 :   return shumate_vector_expression_eval_boolean (expression, scope, FALSE);
     209                 :            : }
     210                 :            : 
     211                 :            : 
     212                 :            : static gboolean
     213                 :        465 : filter (const char *filter)
     214                 :            : {
     215                 :        465 :   return filter_with_scope (NULL, filter);
     216                 :            : }
     217                 :            : 
     218                 :            : 
     219                 :            : static void
     220                 :          3 : test_vector_expression_basic_filter (void)
     221                 :            : {
     222         [ -  + ]:          3 :   g_assert_true  (filter ("true"));
     223         [ -  + ]:          3 :   g_assert_false (filter ("false"));
     224         [ -  + ]:          3 :   g_assert_false (filter ("[\"!\", true]"));
     225         [ -  + ]:          3 :   g_assert_true  (filter ("[\"!\", false]"));
     226         [ -  + ]:          3 :   g_assert_true  (filter ("[\"any\", false, true]"));
     227         [ -  + ]:          3 :   g_assert_false (filter ("[\"any\", false, false]"));
     228         [ -  + ]:          3 :   g_assert_true  (filter ("[\"none\", false, false]"));
     229         [ -  + ]:          3 :   g_assert_false (filter ("[\"none\", true, false]"));
     230         [ -  + ]:          3 :   g_assert_true  (filter ("[\"all\", true, true]"));
     231         [ -  + ]:          3 :   g_assert_false (filter ("[\"all\", false, true]"));
     232                 :            : 
     233         [ -  + ]:          3 :   g_assert_false (filter ("[\"any\"]"));
     234         [ -  + ]:          3 :   g_assert_true  (filter ("[\"none\"]"));
     235         [ -  + ]:          3 :   g_assert_true  (filter ("[\"all\"]"));
     236                 :            : 
     237         [ -  + ]:          3 :   g_assert_true  (filter ("[\"in\", 10, 20, 10, 13]"));
     238         [ -  + ]:          3 :   g_assert_true  (filter ("[\"!in\", 10, 20, 0, 13]"));
     239         [ -  + ]:          3 :   g_assert_true  (filter ("[\"==\", [\"literal\", []], [\"literal\", []]]"));
     240         [ -  + ]:          3 :   g_assert_true  (filter ("[\"==\", [\"literal\", [10, true, \"A\", null]], [\"literal\", [10, true, \"A\", null]]]"));
     241         [ -  + ]:          3 :   g_assert_true  (filter ("[\"in\", 13, [\"literal\", [10, 20, 0, 13]]]"));
     242                 :            : 
     243         [ -  + ]:          3 :   g_assert_true  (filter ("[\"==\", null, null]"));
     244         [ -  + ]:          3 :   g_assert_true  (filter ("[\"==\", 10, 10]"));
     245         [ -  + ]:          3 :   g_assert_false (filter ("[\"==\", 10, 20]"));
     246         [ -  + ]:          3 :   g_assert_false (filter ("[\"==\", 10, \"10\"]"));
     247         [ -  + ]:          3 :   g_assert_false (filter ("[\"!=\", 10, 10]"));
     248         [ -  + ]:          3 :   g_assert_true  (filter ("[\"!=\", 10, 20]"));
     249         [ -  + ]:          3 :   g_assert_true  (filter ("[\"!=\", 10, \"10\"]"));
     250         [ -  + ]:          3 :   g_assert_true  (filter ("[\">\", 20, 10]"));
     251         [ -  + ]:          3 :   g_assert_false (filter ("[\">\", 10, 10]"));
     252         [ -  + ]:          3 :   g_assert_false (filter ("[\">\", 5, 10]"));
     253         [ -  + ]:          3 :   g_assert_true  (filter ("[\"<\", 10, 20]"));
     254         [ -  + ]:          3 :   g_assert_false (filter ("[\"<\", 10, 10]"));
     255         [ -  + ]:          3 :   g_assert_false (filter ("[\"<\", 10, 5]"));
     256         [ -  + ]:          3 :   g_assert_true  (filter ("[\">=\", 20, 10]"));
     257         [ -  + ]:          3 :   g_assert_true  (filter ("[\">=\", 10, 10]"));
     258         [ -  + ]:          3 :   g_assert_false (filter ("[\">=\", 5, 10]"));
     259         [ -  + ]:          3 :   g_assert_true  (filter ("[\"<=\", 10, 20]"));
     260         [ -  + ]:          3 :   g_assert_true  (filter ("[\"<=\", 10, 10]"));
     261         [ -  + ]:          3 :   g_assert_false (filter ("[\"<=\", 10, 5]"));
     262                 :            : 
     263         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"case\", true, 0, 1], 0]"));
     264         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"case\", false, 0, 1], 1]"));
     265         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"case\", false, 0, true, 2], 2]"));
     266         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"match\", \"a\", \"b\", 2, \"c\", 3, \"a\", 1, 0], 1]"));
     267         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"match\", \"b\", 2], 2]"));
     268         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"match\", 3, [1, 2], \"x\", [3, 4, 5], \"y\", \"z\"], \"y\"]"));
     269                 :            : 
     270         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"+\", 3, 1, 7], 11]"));
     271         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"-\", 3, 1], 2]"));
     272         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"-\", 1], -1]"));
     273         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"*\", 5, 6, 7], 210]"));
     274         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"/\", 10, 4], 2.5]"));
     275         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", -1, [\"%\", -21, 4]]"));
     276                 :            : 
     277         [ -  + ]:          3 :   g_assert_true (filter ("[\">=\", 2, [\"^\", [\"e\"], [\"ln2\"]]]"));
     278         [ -  + ]:          3 :   g_assert_true (filter ("[\"<=\", 1.9999999999, [\"^\", [\"e\"], [\"ln2\"]]]"));
     279         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", 1, [\"abs\", -1]]"));
     280         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", 1, [\"abs\", 1]]"));
     281         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", 0, [\"acos\", 1]]"));
     282         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", 0, [\"asin\", 0]]"));
     283         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", 0, [\"atan\", 0]]"));
     284         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", 0, [\"ceil\", -0.5]]"));
     285         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", -1, [\"cos\", [\"pi\"]]]"));
     286         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", -1, [\"floor\", -0.5]]"));
     287         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", 1, [\"ln\", [\"e\"]]]"));
     288         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", 2, [\"log10\", 100]]"));
     289         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", 6, [\"log2\", 64]]"));
     290         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", 6, [\"max\", -10, 3, 6, -10000]]"));
     291         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", -10000, [\"min\", -10, 3, 6, -10000]]"));
     292         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", 0, [\"round\", 0.49999]]"));
     293         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", 1, [\"round\", 0.5]]"));
     294         [ -  + ]:          3 :   g_assert_true (filter ("[\">=\", 0.0000000000001, [\"sin\", [\"pi\"]]]"));
     295         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", 12, [\"sqrt\", 144]]"));
     296         [ -  + ]:          3 :   g_assert_true (filter ("[\">=\", 0.0000000000001, [\"tan\", [\"pi\"]]]"));
     297                 :            : 
     298         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"coalesce\", null, [\"*\", 0, \"b\"], 2, 3], 2]"));
     299         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"coalesce\", null, [\"*\", 0, \"b\"]], null]"));
     300         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"coalesce\", \"red\"], \"red\"]"));
     301                 :            : 
     302         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"concat\", \"hello\", 10, \"world\", true], \"hello10worldtrue\"]"));
     303         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"downcase\", \"HeLlO, WoRlD!\"], \"hello, world!\"]"));
     304         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"upcase\", \"HeLlO, WoRlD!\"], \"HELLO, WORLD!\"]"));
     305         [ -  + ]:          3 :   g_assert_true (filter ("[\">\", [\"literal\", \"oranges\"], \"apples\"]"));
     306         [ -  + ]:          3 :   g_assert_true (filter ("[\"<\", [\"literal\", \"apples\"], \"oranges\"]"));
     307         [ -  + ]:          3 :   g_assert_true (filter ("[\">=\", [\"literal\", \"oranges\"], \"apples\"]"));
     308         [ -  + ]:          3 :   g_assert_true (filter ("[\"<=\", [\"literal\", \"apples\"], \"oranges\"]"));
     309         [ -  + ]:          3 :   g_assert_true (filter ("[\">=\", [\"literal\", \"apples\"], \"apples\"]"));
     310         [ -  + ]:          3 :   g_assert_true (filter ("[\"<=\", [\"literal\", \"oranges\"], \"oranges\"]"));
     311                 :            : 
     312         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"at\", 0, [\"literal\", [\"a\", \"b\", \"c\"]]], \"a\"]"));
     313         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"at\", 1, [\"literal\", [\"a\", \"b\", \"c\"]]], \"b\"]"));
     314         [ -  + ]:          3 :   g_assert_false (filter ("[\"==\", [\"at\", 3, [\"literal\", [\"a\", \"b\", \"c\"]]], null]"));
     315         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"index-of\", 2, [\"literal\", [1, 2, 3]]], 1]"));
     316         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"index-of\", 4, [\"literal\", [1, 2, 3]]], -1]"));
     317         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"index-of\", \"!\", \"Hello, \U0001F30E!\"], 8]"));
     318         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"index-of\", \"world\", \"Hello, world!\"], 7]"));
     319         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"index-of\", \"WORLD\", \"Hello, world!\"], -1]"));
     320         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"index-of\", \"Hello\", \"Hello, world!\", 1], -1]"));
     321         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"length\", [\"literal\", []]], 0]"));
     322         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"length\", [\"literal\", [\"a\", \"b\", \"c\"]]], 3]"));
     323         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"length\", \"Hello, \U0001F30E!\"], 9]"));
     324         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"slice\", [\"literal\", [\"a\", \"b\", \"c\"]], 0, 2], [\"literal\", [\"a\", \"b\"]]]"));
     325         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"slice\", [\"literal\", [\"a\", \"b\", \"c\"]], 1, 2], [\"literal\", [\"b\"]]]"));
     326         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"slice\", \"Hello, \U0001F30E!\", 7], \"\U0001F30E!\"]"));
     327         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"slice\", \"Hello, \U0001F30E!\", 7, 8], \"\U0001F30E\"]"));
     328                 :            : 
     329                 :            :   /* Test slice with negative and out of range indices */
     330         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"slice\", [\"literal\", [\"a\", \"b\", \"c\"]], -2], [\"literal\", [\"b\", \"c\"]]]"));
     331         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"slice\", [\"literal\", [\"a\", \"b\", \"c\"]], -3], [\"literal\", [\"a\", \"b\", \"c\"]]]"));
     332         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"slice\", [\"literal\", [\"a\", \"b\", \"c\"]], -4], [\"literal\", [\"a\", \"b\", \"c\"]]]"));
     333         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"slice\", [\"literal\", [\"a\", \"b\", \"c\"]], 0, -1], [\"literal\", [\"a\", \"b\"]]]"));
     334         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"slice\", [\"literal\", [\"a\", \"b\", \"c\"]], 0, -3], [\"literal\", []]]"));
     335         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"slice\", [\"literal\", [\"a\", \"b\", \"c\"]], 0, -4], [\"literal\", []]]"));
     336         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"slice\", [\"literal\", [\"a\", \"b\", \"c\"]], 3, 4], [\"literal\", []]]"));
     337         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"slice\", \"abc\", -2], \"bc\"]"));
     338         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"slice\", \"abc\", -3], \"abc\"]"));
     339         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"slice\", \"abc\", -4], \"abc\"]"));
     340         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"slice\", \"abc\", 0, -1], \"ab\"]"));
     341         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"slice\", \"abc\", 0, -3], \"\"]"));
     342         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"slice\", \"abc\", 0, -4], \"\"]"));
     343         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"slice\", \"abc\", 3, 4], \"\"]"));
     344                 :            : 
     345         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"literal\", \"hello\"], \"HELLO\", [\"collator\", {\"case-sensitive\": false}]]"));
     346         [ -  + ]:          3 :   g_assert_true (filter ("[\"!=\", [\"literal\", \"hello\"], \"HELLO\", [\"collator\", {\"case-sensitive\": true}]]"));
     347         [ -  + ]:          3 :   g_assert_true (filter ("[\">\", [\"literal\", \"hello\"], \"a\", [\"collator\", {}]]"));
     348         [ -  + ]:          3 :   g_assert_true (filter ("[\"<\", [\"literal\", \"a\"], \"hello\", [\"collator\", {}]]"));
     349         [ -  + ]:          3 :   g_assert_true (filter ("[\"!=\", [\"resolved-locale\", [\"collator\", {}]], \"foo\"]"));
     350                 :            : 
     351         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"step\", -10, \"a\", 1, \"b\", 2, \"c\"], \"a\"]"));
     352         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"step\", 1.5, \"a\", 1, \"b\", 2, \"c\"], \"b\"]"));
     353         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"step\", 2, \"a\", 1, \"b\", 2, \"c\"], \"c\"]"));
     354         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"step\", 3, \"a\", 1, \"b\", 2, \"c\"], \"c\"]"));
     355                 :            : 
     356         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"to-boolean\", 0], false]"));
     357         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"to-boolean\", 1], true]"));
     358         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"to-boolean\", -2], true]"));
     359         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"to-boolean\", null], false]"));
     360         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"to-boolean\", \"\"], false]"));
     361         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"to-boolean\", \"hello\"], true]"));
     362         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"to-boolean\", [\"collator\", {}]], true]"));
     363         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"to-color\", \"red\"], [\"to-color\", \"rgb(255, 0, 0)\"]]"));
     364         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"to-color\", \"not a color\", \"#FF0000\"], [\"to-color\", \"rgb(255, 0, 0)\"]]"));
     365         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"to-number\", \"2\"], 2]"));
     366         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"to-number\", \"-.5\"], -0.5]"));
     367         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"to-number\", \"1e3\"], 1000]"));
     368         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"to-number\", null], 0]"));
     369         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"to-number\", false], 0]"));
     370         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"to-number\", true], 1]"));
     371         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"to-number\", \"not a number\", 10], 10]"));
     372         [ -  + ]:          3 :   g_assert_false (filter ("[\"==\", 2, \"2\"]"));
     373         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"to-string\", 2], \"2\"]"));
     374         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"to-string\", \"a\"], \"a\"]"));
     375         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"to-string\", true], \"true\"]"));
     376         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"to-string\", false], \"false\"]"));
     377         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"to-string\", null], \"\"]"));
     378         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"to-string\", [\"to-color\", \"gold\"]], \"rgba(255,215,0,1)\"]"));
     379         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"to-string\", [\"to-color\", \"rgba(255, 1, 2, 0.1)\"]], \"rgba(255,1,2,0.1)\"]"));
     380         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"to-string\", [\"literal\", [1, 0.5, null, true, [\"b\"]]]], \"[1,0.5,null,true,[\\\"b\\\"]]\"]"));
     381                 :            : 
     382                 :            :   /* Test NaN/inf handling */
     383         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"to-boolean\", [\"/\", 0, 0]], false]"));
     384         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"to-boolean\", [\"/\", 1, 0]], true]"));
     385         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"to-string\", [\"/\", 0, 0]], \"NaN\"]"));
     386         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"to-string\", [\"/\", 1, 0]], \"Infinity\"]"));
     387         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"to-string\", [\"/\", -1, 0]], \"-Infinity\"]"));
     388         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"to-string\", [\"%\", 0, 0]], \"NaN\"]"));
     389         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"to-string\", [\"%\", 1, 0]], \"NaN\"]"));
     390         [ -  + ]:          3 :   g_assert_true (filter ("[\"==\", [\"to-string\", [\"%\", -1, 0]], \"NaN\"]"));
     391                 :          3 : }
     392                 :            : 
     393                 :            : 
     394                 :            : static void
     395                 :          3 : test_vector_expression_variable_binding (void)
     396                 :            : {
     397         [ -  + ]:          3 :   g_assert_true  (filter ("[\"let\", \"a\", [\"-\", 15, 5], \"b\", 20, [\"==\", 30, [\"+\", [\"var\", \"a\"], [\"var\", \"b\"]]]]"));
     398                 :            : 
     399                 :            :   /* Test nesting */
     400         [ -  + ]:          3 :   g_assert_true  (filter ("[\"let\", \"a\", 10, [\"==\", 20, [\"let\", \"a\", 20, [\"var\", \"a\"]]]]"));
     401                 :          3 : }
     402                 :            : 
     403                 :            : 
     404                 :            : static void
     405                 :          3 : test_vector_expression_image (void)
     406                 :            : {
     407                 :          6 :   g_autoptr(GdkTexture) texture = NULL;
     408         [ +  - ]:          3 :   g_autoptr(GBytes) json_data = NULL;
     409                 :          3 :   GError *error = NULL;
     410                 :          3 :   ShumateVectorRenderScope scope;
     411                 :            : 
     412                 :          3 :   texture = gdk_texture_new_from_resource ("/org/gnome/shumate/Tests/sprites.png");
     413         [ -  + ]:          3 :   g_assert_no_error (error);
     414                 :          3 :   json_data = g_resources_lookup_data ("/org/gnome/shumate/Tests/sprites.json", G_RESOURCE_LOOKUP_FLAGS_NONE, NULL);
     415         [ -  + ]:          3 :   g_assert_no_error (error);
     416                 :            : 
     417                 :          3 :   scope.sprites = shumate_vector_sprite_sheet_new ();
     418                 :          3 :   scope.scale_factor = 1;
     419                 :          3 :   shumate_vector_sprite_sheet_add_page (scope.sprites, texture, g_bytes_get_data (json_data, NULL), 1, &error);
     420         [ -  + ]:          3 :   g_assert_no_error (error);
     421                 :            : 
     422         [ -  + ]:          3 :   g_assert_true (filter_with_scope (&scope, "[\"!=\", null, [\"image\", \"sprite\"]]"));
     423         [ -  + ]:          3 :   g_assert_true (filter_with_scope (&scope, "[\"==\", null, [\"image\", \"does-not-exist\"]]"));
     424                 :            : 
     425   [ +  -  +  - ]:          3 :   g_clear_object (&scope.sprites);
     426                 :          3 : }
     427                 :            : 
     428                 :            : 
     429                 :            : static void
     430                 :          3 : test_vector_expression_feature_filter (void)
     431                 :            : {
     432                 :          3 :   GError *error = NULL;
     433                 :          6 :   g_autoptr(GBytes) vector_data = NULL;
     434         [ +  - ]:          3 :   g_autoptr(ShumateVectorReader) reader = NULL;
     435                 :          3 :   ShumateVectorRenderScope scope;
     436                 :            : 
     437                 :          3 :   vector_data = g_resources_lookup_data ("/org/gnome/shumate/Tests/0.pbf", G_RESOURCE_LOOKUP_FLAGS_NONE, NULL);
     438                 :          3 :   g_assert_no_error (error);
     439                 :            : 
     440                 :          3 :   reader = shumate_vector_reader_new (vector_data);
     441                 :          3 :   scope.reader = shumate_vector_reader_iterate (reader);
     442         [ -  + ]:          3 :   g_assert_nonnull (scope.reader);
     443                 :            : 
     444                 :          3 :   scope.zoom_level = 10;
     445                 :            : 
     446         [ -  + ]:          3 :   g_assert_true (shumate_vector_reader_iter_read_layer_by_name (scope.reader, "helloworld"));
     447         [ -  + ]:          3 :   g_assert_true (shumate_vector_reader_iter_next_feature (scope.reader));
     448                 :            : 
     449         [ -  + ]:          3 :   g_assert_true  (filter_with_scope (&scope, "[\"==\", \"name\", \"Hello, world!\"]"));
     450         [ -  + ]:          3 :   g_assert_true  (filter_with_scope (&scope, "[\"==\", [\"get\", \"name\"], \"Hello, world!\"]"));
     451         [ -  + ]:          3 :   g_assert_true  (filter_with_scope (&scope, "[\"!=\", [\"get\", \"name\"], \"HELLO, WORLD!\"]"));
     452         [ -  + ]:          3 :   g_assert_false (filter_with_scope (&scope, "[\"==\", \"name\", \"Goodbye, world!\"]"));
     453         [ -  + ]:          3 :   g_assert_true  (filter_with_scope (&scope, "[\"has\", \"name\"]"));
     454                 :            :   // Use concat to avoid optimizations and test the regular code path
     455         [ -  + ]:          3 :   g_assert_true  (filter_with_scope (&scope, "[\"==\", [\"get\", [\"concat\", \"name\"]], \"Hello, world!\"]"));
     456         [ -  + ]:          3 :   g_assert_true  (filter_with_scope (&scope, "[\"has\", [\"concat\", \"name\"]]"));
     457         [ -  + ]:          3 :   g_assert_false (filter_with_scope (&scope, "[\"!has\", \"name\"]"));
     458         [ -  + ]:          3 :   g_assert_false (filter_with_scope (&scope, "[\"!has\", [\"concat\", \"name\"]]"));
     459         [ -  + ]:          3 :   g_assert_false (filter_with_scope (&scope, "[\"has\", \"name:en\"]"));
     460         [ -  + ]:          3 :   g_assert_true  (filter_with_scope (&scope, "[\"!has\", \"name:en\"]"));
     461         [ -  + ]:          3 :   g_assert_false (filter_with_scope (&scope, "[\"has\", [\"concat\", \"name:en\"]]"));
     462         [ -  + ]:          3 :   g_assert_true  (filter_with_scope (&scope, "[\"!has\", [\"concat\", \"name:en\"]]"));
     463         [ -  + ]:          3 :   g_assert_true  (filter_with_scope (&scope, "[\"==\", \"$type\", \"Point\"]"));
     464         [ -  + ]:          3 :   g_assert_true  (filter_with_scope (&scope, "[\"!=\", \"$type\", \"Polygon\"]"));
     465         [ -  + ]:          3 :   g_assert_true  (filter_with_scope (&scope, "[\"!=\", \"$type\", \"NotAShape\"]"));
     466         [ -  + ]:          3 :   g_assert_true  (filter_with_scope (&scope, "[\"==\", [\"geometry-type\"], [\"concat\", \"Point\"]]"));
     467         [ -  + ]:          3 :   g_assert_true  (filter_with_scope (&scope, "[\"!=\", [\"geometry-type\"], [\"concat\", \"Polygon\"]]"));
     468         [ -  + ]:          3 :   g_assert_true  (filter_with_scope (&scope, "[\"==\", \"zoom\", 10]"));
     469         [ -  + ]:          3 :   g_assert_true  (filter_with_scope (&scope, "[\"in\", \"name\", [\"literal\", [\"Hello, world!\", true, 3]]]"));
     470         [ -  + ]:          3 :   g_assert_true  (filter_with_scope (&scope, "[\"!in\", \"name\", [\"literal\", [\"HELLO, WORLD!\", true, 3]]]"));
     471         [ -  + ]:          3 :   g_assert_true  (filter_with_scope (&scope, "[\"==\", [\"concat\", \"Hello, world!\"], \"Hello, world!\"]"));
     472         [ -  + ]:          3 :   g_assert_true  (filter_with_scope (&scope, "[\"!=\", [\"concat\", \"Hello, world!\"], \"HELLO, WORLD!\"]"));
     473                 :            : 
     474   [ +  -  +  - ]:          3 :   g_clear_object (&scope.reader);
     475                 :          3 : }
     476                 :            : 
     477                 :            : 
     478                 :            : static void
     479                 :         30 : filter_expect_error (const char *filter)
     480                 :            : {
     481                 :         60 :   g_autoptr(GError) error = NULL;
     482         [ +  - ]:         60 :   g_autoptr(JsonNode) node = json_from_string (filter, NULL);
     483         [ +  - ]:         60 :   g_autoptr(ShumateVectorExpression) expression = shumate_vector_expression_from_json (node, &error);
     484                 :            : 
     485   [ +  -  +  -  :         30 :   g_assert_error (error, SHUMATE_STYLE_ERROR, SHUMATE_STYLE_ERROR_INVALID_EXPRESSION);
                   -  + ]
     486   [ -  +  -  + ]:         30 :   g_assert_null (expression);
     487                 :         30 : }
     488                 :            : 
     489                 :            : static void
     490                 :          3 : test_vector_expression_filter_errors (void)
     491                 :            : {
     492                 :          3 :   filter_expect_error ("[\"not an operator\"]");
     493                 :          3 :   filter_expect_error ("[\"in\"]");
     494                 :          3 :   filter_expect_error ("[\"==\", 0, 1, 2, 3]");
     495                 :          3 :   filter_expect_error ("[]");
     496                 :          3 :   filter_expect_error ("[[]]");
     497                 :            : 
     498                 :          3 :   filter_expect_error ("[\"+\"]");
     499                 :          3 :   filter_expect_error ("[\"-\", 1, 2, 3]");
     500                 :          3 :   filter_expect_error ("[\"/\", 1, 2, 3]");
     501                 :          3 :   filter_expect_error ("[\"abs\", 1, 2]");
     502                 :          3 :   filter_expect_error ("[\"%\", 1]");
     503                 :          3 : }
     504                 :            : 
     505                 :            : 
     506                 :            : static void
     507                 :          3 : test_vector_expression_format ()
     508                 :            : {
     509                 :          3 :   GError *error = NULL;
     510                 :          6 :   g_autoptr(GBytes) vector_data = NULL;
     511         [ +  - ]:          3 :   g_autoptr(ShumateVectorReader) reader = NULL;
     512                 :          3 :   ShumateVectorRenderScope scope;
     513         [ +  - ]:          6 :   g_autoptr(JsonNode) node = json_from_string ("\"***** {name} *****\"", NULL);
     514         [ +  - ]:          3 :   g_autoptr(ShumateVectorExpression) expression;
     515         [ +  - ]:          3 :   g_autofree char *result = NULL;
     516                 :            : 
     517                 :          3 :   expression = shumate_vector_expression_from_json (node, &error);
     518         [ -  + ]:          3 :   g_assert_no_error (error);
     519                 :            : 
     520                 :          3 :   vector_data = g_resources_lookup_data ("/org/gnome/shumate/Tests/0.pbf", G_RESOURCE_LOOKUP_FLAGS_NONE, NULL);
     521         [ -  + ]:          3 :   g_assert_no_error (error);
     522                 :            : 
     523                 :          3 :   reader = shumate_vector_reader_new (vector_data);
     524                 :          3 :   scope.reader = shumate_vector_reader_iterate (reader);
     525         [ -  + ]:          3 :   g_assert_nonnull (scope.reader);
     526                 :            : 
     527                 :          3 :   scope.zoom_level = 10;
     528                 :            : 
     529         [ -  + ]:          3 :   g_assert_true (shumate_vector_reader_iter_read_layer_by_name (scope.reader, "helloworld"));
     530         [ -  + ]:          3 :   g_assert_true (shumate_vector_reader_iter_next_feature (scope.reader));
     531                 :            : 
     532                 :          3 :   result = shumate_vector_expression_eval_string (expression, &scope, NULL);
     533         [ -  + ]:          3 :   g_assert_cmpstr (result, ==, "***** Hello, world! *****");
     534                 :            : 
     535         [ +  - ]:          3 :   g_clear_object (&scope.reader);
     536                 :          3 : }
     537                 :            : 
     538                 :            : 
     539                 :            : static void
     540                 :          3 : test_vector_expression_array ()
     541                 :            : {
     542                 :          6 :   g_autofree char *string = NULL;
     543                 :          3 :   g_auto(ShumateVectorValue) element1 = SHUMATE_VECTOR_VALUE_INIT;
     544                 :          3 :   g_auto(ShumateVectorValue) element2 = SHUMATE_VECTOR_VALUE_INIT;
     545                 :          3 :   g_auto(ShumateVectorValue) array1 = SHUMATE_VECTOR_VALUE_INIT;
     546                 :          3 :   g_auto(ShumateVectorValue) array2 = SHUMATE_VECTOR_VALUE_INIT;
     547                 :            : 
     548                 :          3 :   g_autoptr(GError) error = NULL;
     549         [ -  + ]:          3 :   g_autoptr(JsonNode) node = NULL;
     550         [ +  - ]:          3 :   g_autoptr(ShumateVectorExpression) expression = NULL;
     551         [ +  - ]:          3 :   g_auto(ShumateVectorValue) eval = SHUMATE_VECTOR_VALUE_INIT;
     552                 :            : 
     553                 :          3 :   shumate_vector_value_set_string (&element1, "Hello, world!");
     554                 :          3 :   shumate_vector_value_set_boolean (&element2, TRUE);
     555                 :            : 
     556                 :          3 :   shumate_vector_value_start_array (&array1);
     557                 :          3 :   shumate_vector_value_array_append (&array1, &element1);
     558                 :          3 :   shumate_vector_value_array_append (&array1, &element2);
     559                 :            : 
     560                 :          3 :   string = shumate_vector_value_as_string (&array1);
     561         [ -  + ]:          3 :   g_assert_cmpstr (string, ==, "[\"Hello, world!\",true]");
     562                 :            : 
     563                 :          3 :   shumate_vector_value_start_array (&array2);
     564                 :          3 :   shumate_vector_value_array_append (&array2, &element1);
     565                 :          3 :   shumate_vector_value_array_append (&array2, &element2);
     566                 :            : 
     567         [ -  + ]:          3 :   g_assert_true (shumate_vector_value_equal (&array1, &array2));
     568                 :            : 
     569                 :          3 :   shumate_vector_value_array_append (&array2, &element1);
     570         [ -  + ]:          3 :   g_assert_false (shumate_vector_value_equal (&array1, &array2));
     571                 :            : 
     572                 :          3 :   node = json_from_string ("[\"literal\", [\"Hello, world!\", true, \"Hello, world!\"]]", NULL);
     573                 :          3 :   expression = shumate_vector_expression_from_json (node, &error);
     574         [ -  + ]:          3 :   g_assert_no_error (error);
     575                 :          3 :   shumate_vector_expression_eval (expression, NULL, &eval);
     576                 :            : 
     577         [ -  + ]:          3 :   g_assert_true (shumate_vector_value_equal (&eval, &array2));
     578                 :          3 : }
     579                 :            : 
     580                 :            : 
     581                 :            : static void
     582                 :          3 : test_vector_expression_formatted_string ()
     583                 :            : {
     584                 :          6 :   g_autoptr(GError) error = NULL;
     585         [ -  + ]:          3 :   g_autoptr(JsonNode) node = NULL;
     586         [ +  - ]:          3 :   g_autoptr(ShumateVectorExpression) expression = NULL;
     587         [ +  - ]:          3 :   g_auto(ShumateVectorValue) eval = SHUMATE_VECTOR_VALUE_INIT;
     588                 :          3 :   g_autofree char *as_string = NULL;
     589                 :          3 :   GPtrArray *format_parts = NULL;
     590                 :          3 :   ShumateVectorFormatPart *part = NULL;
     591                 :            : 
     592                 :          3 :   node = json_from_string ("[\"format\",\
     593                 :            :     \"Hello \",\
     594                 :            :     [\"concat\", \"world\", \"!\"], {\"font-scale\": 0.1},\
     595                 :            :     \"\n\", {\"text-color\": [\"coalesce\", \"red\"]},\
     596                 :            :     null,\
     597                 :            :     \"test\"\
     598                 :            :     ]", &error);
     599         [ -  + ]:          3 :   g_assert_no_error (error);
     600                 :          3 :   expression = shumate_vector_expression_from_json (node, &error);
     601         [ -  + ]:          3 :   g_assert_no_error (error);
     602                 :            : 
     603         [ -  + ]:          3 :   g_assert_true (shumate_vector_expression_eval (expression, NULL, &eval));
     604         [ -  + ]:          3 :   g_assert_true (shumate_vector_value_get_formatted (&eval, &format_parts));
     605         [ -  + ]:          3 :   g_assert_cmpint (format_parts->len, ==, 4);
     606                 :            : 
     607                 :          3 :   as_string = shumate_vector_value_as_string (&eval);
     608         [ -  + ]:          3 :   g_assert_cmpstr (as_string, ==, "Hello world!\ntest");
     609                 :            : 
     610                 :          3 :   part = format_parts->pdata[0];
     611         [ -  + ]:          3 :   g_assert_cmpstr (part->string, ==, "Hello ");
     612         [ -  + ]:          3 :   g_assert_null (part->sprite);
     613         [ -  + ]:          3 :   g_assert_false (part->has_font_scale);
     614         [ -  + ]:          3 :   g_assert_false (part->has_text_color);
     615                 :            : 
     616                 :          3 :   part = format_parts->pdata[1];
     617         [ -  + ]:          3 :   g_assert_cmpstr (part->string, ==, "world!");
     618         [ -  + ]:          3 :   g_assert_null (part->sprite);
     619         [ -  + ]:          3 :   g_assert_true (part->has_font_scale);
     620         [ -  + ]:          3 :   g_assert_cmpfloat (part->font_scale, ==, 0.1);
     621         [ -  + ]:          3 :   g_assert_false (part->has_text_color);
     622                 :            : 
     623                 :          3 :   part = format_parts->pdata[2];
     624         [ -  + ]:          3 :   g_assert_cmpstr (part->string, ==, "\n");
     625         [ -  + ]:          3 :   g_assert_null (part->sprite);
     626         [ -  + ]:          3 :   g_assert_false (part->has_font_scale);
     627         [ -  + ]:          3 :   g_assert_true (part->has_text_color);
     628                 :            : 
     629                 :          3 :   part = format_parts->pdata[3];
     630         [ -  + ]:          3 :   g_assert_cmpstr (part->string, ==, "test");
     631         [ -  + ]:          3 :   g_assert_null (part->sprite);
     632         [ -  + ]:          3 :   g_assert_false (part->has_font_scale);
     633         [ -  + ]:          3 :   g_assert_false (part->has_text_color);
     634                 :          3 : }
     635                 :            : 
     636                 :            : 
     637                 :            : int
     638                 :          3 : main (int argc, char *argv[])
     639                 :            : {
     640                 :          3 :   g_test_init (&argc, &argv, NULL);
     641                 :            : 
     642                 :          3 :   g_test_add_func ("/vector/expression/parse", test_vector_expression_parse);
     643                 :          3 :   g_test_add_func ("/vector/expression/literal", test_vector_expression_literal);
     644                 :          3 :   g_test_add_func ("/vector/expression/number-array", test_vector_expression_number_array);
     645                 :          3 :   g_test_add_func ("/vector/expression/nested-array-literal", test_vector_expression_nested_array_literal);
     646                 :          3 :   g_test_add_func ("/vector/expression/interpolate", test_vector_expression_interpolate);
     647                 :          3 :   g_test_add_func ("/vector/expression/interpolate-filter", test_vector_expression_interpolate_filter);
     648                 :          3 :   g_test_add_func ("/vector/expression/interpolate-color", test_vector_expression_interpolate_color);
     649                 :          3 :   g_test_add_func ("/vector/expression/interpolate-color-filter", test_vector_expression_interpolate_color_filter);
     650                 :          3 :   g_test_add_func ("/vector/expression/basic-filter", test_vector_expression_basic_filter);
     651                 :          3 :   g_test_add_func ("/vector/expression/variable-binding", test_vector_expression_variable_binding);
     652                 :          3 :   g_test_add_func ("/vector/expression/image", test_vector_expression_image);
     653                 :          3 :   g_test_add_func ("/vector/expression/feature-filter", test_vector_expression_feature_filter);
     654                 :          3 :   g_test_add_func ("/vector/expression/filter-errors", test_vector_expression_filter_errors);
     655                 :          3 :   g_test_add_func ("/vector/expression/format", test_vector_expression_format);
     656                 :          3 :   g_test_add_func ("/vector/expression/array", test_vector_expression_array);
     657                 :          3 :   g_test_add_func ("/vector/expression/formatted-string", test_vector_expression_formatted_string);
     658                 :            : 
     659                 :          3 :   return g_test_run ();
     660                 :            : }

Generated by: LCOV version 1.14