#include #include #include // for EXIT_FAILURE /*#include */ #include /* * test program for the stack implementation in stack.h. * Uses different test functions to check if the stack implementation * works as intended. * * Author: Marc Meunier (mame0264@student.umu.se). * * Version information: * 2025-04-22: v1.0. First version. * 2025-05-01: v2.0. fixed comments from labres, see changes.txt for details. */ #define VERSION "v2.0" #define VERSION_DATE "2025-05-01" // // Function to compare the values stored in the list. bool value_equal(int v1, int v2) { return v1 == v2; } // int_create() - make a dynamic copy of an integer // @i: Integer to copy // // Returns: A pointer to a dynamic copy of i int *int_create(int i) { // Allocate memory for an integer and set the value int *v = malloc(sizeof(*v)); *v = i; return v; } // Return the memory used by the integer. // void int_kill(void *v) { int *p = v; free(p); } // test that the stack_empty() function creates an empty stack. // no input parameters // returns nothing void test_stack_empty(void) { fprintf(stderr, "Starting test_stack_empty()...\n"); // initialize stack stack *s = stack_empty(int_kill); // check that stack initialized correctly if (s == NULL) { fprintf(stderr, "FAIL: stack_empty() returned NULL.\n"); exit(1); } // returns memory and exit message. stack_kill(s); fprintf(stderr, "done.\n"); } // test that the stack_is_empty() function returns true for an empty stack // no input parameters // returns nothing void isempty_return_true(void) { fprintf(stderr, "Starting isempty_return_true()...\n"); // initialize stack stack *s = stack_empty(int_kill); // prints if function returns false if (!stack_is_empty(s)) { fprintf(stderr, "\nStack is empty but \"stack_is_empty\" reports non empty\n"); exit(1); } // adds values to stack s = stack_push(s, int_create(10)); // test if stack prints false with values inside if (stack_is_empty(s)) { fprintf(stderr, "\nStack is non empty but \"stack_is_empty\" reports empty.\n"); exit(1); } // returns memory and exit message. stack_kill(s); fprintf(stderr, "done.\n"); } // tests if stack returns top value in stack. // no input parameters // returns nothing void push_stack_on_top(void) { fprintf(stderr, "Starting push_stack_on_top()...\n"); // initialize stack stack *s = stack_empty(int_kill); // how many numbers that should be added to stack int numberofelements = 10; // adds nonlinear values to stack for (int i = 1; i <= numberofelements; i++) { if (i > 5) { int a = 5 * i; s = stack_push(s, int_create((a))); } else { s = stack_push(s, int_create(i)); } } // top value of stack int a = 0; // checks return order for (int i = 0; i <= numberofelements - 1; i++) { a = numberofelements - i; // converts pointer to an intedger value. int *stored_ptr = stack_top(s); int stored_value = *stored_ptr; // checks if value higher then 5 so it has same values as inserted into stack. if (a > 5) { if (!value_equal(stored_value, a * 5)) { fprintf(stderr, "FAIL: Expected <%d>, got <%d>.\n", (a * 5), stored_value); exit(1); } } else { if (!value_equal(stored_value, a)) { fprintf(stderr, "FAIL: Expected <%d>, got <%d>.\n", a, stored_value); exit(1); } } // removes one value from the stack so that the next value can be checked. s = stack_pop(s); } // Check if stack is empty after running test. if (!stack_is_empty(s)) { fprintf(stderr, "\nStack is non empty but should be empty.\n"); exit(1); } // returns memory and exit message. stack_kill(s); fprintf(stderr, "done.\n"); } // tests if the top reads wrong value. // no input parameters // returns nothing void top_read_wrong(void) { fprintf(stderr, "Starting top_read_wrong()...\n"); // initialize stack stack *s = stack_empty(int_kill); // loops over some values to add to the stack. for (int i = 0; i <= 3; i++) { s = stack_push(s, int_create(i)); // converts the pointer to an intedger value. int *stored_ptr = stack_top(s); int stored_value = *stored_ptr; // checks values in stack and compare to inputed value. if (!value_equal(stored_value, i)) { fprintf(stderr, "FAIL: Expected <%d>, got <%d>.\n", i, stored_value); exit(1); } } // returns memory and exit message. stack_kill(s); fprintf(stderr, "done.\n"); } // tests if the pop function removes the wrong value or not. // no input parameters // returns nothing void pop_remove_wrong(void) { fprintf(stderr, "Starting pop_remove_wrong()...\n"); // how many numbers that should be added to stack int iter = 3; // initialize stack stack *s = stack_empty(int_kill); // adds values to stack for (int i = 0; i <= iter; i++) { s = stack_push(s, int_create(i)); } // check if values are correct order in stack for (int i = 0; i <= iter; i++) { int *stored_ptr = stack_top(s); int stored_value = *stored_ptr; if (!value_equal(stored_value, 3 - i)) { fprintf(stderr, "FAIL: Expected <%d>, got <%d>.\n", i, stored_value); exit(1); } s = stack_pop(s); } // Check if stack is empty after running test. if (!stack_is_empty(s)) { fprintf(stderr, "\nStack is non empty but should be empty.\n"); exit(1); } // returns memory and exit message. stack_kill(s); fprintf(stderr, "done.\n"); } // main function that runs all the tests. int main(void) { // prints the version and date of the program printf("%s, %s %s: Test program for the typed stack datatype.\n", __FILE__, VERSION, VERSION_DATE); // tests each function. test_stack_empty(); isempty_return_true(); push_stack_on_top(); top_read_wrong(); pop_remove_wrong(); // test sucessful fprintf(stderr, "\nSUCCESS: Implementation passed all tests. Normal exit.\n"); return 0; }