package snowflake import ( "encoding/json" "testing" ) func TestNew(t *testing.T) { s, err := New() if err != nil { t.Fatalf("New() returned error: %v", err) } if s.IsZero() { t.Error("New() returned zero Snowflake") } } func TestNewUnique(t *testing.T) { seen := make(map[string]bool, 1000) for i := 0; i < 1000; i++ { s, err := New() if err != nil { t.Fatalf("New() returned error: %v", err) } str := s.String() if seen[str] { t.Fatalf("duplicate ID generated: %s", str) } seen[str] = true } } func TestIsZero(t *testing.T) { zero := Zero() if !zero.IsZero() { t.Error("Zero Snowflake should be zero") } nonZero, err := New() if err != nil { t.Fatalf("New() returned error: %v", err) } if nonZero.IsZero() { t.Error("New Snowflake should not be zero") } } func TestStringRoundTrip(t *testing.T) { original, err := New() if err != nil { t.Fatalf("New() returned error: %v", err) } str := original.String() parsed, err := FromString(str) if err != nil { t.Fatalf("FromString failed: %v", err) } if parsed != original { t.Errorf("round-trip mismatch: original=%+v, parsed=%+v", original, parsed) } } func TestStringRoundTripMany(t *testing.T) { for i := 0; i < 100; i++ { original, err := New() if err != nil { t.Fatalf("New() returned error: %v", err) } str := original.String() parsed, err := FromString(str) if err != nil { t.Fatalf("iteration %d: FromString failed: %v", i, err) } if parsed != original { t.Fatalf("iteration %d: round-trip mismatch", i) } } } func TestFromStringInvalidChars(t *testing.T) { _, err := FromString("!!invalid!!") if err != ErrInvalidEncoding { t.Errorf("expected ErrInvalidEncoding, got: %v", err) } } func TestFromStringEmpty(t *testing.T) { s, err := FromString("") if err != nil { t.Errorf("unexpected error for empty string: %v", err) } if !s.IsZero() { t.Error("empty string should produce zero Snowflake") } } func TestFromStringTooLong(t *testing.T) { _, err := FromString("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") if err != ErrInvalidEncoding { t.Errorf("expected ErrInvalidEncoding for overflow, got: %v", err) } } func TestHexString(t *testing.T) { s, err := New() if err != nil { t.Fatalf("New() returned error: %v", err) } hex := s.Hex() if len(hex) != IDByteSize*2 { t.Errorf("expected hex length %d, got %d", IDByteSize*2, len(hex)) } for _, c := range hex { if !((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f')) { t.Errorf("invalid hex character: %c", c) } } } func TestZeroString(t *testing.T) { zero := Zero() str := zero.String() if str != "0" { t.Errorf("Zero Snowflake should stringify to %q, got: %q", "0", str) } parsed, err := FromString(str) if err != nil { t.Fatalf("FromString(%q) failed: %v", str, err) } if !parsed.IsZero() { t.Error("FromString(Zero().String()) should round-trip to zero") } } func TestHexRoundTrip(t *testing.T) { original, err := New() if err != nil { t.Fatalf("New() returned error: %v", err) } hex := original.Hex() parsed, err := FromHex(hex) if err != nil { t.Fatalf("FromHex failed: %v", err) } if parsed != original { t.Error("hex round-trip mismatch") } } func TestFromHexInvalid(t *testing.T) { _, err := FromHex("xyz") if err == nil { t.Error("expected error for invalid hex") } } func TestFromHexWrongLength(t *testing.T) { _, err := FromHex("01") if err != ErrInvalidIDLength { t.Errorf("expected ErrInvalidIDLength, got: %v", err) } } func TestMarshalText(t *testing.T) { s, err := New() if err != nil { t.Fatalf("New() returned error: %v", err) } text, err := s.MarshalText() if err != nil { t.Fatalf("MarshalText failed: %v", err) } var decoded Snowflake err = decoded.UnmarshalText(text) if err != nil { t.Fatalf("UnmarshalText failed: %v", err) } if decoded != s { t.Error("text marshal/unmarshal mismatch") } } func TestUnmarshalTextInvalid(t *testing.T) { var s Snowflake err := s.UnmarshalText([]byte("!!!")) if err == nil { t.Error("expected error for invalid text") } } func TestMarshalJSON(t *testing.T) { s, err := New() if err != nil { t.Fatalf("New() returned error: %v", err) } data, err := s.MarshalJSON() if err != nil { t.Fatalf("MarshalJSON failed: %v", err) } var decoded Snowflake err = json.Unmarshal(data, &decoded) if err != nil { t.Fatalf("json.Unmarshal failed: %v", err) } if decoded != s { t.Error("JSON marshal/unmarshal mismatch") } } func TestUnmarshalJSONMissingQuotes(t *testing.T) { var s Snowflake err := s.UnmarshalJSON([]byte(`invalid`)) if err != ErrInvalidEncoding { t.Errorf("expected ErrInvalidEncoding, got: %v", err) } } func TestUnmarshalJSONEmpty(t *testing.T) { var s Snowflake err := s.UnmarshalJSON([]byte(`""`)) if err != nil { t.Fatalf("unexpected error: %v", err) } if !s.IsZero() { t.Error("empty JSON string should produce zero Snowflake") } } func TestUnmarshalJSONInvalidInner(t *testing.T) { var s Snowflake err := s.UnmarshalJSON([]byte(`"!!!"`)) if err != ErrInvalidEncoding { t.Errorf("expected ErrInvalidEncoding for invalid inner content, got: %v", err) } } func TestDriverValue(t *testing.T) { s, err := New() if err != nil { t.Fatalf("New() returned error: %v", err) } val, err := s.Value() if err != nil { t.Fatalf("Value failed: %v", err) } bytes, ok := val.([]byte) if !ok { t.Fatal("Value should return []byte") } if len(bytes) != IDByteSize { t.Errorf("expected byte length %d, got %d", IDByteSize, len(bytes)) } } func TestDriverScan(t *testing.T) { original, err := New() if err != nil { t.Fatalf("New() returned error: %v", err) } bytes := make([]byte, IDByteSize) copy(bytes, original.bytes[:]) var s Snowflake err = s.Scan(bytes) if err != nil { t.Fatalf("Scan failed: %v", err) } if s != original { t.Error("Scan produced mismatched value") } } func TestDriverScanString(t *testing.T) { original, err := New() if err != nil { t.Fatalf("New() returned error: %v", err) } bytes := make([]byte, IDByteSize) copy(bytes, original.bytes[:]) var s Snowflake err = s.Scan(string(bytes)) if err != nil { t.Fatalf("Scan(string) failed: %v", err) } if s != original { t.Error("Scan(string) produced mismatched value") } } func TestDriverScanNil(t *testing.T) { var s Snowflake err := s.Scan(nil) if err != nil { t.Fatalf("Scan(nil) failed: %v", err) } if !s.IsZero() { t.Error("Scan(nil) should produce zero Snowflake") } } func TestDriverScanWrongLength(t *testing.T) { var s Snowflake err := s.Scan([]byte{1, 2, 3}) if err != ErrInvalidIDLength { t.Errorf("expected ErrInvalidIDLength, got: %v", err) } } func TestDriverScanZeroBytes(t *testing.T) { var s Snowflake zeroBytes := make([]byte, IDByteSize) err := s.Scan(zeroBytes) if err != nil { t.Fatalf("unexpected error: %v", err) } if !s.IsZero() { t.Error("Scan with all-zero bytes should produce zero Snowflake") } } func TestDriverScanUnsupportedType(t *testing.T) { var s Snowflake err := s.Scan(42) if err == nil { t.Error("expected error for unsupported type") } } func TestJSONEmbedding(t *testing.T) { type Wrapper struct { Name string `json:"name"` ID Snowflake `json:"id"` Ref *Snowflake `json:"ref,omitempty"` } s, err := New() if err != nil { t.Fatalf("New() returned error: %v", err) } w := Wrapper{ Name: "test", ID: s, Ref: &s, } data, err := json.Marshal(&w) if err != nil { t.Fatalf("marshal failed: %v", err) } var decoded Wrapper err = json.Unmarshal(data, &decoded) if err != nil { t.Fatalf("unmarshal failed: %v", err) } if decoded.ID != s { t.Error("embedded ID mismatch") } if decoded.Ref == nil || *decoded.Ref != s { t.Error("embedded ref mismatch") } }