Skip to content

Commit

Permalink
Merge pull request #58 from ThoSe1990/fix/remove-warnings
Browse files Browse the repository at this point in the history
Fix/remove warnings
  • Loading branch information
ThoSe1990 authored Nov 13, 2024
2 parents 750027a + 554c3a5 commit 2208d6d
Show file tree
Hide file tree
Showing 12 changed files with 94 additions and 74 deletions.
49 changes: 37 additions & 12 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ on:
branches: [ "**" ]

jobs:
build-gcc:
gcc:
runs-on: ubuntu-latest
container: those90/ci-image:1.0
env:
Expand All @@ -22,18 +22,15 @@ jobs:
- name: build
run: |
conan install . -of ./build_gcc --build missing
cmake -S . -B ./build_gcc -DCMAKE_TOOLCHAIN_FILE=./build_gcc/conan_toolchain.cmake
ls -la ./gtest
ls -la ./gtest/test_files
cat ./gtest/test_paths.hpp
echo "****"
pwd
echo "****"
cmake -S . -B ./build_gcc -DCMAKE_TOOLCHAIN_FILE=./build_gcc/conan_toolchain.cmake -DCMAKE_CXX_COMPILER=g++ -DCMAKE_C_COMPILER=gcc
cmake --build ./build_gcc -j12
- name: unittests
run: ./build_gcc/bin/unittests
- name: example
run: ./build_gcc/bin/example ./examples

build-clang:

Clang:
runs-on: ubuntu-latest
container: those90/ci-image:1.0
env:
Expand All @@ -45,10 +42,38 @@ jobs:
run: |
conan install . -of ./build_clang --build missing -pr clang
cmake -S . -B ./build_clang -DCMAKE_TOOLCHAIN_FILE=./build_clang/conan_toolchain.cmake -DCMAKE_CXX_COMPILER=clang++-17 -DCMAKE_C_COMPILER=clang-17
ls -la ./gtest
ls -la ./gtest/test_files
cat ./gtest/test_paths.hpp
cmake --build ./build_clang -j12
- name: unittests
run: ./build_clang/bin/unittests
- name: examples
run: ./build_clang/bin/example ./examples

MSVC:
runs-on: windows-latest
steps:
- name: checkout repo
uses: actions/checkout@v2
- name: set up Python
uses: actions/setup-python@v2
with:
python-version: '3.12'
- name: install pip tools
run: |
python -m pip install --upgrade pip
pip install cmake conan
- name: conan
run: |
conan --version
conan profile detect
powershell -Command "(gc C:\Users\runneradmin\.conan2\profiles\default) -replace 'compiler.cppstd=14', 'compiler.cppstd=20' | Out-File -encoding ASCII C:\Users\runneradmin\.conan2\profiles\default"
powershell -Command "(gc C:\Users\runneradmin\.conan2\profiles\default) -replace 'compiler.runtime=dynamic', 'compiler.runtime=static' | Out-File -encoding ASCII C:\Users\runneradmin\.conan2\profiles\default"
conan profile show
- name: build
run: |
conan install . -of build --build missing
cmake -S . -B ./build -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=".\build\conan_toolchain.cmake" -DMSVC_STATIC=ON
cmake --build ./build --config Release -j12
- name: unittests
run: .\build\bin\Release\unittests.exe
- name: example
run: .\build\bin\Release\example.exe ./examples
1 change: 0 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
- Define custom types with `CUSTOM_PARAMETER(function-name, "{your type}", "regex pattern", "description") { your callback implementation }`
- In your callback implement how to consume capture groups
- Access capture groups with `CUKE_PARAM_ARG(index)`, where index starts at 1 and goes from left to write
- Description is an argument in `CUKE_PARAMETER` ([57](https://github.com/ThoSe1990/cwt-cucumber/pull/57))
- Renamed example target `box` to `example` ([56](https://github.com/ThoSe1990/cwt-cucumber/pull/56))

## [2.3.1] 2024-10-23
Expand Down
8 changes: 8 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif()

option(MSVC_STATIC "Use static runtime libraries with MSVC" OFF)

if(MSVC_STATIC)
message(STATUS "MSVC: Setting MT/MTd")
cmake_policy(SET CMP0091 NEW)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
endif()

set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
Expand Down
30 changes: 20 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
[![CI](https://github.com/ThoSe1990/cucumber-cpp/actions/workflows/main.yml/badge.svg?branch=main)](https://github.com/ThoSe1990/cucumber-cpp/actions/workflows/main.yml) [![Build Status](https://dev.azure.com/thomassedlmair/cwt-cucumber/_apis/build/status%2FThoSe1990.cwt-cucumber?branchName=main)](https://dev.azure.com/thomassedlmair/cwt-cucumber/_build/latest?definitionId=14&branchName=main)

[![CI](https://github.com/ThoSe1990/cucumber-cpp/actions/workflows/main.yml/badge.svg?branch=main)](https://github.com/ThoSe1990/cucumber-cpp/actions/workflows/main.yml)

## Coding With Thomas Cucumber: A C++ Cucumber Interpreter

Expand Down Expand Up @@ -566,26 +565,25 @@ If you want to execute all feature files in a directory (and subdirectory), just

CWT-Cucumber supports custom parameter types. This means that we can define custom expressions in our steps to introduce custom types (so to speak) and make the step definition more understandable.

In general: A custom parameter type is an individually defined type that we can use in the step definition. So we give the parameter a function name (as in a step), give the custom type a meaningful name, a description and a regex pattern. Then we implement a callback to consume the capture groups from the regex pattern. Here we use `CUSTOM_PARAMETER(function-name, "{here goes your type}", "regex pattern", "optional: description")`.
In general: A custom parameter type is an individually defined type that we can use in the step definition. So we give the parameter a function name (as in a step), give the custom type a meaningful name, a description and a regex pattern. Then we implement a callback to consume the capture groups from the regex pattern. Here we use `CUSTOM_PARAMETER(function-name, "{here goes your type}", "regex pattern", "description")`.

- Function-name: A defined function name (same as in steps)
- Custom-Type: Define the type you want, **with curly braces** as string
- Regex-Pattern: The regex pattern to match the step, you can use raw string literals, which makes it easier to write regex pattern (see below)
- **Optional** description: A string value to give a meaning full description. This will be printed to the catalog and has no effect on the scenarios.
- Description: A string value to give a meaning full description. This will be printed to the catalog and has no effect on the scenarios.

In order to access the capture groups, use `CUKE_PARAM_ARG(index)` where the index starts at 1 from left to right.

**Note: You must explicitly return the dedicated type in the callback. The implementation uses type erasure and does not know which type will be used later.**



Find all implementations in `examples/step_definition.cpp` and the examples in `examples/features/8_custom_parameters.feature`.

### Example: Pair of Integers

Lets define a type `{pair of integers}`, which will create a `std::pair<int,int>`:

```cpp
CUSTOM_PARAMETER(custom, "{pair of integers}", R"(var1=(\d+), var2=(\d+))")
CUSTOM_PARAMETER(custom, "{pair of integers}", R"(var1=(\d+), var2=(\d+))", "a pair of integers")
{
int var1 = CUKE_PARAM_ARG(1);
int var2 = CUKE_PARAM_ARG(2);
Expand Down Expand Up @@ -620,7 +618,7 @@ A more complex example is defined below. We want to parse an event (which is rep
`{event}` is fairly easy here:

```cpp
CUSTOM_PARAMETER(custom_event, "{event}", R"('(.*?)')")
CUSTOM_PARAMETER(custom_event, "{event}", R"('(.*?)')", "a custom event")
{
return CUKE_PARAM_ARG(1).to_string();
}
Expand Down Expand Up @@ -653,12 +651,12 @@ CUSTOM_PARAMETER(
"a custom date pattern")
{
date begin;
begin.month = std::string(CUKE_PARAM_ARG(1));
begin.month = CUKE_PARAM_ARG(1).to_string();
begin.day = int(CUKE_PARAM_ARG(2));
begin.year = CUKE_PARAM_ARG(3).as<int>();

date end;
end.month = static_cast<std::string>(CUKE_PARAM_ARG(4));
end.month = CUKE_PARAM_ARG(4).to_string();
end.day = static_cast<int>(CUKE_PARAM_ARG(5));
end.year = CUKE_PARAM_ARG(6).as<int>();

Expand Down Expand Up @@ -689,6 +687,18 @@ Scenario: Date example
Then The beginning month is April and the ending month is Mai
```

### Strings in Custom Type Parameters

There are two options in order to create a string value. Some compiler have problems with can not find the correct string type. Therefore we have two options to create a string value from a regex capture:

Option 1: Dedicated `to_string()` function:
```cpp
CUKE_PARAM_ARG(..).to_string();
```
Option 2: Initialize a `std::string`
```cpp
std::string str = CUKE_PARAM_ARG(..)
```

## Catalog

Expand Down
28 changes: 0 additions & 28 deletions azure-pipelines.yml

This file was deleted.

1 change: 0 additions & 1 deletion examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ add_executable(${target}
install(
TARGETS ${target}
COMPONENT test

)

target_include_directories(${target} PRIVATE ${PROJECT_SOURCE_DIR}/src)
Expand Down
9 changes: 5 additions & 4 deletions examples/step_definition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,22 @@ CUSTOM_PARAMETER(
"a custom date pattern")
{
date begin;
begin.month = std::string(CUKE_PARAM_ARG(1));
begin.month = CUKE_PARAM_ARG(1).to_string();
begin.day = int(CUKE_PARAM_ARG(2));
begin.year = CUKE_PARAM_ARG(3).as<int>();

date end;
end.month = static_cast<std::string>(CUKE_PARAM_ARG(4));
end.month = CUKE_PARAM_ARG(4).to_string();
end.day = static_cast<int>(CUKE_PARAM_ARG(5));
end.year = CUKE_PARAM_ARG(6).as<int>();

return date_range{begin, end};
}

CUSTOM_PARAMETER(custom_event, "{event}", R"('(.*?)')")
CUSTOM_PARAMETER(custom_event, "{event}", R"('(.*?)')", "a custom event")
{
return CUKE_PARAM_ARG(1).to_string();
std::string event = CUKE_PARAM_ARG(1);
return event;
}

WHEN(using_date, "{event} is {date}")
Expand Down
11 changes: 1 addition & 10 deletions src/defines.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@
[[maybe_unused]] cuke::value_array::const_iterator __cuke__values__, \
[[maybe_unused]] std::size_t __cuke__values__count__)

#define GET_MACRO(_1, _2, _3, _4, NAME, ...) NAME
/**
* @def CUSTOM_PARAMETER(function_name, key, pattern, opt: description)
* @brief Creates a custom expression type to use in steps.
Expand All @@ -67,17 +66,9 @@
* @param description Optional description: This description is only printed as
* is in the steps-catalog.
*/
#define CUSTOM_PARAMETER(...) \
GET_MACRO(__VA_ARGS__, _CUSTOM_PARAMETER_WITH_DESC, \
_CUSTOM_PARAMETER_NO_DESC) \
(__VA_ARGS__)

#define _CUSTOM_PARAMETER_WITH_DESC(function_name, key, pattern, description) \
#define CUSTOM_PARAMETER(function_name, key, pattern, description) \
_CUSTOM_PARAMETER_IMPL(function_name, key, pattern, description)

#define _CUSTOM_PARAMETER_NO_DESC(function_name, key, pattern) \
_CUSTOM_PARAMETER_IMPL(function_name, key, pattern, "No description found")

/**
* @def CUKE_PARAM_ARG(index)
* @brief Access capture groups from a custom expression in its callback.
Expand Down
14 changes: 12 additions & 2 deletions src/get_args.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#pragma once

#include <iterator>
#include <stdexcept>
#include <string_view>
#include <type_traits>

#include "param_info.hpp"
#include "value.hpp"
Expand All @@ -20,8 +22,16 @@ struct conversion
template <typename T>
operator T() const
{
return cuke::registry().get_expression(key).callback(begin + idx,
values_count);
// NOTE: MSVC treats std::size_t differently then mac/linux
if constexpr (std::is_same_v<T, std::size_t>)
{
return make_parameter_value<std::size_t>(begin + idx, values_count);
}
else
{
return cuke::registry().get_expression(key).callback(begin + idx,
values_count);
}
}
};

Expand Down
2 changes: 2 additions & 0 deletions src/step.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ std::string to_string(step::type type)
return "Then";
case step::type::step:
return "Step";
default:
return "...";
}
}
} // namespace cuke::internal
8 changes: 4 additions & 4 deletions src/util_regex.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,12 @@ create_regex_definition(const std::string& step)
return {result, type_info};
}

static const std::unordered_set<char> special_chars = {
'.', '^', '$', '*', '+', '?', '[', ']', /* '(', ')', */ '\\',
/* '|' */};

static std::string add_escape_chars(const std::string& input)
{
static const std::unordered_set<char> special_chars = {
'.', '^', '$', '*', '+', '?', '[', ']', /* '(', ')', */ '\\',
/* '|' */};

std::string result;
for (char c : input)
{
Expand Down
7 changes: 5 additions & 2 deletions src/value.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include <string_view>
#include <vector>
#include <string>
#include <format>
Expand Down Expand Up @@ -33,12 +34,13 @@ class value

~value() = default;

operator const std::string&() const { return m_value; }

template <typename T>
operator T() const
{
return this->as<T>();
}

/**
* @brief Checks if the cuke::value is nil
* @return True if it is a nil type, else its false
Expand Down Expand Up @@ -112,7 +114,8 @@ class value
* @brief Converts the underlying value to a string. If not possible, this
* function throws a std::runtime_error
*/
[[nodiscard]] std::string to_string() const { return m_value; }
[[nodiscard]] std::string to_string() { return m_value; }
[[nodiscard]] const std::string& to_string() const { return m_value; }

private:
std::string m_value;
Expand Down

0 comments on commit 2208d6d

Please sign in to comment.