github.com/duskeagle/pop@v4.10.1-0.20190417200916-92f2b794aab5+incompatible/executors_test.go (about) 1 package pop 2 3 import ( 4 "testing" 5 6 "github.com/gobuffalo/nulls" 7 "github.com/gofrs/uuid" 8 "github.com/stretchr/testify/require" 9 ) 10 11 func Test_IsZeroOfUnderlyingType(t *testing.T) { 12 r := require.New(t) 13 transaction(func(tx *Connection) { 14 car := &ValidatableCar{Name: "VW"} 15 r.True(IsZeroOfUnderlyingType(car.ID)) 16 err := tx.Save(car) 17 r.NoError(err) 18 r.NotZero(car.ID) 19 r.NotZero(car.CreatedAt) 20 21 r.False(IsZeroOfUnderlyingType(car.ID)) 22 23 var i int 24 r.True(IsZeroOfUnderlyingType(i)) 25 i = 32 26 r.False(IsZeroOfUnderlyingType(i)) 27 28 var s string 29 r.True(IsZeroOfUnderlyingType(s)) 30 s = "42" 31 r.False(IsZeroOfUnderlyingType(s)) 32 33 var u uuid.UUID 34 r.True(IsZeroOfUnderlyingType(u)) 35 u, err = uuid.NewV1() 36 r.NoError(err) 37 r.False(IsZeroOfUnderlyingType(u)) 38 }) 39 } 40 41 func Test_ValidateAndSave(t *testing.T) { 42 r := require.New(t) 43 validationLogs = []string{} 44 transaction(func(tx *Connection) { 45 car := &ValidatableCar{Name: "VW"} 46 verrs, err := tx.ValidateAndSave(car) 47 r.NoError(err) 48 r.False(verrs.HasAny()) 49 r.Len(validationLogs, 2) 50 r.Equal([]string{"Validate", "ValidateSave"}, validationLogs) 51 r.NotZero(car.ID) 52 r.NotZero(car.CreatedAt) 53 54 validationLogs = []string{} 55 car = &ValidatableCar{Name: ""} 56 verrs, err = tx.ValidateAndSave(car) 57 r.NoError(err) 58 r.True(verrs.HasAny()) 59 r.Len(validationLogs, 2) 60 errs := verrs.Get("name") 61 r.Len(errs, 1) 62 63 validationLogs = []string{} 64 ncar := &NotValidatableCar{Name: ""} 65 verrs, err = tx.ValidateAndSave(ncar) 66 r.NoError(err) 67 r.False(verrs.HasAny()) 68 r.Len(validationLogs, 0) 69 }) 70 } 71 72 func Test_ValidateAndSave_With_Slice(t *testing.T) { 73 r := require.New(t) 74 validationLogs = []string{} 75 transaction(func(tx *Connection) { 76 car := []ValidatableCar{ 77 {Name: "VW"}, 78 {Name: "AU"}, 79 } 80 verrs, err := tx.ValidateAndSave(&car) 81 r.NoError(err) 82 r.False(verrs.HasAny()) 83 r.Len(validationLogs, 4) 84 r.Equal([]string{"Validate", "ValidateSave", "Validate", "ValidateSave"}, validationLogs) 85 86 r.NotZero(car[0].ID) 87 r.NotZero(car[0].CreatedAt) 88 r.NotZero(car[1].ID) 89 r.NotZero(car[1].CreatedAt) 90 91 validationLogs = []string{} 92 car = []ValidatableCar{ 93 {Name: ""}, 94 {Name: "AU"}, 95 } 96 verrs, err = tx.ValidateAndSave(&car) 97 r.NoError(err) 98 r.True(verrs.HasAny()) 99 r.Len(validationLogs, 2) 100 errs := verrs.Get("name") 101 r.Len(errs, 1) 102 103 validationLogs = []string{} 104 ncar := []NotValidatableCar{ 105 {Name: ""}, 106 {Name: "AU"}, 107 } 108 verrs, err = tx.ValidateAndSave(&ncar) 109 r.NoError(err) 110 r.False(verrs.HasAny()) 111 r.Len(validationLogs, 0) 112 }) 113 } 114 115 func Test_ValidateAndCreate(t *testing.T) { 116 r := require.New(t) 117 validationLogs = []string{} 118 transaction(func(tx *Connection) { 119 car := &ValidatableCar{Name: "VW"} 120 verrs, err := tx.ValidateAndCreate(car) 121 r.NoError(err) 122 r.False(verrs.HasAny()) 123 r.Len(validationLogs, 2) 124 r.Equal([]string{"Validate", "ValidateCreate"}, validationLogs) 125 r.NotZero(car.ID) 126 r.NotZero(car.CreatedAt) 127 128 validationLogs = []string{} 129 car = &ValidatableCar{Name: ""} 130 verrs, err = tx.ValidateAndSave(car) 131 r.NoError(err) 132 r.True(verrs.HasAny()) 133 r.Len(validationLogs, 2) 134 errs := verrs.Get("name") 135 r.Len(errs, 1) 136 137 validationLogs = []string{} 138 ncar := &NotValidatableCar{Name: ""} 139 verrs, err = tx.ValidateAndCreate(ncar) 140 r.NoError(err) 141 r.False(verrs.HasAny()) 142 r.Len(validationLogs, 0) 143 }) 144 } 145 146 func Test_Create_Single_Incremental_ID(t *testing.T) { 147 r := require.New(t) 148 validationLogs = []string{} 149 transaction(func(tx *Connection) { 150 singleID := &SingleID{} 151 err := tx.Create(singleID) 152 r.NoError(err) 153 r.NotZero(singleID.ID) 154 }) 155 } 156 157 func Test_ValidateAndCreate_With_Slice(t *testing.T) { 158 r := require.New(t) 159 validationLogs = []string{} 160 transaction(func(tx *Connection) { 161 car := []ValidatableCar{ 162 {Name: "VW"}, 163 {Name: "AU"}, 164 } 165 verrs, err := tx.ValidateAndCreate(&car) 166 r.NoError(err) 167 r.False(verrs.HasAny()) 168 r.Len(validationLogs, 4) 169 r.Equal([]string{"Validate", "ValidateCreate", "Validate", "ValidateCreate"}, validationLogs) 170 r.NotZero(car[0].ID) 171 r.NotZero(car[0].CreatedAt) 172 r.NotZero(car[1].ID) 173 r.NotZero(car[1].CreatedAt) 174 175 validationLogs = []string{} 176 car = []ValidatableCar{ 177 {Name: ""}, 178 {Name: "AU"}, 179 } 180 verrs, err = tx.ValidateAndSave(&car) 181 r.NoError(err) 182 r.True(verrs.HasAny()) 183 r.Len(validationLogs, 2) 184 errs := verrs.Get("name") 185 r.Len(errs, 1) 186 187 validationLogs = []string{} 188 ncar := []NotValidatableCar{ 189 {Name: ""}, 190 {Name: "AU"}, 191 } 192 verrs, err = tx.ValidateAndCreate(ncar) 193 r.NoError(err) 194 r.False(verrs.HasAny()) 195 r.Len(validationLogs, 0) 196 }) 197 } 198 199 func Test_ValidateAndUpdate(t *testing.T) { 200 r := require.New(t) 201 validationLogs = []string{} 202 transaction(func(tx *Connection) { 203 car := &ValidatableCar{Name: "VW"} 204 verrs, err := tx.ValidateAndCreate(car) 205 r.NoError(err) 206 r.False(verrs.HasAny()) 207 r.Len(validationLogs, 2) 208 r.Equal([]string{"Validate", "ValidateCreate"}, validationLogs) 209 r.NotZero(car.ID) 210 r.NotZero(car.CreatedAt) 211 212 validationLogs = []string{} 213 car.Name = "" 214 verrs, err = tx.ValidateAndUpdate(car) 215 r.NoError(err) 216 r.True(verrs.HasAny()) 217 r.Len(validationLogs, 2) 218 errs := verrs.Get("name") 219 r.Len(errs, 1) 220 221 validationLogs = []string{} 222 ncar := &NotValidatableCar{Name: ""} 223 verrs, err = tx.ValidateAndCreate(ncar) 224 r.NoError(err) 225 r.False(verrs.HasAny()) 226 r.Len(validationLogs, 0) 227 228 validationLogs = []string{} 229 ncar.Name = "" 230 verrs, err = tx.ValidateAndUpdate(ncar) 231 r.NoError(err) 232 r.False(verrs.HasAny()) 233 r.Len(validationLogs, 0) 234 }) 235 } 236 237 func Test_ValidateAndUpdate_With_Slice(t *testing.T) { 238 r := require.New(t) 239 validationLogs = []string{} 240 transaction(func(tx *Connection) { 241 car := []ValidatableCar{ 242 {Name: "VW"}, 243 {Name: "AU"}, 244 } 245 verrs, err := tx.ValidateAndCreate(&car) 246 r.NoError(err) 247 r.False(verrs.HasAny()) 248 r.Len(validationLogs, 4) 249 r.Equal([]string{"Validate", "ValidateCreate", "Validate", "ValidateCreate"}, validationLogs) 250 r.NotZero(car[0].ID) 251 r.NotZero(car[0].CreatedAt) 252 r.NotZero(car[1].ID) 253 r.NotZero(car[1].CreatedAt) 254 255 validationLogs = []string{} 256 car[0].Name = "" 257 verrs, err = tx.ValidateAndUpdate(&car) 258 r.NoError(err) 259 r.True(verrs.HasAny()) 260 r.Len(validationLogs, 2) 261 errs := verrs.Get("name") 262 r.Len(errs, 1) 263 264 validationLogs = []string{} 265 ncar := []NotValidatableCar{ 266 {Name: ""}, 267 {Name: "AU"}, 268 } 269 verrs, err = tx.ValidateAndCreate(&ncar) 270 r.NoError(err) 271 r.False(verrs.HasAny()) 272 r.Len(validationLogs, 0) 273 274 validationLogs = []string{} 275 ncar[1].Name = "" 276 verrs, err = tx.ValidateAndUpdate(&ncar) 277 r.NoError(err) 278 r.False(verrs.HasAny()) 279 r.Len(validationLogs, 0) 280 }) 281 } 282 283 func Test_Exec(t *testing.T) { 284 transaction(func(tx *Connection) { 285 r := require.New(t) 286 287 user := User{Name: nulls.NewString("Mark 'Awesome' Bates")} 288 tx.Create(&user) 289 290 ctx, _ := tx.Count(user) 291 r.Equal(1, ctx) 292 293 q := tx.RawQuery("delete from users where id = ?", user.ID) 294 err := q.Exec() 295 r.NoError(err) 296 297 ctx, _ = tx.Count(user) 298 r.Equal(0, ctx) 299 }) 300 } 301 302 func Test_ExecCount(t *testing.T) { 303 transaction(func(tx *Connection) { 304 r := require.New(t) 305 306 user := User{Name: nulls.NewString("Mark 'Awesome' Bates")} 307 tx.Create(&user) 308 309 ctx, _ := tx.Count(user) 310 r.Equal(1, ctx) 311 312 q := tx.RawQuery("delete from users where id = ?", user.ID) 313 count, err := q.ExecWithCount() 314 r.NoError(err) 315 316 r.Equal(1, count) 317 318 ctx, _ = tx.Count(user) 319 r.Equal(0, ctx) 320 }) 321 } 322 323 func Test_Save(t *testing.T) { 324 r := require.New(t) 325 transaction(func(tx *Connection) { 326 u := &User{Name: nulls.NewString("Mark")} 327 r.Zero(u.ID) 328 r.NoError(tx.Save(u)) 329 r.NotZero(u.ID) 330 331 uat := u.UpdatedAt.UnixNano() 332 333 r.NoError(tx.Save(u)) 334 r.NotEqual(uat, u.UpdatedAt.UnixNano()) 335 }) 336 } 337 338 func Test_Save_With_Slice(t *testing.T) { 339 r := require.New(t) 340 transaction(func(tx *Connection) { 341 u := Users{ 342 {Name: nulls.NewString("Mark")}, 343 {Name: nulls.NewString("Larry")}, 344 } 345 r.Zero(u[0].ID) 346 r.Zero(u[1].ID) 347 348 r.NoError(tx.Save(&u)) 349 r.NotZero(u[0].ID) 350 r.NotZero(u[1].ID) 351 352 uat := u[0].UpdatedAt.UnixNano() 353 354 r.NoError(tx.Save(u)) 355 r.NotEqual(uat, u[0].UpdatedAt.UnixNano()) 356 }) 357 } 358 359 func Test_Create(t *testing.T) { 360 transaction(func(tx *Connection) { 361 r := require.New(t) 362 363 count, _ := tx.Count(&User{}) 364 user := User{Name: nulls.NewString("Mark 'Awesome' Bates")} 365 err := tx.Create(&user) 366 r.NoError(err) 367 r.NotEqual(0, user.ID) 368 369 ctx, _ := tx.Count(&User{}) 370 r.Equal(count+1, ctx) 371 372 u := User{} 373 q := tx.Where("name = ?", "Mark 'Awesome' Bates") 374 err = q.First(&u) 375 r.NoError(err) 376 r.Equal("Mark 'Awesome' Bates", user.Name.String) 377 }) 378 } 379 380 func Test_Create_stringID(t *testing.T) { 381 transaction(func(tx *Connection) { 382 r := require.New(t) 383 384 count, err := tx.Count(&Label{}) 385 r.NoError(err) 386 label := Label{ID: "red"} 387 err = tx.Create(&label) 388 r.NoError(err) 389 r.Equal("red", label.ID) 390 391 ctx, err := tx.Count(&Label{}) 392 r.NoError(err) 393 r.Equal(count+1, ctx) 394 395 l := Label{} 396 err = tx.Find(&l, "red") 397 r.NoError(err) 398 r.Equal("red", l.ID) 399 }) 400 } 401 402 func Test_Create_With_Slice(t *testing.T) { 403 transaction(func(tx *Connection) { 404 r := require.New(t) 405 406 count, _ := tx.Count(&User{}) 407 users := Users{ 408 {Name: nulls.NewString("Mark Bates")}, 409 {Name: nulls.NewString("Larry M. Jordan")}, 410 {Name: nulls.NewString("Pop")}, 411 } 412 err := tx.Create(&users) 413 r.NoError(err) 414 415 ctx, _ := tx.Count(&User{}) 416 r.Equal(count+3, ctx) 417 }) 418 } 419 420 func Test_Eager_Create_Has_Many(t *testing.T) { 421 transaction(func(tx *Connection) { 422 r := require.New(t) 423 count, _ := tx.Count(&User{}) 424 user := User{ 425 Name: nulls.NewString("Mark 'Awesome' Bates"), 426 Books: Books{{Title: "Pop Book", Description: "Pop Book", Isbn: "PB1"}}, 427 FavoriteSong: Song{Title: "Hook - Blues Traveler"}, 428 Houses: Addresses{ 429 Address{HouseNumber: 86, Street: "Modelo"}, 430 }, 431 } 432 433 err := tx.Eager().Create(&user) 434 r.NoError(err) 435 r.NotEqual(user.ID, 0) 436 437 ctx, _ := tx.Count(&User{}) 438 r.Equal(count+1, ctx) 439 440 ctx, _ = tx.Count(&Book{}) 441 r.Equal(count+1, ctx) 442 443 ctx, _ = tx.Count(&Song{}) 444 r.Equal(count+1, ctx) 445 446 ctx, _ = tx.Count(&Address{}) 447 r.Equal(count+1, ctx) 448 449 u := User{} 450 q := tx.Eager().Where("name = ?", "Mark 'Awesome' Bates") 451 err = q.First(&u) 452 r.NoError(err) 453 r.Equal(u.Name.String, "Mark 'Awesome' Bates") 454 r.Equal(1, len(u.Books)) 455 r.Equal(u.Books[0].Title, "Pop Book") 456 r.Equal(u.FavoriteSong.Title, "Hook - Blues Traveler") 457 r.Equal(1, len(u.Houses)) 458 r.Equal(u.Houses[0].Street, "Modelo") 459 }) 460 } 461 462 func Test_Eager_Create_Has_Many_With_Existing(t *testing.T) { 463 transaction(func(tx *Connection) { 464 r := require.New(t) 465 466 addr := Address{HouseNumber: 42, Street: "Life"} 467 addrVerrs, addrErr := tx.ValidateAndCreate(&addr) 468 r.NoError(addrErr) 469 addrCount, _ := tx.Count(&Address{}) 470 r.Zero(addrVerrs.Count()) 471 r.Equal(1, addrCount) 472 r.NotZero(addr.ID) 473 474 count, _ := tx.Count(&User{}) 475 user := User{ 476 Name: nulls.NewString("Mark 'Awesome' Bates"), 477 Books: Books{{Title: "Pop Book", Description: "Pop Book", Isbn: "PB1"}}, 478 FavoriteSong: Song{Title: "Hook - Blues Traveler"}, 479 Houses: Addresses{ 480 Address{HouseNumber: 86, Street: "Modelo"}, 481 addr, 482 }, 483 } 484 485 err := tx.Eager().Create(&user) 486 r.NoError(err) 487 r.NotEqual(user.ID, 0) 488 489 ctx, _ := tx.Count(&User{}) 490 r.Equal(count+1, ctx) 491 492 ctx, _ = tx.Count(&Book{}) 493 r.Equal(count+1, ctx) 494 495 ctx, _ = tx.Count(&Song{}) 496 r.Equal(count+1, ctx) 497 498 ctx, _ = tx.Count(&Address{}) 499 r.Equal(addrCount+1, ctx) 500 501 u := User{} 502 q := tx.Eager().Where("name = ?", "Mark 'Awesome' Bates") 503 err = q.First(&u) 504 r.NoError(err) 505 r.Equal(u.Name.String, "Mark 'Awesome' Bates") 506 r.Equal(1, len(u.Books)) 507 r.Equal(u.Books[0].Title, "Pop Book") 508 r.Equal(u.FavoriteSong.Title, "Hook - Blues Traveler") 509 r.Equal(2, len(u.Houses)) 510 if u.Houses[0].ID == addr.ID { 511 r.Equal(u.Houses[0].Street, "Life") 512 r.Equal(u.Houses[1].Street, "Modelo") 513 } else { 514 r.Equal(u.Houses[0].Street, "Modelo") 515 r.Equal(u.Houses[1].Street, "Life") 516 } 517 }) 518 } 519 520 func Test_Eager_Create_Has_Many_Reset_Eager_Mode_Connection(t *testing.T) { 521 transaction(func(tx *Connection) { 522 r := require.New(t) 523 count, _ := tx.Count(&User{}) 524 user1 := User{ 525 Name: nulls.NewString("Mark 'Awesome' Bates"), 526 Books: Books{{Title: "Pop Book", Description: "Pop Book", Isbn: "PB1"}}, 527 } 528 529 err := tx.Eager("Books").Create(&user1) 530 r.NoError(err) 531 ctx, _ := tx.Count(&User{}) 532 r.Equal(count+1, ctx) 533 ctx, _ = tx.Count(&Book{}) 534 r.Equal(count+1, ctx) 535 536 book := Book{Title: "Pop Book", Description: "Pop Book", Isbn: "PB1"} 537 538 err = tx.Eager().Create(&book) 539 r.NoError(err) 540 ctx, _ = tx.Count(&Book{}) 541 r.Equal(count+2, ctx) 542 }) 543 } 544 545 func Test_Eager_Validate_And_Create_Has_Many(t *testing.T) { 546 r := require.New(t) 547 transaction(func(tx *Connection) { 548 user := User{ 549 Name: nulls.NewString("Mark 'Awesome' Bates"), 550 Books: Books{{Title: "Pop Book", Isbn: "PB1"}}, 551 FavoriteSong: Song{Title: "Hook - Blues Traveler"}, 552 Houses: Addresses{ 553 Address{HouseNumber: 86, Street: "Modelo"}, 554 }, 555 } 556 557 verrs, err := tx.Eager().ValidateAndCreate(&user) 558 r.NoError(err) 559 ctx, _ := tx.Count(&User{}) 560 r.Zero(ctx) 561 r.Equal(1, verrs.Count()) // Missing Books.Description. 562 }) 563 } 564 565 func Test_Eager_Validate_And_Create_Parental(t *testing.T) { 566 r := require.New(t) 567 transaction(func(tx *Connection) { 568 user := User{ 569 Name: nulls.NewString(""), 570 Books: Books{{Title: "Pop Book", Isbn: "PB1", Description: "Awesome Book!"}}, 571 FavoriteSong: Song{Title: "Hook - Blues Traveler"}, 572 Houses: Addresses{ 573 Address{HouseNumber: 86, Street: "Modelo"}, 574 }, 575 } 576 577 verrs, err := tx.Eager().ValidateAndCreate(&user) 578 r.NoError(err) 579 ctx, _ := tx.Count(&User{}) 580 r.Zero(ctx) 581 r.Equal(1, verrs.Count()) // Missing Books.Description. 582 }) 583 } 584 585 func Test_Eager_Validate_And_Create_Parental_With_Existing(t *testing.T) { 586 r := require.New(t) 587 transaction(func(tx *Connection) { 588 addr := Address{HouseNumber: 42, Street: "Life"} 589 addrVerrs, addrErr := tx.ValidateAndCreate(&addr) 590 r.NoError(addrErr) 591 addrCount, _ := tx.Count(&Address{}) 592 r.Zero(addrVerrs.Count()) 593 r.Equal(1, addrCount) 594 r.NotZero(addr.ID) 595 596 m2mCount, m2mErr := tx.Count(&UsersAddress{}) 597 r.NoError(m2mErr) 598 r.Zero(m2mCount) 599 600 user := User{ 601 Name: nulls.NewString("Mark 'Awesome' Bates"), 602 Books: Books{{Title: "Pop Book", Isbn: "PB1", Description: "Awesome Book!"}}, 603 FavoriteSong: Song{Title: "Hook - Blues Traveler"}, 604 Houses: Addresses{ 605 Address{HouseNumber: 86, Street: "Modelo"}, 606 addr, 607 }, 608 } 609 count, _ := tx.Count(&User{}) 610 611 verrs, err := tx.Eager().ValidateAndCreate(&user) 612 r.NoError(err) 613 r.NotEqual(user.ID, 0) 614 r.Equal(0, verrs.Count()) 615 616 ctx, _ := tx.Count(&User{}) 617 r.Equal(count+1, ctx) 618 619 ctx, _ = tx.Count(&Address{}) 620 r.Equal(addrCount+1, ctx) 621 622 m2mCount, m2mErr = tx.Count(&UsersAddress{}) 623 r.NoError(m2mErr) 624 r.Equal(2, m2mCount) 625 626 u := User{} 627 q := tx.Eager().Where("name = ?", "Mark 'Awesome' Bates") 628 err = q.First(&u) 629 r.NoError(err) 630 r.Equal(u.Name.String, "Mark 'Awesome' Bates") 631 r.Equal(1, len(u.Books)) 632 r.Equal(u.Books[0].Title, "Pop Book") 633 r.Equal(u.FavoriteSong.Title, "Hook - Blues Traveler") 634 r.Equal(2, len(u.Houses)) 635 if u.Houses[0].ID == addr.ID { 636 r.Equal(u.Houses[0].Street, "Life") 637 r.Equal(u.Houses[1].Street, "Modelo") 638 } else { 639 r.Equal(u.Houses[1].ID, addr.ID) 640 r.Equal(u.Houses[0].Street, "Modelo") 641 r.Equal(u.Houses[1].Street, "Life") 642 } 643 }) 644 } 645 646 func Test_Eager_Validate_And_Create_Parental_With_Partial_Existing(t *testing.T) { 647 r := require.New(t) 648 transaction(func(tx *Connection) { 649 addr := Address{HouseNumber: 42, Street: "Life"} 650 addrVerrs, addrErr := tx.ValidateAndCreate(&addr) 651 r.NoError(addrErr) 652 addrCount, _ := tx.Count(&Address{}) 653 r.Zero(addrVerrs.Count()) 654 r.Equal(1, addrCount) 655 r.NotZero(addr.ID) 656 657 m2mCount, m2mErr := tx.Count(&UsersAddress{}) 658 r.NoError(m2mErr) 659 r.Zero(m2mCount) 660 661 user := User{ 662 Name: nulls.NewString("Mark 'Awesome' Bates"), 663 Books: Books{{Title: "Pop Book", Isbn: "PB1", Description: "Awesome Book!"}}, 664 FavoriteSong: Song{Title: "Hook - Blues Traveler"}, 665 Houses: Addresses{ 666 Address{HouseNumber: 86, Street: "Modelo"}, 667 Address{ID: addr.ID}, 668 }, 669 } 670 count, _ := tx.Count(&User{}) 671 672 verrs, err := tx.Eager().ValidateAndCreate(&user) 673 r.NoError(err) 674 r.NotEqual(user.ID, 0) 675 r.Equal(0, verrs.Count()) 676 677 ctx, _ := tx.Count(&User{}) 678 r.Equal(count+1, ctx) 679 680 ctx, _ = tx.Count(&Address{}) 681 r.Equal(addrCount+1, ctx) 682 683 m2mCount, m2mErr = tx.Count(&UsersAddress{}) 684 r.NoError(m2mErr) 685 r.Equal(2, m2mCount) 686 687 u := User{} 688 q := tx.Eager().Where("name = ?", "Mark 'Awesome' Bates") 689 err = q.First(&u) 690 r.NoError(err) 691 r.Equal(u.Name.String, "Mark 'Awesome' Bates") 692 r.Equal(1, len(u.Books)) 693 r.Equal(u.Books[0].Title, "Pop Book") 694 r.Equal(u.FavoriteSong.Title, "Hook - Blues Traveler") 695 r.Equal(2, len(u.Houses)) 696 if u.Houses[0].ID == addr.ID { 697 r.Equal("Life", u.Houses[0].Street) // Street is blanked out 698 r.Equal("Modelo", u.Houses[1].Street) 699 } else { 700 r.Equal(addr.ID, u.Houses[1].ID) 701 r.Equal("Modelo", u.Houses[0].Street) 702 r.Equal("Life", u.Houses[1].Street) // Street is blanked out 703 } 704 }) 705 } 706 707 func Test_Flat_Validate_And_Create_Parental_With_Existing(t *testing.T) { 708 r := require.New(t) 709 transaction(func(tx *Connection) { 710 addr := Address{HouseNumber: 42, Street: "Life"} 711 addrVerrs, addrErr := tx.ValidateAndCreate(&addr) 712 r.NoError(addrErr) 713 addrCount, _ := tx.Count(&Address{}) 714 r.Zero(addrVerrs.Count()) 715 r.Equal(1, addrCount) 716 r.NotZero(addr.ID) 717 718 book := Book{Title: "Pop Book", Isbn: "PB1", Description: "Awesome Book!"} 719 bookVerrs, bookErr := tx.ValidateAndCreate(&book) 720 r.NoError(bookErr) 721 r.Zero(bookVerrs.Count()) 722 r.NotZero(book.ID) 723 724 book2 := Book{Title: "Pop Book2", Isbn: "PB2", Description: "Awesome Book Also!"} 725 bookVerrs, bookErr = tx.ValidateAndCreate(&book2) 726 r.NoError(bookErr) 727 r.Zero(bookVerrs.Count()) 728 r.NotZero(book2.ID) 729 730 bookCount, _ := tx.Count(&Book{}) 731 r.Equal(2, bookCount) 732 733 song := Song{Title: "Hook - Blues Traveler"} 734 songVerrs, songErr := tx.ValidateAndCreate(&song) 735 r.NoError(songErr) 736 songCount, _ := tx.Count(&Song{}) 737 r.Zero(songVerrs.Count()) 738 r.Equal(1, songCount) 739 r.NotZero(song.ID) 740 741 m2mCount, m2mErr := tx.Count(&UsersAddress{}) 742 r.NoError(m2mErr) 743 r.Zero(m2mCount) 744 745 user := User{ 746 Name: nulls.NewString("Mark 'Awesome' Bates"), 747 Books: Books{book, book2}, 748 FavoriteSong: song, 749 Houses: Addresses{ 750 Address{HouseNumber: 86, Street: "Modelo"}, 751 addr, 752 }, 753 } 754 count, _ := tx.Count(&User{}) 755 756 verrs, err := tx.ValidateAndCreate(&user) 757 r.NoError(err) 758 r.NotEqual(user.ID, 0) 759 r.Equal(0, verrs.Count()) 760 761 ctx, _ := tx.Count(&User{}) 762 r.Equal(count+1, ctx) 763 764 ctx, _ = tx.Count(&Address{}) 765 r.Equal(addrCount, ctx) 766 767 ctx, _ = tx.Count(&Book{}) 768 r.Equal(bookCount, ctx) 769 770 ctx, _ = tx.Count(&Song{}) 771 r.Equal(songCount, ctx) 772 773 m2mCount, m2mErr = tx.Count(&UsersAddress{}) 774 r.NoError(m2mErr) 775 r.Equal(1, m2mCount) 776 777 u := User{} 778 q := tx.Eager().Where("name = ?", "Mark 'Awesome' Bates") 779 err = q.First(&u) 780 r.NoError(err) 781 r.Equal(u.Name.String, "Mark 'Awesome' Bates") 782 r.Equal(2, len(u.Books)) 783 if u.Books[0].ID == book.ID { 784 r.Equal(u.Books[0].Title, "Pop Book") 785 r.Equal(u.Books[1].Title, "Pop Book2") 786 } else { 787 r.Equal(u.Books[1].Title, "Pop Book") 788 r.Equal(u.Books[0].Title, "Pop Book2") 789 } 790 r.Equal(u.FavoriteSong.Title, "Hook - Blues Traveler") 791 r.Equal(1, len(u.Houses)) 792 r.Equal(addr.ID, u.Houses[0].ID) 793 r.Equal("Life", u.Houses[0].Street) 794 }) 795 } 796 797 func Test_Flat_Validate_And_Create_Parental_With_Partial_Existing(t *testing.T) { 798 r := require.New(t) 799 transaction(func(tx *Connection) { 800 addr := Address{HouseNumber: 42, Street: "Life"} 801 addrVerrs, addrErr := tx.ValidateAndCreate(&addr) 802 r.NoError(addrErr) 803 addrCount, _ := tx.Count(&Address{}) 804 r.Zero(addrVerrs.Count()) 805 r.Equal(1, addrCount) 806 r.NotZero(addr.ID) 807 808 book := Book{Title: "Pop Book", Isbn: "PB1", Description: "Awesome Book!"} 809 bookVerrs, bookErr := tx.ValidateAndCreate(&book) 810 r.NoError(bookErr) 811 bookCount, _ := tx.Count(&Book{}) 812 r.Zero(bookVerrs.Count()) 813 r.Equal(1, bookCount) 814 r.NotZero(book.ID) 815 816 song := Song{Title: "Hook - Blues Traveler"} 817 songVerrs, songErr := tx.ValidateAndCreate(&song) 818 r.NoError(songErr) 819 songCount, _ := tx.Count(&Song{}) 820 r.Zero(songVerrs.Count()) 821 r.Equal(1, songCount) 822 r.NotZero(song.ID) 823 824 m2mCount, m2mErr := tx.Count(&UsersAddress{}) 825 r.NoError(m2mErr) 826 r.Zero(m2mCount) 827 828 user := User{ 829 Name: nulls.NewString("Mark 'Awesome' Bates"), 830 //TODO: add another existing here and test for it to make sure this works with multiples (books) 831 Books: Books{Book{ID: book.ID}}, 832 FavoriteSong: Song{ID: song.ID}, 833 Houses: Addresses{ 834 Address{HouseNumber: 86, Street: "Modelo"}, 835 Address{ID: addr.ID}, 836 }, 837 } 838 count, _ := tx.Count(&User{}) 839 840 verrs, err := tx.ValidateAndCreate(&user) 841 r.NoError(err) 842 r.NotEqual(user.ID, 0) 843 r.Equal(0, verrs.Count()) 844 845 ctx, _ := tx.Count(&User{}) 846 r.Equal(count+1, ctx) 847 848 ctx, _ = tx.Count(&Address{}) 849 r.Equal(addrCount, ctx) 850 851 ctx, _ = tx.Where("user_id = ?", user.ID).Count(&Book{}) 852 r.Equal(bookCount, ctx) 853 854 ctx, _ = tx.Count(&Song{}) 855 r.Equal(songCount, ctx) 856 857 m2mCount, m2mErr = tx.Count(&UsersAddress{}) 858 r.NoError(m2mErr) 859 r.Equal(1, m2mCount) 860 861 u := User{} 862 q := tx.Eager().Where("name = ?", "Mark 'Awesome' Bates") 863 err = q.First(&u) 864 r.NoError(err) 865 r.Equal(u.Name.String, "Mark 'Awesome' Bates") 866 r.Equal(1, len(u.Books)) 867 r.Equal(u.Books[0].Title, "Pop Book") 868 r.Equal(u.FavoriteSong.Title, "Hook - Blues Traveler") 869 r.Equal(1, len(u.Houses)) 870 r.Equal(addr.ID, u.Houses[0].ID) 871 r.Equal("Life", u.Houses[0].Street) 872 }) 873 } 874 875 func Test_Eager_Create_Belongs_To(t *testing.T) { 876 transaction(func(tx *Connection) { 877 r := require.New(t) 878 book := Book{ 879 Title: "Pop Book", 880 Description: "Pop Book", 881 Isbn: "PB1", 882 User: User{ 883 Name: nulls.NewString("Larry"), 884 }, 885 } 886 887 err := tx.Eager().Create(&book) 888 r.NoError(err) 889 890 ctx, _ := tx.Count(&Book{}) 891 r.Equal(1, ctx) 892 893 ctx, _ = tx.Count(&User{}) 894 r.Equal(1, ctx) 895 896 car := Taxi{ 897 Model: "Fancy car", 898 Driver: User{ 899 Name: nulls.NewString("Larry 2"), 900 }, 901 } 902 903 err = tx.Eager().Create(&car) 904 r.NoError(err) 905 906 ctx, _ = tx.Count(&Taxi{}) 907 r.Equal(1, ctx) 908 909 err = tx.Eager().Find(&car, car.ID) 910 r.NoError(err) 911 912 r.Equal(nulls.NewString("Larry 2"), car.Driver.Name) 913 }) 914 } 915 916 func Test_Eager_Create_Belongs_To_Pointers(t *testing.T) { 917 transaction(func(tx *Connection) { 918 r := require.New(t) 919 // Create a body with a head 920 body := Body{ 921 Head: &Head{}, 922 } 923 924 err := tx.Eager().Create(&body) 925 r.NoError(err) 926 r.NotZero(body.ID) 927 r.NotZero(body.Head.ID) 928 929 ctx, _ := tx.Count(&Body{}) 930 r.Equal(1, ctx) 931 932 ctx, _ = tx.Count(&Head{}) 933 r.Equal(1, ctx) 934 935 // Create a body without a head: 936 body = Body{ 937 Head: nil, 938 } 939 940 err = tx.Eager().Create(&body) 941 r.NoError(err) 942 r.NotZero(body.ID) 943 r.Nil(body.Head) 944 945 ctx, _ = tx.Count(&Body{}) 946 r.Equal(2, ctx) 947 948 ctx, _ = tx.Count(&Head{}) 949 r.Equal(1, ctx) 950 951 err = tx.Eager().Create(&Head{ 952 BodyID: body.ID, 953 Body: nil, 954 }) 955 r.NoError(err) 956 }) 957 } 958 959 func Test_Create_Belongs_To_Pointers(t *testing.T) { 960 transaction(func(tx *Connection) { 961 r := require.New(t) 962 // Create a body without a head: 963 body := Body{ 964 Head: nil, 965 } 966 967 err := tx.Create(&body) 968 r.NoError(err) 969 r.NotZero(body.ID) 970 r.Nil(body.Head) 971 972 // Create a head with the associated model set but not the ID 973 created := HeadPtr{ 974 Body: &body, 975 } 976 err = tx.Create(&created) 977 r.NoError(err) 978 979 found := HeadPtr{} 980 err = tx.Find(&found, created.ID) 981 r.NoError(err) 982 r.Equal(body.ID, *found.BodyID) 983 }) 984 } 985 986 func Test_Flat_Create_Belongs_To(t *testing.T) { 987 transaction(func(tx *Connection) { 988 r := require.New(t) 989 user := User{ 990 Name: nulls.NewString("Larry"), 991 } 992 993 err := tx.Create(&user) 994 r.NoError(err) 995 ctx, _ := tx.Count(&User{}) 996 r.Equal(1, ctx) 997 998 book := Book{ 999 Title: "Pop Book", 1000 Description: "Pop Book", 1001 Isbn: "PB1", 1002 User: user, 1003 } 1004 1005 err = tx.Create(&book) 1006 r.NoError(err) 1007 1008 ctx, _ = tx.Count(&Book{}) 1009 r.Equal(1, ctx) 1010 1011 err = tx.Eager().Find(&book, book.ID) 1012 r.NoError(err) 1013 1014 r.Equal(nulls.NewString("Larry"), book.User.Name) 1015 1016 car := Taxi{ 1017 Model: "Fancy car", 1018 Driver: user, 1019 } 1020 1021 err = tx.Create(&car) 1022 r.NoError(err) 1023 1024 ctx, _ = tx.Count(&Taxi{}) 1025 r.Equal(1, ctx) 1026 1027 err = tx.Eager().Find(&car, car.ID) 1028 r.NoError(err) 1029 1030 r.Equal(nulls.NewString("Larry"), car.Driver.Name) 1031 }) 1032 } 1033 1034 func Test_Eager_Creation_Without_Associations(t *testing.T) { 1035 transaction(func(tx *Connection) { 1036 r := require.New(t) 1037 code := CourseCode{ 1038 Course: Course{}, 1039 } 1040 1041 err := tx.Eager().Create(&code) 1042 r.NoError(err) 1043 1044 ctx, _ := tx.Count(&CourseCode{}) 1045 r.Equal(1, ctx) 1046 }) 1047 } 1048 1049 func Test_Create_UUID(t *testing.T) { 1050 transaction(func(tx *Connection) { 1051 r := require.New(t) 1052 1053 count, _ := tx.Count(&Song{}) 1054 song := Song{Title: "Automatic Buffalo"} 1055 err := tx.Create(&song) 1056 r.NoError(err) 1057 r.NotZero(song.ID) 1058 1059 ctx, _ := tx.Count(&Song{}) 1060 r.Equal(count+1, ctx) 1061 1062 u := Song{} 1063 q := tx.Where("title = ?", "Automatic Buffalo") 1064 err = q.First(&u) 1065 r.NoError(err) 1066 }) 1067 } 1068 1069 func Test_Create_Existing_UUID(t *testing.T) { 1070 transaction(func(tx *Connection) { 1071 r := require.New(t) 1072 id, err := uuid.NewV4() 1073 r.NoError(err) 1074 1075 count, _ := tx.Count(&Song{}) 1076 song := Song{ 1077 ID: id, 1078 Title: "Automatic Buffalo", 1079 } 1080 1081 err = tx.Create(&song) 1082 r.NoError(err) 1083 r.NotZero(song.ID) 1084 r.Equal(id.String(), song.ID.String()) 1085 1086 ctx, _ := tx.Count(&Song{}) 1087 r.Equal(count+1, ctx) 1088 1089 }) 1090 } 1091 1092 func Test_Create_Timestamps(t *testing.T) { 1093 transaction(func(tx *Connection) { 1094 r := require.New(t) 1095 1096 user := User{Name: nulls.NewString("Mark 'Awesome' Bates")} 1097 r.Zero(user.CreatedAt) 1098 r.Zero(user.UpdatedAt) 1099 1100 err := tx.Create(&user) 1101 r.NoError(err) 1102 1103 r.NotZero(user.CreatedAt) 1104 r.NotZero(user.UpdatedAt) 1105 1106 friend := Friend{FirstName: "Ross", LastName: "Gellar"} 1107 err = tx.Create(&friend) 1108 r.NoError(err) 1109 }) 1110 } 1111 1112 func Test_Update(t *testing.T) { 1113 transaction(func(tx *Connection) { 1114 r := require.New(t) 1115 1116 user := User{Name: nulls.NewString("Mark")} 1117 tx.Create(&user) 1118 1119 r.NotZero(user.CreatedAt) 1120 r.NotZero(user.UpdatedAt) 1121 1122 user.Name.String = "Marky" 1123 err := tx.Update(&user) 1124 r.NoError(err) 1125 1126 r.NoError(tx.Reload(&user)) 1127 r.Equal(user.Name.String, "Marky") 1128 }) 1129 } 1130 1131 func Test_Update_With_Slice(t *testing.T) { 1132 transaction(func(tx *Connection) { 1133 r := require.New(t) 1134 1135 user := Users{ 1136 {Name: nulls.NewString("Mark")}, 1137 {Name: nulls.NewString("Larry")}, 1138 } 1139 tx.Create(&user) 1140 1141 r.NotZero(user[0].CreatedAt) 1142 r.NotZero(user[0].UpdatedAt) 1143 1144 r.NotZero(user[1].CreatedAt) 1145 r.NotZero(user[1].UpdatedAt) 1146 1147 user[0].Name.String = "Marky" 1148 user[1].Name.String = "Lawrence" 1149 1150 err := tx.Update(&user) 1151 r.NoError(err) 1152 1153 r.NoError(tx.Reload(&user)) 1154 r.Equal(user[0].Name.String, "Marky") 1155 r.Equal(user[1].Name.String, "Lawrence") 1156 }) 1157 } 1158 1159 func Test_Update_UUID(t *testing.T) { 1160 transaction(func(tx *Connection) { 1161 r := require.New(t) 1162 1163 song := Song{Title: "Automatic Buffalo"} 1164 err := tx.Create(&song) 1165 r.NoError(err) 1166 1167 r.NotZero(song.CreatedAt) 1168 r.NotZero(song.UpdatedAt) 1169 1170 song.Title = "Hum" 1171 err = tx.Update(&song) 1172 r.NoError(err) 1173 1174 err = tx.Reload(&song) 1175 r.NoError(err) 1176 r.Equal("Hum", song.Title) 1177 }) 1178 } 1179 1180 func Test_Destroy(t *testing.T) { 1181 transaction(func(tx *Connection) { 1182 r := require.New(t) 1183 1184 count, err := tx.Count("users") 1185 r.NoError(err) 1186 user := User{Name: nulls.NewString("Mark")} 1187 err = tx.Create(&user) 1188 r.NoError(err) 1189 r.NotEqual(user.ID, 0) 1190 1191 ctx, err := tx.Count("users") 1192 r.NoError(err) 1193 r.Equal(count+1, ctx) 1194 1195 err = tx.Destroy(&user) 1196 r.NoError(err) 1197 1198 ctx, _ = tx.Count("users") 1199 r.Equal(count, ctx) 1200 }) 1201 } 1202 1203 func Test_Destroy_With_Slice(t *testing.T) { 1204 transaction(func(tx *Connection) { 1205 r := require.New(t) 1206 1207 count, err := tx.Count("users") 1208 r.NoError(err) 1209 user := Users{ 1210 {Name: nulls.NewString("Mark")}, 1211 {Name: nulls.NewString("Larry")}, 1212 } 1213 err = tx.Create(&user) 1214 r.NoError(err) 1215 r.NotEqual(user[0].ID, 0) 1216 r.NotEqual(user[1].ID, 0) 1217 1218 ctx, err := tx.Count("users") 1219 r.NoError(err) 1220 r.Equal(count+2, ctx) 1221 1222 err = tx.Destroy(&user) 1223 r.NoError(err) 1224 1225 ctx, _ = tx.Count("users") 1226 r.Equal(count, ctx) 1227 }) 1228 } 1229 1230 func Test_Destroy_UUID(t *testing.T) { 1231 transaction(func(tx *Connection) { 1232 r := require.New(t) 1233 1234 count, err := tx.Count("songs") 1235 r.NoError(err) 1236 song := Song{Title: "Automatic Buffalo"} 1237 err = tx.Create(&song) 1238 r.NoError(err) 1239 r.NotZero(song.ID) 1240 1241 ctx, err := tx.Count("songs") 1242 r.NoError(err) 1243 r.Equal(count+1, ctx) 1244 1245 err = tx.Destroy(&song) 1246 r.NoError(err) 1247 1248 ctx, _ = tx.Count("songs") 1249 r.Equal(count, ctx) 1250 }) 1251 } 1252 1253 func Test_TruncateAll(t *testing.T) { 1254 count := int(0) 1255 transaction(func(tx *Connection) { 1256 r := require.New(t) 1257 1258 var err error 1259 count, err = tx.Count("users") 1260 r.NoError(err) 1261 user := User{Name: nulls.NewString("Mark")} 1262 err = tx.Create(&user) 1263 r.NoError(err) 1264 r.NotEqual(user.ID, 0) 1265 1266 ctx, err := tx.Count("users") 1267 r.NoError(err) 1268 r.Equal(count+1, ctx) 1269 1270 err = tx.TruncateAll() 1271 r.NoError(err) 1272 1273 ctx, _ = tx.Count("users") 1274 r.Equal(count, ctx) 1275 }) 1276 }