Files
streamsql/streamsql_complex_conditions_test.go
T
2025-08-06 11:05:06 +08:00

282 lines
7.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* Copyright 2025 The RuleGo Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package streamsql
import (
"testing"
)
// TestComplexConditions 测试复杂条件和组合条件的支持
func TestComplexConditions(t *testing.T) {
tests := []struct {
name string
sql string
data map[string]interface{}
expectMatch bool
description string
}{
{
name: "简单AND条件",
sql: "SELECT * FROM stream WHERE temperature > 20 AND humidity < 80",
data: map[string]interface{}{
"temperature": 25.0,
"humidity": 70.0,
},
expectMatch: true,
description: "两个条件都满足",
},
{
name: "简单OR条件",
sql: "SELECT * FROM stream WHERE temperature > 30 OR humidity > 90",
data: map[string]interface{}{
"temperature": 25.0,
"humidity": 95.0,
},
expectMatch: true,
description: "其中一个条件满足",
},
{
name: "复杂组合条件 - 括号优先级",
sql: "SELECT * FROM stream WHERE (temperature > 20 AND humidity < 80) OR status == 'active'",
data: map[string]interface{}{
"temperature": 15.0,
"humidity": 70.0,
"status": "active",
},
expectMatch: true,
description: "第一组条件不满足但status条件满足",
},
{
name: "多重AND条件",
sql: "SELECT * FROM stream WHERE temperature > 20 AND humidity < 80 AND pressure > 1000",
data: map[string]interface{}{
"temperature": 25.0,
"humidity": 70.0,
"pressure": 1050.0,
},
expectMatch: true,
description: "三个条件都满足",
},
{
name: "多重OR条件",
sql: "SELECT * FROM stream WHERE temperature > 40 OR humidity > 90 OR pressure < 900",
data: map[string]interface{}{
"temperature": 25.0,
"humidity": 70.0,
"pressure": 850.0,
},
expectMatch: true,
description: "第三个条件满足",
},
{
name: "复杂嵌套条件",
sql: "SELECT * FROM stream WHERE (temperature > 20 AND humidity < 80) OR (pressure > 1000 AND status == 'normal')",
data: map[string]interface{}{
"temperature": 15.0,
"humidity": 85.0,
"pressure": 1100.0,
"status": "normal",
},
expectMatch: true,
description: "第一组条件不满足,第二组条件满足",
},
{
name: "字符串条件组合",
sql: "SELECT * FROM stream WHERE deviceId == 'sensor001' AND location == 'room1'",
data: map[string]interface{}{
"deviceId": "sensor001",
"location": "room1",
},
expectMatch: true,
description: "字符串相等条件组合",
},
{
name: "混合类型条件",
sql: "SELECT * FROM stream WHERE temperature > 20 AND deviceId == 'sensor001' AND active == true",
data: map[string]interface{}{
"temperature": 25.0,
"deviceId": "sensor001",
"active": true,
},
expectMatch: true,
description: "数字、字符串、布尔值混合条件",
},
{
name: "NOT条件组合",
sql: "SELECT * FROM stream WHERE temperature >= 20 AND humidity > 50",
data: map[string]interface{}{
"temperature": 25.0,
"humidity": 60.0,
},
expectMatch: true,
description: "NOT条件与其他条件组合",
},
{
name: "条件不满足的情况",
sql: "SELECT * FROM stream WHERE temperature > 30 AND humidity < 50",
data: map[string]interface{}{
"temperature": 25.0,
"humidity": 60.0,
},
expectMatch: false,
description: "两个条件都不满足",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ssql := New()
err := ssql.Execute(tt.sql)
if err != nil {
t.Fatalf("Execute() failed: %v", err)
}
// 使用EmitSync进行同步测试
result, err := ssql.EmitSync(tt.data)
if err != nil {
t.Fatalf("EmitSync() failed: %v", err)
}
// 检查结果是否符合预期
if tt.expectMatch {
if result == nil {
t.Errorf("Expected match but got nil result. %s", tt.description)
}
} else {
if result != nil {
t.Errorf("Expected no match but got result: %v. %s", result, tt.description)
}
}
// 清理资源
ssql.Stop()
})
}
}
// TestComplexConditionsWithLike 测试LIKE条件与其他条件的组合
func TestComplexConditionsWithLike(t *testing.T) {
tests := []struct {
name string
sql string
data map[string]interface{}
expectMatch bool
}{
{
name: "LIKE与AND条件组合",
sql: "SELECT * FROM stream WHERE deviceId LIKE 'sensor%' AND temperature > 20",
data: map[string]interface{}{
"deviceId": "sensor001",
"temperature": 25.0,
},
expectMatch: true,
},
{
name: "LIKE与OR条件组合",
sql: "SELECT * FROM stream WHERE deviceId LIKE 'temp%' OR location LIKE '%room%'",
data: map[string]interface{}{
"deviceId": "sensor001",
"location": "meeting_room_1",
},
expectMatch: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ssql := New()
err := ssql.Execute(tt.sql)
if err != nil {
t.Fatalf("Execute() failed: %v", err)
}
result, err := ssql.EmitSync(tt.data)
if err != nil {
t.Fatalf("EmitSync() failed: %v", err)
}
if tt.expectMatch {
if result == nil {
t.Errorf("Expected match but got nil result")
}
} else {
if result != nil {
t.Errorf("Expected no match but got result: %v", result)
}
}
ssql.Stop()
})
}
}
// TestComplexConditionsWithNullChecks 测试NULL检查与其他条件的组合
func TestComplexConditionsWithNullChecks(t *testing.T) {
tests := []struct {
name string
sql string
data map[string]interface{}
expectMatch bool
}{
{
name: "IS NULL与AND条件组合",
sql: "SELECT * FROM stream WHERE description IS NULL AND temperature > 20",
data: map[string]interface{}{
"temperature": 25.0,
// description字段缺失应该被视为null
},
expectMatch: true,
},
{
name: "IS NOT NULL与OR条件组合",
sql: "SELECT * FROM stream WHERE description IS NOT NULL OR temperature > 30",
data: map[string]interface{}{
"temperature": 35.0,
// description字段缺失但temperature条件满足
},
expectMatch: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ssql := New()
err := ssql.Execute(tt.sql)
if err != nil {
t.Fatalf("Execute() failed: %v", err)
}
result, err := ssql.EmitSync(tt.data)
if err != nil {
t.Fatalf("EmitSync() failed: %v", err)
}
if tt.expectMatch {
if result == nil {
t.Errorf("Expected match but got nil result")
}
} else {
if result != nil {
t.Errorf("Expected no match but got result: %v", result)
}
}
ssql.Stop()
})
}
}