Skip to content
Snippets Groups Projects
Commit fc63ed09 authored by Bruce Cowan's avatar Bruce Cowan :airplane:
Browse files

Port average to GLib

parent 1fdc1f6f
No related branches found
No related tags found
No related merge requests found
......@@ -4,7 +4,7 @@ stages:
- test
before_script:
- dnf install -y gcc meson ninja-build
- dnf install -y gcc meson ninja-build "pkgconfig(glib-2.0)"
build:
stage: build
......
......@@ -18,88 +18,104 @@
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#include <math.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <glib.h>
#include <array.h>
#define INT_TO_PTR(x) ((void *) (size_t) (x))
#define PTR_TO_INT(x) ((int) (size_t) (x))
typedef struct
{
Array *array;
} ArrayFixture;
static double
get_total (const Array *array,
ValueFunc func)
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++)
total += func (array_get (array, i));
total += (double) GPOINTER_TO_INT (array_get (array, i));
return total;
}
static double
get_average (const Array *array,
ValueFunc func)
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)
{
return get_total (array, func) / array_get_length (array);
g_clear_pointer (&fixture->array, array_unref);
}
static double
array_to_int (const void *data)
static void
expected_values (Array *array,
double *total,
double *average)
{
return (double) PTR_TO_INT (data);
size_t n = array_get_length (array);
gdouble sum = (n * (n+1)) / 2;
if (total)
*total = sum;
if (average)
*average = sum / n;
}
static Array *
create_test_array (size_t start,
size_t end)
static void
test_total (ArrayFixture *fixture,
gconstpointer user_data)
{
Array *array = array_new (NULL);
gdouble expected_total;
for (size_t i = start; i < end; i++)
array_add (array, INT_TO_PTR (i));
gdouble total = get_total (fixture->array);
expected_values (fixture->array, &expected_total, NULL);
return array;
g_assert_cmpfloat (total, ==, expected_total);
}
static bool
is_close (double a,
double b)
static void
test_average (ArrayFixture *fixture,
gconstpointer user_data)
{
return fabs (a - b) <= (1e-8 + 1e-5 * b); // Values from numpy
gdouble expected_average;
gdouble average = get_average (fixture->array);
expected_values (fixture->array, NULL, &expected_average);
g_assert_cmpfloat (average, ==, expected_average);
}
int
main (void)
main (int argc,
char **argv)
{
int start = 1;
int end = 100;
Array *array = create_test_array (start, end);
int n = end - start;
double expected_total = (n * (n+1)) / 2; // Only valid if starting from 1
double expected_average = expected_total / n;
double total = get_total (array, array_to_int);
if (!is_close (total, expected_total))
{
fprintf (stderr, "Expected total %lf, value returned was %lf\n",
expected_total, total);
return EXIT_FAILURE;
}
double average = get_average (array, array_to_int);
if (!is_close (average, expected_average))
{
fprintf (stderr, "Expected average %lf, value returned was %lf\n",
expected_average, average);
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
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 ();
}
avg = executable('average', 'average.c', link_with: lib, include_directories: lib_inc)
create = executable('create', 'create.c', link_with: lib, include_directories: lib_inc)
range = executable('range', 'range.c', link_with: lib, include_directories: lib_inc)
glib_dep = dependency('glib-2.0')
avg = executable('average',
'average.c',
link_with: lib,
include_directories: lib_inc,
dependencies: [glib_dep])
test('average', avg)
test('create', create)
test('range', range)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment