quakeforge/libs/util/test/test-pqueue.c
Bill Currie 80b17623b1 [util] Fix an out-by-one in pqueue tests
Showed up only when the data arrays were packed.
2021-08-02 23:08:14 +09:00

254 lines
5.2 KiB
C

/*
test-pqueue.c
Priority queue related tests
Copyright (C) 2021 Bill Currie <bill@taniwha.org>
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 2
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, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdio.h>
#include <string.h>
#include "QF/pqueue.h"
#define SIZEOF(x) (sizeof(x) / sizeof(x[0]))
static int
compare (const int *a, const int *b, void *arg)
{
//printf ("%d %d\n", *a, *b);
return *a - *b;
}
static int
rev (const int *a, const int *b, void *arg)
{
return *b - *a;
}
static int queue_array[7];
static struct PQUEUE_TYPE (int) pqueue = {
.maxSize = SIZEOF (queue_array),
.compare = compare,
.a = queue_array,
.data = 0,
};
static int
pq_is_empty (void)
{
return PQUEUE_IS_EMPTY (&pqueue);
}
static int
pq_is_full (void)
{
return PQUEUE_IS_FULL (&pqueue);
}
static int
pq_peek (void)
{
return PQUEUE_PEEK (&pqueue);
}
static void
pq_insert (int value)
{
PQUEUE_INSERT (&pqueue, value);
}
static int
pq_remove (void)
{
return PQUEUE_REMOVE (&pqueue);
}
static void
pq_adjust (int index)
{
PQUEUE_ADJUST (&pqueue, index);
}
static void
dump_array (const int *arr, size_t n)
{
while (n-- > 0) {
printf (" %d", *arr++);
}
printf ("\n");
}
static int
test_insert (const int *data, size_t count)
{
while (count-- > 0) {
pq_insert (*data++);
}
return 1;
}
static int
test_remove (const int *data, size_t count)
{
while (count-- > 0) {
if (pq_remove () != *data++) {
return 0;
}
}
return 1;
}
static int
test_adjust (const int *data, size_t count)
{
//printf ("adjust start\n");
pqueue.a[count] = *data;
pq_adjust (count);
//printf ("adjust end\n");
return 1;
}
static int
test_peek (const int *data, size_t count)
{
return pq_peek () == *data;
}
static int
test_size (const int *data, size_t count)
{
return pqueue.size == count;
}
static int
test_is_empty (const int *data, size_t count)
{
return pq_is_empty () == *data;
}
static int
test_is_full (const int *data, size_t count)
{
return pq_is_full () == *data;
}
static int
dump_queue (const int *data, size_t count)
{
if (0) {
dump_array (pqueue.a, pqueue.size);
}
return 1;
}
static int true = 1;
static int false = 0;
static int data[] = { 3, 2, 5, 6, 8, 1, 9 };
static int data1[] = { 3, 7, 5, 6, 8, 1, 9 };
static int data2[] = { 3, 7, 5, 6, 8, 1, 4 };
static int data3[] = { 3, 7, 0, 6, 8, 1, 4 };
static int sort[SIZEOF(data)];
static int sort1[SIZEOF(data1)];
static int sort2[SIZEOF(data2)];
static int sort3[SIZEOF(data3)];
typedef struct {
const int *data;
size_t nele;
int (*test) (const int *data, size_t nele);
} test_t;
static test_t tests[] = {
{ &true, 1, test_is_empty },
{ &false, 1, test_is_full },
{ 0, 0, test_size },
{ data + 0, 1, test_insert },
{ 0, 1, test_size },
{ &false, 1, test_is_empty },
{ &false, 1, test_is_full },
{ data + 0, 1, test_peek },
{ data + 0, 1, test_remove },
{ &true, 1, test_is_empty },
{ &false, 1, test_is_full },
{ 0, 0, test_size },
{ data + 0, 3, test_insert },
{ 0, 3, test_size },
{ data + 2, 1, test_peek },
{ data + 2, 1, test_remove },
{ data + 0, 1, test_remove },
{ data + 1, 1, test_remove },
{ &true, 1, test_is_empty },
{ data + 0, SIZEOF(data), test_insert },
{ 0, SIZEOF(data), test_size },
{ &false, 1, test_is_empty },
{ &true, 1, test_is_full },
{ 0, 0, dump_queue },
{ sort1 + 2, 3, test_adjust },
{ 0, 0, dump_queue },
{ sort2 + 4, 0, test_adjust },
{ 0, 0, dump_queue },
{ sort3 + 6, 4, test_adjust },
{ 0, 0, dump_queue },
{ sort3 + 0, SIZEOF(sort), test_remove },
};
#define num_tests ((int) SIZEOF (tests))
static int
run_test (const test_t *test)
{
return test->test (test->data, test->nele);
}
int
main(int argc, const char **argv)
{
int ret = 0;
memcpy (sort, data, sizeof (sort));
memcpy (sort1, data1, sizeof (sort1));
memcpy (sort2, data2, sizeof (sort2));
memcpy (sort3, data3, sizeof (sort3));
heapsort_r (sort, SIZEOF(sort), sizeof(int), (__compar_d_fn_t)rev, 0);
heapsort_r (sort1, SIZEOF(sort1), sizeof(int), (__compar_d_fn_t)rev, 0);
heapsort_r (sort2, SIZEOF(sort2), sizeof(int), (__compar_d_fn_t)rev, 0);
heapsort_r (sort3, SIZEOF(sort3), sizeof(int), (__compar_d_fn_t)rev, 0);
//dump_array (sort, SIZEOF(sort));
//dump_array (sort1, SIZEOF(sort1));
//dump_array (sort2, SIZEOF(sort2));
//dump_array (sort3, SIZEOF(sort3));
for (int i = 0; i < num_tests; i++) {
if (!run_test (&tests[i])) {
printf ("test %d failed\n", i);
ret = 1;
}
}
return ret;
}