Skip to content

Commit 4968556

Browse files
authored
Added null defaultVariant handling (#79)
* Added null defaultVariant handling Signed-off-by: Marcin Olko <molko@google.com> * Fixed bug and linter errors Signed-off-by: Marcin Olko <molko@google.com> * Fixed linter and improved tests Signed-off-by: Marcin Olko <molko@google.com> --------- Signed-off-by: Marcin Olko <molko@google.com>
1 parent 160c7de commit 4968556

2 files changed

Lines changed: 58 additions & 21 deletions

File tree

providers/flagd/src/evaluator.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -193,12 +193,10 @@ JsonLogicEvaluator::ResolveAny(std::string_view flag_key, T default_value,
193193
variant_name = std::move(*variant);
194194
reason = openfeature::Reason::kTargetingMatch;
195195
} else {
196-
if (!flag_config.contains("defaultVariant")) {
196+
if (flag_config.value("defaultVariant", nlohmann::json()).is_null()) {
197197
return std::make_unique<openfeature::ResolutionDetails<T>>(
198-
std::move(default_value), openfeature::Reason::kError, "",
199-
flag_metadata, openfeature::ErrorCode::kFlagNotFound,
200-
absl::StrCat("flag: ", flag_key,
201-
" doesn't have defaultVariant defined."));
198+
std::move(default_value), openfeature::Reason::kDefault, "",
199+
flag_metadata, std::nullopt, std::nullopt);
202200
}
203201

204202
variant_name = flag_config["defaultVariant"];

providers/flagd/tests/evaluator_test.cpp

Lines changed: 55 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class EvaluatorTest : public ::testing::Test {
3232
std::unique_ptr<flagd::JsonLogicEvaluator> evaluator_;
3333
};
3434

35-
TEST_F(EvaluatorTest, ResolveBoolean_Success) {
35+
TEST_F(EvaluatorTest, ResolveBooleanSuccess) {
3636
nlohmann::json flags = {{"flags",
3737
{{"my-bool-flag",
3838
{{"state", "ENABLED"},
@@ -52,7 +52,7 @@ TEST_F(EvaluatorTest, ResolveBoolean_Success) {
5252
EXPECT_FALSE(result->GetErrorCode().has_value());
5353
}
5454

55-
TEST_F(EvaluatorTest, ResolveBoolean_FlagNotFound) {
55+
TEST_F(EvaluatorTest, ResolveBooleanFlagNotFound) {
5656
nlohmann::json flags = {{"flags", nlohmann::json::object()}};
5757
sync_->TriggerUpdate(flags);
5858

@@ -66,7 +66,7 @@ TEST_F(EvaluatorTest, ResolveBoolean_FlagNotFound) {
6666
EXPECT_EQ(result->GetErrorCode(), openfeature::ErrorCode::kFlagNotFound);
6767
}
6868

69-
TEST_F(EvaluatorTest, ResolveBoolean_TypeMismatch) {
69+
TEST_F(EvaluatorTest, ResolveBooleanTypeMismatch) {
7070
nlohmann::json flags = {
7171
{"flags",
7272
{{"my-string-flag",
@@ -86,7 +86,7 @@ TEST_F(EvaluatorTest, ResolveBoolean_TypeMismatch) {
8686
EXPECT_EQ(result->GetErrorCode(), openfeature::ErrorCode::kTypeMismatch);
8787
}
8888

89-
TEST_F(EvaluatorTest, ResolveBoolean_Metadata) {
89+
TEST_F(EvaluatorTest, ResolveBooleanMetadata) {
9090
nlohmann::json flags = {
9191
{"metadata",
9292
{{"global-key", "global-value"}, {"override-key", "global-override"}}},
@@ -116,7 +116,7 @@ TEST_F(EvaluatorTest, ResolveBoolean_Metadata) {
116116
"flag-override");
117117
}
118118

119-
TEST_F(EvaluatorTest, ResolveBoolean_VariantNotFound) {
119+
TEST_F(EvaluatorTest, ResolveBooleanVariantNotFound) {
120120
nlohmann::json flags = {{"flags",
121121
{{"my-broken-flag",
122122
{{"state", "ENABLED"},
@@ -138,7 +138,7 @@ TEST_F(EvaluatorTest, ResolveBoolean_VariantNotFound) {
138138
"missing-variant.");
139139
}
140140

141-
TEST_F(EvaluatorTest, ResolveString_Success) {
141+
TEST_F(EvaluatorTest, ResolveStringSuccess) {
142142
nlohmann::json flags = {
143143
{"flags",
144144
{{"my-string-flag",
@@ -158,7 +158,7 @@ TEST_F(EvaluatorTest, ResolveString_Success) {
158158
EXPECT_EQ(result->GetVariant(), "v1");
159159
}
160160

161-
TEST_F(EvaluatorTest, ResolveInteger_Success) {
161+
TEST_F(EvaluatorTest, ResolveIntegerSuccess) {
162162
nlohmann::json flags = {{"flags",
163163
{{"my-int-flag",
164164
{{"state", "ENABLED"},
@@ -177,11 +177,13 @@ TEST_F(EvaluatorTest, ResolveInteger_Success) {
177177
EXPECT_EQ(result->GetVariant(), "two");
178178
}
179179

180-
TEST_F(EvaluatorTest, ResolveDouble_Success) {
180+
TEST_F(EvaluatorTest, ResolveDoubleSuccess) {
181+
const double double1 = 1.1;
182+
const double double2 = 2.2;
181183
nlohmann::json flags = {{"flags",
182184
{{"my-double-flag",
183185
{{"state", "ENABLED"},
184-
{"variants", {{"d1", 1.1}, {"d2", 2.2}}},
186+
{"variants", {{"d1", double1}, {"d2", double2}}},
185187
{"defaultVariant", "d1"}}}}}};
186188

187189
sync_->TriggerUpdate(flags);
@@ -191,17 +193,18 @@ TEST_F(EvaluatorTest, ResolveDouble_Success) {
191193
std::unique_ptr<openfeature::DoubleResolutionDetails> result =
192194
evaluator_->ResolveDouble("my-double-flag", 0.0, ctx);
193195

194-
EXPECT_DOUBLE_EQ(result->GetValue(), 1.1);
196+
EXPECT_DOUBLE_EQ(result->GetValue(), double1);
195197
EXPECT_EQ(result->GetReason(), openfeature::Reason::kStatic);
196198
EXPECT_EQ(result->GetVariant(), "d1");
197199
}
198200

199-
TEST_F(EvaluatorTest, ResolveObject_Success) {
201+
TEST_F(EvaluatorTest, ResolveObjectSuccess) {
202+
const int baz = 123;
200203
nlohmann::json flags = {{"flags",
201204
{{"my-object-flag",
202205
{{"state", "ENABLED"},
203206
{"variants",
204-
{{"obj1", {{"foo", "bar"}, {"baz", 123}}},
207+
{{"obj1", {{"foo", "bar"}, {"baz", baz}}},
205208
{"obj2", {{"key", true}}}}},
206209
{"defaultVariant", "obj1"}}}}}};
207210

@@ -225,10 +228,10 @@ TEST_F(EvaluatorTest, ResolveObject_Success) {
225228

226229
EXPECT_TRUE(structure->at("foo").IsString());
227230
EXPECT_EQ(structure->at("foo").AsString().value(), "bar");
228-
EXPECT_EQ(structure->at("baz").AsInt().value(), 123);
231+
EXPECT_EQ(structure->at("baz").AsInt().value(), baz);
229232
}
230233

231-
TEST_F(EvaluatorTest, ResolveString_TypeMismatch) {
234+
TEST_F(EvaluatorTest, ResolveStringTypeMismatch) {
232235
nlohmann::json flags = {{"flags",
233236
{{"my-int-flag",
234237
{{"state", "ENABLED"},
@@ -247,7 +250,7 @@ TEST_F(EvaluatorTest, ResolveString_TypeMismatch) {
247250
EXPECT_EQ(result->GetErrorCode(), openfeature::ErrorCode::kTypeMismatch);
248251
}
249252

250-
TEST_F(EvaluatorTest, ResolveInteger_TypeMismatch) {
253+
TEST_F(EvaluatorTest, ResolveIntegerTypeMismatch) {
251254
nlohmann::json flags = {{"flags",
252255
{{"my-string-flag",
253256
{{"state", "ENABLED"},
@@ -266,7 +269,7 @@ TEST_F(EvaluatorTest, ResolveInteger_TypeMismatch) {
266269
EXPECT_EQ(result->GetErrorCode(), openfeature::ErrorCode::kTypeMismatch);
267270
}
268271

269-
TEST_F(EvaluatorTest, ResolveDouble_TypeMismatch) {
272+
TEST_F(EvaluatorTest, ResolveDoubleTypeMismatch) {
270273
nlohmann::json flags = {{"flags",
271274
{{"my-string-flag",
272275
{{"state", "ENABLED"},
@@ -284,3 +287,39 @@ TEST_F(EvaluatorTest, ResolveDouble_TypeMismatch) {
284287
EXPECT_EQ(result->GetReason(), openfeature::Reason::kError);
285288
EXPECT_EQ(result->GetErrorCode(), openfeature::ErrorCode::kTypeMismatch);
286289
}
290+
291+
class EvaluatorDefaultVariantTest
292+
: public EvaluatorTest,
293+
public ::testing::WithParamInterface<nlohmann::json> {};
294+
295+
TEST_P(EvaluatorDefaultVariantTest, ResolveBooleanReturnsDefault) {
296+
nlohmann::json flags = {{"flags", GetParam()}};
297+
sync_->TriggerUpdate(flags);
298+
299+
openfeature::EvaluationContext ctx =
300+
openfeature::EvaluationContext::Builder().build();
301+
std::unique_ptr<openfeature::BoolResolutionDetails> result =
302+
evaluator_->ResolveBoolean("my-bool-flag", false, ctx);
303+
304+
EXPECT_EQ(result->GetValue(), false);
305+
EXPECT_EQ(result->GetReason(), openfeature::Reason::kDefault);
306+
EXPECT_FALSE(result->GetErrorCode().has_value());
307+
}
308+
309+
INSTANTIATE_TEST_SUITE_P(
310+
DefaultVariantHandling, EvaluatorDefaultVariantTest,
311+
::testing::Values(
312+
// Missing default variant
313+
nlohmann::json{{"my-bool-flag",
314+
{{"state", "ENABLED"},
315+
{"variants", {{"on", true}, {"off", false}}}}}},
316+
// Null default variant
317+
nlohmann::json{{"my-bool-flag",
318+
{{"state", "ENABLED"},
319+
{"variants", {{"on", true}, {"off", false}}},
320+
{"defaultVariant", nullptr}}}},
321+
// Targeting returns null, missing default variant
322+
nlohmann::json{{"my-bool-flag",
323+
{{"state", "ENABLED"},
324+
{"variants", {{"on", true}, {"off", false}}},
325+
{"targeting", {{"if", {{false}, "on", nullptr}}}}}}}));

0 commit comments

Comments
 (0)