github.com/muyo/sno@v1.2.1/id_test.go (about)

     1  package sno
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"reflect"
     7  	"sync/atomic"
     8  	"testing"
     9  	"time"
    10  )
    11  
    12  func TestID_Time(t *testing.T) {
    13  	tn := time.Now()
    14  	id := New(255)
    15  
    16  	// As we prune the fraction, actual cmp needs to be adjusted. This *may* also fail
    17  	// in the rare condition that a new timeframe started between time.Now() and New()
    18  	// since we're not using a deterministic time source currently.
    19  	expected := tn.UnixNano() / TimeUnit
    20  	actual := id.Time().UnixNano() / TimeUnit
    21  
    22  	if actual != expected {
    23  		t.Errorf("expected [%v], got [%v]", expected, actual)
    24  	}
    25  
    26  	id = NewWithTime(255, tn)
    27  	actual = id.Time().UnixNano() / TimeUnit
    28  
    29  	if actual != expected {
    30  		t.Errorf("expected [%v], got [%v]", expected, actual)
    31  	}
    32  }
    33  
    34  func TestID_Timestamp(t *testing.T) {
    35  	tn := time.Now()
    36  	id := New(255)
    37  
    38  	expected := tn.UnixNano() / TimeUnit * TimeUnit // Drop precision for the comparison.
    39  	actual := id.Timestamp()
    40  
    41  	if actual != expected {
    42  		t.Errorf("expected [%v], got [%v]", expected, actual)
    43  	}
    44  
    45  	id = NewWithTime(255, tn)
    46  	actual = id.Timestamp()
    47  
    48  	if actual != expected {
    49  		t.Errorf("expected [%v], got [%v]", expected, actual)
    50  	}
    51  }
    52  
    53  func TestID_Meta(t *testing.T) {
    54  	var expected byte = 255
    55  	id := New(expected)
    56  	actual := id.Meta()
    57  
    58  	if actual != expected {
    59  		t.Errorf("expected [%v], got [%v]", expected, actual)
    60  	}
    61  }
    62  
    63  func TestID_Partition(t *testing.T) {
    64  	expected := generator.Partition()
    65  	actual := generator.New(255).Partition()
    66  
    67  	if actual != expected {
    68  		t.Errorf("expected [%v], got [%v]", expected, actual)
    69  	}
    70  }
    71  
    72  func TestID_Sequence(t *testing.T) {
    73  	expected := atomic.LoadUint32(&generator.seq) + 1
    74  	actual := generator.New(255).Sequence()
    75  
    76  	if actual != uint16(expected) {
    77  		t.Errorf("expected [%v], got [%v]", expected, actual)
    78  	}
    79  }
    80  
    81  func TestID_String(t *testing.T) {
    82  	src := ID{78, 111, 33, 96, 160, 255, 154, 10, 16, 51}
    83  	expected := "brpk4q72xwf2m63l"
    84  	actual := src.String()
    85  
    86  	if actual != expected {
    87  		t.Errorf("expected [%s], got [%s]", expected, actual)
    88  	}
    89  }
    90  
    91  func TestID_Bytes(t *testing.T) {
    92  	src := ID{78, 111, 33, 96, 160, 255, 154, 10, 16, 51}
    93  	expected := make([]byte, SizeBinary)
    94  	copy(expected, src[:])
    95  
    96  	actual := src.Bytes()
    97  	if !bytes.Equal(actual, expected) {
    98  		t.Errorf("expected [%s], got [%s]", expected, actual)
    99  	}
   100  
   101  	actual[SizeBinary-1]++
   102  	if bytes.Equal(expected, actual) {
   103  		t.Error("returned a reference to underlying array")
   104  	}
   105  }
   106  
   107  func TestID_MarshalText(t *testing.T) {
   108  	src := ID{78, 111, 33, 96, 160, 255, 154, 10, 16, 51}
   109  	expected := []byte("brpk4q72xwf2m63l")
   110  
   111  	actual, err := src.MarshalText()
   112  	if err != nil {
   113  		t.Fatal(err)
   114  	}
   115  
   116  	if !bytes.Equal(actual, expected) {
   117  		t.Errorf("expected [%s], got [%s]", expected, actual)
   118  	}
   119  }
   120  
   121  func TestID_UnmarshalText_Valid(t *testing.T) {
   122  	actual := ID{}
   123  	expected := ID{78, 111, 33, 96, 160, 255, 154, 10, 16, 51}
   124  
   125  	if err := actual.UnmarshalText([]byte("brpk4q72xwf2m63l")); err != nil {
   126  		t.Fatal(err)
   127  	}
   128  
   129  	if actual != expected {
   130  		t.Errorf("expected [%s], got [%s]", expected, actual)
   131  	}
   132  }
   133  
   134  func TestID_UnmarshalText_Invalid(t *testing.T) {
   135  	id := ID{}
   136  	err := id.UnmarshalText([]byte("012brpk4q72xwf2m63l1245453gfdgxz"))
   137  
   138  	if _, ok := err.(*InvalidDataSizeError); !ok {
   139  		t.Errorf("expected error with type [%T], got [%T]", &InvalidDataSizeError{}, err)
   140  	}
   141  }
   142  
   143  func TestID_MarshalJSON_Valid(t *testing.T) {
   144  	src := ID{78, 111, 33, 96, 160, 255, 154, 10, 16, 51}
   145  	expected := []byte("\"brpk4q72xwf2m63l\"")
   146  
   147  	actual, err := src.MarshalJSON()
   148  	if err != nil {
   149  		t.Fatal(err)
   150  	}
   151  
   152  	if !bytes.Equal(actual, expected) {
   153  		t.Errorf("expected [%s], got [%s]", expected, actual)
   154  	}
   155  }
   156  
   157  func TestID_MarshalJSON_Null(t *testing.T) {
   158  	src := ID{}
   159  	expected := []byte("null")
   160  	actual, err := src.MarshalJSON()
   161  	if err != nil {
   162  		t.Fatal(err)
   163  	}
   164  
   165  	if !bytes.Equal(actual, expected) {
   166  		t.Errorf("expected [%s], got [%s]", expected, actual)
   167  	}
   168  }
   169  
   170  func TestID_UnmarshalJSON_Valid(t *testing.T) {
   171  	actual := ID{}
   172  	expected := ID{78, 111, 33, 96, 160, 255, 154, 10, 16, 51}
   173  
   174  	if err := actual.UnmarshalJSON([]byte("\"brpk4q72xwf2m63l\"")); err != nil {
   175  		t.Fatal(err)
   176  	}
   177  
   178  	if actual != expected {
   179  		t.Errorf("expected [%s], got [%s]", expected, actual)
   180  	}
   181  }
   182  
   183  func TestID_UnmarshalJSON_Invalid(t *testing.T) {
   184  	id := ID{}
   185  	err := id.UnmarshalJSON([]byte("\"012brpk4q72xwf2m63l1245453gfdgxz\""))
   186  
   187  	if _, ok := err.(*InvalidDataSizeError); !ok {
   188  		t.Errorf("expected error with type [%T], got [%T]", &InvalidDataSizeError{}, err)
   189  	}
   190  
   191  	if err != nil && err.Error() != errInvalidDataSizeMsg {
   192  		t.Errorf("expected error [%s], got [%s]", errInvalidDataSizeMsg, err.Error())
   193  	}
   194  }
   195  
   196  func TestID_UnmarshalJSON_Null(t *testing.T) {
   197  	actual := ID{}
   198  	expected := ID{}
   199  
   200  	if err := actual.UnmarshalJSON([]byte("null")); err != nil {
   201  		t.Fatal(err)
   202  	}
   203  
   204  	if actual != expected {
   205  		t.Errorf("expected [%s], got [%s]", expected, actual)
   206  	}
   207  }
   208  
   209  func TestID_IsZero(t *testing.T) {
   210  	for _, c := range []struct {
   211  		id   ID
   212  		want bool
   213  	}{
   214  		{
   215  			id:   New(255),
   216  			want: false,
   217  		},
   218  		{
   219  			id:   ID{},
   220  			want: true,
   221  		},
   222  	} {
   223  		if actual, expected := c.id.IsZero(), c.want; actual != expected {
   224  			t.Errorf("expected [%v], got [%v]", expected, actual)
   225  		}
   226  	}
   227  }
   228  
   229  func TestID_Compare(t *testing.T) {
   230  	a := New(100)
   231  	l := a
   232  	l[5]++
   233  	e := a
   234  	b := a
   235  	b[5]--
   236  
   237  	if actual := a.Compare(l); actual != -1 {
   238  		t.Errorf("expected [-1], got [%d]", actual)
   239  	}
   240  
   241  	if actual := a.Compare(e); actual != 0 {
   242  		t.Errorf("expected [0], got [%d]", actual)
   243  	}
   244  
   245  	if actual := a.Compare(b); actual != 1 {
   246  		t.Errorf("expected [1], got [%d]", actual)
   247  	}
   248  }
   249  
   250  func TestID_Value(t *testing.T) {
   251  	src := ID{78, 111, 33, 96, 160, 255, 154, 10, 16, 51}
   252  	expected := make([]byte, SizeBinary)
   253  	copy(expected, src[:])
   254  
   255  	v, err := src.Value()
   256  	if err != nil {
   257  		t.Errorf("got unexpected error: %s", err)
   258  	}
   259  
   260  	actual, ok := v.([]byte)
   261  	if !ok {
   262  		t.Errorf("expected type [%T], got [%T]", expected, actual)
   263  	}
   264  
   265  	if !bytes.Equal(actual, expected) {
   266  		t.Errorf("expected [%s], got [%s]", expected, actual)
   267  	}
   268  
   269  	actual[SizeBinary-1]++
   270  	if bytes.Equal(expected, actual) {
   271  		t.Error("returned a reference to underlying array")
   272  	}
   273  }
   274  
   275  func TestID_Scan(t *testing.T) {
   276  	id := New(255)
   277  
   278  	for _, c := range []struct {
   279  		name   string
   280  		in     interface{}
   281  		out    ID
   282  		err    error
   283  		errMsg string
   284  	}{
   285  		{"nil", nil, ID{}, nil, ""},
   286  		{"bytes-valid", id[:], id, nil, ""},
   287  		{"bytes-invalid", make([]byte, 3), zero, &InvalidDataSizeError{Size: 3}, errInvalidDataSizeMsg},
   288  		{"bytes-zero", []byte{}, zero, nil, ""},
   289  		{"string-valid", id.String(), id, nil, ""},
   290  		{"string-invalid", "123", zero, &InvalidDataSizeError{Size: 3}, errInvalidDataSizeMsg},
   291  		{"string-zero", "", zero, nil, ""},
   292  		{"invalid", 69, ID{}, &InvalidTypeError{Value: 69}, fmt.Sprintf(errInvalidTypeFmt, 69)},
   293  	} {
   294  		c := c
   295  		t.Run(c.name, func(t *testing.T) {
   296  			t.Parallel()
   297  
   298  			var out ID
   299  			err := out.Scan(c.in)
   300  
   301  			if actual, expected := out, c.out; actual != expected {
   302  				t.Errorf("expected [%s], got [%s]", expected, actual)
   303  			}
   304  
   305  			if err != nil && c.err == nil {
   306  				t.Errorf("got unexpected error: %s", err)
   307  			} else if actual, expected := reflect.TypeOf(err), reflect.TypeOf(c.err); actual != expected {
   308  				t.Errorf("expected error type [%s], got [%s]", expected, actual)
   309  			} else if err != nil && c.errMsg != "" && err.Error() != c.errMsg {
   310  				t.Errorf("expected error message [%s], got [%s]", c.errMsg, err.Error())
   311  			}
   312  		})
   313  	}
   314  }