Subject: [RFC PATCH v3 0/7] Introduce clar testing framework

From: Patrick Steinhardt <[email-masked]>
Date: Thu, 8 Aug 2024 07:38:08 +0200

Hi,

this is the third version of my RFC patch series that introduces the
clar testing framework into our unit tests. The intent is to not have to
hand-craft all features of a proper unit testing framework, while still
not painting us into a corner. As such, the clar itself is small and
extensible while still bringing some nice features to the table.

Changes compared to v2:

  - Fix a copy/paste error for the clar license. It's ISC, not LGPL.

  - Include "clar.h" via "clar/clar.h" such that we do not have to add
    "clar/" as in preprocessor include directive.

  - Adapt strvec unit test to use `cl_assert_equal_i()` instead of
    `cl_assert()`.

Thanks!

Patrick

Patrick Steinhardt (7):
  t: do not pass GIT_TEST_OPTS to unit tests with prove
  t: import the clar unit testing framework
  t/clar: fix whitespace errors
  t/clar: fix compatibility with NonStop
  Makefile: wire up the clar unit testing framework
  t/unit-tests: convert strvec tests to use clar
  t/unit-tests: convert ctype tests to use clar

 .gitignore                                 |   1 +
 Documentation/technical/unit-tests.txt     |   2 +
 Makefile                                   |  42 +-
 t/Makefile                                 |   4 +-
 t/run-test.sh                              |   2 +-
 t/unit-tests/.gitignore                    |   2 +
 t/unit-tests/clar-generate.awk             |  50 ++
 t/unit-tests/clar/.github/workflows/ci.yml |  23 +
 t/unit-tests/clar/COPYING                  |  15 +
 t/unit-tests/clar/README.md                | 329 ++++++++
 t/unit-tests/clar/clar.c                   | 842 +++++++++++++++++++++
 t/unit-tests/clar/clar.h                   | 173 +++++
 t/unit-tests/clar/clar/fixtures.h          |  50 ++
 t/unit-tests/clar/clar/fs.h                | 522 +++++++++++++
 t/unit-tests/clar/clar/print.h             | 211 ++++++
 t/unit-tests/clar/clar/sandbox.h           | 159 ++++
 t/unit-tests/clar/clar/summary.h           | 143 ++++
 t/unit-tests/clar/generate.py              | 266 +++++++
 t/unit-tests/clar/test/.gitignore          |   4 +
 t/unit-tests/clar/test/Makefile            |  39 +
 t/unit-tests/clar/test/clar_test.h         |  16 +
 t/unit-tests/clar/test/main.c              |  40 +
 t/unit-tests/clar/test/main.c.sample       |  27 +
 t/unit-tests/clar/test/resources/test/file |   1 +
 t/unit-tests/clar/test/sample.c            |  84 ++
 t/unit-tests/{t-ctype.c => ctype.c}        |  71 +-
 t/unit-tests/{t-strvec.c => strvec.c}      | 119 ++-
 t/unit-tests/unit-test.c                   |  17 +
 t/unit-tests/unit-test.h                   |   3 +
 29 files changed, 3159 insertions(+), 98 deletions(-)
 create mode 100644 t/unit-tests/clar-generate.awk
 create mode 100644 t/unit-tests/clar/.github/workflows/ci.yml
 create mode 100644 t/unit-tests/clar/COPYING
 create mode 100644 t/unit-tests/clar/README.md
 create mode 100644 t/unit-tests/clar/clar.c
 create mode 100644 t/unit-tests/clar/clar.h
 create mode 100644 t/unit-tests/clar/clar/fixtures.h
 create mode 100644 t/unit-tests/clar/clar/fs.h
 create mode 100644 t/unit-tests/clar/clar/print.h
 create mode 100644 t/unit-tests/clar/clar/sandbox.h
 create mode 100644 t/unit-tests/clar/clar/summary.h
 create mode 100755 t/unit-tests/clar/generate.py
 create mode 100644 t/unit-tests/clar/test/.gitignore
 create mode 100644 t/unit-tests/clar/test/Makefile
 create mode 100644 t/unit-tests/clar/test/clar_test.h
 create mode 100644 t/unit-tests/clar/test/main.c
 create mode 100644 t/unit-tests/clar/test/main.c.sample
 create mode 100644 t/unit-tests/clar/test/resources/test/file
 create mode 100644 t/unit-tests/clar/test/sample.c
 rename t/unit-tests/{t-ctype.c => ctype.c} (71%)
 rename t/unit-tests/{t-strvec.c => strvec.c} (54%)
 create mode 100644 t/unit-tests/unit-test.c
 create mode 100644 t/unit-tests/unit-test.h

Range-diff against v2:
1:  78a9cc1162 = 1:  78a9cc1162 t: do not pass GIT_TEST_OPTS to unit tests with prove
2:  6a88cf22a5 ! 2:  b6c066ee4e t: import the clar unit testing framework
    @@ Documentation/technical/unit-tests.txt: Framework,"<<license,License>>","<<vendo
      {criterion},{mit},{false},{partial},{true},{true},{true},{true},{true},{false},{true},19,1800
      {c-tap},{expat},{true},{partial},{partial},{true},{false},{true},{false},{false},{false},4,33
      {check},{lgpl},{false},{partial},{true},{true},{true},{false},{false},{false},{true},17,973
    -+{clar},{lgpl},{false},{partial},{true},{true},{true},{true},{false},{false},{true},1,192
    ++{clar},{isc},{false},{partial},{true},{true},{true},{true},{false},{false},{true},1,192
      |=====
      
      === Additional framework candidates
3:  a52ee59bf4 = 3:  35682b7686 t/clar: fix whitespace errors
4:  02fb86dfbc = 4:  7a76c21bcb t/clar: fix compatibility with NonStop
5:  848dc673c4 ! 5:  68b3c65951 Makefile: wire up the clar unit testing framework
    @@ Makefile: endif
      
      bin-wrappers/%: wrap-for-bin.sh
      	$(call mkdir_p_parent_template)
    -@@ Makefile: $(SP_OBJ): %.sp: %.c %.o
    - .PHONY: sparse
    - sparse: $(SP_OBJ)
    - 
    --EXCEPT_HDRS := $(GENERATED_H) unicode-width.h compat/% xdiff/% $(UNIT_TEST_DIR)/clar/% $(UNIT_TEST_DIR)/clar/clar/%
    -+EXCEPT_HDRS := $(GENERATED_H) unicode-width.h compat/% xdiff/% $(UNIT_TEST_DIR)/unit-test.h $(UNIT_TEST_DIR)/clar/% $(UNIT_TEST_DIR)/clar/clar/%
    - ifndef OPENSSL_SHA1
    - 	EXCEPT_HDRS += sha1/openssl.h
    - endif
     @@ Makefile: endif
      
      artifacts-tar:: $(ALL_COMMANDS_TO_INSTALL) $(SCRIPT_LIB) $(OTHER_PROGRAMS) \
    @@ Makefile: $(UNIT_TEST_PROGS): $(UNIT_TEST_BIN)/%$X: $(UNIT_TEST_DIR)/%.o \
     +$(UNIT_TEST_DIR)/clar.suite: $(UNIT_TEST_DIR)/clar-decls.h
     +	$(QUIET_GEN)awk -f $(UNIT_TEST_DIR)/clar-generate.awk $< >$(UNIT_TEST_DIR)/clar.suite
     +$(UNIT_TESTS_OBJS): $(UNIT_TEST_DIR)/clar-decls.h
    -+$(UNIT_TESTS_OBJS): EXTRA_CPPFLAGS = -I$(UNIT_TEST_DIR) -I$(UNIT_TEST_DIR)/clar
    ++$(UNIT_TESTS_OBJS): EXTRA_CPPFLAGS = -I$(UNIT_TEST_DIR)
     +$(UNIT_TESTS_PROG): $(UNIT_TEST_DIR)/clar.suite $(UNIT_TESTS_OBJS) $(GITLIBS) GIT-LDFLAGS
     +	$(call mkdir_p_parent_template)
     +	$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS)
    @@ t/unit-tests/unit-test.c (new)
      ## t/unit-tests/unit-test.h (new) ##
     @@
     +#include "git-compat-util.h"
    -+#include "clar.h"
    ++#include "clar/clar.h"
     +#include "clar-decls.h"
6:  578e657269 ! 6:  4a0888380e t/unit-tests: convert strvec tests to use clar
    @@ t/unit-tests/t-strvec.c => t/unit-tests/strvec.c
     -	check_uint(vec.nr, ==, 0);
     -	check_uint(vec.alloc, ==, 0);
     +	cl_assert_equal_p(vec.v, empty_strvec);
    -+	cl_assert(vec.nr == 0);
    -+	cl_assert(vec.alloc == 0);
    ++	cl_assert_equal_i(vec.nr, 0);
    ++	cl_assert_equal_i(vec.alloc, 0);
      }
      
     -static void t_dynamic_init(void)
    @@ t/unit-tests/t-strvec.c => t/unit-tests/strvec.c
     -	check_uint(vec.nr, ==, 0);
     -	check_uint(vec.alloc, ==, 0);
     +	cl_assert_equal_p(vec.v, empty_strvec);
    -+	cl_assert(vec.nr == 0);
    -+	cl_assert(vec.alloc == 0);
    ++	cl_assert_equal_i(vec.nr, 0);
    ++	cl_assert_equal_i(vec.alloc, 0);
      }
      
     -static void t_clear(void)
    @@ t/unit-tests/t-strvec.c => t/unit-tests/strvec.c
     -	check_uint(vec.nr, ==, 0);
     -	check_uint(vec.alloc, ==, 0);
     +	cl_assert_equal_p(vec.v, empty_strvec);
    -+	cl_assert(vec.nr == 0);
    -+	cl_assert(vec.alloc == 0);
    ++	cl_assert_equal_i(vec.nr, 0);
    ++	cl_assert_equal_i(vec.alloc, 0);
      }
      
     -static void t_push(void)
    @@ t/unit-tests/strvec.c: static void t_detach(void)
     -	check_uint(vec.nr, ==, 0);
     -	check_uint(vec.alloc, ==, 0);
     +	cl_assert_equal_p(vec.v, empty_strvec);
    -+	cl_assert(vec.nr == 0);
    -+	cl_assert(vec.alloc == 0);
    ++	cl_assert_equal_i(vec.nr, 0);
    ++	cl_assert_equal_i(vec.alloc, 0);
      
      	free((char *) detached[0]);
      	free(detached);
7:  238de33b93 = 7:  f423b01c05 t/unit-tests: convert ctype tests to use clar
-- 
2.46.0.dirty