1// This package provides immutable UUID structs and the functions
2// NewV3, NewV4, NewV5 and Parse() for generating versions 3, 4
3// and 5 UUIDs as specified in RFC 4122.
4//
5// Copyright (C) 2011 by Krzysztof Kowalik <chris@nu7hat.ch>
6package uuid
7
8import (
9	"regexp"
10	"testing"
11)
12
13const format = "^[a-z0-9]{8}-[a-z0-9]{4}-[1-5][a-z0-9]{3}-[a-z0-9]{4}-[a-z0-9]{12}$"
14
15func TestParse(t *testing.T) {
16	_, err := Parse([]byte{1, 2, 3, 4, 5})
17	if err == nil {
18		t.Errorf("Expected error due to invalid UUID sequence")
19	}
20	base, _ := NewV4()
21	u, err := Parse(base[:])
22	if err != nil {
23		t.Errorf("Expected to parse UUID sequence without problems")
24		return
25	}
26	if u.String() != base.String() {
27		t.Errorf("Expected parsed UUID to be the same as base, %s != %s", u.String(), base.String())
28	}
29}
30
31func TestParseString(t *testing.T) {
32	_, err := ParseHex("foo")
33	if err == nil {
34		t.Errorf("Expected error due to invalid UUID string")
35	}
36	base, _ := NewV4()
37	u, err := ParseHex(base.String())
38	if err != nil {
39		t.Errorf("Expected to parse UUID sequence without problems")
40		return
41	}
42	if u.String() != base.String() {
43		t.Errorf("Expected parsed UUID to be the same as base, %s != %s", u.String(), base.String())
44	}
45}
46
47func TestNewV3(t *testing.T) {
48	u, err := NewV3(NamespaceURL, []byte("golang.org"))
49	if err != nil {
50		t.Errorf("Expected to generate UUID without problems, error thrown: %d", err.Error())
51		return
52	}
53	if u.Version() != 3 {
54		t.Errorf("Expected to generate UUIDv3, given %d", u.Version())
55	}
56	if u.Variant() != ReservedRFC4122 {
57		t.Errorf("Expected to generate UUIDv3 RFC4122 variant, given %x", u.Variant())
58	}
59	re := regexp.MustCompile(format)
60	if !re.MatchString(u.String()) {
61		t.Errorf("Expected string representation to be valid, given %s", u.String())
62	}
63	u2, _ := NewV3(NamespaceURL, []byte("golang.org"))
64	if u2.String() != u.String() {
65		t.Errorf("Expected UUIDs generated of the same namespace and name to be the same")
66	}
67	u3, _ := NewV3(NamespaceDNS, []byte("golang.org"))
68	if u3.String() == u.String() {
69		t.Errorf("Expected UUIDs generated of different namespace and the same name to be different")
70	}
71	u4, _ := NewV3(NamespaceURL, []byte("code.google.com"))
72	if u4.String() == u.String() {
73		t.Errorf("Expected UUIDs generated of the same namespace and different names to be different")
74	}
75}
76
77func TestNewV4(t *testing.T) {
78	u, err := NewV4()
79	if err != nil {
80		t.Errorf("Expected to generate UUID without problems, error thrown: %s", err.Error())
81		return
82	}
83	if u.Version() != 4 {
84		t.Errorf("Expected to generate UUIDv4, given %d", u.Version())
85	}
86	if u.Variant() != ReservedRFC4122 {
87		t.Errorf("Expected to generate UUIDv4 RFC4122 variant, given %x", u.Variant())
88	}
89	re := regexp.MustCompile(format)
90	if !re.MatchString(u.String()) {
91		t.Errorf("Expected string representation to be valid, given %s", u.String())
92	}
93}
94
95func TestNewV5(t *testing.T) {
96	u, err := NewV5(NamespaceURL, []byte("golang.org"))
97	if err != nil {
98		t.Errorf("Expected to generate UUID without problems, error thrown: %d", err.Error())
99		return
100	}
101	if u.Version() != 5 {
102		t.Errorf("Expected to generate UUIDv5, given %d", u.Version())
103	}
104	if u.Variant() != ReservedRFC4122 {
105		t.Errorf("Expected to generate UUIDv5 RFC4122 variant, given %x", u.Variant())
106	}
107	re := regexp.MustCompile(format)
108	if !re.MatchString(u.String()) {
109		t.Errorf("Expected string representation to be valid, given %s", u.String())
110	}
111	u2, _ := NewV5(NamespaceURL, []byte("golang.org"))
112	if u2.String() != u.String() {
113		t.Errorf("Expected UUIDs generated of the same namespace and name to be the same")
114	}
115	u3, _ := NewV5(NamespaceDNS, []byte("golang.org"))
116	if u3.String() == u.String() {
117		t.Errorf("Expected UUIDs generated of different namespace and the same name to be different")
118	}
119	u4, _ := NewV5(NamespaceURL, []byte("code.google.com"))
120	if u4.String() == u.String() {
121		t.Errorf("Expected UUIDs generated of the same namespace and different names to be different")
122	}
123}
124
125func BenchmarkParseHex(b *testing.B) {
126	s := "f3593cff-ee92-40df-4086-87825b523f13"
127	for i := 0; i < b.N; i++ {
128		_, err := ParseHex(s)
129		if err != nil {
130			b.Fatal(err)
131		}
132	}
133	b.StopTimer()
134	b.ReportAllocs()
135}
136