Skip to content
Snippets Groups Projects
average.c 2.84 KiB
Newer Older
Bruce Cowan's avatar
Bruce Cowan committed
/* average.c
 *
 * Copyright 2018 Bruce Cowan <bruce@bcowan.me.uk>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * SPDX-License-Identifier: GPL-3.0-or-later
 */

Bruce Cowan's avatar
Bruce Cowan committed
#include <stdlib.h>
Bruce Cowan's avatar
Bruce Cowan committed
#include <math.h>

#include <glib.h>
Bruce Cowan's avatar
Bruce Cowan committed

Bruce Cowan's avatar
Bruce Cowan committed
#include <array.h>
Bruce Cowan's avatar
Bruce Cowan committed

Bruce Cowan's avatar
Bruce Cowan committed
typedef struct
{
    Array *array;
} ArrayFixture;
Bruce Cowan's avatar
Bruce Cowan committed

Bruce Cowan's avatar
Bruce Cowan committed
static gdouble
get_total (const Array *array)
{
    double total = 0;
    size_t length = array_get_length (array);

    for (size_t i = 0; i < length; i++)
Bruce Cowan's avatar
Bruce Cowan committed
        total += (double) GPOINTER_TO_INT (array_get (array, i));
Bruce Cowan's avatar
Bruce Cowan committed
static gdouble
get_average (const Array *array)
{
    return get_total (array) / array_get_length (array);
}

static void
create_array (ArrayFixture  *fixture,
              gconstpointer  user_data)
{
    size_t length = GPOINTER_TO_SIZE (user_data);
    fixture->array = array_new (NULL);

    for (size_t i = 1; i < length; i++)
        array_add (fixture->array, GINT_TO_POINTER (i));
}

static void
destroy_array (ArrayFixture  *fixture,
               gconstpointer  user_data)
Bruce Cowan's avatar
Bruce Cowan committed
    g_clear_pointer (&fixture->array, array_unref);
Bruce Cowan's avatar
Bruce Cowan committed
static void
expected_values (Array  *array,
                 double *total,
                 double *average)
Bruce Cowan's avatar
Bruce Cowan committed
{
Bruce Cowan's avatar
Bruce Cowan committed
    size_t n = array_get_length (array);
    gdouble sum = (n * (n+1)) / 2;

    if (total)
        *total = sum;

    if (average)
        *average = sum / n;
Bruce Cowan's avatar
Bruce Cowan committed
}

Bruce Cowan's avatar
Bruce Cowan committed
static void
test_total (ArrayFixture *fixture,
            gconstpointer user_data)
Bruce Cowan's avatar
Bruce Cowan committed
{
Bruce Cowan's avatar
Bruce Cowan committed
    gdouble expected_total;
Bruce Cowan's avatar
Bruce Cowan committed

Bruce Cowan's avatar
Bruce Cowan committed
    gdouble total = get_total (fixture->array);
    expected_values (fixture->array, &expected_total, NULL);
Bruce Cowan's avatar
Bruce Cowan committed

Bruce Cowan's avatar
Bruce Cowan committed
    g_assert_cmpfloat (total, ==, expected_total);
Bruce Cowan's avatar
Bruce Cowan committed
}

Bruce Cowan's avatar
Bruce Cowan committed
static void
test_average (ArrayFixture *fixture,
              gconstpointer user_data)
Bruce Cowan's avatar
Bruce Cowan committed
    gdouble expected_average;

    gdouble average = get_average (fixture->array);
    expected_values (fixture->array, NULL, &expected_average);

    g_assert_cmpfloat (average, ==, expected_average);
Bruce Cowan's avatar
Bruce Cowan committed
int
Bruce Cowan's avatar
Bruce Cowan committed
main (int    argc,
      char **argv)
Bruce Cowan's avatar
Bruce Cowan committed
{
Bruce Cowan's avatar
Bruce Cowan committed
    g_test_init (&argc, &argv, NULL);

    g_test_add ("/array/total", ArrayFixture, GSIZE_TO_POINTER (100),
                create_array, test_total, destroy_array);
    g_test_add ("/array/average", ArrayFixture, GSIZE_TO_POINTER (100),
                create_array, test_average, destroy_array);

    return g_test_run ();
Bruce Cowan's avatar
Bruce Cowan committed
}