Skip to content

Commit 0df2cd0

Browse files
aepfliCopilot
andcommitted
test(fractional): mirror nested fractional scenarios to evaluator gherkin suite
Adds evaluator counterparts for the four @fractional-nested scenarios that were added to the SDK-level gherkin in #345 and subsequent commits but never mirrored to the evaluator suite: - Nested if expression as variant name (fractional-nested-if-flag) - Nested var expression as variant name (fractional-nested-var-flag) - Nested if expression as weight (fractional-nested-weight-flag) - Fractional operator used as a boolean condition (fractional-as-condition-flag) All scenarios are tagged @fractional-nested so evaluator implementations can opt out during migration with -t 'not @fractional-nested'. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Simon Schrottner <simon.schrottner@dynatrace.com>
1 parent fdfac67 commit 0df2cd0

2 files changed

Lines changed: 111 additions & 0 deletions

File tree

evaluator/flags/testkit-flags.json

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,54 @@
386386
null
387387
]
388388
}
389+
},
390+
"fractional-nested-if-flag": {
391+
"state": "ENABLED",
392+
"variants": { "premium": "premium", "standard": "standard", "fallback": "fallback" },
393+
"defaultVariant": "fallback",
394+
"targeting": {
395+
"fractional": [
396+
{"var": "targetingKey"},
397+
[{"if": [{"==": [{"var": "tier"}, "premium"]}, "premium", "standard"]}, 50],
398+
["standard", 50]
399+
]
400+
}
401+
},
402+
"fractional-nested-var-flag": {
403+
"state": "ENABLED",
404+
"variants": { "red": "red", "green": "green", "blue": "blue", "fallback": "fallback" },
405+
"defaultVariant": "fallback",
406+
"targeting": {
407+
"fractional": [
408+
{"var": "targetingKey"},
409+
[{"var": "color"}, 50],
410+
["blue", 50]
411+
]
412+
}
413+
},
414+
"fractional-nested-weight-flag": {
415+
"state": "ENABLED",
416+
"variants": { "red": "red", "blue": "blue", "fallback": "fallback" },
417+
"defaultVariant": "fallback",
418+
"targeting": {
419+
"fractional": [
420+
{"var": "targetingKey"},
421+
["red", {"if": [{"==": [{"var": "tier"}, "premium"]}, 100, 0]}],
422+
["blue", 10]
423+
]
424+
}
425+
},
426+
"fractional-as-condition-flag": {
427+
"state": "ENABLED",
428+
"variants": { "big": "hundreds", "small": "ones", "fallback": "zero" },
429+
"defaultVariant": "fallback",
430+
"targeting": {
431+
"if": [
432+
{"fractional": [["false", 0], ["true", 100]]},
433+
"big",
434+
"small"
435+
]
436+
}
389437
}
390438
},
391439
"$evaluators": {

evaluator/gherkin/fractional.feature

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,3 +110,66 @@ Feature: Evaluator fractional operator
110110
| SI7p- | lower |
111111
| 6LvT0 | upper |
112112
| ceQdGm | upper |
113+
114+
# Nested JSON Logic expressions as bucket variant names / weights.
115+
# Requires evaluator implementations to support the @fractional-nested feature.
116+
# Use -t "not @fractional-nested" to exclude during transition.
117+
118+
@fractional-nested
119+
Scenario Outline: Fractional operator with nested if expression as variant name
120+
# bucket0=[if(tier=="premium","premium","standard"),50], bucket1=["standard",50]
121+
# jon@company.com bv(100)=36 → bucket0; user1 bv(100)=76 → bucket1
122+
Given an evaluator
123+
And a String-flag with key "fractional-nested-if-flag" and a fallback value "fallback"
124+
And a context containing a targeting key with value "<targetingKey>"
125+
And a context containing a key "tier", with type "String" and with value "<tier>"
126+
When the flag was evaluated with details
127+
Then the resolved details value should be "<value>"
128+
Examples:
129+
| targetingKey | tier | value |
130+
| jon@company.com | premium | premium |
131+
| jon@company.com | basic | standard |
132+
| user1 | premium | standard |
133+
| user1 | basic | standard |
134+
135+
@fractional-nested
136+
Scenario Outline: Fractional operator with nested var expression as variant name
137+
# bucket0=[var("color"),50], bucket1=["blue",50]
138+
# jon@company.com bv(100)=36 → bucket0 (resolves var "color"); user1 bv(100)=76 → bucket1 ("blue")
139+
Given an evaluator
140+
And a String-flag with key "fractional-nested-var-flag" and a fallback value "fallback"
141+
And a context containing a targeting key with value "<targetingKey>"
142+
And a context containing a key "color", with type "String" and with value "<color>"
143+
When the flag was evaluated with details
144+
Then the resolved details value should be "<value>"
145+
Examples:
146+
| targetingKey | color | value |
147+
| jon@company.com | red | red |
148+
| jon@company.com | green | green |
149+
| user1 | red | blue |
150+
| jon@company.com | yellow | fallback |
151+
| jon@company.com | | fallback |
152+
153+
@fractional-nested
154+
Scenario Outline: Fractional operator with nested if expression as weight
155+
# bucket0=["red",if(tier=="premium",100,0)], bucket1=["blue",10]
156+
Given an evaluator
157+
And a String-flag with key "fractional-nested-weight-flag" and a fallback value "fallback"
158+
And a context containing a targeting key with value "<targetingKey>"
159+
And a context containing a key "tier", with type "String" and with value "<tier>"
160+
When the flag was evaluated with details
161+
Then the resolved details value should be "<value>"
162+
Examples:
163+
| targetingKey | tier | value |
164+
| jon@company.com | premium | red |
165+
| jon@company.com | basic | blue |
166+
| user1 | premium | red |
167+
| user1 | basic | blue |
168+
169+
@fractional-nested
170+
Scenario: Fractional as condition
171+
Given an evaluator
172+
And a String-flag with key "fractional-as-condition-flag" and a fallback value "zero"
173+
And a context containing a targeting key with value "some-targeting-key"
174+
When the flag was evaluated with details
175+
Then the resolved details value should be "hundreds"

0 commit comments

Comments
 (0)