github.com/RevenueMonster/sqlike@v1.0.6/types/key_test.go (about) 1 package types 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "fmt" 7 "reflect" 8 "strconv" 9 "testing" 10 11 "github.com/RevenueMonster/sqlike/jsonb" 12 "github.com/RevenueMonster/sqlike/reflext" 13 "github.com/stretchr/testify/require" 14 "go.mongodb.org/mongo-driver/bson/bsontype" 15 ) 16 17 type field struct { 18 name string 19 t reflect.Type 20 null bool 21 opts map[string]string 22 } 23 24 // Name : 25 func (f field) Name() string { 26 return f.name 27 } 28 29 // Type : 30 func (f field) Type() reflect.Type { 31 return f.t 32 } 33 34 // Index : 35 func (field) Index() []int { 36 return nil 37 } 38 39 // Tag : 40 func (f field) Tag() reflext.StructTag { 41 return reflext.StructTag{} 42 } 43 44 // Parent : 45 func (field) Parent() reflext.StructFielder { 46 return nil 47 } 48 49 // ParentByTraversal : 50 func (field) ParentByTraversal(cb func(reflext.StructFielder) bool) reflext.StructFielder { 51 return nil 52 } 53 54 // Children : 55 func (field) Children() []reflext.StructFielder { 56 return nil 57 } 58 59 // IsNullable : 60 func (f field) IsNullable() bool { 61 return f.null 62 } 63 64 // IsEmbedded : 65 func (field) IsEmbedded() bool { 66 return false 67 } 68 69 var _ reflext.StructFielder = (*field)(nil) 70 71 func TestKey(t *testing.T) { 72 var ( 73 k *Key 74 a bsontype.Type 75 b []byte 76 err error 77 ) 78 79 t.Run("DataType", func(it *testing.T) { 80 k := new(Key) 81 col := k.DataType(nil, field{ 82 name: "Key", 83 t: reflect.TypeOf(k), 84 }) 85 86 require.Equal(it, "Key", col.Name) 87 require.Equal(it, "VARCHAR", col.DataType) 88 require.Equal(it, "VARCHAR(512)", col.Type) 89 require.Equal(it, "latin1", *col.Charset) 90 require.Equal(it, "latin1_bin", *col.Collation) 91 require.True(it, col.Nullable) 92 }) 93 94 t.Run("String and GoString", func(it *testing.T) { 95 k := NameKey("Child", "!@#$%^&*()'dajhdkhas", NameKey("Parent", "{}|askjdhkashy8q,L:\"><<", nil)) 96 97 encodedKey := `Parent,'%7B%7D%7Caskjdhkashy8q%2CL:%22%3E%3C%3C'/Child,'%21@%23$%25%5E&%2A%28%29%27dajhdkhas'` 98 rawStrKey := `Parent,'{}|askjdhkashy8q,L:"><<'/Child,'!@#$%^&*()'dajhdkhas'` 99 require.Equal(it, encodedKey, k.String()) 100 require.Equal(it, rawStrKey, k.GoString()) 101 require.Equal(it, rawStrKey, fmt.Sprintf("%#v", k)) 102 }) 103 104 t.Run("ID", func(it *testing.T) { 105 nk := NameKey("Name", "name-value", nil) 106 require.Equal(it, "name-value", nk.ID()) 107 108 idk := IDKey("Name", 217371238213213, nil) 109 require.Equal(it, "217371238213213", idk.ID()) 110 111 var nilkey *Key 112 require.Equal(it, "", nilkey.ID()) 113 }) 114 115 t.Run("Empty Key", func(it *testing.T) { 116 k := new(Key) 117 require.True(it, k.Incomplete()) 118 require.Equal(it, k, k.Root()) 119 require.Nil(it, k.Parent) 120 }) 121 122 t.Run("ParseKey", func(it *testing.T) { 123 str := `Parent,1288888/Name,'sianloong%40gmail.com'` 124 k, err = ParseKey(str) 125 require.NoError(it, err) 126 require.NotNil(it, k) 127 nk := NameKey("Name", "sianloong@gmail.com", IDKey("Parent", 1288888, nil)) 128 require.Equal(it, nk, k) 129 require.True(it, nk.Equal(k)) 130 }) 131 132 t.Run("Clone", func(it *testing.T) { 133 str := `Parent,1288888/Name,'sianloong'` 134 k, err = ParseKey(str) 135 require.NoError(it, err) 136 require.NotNil(it, k) 137 require.Equal(it, k, k.Clone()) 138 }) 139 140 t.Run("Encode & Decode", func(it *testing.T) { 141 str := `Parent,1288888/Name,'sianloong'` 142 k, err = ParseKey(str) 143 require.NoError(it, err) 144 require.Equal(it, `EgROYW1lIglzaWFubG9vbmcqDBIGUGFyZW50GLjVTg`, k.Encode()) 145 146 var pk *Key 147 pk, err = DecodeKey(k.Encode()) 148 require.NoError(it, err) 149 require.Equal(it, NameKey("Name", "sianloong", IDKey("Parent", 1288888, nil)), pk) 150 }) 151 152 t.Run("Encode & Decode Unicode", func(it *testing.T) { 153 str := `Parent,1288888/Name,'%F0%9F%A4%94%E3%83%A4%E3%83%9E%E3%83%88'` 154 k, err = ParseKey(str) 155 require.NoError(it, err) 156 require.Equal(it, `EgROYW1lIg3wn6SU44Ok44Oe44OIKgwSBlBhcmVudBi41U4`, k.Encode()) 157 158 str = `Parent,1288888/Name,'🤔ヤマト'` 159 k, err = ParseKey(str) 160 require.NoError(it, err) 161 require.Equal(it, `EgROYW1lIg3wn6SU44Ok44Oe44OIKgwSBlBhcmVudBi41U4`, k.Encode()) 162 163 var pk *Key 164 pk, err = DecodeKey(`EgROYW1lIg3wn6SU44Ok44Oe44OIKgwSBlBhcmVudBi41U4`) 165 require.NoError(it, err) 166 require.Equal(it, NameKey("Name", "🤔ヤマト", IDKey("Parent", 1288888, nil)), pk) 167 }) 168 169 t.Run("MarshalerText & UnmarshalText", func(it *testing.T) { 170 pk := IDKey("Parent", 1288888, nil) 171 require.Equal(it, "1288888", pk.ID()) 172 173 b, err = pk.MarshalText() 174 require.NoError(it, err) 175 require.Equal(it, b, []byte(`Parent,1288888`)) 176 177 str := `EgROYW1lIg1zaWFubG9vbmcvQDkwKhISBlBhcmVudBjQ1deb4Mjr0xU` 178 err = pk.UnmarshalText([]byte(str)) 179 require.NoError(it, err) 180 require.Equal(it, "Parent,1560407411636169424/Name,'sianloong%2F@90'", pk.String()) 181 require.Equal(it, str, pk.Encode()) 182 }) 183 184 t.Run("MarshalBSONValue & UnmarshalBSONValue", func(it *testing.T) { 185 186 pk := IDKey("Parent", 1288888, nil) 187 require.Equal(it, "1288888", pk.ID()) 188 189 a, b, err = pk.MarshalBSONValue() 190 require.NoError(it, err) 191 require.Equal(it, bsontype.String, a) 192 193 err = pk.UnmarshalBSONValue(a, b) 194 require.NoError(it, err) 195 }) 196 197 t.Run("JSONB Marshal & Unmarshal", func(it *testing.T) { 198 var nilKey *Key 199 b, err = jsonb.Marshal(nilKey) 200 require.NoError(it, err) 201 require.Equal(t, []byte(`null`), b) 202 203 var o struct { 204 Key *Key 205 } 206 207 ik := new(Key) 208 b, err = json.Marshal(ik) 209 require.NoError(it, err) 210 require.Equal(t, []byte(`null`), b) 211 212 ik2 := new(Key) 213 b, err = jsonb.Marshal(ik2) 214 require.NoError(it, err) 215 require.Equal(t, []byte(`null`), b) 216 217 b, err = jsonb.Marshal(o) 218 require.NoError(it, err) 219 require.Equal(t, []byte(`{"Key":null}`), b) 220 221 pk := IDKey("Parent", 1288888, nil) 222 require.Equal(it, "1288888", pk.ID()) 223 224 b, err = pk.MarshalJSONB() 225 require.NoError(it, err) 226 require.Equal(it, `"Parent,1288888"`, string(b)) 227 228 rk := NameKey("Name", "sianloong", pk) 229 require.NoError(it, err) 230 b, err = rk.MarshalJSONB() 231 require.Equal(it, `"Parent,1288888/Name,'sianloong'"`, string(b)) 232 233 kv := `Parent,1560407411636169424/Name,'sianloong'` 234 b = []byte(strconv.Quote(kv)) 235 err = rk.UnmarshalJSONB(b) 236 require.NoError(it, err) 237 require.Equal(it, kv, rk.String()) 238 239 kv = `Parent,1560407411636169424` 240 b = []byte(strconv.Quote(kv)) 241 k = new(Key) 242 err = k.UnmarshalJSONB(b) 243 require.NoError(it, err) 244 require.Equal(it, kv, k.String()) 245 246 kv = `Parent,'a'` 247 b = []byte(strconv.Quote(kv)) 248 k = new(Key) 249 err = k.UnmarshalJSONB(b) 250 require.NoError(it, err) 251 require.Equal(it, kv, k.String()) 252 253 k = new(Key) 254 err = k.UnmarshalJSONB([]byte("null")) 255 require.NoError(it, err) 256 require.Equal(it, new(Key), k) 257 258 nk := NameKey("Name", "sianloong", pk) 259 b, err = jsonb.Marshal(nk) 260 require.NoError(it, err) 261 require.Equal(it, `"Parent,1560407411636169424/Name,'sianloong'"`, string(b)) 262 263 k2 := new(Key) 264 err = jsonb.Unmarshal(b, k2) 265 require.NoError(it, err) 266 require.Equal(it, nk, k2) 267 268 k3 := new(Key) 269 err = jsonb.Unmarshal([]byte(`null`), k3) 270 require.NoError(it, err) 271 require.Equal(it, &Key{}, k3) 272 }) 273 274 t.Run("JSON Marshal & Unmarshal", func(it *testing.T) { 275 k := NameKey("Name", "sianloong", nil) 276 b := []byte(`"EgROYW1lIglzaWFubG9vbmc"`) 277 binary, err := json.Marshal(k) 278 require.NoError(it, err) 279 require.Equal(it, b, binary) 280 281 var k2 *Key 282 err = json.Unmarshal(binary, &k2) 283 require.NoError(it, err) 284 require.Equal(it, k, k2) 285 286 k3 := new(Key) 287 err = json.Unmarshal([]byte(`null`), k3) 288 require.NoError(it, err) 289 require.Equal(it, &Key{}, k3) 290 }) 291 292 t.Run("driver.Valuer", func(it *testing.T) { 293 k := NameKey("Parent", "hello-world!", nil) 294 v, err := k.Value() 295 require.NoError(it, err) 296 require.Equal(it, `Parent,'hello-world%21'`, v) 297 298 nk := NameKey("Child", "hRTYUI,O88191", k) 299 v, err = nk.Value() 300 require.NoError(it, err) 301 require.Equal(it, `Parent,'hello-world%21'/Child,'hRTYUI%2CO88191'`, v) 302 303 idk := IDKey("Parent", 187239123213, nil) 304 v, err = idk.Value() 305 require.NoError(it, err) 306 require.Equal(it, `Parent,187239123213`, v) 307 308 idck := IDKey("Child", 17288, idk) 309 v, err = idck.Value() 310 require.NoError(it, err) 311 require.Equal(it, `Parent,187239123213/Child,17288`, v) 312 313 mk := NameKey("Mix", "Name-value", idk) 314 v, err = mk.Value() 315 require.NoError(it, err) 316 require.Equal(it, `Parent,187239123213/Mix,'Name-value'`, v) 317 }) 318 319 t.Run("MarshalGQL and UnmarshalGQL", func(it *testing.T) { 320 k := NameKey("Parent", "hello-world!", nil) 321 w := new(bytes.Buffer) 322 k.MarshalGQL(w) 323 require.NoError(it, err) 324 require.Equal(it, `"EgZQYXJlbnQiDGhlbGxvLXdvcmxkIQ"`, w.String()) 325 326 nk := NameKey("Child", "hRTYUI,O88191", k) 327 encoded := `"EgVDaGlsZCINaFJUWVVJLE84ODE5MSoWEgZQYXJlbnQiDGhlbGxvLXdvcmxkIQ"` 328 w.Reset() 329 nk.MarshalGQL(w) 330 require.NoError(it, err) 331 require.Equal(it, encoded, w.String()) 332 333 w.Reset() 334 emptyk := new(Key) 335 emptyk.MarshalGQL(w) 336 require.NoError(it, err) 337 require.Equal(it, `null`, w.String()) 338 339 err = emptyk.UnmarshalGQL(encoded) 340 require.NoError(t, err) 341 require.Equal(t, `Parent,'hello-world%21'/Child,'hRTYUI%2CO88191'`, emptyk.String()) 342 }) 343 344 t.Run("Check Panic", func(it *testing.T) { 345 var ( 346 k Key 347 nilKey *Key 348 nullKey *Key 349 ) 350 351 require.True(it, k.Incomplete()) 352 require.True(it, nilKey.Incomplete()) 353 require.False(it, k.Equal(nilKey)) 354 require.True(it, nilKey.Equal(nullKey)) 355 356 v, err := k.Value() 357 require.NoError(t, err) 358 require.Nil(t, v) 359 360 require.Panics(it, func() { 361 nilKey.String() 362 }) 363 require.Panics(it, func() { 364 nilKey.GoString() 365 }) 366 require.Panics(it, func() { 367 nilKey.MarshalText() 368 }) 369 require.Panics(it, func() { 370 nilKey.MarshalBinary() 371 }) 372 require.Panics(it, func() { 373 nilKey.MarshalJSON() 374 }) 375 require.Panics(it, func() { 376 nilKey.MarshalJSONB() 377 }) 378 require.Panics(it, func() { 379 nilKey.MarshalBSONValue() 380 }) 381 require.Panics(it, func() { 382 nilKey.GobEncode() 383 }) 384 require.Panics(it, func() { 385 nilKey.Encode() 386 }) 387 }) 388 389 nk := NewNameKey("Name", nil) 390 require.NotEmpty(t, nk.NameID) 391 require.Equal(t, "Name", nk.Kind) 392 require.Empty(t, nk.IntID) 393 require.Nil(t, nk.Parent) 394 395 idk := NewIDKey("ID", nil) 396 require.Empty(t, idk.NameID) 397 require.Equal(t, "ID", idk.Kind) 398 require.NotEmpty(t, idk.IntID) 399 require.Nil(t, idk.Parent) 400 }