github.com/ecodeclub/eorm@v0.0.2-0.20231001112437-dae71da914d0/internal/valuer/reflect_test.go (about) 1 // Copyright 2021 ecodeclub 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package valuer 16 17 import ( 18 "database/sql" 19 "reflect" 20 "testing" 21 22 "github.com/ecodeclub/eorm/internal/errs" 23 "github.com/ecodeclub/eorm/internal/model" 24 "github.com/ecodeclub/eorm/internal/test" 25 "github.com/stretchr/testify/assert" 26 ) 27 28 func TestReflectValue_Field(t *testing.T) { 29 testValueField(t, NewReflectValue) 30 invalidCases := []valueFieldTestCase{ 31 { 32 // 不存在的字段 33 name: "invalid field", 34 field: "UpdateTime", 35 wantError: errs.NewInvalidFieldError("UpdateTime"), 36 }, 37 } 38 t.Run("invalid cases", func(t *testing.T) { 39 meta, err := model.NewMetaRegistry().Get(&test.SimpleStruct{}) 40 if err != nil { 41 t.Fatal(err) 42 } 43 val := NewReflectValue(&test.SimpleStruct{}, meta) 44 for _, tc := range invalidCases { 45 t.Run(tc.name, func(t *testing.T) { 46 v, err := val.Field(tc.field) 47 assert.Equal(t, tc.wantError, err) 48 if err != nil { 49 return 50 } 51 assert.Equal(t, tc.wantVal, v.Interface()) 52 }) 53 } 54 }) 55 } 56 57 func Test_reflectValue_SetColumn(t *testing.T) { 58 testSetColumn(t, NewReflectValue) 59 } 60 61 func FuzzReflectValue_Field(f *testing.F) { 62 f.Fuzz(fuzzValueField(NewReflectValue)) 63 } 64 65 func fuzzValueField(factory Creator) any { 66 meta, _ := model.NewMetaRegistry().Get(&test.SimpleStruct{}) 67 return func(t *testing.T, b bool, 68 i int, i8 int8, i16 int16, i32 int32, i64 int64, 69 u uint, u8 uint8, u16 uint16, u32 uint32, u64 uint64, 70 f32 float32, f64 float64, bt byte, bs []byte, s string) { 71 cb := b 72 entity := &test.SimpleStruct{ 73 Bool: b, BoolPtr: &cb, 74 Int: i, IntPtr: &i, 75 Int8: i8, Int8Ptr: &i8, 76 Int16: i16, Int16Ptr: &i16, 77 Int32: i32, Int32Ptr: &i32, 78 Int64: i64, Int64Ptr: &i64, 79 Uint: u, UintPtr: &u, 80 Uint8: u8, Uint8Ptr: &u8, 81 Uint16: u16, Uint16Ptr: &u16, 82 Uint32: u32, Uint32Ptr: &u32, 83 Uint64: u64, Uint64Ptr: &u64, 84 Float32: f32, Float32Ptr: &f32, 85 Float64: f64, Float64Ptr: &f64, 86 String: s, 87 NullStringPtr: &sql.NullString{String: s, Valid: b}, 88 NullInt16Ptr: &sql.NullInt16{Int16: i16, Valid: b}, 89 NullInt32Ptr: &sql.NullInt32{Int32: i32, Valid: b}, 90 NullInt64Ptr: &sql.NullInt64{Int64: i64, Valid: b}, 91 NullBoolPtr: &sql.NullBool{Bool: b, Valid: b}, 92 NullFloat64Ptr: &sql.NullFloat64{Float64: f64, Valid: b}, 93 } 94 val := factory(entity, meta) 95 cases := newValueFieldTestCases(entity) 96 for _, c := range cases { 97 v, err := val.Field(c.field) 98 assert.Nil(t, err) 99 assert.Equal(t, c.wantVal, v.Interface()) 100 } 101 } 102 } 103 104 func BenchmarkReflectValue_Field(b *testing.B) { 105 meta, _ := model.NewMetaRegistry().Get(&test.SimpleStruct{}) 106 ins := NewReflectValue(&test.SimpleStruct{Int64: 13}, meta) 107 for i := 0; i < b.N; i++ { 108 val, err := ins.Field("Int64") 109 assert.Nil(b, err) 110 assert.Equal(b, int64(13), val.Interface()) 111 } 112 } 113 114 func BenchmarkReflectValue_fieldByIndexes_VS_FieldByName(b *testing.B) { 115 meta, _ := model.NewMetaRegistry().Get(&test.SimpleStruct{}) 116 ins := NewReflectValue(&test.SimpleStruct{Int64: 13}, meta) 117 in, ok := ins.(reflectValue) 118 assert.True(b, ok) 119 fieldName, unknownFieldName := "Int64", "XXXX" 120 unknownValue := int64(13) 121 var fieldValue reflect.Value 122 b.Run("fieldByIndex found", func(b *testing.B) { 123 for i := 0; i < b.N; i++ { 124 val, ok := in.fieldByIndex(fieldName) 125 assert.True(b, ok) 126 assert.Equal(b, fieldValue, val.Interface()) 127 } 128 }) 129 b.Run("fieldByIndex not found", func(b *testing.B) { 130 for i := 0; i < b.N; i++ { 131 val, ok := in.fieldByIndex(unknownFieldName) 132 assert.False(b, ok) 133 assert.Equal(b, unknownValue, val) 134 } 135 }) 136 b.Run("FieldByName found", func(b *testing.B) { 137 for i := 0; i < b.N; i++ { 138 val := in.val.FieldByName(fieldName) 139 assert.Equal(b, fieldValue, val.Interface()) 140 } 141 }) 142 b.Run("fieldByIndex not found", func(b *testing.B) { 143 for i := 0; i < b.N; i++ { 144 val := in.val.FieldByName(unknownFieldName) 145 assert.Equal(b, unknownValue, val) 146 } 147 }) 148 }