diff --git a/README.md b/README.md index 271dba4..c03a1dc 100644 --- a/README.md +++ b/README.md @@ -122,21 +122,21 @@ openfeature::OpenFeatureAPI& api = openfeature::OpenFeatureAPI::GetInstance(); // Set a global evaluation context openfeature::EvaluationContext global_ctx = openfeature::EvaluationContext::Builder() .WithAttribute("region", "us-east-1") - .build(); + .Build(); api.SetEvaluationContext(global_ctx); // Set a client-level evaluation context std::shared_ptr client = api.GetClient(); openfeature::EvaluationContext client_ctx = openfeature::EvaluationContext::Builder() .WithAttribute("app_version", "1.0.5") - .build(); + .Build(); client->SetEvaluationContext(client_ctx); // Provide an invocation-level evaluation context openfeature::EvaluationContext req_ctx = openfeature::EvaluationContext::Builder() .WithTargetingKey("session-id-12345") .WithAttribute("email", "user@example.com") - .build(); + .Build(); bool flag_value = client->GetBooleanValue("some-flag", false, req_ctx); ``` diff --git a/openfeature/client_api.cpp b/openfeature/client_api.cpp index f1cc360..56b72ea 100644 --- a/openfeature/client_api.cpp +++ b/openfeature/client_api.cpp @@ -12,7 +12,7 @@ namespace openfeature { ClientAPI::ClientAPI(ProviderRepository& repository, std::string_view domain) : provider_repository_(repository), domain_(domain), - evaluation_context_(EvaluationContext::Builder().build()) {} + evaluation_context_(EvaluationContext::Builder().Build()) {} Metadata ClientAPI::GetMetadata() { return Metadata{domain_}; } diff --git a/openfeature/evaluation_context.cpp b/openfeature/evaluation_context.cpp index 741aea0..c62eb6e 100644 --- a/openfeature/evaluation_context.cpp +++ b/openfeature/evaluation_context.cpp @@ -15,9 +15,9 @@ std::optional EvaluationContext::GetTargetingKey() const { } const std::any* EvaluationContext::GetValue(std::string_view key) const { - auto it = attributes_.find(std::string(key)); - if (it != attributes_.end()) { - return &it->second; + auto iterator = attributes_.find(std::string(key)); + if (iterator != attributes_.end()) { + return &iterator->second; } return nullptr; } @@ -56,7 +56,7 @@ EvaluationContext EvaluationContext::Merge( } } - return builder.build(); + return builder.Build(); } EvaluationContext::Builder& EvaluationContext::Builder::WithTargetingKey( @@ -76,8 +76,8 @@ EvaluationContext::Builder& EvaluationContext::Builder::WithAttribute( return this->WithAttribute(std::move(key), std::string(value)); } -EvaluationContext EvaluationContext::Builder::build() const { - return EvaluationContext(targeting_key_, attributes_); +EvaluationContext EvaluationContext::Builder::Build() const { + return {targeting_key_, attributes_}; } } // namespace openfeature diff --git a/openfeature/evaluation_context.h b/openfeature/evaluation_context.h index 51c876f..c82c80e 100644 --- a/openfeature/evaluation_context.h +++ b/openfeature/evaluation_context.h @@ -50,8 +50,8 @@ class EvaluationContext::Builder { // Overload for const char* to ensure implicit conversion to std::string Builder& WithAttribute(std::string key, const char* value); - // The build() method creates the final, immutable EvaluationContext object. - EvaluationContext build() const; + // The Build() method creates the final, immutable EvaluationContext object. + EvaluationContext Build() const; private: std::optional targeting_key_; diff --git a/openfeature/global_context_manager.cpp b/openfeature/global_context_manager.cpp index aa0341b..8e559cf 100644 --- a/openfeature/global_context_manager.cpp +++ b/openfeature/global_context_manager.cpp @@ -7,7 +7,7 @@ namespace openfeature { GlobalContextManager::GlobalContextManager() - : global_evaluation_context_(EvaluationContext::Builder().build()) {} + : global_evaluation_context_(EvaluationContext::Builder().Build()) {} GlobalContextManager& GlobalContextManager::GetInstance() { static absl::NoDestructor instance; diff --git a/openfeature/value.cpp b/openfeature/value.cpp index 84edd01..64db15d 100644 --- a/openfeature/value.cpp +++ b/openfeature/value.cpp @@ -15,8 +15,8 @@ Value::Value(double value) : inner_value_(value) {} Value::Value(std::string value) : inner_value_(std::move(value)) {} -Value::Value(const char* value) : inner_value_() { - if (value) { +Value::Value(const char* value) { + if (value != nullptr) { inner_value_ = std::string(value); } } @@ -32,12 +32,12 @@ Value::Value(std::chrono::system_clock::time_point value) Value::Value(const Value& other) { if (other.IsStructure()) { - auto& ptr = std::get>>( + const auto& ptr = std::get>>( other.inner_value_); inner_value_ = ptr ? std::make_unique>(*ptr) : std::unique_ptr>(nullptr); } else if (other.IsList()) { - auto& ptr = + const auto& ptr = std::get>>(other.inner_value_); inner_value_ = ptr ? std::make_unique>(*ptr) : std::unique_ptr>(nullptr); @@ -57,7 +57,9 @@ Value::Value(const Value& other) { } Value& Value::operator=(const Value& other) { - if (this == &other) return *this; + if (this == &other) { + return *this; + } Value temp(other); std::swap(this->inner_value_, temp.inner_value_); return *this; @@ -90,68 +92,90 @@ bool Value::IsDateTime() const { } std::optional Value::AsBool() const { - if (auto* v = std::get_if(&inner_value_)) return *v; + if (const auto* val = std::get_if(&inner_value_)) { + return *val; + } return std::nullopt; } std::optional Value::AsString() const { - if (auto* v = std::get_if(&inner_value_)) return *v; + if (const auto* val = std::get_if(&inner_value_)) { + return *val; + } return std::nullopt; } std::optional Value::AsInt() const { - if (auto* v = std::get_if(&inner_value_)) return *v; - if (auto* v = std::get_if(&inner_value_)) - return static_cast(std::floor(*v + 0.5)); + if (const auto* val = std::get_if(&inner_value_)) { + return *val; + } + if (const auto* val = std::get_if(&inner_value_)) { + constexpr double kRoundingOffset = 0.5; + return static_cast(std::floor(*val + kRoundingOffset)); + } return std::nullopt; } std::optional Value::AsDouble() const { - if (auto* v = std::get_if(&inner_value_)) return *v; - if (auto* v = std::get_if(&inner_value_)) - return static_cast(*v); + if (const auto* val = std::get_if(&inner_value_)) { + return *val; + } + if (const auto* val = std::get_if(&inner_value_)) { + return static_cast(*val); + } return std::nullopt; } std::optional Value::AsDateTime() const { - if (auto* v = - std::get_if(&inner_value_)) - return *v; + if (const auto* val = + std::get_if(&inner_value_)) { + return *val; + } return std::nullopt; } const std::map* Value::AsStructure() const { - if (auto* v = std::get_if>>( - &inner_value_)) { - return v->get(); + if (const auto* val = + std::get_if>>( + &inner_value_)) { + return val->get(); } return nullptr; } const std::vector* Value::AsList() const { - if (auto* v = + if (const auto* val = std::get_if>>(&inner_value_)) { - return v->get(); + return val->get(); } return nullptr; } bool operator==(const Value& lhs, const Value& rhs) { - if (lhs.IsBool() && rhs.IsBool()) return lhs.AsBool() == rhs.AsBool(); + if (lhs.IsBool() && rhs.IsBool()) { + return lhs.AsBool() == rhs.AsBool(); + } - if (lhs.IsString() && rhs.IsString()) return lhs.AsString() == rhs.AsString(); + if (lhs.IsString() && rhs.IsString()) { + return lhs.AsString() == rhs.AsString(); + } - if (lhs.IsNumber() && rhs.IsNumber()) return lhs.AsDouble() == rhs.AsDouble(); + if (lhs.IsNumber() && rhs.IsNumber()) { + return lhs.AsDouble() == rhs.AsDouble(); + } - if (lhs.IsNull() && rhs.IsNull()) return true; + if (lhs.IsNull() && rhs.IsNull()) { + return true; + } - if (lhs.IsDateTime() && rhs.IsDateTime()) + if (lhs.IsDateTime() && rhs.IsDateTime()) { return lhs.AsDateTime() == rhs.AsDateTime(); + } if (lhs.IsStructure() && rhs.IsStructure()) { const auto* lhs_struct = lhs.AsStructure(); const auto* rhs_struct = rhs.AsStructure(); - if (lhs_struct && rhs_struct) { + if (lhs_struct != nullptr && rhs_struct != nullptr) { return *lhs_struct == *rhs_struct; } return lhs_struct == rhs_struct; @@ -159,7 +183,7 @@ bool operator==(const Value& lhs, const Value& rhs) { if (lhs.IsList() && rhs.IsList()) { const auto* lhs_list = lhs.AsList(); const auto* rhs_list = rhs.AsList(); - if (lhs_list && rhs_list) { + if (lhs_list != nullptr && rhs_list != nullptr) { return *lhs_list == *rhs_list; } return lhs_list == rhs_list; @@ -170,4 +194,4 @@ bool operator==(const Value& lhs, const Value& rhs) { bool operator!=(const Value& lhs, const Value& rhs) { return !(lhs == rhs); } -} // namespace openfeature \ No newline at end of file +} // namespace openfeature diff --git a/openfeature/value.h b/openfeature/value.h index 4ecc9d2..4c8970f 100644 --- a/openfeature/value.h +++ b/openfeature/value.h @@ -17,15 +17,15 @@ namespace openfeature { class Value { public: Value(); - Value(bool value); - Value(int64_t value); - Value(int value); - Value(double value); - Value(std::string value); - Value(const char* value); - Value(const std::map& value); - Value(const std::vector& value); - Value(std::chrono::system_clock::time_point value); + explicit Value(bool value); + explicit Value(int64_t value); + explicit Value(int value); + explicit Value(double value); + explicit Value(std::string value); + explicit Value(const char* value); + explicit Value(const std::map& value); + explicit Value(const std::vector& value); + explicit Value(std::chrono::system_clock::time_point value); Value(const Value& other); Value& operator=(const Value& other); diff --git a/test/client_api_test.cpp b/test/client_api_test.cpp index 9997f7f..fbf4edf 100644 --- a/test/client_api_test.cpp +++ b/test/client_api_test.cpp @@ -48,7 +48,7 @@ class ClientAPITest : public ::testing::Test { void SetUp() override { // Reset Global Context to a clean state before each test. GlobalContextManager::GetInstance().SetGlobalEvaluationContext( - EvaluationContext::Builder().build()); + EvaluationContext::Builder().Build()); } ProviderRepository repo_; @@ -78,7 +78,7 @@ TEST_F(ClientAPITest, GetProviderStatusDefaultsToReady) { // Test setting and getting the EvaluationContext. TEST_F(ClientAPITest, SetAndGetEvaluationContext) { ClientAPI client(repo_, "test-domain"); - EvaluationContext ctx = EvaluationContext::Builder().build(); + EvaluationContext ctx = EvaluationContext::Builder().Build(); // Verify we can set the context without error. EXPECT_NO_THROW(client.SetEvaluationContext(ctx)); @@ -132,7 +132,7 @@ TEST_F(ClientAPITest, GetObjectValueReturnsDefaultWithNoopProvider) { // Test GetBooleanValue with an EvaluationContext passed in. TEST_F(ClientAPITest, GetBooleanValueWithContextReturnsDefault) { ClientAPI client(repo_, "test-domain"); - EvaluationContext ctx = EvaluationContext::Builder().build(); + EvaluationContext ctx = EvaluationContext::Builder().Build(); std::string flag_key = "my-boolean-flag"; EXPECT_TRUE(client.GetBooleanValue(flag_key, true, ctx)); @@ -142,7 +142,7 @@ TEST_F(ClientAPITest, GetBooleanValueWithContextReturnsDefault) { // Test GetStringValue with an EvaluationContext passed in. TEST_F(ClientAPITest, GetStringValueWithContextReturnsDefault) { ClientAPI client(repo_, "test-domain"); - EvaluationContext ctx = EvaluationContext::Builder().build(); + EvaluationContext ctx = EvaluationContext::Builder().Build(); std::string flag_key = "my-string-flag"; EXPECT_EQ(client.GetStringValue(flag_key, "default", ctx), "default"); } @@ -150,7 +150,7 @@ TEST_F(ClientAPITest, GetStringValueWithContextReturnsDefault) { // Test that GetIntegerValue with an EvaluationContext passed in. TEST_F(ClientAPITest, GetIntegerValueWithContextReturnsDefault) { ClientAPI client(repo_, "test-domain"); - EvaluationContext ctx = EvaluationContext::Builder().build(); + EvaluationContext ctx = EvaluationContext::Builder().Build(); std::string flag_key = "my-integer-flag"; EXPECT_EQ(client.GetIntegerValue(flag_key, kDefaultIntValue, ctx), kDefaultIntValue); @@ -159,7 +159,7 @@ TEST_F(ClientAPITest, GetIntegerValueWithContextReturnsDefault) { // Test that GetDoubleValue with an EvaluationContext passed in. TEST_F(ClientAPITest, GetDoubleValueWithContextReturnsDefault) { ClientAPI client(repo_, "test-domain"); - EvaluationContext ctx = EvaluationContext::Builder().build(); + EvaluationContext ctx = EvaluationContext::Builder().Build(); std::string flag_key = "my-double-flag"; EXPECT_DOUBLE_EQ(client.GetDoubleValue(flag_key, kDefaultDoubleValue, ctx), kDefaultDoubleValue); @@ -168,7 +168,7 @@ TEST_F(ClientAPITest, GetDoubleValueWithContextReturnsDefault) { // Test that GetObjectValue with an EvaluationContext passed in. TEST_F(ClientAPITest, GetObjectValueWithContextReturnsDefault) { ClientAPI client(repo_, "test-domain"); - EvaluationContext ctx = EvaluationContext::Builder().build(); + EvaluationContext ctx = EvaluationContext::Builder().Build(); std::string flag_key = "my-object-flag"; EXPECT_EQ(client.GetObjectValue(flag_key, Value(1), ctx), Value(1)); } @@ -182,7 +182,7 @@ TEST_F(ClientAPITest, GetBooleanValueWithOptionsReturnsDefault) { EXPECT_TRUE(client.GetBooleanValue(flag_key, true, options)); EXPECT_FALSE(client.GetBooleanValue(flag_key, false, options)); - EvaluationContext ctx = EvaluationContext::Builder().build(); + EvaluationContext ctx = EvaluationContext::Builder().Build(); EXPECT_TRUE(client.GetBooleanValue(flag_key, true, ctx, options)); EXPECT_FALSE(client.GetBooleanValue(flag_key, false, ctx, options)); } @@ -195,7 +195,7 @@ TEST_F(ClientAPITest, GetStringValueWithOptionsReturnsDefault) { EXPECT_EQ(client.GetStringValue(flag_key, "default", options), "default"); - EvaluationContext ctx = EvaluationContext::Builder().build(); + EvaluationContext ctx = EvaluationContext::Builder().Build(); EXPECT_EQ(client.GetStringValue(flag_key, "default", ctx, options), "default"); } @@ -209,7 +209,7 @@ TEST_F(ClientAPITest, GetIntegerValueWithOptionsReturnsDefault) { EXPECT_EQ(client.GetIntegerValue(flag_key, kDefaultIntValue, options), kDefaultIntValue); - EvaluationContext ctx = EvaluationContext::Builder().build(); + EvaluationContext ctx = EvaluationContext::Builder().Build(); EXPECT_EQ(client.GetIntegerValue(flag_key, kDefaultIntValue, ctx, options), kDefaultIntValue); } @@ -224,7 +224,7 @@ TEST_F(ClientAPITest, GetDoubleValueWithOptionsReturnsDefault) { client.GetDoubleValue(flag_key, kDefaultDoubleValue, options), kDefaultDoubleValue); - EvaluationContext ctx = EvaluationContext::Builder().build(); + EvaluationContext ctx = EvaluationContext::Builder().Build(); EXPECT_DOUBLE_EQ( client.GetDoubleValue(flag_key, kDefaultDoubleValue, ctx, options), kDefaultDoubleValue); @@ -238,7 +238,7 @@ TEST_F(ClientAPITest, GetObjectValueWithOptionsReturnsDefault) { EXPECT_EQ(client.GetObjectValue(flag_key, Value(1), options), Value(1)); - EvaluationContext ctx = EvaluationContext::Builder().build(); + EvaluationContext ctx = EvaluationContext::Builder().Build(); EXPECT_EQ(client.GetObjectValue(flag_key, Value(1), ctx, options), Value(1)); } @@ -246,7 +246,7 @@ TEST_F(ClientAPITest, GetObjectValueWithOptionsReturnsDefault) { TEST_F(ClientAPITest, GetBooleanDetailsReturnsDetailsWithNoopProvider) { ClientAPI client(repo_, "test-domain"); std::string flag_key = "my-boolean-flag"; - EvaluationContext ctx = EvaluationContext::Builder().build(); + EvaluationContext ctx = EvaluationContext::Builder().Build(); EvaluationOptions options; auto details1 = client.GetBooleanDetails(flag_key, true); @@ -275,7 +275,7 @@ TEST_F(ClientAPITest, GetBooleanDetailsReturnsDetailsWithNoopProvider) { TEST_F(ClientAPITest, GetStringDetailsReturnsDetailsWithNoopProvider) { ClientAPI client(repo_, "test-domain"); std::string flag_key = "my-string-flag"; - EvaluationContext ctx = EvaluationContext::Builder().build(); + EvaluationContext ctx = EvaluationContext::Builder().Build(); EvaluationOptions options; auto details1 = client.GetStringDetails(flag_key, "default_val"); @@ -302,7 +302,7 @@ TEST_F(ClientAPITest, GetStringDetailsReturnsDetailsWithNoopProvider) { TEST_F(ClientAPITest, GetIntegerDetailsReturnsDetailsWithNoopProvider) { ClientAPI client(repo_, "test-domain"); std::string flag_key = "my-integer-flag"; - EvaluationContext ctx = EvaluationContext::Builder().build(); + EvaluationContext ctx = EvaluationContext::Builder().Build(); EvaluationOptions options; auto details1 = client.GetIntegerDetails(flag_key, kDefaultIntValue); @@ -329,7 +329,7 @@ TEST_F(ClientAPITest, GetIntegerDetailsReturnsDetailsWithNoopProvider) { TEST_F(ClientAPITest, GetDoubleDetailsReturnsDetailsWithNoopProvider) { ClientAPI client(repo_, "test-domain"); std::string flag_key = "my-double-flag"; - EvaluationContext ctx = EvaluationContext::Builder().build(); + EvaluationContext ctx = EvaluationContext::Builder().Build(); EvaluationOptions options; auto details1 = client.GetDoubleDetails(flag_key, kDefaultDoubleValue); @@ -357,7 +357,7 @@ TEST_F(ClientAPITest, GetDoubleDetailsReturnsDetailsWithNoopProvider) { TEST_F(ClientAPITest, GetObjectDetailsReturnsDetailsWithNoopProvider) { ClientAPI client(repo_, "test-domain"); std::string flag_key = "my-object-flag"; - EvaluationContext ctx = EvaluationContext::Builder().build(); + EvaluationContext ctx = EvaluationContext::Builder().Build(); EvaluationOptions options; auto details1 = @@ -391,7 +391,7 @@ TEST_F(ClientAPITest, ContextMergingPrecedence) { .WithAttribute("global_attr", "global_value") .WithAttribute("shared_attr_gc", "global_shared_gc") .WithAttribute("shared_attr_gci", "global_shared_gci") - .build()); + .Build()); std::shared_ptr> mock_provider = std::make_shared>(); @@ -399,7 +399,7 @@ TEST_F(ClientAPITest, ContextMergingPrecedence) { EXPECT_CALL(*mock_provider, Init(_)).WillOnce(Return(absl::OkStatus())); EXPECT_CALL(*mock_provider, Shutdown()).WillOnce(Return(absl::OkStatus())); - EvaluationContext provider_init_ctx = EvaluationContext::Builder().build(); + EvaluationContext provider_init_ctx = EvaluationContext::Builder().Build(); repo_.SetProvider("test-domain", mock_provider, provider_init_ctx, true); ClientAPI client(repo_, "test-domain"); @@ -409,20 +409,20 @@ TEST_F(ClientAPITest, ContextMergingPrecedence) { .WithAttribute("client_attr", "client_value") .WithAttribute("shared_attr_gc", "client_shared_gc") .WithAttribute("shared_attr_gci", "client_shared_gci") - .build()); + .Build()); EvaluationContext invocation_ctx = EvaluationContext::Builder() .WithTargetingKey("invocation-target") .WithAttribute("invocation_attr", "invocation_value") .WithAttribute("shared_attr_gci", "invocation_shared_gci") - .build(); + .Build(); std::string flag_key = "my-test-flag"; bool default_value = false; bool expected_value = true; - EvaluationContext captured_merged_ctx = EvaluationContext::Builder().build(); + EvaluationContext captured_merged_ctx = EvaluationContext::Builder().Build(); // Expect the provider's GetBooleanEvaluation to be called with the merged // context. @@ -486,7 +486,7 @@ TEST_F(ClientAPITest, EvaluateFlagHandlesProviderErrorStatus) { })); repo_.SetProvider("test-domain", mock_provider, - EvaluationContext::Builder().build(), true); + EvaluationContext::Builder().Build(), true); ClientAPI client(repo_, "test-domain"); EXPECT_FALSE(client.GetBooleanValue("flag", false)); @@ -503,7 +503,7 @@ TEST_F(ClientAPITest, GetDetailsPropagatesProviderVariantAndMetadata) { true, Reason::kTargetingMatch, "variant_a", metadata))); repo_.SetProvider("test-domain", mock_provider, - EvaluationContext::Builder().build(), true); + EvaluationContext::Builder().Build(), true); ClientAPI client(repo_, "test-domain"); auto details = client.GetBooleanDetails("flag", false); @@ -525,7 +525,7 @@ TEST_F(ClientAPITest, GetDetailsHandlesProviderErrors) { .WillOnce(Return(absl::InternalError("Provider failed"))); repo_.SetProvider("test-domain", mock_provider, - EvaluationContext::Builder().build(), true); + EvaluationContext::Builder().Build(), true); ClientAPI client(repo_, "test-domain"); auto details = client.GetBooleanDetails("flag", false); @@ -548,7 +548,7 @@ TEST_F(ClientAPITest, EvaluateFlagHandlesProviderNullResolutionDetails) { })); repo_.SetProvider("test-domain", mock_provider, - EvaluationContext::Builder().build(), true); + EvaluationContext::Builder().Build(), true); ClientAPI client(repo_, "test-domain"); EXPECT_FALSE(client.GetBooleanValue("flag", false)); @@ -568,7 +568,7 @@ TEST_F(ClientAPITest, EvaluateFlagHandlesProviderStdException) { })); repo_.SetProvider("test-domain", mock_provider, - EvaluationContext::Builder().build(), true); + EvaluationContext::Builder().Build(), true); ClientAPI client(repo_, "test-domain"); EXPECT_FALSE(client.GetBooleanValue("flag", false)); @@ -588,7 +588,7 @@ TEST_F(ClientAPITest, EvaluateFlagHandlesProviderUnknownException) { })); repo_.SetProvider("test-domain", mock_provider, - EvaluationContext::Builder().build(), true); + EvaluationContext::Builder().Build(), true); ClientAPI client(repo_, "test-domain"); EXPECT_FALSE(client.GetBooleanValue("flag", false)); @@ -599,7 +599,7 @@ TEST_F(ClientAPITest, EvaluateFlagBlocksWhenProviderNotReady) { auto mock_provider = std::make_shared>(); EXPECT_CALL(*mock_provider, GetBooleanEvaluation(_, _, _)).Times(0); repo_.SetProvider("test-domain", mock_provider, - EvaluationContext::Builder().build(), true); + EvaluationContext::Builder().Build(), true); auto status_manager = repo_.GetFeatureProviderStatusManager("test-domain"); ASSERT_NE(status_manager, nullptr); @@ -614,7 +614,7 @@ TEST_F(ClientAPITest, EvaluateFlagBlocksWhenProviderFatal) { auto mock_provider = std::make_shared>(); EXPECT_CALL(*mock_provider, GetBooleanEvaluation(_, _, _)).Times(0); repo_.SetProvider("test-domain", mock_provider, - EvaluationContext::Builder().build(), true); + EvaluationContext::Builder().Build(), true); auto status_manager = repo_.GetFeatureProviderStatusManager("test-domain"); ASSERT_NE(status_manager, nullptr); @@ -630,7 +630,7 @@ TEST_F(ClientAPITest, EvaluateFlagProceedsWhenProviderInErrorState) { .WillOnce(Return(std::make_unique( true, Reason::kCached, std::nullopt, FlagMetadata()))); repo_.SetProvider("test-domain", mock_provider, - EvaluationContext::Builder().build(), true); + EvaluationContext::Builder().Build(), true); auto status_manager = repo_.GetFeatureProviderStatusManager("test-domain"); ASSERT_NE(status_manager, nullptr); @@ -646,7 +646,7 @@ TEST_F(ClientAPITest, EvaluateFlagProceedsWhenProviderInStaleState) { .WillOnce(Return(std::make_unique( true, Reason::kCached, std::nullopt, FlagMetadata()))); repo_.SetProvider("test-domain", mock_provider, - EvaluationContext::Builder().build(), true); + EvaluationContext::Builder().Build(), true); auto status_manager = repo_.GetFeatureProviderStatusManager("test-domain"); ASSERT_NE(status_manager, nullptr); @@ -671,7 +671,7 @@ TEST_F(ClientAPITest, ParallelProviderSwapRaceCondition) { true, Reason::kTargetingMatch, std::nullopt, FlagMetadata()); })); repo_.SetProvider(domain, ready_provider, - EvaluationContext::Builder().build(), true); + EvaluationContext::Builder().Build(), true); std::thread evaluation_thread([&]() { while (running) { @@ -705,7 +705,7 @@ TEST_F(ClientAPITest, ParallelProviderSwapRaceCondition) { .WillOnce(Return(absl::OkStatus())); repo_.SetProvider(domain, not_ready_provider, - EvaluationContext::Builder().build(), false); + EvaluationContext::Builder().Build(), false); init_called->get_future().wait(); diff --git a/test/e2e/context_storing_provider.h b/test/e2e/context_storing_provider.h index f75b3bc..bedcad8 100644 --- a/test/e2e/context_storing_provider.h +++ b/test/e2e/context_storing_provider.h @@ -18,7 +18,7 @@ namespace openfeature_e2e { class ContextStoringProvider : public openfeature::FeatureProvider { public: mutable openfeature::EvaluationContext last_ctx = - openfeature::EvaluationContext::Builder().build(); + openfeature::EvaluationContext::Builder().Build(); ~ContextStoringProvider() override = default; diff --git a/test/e2e/steps/minimal_steps.cpp b/test/e2e/steps/minimal_steps.cpp index 8b4f2b8..db8c5b3 100644 --- a/test/e2e/steps/minimal_steps.cpp +++ b/test/e2e/steps/minimal_steps.cpp @@ -258,7 +258,7 @@ WHEN(setup_context, .WithAttribute(field2, value2) .WithAttribute(field3, value3) .WithAttribute(field4, value4) - .build(); + .Build(); state.context = std::make_unique(ctx); } @@ -292,7 +292,7 @@ THEN(check_resolved_flag_empty_ctx, auto& state = cuke::context(); openfeature::EvaluationContext empty_ctx = - openfeature::EvaluationContext::Builder().build(); + openfeature::EvaluationContext::Builder().Build(); std::string actual = state.client->GetStringValue("context-aware", "EXTERNAL", empty_ctx); diff --git a/test/evaluation_context_test.cpp b/test/evaluation_context_test.cpp index 37cec61..f8b3646 100644 --- a/test/evaluation_context_test.cpp +++ b/test/evaluation_context_test.cpp @@ -5,7 +5,7 @@ #include #include -using namespace openfeature; +namespace openfeature { class EvaluationContextTest : public ::testing::Test { protected: @@ -19,7 +19,7 @@ class EvaluationContextTest : public ::testing::Test { // Test that a context built with no properties returns expected defaults. TEST_F(EvaluationContextTest, DefaultBuilderCreatesEmptyContext) { - EvaluationContext ctx = EvaluationContext::Builder().build(); + EvaluationContext ctx = EvaluationContext::Builder().Build(); // Based on implementation, a missing key in builder becomes "" in // constructor. @@ -33,7 +33,7 @@ TEST_F(EvaluationContextTest, DefaultBuilderCreatesEmptyContext) { TEST_F(EvaluationContextTest, BuilderSetsTargetingKey) { std::string expected_key = "user-12345"; EvaluationContext ctx = - EvaluationContext::Builder().WithTargetingKey(expected_key).build(); + EvaluationContext::Builder().WithTargetingKey(expected_key).Build(); auto key = ctx.GetTargetingKey(); ASSERT_TRUE(key.has_value()); @@ -42,15 +42,18 @@ TEST_F(EvaluationContextTest, BuilderSetsTargetingKey) { // Test setting and retrieving various attribute types. TEST_F(EvaluationContextTest, BuilderSetsAttributesOfVariousTypes) { + constexpr int kIntValue = 42; + constexpr double kDoubleValue = 3.14; + constexpr size_t kExpectedAttrCount = 4; EvaluationContext ctx = EvaluationContext::Builder() .WithAttribute("str_attr", std::string("test")) - .WithAttribute("int_attr", 42) + .WithAttribute("int_attr", kIntValue) .WithAttribute("bool_attr", true) - .WithAttribute("double_attr", 3.14) - .build(); + .WithAttribute("double_attr", kDoubleValue) + .Build(); const auto& attrs = ctx.GetAttributes(); - EXPECT_EQ(attrs.size(), 4); + EXPECT_EQ(attrs.size(), kExpectedAttrCount); const std::any* str_val = ctx.GetValue("str_attr"); ASSERT_NE(str_val, nullptr); @@ -58,7 +61,7 @@ TEST_F(EvaluationContextTest, BuilderSetsAttributesOfVariousTypes) { const std::any* int_val = ctx.GetValue("int_attr"); ASSERT_NE(int_val, nullptr); - EXPECT_EQ(std::any_cast(*int_val), 42); + EXPECT_EQ(std::any_cast(*int_val), kIntValue); const std::any* bool_val = ctx.GetValue("bool_attr"); ASSERT_NE(bool_val, nullptr); @@ -66,13 +69,13 @@ TEST_F(EvaluationContextTest, BuilderSetsAttributesOfVariousTypes) { const std::any* double_val = ctx.GetValue("double_attr"); ASSERT_NE(double_val, nullptr); - EXPECT_DOUBLE_EQ(std::any_cast(*double_val), 3.14); + EXPECT_DOUBLE_EQ(std::any_cast(*double_val), kDoubleValue); } // Test behavior when requesting a non-existent attribute. TEST_F(EvaluationContextTest, GetValueReturnsNullForMissingKey) { EvaluationContext ctx = - EvaluationContext::Builder().WithAttribute("exists", 1).build(); + EvaluationContext::Builder().WithAttribute("exists", 1).Build(); EXPECT_NE(ctx.GetValue("exists"), nullptr); EXPECT_EQ(ctx.GetValue("does_not_exist"), nullptr); @@ -81,33 +84,38 @@ TEST_F(EvaluationContextTest, GetValueReturnsNullForMissingKey) { // Test that setting the same attribute key twice overwrites the previous value // within the same builder chain. TEST_F(EvaluationContextTest, BuilderOverwritesDuplicateKeys) { + constexpr int kInitialValue = 100; + constexpr int kOverwrittenValue = 200; EvaluationContext ctx = EvaluationContext::Builder() - .WithAttribute("key", 100) - .WithAttribute("key", 200) - .build(); + .WithAttribute("key", kInitialValue) + .WithAttribute("key", kOverwrittenValue) + .Build(); const std::any* val = ctx.GetValue("key"); ASSERT_NE(val, nullptr); - EXPECT_EQ(std::any_cast(*val), 200); + EXPECT_EQ(std::any_cast(*val), kOverwrittenValue); } // Test merging attributes with precedence. TEST_F(EvaluationContextTest, MergeAttributesWithPrecedence) { + constexpr int kCommonVal1 = 1; + constexpr int kCommonVal2 = 2; + constexpr size_t kExpectedAttrCount = 3; EvaluationContext ctx1 = EvaluationContext::Builder() - .WithAttribute("common", 1) + .WithAttribute("common", kCommonVal1) .WithAttribute("ctx1", std::string("A")) - .build(); + .Build(); EvaluationContext ctx2 = EvaluationContext::Builder() - .WithAttribute("common", 2) + .WithAttribute("common", kCommonVal2) .WithAttribute("ctx2", std::string("B")) - .build(); + .Build(); EvaluationContext merged = EvaluationContext::Merge({&ctx1, &ctx2}); - EXPECT_EQ(merged.GetAttributes().size(), 3); + EXPECT_EQ(merged.GetAttributes().size(), kExpectedAttrCount); - EXPECT_EQ(std::any_cast(*merged.GetValue("common")), 2); + EXPECT_EQ(std::any_cast(*merged.GetValue("common")), kCommonVal2); EXPECT_EQ(std::any_cast(*merged.GetValue("ctx1")), "A"); EXPECT_EQ(std::any_cast(*merged.GetValue("ctx2")), "B"); } @@ -115,11 +123,11 @@ TEST_F(EvaluationContextTest, MergeAttributesWithPrecedence) { // Test that the last context in the list with a valid and non-empty targeting // key remains as the final result. TEST_F(EvaluationContextTest, MergeTargetingKeyWithPrecedence) { - EvaluationContext ctx_no_key = EvaluationContext::Builder().build(); + EvaluationContext ctx_no_key = EvaluationContext::Builder().Build(); EvaluationContext ctx_key_a = - EvaluationContext::Builder().WithTargetingKey("KeyA").build(); + EvaluationContext::Builder().WithTargetingKey("KeyA").Build(); EvaluationContext ctx_key_b = - EvaluationContext::Builder().WithTargetingKey("KeyB").build(); + EvaluationContext::Builder().WithTargetingKey("KeyB").Build(); EvaluationContext res1 = EvaluationContext::Merge({&ctx_key_a, &ctx_key_b}); EXPECT_EQ(res1.GetTargetingKey().value(), "KeyB"); @@ -135,18 +143,19 @@ TEST_F(EvaluationContextTest, MergeTargetingKeyWithPrecedence) { // Test Merging: Complex scenario with attributes and keys. TEST_F(EvaluationContextTest, MergeComplexScenario) { + constexpr int kRequestId = 123; EvaluationContext base = EvaluationContext::Builder() .WithTargetingKey("base-user") .WithAttribute("env", std::string("prod")) .WithAttribute("region", std::string("us-east")) - .build(); + .Build(); EvaluationContext request = EvaluationContext::Builder() .WithTargetingKey("req-user") .WithAttribute("region", std::string("us-west")) - .WithAttribute("request_id", 123) - .build(); + .WithAttribute("request_id", kRequestId) + .Build(); EvaluationContext merged = EvaluationContext::Merge({&base, &request}); @@ -154,13 +163,13 @@ TEST_F(EvaluationContextTest, MergeComplexScenario) { EXPECT_EQ(std::any_cast(*merged.GetValue("env")), "prod"); EXPECT_EQ(std::any_cast(*merged.GetValue("region")), "us-west"); - EXPECT_EQ(std::any_cast(*merged.GetValue("request_id")), 123); + EXPECT_EQ(std::any_cast(*merged.GetValue("request_id")), kRequestId); } // The merged context should only reflect non-null inputs. TEST_F(EvaluationContextTest, MergeIgnoresNullPointers) { EvaluationContext ctx = - EvaluationContext::Builder().WithTargetingKey("valid").build(); + EvaluationContext::Builder().WithTargetingKey("valid").Build(); EvaluationContext merged = EvaluationContext::Merge({nullptr, &ctx, nullptr}); @@ -170,7 +179,7 @@ TEST_F(EvaluationContextTest, MergeIgnoresNullPointers) { // Test that string literals and std::string are stored and retrieved correctly. TEST_F(EvaluationContextTest, StoresStringCorrectly) { EvaluationContext ctx_char = - EvaluationContext::Builder().WithAttribute("k", "v").build(); + EvaluationContext::Builder().WithAttribute("k", "v").Build(); const std::any* val_char = ctx_char.GetValue("k"); // Verify it is stored as std::string, not const char* @@ -179,8 +188,10 @@ TEST_F(EvaluationContextTest, StoresStringCorrectly) { EXPECT_EQ(std::any_cast(*val_char), "v"); EvaluationContext ctx_str = - EvaluationContext::Builder().WithAttribute("k", std::string("v")).build(); + EvaluationContext::Builder().WithAttribute("k", std::string("v")).Build(); const std::any* val_str = ctx_str.GetValue("k"); EXPECT_EQ(val_str->type(), typeid(std::string)); EXPECT_EQ(std::any_cast(*val_str), "v"); } + +} // namespace openfeature diff --git a/test/feature_provider_status_manager_test.cpp b/test/feature_provider_status_manager_test.cpp index 21e736f..827377a 100644 --- a/test/feature_provider_status_manager_test.cpp +++ b/test/feature_provider_status_manager_test.cpp @@ -10,7 +10,8 @@ #include "openfeature/evaluation_context.h" #include "openfeature/provider_status.h" -using namespace openfeature; +namespace openfeature { + using ::testing::_; using ::testing::Return; using ::testing::Test; @@ -29,7 +30,7 @@ class FeatureProviderStatusManagerTest : public Test { std::shared_ptr mock_provider_; std::unique_ptr manager_; - EvaluationContext ctx_ = EvaluationContext::Builder().build(); + EvaluationContext ctx_ = EvaluationContext::Builder().Build(); }; TEST_F(FeatureProviderStatusManagerTest, CreateWithNullProviderReturnsError) { @@ -48,7 +49,7 @@ class FeatureProviderStatusManagerInitTest public WithParamInterface> {}; TEST_P(FeatureProviderStatusManagerInitTest, InitSetsCorrectStatus) { - auto [provider_init_status, expected_manager_status] = GetParam(); + const auto& [provider_init_status, expected_manager_status] = GetParam(); EXPECT_CALL(*mock_provider_, Init(_)).WillOnce(Return(provider_init_status)); manager_->Init(ctx_); @@ -69,7 +70,7 @@ class FeatureProviderStatusManagerShutdownTest TEST_P(FeatureProviderStatusManagerShutdownTest, ShutdownAlwaysSetsStatusToNotReady) { manager_->SetStatus(ProviderStatus::kReady); - auto provider_shutdown_status = GetParam(); + const auto& provider_shutdown_status = GetParam(); EXPECT_CALL(*mock_provider_, Shutdown()) .WillOnce(Return(provider_shutdown_status)); manager_->Shutdown(); @@ -103,8 +104,4 @@ TEST_F(FeatureProviderStatusManagerTest, GetProviderReturnsCorrectProvider) { manager_->SetStatus(ProviderStatus::kReady); EXPECT_EQ(manager_->GetProvider(), mock_provider_); } - -int main(int argc, char** argv) { - testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} \ No newline at end of file +} // namespace openfeature \ No newline at end of file diff --git a/test/global_context_manager_test.cpp b/test/global_context_manager_test.cpp index dde462f..572cbae 100644 --- a/test/global_context_manager_test.cpp +++ b/test/global_context_manager_test.cpp @@ -8,14 +8,14 @@ #include "openfeature/evaluation_context.h" -using namespace openfeature; +namespace openfeature { class GlobalContextManagerTest : public ::testing::Test { protected: // Reset to a clean state before every test. void SetUp() override { GlobalContextManager::GetInstance().SetGlobalEvaluationContext( - EvaluationContext::Builder().build()); + EvaluationContext::Builder().Build()); } }; @@ -28,7 +28,7 @@ TEST_F(GlobalContextManagerTest, ReturnsSameInstance) { TEST_F(GlobalContextManagerTest, SetAndGetContext) { GlobalContextManager& manager = GlobalContextManager::GetInstance(); - EvaluationContext input_ctx = EvaluationContext::Builder().build(); + EvaluationContext input_ctx = EvaluationContext::Builder().Build(); EXPECT_NO_THROW(manager.SetGlobalEvaluationContext(input_ctx)); @@ -50,7 +50,7 @@ TEST_F(GlobalContextManagerTest, ThreadSafetyStressTest) { // Writer Thread: Continuously updates the context. std::thread writer([&]() { while (!stop) { - EvaluationContext ctx = EvaluationContext::Builder().build(); + EvaluationContext ctx = EvaluationContext::Builder().Build(); // In a real scenario, we would populate ctx with different data here. manager.SetGlobalEvaluationContext(ctx); std::this_thread::sleep_for(std::chrono::milliseconds(1)); @@ -58,8 +58,10 @@ TEST_F(GlobalContextManagerTest, ThreadSafetyStressTest) { }); // Reader Threads: Continuously read the context. + constexpr int kReaderThreadCount = 10; std::vector readers; - for (int i = 0; i < 10; ++i) { + readers.reserve(kReaderThreadCount); + for (int index = 0; index < kReaderThreadCount; ++index) { readers.emplace_back([&]() { while (!stop) { // Just calling the getter to ensure locks work and no race conditions @@ -74,11 +76,13 @@ TEST_F(GlobalContextManagerTest, ThreadSafetyStressTest) { } // Let the chaos run for a short duration. - std::this_thread::sleep_for(std::chrono::milliseconds(100)); + constexpr int kChaosDurationMs = 100; + std::this_thread::sleep_for(std::chrono::milliseconds(kChaosDurationMs)); stop = true; writer.join(); - for (auto& t : readers) { - t.join(); + for (auto& reader_thread : readers) { + reader_thread.join(); } } +} // namespace openfeature \ No newline at end of file diff --git a/test/hook_context_test.cpp b/test/hook_context_test.cpp index 174a21b..d94f64b 100644 --- a/test/hook_context_test.cpp +++ b/test/hook_context_test.cpp @@ -21,7 +21,7 @@ class HookContextTest : public ::testing::Test { : initial_ctx_(EvaluationContext::Builder() .WithTargetingKey("initial-user") .WithAttribute("env", std::string("test")) - .build()) {} + .Build()) {} EvaluationContext initial_ctx_; Metadata client_metadata_{"test-client"}; @@ -276,7 +276,7 @@ TEST_F(HookContextTest, SetEvaluationContextUpdatesContext) { EvaluationContext updated_ctx = EvaluationContext::Builder() .WithTargetingKey("updated-user") .WithAttribute("env", std::string("prod")) - .build(); + .Build(); hook_ctx.SetEvaluationContext(std::move(updated_ctx)); diff --git a/test/hook_support_test.cpp b/test/hook_support_test.cpp index 6b2bd23..fc87951 100644 --- a/test/hook_support_test.cpp +++ b/test/hook_support_test.cpp @@ -60,7 +60,7 @@ class HookSupportTest : public ::testing::Test { protected: void SetUp() override { GlobalContextManager::GetInstance().SetGlobalEvaluationContext( - EvaluationContext::Builder().build()); + EvaluationContext::Builder().Build()); HookManager::GetInstance().ClearHooks(); } @@ -118,7 +118,7 @@ class ContextMutatingHook : public openfeature::BoolHook { std::optional Before( const openfeature::HookContext& /*ctx*/, const openfeature::HookHints& /*hints*/) override { - return EvaluationContext::Builder().WithAttribute(key_, value_).build(); + return EvaluationContext::Builder().WithAttribute(key_, value_).Build(); } private: @@ -380,7 +380,7 @@ TEST_F(HookSupportTest, HooksExecuteInCorrectOrderOnSuccess) { Return(std::vector>{ provider_hook})); - repo_.SetProvider(domain, mock_provider, EvaluationContext::Builder().build(), + repo_.SetProvider(domain, mock_provider, EvaluationContext::Builder().Build(), true); HookManager::GetInstance().AddHook(api_hook); @@ -409,14 +409,14 @@ TEST_F(HookSupportTest, auto mock_provider = std::make_shared>(); ON_CALL(*mock_provider, Init(_)).WillByDefault(Return(absl::OkStatus())); - EvaluationContext captured_context = EvaluationContext::Builder().build(); + EvaluationContext captured_context = EvaluationContext::Builder().Build(); EXPECT_CALL(*mock_provider, GetBooleanEvaluation(_, _, _)) .WillOnce(DoAll( SaveArg<2>(&captured_context), Return(std::make_unique( true, Reason::kTargetingMatch, std::nullopt, FlagMetadata())))); - repo_.SetProvider(domain, mock_provider, EvaluationContext::Builder().build(), + repo_.SetProvider(domain, mock_provider, EvaluationContext::Builder().Build(), true); ClientAPI client(repo_, domain); @@ -449,7 +449,7 @@ TEST_F(HookSupportTest, HookDataIsIsolatedPerHookAndPersistsAcrossStages) { true, Reason::kTargetingMatch, std::nullopt, FlagMetadata()); })); - repo_.SetProvider(domain, mock_provider, EvaluationContext::Builder().build(), + repo_.SetProvider(domain, mock_provider, EvaluationContext::Builder().Build(), true); auto hook_first = std::make_shared("hook-1"); @@ -480,7 +480,7 @@ TEST_F(HookSupportTest, HookHintsArePropagatedToAllStages) { true, Reason::kTargetingMatch, std::nullopt, FlagMetadata()); })); - repo_.SetProvider(domain, mock_provider, EvaluationContext::Builder().build(), + repo_.SetProvider(domain, mock_provider, EvaluationContext::Builder().Build(), true); auto tracking_hook = std::make_shared(); @@ -508,7 +508,7 @@ TEST_F(HookSupportTest, ON_CALL(*mock_provider, Init(_)).WillByDefault(Return(absl::OkStatus())); EXPECT_CALL(*mock_provider, GetBooleanEvaluation(_, _, _)).Times(0); - repo_.SetProvider(domain, mock_provider, EvaluationContext::Builder().build(), + repo_.SetProvider(domain, mock_provider, EvaluationContext::Builder().Build(), true); std::vector execution_log; @@ -536,7 +536,7 @@ TEST_F(HookSupportTest, .WillOnce(Return(std::make_unique( true, Reason::kTargetingMatch, std::nullopt, FlagMetadata()))); - repo_.SetProvider(domain, mock_provider, EvaluationContext::Builder().build(), + repo_.SetProvider(domain, mock_provider, EvaluationContext::Builder().Build(), true); std::vector execution_log; @@ -561,7 +561,7 @@ TEST_F(HookSupportTest, ExceptionInErrorOrFinallyDoesNotAbortExecution) { auto mock_provider = std::make_shared>(); ON_CALL(*mock_provider, Init(_)).WillByDefault(Return(absl::OkStatus())); - repo_.SetProvider(domain, mock_provider, EvaluationContext::Builder().build(), + repo_.SetProvider(domain, mock_provider, EvaluationContext::Builder().Build(), true); std::vector execution_log; @@ -590,7 +590,7 @@ TEST_F(HookSupportTest, TypeSpecificHooksExecuteOnlyForMatchingFlagTypes) { auto mock_provider = std::make_shared>(); ON_CALL(*mock_provider, Init(_)).WillByDefault(Return(absl::OkStatus())); - repo_.SetProvider(domain, mock_provider, EvaluationContext::Builder().build(), + repo_.SetProvider(domain, mock_provider, EvaluationContext::Builder().Build(), true); bool string_hook_called = false; @@ -744,7 +744,7 @@ TEST_F(HookSupportTest, ProviderNotReadyTriggersErrorAndFinallyHooks) { Return(std::vector>{ provider_hook})); - repo_.SetProvider(domain, mock_provider, EvaluationContext::Builder().build(), + repo_.SetProvider(domain, mock_provider, EvaluationContext::Builder().Build(), true); auto status_manager = repo_.GetFeatureProviderStatusManager(domain); @@ -781,7 +781,7 @@ TEST_F(HookSupportTest, ProviderFatalTriggersErrorAndFinallyHooks) { Return(std::vector>{ provider_hook})); - repo_.SetProvider(domain, mock_provider, EvaluationContext::Builder().build(), + repo_.SetProvider(domain, mock_provider, EvaluationContext::Builder().Build(), true); auto status_manager = repo_.GetFeatureProviderStatusManager(domain); diff --git a/test/hook_test.cpp b/test/hook_test.cpp index 418b7a5..d0c18c3 100644 --- a/test/hook_test.cpp +++ b/test/hook_test.cpp @@ -112,7 +112,7 @@ class HookTest : public ::testing::Test { protected: HookTest() : initial_ctx_( - EvaluationContext::Builder().WithTargetingKey("user-123").build()), + EvaluationContext::Builder().WithTargetingKey("user-123").Build()), hook_data_(std::make_shared()) {} EvaluationContext initial_ctx_; @@ -210,7 +210,7 @@ TEST_F(HookTest, OverriddenBeforeCanModifyAndReturnEvaluationContext) { EvaluationContext::Builder() .WithTargetingKey("mutated-user") .WithAttribute("region", std::string("us-east")) - .build(); + .Build(); hook.SetReturnContext(modified_ctx); std::optional result = hook.Before(ctx, hints); diff --git a/test/memory_provider/flag_test.cpp b/test/memory_provider/flag_test.cpp index 6a72ec7..f03f1ad 100644 --- a/test/memory_provider/flag_test.cpp +++ b/test/memory_provider/flag_test.cpp @@ -13,6 +13,43 @@ namespace openfeature { +namespace { + +void VerifyVariants(const Flag& flag) { + constexpr size_t kExpectedVariantsCount = 2; + const std::unordered_map& got_variants = + flag.GetVariants(); + EXPECT_EQ(got_variants.size(), kExpectedVariantsCount); + EXPECT_EQ(got_variants.at("v1"), "value1"); + EXPECT_EQ(got_variants.at("v2"), "value2"); + EXPECT_EQ(flag.GetDefaultVariant(), "v1"); +} + +void VerifyEvaluator(const Flag& flag) { + const auto& got_evaluator = flag.GetContextEvaluator(); + ASSERT_TRUE(got_evaluator != nullptr); + absl::StatusOr eval_result = + got_evaluator(flag, EvaluationContext::Builder().Build()); + ASSERT_TRUE(eval_result.ok()); + EXPECT_EQ(*eval_result, "evaluated"); +} + +void VerifyMetadata(const FlagMetadata& got_metadata) { + constexpr size_t kExpectedMetadataCount = 4; + constexpr int64_t kIntPropValue = 42; + constexpr double kDoublePropValue = 3.14; + + EXPECT_EQ(got_metadata.data.size(), kExpectedMetadataCount); + EXPECT_EQ(std::get(got_metadata.data.at("bool_prop")), true); + EXPECT_EQ(std::get(got_metadata.data.at("str_prop")), + "meta_str"); + EXPECT_EQ(std::get(got_metadata.data.at("int_prop")), kIntPropValue); + EXPECT_DOUBLE_EQ(std::get(got_metadata.data.at("double_prop")), + kDoublePropValue); +} + +} // namespace + TEST(FlagTest, InitializesAndReturnsPropertiesCorrectly) { std::unordered_map variants = { {"v1", std::string("value1")}, {"v2", std::string("value2")}}; @@ -24,36 +61,20 @@ TEST(FlagTest, InitializesAndReturnsPropertiesCorrectly) { return "evaluated"; }; + constexpr int64_t kIntPropValue = 42; + constexpr double kDoublePropValue = 3.14; + FlagMetadata metadata; metadata.data["bool_prop"] = true; metadata.data["str_prop"] = std::string("meta_str"); - metadata.data["int_prop"] = int64_t{42}; - metadata.data["double_prop"] = 3.14; + metadata.data["int_prop"] = kIntPropValue; + metadata.data["double_prop"] = kDoublePropValue; Flag flag(variants, default_variant, evaluator, metadata, true); - const std::unordered_map& got_variants = - flag.GetVariants(); - EXPECT_EQ(got_variants.size(), 2); - EXPECT_EQ(got_variants.at("v1"), "value1"); - EXPECT_EQ(got_variants.at("v2"), "value2"); - - EXPECT_EQ(flag.GetDefaultVariant(), "v1"); - - const auto& got_evaluator = flag.GetContextEvaluator(); - ASSERT_TRUE(got_evaluator != nullptr); - absl::StatusOr eval_result = - got_evaluator(flag, EvaluationContext::Builder().build()); - ASSERT_TRUE(eval_result.ok()); - EXPECT_EQ(*eval_result, "evaluated"); - - const FlagMetadata& got_metadata = flag.GetFlagMetadata(); - EXPECT_EQ(got_metadata.data.size(), 4); - EXPECT_EQ(std::get(got_metadata.data.at("bool_prop")), true); - EXPECT_EQ(std::get(got_metadata.data.at("str_prop")), - "meta_str"); - EXPECT_EQ(std::get(got_metadata.data.at("int_prop")), 42); - EXPECT_DOUBLE_EQ(std::get(got_metadata.data.at("double_prop")), 3.14); + VerifyVariants(flag); + VerifyEvaluator(flag); + VerifyMetadata(flag.GetFlagMetadata()); EXPECT_TRUE(flag.IsDisabled()); } @@ -73,62 +94,64 @@ TEST(FlagTest, EvaluatorUsesTargetingKey) { {"feature_off", false}}; Flag::ContextEvaluator evaluator = - [](const Flag& f, + [](const Flag& flag, const EvaluationContext& ctx) -> absl::StatusOr { - std::optional tk = ctx.GetTargetingKey(); - if (tk && *tk == "beta_tester") { - return f.GetVariants().at("feature_on"); + std::optional targeting_key = ctx.GetTargetingKey(); + if (targeting_key.has_value() && *targeting_key == "beta_tester") { + return flag.GetVariants().at("feature_on"); } - return f.GetVariants().at("feature_off"); + return flag.GetVariants().at("feature_off"); }; Flag flag(variants, "feature_off", evaluator, FlagMetadata{}); const auto& eval_func = flag.GetContextEvaluator(); EvaluationContext beta_ctx = - EvaluationContext::Builder().WithTargetingKey("beta_tester").build(); + EvaluationContext::Builder().WithTargetingKey("beta_tester").Build(); absl::StatusOr beta_res = eval_func(flag, beta_ctx); ASSERT_TRUE(beta_res.ok()); EXPECT_TRUE(*beta_res); EvaluationContext normal_ctx = - EvaluationContext::Builder().WithTargetingKey("regular_user").build(); + EvaluationContext::Builder().WithTargetingKey("regular_user").Build(); absl::StatusOr normal_res = eval_func(flag, normal_ctx); ASSERT_TRUE(normal_res.ok()); EXPECT_FALSE(*normal_res); } TEST(FlagTest, EvaluatorUsesContextAttributes) { - std::unordered_map variants = {{"premium", 100}, - {"standard", 10}}; + constexpr int kPremiumValue = 100; + constexpr int kStandardValue = 10; + std::unordered_map variants = { + {"premium", kPremiumValue}, {"standard", kStandardValue}}; Flag::ContextEvaluator evaluator = - [](const Flag& f, + [](const Flag& flag, const EvaluationContext& ctx) -> absl::StatusOr { const std::any* user_tier = ctx.GetValue("tier"); - if (user_tier && user_tier->type() == typeid(std::string)) { + if (user_tier != nullptr && user_tier->type() == typeid(std::string)) { if (std::any_cast(*user_tier) == "premium") { - return f.GetVariants().at("premium"); + return flag.GetVariants().at("premium"); } } - return f.GetVariants().at("standard"); + return flag.GetVariants().at("standard"); }; Flag flag(variants, "standard", evaluator, FlagMetadata{}); const auto& eval_func = flag.GetContextEvaluator(); EvaluationContext premium_ctx = - EvaluationContext::Builder().WithAttribute("tier", "premium").build(); + EvaluationContext::Builder().WithAttribute("tier", "premium").Build(); absl::StatusOr premium_res = eval_func(flag, premium_ctx); ASSERT_TRUE(premium_res.ok()); - EXPECT_EQ(*premium_res, 100); + EXPECT_EQ(*premium_res, kPremiumValue); EvaluationContext standard_ctx = - EvaluationContext::Builder().WithAttribute("tier", "standard").build(); + EvaluationContext::Builder().WithAttribute("tier", "standard").Build(); absl::StatusOr standard_res = eval_func(flag, standard_ctx); ASSERT_TRUE(standard_res.ok()); - EXPECT_EQ(*standard_res, 10); + EXPECT_EQ(*standard_res, kStandardValue); } TEST(FlagTest, EvaluatorReturnsErrorStatus) { @@ -140,7 +163,7 @@ TEST(FlagTest, EvaluatorReturnsErrorStatus) { Flag flag({}, "default", evaluator, FlagMetadata{}); - EvaluationContext empty_ctx = EvaluationContext::Builder().build(); + EvaluationContext empty_ctx = EvaluationContext::Builder().Build(); absl::StatusOr result = flag.GetContextEvaluator()(flag, empty_ctx); EXPECT_FALSE(result.ok()); diff --git a/test/memory_provider/in_memory_provider_test.cpp b/test/memory_provider/in_memory_provider_test.cpp index d63adfc..ec0939c 100644 --- a/test/memory_provider/in_memory_provider_test.cpp +++ b/test/memory_provider/in_memory_provider_test.cpp @@ -24,7 +24,7 @@ using ::testing::Optional; class InMemoryProviderTest : public ::testing::Test { protected: - EvaluationContext empty_ctx_ = EvaluationContext::Builder().build(); + EvaluationContext empty_ctx_ = EvaluationContext::Builder().Build(); // Helper method to create a generic flag for testing. template @@ -372,7 +372,7 @@ class ContextAwareProviderTest : public InMemoryProviderTest { TEST_F(ContextAwareProviderTest, AdminUserMatchesTargeting) { EvaluationContext admin_ctx = - EvaluationContext::Builder().WithAttribute("user_is_admin", true).build(); + EvaluationContext::Builder().WithAttribute("user_is_admin", true).Build(); absl::StatusOr> res_or = provider_.GetBooleanEvaluation("admin_flag", false, admin_ctx); ASSERT_TRUE(res_or.ok()); @@ -386,7 +386,7 @@ TEST_F(ContextAwareProviderTest, AdminUserMatchesTargeting) { TEST_F(ContextAwareProviderTest, NonAdminUserMatchesTargeting) { EvaluationContext non_admin_ctx = EvaluationContext::Builder() .WithAttribute("user_is_admin", false) - .build(); + .Build(); absl::StatusOr> res_or = provider_.GetBooleanEvaluation("admin_flag", true, non_admin_ctx); ASSERT_TRUE(res_or.ok()); @@ -412,7 +412,7 @@ TEST_F(ContextAwareProviderTest, WrongAttributeTypeFallsBackToDefaultVariant) { EvaluationContext wrong_type_ctx = EvaluationContext::Builder() .WithAttribute("user_is_admin", std::string("true")) - .build(); + .Build(); absl::StatusOr> res_or = provider_.GetBooleanEvaluation("admin_flag", true, wrong_type_ctx); ASSERT_TRUE(res_or.ok()); diff --git a/test/noop_provider_test.cpp b/test/noop_provider_test.cpp index 747f161..f558b43 100644 --- a/test/noop_provider_test.cpp +++ b/test/noop_provider_test.cpp @@ -18,7 +18,7 @@ using ::openfeature::Value; class NoopProviderTest : public ::testing::Test { protected: NoopProvider provider_; - EvaluationContext ctx_ = EvaluationContext::Builder().build(); + EvaluationContext ctx_ = EvaluationContext::Builder().Build(); }; // Test to verify the metadata returned by the provider. diff --git a/test/openfeature_api_test.cpp b/test/openfeature_api_test.cpp index a8f1e97..8075a6a 100644 --- a/test/openfeature_api_test.cpp +++ b/test/openfeature_api_test.cpp @@ -22,7 +22,7 @@ class OpenFeatureAPITest : public ::testing::Test { void SetUp() override {} void TearDown() override { api_.Shutdown(); - api_.SetEvaluationContext(EvaluationContext::Builder().build()); + api_.SetEvaluationContext(EvaluationContext::Builder().Build()); } OpenFeatureAPI& api_ = OpenFeatureAPI::GetInstance(); @@ -215,7 +215,7 @@ TEST_F(OpenFeatureAPITest, SetAndGetGlobalEvaluationContext) { .WithTargetingKey("global-user-123") .WithAttribute("environment", std::string("production")) .WithAttribute("app_version", std::string("2.1.0")) - .build(); + .Build(); api_.SetEvaluationContext(new_ctx); @@ -235,13 +235,13 @@ TEST_F(OpenFeatureAPITest, SetAndGetGlobalEvaluationContext) { // Test overwriting an existing global evaluation context. TEST_F(OpenFeatureAPITest, OverwriteGlobalEvaluationContext) { EvaluationContext first_ctx = - EvaluationContext::Builder().WithTargetingKey("user-initial").build(); + EvaluationContext::Builder().WithTargetingKey("user-initial").Build(); api_.SetEvaluationContext(first_ctx); EXPECT_EQ(api_.GetEvaluationContext().GetTargetingKey().value(), "user-initial"); EvaluationContext updated_ctx = - EvaluationContext::Builder().WithTargetingKey("user-updated").build(); + EvaluationContext::Builder().WithTargetingKey("user-updated").Build(); api_.SetEvaluationContext(updated_ctx); EXPECT_EQ(api_.GetEvaluationContext().GetTargetingKey().value(), "user-updated"); diff --git a/test/provider_repository_test.cpp b/test/provider_repository_test.cpp index dc1e883..80385ad 100644 --- a/test/provider_repository_test.cpp +++ b/test/provider_repository_test.cpp @@ -24,7 +24,7 @@ class ProviderRepositoryTest : public ::testing::Test { protected: static constexpr std::chrono::milliseconds kWaitDuration{100}; ProviderRepository repo_; - EvaluationContext ctx_ = EvaluationContext::Builder().build(); + EvaluationContext ctx_ = EvaluationContext::Builder().Build(); }; // Test to verify the constructor initializes with a NoopProvider. diff --git a/test/value_test.cpp b/test/value_test.cpp index 8c0be17..e4524f1 100644 --- a/test/value_test.cpp +++ b/test/value_test.cpp @@ -3,6 +3,9 @@ #include #include #include +#include +#include +#include #include #include "gtest/gtest.h" @@ -11,6 +14,47 @@ namespace openfeature { using namespace std::chrono_literals; +namespace { + +// Test constants to avoid magic numbers +constexpr int kTestInt = 456; +constexpr int64_t kTestInt64 = 123LL; +constexpr int64_t kExpectedInt64 = 456LL; +constexpr int kTestVal5 = 5; +constexpr int64_t kExpectedInt5 = 5LL; +constexpr int kTestVal6 = 6; +constexpr int64_t kExpectedInt6 = 6LL; +constexpr int kTestVal10 = 10; +constexpr int64_t kExpectedInt10 = 10LL; +constexpr int kTestVal11 = 11; +constexpr int kTestVal100 = 100; +constexpr int64_t kExpectedInt100 = 100LL; +constexpr int kTestVal200 = 200; +constexpr int64_t kExpectedInt200 = 200LL; +constexpr int64_t kExpectedRoundedInt = 123LL; +constexpr int64_t kRoundUpExpected = 124LL; +constexpr int64_t kRoundDownExpected = 123LL; +constexpr int64_t kExpectedRoundedUp6 = 6LL; +constexpr int64_t kExpectedNegative5 = -5LL; + +constexpr double kTestDouble = 123.45; +constexpr double kTestDouble123 = 123.0; +constexpr double kExpectedDouble = 456.0; +constexpr double kRoundUpInput = 123.5; +constexpr double kRoundDownInput = 123.4; +constexpr double kTestDoubleList = 4.5; +constexpr double kTestDoublePi = 3.14; +constexpr double kTestDoublePiOther = 3.15; +constexpr double kTestDouble50 = 5.0; +constexpr double kTestDouble51 = 5.1; +constexpr double kTestDouble57 = 5.7; +constexpr double kNegative53 = -5.3; +constexpr double kNegative55 = -5.5; + +constexpr size_t kExpectedListSize = 3; + +} // namespace + TEST(ValueTest, DefaultConstructorIsNull) { Value value; EXPECT_TRUE(value.IsNull()); @@ -35,11 +79,11 @@ TEST(ValueTest, BoolConstructorAndAccessors) { } TEST(ValueTest, Int64ConstructorAndAccessors) { - Value int_val(static_cast(123LL)); + Value int_val(static_cast(kTestInt64)); EXPECT_FALSE(int_val.IsNull()); EXPECT_TRUE(int_val.IsNumber()); - EXPECT_EQ(int_val.AsInt(), 123LL); - EXPECT_EQ(int_val.AsDouble(), 123.0); + EXPECT_EQ(int_val.AsInt(), kTestInt64); + EXPECT_EQ(int_val.AsDouble(), kTestDouble123); EXPECT_FALSE(int_val.AsBool().has_value()); Value int_min(std::numeric_limits::min()); @@ -50,30 +94,30 @@ TEST(ValueTest, Int64ConstructorAndAccessors) { } TEST(ValueTest, IntConstructorAndAccessors) { - Value int_val(456); + Value int_val(kTestInt); EXPECT_FALSE(int_val.IsNull()); EXPECT_TRUE(int_val.IsNumber()); - EXPECT_EQ(int_val.AsInt(), 456LL); - EXPECT_EQ(int_val.AsDouble(), 456.0); + EXPECT_EQ(int_val.AsInt(), kExpectedInt64); + EXPECT_EQ(int_val.AsDouble(), kExpectedDouble); } TEST(ValueTest, DoubleConstructorAndAccessors) { - Value double_val(123.45); + Value double_val(kTestDouble); EXPECT_FALSE(double_val.IsNull()); EXPECT_TRUE(double_val.IsNumber()); - EXPECT_EQ(double_val.AsDouble(), 123.45); - EXPECT_EQ(double_val.AsInt(), 123LL); // Should round + EXPECT_EQ(double_val.AsDouble(), kTestDouble); + EXPECT_EQ(double_val.AsInt(), kExpectedRoundedInt); // Should round EXPECT_FALSE(double_val.AsBool().has_value()); - Value double_round_up(123.5); - EXPECT_EQ(double_round_up.AsInt(), 124LL); + Value double_round_up(kRoundUpInput); + EXPECT_EQ(double_round_up.AsInt(), kRoundUpExpected); - Value double_round_down(123.4); - EXPECT_EQ(double_round_down.AsInt(), 123LL); + Value double_round_down(kRoundDownInput); + EXPECT_EQ(double_round_down.AsInt(), kRoundDownExpected); } TEST(ValueTest, StringConstructorAndAccessors) { - Value string_val(std::string("hello")); + Value string_val(std::string{"hello"}); EXPECT_FALSE(string_val.IsNull()); EXPECT_TRUE(string_val.IsString()); EXPECT_EQ(string_val.AsString(), "hello"); @@ -88,7 +132,7 @@ TEST(ValueTest, MapConstructorAndAccessors) { std::map test_map; test_map["key1"] = Value("value1"); test_map["key2"] = Value(true); - test_map["key3"] = Value(123); + test_map["key3"] = Value(static_cast(kTestInt64)); Value map_val(test_map); EXPECT_FALSE(map_val.IsNull()); @@ -97,7 +141,7 @@ TEST(ValueTest, MapConstructorAndAccessors) { ASSERT_TRUE(map_val.AsStructure()->count("key1")); EXPECT_EQ(map_val.AsStructure()->at("key1").AsString(), "value1"); EXPECT_EQ(map_val.AsStructure()->at("key2").AsBool(), true); - EXPECT_EQ(map_val.AsStructure()->at("key3").AsInt(), 123LL); + EXPECT_EQ(map_val.AsStructure()->at("key3").AsInt(), kTestInt64); EXPECT_FALSE(map_val.AsBool().has_value()); EXPECT_EQ(map_val.AsList(), nullptr); @@ -110,18 +154,18 @@ TEST(ValueTest, MapConstructorAndAccessors) { TEST(ValueTest, VectorConstructorAndAccessors) { std::vector test_list; - test_list.push_back(Value("item1")); - test_list.push_back(Value(false)); - test_list.push_back(Value(4.5)); + test_list.emplace_back("item1"); + test_list.emplace_back(false); + test_list.emplace_back(kTestDoubleList); Value list_val(test_list); EXPECT_FALSE(list_val.IsNull()); EXPECT_TRUE(list_val.IsList()); EXPECT_NE(list_val.AsList(), nullptr); - ASSERT_EQ(list_val.AsList()->size(), 3); + ASSERT_EQ(list_val.AsList()->size(), kExpectedListSize); EXPECT_EQ(list_val.AsList()->at(0).AsString(), "item1"); EXPECT_EQ(list_val.AsList()->at(1).AsBool(), false); - EXPECT_EQ(list_val.AsList()->at(2).AsDouble(), 4.5); + EXPECT_EQ(list_val.AsList()->at(2).AsDouble(), kTestDoubleList); EXPECT_FALSE(list_val.AsInt().has_value()); EXPECT_EQ(list_val.AsStructure(), nullptr); @@ -143,12 +187,12 @@ TEST(ValueTest, DateTimeConstructorAndAccessors) { TEST(ValueTest, CopyConstructor) { std::map inner_map; - inner_map["nested_key"] = Value(100); + inner_map["nested_key"] = Value(kTestVal100); std::vector inner_list = {Value("list_item")}; std::map original_map; original_map["bool"] = Value(true); - original_map["int"] = Value(123); + original_map["int"] = Value(static_cast(kTestInt64)); original_map["str"] = Value("original"); original_map["sub_map"] = Value(inner_map); original_map["sub_list"] = Value(inner_list); @@ -176,17 +220,17 @@ TEST(ValueTest, CopyConstructor) { .AsStructure() ->at("nested_key") .AsInt(), - 100LL); + kExpectedInt100); EXPECT_EQ(copied_value.AsStructure() ->at("sub_map") .AsStructure() ->at("nested_key") .AsInt(), - 100LL); + kExpectedInt100); std::map original_nested_map = *original_value.AsStructure()->at("sub_map").AsStructure(); - original_nested_map["nested_key"] = Value(200); + original_nested_map["nested_key"] = Value(kTestVal200); original_map["sub_map"] = Value(original_nested_map); original_value = Value(original_map); @@ -195,22 +239,22 @@ TEST(ValueTest, CopyConstructor) { .AsStructure() ->at("nested_key") .AsInt(), - 200LL); + kExpectedInt200); EXPECT_EQ(copied_value.AsStructure() ->at("sub_map") .AsStructure() ->at("nested_key") .AsInt(), - 100LL); + kExpectedInt100); } TEST(ValueTest, AssignmentOperator) { - Value val1(10); + Value val1(kTestVal10); Value val2("test"); Value val3; val3 = val1; - EXPECT_EQ(val3.AsInt(), 10LL); + EXPECT_EQ(val3.AsInt(), kExpectedInt10); EXPECT_EQ(val3, val1); val3 = val2; @@ -218,7 +262,7 @@ TEST(ValueTest, AssignmentOperator) { EXPECT_EQ(val3, val2); std::map original_map; - original_map["key"] = Value(5); + original_map["key"] = Value(kTestVal5); Value map_val(original_map); Value assigned_map_val; @@ -226,19 +270,19 @@ TEST(ValueTest, AssignmentOperator) { EXPECT_EQ(assigned_map_val, map_val); std::map modified_map = *map_val.AsStructure(); - modified_map["key"] = Value(6); + modified_map["key"] = Value(kTestVal6); map_val = Value(modified_map); EXPECT_NE(assigned_map_val, map_val); - EXPECT_EQ(assigned_map_val.AsStructure()->at("key").AsInt(), 5LL); - EXPECT_EQ(map_val.AsStructure()->at("key").AsInt(), 6LL); + EXPECT_EQ(assigned_map_val.AsStructure()->at("key").AsInt(), kExpectedInt5); + EXPECT_EQ(map_val.AsStructure()->at("key").AsInt(), kExpectedInt6); } TEST(ValueTest, IsNumberHandlesIntAndDouble) { - Value int_val(100); + Value int_val(kTestVal100); EXPECT_TRUE(int_val.IsNumber()); - Value double_val(3.14); + Value double_val(kTestDoublePi); EXPECT_TRUE(double_val.IsNumber()); Value bool_val(true); @@ -249,58 +293,60 @@ TEST(ValueTest, IsNumberHandlesIntAndDouble) { } TEST(ValueTest, AsNumberConversions) { - Value int_val(5); - EXPECT_EQ(int_val.AsInt(), 5LL); - EXPECT_EQ(int_val.AsDouble(), 5.0); + Value int_val(kTestVal5); + EXPECT_EQ(int_val.AsInt(), kExpectedInt5); + EXPECT_EQ(int_val.AsDouble(), kTestDouble50); - Value double_val(5.7); - EXPECT_EQ(double_val.AsInt(), 6LL); - EXPECT_EQ(double_val.AsDouble(), 5.7); + Value double_val(kTestDouble57); + EXPECT_EQ(double_val.AsInt(), kExpectedRoundedUp6); + EXPECT_EQ(double_val.AsDouble(), kTestDouble57); - Value double_val_negative(-5.3); + Value double_val_negative(kNegative53); EXPECT_EQ(double_val_negative.AsInt(), - -5LL); // Rounds to nearest even on .5, otherwise standard rounding - EXPECT_EQ(double_val_negative.AsDouble(), -5.3); + kExpectedNegative5); // Rounds to nearest even on .5, otherwise + // standard rounding + EXPECT_EQ(double_val_negative.AsDouble(), kNegative53); - Value double_val_negative_half(-5.5); - EXPECT_EQ(double_val_negative_half.AsInt(), -5LL); // Rounds to nearest even + Value double_val_negative_half(kNegative55); + EXPECT_EQ(double_val_negative_half.AsInt(), + kExpectedNegative5); // Rounds to nearest even } -TEST(ValueTest, EqualityOperator_BasicTypes) { +TEST(ValueTest, EqualityOperatorBasicTypes) { EXPECT_TRUE(Value(true) == Value(true)); EXPECT_FALSE(Value(true) == Value(false)); - EXPECT_TRUE(Value(10) == Value(10)); - EXPECT_FALSE(Value(10) == Value(11)); - EXPECT_TRUE(Value(3.14) == Value(3.14)); - EXPECT_FALSE(Value(3.14) == Value(3.15)); + EXPECT_TRUE(Value(kTestVal10) == Value(kTestVal10)); + EXPECT_FALSE(Value(kTestVal10) == Value(kTestVal11)); + EXPECT_TRUE(Value(kTestDoublePi) == Value(kTestDoublePi)); + EXPECT_FALSE(Value(kTestDoublePi) == Value(kTestDoublePiOther)); EXPECT_TRUE(Value("test") == Value("test")); EXPECT_FALSE(Value("test") == Value("other")); EXPECT_TRUE(Value() == Value()); - auto t1 = std::chrono::system_clock::now(); - auto t2 = t1 + 1s; - EXPECT_TRUE(Value(t1) == Value(t1)); - EXPECT_FALSE(Value(t1) == Value(t2)); + auto time1 = std::chrono::system_clock::now(); + auto time2 = time1 + 1s; + EXPECT_TRUE(Value(time1) == Value(time1)); + EXPECT_FALSE(Value(time1) == Value(time2)); } -TEST(ValueTest, EqualityOperator_NumberCrossTypes) { - EXPECT_TRUE(Value(5) == Value(5.0)); - EXPECT_TRUE(Value(5.0) == Value(5)); - EXPECT_FALSE(Value(5) == Value(5.1)); - EXPECT_FALSE(Value(5.1) == Value(5)); +TEST(ValueTest, EqualityOperatorNumberCrossTypes) { + EXPECT_TRUE(Value(kTestVal5) == Value(kTestDouble50)); + EXPECT_TRUE(Value(kTestDouble50) == Value(kTestVal5)); + EXPECT_FALSE(Value(kTestVal5) == Value(kTestDouble51)); + EXPECT_FALSE(Value(kTestDouble51) == Value(kTestVal5)); EXPECT_TRUE(Value(std::numeric_limits::max()) == Value(static_cast(std::numeric_limits::max()))); } -TEST(ValueTest, EqualityOperator_DifferentTypes) { +TEST(ValueTest, EqualityOperatorDifferentTypes) { EXPECT_FALSE(Value(true) == Value(1)); - EXPECT_FALSE(Value(10) == Value("10")); - EXPECT_FALSE(Value(3.14) == Value(true)); + EXPECT_FALSE(Value(kTestVal10) == Value("10")); + EXPECT_FALSE(Value(kTestDoublePi) == Value(true)); EXPECT_FALSE(Value("hello") == Value()); EXPECT_FALSE(Value() == Value(false)); } -TEST(ValueTest, EqualityOperator_ComplexTypes) { +TEST(ValueTest, EqualityOperatorComplexTypes) { std::map map1 = {{"a", Value(1)}, {"b", Value("x")}}; std::map map2 = {{"a", Value(1)}, {"b", Value("x")}}; std::map map3 = {{"a", Value(1)}, {"b", Value("y")}}; @@ -331,9 +377,9 @@ TEST(ValueTest, EqualityOperator_ComplexTypes) { TEST(ValueTest, InequalityOperator) { EXPECT_TRUE(Value(true) != Value(false)); - EXPECT_TRUE(Value(10) != Value(11)); + EXPECT_TRUE(Value(kTestVal10) != Value(kTestVal11)); EXPECT_TRUE(Value("test") != Value("other")); - EXPECT_TRUE(Value(5) != Value(5.1)); + EXPECT_TRUE(Value(kTestVal5) != Value(kTestDouble51)); EXPECT_TRUE(Value(true) != Value(1)); EXPECT_TRUE(Value("hello") != Value()); @@ -347,7 +393,7 @@ TEST(ValueTest, InequalityOperator) { EXPECT_FALSE(Value(true) != Value(true)); EXPECT_FALSE(Value() != Value()); - EXPECT_FALSE(Value(5) != Value(5.0)); + EXPECT_FALSE(Value(kTestVal5) != Value(kTestDouble50)); } TEST(ValueTest, MoveConstructorAndAssignmentDefaulted) { @@ -359,7 +405,7 @@ TEST(ValueTest, MoveConstructorAndAssignmentDefaulted) { // Move assignment Value original_map_val; - std::map data_map = {{"key", Value(100)}}; + std::map data_map = {{"key", Value(kTestVal100)}}; original_map_val = Value(data_map); Value target_val("old value"); @@ -367,7 +413,7 @@ TEST(ValueTest, MoveConstructorAndAssignmentDefaulted) { EXPECT_TRUE(target_val.IsStructure()); EXPECT_NE(target_val.AsStructure(), nullptr); - EXPECT_EQ(target_val.AsStructure()->at("key").AsInt(), 100LL); + EXPECT_EQ(target_val.AsStructure()->at("key").AsInt(), kExpectedInt100); } -} // namespace openfeature \ No newline at end of file +} // namespace openfeature