diff --git a/.clangd b/.clangd new file mode 100644 index 00000000..fe895f19 --- /dev/null +++ b/.clangd @@ -0,0 +1,23 @@ +CompileFlags: + Add: + - -std=c++23 + - -xc++-header + - -Iinclude + - -Itests/include + - -Itests/external + - -Wall + - -Wextra + - -ftemplate-depth=512 + +Diagnostics: + UnusedIncludes: None + ClangTidy: + Add: + - bugprone-* + - modernize-* + - performance-* + Remove: + - modernize-use-trailing-return-type + +Index: + Background: Build diff --git a/.github/workflows/clang.yaml b/.github/workflows/clang.yaml index 164a119a..526f02a7 100644 --- a/.github/workflows/clang.yaml +++ b/.github/workflows/clang.yaml @@ -2,7 +2,7 @@ name: Clang on: push: branches: - - '*' + - "*" paths: - .github/workflows/clang.yaml - include/** @@ -23,17 +23,17 @@ jobs: - name: Prepare env: - CC: clang-17 + CC: clang-17 CXX: clang++-17 run: | cmake -B build_clang -DBUILD_TESTS=ON -DCMAKE_CXX_COMPILER=$CXX -DCMAKE_C_COMPILER=$CC continue-on-error: false - - name: Build tests + - name: Build and Run tests run: | - cmake --build build_clang/ -j 4 + cmake --build build_clang/ -j4 continue-on-error: false - name: Run tests run: | - ctest --test-dir build_clang/tests/ -V + ./build_clang/tests/run_uts diff --git a/.github/workflows/demo.yaml b/.github/workflows/demo.yaml index 45db44d3..5667c22a 100644 --- a/.github/workflows/demo.yaml +++ b/.github/workflows/demo.yaml @@ -2,7 +2,7 @@ name: demo on: push: branches: - - '*' + - "*" paths: - .github/workflows/demo.yaml - .gitmodules diff --git a/.github/workflows/documentation.yaml b/.github/workflows/documentation.yaml index 52966f87..36bcd6a4 100644 --- a/.github/workflows/documentation.yaml +++ b/.github/workflows/documentation.yaml @@ -3,10 +3,10 @@ name: documentation on: pull_request: branches: - - '*' + - "*" push: tags: - - 'v*' + - "v*" jobs: build-doc: diff --git a/.github/workflows/format.yaml b/.github/workflows/format.yaml index c2d4ed15..f8a84fef 100644 --- a/.github/workflows/format.yaml +++ b/.github/workflows/format.yaml @@ -2,7 +2,7 @@ name: format on: push: branches: - - '*' + - "*" paths: - .github/workflows/format.yaml - scripts/format.py @@ -31,4 +31,4 @@ jobs: - name: Test formatting shell: bash run: | - python3 scripts/format.py --check + python3 scripts/format.py --check -exe clang-format-18 diff --git a/.github/workflows/gcc.yaml b/.github/workflows/gcc.yaml index 3d4c9a62..1000a563 100644 --- a/.github/workflows/gcc.yaml +++ b/.github/workflows/gcc.yaml @@ -2,7 +2,7 @@ name: GCC on: push: branches: - - '*' + - "*" paths: - .github/workflows/gcc.yaml - include/** @@ -23,7 +23,7 @@ jobs: - name: Prepare env: - CC: gcc-13 + CC: gcc-13 CXX: g++-13 run: | cmake -B build_gcc -DBUILD_TESTS=ON -DCMAKE_CXX_COMPILER=$CXX -DCMAKE_C_COMPILER=$CC @@ -36,4 +36,4 @@ jobs: - name: Run tests run: | - ctest --test-dir build_gcc/tests/ -V + ./build_gcc/tests/run_uts diff --git a/.github/workflows/license.yaml b/.github/workflows/license.yaml index 094aa1dc..b82682e4 100644 --- a/.github/workflows/license.yaml +++ b/.github/workflows/license.yaml @@ -2,7 +2,7 @@ name: license on: push: branches: - - '*' + - "*" paths: - .github/workflows/license.yaml - scripts/check_licence.py diff --git a/.github/workflows/msvc.yaml b/.github/workflows/msvc.yaml index 401fe236..658e6084 100644 --- a/.github/workflows/msvc.yaml +++ b/.github/workflows/msvc.yaml @@ -2,7 +2,7 @@ name: MSVC on: push: branches: - - '*' + - "*" paths: - .github/workflows/msvc.yaml - include/** @@ -33,5 +33,5 @@ jobs: - name: Run tests run: | - ctest --test-dir build_msvc/tests -V -C Debug + ./build_msvc/tests/Debug/run_uts.exe shell: powershell diff --git a/CMakeLists.txt b/CMakeLists.txt index ebfb1481..639ac236 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ else() endif() project(cpp-ap - VERSION 3.0.1 + VERSION 3.1.0 DESCRIPTION "Command-line argument parser for C++20" HOMEPAGE_URL "https://github.com/SpectraL519/cpp-ap" LANGUAGES CXX diff --git a/Doxyfile b/Doxyfile index a2019f17..c0ecdba9 100644 --- a/Doxyfile +++ b/Doxyfile @@ -48,7 +48,7 @@ PROJECT_NAME = CPP-AP # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 3.0.1 +PROJECT_NUMBER = 3.1.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/MODULE.bazel b/MODULE.bazel index fb319502..ee564582 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -1,4 +1,4 @@ module( name = "cpp-ap", - version = "3.0.1", + version = "3.1.0", ) diff --git a/docs/dev_notes.md b/docs/dev_notes.md index 2f8bc52b..5a360f26 100644 --- a/docs/dev_notes.md +++ b/docs/dev_notes.md @@ -2,34 +2,34 @@
-## Building and testing +## Building and Testing > [!NOTE] > > The project uses [doctest](https://github.com/doctest/doctest) framework for unit testing, however it is already installed in the [tests/external](/tests/external/) directory, so there is no need to install it sepparately. -### Build the testing executable +### Build the Testing Executable ```shell cmake -B build -DBUILD_TESTS=ON -cmake --build build/ # -j +cmake --build build/ # -j ``` -This will build each test file as a separate executable in the `build/tests/` directory. +This will build a `run_uts` executable executable in the `build/tests/` directory. -### Run the tests +### Runing the Tests -You can run tests from each test file separately with: +To run the project's unit tests, simply run the testing executable: ```shell -./build/tests/ +./build/tests/run_uts ``` -To execute all tests at once run: - -```shell -ctest --test-dir build/tests/ # -V (to capture output from each test executable) -``` +> [!TIP] +> Each test file defines its unique test suite with the same name as the test file. To run tests within such test suite, execute: +> ```shell +> ./build/tests/run_uts -ts= +> ```

diff --git a/docs/tutorial.md b/docs/tutorial.md index b90332d6..259fa2bd 100644 --- a/docs/tutorial.md +++ b/docs/tutorial.md @@ -908,6 +908,15 @@ auto& out_opts = parser.add_group("Output Options") > > Consider the example in the section below. Normally the `--output, -o` argument would expect a value to be given in the command-line. However, if the `--print, -p` flag is used, then the `nargs` requirement of the `--output, -o` argument will not be verified, and therefore no exception will be thrown, even though the `nargs` requirement is not satisfied. +Additionally, argument groups can be marked `hidden` - a hidden group will not be visible in the parser's help output (even if it has visible arguments). + +```cpp +auto& hidden_opts = parser.add_group("Hidden Options").hidden(); +parser.add_optional_argument("visible").help("A visible arg"); +``` + +In the example above, neither the `Hidden Options` group nor the `visible` arg will be visible in the parser's help output. + ### Complete Example Below is a small program that demonstrates how to use a mutually exclusive group of required arguments: diff --git a/include/ap/action/predefined.hpp b/include/ap/action/predefined.hpp index ecedc037..31c1e283 100644 --- a/include/ap/action/predefined.hpp +++ b/include/ap/action/predefined.hpp @@ -6,8 +6,8 @@ #pragma once +#include "ap/action/util/helpers.hpp" #include "ap/exceptions.hpp" -#include "util/helpers.hpp" #include #include diff --git a/include/ap/action/util/helpers.hpp b/include/ap/action/util/helpers.hpp index 092fba05..be2abb52 100644 --- a/include/ap/action/util/helpers.hpp +++ b/include/ap/action/util/helpers.hpp @@ -9,7 +9,7 @@ #pragma once -#include "concepts.hpp" +#include "ap/action/util/concepts.hpp" #include #include diff --git a/include/ap/argument.hpp b/include/ap/argument.hpp index 3ddf8462..2ea49910 100644 --- a/include/ap/argument.hpp +++ b/include/ap/argument.hpp @@ -6,14 +6,14 @@ #pragma once -#include "action/predefined.hpp" -#include "action/util/helpers.hpp" -#include "detail/argument_base.hpp" -#include "detail/help_builder.hpp" -#include "nargs/range.hpp" -#include "types.hpp" -#include "util/concepts.hpp" -#include "util/ranges.hpp" +#include "ap/action/predefined.hpp" +#include "ap/action/util/helpers.hpp" +#include "ap/detail/argument_base.hpp" +#include "ap/detail/help_builder.hpp" +#include "ap/nargs/range.hpp" +#include "ap/types.hpp" +#include "ap/util/concepts.hpp" +#include "ap/util/ranges.hpp" #ifdef AP_TESTING diff --git a/include/ap/argument_group.hpp b/include/ap/argument_group.hpp index dc30bb8a..580a794e 100644 --- a/include/ap/argument_group.hpp +++ b/include/ap/argument_group.hpp @@ -6,7 +6,7 @@ #pragma once -#include "detail/argument_base.hpp" +#include "ap/detail/argument_base.hpp" #include @@ -42,6 +42,20 @@ class argument_group { public: argument_group() = delete; + /** + * @brief Set the `hidden` attribute of the group. + * + * - If set to true, the group will be hidden from the help output. + * - Groups are NOT hidden by default. + * + * @param h The value to set for the attribute (default: true). + * @return Reference to the group instance. + */ + argument_group& hidden(const bool h = true) noexcept { + this->_hidden = h; + return *this; + } + /** * @brief Set the `required` attribute of the group. * @@ -100,6 +114,7 @@ class argument_group { std::string _name; ///< Name of the group (used in help output). arg_ptr_vec_t _arguments; ///< A list of arguments that belong to this group. + bool _hidden : 1 = false; ///< The hidden attribute value (default: false). bool _required : 1 = false; ///< The required attribute value (default: false). bool _mutually_exclusive : 1 = false; ///< The mutually exclusive attribute value (default: false). diff --git a/include/ap/argument_parser.hpp b/include/ap/argument_parser.hpp index 61950c9d..835cbbca 100644 --- a/include/ap/argument_parser.hpp +++ b/include/ap/argument_parser.hpp @@ -9,10 +9,10 @@ #pragma once -#include "argument.hpp" -#include "argument_group.hpp" -#include "detail/argument_token.hpp" -#include "types.hpp" +#include "ap/argument.hpp" +#include "ap/argument_group.hpp" +#include "ap/detail/argument_token.hpp" +#include "ap/types.hpp" #include #include @@ -1508,6 +1508,9 @@ class argument_parser { */ void _print_group(std::ostream& os, const argument_group& group, const bool verbose) const noexcept { + if (group._hidden) + return; + auto visible_args = std::views::filter(group._arguments, [](const auto& arg) { return not arg->is_hidden(); }); @@ -1515,16 +1518,15 @@ class argument_parser { if (std::ranges::empty(visible_args)) return; - os << '\n' << group._name << ":"; + os << '\n' << group._name << ':'; - std::vector group_attrs; + std::vector group_attrs; if (group._required) group_attrs.emplace_back("required"); if (group._mutually_exclusive) group_attrs.emplace_back("mutually exclusive"); if (not group_attrs.empty()) os << " (" << util::join(group_attrs) << ')'; - os << '\n'; if (verbose) { diff --git a/include/ap/detail/argument_base.hpp b/include/ap/detail/argument_base.hpp index e3f1de6e..2f2f4502 100644 --- a/include/ap/detail/argument_base.hpp +++ b/include/ap/detail/argument_base.hpp @@ -9,8 +9,8 @@ #pragma once -#include "argument_name.hpp" -#include "help_builder.hpp" +#include "ap/detail/argument_name.hpp" +#include "ap/detail/help_builder.hpp" #include #include diff --git a/include/ap/detail/argument_token.hpp b/include/ap/detail/argument_token.hpp index 8328e4df..4574da10 100644 --- a/include/ap/detail/argument_token.hpp +++ b/include/ap/detail/argument_token.hpp @@ -6,9 +6,10 @@ #pragma once -#include "argument_base.hpp" +#include "ap/detail/argument_base.hpp" #include +#include #include #include diff --git a/include/ap/detail/help_builder.hpp b/include/ap/detail/help_builder.hpp index 830a1982..ddb69752 100644 --- a/include/ap/detail/help_builder.hpp +++ b/include/ap/detail/help_builder.hpp @@ -9,9 +9,9 @@ #pragma once +#include "ap/detail/argument_name.hpp" #include "ap/util/concepts.hpp" #include "ap/util/string.hpp" -#include "argument_name.hpp" #include #include diff --git a/include/ap/util/ranges.hpp b/include/ap/util/ranges.hpp index 8f82f9be..5de2a91a 100644 --- a/include/ap/util/ranges.hpp +++ b/include/ap/util/ranges.hpp @@ -9,7 +9,7 @@ #pragma once -#include "concepts.hpp" +#include "ap/util/concepts.hpp" #include #include diff --git a/include/ap/util/string.hpp b/include/ap/util/string.hpp index 8c640e00..79a108ee 100644 --- a/include/ap/util/string.hpp +++ b/include/ap/util/string.hpp @@ -9,7 +9,7 @@ #pragma once -#include "concepts.hpp" +#include "ap/util/concepts.hpp" #include #include diff --git a/scripts/format.py b/scripts/format.py index b077c663..11bc9c8d 100644 --- a/scripts/format.py +++ b/scripts/format.py @@ -1,7 +1,6 @@ import argparse import subprocess import sys -from collections.abc import Iterable from pathlib import Path from common import find_files @@ -9,51 +8,59 @@ class DefaultParameters: modified_files: bool = False - search_paths: Iterable[str] = ["include", "source", "tests"] - file_patterns: Iterable[str] = ["*.cpp", "*.hpp", "*.c", "*.h"] - exclude_paths: Iterable[str] = ["tests/external"] + search_paths: list[str] = ["include", "tests"] + file_patterns: list[str] = ["*.cpp", "*.hpp", "*.c", "*.h"] + exclude_paths: list[str] = ["tests/external"] check: bool = False + clang_format_executable: str = "clang-format" def parse_args(): parser = argparse.ArgumentParser() parser.add_argument( - "-m", "--modified-files", - type=bool, + "-m", + "--modified-files", default=DefaultParameters.modified_files, action=argparse.BooleanOptionalAction, - help="run clang-format only on the files modified since last pushed commit" + help="run clang-format only on the files modified since last pushed commit", ) parser.add_argument( - "-p", "--search-paths", + "-p", + "--search-paths", type=str, default=DefaultParameters.search_paths, nargs="*", - action="extend", - help="list of search directory paths" + help="list of search directory paths", ) parser.add_argument( - "-f", "--file-patterns", + "-f", + "--file-patterns", type=str, default=DefaultParameters.file_patterns, nargs="*", - action="extend", - help="list of file patterns to include" + help="list of file patterns to include", ) parser.add_argument( - "-e", "--exclude-paths", + "-e", + "--exclude-paths", type=str, default=DefaultParameters.exclude_paths, nargs="*", - action="extend", - help="list of directory paths to exclude" + help="list of directory paths to exclude", ) parser.add_argument( - "-c", "--check", - type=bool, + "-c", + "--check", default=DefaultParameters.check, action=argparse.BooleanOptionalAction, - help="run format check" + help="run format check", + ) + parser.add_argument( + "-exe", + "--clang-format-executable", + type=str, + default=DefaultParameters.clang_format_executable, + help="path or name of the clang-format executable (default: clang-format)", ) return vars(parser.parse_args()) @@ -66,7 +73,7 @@ def get_modified_files(files: set[Path]) -> set[Path]: check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, - text=True + text=True, ) modified_files = {Path(file) for file in result.stdout.splitlines() if file} @@ -77,7 +84,7 @@ def get_modified_files(files: set[Path]) -> set[Path]: raise RuntimeError("Failed to retrieve the modified files.") -def run_clang_format(files: set[Path], check: bool) -> int: +def run_clang_format(clang_format_exec: str, files: set[Path], check: bool) -> int: n_files = len(files) if check: print(f"Files to check: {n_files}") @@ -88,7 +95,7 @@ def run_clang_format(files: set[Path], check: bool) -> int: for i, file in enumerate(files): print(f"[{i + 1}/{n_files}] {file}") - cmd = ["clang-format-18", str(file)] + cmd = [clang_format_exec, str(file)] if check: cmd.extend(["--dry-run", "--Werror"]) else: @@ -96,7 +103,9 @@ def run_clang_format(files: set[Path], check: bool) -> int: result = subprocess.run(cmd, capture_output=True, text=True) if result.returncode != 0: return_code = result.returncode - print(f"[Format error]\n[stdout]\n{result.stdout}\n[stderr]\n{result.stderr}") + print( + f"[Format error]\n[stdout]\n{result.stdout}\n[stderr]\n{result.stderr}" + ) print("Done!") return return_code @@ -104,16 +113,17 @@ def run_clang_format(files: set[Path], check: bool) -> int: def main( modified_files: bool, - search_paths: Iterable[str], - file_patterns: Iterable[str], - exclude_paths: Iterable[str], - check: bool + search_paths: list[str], + file_patterns: list[str], + exclude_paths: list[str], + check: bool, + clang_format_executable: str, ): files_to_format = find_files(search_paths, file_patterns, exclude_paths) if modified_files: files_to_format = get_modified_files(files_to_format) - sys.exit(run_clang_format(files_to_format, check)) + sys.exit(run_clang_format(clang_format_executable, files_to_format, check)) if __name__ == "__main__": diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index a9184b25..f2eb137f 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -3,11 +3,6 @@ cmake_minimum_required(VERSION 3.12) # Project project(cpp-ap-test) -enable_testing() - -# Structure -set(INCLUDE_DIRS "include" "external") -set(EXECUTABLE_DIR "${CMAKE_CURRENT_BINARY_DIR}") # Set compile options if (MSVC) @@ -26,51 +21,26 @@ endif() message(STATUS "[CMAKE_CXX_FLAGS = ${CMAKE_CXX_FLAGS}]") set(COMMON_COMPILE_DEFINITIONS "AP_TESTING") +# Structure +set(SOURCE_DIRS "source" "app") +set(INCLUDE_DIRS "include" "external") +set(EXECUTABLE_DIR "${CMAKE_CURRENT_BINARY_DIR}") -# Decalre test targets -add_library(doctest_main STATIC app/main.cpp) -set_target_properties(doctest_main PROPERTIES +# Source files +file(GLOB_RECURSE SOURCES "") +foreach(SOURCE_DIR ${SOURCE_DIRS}) + file(GLOB_RECURSE CURRENT_SOURCES ${SOURCE_DIR}/*.cpp) + list(APPEND SOURCES ${CURRENT_SOURCES}) +endforeach() + +# Executable +add_executable(run_uts ${SOURCES}) +set_target_properties(run_uts PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${EXECUTABLE_DIR}" CXX_STANDARD 20 CXX_STANDARD_REQUIRED YES CXX_EXTENSIONS NO ) -target_include_directories(doctest_main PUBLIC "external") - -macro(add_doctest SOURCE_FILE) - # Parse macro arguments - get_filename_component(TEST_NAME ${SOURCE_FILE} NAME_WE) - set(options) - set(oneValueArgs) - set(multiValueArgs COMPILE_DEFINITIONS) - cmake_parse_arguments(ARGS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) - - # Define the executable - add_executable(${TEST_NAME} ${SOURCE_FILE}) - set_target_properties(${TEST_NAME} PROPERTIES - RUNTIME_OUTPUT_DIRECTORY "${EXECUTABLE_DIR}" - CXX_STANDARD 20 - CXX_STANDARD_REQUIRED YES - CXX_EXTENSIONS NO - ) - target_include_directories(${TEST_NAME} PRIVATE ${INCLUDE_DIRS}) - target_compile_definitions(${TEST_NAME} PRIVATE ${COMMON_COMPILE_DEFINITIONS}) - if(ARGS_COMPILE_DEFINITIONS) - target_compile_definitions(${TEST_NAME} PRIVATE ${ARGS_COMPILE_DEFINITIONS}) - endif() - target_link_libraries(${TEST_NAME} PRIVATE doctest_main cpp-ap) - - # Register with CTest - add_test(NAME ${TEST_NAME} COMMAND ${TEST_NAME}) -endmacro() - -add_doctest("source/test_string_utility.cpp") -add_doctest("source/test_argument_name.cpp") -add_doctest("source/test_nargs_range.cpp") -add_doctest("source/test_help_builder.cpp") -add_doctest("source/test_argument_token.cpp") -add_doctest("source/test_none_type_argument.cpp") -add_doctest("source/test_positional_argument.cpp") -add_doctest("source/test_optional_argument.cpp") -add_doctest("source/test_argument_parser_add_elements.cpp") -add_doctest("source/test_argument_parser_info.cpp") -add_doctest("source/test_argument_parser_parse_args.cpp") +target_include_directories(run_uts PRIVATE ${INCLUDE_DIRS}) +target_compile_definitions(run_uts PRIVATE "AP_TESTING") +target_link_libraries(run_uts PRIVATE cpp-ap) diff --git a/tests/source/test_argument_name.cpp b/tests/source/test_argument_name.cpp index 273a1e16..60856ac5 100644 --- a/tests/source/test_argument_name.cpp +++ b/tests/source/test_argument_name.cpp @@ -6,6 +6,8 @@ using namespace ap::detail; +TEST_SUITE_BEGIN("test_argument_name"); + namespace { constexpr std::string_view primary_1 = "primary_1"; @@ -171,3 +173,5 @@ TEST_CASE("operator<< should push correct data to the output stream") { REQUIRE_EQ(ss.str(), expected_ss.str()); } + +TEST_SUITE_END(); // test_argument_name diff --git a/tests/source/test_argument_parser_add_elements.cpp b/tests/source/test_argument_parser_add_elements.cpp index 9da936fc..8eebca90 100644 --- a/tests/source/test_argument_parser_add_elements.cpp +++ b/tests/source/test_argument_parser_add_elements.cpp @@ -9,6 +9,8 @@ using ap::argument_parser; using ap::default_argument; using ap::invalid_configuration; +TEST_SUITE_BEGIN("test_argument_parser_add_elements"); + struct test_argument_parser_add_elements : public argument_parser_test_fixture { const char flag_char = '-'; @@ -392,3 +394,5 @@ TEST_CASE_FIXTURE( std::logic_error ); } + +TEST_SUITE_END(); // test_argument_parser_add_elements diff --git a/tests/source/test_argument_parser_info.cpp b/tests/source/test_argument_parser_info.cpp index fe4d0c7a..1d6fdc7b 100644 --- a/tests/source/test_argument_parser_info.cpp +++ b/tests/source/test_argument_parser_info.cpp @@ -6,6 +6,8 @@ using namespace ap_testing; using ap::argument_parser; using ap::invalid_configuration; +TEST_SUITE_BEGIN("test_argument_parser_info"); + struct test_argument_parser_info : public argument_parser_test_fixture { const std::string test_description = "test program description"; const ap::version test_version{1u, 2u, 3u}; @@ -91,3 +93,5 @@ TEST_CASE_FIXTURE( REQUIRE(stored_program_description); CHECK_EQ(stored_program_description.value(), test_description); } + +TEST_SUITE_END(); // test_argument_parser_info diff --git a/tests/source/test_argument_parser_parse_args.cpp b/tests/source/test_argument_parser_parse_args.cpp index 5a540101..8a017f76 100644 --- a/tests/source/test_argument_parser_parse_args.cpp +++ b/tests/source/test_argument_parser_parse_args.cpp @@ -8,6 +8,8 @@ using ap::invalid_configuration; using ap::parsing_failure; using ap::unknown_policy; +TEST_SUITE_BEGIN("test_argument_parser_parse_args"); + struct test_argument_parser_parse_args : public argument_parser_test_fixture { const std::string_view test_program_name = "test program name"; @@ -1519,3 +1521,5 @@ TEST_CASE_FIXTURE( CHECK_EQ(subparser.value(pos_arg_name), pos_arg_val); CHECK_EQ(subparser.value(opt_arg_name), opt_arg_val); } + +TEST_SUITE_END(); // test_argument_parser_parse_args; diff --git a/tests/source/test_argument_token.cpp b/tests/source/test_argument_token.cpp index f88c6adc..9a26e18d 100644 --- a/tests/source/test_argument_token.cpp +++ b/tests/source/test_argument_token.cpp @@ -9,6 +9,8 @@ using ap::optional_argument; using ap::detail::argument_base; using ap::detail::argument_name; +TEST_SUITE_BEGIN("test_argument_token"); + namespace { const std::string token_value_1 = "tok-val-1"; @@ -60,3 +62,5 @@ TEST_CASE("is_valid_flag_token should return true if the token is a flag token a CHECK(sut_type{t_flag_primary, "", {arg_ptr}}.is_valid_flag_token()); CHECK(sut_type{t_flag_secondary, "", {arg_ptr}}.is_valid_flag_token()); } + +TEST_SUITE_END(); // test_argument_token diff --git a/tests/source/test_help_builder.cpp b/tests/source/test_help_builder.cpp index 00290e72..a1d7d0b0 100644 --- a/tests/source/test_help_builder.cpp +++ b/tests/source/test_help_builder.cpp @@ -4,6 +4,8 @@ #include +TEST_SUITE_BEGIN("test_help_builder"); + using sut_type = ap::detail::help_builder; namespace { @@ -155,3 +157,5 @@ TEST_CASE("get should fall back to multiline output if string is too wide") { CHECK_EQ(sut.get(indent_width, max_line_width), expected.str()); } + +TEST_SUITE_END(); // test_help_builder diff --git a/tests/source/test_nargs_range.cpp b/tests/source/test_nargs_range.cpp index c8daeb31..b005d791 100644 --- a/tests/source/test_nargs_range.cpp +++ b/tests/source/test_nargs_range.cpp @@ -6,6 +6,8 @@ using namespace ap::nargs; +TEST_SUITE_BEGIN("test_nargs_range"); + namespace { constexpr count_type exact_bound = 1ull; @@ -149,3 +151,5 @@ TEST_CASE("range builders should return correct range objects") { CHECK(std::is_eq(max_bound <=> sut)); } } + +TEST_SUITE_END(); // test_nargs_range diff --git a/tests/source/test_none_type_argument.cpp b/tests/source/test_none_type_argument.cpp index 57861c8c..e0492eea 100644 --- a/tests/source/test_none_type_argument.cpp +++ b/tests/source/test_none_type_argument.cpp @@ -3,6 +3,8 @@ using namespace ap_testing; +TEST_SUITE_BEGIN("test_none_type_argument"); + using ap::optional_argument; using ap::parsing_failure; using ap::detail::argument_name; @@ -47,3 +49,5 @@ TEST_CASE_FIXTURE( parsing_failure ); } + +TEST_SUITE_END(); // test_none_type_argument diff --git a/tests/source/test_optional_argument.cpp b/tests/source/test_optional_argument.cpp index b1e456b1..26aebb3a 100644 --- a/tests/source/test_optional_argument.cpp +++ b/tests/source/test_optional_argument.cpp @@ -11,6 +11,8 @@ using ap::parsing_failure; using ap::detail::argument_name; using ap::detail::parameter_descriptor; +TEST_SUITE_BEGIN("test_optional_argument"); + namespace { constexpr char flag_char = '-'; @@ -634,3 +636,5 @@ TEST_CASE_FIXTURE( set_value_force(sut, invalid_choice); CHECK(std::is_gt(nvalues_ordering(sut))); } + +TEST_SUITE_END(); // test_optional_argument diff --git a/tests/source/test_positional_argument.cpp b/tests/source/test_positional_argument.cpp index 759892c6..e246aa58 100644 --- a/tests/source/test_positional_argument.cpp +++ b/tests/source/test_positional_argument.cpp @@ -10,6 +10,8 @@ using ap::positional_argument; using ap::detail::argument_name; using ap::detail::parameter_descriptor; +TEST_SUITE_BEGIN("test_positional_argument"); + namespace { constexpr std::string_view help_msg = "test help msg"; @@ -505,3 +507,5 @@ TEST_CASE_FIXTURE( set_value_force(sut, invalid_choice); CHECK(std::is_gt(nvalues_ordering(sut))); } + +TEST_SUITE_END(); // test_positional_argument diff --git a/tests/source/test_string_utility.cpp b/tests/source/test_string_utility.cpp index cc5c686c..93b9b12f 100644 --- a/tests/source/test_string_utility.cpp +++ b/tests/source/test_string_utility.cpp @@ -8,6 +8,8 @@ using namespace ap::util; +TEST_SUITE_BEGIN("test_string_utility"); + namespace { constexpr std::string_view delimiter = ","; @@ -57,3 +59,5 @@ TEST_CASE("join should return a proper range representation for a multi element std::vector range = {1, 2, 3}; CHECK_EQ(join(range, delimiter), "1,2,3"); } + +TEST_SUITE_END(); // test_string_utility