mirror of
https://gitee.com/rulego/streamsql.git
synced 2026-03-19 16:50:44 +00:00
306 lines
8.1 KiB
Go
306 lines
8.1 KiB
Go
/*
|
|
* 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 reflectutil
|
|
|
|
import (
|
|
"reflect"
|
|
"testing"
|
|
)
|
|
|
|
// TestStruct 用于测试的结构体
|
|
type TestStruct struct {
|
|
Name string
|
|
Age int
|
|
Email string
|
|
Active bool
|
|
Balance float64
|
|
}
|
|
|
|
// TestSafeFieldByName 测试 SafeFieldByName 函数的基本功能
|
|
func TestSafeFieldByName(t *testing.T) {
|
|
testObj := TestStruct{
|
|
Name: "John Doe",
|
|
Age: 30,
|
|
Email: "john@example.com",
|
|
Active: true,
|
|
Balance: 1000.50,
|
|
}
|
|
|
|
v := reflect.ValueOf(testObj)
|
|
|
|
// 测试获取存在的字段
|
|
nameField, err := SafeFieldByName(v, "Name")
|
|
if err != nil {
|
|
t.Errorf("Expected no error for existing field 'Name', got: %v", err)
|
|
}
|
|
|
|
if !nameField.IsValid() {
|
|
t.Error("Expected valid field for 'Name'")
|
|
}
|
|
|
|
if nameField.String() != "John Doe" {
|
|
t.Errorf("Expected field value 'John Doe', got: %v", nameField.String())
|
|
}
|
|
|
|
// 测试获取 Age 字段
|
|
ageField, err := SafeFieldByName(v, "Age")
|
|
if err != nil {
|
|
t.Errorf("Expected no error for existing field 'Age', got: %v", err)
|
|
}
|
|
|
|
if ageField.Int() != 30 {
|
|
t.Errorf("Expected field value 30, got: %v", ageField.Int())
|
|
}
|
|
|
|
// 测试获取 Active 字段
|
|
activeField, err := SafeFieldByName(v, "Active")
|
|
if err != nil {
|
|
t.Errorf("Expected no error for existing field 'Active', got: %v", err)
|
|
}
|
|
|
|
if !activeField.Bool() {
|
|
t.Errorf("Expected field value true, got: %v", activeField.Bool())
|
|
}
|
|
|
|
// 测试获取 Balance 字段
|
|
balanceField, err := SafeFieldByName(v, "Balance")
|
|
if err != nil {
|
|
t.Errorf("Expected no error for existing field 'Balance', got: %v", err)
|
|
}
|
|
|
|
if balanceField.Float() != 1000.50 {
|
|
t.Errorf("Expected field value 1000.50, got: %v", balanceField.Float())
|
|
}
|
|
}
|
|
|
|
// TestSafeFieldByNameNonExistentField 测试获取不存在的字段
|
|
func TestSafeFieldByNameNonExistentField(t *testing.T) {
|
|
testObj := TestStruct{Name: "John Doe"}
|
|
v := reflect.ValueOf(testObj)
|
|
|
|
// 测试获取不存在的字段
|
|
_, err := SafeFieldByName(v, "NonExistentField")
|
|
if err == nil {
|
|
t.Error("Expected error for non-existent field, got nil")
|
|
}
|
|
|
|
expectedError := "field NonExistentField not found"
|
|
if err.Error() != expectedError {
|
|
t.Errorf("Expected error message '%s', got: %v", expectedError, err.Error())
|
|
}
|
|
}
|
|
|
|
// TestSafeFieldByNameInvalidValue 测试无效的 reflect.Value
|
|
func TestSafeFieldByNameInvalidValue(t *testing.T) {
|
|
// 创建一个无效的 reflect.Value
|
|
var invalidValue reflect.Value
|
|
|
|
_, err := SafeFieldByName(invalidValue, "Name")
|
|
if err == nil {
|
|
t.Error("Expected error for invalid value, got nil")
|
|
}
|
|
|
|
expectedError := "invalid value"
|
|
if err.Error() != expectedError {
|
|
t.Errorf("Expected error message '%s', got: %v", expectedError, err.Error())
|
|
}
|
|
}
|
|
|
|
// TestSafeFieldByNameNonStructValue 测试非结构体类型的值
|
|
func TestSafeFieldByNameNonStructValue(t *testing.T) {
|
|
// 测试字符串类型
|
|
stringValue := reflect.ValueOf("test string")
|
|
_, err := SafeFieldByName(stringValue, "Name")
|
|
if err == nil {
|
|
t.Error("Expected error for non-struct value, got nil")
|
|
}
|
|
|
|
expectedError := "value is not a struct, got string"
|
|
if err.Error() != expectedError {
|
|
t.Errorf("Expected error message '%s', got: %v", expectedError, err.Error())
|
|
}
|
|
|
|
// 测试整数类型
|
|
intValue := reflect.ValueOf(42)
|
|
_, err = SafeFieldByName(intValue, "Name")
|
|
if err == nil {
|
|
t.Error("Expected error for non-struct value, got nil")
|
|
}
|
|
|
|
expectedError = "value is not a struct, got int"
|
|
if err.Error() != expectedError {
|
|
t.Errorf("Expected error message '%s', got: %v", expectedError, err.Error())
|
|
}
|
|
|
|
// 测试切片类型
|
|
sliceValue := reflect.ValueOf([]string{"a", "b", "c"})
|
|
_, err = SafeFieldByName(sliceValue, "Name")
|
|
if err == nil {
|
|
t.Error("Expected error for non-struct value, got nil")
|
|
}
|
|
|
|
expectedError = "value is not a struct, got slice"
|
|
if err.Error() != expectedError {
|
|
t.Errorf("Expected error message '%s', got: %v", expectedError, err.Error())
|
|
}
|
|
}
|
|
|
|
// TestSafeFieldByNameWithPointer 测试指针类型的结构体
|
|
func TestSafeFieldByNameWithPointer(t *testing.T) {
|
|
testObj := &TestStruct{
|
|
Name: "Jane Doe",
|
|
Age: 25,
|
|
Active: false,
|
|
}
|
|
|
|
// 获取指针指向的值
|
|
v := reflect.ValueOf(testObj).Elem()
|
|
|
|
// 测试获取字段
|
|
nameField, err := SafeFieldByName(v, "Name")
|
|
if err != nil {
|
|
t.Errorf("Expected no error for existing field 'Name', got: %v", err)
|
|
}
|
|
|
|
if nameField.String() != "Jane Doe" {
|
|
t.Errorf("Expected field value 'Jane Doe', got: %v", nameField.String())
|
|
}
|
|
|
|
ageField, err := SafeFieldByName(v, "Age")
|
|
if err != nil {
|
|
t.Errorf("Expected no error for existing field 'Age', got: %v", err)
|
|
}
|
|
|
|
if ageField.Int() != 25 {
|
|
t.Errorf("Expected field value 25, got: %v", ageField.Int())
|
|
}
|
|
}
|
|
|
|
// TestSafeFieldByNameWithInterface 测试接口类型
|
|
func TestSafeFieldByNameWithInterface(t *testing.T) {
|
|
var testInterface interface{} = TestStruct{
|
|
Name: "Interface Test",
|
|
Age: 35,
|
|
Email: "interface@test.com",
|
|
}
|
|
|
|
v := reflect.ValueOf(testInterface)
|
|
|
|
nameField, err := SafeFieldByName(v, "Name")
|
|
if err != nil {
|
|
t.Errorf("Expected no error for existing field 'Name', got: %v", err)
|
|
}
|
|
|
|
if nameField.String() != "Interface Test" {
|
|
t.Errorf("Expected field value 'Interface Test', got: %v", nameField.String())
|
|
}
|
|
}
|
|
|
|
// TestSafeFieldByNameEmptyStruct 测试空结构体
|
|
func TestSafeFieldByNameEmptyStruct(t *testing.T) {
|
|
type EmptyStruct struct{}
|
|
|
|
emptyObj := EmptyStruct{}
|
|
v := reflect.ValueOf(emptyObj)
|
|
|
|
// 尝试获取不存在的字段
|
|
_, err := SafeFieldByName(v, "NonExistentField")
|
|
if err == nil {
|
|
t.Error("Expected error for non-existent field in empty struct, got nil")
|
|
}
|
|
|
|
expectedError := "field NonExistentField not found"
|
|
if err.Error() != expectedError {
|
|
t.Errorf("Expected error message '%s', got: %v", expectedError, err.Error())
|
|
}
|
|
}
|
|
|
|
// TestSafeFieldByNameCaseSensitive 测试字段名大小写敏感性
|
|
func TestSafeFieldByNameCaseSensitive(t *testing.T) {
|
|
testObj := TestStruct{Name: "Case Test"}
|
|
v := reflect.ValueOf(testObj)
|
|
|
|
// 测试正确的大小写
|
|
nameField, err := SafeFieldByName(v, "Name")
|
|
if err != nil {
|
|
t.Errorf("Expected no error for correct case 'Name', got: %v", err)
|
|
}
|
|
|
|
if nameField.String() != "Case Test" {
|
|
t.Errorf("Expected field value 'Case Test', got: %v", nameField.String())
|
|
}
|
|
|
|
// 测试错误的大小写
|
|
_, err = SafeFieldByName(v, "name") // 小写
|
|
if err == nil {
|
|
t.Error("Expected error for incorrect case 'name', got nil")
|
|
}
|
|
|
|
_, err = SafeFieldByName(v, "NAME") // 大写
|
|
if err == nil {
|
|
t.Error("Expected error for incorrect case 'NAME', got nil")
|
|
}
|
|
}
|
|
|
|
// TestSafeFieldByNameConcurrentAccess 测试并发访问
|
|
func TestSafeFieldByNameConcurrentAccess(t *testing.T) {
|
|
testObj := TestStruct{
|
|
Name: "Concurrent Test",
|
|
Age: 40,
|
|
Email: "concurrent@test.com",
|
|
Active: true,
|
|
Balance: 2000.75,
|
|
}
|
|
|
|
v := reflect.ValueOf(testObj)
|
|
|
|
// 启动多个 goroutine 并发访问
|
|
done := make(chan bool, 10)
|
|
for i := 0; i < 10; i++ {
|
|
go func() {
|
|
for j := 0; j < 100; j++ {
|
|
// 测试获取不同字段
|
|
nameField, err := SafeFieldByName(v, "Name")
|
|
if err != nil {
|
|
t.Errorf("Concurrent access error for Name: %v", err)
|
|
return
|
|
}
|
|
if nameField.String() != "Concurrent Test" {
|
|
t.Errorf("Concurrent access value error for Name: expected 'Concurrent Test', got %v", nameField.String())
|
|
return
|
|
}
|
|
|
|
ageField, err := SafeFieldByName(v, "Age")
|
|
if err != nil {
|
|
t.Errorf("Concurrent access error for Age: %v", err)
|
|
return
|
|
}
|
|
if ageField.Int() != 40 {
|
|
t.Errorf("Concurrent access value error for Age: expected 40, got %v", ageField.Int())
|
|
return
|
|
}
|
|
}
|
|
done <- true
|
|
}()
|
|
}
|
|
|
|
// 等待所有 goroutine 完成
|
|
for i := 0; i < 10; i++ {
|
|
<-done
|
|
}
|
|
}
|