| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 |
- package id
- import (
- "strings"
- "testing"
- "time"
- )
- // TestNewCanonicalUserID 验证 ULID 生成基本性质(26 位、Crockford、可解码)。
- func TestNewCanonicalUserID(t *testing.T) {
- uid, err := NewCanonicalUserID()
- if err != nil {
- t.Fatalf("NewCanonicalUserID 失败: %v", err)
- }
- if len(uid) != Length {
- t.Fatalf("ULID 长度应为 %d,得 %d(%q)", Length, len(uid), uid)
- }
- if !Validate(uid) {
- t.Fatalf("生成的 ULID 应通过 Validate:%q", uid)
- }
- }
- // TestNewCanonicalUserIDAt 验证指定时间戳 + 时间有序性(前 48bit 毫秒时间戳)。
- func TestNewCanonicalUserIDAt(t *testing.T) {
- base := time.Date(2026, 11, 7, 10, 0, 0, 0, time.UTC)
- uidA, err := NewCanonicalUserIDAt(base)
- if err != nil {
- t.Fatalf("NewCanonicalUserIDAt 失败: %v", err)
- }
- uidB, err := NewCanonicalUserIDAt(base.Add(2 * time.Second))
- if err != nil {
- t.Fatalf("NewCanonicalUserIDAt(+2s) 失败: %v", err)
- }
- // 时间戳后移 → ULID 字典序应更大(前 48bit 时间戳递增)
- if !(uidA < uidB) {
- t.Errorf("时间有序的 ULID 应满足 uidA(%s) < uidB(%s)", uidA, uidB)
- }
- }
- // TestValidate 校验合法/非法 ULID。
- func TestValidate(t *testing.T) {
- uid, _ := NewCanonicalUserID()
- cases := []struct {
- in string
- want bool
- }{
- {uid, true}, // 合法(新生成)
- {strings.ToLower(uid), false}, // 小写非法(统一大写)
- {"01GAQF0Z6C1V9Y3E5H7K2M8B4T", true}, // 标准样例
- {"abc", false}, // 长度不符
- {"", false}, // 空
- {"01GAQF0Z6C1V9Y3E5H7K2M8B4I", false}, // 含 I(Crockford 剔除)
- {"01GAQF0Z6C1V9Y3E5H7K2M8B4L", false}, // 含 L
- {"01GAQF0Z6C1V9Y3E5H7K2M8B4O", false}, // 含 O
- {"01GAQF0Z6C1V9Y3E5H7K2M8B4U", false}, // 含 U
- {"01GAQF0Z6C1V9Y3E5H7K2M8B4T0", false}, // 27 位(长度)
- }
- for i, c := range cases {
- if got := Validate(c.in); got != c.want {
- t.Errorf("case %d: Validate(%q)=%v, want %v", i, c.in, got, c.want)
- }
- }
- }
- // TestNewCanonicalUserIDUniqueness 验证并发/批量生成的唯一性(80bit 随机熵)。
- func TestNewCanonicalUserIDUniqueness(t *testing.T) {
- seen := make(map[string]struct{}, 1000)
- // 同一毫秒内批量生成(随机部分保证唯一)
- fixed := time.Date(2026, 11, 7, 8, 0, 0, 0, time.UTC)
- for i := 0; i < 1000; i++ {
- uid, err := NewCanonicalUserIDAt(fixed)
- if err != nil {
- t.Fatalf("第 %d 次生成失败: %v", i, err)
- }
- if _, dup := seen[uid]; dup {
- t.Fatalf("第 %d 次生成重复 ULID:%s(随机熵不足)", i, uid)
- }
- seen[uid] = struct{}{}
- }
- }
|