Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
0b65602
Set up environment to write e2e tests
NeaguGeorgiana23 Feb 17, 2026
becd972
fic clang
NeaguGeorgiana23 Feb 17, 2026
296e01a
add linter rule
NeaguGeorgiana23 Feb 17, 2026
b78cef6
Create communication with cucumber
NeaguGeorgiana23 Feb 18, 2026
8467f3e
update Ruby version
NeaguGeorgiana23 Feb 18, 2026
c83ef34
update Ruby version
NeaguGeorgiana23 Feb 18, 2026
e6c6fa8
Merge branch 'e2e' of https://github.com/open-feature/cpp-sdk into e2e
NeaguGeorgiana23 Feb 18, 2026
17352e9
Merge branch 'e2e' of https://github.com/open-feature/cpp-sdk into e2e
NeaguGeorgiana23 Feb 18, 2026
c268484
Merge branch 'e2e' of https://github.com/open-feature/cpp-sdk into e2e
NeaguGeorgiana23 Feb 19, 2026
f17b6b0
Merge branch 'main' into e2e
NeaguGeorgiana23 Feb 19, 2026
22cab23
Merge branch 'main' into e2e
NeaguGeorgiana23 Feb 19, 2026
3ce7352
e2e tests for MVP.
NeaguGeorgiana23 Feb 23, 2026
7a760e1
e2e tests for MVP.
NeaguGeorgiana23 Feb 23, 2026
9ed42fc
Merge branch 'e2e' of https://github.com/open-feature/cpp-sdk into e2e
NeaguGeorgiana23 Feb 23, 2026
28d332e
Merge branch 'e2e' of https://github.com/open-feature/cpp-sdk into e2e
NeaguGeorgiana23 Feb 23, 2026
cd37ddb
Merge branch 'e2e' of https://github.com/open-feature/cpp-sdk into e2e
NeaguGeorgiana23 Feb 23, 2026
3d2fdd2
Merge branch 'main' into e2e
NeaguGeorgiana23 Feb 24, 2026
cefcf9a
add recursive submodules checkout for bazel build
NeaguGeorgiana23 Feb 24, 2026
4bfcdd4
Merge branch 'main' into e2e
NeaguGeorgiana23 Feb 25, 2026
52c3814
resolve comments
NeaguGeorgiana23 Feb 25, 2026
5666dbc
resolve comments
NeaguGeorgiana23 Feb 25, 2026
d3f6639
Merge branch 'e2e' of https://github.com/open-feature/cpp-sdk into e2e
NeaguGeorgiana23 Feb 25, 2026
86c54e2
Merge branch 'e2e' of https://github.com/open-feature/cpp-sdk into e2e
NeaguGeorgiana23 Feb 25, 2026
35bb8a3
Merge branch 'e2e' of https://github.com/open-feature/cpp-sdk into e2e
NeaguGeorgiana23 Feb 25, 2026
97547bf
Merge branch 'e2e' of https://github.com/open-feature/cpp-sdk into e2e
NeaguGeorgiana23 Feb 25, 2026
f1e1f43
Merge branch 'e2e' of https://github.com/open-feature/cpp-sdk into e2e
NeaguGeorgiana23 Feb 25, 2026
839ea00
only run gherkin scenarios relevant for the MVP.
NeaguGeorgiana23 Feb 26, 2026
815f867
only run gherkin scenarios relevant for the MVP.
NeaguGeorgiana23 Feb 26, 2026
d27dd34
Merge branch 'e2e' of https://github.com/open-feature/cpp-sdk into e2e
NeaguGeorgiana23 Feb 26, 2026
b61700a
Merge branch 'e2e' of https://github.com/open-feature/cpp-sdk into e2e
NeaguGeorgiana23 Feb 26, 2026
a05d777
Merge branch 'e2e' of https://github.com/open-feature/cpp-sdk into e2e
NeaguGeorgiana23 Feb 26, 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
4 changes: 4 additions & 0 deletions .github/workflows/ci-format-test-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
submodules: 'recursive'

- uses: bazel-contrib/setup-bazel@0.18.0
with:
Expand All @@ -28,6 +30,8 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
submodules: 'recursive'

- uses: bazel-contrib/setup-bazel@0.18.0
with:
Expand Down
7 changes: 7 additions & 0 deletions BUILD
Original file line number Diff line number Diff line change
@@ -1 +1,8 @@
load("@rules_gherkin//gherkin:defs.bzl", "gherkin_library")

package(default_visibility = ["//visibility:public"])

gherkin_library(
name = "openfeature_gherkin_spec_features",
srcs = glob(["spec/specification/assets/gherkin/evaluation.feature"]),
)
3 changes: 3 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
source 'https://rubygems.org'
gem 'cucumber', '~> 10.2.0'
gem 'cucumber-wire', '~> 8.0.0'
56 changes: 56 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
GEM
remote: https://rubygems.org/
specs:
base64 (0.3.0)
bigdecimal (4.0.1)
bigdecimal (4.0.1-java)
builder (3.3.0)
cucumber (10.2.0)
base64 (~> 0.2)
builder (~> 3.2)
cucumber-ci-environment (> 9, < 12)
cucumber-core (> 15, < 17)
cucumber-cucumber-expressions (> 17, < 20)
cucumber-html-formatter (> 21, < 23)
diff-lcs (~> 1.5)
logger (~> 1.6)
mini_mime (~> 1.1)
multi_test (~> 1.1)
sys-uname (~> 1.3)
cucumber-ci-environment (11.0.0)
cucumber-core (15.4.0)
cucumber-gherkin (> 27, < 40)
cucumber-messages (> 26, < 33)
cucumber-tag-expressions (> 5, < 9)
cucumber-cucumber-expressions (19.0.0)
bigdecimal
cucumber-gherkin (38.0.0)
cucumber-messages (>= 31, < 33)
cucumber-html-formatter (22.3.0)
cucumber-messages (> 23, < 33)
cucumber-messages (32.0.1)
cucumber-tag-expressions (8.1.0)
cucumber-wire (8.0.0)
cucumber-core (> 11, < 16)
cucumber-cucumber-expressions (> 14, < 20)
diff-lcs (1.6.2)
ffi (1.17.3-java)
ffi (1.17.3-x86_64-linux-gnu)
logger (1.7.0)
memoist3 (1.0.0)
mini_mime (1.1.5)
multi_test (1.1.0)
sys-uname (1.5.0)
ffi (~> 1.1)
memoist3 (~> 1.0.0)

PLATFORMS
universal-java-11
x86_64-linux

DEPENDENCIES
cucumber (~> 10.2.0)
cucumber-wire (~> 8.0.0)

BUNDLED WITH
2.4.19
20 changes: 20 additions & 0 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,26 @@ module(name = "openfeature_cpp_sdk")
bazel_dep(name = "googletest", version = "1.17.0.bcr.2")
bazel_dep(name = "abseil-cpp", version = "20250814.2")
bazel_dep(name = "rules_cc", version = "0.2.17")
bazel_dep(name = "cucumber-cpp", version = "0.8.0.bcr.1")

bazel_dep(name = "rules_gherkin", version = "0.2.0")
bazel_dep(name = "rules_ruby", version = "0.21.1")

# Hermetic Ruby Toolchain Configuration
ruby = use_extension("@rules_ruby//ruby:extensions.bzl", "ruby")
ruby.toolchain(
name = "ruby",
version = "3.2.2", # JRuby or standard MRI version suitable for execution
)

# Cucumber Gem provisioning via Bundler integration
ruby.bundle_fetch(
name = "cucumber",
gemfile = "//:Gemfile",
gemfile_lock = "//:Gemfile.lock",
)
use_repo(ruby, "cucumber", "ruby", "ruby_toolchains")
register_toolchains("@ruby_toolchains//:all")

# Hedron's Compile Commands Extractor for Bazel
# https://github.com/hedronvision/bazel-compile-commands-extractor
Expand Down
1 change: 1 addition & 0 deletions spec
Submodule spec added at eefdf4
6 changes: 4 additions & 2 deletions test/BUILD
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test")

package(
default_visibility = ["//visibility:public"],
)

cc_library(
name = "mock_feature_provider",
testonly = True,
hdrs = ["mocks/mock_feature_provider.h"],
visibility = ["//test:__pkg__"],
deps = [
"//openfeature:provider",
"@googletest//:gtest",
Expand Down
60 changes: 60 additions & 0 deletions test/e2e/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
load("@rules_cc//cc:defs.bzl", "cc_library")
load("@rules_gherkin//gherkin:defs.bzl", "gherkin_test")

package(
default_visibility = ["//visibility:public"],
)

cc_library(
name = "context_storing_provider",
srcs = [
"context_storing_provider.cpp",
],
hdrs = [
"context_storing_provider.h",
],
include_prefix = "test/e2e",
deps = [
"//openfeature:evaluation_context",
"//openfeature:flag_metadata",
"//openfeature:metadata",
"//openfeature:provider",
"//openfeature:reason",
"//openfeature:value",
"//openfeature:resolution_details",
"@cucumber-cpp//:cucumber-cpp",
"@googletest//:gtest",
],
)

cc_library(
name = "flag_test",
hdrs = [
"flag_test.h",
],
include_prefix = "test/e2e",
)

cc_library(
name = "state",
hdrs = [
"state.h",
],
include_prefix = "test/e2e",
deps = [
"//openfeature:client",
"//openfeature:evaluation_context",
"//openfeature:provider",
"//openfeature:resolution_details",
"//openfeature:value",
":flag_test",
],
)

gherkin_test(
name = "openfeature_gherkin_e2e_tests",
steps = "//test/e2e/steps:gherkin_step_definitions",
deps = [
"//:openfeature_gherkin_spec_features",
],
)
75 changes: 75 additions & 0 deletions test/e2e/context_storing_provider.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#include "test/e2e/context_storing_provider.h"

#include <gtest/gtest.h>

#include <cucumber-cpp/autodetect.hpp>
#include <optional>

#include "openfeature/flag_metadata.h"
#include "openfeature/reason.h"
#include "openfeature/value.h"

using cucumber::ScenarioScope;

namespace openfeature_e2e {

openfeature::Metadata ContextStoringProvider::GetMetadata() const {
return openfeature::Metadata{"ContextStoringProvider"};
}

std::unique_ptr<openfeature::BoolResolutionDetails>
ContextStoringProvider::GetBooleanEvaluation(
std::string_view key, bool default_value,
const openfeature::EvaluationContext& ctx) {
last_ctx = ctx;

return std::make_unique<openfeature::BoolResolutionDetails>(
default_value, openfeature::Reason::kDefault, "default-variant",
openfeature::FlagMetadata{}, std::nullopt, "");
}

std::unique_ptr<openfeature::StringResolutionDetails>
ContextStoringProvider::GetStringEvaluation(
std::string_view key, std::string_view default_value,
const openfeature::EvaluationContext& ctx) {
last_ctx = ctx;
std::string default_str(default_value);
return std::make_unique<openfeature::StringResolutionDetails>(
default_str, openfeature::Reason::kDefault, "default-variant",
openfeature::FlagMetadata{}, std::nullopt, "");
}

std::unique_ptr<openfeature::IntResolutionDetails>
ContextStoringProvider::GetIntegerEvaluation(
std::string_view key, int64_t default_value,
const openfeature::EvaluationContext& ctx) {
last_ctx = ctx;

return std::make_unique<openfeature::IntResolutionDetails>(
default_value, openfeature::Reason::kDefault, "default-variant",
openfeature::FlagMetadata{}, std::nullopt, "");
}

std::unique_ptr<openfeature::DoubleResolutionDetails>
ContextStoringProvider::GetDoubleEvaluation(
std::string_view key, double default_value,
const openfeature::EvaluationContext& ctx) {
last_ctx = ctx;

return std::make_unique<openfeature::DoubleResolutionDetails>(
default_value, openfeature::Reason::kDefault, "default-variant",
openfeature::FlagMetadata{}, std::nullopt, "");
}

std::unique_ptr<openfeature::ObjectResolutionDetails>
ContextStoringProvider::GetObjectEvaluation(
std::string_view key, const openfeature::Value default_value,
const openfeature::EvaluationContext& ctx) {
last_ctx = ctx;

return std::make_unique<openfeature::ObjectResolutionDetails>(
default_value, openfeature::Reason::kDefault, "default-variant",
openfeature::FlagMetadata{}, std::nullopt, "");
}

} // namespace openfeature_e2e
47 changes: 47 additions & 0 deletions test/e2e/context_storing_provider.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#ifndef CPP_SDK_INCLUDE_TEST_E2E_CONTEXT_STORING_PROVIDER_H_
#define CPP_SDK_INCLUDE_TEST_E2E_CONTEXT_STORING_PROVIDER_H_

#include <memory>
#include <string>
#include <string_view>

#include "openfeature/evaluation_context.h"
#include "openfeature/metadata.h"
#include "openfeature/provider.h"
#include "openfeature/resolution_details.h"

namespace openfeature_e2e {

// A simple provider that stores the last evaluation context it received.
class ContextStoringProvider : public openfeature::FeatureProvider {
public:
mutable openfeature::EvaluationContext last_ctx =
openfeature::EvaluationContext::Builder().build();

~ContextStoringProvider() override = default;

openfeature::Metadata GetMetadata() const override;

std::unique_ptr<openfeature::BoolResolutionDetails> GetBooleanEvaluation(
std::string_view key, bool default_value,
const openfeature::EvaluationContext& ctx) override;

std::unique_ptr<openfeature::StringResolutionDetails> GetStringEvaluation(
std::string_view key, std::string_view default_value,
const openfeature::EvaluationContext& ctx) override;

std::unique_ptr<openfeature::IntResolutionDetails> GetIntegerEvaluation(
std::string_view key, int64_t default_value,
const openfeature::EvaluationContext& ctx) override;

std::unique_ptr<openfeature::DoubleResolutionDetails> GetDoubleEvaluation(
std::string_view key, double default_value,
const openfeature::EvaluationContext& ctx) override;

std::unique_ptr<openfeature::ObjectResolutionDetails> GetObjectEvaluation(
std::string_view key, openfeature::Value default_value,
const openfeature::EvaluationContext& ctx) override;
};

} // namespace openfeature_e2e
#endif // CPP_SDK_INCLUDE_TEST_E2E_CONTEXT_STORING_PROVIDER_H_
16 changes: 16 additions & 0 deletions test/e2e/flag_test.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#ifndef CPP_SDK_INCLUDE_TEST_E2E_FLAG_TEST_H_
#define CPP_SDK_INCLUDE_TEST_E2E_FLAG_TEST_H_

#include <any>
#include <string>

namespace openfeature_e2e {

struct FlagTest {
std::string type;
std::string name;
std::any default_value;
};

} // namespace openfeature_e2e
#endif // CPP_SDK_INCLUDE_TEST_E2E_FLAG_TEST_H_
31 changes: 31 additions & 0 deletions test/e2e/state.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#ifndef CPP_SDK_INCLUDE_TEST_E2E_STATE_H_
#define CPP_SDK_INCLUDE_TEST_E2E_STATE_H_

#include <map>
#include <memory>
#include <string>
#include <vector>

#include "openfeature/client.h"
#include "openfeature/evaluation_context.h"
#include "openfeature/provider.h"
#include "openfeature/resolution_details.h"
#include "openfeature/value.h"
#include "test/e2e/flag_test.h"

namespace openfeature_e2e {

struct State {
std::shared_ptr<openfeature::Client> client;
std::shared_ptr<openfeature::FeatureProvider> provider;
FlagTest flag;
std::unique_ptr<openfeature::EvaluationContext> context;
std::unique_ptr<openfeature::EvaluationContext> invocation_context;
std::vector<std::string> levels;

openfeature::Value last_evaluation_value;
};

// TODO: Update struct after implementing hooks and flag evaluation details.
} // namespace openfeature_e2e
#endif // CPP_SDK_INCLUDE_TEST_E2E_STATE_H_
20 changes: 20 additions & 0 deletions test/e2e/steps/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
load("@rules_gherkin//gherkin:defs.bzl", "cc_gherkin_steps")

package(default_visibility = ["//visibility:public"])

cc_gherkin_steps(
name = "gherkin_step_definitions",
srcs = ["minimal_steps.cpp"],
deps = [
"//openfeature:evaluation_context",
"//openfeature:openfeature_api",
"//openfeature/memory_provider:flag",
"//openfeature/memory_provider:in_memory_provider",
"//test/e2e:context_storing_provider",
"//test/e2e:state",
"//test:mock_feature_provider",
"@cucumber-cpp//:cucumber-cpp",
"@googletest//:gtest",
],
visibility = ["//test/e2e:__subpackages__"],
)
Loading