Skip to content

Commit 4e701d8

Browse files
build: Add unit test target generation to cpp_library CMake util; Add tasks for building and running unit tests. (#26)
Co-authored-by: davidlion <[email protected]>
1 parent dde5732 commit 4e701d8

File tree

8 files changed

+133
-23
lines changed

8 files changed

+133
-23
lines changed

.github/workflows/unit-tests.yaml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,5 @@ jobs:
6161
command -v tar
6262
command -v task
6363
64-
# TODO: Change the task to run all unittests once any unittest is added. Until then we check
65-
# that building the project succeeds.
66-
- run: "task build:all"
64+
- name: "Run unit tests"
65+
run: "task test-all"

CMake/ystdlib-cpp-helpers.cmake

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
# Adds a c++20 interface library in the subdirectory NAME with the target NAME and alias
22
# NAMESPACE::NAME. Libraries with multiple levels of namespace nesting are currently not supported.
33
#
4+
# If `BUILD_TESTING` is ON, build the unit tests specific to the current library, and link this
5+
# library against the unified unit test target for the entire `ystdlib-cpp`.
6+
#
47
# @param NAME
58
# @param NAMESPACE
9+
# @parms TESTS_SOURCES
610
# @param [LIB_BUILD_INTERFACE="${PROJECT_SOURCE_DIR}/src"] The list of include paths for building
711
# the library and for external projects that link against it via the add_subdirectory() function.
812
function(cpp_library)
@@ -11,7 +15,10 @@ function(cpp_library)
1115
NAME
1216
NAMESPACE
1317
)
14-
set(multiValueArgs LIB_BUILD_INTERFACE)
18+
set(multiValueArgs
19+
TESTS_SOURCES
20+
LIB_BUILD_INTERFACE
21+
)
1522
cmake_parse_arguments(arg_cpp_lib "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
1623

1724
# TODO: Turn this into a function for handling other optional params that have default values.
@@ -24,6 +31,7 @@ function(cpp_library)
2431
set(arg_cpp_lib_LIB_BUILD_INTERFACE "${PROJECT_SOURCE_DIR}/src")
2532
endif()
2633

34+
# Build interface library
2735
add_library(${arg_cpp_lib_NAME} INTERFACE)
2836
target_include_directories(
2937
${arg_cpp_lib_NAME}
@@ -32,4 +40,32 @@ function(cpp_library)
3240
)
3341
target_compile_features(${arg_cpp_lib_NAME} INTERFACE cxx_std_20)
3442
add_library(${arg_cpp_lib_NAMESPACE}::${arg_cpp_lib_NAME} ALIAS ${arg_cpp_lib_NAME})
43+
44+
if(BUILD_TESTING)
45+
set(_UNIT_TEST_TARGET "unit-test-${arg_cpp_lib_NAME}")
46+
add_executable(${_UNIT_TEST_TARGET})
47+
target_sources(${_UNIT_TEST_TARGET} PRIVATE ${arg_cpp_lib_TESTS_SOURCES})
48+
target_link_libraries(
49+
${_UNIT_TEST_TARGET}
50+
PRIVATE
51+
Catch2::Catch2WithMain
52+
${arg_cpp_lib_NAMESPACE}::${arg_cpp_lib_NAME}
53+
)
54+
target_compile_features(${_UNIT_TEST_TARGET} PRIVATE cxx_std_20)
55+
set_property(
56+
TARGET
57+
${_UNIT_TEST_TARGET}
58+
PROPERTY
59+
RUNTIME_OUTPUT_DIRECTORY
60+
${CMAKE_BINARY_DIR}/testbin
61+
)
62+
63+
# Link against unified unit test
64+
target_sources(${UNIFIED_UNIT_TEST_TARGET} PRIVATE ${arg_cpp_lib_TESTS_SOURCES})
65+
target_link_libraries(
66+
${UNIFIED_UNIT_TEST_TARGET}
67+
PRIVATE
68+
${arg_cpp_lib_NAMESPACE}::${arg_cpp_lib_NAME}
69+
)
70+
endif()
3571
endfunction()

CMakeLists.txt

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,33 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS
1111
FORCE
1212
)
1313

14-
find_package(Catch2 3.8.0 REQUIRED)
15-
if(Catch2_FOUND)
16-
message(STATUS "Found Catch2 ${Catch2_VERSION}.")
17-
else()
18-
message(FATAL_ERROR "Could not find libraries for Catch2.")
19-
endif()
14+
option(BUILD_TESTING "If ON, unit tests will be built." ON)
2015

2116
# Import CMake helper functions
2217
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/CMake)
18+
19+
if(BUILD_TESTING)
20+
find_package(Catch2 3.8.0 REQUIRED)
21+
if(Catch2_FOUND)
22+
message(STATUS "Found Catch2 ${Catch2_VERSION}.")
23+
else()
24+
message(FATAL_ERROR "Could not find libraries for Catch2.")
25+
endif()
26+
27+
# Set up the unified unit test target
28+
set(UNIFIED_UNIT_TEST_TARGET "unit-test-all")
29+
add_executable(${UNIFIED_UNIT_TEST_TARGET})
30+
target_link_libraries(${UNIFIED_UNIT_TEST_TARGET} PRIVATE Catch2::Catch2WithMain)
31+
target_compile_features(${UNIFIED_UNIT_TEST_TARGET} PRIVATE cxx_std_20)
32+
set_property(
33+
TARGET
34+
${UNIFIED_UNIT_TEST_TARGET}
35+
PROPERTY
36+
RUNTIME_OUTPUT_DIRECTORY
37+
${CMAKE_BINARY_DIR}/testbin
38+
)
39+
endif()
40+
2341
include(ystdlib-cpp-helpers)
2442

2543
add_subdirectory(src/ystdlib)
26-
27-
add_executable(unitTest)
28-
target_sources(unitTest PRIVATE src/main.cpp)
29-
target_link_libraries(
30-
unitTest
31-
PRIVATE
32-
ystdlib::testlib
33-
Catch2::Catch2WithMain
34-
)
35-
target_compile_features(unitTest PRIVATE cxx_std_20)

README.md

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,32 @@ git submodule update --init --recursive
2828
```
2929

3030
## Building
31-
To build all targets in `ystdlib-cpp`:
31+
To build all targets:
3232
```shell
3333
task build:all
3434
```
3535

36+
To build an executable containing all unit tests:
37+
```shell
38+
task build:unit-test-all
39+
```
40+
41+
To build an executable containing a single library's unit tests:
42+
```shell
43+
task build:unit-test-<lib_name>
44+
```
45+
46+
## Testing
47+
To build and run all unit tests:
48+
```shell
49+
task test-all
50+
```
51+
52+
To build and run unit tests for a specific library:
53+
```shell
54+
task test-<lib_name>
55+
```
56+
3657
## Linting
3758
Before submitting a pull request, ensure you’ve run the linting commands below and have fixed all
3859
violations and suppressed all warnings.

src/ystdlib/testlib/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
cpp_library(NAME testlib NAMESPACE ystdlib)
1+
cpp_library(NAME testlib NAMESPACE ystdlib TESTS_SOURCES test-hello.cpp)
File renamed without changes.

taskfile.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ vars:
1010
G_BUILD_DIR: "{{.ROOT_DIR}}/build"
1111
G_CPP_SRC_DIR: "{{.ROOT_DIR}}/src"
1212
G_DEPS_DIR: "{{.G_BUILD_DIR}}/deps"
13+
G_TEST_BIN_DIR: "{{.G_BUILD_DIR}}/testbin"
14+
G_TEST_TARGET_SUFFIXES:
15+
- "all"
16+
- "testlib"
1317

1418
tasks:
1519
clean:
@@ -23,3 +27,13 @@ tasks:
2327
run: "once"
2428
cmds:
2529
- "mkdir -p '{{.G_BUILD_DIR}}'"
30+
31+
test-*:
32+
desc: "Runs unit tests for the specified test target."
33+
vars:
34+
TEST_TARGET: >-
35+
{{printf "unit-test-%s" (index .MATCH 0)}}
36+
deps:
37+
- "build:{{.TEST_TARGET}}"
38+
cmds:
39+
- "{{.G_TEST_BIN_DIR}}/{{.TEST_TARGET}}"

taskfiles/build.yaml

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,46 @@ vars:
88

99
tasks:
1010
all:
11-
desc: "Builds ystdlib-cpp."
11+
desc: "Builds all of ystdlib-cpp."
1212
deps:
1313
- "init"
1414
cmds:
1515
- task: ":utils:cmake-build"
1616
vars:
1717
BUILD_DIR: "{{.G_BUILD_DIR}}"
1818

19+
target-*:
20+
desc: "Builds a CMake target."
21+
vars:
22+
TARGET: "{{index .MATCH 0}}"
23+
deps:
24+
- "init"
25+
cmds:
26+
- task: ":utils:cmake-build"
27+
vars:
28+
BUILD_DIR: "{{.G_BUILD_DIR}}"
29+
TARGETS:
30+
- "{{.TARGET}}"
31+
32+
unit-test-*:
33+
desc: "Builds the specified unit test target."
34+
vars:
35+
TARGET_SUFFIX: >-
36+
{{index .MATCH 0}}
37+
TARGET_NAME: >-
38+
{{printf "unit-test-%s" .TARGET_SUFFIX}}
39+
preconditions:
40+
- sh: >-
41+
{{has .TARGET_SUFFIX .G_TEST_TARGET_SUFFIXES}}
42+
msg: |-
43+
{{.TARGET_NAME}} is not a valid unit test target!
44+
List of unit test targets:
45+
{{- range .G_TEST_TARGET_SUFFIXES }}
46+
unit-test-{{.}}
47+
{{- end}}
48+
cmds:
49+
- task: "target-{{.TARGET_NAME}}"
50+
1951
clean:
2052
desc: "Removes all built artifacts."
2153
deps:

0 commit comments

Comments
 (0)