Files
2025-08-07 19:23:48 +08:00

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
}
}