Skip to content

Commit

Permalink
feat: improve gherkin files
Browse files Browse the repository at this point in the history
Signed-off-by: Simon Schrottner <[email protected]>
  • Loading branch information
aepfli committed Dec 5, 2024
1 parent 536d484 commit 9fbb85d
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 145 deletions.
12 changes: 6 additions & 6 deletions gherkin/config.feature
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Feature: Configuration Test

@rpc @in-process
Scenario Outline: Default Config
When we initialize a config
When a config was initialized
Then the option "<option>" of type "<type>" should have the value "<default>"
Examples: Basic
| option | type | default |
Expand Down Expand Up @@ -44,23 +44,23 @@ Feature: Configuration Test

@rpc
Scenario Outline: Default Config RPC
When we initialize a config for "rpc"
When a config was initialized for "rpc"
Then the option "<option>" of type "<type>" should have the value "<default>"
Examples:
| option | type | default |
| port | Integer | 8013 |

@in-process
Scenario Outline: Default Config In-Process
When we initialize a config for "in-process"
When a config was initialized for "in-process"
Then the option "<option>" of type "<type>" should have the value "<default>"
Examples:
| option | type | default |
| port | Integer | 8015 |

Scenario Outline: Dedicated Config
When we have an option "<option>" of type "<type>" with value "<value>"
And we initialize a config
When a config was initialized
Then the option "<option>" of type "<type>" should have the value "<value>"
Examples:
| option | type | value |
Expand Down Expand Up @@ -102,7 +102,7 @@ Feature: Configuration Test

Scenario Outline: Dedicated Config via Env_var
When we have an environment variable "<env>" with value "<value>"
And we initialize a config
When a config was initialized
Then the option "<option>" of type "<type>" should have the value "<value>"
Examples:
| option | env | type | value |
Expand Down Expand Up @@ -148,7 +148,7 @@ Feature: Configuration Test
Scenario Outline: Dedicated Config via Env_var and set
When we have an environment variable "<env>" with value "<env-value>"
And we have an option "<option>" of type "<type>" with value "<value>"
And we initialize a config
When a config was initialized
Then the option "<option>" of type "<type>" should have the value "<value>"
Examples:
| option | env | type | value | env-value |
Expand Down
171 changes: 91 additions & 80 deletions gherkin/flagd-json-evaluator.feature
Original file line number Diff line number Diff line change
Expand Up @@ -9,118 +9,129 @@ Feature: flagd json evaluation

# evaluator refs
Scenario Outline: Evaluator reuse
When a string flag with key <key> is evaluated with default value "fallback"
And a context containing a key "email", with value "[email protected]"
Then the returned value should be <value>
Given a String-flag with key "<key>" and a default value "fallback"
And a context containing a key "email", with type "String" and with value "[email protected]"
When the flag was evaluated with details
Then the resolved details value should be "<value>"
Examples:
| key | value |
| "some-email-targeted-flag" | "hi" |
| "some-other-email-targeted-flag" | "yes" |
| key | value |
| some-email-targeted-flag | hi |
| some-other-email-targeted-flag | yes |

# custom operators
Scenario Outline: Fractional operator
When a string flag with key "fractional-flag" is evaluated with default value "fallback"
And a context containing a nested property with outer key "user" and inner key "name", with value <name>
Then the returned value should be <value>
Given a String-flag with key "fractional-flag" and a default value "fallback"
And a context containing a nested property with outer key "user" and inner key "name", with value "<name>"
When the flag was evaluated with details
Then the resolved details value should be "<value>"
Examples:
| name | value |
| "jack" | "spades" |
| "queen" | "clubs" |
| "ten" | "diamonds" |
| "nine" | "hearts" |
| 3 | "diamonds" |
| name | value |
| jack | spades |
| queen | clubs |
| ten | diamonds |
| nine | hearts |
| 3 | diamonds |

Scenario Outline: Fractional operator shorthand
When a string flag with key "fractional-flag-shorthand" is evaluated with default value "fallback"
And a context containing a targeting key with value <targeting key>
Then the returned value should be <value>
Given a String-flag with key "fractional-flag-shorthand" and a default value "fallback"
And a context containing a targeting key with value "<targeting key>"
When the flag was evaluated with details
Then the resolved details value should be "<value>"
Examples:
| targeting key | value |
| "jon@company.com" | "heads" |
| "jane@company.com" | "tails" |
| targeting key | value |
| jon@company.com | heads |
| jane@company.com | tails |

Scenario Outline: Fractional operator with shared seed
When a string flag with key "fractional-flag-A-shared-seed" is evaluated with default value "fallback"
And a context containing a nested property with outer key "user" and inner key "name", with value <name>
Then the returned value should be <value>
Given a String-flag with key "fractional-flag-A-shared-seed" and a default value "fallback"
And a context containing a nested property with outer key "user" and inner key "name", with value "<name>"
When the flag was evaluated with details
Then the resolved details value should be "<value>"
Examples:
| name | value |
| "jack" | "hearts" |
| "queen" | "spades" |
| "ten" | "hearts" |
| "nine" | "diamonds" |
| name | value |
| jack | hearts |
| queen | spades |
| ten | hearts |
| nine | diamonds |

Scenario Outline: Second fractional operator with shared seed
When a string flag with key "fractional-flag-B-shared-seed" is evaluated with default value "fallback"
And a context containing a nested property with outer key "user" and inner key "name", with value <name>
Then the returned value should be <value>
Given a String-flag with key "fractional-flag-B-shared-seed" and a default value "fallback"
And a context containing a nested property with outer key "user" and inner key "name", with value "<name>"
When the flag was evaluated with details
Then the resolved details value should be "<value>"
Examples:
| name | value |
| "jack" | "ace-of-hearts" |
| "queen" | "ace-of-spades" |
| "ten" | "ace-of-hearts" |
| "nine" | "ace-of-diamonds" |
| name | value |
| jack | ace-of-hearts |
| queen | ace-of-spades |
| ten | ace-of-hearts |
| nine | ace-of-diamonds |

Scenario Outline: Substring operators
When a string flag with key "starts-ends-flag" is evaluated with default value "fallback"
And a context containing a key "id", with value <id>
Then the returned value should be <value>
Given a String-flag with key "starts-ends-flag" and a default value "fallback"
And a context containing a key "id", with type "String" and with value "<id>"
When the flag was evaluated with details
Then the resolved details value should be "<value>"
Examples:
| id | value |
| "abcdef" | "prefix" |
| "uvwxyz" | "postfix" |
| "abcxyz" | "prefix" |
| "lmnopq" | "none" |
| 3 | "none" |
| id | value |
| abcdef | prefix |
| uvwxyz | postfix |
| abcxyz | prefix |
| lmnopq | none |
| 3 | none |

Scenario Outline: Semantic version operator numeric comparison
When a string flag with key "equal-greater-lesser-version-flag" is evaluated with default value "fallback"
And a context containing a key "version", with value <version>
Then the returned value should be <value>
Given a String-flag with key "equal-greater-lesser-version-flag" and a default value "fallback"
And a context containing a key "version", with type "String" and with value "<version>"
When the flag was evaluated with details
Then the resolved details value should be "<value>"
Examples:
| version | value |
| "2.0.0" | "equal" |
| "2.1.0" | "greater" |
| "1.9.0" | "lesser" |
| "2.0.0-alpha" | "lesser" |
| "2.0.0.0" | "none" |
| version | value |
| 2.0.0 | equal |
| 2.1.0 | greater |
| 1.9.0 | lesser |
| 2.0.0-alpha | lesser |
| 2.0.0.0 | none |

Scenario Outline: Semantic version operator semantic comparison
When a string flag with key "major-minor-version-flag" is evaluated with default value "fallback"
And a context containing a key "version", with value <version>
Then the returned value should be <value>
Given a String-flag with key "major-minor-version-flag" and a default value "fallback"
And a context containing a key "version", with type "String" and with value "<version>"
When the flag was evaluated with details
Then the resolved details value should be "<value>"
Examples:
| version | value |
| "3.0.1" | "minor" |
| "3.1.0" | "major" |
| "4.0.0" | "none" |
| version | value |
| 3.0.1 | minor |
| 3.1.0 | major |
| 4.0.0 | none |

Scenario Outline: Time-based operations
When an integer flag with key "timestamp-flag" is evaluated with default value 0
And a context containing a key "time", with value <time>
Then the returned value should be <value>
Given a Integer-flag with key "timestamp-flag" and a default value "0"
And a context containing a key "time", with type "Integer" and with value "<time>"
When the flag was evaluated with details
Then the resolved details value should be "<value>"
Examples:
| time | value |
| 1 | -1 |
| 4133980802 | 1 |

Scenario Outline: Targeting by targeting key
When a string flag with key "targeting-key-flag" is evaluated with default value "fallback"
And a context containing a targeting key with value <targeting key>
Then the returned value should be <value>
Then the returned reason should be <reason>
Given a String-flag with key "targeting-key-flag" and a default value "fallback"
And a context containing a targeting key with value "<targeting key>"
When the flag was evaluated with details
Then the resolved details value should be "<value>"
Then the reason should be "<reason>"
Examples:
| targeting key | value | reason |
| "5c3d8535-f81a-4478-a6d3-afaa4d51199e" | "hit" | "TARGETING_MATCH" |
| "f20bd32d-703b-48b6-bc8e-79d53c85134a" | "miss" | "DEFAULT" |
| targeting key | value | reason |
| 5c3d8535-f81a-4478-a6d3-afaa4d51199e | hit | TARGETING_MATCH |
| f20bd32d-703b-48b6-bc8e-79d53c85134a | miss | DEFAULT |

Scenario Outline: Errors and edge cases
When an integer flag with key <key> is evaluated with default value 3
Then the returned value should be <value>
Given a Integer-flag with key "<key>" and a default value "3"
When the flag was evaluated with details
Then the resolved details value should be "<value>"
Examples:
| key | value |
| "targeting-null-variant-flag" | 2 |
| "error-targeting-flag" | 3 |
| "missing-variant-targeting-flag" | 3 |
| "non-string-variant-targeting-flag" | 2 |
| "empty-targeting-flag" | 1 |
| key | value |
| targeting-null-variant-flag | 2 |
| error-targeting-flag | 3 |
| missing-variant-targeting-flag | 3 |
| non-string-variant-targeting-flag | 2 |
| empty-targeting-flag | 1 |
10 changes: 6 additions & 4 deletions gherkin/flagd-reconnect.feature
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ Feature: flagd provider disconnect and reconnect functionality

Scenario: Provider reconnection
Given a flagd provider is set
When a PROVIDER_READY handler and a PROVIDER_ERROR handler are added
Then the PROVIDER_READY handler must run when the provider connects
And the PROVIDER_ERROR handler must run when the provider's connection is lost
And when the connection is reestablished the PROVIDER_READY handler must run again
Given a PROVIDER_READY handler was added
And a PROVIDER_ERROR handler was added
When a PROVIDER_READY was fired
Then the PROVIDER_READY handler must run
When a PROVIDER_ERROR was fired
Then the PROVIDER_ERROR handler must run

Scenario: Provider unavailable
Given flagd is unavailable
Expand Down
67 changes: 32 additions & 35 deletions gherkin/flagd-rpc-caching.feature
Original file line number Diff line number Diff line change
Expand Up @@ -5,40 +5,37 @@ Feature: Flag evaluation with Caching
Background:
Given a provider is registered

Scenario: Resolves boolean details with caching
When a boolean flag with key "boolean-flag" is evaluated with details and default value "false"
Then the resolved boolean details value should be "true", the variant should be "on", and the reason should be "STATIC"
Then the resolved boolean details value should be "true", the variant should be "on", and the reason should be "CACHED"

Scenario: Resolves string details with caching
When a string flag with key "string-flag" is evaluated with details and default value "bye"
Then the resolved string details value should be "hi", the variant should be "greeting", and the reason should be "STATIC"
Then the resolved string details value should be "hi", the variant should be "greeting", and the reason should be "CACHED"

Scenario: Resolves integer details with caching
When an integer flag with key "integer-flag" is evaluated with details and default value 1
Then the resolved integer details value should be 10, the variant should be "ten", and the reason should be "STATIC"
Then the resolved integer details value should be 10, the variant should be "ten", and the reason should be "CACHED"

Scenario: Resolves float details with caching
When a float flag with key "float-flag" is evaluated with details and default value 0.1
Then the resolved float details value should be 0.5, the variant should be "half", and the reason should be "STATIC"
Then the resolved float details value should be 0.5, the variant should be "half", and the reason should be "CACHED"

Scenario: Resolves object details with caching
When an object flag with key "object-flag" is evaluated with details and a null default value
Then the resolved object details value should be contain fields "showImages", "title", and "imagesPerPage", with values "true", "Check out these pics!" and 100, respectively
And the variant should be "template", and the reason should be "STATIC"
Then the resolved object details value should be contain fields "showImages", "title", and "imagesPerPage", with values "true", "Check out these pics!" and 100, respectively
And the variant should be "template", and the reason should be "CACHED"
Scenario Outline: Resolves <type> details with caching
Given a <type>-flag with key "<key>" and a default value "<default>"
When the flag was evaluated with details
Then the resolved details value should be "<resolved_value>"
And the variant should be "<resolved_variant>"
And the reason should be "STATIC"
When the flag was evaluated with details
Then the resolved details value should be "<resolved_value>"
And the variant should be "<resolved_variant>"
And the reason should be "CACHED"

Examples:
| key | type | default | resolved_variant | resolved_value |
| boolean-flag | Boolean | false | on | true |
| string-flag | String | bye | greeting | hi |
| integer-flag | Integer | 1 | ten | 10 |
| float-flag | Float | 0.1 | half | 0.5 |
| object-flag | Object | null | template | {"showImages": true, "title": "Check out these pics!", "imagesPerPage": 100 } |

Scenario: Flag change event with caching
When a string flag with key "changing-flag" is evaluated with details
When a PROVIDER_CONFIGURATION_CHANGED handler is added
And a flag with key "changing-flag" is modified
Then the returned reason should be "STATIC"
Then the returned reason should be "CACHED"
Then the PROVIDER_CONFIGURATION_CHANGED handler must run
And the event details must indicate "changing-flag" was altered
Then the returned reason should be "STATIC"
Then the returned reason should be "CACHED"
Given a String-flag with key "changing-flag" and a default value "false"
And a PROVIDER_CONFIGURATION_CHANGED handler was added
When the flag was modified
Then the flag is part of the event payload
When the flag was evaluated with details
Then the reason should be "STATIC"
When the flag was evaluated with details
Then the reason should be "CACHED"
When the flag was modified
Then the flag is part of the event payload
When the flag was evaluated with details
Then the reason should be "STATIC"
When the flag was evaluated with details
Then the reason should be "CACHED"
36 changes: 16 additions & 20 deletions gherkin/flagd.feature
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,20 @@ Feature: flagd providers
Then the PROVIDER_READY handler must run

Scenario: Flag change event
When a PROVIDER_CONFIGURATION_CHANGED handler is added
And a flag with key "changing-flag" is modified
Given a String-flag with key "changing-flag" and a default value "false"
And a PROVIDER_CONFIGURATION_CHANGED handler was added
When the flag was modified
Then the PROVIDER_CONFIGURATION_CHANGED handler must run
And the event details must indicate "changing-flag" was altered

# zero evaluation
Scenario: Resolves boolean zero value
When a zero-value boolean flag with key "boolean-zero-flag" is evaluated with default value "true"
Then the resolved boolean zero-value should be "false"

Scenario: Resolves string zero value
When a zero-value string flag with key "string-zero-flag" is evaluated with default value "hi"
Then the resolved string zero-value should be ""

Scenario: Resolves integer zero value
When a zero-value integer flag with key "integer-zero-flag" is evaluated with default value 1
Then the resolved integer zero-value should be 0

Scenario: Resolves float zero value
When a zero-value float flag with key "float-zero-flag" is evaluated with default value 0.1
Then the resolved float zero-value should be 0.0
And the flag is part of the event payload

Scenario Outline: Resolves zero value
Given a <type>-flag with key "<key>" and a default value "<default>"
When the flag was evaluated with details
Then the resolved details value should be "<resolved_value>"

Examples:
| key | type | default | resolved_value |
| boolean-zero-flag | Boolean | true | false |
| string-zero-flag | String | hi | |
| integer-zero-flag | Integer | 1 | 0 |
| float-zero-flag | Float | 0.1 | 0.0 |

0 comments on commit 9fbb85d

Please sign in to comment.