Read-only mirrors. Development, issues and pull requests are on GitHub.

summaryrefslogtreecommitdiffhomepage
path: root/tests/TestScripts/DiscoverTests/TestPrepareCommandFragment.cmake
diff options
context:
space:
mode:
authorMartin Hořeňovský2026-08-10 11:45:08 +0200
committerMartin Hořeňovský2026-08-10 11:53:22 +0200
commit97ec4e8e2e4a86719701746d1cb2426f16292ff8 (patch)
treeef8f99ce2dd607f360c3ae281c6b55786ff79596 /tests/TestScripts/DiscoverTests/TestPrepareCommandFragment.cmake
parent0136276e15e140cc332630dc83e2a77b796c5fa7 (diff)
downloadcatch3-97ec4e8e2e4a86719701746d1cb2426f16292ff8.tar.gz
catch_discover_tests: Escape test-invariant parts of CTest script only once
Previously, the `catch_discover_tests` would prepare the entire CTest command (e.g. `add_test(...)` or `set_tests_properties(...)`) first, and then escape it when finished. However, this caused lot of the command args to be escaped over and over again (e.g. executable name or Catch2's reporter args), for no reason, as they were always the same, and thus their escaping was always the same. Until recently, the performance overhead didn't matter as there were many spots which had quadratic runtime in number of tests. However, the recent refactorings fixed these, and this commit now improves the throughput by 10-20%. Also extended the benchmarked COUNTS in `benchmark_discovery.py`, because the performance is now good enough that it is reasonable to benchmark 16k tests.
Diffstat (limited to 'tests/TestScripts/DiscoverTests/TestPrepareCommandFragment.cmake')
-rw-r--r--tests/TestScripts/DiscoverTests/TestPrepareCommandFragment.cmake61
1 files changed, 61 insertions, 0 deletions
diff --git a/tests/TestScripts/DiscoverTests/TestPrepareCommandFragment.cmake b/tests/TestScripts/DiscoverTests/TestPrepareCommandFragment.cmake
new file mode 100644
index 00000000..cfcaf0d1
--- /dev/null
+++ b/tests/TestScripts/DiscoverTests/TestPrepareCommandFragment.cmake
@@ -0,0 +1,61 @@
+# SPDX-License-Identifier: BSL-1.0
+
+# Unit tests for `prepare_command_fragment` helper in `extras/CatchAddTests.cmake`.
+#
+# Yes, we are at the stage where the script helpers need unit tests.
+#
+# Run as
+# cmake -DCATCH_ADD_TESTS_SCRIPT=/path/to/extras/CatchAddTests.cmake \
+# -P TestPrepareCommandFragment.cmake
+
+
+cmake_minimum_required(VERSION 3.19)
+
+if(NOT DEFINED CATCH_ADD_TESTS_SCRIPT)
+ message(FATAL_ERROR "Missing argument `CATCH_ADD_TESTS_SCRIPT`")
+endif()
+
+if(NOT EXISTS "${CATCH_ADD_TESTS_SCRIPT}")
+ message(FATAL_ERROR "Cannot find CatchAddTests.cmake at '${CATCH_ADD_TESTS_SCRIPT}'")
+endif()
+
+# Pull in the helper functions. Without `TEST_EXECUTABLE` being defined,
+# `catch_discover_tests_impl` is not called.
+include("${CATCH_ADD_TESTS_SCRIPT}")
+
+set(_failures 0)
+
+function(expect_equal description actual expected)
+ if(actual STREQUAL expected)
+ message(" [PASS] ${description}")
+ else()
+ message(" [FAIL] ${description}")
+ message(" expected: [${expected}]")
+ message(" actual: [${actual}]")
+ math(EXPR _n "${_failures} + 1")
+ set(_failures "${_n}" PARENT_SCOPE)
+ endif()
+endfunction()
+
+prepare_command_fragment(test_fragment SimpleName /path/to/tests)
+expect_equal("Simple arg, no quotes" "${test_fragment}" " SimpleName /path/to/tests")
+
+prepare_command_fragment(test_fragment "Name with spaces")
+expect_equal("Spaces in arg, needs quotes" "${test_fragment}" " [==[Name with spaces]==]")
+
+prepare_command_fragment(test_fragment Foo PROPERTIES LABELS "tagA\;tagB\;tagC")
+expect_equal("semicolons in argument are kept and quoted"
+ "${test_fragment}" " Foo PROPERTIES LABELS [==[tagA\;tagB\;tagC]==]")
+
+set(test_fragment "PRE-EXISTING")
+prepare_command_fragment(test_fragment Foo PROPERTIES BAR baz)
+expect_equal("out var does no accumulate commands"
+ "${test_fragment}" " Foo PROPERTIES BAR baz")
+
+
+
+if(_failures GREATER 0)
+ message(FATAL_ERROR "${_failures} prepare_command_fragment test(s) failed")
+else()
+ message(STATUS "All prepare_command_fragment tests passed")
+endif()