Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions core/validation/testdata/valid_zero_values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
version: "1.5"
flags:
- key: test_variant_flag
name: Test Variant Flag
type: VARIANT_FLAG_TYPE
enabled: true
variants:
- key: variant1
name: Variant 1
description: First variant
- key: variant2
name: Variant 2
description: Second variant
rules:
- segment: test_segment
distributions:
- variant: variant1
rollout: 0
- variant: variant2
rollout: 100
- key: test_boolean_flag
name: Test Boolean Flag
type: BOOLEAN_FLAG_TYPE
enabled: true
rollouts:
- description: "enabled for 0% threshold"
threshold:
percentage: 0
value: true
- description: "enabled for 0.0% threshold"
threshold:
percentage: 0.0
value: true
- description: "enabled for 50% threshold"
threshold:
percentage: 50
value: true
- description: "enabled for test segment with false value"
segment:
key: test_segment
value: false

segments:
- key: test_segment
name: Test Segment
match_type: ANY_MATCH_TYPE
constraints:
- type: STRING_COMPARISON_TYPE
property: user_id
operator: eq
value: test_user
14 changes: 14 additions & 0 deletions core/validation/validate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,20 @@ func TestValidate_NamespaceDetails_v4(t *testing.T) {
assert.NoError(t, err)
}

func TestValidate_ZeroValues_Success(t *testing.T) {
const file = "testdata/valid_zero_values.yaml"
f, err := os.Open(file)
require.NoError(t, err)

defer f.Close()

v, err := NewFeaturesValidator()
require.NoError(t, err)

err = v.Validate(file, f)
assert.NoError(t, err)
}

func TestValidate_YAML_Stream(t *testing.T) {
const file = "testdata/valid_yaml_stream.yaml"
f, err := os.Open(file)
Expand Down
4 changes: 2 additions & 2 deletions internal/ext/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ type Rule struct {

type Distribution struct {
VariantKey string `yaml:"variant,omitempty" json:"variant,omitempty"`
Rollout float32 `yaml:"rollout,omitempty" json:"rollout,omitempty"`
Rollout float32 `yaml:"rollout" json:"rollout"`
}

type Rollout struct {
Expand Down Expand Up @@ -137,7 +137,7 @@ func (s *SegmentRule) UnmarshalJSON(data []byte) error {
}

type ThresholdRule struct {
Percentage float32 `yaml:"percentage,omitempty" json:"percentage,omitempty"`
Percentage float32 `yaml:"percentage" json:"percentage"`
Value bool `yaml:"value,omitempty" json:"value,omitempty"`
}

Expand Down
194 changes: 194 additions & 0 deletions internal/ext/common_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
package ext

import (
"encoding/json"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gopkg.in/yaml.v3"
)

func TestDistribution_ZeroRollout_YAML(t *testing.T) {
tests := []struct {
name string
rollout float32
expected string
}{
{
name: "zero rollout",
rollout: 0,
expected: "variant: test\nrollout: 0\n",
},
{
name: "zero float rollout",
rollout: 0.0,
expected: "variant: test\nrollout: 0\n",
},
{
name: "non-zero rollout",
rollout: 50.0,
expected: "variant: test\nrollout: 50\n",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
dist := &Distribution{
VariantKey: "test",
Rollout: tt.rollout,
}

data, err := yaml.Marshal(dist)
require.NoError(t, err)
assert.Equal(t, tt.expected, string(data))

// Test unmarshaling back
var unmarshaled Distribution
err = yaml.Unmarshal(data, &unmarshaled)
require.NoError(t, err)
assert.Equal(t, dist.VariantKey, unmarshaled.VariantKey)
assert.InDelta(t, dist.Rollout, unmarshaled.Rollout, 0.001)
})
}
}

func TestDistribution_ZeroRollout_JSON(t *testing.T) {
tests := []struct {
name string
rollout float32
expected string
}{
{
name: "zero rollout",
rollout: 0,
expected: `{"variant":"test","rollout":0}`,
},
{
name: "zero float rollout",
rollout: 0.0,
expected: `{"variant":"test","rollout":0}`,
},
{
name: "non-zero rollout",
rollout: 50.0,
expected: `{"variant":"test","rollout":50}`,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
dist := &Distribution{
VariantKey: "test",
Rollout: tt.rollout,
}

data, err := json.Marshal(dist)
require.NoError(t, err)
assert.Equal(t, tt.expected, string(data))

// Test unmarshaling back
var unmarshaled Distribution
err = json.Unmarshal(data, &unmarshaled)
require.NoError(t, err)
assert.Equal(t, dist.VariantKey, unmarshaled.VariantKey)
assert.InDelta(t, dist.Rollout, unmarshaled.Rollout, 0.001)
})
}
}

func TestThresholdRule_ZeroPercentage_YAML(t *testing.T) {
tests := []struct {
name string
percentage float32
value bool
expected string
}{
{
name: "zero percentage with true value",
percentage: 0,
value: true,
expected: "percentage: 0\nvalue: true\n",
},
{
name: "zero float percentage with false value",
percentage: 0.0,
value: false,
expected: "percentage: 0\n",
},
{
name: "non-zero percentage",
percentage: 50.0,
value: true,
expected: "percentage: 50\nvalue: true\n",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
threshold := &ThresholdRule{
Percentage: tt.percentage,
Value: tt.value,
}

data, err := yaml.Marshal(threshold)
require.NoError(t, err)
assert.Equal(t, tt.expected, string(data))

// Test unmarshaling back
var unmarshaled ThresholdRule
err = yaml.Unmarshal(data, &unmarshaled)
require.NoError(t, err)
assert.InDelta(t, threshold.Percentage, unmarshaled.Percentage, 0.001)
assert.Equal(t, threshold.Value, unmarshaled.Value)
})
}
}

func TestThresholdRule_ZeroPercentage_JSON(t *testing.T) {
tests := []struct {
name string
percentage float32
value bool
expected string
}{
{
name: "zero percentage with true value",
percentage: 0,
value: true,
expected: `{"percentage":0,"value":true}`,
},
{
name: "zero float percentage with false value",
percentage: 0.0,
value: false,
expected: `{"percentage":0}`,
},
{
name: "non-zero percentage",
percentage: 50.0,
value: true,
expected: `{"percentage":50,"value":true}`,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
threshold := &ThresholdRule{
Percentage: tt.percentage,
Value: tt.value,
}

data, err := json.Marshal(threshold)
require.NoError(t, err)
assert.Equal(t, tt.expected, string(data))

// Test unmarshaling back
var unmarshaled ThresholdRule
err = json.Unmarshal(data, &unmarshaled)
require.NoError(t, err)
assert.InDelta(t, threshold.Percentage, unmarshaled.Percentage, 0.001)
assert.Equal(t, threshold.Value, unmarshaled.Value)
})
}
}
Loading