ulid/ulid_test.go

219 lines
4.5 KiB
Go

package ulid
import (
"fmt"
"io"
"log"
"math/rand"
"testing"
"time"
)
func TestGetMSBytes(t *testing.T) {
runAll := true
type testData struct {
TestName string
RunIt bool
Time time.Time
Expected []byte
Err bool
}
tests := []testData{
{
TestName: "normal time",
RunIt: false || runAll,
Time: time.Date(2024, 02, 16, 14, 02, 15, 17, time.UTC),
Expected: []byte{0x01, 0x8D, 0xB2, 0x39, 0x96, 0x58},
Err: false,
},
{
TestName: "zero time",
RunIt: false || runAll,
Time: time.Time{}, // zero time overflows when using Unix epoch
Expected: []byte{},
Err: true,
},
{
TestName: "max time",
RunIt: false || runAll,
Time: time.UnixMilli(1 << 48),
Expected: []byte{},
Err: true,
},
{
TestName: "max time minus 1",
RunIt: false || runAll,
Time: time.UnixMilli(int64(1<<48) - 1),
Expected: []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
Err: false,
},
}
for _, test := range tests {
t.Run(test.TestName, func(t *testing.T) {
if !test.RunIt {
t.SkipNow()
}
output, err := GetMSBytes(test.Time)
if test.Err {
if err == nil {
t.Errorf("expected an error")
}
} else {
errMsg := fmt.Sprintf("expected: %X, received %X", test.Expected, output)
if len(test.Expected) != len(output) {
t.Fatal(errMsg)
}
for i, b := range test.Expected {
if b != output[i] {
t.Error(errMsg)
}
}
}
})
}
}
func TestNewULID(t *testing.T) {
runAll := true
type testData struct {
TestName string
RunIt bool
Time time.Time
Entropy io.Reader
Expected []byte
Err bool
}
tests := []testData{
{
TestName: "nil entropy",
RunIt: false || runAll,
Time: time.Time{},
Entropy: nil,
Expected: nil,
Err: true,
},
{
TestName: "Unix zero time",
RunIt: false || runAll,
Time: time.Unix(0, 0),
Entropy: rand.New(rand.NewSource(0)),
Expected: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x94, 0xFD, 0xC2, 0xFA, 0x2F, 0xFC, 0xC0, 0x41, 0xD3},
Err: false,
},
{
TestName: "time overflow",
RunIt: false || runAll,
Time: time.Time{}, // zero time overflows when using Unix epoch time
Entropy: rand.New(rand.NewSource(0)),
Expected: nil,
Err: true,
},
{
TestName: "seed 0, real time",
RunIt: false || runAll,
Time: time.Date(2024, 02, 16, 14, 02, 15, 17, time.UTC),
Entropy: rand.New(rand.NewSource(0)),
Expected: []byte{0x01, 0x8D, 0xB2, 0x39, 0x96, 0x58, 0x01, 0x94, 0xFD, 0xC2, 0xFA, 0x2F, 0xFC, 0xC0, 0x41, 0xD3},
Err: false,
},
}
for _, test := range tests {
t.Run(test.TestName, func(t *testing.T) {
if !test.RunIt {
t.SkipNow()
}
output, err := NewULID(test.Time, test.Entropy)
if test.Err {
if err == nil {
t.Errorf("expected an error")
}
} else {
errMsg := fmt.Sprintf("expected: %X, received %X", test.Expected, output)
if len(test.Expected) != len(output) {
t.Fatal(errMsg)
}
for i, b := range test.Expected {
if b != output[i] {
t.Fatal(errMsg)
}
}
}
})
}
}
func TestULIDString(t *testing.T) {
runAll := true
type testData struct {
TestName string
RunIt bool
Time time.Time
Entropy io.Reader
Expected string
Err bool
}
tests := []testData{
{
TestName: "nil entropy",
RunIt: false || runAll,
Time: time.Time{},
Entropy: nil,
Expected: "",
Err: true,
},
{
TestName: "Unix zero time",
RunIt: false || runAll,
Time: time.Unix(0, 0),
Entropy: rand.New(rand.NewSource(0)),
Expected: "000000000006AFVGQT5ZYC0GEK",
Err: false,
},
{
TestName: "time overflow",
RunIt: false || runAll,
Time: time.Time{}, // zero time overflows when using Unix epoch time
Entropy: rand.New(rand.NewSource(0)),
Expected: "",
Err: true,
},
{
TestName: "seed 0, real time",
RunIt: false || runAll,
Time: time.Date(2024, 02, 16, 14, 02, 15, 17, time.UTC),
Entropy: rand.New(rand.NewSource(0)),
Expected: "01HPS3K5JR06AFVGQT5ZYC0GEK",
Err: false,
},
}
for _, test := range tests {
t.Run(test.TestName, func(t *testing.T) {
if !test.RunIt {
t.SkipNow()
}
output, err := NewULIDString(test.Time, test.Entropy)
if test.Err {
if err == nil {
t.Errorf("expected an error")
}
} else {
if test.Expected != output {
log.Fatalf("expected: %s, received %s", test.Expected, output)
}
}
})
}
}