├── .github ├── dependabot.yml └── workflows │ └── ci.yml ├── .gitignore ├── CMakeLists.txt ├── LICENSE ├── README.md ├── app ├── CMakeLists.txt └── adder_app.cpp ├── cmake ├── Catch.cmake └── CatchAddTests.cmake ├── ext └── catch2 │ └── catch.hpp ├── include └── adder │ └── adder.hpp ├── src ├── CMakeLists.txt └── adder.cpp └── tests ├── CMakeLists.txt ├── adder_t.cpp └── tests.cpp /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: 'github-actions' 4 | directory: '/' 5 | schedule: 6 | interval: 'monthly' 7 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | branches: [ main ] 8 | 9 | jobs: 10 | build-and-test: 11 | name: Testing on ${{ matrix.os }} 12 | runs-on: ${{ matrix.os }} 13 | strategy: 14 | matrix: 15 | os: [ubuntu-latest, macos-latest, windows-latest] 16 | 17 | steps: 18 | - uses: actions/checkout@v4 19 | 20 | - name: make build directory 21 | run: cmake -E make_directory ${{runner.workspace}}/build 22 | 23 | - name: configure cmake 24 | shell: bash 25 | working-directory: ${{runner.workspace}}/build 26 | run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=Debug 27 | 28 | - name: build 29 | shell: bash 30 | working-directory: ${{runner.workspace}}/build 31 | run: cmake --build . 32 | 33 | - name: run tests 34 | shell: bash 35 | working-directory: ${{runner.workspace}}/build 36 | run: ctest --output-on-failure 37 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8.2) 2 | 3 | # Set a name and a version number for your project: 4 | project(cpp-project-template VERSION 0.0.1 LANGUAGES CXX) 5 | 6 | # this needs to be in the top level CMakeLists.txt to enable tests 7 | include(CTest) 8 | 9 | # compile the library 10 | add_subdirectory(src) 11 | 12 | # compile the tests 13 | add_subdirectory(tests) 14 | 15 | # compile the application 16 | add_subdirectory(app) 17 | 18 | # optionally add doxygen target to generate documentation 19 | option(BUILD_DOCS "Enable building of documentation (requires Doxygen)" OFF) 20 | if(BUILD_DOCS) 21 | find_package(Doxygen REQUIRED) 22 | set(DOXYGEN_EXCLUDE_PATTERNS "${CMAKE_SOURCE_DIR}/ext/*") 23 | doxygen_add_docs(doxygen 24 | ${CMAKE_SOURCE_DIR} 25 | WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 26 | ) 27 | endif() -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 SSC 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # C++ Project Template 2 | 3 | A simple template repository to start a new C++ project using CMake. 4 | 5 | Click on the green [`Use this template`](https://github.com/ssciwr/cpp-project-template/generate) button to get started. 6 | 7 | If you are looking for more advanced features (such as Python bindings or integration with sites like ReadTheDocs, codecov, sonarcloud or PyPI) 8 | take a look at our [C++ Project Cookiecutter](https://github.com/ssciwr/cookiecutter-cpp-project) 9 | 10 | ## Contents 11 | 12 | This example project contains the `adder` library, 13 | an application `adder_app` which uses this library, 14 | and a test-suite which tests the library. 15 | 16 | Any pull-requests or commits to the repository trigger GitHub Actions, 17 | which will compile the code and run the tests. 18 | 19 | Project structure: 20 | 21 | - [src](src) 22 | - the `adder` library source code 23 | - this is where the meat of the project is: the implementation 24 | - [include/adder](include/adder) 25 | - the `adder` library headers 26 | - the public interface of the library 27 | - [app](app) 28 | - the application which uses the `adder` library 29 | - [tests](tests) 30 | - the test code 31 | - each `x.cpp` file has a corresponding `x_t.cpp` file here with tests 32 | - [ext](ext) 33 | - external libraries, e.g. Catch2 testing framework 34 | - [.github/workflows/ci.yml](.github/workflows/ci.yml) 35 | - the GitHub Actions configuration 36 | 37 | ## Compiling 38 | 39 | To compile the project and run the tests: 40 | 41 | ``` 42 | mkdir build 43 | cd build 44 | cmake .. -DCMAKE_BUILD_TYPE=Release 45 | make 46 | make test 47 | ``` 48 | 49 | ## Documentation 50 | 51 | If you have Doxygen installed you can also build the documentation by enabling the `BUILD_DOCS` CMake option, and then running `make doxygen`: 52 | 53 | ``` 54 | cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_DOCS=ON 55 | make doxygen 56 | ``` 57 | 58 | This will generate the documentation in the `html` folder. -------------------------------------------------------------------------------- /app/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(adder_app adder_app.cpp) 2 | target_link_libraries(adder_app PRIVATE adder) 3 | -------------------------------------------------------------------------------- /app/adder_app.cpp: -------------------------------------------------------------------------------- 1 | #include "adder/adder.hpp" 2 | #include 3 | 4 | int main(){ 5 | int result = adder::add_one(1); 6 | std::cout << "1 + 1 = " << result << std::endl; 7 | } 8 | -------------------------------------------------------------------------------- /cmake/Catch.cmake: -------------------------------------------------------------------------------- 1 | # Distributed under the OSI-approved BSD 3-Clause License. See accompanying 2 | # file Copyright.txt or https://cmake.org/licensing for details. 3 | 4 | #[=======================================================================[.rst: 5 | Catch 6 | ----- 7 | 8 | This module defines a function to help use the Catch test framework. 9 | 10 | The :command:`catch_discover_tests` discovers tests by asking the compiled test 11 | executable to enumerate its tests. This does not require CMake to be re-run 12 | when tests change. However, it may not work in a cross-compiling environment, 13 | and setting test properties is less convenient. 14 | 15 | This command is intended to replace use of :command:`add_test` to register 16 | tests, and will create a separate CTest test for each Catch test case. Note 17 | that this is in some cases less efficient, as common set-up and tear-down logic 18 | cannot be shared by multiple test cases executing in the same instance. 19 | However, it provides more fine-grained pass/fail information to CTest, which is 20 | usually considered as more beneficial. By default, the CTest test name is the 21 | same as the Catch name; see also ``TEST_PREFIX`` and ``TEST_SUFFIX``. 22 | 23 | .. command:: catch_discover_tests 24 | 25 | Automatically add tests with CTest by querying the compiled test executable 26 | for available tests:: 27 | 28 | catch_discover_tests(target 29 | [TEST_SPEC arg1...] 30 | [EXTRA_ARGS arg1...] 31 | [WORKING_DIRECTORY dir] 32 | [TEST_PREFIX prefix] 33 | [TEST_SUFFIX suffix] 34 | [PROPERTIES name1 value1...] 35 | [TEST_LIST var] 36 | [REPORTER reporter] 37 | [OUTPUT_DIR dir] 38 | [OUTPUT_PREFIX prefix} 39 | [OUTPUT_SUFFIX suffix] 40 | ) 41 | 42 | ``catch_discover_tests`` sets up a post-build command on the test executable 43 | that generates the list of tests by parsing the output from running the test 44 | with the ``--list-test-names-only`` argument. This ensures that the full 45 | list of tests is obtained. Since test discovery occurs at build time, it is 46 | not necessary to re-run CMake when the list of tests changes. 47 | However, it requires that :prop_tgt:`CROSSCOMPILING_EMULATOR` is properly set 48 | in order to function in a cross-compiling environment. 49 | 50 | Additionally, setting properties on tests is somewhat less convenient, since 51 | the tests are not available at CMake time. Additional test properties may be 52 | assigned to the set of tests as a whole using the ``PROPERTIES`` option. If 53 | more fine-grained test control is needed, custom content may be provided 54 | through an external CTest script using the :prop_dir:`TEST_INCLUDE_FILES` 55 | directory property. The set of discovered tests is made accessible to such a 56 | script via the ``_TESTS`` variable. 57 | 58 | The options are: 59 | 60 | ``target`` 61 | Specifies the Catch executable, which must be a known CMake executable 62 | target. CMake will substitute the location of the built executable when 63 | running the test. 64 | 65 | ``TEST_SPEC arg1...`` 66 | Specifies test cases, wildcarded test cases, tags and tag expressions to 67 | pass to the Catch executable with the ``--list-test-names-only`` argument. 68 | 69 | ``EXTRA_ARGS arg1...`` 70 | Any extra arguments to pass on the command line to each test case. 71 | 72 | ``WORKING_DIRECTORY dir`` 73 | Specifies the directory in which to run the discovered test cases. If this 74 | option is not provided, the current binary directory is used. 75 | 76 | ``TEST_PREFIX prefix`` 77 | Specifies a ``prefix`` to be prepended to the name of each discovered test 78 | case. This can be useful when the same test executable is being used in 79 | multiple calls to ``catch_discover_tests()`` but with different 80 | ``TEST_SPEC`` or ``EXTRA_ARGS``. 81 | 82 | ``TEST_SUFFIX suffix`` 83 | Similar to ``TEST_PREFIX`` except the ``suffix`` is appended to the name of 84 | every discovered test case. Both ``TEST_PREFIX`` and ``TEST_SUFFIX`` may 85 | be specified. 86 | 87 | ``PROPERTIES name1 value1...`` 88 | Specifies additional properties to be set on all tests discovered by this 89 | invocation of ``catch_discover_tests``. 90 | 91 | ``TEST_LIST var`` 92 | Make the list of tests available in the variable ``var``, rather than the 93 | default ``_TESTS``. This can be useful when the same test 94 | executable is being used in multiple calls to ``catch_discover_tests()``. 95 | Note that this variable is only available in CTest. 96 | 97 | ``REPORTER reporter`` 98 | Use the specified reporter when running the test case. The reporter will 99 | be passed to the Catch executable as ``--reporter reporter``. 100 | 101 | ``OUTPUT_DIR dir`` 102 | If specified, the parameter is passed along as 103 | ``--out dir/`` to Catch executable. The actual file name is the 104 | same as the test name. This should be used instead of 105 | ``EXTRA_ARGS --out foo`` to avoid race conditions writing the result output 106 | when using parallel test execution. 107 | 108 | ``OUTPUT_PREFIX prefix`` 109 | May be used in conjunction with ``OUTPUT_DIR``. 110 | If specified, ``prefix`` is added to each output file name, like so 111 | ``--out dir/prefix``. 112 | 113 | ``OUTPUT_SUFFIX suffix`` 114 | May be used in conjunction with ``OUTPUT_DIR``. 115 | If specified, ``suffix`` is added to each output file name, like so 116 | ``--out dir/suffix``. This can be used to add a file extension to 117 | the output e.g. ".xml". 118 | 119 | #]=======================================================================] 120 | 121 | #------------------------------------------------------------------------------ 122 | function(catch_discover_tests TARGET) 123 | cmake_parse_arguments( 124 | "" 125 | "" 126 | "TEST_PREFIX;TEST_SUFFIX;WORKING_DIRECTORY;TEST_LIST;REPORTER;OUTPUT_DIR;OUTPUT_PREFIX;OUTPUT_SUFFIX" 127 | "TEST_SPEC;EXTRA_ARGS;PROPERTIES" 128 | ${ARGN} 129 | ) 130 | 131 | if(NOT _WORKING_DIRECTORY) 132 | set(_WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") 133 | endif() 134 | if(NOT _TEST_LIST) 135 | set(_TEST_LIST ${TARGET}_TESTS) 136 | endif() 137 | 138 | ## Generate a unique name based on the extra arguments 139 | string(SHA1 args_hash "${_TEST_SPEC} ${_EXTRA_ARGS} ${_REPORTER} ${_OUTPUT_DIR} ${_OUTPUT_PREFIX} ${_OUTPUT_SUFFIX}") 140 | string(SUBSTRING ${args_hash} 0 7 args_hash) 141 | 142 | # Define rule to generate test list for aforementioned test executable 143 | set(ctest_include_file "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_include-${args_hash}.cmake") 144 | set(ctest_tests_file "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_tests-${args_hash}.cmake") 145 | get_property(crosscompiling_emulator 146 | TARGET ${TARGET} 147 | PROPERTY CROSSCOMPILING_EMULATOR 148 | ) 149 | add_custom_command( 150 | TARGET ${TARGET} POST_BUILD 151 | BYPRODUCTS "${ctest_tests_file}" 152 | COMMAND "${CMAKE_COMMAND}" 153 | -D "TEST_TARGET=${TARGET}" 154 | -D "TEST_EXECUTABLE=$" 155 | -D "TEST_EXECUTOR=${crosscompiling_emulator}" 156 | -D "TEST_WORKING_DIR=${_WORKING_DIRECTORY}" 157 | -D "TEST_SPEC=${_TEST_SPEC}" 158 | -D "TEST_EXTRA_ARGS=${_EXTRA_ARGS}" 159 | -D "TEST_PROPERTIES=${_PROPERTIES}" 160 | -D "TEST_PREFIX=${_TEST_PREFIX}" 161 | -D "TEST_SUFFIX=${_TEST_SUFFIX}" 162 | -D "TEST_LIST=${_TEST_LIST}" 163 | -D "TEST_REPORTER=${_REPORTER}" 164 | -D "TEST_OUTPUT_DIR=${_OUTPUT_DIR}" 165 | -D "TEST_OUTPUT_PREFIX=${_OUTPUT_PREFIX}" 166 | -D "TEST_OUTPUT_SUFFIX=${_OUTPUT_SUFFIX}" 167 | -D "CTEST_FILE=${ctest_tests_file}" 168 | -P "${_CATCH_DISCOVER_TESTS_SCRIPT}" 169 | VERBATIM 170 | ) 171 | 172 | file(WRITE "${ctest_include_file}" 173 | "if(EXISTS \"${ctest_tests_file}\")\n" 174 | " include(\"${ctest_tests_file}\")\n" 175 | "else()\n" 176 | " add_test(${TARGET}_NOT_BUILT-${args_hash} ${TARGET}_NOT_BUILT-${args_hash})\n" 177 | "endif()\n" 178 | ) 179 | 180 | if(NOT ${CMAKE_VERSION} VERSION_LESS "3.10.0") 181 | # Add discovered tests to directory TEST_INCLUDE_FILES 182 | set_property(DIRECTORY 183 | APPEND PROPERTY TEST_INCLUDE_FILES "${ctest_include_file}" 184 | ) 185 | else() 186 | # Add discovered tests as directory TEST_INCLUDE_FILE if possible 187 | get_property(test_include_file_set DIRECTORY PROPERTY TEST_INCLUDE_FILE SET) 188 | if (NOT ${test_include_file_set}) 189 | set_property(DIRECTORY 190 | PROPERTY TEST_INCLUDE_FILE "${ctest_include_file}" 191 | ) 192 | else() 193 | message(FATAL_ERROR 194 | "Cannot set more than one TEST_INCLUDE_FILE" 195 | ) 196 | endif() 197 | endif() 198 | 199 | endfunction() 200 | 201 | ############################################################################### 202 | 203 | set(_CATCH_DISCOVER_TESTS_SCRIPT 204 | ${CMAKE_CURRENT_LIST_DIR}/CatchAddTests.cmake 205 | CACHE INTERNAL "Catch2 full path to CatchAddTests.cmake helper file" 206 | ) 207 | -------------------------------------------------------------------------------- /cmake/CatchAddTests.cmake: -------------------------------------------------------------------------------- 1 | # Distributed under the OSI-approved BSD 3-Clause License. See accompanying 2 | # file Copyright.txt or https://cmake.org/licensing for details. 3 | 4 | set(prefix "${TEST_PREFIX}") 5 | set(suffix "${TEST_SUFFIX}") 6 | set(spec ${TEST_SPEC}) 7 | set(extra_args ${TEST_EXTRA_ARGS}) 8 | set(properties ${TEST_PROPERTIES}) 9 | set(reporter ${TEST_REPORTER}) 10 | set(output_dir ${TEST_OUTPUT_DIR}) 11 | set(output_prefix ${TEST_OUTPUT_PREFIX}) 12 | set(output_suffix ${TEST_OUTPUT_SUFFIX}) 13 | set(script) 14 | set(suite) 15 | set(tests) 16 | 17 | function(add_command NAME) 18 | set(_args "") 19 | # use ARGV* instead of ARGN, because ARGN splits arrays into multiple arguments 20 | math(EXPR _last_arg ${ARGC}-1) 21 | foreach(_n RANGE 1 ${_last_arg}) 22 | set(_arg "${ARGV${_n}}") 23 | if(_arg MATCHES "[^-./:a-zA-Z0-9_]") 24 | set(_args "${_args} [==[${_arg}]==]") # form a bracket_argument 25 | else() 26 | set(_args "${_args} ${_arg}") 27 | endif() 28 | endforeach() 29 | set(script "${script}${NAME}(${_args})\n" PARENT_SCOPE) 30 | endfunction() 31 | 32 | # Run test executable to get list of available tests 33 | if(NOT EXISTS "${TEST_EXECUTABLE}") 34 | message(FATAL_ERROR 35 | "Specified test executable '${TEST_EXECUTABLE}' does not exist" 36 | ) 37 | endif() 38 | execute_process( 39 | COMMAND ${TEST_EXECUTOR} "${TEST_EXECUTABLE}" ${spec} --list-test-names-only 40 | OUTPUT_VARIABLE output 41 | RESULT_VARIABLE result 42 | WORKING_DIRECTORY "${TEST_WORKING_DIR}" 43 | ) 44 | # Catch --list-test-names-only reports the number of tests, so 0 is... surprising 45 | if(${result} EQUAL 0) 46 | message(WARNING 47 | "Test executable '${TEST_EXECUTABLE}' contains no tests!\n" 48 | ) 49 | elseif(${result} LESS 0) 50 | message(FATAL_ERROR 51 | "Error running test executable '${TEST_EXECUTABLE}':\n" 52 | " Result: ${result}\n" 53 | " Output: ${output}\n" 54 | ) 55 | endif() 56 | 57 | string(REPLACE "\n" ";" output "${output}") 58 | 59 | # Run test executable to get list of available reporters 60 | execute_process( 61 | COMMAND ${TEST_EXECUTOR} "${TEST_EXECUTABLE}" ${spec} --list-reporters 62 | OUTPUT_VARIABLE reporters_output 63 | RESULT_VARIABLE reporters_result 64 | WORKING_DIRECTORY "${TEST_WORKING_DIR}" 65 | ) 66 | if(${reporters_result} EQUAL 0) 67 | message(WARNING 68 | "Test executable '${TEST_EXECUTABLE}' contains no reporters!\n" 69 | ) 70 | elseif(${reporters_result} LESS 0) 71 | message(FATAL_ERROR 72 | "Error running test executable '${TEST_EXECUTABLE}':\n" 73 | " Result: ${reporters_result}\n" 74 | " Output: ${reporters_output}\n" 75 | ) 76 | endif() 77 | string(FIND "${reporters_output}" "${reporter}" reporter_is_valid) 78 | if(reporter AND ${reporter_is_valid} EQUAL -1) 79 | message(FATAL_ERROR 80 | "\"${reporter}\" is not a valid reporter!\n" 81 | ) 82 | endif() 83 | 84 | # Prepare reporter 85 | if(reporter) 86 | set(reporter_arg "--reporter ${reporter}") 87 | endif() 88 | 89 | # Prepare output dir 90 | if(output_dir AND NOT IS_ABSOLUTE ${output_dir}) 91 | set(output_dir "${TEST_WORKING_DIR}/${output_dir}") 92 | if(NOT EXISTS ${output_dir}) 93 | file(MAKE_DIRECTORY ${output_dir}) 94 | endif() 95 | endif() 96 | 97 | # Parse output 98 | foreach(line ${output}) 99 | set(test ${line}) 100 | # Escape characters in test case names that would be parsed by Catch2 101 | set(test_name ${test}) 102 | foreach(char , [ ]) 103 | string(REPLACE ${char} "\\${char}" test_name ${test_name}) 104 | endforeach(char) 105 | # ...add output dir 106 | if(output_dir) 107 | string(REGEX REPLACE "[^A-Za-z0-9_]" "_" test_name_clean ${test_name}) 108 | set(output_dir_arg "--out ${output_dir}/${output_prefix}${test_name_clean}${output_suffix}") 109 | endif() 110 | 111 | # ...and add to script 112 | add_command(add_test 113 | "${prefix}${test}${suffix}" 114 | ${TEST_EXECUTOR} 115 | "${TEST_EXECUTABLE}" 116 | "${test_name}" 117 | ${extra_args} 118 | "${reporter_arg}" 119 | "${output_dir_arg}" 120 | ) 121 | add_command(set_tests_properties 122 | "${prefix}${test}${suffix}" 123 | PROPERTIES 124 | WORKING_DIRECTORY "${TEST_WORKING_DIR}" 125 | ${properties} 126 | ) 127 | list(APPEND tests "${prefix}${test}${suffix}") 128 | endforeach() 129 | 130 | # Create a list of all discovered tests, which users may use to e.g. set 131 | # properties on the tests 132 | add_command(set ${TEST_LIST} ${tests}) 133 | 134 | # Write CTest script 135 | file(WRITE "${CTEST_FILE}" "${script}") 136 | -------------------------------------------------------------------------------- /include/adder/adder.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @brief One line description of the adder library 3 | * 4 | * More information about the adder library 5 | * can go here. 6 | * 7 | * @see https://github.com/ssciwr/cpp-project-template 8 | */ 9 | #pragma once 10 | 11 | namespace adder { 12 | 13 | /** 14 | * @brief One line description of add_one goes here 15 | * 16 | * For a more complicated function, here 17 | * would be more information about what it does. 18 | * 19 | * @param x Description of the input parameter x 20 | * 21 | * @note Something particular to note about add_one 22 | * 23 | * @warning A warning about add_one 24 | */ 25 | int add_one(int x); 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(adder adder.cpp) 2 | target_include_directories(adder PUBLIC ../include) 3 | # require at least c++11 4 | target_compile_features(adder PUBLIC cxx_std_11) 5 | -------------------------------------------------------------------------------- /src/adder.cpp: -------------------------------------------------------------------------------- 1 | #include "adder/adder.hpp" 2 | 3 | namespace adder { 4 | 5 | int add_one(int x){ 6 | return x + 1; 7 | } 8 | 9 | } 10 | -------------------------------------------------------------------------------- /tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(tests tests.cpp adder_t.cpp) 2 | target_link_libraries(tests PUBLIC adder) 3 | target_include_directories(tests PUBLIC ../ext) 4 | 5 | # allow user to run tests with `make test` or `ctest` 6 | include(../cmake/Catch.cmake) 7 | catch_discover_tests(tests) -------------------------------------------------------------------------------- /tests/adder_t.cpp: -------------------------------------------------------------------------------- 1 | #include "adder/adder.hpp" 2 | #include "catch2/catch.hpp" 3 | 4 | using namespace adder; 5 | 6 | TEST_CASE( "add_one", "[adder]" ){ 7 | REQUIRE(add_one(0) == 1); 8 | REQUIRE(add_one(123) == 124); 9 | REQUIRE(add_one(-1) == 0); 10 | } 11 | -------------------------------------------------------------------------------- /tests/tests.cpp: -------------------------------------------------------------------------------- 1 | #define CATCH_CONFIG_MAIN 2 | #include "catch2/catch.hpp" 3 | --------------------------------------------------------------------------------