1 package strfmt
2
3 import (
4 "bytes"
5 "database/sql/driver"
6 "encoding/gob"
7 "fmt"
8 "sync"
9 "testing"
10
11 "github.com/stretchr/testify/assert"
12 "github.com/stretchr/testify/require"
13 "go.mongodb.org/mongo-driver/bson"
14 )
15
16 const testUlid = string("01EYXZVGBHG26MFTG4JWR4K558")
17 const testUlidAlt = string("01EYXZW663G7PYHVSQ8WTMDA67")
18
19 var testUlidOverrideMtx sync.Mutex
20 var testUlidOverrideValMtx sync.Mutex
21
22 func TestFormatULID_Text(t *testing.T) {
23 t.Parallel()
24
25 t.Run("positive", func(t *testing.T) {
26 t.Parallel()
27 ulid, err := ParseULID(testUlid)
28 require.NoError(t, err)
29
30 res, err := ulid.MarshalText()
31 require.NoError(t, err)
32 assert.Equal(t, testUlid, string(res))
33
34 ulid2, _ := ParseULID(testUlidAlt)
35 require.NoError(t, err)
36
37 what := []byte(testUlid)
38 err = ulid2.UnmarshalText(what)
39 require.NoError(t, err)
40 assert.Equal(t, testUlid, ulid2.String())
41 })
42 t.Run("negative", func(t *testing.T) {
43 t.Parallel()
44 ulid, err := ParseULID(testUlid)
45 require.NoError(t, err)
46
47 what := []byte("00000000-0000-0000-0000-000000000000")
48
49 err = ulid.UnmarshalText(what)
50 require.Error(t, err)
51 })
52 }
53
54 func TestFormatULID_BSON(t *testing.T) {
55 t.Parallel()
56 t.Run("positive", func(t *testing.T) {
57 t.Parallel()
58 ulid, _ := ParseULID(testUlid)
59
60 bsonData, err := bson.Marshal(&ulid)
61 require.NoError(t, err)
62
63 var ulidUnmarshaled ULID
64 err = bson.Unmarshal(bsonData, &ulidUnmarshaled)
65 require.NoError(t, err)
66 assert.Equal(t, ulid, ulidUnmarshaled)
67
68
69 m := bson.M{"data": ulid}
70 bsonData, err = bson.Marshal(&m)
71 require.NoError(t, err)
72
73 var mUnmarshaled bson.M
74 err = bson.Unmarshal(bsonData, &mUnmarshaled)
75 require.NoError(t, err)
76
77 data, ok := m["data"].(ULID)
78 assert.True(t, ok)
79 assert.Equal(t, ulid, data)
80 })
81 t.Run("negative", func(t *testing.T) {
82 t.Parallel()
83 uuid := UUID("00000000-0000-0000-0000-000000000000")
84 bsonData, err := bson.Marshal(&uuid)
85 require.NoError(t, err)
86
87 var ulidUnmarshaled ULID
88 err = bson.Unmarshal(bsonData, &ulidUnmarshaled)
89 require.Error(t, err)
90 })
91 }
92
93 func TestFormatULID_JSON(t *testing.T) {
94 t.Parallel()
95 t.Run("positive", func(t *testing.T) {
96 t.Parallel()
97 ulid, err := ParseULID(testUlid)
98 require.NoError(t, err)
99
100 whatStr := fmt.Sprintf(`"%s"`, testUlidAlt)
101 what := []byte(whatStr)
102 err = ulid.UnmarshalJSON(what)
103 require.NoError(t, err)
104 assert.Equal(t, testUlidAlt, ulid.String())
105
106 data, err := ulid.MarshalJSON()
107 require.NoError(t, err)
108 assert.Equal(t, whatStr, string(data))
109 })
110 t.Run("null", func(t *testing.T) {
111 t.Parallel()
112 ulid, err := ParseULID(testUlid)
113 require.NoError(t, err)
114
115 err = ulid.UnmarshalJSON([]byte("null"))
116 require.NoError(t, err)
117 })
118 t.Run("negative", func(t *testing.T) {
119 t.Parallel()
120
121 ulid := NewULIDZero()
122 err := ulid.UnmarshalJSON([]byte("zorg emperor"))
123 require.Error(t, err)
124
125
126 err = ulid.UnmarshalJSON([]byte(`"zorg emperor"`))
127 require.Error(t, err)
128 })
129 }
130
131 func TestFormatULID_Scan(t *testing.T) {
132 t.Parallel()
133 t.Run("db.Scan", func(t *testing.T) {
134 t.Parallel()
135 testUlidOverrideMtx.Lock()
136 defer testUlidOverrideMtx.Unlock()
137
138 srcUlid := testUlidAlt
139
140 ulid, err := ParseULID(testUlid)
141 require.NoError(t, err)
142
143 err = ulid.Scan(srcUlid)
144 require.NoError(t, err)
145 assert.Equal(t, srcUlid, ulid.String())
146
147 ulid, _ = ParseULID(testUlid)
148 err = ulid.Scan([]byte(srcUlid))
149 require.NoError(t, err)
150 assert.Equal(t, srcUlid, ulid.String())
151 })
152 t.Run("db.Scan_Failed", func(t *testing.T) {
153 t.Parallel()
154 testUlidOverrideMtx.Lock()
155 defer testUlidOverrideMtx.Unlock()
156
157 ulid, err := ParseULID(testUlid)
158 zero := NewULIDZero()
159 require.NoError(t, err)
160
161 err = ulid.Scan(nil)
162 require.NoError(t, err)
163 assert.Equal(t, zero, ulid)
164
165 err = ulid.Scan("")
166 require.NoError(t, err)
167 assert.Equal(t, zero, ulid)
168
169 err = ulid.Scan(int64(0))
170 require.Error(t, err)
171
172 err = ulid.Scan(float64(0))
173 require.Error(t, err)
174 })
175 t.Run("db.Value", func(t *testing.T) {
176 t.Parallel()
177 testUlidOverrideValMtx.Lock()
178 defer testUlidOverrideValMtx.Unlock()
179
180 ulid, err := ParseULID(testUlid)
181 require.NoError(t, err)
182
183 val, err := ulid.Value()
184 require.NoError(t, err)
185
186 assert.EqualValues(t, testUlid, val)
187 })
188 t.Run("override.Scan", func(t *testing.T) {
189 t.Parallel()
190 testUlidOverrideMtx.Lock()
191 defer testUlidOverrideMtx.Unlock()
192
193 ulid, err := ParseULID(testUlid)
194 require.NoError(t, err)
195 ulid2, err := ParseULID(testUlidAlt)
196 require.NoError(t, err)
197
198 ULIDScanOverrideFunc = func(raw interface{}) (ULID, error) {
199 u := NewULIDZero()
200 switch x := raw.(type) {
201 case [16]byte:
202 return u, u.ULID.UnmarshalBinary(x[:])
203 case int:
204 return u, fmt.Errorf("cannot sql.Scan() strfmt.ULID from: %#v", raw)
205 }
206 return u, fmt.Errorf("cannot sql.Scan() strfmt.ULID from: %#v", raw)
207 }
208
209
210 bytes := [16]byte(ulid.ULID)
211
212 err = ulid2.Scan(bytes)
213 require.NoError(t, err)
214 assert.Equal(t, ulid2, ulid)
215 assert.Equal(t, ulid2.String(), ulid.String())
216
217
218 err = ulid2.Scan(testUlid)
219 require.Error(t, err)
220
221
222 ULIDScanOverrideFunc = ULIDScanDefaultFunc
223 err = ulid2.Scan(testUlid)
224 require.NoError(t, err)
225 assert.Equal(t, testUlid, ulid2.String())
226 })
227 t.Run("override.Value", func(t *testing.T) {
228 t.Parallel()
229 testUlidOverrideValMtx.Lock()
230 defer testUlidOverrideValMtx.Unlock()
231
232 ulid, err := ParseULID(testUlid)
233 require.NoError(t, err)
234 ulid2, err := ParseULID(testUlid)
235 require.NoError(t, err)
236
237 ULIDValueOverrideFunc = func(u ULID) (driver.Value, error) {
238 bytes := [16]byte(u.ULID)
239 return driver.Value(bytes), nil
240 }
241
242 exp := [16]byte(ulid2.ULID)
243 val, err := ulid.Value()
244 require.NoError(t, err)
245
246 assert.EqualValues(t, exp, val)
247
248
249 ULIDValueOverrideFunc = ULIDValueDefaultFunc
250
251 val, err = ulid.Value()
252 require.NoError(t, err)
253
254 assert.EqualValues(t, testUlid, val)
255 })
256 }
257
258 func TestFormatULID_DeepCopy(t *testing.T) {
259 ulid, err := ParseULID(testUlid)
260 require.NoError(t, err)
261 in := &ulid
262
263 out := new(ULID)
264 in.DeepCopyInto(out)
265 assert.Equal(t, in, out)
266
267 out2 := in.DeepCopy()
268 assert.Equal(t, in, out2)
269
270 var inNil *ULID
271 out3 := inNil.DeepCopy()
272 assert.Nil(t, out3)
273 }
274
275 func TestFormatULID_GobEncoding(t *testing.T) {
276 ulid, err := ParseULID(testUlid)
277 require.NoError(t, err)
278
279 b := bytes.Buffer{}
280 enc := gob.NewEncoder(&b)
281 err = enc.Encode(ulid)
282 require.NoError(t, err)
283 assert.NotEmpty(t, b.Bytes())
284
285 var result ULID
286
287 dec := gob.NewDecoder(&b)
288 err = dec.Decode(&result)
289 require.NoError(t, err)
290 assert.Equal(t, ulid, result)
291 assert.Equal(t, ulid.String(), result.String())
292 }
293
294 func TestFormatULID_NewULID_and_Equal(t *testing.T) {
295 t.Parallel()
296
297 ulid1, err := NewULID()
298 require.NoError(t, err)
299
300 ulid2, err := NewULID()
301 require.NoError(t, err)
302
303
304 assert.True(t, ulid1.Equal(ulid1), "ULID instances should be equal")
305 assert.False(t, ulid1.Equal(ulid2), "ULID instances should not be equal")
306
307 ulidZero := NewULIDZero()
308 ulidZero2 := NewULIDZero()
309 assert.True(t, ulidZero.Equal(ulidZero2), "ULID instances should be equal")
310 }
311
312 func TestIsULID(t *testing.T) {
313 t.Parallel()
314
315 tcases := []struct {
316 ulid string
317 expect bool
318 }{
319 {ulid: "01EYXZVGBHG26MFTG4JWR4K558", expect: true},
320 {ulid: "01EYXZW663G7PYHVSQ8WTMDA67", expect: true},
321 {ulid: "7ZZZZZZZZZ0000000000000000", expect: true},
322 {ulid: "00000000000000000000000000", expect: true},
323 {ulid: "7ZZZZZZZZZZZZZZZZZZZZZZZZZ", expect: true},
324 {ulid: "not-a-ulid", expect: false},
325 {ulid: "8000000000FJ2MMFJ3ATV3XB2C", expect: false},
326 {ulid: "81EYY0NEYJZZZZZZZZZZZZZZZZ", expect: false},
327 {ulid: "7ZZZZZZZZZ000000000000000U", expect: false},
328 {ulid: "7ZZZZZZZZZ000000000000000L", expect: false},
329 {ulid: "7ZZZZZZZZZ000000000000000O", expect: false},
330 {ulid: "7ZZZZZZZZZ000000000000000I", expect: false},
331 }
332 for _, tcase := range tcases {
333 tc := tcase
334 t.Run(fmt.Sprintf("%s:%t", tc.ulid, tc.expect), func(t *testing.T) {
335 t.Parallel()
336 if tc.expect {
337 assert.True(t, IsULID(tc.ulid))
338 } else {
339 assert.False(t, IsULID(tc.ulid))
340 }
341 })
342 }
343
344 }
345
View as plain text