Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
de36995
feat: add parallel support
daantimmer Mar 18, 2026
5952264
Add feature hooks support and corresponding tests
daantimmer Mar 18, 2026
f583896
refactor: rename parallel presets to asynchronous and add new configu…
daantimmer Mar 19, 2026
15dd373
fix: change return type to const for test case list in task latch ini…
daantimmer Mar 20, 2026
0d28299
fix: remove unnecessary loop in task creation for test cases
daantimmer Mar 20, 2026
e626bf0
Merge branch 'main' into feature/add-optional-parallel/async-support
daantimmer Mar 20, 2026
6fdada5
feat: add asynchronous support and update CI configurations
daantimmer Mar 20, 2026
54f62ff
fix: update cucumber_gherkin GIT_TAG to unreleased main and remove C+…
daantimmer Mar 20, 2026
52414ff
feat: update CI configuration to support asynchronous build and test …
daantimmer Mar 20, 2026
26cbedb
fix: remove global compile option and conditionally set target compil…
daantimmer Mar 20, 2026
4d126c1
feat: add cache variables for macOS Debug presets to specify Clang co…
daantimmer Mar 20, 2026
dc80b55
fix: update macOS Debug compiler paths to use LLVM 18
daantimmer Mar 20, 2026
3af94f7
refactor: simplify macOS Debug presets by removing redundant cache va…
daantimmer Mar 20, 2026
88e5a82
refactor: replace floating-point literals with integer constants for …
daantimmer Mar 20, 2026
2e7d140
refactor: change floating-point literals to std::size_t for time cons…
daantimmer Mar 20, 2026
66b8724
refactor: rename parameters in Step methods for clarity
daantimmer Mar 20, 2026
a4e3f74
fix: update cucumber_gherkin GIT_TAG to match unrelease PR
daantimmer Mar 20, 2026
a65fee8
refactor: remove unused runPassed member from Application class
daantimmer Mar 20, 2026
dcda946
refactor: mark parameters as maybe unused in step definitions
daantimmer Mar 20, 2026
a4987dc
fix: update cucumber_gherkin GIT_TAG to match unreleased main
daantimmer Mar 23, 2026
963455f
chore: update libcoro to forked version fixing Wall and Wextra being …
daantimmer Mar 29, 2026
fd1c628
Merge origin/main into feature/add-optional-parallel/async-support
Copilot May 28, 2026
797656a
fix(ci): define type and preset suffix matrix axes
Copilot May 28, 2026
5eb61e9
fix(ci): fix failing macOS GitHub Actions jobs (#344)
Copilot May 28, 2026
53d32ec
refactor(CMakeLists): reorganize testing and coverage options for cla…
daantimmer May 29, 2026
83539e8
refactor(Worker): improve envelope construction for test run hooks
daantimmer May 29, 2026
25deabc
fix(static-analysis): exclude additional directories from coverage co…
daantimmer May 29, 2026
71e08bf
Merge branch 'main' into feature/add-optional-parallel/async-support
daantimmer May 29, 2026
04d2e3e
refactor(ParallelRuntimeAdapter): replace bool with atomic_bool for t…
daantimmer May 29, 2026
36d68ba
feat(IdGenerator): add thread-safe ID generator for parallel support
daantimmer May 29, 2026
0b1ef99
fix(ParallelRuntimeAdapter): ensure task scheduling is correctly awai…
daantimmer May 29, 2026
a29b6b7
refactor(DefinitionRegistration): remove unused fmt includes and simp…
daantimmer May 29, 2026
71d54bb
refactor(SerialRuntimeAdapter): simplify failure checks for before an…
daantimmer May 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .clang-tidy
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Checks: '
-cppcoreguidelines-pro-bounds-constant-array-index,
-cppcoreguidelines-pro-type-cstyle-cast,
-cppcoreguidelines-special-member-functions,
-cppcoreguidelines-avoid-reference-coroutine-parameters,
misc-*,
-misc-no-recursion,
-misc-non-private-member-variables-in-classes,
Expand Down
13 changes: 9 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
container: ghcr.io/philips-software/amp-devcontainer-cpp:6.10.3@sha256:e1f388179dbeabaddcdd37b8b563ed89ca3cd36dcf158aa2e5c4f70eb513efec
strategy:
matrix:
target: [Host, Windows]
target: [Host, Host-Asynchronous, Windows]
fail-fast: false
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
Expand Down Expand Up @@ -65,8 +65,8 @@ jobs:
max-size: 2G
- uses: lukka/run-cmake@5d55ea7949e25f69f0ecb516d8d572297e03a956 # v10.9
with:
configurePreset: "Host"
buildPreset: "Host-Debug"
configurePreset: "Host-Asynchronous"
buildPreset: "Host-Asynchronous-Debug"
- run: |
bats --formatter junit cucumber_cpp/acceptance_test/test.bats | tee test-report.xml
- uses: EnricoMi/publish-unit-test-result-action@c950f6fb443cb5af20a377fd0dfaa78838901040 # v2.23.0
Expand All @@ -81,8 +81,13 @@ jobs:
matrix:
os: [macos, windows, ubuntu]
version: [latest]
type: [synchronous]
type: [synchronous, asynchronous]
preset_suffix: ["", "-no-re2"]
exclude:
- type: asynchronous
preset_suffix: "-no-re2"
- type: asynchronous
os: macos
fail-fast: false
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/static-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ jobs:

- name: Collect coverage
run: |
gcovr --sonarqube=coverage.xml --exclude-lines-by-pattern '.*assert\(.*\);|.*really_assert\(.*\);|.*std::abort();' --exclude-unreachable-branches --exclude-throw-branches -j "$(nproc)" --exclude=.*/example/.* --exclude=.*/external/.* --exclude=.*/test/.*
gcovr --sonarqube=coverage.xml --exclude-lines-by-pattern '.*assert\(.*\);|.*really_assert\(.*\);|.*std::abort();' --exclude-unreachable-branches --exclude-throw-branches -j "$(nproc)" --exclude=.*/example/.* --exclude=.*/external/.* --exclude=.*/test/.* --exclude=.*/_deps/.*

- uses: philips-software/sonarqube-issue-conversion@9e9958764ba5fd1d302b039779dc902bedfa4d01 # v1.2.0
with:
Expand Down
5 changes: 4 additions & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,10 @@
"args": [
"--format",
"pretty",
"summary",
// "summary",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

todo(?)

"--parallel",
"2",
"--fail-fast",
"--retry",
"1",
"--tags",
Expand Down
53 changes: 30 additions & 23 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")

project(cucumber-cpp-runner LANGUAGES C CXX VERSION 4.0.1) # x-release-please-version

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED On)
set(CMAKE_CXX_EXTENSIONS Off)

include(ccr_test_helpers)

if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
Expand All @@ -18,43 +22,22 @@ else()
set(CCR_EXCLUDE_FROM_ALL "EXCLUDE_FROM_ALL")
endif()


option(CCR_FETCH_DEPS "Fetch dependencies via FetchContent." ${CCR_DEFAULTOPT} )
option(CCR_BUILD_TESTS "Enable build of the tests" ${CCR_DEFAULTOPT})
option(CCR_USE_RE2 "Use the RE2 regex engine (fetched when CCR_FETCH_DEPS is set, otherwise auto-detected)" ${CCR_DEFAULTOPT})
option(CCR_ENABLE_COVERAGE "Enable compiler flags for code coverage measurements" Off)
option(CCR_ENABLE_TIME_PROFILE "Enable compiler flags for time profiling measurements" Off)
option(CCR_ENABLE_PARALLEL_SUPPORT "Enable parallel support through libcoro" Off)

set(CMAKE_POSITION_INDEPENDENT_CODE ON)

if (CCR_BUILD_TESTS)
ccr_enable_testing()
endif()

if (CCR_ENABLE_COVERAGE)
find_program(GCOVR_PATH gcovr)

if (NOT GCOVR_PATH)
message(FATAL_ERROR "Could not find gcovr, which is required for code coverage IDE integration")
endif()

add_custom_target(
generate-coverage-report
COMMAND ${GCOVR_PATH} --delete --lcov ${CMAKE_CURRENT_BINARY_DIR}/lcov.info
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "Generating code coverage report in LCOV format"
)
endif()

if (CCR_ENABLE_TIME_PROFILE)
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-ftime-trace)
endif()
endif()

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED On)
set(CMAKE_CXX_EXTENSIONS Off)

set_directory_properties(PROPERTY USE_FOLDERS ON)

include(FetchContent)
Expand All @@ -72,6 +55,10 @@ else()
find_package(cucumber_gherkin REQUIRED)
find_package(fmt REQUIRED)

if(CCR_ENABLE_PARALLEL_SUPPORT)
find_package(libcoro REQUIRED)
endif()

if (CCR_BUILD_TESTS)
find_package(yaml-cpp REQUIRED)
endif()
Expand All @@ -88,6 +75,26 @@ else()
set(CCR_HAS_RE2 Off)
endif()


if (CCR_BUILD_TESTS)
ccr_enable_testing()
endif()

if (CCR_ENABLE_COVERAGE)
find_program(GCOVR_PATH gcovr)

if (NOT GCOVR_PATH)
message(FATAL_ERROR "Could not find gcovr, which is required for code coverage IDE integration")
endif()

add_custom_target(
generate-coverage-report
COMMAND ${GCOVR_PATH} --lcov ${CMAKE_CURRENT_BINARY_DIR}/lcov.info
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "Generating code coverage report in LCOV format"
)
endif()

# Sanitizer flags are set after external dependencies so that fetched third-party
# libraries (abseil, re2) are not compiled with sanitizer instrumentation.
# Abseil's constexpr function-pointer comparisons are not compatible with GCC's
Expand Down
139 changes: 138 additions & 1 deletion CMakePresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,23 @@
"generator": "Ninja",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"CCR_ENABLE_COVERAGE": "On"
"CCR_ENABLE_COVERAGE": "On",
"CCR_ENABLE_PARALLEL_SUPPORT": "On"
}
},
{
"name": "Host",
"inherits": "defaults",
"generator": "Ninja Multi-Config"
},
{
"name": "Host-Asynchronous",
"inherits": "Host",
"generator": "Ninja Multi-Config",
"cacheVariables": {
"CCR_ENABLE_PARALLEL_SUPPORT": "On"
}
},
{
"name": "host-single-Debug-synchronous",
"hidden": true,
Expand Down Expand Up @@ -82,6 +91,32 @@
"CCR_USE_RE2": "Off"
}
},
{
"name": "host-single-Debug-asynchronous",
"hidden": true,
"inherits": "defaults",
"generator": "Ninja",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"CCR_ENABLE_PARALLEL_SUPPORT": "On"
}
},
{
"name": "ubuntu-Debug-asynchronous",
"displayName": "Configuration for Linux Debug and Tests, Single Config Generator, asynchronous",
"inherits": "host-single-Debug-asynchronous"
},
{
"name": "windows-Debug-asynchronous",
"displayName": "Configuration for Windows Debug and Tests, Single Config Generator, asynchronous",
"inherits": "host-single-Debug-asynchronous",
"toolchainFile": "${sourceDir}/cmake/Windows.MSVC.toolchain.cmake"
},
{
"name": "macos-Debug-asynchronous",
"displayName": "Configuration for macOS Debug and Tests, Single Config Generator, asynchronous",
"inherits": "host-single-Debug-asynchronous"
},
{
"name": "host-single-time-profile",
"displayName": "Configuration time profiling",
Expand Down Expand Up @@ -111,6 +146,13 @@
"CCACHE_COMPILERTYPE": "clang-cl"
},
"generator": "Ninja Multi-Config"
},
{
"name": "Windows-Asynchronous",
"inherits": "Windows",
"cacheVariables": {
"CCR_ENABLE_PARALLEL_SUPPORT": "On"
}
}
],
"buildPresets": [
Expand All @@ -129,6 +171,17 @@
"configurePreset": "Host",
"jobs": 4
},
{
"name": "Host-Asynchronous-Release",
"configuration": "Release",
"configurePreset": "Host-Asynchronous"
},
{
"name": "Host-Asynchronous-Debug",
"configuration": "Debug",
"configurePreset": "Host-Asynchronous",
"jobs": 4
},
{
"name": "Host-Iwyu-Debug",
"configuration": "Debug",
Expand Down Expand Up @@ -164,6 +217,21 @@
"configuration": "Debug",
"configurePreset": "macos-Debug-synchronous-no-re2"
},
{
"name": "ubuntu-Debug-asynchronous",
"configuration": "Debug",
"configurePreset": "ubuntu-Debug-asynchronous"
},
{
"name": "windows-Debug-asynchronous",
"configuration": "Debug",
"configurePreset": "windows-Debug-asynchronous"
},
{
"name": "macos-Debug-asynchronous",
"configuration": "Debug",
"configurePreset": "macos-Debug-asynchronous"
},
{
"name": "host-single-time-profile",
"configuration": "Debug",
Expand Down Expand Up @@ -250,6 +318,24 @@
"configurePreset": "macos-Debug-synchronous-no-re2",
"configuration": "Debug",
"inherits": "defaults"
},
{
"name": "ubuntu-Debug-asynchronous",
"configurePreset": "ubuntu-Debug-asynchronous",
"configuration": "Debug",
"inherits": "defaults"
},
{
"name": "windows-Debug-asynchronous",
"configurePreset": "windows-Debug-asynchronous",
"configuration": "Debug",
"inherits": "defaults"
},
{
"name": "macos-Debug-asynchronous",
"configurePreset": "macos-Debug-asynchronous",
"configuration": "Debug",
"inherits": "defaults"
}
],
"workflowPresets": [
Expand Down Expand Up @@ -354,6 +440,57 @@
"name": "macos-Debug-synchronous-no-re2"
}
]
},
{
"name": "ubuntu-Debug-asynchronous",
"steps": [
{
"type": "configure",
"name": "ubuntu-Debug-asynchronous"
},
{
"type": "build",
"name": "ubuntu-Debug-asynchronous"
},
{
"type": "test",
"name": "ubuntu-Debug-asynchronous"
}
]
},
{
"name": "windows-Debug-asynchronous",
"steps": [
{
"type": "configure",
"name": "windows-Debug-asynchronous"
},
{
"type": "build",
"name": "windows-Debug-asynchronous"
},
{
"type": "test",
"name": "windows-Debug-asynchronous"
}
]
},
{
"name": "macos-Debug-asynchronous",
"steps": [
{
"type": "configure",
"name": "macos-Debug-asynchronous"
},
{
"type": "build",
"name": "macos-Debug-asynchronous"
},
{
"type": "test",
"name": "macos-Debug-asynchronous"
}
]
}
]
}
2 changes: 1 addition & 1 deletion compatibility/BaseCompatibility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ namespace compatibility
auto contextStorageFactory{ std::make_shared<cucumber_cpp::library::ContextStorageFactoryImpl>() };
auto programContext{ std::make_unique<cucumber_cpp::Context>(contextStorageFactory) };

cucumber_cpp::library::util::Broadcaster broadcaster;
cucumber_cpp::library::util::BroadcasterImpl broadcaster;

BroadcastListener broadcastListener{ devkit.ndjsonFile, devkit.ndjsonFile.parent_path() / "expected.ndjson", devkit.ndjsonFile.parent_path() / "actual.ndjson", broadcaster };

Expand Down
4 changes: 2 additions & 2 deletions compatibility/ambiguous/ambiguous.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
#include "cucumber_cpp/Steps.hpp"
#include <string>

STEP(R"(^a (.*?) with (.*?)$)", (const std::string& arg1, const std::string& arg2))
STEP(R"(^a (.*?) with (.*?)$)", ([[maybe_unused]] const std::string& arg1, [[maybe_unused]] const std::string& arg2))
{
// no-op
}

STEP(R"(^a step with (.*?)$)", (const std::string& arg1))
STEP(R"(^a step with (.*?)$)", ([[maybe_unused]] const std::string& arg1))
{
// no-op
}
2 changes: 1 addition & 1 deletion compatibility/minimal/minimal.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "cucumber_cpp/Steps.hpp"
#include <cstdint>

STEP(R"(I have {int} cukes in my belly)", (std::int32_t number))
STEP(R"(I have {int} cukes in my belly)", ([[maybe_unused]] std::int32_t number))
{
// no-op
}
2 changes: 1 addition & 1 deletion compatibility/regular-expression/regular-expression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#include <optional>
#include <string>

STEP(R"(^a (.*?)(?: and a (.*?))?(?: and a (.*?))?$)", (const std::optional<std::string>& vegetable1, const std::optional<std::string>& vegetable2, const std::optional<std::string>& vegetable3))
STEP(R"(^a (.*?)(?: and a (.*?))?(?: and a (.*?))?$)", ([[maybe_unused]] const std::optional<std::string>& vegetable1, [[maybe_unused]] const std::optional<std::string>& vegetable2, [[maybe_unused]] const std::optional<std::string>& vegetable3))
{
// no-op
}
Loading
Loading