Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
80d1d25
feat: added semver support to our existing matchers
pawels-optimizely Aug 13, 2020
2981c20
fix linters
pawels-optimizely Aug 13, 2020
ad65d4b
fix linters
pawels-optimizely Aug 14, 2020
cf66c93
added more changes
pawels-optimizely Aug 17, 2020
a044757
added semver for registry pattern
pawels-optimizely Aug 18, 2020
068ac3d
consolidate all the semver code
pawels-optimizely Aug 19, 2020
e3d7150
added ge and le evaluators
pawels-optimizely Aug 19, 2020
de95b6a
simplify tests
pawels-optimizely Aug 20, 2020
e89d07d
Update pkg/decision/evaluator/matchers/semver_test.go
pawels-optimizely Aug 20, 2020
5cafc5a
cleaning up
pawels-optimizely Aug 20, 2020
89b9406
addressing nit comments
pawels-optimizely Aug 20, 2020
e272112
addressing PR comments
pawels-optimizely Aug 20, 2020
a91371e
increase coverage
pawels-optimizely Aug 20, 2020
ff5136d
increase coverage
pawels-optimizely Aug 20, 2020
18361fd
corrected tests
pawels-optimizely Aug 21, 2020
ae97a2d
increased coverage
pawels-optimizely Aug 21, 2020
9a9ca1b
increase coverage
pawels-optimizely Aug 21, 2020
be1e4a5
small improvement in the coverage
pawels-optimizely Aug 21, 2020
8eaadb8
add a few more tests and fix split when not build or release
thomaszurkan-optimizely Aug 21, 2020
7849cae
Merge branch 'master' into pawel/semver
thomaszurkan-optimizely Aug 21, 2020
ef25dcd
fix merge errors
thomaszurkan-optimizely Aug 21, 2020
57bebb1
slight refactor for lint
thomaszurkan-optimizely Aug 21, 2020
a1ba38b
fixing after a refactor right in the middle of doing this pr.
thomaszurkan-optimizely Aug 21, 2020
f4c2f88
Merge branch 'master' into pawel/semver
thomaszurkan-optimizely Aug 21, 2020
64ae09c
fix lint error
thomaszurkan-optimizely Aug 21, 2020
d2f1ba5
Merge branch 'pawel/semver' of https://github.com/optimizely/go-sdk i…
thomaszurkan-optimizely Aug 21, 2020
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
21 changes: 21 additions & 0 deletions pkg/decision/evaluator/condition_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,24 @@ func TestCustomAttributeConditionEvaluatorWithoutMatchType(t *testing.T) {
result, _ = conditionEvaluator.Evaluate(condition, condTreeParams)
assert.Equal(t, result, false)
}

func TestCustomAttributeConditionEvaluatorForSemver(t *testing.T) {
conditionEvaluator := CustomAttributeConditionEvaluator{}
condition := entities.Condition{
Match: "semver_ge",
Value: "2.9",
Name: "string_foo",
Type: "custom_attribute",
}

// Test condition passes
user := entities.UserContext{
Attributes: map[string]interface{}{
"string_foo": "2.9.1",
},
}

condTreeParams := entities.NewTreeParameters(&user, map[string]entities.Audience{})
result, _ := conditionEvaluator.Evaluate(condition, condTreeParams)
assert.Equal(t, result, true)
}
39 changes: 39 additions & 0 deletions pkg/decision/evaluator/matchers/ge.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/****************************************************************************
* Copyright 2020, Optimizely, Inc. and contributors *
* *
* Licensed under the Apache License, Version 2.0 (the "License"); *
* you may not use this file except in compliance with the License. *
* You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, software *
* distributed under the License is distributed on an "AS IS" BASIS, *
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and *
* limitations under the License. *
***************************************************************************/

// Package matchers //
package matchers

import (
"fmt"

"github.com/optimizely/go-sdk/pkg/decision/evaluator/matchers/utils"
"github.com/optimizely/go-sdk/pkg/entities"
)

// GeMatcher matches against the "ge" match type
func GeMatcher(condition entities.Condition, user entities.UserContext) (bool, error) {

if floatValue, ok := utils.ToFloat(condition.Value); ok {
attributeValue, err := user.GetFloatAttribute(condition.Name)
if err != nil {
return false, err
}
return floatValue <= attributeValue, nil
}

return false, fmt.Errorf("audience condition %s evaluated to NULL because the condition value type is not supported", condition.Name)
}
137 changes: 137 additions & 0 deletions pkg/decision/evaluator/matchers/ge_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
/****************************************************************************
* Copyright 2020, Optimizely, Inc. and contributors *
* *
* Licensed under the Apache License, Version 2.0 (the "License"); *
* you may not use this file except in compliance with the License. *
* You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, software *
* distributed under the License is distributed on an "AS IS" BASIS, *
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and *
* limitations under the License. *
***************************************************************************/

package matchers

import (
"testing"

"github.com/stretchr/testify/assert"

"github.com/optimizely/go-sdk/pkg/entities"
)

var geMatcher, _ = Get(GeMatchType)

func TestGeMatcherInt(t *testing.T) {
condition := entities.Condition{
Match: "ge",
Value: 42,
Name: "int_42",
}

// Test match - same type
user := entities.UserContext{
Attributes: map[string]interface{}{
"int_42": 43,
},
}
result, err := gtMatcher(condition, user)
assert.NoError(t, err)
assert.True(t, result)

// Test match int to float
user = entities.UserContext{
Attributes: map[string]interface{}{
"int_42": 42.9999,
},
}

result, err = geMatcher(condition, user)
assert.NoError(t, err)
assert.True(t, result)

// Test match: 42.9999 converts to 42
user = entities.UserContext{
Attributes: map[string]interface{}{
"int_42": 42.00000,
},
}

result, err = geMatcher(condition, user)
assert.NoError(t, err)
assert.True(t, result)

// Test no match
user = entities.UserContext{
Attributes: map[string]interface{}{
"int_42": 41,
},
}

result, err = geMatcher(condition, user)
assert.NoError(t, err)
assert.False(t, result)

// Test attribute not found
user = entities.UserContext{
Attributes: map[string]interface{}{
"int_43": 42,
},
}

_, err = gtMatcher(condition, user)
assert.Error(t, err)
}

func TestGeMatcherFloat(t *testing.T) {
condition := entities.Condition{
Match: "ge",
Value: 4.2,
Name: "float_4_2",
}

// Test match float to int
user := entities.UserContext{
Attributes: map[string]interface{}{
"float_4_2": 5,
},
}
result, err := geMatcher(condition, user)
assert.NoError(t, err)
assert.True(t, result)

// Test match
user = entities.UserContext{
Attributes: map[string]interface{}{
"float_4_2": 4.29999,
},
}
result, err = geMatcher(condition, user)
assert.NoError(t, err)
assert.True(t, result)

// Test match
user = entities.UserContext{
Attributes: map[string]interface{}{
"float_4_2": 4.2,
},
}

result, err = geMatcher(condition, user)
assert.NoError(t, err)
assert.True(t, result)

// Test attribute not found
user = entities.UserContext{
Attributes: map[string]interface{}{
"float_4_3": 4.2,
},
}

_, err = gtMatcher(condition, user)
assert.Error(t, err)
}
39 changes: 39 additions & 0 deletions pkg/decision/evaluator/matchers/le.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/****************************************************************************
* Copyright 2020, Optimizely, Inc. and contributors *
* *
* Licensed under the Apache License, Version 2.0 (the "License"); *
* you may not use this file except in compliance with the License. *
* You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, software *
* distributed under the License is distributed on an "AS IS" BASIS, *
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and *
* limitations under the License. *
***************************************************************************/

// Package matchers //
package matchers

import (
"fmt"

"github.com/optimizely/go-sdk/pkg/decision/evaluator/matchers/utils"
"github.com/optimizely/go-sdk/pkg/entities"
)

// LeMatcher matches against the "le" match type
func LeMatcher(condition entities.Condition, user entities.UserContext) (bool, error) {

if floatValue, ok := utils.ToFloat(condition.Value); ok {
attributeValue, err := user.GetFloatAttribute(condition.Name)
if err != nil {
return false, err
}
return floatValue >= attributeValue, nil
}

return false, fmt.Errorf("audience condition %s evaluated to NULL because the condition value type is not supported", condition.Name)
}
156 changes: 156 additions & 0 deletions pkg/decision/evaluator/matchers/le_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
/****************************************************************************
* Copyright 2020, Optimizely, Inc. and contributors *
* *
* Licensed under the Apache License, Version 2.0 (the "License"); *
* you may not use this file except in compliance with the License. *
* You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, software *
* distributed under the License is distributed on an "AS IS" BASIS, *
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and *
* limitations under the License. *
***************************************************************************/

package matchers

import (
"testing"

"github.com/stretchr/testify/assert"

"github.com/optimizely/go-sdk/pkg/entities"
)

var leMatcher, _ = Get(LeMatchType)

func TestLeMatcherInt(t *testing.T) {
condition := entities.Condition{
Match: "le",
Value: 42,
Name: "int_42",
}

// Test match - same type
user := entities.UserContext{
Attributes: map[string]interface{}{
"int_42": 41,
},
}
result, err := leMatcher(condition, user)
assert.NoError(t, err)
assert.True(t, result)

// Test match - same type
user = entities.UserContext{
Attributes: map[string]interface{}{
"int_42": 42,
},
}
result, err = leMatcher(condition, user)
assert.NoError(t, err)
assert.True(t, result)
// Test match int to float
user = entities.UserContext{
Attributes: map[string]interface{}{
"int_42": 41.9999,
},
}

result, err = leMatcher(condition, user)
assert.NoError(t, err)
assert.True(t, result)

// Test no match
user = entities.UserContext{
Attributes: map[string]interface{}{
"int_42": 43.00000,
},
}

result, err = leMatcher(condition, user)
assert.NoError(t, err)
assert.False(t, result)

// Test no match
user = entities.UserContext{
Attributes: map[string]interface{}{
"int_42": 43,
},
}

result, err = leMatcher(condition, user)
assert.NoError(t, err)
assert.False(t, result)

// Test attribute not found
user = entities.UserContext{
Attributes: map[string]interface{}{
"int_43": 42,
},
}

_, err = leMatcher(condition, user)
assert.Error(t, err)
}

func TestLeMatcherFloat(t *testing.T) {
condition := entities.Condition{
Match: "le",
Value: 4.2,
Name: "float_4_2",
}

// Test match float to int
user := entities.UserContext{
Attributes: map[string]interface{}{
"float_4_2": 4,
},
}
result, err := leMatcher(condition, user)
assert.NoError(t, err)
assert.True(t, result)

// Test match
user = entities.UserContext{
Attributes: map[string]interface{}{
"float_4_2": 4.19999,
},
}
result, err = leMatcher(condition, user)
assert.NoError(t, err)
assert.True(t, result)

// Test match
user = entities.UserContext{
Attributes: map[string]interface{}{
"float_4_2": 4.200000,
},
}
result, err = leMatcher(condition, user)
assert.NoError(t, err)
assert.True(t, result)

// Test no match
user = entities.UserContext{
Attributes: map[string]interface{}{
"float_4_2": 4.3,
},
}

result, err = leMatcher(condition, user)
assert.NoError(t, err)
assert.False(t, result)

// Test attribute not found
user = entities.UserContext{
Attributes: map[string]interface{}{
"float_4_3": 4.2,
},
}

_, err = leMatcher(condition, user)
assert.Error(t, err)
}
Loading