Something went wrong on our end
-
Danis Kirasirov authored4d94ec48
expr_test.go 3.72 KiB
package expr
import (
"context"
"fmt"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestIsExpression(t *testing.T) {
now := time.Now()
tests := []struct {
name string
eval string
want bool
}{
{"equal", "i == 3", true},
{"in array", "i in [1,2,3]", true},
{"contains", "value contains 'some'", true},
{"contains with . + () $ {} ^", "value contains 'something with . + () $ {} ^'", true},
{"startsWith", "value startsWith 'some'", true},
{"startsWith . + () $ {} ^", "value startsWith '. + () $ {} ^'", true},
{"endsWith", "value endsWith 'some'", true},
{"endsWith . + () $ {} ^", "value endsWith '. + () $ {} ^'", true},
{"icontains", "icontains(value, 'some')", true},
{"icontains with . + () $ {} ^", "icontains (value, 'something with . + () $ {} ^')", true},
{"istartsWith", "istartsWith(value, 'Some')", true},
{"istartsWith . + () $ {} ^ . + () $ {} ^", "istartsWith(value, '. + () $ {} ^')", true},
{"iendsWith", "iendsWith(value, 'some')", true},
{"iendsWith . + () $ {} ^", "iendsWith(value,'. + () $ {} ^')", true},
{"or", "i == 2 || i > 10", true},
{"search", "search('some') || i > 10", true},
{"vars:or", "i == a + 2 || i > a + 10", true},
{"near", "near(a, [55.5, 37.5], 1000)", true},
{"within", "within(a, 'box', [[54.54, 36.36], [55.55, 37.37]])", true},
{"time", "d > Time.Date('2021-08-31')", true},
{"time", fmt.Sprintf("d > Time.Time('%s')", now.Format(time.RFC3339)), true},
{"in", "In(s, [1,2,3])", true},
{"in", "In(s, 1)", true},
{"exists#1", "exists(s)", true},
{"exists#2", "exists", false},
{"len#1", "len(s) == 1", true},
{"len#2", "len(s) != 1", true},
{"len#3", "len(s) > 1", true},
{"len#4", "len(s) >= 1", true},
{"len#5", "len(s) < 1", true},
{"len#6", "len(s) <= 1", true},
{"len#7", "len", false},
{"text search or id", "id", false},
{"numbers", "3", false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := IsExpression(tt.eval)
assert.Equal(t, tt.want, got)
})
}
}
type testEnvStruct struct {
ID string `expr:"id"`
Size int `expr:"size"`
Data interface{} `expr:"data"`
}
func (s *testEnvStruct) Equal(other *testEnvStruct) bool {
return s.ID == other.ID
}
func TestExpr_Example(t *testing.T) {
ctx := context.Background()
tests := []struct {
name string
exp string
env map[string]interface{}
wantErr bool
wantResult interface{}
}{
{
name: "get field by expr tag",
exp: "s.id",
env: map[string]interface{}{"s": &testEnvStruct{ID: "id1"}},
wantResult: "id1",
},
{
name: "get field by field name",
exp: "s.ID",
env: map[string]interface{}{"s": &testEnvStruct{ID: "id1"}},
wantResult: "id1",
},
{
name: "get nested field",
exp: "m.s.size",
env: map[string]interface{}{"m": map[string]interface{}{"s": &testEnvStruct{Size: 1}}},
wantResult: 1,
},
{
name: "check field",
exp: "s.data.size < 100",
env: map[string]interface{}{"s": &testEnvStruct{Data: &testEnvStruct{Size: 0}}},
wantResult: true,
},
{
name: "use method",
exp: "s1.Equal(s2)",
env: map[string]interface{}{"s1": &testEnvStruct{ID: "id1"}, "s2": &testEnvStruct{ID: "id2"}},
wantResult: false,
},
{
name: "field not exists",
exp: "s.not_exists",
env: map[string]interface{}{"s": &testEnvStruct{}},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result, err := Eval(ctx, tt.exp, tt.env)
if tt.wantErr {
require.Error(t, err)
return
}
require.NoError(t, err)
require.Equal(t, tt.wantResult, result)
})
}
}