Skip to content

test the module with more complex parsing tests - #1321

Open
phlptp wants to merge 3 commits into
CLIUtils:mainfrom
phlptp:module_testing
Open

test the module with more complex parsing tests#1321
phlptp wants to merge 3 commits into
CLIUtils:mainfrom
phlptp:module_testing

Conversation

@phlptp

@phlptp phlptp commented Mar 24, 2026

Copy link
Copy Markdown
Collaborator

Looking #1318, adding a more complex test for modules using subcommands and different types of options

@codecov

codecov Bot commented Mar 24, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (4d2aa8c) to head (fe4f37a).

Additional details and impacted files
@@            Coverage Diff            @@
##              main     #1321   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           19        19           
  Lines         5225      5225           
  Branches      1131      1131           
=========================================
  Hits          5225      5225           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@henryiii

Copy link
Copy Markdown
Collaborator

🤖 AI text below 🤖

Pushed a touch-up: the new options were registered but never parsed (the only invocation was module-test one), so the #1318 failure mode (long options rejected in module builds) was not exercised. The test app now prints the parsed values, and three ctest cases pass long options, short options, and an option-group option. Also made -o,--output bind the previously unused output variable instead of value. Verified locally with LLVM clang 22 on macOS: all 5 tests pass.

phlptp and others added 3 commits July 29, 2026 18:10
…e test

The new options were registered but never parsed; the only test invocation
was 'module-test one'. Add ctest cases that pass long options, short
options, and an option-group option through the module build, and print
the parsed values so PASS_REGULAR_EXPRESSION can verify them (see CLIUtils#1318).

Assisted-by: ClaudeCode:claude-fable-5
henryiii added a commit that referenced this pull request Jul 31, 2026
… the real floor (#1413)

Close #194.

:robot: _AI text below_ :robot:

Named-module support (`import cli11;`) already landed in #1286 with CI
in #1388, so this PR builds on that work instead of adding a new module.
It makes the C++20 floor real, compiles the module in precompiled mode
so importers build fast, makes `CLI11::Module` work everywhere, and
documents it all — toward the module ask in #194.

## Changes

- Lower the `CLI11_Module` compile-feature floor from `cxx_std_23` to
`cxx_std_20`. The interface unit only re-exports names from the C++11
headers.
- Compile the module in precompiled mode: define `CLI11_COMPILE` on the
target (PUBLIC, so importers agree) and build `src/Precompile.cpp` into
the module library. When `CLI11_PRECOMPILED` is also ON, link the
`CLI11` static library instead to avoid duplicate implementation
objects. Previously the global module fragment held the full header-only
library, so every importing TU re-optimized every inline function body;
now it holds declarations only.
- Make `CLI11::Module` work everywhere without renaming anything: the
installed `CLI11Config.cmake` is now a small wrapper that includes the
exported `CLI11Targets.cmake` and adds `CLI11::Module` as an alias of
`CLI11::CLI11_Module` (guarded so the config still loads on the 3.14
project minimum without modules), and the build tree gains the matching
`CLI11::CLI11_Module` alias. Both names work for both `find_package` and
`add_subdirectory`; nothing breaks for 2.7.x consumers.
- Fail configure with a clear message when `CLI11_MODULES` is on and
CMake < 3.28 (project minimum is 3.14, so the `FILE_SET CXX_MODULES`
error was cryptic).
- Make `tests/module_test` compile at C++20 (`std::cout` instead of
`std::println`, default standard 20) and link the recommended
`CLI11::Module` name.
- Move the test's includes before `import cli11;` — GCC 16 rejects
textual includes that follow an import whose global module fragment
overlaps them (clang accepts either order).
- Docs: fix the target name in the book (it said `CLI11::Modules`, which
never existed), recommend `CLI11::Module`, note that macros
(`CLI11_PARSE`) do not come through the import, add a short
experimental-modules bullet to the README, and add a complete minimal
example (CMakeLists + source) plus an `import std;` variant on a new
book Examples page (`book/chapters/modules-example.md`) with direct
clang/libc++ commands — CMake's own `import std` support
(`CMAKE_CXX_MODULE_STD`, 3.30+) is still behind the
`CMAKE_EXPERIMENTAL_CXX_IMPORT_STD` gate, so the book does not show it.
- CI: the clang module install-test job now covers C++20/23/26 and the
gcc job enables `CLI11_MODULES` at C++20/23.

## Measured client compile time

Per-TU compile of a 3-option app doing `import cli11;`, CMake-built
Release artifacts, Homebrew clang 22.1.8, C++20, macOS arm64 (best of
3):

| Module configuration                    | Client TU |
| --------------------------------------- | --------- |
| Before (header-only in the GMF)         | 1.30 s    |
| After (`CLI11_COMPILE` + precompiled)   | 0.27 s    |

For reference, a header-only `#include <CLI/CLI.hpp>` TU is ~1.9 s and a
`CLI11_PRECOMPILED` header client is ~0.55 s on the same machine, so the
module is now the fastest consumption mode. The `import std;` variant of
the book example (C++23, manual clang commands, `std::println`) builds
and runs correctly; its client TU is ~0.5 s, dominated by format
machinery in the app itself.

## Tested (macOS arm64, CMake 4.4.0, Ninja 1.13.2)

- Homebrew clang 22.1.8, `-std=c++20`: `CLI11_MODULES=ON` build,
install, `tests/module_test` (both tests pass) with `CLI11_PRECOMPILED`
OFF and ON, plus an out-of-tree smoke app that does `import cli11;` and
parses `-f/--file` and `-n/--count` (long form, short form, and the
required-option error path).
- Homebrew gcc 16.1.0, `-std=c++20`: same build/install/module_test
cycle passes after the include-order fix; before it, `#include
<iostream>` after the import failed with redefinition errors.
- Target names: installed package and build tree each consumed through
both `CLI11::Module` and `CLI11::CLI11_Module`, on both toolchains; a
plain non-module install still loads the config, links `CLI11::CLI11`,
and defines no `CLI11::Module`.
- `import std` + `import cli11` composed at C++23 with clang/libc++
(manual `--precompile` of `std.cppm` and `CLI11.cppm`, `-fmodule-file=`
for both), exactly the commands now shown in the book.
- Non-module regression check: full `dev` preset build, all 24 tests
pass.

## Known limitations

- Macros are not exported by modules, so `CLI11_PARSE` needs a header
include or a manual try/catch around `app.parse()`.
- A TU that imports the module and also includes CLI11 headers must see
`-DCLI11_COMPILE` (propagated automatically through the CMake target);
header includes without the definition would create inline duplicates of
the compiled implementation.
- Include-after-import is fragile on GCC in user code; the docs show
includes first.
- CMake `import std` integration is not wired up (still experimental
upstream); the book documents the manual toolchain invocation instead.
- Not tested here: MSVC, Apple system clang.

Runtime-coverage expansion of the module test is left to #1321.

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants