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  }