github.com/artisanhe/tools@v1.0.1-0.20210607022958-19a8fef2eb04/xid/xid_test.go (about)

     1  package xid
     2  
     3  import (
     4  	"encoding/json"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/stretchr/testify/assert"
     9  )
    10  
    11  const strInvalidID = "xid: invalid ID"
    12  
    13  type IDParts struct {
    14  	id        ID
    15  	timestamp int64
    16  	machine   []byte
    17  	pid       uint16
    18  	counter   int32
    19  }
    20  
    21  var IDs = []IDParts{
    22  	IDParts{
    23  		ID{0x4d, 0x88, 0xe1, 0x5b, 0x60, 0xf4, 0x86, 0xe4, 0x28, 0x41, 0x2d, 0xc9},
    24  		1300816219,
    25  		[]byte{0x60, 0xf4, 0x86},
    26  		0xe428,
    27  		4271561,
    28  	},
    29  	IDParts{
    30  		ID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
    31  		0,
    32  		[]byte{0x00, 0x00, 0x00},
    33  		0x0000,
    34  		0,
    35  	},
    36  	IDParts{
    37  		ID{0x00, 0x00, 0x00, 0x00, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0x00, 0x00, 0x01},
    38  		0,
    39  		[]byte{0xaa, 0xbb, 0xcc},
    40  		0xddee,
    41  		1,
    42  	},
    43  }
    44  
    45  func TestIDPartsExtraction(t *testing.T) {
    46  	for i, v := range IDs {
    47  		assert.Equal(t, v.id.Time(), time.Unix(v.timestamp, 0), "#%d timestamp", i)
    48  		assert.Equal(t, v.id.Machine(), v.machine, "#%d machine", i)
    49  		assert.Equal(t, v.id.Pid(), v.pid, "#%d pid", i)
    50  		assert.Equal(t, v.id.Counter(), v.counter, "#%d counter", i)
    51  	}
    52  }
    53  
    54  func TestNew(t *testing.T) {
    55  	// Generate 10 ids
    56  	ids := make([]ID, 10)
    57  	for i := 0; i < 10; i++ {
    58  		ids[i] = New()
    59  	}
    60  	for i := 1; i < 10; i++ {
    61  		prevID := ids[i-1]
    62  		id := ids[i]
    63  		// Test for uniqueness among all other 9 generated ids
    64  		for j, tid := range ids {
    65  			if j != i {
    66  				assert.NotEqual(t, id, tid, "Generated ID is not unique")
    67  			}
    68  		}
    69  		// Check that timestamp was incremented and is within 30 seconds of the previous one
    70  		secs := id.Time().Sub(prevID.Time()).Seconds()
    71  		assert.Equal(t, (secs >= 0 && secs <= 30), true, "Wrong timestamp in generated ID")
    72  		// Check that machine ids are the same
    73  		assert.Equal(t, id.Machine(), prevID.Machine())
    74  		// Check that pids are the same
    75  		assert.Equal(t, id.Pid(), prevID.Pid())
    76  		// Test for proper increment
    77  		delta := int(id.Counter() - prevID.Counter())
    78  		assert.Equal(t, delta, 1, "Wrong increment in generated ID")
    79  	}
    80  }
    81  
    82  func TestIDString(t *testing.T) {
    83  	id := ID{0x4d, 0x88, 0xe1, 0x5b, 0x60, 0xf4, 0x86, 0xe4, 0x28, 0x41, 0x2d, 0xc9}
    84  	assert.Equal(t, "9m4e2mr0ui3e8a215n4g", id.String())
    85  }
    86  
    87  func TestFromString(t *testing.T) {
    88  	id, err := FromString("9m4e2mr0ui3e8a215n4g")
    89  	assert.NoError(t, err)
    90  	assert.Equal(t, ID{0x4d, 0x88, 0xe1, 0x5b, 0x60, 0xf4, 0x86, 0xe4, 0x28, 0x41, 0x2d, 0xc9}, id)
    91  }
    92  
    93  func TestFromStringInvalid(t *testing.T) {
    94  	id, err := FromString("invalid")
    95  	assert.EqualError(t, err, strInvalidID)
    96  	assert.Equal(t, ID{}, id)
    97  }
    98  
    99  type jsonType struct {
   100  	ID  *ID
   101  	Str string
   102  }
   103  
   104  func TestIDJSONMarshaling(t *testing.T) {
   105  	id := ID{0x4d, 0x88, 0xe1, 0x5b, 0x60, 0xf4, 0x86, 0xe4, 0x28, 0x41, 0x2d, 0xc9}
   106  	v := jsonType{ID: &id, Str: "test"}
   107  	data, err := json.Marshal(&v)
   108  	assert.NoError(t, err)
   109  	assert.Equal(t, `{"ID":"9m4e2mr0ui3e8a215n4g","Str":"test"}`, string(data))
   110  }
   111  
   112  func TestIDJSONUnmarshaling(t *testing.T) {
   113  	data := []byte(`{"ID":"9m4e2mr0ui3e8a215n4g","Str":"test"}`)
   114  	v := jsonType{}
   115  	err := json.Unmarshal(data, &v)
   116  	assert.NoError(t, err)
   117  	assert.Equal(t, ID{0x4d, 0x88, 0xe1, 0x5b, 0x60, 0xf4, 0x86, 0xe4, 0x28, 0x41, 0x2d, 0xc9}, *v.ID)
   118  }
   119  
   120  func TestIDJSONUnmarshalingError(t *testing.T) {
   121  	v := jsonType{}
   122  	err := json.Unmarshal([]byte(`{"ID":"9M4E2MR0UI3E8A215N4G"}`), &v)
   123  	assert.EqualError(t, err, strInvalidID)
   124  	err = json.Unmarshal([]byte(`{"ID":"TYjhW2D0huQoQS"}`), &v)
   125  	assert.EqualError(t, err, strInvalidID)
   126  	err = json.Unmarshal([]byte(`{"ID":"TYjhW2D0huQoQS3kdk"}`), &v)
   127  	assert.EqualError(t, err, strInvalidID)
   128  }
   129  
   130  func TestIDDriverValue(t *testing.T) {
   131  	id := ID{0x4d, 0x88, 0xe1, 0x5b, 0x60, 0xf4, 0x86, 0xe4, 0x28, 0x41, 0x2d, 0xc9}
   132  	data, err := id.Value()
   133  	assert.NoError(t, err)
   134  	assert.Equal(t, "9m4e2mr0ui3e8a215n4g", data)
   135  }
   136  
   137  func TestIDDriverScan(t *testing.T) {
   138  	id := ID{}
   139  	err := id.Scan("9m4e2mr0ui3e8a215n4g")
   140  	assert.NoError(t, err)
   141  	assert.Equal(t, ID{0x4d, 0x88, 0xe1, 0x5b, 0x60, 0xf4, 0x86, 0xe4, 0x28, 0x41, 0x2d, 0xc9}, id)
   142  }
   143  
   144  func TestIDDriverScanError(t *testing.T) {
   145  	id := ID{}
   146  	err := id.Scan(0)
   147  	assert.EqualError(t, err, "xid: scanning unsupported type: int")
   148  	err = id.Scan("0")
   149  	assert.EqualError(t, err, strInvalidID)
   150  }
   151  
   152  func TestIDDriverScanByteFromDatabase(t *testing.T) {
   153  	id := ID{}
   154  	bs := []byte("9m4e2mr0ui3e8a215n4g")
   155  	err := id.Scan(bs)
   156  	assert.NoError(t, err)
   157  	assert.Equal(t, ID{0x4d, 0x88, 0xe1, 0x5b, 0x60, 0xf4, 0x86, 0xe4, 0x28, 0x41, 0x2d, 0xc9}, id)
   158  }
   159  
   160  func BenchmarkNew(b *testing.B) {
   161  	b.RunParallel(func(pb *testing.PB) {
   162  		for pb.Next() {
   163  			_ = New()
   164  		}
   165  	})
   166  }
   167  
   168  func BenchmarkNewString(b *testing.B) {
   169  	b.RunParallel(func(pb *testing.PB) {
   170  		for pb.Next() {
   171  			_ = New().String()
   172  		}
   173  	})
   174  }
   175  
   176  func BenchmarkFromString(b *testing.B) {
   177  	b.RunParallel(func(pb *testing.PB) {
   178  		for pb.Next() {
   179  			_, _ = FromString("9m4e2mr0ui3e8a215n4g")
   180  		}
   181  	})
   182  }
   183  
   184  // func BenchmarkUUIDv1(b *testing.B) {
   185  // 	b.RunParallel(func(pb *testing.PB) {
   186  // 		for pb.Next() {
   187  // 			_ = uuid.NewV1().String()
   188  // 		}
   189  // 	})
   190  // }
   191  
   192  // func BenchmarkUUIDv4(b *testing.B) {
   193  // 	b.RunParallel(func(pb *testing.PB) {
   194  // 		for pb.Next() {
   195  // 			_ = uuid.NewV4().String()
   196  // 		}
   197  // 	})
   198  // }