Organize backend into product executable and shared Go modules
This commit is contained in:
1 parent
981e84a4b4
commit
f0720ec66b
382 files changed
+1944
-6989
No files matched your search
@@ -0,0 +1,576 @@
|
||||
package builderimp
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.sendico.io/tech/sxchnge/shared/database/repository/builder"
|
||||
"git.sendico.io/tech/sxchnge/shared/service"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"go.mongodb.org/mongo-driver/v2/bson"
|
||||
"go.mongodb.org/mongo-driver/v2/mongo"
|
||||
"go.mongodb.org/mongo-driver/v2/mongo/options"
|
||||
)
|
||||
|
||||
func TestNewPipelineImp(t *testing.T) {
|
||||
pipeline := NewPipelineImp()
|
||||
|
||||
assert.NotNil(t, pipeline)
|
||||
assert.IsType(t, &PipelineImp{}, pipeline)
|
||||
|
||||
// Build should return empty pipeline initially
|
||||
built := pipeline.Build()
|
||||
assert.NotNil(t, built)
|
||||
assert.Len(t, built, 0)
|
||||
}
|
||||
|
||||
func TestNewPipelineImpSeedsComposableStages(t *testing.T) {
|
||||
sortStage := bson.D{{Key: "$sort", Value: bson.D{{Key: "createdAt", Value: -1}}}}
|
||||
pipeline := NewPipelineImp(sortStage)
|
||||
|
||||
result := pipeline.Count(&MockField{build: "total"})
|
||||
|
||||
assert.Same(t, pipeline, result)
|
||||
assert.Equal(t, mongo.Pipeline{
|
||||
sortStage,
|
||||
bson.D{{Key: "$count", Value: "total"}},
|
||||
}, pipeline.Build())
|
||||
}
|
||||
|
||||
func TestPipelineImp_Match(t *testing.T) {
|
||||
pipeline := NewPipelineImp()
|
||||
mockQuery := &MockQuery{
|
||||
buildPipeline: bson.D{{Key: "$match", Value: bson.D{{Key: "field", Value: "value"}}}},
|
||||
}
|
||||
|
||||
result := pipeline.Match(mockQuery)
|
||||
|
||||
// Should return self for chaining
|
||||
assert.Same(t, pipeline, result)
|
||||
|
||||
built := pipeline.Build()
|
||||
assert.Len(t, built, 1)
|
||||
assert.Equal(t, bson.D{{Key: "$match", Value: bson.D{{Key: "field", Value: "value"}}}}, built[0])
|
||||
}
|
||||
|
||||
func TestPipelineImp_Lookup(t *testing.T) {
|
||||
pipeline := NewPipelineImp()
|
||||
mockLocalField := &MockField{build: "localField"}
|
||||
mockForeignField := &MockField{build: "foreignField"}
|
||||
mockAsField := &MockField{build: "asField"}
|
||||
|
||||
result := pipeline.Lookup(mservice.Site, mockLocalField, mockForeignField, mockAsField)
|
||||
|
||||
// Should return self for chaining
|
||||
assert.Same(t, pipeline, result)
|
||||
|
||||
built := pipeline.Build()
|
||||
assert.Len(t, built, 1)
|
||||
|
||||
expected := bson.D{{Key: string(builder.Lookup), Value: bson.D{
|
||||
{Key: string(builder.MKFrom), Value: mservice.Site},
|
||||
{Key: string(builder.MKLocalField), Value: "localField"},
|
||||
{Key: string(builder.MKForeignField), Value: "foreignField"},
|
||||
{Key: string(builder.MKAs), Value: "asField"},
|
||||
}}}
|
||||
|
||||
assert.Equal(t, expected, built[0])
|
||||
}
|
||||
|
||||
func TestPipelineImp_LookupWithPipeline_WithoutLet(t *testing.T) {
|
||||
pipeline := NewPipelineImp()
|
||||
mockNestedPipeline := &MockPipeline{
|
||||
build: mongo.Pipeline{bson.D{{Key: "$match", Value: bson.D{{Key: "nested", Value: true}}}}},
|
||||
}
|
||||
mockAsField := &MockField{build: "asField"}
|
||||
|
||||
result := pipeline.LookupWithPipeline(mservice.Site, mockNestedPipeline, mockAsField, nil)
|
||||
|
||||
// Should return self for chaining
|
||||
assert.Same(t, pipeline, result)
|
||||
|
||||
built := pipeline.Build()
|
||||
assert.Len(t, built, 1)
|
||||
|
||||
expected := bson.D{{Key: string(builder.Lookup), Value: bson.D{
|
||||
{Key: string(builder.MKFrom), Value: mservice.Site},
|
||||
{Key: string(builder.MKPipeline), Value: mockNestedPipeline.build},
|
||||
{Key: string(builder.MKAs), Value: "asField"},
|
||||
}}}
|
||||
|
||||
assert.Equal(t, expected, built[0])
|
||||
}
|
||||
|
||||
func TestPipelineImp_LookupWithPipeline_WithLet(t *testing.T) {
|
||||
pipeline := NewPipelineImp()
|
||||
mockNestedPipeline := &MockPipeline{
|
||||
build: mongo.Pipeline{bson.D{{Key: "$match", Value: bson.D{{Key: "nested", Value: true}}}}},
|
||||
}
|
||||
mockAsField := &MockField{build: "asField"}
|
||||
mockLetField := &MockField{build: "$_id"}
|
||||
|
||||
letVars := map[string]builder.Field{
|
||||
"projRef": mockLetField,
|
||||
}
|
||||
|
||||
result := pipeline.LookupWithPipeline(mservice.Site, mockNestedPipeline, mockAsField, &letVars)
|
||||
|
||||
// Should return self for chaining
|
||||
assert.Same(t, pipeline, result)
|
||||
|
||||
built := pipeline.Build()
|
||||
assert.Len(t, built, 1)
|
||||
|
||||
expected := bson.D{{Key: string(builder.Lookup), Value: bson.D{
|
||||
{Key: string(builder.MKFrom), Value: mservice.Site},
|
||||
{Key: string(builder.MKPipeline), Value: mockNestedPipeline.build},
|
||||
{Key: string(builder.MKAs), Value: "asField"},
|
||||
{Key: string(builder.MKLet), Value: bson.D{{Key: "projRef", Value: "$_id"}}},
|
||||
}}}
|
||||
|
||||
assert.Equal(t, expected, built[0])
|
||||
}
|
||||
|
||||
func TestPipelineImp_LookupWithPipeline_WithEmptyLet(t *testing.T) {
|
||||
pipeline := NewPipelineImp()
|
||||
mockNestedPipeline := &MockPipeline{
|
||||
build: mongo.Pipeline{bson.D{{Key: "$match", Value: bson.D{{Key: "nested", Value: true}}}}},
|
||||
}
|
||||
mockAsField := &MockField{build: "asField"}
|
||||
|
||||
emptyLetVars := map[string]builder.Field{}
|
||||
|
||||
pipeline.LookupWithPipeline(mservice.Site, mockNestedPipeline, mockAsField, &emptyLetVars)
|
||||
|
||||
built := pipeline.Build()
|
||||
assert.Len(t, built, 1)
|
||||
|
||||
// Should not include let field when empty
|
||||
expected := bson.D{{Key: string(builder.Lookup), Value: bson.D{
|
||||
{Key: string(builder.MKFrom), Value: mservice.Site},
|
||||
{Key: string(builder.MKPipeline), Value: mockNestedPipeline.build},
|
||||
{Key: string(builder.MKAs), Value: "asField"},
|
||||
}}}
|
||||
|
||||
assert.Equal(t, expected, built[0])
|
||||
}
|
||||
|
||||
func TestPipelineImp_Unwind_Simple(t *testing.T) {
|
||||
pipeline := NewPipelineImp()
|
||||
mockField := &MockField{build: "$array"}
|
||||
|
||||
result := pipeline.Unwind(mockField)
|
||||
|
||||
// Should return self for chaining
|
||||
assert.Same(t, pipeline, result)
|
||||
|
||||
built := pipeline.Build()
|
||||
assert.Len(t, built, 1)
|
||||
|
||||
expected := bson.D{{Key: string(builder.Unwind), Value: "$array"}}
|
||||
assert.Equal(t, expected, built[0])
|
||||
}
|
||||
|
||||
func TestPipelineImp_Unwind_WithPreserveNullAndEmptyArrays(t *testing.T) {
|
||||
pipeline := NewPipelineImp()
|
||||
mockField := &MockField{build: "$array"}
|
||||
|
||||
// Mock the UnwindOption function
|
||||
preserveOpt := func(opts *builder.UnwindOpts) {
|
||||
opts.PreserveNullAndEmptyArrays = true
|
||||
}
|
||||
|
||||
pipeline.Unwind(mockField, preserveOpt)
|
||||
|
||||
built := pipeline.Build()
|
||||
assert.Len(t, built, 1)
|
||||
|
||||
expected := bson.D{{Key: string(builder.Unwind), Value: bson.D{
|
||||
{Key: string(builder.MKPath), Value: "$array"},
|
||||
{Key: string(builder.MKPreserveNullAndEmptyArrays), Value: true},
|
||||
}}}
|
||||
|
||||
assert.Equal(t, expected, built[0])
|
||||
}
|
||||
|
||||
func TestPipelineImp_Unwind_WithIncludeArrayIndex(t *testing.T) {
|
||||
pipeline := NewPipelineImp()
|
||||
mockField := &MockField{build: "$array"}
|
||||
|
||||
// Mock the UnwindOption function
|
||||
indexOpt := func(opts *builder.UnwindOpts) {
|
||||
opts.IncludeArrayIndex = "arrayIndex"
|
||||
}
|
||||
|
||||
pipeline.Unwind(mockField, indexOpt)
|
||||
|
||||
built := pipeline.Build()
|
||||
assert.Len(t, built, 1)
|
||||
|
||||
expected := bson.D{{Key: string(builder.Unwind), Value: bson.D{
|
||||
{Key: string(builder.MKPath), Value: "$array"},
|
||||
{Key: string(builder.MKIncludeArrayIndex), Value: "arrayIndex"},
|
||||
}}}
|
||||
|
||||
assert.Equal(t, expected, built[0])
|
||||
}
|
||||
|
||||
func TestPipelineImp_Unwind_WithBothOptions(t *testing.T) {
|
||||
pipeline := NewPipelineImp()
|
||||
mockField := &MockField{build: "$array"}
|
||||
|
||||
// Mock the UnwindOption functions
|
||||
preserveOpt := func(opts *builder.UnwindOpts) {
|
||||
opts.PreserveNullAndEmptyArrays = true
|
||||
}
|
||||
indexOpt := func(opts *builder.UnwindOpts) {
|
||||
opts.IncludeArrayIndex = "arrayIndex"
|
||||
}
|
||||
|
||||
pipeline.Unwind(mockField, preserveOpt, indexOpt)
|
||||
|
||||
built := pipeline.Build()
|
||||
assert.Len(t, built, 1)
|
||||
|
||||
expected := bson.D{{Key: string(builder.Unwind), Value: bson.D{
|
||||
{Key: string(builder.MKPath), Value: "$array"},
|
||||
{Key: string(builder.MKPreserveNullAndEmptyArrays), Value: true},
|
||||
{Key: string(builder.MKIncludeArrayIndex), Value: "arrayIndex"},
|
||||
}}}
|
||||
|
||||
assert.Equal(t, expected, built[0])
|
||||
}
|
||||
|
||||
func TestPipelineImp_Count(t *testing.T) {
|
||||
pipeline := NewPipelineImp()
|
||||
mockField := &MockField{build: "totalCount"}
|
||||
|
||||
result := pipeline.Count(mockField)
|
||||
|
||||
// Should return self for chaining
|
||||
assert.Same(t, pipeline, result)
|
||||
|
||||
built := pipeline.Build()
|
||||
assert.Len(t, built, 1)
|
||||
|
||||
expected := bson.D{{Key: string(builder.Count), Value: "totalCount"}}
|
||||
assert.Equal(t, expected, built[0])
|
||||
}
|
||||
|
||||
func TestPipelineImp_Group(t *testing.T) {
|
||||
pipeline := NewPipelineImp()
|
||||
mockAlias := &MockAlias{
|
||||
build: bson.D{{Key: "_id", Value: "$field"}},
|
||||
field: &MockField{build: "_id"},
|
||||
}
|
||||
mockAccumulator := &MockGroupAccumulator{
|
||||
build: bson.D{{Key: "count", Value: bson.D{{Key: "$sum", Value: 1}}}},
|
||||
}
|
||||
|
||||
result := pipeline.Group(mockAlias, mockAccumulator)
|
||||
|
||||
// Should return self for chaining
|
||||
assert.Same(t, pipeline, result)
|
||||
|
||||
built := pipeline.Build()
|
||||
assert.Len(t, built, 1)
|
||||
|
||||
expected := bson.D{{Key: string(builder.Group), Value: bson.D{
|
||||
{Key: "_id", Value: "$field"},
|
||||
{Key: "count", Value: bson.D{{Key: "$sum", Value: 1}}},
|
||||
}}}
|
||||
|
||||
assert.Equal(t, expected, built[0])
|
||||
}
|
||||
|
||||
func TestPipelineImp_Group_MultipleAccumulators(t *testing.T) {
|
||||
pipeline := NewPipelineImp()
|
||||
mockAlias := &MockAlias{
|
||||
build: bson.D{{Key: "_id", Value: "$field"}},
|
||||
field: &MockField{build: "_id"},
|
||||
}
|
||||
mockAccumulator1 := &MockGroupAccumulator{
|
||||
build: bson.D{{Key: "count", Value: bson.D{{Key: "$sum", Value: 1}}}},
|
||||
}
|
||||
mockAccumulator2 := &MockGroupAccumulator{
|
||||
build: bson.D{{Key: "total", Value: bson.D{{Key: "$sum", Value: "$amount"}}}},
|
||||
}
|
||||
|
||||
pipeline.Group(mockAlias, mockAccumulator1, mockAccumulator2)
|
||||
|
||||
built := pipeline.Build()
|
||||
assert.Len(t, built, 1)
|
||||
|
||||
expected := bson.D{{Key: string(builder.Group), Value: bson.D{
|
||||
{Key: "_id", Value: "$field"},
|
||||
{Key: "count", Value: bson.D{{Key: "$sum", Value: 1}}},
|
||||
{Key: "total", Value: bson.D{{Key: "$sum", Value: "$amount"}}},
|
||||
}}}
|
||||
|
||||
assert.Equal(t, expected, built[0])
|
||||
}
|
||||
|
||||
func TestPipelineImp_Project(t *testing.T) {
|
||||
pipeline := NewPipelineImp()
|
||||
mockProjection := &MockProjection{
|
||||
build: bson.D{{Key: "field1", Value: 1}},
|
||||
}
|
||||
|
||||
result := pipeline.Project(mockProjection)
|
||||
|
||||
// Should return self for chaining
|
||||
assert.Same(t, pipeline, result)
|
||||
|
||||
built := pipeline.Build()
|
||||
assert.Len(t, built, 1)
|
||||
|
||||
expected := bson.D{{Key: string(builder.Project), Value: bson.D{
|
||||
{Key: "field1", Value: 1},
|
||||
}}}
|
||||
|
||||
assert.Equal(t, expected, built[0])
|
||||
}
|
||||
|
||||
func TestPipelineImp_Project_MultipleProjections(t *testing.T) {
|
||||
pipeline := NewPipelineImp()
|
||||
mockProjection1 := &MockProjection{
|
||||
build: bson.D{{Key: "field1", Value: 1}},
|
||||
}
|
||||
mockProjection2 := &MockProjection{
|
||||
build: bson.D{{Key: "field2", Value: 0}},
|
||||
}
|
||||
|
||||
pipeline.Project(mockProjection1, mockProjection2)
|
||||
|
||||
built := pipeline.Build()
|
||||
assert.Len(t, built, 1)
|
||||
|
||||
expected := bson.D{{Key: string(builder.Project), Value: bson.D{
|
||||
{Key: "field1", Value: 1},
|
||||
{Key: "field2", Value: 0},
|
||||
}}}
|
||||
|
||||
assert.Equal(t, expected, built[0])
|
||||
}
|
||||
|
||||
func TestPipelineImp_ChainedOperations(t *testing.T) {
|
||||
pipeline := NewPipelineImp()
|
||||
|
||||
// Create mocks
|
||||
mockQuery := &MockQuery{
|
||||
buildPipeline: bson.D{{Key: "$match", Value: bson.D{{Key: "status", Value: "active"}}}},
|
||||
}
|
||||
mockLocalField := &MockField{build: "userId"}
|
||||
mockForeignField := &MockField{build: "_id"}
|
||||
mockAsField := &MockField{build: "user"}
|
||||
mockUnwindField := &MockField{build: "$user"}
|
||||
mockProjection := &MockProjection{
|
||||
build: bson.D{{Key: "name", Value: "$user.name"}},
|
||||
}
|
||||
|
||||
// Chain operations
|
||||
result := pipeline.
|
||||
Match(mockQuery).
|
||||
Lookup(mservice.Accounts, mockLocalField, mockForeignField, mockAsField).
|
||||
Unwind(mockUnwindField).
|
||||
Project(mockProjection)
|
||||
|
||||
// Should return self for chaining
|
||||
assert.Same(t, pipeline, result)
|
||||
|
||||
built := pipeline.Build()
|
||||
assert.Len(t, built, 4)
|
||||
|
||||
// Verify each stage
|
||||
assert.Equal(t, bson.D{{Key: "$match", Value: bson.D{{Key: "status", Value: "active"}}}}, built[0])
|
||||
|
||||
expectedLookup := bson.D{{Key: string(builder.Lookup), Value: bson.D{
|
||||
{Key: string(builder.MKFrom), Value: mservice.Accounts},
|
||||
{Key: string(builder.MKLocalField), Value: "userId"},
|
||||
{Key: string(builder.MKForeignField), Value: "_id"},
|
||||
{Key: string(builder.MKAs), Value: "user"},
|
||||
}}}
|
||||
assert.Equal(t, expectedLookup, built[1])
|
||||
|
||||
assert.Equal(t, bson.D{{Key: string(builder.Unwind), Value: "$user"}}, built[2])
|
||||
|
||||
expectedProject := bson.D{{Key: string(builder.Project), Value: bson.D{
|
||||
{Key: "name", Value: "$user.name"},
|
||||
}}}
|
||||
assert.Equal(t, expectedProject, built[3])
|
||||
}
|
||||
|
||||
func TestNewUnwindOpts(t *testing.T) {
|
||||
t.Run("NoOptions", func(t *testing.T) {
|
||||
opts := NewUnwindOpts()
|
||||
|
||||
assert.NotNil(t, opts)
|
||||
assert.False(t, opts.PreserveNullAndEmptyArrays)
|
||||
assert.Empty(t, opts.IncludeArrayIndex)
|
||||
})
|
||||
|
||||
t.Run("WithPreserveOption", func(t *testing.T) {
|
||||
preserveOpt := func(opts *builder.UnwindOpts) {
|
||||
opts.PreserveNullAndEmptyArrays = true
|
||||
}
|
||||
|
||||
opts := NewUnwindOpts(preserveOpt)
|
||||
|
||||
assert.True(t, opts.PreserveNullAndEmptyArrays)
|
||||
assert.Empty(t, opts.IncludeArrayIndex)
|
||||
})
|
||||
|
||||
t.Run("WithIndexOption", func(t *testing.T) {
|
||||
indexOpt := func(opts *builder.UnwindOpts) {
|
||||
opts.IncludeArrayIndex = "index"
|
||||
}
|
||||
|
||||
opts := NewUnwindOpts(indexOpt)
|
||||
|
||||
assert.False(t, opts.PreserveNullAndEmptyArrays)
|
||||
assert.Equal(t, "index", opts.IncludeArrayIndex)
|
||||
})
|
||||
|
||||
t.Run("WithBothOptions", func(t *testing.T) {
|
||||
preserveOpt := func(opts *builder.UnwindOpts) {
|
||||
opts.PreserveNullAndEmptyArrays = true
|
||||
}
|
||||
indexOpt := func(opts *builder.UnwindOpts) {
|
||||
opts.IncludeArrayIndex = "index"
|
||||
}
|
||||
|
||||
opts := NewUnwindOpts(preserveOpt, indexOpt)
|
||||
|
||||
assert.True(t, opts.PreserveNullAndEmptyArrays)
|
||||
assert.Equal(t, "index", opts.IncludeArrayIndex)
|
||||
})
|
||||
}
|
||||
|
||||
// Mock implementations for testing
|
||||
|
||||
type MockQuery struct {
|
||||
buildPipeline bson.D
|
||||
}
|
||||
|
||||
func (m *MockQuery) And(filters ...builder.Query) builder.Query { return m }
|
||||
func (m *MockQuery) Or(filters ...builder.Query) builder.Query { return m }
|
||||
func (m *MockQuery) Filter(field builder.Field, value any) builder.Query { return m }
|
||||
func (m *MockQuery) Expression(value builder.Expression) builder.Query { return m }
|
||||
func (m *MockQuery) Comparison(field builder.Field, operator builder.MongoOperation, value any) builder.Query {
|
||||
return m
|
||||
}
|
||||
func (m *MockQuery) RegEx(field builder.Field, pattern, options string) builder.Query { return m }
|
||||
func (m *MockQuery) In(field builder.Field, values ...any) builder.Query { return m }
|
||||
func (m *MockQuery) NotIn(field builder.Field, values ...any) builder.Query { return m }
|
||||
func (m *MockQuery) Sort(field builder.Field, ascending bool) builder.Query { return m }
|
||||
func (m *MockQuery) Limit(limit *int64) builder.Query { return m }
|
||||
func (m *MockQuery) Offset(offset *int64) builder.Query { return m }
|
||||
func (m *MockQuery) Archived(isArchived *bool) builder.Query { return m }
|
||||
func (m *MockQuery) BuildPipeline() bson.D { return m.buildPipeline }
|
||||
func (m *MockQuery) BuildQuery() bson.D { return bson.D{} }
|
||||
func (m *MockQuery) BuildOptions() *options.FindOptionsBuilder { return &options.FindOptionsBuilder{} }
|
||||
|
||||
type MockField struct {
|
||||
build string
|
||||
}
|
||||
|
||||
func (m *MockField) Dot(field string) builder.Field { return &MockField{build: m.build + "." + field} }
|
||||
func (m *MockField) CopyWith(field string) builder.Field { return &MockField{build: field} }
|
||||
func (m *MockField) Build() string { return m.build }
|
||||
|
||||
type MockPipeline struct {
|
||||
build mongo.Pipeline
|
||||
}
|
||||
|
||||
func (m *MockPipeline) Match(filter builder.Query) builder.Pipeline { return m }
|
||||
func (m *MockPipeline) Lookup(from mservice.Type, localField, foreignField, as builder.Field) builder.Pipeline {
|
||||
return m
|
||||
}
|
||||
func (m *MockPipeline) LookupWithPipeline(from mservice.Type, pipeline builder.Pipeline, as builder.Field, let *map[string]builder.Field) builder.Pipeline {
|
||||
return m
|
||||
}
|
||||
func (m *MockPipeline) Unwind(path builder.Field, opts ...UnwindOption) builder.Pipeline { return m }
|
||||
func (m *MockPipeline) Count(field builder.Field) builder.Pipeline { return m }
|
||||
func (m *MockPipeline) Group(groupBy builder.Alias, accumulators ...builder.GroupAccumulator) builder.Pipeline {
|
||||
return m
|
||||
}
|
||||
func (m *MockPipeline) Project(projections ...builder.Projection) builder.Pipeline { return m }
|
||||
func (m *MockPipeline) ReplaceRoot(newRoot builder.Expression) builder.Pipeline { return m }
|
||||
func (m *MockPipeline) Build() mongo.Pipeline { return m.build }
|
||||
|
||||
type MockAlias struct {
|
||||
build bson.D
|
||||
field builder.Field
|
||||
}
|
||||
|
||||
func (m *MockAlias) Field() builder.Field { return m.field }
|
||||
func (m *MockAlias) Build() bson.D { return m.build }
|
||||
|
||||
type MockGroupAccumulator struct {
|
||||
build bson.D
|
||||
}
|
||||
|
||||
func (m *MockGroupAccumulator) Build() bson.D { return m.build }
|
||||
|
||||
type MockProjection struct {
|
||||
build bson.D
|
||||
}
|
||||
|
||||
func (m *MockProjection) Build() bson.D { return m.build }
|
||||
|
||||
func TestPipelineImp_ReplaceRoot(t *testing.T) {
|
||||
pipeline := NewPipelineImp()
|
||||
mockExpr := &MockExpression{build: "$newRoot"}
|
||||
|
||||
result := pipeline.ReplaceRoot(mockExpr)
|
||||
|
||||
// Should return self for chaining
|
||||
assert.Same(t, pipeline, result)
|
||||
|
||||
built := pipeline.Build()
|
||||
assert.Len(t, built, 1)
|
||||
|
||||
expected := bson.D{{Key: string(builder.ReplaceRoot), Value: bson.D{
|
||||
{Key: string(builder.MKNewRoot), Value: "$newRoot"},
|
||||
}}}
|
||||
|
||||
assert.Equal(t, expected, built[0])
|
||||
}
|
||||
|
||||
func TestPipelineImp_ReplaceRoot_WithNestedField(t *testing.T) {
|
||||
pipeline := NewPipelineImp()
|
||||
mockExpr := &MockExpression{build: "$document.data"}
|
||||
|
||||
pipeline.ReplaceRoot(mockExpr)
|
||||
|
||||
built := pipeline.Build()
|
||||
assert.Len(t, built, 1)
|
||||
|
||||
expected := bson.D{{Key: string(builder.ReplaceRoot), Value: bson.D{
|
||||
{Key: string(builder.MKNewRoot), Value: "$document.data"},
|
||||
}}}
|
||||
|
||||
assert.Equal(t, expected, built[0])
|
||||
}
|
||||
|
||||
func TestPipelineImp_ReplaceRoot_WithExpression(t *testing.T) {
|
||||
pipeline := NewPipelineImp()
|
||||
// Mock a complex expression like { $mergeObjects: [...] }
|
||||
mockExpr := &MockExpression{build: bson.D{{Key: "$mergeObjects", Value: bson.A{"$field1", "$field2"}}}}
|
||||
|
||||
pipeline.ReplaceRoot(mockExpr)
|
||||
|
||||
built := pipeline.Build()
|
||||
assert.Len(t, built, 1)
|
||||
|
||||
expected := bson.D{{Key: string(builder.ReplaceRoot), Value: bson.D{
|
||||
{Key: string(builder.MKNewRoot), Value: bson.D{{Key: "$mergeObjects", Value: bson.A{"$field1", "$field2"}}}},
|
||||
}}}
|
||||
|
||||
assert.Equal(t, expected, built[0])
|
||||
}
|
||||
|
||||
type MockExpression struct {
|
||||
build any
|
||||
}
|
||||
|
||||
func (m *MockExpression) Build() any { return m.build }
|
||||
Reference in new issue
Block a user