github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/util/uuid/sql_test.go (about) 1 // Copyright 2019 The Cockroach Authors. 2 // 3 // Use of this software is governed by the Business Source License 4 // included in the file licenses/BSL.txt. 5 // 6 // As of the Change Date specified in that file, in accordance with 7 // the Business Source License, use of this software will be governed 8 // by the Apache License, Version 2.0, included in the file 9 // licenses/APL.txt. 10 11 // Copyright (C) 2013-2018 by Maxim Bublis <b@codemonkey.ru> 12 // Use of this source code is governed by a MIT-style 13 // license that can be found in licenses/MIT-gofrs.txt. 14 15 // This code originated in github.com/gofrs/uuid. 16 17 package uuid 18 19 import ( 20 "encoding/json" 21 "fmt" 22 "testing" 23 ) 24 25 func TestSQL(t *testing.T) { 26 t.Run("Value", testSQLValue) 27 t.Run("Scan", func(t *testing.T) { 28 t.Run("Binary", testSQLScanBinary) 29 t.Run("String", testSQLScanString) 30 t.Run("Text", testSQLScanText) 31 t.Run("Unsupported", testSQLScanUnsupported) 32 t.Run("Nil", testSQLScanNil) 33 }) 34 } 35 36 func testSQLValue(t *testing.T) { 37 v, err := codecTestUUID.Value() 38 if err != nil { 39 t.Fatal(err) 40 } 41 got, ok := v.(string) 42 if !ok { 43 t.Fatalf("Value() returned %T, want string", v) 44 } 45 if want := codecTestUUID.String(); got != want { 46 t.Errorf("Value() == %q, want %q", got, want) 47 } 48 } 49 50 func testSQLScanBinary(t *testing.T) { 51 got := UUID{} 52 err := got.Scan(codecTestData) 53 if err != nil { 54 t.Fatal(err) 55 } 56 if got != codecTestUUID { 57 t.Errorf("Scan(%x): got %v, want %v", codecTestData, got, codecTestUUID) 58 } 59 } 60 61 func testSQLScanString(t *testing.T) { 62 s := "6ba7b810-9dad-11d1-80b4-00c04fd430c8" 63 got := UUID{} 64 err := got.Scan(s) 65 if err != nil { 66 t.Fatal(err) 67 } 68 if got != codecTestUUID { 69 t.Errorf("Scan(%q): got %v, want %v", s, got, codecTestUUID) 70 } 71 } 72 73 func testSQLScanText(t *testing.T) { 74 text := []byte("6ba7b810-9dad-11d1-80b4-00c04fd430c8") 75 got := UUID{} 76 err := got.Scan(text) 77 if err != nil { 78 t.Fatal(err) 79 } 80 if got != codecTestUUID { 81 t.Errorf("Scan(%q): got %v, want %v", text, got, codecTestUUID) 82 } 83 } 84 85 func testSQLScanUnsupported(t *testing.T) { 86 unsupported := []interface{}{ 87 true, 88 42, 89 } 90 for _, v := range unsupported { 91 got := UUID{} 92 err := got.Scan(v) 93 if err == nil { 94 t.Errorf("Scan(%T) succeeded, got %v", v, got) 95 } 96 } 97 } 98 99 func testSQLScanNil(t *testing.T) { 100 got := UUID{} 101 err := got.Scan(nil) 102 if err == nil { 103 t.Errorf("Scan(nil) succeeded, got %v", got) 104 } 105 } 106 107 func TestNullUUID(t *testing.T) { 108 t.Run("Value", func(t *testing.T) { 109 t.Run("Nil", testNullUUIDValueNil) 110 t.Run("Valid", testNullUUIDValueValid) 111 }) 112 113 t.Run("Scan", func(t *testing.T) { 114 t.Run("Nil", testNullUUIDScanNil) 115 t.Run("Valid", testNullUUIDScanValid) 116 t.Run("UUID", testNullUUIDScanUUID) 117 }) 118 119 t.Run("MarshalJSON", func(t *testing.T) { 120 t.Run("Nil", testNullUUIDMarshalJSONNil) 121 t.Run("Null", testNullUUIDMarshalJSONNull) 122 t.Run("Valid", testNullUUIDMarshalJSONValid) 123 }) 124 125 t.Run("UnmarshalJSON", func(t *testing.T) { 126 t.Run("Nil", testNullUUIDUnmarshalJSONNil) 127 t.Run("Null", testNullUUIDUnmarshalJSONNull) 128 t.Run("Valid", testNullUUIDUnmarshalJSONValid) 129 t.Run("Malformed", testNullUUIDUnmarshalJSONMalformed) 130 }) 131 } 132 133 func testNullUUIDValueNil(t *testing.T) { 134 nu := NullUUID{} 135 got, err := nu.Value() 136 if got != nil { 137 t.Errorf("null NullUUID.Value returned non-nil driver.Value") 138 } 139 if err != nil { 140 t.Errorf("null NullUUID.Value returned non-nil error") 141 } 142 } 143 144 func testNullUUIDValueValid(t *testing.T) { 145 nu := NullUUID{ 146 Valid: true, 147 UUID: codecTestUUID, 148 } 149 got, err := nu.Value() 150 if err != nil { 151 t.Fatal(err) 152 } 153 s, ok := got.(string) 154 if !ok { 155 t.Errorf("Value() returned %T, want string", got) 156 } 157 want := "6ba7b810-9dad-11d1-80b4-00c04fd430c8" 158 if s != want { 159 t.Errorf("%v.Value() == %s, want %s", nu, s, want) 160 } 161 } 162 163 func testNullUUIDScanNil(t *testing.T) { 164 u := NullUUID{} 165 err := u.Scan(nil) 166 if err != nil { 167 t.Fatal(err) 168 } 169 if u.Valid { 170 t.Error("NullUUID is valid after Scan(nil)") 171 } 172 if u.UUID != Nil { 173 t.Errorf("NullUUID.UUID is %v after Scan(nil) want Nil", u.UUID) 174 } 175 } 176 177 func testNullUUIDScanValid(t *testing.T) { 178 s := "6ba7b810-9dad-11d1-80b4-00c04fd430c8" 179 u := NullUUID{} 180 err := u.Scan(s) 181 if err != nil { 182 t.Fatal(err) 183 } 184 if !u.Valid { 185 t.Errorf("Valid == false after Scan(%q)", s) 186 } 187 if u.UUID != codecTestUUID { 188 t.Errorf("UUID == %v after Scan(%q), want %v", u.UUID, s, codecTestUUID) 189 } 190 } 191 192 func testNullUUIDScanUUID(t *testing.T) { 193 u := NullUUID{} 194 err := u.Scan(codecTestUUID) 195 if err != nil { 196 t.Fatal(err) 197 } 198 if !u.Valid { 199 t.Errorf("Valid == false after scan(%v)", codecTestUUID) 200 } 201 if u.UUID != codecTestUUID { 202 t.Errorf("UUID == %v after Scan(%v), want %v", u.UUID, codecTestUUID, codecTestUUID) 203 } 204 } 205 206 func testNullUUIDMarshalJSONNil(t *testing.T) { 207 u := NullUUID{Valid: true} 208 209 data, err := u.MarshalJSON() 210 if err != nil { 211 t.Fatalf("(%#v).MarshalJSON err want: <nil>, got: %v", u, err) 212 } 213 214 dataStr := string(data) 215 216 if dataStr != fmt.Sprintf("%q", Nil) { 217 t.Fatalf("(%#v).MarshalJSON value want: %s, got: %s", u, Nil, dataStr) 218 } 219 } 220 221 func testNullUUIDMarshalJSONValid(t *testing.T) { 222 u := NullUUID{ 223 Valid: true, 224 UUID: codecTestUUID, 225 } 226 227 data, err := u.MarshalJSON() 228 if err != nil { 229 t.Fatalf("(%#v).MarshalJSON err want: <nil>, got: %v", u, err) 230 } 231 232 dataStr := string(data) 233 234 if dataStr != fmt.Sprintf("%q", codecTestUUID) { 235 t.Fatalf("(%#v).MarshalJSON value want: %s, got: %s", u, codecTestUUID, dataStr) 236 } 237 } 238 239 func testNullUUIDMarshalJSONNull(t *testing.T) { 240 u := NullUUID{} 241 242 data, err := u.MarshalJSON() 243 if err != nil { 244 t.Fatalf("(%#v).MarshalJSON err want: <nil>, got: %v", u, err) 245 } 246 247 dataStr := string(data) 248 249 if dataStr != "null" { 250 t.Fatalf("(%#v).MarshalJSON value want: %s, got: %s", u, "null", dataStr) 251 } 252 } 253 254 func testNullUUIDUnmarshalJSONNil(t *testing.T) { 255 var u NullUUID 256 257 data := []byte(`"00000000-0000-0000-0000-000000000000"`) 258 259 if err := json.Unmarshal(data, &u); err != nil { 260 t.Fatalf("json.Unmarshal err = %v, want <nil>", err) 261 } 262 263 if !u.Valid { 264 t.Fatalf("u.Valid = false, want true") 265 } 266 267 if u.UUID != Nil { 268 t.Fatalf("u.UUID = %v, want %v", u.UUID, Nil) 269 } 270 } 271 272 func testNullUUIDUnmarshalJSONNull(t *testing.T) { 273 var u NullUUID 274 275 data := []byte(`null`) 276 277 if err := json.Unmarshal(data, &u); err != nil { 278 t.Fatalf("json.Unmarshal err = %v, want <nil>", err) 279 } 280 281 if u.Valid { 282 t.Fatalf("u.Valid = true, want false") 283 } 284 285 if u.UUID != Nil { 286 t.Fatalf("u.UUID = %v, want %v", u.UUID, Nil) 287 } 288 } 289 func testNullUUIDUnmarshalJSONValid(t *testing.T) { 290 var u NullUUID 291 292 data := []byte(`"6ba7b810-9dad-11d1-80b4-00c04fd430c8"`) 293 294 if err := json.Unmarshal(data, &u); err != nil { 295 t.Fatalf("json.Unmarshal err = %v, want <nil>", err) 296 } 297 298 if !u.Valid { 299 t.Fatalf("u.Valid = false, want true") 300 } 301 302 if u.UUID != codecTestUUID { 303 t.Fatalf("u.UUID = %v, want %v", u.UUID, Nil) 304 } 305 } 306 307 func testNullUUIDUnmarshalJSONMalformed(t *testing.T) { 308 var u NullUUID 309 310 data := []byte(`257`) 311 312 if err := json.Unmarshal(data, &u); err == nil { 313 t.Fatal("json.Unmarshal err = <nil>, want error") 314 } 315 }