302 lines
7.1 KiB
Go
302 lines
7.1 KiB
Go
package engine
|
|
|
|
import (
|
|
"testing"
|
|
)
|
|
|
|
func TestBitwiseOps_BitAnd(t *testing.T) {
|
|
engine := &AggregationEngine{}
|
|
|
|
tests := []struct {
|
|
name string
|
|
data map[string]interface{}
|
|
operand interface{}
|
|
expected int64
|
|
}{
|
|
{
|
|
name: "basic AND operation",
|
|
data: map[string]interface{}{},
|
|
operand: []interface{}{float64(12), float64(10)}, // 1100 & 1010 = 1000
|
|
expected: 8,
|
|
},
|
|
{
|
|
name: "multiple operands",
|
|
data: map[string]interface{}{},
|
|
operand: []interface{}{float64(15), float64(7), float64(3)}, // 1111 & 0111 & 0011 = 0011
|
|
expected: 3,
|
|
},
|
|
{
|
|
name: "with field references",
|
|
data: map[string]interface{}{"a": float64(12), "b": float64(10)},
|
|
operand: []interface{}{"$a", "$b"},
|
|
expected: 8,
|
|
},
|
|
{
|
|
name: "single operand returns zero",
|
|
data: map[string]interface{}{},
|
|
operand: []interface{}{float64(5)},
|
|
expected: 0,
|
|
},
|
|
{
|
|
name: "empty operand returns zero",
|
|
data: map[string]interface{}{},
|
|
operand: []interface{}{},
|
|
expected: 0,
|
|
},
|
|
{
|
|
name: "AND with zero",
|
|
data: map[string]interface{}{},
|
|
operand: []interface{}{float64(255), float64(0)},
|
|
expected: 0,
|
|
},
|
|
{
|
|
name: "AND same numbers",
|
|
data: map[string]interface{}{},
|
|
operand: []interface{}{float64(42), float64(42)},
|
|
expected: 42,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := engine.bitAnd(tt.operand, tt.data)
|
|
if result != tt.expected {
|
|
t.Errorf("bitAnd() = %v, want %v", result, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestBitwiseOps_BitOr(t *testing.T) {
|
|
engine := &AggregationEngine{}
|
|
|
|
tests := []struct {
|
|
name string
|
|
data map[string]interface{}
|
|
operand interface{}
|
|
expected int64
|
|
}{
|
|
{
|
|
name: "basic OR operation",
|
|
data: map[string]interface{}{},
|
|
operand: []interface{}{float64(12), float64(10)}, // 1100 | 1010 = 1110
|
|
expected: 14,
|
|
},
|
|
{
|
|
name: "multiple operands",
|
|
data: map[string]interface{}{},
|
|
operand: []interface{}{float64(1), float64(2), float64(4)}, // 001 | 010 | 100 = 111
|
|
expected: 7,
|
|
},
|
|
{
|
|
name: "with field references",
|
|
data: map[string]interface{}{"a": float64(5), "b": float64(3)},
|
|
operand: []interface{}{"$a", "$b"}, // 101 | 011 = 111
|
|
expected: 7,
|
|
},
|
|
{
|
|
name: "single operand returns zero",
|
|
data: map[string]interface{}{},
|
|
operand: []interface{}{float64(5)},
|
|
expected: 0,
|
|
},
|
|
{
|
|
name: "OR with zero",
|
|
data: map[string]interface{}{},
|
|
operand: []interface{}{float64(42), float64(0)},
|
|
expected: 42,
|
|
},
|
|
{
|
|
name: "OR same numbers",
|
|
data: map[string]interface{}{},
|
|
operand: []interface{}{float64(15), float64(15)},
|
|
expected: 15,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := engine.bitOr(tt.operand, tt.data)
|
|
if result != tt.expected {
|
|
t.Errorf("bitOr() = %v, want %v", result, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestBitwiseOps_BitXor(t *testing.T) {
|
|
engine := &AggregationEngine{}
|
|
|
|
tests := []struct {
|
|
name string
|
|
data map[string]interface{}
|
|
operand interface{}
|
|
expected int64
|
|
}{
|
|
{
|
|
name: "basic XOR operation",
|
|
data: map[string]interface{}{},
|
|
operand: []interface{}{float64(12), float64(10)}, // 1100 ^ 1010 = 0110
|
|
expected: 6,
|
|
},
|
|
{
|
|
name: "multiple operands",
|
|
data: map[string]interface{}{},
|
|
operand: []interface{}{float64(5), float64(3), float64(1)}, // 101 ^ 011 ^ 001 = 111
|
|
expected: 7,
|
|
},
|
|
{
|
|
name: "with field references",
|
|
data: map[string]interface{}{"x": float64(7), "y": float64(3)},
|
|
operand: []interface{}{"$x", "$y"}, // 111 ^ 011 = 100
|
|
expected: 4,
|
|
},
|
|
{
|
|
name: "single operand returns zero",
|
|
data: map[string]interface{}{},
|
|
operand: []interface{}{float64(5)},
|
|
expected: 0,
|
|
},
|
|
{
|
|
name: "XOR with zero",
|
|
data: map[string]interface{}{},
|
|
operand: []interface{}{float64(42), float64(0)},
|
|
expected: 42,
|
|
},
|
|
{
|
|
name: "XOR same numbers",
|
|
data: map[string]interface{}{},
|
|
operand: []interface{}{float64(25), float64(25)},
|
|
expected: 0,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := engine.bitXor(tt.operand, tt.data)
|
|
if result != tt.expected {
|
|
t.Errorf("bitXor() = %v, want %v", result, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestBitwiseOps_BitNot(t *testing.T) {
|
|
engine := &AggregationEngine{}
|
|
|
|
tests := []struct {
|
|
name string
|
|
data map[string]interface{}
|
|
operand interface{}
|
|
expected int64
|
|
}{
|
|
{
|
|
name: "basic NOT operation",
|
|
data: map[string]interface{}{},
|
|
operand: float64(5),
|
|
expected: ^int64(5),
|
|
},
|
|
{
|
|
name: "NOT zero",
|
|
data: map[string]interface{}{},
|
|
operand: float64(0),
|
|
expected: ^int64(0), // -1
|
|
},
|
|
{
|
|
name: "with field reference",
|
|
data: map[string]interface{}{"value": float64(10)},
|
|
operand: "$value",
|
|
expected: ^int64(10),
|
|
},
|
|
{
|
|
name: "NOT negative number",
|
|
data: map[string]interface{}{},
|
|
operand: float64(-5),
|
|
expected: ^int64(-5),
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := engine.bitNot(tt.operand, tt.data)
|
|
if result != tt.expected {
|
|
t.Errorf("bitNot() = %v, want %v", result, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestBitwiseOps_Integration(t *testing.T) {
|
|
engine := &AggregationEngine{}
|
|
|
|
// 测试组合使用多个位运算操作符
|
|
tests := []struct {
|
|
name string
|
|
data map[string]interface{}
|
|
pipeline []map[string]interface{}
|
|
expectedLen int
|
|
checkFunc func([]map[string]interface{}) bool
|
|
}{
|
|
{
|
|
name: "combined bitwise operations",
|
|
data: map[string]interface{}{
|
|
"a": float64(12), // 1100
|
|
"b": float64(10), // 1010
|
|
"c": float64(6), // 0110
|
|
},
|
|
pipeline: []map[string]interface{}{
|
|
{
|
|
"$addFields": map[string]interface{}{
|
|
"and_result": map[string]interface{}{
|
|
"$bitAnd": []interface{}{"$a", "$b"},
|
|
},
|
|
"or_result": map[string]interface{}{
|
|
"$bitOr": []interface{}{"$a", "$b"},
|
|
},
|
|
"xor_result": map[string]interface{}{
|
|
"$bitXor": []interface{}{"$a", "$b"},
|
|
},
|
|
"not_result": map[string]interface{}{
|
|
"$bitNot": "$c",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
expectedLen: 1,
|
|
checkFunc: func(results []map[string]interface{}) bool {
|
|
return results[0]["and_result"] == int64(8) &&
|
|
results[0]["or_result"] == int64(14) &&
|
|
results[0]["xor_result"] == int64(6)
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
// 简化测试:直接测试表达式评估
|
|
doc := tt.data
|
|
|
|
// 测试 bitAnd
|
|
andOperand := []interface{}{"$a", "$b"}
|
|
andResult := engine.bitAnd(andOperand, doc)
|
|
if andResult != 8 {
|
|
t.Errorf("bitAnd integration = %v, want 8", andResult)
|
|
}
|
|
|
|
// 测试 bitOr
|
|
orOperand := []interface{}{"$a", "$b"}
|
|
orResult := engine.bitOr(orOperand, doc)
|
|
if orResult != 14 {
|
|
t.Errorf("bitOr integration = %v, want 14", orResult)
|
|
}
|
|
|
|
// 测试 bitXor
|
|
xorOperand := []interface{}{"$a", "$b"}
|
|
xorResult := engine.bitXor(xorOperand, doc)
|
|
if xorResult != 6 {
|
|
t.Errorf("bitXor integration = %v, want 6", xorResult)
|
|
}
|
|
})
|
|
}
|
|
}
|