Skip to content

Commit

Permalink
t/unit-tests: convert strvec tests to use clar
Browse files Browse the repository at this point in the history
Convert the strvec tests to use the new clar unit testing framework.
This is a first test balloon that demonstrates how the testing infra for
clar-based tests looks like.

The tests are part of the "t/unit-tests/bin/unit-tests" binary. When
running that binary, it generates TAP output:

    # ./t/unit-tests/bin/unit-tests
    TAP version 13
    # start of suite 1: strvec
    ok 1 - strvec::init
    ok 2 - strvec::dynamic_init
    ok 3 - strvec::clear
    ok 4 - strvec::push
    ok 5 - strvec::pushft_pushf
    ok 6 - strvec::pushl
    ok 7 - strvec::pushv
    ok 8 - strvec::replace_at_head
    ok 9 - strvec::replace_at_tail
    ok 10 - strvec::replace_in_between
    ok 11 - strvec::replace_with_substring
    ok 12 - strvec::remove_at_head
    ok 13 - strvec::remove_at_tail
    ok 14 - strvec::remove_in_between
    ok 15 - strvec::pop_empty_array
    ok 16 - strvec::pop_non_empty_array
    ok 17 - strvec::split_empty_string
    ok 18 - strvec::split_single_item
    ok 19 - strvec::split_multiple_items
    ok 20 - strvec::split_whitespace_only
    ok 21 - strvec::split_multiple_consecutive_whitespaces
    ok 22 - strvec::detach
    1..22

The binary also supports some parameters that allow us to run only a
subset of unit tests or alter the output:

    $ ./t/unit-tests/bin/unit-tests -h
    Usage: ./t/unit-tests/bin/unit-tests [options]

    Options:
      -sname        Run only the suite with `name` (can go to individual test name)
      -iname        Include the suite with `name`
      -xname        Exclude the suite with `name`
      -v            Increase verbosity (show suite names)
      -q            Only report tests that had an error
      -Q            Quit as soon as a test fails
      -t            Display results in tap format
      -l            Print suite names
      -r[filename]  Write summary file (to the optional filename)

Furthermore, running `make unit-tests` runs the binary along with all
the other unit tests we have.

Signed-off-by: Patrick Steinhardt <[email protected]>
  • Loading branch information
pks-t committed Aug 20, 2024
1 parent 464f941 commit bce47fc
Show file tree
Hide file tree
Showing 3 changed files with 223 additions and 212 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -1336,6 +1336,7 @@ THIRD_PARTY_SOURCES += sha1dc/%
THIRD_PARTY_SOURCES += $(UNIT_TEST_DIR)/clar/%
THIRD_PARTY_SOURCES += $(UNIT_TEST_DIR)/clar/clar/%

UNIT_TESTS_SUITES += strvec
UNIT_TESTS_PROG = $(UNIT_TEST_BIN)/unit-tests$(X)
UNIT_TESTS_OBJS = $(patsubst %,$(UNIT_TEST_DIR)/%.o,$(UNIT_TESTS_SUITES))
UNIT_TESTS_OBJS += $(UNIT_TEST_DIR)/clar/clar.o
Expand All @@ -1356,7 +1357,6 @@ UNIT_TEST_PROGRAMS += t-reftable-record
UNIT_TEST_PROGRAMS += t-reftable-tree
UNIT_TEST_PROGRAMS += t-strbuf
UNIT_TEST_PROGRAMS += t-strcmp-offset
UNIT_TEST_PROGRAMS += t-strvec
UNIT_TEST_PROGRAMS += t-trailer
UNIT_TEST_PROGS = $(patsubst %,$(UNIT_TEST_BIN)/%$X,$(UNIT_TEST_PROGRAMS))
UNIT_TEST_OBJS = $(patsubst %,$(UNIT_TEST_DIR)/%.o,$(UNIT_TEST_PROGRAMS))
Expand Down
222 changes: 222 additions & 0 deletions t/unit-tests/strvec.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
#include "unit-test.h"
#include "strbuf.h"
#include "strvec.h"

#define check_strvec(vec, ...) \
do { \
const char *expect[] = { __VA_ARGS__ }; \
cl_assert(ARRAY_SIZE(expect) > 0); \
cl_assert_equal_p(expect[ARRAY_SIZE(expect) - 1], NULL); \
cl_assert_equal_i((vec)->nr, ARRAY_SIZE(expect) - 1); \
cl_assert((vec)->nr <= (vec)->alloc); \
for (size_t i = 0; i < ARRAY_SIZE(expect); i++) \
cl_assert_equal_s((vec)->v[i], expect[i]); \
} while (0)

void test_strvec__init(void)
{
struct strvec vec = STRVEC_INIT;
cl_assert_equal_p(vec.v, empty_strvec);
cl_assert_equal_i(vec.nr, 0);
cl_assert_equal_i(vec.alloc, 0);
}

void test_strvec__dynamic_init(void)
{
struct strvec vec;
strvec_init(&vec);
cl_assert_equal_p(vec.v, empty_strvec);
cl_assert_equal_i(vec.nr, 0);
cl_assert_equal_i(vec.alloc, 0);
}

void test_strvec__clear(void)
{
struct strvec vec = STRVEC_INIT;
strvec_push(&vec, "foo");
strvec_clear(&vec);
cl_assert_equal_p(vec.v, empty_strvec);
cl_assert_equal_i(vec.nr, 0);
cl_assert_equal_i(vec.alloc, 0);
}

void test_strvec__push(void)
{
struct strvec vec = STRVEC_INIT;

strvec_push(&vec, "foo");
check_strvec(&vec, "foo", NULL);

strvec_push(&vec, "bar");
check_strvec(&vec, "foo", "bar", NULL);

strvec_clear(&vec);
}

void test_strvec__pushf(void)
{
struct strvec vec = STRVEC_INIT;
strvec_pushf(&vec, "foo: %d", 1);
check_strvec(&vec, "foo: 1", NULL);
strvec_clear(&vec);
}

void test_strvec__pushl(void)
{
struct strvec vec = STRVEC_INIT;
strvec_pushl(&vec, "foo", "bar", "baz", NULL);
check_strvec(&vec, "foo", "bar", "baz", NULL);
strvec_clear(&vec);
}

void test_strvec__pushv(void)
{
const char *strings[] = {
"foo", "bar", "baz", NULL,
};
struct strvec vec = STRVEC_INIT;

strvec_pushv(&vec, strings);
check_strvec(&vec, "foo", "bar", "baz", NULL);

strvec_clear(&vec);
}

void test_strvec__replace_at_head(void)
{
struct strvec vec = STRVEC_INIT;
strvec_pushl(&vec, "foo", "bar", "baz", NULL);
strvec_replace(&vec, 0, "replaced");
check_strvec(&vec, "replaced", "bar", "baz", NULL);
strvec_clear(&vec);
}

void test_strvec__replace_at_tail(void)
{
struct strvec vec = STRVEC_INIT;
strvec_pushl(&vec, "foo", "bar", "baz", NULL);
strvec_replace(&vec, 2, "replaced");
check_strvec(&vec, "foo", "bar", "replaced", NULL);
strvec_clear(&vec);
}

void test_strvec__replace_in_between(void)
{
struct strvec vec = STRVEC_INIT;
strvec_pushl(&vec, "foo", "bar", "baz", NULL);
strvec_replace(&vec, 1, "replaced");
check_strvec(&vec, "foo", "replaced", "baz", NULL);
strvec_clear(&vec);
}

void test_strvec__replace_with_substring(void)
{
struct strvec vec = STRVEC_INIT;
strvec_pushl(&vec, "foo", NULL);
strvec_replace(&vec, 0, vec.v[0] + 1);
check_strvec(&vec, "oo", NULL);
strvec_clear(&vec);
}

void test_strvec__remove_at_head(void)
{
struct strvec vec = STRVEC_INIT;
strvec_pushl(&vec, "foo", "bar", "baz", NULL);
strvec_remove(&vec, 0);
check_strvec(&vec, "bar", "baz", NULL);
strvec_clear(&vec);
}

void test_strvec__remove_at_tail(void)
{
struct strvec vec = STRVEC_INIT;
strvec_pushl(&vec, "foo", "bar", "baz", NULL);
strvec_remove(&vec, 2);
check_strvec(&vec, "foo", "bar", NULL);
strvec_clear(&vec);
}

void test_strvec__remove_in_between(void)
{
struct strvec vec = STRVEC_INIT;
strvec_pushl(&vec, "foo", "bar", "baz", NULL);
strvec_remove(&vec, 1);
check_strvec(&vec, "foo", "baz", NULL);
strvec_clear(&vec);
}

void test_strvec__pop_empty_array(void)
{
struct strvec vec = STRVEC_INIT;
strvec_pop(&vec);
check_strvec(&vec, NULL);
strvec_clear(&vec);
}

void test_strvec__pop_non_empty_array(void)
{
struct strvec vec = STRVEC_INIT;
strvec_pushl(&vec, "foo", "bar", "baz", NULL);
strvec_pop(&vec);
check_strvec(&vec, "foo", "bar", NULL);
strvec_clear(&vec);
}

void test_strvec__split_empty_string(void)
{
struct strvec vec = STRVEC_INIT;
strvec_split(&vec, "");
check_strvec(&vec, NULL);
strvec_clear(&vec);
}

void test_strvec__split_single_item(void)
{
struct strvec vec = STRVEC_INIT;
strvec_split(&vec, "foo");
check_strvec(&vec, "foo", NULL);
strvec_clear(&vec);
}

void test_strvec__split_multiple_items(void)
{
struct strvec vec = STRVEC_INIT;
strvec_split(&vec, "foo bar baz");
check_strvec(&vec, "foo", "bar", "baz", NULL);
strvec_clear(&vec);
}

void test_strvec__split_whitespace_only(void)
{
struct strvec vec = STRVEC_INIT;
strvec_split(&vec, " \t\n");
check_strvec(&vec, NULL);
strvec_clear(&vec);
}

void test_strvec__split_multiple_consecutive_whitespaces(void)
{
struct strvec vec = STRVEC_INIT;
strvec_split(&vec, "foo\n\t bar");
check_strvec(&vec, "foo", "bar", NULL);
strvec_clear(&vec);
}

void test_strvec__detach(void)
{
struct strvec vec = STRVEC_INIT;
const char **detached;

strvec_push(&vec, "foo");

detached = strvec_detach(&vec);
cl_assert_equal_s(detached[0], "foo");
cl_assert_equal_p(detached[1], NULL);

cl_assert_equal_p(vec.v, empty_strvec);
cl_assert_equal_i(vec.nr, 0);
cl_assert_equal_i(vec.alloc, 0);

free((char *) detached[0]);
free(detached);
}
Loading

0 comments on commit bce47fc

Please sign in to comment.