1 /* PSPP - a program for statistical analysis.
2 Copyright (C) 2007 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
17 /* This is a test program for the routines defined in tower.c.
18 This test program aims to be as comprehensive as possible.
19 With -DNDEBUG, "gcov -b" should report 100% coverage of lines
20 and branches in tower.c routines. (Without -DNDEBUG, branches
21 caused by failed assertions will not be taken.) "valgrind
22 --leak-check=yes --show-reachable=yes" should give a clean
23 report, both with and without -DNDEBUG. */
29 #include <libpspp/tower.h>
38 #include <libpspp/compiler.h>
42 /* Currently running test. */
43 static const char *test_name;
45 /* Exit with a failure code.
46 (Place a breakpoint on this function while debugging.) */
53 /* If OK is not true, prints a message about failure on the
54 current source file and the given LINE and terminates. */
56 check_func (bool ok, int line)
60 printf ("Check failed in %s test at %s, line %d\n",
61 test_name, __FILE__, line);
66 /* Verifies that EXPR evaluates to true.
67 If not, prints a message citing the calling line number and
69 #define check(EXPR) check_func ((EXPR), __LINE__)
71 /* Node type and support routines. */
73 /* Test data block. */
76 struct tower_node node; /* Embedded tower block. */
77 int x; /* Primary value. */
80 /* Returns the `struct block' that NODE is embedded within. */
82 tower_node_to_block (const struct tower_node *node)
84 return tower_data (node, struct block, node);
87 /* Swaps *A and *B. */
96 /* Reverses the order of the CNT integers starting at VALUES. */
98 reverse (int *values, size_t cnt)
104 swap (&values[i++], &values[--j]);
107 /* Arranges the CNT blocks in VALUES into the lexicographically
108 next greater permutation. Returns true if successful.
109 If VALUES is already the lexicographically greatest
110 permutation of its blocks (i.e. ordered from greatest to
111 smallest), arranges them into the lexicographically least
112 permutation (i.e. ordered from smallest to largest) and
115 next_permutation (int *values, size_t cnt)
123 if (values[i] < values[i + 1])
126 for (j = cnt - 1; values[i] >= values[j]; j--)
128 swap (values + i, values + j);
129 reverse (values + (i + 1), cnt - (i + 1));
134 reverse (values, cnt);
142 factorial (unsigned int n)
144 unsigned int value = 1;
145 /* Disallow N values that overflow on 32-bit machines. */
152 /* Returns C(n, k), the number of ways that K choices can be made
153 from N items when order is unimportant. */
155 binomial_cofficient (unsigned int n, unsigned int k)
158 return factorial (n) / factorial (k) / factorial (n - k);
161 /* Tests whether PARTS is a K-part integer composition of N.
162 Returns true if so, false otherwise. */
164 is_k_composition (int n, int k, const int parts[])
170 for (i = 0; i < k; i++)
172 if (parts[i] < 1 || parts[i] > n)
179 /* Advances the K-part integer composition of N stored in PARTS
180 to the next lexicographically greater one.
181 Returns true if successful, false if the composition was
182 already the greatest K-part composition of N (in which case
183 PARTS is unaltered). */
185 next_k_composition (int n UNUSED, int k, int parts[])
189 assert (is_k_composition (n, k, parts));
193 for (i = k - 1; i > 0; i--)
204 assert (is_k_composition (n, k, parts));
208 /* Sets the K integers in PARTS to the lexicographically first
209 K-part composition of N. */
211 first_k_composition (int n, int k, int parts[])
217 for (i = 0; i < k; i++)
219 parts[k - 1] += n - k;
222 /* Advances *K and PARTS to the next integer composition of N.
223 Compositions are ordered from shortest to longest and in
224 lexicographical order within a given length.
225 Before the first call, initialize *K to 0.
226 After each successful call, *K contains the length of the
227 current composition and the *K blocks in PARTS contain its
229 Returns true if successful, false if the set of compositions
230 has been exhausted. */
232 next_composition (int n, int *k, int parts[])
234 if (*k >= 1 && next_k_composition (n, *k, parts))
238 first_k_composition (n, ++*k, parts);
245 /* A block expected to be found in a tower. */
246 struct expected_block
248 int height; /* Expected height of bottom of block. */
249 int x; /* Expected value for `x' member. */
252 /* Checks that tower T contains the BLOCK_CNT blocks described by
255 check_tower (struct tower *t,
256 struct expected_block blocks[], size_t block_cnt)
259 struct tower_node *node;
262 check (tower_is_empty (t) == (block_cnt == 0));
265 for (i = 0; i < block_cnt; i++)
267 unsigned long int level;
268 for (level = total_height;
269 level < total_height + blocks[i].height;
272 struct tower_node *found;
273 unsigned long int block_start;
274 found = tower_lookup (t, level, &block_start);
275 check (found != NULL);
276 check (tower_node_to_block (found)->x == blocks[i].x);
277 check (block_start == total_height);
279 total_height += blocks[i].height;
281 check (tower_height (t) == total_height);
283 for (node = tower_first (t), i = 0;
285 node = tower_next (t, node), i++)
287 check (tower_node_get_height (node) == blocks[i].height);
288 check (tower_node_to_block (node)->x == blocks[i].x);
290 check (i == block_cnt);
292 for (node = tower_last (t), i = block_cnt - 1;
294 node = tower_prev (t, node), i--)
296 check (tower_node_get_height (node) == blocks[i].height);
297 check (tower_node_to_block (node)->x == blocks[i].x);
299 check (i == SIZE_MAX);
302 /* Tests inserting all possible sets of block heights into a
303 tower in all possible orders, up to a specified maximum tower
308 const int max_height = 7;
311 for (cnt = 1; cnt <= max_height; cnt++)
313 unsigned int composition_cnt;
314 struct expected_block *expected;
318 struct block *blocks;
320 expected = xnmalloc (cnt, sizeof *expected);
321 heights = xnmalloc (cnt, sizeof *heights);
322 order = xnmalloc (cnt, sizeof *order);
323 blocks = xnmalloc (cnt, sizeof *blocks);
327 while (next_composition (cnt, &block_cnt, heights))
330 unsigned int permutation_cnt;
332 for (i = 0; i < block_cnt; i++)
336 while (permutation_cnt == 0 || next_permutation (order, block_cnt))
340 /* Inserts the block_cnt blocks with the given
341 heights[] into T in the order given by order[]. */
343 for (i = 0; i < block_cnt; i++)
352 for (j = 0; j < i; j++)
354 && (under == NULL || under->x > order[j]))
355 under = &blocks[order[j]];
357 tower_insert (&t, heights[idx], &blocks[idx].node,
358 under != NULL ? &under->node : NULL);
361 /* Check that the result is what we expect. */
362 for (i = 0; i < block_cnt; i++)
364 expected[i].height = heights[i];
367 check_tower (&t, expected, block_cnt);
371 check (permutation_cnt == factorial (block_cnt));
375 check (composition_cnt == 1 << (cnt - 1));
384 /* Tests deleting blocks from towers that initially contain all
385 possible sets of block heights into a tower in all possible
386 orders, up to a specified maximum tower height. */
390 const int max_height = 7;
393 for (cnt = 1; cnt <= max_height; cnt++)
395 unsigned int composition_cnt;
396 struct expected_block *expected;
400 struct block *blocks;
402 expected = xnmalloc (cnt, sizeof *expected);
403 heights = xnmalloc (cnt, sizeof *heights);
404 order = xnmalloc (cnt, sizeof *order);
405 blocks = xnmalloc (cnt, sizeof *blocks);
409 while (next_composition (cnt, &block_cnt, heights))
412 unsigned int permutation_cnt;
414 for (i = 0; i < block_cnt; i++)
418 while (permutation_cnt == 0 || next_permutation (order, block_cnt))
422 /* Insert blocks into tower in ascending order. */
424 for (i = 0; i < block_cnt; i++)
427 tower_insert (&t, heights[i], &blocks[i].node, NULL);
429 expected[i].height = heights[i];
431 check_tower (&t, expected, block_cnt);
433 /* Delete blocks from tower in the order of
435 for (i = 0; i < block_cnt; i++)
439 tower_delete (&t, &blocks[idx].node);
442 assert (j < block_cnt - i);
443 if (expected[j].x == idx)
445 memcpy (&expected[j], &expected[j + 1],
446 sizeof *expected * (block_cnt - i - j - 1));
450 check_tower (&t, expected, block_cnt - i - 1);
455 check (permutation_cnt == factorial (block_cnt));
459 check (composition_cnt == 1 << (cnt - 1));
468 /* Tests towers containing all possible block heights, resizing
469 the blocks to all possible heights that conserve the total
470 tower height, up to a maximum total tower height. */
474 const int max_height = 9;
477 for (cnt = 1; cnt <= max_height; cnt++)
479 unsigned int composition_cnt;
480 struct expected_block *expected;
481 int *heights, *new_heights;
484 struct block *blocks;
486 expected = xnmalloc (cnt, sizeof *expected);
487 heights = xnmalloc (cnt, sizeof *heights);
488 new_heights = xnmalloc (cnt, sizeof *new_heights);
489 order = xnmalloc (cnt, sizeof *order);
490 blocks = xnmalloc (cnt, sizeof *blocks);
494 while (next_composition (cnt, &block_cnt, heights))
497 unsigned int resizes = 0;
499 for (resizes = 0, first_k_composition (cnt, block_cnt, new_heights);
501 || next_k_composition (cnt, block_cnt, new_heights));
506 /* Insert blocks into tower in ascending order. */
508 for (i = 0; i < block_cnt; i++)
511 tower_insert (&t, heights[i], &blocks[i].node, NULL);
513 expected[i].height = heights[i];
515 check_tower (&t, expected, block_cnt);
517 /* Resize all the blocks. */
518 for (i = 0; i < block_cnt; i++)
520 if (expected[i].height != new_heights[i] || rand () % 2)
521 tower_resize (&t, &blocks[i].node, new_heights[i]);
522 expected[i].height = new_heights[i];
524 check_tower (&t, expected, block_cnt);
526 check (resizes == binomial_cofficient (cnt - 1, block_cnt - 1));
530 check (composition_cnt == 1 << (cnt - 1));
540 /* Tests splicing all possible contiguous sets of blocks out of one
541 tower into a second, initially empty tower. */
543 test_splice_out (void)
545 const int max_height = 9;
548 for (cnt = 1; cnt <= max_height; cnt++)
550 unsigned int composition_cnt;
551 struct expected_block *expected;
552 int *heights, *new_heights;
555 struct block *blocks;
557 expected = xnmalloc (cnt, sizeof *expected);
558 heights = xnmalloc (cnt, sizeof *heights);
559 new_heights = xnmalloc (cnt, sizeof *new_heights);
560 order = xnmalloc (cnt, sizeof *order);
561 blocks = xnmalloc (cnt, sizeof *blocks);
565 while (next_composition (cnt, &block_cnt, heights))
569 for (i = 0; i < block_cnt; i++)
570 for (j = i; j <= block_cnt; j++)
572 struct tower src, dst;
578 /* Insert blocks into SRC and DST in ascending order. */
579 for (k = 0; k < block_cnt; k++)
582 tower_insert (&src, heights[k], &blocks[k].node, NULL);
584 expected[k].height = heights[k];
586 check_tower (&src, expected, block_cnt);
588 /* Splice blocks I...J into DST. */
589 tower_splice (&dst, NULL, &src, &blocks[i].node,
590 j < block_cnt ? &blocks[j].node : NULL);
591 check_tower (&dst, &expected[i], j - i);
592 memmove (&expected[i], &expected[j],
593 sizeof *expected * (block_cnt - j));
594 check_tower (&src, expected, block_cnt - (j - i));
598 check (composition_cnt == 1 << (cnt - 1));
608 /* Tests splicing all of the contents of a tower into all
609 possible positions in a second tower. */
611 test_splice_in (void)
613 const int max_height = 9;
616 for (cnt = 1; cnt <= max_height; cnt++)
618 unsigned int composition_cnt;
619 struct expected_block *expected;
620 int *heights, *new_heights;
623 struct block *blocks;
625 expected = xnmalloc (cnt, sizeof *expected);
626 heights = xnmalloc (cnt, sizeof *heights);
627 new_heights = xnmalloc (cnt, sizeof *new_heights);
628 order = xnmalloc (cnt, sizeof *order);
629 blocks = xnmalloc (cnt, sizeof *blocks);
633 while (next_composition (cnt, &block_cnt, heights))
637 for (i = 0; i < block_cnt; i++)
638 for (j = i; j <= block_cnt; j++)
640 struct tower src, dst;
646 /* Insert blocks into SRC and DST in ascending order. */
647 for (k = 0; k < block_cnt; k++)
650 tower_insert (k >= i && k < j ? &src : &dst,
651 heights[k], &blocks[k].node, NULL);
653 expected[k].height = heights[k];
656 /* Splice SRC into DST. */
657 tower_splice (&dst, j < block_cnt ? &blocks[j].node : NULL,
658 &src, i != j ? &blocks[i].node : NULL, NULL);
659 check_tower (&dst, expected, block_cnt);
663 check (composition_cnt == 1 << (cnt - 1));
676 /* Runs TEST_FUNCTION and prints a message about NAME. */
678 run_test (void (*test_function) (void), const char *name)
689 run_test (test_insert, "insert");
690 run_test (test_delete, "delete");
691 run_test (test_resize, "resize");
692 run_test (test_splice_out, "splice out");
693 run_test (test_splice_in, "splice in");