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