/* SPDX-License-Identifier: BSD-3-Clause */ /* * Copyright © 2010, Zed A. Shaw. * Copyright © 2020 rsiddharth */ #include "minunit.h" #include static DArray *array = NULL; static int *val1 = NULL; static int *val2 = NULL; int testcmp(int **a, int **b) { int x = **a, y = **b; if (x == y) { return 0; } else if (x < y) { return -1; } else { return 1; } } char *test_create() { // Test fail. array = DArray_create(0, 0); mu_assert(array == NULL, "array must be NULL."); // Test success. array = DArray_create(sizeof(int), 100); mu_assert(array != NULL, "DArray_create failed."); mu_assert(array->contents != NULL, "contents are wrong in array."); mu_assert(array->end == 0, "end isn't at the right spot"); mu_assert(array->element_size == sizeof(int), "element size is wrong."); mu_assert(array->max == 100, "wrong max length on initial size"); return NULL; } char *test_destroy() { DArray_destroy(array); return NULL; } char *test_new() { // Test fail. val1 = DArray_new(NULL); mu_assert(val1 == NULL, "val1 must be NULL"); // Test success val1 = DArray_new(array); mu_assert(val1 != NULL, "failed to make a new element"); val2 = DArray_new(array); mu_assert(val2 != NULL, "failed to make a new element"); return NULL; } char *test_set() { int rc = 0; // Test fail. // case where array is NULL rc = DArray_set(NULL, 0, val1); mu_assert(rc == -1, "rc must be -1"); // case where i < 0 rc = DArray_set(array, -1, val1); mu_assert(rc == -1, "rc must be -1"); // case where i > array->max rc = DArray_set(array, array->max + 1, val1); mu_assert(rc == -1, "rc must be -1"); // Test success. // must set val1 at index 0 rc = DArray_set(array, 0, val1); mu_assert(rc == 0, "rc must be 0"); // must set val2 at index 1 rc = DArray_set(array, 1, val2); mu_assert(rc == 1, "rc must be 1"); return NULL; } char *test_get() { void *rc = NULL; // Test fail. // case where array is NULL rc = DArray_get(NULL, 0); mu_assert(rc == NULL, "rc must be NULL"); // case where i < 0 rc = DArray_get(array, -2); mu_assert(rc == NULL, "rc must be NULL"); // case where i > array->max rc = DArray_get(array, array->max + 1); mu_assert(rc == NULL, "rc must be NULL"); // Test succcess. mu_assert(DArray_get(array, 0) == val1, "Wrong first value"); mu_assert(DArray_get(array, 1) == val2, "Wrong second value"); return NULL; } char *test_remove() { int *val_check = NULL; // Test fail. // case where array is NULL. val_check = DArray_remove(NULL, 0); mu_assert(val_check == NULL, "val_check must be NULL"); mu_assert(array->contents[0] != NULL, "array->contents[0] must not be NULL"); // case where i < 0 val_check = DArray_remove(array, -1); mu_assert(val_check == NULL, "val_check must be NULL"); // case where i > array->max val_check = DArray_remove(array, array->max + 1); mu_assert(val_check == NULL, "val_check must be NULL"); // Test success. val_check = DArray_remove(array, 0); mu_assert(val_check !=NULL, "Should not get NULL"); mu_assert(*val_check == *val1, "Should get the first value."); mu_assert(DArray_get(array, 0) == NULL, "Should be gone."); DArray_free(val_check); val_check = DArray_remove(array, 1); mu_assert(val_check != NULL, "Should not get NULL."); mu_assert(*val_check == *val2, "Should get second value."); mu_assert(DArray_get(array, 1) == NULL, "Should be gone"); DArray_free(val_check); return NULL; } char *test_expand_contract() { int old_max = array->max; DArray_expand(array); mu_assert((unsigned int) array->max == old_max + array->expand_rate, "Wrong size after expand."); // Check if newly allocated space is all set to 0. int i = 0; for (i = old_max; i < array->max; i++) { mu_assert(array->contents[i] == 0, "contents must be 0"); } int rc = 0; rc = DArray_contract(array); mu_assert(rc == 0, "rc must be 0"); mu_assert((unsigned int) array->max == array->expand_rate + 1, "Should stay at the expand_rate at least."); rc = DArray_contract(array); mu_assert(rc == 0, "rc must be 0"); mu_assert((unsigned int) array->max == array->expand_rate + 1, "Should stay at the expand_rate at least"); return NULL; } char *test_push_pop() { int i = 0, rc = 0; for (i = 0; i < 1000; i++) { int *val = DArray_new(array); *val = i * 333; rc = DArray_push(array, val); mu_assert(rc == 0, "Darray_push failed"); } mu_assert(array->max == 1201, "Wrong max size."); for (i = 999; i >= 0; i--) { int *val = DArray_pop(array); mu_assert(val != NULL, "Shouldn't get a NULL"); mu_assert(*val == i * 333, "Wrong value."); if ((DArray_end(array) > (int) array->expand_rate) && (DArray_end(array) % array->expand_rate)) { mu_assert(array->max == DArray_end(array) + 1, "DArray pop contract error"); } DArray_free(val); } return NULL; } int is_sorted(DArray *array) { int i = 0; for (i = 0; i < DArray_count(array) -1; i++) { if (*((int *) DArray_get(array, i)) > *((int *) DArray_get(array, i + 1))) { return 0; } } return 1; } char *test_shallow_copy() { // First populate array. array = DArray_create(sizeof(int), 100); int i = 0, rc = 0; int *val = NULL; for (i = 0; i < 1000; i++) { val = DArray_new(array); *val = i * 333; rc = DArray_push(array, val); mu_assert(rc == 0, "Darray_push failed"); } mu_assert(array->max == 1300, "Wrong max size."); // Set at 1100 val = DArray_new(array); *val = 42; rc = DArray_set(array, 1100, val); mu_assert(rc == 1100, "Error setting value at 1100"); // Set at 1110 val = DArray_new(array); *val = 4242; rc = DArray_set(array, 1110, val); mu_assert(rc == 1110, "Error setting value at 1110"); // Test shallow copy DArray *copy = DArray_shallow_copy(array); mu_assert(copy != NULL, "Shallow copy failed"); int expected = 0; for (i = 0; i < 1000; i++) { expected = i * 333; val = DArray_get(copy, i); mu_assert(*val == expected, "Unexpected element in copy."); } expected = 42; val = DArray_get(copy, 1100); mu_assert(*val == expected, "Unexpected element at in copy."); expected = 4242; val = DArray_get(copy, 1110); mu_assert(*val == expected, "Unexpected element at in copy."); // Destroy copy. DArray_destroy(copy); // Destroy array. DArray_clear_destroy(array); return NULL; } char *test_sort_add() { array = DArray_create(sizeof(int), 100); mu_assert(array != NULL, "Error initializing array"); int i = 0, rc = 0; int *val = NULL; for (i = 0; i < 2000; i++) { val = DArray_new(array); mu_assert(val != NULL, "Error creating new element"); *val = rand(); rc = DArray_sort_add(array, val, (DArray_compare) testcmp); mu_assert(rc == 0, "Error adding element."); mu_assert(is_sorted(array) == 1, "array not sorted."); } DArray_clear_destroy(array); return NULL; } char *test_find() { array = DArray_create(sizeof(int), 100); mu_assert(array != NULL, "Error initializing array"); // test setup. int i = 0, rc = 0; int *val = NULL; for (i = 0; i < 2000; i++) { val = DArray_new(array); mu_assert(val != NULL, "Error creating new element"); *val = i; rc = DArray_sort_add(array, val, (DArray_compare) testcmp); mu_assert(rc == 0, "Error adding element"); mu_assert(is_sorted(array) == 1, "array not sorted"); } // tests. val = DArray_new(array); mu_assert(val != NULL, "Error creating new element"); for (i = 0; i < 2000; i++) { *val = i; rc = DArray_find(array, val, (DArray_compare) testcmp); mu_assert(rc == i, "val not found in array"); } *val = 3000; rc = DArray_find(array, val, (DArray_compare) testcmp); mu_assert(rc == -1, "rc must be -1"); // test teardown. DArray_clear_destroy(array); free(val); return NULL; } char *all_tests() { mu_suite_start(); mu_run_test(test_create); mu_run_test(test_new); mu_run_test(test_set); mu_run_test(test_get); mu_run_test(test_remove); mu_run_test(test_expand_contract); mu_run_test(test_push_pop); mu_run_test(test_destroy); mu_run_test(test_shallow_copy); mu_run_test(test_sort_add); mu_run_test(test_find); return NULL; } RUN_TESTS(all_tests);