summaryrefslogtreecommitdiffstats
path: root/go/snowflake_test.go
diff options
context:
space:
mode:
authorEthan Werner <mail@ethanwerner.com>2026-08-07 17:17:32 +0400
committerEthan Werner <mail@ethanwerner.com>2026-08-07 17:17:32 +0400
commite4e84c7aad9fb887150ba1fcfaf64463765419c9 (patch)
treecdafa934aa61d8b646435d2a7b4ed0d7ac5c9f55 /go/snowflake_test.go
parente0f9cc69f9f7f524610d65b288eecdbf2ad958d6 (diff)
javascript portHEADmaster
Diffstat (limited to 'go/snowflake_test.go')
-rw-r--r--go/snowflake_test.go340
1 files changed, 340 insertions, 0 deletions
diff --git a/go/snowflake_test.go b/go/snowflake_test.go
new file mode 100644
index 0000000..e69644c
--- /dev/null
+++ b/go/snowflake_test.go
@@ -0,0 +1,340 @@
+package snowflake
+
+import (
+ "encoding/json"
+ "testing"
+)
+
+func TestNew(t *testing.T) {
+ s := New()
+ 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 := New()
+
+ 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 := New()
+ if nonZero.IsZero() {
+ t.Error("New Snowflake should not be zero")
+ }
+}
+
+func TestStringRoundTrip(t *testing.T) {
+ original := New()
+ 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 := New()
+
+ 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 := New()
+ 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 := New()
+ 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 := New()
+ 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 := New()
+ 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 := New()
+ 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 := New()
+ bytes := make([]byte, IDByteSize)
+ copy(bytes, original.bytes[:])
+
+ var s Snowflake
+ if err := s.Scan(bytes); err != nil {
+ t.Fatalf("Scan failed: %v", err)
+ }
+
+ if s != original {
+ t.Error("Scan produced mismatched value")
+ }
+}
+
+func TestDriverScanString(t *testing.T) {
+ original := New()
+ bytes := make([]byte, IDByteSize)
+ copy(bytes, original.bytes[:])
+
+ var s Snowflake
+ if err := s.Scan(string(bytes)); 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 := New()
+ 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")
+ }
+}