1
0
Fork 0
mirror of https://github.com/anyproto/anytype-heart.git synced 2025-06-07 21:37:04 +09:00

Fix database tests save one

This commit is contained in:
Sergey 2024-08-21 17:00:46 +02:00
parent af6169ed5a
commit 61a32b56d5
No known key found for this signature in database
GPG key ID: 3B6BEF79160221C6
13 changed files with 514 additions and 523 deletions

View file

@ -164,12 +164,12 @@ func TestBasic_Duplicate(t *testing.T) {
AddBlock(simple.New(&model.Block{Id: "f1", Content: &model.BlockContentOfFile{File: &model.BlockContentFile{TargetObjectId: "file1_space1"}}})).
AddBlock(simple.New(&model.Block{Id: "f2", Content: &model.BlockContentOfFile{File: &model.BlockContentFile{TargetObjectId: "file2_space1"}}}))
ss := source.NewState()
ss.SetDetail(bundle.RelationKeySpaceId, pbtypes.String(tc.spaceIds[0]))
ss.SetDetail(bundle.RelationKeySpaceId, domain.String(tc.spaceIds[0]))
target := smarttest.New("target").
AddBlock(simple.New(&model.Block{Id: "target"}))
ts := target.NewState()
ts.SetDetail(bundle.RelationKeySpaceId, pbtypes.String(tc.spaceIds[1]))
ts.SetDetail(bundle.RelationKeySpaceId, domain.String(tc.spaceIds[1]))
// when
newIds, err := NewBasic(source, nil, nil, tc.fos()).Duplicate(ss, ts, "target", model.Block_Inner, []string{"1", "f1"})
@ -565,7 +565,7 @@ func TestBasic_SetFields(t *testing.T) {
fields := &types.Struct{
Fields: map[string]*types.Value{
"x": pbtypes.String("x"),
"x": domain.String("x"),
},
}
err := b.SetFields(nil, &pb.RpcBlockListSetFieldsRequestBlockField{
@ -690,7 +690,7 @@ func TestBasic_ReplaceLink(t *testing.T) {
sb := smarttest.New("test")
s := sb.NewState()
s.SetDetail("link", pbtypes.String(oldId))
s.SetDetail("link", domain.String(oldId))
s.AddRelationLinks(&model.RelationLink{Key: "link", Format: model.RelationFormat_object})
template.WithDescription(s)
newBlocks := []simple.Block{

View file

@ -22,10 +22,10 @@ import (
"github.com/anyproto/anytype-heart/pb"
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
coresb "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock"
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/mock_objectstore"
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
"github.com/anyproto/anytype-heart/util/pbtypes"
"github.com/anyproto/anytype-heart/util/slice"
"github.com/anyproto/anytype-heart/util/testMock"
)
type testCreator struct {
@ -36,7 +36,7 @@ func (tc testCreator) Add(object *smarttest.SmartTest) {
tc.objects[object.Id()] = object
}
func (tc testCreator) CreateSmartBlockFromState(_ context.Context, _ string, _ []domain.TypeKey, createState *state.State) (id string, newDetails *types.Struct, err error) {
func (tc testCreator) CreateSmartBlockFromState(_ context.Context, _ string, _ []domain.TypeKey, createState *state.State) (id string, newdetails *domain.Details, err error) {
id = bson.NewObjectId().Hex()
object := smarttest.New(id)
tc.objects[id] = object
@ -55,7 +55,7 @@ func (tts testTemplateService) AddTemplate(id string, st *state.State) {
tts.templates[id] = st
}
func (tts testTemplateService) CreateTemplateStateWithDetails(id string, details *types.Struct) (st *state.State, err error) {
func (tts testTemplateService) CreateTemplateStateWithDetails(id string, details *domain.Details) (st *state.State, err error) {
if id == "" {
st = state.NewDoc("", nil).NewState()
template.InitTemplate(st, template.WithEmpty,
@ -68,12 +68,12 @@ func (tts testTemplateService) CreateTemplateStateWithDetails(id string, details
st = tts.templates[id]
}
templateDetails := st.Details()
newDetails := pbtypes.StructMerge(templateDetails, details, false)
newDetails := templateDetails.Merge(details)
st.SetDetails(newDetails)
return st, nil
}
func (tts testTemplateService) CreateTemplateStateFromSmartBlock(sb smartblock.SmartBlock, details *types.Struct) *state.State {
func (tts testTemplateService) CreateTemplateStateFromSmartBlock(sb smartblock.SmartBlock, details *domain.Details) *state.State {
return tts.templates[sb.Id()]
}
@ -107,15 +107,16 @@ func assertLinkedObjectHasTextBlocks(t *testing.T, ts testCreator, sourceObject
assertHasTextBlocks(t, object, texts)
}
func assertDetails(t *testing.T, id string, ts testCreator, details *types.Struct) {
func assertDetails(t *testing.T, id string, ts testCreator, details *domain.Details) {
object, ok := ts.objects[id]
if !ok {
return
}
objDetails := object.Details()
for key, value := range details.Fields {
assert.Equal(t, value, objDetails.Fields[key])
}
details.Iterate(func(key domain.RelationKey, value domain.Value) bool {
assert.Equal(t, value, objDetails.Get(key))
return true
})
}
func TestExtractObjects(t *testing.T) {
@ -136,10 +137,10 @@ func TestExtractObjects(t *testing.T) {
}
templateDetails := []*model.Detail{
{Key: bundle.RelationKeyName.String(), Value: pbtypes.String("template")},
{Key: bundle.RelationKeyIconImage.String(), Value: pbtypes.String("very funny img")},
{Key: bundle.RelationKeyFeaturedRelations.String(), Value: pbtypes.StringList([]string{"tag", "type", "status"})},
{Key: bundle.RelationKeyCoverId.String(), Value: pbtypes.String("poster with Van Damme")},
{Key: bundle.RelationKeyName, Value: domain.String("template")},
{Key: bundle.RelationKeyIconImage, Value: domain.String("very funny img")},
{Key: bundle.RelationKeyFeaturedRelations, Value: pbtypes.StringList([]string{"tag", "type", "status"})},
{Key: bundle.RelationKeyCoverId, Value: domain.String("poster with Van Damme")},
}
makeTemplateState := func(id string) *state.State {
@ -159,7 +160,7 @@ func TestExtractObjects(t *testing.T) {
typeKey string
templateId string
wantObjectsWithTexts [][]string
wantDetails *types.Struct
wantDetails *domain.Details
}{
{
name: "undefined block",
@ -217,7 +218,7 @@ func TestExtractObjects(t *testing.T) {
"text 2.1",
},
},
wantDetails: &types.Struct{},
wantDetails: domain.NewDetails(),
},
{
name: "two blocks, not all descendants present in requests",
@ -249,12 +250,12 @@ func TestExtractObjects(t *testing.T) {
"text 3", "text 3.1", "text 3.1.1",
},
},
wantDetails: &types.Struct{Fields: map[string]*types.Value{
bundle.RelationKeyName.String(): pbtypes.String("text 3"),
bundle.RelationKeyIconImage.String(): pbtypes.String("very funny img"),
bundle.RelationKeyFeaturedRelations.String(): pbtypes.StringList([]string{"tag", "type", "status"}),
bundle.RelationKeyCoverId.String(): pbtypes.String("poster with Van Damme"),
}},
wantDetails: domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{
bundle.RelationKeyName: domain.String("text 3"),
bundle.RelationKeyIconImage: domain.String("very funny img"),
bundle.RelationKeyFeaturedRelations: pbtypes.StringList([]string{"tag", "type", "status"}),
bundle.RelationKeyCoverId: domain.String("poster with Van Damme"),
}),
},
{
name: "two blocks with children, from template",
@ -272,20 +273,20 @@ func TestExtractObjects(t *testing.T) {
"text 3", "text 3.1", "text 3.1.1",
},
},
wantDetails: &types.Struct{Fields: map[string]*types.Value{
bundle.RelationKeyIconImage.String(): pbtypes.String("very funny img"),
bundle.RelationKeyFeaturedRelations.String(): pbtypes.StringList([]string{"tag", "type", "status"}),
bundle.RelationKeyCoverId.String(): pbtypes.String("poster with Van Damme"),
}},
wantDetails: domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{
bundle.RelationKeyIconImage: domain.String("very funny img"),
bundle.RelationKeyFeaturedRelations: pbtypes.StringList([]string{"tag", "type", "status"}),
bundle.RelationKeyCoverId: domain.String("poster with Van Damme"),
}),
},
{
name: "if target layout includes title, root is not added",
blockIds: []string{"1.1"},
typeKey: bundle.TypeKeyTask.String(),
wantObjectsWithTexts: [][]string{{"text 1.1.1"}},
wantDetails: &types.Struct{Fields: map[string]*types.Value{
bundle.RelationKeyName.String(): pbtypes.String("1.1"),
}},
wantDetails: domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{
bundle.RelationKeyName: domain.String("1.1"),
}),
},
{
name: "template and source are the same objects",
@ -348,13 +349,13 @@ func TestExtractObjects(t *testing.T) {
t.Run("do not add relation name - when creating note", func(t *testing.T) {
fields := createTargetObjectDetails("whatever name", model.ObjectType_note).Fields
assert.NotContains(t, fields, bundle.RelationKeyName.String())
assert.NotContains(t, fields, bundle.RelationKeyName)
})
t.Run("add relation name - when creating not note", func(t *testing.T) {
fields := createTargetObjectDetails("whatever name", model.ObjectType_basic).Fields
assert.Contains(t, fields, bundle.RelationKeyName.String())
assert.Contains(t, fields, bundle.RelationKeyName)
})
t.Run("add custom link block", func(t *testing.T) {
fixture := newFixture(t)
@ -616,14 +617,13 @@ func generateState(root string, blocks []simple.Block) *state.State {
type fixture struct {
t *testing.T
ctrl *gomock.Controller
store *testMock.MockObjectStore
store *mock_objectstore.MockObjectStore
}
func newFixture(t *testing.T) *fixture {
ctrl := gomock.NewController(t)
objectStore := testMock.NewMockObjectStore(ctrl)
objectStore := mock_objectstore.NewMockObjectStore(t)
objectStore.EXPECT().GetObjectByUniqueKey(gomock.Any(), gomock.Any()).DoAndReturn(
objectStore.EXPECT().GetObjectByUniqueKey(gomock.Any(), gomock.Any()).RunAndReturn(
func(_ string, uk domain.UniqueKey) (*model.ObjectDetails, error) {
layout := pbtypes.Int64(int64(model.ObjectType_basic))
switch uk.InternalKey() {
@ -635,15 +635,14 @@ func newFixture(t *testing.T) *fixture {
return &model.ObjectDetails{
Details: &types.Struct{
Fields: map[string]*types.Value{
bundle.RelationKeyRecommendedLayout.String(): layout,
bundle.RelationKeyRecommendedLayout: layout,
},
},
}, nil
}).AnyTimes()
}).Maybe()
return &fixture{
t: t,
ctrl: ctrl,
store: objectStore,
}
}

View file

@ -12,19 +12,18 @@ import (
"github.com/anyproto/anytype-heart/core/block/editor/state"
"github.com/anyproto/anytype-heart/core/block/simple"
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
"github.com/anyproto/anytype-heart/util/pbtypes"
)
func TestHistory_Undo(t *testing.T) {
t.Run("basic", func(t *testing.T) {
bDetails := &types.Struct{
Fields: map[string]*types.Value{
"beforeK": pbtypes.String("beforeV"),
"beforeK": domain.String("beforeV"),
},
}
aDetails := &types.Struct{
Fields: map[string]*types.Value{
"afterK": pbtypes.String("afterV"),
"afterK": domain.String("afterV"),
},
}
sb := smarttest.New("test")
@ -55,7 +54,7 @@ func TestHistory_Undo(t *testing.T) {
s.Unlink("3")
require.NoError(t, s.InsertTo("2", model.Block_Right, "3"))
require.NoError(t, sb.Apply(s))
//t.Log(sb.Doc.(*state.State).String())
// t.Log(sb.Doc.(*state.State).String())
s = sb.NewState()
s.Unlink("3")
@ -66,7 +65,7 @@ func TestHistory_Undo(t *testing.T) {
_, err := h.Undo(nil)
require.NoError(t, err)
//t.Log(sb.Doc.(*state.State).String())
// t.Log(sb.Doc.(*state.State).String())
require.Len(t, sb.Doc.Pick("test").Model().ChildrenIds, 1)
assert.True(t, strings.HasPrefix(sb.Doc.Pick("test").Model().ChildrenIds[0], "r-"))
})

View file

@ -9,7 +9,6 @@ import (
"github.com/anyproto/any-sync/app"
"github.com/anyproto/any-sync/commonspace/object/tree/objecttree"
"github.com/anyproto/any-sync/commonspace/objecttreebuilder"
"github.com/gogo/protobuf/types"
"github.com/anyproto/anytype-heart/core/block/editor/smartblock"
"github.com/anyproto/anytype-heart/core/block/editor/state"
@ -23,9 +22,9 @@ import (
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
coresb "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock"
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore"
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/mock_objectstore"
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
"github.com/anyproto/anytype-heart/pkg/lib/threads"
"github.com/anyproto/anytype-heart/util/testMock"
)
func New(id string) *SmartTest {
@ -61,7 +60,7 @@ type SmartTest struct {
App *app.App
objectTree objecttree.ObjectTree
isDeleted bool
os *testMock.MockObjectStore
os *mock_objectstore.MockObjectStore
space smartblock.Space
// Rudimentary hooks
@ -221,17 +220,17 @@ func (st *SmartTest) TemplateCreateFromObjectState() (*state.State, error) {
return st.Doc.NewState().Copy(), nil
}
func (st *SmartTest) AddRelationLinks(ctx session.Context, relationKeys ...string) (err error) {
func (st *SmartTest) AddRelationLinks(ctx session.Context, relationKeys ...domain.RelationKey) (err error) {
for _, key := range relationKeys {
st.Doc.(*state.State).AddRelationLinks(&model.RelationLink{
Key: key,
Key: key.String(),
Format: 0, // todo
})
}
return nil
}
func (st *SmartTest) AddRelationLinksToState(s *state.State, relationKeys ...string) (err error) {
func (st *SmartTest) AddRelationLinksToState(s *state.State, relationKeys ...domain.RelationKey) (err error) {
return st.AddRelationLinks(nil, relationKeys...)
}
@ -243,7 +242,7 @@ func (st *SmartTest) RefreshLocalDetails(ctx session.Context) error {
return nil
}
func (st *SmartTest) RemoveExtraRelations(ctx session.Context, relationKeys []string) (err error) {
func (st *SmartTest) RemoveExtraRelations(ctx session.Context, relationKeys []domain.RelationKey) (err error) {
return nil
}
@ -260,9 +259,9 @@ func (st *SmartTest) SendEvent(msgs []*pb.EventMessage) {
}
func (st *SmartTest) SetDetails(ctx session.Context, details []*model.Detail, showEvent bool) (err error) {
dets := &types.Struct{Fields: map[string]*types.Value{}}
dets := domain.NewDetails()
for _, d := range details {
dets.Set(d.Key, d.Value)
dets.Set(domain.RelationKey(d.Key), domain.ValueFromProto(d.Value))
}
st.Doc.(*state.State).SetDetails(dets)
return
@ -319,7 +318,7 @@ func (st *SmartTest) Apply(s *state.State, flags ...smartblock.ApplyFlag) (err e
}
if !keepInternalFlags {
s.RemoveDetail(bundle.RelationKeyInternalFlags.String())
s.RemoveDetail(bundle.RelationKeyInternalFlags)
}
msgs, act, err := state.ApplyState(s, true)
@ -374,10 +373,6 @@ func (st *SmartTest) TryClose(objectTTL time.Duration) (res bool, err error) {
return
}
func (st *SmartTest) SetObjectStore(os *testMock.MockObjectStore) {
st.os = os
}
func (st *SmartTest) Inner() smartblock.SmartBlock {
return nil
}

View file

@ -5,17 +5,17 @@ import (
"github.com/anyproto/any-sync/commonspace/object/tree/objecttree/mock_objecttree"
"github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto"
"github.com/gogo/protobuf/types"
"github.com/stretchr/testify/require"
"go.uber.org/mock/gomock"
"github.com/anyproto/anytype-heart/util/testMock"
"github.com/anyproto/anytype-heart/core/block/editor/smartblock"
"github.com/anyproto/anytype-heart/core/block/editor/smartblock/smarttest"
"github.com/anyproto/anytype-heart/core/block/migration"
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
"github.com/anyproto/anytype-heart/space/spaceinfo"
"github.com/anyproto/anytype-heart/util/testMock"
)
func TestSpaceView_AccessType(t *testing.T) {
@ -125,7 +125,7 @@ type spaceServiceStub struct {
func (s *spaceServiceStub) OnViewUpdated(info spaceinfo.SpacePersistentInfo) {
}
func (s *spaceServiceStub) OnWorkspaceChanged(spaceId string, details *types.Struct) {
func (s *spaceServiceStub) OnWorkspaceChanged(spaceId string, details *domain.Details) {
}
func NewSpaceViewTest(t *testing.T, ctrl *gomock.Controller, targetSpaceId string, tree *mock_objecttree.MockObjectTree) (*SpaceView, error) {

View file

@ -1,6 +1,7 @@
package domain
import (
"fmt"
"strings"
"github.com/gogo/protobuf/types"
@ -246,6 +247,10 @@ const (
ValueTypeFloatList
)
func Invalid() Value {
return Value{ok: false}
}
func Null() Value {
return Value{ok: true, value: nullValue{}}
}
@ -476,6 +481,38 @@ func (v Value) Float64List() []float64 {
return res
}
func (v Value) WrapToList() []Value {
list, err := v.TryWrapToList()
if err != nil {
return nil
}
return list
}
func (v Value) TryWrapToList() ([]Value, error) {
if v, ok := v.TryString(); ok {
return []Value{String(v)}, nil
}
if v, ok := v.TryFloat64(); ok {
return []Value{Float64(v)}, nil
}
if v, ok := v.TryStringList(); ok {
res := make([]Value, 0, len(v))
for _, s := range v {
res = append(res, String(s))
}
return res, nil
}
if v, ok := v.TryFloat64List(); ok {
res := make([]Value, 0, len(v))
for _, f := range v {
res = append(res, Float64(f))
}
return res, nil
}
return nil, fmt.Errorf("unsupported type: %v", v.Type())
}
func (v Value) Type() ValueType {
if !v.ok {
return ValueTypeNone
@ -677,11 +714,13 @@ func (v Value) Equal(other Value) bool {
return false
}
func (v Value) Match(boolCase func(v bool), floatCase func(v float64), stringCase func(v string), stringListCase func(v []string), floatListCase func(v []float64)) {
func (v Value) Match(nullCase func(), boolCase func(v bool), floatCase func(v float64), stringCase func(v string), stringListCase func(v []string), floatListCase func(v []float64)) {
if !v.ok {
return
}
switch v := v.value.(type) {
case nullValue:
nullCase()
case bool:
boolCase(v)
case float64:
@ -695,21 +734,26 @@ func (v Value) Match(boolCase func(v bool), floatCase func(v float64), stringCas
}
}
// TODO Refactor, maybe remove Match function
func (v Value) IsEmpty() bool {
if !v.ok {
return true
}
var ok bool
v.Match(func(v bool) {
ok = !v
}, func(v float64) {
ok = v == 0
}, func(v string) {
ok = v == ""
}, func(v []string) {
ok = len(v) == 0
}, func(v []float64) {
ok = len(v) == 0
})
v.Match(
func() {
ok = true
},
func(v bool) {
ok = !v
}, func(v float64) {
ok = v == 0
}, func(v string) {
ok = v == ""
}, func(v []string) {
ok = len(v) == 0
}, func(v []float64) {
ok = len(v) == 0
})
return ok
}

View file

@ -71,9 +71,9 @@ func TestRelations_New_Account(t *testing.T) {
respRelationCreate := mw.ObjectCreateRelation(context.Background(), &pb.RpcObjectCreateRelationRequest{
Details: &types.Struct{Fields: map[string]*types.Value{
bundle.RelationKeyRelationFormat.String(): pbtypes.Float64(float64(relFormat)),
bundle.RelationKeyName.String(): pbtypes.String(relName),
bundle.RelationKeyDescription.String(): pbtypes.String(relDesc),
bundle.RelationKeyType.String(): pbtypes.String(bundle.TypeKeyRelation.URL()),
bundle.RelationKeyName.String(): domain.String(relName),
bundle.RelationKeyDescription.String(): domain.String(relDesc),
bundle.RelationKeyType.String(): domain.String(bundle.TypeKeyRelation.URL()),
}},
})
require.Equal(t, 0, int(respRelationCreate.Error.Code), respRelationCreate.Error.Description)
@ -117,7 +117,7 @@ func TestRelations_New_Account(t *testing.T) {
}
require.True(t, found)
var details *types.Struct
var details *domain.Details
for _, detEvent := range respObjectShow.ObjectView.Details {
if detEvent.Id == respRelationCreate.ObjectId {
details = detEvent.Details
@ -148,9 +148,9 @@ func TestRelations_New_Account(t *testing.T) {
respRelationCreateOption := mw.ObjectCreateRelationOption(context.Background(), &pb.RpcObjectCreateRelationOptionRequest{
Details: &types.Struct{Fields: map[string]*types.Value{
bundle.RelationKeyRelationKey.String(): pbtypes.String(respRelationCreate.Key),
bundle.RelationKeyName.String(): pbtypes.String("test_option_text"),
bundle.RelationKeyRelationOptionColor.String(): pbtypes.String("red"),
bundle.RelationKeyRelationKey.String(): domain.String(respRelationCreate.Key),
bundle.RelationKeyName.String(): domain.String("test_option_text"),
bundle.RelationKeyRelationOptionColor.String(): domain.String("red"),
},
}})
@ -167,7 +167,7 @@ func TestRelations_New_Account(t *testing.T) {
RelationKey: bundle.RelationKeyType.String(),
RelationProperty: "",
Condition: model.BlockContentDataviewFilter_Equal,
Value: pbtypes.String(bundle.TypeKeyRelationOption.URL()),
Value: domain.String(bundle.TypeKeyRelationOption.URL()),
QuickOption: 0,
},
{
@ -175,7 +175,7 @@ func TestRelations_New_Account(t *testing.T) {
RelationKey: bundle.RelationKeyRelationKey.String(),
RelationProperty: "",
Condition: model.BlockContentDataviewFilter_Equal,
Value: pbtypes.String(respRelationCreate.Key),
Value: domain.String(respRelationCreate.Key),
QuickOption: 0,
},
},
@ -208,7 +208,7 @@ func TestRelations_New_Account(t *testing.T) {
RelationKey: bundle.RelationKeyType.String(),
RelationProperty: "",
Condition: model.BlockContentDataviewFilter_Equal,
Value: pbtypes.String(bundle.TypeKeyRelationOption.URL()),
Value: domain.String(bundle.TypeKeyRelationOption.URL()),
QuickOption: 0,
},
{
@ -216,7 +216,7 @@ func TestRelations_New_Account(t *testing.T) {
RelationKey: bundle.RelationKeyRelationKey.String(),
RelationProperty: "",
Condition: model.BlockContentDataviewFilter_Equal,
Value: pbtypes.String(respRelationCreate.Key),
Value: domain.String(respRelationCreate.Key),
QuickOption: 0,
},
},

View file

@ -10,7 +10,6 @@ import (
"github.com/anyproto/anytype-heart/core/domain"
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
"github.com/anyproto/anytype-heart/util/pbtypes"
)
func TestDatabase(t *testing.T) {
@ -34,8 +33,8 @@ func TestDatabase(t *testing.T) {
func newTestQueryBuilder(t *testing.T) queryBuilder {
objectStore := NewMockObjectStore(t)
objectStore.EXPECT().GetRelationFormatByKey(mock.Anything).RunAndReturn(func(key string) (model.RelationFormat, error) {
rel, err := bundle.GetRelation(domain.RelationKey(key))
objectStore.EXPECT().GetRelationFormatByKey(mock.Anything).RunAndReturn(func(key domain.RelationKey) (model.RelationFormat, error) {
rel, err := bundle.GetRelation(key)
if err != nil {
return 0, nil
}
@ -105,33 +104,33 @@ func assertNotIncludeTime(t *testing.T, order SetOrder) {
assert.Equal(t, order[0].(*KeyOrder).IncludeTime, false)
}
func givenSingleDateSort() []*model.BlockContentDataviewSort {
sorts := make([]*model.BlockContentDataviewSort, 1)
sorts[0] = &model.BlockContentDataviewSort{
func givenSingleDateSort() []SortRequest {
sorts := make([]SortRequest, 1)
sorts[0] = SortRequest{
Format: model.RelationFormat_date,
}
return sorts
}
func givenNotSingleDateSort() []*model.BlockContentDataviewSort {
func givenNotSingleDateSort() []SortRequest {
sorts := givenSingleDateSort()
sorts = append(sorts, &model.BlockContentDataviewSort{
sorts = append(sorts, SortRequest{
Format: model.RelationFormat_shorttext,
})
return sorts
}
func givenSingleNotDateSort() []*model.BlockContentDataviewSort {
sorts := make([]*model.BlockContentDataviewSort, 1)
sorts[0] = &model.BlockContentDataviewSort{
func givenSingleNotDateSort() []SortRequest {
sorts := make([]SortRequest, 1)
sorts[0] = SortRequest{
Format: model.RelationFormat_shorttext,
}
return sorts
}
func givenSingleIncludeTime() []*model.BlockContentDataviewSort {
sorts := make([]*model.BlockContentDataviewSort, 1)
sorts[0] = &model.BlockContentDataviewSort{
func givenSingleIncludeTime() []SortRequest {
sorts := make([]SortRequest, 1)
sorts[0] = SortRequest{
Format: model.RelationFormat_shorttext,
IncludeTime: true,
}
@ -153,22 +152,22 @@ func Test_NewFilters(t *testing.T) {
t.Run("and filter with 3 default", func(t *testing.T) {
// given
mockStore := NewMockObjectStore(t)
filter := []*model.BlockContentDataviewFilter{
filter := []FilterRequest{
{
Operator: model.BlockContentDataviewFilter_And,
NestedFilters: []*model.BlockContentDataviewFilter{
NestedFilters: []FilterRequest{
{
Operator: model.BlockContentDataviewFilter_No,
RelationKey: "relationKey",
Condition: model.BlockContentDataviewFilter_Equal,
Value: pbtypes.String("option2"),
Value: domain.String("option2"),
Format: model.RelationFormat_status,
},
{
Operator: model.BlockContentDataviewFilter_No,
RelationKey: bundle.RelationKeyName.String(),
RelationKey: bundle.RelationKeyName,
Condition: model.BlockContentDataviewFilter_Equal,
Value: pbtypes.String("Object 1"),
Value: domain.String("Object 1"),
Format: model.RelationFormat_shorttext,
},
},
@ -187,29 +186,29 @@ func Test_NewFilters(t *testing.T) {
t.Run("deleted filter", func(t *testing.T) {
// given
mockStore := NewMockObjectStore(t)
filter := []*model.BlockContentDataviewFilter{
filter := []FilterRequest{
{
Operator: model.BlockContentDataviewFilter_And,
NestedFilters: []*model.BlockContentDataviewFilter{
NestedFilters: []FilterRequest{
{
Operator: model.BlockContentDataviewFilter_No,
RelationKey: "relationKey",
Condition: model.BlockContentDataviewFilter_Equal,
Value: pbtypes.String("option2"),
Value: domain.String("option2"),
Format: model.RelationFormat_status,
},
{
Operator: model.BlockContentDataviewFilter_No,
RelationKey: bundle.RelationKeyName.String(),
RelationKey: bundle.RelationKeyName,
Condition: model.BlockContentDataviewFilter_Equal,
Value: pbtypes.String("Object 1"),
Value: domain.String("Object 1"),
Format: model.RelationFormat_shorttext,
},
{
Operator: model.BlockContentDataviewFilter_No,
RelationKey: bundle.RelationKeyIsDeleted.String(),
RelationKey: bundle.RelationKeyIsDeleted,
Condition: model.BlockContentDataviewFilter_Equal,
Value: pbtypes.Bool(true),
Value: domain.Bool(true),
},
},
},
@ -227,29 +226,29 @@ func Test_NewFilters(t *testing.T) {
t.Run("archived filter", func(t *testing.T) {
// given
mockStore := NewMockObjectStore(t)
filter := []*model.BlockContentDataviewFilter{
filter := []FilterRequest{
{
Operator: model.BlockContentDataviewFilter_And,
NestedFilters: []*model.BlockContentDataviewFilter{
NestedFilters: []FilterRequest{
{
Operator: model.BlockContentDataviewFilter_No,
RelationKey: "relationKey",
Condition: model.BlockContentDataviewFilter_Equal,
Value: pbtypes.String("option2"),
Value: domain.String("option2"),
Format: model.RelationFormat_status,
},
{
Operator: model.BlockContentDataviewFilter_No,
RelationKey: bundle.RelationKeyName.String(),
RelationKey: bundle.RelationKeyName,
Condition: model.BlockContentDataviewFilter_Equal,
Value: pbtypes.String("Object 1"),
Value: domain.String("Object 1"),
Format: model.RelationFormat_shorttext,
},
{
Operator: model.BlockContentDataviewFilter_No,
RelationKey: bundle.RelationKeyIsArchived.String(),
RelationKey: bundle.RelationKeyIsArchived,
Condition: model.BlockContentDataviewFilter_Equal,
Value: pbtypes.Bool(true),
Value: domain.Bool(true),
},
},
},
@ -267,29 +266,29 @@ func Test_NewFilters(t *testing.T) {
t.Run("type filter", func(t *testing.T) {
// given
mockStore := NewMockObjectStore(t)
filter := []*model.BlockContentDataviewFilter{
filter := []FilterRequest{
{
Operator: model.BlockContentDataviewFilter_And,
NestedFilters: []*model.BlockContentDataviewFilter{
NestedFilters: []FilterRequest{
{
Operator: model.BlockContentDataviewFilter_No,
RelationKey: "relationKey",
Condition: model.BlockContentDataviewFilter_Equal,
Value: pbtypes.String("option2"),
Value: domain.String("option2"),
Format: model.RelationFormat_status,
},
{
Operator: model.BlockContentDataviewFilter_No,
RelationKey: bundle.RelationKeyName.String(),
RelationKey: bundle.RelationKeyName,
Condition: model.BlockContentDataviewFilter_Equal,
Value: pbtypes.String("Object 1"),
Value: domain.String("Object 1"),
Format: model.RelationFormat_shorttext,
},
{
Operator: model.BlockContentDataviewFilter_No,
RelationKey: bundle.RelationKeyType.String(),
RelationKey: bundle.RelationKeyType,
Condition: model.BlockContentDataviewFilter_In,
Value: pbtypes.Float64(float64(model.ObjectType_space)),
Value: domain.Int64(model.ObjectType_space),
},
},
},
@ -307,22 +306,22 @@ func Test_NewFilters(t *testing.T) {
t.Run("or filter with 3 default", func(t *testing.T) {
// given
mockStore := NewMockObjectStore(t)
filter := []*model.BlockContentDataviewFilter{
filter := []FilterRequest{
{
Operator: model.BlockContentDataviewFilter_Or,
NestedFilters: []*model.BlockContentDataviewFilter{
NestedFilters: []FilterRequest{
{
Operator: model.BlockContentDataviewFilter_No,
RelationKey: "relationKey",
Condition: model.BlockContentDataviewFilter_Equal,
Value: pbtypes.String("option2"),
Value: domain.String("option2"),
Format: model.RelationFormat_status,
},
{
Operator: model.BlockContentDataviewFilter_No,
RelationKey: bundle.RelationKeyName.String(),
RelationKey: bundle.RelationKeyName,
Condition: model.BlockContentDataviewFilter_Equal,
Value: pbtypes.String("Object 1"),
Value: domain.String("Object 1"),
Format: model.RelationFormat_shorttext,
},
},

View file

@ -138,7 +138,7 @@ func makeFilterByCondition(spaceID string, rawFilter FilterRequest, store Object
Value: rawFilter.Value.String(),
}}, nil
case model.BlockContentDataviewFilter_In:
list, err := wrapValueToList(rawFilter.Value)
list, err := rawFilter.Value.TryWrapToList()
if err != nil {
return nil, errors.Join(ErrValueMustBeListSupporting, err)
}
@ -147,7 +147,7 @@ func makeFilterByCondition(spaceID string, rawFilter FilterRequest, store Object
Value: list,
}, nil
case model.BlockContentDataviewFilter_NotIn:
list, err := wrapValueToList(rawFilter.Value)
list, err := rawFilter.Value.TryWrapToList()
if err != nil {
return nil, errors.Join(ErrValueMustBeListSupporting, err)
}
@ -157,22 +157,22 @@ func makeFilterByCondition(spaceID string, rawFilter FilterRequest, store Object
}}, nil
case model.BlockContentDataviewFilter_Empty:
return FilterEmpty{
Key: domain.RelationKey(rawFilter.RelationKey),
Key: rawFilter.RelationKey,
}, nil
case model.BlockContentDataviewFilter_NotEmpty:
return FilterNot{FilterEmpty{
Key: domain.RelationKey(rawFilter.RelationKey),
Key: rawFilter.RelationKey,
}}, nil
case model.BlockContentDataviewFilter_AllIn:
if list, err := wrapValueToStringList(rawFilter.Value); err == nil {
return FilterAllIn{
Key: domain.RelationKey(rawFilter.RelationKey),
Key: rawFilter.RelationKey,
Strings: list,
}, nil
}
if list, err := wrapValueToFloatList(rawFilter.Value); err == nil {
return FilterAllIn{
Key: domain.RelationKey(rawFilter.RelationKey),
Key: rawFilter.RelationKey,
Floats: list,
}, nil
}
@ -180,13 +180,13 @@ func makeFilterByCondition(spaceID string, rawFilter FilterRequest, store Object
case model.BlockContentDataviewFilter_NotAllIn:
if list, err := wrapValueToStringList(rawFilter.Value); err == nil {
return FilterNot{FilterAllIn{
Key: domain.RelationKey(rawFilter.RelationKey),
Key: rawFilter.RelationKey,
Strings: list,
}}, nil
}
if list, err := wrapValueToFloatList(rawFilter.Value); err == nil {
return FilterNot{FilterAllIn{
Key: domain.RelationKey(rawFilter.RelationKey),
Key: rawFilter.RelationKey,
Floats: list,
}}, nil
}
@ -197,9 +197,9 @@ func makeFilterByCondition(spaceID string, rawFilter FilterRequest, store Object
return nil, ErrValueMustBeListSupporting
}
return FilterOptionsEqual{
Key: domain.RelationKey(rawFilter.RelationKey),
Key: rawFilter.RelationKey,
Value: list,
Options: optionsToMap(spaceID, domain.RelationKey(rawFilter.RelationKey), store),
Options: optionsToMap(spaceID, rawFilter.RelationKey, store),
}, nil
case model.BlockContentDataviewFilter_NotExactIn:
list, err := wrapValueToStringList(rawFilter.Value)
@ -207,12 +207,12 @@ func makeFilterByCondition(spaceID string, rawFilter FilterRequest, store Object
return nil, ErrValueMustBeListSupporting
}
return FilterNot{FilterOptionsEqual{
Key: domain.RelationKey(rawFilter.RelationKey),
Key: rawFilter.RelationKey,
Value: list,
}}, nil
case model.BlockContentDataviewFilter_Exists:
return FilterExists{
Key: domain.RelationKey(rawFilter.RelationKey),
Key: rawFilter.RelationKey,
}, nil
default:
return nil, fmt.Errorf("unexpected filter cond: %v", rawFilter.Condition)
@ -239,30 +239,6 @@ func wrapValueToFloatList(val domain.Value) ([]float64, error) {
return nil, fmt.Errorf("unsupported type: %v", val.Type())
}
func wrapValueToList(val domain.Value) ([]domain.Value, error) {
if v, ok := val.TryString(); ok {
return []domain.Value{domain.String(v)}, nil
}
if v, ok := val.TryFloat64(); ok {
return []domain.Value{domain.Float64(v)}, nil
}
if v, ok := val.TryStringList(); ok {
res := make([]domain.Value, 0, len(v))
for _, s := range v {
res = append(res, domain.String(s))
}
return res, nil
}
if v, ok := val.TryFloat64List(); ok {
res := make([]domain.Value, 0, len(v))
for _, f := range v {
res = append(res, domain.Float64(f))
}
return res, nil
}
return nil, fmt.Errorf("unsupported type: %v", val.Type())
}
type WithNestedFilter interface {
IterateNestedFilters(func(nestedFilter Filter) error) error
}

View file

@ -5,186 +5,185 @@ import (
"time"
"github.com/anyproto/any-store/query"
"github.com/gogo/protobuf/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
"github.com/valyala/fastjson"
"github.com/anyproto/anytype-heart/core/domain"
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
"github.com/anyproto/anytype-heart/util/pbtypes"
)
func assertFilter(t *testing.T, f Filter, obj *types.Struct, expected bool) {
func assertFilter(t *testing.T, f Filter, obj *domain.Details, expected bool) {
assert.Equal(t, expected, f.FilterObject(obj))
anystoreFilter := f.AnystoreFilter()
_, err := query.ParseCondition(anystoreFilter.String())
require.NoError(t, err, anystoreFilter.String())
arena := &fastjson.Arena{}
val := pbtypes.ProtoToJson(arena, obj)
val := obj.ToJson(arena)
assert.Equal(t, expected, anystoreFilter.Ok(val))
}
func TestEq_FilterObject(t *testing.T) {
t.Run("eq", func(t *testing.T) {
t.Run("ok", func(t *testing.T) {
eq := FilterEq{Key: "k", Value: pbtypes.String("equal test"), Cond: model.BlockContentDataviewFilter_Equal}
g := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("equal test")}}
eq := FilterEq{Key: "k", Value: domain.String("equal test"), Cond: model.BlockContentDataviewFilter_Equal}
g := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.String("equal test")})
assertFilter(t, eq, g, true)
})
t.Run("list ok", func(t *testing.T) {
eq := FilterEq{Key: "k", Value: pbtypes.String("equal test"), Cond: model.BlockContentDataviewFilter_Equal}
g := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.StringList([]string{"11", "equal test", "other"})}}
eq := FilterEq{Key: "k", Value: domain.String("equal test"), Cond: model.BlockContentDataviewFilter_Equal}
g := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.StringList([]string{"11", "equal test", "other"})})
assertFilter(t, eq, g, true)
})
t.Run("not ok", func(t *testing.T) {
eq := FilterEq{Key: "k", Value: pbtypes.String("equal test"), Cond: model.BlockContentDataviewFilter_Equal}
g := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("not equal test")}}
eq := FilterEq{Key: "k", Value: domain.String("equal test"), Cond: model.BlockContentDataviewFilter_Equal}
g := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.String("not equal test")})
assertFilter(t, eq, g, false)
})
t.Run("not ok list", func(t *testing.T) {
eq := FilterEq{Key: "k", Value: pbtypes.String("equal test"), Cond: model.BlockContentDataviewFilter_Equal}
g := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.StringList([]string{"11", "not equal test", "other"})}}
eq := FilterEq{Key: "k", Value: domain.String("equal test"), Cond: model.BlockContentDataviewFilter_Equal}
g := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.StringList([]string{"11", "not equal test", "other"})})
assertFilter(t, eq, g, false)
})
})
t.Run("gt", func(t *testing.T) {
t.Run("ok", func(t *testing.T) {
eq := FilterEq{Key: "k", Value: pbtypes.Float64(1), Cond: model.BlockContentDataviewFilter_Greater}
g := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Float64(2)}}
eq := FilterEq{Key: "k", Value: domain.Float64(1), Cond: model.BlockContentDataviewFilter_Greater}
g := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Float64(2)})
assertFilter(t, eq, g, true)
})
t.Run("not ok eq", func(t *testing.T) {
eq := FilterEq{Key: "k", Value: pbtypes.Float64(2), Cond: model.BlockContentDataviewFilter_Greater}
g := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Float64(2)}}
eq := FilterEq{Key: "k", Value: domain.Float64(2), Cond: model.BlockContentDataviewFilter_Greater}
g := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Float64(2)})
assertFilter(t, eq, g, false)
})
t.Run("not ok less", func(t *testing.T) {
eq := FilterEq{Key: "k", Value: pbtypes.Float64(2), Cond: model.BlockContentDataviewFilter_Greater}
g := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Float64(1)}}
eq := FilterEq{Key: "k", Value: domain.Float64(2), Cond: model.BlockContentDataviewFilter_Greater}
g := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Float64(1)})
assertFilter(t, eq, g, false)
})
})
t.Run("gte", func(t *testing.T) {
t.Run("ok", func(t *testing.T) {
eq := FilterEq{Key: "k", Value: pbtypes.Float64(1), Cond: model.BlockContentDataviewFilter_GreaterOrEqual}
g := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Float64(2)}}
eq := FilterEq{Key: "k", Value: domain.Float64(1), Cond: model.BlockContentDataviewFilter_GreaterOrEqual}
g := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Float64(2)})
assertFilter(t, eq, g, true)
})
t.Run("ok eq", func(t *testing.T) {
eq := FilterEq{Key: "k", Value: pbtypes.Float64(2), Cond: model.BlockContentDataviewFilter_GreaterOrEqual}
g := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Float64(2)}}
eq := FilterEq{Key: "k", Value: domain.Float64(2), Cond: model.BlockContentDataviewFilter_GreaterOrEqual}
g := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Float64(2)})
assertFilter(t, eq, g, true)
})
t.Run("not ok less", func(t *testing.T) {
eq := FilterEq{Key: "k", Value: pbtypes.Float64(2), Cond: model.BlockContentDataviewFilter_GreaterOrEqual}
g := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Float64(1)}}
eq := FilterEq{Key: "k", Value: domain.Float64(2), Cond: model.BlockContentDataviewFilter_GreaterOrEqual}
g := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Float64(1)})
assertFilter(t, eq, g, false)
})
})
t.Run("lt", func(t *testing.T) {
t.Run("ok", func(t *testing.T) {
eq := FilterEq{Key: "k", Value: pbtypes.Float64(2), Cond: model.BlockContentDataviewFilter_Less}
g := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Float64(1)}}
eq := FilterEq{Key: "k", Value: domain.Float64(2), Cond: model.BlockContentDataviewFilter_Less}
g := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Float64(1)})
assertFilter(t, eq, g, true)
})
t.Run("not ok eq", func(t *testing.T) {
eq := FilterEq{Key: "k", Value: pbtypes.Float64(2), Cond: model.BlockContentDataviewFilter_Less}
g := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Float64(2)}}
eq := FilterEq{Key: "k", Value: domain.Float64(2), Cond: model.BlockContentDataviewFilter_Less}
g := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Float64(2)})
assertFilter(t, eq, g, false)
})
t.Run("not ok less", func(t *testing.T) {
eq := FilterEq{Key: "k", Value: pbtypes.Float64(1), Cond: model.BlockContentDataviewFilter_Less}
g := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Float64(2)}}
eq := FilterEq{Key: "k", Value: domain.Float64(1), Cond: model.BlockContentDataviewFilter_Less}
g := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Float64(2)})
assertFilter(t, eq, g, false)
})
})
t.Run("lte", func(t *testing.T) {
t.Run("ok", func(t *testing.T) {
eq := FilterEq{Key: "k", Value: pbtypes.Float64(2), Cond: model.BlockContentDataviewFilter_LessOrEqual}
g := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Float64(1)}}
eq := FilterEq{Key: "k", Value: domain.Float64(2), Cond: model.BlockContentDataviewFilter_LessOrEqual}
g := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Float64(1)})
assertFilter(t, eq, g, true)
})
t.Run("ok eq", func(t *testing.T) {
eq := FilterEq{Key: "k", Value: pbtypes.Float64(2), Cond: model.BlockContentDataviewFilter_LessOrEqual}
g := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Float64(2)}}
eq := FilterEq{Key: "k", Value: domain.Float64(2), Cond: model.BlockContentDataviewFilter_LessOrEqual}
g := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Float64(2)})
assertFilter(t, eq, g, true)
})
t.Run("not ok less", func(t *testing.T) {
eq := FilterEq{Key: "k", Value: pbtypes.Float64(1), Cond: model.BlockContentDataviewFilter_LessOrEqual}
g := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Float64(2)}}
eq := FilterEq{Key: "k", Value: domain.Float64(1), Cond: model.BlockContentDataviewFilter_LessOrEqual}
g := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Float64(2)})
assertFilter(t, eq, g, false)
})
})
t.Run("not equal", func(t *testing.T) {
eq := FilterEq{Key: "k", Value: pbtypes.Float64(2), Cond: model.BlockContentDataviewFilter_NotEqual}
obj := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Float64(1)}}
eq := FilterEq{Key: "k", Value: domain.Float64(2), Cond: model.BlockContentDataviewFilter_NotEqual}
obj := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Float64(1)})
assertFilter(t, eq, obj, true)
obj = &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Float64(2)}}
obj = domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Float64(2)})
assertFilter(t, eq, obj, false)
})
}
func TestNot_FilterObject(t *testing.T) {
eq := FilterEq{Key: "k", Value: pbtypes.Float64(1), Cond: model.BlockContentDataviewFilter_Equal}
g := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Float64(1)}}
eq := FilterEq{Key: "k", Value: domain.Float64(1), Cond: model.BlockContentDataviewFilter_Equal}
g := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Float64(1)})
assertFilter(t, eq, g, true)
assertFilter(t, FilterNot{eq}, g, false)
}
func TestIn_FilterObject(t *testing.T) {
in := FilterIn{Key: "k", Value: pbtypes.StringList([]string{"1", "2", "3"}).GetListValue()}
in := FilterIn{Key: "k", Value: domain.StringList([]string{"1", "2", "3"}).WrapToList()}
t.Run("ok list -> str", func(t *testing.T) {
for _, v := range []string{"1", "2", "3"} {
g := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String(v)}}
g := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.String(v)})
assertFilter(t, in, g, true)
}
})
t.Run("not ok list -> str", func(t *testing.T) {
g := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("not ok")}}
g := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.String("not ok")})
assertFilter(t, in, g, false)
})
t.Run("ok list -> list", func(t *testing.T) {
g := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.StringList([]string{"not ok", "1", "222"})}}
g := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.StringList([]string{"not ok", "1", "222"})})
assertFilter(t, in, g, true)
})
t.Run("not ok list -> list", func(t *testing.T) {
g := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.StringList([]string{"not ok"})}}
g := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.StringList([]string{"not ok"})})
assertFilter(t, in, g, false)
})
t.Run("not in", func(t *testing.T) {
f := FilterNot{FilterIn{Key: "k", Value: pbtypes.StringList([]string{"1", "2", "3"}).GetListValue()}}
obj := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("4")}}
f := FilterNot{FilterIn{Key: "k", Value: domain.StringList([]string{"1", "2", "3"}).WrapToList()}}
obj := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.String("4")})
assertFilter(t, f, obj, true)
obj = &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("1")}}
obj = domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.String("1")})
assertFilter(t, f, obj, false)
})
}
func TestLike_FilterObject(t *testing.T) {
t.Run("ok", func(t *testing.T) {
like := FilterLike{Key: "k", Value: pbtypes.String("sub")}
g := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("with suBstr")}}
like := FilterLike{Key: "k", Value: "sub"}
g := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.String("with suBstr")})
assertFilter(t, like, g, true)
})
t.Run("not ok", func(t *testing.T) {
like := FilterLike{Key: "k", Value: pbtypes.String("sub")}
g := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("with str")}}
like := FilterLike{Key: "k", Value: "sub"}
g := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.String("with str")})
assertFilter(t, like, g, false)
})
t.Run("escape regexp", func(t *testing.T) {
like := FilterLike{Key: "k", Value: pbtypes.String("[abc]")}
like := FilterLike{Key: "k", Value: "[abc]"}
t.Run("ok", func(t *testing.T) {
g := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("[abc]")}}
g := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.String("[abc]")})
assertFilter(t, like, g, true)
})
t.Run("not ok", func(t *testing.T) {
g := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("a")}}
g := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.String("a")})
assertFilter(t, like, g, false)
})
})
@ -192,104 +191,101 @@ func TestLike_FilterObject(t *testing.T) {
func TestEmpty_FilterObject(t *testing.T) {
empty := FilterEmpty{Key: "k"}
var emptyVals = []*types.Value{
pbtypes.String(""),
pbtypes.Bool(false),
pbtypes.Float64(0),
nil,
&types.Value{},
&types.Value{Kind: &types.Value_NullValue{}},
&types.Value{Kind: &types.Value_StructValue{}},
pbtypes.StringList([]string{}),
var emptyVals = []domain.Value{
domain.String(""),
domain.Bool(false),
domain.Float64(0),
domain.Invalid(),
domain.StringList([]string{}),
domain.Float64List(nil),
domain.Null(),
}
for _, ev := range emptyVals {
g := &types.Struct{Fields: map[string]*types.Value{"k": ev}}
g := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": ev})
assertFilter(t, empty, g, true)
}
var notEmptyVals = []*types.Value{
pbtypes.String("1"),
pbtypes.Bool(true),
pbtypes.Float64(1),
pbtypes.StringList([]string{"1"}),
var notEmptyVals = []domain.Value{
domain.String("1"),
domain.Bool(true),
domain.Float64(1),
domain.StringList([]string{"1"}),
domain.Float64List([]float64{1}),
}
for _, ev := range notEmptyVals {
g := &types.Struct{Fields: map[string]*types.Value{"k": ev}}
g := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": ev})
assertFilter(t, empty, g, false)
}
}
func TestAndFilters_FilterObject(t *testing.T) {
and := FiltersAnd{
FilterEq{Key: "k1", Value: pbtypes.String("v1"), Cond: model.BlockContentDataviewFilter_Equal},
FilterEq{Key: "k2", Value: pbtypes.String("v2"), Cond: model.BlockContentDataviewFilter_Equal},
FilterEq{Key: "k1", Value: domain.String("v1"), Cond: model.BlockContentDataviewFilter_Equal},
FilterEq{Key: "k2", Value: domain.String("v2"), Cond: model.BlockContentDataviewFilter_Equal},
}
t.Run("ok", func(t *testing.T) {
g := &types.Struct{Fields: map[string]*types.Value{"k1": pbtypes.String("v1"), "k2": pbtypes.String("v2")}}
g := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k1": domain.String("v1"), "k2": domain.String("v2")})
assertFilter(t, and, g, true)
})
t.Run("not ok", func(t *testing.T) {
g := &types.Struct{Fields: map[string]*types.Value{"k1": pbtypes.String("v1"), "k2": pbtypes.String("v3")}}
g := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k1": domain.String("v1"), "k2": domain.String("v3")})
assertFilter(t, and, g, false)
})
t.Run("not ok all", func(t *testing.T) {
g := &types.Struct{Fields: map[string]*types.Value{"k2": pbtypes.String("v3")}}
g := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k2": domain.String("v3")})
assertFilter(t, and, g, false)
})
}
func TestOrFilters_FilterObject(t *testing.T) {
or := FiltersOr{
FilterEq{Key: "k1", Value: pbtypes.String("v1"), Cond: model.BlockContentDataviewFilter_Equal},
FilterEq{Key: "k2", Value: pbtypes.String("v2"), Cond: model.BlockContentDataviewFilter_Equal},
FilterEq{Key: "k1", Value: domain.String("v1"), Cond: model.BlockContentDataviewFilter_Equal},
FilterEq{Key: "k2", Value: domain.String("v2"), Cond: model.BlockContentDataviewFilter_Equal},
}
t.Run("ok all", func(t *testing.T) {
g := &types.Struct{Fields: map[string]*types.Value{"k1": pbtypes.String("v1"), "k2": pbtypes.String("v2")}}
g := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k1": domain.String("v1"), "k2": domain.String("v2")})
assertFilter(t, or, g, true)
})
t.Run("ok", func(t *testing.T) {
g := &types.Struct{Fields: map[string]*types.Value{"k1": pbtypes.String("v1"), "k2": pbtypes.String("v3")}}
g := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k1": domain.String("v1"), "k2": domain.String("v3")})
assertFilter(t, or, g, true)
})
t.Run("not ok all", func(t *testing.T) {
g := &types.Struct{Fields: map[string]*types.Value{"k2": pbtypes.String("v3")}}
g := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k2": domain.String("v3")})
assertFilter(t, or, g, false)
})
}
func TestAllIn_FilterObject(t *testing.T) {
allIn := FilterAllIn{Key: "k", Value: pbtypes.StringList([]string{"1", "2", "3"}).GetListValue()}
allIn := FilterAllIn{Key: "k", Strings: []string{"1", "2", "3"}}
t.Run("ok", func(t *testing.T) {
g := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.StringList([]string{"2", "1", "3", "4"})}}
g := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.StringList([]string{"2", "1", "3", "4"})})
assertFilter(t, allIn, g, true)
})
t.Run("not ok", func(t *testing.T) {
g := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.StringList([]string{"2", "3", "4"})}}
g := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.StringList([]string{"2", "3", "4"})})
assertFilter(t, allIn, g, false)
})
t.Run("ok string in Object", func(t *testing.T) {
allIn := FilterAllIn{Key: "k", Value: pbtypes.StringList([]string{"1"}).GetListValue()}
g := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("1")}}
allIn := FilterAllIn{Key: "k", Strings: []string{"1"}}
g := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.String("1")})
assertFilter(t, allIn, g, true)
})
t.Run("ok string in Filter", func(t *testing.T) {
v, err := pbtypes.ValueListWrapper(pbtypes.String("1"))
assert.NoError(t, err)
allIn := FilterAllIn{Key: "k", Value: v}
g := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.StringList([]string{"1", "2", "3"})}}
allIn := FilterAllIn{Key: "k", Strings: []string{"1"}}
g := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.StringList([]string{"1", "2", "3"})})
assertFilter(t, allIn, g, true)
})
t.Run("not all in", func(t *testing.T) {
f := FilterNot{FilterAllIn{Key: "k", Value: pbtypes.StringList([]string{"1", "2"}).GetListValue()}}
f := FilterNot{FilterAllIn{Key: "k", Strings: []string{"1", "2"}}}
obj := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.StringList([]string{"1", "3"})}}
obj := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.StringList([]string{"1", "3"})})
assertFilter(t, f, obj, true)
obj = &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.StringList([]string{"1", "2", "3"})}}
obj = domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.StringList([]string{"1", "2", "3"})})
assertFilter(t, f, obj, false)
})
}
@ -297,56 +293,56 @@ func TestAllIn_FilterObject(t *testing.T) {
func TestMakeAndFilter(t *testing.T) {
store := NewMockObjectStore(t)
t.Run("valid", func(t *testing.T) {
filters := []*model.BlockContentDataviewFilter{
filters := []FilterRequest{
{
RelationKey: "1",
Condition: model.BlockContentDataviewFilter_Equal,
Value: pbtypes.String("1"),
Value: domain.String("1"),
},
{
RelationKey: "2",
Condition: model.BlockContentDataviewFilter_NotEqual,
Value: pbtypes.String("2"),
Value: domain.String("2"),
},
{
RelationKey: "3",
Condition: model.BlockContentDataviewFilter_Greater,
Value: pbtypes.String("3"),
Value: domain.String("3"),
},
{
RelationKey: "4",
Condition: model.BlockContentDataviewFilter_GreaterOrEqual,
Value: pbtypes.String("4"),
Value: domain.String("4"),
},
{
RelationKey: "5",
Condition: model.BlockContentDataviewFilter_Less,
Value: pbtypes.String("5"),
Value: domain.String("5"),
},
{
RelationKey: "6",
Condition: model.BlockContentDataviewFilter_LessOrEqual,
Value: pbtypes.String("6"),
Value: domain.String("6"),
},
{
RelationKey: "7",
Condition: model.BlockContentDataviewFilter_Like,
Value: pbtypes.String("7"),
Value: domain.String("7"),
},
{
RelationKey: "8",
Condition: model.BlockContentDataviewFilter_NotLike,
Value: pbtypes.String("8"),
Value: domain.String("8"),
},
{
RelationKey: "9",
Condition: model.BlockContentDataviewFilter_In,
Value: pbtypes.StringList([]string{"9"}),
Value: domain.StringList([]string{"9"}),
},
{
RelationKey: "10",
Condition: model.BlockContentDataviewFilter_NotIn,
Value: pbtypes.StringList([]string{"10"}),
Value: domain.StringList([]string{"10"}),
},
{
RelationKey: "11",
@ -359,12 +355,12 @@ func TestMakeAndFilter(t *testing.T) {
{
RelationKey: "13",
Condition: model.BlockContentDataviewFilter_AllIn,
Value: pbtypes.StringList([]string{"13"}),
Value: domain.StringList([]string{"13"}),
},
{
RelationKey: "14",
Condition: model.BlockContentDataviewFilter_NotAllIn,
Value: pbtypes.StringList([]string{"14"}),
Value: domain.StringList([]string{"14"}),
},
}
andFilter, err := MakeFilters(filters, store)
@ -378,55 +374,55 @@ func TestMakeAndFilter(t *testing.T) {
model.BlockContentDataviewFilter_AllIn,
model.BlockContentDataviewFilter_NotAllIn,
} {
_, err := MakeFilters([]*model.BlockContentDataviewFilter{
{Condition: cond, Value: pbtypes.Null()},
_, err := MakeFilters([]FilterRequest{
{Condition: cond, Value: domain.Null()},
}, store)
assert.Equal(t, ErrValueMustBeListSupporting, err)
assert.Error(t, err)
}
})
t.Run("unexpected condition", func(t *testing.T) {
_, err := MakeFilters([]*model.BlockContentDataviewFilter{
_, err := MakeFilters([]FilterRequest{
{Condition: 10000},
}, store)
assert.Error(t, err)
})
t.Run("replace 'value == false' to 'value != true'", func(t *testing.T) {
f, err := MakeFilters([]*model.BlockContentDataviewFilter{
f, err := MakeFilters([]FilterRequest{
{
RelationKey: "b",
Condition: model.BlockContentDataviewFilter_Equal,
Value: pbtypes.Bool(false),
Value: domain.Bool(false),
},
}, store)
require.NoError(t, err)
g := &types.Struct{Fields: map[string]*types.Value{"b": pbtypes.Bool(false)}}
g := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"b": domain.Bool(false)})
assertFilter(t, f, g, true)
g = &types.Struct{Fields: map[string]*types.Value{"not_exists": pbtypes.Bool(false)}}
g = domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"not_exists": domain.Bool(false)})
assertFilter(t, f, g, true)
g = &types.Struct{Fields: map[string]*types.Value{"b": pbtypes.Bool(true)}}
g = domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"b": domain.Bool(true)})
assertFilter(t, f, g, false)
})
t.Run("replace 'value != false' to 'value == true'", func(t *testing.T) {
f, err := MakeFilters([]*model.BlockContentDataviewFilter{
f, err := MakeFilters([]FilterRequest{
{
RelationKey: "b",
Condition: model.BlockContentDataviewFilter_NotEqual,
Value: pbtypes.Bool(false),
Value: domain.Bool(false),
},
}, store)
require.NoError(t, err)
g := &types.Struct{Fields: map[string]*types.Value{"b": pbtypes.Bool(false)}}
g := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"b": domain.Bool(false)})
assertFilter(t, f, g, false)
g = &types.Struct{Fields: map[string]*types.Value{"not_exists": pbtypes.Bool(false)}}
g = domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"not_exists": domain.Bool(false)})
assertFilter(t, f, g, false)
g = &types.Struct{Fields: map[string]*types.Value{"b": pbtypes.Bool(true)}}
g = domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"b": domain.Bool(true)})
assertFilter(t, f, g, true)
})
}
@ -437,32 +433,28 @@ func TestNestedFilters(t *testing.T) {
// Query will occur while nested filter resolving
store.EXPECT().QueryRaw(mock.Anything, 0, 0).Return([]Record{
{
Details: &types.Struct{
Fields: map[string]*types.Value{
bundle.RelationKeyId.String(): pbtypes.String("id1"),
"typeKey": pbtypes.String("note"),
},
},
Details: domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{
bundle.RelationKeyId: domain.String("id1"),
"typeKey": domain.String("note"),
}),
},
{
Details: &types.Struct{
Fields: map[string]*types.Value{
bundle.RelationKeyId.String(): pbtypes.String("id2"),
"typeKey": pbtypes.String("note"),
},
},
Details: domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{
bundle.RelationKeyId: domain.String("id2"),
"typeKey": domain.String("note"),
}),
},
}, nil)
f, err := MakeFilter("spaceId", &model.BlockContentDataviewFilter{
f, err := MakeFilter("spaceId", FilterRequest{
RelationKey: "type.typeKey",
Condition: model.BlockContentDataviewFilter_Equal,
Value: pbtypes.String("note"),
Value: domain.String("note"),
}, store)
require.NoError(t, err)
obj1 := &types.Struct{Fields: map[string]*types.Value{"type": pbtypes.String("id1")}}
obj2 := &types.Struct{Fields: map[string]*types.Value{"type": pbtypes.StringList([]string{"id2", "id1"})}}
obj1 := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"type": domain.String("id1")})
obj2 := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"type": domain.StringList([]string{"id2", "id1"})})
assertFilter(t, f, obj1, true)
assertFilter(t, f, obj2, true)
})
@ -472,12 +464,12 @@ func TestNestedFilters(t *testing.T) {
func TestFilterExists(t *testing.T) {
t.Run("ok", func(t *testing.T) {
eq := FilterExists{Key: "k"}
obj := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("equal test")}}
obj := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.String("equal test")})
assertFilter(t, eq, obj, true)
})
t.Run("not ok", func(t *testing.T) {
eq := FilterExists{Key: "foo"}
obj := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("equal test")}}
obj := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.String("equal test")})
assertFilter(t, eq, obj, false)
})
}
@ -492,54 +484,54 @@ func TestFilterOptionsEqual(t *testing.T) {
eq := FilterOptionsEqual{
Key: "k",
Options: optionIdToName,
Value: pbtypes.StringList([]string{"optionId1"}).GetListValue(),
Value: []string{"optionId1"},
}
obj := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.StringList([]string{"optionId1"})}}
obj := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.StringList([]string{"optionId1"})})
assertFilter(t, eq, obj, true)
})
t.Run("two options, ok", func(t *testing.T) {
eq := FilterOptionsEqual{
Key: "k",
Options: optionIdToName,
Value: pbtypes.StringList([]string{"optionId1", "optionId3"}).GetListValue(),
Value: []string{"optionId1", "optionId3"},
}
obj := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.StringList([]string{"optionId1", "optionId3"})}}
obj := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.StringList([]string{"optionId1", "optionId3"})})
assertFilter(t, eq, obj, true)
})
t.Run("two options, ok, not existing options are discarded", func(t *testing.T) {
eq := FilterOptionsEqual{
Key: "k",
Options: optionIdToName,
Value: pbtypes.StringList([]string{"optionId1", "optionId3"}).GetListValue(),
Value: []string{"optionId1", "optionId3"},
}
obj := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.StringList([]string{"optionId1", "optionId3", "optionId7000"})}}
obj := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.StringList([]string{"optionId1", "optionId3", "optionId7000"})})
assertFilter(t, eq, obj, true)
})
t.Run("two options, not ok", func(t *testing.T) {
eq := FilterOptionsEqual{
Key: "k",
Options: optionIdToName,
Value: pbtypes.StringList([]string{"optionId1", "optionId2"}).GetListValue(),
Value: []string{"optionId1", "optionId2"},
}
obj := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.StringList([]string{"optionId1", "optionId3"})}}
obj := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.StringList([]string{"optionId1", "optionId3"})})
assertFilter(t, eq, obj, false)
})
t.Run("two options, not ok, because object has 1 option", func(t *testing.T) {
eq := FilterOptionsEqual{
Key: "k",
Options: optionIdToName,
Value: pbtypes.StringList([]string{"optionId1", "optionId2"}).GetListValue(),
Value: []string{"optionId1", "optionId2"},
}
obj := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.StringList([]string{"optionId1"})}}
obj := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.StringList([]string{"optionId1"})})
assertFilter(t, eq, obj, false)
})
t.Run("two options, not ok, because object has 3 options", func(t *testing.T) {
eq := FilterOptionsEqual{
Key: "k",
Options: optionIdToName,
Value: pbtypes.StringList([]string{"optionId1", "optionId2"}).GetListValue(),
Value: []string{"optionId1", "optionId2"},
}
obj := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.StringList([]string{"optionId1", "optionId2", "optionId3"})}}
obj := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.StringList([]string{"optionId1", "optionId2", "optionId3"})})
assertFilter(t, eq, obj, false)
})
}
@ -559,22 +551,22 @@ func TestMakeFilters(t *testing.T) {
t.Run("or filter", func(t *testing.T) {
// given
mockStore := NewMockObjectStore(t)
filter := []*model.BlockContentDataviewFilter{
filter := []FilterRequest{
{
Operator: model.BlockContentDataviewFilter_Or,
NestedFilters: []*model.BlockContentDataviewFilter{
NestedFilters: []FilterRequest{
{
Operator: model.BlockContentDataviewFilter_No,
RelationKey: "relationKey",
Condition: model.BlockContentDataviewFilter_Equal,
Value: pbtypes.String("option2"),
Value: domain.String("option2"),
Format: model.RelationFormat_status,
},
{
Operator: model.BlockContentDataviewFilter_No,
RelationKey: bundle.RelationKeyName.String(),
RelationKey: bundle.RelationKeyName,
Condition: model.BlockContentDataviewFilter_Equal,
Value: pbtypes.String("Object 1"),
Value: domain.String("Object 1"),
Format: model.RelationFormat_shorttext,
},
},
@ -590,30 +582,30 @@ func TestMakeFilters(t *testing.T) {
assert.NotNil(t, filters.(FiltersOr))
assert.NotNil(t, filters.(FiltersOr)[0].(FilterEq))
assert.NotNil(t, filters.(FiltersOr)[1].(FilterEq))
assert.Equal(t, "relationKey", filters.(FiltersOr)[0].(FilterEq).Key)
assert.Equal(t, pbtypes.String("option2"), filters.(FiltersOr)[0].(FilterEq).Value)
assert.Equal(t, "name", filters.(FiltersOr)[1].(FilterEq).Key)
assert.Equal(t, pbtypes.String("Object 1"), filters.(FiltersOr)[1].(FilterEq).Value)
assert.Equal(t, domain.RelationKey("relationKey"), filters.(FiltersOr)[0].(FilterEq).Key)
assert.Equal(t, domain.String("option2"), filters.(FiltersOr)[0].(FilterEq).Value)
assert.Equal(t, domain.RelationKey("name"), filters.(FiltersOr)[1].(FilterEq).Key)
assert.Equal(t, domain.String("Object 1"), filters.(FiltersOr)[1].(FilterEq).Value)
})
t.Run("and filter", func(t *testing.T) {
// given
mockStore := NewMockObjectStore(t)
filter := []*model.BlockContentDataviewFilter{
filter := []FilterRequest{
{
Operator: model.BlockContentDataviewFilter_And,
NestedFilters: []*model.BlockContentDataviewFilter{
NestedFilters: []FilterRequest{
{
Operator: model.BlockContentDataviewFilter_No,
RelationKey: "relationKey",
Condition: model.BlockContentDataviewFilter_Equal,
Value: pbtypes.String("option2"),
Value: domain.String("option2"),
Format: model.RelationFormat_status,
},
{
Operator: model.BlockContentDataviewFilter_No,
RelationKey: bundle.RelationKeyName.String(),
RelationKey: bundle.RelationKeyName,
Condition: model.BlockContentDataviewFilter_Equal,
Value: pbtypes.String("Object 1"),
Value: domain.String("Object 1"),
Format: model.RelationFormat_shorttext,
},
},
@ -629,20 +621,20 @@ func TestMakeFilters(t *testing.T) {
assert.NotNil(t, filters.(FiltersAnd))
assert.NotNil(t, filters.(FiltersAnd)[0].(FilterEq))
assert.NotNil(t, filters.(FiltersAnd)[1].(FilterEq))
assert.Equal(t, "relationKey", filters.(FiltersAnd)[0].(FilterEq).Key)
assert.Equal(t, pbtypes.String("option2"), filters.(FiltersAnd)[0].(FilterEq).Value)
assert.Equal(t, "name", filters.(FiltersAnd)[1].(FilterEq).Key)
assert.Equal(t, pbtypes.String("Object 1"), filters.(FiltersAnd)[1].(FilterEq).Value)
assert.Equal(t, domain.RelationKey("relationKey"), filters.(FiltersAnd)[0].(FilterEq).Key)
assert.Equal(t, domain.String("option2"), filters.(FiltersAnd)[0].(FilterEq).Value)
assert.Equal(t, domain.RelationKey("name"), filters.(FiltersAnd)[1].(FilterEq).Key)
assert.Equal(t, domain.String("Object 1"), filters.(FiltersAnd)[1].(FilterEq).Value)
})
t.Run("none filter", func(t *testing.T) {
// given
mockStore := NewMockObjectStore(t)
filter := []*model.BlockContentDataviewFilter{
filter := []FilterRequest{
{
Operator: model.BlockContentDataviewFilter_No,
RelationKey: "relationKey",
Condition: model.BlockContentDataviewFilter_Equal,
Value: pbtypes.String("option1"),
Value: domain.String("option1"),
Format: model.RelationFormat_status,
},
}
@ -655,31 +647,31 @@ func TestMakeFilters(t *testing.T) {
assert.Len(t, filters, 1)
assert.NotNil(t, filters.(FiltersAnd))
assert.NotNil(t, filters.(FiltersAnd)[0].(FilterEq))
assert.Equal(t, "relationKey", filters.(FiltersAnd)[0].(FilterEq).Key)
assert.Equal(t, pbtypes.String("option1"), filters.(FiltersAnd)[0].(FilterEq).Value)
assert.Equal(t, domain.RelationKey("relationKey"), filters.(FiltersAnd)[0].(FilterEq).Key)
assert.Equal(t, domain.String("option1"), filters.(FiltersAnd)[0].(FilterEq).Value)
})
t.Run("combined filter", func(t *testing.T) {
// given
mockStore := NewMockObjectStore(t)
filter := []*model.BlockContentDataviewFilter{
filter := []FilterRequest{
{
Operator: model.BlockContentDataviewFilter_And,
NestedFilters: []*model.BlockContentDataviewFilter{
NestedFilters: []FilterRequest{
{
Operator: model.BlockContentDataviewFilter_Or,
NestedFilters: []*model.BlockContentDataviewFilter{
NestedFilters: []FilterRequest{
{
Operator: model.BlockContentDataviewFilter_No,
RelationKey: "relationKey",
Condition: model.BlockContentDataviewFilter_Equal,
Value: pbtypes.String("option1"),
Value: domain.String("option1"),
Format: model.RelationFormat_status,
},
{
Operator: model.BlockContentDataviewFilter_No,
RelationKey: "relationKey1",
Condition: model.BlockContentDataviewFilter_Equal,
Value: pbtypes.String("option2"),
Value: domain.String("option2"),
Format: model.RelationFormat_status,
},
},
@ -688,7 +680,7 @@ func TestMakeFilters(t *testing.T) {
Operator: model.BlockContentDataviewFilter_No,
RelationKey: "relationKey3",
Condition: model.BlockContentDataviewFilter_Equal,
Value: pbtypes.String("option3"),
Value: domain.String("option3"),
Format: model.RelationFormat_status,
},
},
@ -708,19 +700,19 @@ func TestMakeFilters(t *testing.T) {
t.Run("linear and nested filters", func(t *testing.T) {
// given
mockStore := NewMockObjectStore(t)
filter := []*model.BlockContentDataviewFilter{
filter := []FilterRequest{
{
RelationKey: "key1",
Condition: model.BlockContentDataviewFilter_Equal,
Value: pbtypes.Bool(true),
Value: domain.Bool(true),
},
{
Operator: model.BlockContentDataviewFilter_Or,
NestedFilters: []*model.BlockContentDataviewFilter{
NestedFilters: []FilterRequest{
{
RelationKey: "key2",
Condition: model.BlockContentDataviewFilter_Equal,
Value: pbtypes.Bool(true),
Value: domain.Bool(true),
},
},
},
@ -739,48 +731,48 @@ func TestMakeFilters(t *testing.T) {
t.Run("linear and nested filters", func(t *testing.T) {
// given
mockStore := NewMockObjectStore(t)
filter := []*model.BlockContentDataviewFilter{
filter := []FilterRequest{
{
Operator: model.BlockContentDataviewFilter_And,
RelationKey: "key1",
Condition: model.BlockContentDataviewFilter_Equal,
Value: pbtypes.Bool(true),
Value: domain.Bool(true),
},
{
Operator: model.BlockContentDataviewFilter_And,
RelationKey: "key1",
Condition: model.BlockContentDataviewFilter_Equal,
Value: pbtypes.Bool(true),
Value: domain.Bool(true),
},
{
Operator: model.BlockContentDataviewFilter_And,
RelationKey: "key1",
Condition: model.BlockContentDataviewFilter_Equal,
Value: pbtypes.Bool(true),
Value: domain.Bool(true),
},
{
Operator: model.BlockContentDataviewFilter_And,
RelationKey: "key1",
Condition: model.BlockContentDataviewFilter_Equal,
Value: pbtypes.Bool(true),
Value: domain.Bool(true),
},
{
Operator: model.BlockContentDataviewFilter_And,
RelationKey: "key1",
Condition: model.BlockContentDataviewFilter_Equal,
Value: pbtypes.Bool(true),
Value: domain.Bool(true),
},
{
Operator: model.BlockContentDataviewFilter_And,
RelationKey: "key1",
Condition: model.BlockContentDataviewFilter_Equal,
Value: pbtypes.Bool(true),
Value: domain.Bool(true),
},
{
Operator: model.BlockContentDataviewFilter_And,
RelationKey: "key1",
Condition: model.BlockContentDataviewFilter_Equal,
Value: pbtypes.Bool(true),
Value: domain.Bool(true),
},
}
@ -793,20 +785,20 @@ func TestMakeFilters(t *testing.T) {
t.Run("transform quick options", func(t *testing.T) {
// given
mockStore := NewMockObjectStore(t)
filter := []*model.BlockContentDataviewFilter{
filter := []FilterRequest{
{
Operator: model.BlockContentDataviewFilter_Or,
NestedFilters: []*model.BlockContentDataviewFilter{
NestedFilters: []FilterRequest{
{
RelationKey: "key2",
Condition: model.BlockContentDataviewFilter_Equal,
Value: pbtypes.Int64(time.Now().Unix()),
Value: domain.Int64(time.Now().Unix()),
QuickOption: model.BlockContentDataviewFilter_CurrentMonth,
},
{
RelationKey: "key3",
Condition: model.BlockContentDataviewFilter_Equal,
Value: pbtypes.Bool(true),
Value: domain.Bool(true),
},
},
},
@ -825,20 +817,20 @@ func TestMakeFilters(t *testing.T) {
t.Run("transform quick options", func(t *testing.T) {
// given
mockStore := NewMockObjectStore(t)
filter := []*model.BlockContentDataviewFilter{
filter := []FilterRequest{
{
Operator: model.BlockContentDataviewFilter_Or,
NestedFilters: []*model.BlockContentDataviewFilter{
NestedFilters: []FilterRequest{
{
RelationKey: "key2",
Condition: model.BlockContentDataviewFilter_Less,
Value: pbtypes.Int64(time.Now().Unix()),
Value: domain.Int64(time.Now().Unix()),
QuickOption: model.BlockContentDataviewFilter_CurrentMonth,
},
{
RelationKey: "key3",
Condition: model.BlockContentDataviewFilter_Equal,
Value: pbtypes.Bool(true),
Value: domain.Bool(true),
},
},
},

View file

@ -5,20 +5,19 @@ import (
"testing"
"time"
"github.com/gogo/protobuf/types"
"github.com/stretchr/testify/assert"
"github.com/valyala/fastjson"
"github.com/anyproto/anytype-heart/core/domain"
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
"github.com/anyproto/anytype-heart/util/pbtypes"
)
func assertCompare(t *testing.T, order Order, a *types.Struct, b *types.Struct, expected int) {
func assertCompare(t *testing.T, order Order, a *domain.Details, b *domain.Details, expected int) {
assert.Equal(t, expected, order.Compare(a, b))
arena := &fastjson.Arena{}
aJson := pbtypes.ProtoToJson(arena, a)
bJson := pbtypes.ProtoToJson(arena, b)
aJson := a.ToJson(arena)
bJson := b.ToJson(arena)
s := order.AnystoreSort()
aBytes := s.AppendKey(nil, aJson)
bBytes := s.AppendKey(nil, bJson)
@ -29,56 +28,44 @@ func assertCompare(t *testing.T, order Order, a *types.Struct, b *types.Struct,
func TestTextSort(t *testing.T) {
arena := &fastjson.Arena{}
t.Run("note layout, not empty name", func(t *testing.T) {
a := &types.Struct{
Fields: map[string]*types.Value{
bundle.RelationKeyName.String(): pbtypes.String("b"),
},
}
b := &types.Struct{
Fields: map[string]*types.Value{
bundle.RelationKeyName.String(): pbtypes.String("a"),
bundle.RelationKeySnippet.String(): pbtypes.String("b"),
bundle.RelationKeyLayout.String(): pbtypes.Int64(int64(model.ObjectType_note)),
},
}
asc := &KeyOrder{arena: arena, Key: bundle.RelationKeyName.String(), Type: model.BlockContentDataviewSort_Asc, relationFormat: model.RelationFormat_shorttext}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{
bundle.RelationKeyName: domain.String("b"),
})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{
bundle.RelationKeyName: domain.String("a"),
bundle.RelationKeySnippet: domain.String("b"),
bundle.RelationKeyLayout: domain.Int64(int64(model.ObjectType_note)),
})
asc := &KeyOrder{arena: arena, Key: bundle.RelationKeyName, Type: model.BlockContentDataviewSort_Asc, relationFormat: model.RelationFormat_shorttext}
assertCompare(t, asc, a, b, 1)
desc := &KeyOrder{arena: arena, Key: bundle.RelationKeyName.String(), Type: model.BlockContentDataviewSort_Desc, relationFormat: model.RelationFormat_shorttext}
desc := &KeyOrder{arena: arena, Key: bundle.RelationKeyName, Type: model.BlockContentDataviewSort_Desc, relationFormat: model.RelationFormat_shorttext}
assertCompare(t, desc, a, b, -1)
})
t.Run("note layout, empty name", func(t *testing.T) {
t.Run("one with name, one with snippet, not equal", func(t *testing.T) {
a := &types.Struct{
Fields: map[string]*types.Value{
bundle.RelationKeyName.String(): pbtypes.String("a"),
},
}
b := &types.Struct{
Fields: map[string]*types.Value{
bundle.RelationKeySnippet.String(): pbtypes.String("b"),
bundle.RelationKeyLayout.String(): pbtypes.Int64(int64(model.ObjectType_note)),
},
}
asc := &KeyOrder{arena: arena, Key: bundle.RelationKeyName.String(), Type: model.BlockContentDataviewSort_Asc, relationFormat: model.RelationFormat_shorttext}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{
bundle.RelationKeyName: domain.String("a"),
})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{
bundle.RelationKeySnippet: domain.String("b"),
bundle.RelationKeyLayout: domain.Int64(int64(model.ObjectType_note)),
})
asc := &KeyOrder{arena: arena, Key: bundle.RelationKeyName, Type: model.BlockContentDataviewSort_Asc, relationFormat: model.RelationFormat_shorttext}
assertCompare(t, asc, a, b, -1)
desc := &KeyOrder{arena: arena, Key: bundle.RelationKeyName.String(), Type: model.BlockContentDataviewSort_Desc, relationFormat: model.RelationFormat_shorttext}
desc := &KeyOrder{arena: arena, Key: bundle.RelationKeyName, Type: model.BlockContentDataviewSort_Desc, relationFormat: model.RelationFormat_shorttext}
assertCompare(t, desc, a, b, 1)
})
t.Run("one with name, one with snippet, equal", func(t *testing.T) {
a := &types.Struct{
Fields: map[string]*types.Value{
bundle.RelationKeyName.String(): pbtypes.String("a"),
},
}
b := &types.Struct{
Fields: map[string]*types.Value{
bundle.RelationKeySnippet.String(): pbtypes.String("a"),
bundle.RelationKeyLayout.String(): pbtypes.Int64(int64(model.ObjectType_note)),
},
}
asc := &KeyOrder{arena: arena, Key: bundle.RelationKeyName.String(), Type: model.BlockContentDataviewSort_Asc, relationFormat: model.RelationFormat_shorttext}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{
bundle.RelationKeyName: domain.String("a"),
})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{
bundle.RelationKeySnippet: domain.String("a"),
bundle.RelationKeyLayout: domain.Int64(int64(model.ObjectType_note)),
})
asc := &KeyOrder{arena: arena, Key: bundle.RelationKeyName, Type: model.BlockContentDataviewSort_Asc, relationFormat: model.RelationFormat_shorttext}
assertCompare(t, asc, a, b, 0)
desc := &KeyOrder{arena: arena, Key: bundle.RelationKeyName.String(), Type: model.BlockContentDataviewSort_Desc, relationFormat: model.RelationFormat_shorttext}
desc := &KeyOrder{arena: arena, Key: bundle.RelationKeyName, Type: model.BlockContentDataviewSort_Desc, relationFormat: model.RelationFormat_shorttext}
assertCompare(t, desc, a, b, 0)
})
})
@ -87,98 +74,98 @@ func TestTextSort(t *testing.T) {
func TestKeyOrder_Compare(t *testing.T) {
arena := &fastjson.Arena{}
t.Run("eq", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("a")}}
b := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("a")}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.String("a")})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.String("a")})
asc := &KeyOrder{arena: arena, Key: "k", Type: model.BlockContentDataviewSort_Asc, relationFormat: model.RelationFormat_shorttext}
assertCompare(t, asc, a, b, 0)
})
t.Run("asc", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("a")}}
b := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("b")}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.String("a")})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.String("b")})
asc := &KeyOrder{arena: arena, Key: "k", Type: model.BlockContentDataviewSort_Asc, relationFormat: model.RelationFormat_shorttext}
assertCompare(t, asc, a, b, -1)
})
t.Run("desc_float", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Float64(1)}}
b := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Float64(2)}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Float64(1)})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Float64(2)})
asc := &KeyOrder{arena: arena, Key: "k", Type: model.BlockContentDataviewSort_Desc, EmptyPlacement: model.BlockContentDataviewSort_End, relationFormat: model.RelationFormat_number}
assertCompare(t, asc, a, b, 1)
})
t.Run("asc_float", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Float64(1)}}
b := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Float64(2)}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Float64(1)})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Float64(2)})
asc := &KeyOrder{arena: arena, Key: "k", Type: model.BlockContentDataviewSort_Asc, EmptyPlacement: model.BlockContentDataviewSort_Start, relationFormat: model.RelationFormat_number}
assertCompare(t, asc, a, b, -1)
})
t.Run("asc_emptylast", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("a")}}
b := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("")}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.String("a")})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.String("")})
asc := &KeyOrder{arena: arena, Key: "k", Type: model.BlockContentDataviewSort_Asc, EmptyPlacement: model.BlockContentDataviewSort_End, relationFormat: model.RelationFormat_shorttext}
assertCompare(t, asc, a, b, -1)
})
t.Run("asc_emptylast_float", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Float64(1)}}
b := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Null()}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Float64(1)})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{})
asc := &KeyOrder{arena: arena, Key: "k", Type: model.BlockContentDataviewSort_Asc, EmptyPlacement: model.BlockContentDataviewSort_End, relationFormat: model.RelationFormat_number}
assertCompare(t, asc, a, b, -1)
})
t.Run("asc_emptylast_str", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("a")}}
b := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("")}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.String("a")})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.String("")})
asc := &KeyOrder{arena: arena, Key: "k", Type: model.BlockContentDataviewSort_Asc, EmptyPlacement: model.BlockContentDataviewSort_End, relationFormat: model.RelationFormat_shorttext}
assertCompare(t, asc, a, b, -1)
})
t.Run("desc_emptylast_str", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("a")}}
b := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("")}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.String("a")})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.String("")})
asc := &KeyOrder{arena: arena, Key: "k", Type: model.BlockContentDataviewSort_Desc, EmptyPlacement: model.BlockContentDataviewSort_End, relationFormat: model.RelationFormat_shorttext}
assertCompare(t, asc, a, b, -1)
})
t.Run("asc_emptyfirst_str", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("a")}}
b := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("")}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.String("a")})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.String("")})
asc := &KeyOrder{arena: arena, Key: "k", Type: model.BlockContentDataviewSort_Asc, EmptyPlacement: model.BlockContentDataviewSort_Start, relationFormat: model.RelationFormat_shorttext}
assertCompare(t, asc, a, b, 1)
})
t.Run("desc_emptyfirst_str", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("a")}}
b := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("")}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.String("a")})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.String("")})
asc := &KeyOrder{arena: arena, Key: "k", Type: model.BlockContentDataviewSort_Desc, EmptyPlacement: model.BlockContentDataviewSort_Start, relationFormat: model.RelationFormat_shorttext}
assertCompare(t, asc, a, b, 1)
})
t.Run("asc_str_end", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("a")}}
b := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("b")}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.String("a")})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.String("b")})
asc := &KeyOrder{arena: arena, Key: "k", Type: model.BlockContentDataviewSort_Asc, EmptyPlacement: model.BlockContentDataviewSort_End, relationFormat: model.RelationFormat_shorttext}
assertCompare(t, asc, a, b, -1)
})
t.Run("desc_str_end", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("a")}}
b := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("b")}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.String("a")})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.String("b")})
asc := &KeyOrder{arena: arena, Key: "k", Type: model.BlockContentDataviewSort_Desc, EmptyPlacement: model.BlockContentDataviewSort_End, relationFormat: model.RelationFormat_shorttext}
assertCompare(t, asc, a, b, 1)
})
t.Run("asc_str_start", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("a")}}
b := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("b")}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.String("a")})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.String("b")})
asc := &KeyOrder{arena: arena, Key: "k", Type: model.BlockContentDataviewSort_Asc, EmptyPlacement: model.BlockContentDataviewSort_Start, relationFormat: model.RelationFormat_shorttext}
assertCompare(t, asc, a, b, -1)
})
t.Run("desc_str_start", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("a")}}
b := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("b")}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.String("a")})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.String("b")})
asc := &KeyOrder{arena: arena, Key: "k", Type: model.BlockContentDataviewSort_Desc, EmptyPlacement: model.BlockContentDataviewSort_Start, relationFormat: model.RelationFormat_shorttext}
assertCompare(t, asc, a, b, 1)
})
@ -189,8 +176,8 @@ func TestKeyOrder_Compare(t *testing.T) {
date1 := time.Date(2020, 2, 4, 15, 22, 0, 0, time.UTC)
date2 := time.Date(2020, 2, 4, 16, 26, 0, 0, time.UTC)
a := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Int64(date1.Unix())}}
b := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Int64(date2.Unix())}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Int64(date1.Unix())})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Int64(date2.Unix())})
asc := &KeyOrder{arena: arena,
Key: "k",
Type: model.BlockContentDataviewSort_Asc,
@ -202,8 +189,8 @@ func TestKeyOrder_Compare(t *testing.T) {
})
t.Run("asc_date_end_empty", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Int64(date.Unix())}}
b := &types.Struct{Fields: map[string]*types.Value{"k": nil}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Int64(date.Unix())})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{})
asc := &KeyOrder{arena: arena,
Key: "k",
Type: model.BlockContentDataviewSort_Asc,
@ -215,8 +202,8 @@ func TestKeyOrder_Compare(t *testing.T) {
})
t.Run("desc_date_end_empty", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Int64(date.Unix())}}
b := &types.Struct{Fields: map[string]*types.Value{"k": nil}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Int64(date.Unix())})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{})
asc := &KeyOrder{arena: arena,
Key: "k",
Type: model.BlockContentDataviewSort_Desc,
@ -228,8 +215,8 @@ func TestKeyOrder_Compare(t *testing.T) {
})
t.Run("asc_date_start_empty", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Int64(date.Unix())}}
b := &types.Struct{Fields: map[string]*types.Value{"k": nil}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Int64(date.Unix())})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Null()})
asc := &KeyOrder{arena: arena,
Key: "k",
Type: model.BlockContentDataviewSort_Asc,
@ -241,8 +228,8 @@ func TestKeyOrder_Compare(t *testing.T) {
})
t.Run("desc_date_start", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Int64(date.Unix())}}
b := &types.Struct{Fields: map[string]*types.Value{"k": nil}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Int64(date.Unix())})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{})
asc := &KeyOrder{arena: arena,
Key: "k",
Type: model.BlockContentDataviewSort_Desc,
@ -254,8 +241,8 @@ func TestKeyOrder_Compare(t *testing.T) {
})
t.Run("desc_date_start key not exists", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Int64(date.Unix())}}
b := &types.Struct{Fields: map[string]*types.Value{}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Int64(date.Unix())})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{})
asc := &KeyOrder{arena: arena,
Key: "k",
Type: model.BlockContentDataviewSort_Desc,
@ -267,106 +254,106 @@ func TestKeyOrder_Compare(t *testing.T) {
})
t.Run("asc_nil_emptylast", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("a")}}
b := &types.Struct{Fields: map[string]*types.Value{"k": nil}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.String("a")})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{})
asc := &KeyOrder{arena: arena, Key: "k", Type: model.BlockContentDataviewSort_Asc, EmptyPlacement: model.BlockContentDataviewSort_End, relationFormat: model.RelationFormat_shorttext}
assertCompare(t, asc, a, b, -1)
})
t.Run("asc_nil_emptylast_float", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Float64(1)}}
b := &types.Struct{Fields: map[string]*types.Value{"k": nil}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Float64(1)})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{})
asc := &KeyOrder{arena: arena, Key: "k", Type: model.BlockContentDataviewSort_Asc, EmptyPlacement: model.BlockContentDataviewSort_End, relationFormat: model.RelationFormat_number}
assertCompare(t, asc, a, b, -1)
})
t.Run("desc_nil_emptylast", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("a")}}
b := &types.Struct{Fields: map[string]*types.Value{"k": nil}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.String("a")})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Null()})
asc := &KeyOrder{arena: arena, Key: "k", Type: model.BlockContentDataviewSort_Desc, EmptyPlacement: model.BlockContentDataviewSort_End, relationFormat: model.RelationFormat_shorttext}
assertCompare(t, asc, a, b, -1)
})
t.Run("desc_nil_emptylast_float", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Float64(1)}}
b := &types.Struct{Fields: map[string]*types.Value{"k": nil}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Float64(1)})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Null()})
asc := &KeyOrder{arena: arena, Key: "k", Type: model.BlockContentDataviewSort_Desc, EmptyPlacement: model.BlockContentDataviewSort_End, relationFormat: model.RelationFormat_number}
assertCompare(t, asc, a, b, -1)
})
t.Run("desc_nil_emptylast_float", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Float64(1)}}
b := &types.Struct{Fields: map[string]*types.Value{"k": nil}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Float64(1)})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Null()})
asc := &KeyOrder{arena: arena, Key: "k", Type: model.BlockContentDataviewSort_Desc, EmptyPlacement: model.BlockContentDataviewSort_End, relationFormat: model.RelationFormat_number}
assertCompare(t, asc, a, b, -1)
})
t.Run("asc_nil_emptyfirst", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("a")}}
b := &types.Struct{Fields: map[string]*types.Value{"k": nil}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.String("a")})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Null()})
asc := &KeyOrder{arena: arena, Key: "k", Type: model.BlockContentDataviewSort_Asc, EmptyPlacement: model.BlockContentDataviewSort_Start, relationFormat: model.RelationFormat_shorttext}
assertCompare(t, asc, a, b, 1)
})
t.Run("asc_nil_emptyfirst_float", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Float64(1)}}
b := &types.Struct{Fields: map[string]*types.Value{"k": nil}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Float64(1)})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Null()})
asc := &KeyOrder{arena: arena, Key: "k", Type: model.BlockContentDataviewSort_Asc, EmptyPlacement: model.BlockContentDataviewSort_Start, relationFormat: model.RelationFormat_number}
assertCompare(t, asc, a, b, 1)
})
t.Run("desc_nil_emptyfirst", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("a")}}
b := &types.Struct{Fields: map[string]*types.Value{"k": nil}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.String("a")})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{})
asc := &KeyOrder{arena: arena, Key: "k", Type: model.BlockContentDataviewSort_Desc, EmptyPlacement: model.BlockContentDataviewSort_Start, relationFormat: model.RelationFormat_shorttext}
assertCompare(t, asc, a, b, 1)
})
t.Run("desc_nil_emptyfirst_float", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Float64(1)}}
b := &types.Struct{Fields: map[string]*types.Value{"k": nil}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Float64(1)})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{})
asc := &KeyOrder{arena: arena, Key: "k", Type: model.BlockContentDataviewSort_Desc, EmptyPlacement: model.BlockContentDataviewSort_Start, relationFormat: model.RelationFormat_number}
assertCompare(t, asc, a, b, 1)
})
t.Run("desc emptyfirst key not exist", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Float64(1)}}
b := &types.Struct{Fields: map[string]*types.Value{}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Float64(1)})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{})
asc := &KeyOrder{arena: arena, Key: "k", Type: model.BlockContentDataviewSort_Desc, EmptyPlacement: model.BlockContentDataviewSort_Start, relationFormat: model.RelationFormat_number}
assertCompare(t, asc, a, b, 1)
})
t.Run("asc_nil", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"k": nil}}
b := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Float64(0)}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Null()})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Float64(0)})
asc := &KeyOrder{arena: arena, Key: "k", Type: model.BlockContentDataviewSort_Asc, relationFormat: model.RelationFormat_number}
assertCompare(t, asc, a, b, -1)
})
t.Run("asc_notspecified", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("a")}}
b := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("")}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.String("a")})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.String("")})
asc := &KeyOrder{arena: arena, Key: "k", Type: model.BlockContentDataviewSort_Asc, relationFormat: model.RelationFormat_shorttext}
assertCompare(t, asc, a, b, 1)
})
t.Run("asc_notspecified", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Float64(1)}}
b := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Float64(0)}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Float64(1)})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Float64(0)})
asc := &KeyOrder{arena: arena, Key: "k", Type: model.BlockContentDataviewSort_Asc, relationFormat: model.RelationFormat_number}
assertCompare(t, asc, a, b, 1)
})
t.Run("desc_notspecified", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("a")}}
b := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("b")}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.String("a")})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.String("b")})
asc := &KeyOrder{arena: arena, Key: "k", Type: model.BlockContentDataviewSort_Desc, relationFormat: model.RelationFormat_shorttext}
assertCompare(t, asc, a, b, 1)
})
t.Run("desc_notspecified_float", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Float64(0)}}
b := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Float64(1)}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Float64(0)})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Float64(1)})
asc := &KeyOrder{arena: arena, Key: "k", Type: model.BlockContentDataviewSort_Desc, relationFormat: model.RelationFormat_number}
assertCompare(t, asc, a, b, 1)
})
@ -375,15 +362,15 @@ func TestKeyOrder_Compare(t *testing.T) {
func TestKeyUnicodeOrder_Compare(t *testing.T) {
arena := &fastjson.Arena{}
t.Run("asc", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("Єгипет")}}
b := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("Японія")}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.String("Єгипет")})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.String("Японія")})
asc := &KeyOrder{arena: arena, Key: "k", Type: model.BlockContentDataviewSort_Asc, relationFormat: model.RelationFormat_shorttext}
assertCompare(t, asc, a, b, -1)
})
t.Run("dsc", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("Ürkmez")}}
b := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("Zurich")}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.String("Ürkmez")})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.String("Zurich")})
asc := &KeyOrder{arena: arena, Key: "k", Type: model.BlockContentDataviewSort_Desc, relationFormat: model.RelationFormat_shorttext}
assertCompare(t, asc, a, b, 1)
})
@ -396,19 +383,19 @@ func TestSetOrder_Compare(t *testing.T) {
&KeyOrder{arena: arena, Key: "b", Type: model.BlockContentDataviewSort_Desc, relationFormat: model.RelationFormat_shorttext},
}
t.Run("eq", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"a": pbtypes.String("a"), "b": pbtypes.String("b")}}
b := &types.Struct{Fields: map[string]*types.Value{"a": pbtypes.String("a"), "b": pbtypes.String("b")}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"a": domain.String("a"), "b": domain.String("b")})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"a": domain.String("a"), "b": domain.String("b")})
assertCompare(t, so, a, b, 0)
})
t.Run("first order", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"a": pbtypes.String("b"), "b": pbtypes.String("a")}}
b := &types.Struct{Fields: map[string]*types.Value{"a": pbtypes.String("a"), "b": pbtypes.String("b")}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"a": domain.String("b"), "b": domain.String("a")})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"a": domain.String("a"), "b": domain.String("b")})
assertCompare(t, so, a, b, 1)
})
t.Run("second order", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"a": pbtypes.String("b"), "b": pbtypes.String("b")}}
b := &types.Struct{Fields: map[string]*types.Value{"a": pbtypes.String("b"), "b": pbtypes.String("a")}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"a": domain.String("b"), "b": domain.String("b")})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"a": domain.String("b"), "b": domain.String("a")})
assertCompare(t, so, a, b, -1)
})
}
@ -425,50 +412,50 @@ func TestCustomOrder_Compare(t *testing.T) {
co := newCustomOrder(arena, "ID", idxIndices, &KeyOrder{arena: arena, Key: "ID", Type: model.BlockContentDataviewSort_Asc, relationFormat: model.RelationFormat_shorttext})
t.Run("gt", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"ID": pbtypes.String("c")}}
b := &types.Struct{Fields: map[string]*types.Value{"ID": pbtypes.String("a")}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"ID": domain.String("c")})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"ID": domain.String("a")})
assertCompare(t, co, a, b, -1)
})
t.Run("eq", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"ID": pbtypes.String("a")}}
b := &types.Struct{Fields: map[string]*types.Value{"ID": pbtypes.String("a")}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"ID": domain.String("a")})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"ID": domain.String("a")})
assertCompare(t, co, a, b, 0)
})
t.Run("lt", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"ID": pbtypes.String("a")}}
b := &types.Struct{Fields: map[string]*types.Value{"ID": pbtypes.String("b")}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"ID": domain.String("a")})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"ID": domain.String("b")})
assertCompare(t, co, a, b, 1)
})
t.Run("first found second not", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"ID": pbtypes.String("a")}}
b := &types.Struct{Fields: map[string]*types.Value{"ID": pbtypes.String("x")}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"ID": domain.String("a")})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"ID": domain.String("x")})
assertCompare(t, co, a, b, -1)
})
t.Run("first not found second yes", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"ID": pbtypes.String("x")}}
b := &types.Struct{Fields: map[string]*types.Value{"ID": pbtypes.String("a")}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"ID": domain.String("x")})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"ID": domain.String("a")})
assertCompare(t, co, a, b, 1)
})
t.Run("both not found gt", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"ID": pbtypes.String("y")}}
b := &types.Struct{Fields: map[string]*types.Value{"ID": pbtypes.String("z")}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"ID": domain.String("y")})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"ID": domain.String("z")})
assertCompare(t, co, a, b, -1)
})
t.Run("both not found eq", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"ID": pbtypes.String("z")}}
b := &types.Struct{Fields: map[string]*types.Value{"ID": pbtypes.String("z")}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"ID": domain.String("z")})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"ID": domain.String("z")})
assertCompare(t, co, a, b, 0)
})
t.Run("both not found lt", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"ID": pbtypes.String("z")}}
b := &types.Struct{Fields: map[string]*types.Value{"ID": pbtypes.String("y")}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"ID": domain.String("z")})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"ID": domain.String("y")})
assertCompare(t, co, a, b, 1)
})
}
@ -477,8 +464,8 @@ func TestTagStatusOrder_Compare(t *testing.T) {
arena := &fastjson.Arena{}
for _, relation := range []model.RelationFormat{model.RelationFormat_tag, model.RelationFormat_status} {
t.Run("eq", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("a")}}
b := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("a")}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.StringList([]string{"a"})})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.StringList([]string{"a"})})
asc := &KeyOrder{arena: arena,
Key: "k",
Type: model.BlockContentDataviewSort_Asc,
@ -489,8 +476,8 @@ func TestTagStatusOrder_Compare(t *testing.T) {
})
t.Run("asc", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("b")}}
b := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("a")}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.StringList([]string{"b"})})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.StringList([]string{"a"})})
asc := &KeyOrder{arena: arena,
Key: "k",
Type: model.BlockContentDataviewSort_Asc,
@ -509,32 +496,32 @@ func TestIncludeTime_Compare(t *testing.T) {
date := time.Unix(1672012800, 0)
arena := &fastjson.Arena{}
t.Run("date only eq", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Int64(date.Add(time.Second * 5).Unix())}}
b := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Int64(date.Add(time.Second * 10).Unix())}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Int64(date.Add(time.Second * 5).Unix())})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Int64(date.Add(time.Second * 10).Unix())})
asc := &KeyOrder{arena: arena, Key: "k", Type: model.BlockContentDataviewSort_Asc,
IncludeTime: false, relationFormat: model.RelationFormat_date}
assertCompare(t, asc, a, b, 0)
})
t.Run("only date lt", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Int64(date.Unix())}}
b := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Int64(date.Add(time.Hour * 24).Unix())}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Int64(date.Unix())})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Int64(date.Add(time.Hour * 24).Unix())})
asc := &KeyOrder{arena: arena, Key: "k", Type: model.BlockContentDataviewSort_Asc,
IncludeTime: false, relationFormat: model.RelationFormat_date}
assertCompare(t, asc, a, b, -1)
})
t.Run("date includeTime eq", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Int64(date.Add(time.Second * 10).Unix())}}
b := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Int64(date.Add(time.Second * 10).Unix())}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Int64(date.Add(time.Second * 10).Unix())})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Int64(date.Add(time.Second * 10).Unix())})
asc := &KeyOrder{arena: arena, Key: "k", Type: model.BlockContentDataviewSort_Asc,
IncludeTime: true, relationFormat: model.RelationFormat_date}
assertCompare(t, asc, a, b, 0)
})
t.Run("date includeTime lt", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Int64(date.Add(time.Second * 5).Unix())}}
b := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Int64(date.Add(time.Second * 10).Unix())}}
a := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Int64(date.Add(time.Second * 5).Unix())})
b := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{"k": domain.Int64(date.Add(time.Second * 10).Unix())})
asc := &KeyOrder{arena: arena, Key: "k", Type: model.BlockContentDataviewSort_Asc,
IncludeTime: true, relationFormat: model.RelationFormat_date}
assertCompare(t, asc, a, b, -1)

View file

@ -86,7 +86,7 @@ func (s *spaceViewStub) GetExistingInviteInfo() (fileCid string, fileKey string)
return
}
func (s *spaceViewStub) SetSpaceData(details *types.Struct) error {
func (s *spaceViewStub) SetSpaceData(details *domain.Details) error {
s.data = details
return nil
}

View file

@ -153,7 +153,7 @@ func TestMigration(t *testing.T) {
}
}
func assertDetails(t *testing.T, wantDetails *types.Struct, gotDetails *types.Struct) {
func assertDetails(t *testing.T, wantdetails *domain.Details, gotdetails *domain.Details) {
for key, want := range wantDetails.Fields {
got := gotDetails.Fields[key]
assert.Equal(t, want, got, key)