Skip to content

Commit

Permalink
Unit tests for NFA State (#71)
Browse files Browse the repository at this point in the history
* Unit test for NFA Initial Commit

* Tests for create and init. TODO: tests for add_transition

* Tests for generic list

* Tests for the NFA State functions

* Removed unused include
  • Loading branch information
mkpro118 authored Jul 1, 2024
1 parent da42915 commit 1afc7d5
Show file tree
Hide file tree
Showing 2 changed files with 312 additions and 0 deletions.
210 changes: 210 additions & 0 deletions tests/test_list.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
#include <string.h>

Check notice on line 1 in tests/test_list.c

View workflow job for this annotation

GitHub Actions / linter

Run clang-format on tests/test_list.c

File tests/test_list.c does not conform to Custom style guidelines. (lines 14, 15, 19, 20, 22, 23, 24, 25, 26, 28, 29, 35, 36, 38, 39, 40, 41, 43, 44, 46, 47, 49, 55, 56, 58, 59, 61, 63, 64, 65, 66, 68, 69, 70, 71, 73, 74, 75, 77, 83, 84, 86, 87, 89, 91, 92, 93, 95, 96, 97, 99, 100, 102, 108, 109, 111, 112, 114, 116, 117, 118, 120, 121, 122, 123, 125, 126, 128, 134, 135, 137, 138, 140, 142, 144, 145, 147, 148, 150, 151, 153, 155, 161, 162, 164, 165, 166, 168, 169, 170, 172, 173, 174, 176, 178, 179, 181, 182, 184, 185, 187, 188, 190, 197, 198, 199, 200, 201, 202, 203, 204, 208, 209)

#include "testlib/asserts.h"
#include "testlib/tests.h"

#include "list.h"

Check failure on line 6 in tests/test_list.c

View workflow job for this annotation

GitHub Actions / linter

tests/test_list.c:6:10 [clang-diagnostic-error]

'list.h' file not found

// Define a test list for integers
CREATE_LIST_FOR(int, IntList)

IntList list;

// Compare function for integers
int compare_int(const int* a, const int* b) {
return *a - *b;
}

// Test function to create a list
int test_create_list() {
TEST_BEGIN;

IntList* list = IntList_create(5);
assert_is_not_null(list);
assert_equals_int(list->capacity, 5);
assert_equals_int(list->size, 0);
assert_is_not_null(list->list);

IntList_free(list, NULL);
free(list);

TEST_END;
}

// Test function to initialize a list
int test_init_list() {
TEST_BEGIN;

assert_equals_int(IntList_init(&list, 5), 0);
assert_equals_int(list.capacity, 5);
assert_equals_int(list.size, 0);
assert_is_not_null(list.list);

// Test initializing with capacity 0
assert_equals_int(IntList_init(&list, 0), -1);

// Test initializing NULL list
assert_equals_int(IntList_init(NULL, 5), -1);

IntList_free(&list, NULL);

TEST_END;
}

// Test function to add elements to the list
int test_add_to_list() {
TEST_BEGIN;

int ret = IntList_init(&list, 2);
assert_equals_int(ret, 0);

int value1 = 10, value2 = 20, value3 = 30;

assert_equals_int(IntList_add(&list, &value1), 1);
assert_equals_int(IntList_add(&list, &value2), 2);
assert_equals_int(list.size, 2);
assert_equals_int(list.capacity, 2);

// This should trigger reallocation
assert_equals_int(IntList_add(&list, &value3), 3);
assert_equals_int(list.size, 3);
assert_equals_int(list.capacity, 3);

assert_equals_int(list.list[0], 10);
assert_equals_int(list.list[1], 20);
assert_equals_int(list.list[2], 30);

IntList_free(&list, NULL);

TEST_END;
}

// Test function for find operation
int test_find_in_list() {
TEST_BEGIN;

int ret = IntList_init(&list, 3);
assert_equals_int(ret, 0);

int value1 = 10, value2 = 20, value3 = 30, value4 = 40;

IntList_add(&list, &value1);
IntList_add(&list, &value2);
IntList_add(&list, &value3);

int* found = IntList_find(&list, &value2, compare_int);
assert_is_not_null(found);
assert_equals_int(*found, 20);

found = IntList_find(&list, &value4, compare_int);
assert_is_null(found);

IntList_free(&list, NULL);

TEST_END;
}

// Test function for remove operation
int test_remove_from_list() {
TEST_BEGIN;

int ret = IntList_init(&list, 3);
assert_equals_int(ret, 0);

int value1 = 10, value2 = 20, value3 = 30, value4 = 40;

IntList_add(&list, &value1);
IntList_add(&list, &value2);
IntList_add(&list, &value3);

assert_equals_int(IntList_remove(&list, &value2, compare_int), 0);
assert_equals_int(list.size, 2);
assert_equals_int(list.list[0], 10);
assert_equals_int(list.list[1], 30);

assert_equals_int(IntList_remove(&list, &value4, compare_int), -1);
assert_equals_int(list.size, 2);

IntList_free(&list, NULL);

TEST_END;
}

// Test function for size operation
int test_list_size() {
TEST_BEGIN;

int ret = IntList_init(&list, 3);
assert_equals_int(ret, 0);

int value1 = 10, value2 = 20;

assert_equals_int(IntList_size(&list), 0);

IntList_add(&list, &value1);
assert_equals_int(IntList_size(&list), 1);

IntList_add(&list, &value2);
assert_equals_int(IntList_size(&list), 2);

IntList_remove(&list, &value1, compare_int);
assert_equals_int(IntList_size(&list), 1);

IntList_free(&list, NULL);

assert_equals_int(IntList_size(NULL), 0);

TEST_END;
}

// Test function for edge cases
int test_edge_cases() {
TEST_BEGIN;

// Test creating list with 0 capacity
int ret = IntList_init(&list, 0);
assert_equals_int(ret, -1);

// Test adding to NULL list
int value = 10;
assert_equals_int(IntList_add(NULL, &value), -1);

// Test adding NULL value
ret = IntList_init(&list, 1);
assert_equals_int(ret, 0);

assert_equals_int(IntList_add(&list, NULL), -1);

// Test finding in NULL list
assert_is_null(IntList_find(NULL, &value, compare_int));

// Test finding with NULL compare function
assert_is_null(IntList_find(&list, &value, NULL));

// Test removing from NULL list
assert_equals_int(IntList_remove(NULL, &value, compare_int), -1);

// Test removing with NULL compare function
assert_equals_int(IntList_remove(&list, &value, NULL), -1);

IntList_free(&list, NULL);

TEST_END;
}

// Define the tests array
Test tests[] = {
{.name="test_create_list", .func=test_create_list},
{.name="test_init_list", .func=test_init_list},
{.name="test_add_to_list", .func=test_add_to_list},
{.name="test_find_in_list", .func=test_find_in_list},
{.name="test_remove_from_list", .func=test_remove_from_list},
{.name="test_list_size", .func=test_list_size},
{.name="test_edge_cases", .func=test_edge_cases},
{NULL, NULL} // Sentinel to mark the end of the array
};

// Main function
int main(int argc, char* argv[]) {
return default_main(&argv[1], argc - 1);
}
102 changes: 102 additions & 0 deletions tests/test_nfa_state.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#include "testlib/asserts.h"

Check notice on line 1 in tests/test_nfa_state.c

View workflow job for this annotation

GitHub Actions / linter

Run clang-format on tests/test_nfa_state.c

File tests/test_nfa_state.c does not conform to Custom style guidelines. (lines 1, 9, 12, 14, 16, 17, 18, 20, 21, 23, 27, 29, 30, 31, 33, 34, 36, 37, 39, 40, 42, 43, 44, 46, 47, 48, 49, 51, 52, 53, 54, 55, 56, 57, 59, 60, 61, 62, 63, 64, 65, 66, 68, 72, 73, 74, 75, 76, 77, 79, 80, 82, 83, 85, 86, 87, 88, 93, 94, 95, 96, 97, 100, 101)
#include "testlib/tests.h"
#include "nfa_state.h"

Check failure on line 3 in tests/test_nfa_state.c

View workflow job for this annotation

GitHub Actions / linter

tests/test_nfa_state.c:3:10 [clang-diagnostic-error]

'nfa_state.h' file not found
#include "list.h"

CREATE_LIST_FOR(NFAState, NFAStateList)

// Global NFAState variable
NFAState state;


int test_state_init() {

TEST_BEGIN;

assert_equals_int(state_init(&state, false), 0);
assert_equals_int(state.is_final, false);
for (int i = 0; i < MAX_N_TRANSITIONS; i++) {

assert_is_null(state.transitions[i]);
}

state_free(&state);
TEST_END;
}

int test_add_transition() {

TEST_BEGIN;
NFAState to;
state_init(&to, true);

int n_transitions = add_transition(&state, &to, 'a');
assert_equals_int(n_transitions, 1);

NFAStateList* list = get_transition(&state, 'a');
assert_is_not_null(list);

int size = NFAStateList_size(get_transition(&state, 'a'));
assert_equals_int(size, 1);

// Add another transition on the same character
NFAState to2;
state_init(&to2, false);

n_transitions = add_transition(&state, &to2, 'a');
assert_equals_int(n_transitions, 2);
size = NFAStateList_size(get_transition(&state, 'a'));
assert_equals_int(size, 2);

// Test invalid transitions
n_transitions = add_transition(NULL, &to, 'b');
assert_equals_int(n_transitions, -1);
n_transitions = add_transition(&state, NULL, 'b');
assert_equals_int(n_transitions, -1);
n_transitions = add_transition(&state, &to, '\n');
assert_equals_int(n_transitions, -1);

// Clean up transitions
for (int i = 0; i < MAX_N_TRANSITIONS; i++) {
if (state.transitions[i] != NULL) {
NFAStateList_free(state.transitions[i], NULL);
free(state.transitions[i]);
state.transitions[i] = NULL;
}
}

state_free(&state);
TEST_END;
}

int test_state_free() {
TEST_BEGIN;
NFAState to1, to2;
state_init(&state, false);
state_init(&to1, false);
state_init(&to2, false);

add_transition(&state, &to1, 'a');
add_transition(&state, &to2, 'b');

// This should free all allocated memory without crashing
state_free(&state);

// Verify that transitions are freed
for (int i = 0; i < MAX_N_TRANSITIONS; i++) {
assert_is_null(state.transitions[i]);
}

TEST_END;
}

Test tests[] = {
{.name="test_state_init", .func=test_state_init},
{.name="test_add_transition", .func=test_add_transition},
{.name="test_state_free", .func=test_state_free},
{.name=NULL, .func=NULL}
};

int main(int argc, char* argv[]) {
return default_main(&argv[1], argc - 1);
}

0 comments on commit 1afc7d5

Please sign in to comment.