-
Notifications
You must be signed in to change notification settings - Fork 378
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Generate V6 from custom time (#172)
* Add NewV6WithTime * Refactor generateV6 * fix NewV6WithTime doc comment * fix: remove fmt.Println from test --------- Co-authored-by: nicumicle <[email protected]>
- Loading branch information
Showing
4 changed files
with
170 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package uuid | ||
|
||
import ( | ||
"testing" | ||
"time" | ||
) | ||
|
||
func TestGetTime(t *testing.T) { | ||
now := time.Now() | ||
tt := map[string]struct { | ||
input func() *time.Time | ||
expectedTime int64 | ||
}{ | ||
"it should return the current time": { | ||
input: func() *time.Time { | ||
return nil | ||
}, | ||
expectedTime: now.Unix(), | ||
}, | ||
"it should return the provided time": { | ||
input: func() *time.Time { | ||
parsed, err := time.Parse(time.RFC3339, "2024-10-15T09:32:23Z") | ||
if err != nil { | ||
t.Errorf("timeParse unexpected error: %v", err) | ||
} | ||
return &parsed | ||
}, | ||
expectedTime: 1728984743, | ||
}, | ||
} | ||
|
||
for name, tc := range tt { | ||
t.Run(name, func(t *testing.T) { | ||
result, _, err := getTime(tc.input()) | ||
if err != nil { | ||
t.Errorf("getTime unexpected error: %v", err) | ||
} | ||
sec, _ := result.UnixTime() | ||
if sec != tc.expectedTime { | ||
t.Errorf("expected %v, got %v", tc.expectedTime, result) | ||
} | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
package uuid | ||
|
||
import ( | ||
"testing" | ||
"time" | ||
) | ||
|
||
func TestNewV6WithTime(t *testing.T) { | ||
testCases := map[string]string{ | ||
"test with current date": time.Now().Format(time.RFC3339), // now | ||
"test with past date": time.Now().Add(-1 * time.Hour * 24 * 365).Format(time.RFC3339), // 1 year ago | ||
"test with future date": time.Now().Add(time.Hour * 24 * 365).Format(time.RFC3339), // 1 year from now | ||
"test with different timezone": "2021-09-01T12:00:00+04:00", | ||
"test with negative timezone": "2021-09-01T12:00:00-12:00", | ||
"test with future date in different timezone": "2124-09-23T12:43:30+09:00", | ||
} | ||
|
||
for testName, inputTime := range testCases { | ||
t.Run(testName, func(t *testing.T) { | ||
customTime, err := time.Parse(time.RFC3339, inputTime) | ||
if err != nil { | ||
t.Errorf("time.Parse returned unexpected error %v", err) | ||
} | ||
id, err := NewV6WithTime(&customTime) | ||
if err != nil { | ||
t.Errorf("NewV6WithTime returned unexpected error %v", err) | ||
} | ||
|
||
if id.Version() != 6 { | ||
t.Errorf("got %d, want version 6", id.Version()) | ||
} | ||
unixTime := time.Unix(id.Time().UnixTime()) | ||
// Compare the times in UTC format, since the input time might have different timezone, | ||
// and the result is always in system timezone | ||
if customTime.UTC().Format(time.RFC3339) != unixTime.UTC().Format(time.RFC3339) { | ||
t.Errorf("got %s, want %s", unixTime.Format(time.RFC3339), customTime.Format(time.RFC3339)) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
func TestNewV6FromTimeGeneratesUniqueUUIDs(t *testing.T) { | ||
now := time.Now() | ||
ids := make([]string, 0) | ||
runs := 26000 | ||
|
||
for i := 0; i < runs; i++ { | ||
now = now.Add(time.Nanosecond) // Without this line, we can generate only 16384 UUIDs for the same timestamp | ||
id, err := NewV6WithTime(&now) | ||
if err != nil { | ||
t.Errorf("NewV6WithTime returned unexpected error %v", err) | ||
} | ||
if id.Version() != 6 { | ||
t.Errorf("got %d, want version 6", id.Version()) | ||
} | ||
|
||
// Make sure we add only unique values | ||
if !contains(t, ids, id.String()) { | ||
ids = append(ids, id.String()) | ||
} | ||
} | ||
|
||
// Check we added all the UIDs | ||
if len(ids) != runs { | ||
t.Errorf("got %d UUIDs, want %d", len(ids), runs) | ||
} | ||
} | ||
|
||
func BenchmarkNewV6WithTime(b *testing.B) { | ||
b.RunParallel(func(pb *testing.PB) { | ||
for pb.Next() { | ||
now := time.Now() | ||
_, err := NewV6WithTime(&now) | ||
if err != nil { | ||
b.Fatal(err) | ||
} | ||
} | ||
}) | ||
} | ||
|
||
func contains(t *testing.T, arr []string, str string) bool { | ||
t.Helper() | ||
|
||
for _, a := range arr { | ||
if a == str { | ||
return true | ||
} | ||
} | ||
|
||
return false | ||
} |