[PATCH v2 2/6] unit-tests: add for_test

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The macro TEST only allows defining a test that consists of a single
expression.  Add a new macro, for_test, which provides a way to define
unit tests that are made up of one or more statements.

for_test allows defining self-contained tests en bloc, a bit like
test_expect_success does for regular tests.  It acts like a for loop
that runs at most once; the test body is executed if test_skip_all()
had not been called before.

Helped-by: Phillip Wood <phillip.wood123@xxxxxxxxx>
Signed-off-by: René Scharfe <l.s.r@xxxxxx>
---
 .clang-format               |  2 ++
 t/helper/test-example-tap.c | 33 +++++++++++++++++++++++++++++++++
 t/t0080/expect              | 35 ++++++++++++++++++++++++++++++++++-
 t/unit-tests/test-lib.h     | 19 +++++++++++++++++++
 4 files changed, 88 insertions(+), 1 deletion(-)

diff --git a/.clang-format b/.clang-format
index 6408251577..863dc87dfc 100644
--- a/.clang-format
+++ b/.clang-format
@@ -151,6 +151,7 @@ Cpp11BracedListStyle: false
 # function calls. Taken from:
 #   git grep -h '^#define [^[:space:]]*for_\?each[^[:space:]]*(' |
 #   sed "s/^#define /  - '/; s/(.*$/'/" | sort | uniq
+# Added for_test from t/unit-tests/test-lib.h manually as a special case.
 ForEachMacros:
   - 'for_each_builtin'
   - 'for_each_string_list_item'
@@ -168,6 +169,7 @@ ForEachMacros:
   - 'strintmap_for_each_entry'
   - 'strmap_for_each_entry'
   - 'strset_for_each_entry'
+  - 'for_test'

 # The maximum number of consecutive empty lines to keep.
 MaxEmptyLinesToKeep: 1
diff --git a/t/helper/test-example-tap.c b/t/helper/test-example-tap.c
index d072ad559f..51d5e6e75b 100644
--- a/t/helper/test-example-tap.c
+++ b/t/helper/test-example-tap.c
@@ -92,5 +92,38 @@ int cmd__example_tap(int argc, const char **argv)
 	test_res = TEST(t_empty(), "test with no checks");
 	TEST(check_int(test_res, ==, 0), "test with no checks returns 0");

+	for_test ("for_test passing test")
+		check_int(1, ==, 1);
+	for_test ("for_test failing test")
+		check_int(1, ==, 2);
+	for_test ("for_test passing TEST_TODO()")
+		TEST_TODO(check(0));
+	for_test ("for_test failing TEST_TODO()")
+		TEST_TODO(check(1));
+	for_test ("for_test test_skip()") {
+		check(0);
+		test_skip("missing prerequisite");
+		check(1);
+	}
+	for_test ("for_test test_skip() inside TEST_TODO()")
+		TEST_TODO((test_skip("missing prerequisite"), 1));
+	for_test ("for_test TEST_TODO() after failing check") {
+		check(0);
+		TEST_TODO(check(0));
+	}
+	for_test ("for_test failing check after TEST_TODO()") {
+		check(1);
+		TEST_TODO(check(0));
+		check(0);
+	}
+	for_test ("for_test messages from failing string and char comparison") {
+		check_str("\thello\\", "there\"\n");
+		check_str("NULL", NULL);
+		check_char('a', ==, '\n');
+		check_char('\\', ==, '\'');
+	}
+	for_test ("for_test test with no checks")
+		; /* nothing */
+
 	return test_done();
 }
diff --git a/t/t0080/expect b/t/t0080/expect
index 0cfa0dc6d8..583f41b8c9 100644
--- a/t/t0080/expect
+++ b/t/t0080/expect
@@ -40,4 +40,37 @@ not ok 17 - messages from failing string and char comparison
 # BUG: test has no checks at t/helper/test-example-tap.c:92
 not ok 18 - test with no checks
 ok 19 - test with no checks returns 0
-1..19
+ok 20 - for_test passing test
+# check "1 == 2" failed at t/helper/test-example-tap.c:98
+#    left: 1
+#   right: 2
+not ok 21 - for_test failing test
+not ok 22 - for_test passing TEST_TODO() # TODO
+# todo check 'check(1)' succeeded at t/helper/test-example-tap.c:102
+not ok 23 - for_test failing TEST_TODO()
+# check "0" failed at t/helper/test-example-tap.c:104
+# skipping test - missing prerequisite
+# skipping check '1' at t/helper/test-example-tap.c:106
+ok 24 - for_test test_skip() # SKIP
+# skipping test - missing prerequisite
+ok 25 - for_test test_skip() inside TEST_TODO() # SKIP
+# check "0" failed at t/helper/test-example-tap.c:111
+not ok 26 - for_test TEST_TODO() after failing check
+# check "0" failed at t/helper/test-example-tap.c:117
+not ok 27 - for_test failing check after TEST_TODO()
+# check "!strcmp("\thello\\", "there\"\n")" failed at t/helper/test-example-tap.c:120
+#    left: "\011hello\\"
+#   right: "there\"\012"
+# check "!strcmp("NULL", NULL)" failed at t/helper/test-example-tap.c:121
+#    left: "NULL"
+#   right: NULL
+# check "'a' == '\n'" failed at t/helper/test-example-tap.c:122
+#    left: 'a'
+#   right: '\012'
+# check "'\\' == '\''" failed at t/helper/test-example-tap.c:123
+#    left: '\\'
+#   right: '\''
+not ok 28 - for_test messages from failing string and char comparison
+# BUG: test has no checks at t/helper/test-example-tap.c:125
+not ok 29 - for_test test with no checks
+1..29
diff --git a/t/unit-tests/test-lib.h b/t/unit-tests/test-lib.h
index 2de6d715d5..12afd47ac9 100644
--- a/t/unit-tests/test-lib.h
+++ b/t/unit-tests/test-lib.h
@@ -14,6 +14,25 @@
 	test__run_end(test__run_begin() ? 0 : (t, 1),	\
 		      TEST_LOCATION(),  __VA_ARGS__)

+/*
+ * Run a test unless test_skip_all() has been called.  Acts like a for
+ * loop that runs at most once, with the test description between the
+ * parentheses and the test body as a statement or block after them.
+ * The description for each test should be unique.  E.g.:
+ *
+ *  for_test ("something else %d %d", arg1, arg2) {
+ *          prepare();
+ *          test_something_else(arg1, arg2);
+ *          cleanup();
+ *  }
+ */
+#define for_test(...)							\
+	for (int for_test_running_ = test__run_begin() ?		\
+		(test__run_end(0, TEST_LOCATION(), __VA_ARGS__), 0) : 1;\
+	     for_test_running_;						\
+	     test__run_end(1, TEST_LOCATION(), __VA_ARGS__),		\
+		for_test_running_ = 0)
+
 /*
  * Print a test plan, should be called before any tests. If the number
  * of tests is not known in advance test_done() will automatically
--
2.45.2





[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux