github.com/machinefi/w3bstream@v1.6.5-rc9.0.20240426031326-b8c7c4876e72/pkg/depends/x/textx/text_z_unit_test.go (about) 1 package textx_test 2 3 import ( 4 "fmt" 5 "reflect" 6 "strconv" 7 "testing" 8 "time" 9 10 . "github.com/onsi/gomega" 11 12 "github.com/machinefi/w3bstream/pkg/depends/x/ptrx" 13 . "github.com/machinefi/w3bstream/pkg/depends/x/textx" 14 ) 15 16 type Duration time.Duration 17 18 func (d Duration) MarshalText() ([]byte, error) { 19 return []byte(time.Duration(d).String()), nil 20 } 21 22 func (d *Duration) UnmarshalText(data []byte) error { 23 dur, err := time.ParseDuration(string(data)) 24 if err != nil { 25 return err 26 } 27 *d = Duration(dur) 28 return nil 29 } 30 31 type NamedString string 32 type NamedInt int 33 34 var ( 35 v = struct { 36 NamedString NamedString 37 NamedInt NamedInt 38 Duration Duration 39 PtrDuration *Duration 40 String string 41 PtrString *string 42 PtrPtrString **string 43 Int int 44 PtrInt *int 45 Uint uint 46 PtrUint *uint 47 Float float32 48 PtrFloat *float32 49 Bool bool 50 PtrBool *bool 51 Bytes []byte 52 }{} 53 54 rv = reflect.ValueOf(&v).Elem() 55 d = Duration(2 * time.Second) 56 ) 57 58 var cases = []struct { 59 name string 60 v interface{} 61 text string 62 expect interface{} 63 }{ 64 { 65 "Ptr String", 66 rv.FieldByName("PtrString"), 67 "string", 68 ptrx.String("string"), 69 }, 70 { 71 "Ptr Ptr String", 72 rv.FieldByName("PtrPtrString"), 73 "string", 74 func() **string { 75 s := ptrx.String("string") 76 return &s 77 }(), 78 }, 79 { 80 "Ptr String raw value", 81 &v.String, 82 "ptr", 83 ptrx.String("ptr"), 84 }, 85 { 86 "Named String", 87 rv.FieldByName("NamedString"), 88 "string", 89 NamedString("string"), 90 }, 91 { 92 "Duration", 93 rv.FieldByName("Duration"), 94 "2s", 95 Duration(2 * time.Second), 96 }, 97 { 98 "Ptr Duration", 99 rv.FieldByName("PtrDuration"), 100 "2s", 101 &d, 102 }, 103 { 104 "Int", 105 rv.FieldByName("Int"), 106 "1", 107 1, 108 }, 109 { 110 "Named Int", 111 rv.FieldByName("NamedInt"), 112 "11", 113 NamedInt(11), 114 }, 115 { 116 "PtrInt", 117 rv.FieldByName("PtrInt"), 118 "1", 119 ptrx.Int(1), 120 }, 121 { 122 "Uint", 123 rv.FieldByName("Uint"), 124 "1", 125 uint(1), 126 }, 127 { 128 "Int raw value", 129 rv.FieldByName("Int").Addr().Interface(), 130 "1", 131 ptrx.Int(1), 132 }, 133 { 134 "PtrUint", 135 rv.FieldByName("PtrUint"), 136 "1", 137 ptrx.Uint(1), 138 }, 139 { 140 "Float", 141 rv.FieldByName("Float"), 142 "1", 143 float32(1), 144 }, 145 { 146 "PtrFloat", 147 rv.FieldByName("PtrFloat"), 148 "1.1", 149 ptrx.Float32(1.1), 150 }, 151 { 152 "Bool", 153 rv.FieldByName("Bool"), 154 "true", 155 true, 156 }, 157 { 158 "PtrBool", 159 rv.FieldByName("PtrBool"), 160 "true", 161 ptrx.Bool(true), 162 }, 163 { 164 "Bytes", 165 rv.FieldByName("Bytes"), 166 "111", 167 []byte("111"), 168 }, 169 { 170 "Bytes direct", 171 &v.Bytes, 172 "111", 173 func() *[]byte { 174 b := []byte("111") 175 return &b 176 }(), 177 }, 178 } 179 180 func BenchmarkPtrFloat(b *testing.B) { 181 v.PtrFloat = ptrx.Float32(1.1) 182 //rv := reflect.ValueOf(v.PtrFloat).Elem() 183 184 b.Run("append", func(b *testing.B) { 185 for i := 0; i < b.N; i++ { 186 //f := rv.Float() 187 //_, _ = MarshalText(v.PtrFloat) 188 d := make([]byte, 0) 189 strconv.AppendFloat(d, float64(*v.PtrFloat), 'f', -1, 32) 190 } 191 192 //fmt.Println(string(d)) 193 }) 194 195 b.Run("format", func(b *testing.B) { 196 for i := 0; i < b.N; i++ { 197 //f := rv.Float() 198 //_, _ = MarshalText(v.PtrFloat) 199 _ = []byte(strconv.FormatFloat(float64(*v.PtrFloat), 'f', -1, 32)) 200 } 201 //fmt.Println(string(d)) 202 }) 203 } 204 205 func BenchmarkUnmarshalTextAndMarshalText(b *testing.B) { 206 for i := range cases { 207 c := cases[i] 208 209 b.Run(fmt.Sprintf("UnmarshalText %s", c.name), func(b *testing.B) { 210 for i := 0; i < b.N; i++ { 211 _ = UnmarshalText(c.v, []byte(c.text)) 212 } 213 }) 214 215 b.Run(fmt.Sprintf("MarshalText %s", c.name), func(b *testing.B) { 216 for i := 0; i < b.N; i++ { 217 _, _ = MarshalText(c.v) 218 } 219 }) 220 } 221 } 222 223 func TestUnmarshalTextAndMarshalText(t *testing.T) { 224 for _, c := range cases { 225 t.Run(fmt.Sprintf("UnmarshalText %s", c.name), func(t *testing.T) { 226 err := UnmarshalText(c.v, []byte(c.text)) 227 228 NewWithT(t).Expect(err).To(BeNil()) 229 230 if rv, ok := c.v.(reflect.Value); ok { 231 NewWithT(t).Expect(c.expect).To(Equal(rv.Interface())) 232 } else { 233 NewWithT(t).Expect(c.expect).To(Equal(c.v)) 234 } 235 }) 236 } 237 238 for _, c := range cases { 239 t.Run(fmt.Sprintf("MarshalText %s", c.name), func(t *testing.T) { 240 text, err := MarshalText(c.v) 241 NewWithT(t).Expect(err).To(BeNil()) 242 NewWithT(t).Expect(c.text).To(Equal(string(text))) 243 }) 244 } 245 246 v2 := struct { 247 PtrString *string 248 Slice []string 249 }{} 250 251 rv2 := reflect.ValueOf(v2) 252 253 { 254 _, err := MarshalText(rv2.FieldByName("Slice")) 255 NewWithT(t).Expect(err).NotTo(BeNil()) 256 } 257 258 { 259 _, err := MarshalText(rv2.FieldByName("PtrString")) 260 NewWithT(t).Expect(err).To(BeNil()) 261 } 262 }