LCOV - code coverage report
Current view: top level - libmogwai-tariff/tests - tariff.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 207 207 100.0 %
Date: 2022-06-30 20:59:16 Functions: 6 6 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 45 74 60.8 %

           Branch data     Line data    Source code
       1                 :            : /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
       2                 :            :  *
       3                 :            :  * Copyright © 2018 Endless Mobile, Inc.
       4                 :            :  *
       5                 :            :  * This library is free software; you can redistribute it and/or
       6                 :            :  * modify it under the terms of the GNU Lesser General Public
       7                 :            :  * License as published by the Free Software Foundation; either
       8                 :            :  * version 2.1 of the License, or (at your option) any later version.
       9                 :            :  *
      10                 :            :  * This library is distributed in the hope that it will be useful,
      11                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      12                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13                 :            :  * Lesser General Public License for more details.
      14                 :            :  *
      15                 :            :  * You should have received a copy of the GNU Lesser General Public
      16                 :            :  * License along with this library; if not, write to the Free Software
      17                 :            :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
      18                 :            :  *
      19                 :            :  * Authors:
      20                 :            :  *  - Philip Withnall <withnall@endlessm.com>
      21                 :            :  */
      22                 :            : 
      23                 :            : #include "config.h"
      24                 :            : 
      25                 :            : #include <glib.h>
      26                 :            : #include <gio/gio.h>
      27                 :            : #include <libmogwai-tariff/tariff.h>
      28                 :            : #include <libmogwai-tariff/tariff-builder.h>
      29                 :            : #include <libmogwai-tariff/tariff-loader.h>
      30                 :            : #include <locale.h>
      31                 :            : 
      32                 :            : #include "common.h"
      33                 :            : 
      34                 :            : 
      35                 :            : static GTimeZone *
      36                 :         90 : time_zone_new (const gchar *tz_str)
      37                 :            : {
      38                 :            : #if GLIB_CHECK_VERSION(2, 68, 0)
      39                 :        180 :   g_autoptr(GTimeZone) tz = g_time_zone_new_identifier (tz_str);
      40         [ -  + ]:         90 :   g_assert_nonnull (tz);
      41                 :         90 :   return g_steal_pointer (&tz);
      42                 :            : #else
      43                 :            :   return g_time_zone_new (tz_str);
      44                 :            : #endif
      45                 :            : }
      46                 :            : 
      47                 :            : /* Test the GObject properties on a tariff. */
      48                 :            : static void
      49                 :          1 : test_tariff_properties (void)
      50                 :            : {
      51                 :          1 :   g_autoptr(MwtTariff) tariff = NULL;
      52                 :          2 :   g_autoptr(GPtrArray) periods = g_ptr_array_new_with_free_func (NULL);
      53                 :          2 :   g_autoptr(GDateTime) period_start = g_date_time_new_utc (2018, 1, 22, 0, 0, 0);
      54                 :          2 :   g_autoptr(GDateTime) period_end = g_date_time_new_utc (2018, 2, 22, 0, 0, 0);
      55                 :          2 :   g_autoptr(MwtPeriod) period = mwt_period_new (period_start, period_end,
      56                 :            :                                                 MWT_PERIOD_REPEAT_NONE, 0,
      57                 :            :                                                 NULL);
      58                 :          1 :   g_ptr_array_add (periods, period);
      59                 :          1 :   tariff = mwt_tariff_new ("name", periods);
      60         [ -  + ]:          1 :   g_assert_true (MWT_IS_TARIFF (tariff));
      61                 :            : 
      62         [ -  + ]:          1 :   g_assert_cmpstr (mwt_tariff_get_name (tariff), ==, "name");
      63                 :          1 :   GPtrArray *actual_periods = mwt_tariff_get_periods (tariff);
      64         [ -  + ]:          1 :   g_assert_cmpuint (actual_periods->len, ==, 1);
      65                 :            : 
      66                 :          1 :   g_autofree gchar *actual_name = NULL;
      67                 :          1 :   g_autoptr(GPtrArray) actual_periods2 = NULL;
      68                 :            : 
      69                 :          1 :   g_object_get (G_OBJECT (tariff),
      70                 :            :                 "name", &actual_name,
      71                 :            :                 "periods", &actual_periods2,
      72                 :            :                 NULL);
      73                 :            : 
      74         [ -  + ]:          1 :   g_assert_cmpstr (actual_name, ==, "name");
      75         [ -  + ]:          1 :   g_assert_cmpuint (actual_periods2->len, ==, 1);
      76                 :          1 : }
      77                 :            : 
      78                 :            : /* Test mwt_tariff_lookup_period() with various dates/times for a generic
      79                 :            :  * tariff. */
      80                 :            : static void
      81                 :          1 : test_tariff_lookup (void)
      82                 :            : {
      83                 :            :   /* Construct a tariff. */
      84                 :          2 :   g_autoptr(GPtrArray) periods = g_ptr_array_new_with_free_func (NULL);
      85                 :            : 
      86                 :          2 :   g_autoptr(GDateTime) period1_start = g_date_time_new_utc (2018, 1, 22, 0, 0, 0);
      87                 :          2 :   g_autoptr(GDateTime) period1_end = g_date_time_new_utc (2018, 2, 22, 0, 0, 0);
      88                 :          2 :   g_autoptr(MwtPeriod) period1 = mwt_period_new (period1_start, period1_end,
      89                 :            :                                                  MWT_PERIOD_REPEAT_NONE, 0,
      90                 :            :                                                  "capacity-limit", (guint64) 2000,
      91                 :            :                                                  NULL);
      92                 :          1 :   g_ptr_array_add (periods, period1);
      93                 :            : 
      94                 :          2 :   g_autoptr(GDateTime) period2_start = g_date_time_new_utc (2018, 1, 22, 0, 0, 0);
      95                 :          2 :   g_autoptr(GDateTime) period2_end = g_date_time_new_utc (2018, 1, 22, 12, 0, 0);
      96                 :          2 :   g_autoptr(MwtPeriod) period2 = mwt_period_new (period2_start, period2_end,
      97                 :            :                                                  MWT_PERIOD_REPEAT_WEEK, 1,
      98                 :            :                                                  "capacity-limit", (guint64) 1000,
      99                 :            :                                                  NULL);
     100                 :          1 :   g_ptr_array_add (periods, period2);
     101                 :            : 
     102                 :          1 :   g_autoptr(MwtTariff) tariff = NULL;
     103                 :          1 :   tariff = mwt_tariff_new ("name", periods);
     104                 :            : 
     105                 :            :   /* Check whether periods are looked up correctly. */
     106                 :            :   const struct
     107                 :            :     {
     108                 :            :       gint year;
     109                 :            :       gint month;
     110                 :            :       gint day;
     111                 :            :       gint hour;
     112                 :            :       gint minute;
     113                 :            :       gdouble seconds;
     114                 :            :       MwtPeriod *expected_period;
     115                 :            :     }
     116                 :          1 :   vectors[] =
     117                 :            :     {
     118                 :            :       { 2018, 1, 21, 23, 59, 59, NULL },
     119                 :            :       { 2018, 1, 22, 0, 0, 0, period2 },
     120                 :            :       { 2018, 1, 22, 1, 0, 0, period2 },
     121                 :            :       { 2018, 1, 22, 11, 59, 59, period2 },
     122                 :            :       { 2018, 1, 22, 12, 0, 0, period1 },
     123                 :            :       { 2018, 1, 22, 12, 0, 1, period1 },
     124                 :            :       { 2018, 1, 23, 0, 0, 0, period1 },
     125                 :            :       { 2018, 2, 21, 23, 59, 59, period1 },
     126                 :            :       { 2018, 2, 22, 0, 0, 0, NULL },
     127                 :            :       /* FIXME: Test recurrence */
     128                 :            :     };
     129                 :            : 
     130         [ +  + ]:         10 :   for (gsize i = 0; i < G_N_ELEMENTS (vectors); i++)
     131                 :            :     {
     132                 :          9 :       g_test_message ("Vector %" G_GSIZE_FORMAT ": %04d-%02d-%02dT%02d:%02d:%02fZ, %p",
     133                 :          9 :                       i, vectors[i].year, vectors[i].month, vectors[i].day,
     134                 :          9 :                       vectors[i].hour, vectors[i].minute, vectors[i].seconds,
     135                 :          9 :                       vectors[i].expected_period);
     136                 :          9 :       g_autoptr(GDateTime) lookup_date =
     137                 :          9 :           g_date_time_new_utc (vectors[i].year, vectors[i].month, vectors[i].day,
     138                 :          9 :                                vectors[i].hour, vectors[i].minute, vectors[i].seconds);
     139                 :          9 :       MwtPeriod *lookup_period = mwt_tariff_lookup_period (tariff, lookup_date);
     140         [ +  + ]:          9 :       if (vectors[i].expected_period == NULL)
     141                 :            :         {
     142         [ -  + ]:          2 :           g_assert_null (lookup_period);
     143                 :            :         }
     144                 :            :       else
     145                 :            :         {
     146         [ -  + ]:          7 :           g_assert_true (MWT_IS_PERIOD (lookup_period));
     147         [ -  + ]:          7 :           g_assert_true (lookup_period == vectors[i].expected_period);
     148                 :            :         }
     149                 :            :     }
     150                 :          1 : }
     151                 :            : 
     152                 :            : /* Test getting the next transition using mwt_tariff_get_next_transition(), and
     153                 :            :  * check that it’s calculated correctly, and returns the correct to/from periods
     154                 :            :  * for a variety of tariffs and date/times. */
     155                 :            : static void
     156                 :          1 : test_tariff_next_transition (void)
     157                 :            : {
     158                 :            :   /* Construct various test tariffs. Firstly, one with a non-recurring period. */
     159                 :          2 :   g_autoptr(GPtrArray) periods1 = g_ptr_array_new_with_free_func (NULL);
     160                 :            : 
     161                 :          2 :   g_autoptr(GDateTime) period1a_start = g_date_time_new_utc (2018, 1, 22, 0, 0, 0);
     162                 :          2 :   g_autoptr(GDateTime) period1a_end = g_date_time_new_utc (2018, 2, 22, 0, 0, 0);
     163                 :          2 :   g_autoptr(MwtPeriod) period1a = mwt_period_new (period1a_start, period1a_end,
     164                 :            :                                                   MWT_PERIOD_REPEAT_NONE, 0,
     165                 :            :                                                   NULL);
     166                 :          1 :   g_ptr_array_add (periods1, period1a);
     167                 :            : 
     168                 :          2 :   g_autoptr(MwtTariff) tariff1 = mwt_tariff_new ("name", periods1);
     169                 :            : 
     170                 :            :   /* One with a single recurring period. */
     171                 :          2 :   g_autoptr(GPtrArray) periods2 = g_ptr_array_new_with_free_func (NULL);
     172                 :            : 
     173                 :          2 :   g_autoptr(GDateTime) period2a_start = g_date_time_new_utc (2018, 1, 10, 2, 0, 0);
     174                 :          2 :   g_autoptr(GDateTime) period2a_end = g_date_time_new_utc (2018, 1, 10, 6, 0, 0);
     175                 :          2 :   g_autoptr(MwtPeriod) period2a = mwt_period_new (period2a_start, period2a_end,
     176                 :            :                                                   MWT_PERIOD_REPEAT_DAY, 1,
     177                 :            :                                                   NULL);
     178                 :          1 :   g_ptr_array_add (periods2, period2a);
     179                 :            : 
     180                 :          2 :   g_autoptr(MwtTariff) tariff2 = mwt_tariff_new ("name", periods2);
     181                 :            : 
     182                 :            :   /* One period which covers all time, and another recurring on top. */
     183                 :          2 :   g_autoptr(GPtrArray) periods3 = g_ptr_array_new_with_free_func (NULL);
     184                 :            : 
     185                 :          2 :   g_autoptr(GDateTime) period3a_start = g_date_time_new_utc (1970, 1, 1, 0, 0, 0);
     186                 :          2 :   g_autoptr(GDateTime) period3a_end = g_date_time_new_utc (9999, 12, 31, 23, 59, 59.99);
     187                 :          2 :   g_autoptr(MwtPeriod) period3a = mwt_period_new (period3a_start, period3a_end,
     188                 :            :                                                   MWT_PERIOD_REPEAT_NONE, 0,
     189                 :            :                                                   NULL);
     190                 :          1 :   g_ptr_array_add (periods3, period3a);
     191                 :            : 
     192                 :          2 :   g_autoptr(GDateTime) period3b_start = g_date_time_new_utc (2018, 1, 10, 2, 0, 0);
     193                 :          2 :   g_autoptr(GDateTime) period3b_end = g_date_time_new_utc (2018, 1, 10, 6, 0, 0);
     194                 :          2 :   g_autoptr(MwtPeriod) period3b = mwt_period_new (period3b_start, period3b_end,
     195                 :            :                                                   MWT_PERIOD_REPEAT_DAY, 1,
     196                 :            :                                                   NULL);
     197                 :          1 :   g_ptr_array_add (periods3, period3b);
     198                 :            : 
     199                 :          2 :   g_autoptr(MwtTariff) tariff3 = mwt_tariff_new ("name", periods3);
     200                 :            : 
     201                 :            :   /* Two recurring periods, one inside the other. */
     202                 :          2 :   g_autoptr(GPtrArray) periods4 = g_ptr_array_new_with_free_func (NULL);
     203                 :            : 
     204                 :          2 :   g_autoptr(GDateTime) period4a_start = g_date_time_new_utc (2018, 1, 8, 1, 0, 0);
     205                 :          2 :   g_autoptr(GDateTime) period4a_end = g_date_time_new_utc (2018, 1, 14, 22, 0, 0);
     206                 :          2 :   g_autoptr(MwtPeriod) period4a = mwt_period_new (period4a_start, period4a_end,
     207                 :            :                                                   MWT_PERIOD_REPEAT_WEEK, 1,
     208                 :            :                                                   NULL);
     209                 :          1 :   g_ptr_array_add (periods4, period4a);
     210                 :            : 
     211                 :          2 :   g_autoptr(GDateTime) period4b_start = g_date_time_new_utc (2018, 1, 8, 2, 0, 0);
     212                 :          2 :   g_autoptr(GDateTime) period4b_end = g_date_time_new_utc (2018, 1, 8, 6, 0, 0);
     213                 :          2 :   g_autoptr(MwtPeriod) period4b = mwt_period_new (period4b_start, period4b_end,
     214                 :            :                                                   MWT_PERIOD_REPEAT_DAY, 1,
     215                 :            :                                                   NULL);
     216                 :          1 :   g_ptr_array_add (periods4, period4b);
     217                 :            : 
     218                 :          2 :   g_autoptr(MwtTariff) tariff4 = mwt_tariff_new ("name", periods4);
     219                 :            : 
     220                 :            :   /* Two recurring periods, ending at the same time. */
     221                 :          2 :   g_autoptr(GPtrArray) periods5 = g_ptr_array_new_with_free_func (NULL);
     222                 :            : 
     223                 :          2 :   g_autoptr(GDateTime) period5a_start = g_date_time_new_utc (2018, 1, 8, 10, 0, 0);
     224                 :          2 :   g_autoptr(GDateTime) period5a_end = g_date_time_new_utc (2018, 1, 8, 22, 0, 0);
     225                 :          2 :   g_autoptr(MwtPeriod) period5a = mwt_period_new (period5a_start, period5a_end,
     226                 :            :                                                   MWT_PERIOD_REPEAT_DAY, 1,
     227                 :            :                                                   NULL);
     228                 :          1 :   g_ptr_array_add (periods5, period5a);
     229                 :            : 
     230                 :          2 :   g_autoptr(GDateTime) period5b_start = g_date_time_new_utc (2018, 1, 8, 12, 0, 0);
     231                 :          2 :   g_autoptr(GDateTime) period5b_end = g_date_time_new_utc (2018, 1, 8, 22, 0, 0);
     232                 :          2 :   g_autoptr(MwtPeriod) period5b = mwt_period_new (period5b_start, period5b_end,
     233                 :            :                                                   MWT_PERIOD_REPEAT_DAY, 1,
     234                 :            :                                                   NULL);
     235                 :          1 :   g_ptr_array_add (periods5, period5b);
     236                 :            : 
     237                 :          2 :   g_autoptr(MwtTariff) tariff5 = mwt_tariff_new ("name", periods5);
     238                 :            : 
     239                 :            :   /* Two recurring periods, each starting as the other ends. */
     240                 :          2 :   g_autoptr(GPtrArray) periods6 = g_ptr_array_new_with_free_func (NULL);
     241                 :            : 
     242                 :          2 :   g_autoptr(GDateTime) period6a_start = g_date_time_new_utc (2018, 1, 8, 0, 0, 0);
     243                 :          2 :   g_autoptr(GDateTime) period6a_end = g_date_time_new_utc (2018, 1, 9, 0, 0, 0);
     244                 :          2 :   g_autoptr(MwtPeriod) period6a = mwt_period_new (period6a_start, period6a_end,
     245                 :            :                                                   MWT_PERIOD_REPEAT_DAY, 2,
     246                 :            :                                                   NULL);
     247                 :          1 :   g_ptr_array_add (periods6, period6a);
     248                 :            : 
     249                 :          2 :   g_autoptr(GDateTime) period6b_start = g_date_time_new_utc (2018, 1, 9, 0, 0, 0);
     250                 :          2 :   g_autoptr(GDateTime) period6b_end = g_date_time_new_utc (2018, 1, 10, 0, 0, 0);
     251                 :          2 :   g_autoptr(MwtPeriod) period6b = mwt_period_new (period6b_start, period6b_end,
     252                 :            :                                                   MWT_PERIOD_REPEAT_DAY, 2,
     253                 :            :                                                   NULL);
     254                 :          1 :   g_ptr_array_add (periods6, period6b);
     255                 :            : 
     256                 :          2 :   g_autoptr(MwtTariff) tariff6 = mwt_tariff_new ("name", periods6);
     257                 :            : 
     258                 :            :   /* Two recurring periods, starting at the same time. */
     259                 :          2 :   g_autoptr(GPtrArray) periods7 = g_ptr_array_new_with_free_func (NULL);
     260                 :            : 
     261                 :          2 :   g_autoptr(GDateTime) period7a_start = g_date_time_new_utc (2018, 1, 8, 10, 0, 0);
     262                 :          2 :   g_autoptr(GDateTime) period7a_end = g_date_time_new_utc (2018, 1, 8, 22, 0, 0);
     263                 :          2 :   g_autoptr(MwtPeriod) period7a = mwt_period_new (period7a_start, period7a_end,
     264                 :            :                                                   MWT_PERIOD_REPEAT_DAY, 1,
     265                 :            :                                                   NULL);
     266                 :          1 :   g_ptr_array_add (periods7, period7a);
     267                 :            : 
     268                 :          2 :   g_autoptr(GDateTime) period7b_start = g_date_time_new_utc (2018, 1, 8, 10, 0, 0);
     269                 :          2 :   g_autoptr(GDateTime) period7b_end = g_date_time_new_utc (2018, 1, 8, 12, 0, 0);
     270                 :          2 :   g_autoptr(MwtPeriod) period7b = mwt_period_new (period7b_start, period7b_end,
     271                 :            :                                                   MWT_PERIOD_REPEAT_DAY, 1,
     272                 :            :                                                   NULL);
     273                 :          1 :   g_ptr_array_add (periods7, period7b);
     274                 :            : 
     275                 :          2 :   g_autoptr(MwtTariff) tariff7 = mwt_tariff_new ("name", periods7);
     276                 :            : 
     277                 :            :   /* One period, recurring so it starts when it ends. */
     278                 :          2 :   g_autoptr(GPtrArray) periods8 = g_ptr_array_new_with_free_func (NULL);
     279                 :            : 
     280                 :          2 :   g_autoptr(GDateTime) period8a_start = g_date_time_new_utc (2018, 1, 8, 0, 0, 0);
     281                 :          2 :   g_autoptr(GDateTime) period8a_end = g_date_time_new_utc (2018, 1, 9, 0, 0, 0);
     282                 :          2 :   g_autoptr(MwtPeriod) period8a = mwt_period_new (period8a_start, period8a_end,
     283                 :            :                                                   MWT_PERIOD_REPEAT_DAY, 1,
     284                 :            :                                                   NULL);
     285                 :          1 :   g_ptr_array_add (periods8, period8a);
     286                 :            : 
     287                 :          2 :   g_autoptr(MwtTariff) tariff8 = mwt_tariff_new ("name", periods8);
     288                 :            : 
     289                 :            :   const struct
     290                 :            :     {
     291                 :            :       MwtTariff *tariff;
     292                 :            : 
     293                 :            :       gint after_year;
     294                 :            :       gint after_month;
     295                 :            :       gint after_day;
     296                 :            :       gint after_hour;
     297                 :            :       gint after_minute;
     298                 :            :       gdouble after_seconds;
     299                 :            :       const gchar *after_tz;
     300                 :            : 
     301                 :            :       gint expected_next_year;
     302                 :            :       gint expected_next_month;
     303                 :            :       gint expected_next_day;
     304                 :            :       gint expected_next_hour;
     305                 :            :       gint expected_next_minute;
     306                 :            :       gdouble expected_next_seconds;
     307                 :            :       const gchar *expected_next_tz;  /* (nullable) */
     308                 :            : 
     309                 :            :       gboolean expected_next_is_first;
     310                 :            : 
     311                 :            :       MwtPeriod *expected_from_period;  /* (nullable) */
     312                 :            :       MwtPeriod *expected_to_period;  /* (nullable) */
     313                 :            :     }
     314                 :          1 :   vectors[] =
     315                 :            :     {
     316                 :            :       /* Some simple tests with a single period tariff, with no recurrence. */
     317                 :            :       { tariff1,
     318                 :            :         2018, 1, 1, 0, 0, 0.0, "Z",
     319                 :            :         2018, 1, 22, 0, 0, 0.0, "Z", TRUE,
     320                 :            :         NULL, period1a },
     321                 :            :       { tariff1,
     322                 :            :         2018, 1, 21, 23, 59, 59.99, "Z",
     323                 :            :         2018, 1, 22, 0, 0, 0.0, "Z", FALSE,
     324                 :            :         NULL, period1a },
     325                 :            :       { tariff1,
     326                 :            :         2018, 1, 22, 0, 0, 0.0, "Z",
     327                 :            :         2018, 2, 22, 0, 0, 0.0, "Z", FALSE,
     328                 :            :         period1a, NULL },
     329                 :            :       { tariff1,
     330                 :            :         2018, 2, 10, 0, 0, 0.0, "Z",
     331                 :            :         2018, 2, 22, 0, 0, 0.0, "Z", FALSE,
     332                 :            :         period1a, NULL },
     333                 :            :       { tariff1,
     334                 :            :         2018, 2, 21, 23, 59, 59.99, "Z",
     335                 :            :         2018, 2, 22, 0, 0, 0.0, "Z", FALSE,
     336                 :            :         period1a, NULL },
     337                 :            :       { tariff1,
     338                 :            :         2018, 2, 22, 0, 0, 0.0, "Z",
     339                 :            :         0, 0, 0, 0, 0, 0.0, NULL, FALSE,
     340                 :            :         NULL, NULL },
     341                 :            :       { tariff1,
     342                 :            :         2018, 3, 1, 0, 0, 0.0, "Z",
     343                 :            :         0, 0, 0, 0, 0, 0.0, NULL, FALSE,
     344                 :            :         NULL, NULL },
     345                 :            :       /* A single recurring period. */
     346                 :            :       { tariff2,
     347                 :            :         2018, 1, 1, 0, 0, 0.0, "Z",
     348                 :            :         2018, 1, 10, 2, 0, 0.0, "Z", TRUE,
     349                 :            :         NULL, period2a },
     350                 :            :       { tariff2,
     351                 :            :         2018, 1, 10, 2, 0, 0.0, "Z",
     352                 :            :         2018, 1, 10, 6, 0, 0.0, "Z", FALSE,
     353                 :            :         period2a, NULL },
     354                 :            :       { tariff2,
     355                 :            :         2018, 1, 10, 4, 0, 0.0, "Z",
     356                 :            :         2018, 1, 10, 6, 0, 0.0, "Z", FALSE,
     357                 :            :         period2a, NULL },
     358                 :            :       { tariff2,
     359                 :            :         2018, 1, 10, 6, 0, 0.0, "Z",
     360                 :            :         2018, 1, 11, 2, 0, 0.0, "Z", FALSE,
     361                 :            :         NULL, period2a },
     362                 :            :       { tariff2,
     363                 :            :         2018, 1, 11, 4, 0, 0.0, "Z",
     364                 :            :         2018, 1, 11, 6, 0, 0.0, "Z", FALSE,
     365                 :            :         period2a, NULL },
     366                 :            :       /* A recurring period over one which lasts for all time (the g-c-c case). */
     367                 :            :       { tariff3,
     368                 :            :         1990, 1, 1, 0, 0, 0.0, "Z",
     369                 :            :         2018, 1, 10, 2, 0, 0.0, "Z", FALSE,
     370                 :            :         period3a, period3b },
     371                 :            :       { tariff3,
     372                 :            :         2018, 1, 10, 1, 59, 59.99, "Z",
     373                 :            :         2018, 1, 10, 2, 0, 0.0, "Z", FALSE,
     374                 :            :         period3a, period3b },
     375                 :            :       { tariff3,
     376                 :            :         2018, 1, 10, 2, 0, 0.0, "Z",
     377                 :            :         2018, 1, 10, 6, 0, 0.0, "Z", FALSE,
     378                 :            :         period3b, period3a },
     379                 :            :       { tariff3,
     380                 :            :         2018, 1, 10, 4, 0, 0.0, "Z",
     381                 :            :         2018, 1, 10, 6, 0, 0.0, "Z", FALSE,
     382                 :            :         period3b, period3a },
     383                 :            :       { tariff3,
     384                 :            :         2018, 1, 10, 6, 0, 0.0, "Z",
     385                 :            :         2018, 1, 11, 2, 0, 0.0, "Z", FALSE,
     386                 :            :         period3a, period3b },
     387                 :            :       { tariff3,
     388                 :            :         2018, 1, 11, 2, 0, 0.0, "Z",
     389                 :            :         2018, 1, 11, 6, 0, 0.0, "Z", FALSE,
     390                 :            :         period3b, period3a },
     391                 :            :       { tariff3,
     392                 :            :         9999, 12, 31, 4, 0, 0.0, "Z",
     393                 :            :         9999, 12, 31, 6, 0, 0.0, "Z", FALSE,
     394                 :            :         period3b, period3a },
     395                 :            :       { tariff3,
     396                 :            :         9999, 12, 31, 6, 0, 0.0, "Z",
     397                 :            :         9999, 12, 31, 23, 59, 59.99, "Z", FALSE,
     398                 :            :         period3a, NULL },
     399                 :            :       /* Two recurring periods, one inside the other. */
     400                 :            :       { tariff4,
     401                 :            :         2018, 1, 1, 1, 0, 0.0, "Z",
     402                 :            :         2018, 1, 8, 1, 0, 0.0, "Z", TRUE,
     403                 :            :         NULL, period4a },
     404                 :            :       { tariff4,
     405                 :            :         2018, 1, 8, 1, 0, 0.0, "Z",
     406                 :            :         2018, 1, 8, 2, 0, 0.0, "Z", FALSE,
     407                 :            :         period4a, period4b },
     408                 :            :       { tariff4,
     409                 :            :         2018, 1, 8, 2, 0, 0.0, "Z",
     410                 :            :         2018, 1, 8, 6, 0, 0.0, "Z", FALSE,
     411                 :            :         period4b, period4a },
     412                 :            :       { tariff4,
     413                 :            :         2018, 1, 8, 6, 0, 0.0, "Z",
     414                 :            :         2018, 1, 9, 2, 0, 0.0, "Z", FALSE,
     415                 :            :         period4a, period4b },
     416                 :            :       { tariff4,
     417                 :            :         2018, 1, 14, 1, 0, 0.0, "Z",
     418                 :            :         2018, 1, 14, 2, 0, 0.0, "Z", FALSE,
     419                 :            :         period4a, period4b },
     420                 :            :       { tariff4,
     421                 :            :         2018, 1, 14, 2, 0, 0.0, "Z",
     422                 :            :         2018, 1, 14, 6, 0, 0.0, "Z", FALSE,
     423                 :            :         period4b, period4a },
     424                 :            :       { tariff4,
     425                 :            :         2018, 1, 14, 6, 0, 0.0, "Z",
     426                 :            :         2018, 1, 14, 22, 0, 0.0, "Z", FALSE,
     427                 :            :         period4a, NULL },
     428                 :            :       { tariff4,
     429                 :            :         2018, 1, 14, 22, 0, 0.0, "Z",
     430                 :            :         2018, 1, 15, 1, 0, 0.0, "Z", FALSE,
     431                 :            :         NULL, period4a },
     432                 :            :       { tariff4,
     433                 :            :         2018, 1, 15, 1, 0, 0.0, "Z",
     434                 :            :         2018, 1, 15, 2, 0, 0.0, "Z", FALSE,
     435                 :            :         period4a, period4b },
     436                 :            :       /* Two periods, ending at the same time. */
     437                 :            :       { tariff5,
     438                 :            :         2018, 1, 8, 9, 0, 0.0, "Z",
     439                 :            :         2018, 1, 8, 10, 0, 0.0, "Z", TRUE,
     440                 :            :         NULL, period5a },
     441                 :            :       { tariff5,
     442                 :            :         2018, 1, 8, 10, 0, 0.0, "Z",
     443                 :            :         2018, 1, 8, 12, 0, 0.0, "Z", FALSE,
     444                 :            :         period5a, period5b },
     445                 :            :       { tariff5,
     446                 :            :         2018, 1, 8, 12, 0, 0.0, "Z",
     447                 :            :         2018, 1, 8, 22, 0, 0.0, "Z", FALSE,
     448                 :            :         period5b, NULL },
     449                 :            :       { tariff5,
     450                 :            :         2018, 1, 8, 22, 0, 0.0, "Z",
     451                 :            :         2018, 1, 9, 10, 0, 0.0, "Z", FALSE,
     452                 :            :         NULL, period5a },
     453                 :            :       /* Two periods, each starting as the other ends. */
     454                 :            :       { tariff6,
     455                 :            :         2018, 1, 7, 10, 0, 0.0, "Z",
     456                 :            :         2018, 1, 8, 0, 0, 0.0, "Z", TRUE,
     457                 :            :         NULL, period6a },
     458                 :            :       { tariff6,
     459                 :            :         2018, 1, 8, 0, 0, 0.0, "Z",
     460                 :            :         2018, 1, 9, 0, 0, 0.0, "Z", FALSE,
     461                 :            :         period6a, period6b },
     462                 :            :       { tariff6,
     463                 :            :         2018, 1, 9, 0, 0, 0.0, "Z",
     464                 :            :         2018, 1, 10, 0, 0, 0.0, "Z", FALSE,
     465                 :            :         period6b, period6a },
     466                 :            :       { tariff6,
     467                 :            :         2018, 1, 10, 0, 0, 0.0, "Z",
     468                 :            :         2018, 1, 11, 0, 0, 0.0, "Z", FALSE,
     469                 :            :         period6a, period6b },
     470                 :            :       { tariff6,
     471                 :            :         2018, 1, 11, 0, 0, 0.0, "Z",
     472                 :            :         2018, 1, 12, 0, 0, 0.0, "Z", FALSE,
     473                 :            :         period6b, period6a },
     474                 :            :       /* Two periods, starting at the same time. */
     475                 :            :       { tariff7,
     476                 :            :         2018, 1, 8, 9, 0, 0.0, "Z",
     477                 :            :         2018, 1, 8, 10, 0, 0.0, "Z", TRUE,
     478                 :            :         NULL, period7b },
     479                 :            :       { tariff7,
     480                 :            :         2018, 1, 8, 10, 0, 0.0, "Z",
     481                 :            :         2018, 1, 8, 12, 0, 0.0, "Z", FALSE,
     482                 :            :         period7b, period7a },
     483                 :            :       { tariff7,
     484                 :            :         2018, 1, 8, 12, 0, 0.0, "Z",
     485                 :            :         2018, 1, 8, 22, 0, 0.0, "Z", FALSE,
     486                 :            :         period7a, NULL },
     487                 :            :       { tariff7,
     488                 :            :         2018, 1, 8, 22, 0, 0.0, "Z",
     489                 :            :         2018, 1, 9, 10, 0, 0.0, "Z", FALSE,
     490                 :            :         NULL, period7b },
     491                 :            :       /* One period, recurring so it starts when it ends. */
     492                 :            :       { tariff8,
     493                 :            :         2018, 1, 7, 5, 0, 0.0, "Z",
     494                 :            :         2018, 1, 8, 0, 0, 0.0, "Z", TRUE,
     495                 :            :         NULL, period8a },
     496                 :            :       { tariff8,
     497                 :            :         2018, 1, 8, 0, 0, 0.0, "Z",
     498                 :            :         2018, 1, 9, 0, 0, 0.0, "Z", FALSE,
     499                 :            :         period8a, period8a },
     500                 :            :       { tariff8,
     501                 :            :         2018, 1, 9, 0, 0, 0.0, "Z",
     502                 :            :         2018, 1, 10, 0, 0, 0.0, "Z", FALSE,
     503                 :            :         period8a, period8a },
     504                 :            :     };
     505                 :            : 
     506         [ +  + ]:         46 :   for (gsize i = 0; i < G_N_ELEMENTS (vectors); i++)
     507                 :            :     {
     508                 :         90 :       g_autoptr(GTimeZone) after_tz = time_zone_new (vectors[i].after_tz);
     509                 :         45 :       g_autoptr(GDateTime) after =
     510                 :         45 :           g_date_time_new (after_tz, vectors[i].after_year, vectors[i].after_month,
     511                 :         45 :                            vectors[i].after_day, vectors[i].after_hour,
     512                 :         45 :                            vectors[i].after_minute, vectors[i].after_seconds);
     513                 :            : 
     514                 :         45 :       g_autoptr(GDateTime) expected_next = NULL;
     515                 :            : 
     516         [ +  + ]:         45 :       if (vectors[i].expected_next_tz != NULL)
     517                 :            :         {
     518                 :         43 :           g_autoptr(GTimeZone) expected_next_tz = time_zone_new (vectors[i].expected_next_tz);
     519                 :         43 :           expected_next =
     520                 :         43 :               g_date_time_new (expected_next_tz, vectors[i].expected_next_year, vectors[i].expected_next_month,
     521                 :         43 :                                vectors[i].expected_next_day, vectors[i].expected_next_hour,
     522                 :         43 :                                vectors[i].expected_next_minute, vectors[i].expected_next_seconds);
     523                 :            :         }
     524                 :            : 
     525                 :         90 :       g_autofree gchar *after_str = g_date_time_format (after, "%FT%T%:::z");
     526                 :         45 :       g_autofree gchar *expected_next_str =
     527         [ +  + ]:         45 :           (expected_next != NULL) ? g_date_time_format (expected_next, "%FT%T%:::z") : g_strdup ("never");
     528                 :            : 
     529                 :         45 :       g_test_message ("Vector %" G_GSIZE_FORMAT ": after: %s, expected next: %s",
     530                 :            :                       i, after_str, expected_next_str);
     531                 :            : 
     532                 :         45 :       g_autoptr(GDateTime) next = NULL;
     533                 :         45 :       MwtPeriod *from_period = NULL, *to_period = NULL;
     534                 :         45 :       next = mwt_tariff_get_next_transition (vectors[i].tariff, after,
     535                 :            :                                              &from_period, &to_period);
     536                 :            : 
     537         [ +  + ]:         45 :       if (expected_next != NULL)
     538                 :            :         {
     539         [ -  + ]:         43 :           g_assert_nonnull (next);
     540         [ -  + ]:         43 :           g_assert_true (g_date_time_equal (next, expected_next));
     541         [ -  + ]:         43 :           g_assert_true (from_period == vectors[i].expected_from_period);
     542         [ -  + ]:         43 :           g_assert_true (to_period == vectors[i].expected_to_period);
     543                 :            :         }
     544                 :            :       else
     545                 :            :         {
     546         [ -  + ]:          2 :           g_assert_null (next);
     547         [ -  + ]:          2 :           g_assert_null (from_period);
     548         [ -  + ]:          2 :           g_assert_null (to_period);
     549                 :            :         }
     550                 :            : 
     551                 :            :       /* Test calling with (@after == NULL). */
     552         [ +  + ]:         45 :       if (vectors[i].expected_next_is_first)
     553                 :            :         {
     554                 :          7 :           g_autoptr(GDateTime) next2 = NULL;
     555                 :          7 :           MwtPeriod *from_period2 = NULL, *to_period2 = NULL;
     556                 :          7 :           next2 = mwt_tariff_get_next_transition (vectors[i].tariff, NULL,
     557                 :            :                                                   &from_period2, &to_period2);
     558                 :            : 
     559         [ -  + ]:          7 :           g_assert_nonnull (next2);
     560         [ -  + ]:          7 :           g_assert_nonnull (expected_next);
     561         [ -  + ]:          7 :           g_assert_true (g_date_time_equal (next2, expected_next));
     562         [ -  + ]:          7 :           g_assert_null (from_period2);
     563         [ -  + ]:          7 :           g_assert_true (to_period2 == vectors[i].expected_to_period);
     564                 :            :         }
     565                 :            :     }
     566                 :            : 
     567                 :            :   /* Special extra test for period 3 to check that (@after == NULL) works to get
     568                 :            :    * the first transition. We can’t include this in the test vectors above,
     569                 :            :    * because it’s impossible to represent a date/time before the first
     570                 :            :    * transition for that tariff. */
     571                 :          1 :   g_autoptr(GDateTime) next = NULL;
     572                 :          1 :   MwtPeriod *from_period = NULL, *to_period = NULL;
     573                 :          1 :   next = mwt_tariff_get_next_transition (tariff3, NULL, &from_period, &to_period);
     574                 :            : 
     575         [ -  + ]:          1 :   g_assert_nonnull (next);
     576         [ -  + ]:          1 :   g_assert_true (g_date_time_equal (next, period3a_start));
     577         [ -  + ]:          1 :   g_assert_null (from_period);
     578         [ -  + ]:          1 :   g_assert_true (to_period == period3a);
     579                 :          1 : }
     580                 :            : 
     581                 :            : /* Test that serialising a tariff with #MwtTariffBuilder, then loading it with
     582                 :            :  * #MwtTariffLoader, gives an identical tariff to the original one. Particularly,
     583                 :            :  * we care that the timezones have not changed. */
     584                 :            : static void
     585                 :          1 : test_tariff_serialisation_roundtrip (void)
     586                 :            : {
     587                 :          1 :   g_autoptr(MwtTariffBuilder) builder = NULL;
     588                 :            : 
     589                 :            :   /* Build the tariff. */
     590                 :          1 :   builder = mwt_tariff_builder_new ();
     591                 :          1 :   mwt_tariff_builder_set_name (builder, "test-tariff");
     592                 :            : 
     593                 :            :   /* Period 1. */
     594                 :          2 :   g_autoptr(GTimeZone) start1_tz = time_zone_new ("Europe/London");
     595                 :          2 :   g_autoptr(GDateTime) start1 = g_date_time_new (start1_tz, 2018, 1, 1, 0, 0, 0);
     596                 :          2 :   g_autoptr(GTimeZone) end1_tz = time_zone_new ("America/Atka");
     597                 :          2 :   g_autoptr(GDateTime) end1 = g_date_time_new (end1_tz, 2018, 2, 1, 0, 0, 0);
     598                 :            : 
     599                 :          1 :   g_autoptr(MwtPeriod) period1 = NULL;
     600                 :          1 :   period1 = mwt_period_new (start1, end1, MWT_PERIOD_REPEAT_MONTH, 1,
     601                 :            :                             "capacity-limit", G_GUINT64_CONSTANT (2 * 1000 * 1000 * 1000),
     602                 :            :                             NULL);
     603                 :          1 :   mwt_tariff_builder_add_period (builder, period1);
     604                 :            : 
     605                 :            :   /* Period 2. */
     606                 :          2 :   g_autoptr(GDateTime) start2 = g_date_time_new_utc (2018, 1, 6, 0, 0, 0);
     607                 :          2 :   g_autoptr(GDateTime) end2 = g_date_time_new_utc (2018, 1, 8, 0, 0, 0);
     608                 :            : 
     609                 :          1 :   g_autoptr(MwtPeriod) period2 = NULL;
     610                 :          1 :   period2 = mwt_period_new (start2, end2, MWT_PERIOD_REPEAT_WEEK, 1,
     611                 :            :                             "capacity-limit", G_MAXUINT64,
     612                 :            :                             NULL);
     613                 :          1 :   mwt_tariff_builder_add_period (builder, period2);
     614                 :            : 
     615                 :            :   /* Finish building the tariff and get it in variant form. */
     616                 :          1 :   g_autoptr(MwtTariff) built_tariff = NULL;
     617                 :          1 :   built_tariff = mwt_tariff_builder_get_tariff (builder);
     618                 :            : 
     619                 :          1 :   g_autoptr(GVariant) variant = NULL;
     620                 :          1 :   variant = mwt_tariff_builder_get_tariff_as_variant (builder);
     621                 :            : 
     622                 :            :   /* Load it again. */
     623                 :          2 :   g_autoptr(MwtTariffLoader) loader = mwt_tariff_loader_new ();
     624                 :          1 :   g_autoptr(GError) local_error = NULL;
     625                 :            : 
     626                 :          1 :   gboolean retval = mwt_tariff_loader_load_from_variant (loader, variant, &local_error);
     627         [ -  + ]:          1 :   g_assert_no_error (local_error);
     628         [ -  + ]:          1 :   g_assert_true (retval);
     629                 :            : 
     630                 :          1 :   MwtTariff *loaded_tariff = mwt_tariff_loader_get_tariff (loader);
     631                 :            : 
     632                 :            :   /* Check properties. */
     633         [ -  + ]:          1 :   g_assert_cmpstr (mwt_tariff_get_name (loaded_tariff), ==,
     634                 :            :                    mwt_tariff_get_name (built_tariff));
     635                 :            : 
     636                 :          1 :   GPtrArray *built_periods = mwt_tariff_get_periods (built_tariff);
     637                 :          1 :   GPtrArray *loaded_periods = mwt_tariff_get_periods (loaded_tariff);
     638         [ -  + ]:          1 :   g_assert_cmpuint (loaded_periods->len, ==, built_periods->len);
     639                 :            : 
     640         [ +  + ]:          3 :   for (gsize i = 0; i < loaded_periods->len; i++)
     641                 :            :     {
     642                 :          2 :       MwtPeriod *built_period = g_ptr_array_index (built_periods, i);
     643                 :          2 :       MwtPeriod *loaded_period = g_ptr_array_index (loaded_periods, i);
     644                 :            : 
     645                 :          2 :       assert_periods_equal (loaded_period, built_period);
     646                 :            :     }
     647                 :          1 : }
     648                 :            : 
     649                 :            : int
     650                 :          1 : main (int    argc,
     651                 :            :       char **argv)
     652                 :            : {
     653                 :          1 :   setlocale (LC_ALL, "");
     654                 :          1 :   g_test_init (&argc, &argv, NULL);
     655                 :            : 
     656                 :          1 :   g_test_add_func ("/tariff/properties", test_tariff_properties);
     657                 :          1 :   g_test_add_func ("/tariff/lookup", test_tariff_lookup);
     658                 :          1 :   g_test_add_func ("/tariff/next-transition", test_tariff_next_transition);
     659                 :          1 :   g_test_add_func ("/tariff/serialisation/roundtrip", test_tariff_serialisation_roundtrip);
     660                 :            : 
     661                 :          1 :   return g_test_run ();
     662                 :            : }

Generated by: LCOV version 1.16