github.com/golang/dep@v0.5.4/manifest_test.go (about) 1 // Copyright 2016 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package dep 6 7 import ( 8 "bytes" 9 "errors" 10 "fmt" 11 "io/ioutil" 12 "log" 13 "reflect" 14 "strings" 15 "testing" 16 17 "github.com/golang/dep/gps" 18 "github.com/golang/dep/internal/test" 19 ) 20 21 func TestReadManifest(t *testing.T) { 22 h := test.NewHelper(t) 23 defer h.Cleanup() 24 25 mf := h.GetTestFile("manifest/golden.toml") 26 defer mf.Close() 27 got, _, err := readManifest(mf) 28 if err != nil { 29 t.Fatalf("should have read manifest correctly, but got err %q", err) 30 } 31 32 c, _ := gps.NewSemverConstraint("^0.12.0") 33 want := Manifest{ 34 Constraints: map[gps.ProjectRoot]gps.ProjectProperties{ 35 gps.ProjectRoot("github.com/golang/dep"): { 36 Constraint: c, 37 }, 38 gps.ProjectRoot("github.com/babble/brook"): { 39 Constraint: gps.Revision("d05d5aca9f895d19e9265839bffeadd74a2d2ecb"), 40 }, 41 }, 42 Ovr: map[gps.ProjectRoot]gps.ProjectProperties{ 43 gps.ProjectRoot("github.com/golang/dep"): { 44 Source: "https://github.com/golang/dep", 45 Constraint: gps.NewBranch("master"), 46 }, 47 }, 48 Ignored: []string{"github.com/foo/bar"}, 49 PruneOptions: gps.CascadingPruneOptions{ 50 DefaultOptions: gps.PruneNestedVendorDirs | gps.PruneNonGoFiles, 51 PerProjectOptions: make(map[gps.ProjectRoot]gps.PruneOptionSet), 52 }, 53 } 54 55 if !reflect.DeepEqual(got.Constraints, want.Constraints) { 56 t.Error("Valid manifest's dependencies did not parse as expected") 57 } 58 if !reflect.DeepEqual(got.Ovr, want.Ovr) { 59 t.Error("Valid manifest's overrides did not parse as expected") 60 } 61 if !reflect.DeepEqual(got.Ignored, want.Ignored) { 62 t.Error("Valid manifest's ignored did not parse as expected") 63 } 64 if !reflect.DeepEqual(got.PruneOptions, want.PruneOptions) { 65 t.Error("Valid manifest's prune options did not parse as expected") 66 t.Error(got.PruneOptions, want.PruneOptions) 67 } 68 } 69 70 func TestWriteManifest(t *testing.T) { 71 h := test.NewHelper(t) 72 defer h.Cleanup() 73 74 golden := "manifest/golden.toml" 75 want := h.GetTestFileString(golden) 76 c, _ := gps.NewSemverConstraint("^0.12.0") 77 m := NewManifest() 78 m.Constraints[gps.ProjectRoot("github.com/golang/dep")] = gps.ProjectProperties{ 79 Constraint: c, 80 } 81 m.Constraints[gps.ProjectRoot("github.com/babble/brook")] = gps.ProjectProperties{ 82 Constraint: gps.Revision("d05d5aca9f895d19e9265839bffeadd74a2d2ecb"), 83 } 84 m.Ovr[gps.ProjectRoot("github.com/golang/dep")] = gps.ProjectProperties{ 85 Source: "https://github.com/golang/dep", 86 Constraint: gps.NewBranch("master"), 87 } 88 m.Ignored = []string{"github.com/foo/bar"} 89 m.PruneOptions = gps.CascadingPruneOptions{ 90 DefaultOptions: gps.PruneNestedVendorDirs | gps.PruneNonGoFiles, 91 PerProjectOptions: make(map[gps.ProjectRoot]gps.PruneOptionSet), 92 } 93 94 got, err := m.MarshalTOML() 95 if err != nil { 96 t.Fatalf("error while marshaling valid manifest to TOML: %q", err) 97 } 98 99 if string(got) != want { 100 if *test.UpdateGolden { 101 if err = h.WriteTestFile(golden, string(got)); err != nil { 102 t.Fatal(err) 103 } 104 } else { 105 t.Errorf("valid manifest did not marshal to TOML as expected:\n(GOT):\n%s\n(WNT):\n%s", string(got), want) 106 } 107 } 108 } 109 110 func TestReadManifestErrors(t *testing.T) { 111 h := test.NewHelper(t) 112 defer h.Cleanup() 113 var err error 114 115 tests := []struct { 116 name string 117 file string 118 }{ 119 {"multiple constraints", "manifest/error1.toml"}, 120 {"multiple dependencies", "manifest/error2.toml"}, 121 {"multiple overrides", "manifest/error3.toml"}, 122 } 123 124 for _, tst := range tests { 125 mf := h.GetTestFile(tst.file) 126 defer mf.Close() 127 _, _, err = readManifest(mf) 128 if err == nil { 129 t.Errorf("reading manifest with %s should have caused error, but did not", tst.name) 130 } else if !strings.Contains(err.Error(), tst.name) { 131 t.Errorf("unexpected error %q; expected %s error", err, tst.name) 132 } 133 } 134 } 135 136 func TestValidateManifest(t *testing.T) { 137 cases := []struct { 138 name string 139 tomlString string 140 wantWarn []error 141 wantError error 142 }{ 143 { 144 name: "valid required", 145 tomlString: ` 146 required = ["github.com/foo/bar"] 147 `, 148 wantWarn: []error{}, 149 wantError: nil, 150 }, 151 { 152 name: "invalid required", 153 tomlString: ` 154 required = "github.com/foo/bar" 155 `, 156 wantWarn: []error{}, 157 wantError: errInvalidRequired, 158 }, 159 { 160 name: "empty required", 161 tomlString: ` 162 required = [] 163 `, 164 wantWarn: []error{}, 165 wantError: nil, 166 }, 167 { 168 name: "invalid required list", 169 tomlString: ` 170 required = [1, 2, 3] 171 `, 172 wantWarn: []error{}, 173 wantError: errInvalidRequired, 174 }, 175 { 176 name: "invalid required format", 177 tomlString: ` 178 [[required]] 179 name = "foo" 180 `, 181 wantWarn: []error{}, 182 wantError: errInvalidRequired, 183 }, 184 { 185 name: "valid ignored", 186 tomlString: ` 187 ignored = ["foo"] 188 `, 189 wantWarn: []error{}, 190 wantError: nil, 191 }, 192 { 193 name: "invalid ignored", 194 tomlString: ` 195 ignored = "foo" 196 `, 197 wantWarn: []error{}, 198 wantError: errInvalidIgnored, 199 }, 200 { 201 name: "empty ignored", 202 tomlString: ` 203 ignored = [] 204 `, 205 wantWarn: []error{}, 206 wantError: nil, 207 }, 208 { 209 name: "invalid ignored list", 210 tomlString: ` 211 ignored = [1, 2, 3] 212 `, 213 wantWarn: []error{}, 214 wantError: errInvalidIgnored, 215 }, 216 { 217 name: "invalid ignored format", 218 tomlString: ` 219 [[ignored]] 220 name = "foo" 221 `, 222 wantWarn: []error{}, 223 wantError: errInvalidIgnored, 224 }, 225 { 226 name: "valid metadata", 227 tomlString: ` 228 [metadata] 229 authors = "foo" 230 version = "1.0.0" 231 `, 232 wantWarn: []error{}, 233 wantError: nil, 234 }, 235 { 236 name: "invalid metadata", 237 tomlString: ` 238 foo = "some-value" 239 version = 14 240 241 [[bar]] 242 author = "xyz" 243 244 [[constraint]] 245 name = "github.com/foo/bar" 246 version = "" 247 `, 248 wantWarn: []error{ 249 errors.New("unknown field in manifest: foo"), 250 errors.New("unknown field in manifest: bar"), 251 errors.New("unknown field in manifest: version"), 252 }, 253 wantError: nil, 254 }, 255 { 256 name: "invalid metadata format", 257 tomlString: ` 258 metadata = "project-name" 259 260 [[constraint]] 261 name = "github.com/foo/bar" 262 `, 263 wantWarn: []error{ 264 errInvalidMetadata, 265 errors.New("branch, version, revision, or source should be provided for \"github.com/foo/bar\""), 266 }, 267 wantError: nil, 268 }, 269 { 270 name: "plain constraint", 271 tomlString: ` 272 [[constraint]] 273 name = "github.com/foo/bar" 274 `, 275 wantWarn: []error{ 276 errors.New("branch, version, revision, or source should be provided for \"github.com/foo/bar\""), 277 }, 278 wantError: nil, 279 }, 280 { 281 name: "empty constraint", 282 tomlString: ` 283 [[constraint]] 284 `, 285 wantWarn: []error{ 286 errNoName, 287 }, 288 wantError: nil, 289 }, 290 { 291 name: "invalid constraint", 292 tomlString: ` 293 constraint = "foo" 294 `, 295 wantWarn: []error{}, 296 wantError: errInvalidConstraint, 297 }, 298 { 299 name: "invalid constraint list", 300 tomlString: ` 301 constraint = ["foo", "bar"] 302 `, 303 wantWarn: []error{}, 304 wantError: errInvalidConstraint, 305 }, 306 { 307 name: "valid override", 308 tomlString: ` 309 [[override]] 310 name = "github.com/foo/bar" 311 `, 312 wantWarn: []error{}, 313 wantError: nil, 314 }, 315 { 316 name: "empty override", 317 tomlString: ` 318 [[override]] 319 `, 320 wantWarn: []error{ 321 errNoName, 322 }, 323 wantError: nil, 324 }, 325 { 326 name: "invalid override", 327 tomlString: ` 328 override = "bar" 329 `, 330 wantWarn: []error{}, 331 wantError: errInvalidOverride, 332 }, 333 { 334 name: "invalid override list", 335 tomlString: ` 336 override = ["foo", "bar"] 337 `, 338 wantWarn: []error{}, 339 wantError: errInvalidOverride, 340 }, 341 { 342 name: "invalid fields", 343 tomlString: ` 344 [[constraint]] 345 name = "github.com/foo/bar" 346 location = "some-value" 347 link = "some-other-value" 348 metadata = "foo" 349 350 [[override]] 351 nick = "foo" 352 `, 353 wantWarn: []error{ 354 errors.New("invalid key \"location\" in \"constraint\""), 355 errors.New("invalid key \"link\" in \"constraint\""), 356 errors.New("metadata in \"constraint\" should be a TOML table"), 357 errors.New("branch, version, revision, or source should be provided for \"github.com/foo/bar\""), 358 errors.New("invalid key \"nick\" in \"override\""), 359 errNoName, 360 }, 361 wantError: nil, 362 }, 363 { 364 name: "constraint metadata", 365 tomlString: ` 366 [[constraint]] 367 name = "github.com/foo/bar" 368 369 [constraint.metadata] 370 color = "blue" 371 `, 372 wantWarn: []error{ 373 errors.New("branch, version, revision, or source should be provided for \"github.com/foo/bar\""), 374 }, 375 wantError: nil, 376 }, 377 { 378 name: "invalid revision", 379 tomlString: ` 380 [[constraint]] 381 name = "github.com/foo/bar" 382 revision = "b86ad16" 383 `, 384 wantWarn: []error{ 385 errors.New("revision \"b86ad16\" should not be in abbreviated form"), 386 }, 387 wantError: nil, 388 }, 389 { 390 name: "invalid hg revision", 391 tomlString: ` 392 [[constraint]] 393 name = "foobar.com/hg" 394 revision = "8d43f8c0b836" 395 `, 396 wantWarn: []error{errors.New("revision \"8d43f8c0b836\" should not be in abbreviated form")}, 397 wantError: nil, 398 }, 399 { 400 name: "valid prune options", 401 tomlString: ` 402 [prune] 403 non-go = true 404 `, 405 wantWarn: []error{}, 406 wantError: nil, 407 }, 408 { 409 name: "invalid root prune options", 410 tomlString: ` 411 [prune] 412 non-go = false 413 `, 414 wantWarn: []error{}, 415 wantError: errInvalidRootPruneValue, 416 }, 417 { 418 name: "root options should not contain a name", 419 tomlString: ` 420 [prune] 421 go-tests = true 422 name = "github.com/golang/dep" 423 `, 424 wantWarn: []error{ 425 errRootPruneContainsName, 426 }, 427 wantError: nil, 428 }, 429 { 430 name: "invalid prune project", 431 tomlString: ` 432 [prune] 433 non-go = true 434 435 [prune.project] 436 name = "github.com/org/project" 437 non-go = true 438 `, 439 wantWarn: []error{}, 440 wantError: errInvalidPruneProject, 441 }, 442 } 443 444 for _, c := range cases { 445 t.Run(c.name, func(t *testing.T) { 446 errs, err := validateManifest(c.tomlString) 447 448 // compare validation errors 449 if err != c.wantError { 450 t.Fatalf("manifest errors are not as expected: \n\t(GOT) %v \n\t(WNT) %v", err, c.wantError) 451 } 452 453 // compare length of error slice 454 if len(errs) != len(c.wantWarn) { 455 t.Fatalf("number of manifest errors are not as expected: \n\t(GOT) %v errors(%v)\n\t(WNT) %v errors(%v).", len(errs), errs, len(c.wantWarn), c.wantWarn) 456 } 457 458 // check if the expected errors exist in actual errors slice 459 for _, er := range errs { 460 if !containsErr(c.wantWarn, er) { 461 t.Fatalf("manifest errors are not as expected: \n\t(MISSING) %v\n\t(FROM) %v", er, c.wantWarn) 462 } 463 } 464 }) 465 } 466 } 467 468 func TestCheckRedundantPruneOptions(t *testing.T) { 469 cases := []struct { 470 name string 471 pruneOptions gps.CascadingPruneOptions 472 wantWarn []error 473 }{ 474 { 475 name: "all redundant on true", 476 pruneOptions: gps.CascadingPruneOptions{ 477 DefaultOptions: 15, 478 PerProjectOptions: map[gps.ProjectRoot]gps.PruneOptionSet{ 479 "github.com/golang/dep": { 480 NestedVendor: pvtrue, 481 UnusedPackages: pvtrue, 482 NonGoFiles: pvtrue, 483 GoTests: pvtrue, 484 }, 485 }, 486 }, 487 wantWarn: []error{ 488 fmt.Errorf("redundant prune option %q set for %q", "unused-packages", "github.com/golang/dep"), 489 fmt.Errorf("redundant prune option %q set for %q", "non-go", "github.com/golang/dep"), 490 fmt.Errorf("redundant prune option %q set for %q", "go-tests", "github.com/golang/dep"), 491 }, 492 }, 493 { 494 name: "all redundant on false", 495 pruneOptions: gps.CascadingPruneOptions{ 496 DefaultOptions: 1, 497 PerProjectOptions: map[gps.ProjectRoot]gps.PruneOptionSet{ 498 "github.com/golang/dep": { 499 NestedVendor: pvtrue, 500 UnusedPackages: pvfalse, 501 NonGoFiles: pvfalse, 502 GoTests: pvfalse, 503 }, 504 }, 505 }, 506 wantWarn: []error{ 507 fmt.Errorf("redundant prune option %q set for %q", "unused-packages", "github.com/golang/dep"), 508 fmt.Errorf("redundant prune option %q set for %q", "non-go", "github.com/golang/dep"), 509 fmt.Errorf("redundant prune option %q set for %q", "go-tests", "github.com/golang/dep"), 510 }, 511 }, 512 { 513 name: "redundancy mix across multiple projects", 514 pruneOptions: gps.CascadingPruneOptions{ 515 DefaultOptions: 7, 516 PerProjectOptions: map[gps.ProjectRoot]gps.PruneOptionSet{ 517 "github.com/golang/dep": { 518 NestedVendor: pvtrue, 519 NonGoFiles: pvtrue, 520 GoTests: pvtrue, 521 }, 522 "github.com/other/project": { 523 NestedVendor: pvtrue, 524 UnusedPackages: pvfalse, 525 GoTests: pvfalse, 526 }, 527 }, 528 }, 529 wantWarn: []error{ 530 fmt.Errorf("redundant prune option %q set for %q", "non-go", "github.com/golang/dep"), 531 fmt.Errorf("redundant prune option %q set for %q", "go-tests", "github.com/other/project"), 532 }, 533 }, 534 } 535 536 for _, c := range cases { 537 t.Run(c.name, func(t *testing.T) { 538 errs := checkRedundantPruneOptions(c.pruneOptions) 539 540 // compare length of error slice 541 if len(errs) != len(c.wantWarn) { 542 t.Fatalf("number of manifest errors are not as expected:\n\t(GOT) %v errors(%v)\n\t(WNT) %v errors(%v).", len(errs), errs, len(c.wantWarn), c.wantWarn) 543 } 544 545 for _, er := range errs { 546 if !containsErr(c.wantWarn, er) { 547 t.Fatalf("manifest errors are not as expected:\n\t(MISSING)\n%v\n\t(FROM)\n%v", er, c.wantWarn) 548 } 549 } 550 }) 551 } 552 } 553 554 func TestValidateProjectRoots(t *testing.T) { 555 cases := []struct { 556 name string 557 manifest Manifest 558 wantError error 559 wantWarn []string 560 }{ 561 { 562 name: "empty Manifest", 563 manifest: Manifest{}, 564 wantError: nil, 565 wantWarn: []string{}, 566 }, 567 { 568 name: "valid project root", 569 manifest: Manifest{ 570 Constraints: map[gps.ProjectRoot]gps.ProjectProperties{ 571 gps.ProjectRoot("github.com/golang/dep"): { 572 Constraint: gps.Any(), 573 }, 574 }, 575 }, 576 wantError: nil, 577 wantWarn: []string{}, 578 }, 579 { 580 name: "invalid project roots in Constraints and Overrides", 581 manifest: Manifest{ 582 Constraints: map[gps.ProjectRoot]gps.ProjectProperties{ 583 gps.ProjectRoot("github.com/golang/dep/foo"): { 584 Constraint: gps.Any(), 585 }, 586 gps.ProjectRoot("github.com/golang/go/xyz"): { 587 Constraint: gps.Any(), 588 }, 589 gps.ProjectRoot("github.com/golang/fmt"): { 590 Constraint: gps.Any(), 591 }, 592 }, 593 Ovr: map[gps.ProjectRoot]gps.ProjectProperties{ 594 gps.ProjectRoot("github.com/golang/mock/bar"): { 595 Constraint: gps.Any(), 596 }, 597 gps.ProjectRoot("github.com/golang/mock"): { 598 Constraint: gps.Any(), 599 }, 600 }, 601 }, 602 wantError: errInvalidProjectRoot, 603 wantWarn: []string{ 604 "the name for \"github.com/golang/dep/foo\" should be changed to \"github.com/golang/dep\"", 605 "the name for \"github.com/golang/mock/bar\" should be changed to \"github.com/golang/mock\"", 606 "the name for \"github.com/golang/go/xyz\" should be changed to \"github.com/golang/go\"", 607 }, 608 }, 609 { 610 name: "invalid source path", 611 manifest: Manifest{ 612 Constraints: map[gps.ProjectRoot]gps.ProjectProperties{ 613 gps.ProjectRoot("github.com/golang"): { 614 Constraint: gps.Any(), 615 }, 616 }, 617 }, 618 wantError: errInvalidProjectRoot, 619 wantWarn: []string{}, 620 }, 621 } 622 623 h := test.NewHelper(t) 624 defer h.Cleanup() 625 626 h.TempDir("src") 627 pwd := h.Path(".") 628 629 // Capture the stderr to verify the warnings 630 stderrOutput := &bytes.Buffer{} 631 errLogger := log.New(stderrOutput, "", 0) 632 ctx := &Ctx{ 633 GOPATH: pwd, 634 Out: log.New(ioutil.Discard, "", 0), 635 Err: errLogger, 636 } 637 638 sm, err := ctx.SourceManager() 639 h.Must(err) 640 defer sm.Release() 641 642 for _, c := range cases { 643 t.Run(c.name, func(t *testing.T) { 644 // Empty the buffer for every case 645 stderrOutput.Reset() 646 err := ValidateProjectRoots(ctx, &c.manifest, sm) 647 if err != c.wantError { 648 t.Fatalf("unexpected error while validating project roots:\n\t(GOT): %v\n\t(WNT): %v", err, c.wantError) 649 } 650 651 warnings := stderrOutput.String() 652 for _, warn := range c.wantWarn { 653 if !strings.Contains(warnings, warn) { 654 t.Fatalf("expected ValidateProjectRoot errors to contain: %q", warn) 655 } 656 } 657 }) 658 } 659 } 660 661 //func TestFromRawPruneOptions(t *testing.T) { 662 //cases := []struct { 663 //name string 664 //rawPruneOptions rawPruneOptions 665 //wantOptions gps.CascadingPruneOptions 666 //}{ 667 //{ 668 //name: "global all options project no options", 669 //rawPruneOptions: rawPruneOptions{ 670 //UnusedPackages: true, 671 //NonGoFiles: true, 672 //GoTests: true, 673 //Projects: []map[string]interface{}{ 674 //{ 675 //"name": "github.com/golang/dep", 676 //pruneOptionUnusedPackages: false, 677 //pruneOptionNonGo: false, 678 //pruneOptionGoTests: false, 679 //}, 680 //}, 681 //}, 682 //wantOptions: gps.CascadingPruneOptions{ 683 //DefaultOptions: 15, 684 //PerProjectOptions: map[gps.ProjectRoot]gps.PruneOptionSet{ 685 //"github.com/golang/dep": gps.PruneOptionSet{ 686 //NestedVendor: pvtrue, 687 //UnusedPackages: pvfalse, 688 //NonGoFiles: pvfalse, 689 //GoTests: pvfalse, 690 //}, 691 //}, 692 //}, 693 //}, 694 //{ 695 //name: "global all options project mixed options", 696 //rawPruneOptions: rawPruneOptions{ 697 //UnusedPackages: true, 698 //NonGoFiles: true, 699 //GoTests: true, 700 //Projects: []map[string]interface{}{ 701 //{ 702 //"name": "github.com/golang/dep", 703 //pruneOptionUnusedPackages: false, 704 //}, 705 //}, 706 //}, 707 //wantOptions: gps.CascadingPruneOptions{ 708 //DefaultOptions: 15, 709 //PerProjectOptions: map[gps.ProjectRoot]gps.PruneOptionSet{ 710 //"github.com/golang/dep": gps.PruneOptionSet{ 711 //NestedVendor: pvtrue, 712 //UnusedPackages: pvfalse, 713 //}, 714 //}, 715 //}, 716 //}, 717 //{ 718 //name: "global no options project all options", 719 //rawPruneOptions: rawPruneOptions{ 720 //UnusedPackages: false, 721 //NonGoFiles: false, 722 //GoTests: false, 723 //Projects: []map[string]interface{}{ 724 //{ 725 //"name": "github.com/golang/dep", 726 //pruneOptionUnusedPackages: true, 727 //pruneOptionNonGo: true, 728 //pruneOptionGoTests: true, 729 //}, 730 //}, 731 //}, 732 //wantOptions: gps.CascadingPruneOptions{ 733 //DefaultOptions: 1, 734 //PerProjectOptions: map[gps.ProjectRoot]gps.PruneOptionSet{ 735 //"github.com/golang/dep": gps.PruneOptionSet{ 736 //NestedVendor: pvtrue, 737 //UnusedPackages: pvtrue, 738 //NonGoFiles: pvtrue, 739 //GoTests: pvtrue, 740 //}, 741 //}, 742 //}, 743 //}, 744 //} 745 746 //for _, c := range cases { 747 //t.Run(c.name, func(t *testing.T) { 748 //opts, err := fromRawPruneOptions(c.rawPruneOptions) 749 //if err != nil { 750 //t.Fatal(err) 751 //} 752 753 //if !reflect.DeepEqual(opts, c.wantOptions) { 754 //t.Fatalf("rawPruneOptions are not as expected:\n\t(GOT) %v\n\t(WNT) %v", opts, c.wantOptions) 755 //} 756 //}) 757 //} 758 //} 759 760 func TestToRawPruneOptions(t *testing.T) { 761 cases := []struct { 762 name string 763 pruneOptions gps.CascadingPruneOptions 764 wantOptions rawPruneOptions 765 }{ 766 { 767 name: "all options", 768 pruneOptions: gps.CascadingPruneOptions{DefaultOptions: 15}, 769 wantOptions: rawPruneOptions{ 770 UnusedPackages: true, 771 NonGoFiles: true, 772 GoTests: true, 773 }, 774 }, 775 { 776 name: "no options", 777 pruneOptions: gps.CascadingPruneOptions{DefaultOptions: 1}, 778 wantOptions: rawPruneOptions{ 779 UnusedPackages: false, 780 NonGoFiles: false, 781 GoTests: false, 782 }, 783 }, 784 } 785 786 for _, c := range cases { 787 t.Run(c.name, func(t *testing.T) { 788 raw := toRawPruneOptions(c.pruneOptions) 789 790 if !reflect.DeepEqual(raw, c.wantOptions) { 791 t.Fatalf("rawPruneOptions are not as expected:\n\t(GOT) %v\n\t(WNT) %v", raw, c.wantOptions) 792 } 793 }) 794 } 795 } 796 797 func TestToRawPruneOptions_Panic(t *testing.T) { 798 pruneOptions := gps.CascadingPruneOptions{ 799 DefaultOptions: 1, 800 PerProjectOptions: map[gps.ProjectRoot]gps.PruneOptionSet{ 801 "github.com/carolynvs/deptest": { 802 NestedVendor: pvtrue, 803 }, 804 }, 805 } 806 defer func() { 807 if err := recover(); err == nil { 808 t.Error("toRawPruneOptions did not panic with non-empty ProjectOptions") 809 } 810 }() 811 _ = toRawPruneOptions(pruneOptions) 812 } 813 814 func containsErr(s []error, e error) bool { 815 for _, a := range s { 816 if a.Error() == e.Error() { 817 return true 818 } 819 } 820 return false 821 }