Skip to content
Snippets Groups Projects
Commit 4d94ec48 authored by Danis Kirasirov's avatar Danis Kirasirov
Browse files

Merge branch 'master' into feature/PRXS-1883-AddExprFuncs

parents 3f099ffd d0069ab4
No related branches found
No related tags found
No related merge requests found
package expr
import (
"context"
"fmt"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestIsExpression(t *testing.T) {
......@@ -58,3 +60,75 @@ func TestIsExpression(t *testing.T) {
})
}
}
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)
})
}
}
......@@ -76,6 +76,7 @@ func TestConvertToMongo(t *testing.T) {
{"in", "In(s, [1,2,3])", nil, bson.M{"s": bson.M{"$in": []interface{}{1, 2, 3}}}, false},
{"in", "In(s, 1)", nil, bson.M{"s": bson.M{"$in": []interface{}{1}}}, false},
{"text search or id", "id", nil, nil, true},
{"struct env", "db_item.id == env_item.id", map[string]interface{}{"env_item": &testEnvStruct{ID: "id1"}}, bson.M{"db_item.id": "id1"}, false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
......
......@@ -16,13 +16,13 @@ const (
// File - описание файла в системе хранения perxis
type File struct {
ID string `mapstructure:"id,omitempty" json:"id" expr:"id"` // Уникальный идентификатор файла в хранилище
Name string `mapstructure:"name,omitempty" json:"name" bson:"name,omitempty" expr:"name"` // Имя файла
Size int `mapstructure:"size,omitempty" json:"size" bson:"size,omitempty" expr:"size"` // Размер файла
ID string `mapstructure:"id,omitempty" json:"id" expr:"id"` // Уникальный идентификатор файла в хранилище
Name string `mapstructure:"name,omitempty" json:"name" bson:"name,omitempty" expr:"name"` // Имя файла
Size int `mapstructure:"size,omitempty" json:"size" bson:"size,omitempty" expr:"size"` // Размер файла
MimeType string `mapstructure:"mimeType,omitempty" json:"mimeType" bson:"mimeType,omitempty" expr:"mime_type"` // Mime-type файла
URL string `mapstructure:"url,omitempty" json:"url" bson:"url,omitempty" expr:"url"` // Адрес для загрузки файла
Key string `mapstructure:"key,omitempty" json:"key" bson:"key,omitempty" expr:"key"` // Ключ для хранения файла в хранилище
File fs.File `mapstructure:"-" json:"-" bson:"-"` // Файл для загрузки(из файловой системы)
URL string `mapstructure:"url,omitempty" json:"url" bson:"url,omitempty" expr:"url"` // Адрес для загрузки файла
Key string `mapstructure:"key,omitempty" json:"key" bson:"key,omitempty" expr:"key"` // Ключ для хранения файла в хранилище
File fs.File `mapstructure:"-" json:"-" bson:"-"` // Файл для загрузки(из файловой системы)
}
func (f File) Clone() *File {
......
package files
import (
"context"
"testing"
"text/template"
"git.perx.ru/perxis/perxis-go/pkg/expr"
"github.com/stretchr/testify/require"
)
......@@ -55,3 +57,35 @@ func TestFile_SetURLWithTemplate(t *testing.T) {
})
}
}
func TestFile_InExpr(t *testing.T) {
ctx := context.Background()
tests := []struct {
exp string
env map[string]interface{}
wantResult interface{}
wantErr bool
}{
{"f.id", map[string]interface{}{"f": &File{ID: "some_id"}}, "some_id", false},
{"f.name", map[string]interface{}{"f": &File{Name: "some_name"}}, "some_name", false},
{"f.size", map[string]interface{}{"f": &File{Size: 1}}, 1, false},
{"f.mime_type", map[string]interface{}{"f": &File{MimeType: "some_mime_type"}}, "some_mime_type", false},
{"f.url", map[string]interface{}{"f": &File{URL: "some_url"}}, "some_url", false},
{"f.key", map[string]interface{}{"f": &File{Key: "some_key"}}, "some_key", false},
{"f.not_exists", map[string]interface{}{"f": &File{}}, "", true},
}
for _, tt := range tests {
t.Run(tt.exp, func(t *testing.T) {
result, err := expr.Eval(ctx, tt.exp, tt.env)
if tt.wantErr {
require.Error(t, err)
return
}
require.NoError(t, err)
require.Equal(t, tt.wantResult, result)
})
}
}
......@@ -398,6 +398,16 @@ func (i *Item) Get(field string) (any, error) {
return i.getItemData(field)
}
// Delete удаляет значение поля Data
func (i *Item) Delete(field string) error {
// Если data == nil, то нет необходимости выполнять удаление
if i.Data == nil {
return nil
}
return data.Delete(field, i.Data)
}
// GetSystemField возвращает описание поля для системных аттрибутов Item
func GetSystemField(fld string) (*field.Field, error) {
switch fld {
......
......@@ -25,6 +25,42 @@ func TestItem_Set(t *testing.T) {
}
func TestItem_DeleteItemData(t *testing.T) {
tests := []struct {
name string
item *Item
field string
want map[string]any
wantErr assert.ErrorAssertionFunc
}{
{
name: "Simple",
item: &Item{Data: map[string]any{"a": "b", "c": "d"}},
field: "a",
want: map[string]any{"c": "d"},
wantErr: assert.NoError,
},
{
name: "Item data is nil",
item: &Item{Data: nil},
field: "a",
want: nil,
wantErr: assert.NoError,
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
err := tc.item.Delete(tc.field)
assert.NoError(t, err)
if !tc.wantErr(t, err) {
return
}
assert.Equal(t, tc.want, tc.item.Data)
})
}
}
func TestGetField(t *testing.T) {
sch := schema.New(
"a", field.String(),
......
package references
import (
"context"
"testing"
"git.perx.ru/perxis/perxis-go/pkg/expr"
"github.com/stretchr/testify/require"
)
func TestReference_InExpr(t *testing.T) {
ctx := context.Background()
tests := []struct {
exp string
env map[string]interface{}
wantResult interface{}
wantErr bool
}{
{"r.id", map[string]interface{}{"r": &Reference{ID: "some_id"}}, "some_id", false},
{"r.collection_id", map[string]interface{}{"r": &Reference{CollectionID: "some_coll_id"}}, "some_coll_id", false},
{"r.disabled", map[string]interface{}{"r": &Reference{Disabled: true}}, true, false},
{"r.String()", map[string]interface{}{"r": &Reference{ID: "id", CollectionID: "collID"}}, "collID.id", false},
{"r1.Equal(r2)", map[string]interface{}{"r1": &Reference{"id", "collID", false}, "r2": &Reference{"id", "collID", false}}, true, false},
{"r.IsValid()", map[string]interface{}{"r": &Reference{}}, false, false},
{"r.not_exists", map[string]interface{}{"r": &Reference{}}, false, true},
}
for _, tt := range tests {
t.Run(tt.exp, func(t *testing.T) {
result, err := expr.Eval(ctx, tt.exp, tt.env)
if tt.wantErr {
require.Error(t, err)
return
}
require.NoError(t, err)
require.Equal(t, tt.wantResult, result)
})
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment