Skip to content

feat: Update gherkin suite to test non-string attributes in fractional - #380

Merged
toddbaert merged 4 commits into
open-feature:mainfrom
NeaguGeorgiana23:fractional_hashing_consistency
Jul 30, 2026
Merged

feat: Update gherkin suite to test non-string attributes in fractional#380
toddbaert merged 4 commits into
open-feature:mainfrom
NeaguGeorgiana23:fractional_hashing_consistency

Conversation

@NeaguGeorgiana23

@NeaguGeorgiana23 NeaguGeorgiana23 commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

This PR

Updates the Gherkin test suite under the a new @fractional-v3 tag in targeting.feature to test the new behavior of the fractional operator as defined in the Fractional Non-String Rand Units ADR.
Before implementing this behavior across multi-language SDK providers, this test suite guarantees that all SDKs implement CBOR normalization, data structures, and edge-case bucketing consistently and correctly.
Specifically, this PR introduces test scenarios covering:

  • Basic Types & Deterministic Encodings: Validates Boolean, String, Integer, and Float encodings resolve to consistent, deterministic v3 buckets.
  • CBOR Specific Constraints & Normalizations:
    • Float-to-Integer Mapping: Ensures conceptually identical values (e.g., 1 and 1.0) normalize to the same integer type before encoding.
    • Zero Values: Asserts that both 0.0 and -0.0 map to the unsigned integer 0.
    • Integer & Float Limits: Validates integer boundary sizes (CBOR width steps at 23/24 and 255/256), large integers near int64 limits, and Float16/32/64 min/max precision boundaries.
  • Complex Types (Objects & Maps):
    • Key Ordering: Validates that map/object keys are sorted lexicographically by bytes before hashing (e.g., {"a": 1, "b": 2} yields the exact same bucket as {"b": 2, "a": 1}).
    • Advanced Structures: Validates empty maps {}, empty arrays [], nested collections, and null value handling inside structures.
  • Encoding Boundaries & UTF-8 Consistency:
    • String Lengths: Tests string encoding at exact CBOR length descriptor thresholds (23/24 bytes and 255/256 bytes).
    • UTF-8 Multibyte Characters: Validates cross-platform hashing consistency for emoji sequences, accents, and multibyte symbols (e.g., Japanese characters).
  • Implicit Targeting Key: Validates that when hashing input is omitted, flagd implicitly builds and CBOR-encodes a 2-element array: [flagKey, targetingKey].
  • Error & Non-Happy Paths:
    • Implicit Failures: Asserts that missing or non-string targetingKey values in implicit mode fail gracefully, falling back to the default variant with a DEFAULT reason.
    • Explicit Nulls: Validates that explicit nulls as hashing input trigger a silent fallback to the defaultVariant.

Related Issues

Fixes #378

Notes

  • Non-Breaking for Existing SDKs: The new scenarios are isolated under the @fractional-v3 tag. Existing SDK implementations (currently running @fractional-v2 or @fractional-v1) will not fail in CI as long as their test runners filter out v3 during the transition period.

Follow-up Tasks

  • Provider SDK teams (Go, Java, JS, Python, C#, etc.) to implement CBOR-based fractional bucketing and enable @fractional-v3 in their respective test suites.

Signed-off-by: NeaguGeorgiana23 <neagugeorgiana@google.com>
@NeaguGeorgiana23
NeaguGeorgiana23 requested a review from a team as a code owner July 23, 2026 15:02
@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The change reformats targeting fixtures, updates one negative fractional-weight case, and adds @fractional-v3 Gherkin coverage for non-string values, numeric boundaries, structured inputs, UTF-8 handling, implicit targeting keys, and invalid inputs.

Changes

Fractional evaluation fixtures

Layer / File(s) Summary
Fractional targeting fixture definitions
flags/custom-ops.json
Expands fractional expressions and nested forms while preserving existing targeting logic and weights.
Custom operator fixture formatting
flags/custom-ops.json
Expands starts_with, ends_with, and sem_ver expressions without changing comparisons or outcomes.
Edge-case targeting fixtures
flags/edge-case-flags.json
Expands null and invalid targeting structures and changes fractional-negative-weight-flag weights to -50 and 100.
Existing fractional scenario examples
gherkin/targeting.feature
Adds @fractional-v3 examples to existing fractional scenarios and adds a targeting-null-flag edge-case expectation.
Non-string and boundary coverage
gherkin/targeting.feature
Adds scenarios for types, numeric normalization and limits, structured values, UTF-8 and string boundaries, implicit keys, and invalid inputs.

Estimated code review effort: 3 (Moderate) | ~30 minutes

Suggested reviewers: bacherfl, james-milligan, lukas-reining

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning Issue #378 requires explicit null hashing inputs to error, but this PR tests silent fallback instead. Align the v3 null-input scenarios with #378 by asserting the required PARSE_ERROR or GENERAL error path instead of defaultVariant fallback.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding fractional test coverage for non-string attributes.
Description check ✅ Passed The description is directly about the new fractional v3 Gherkin suite and matches the PR changes.
Out of Scope Changes check ✅ Passed The changes stay within the fractional test suite and supporting fixtures, with no clearly unrelated additions.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@gherkin/targeting.feature`:
- Around line 608-640: Replace the duplicate JSON member names in the affected
Examples rows of “Fractional operator with advanced structures” with distinct
keys, preserving each row’s intended value coverage. Recompute and update the
expected bucket values for those modified hashing inputs so the fixtures remain
deterministic and valid across SDK parsers.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 918401f1-69b4-4d6c-81a9-56cc069da3a8

📥 Commits

Reviewing files that changed from the base of the PR and between 7575a1d and d2c9792.

📒 Files selected for processing (3)
  • flags/custom-ops.json
  • flags/edge-case-flags.json
  • gherkin/targeting.feature

Comment thread gherkin/targeting.feature Outdated
Signed-off-by: NeaguGeorgiana23 <neagugeorgiana@google.com>
Comment thread gherkin/targeting.feature Outdated
Comment thread gherkin/targeting.feature
Comment thread gherkin/targeting.feature

@toddbaert toddbaert left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left a couple things for you to confirm, and I will leave one more here:

We mentioned wanting an "opt-in" new error handling paradigm, wherein targeting errors would cause erroneous evaluations; however, that's not implemented here (in fact the opposite is explicitly asserted). I'm fine with that, I just want to mention it. in case it was an oversight. Maybe you intend to work on that separately (no problem).

@NeaguGeorgiana23

Copy link
Copy Markdown
Contributor Author

I left a couple things for you to confirm, and I will leave one more here:

We mentioned wanting an "opt-in" new error handling paradigm, wherein targeting errors would cause erroneous evaluations; however, that's not implemented here (in fact the opposite is explicitly asserted). I'm fine with that, I just want to mention it. in case it was an oversight. Maybe you intend to work on that separately (no problem).

Yes, this PR only deals with our default behaviour and a future PR will create tests for this opt-in strict mode.

Signed-off-by: NeaguGeorgiana23 <neagugeorgiana@google.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
gherkin/targeting.feature (1)

680-684: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Expect the supplied fallback value for invalid implicit inputs.

The scenario passes "fallback" as the evaluation default at Line 680, but expects "draw" at Line 683. Invalid implicit targeting should return "fallback" with reason "DEFAULT"; otherwise this test contradicts the documented fallback contract.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@gherkin/targeting.feature` around lines 680 - 684, Update the scenario for
the String flag "fractional-flag-shorthand" so invalid implicit targeting
expects the supplied default value "fallback" instead of "draw", while
preserving the expected reason "DEFAULT".
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@gherkin/targeting.feature`:
- Around line 680-684: Update the scenario for the String flag
"fractional-flag-shorthand" so invalid implicit targeting expects the supplied
default value "fallback" instead of "draw", while preserving the expected reason
"DEFAULT".

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: c3e84c22-6d51-46cb-b609-538cb8120736

📥 Commits

Reviewing files that changed from the base of the PR and between da3e371 and 111e8a4.

📒 Files selected for processing (1)
  • gherkin/targeting.feature

@toddbaert
toddbaert requested a review from leakonvalinka July 30, 2026 13:02
@toddbaert
toddbaert merged commit 197a3c0 into open-feature:main Jul 30, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add new test suite for non-string attributes in fractional evaluation

2 participants