github.com/cheshirekow/buildtools@v0.0.0-20200224190056-5d637702fe81/edit/edit_test.go (about) 1 /* 2 Copyright 2016 Google Inc. All Rights Reserved. 3 Licensed under the Apache License, Version 2.0 (the "License"); 4 you may not use this file except in compliance with the License. 5 You may obtain a copy of the License at 6 http://www.apache.org/licenses/LICENSE-2.0 7 Unless required by applicable law or agreed to in writing, software 8 distributed under the License is distributed on an "AS IS" BASIS, 9 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 See the License for the specific language governing permissions and 11 limitations under the License. 12 */ 13 package edit 14 15 import ( 16 "fmt" 17 "io/ioutil" 18 "os" 19 "path/filepath" 20 "reflect" 21 "regexp" 22 "strings" 23 "testing" 24 25 "github.com/cheshirekow/buildtools/build" 26 ) 27 28 var parseLabelTests = []struct { 29 in string 30 repo string 31 pkg string 32 rule string 33 }{ 34 {"//devtools/buildozer:rule", "", "devtools/buildozer", "rule"}, 35 {"devtools/buildozer:rule", "", "devtools/buildozer", "rule"}, 36 {"//devtools/buildozer", "", "devtools/buildozer", "buildozer"}, 37 {"//base", "", "base", "base"}, 38 {"//base:", "", "base", "base"}, 39 {"@r//devtools/buildozer:rule", "r", "devtools/buildozer", "rule"}, 40 {"@r//devtools/buildozer", "r", "devtools/buildozer", "buildozer"}, 41 {"@r//base", "r", "base", "base"}, 42 {"@r//base:", "r", "base", "base"}, 43 {"@foo", "foo", "", "foo"}, 44 {":label", "", "", "label"}, 45 {"label", "", "", "label"}, 46 {"/abs/path/to/WORKSPACE:rule", "", "/abs/path/to/WORKSPACE", "rule"}, 47 } 48 49 func TestParseLabel(t *testing.T) { 50 for i, tt := range parseLabelTests { 51 repo, pkg, rule := ParseLabel(tt.in) 52 if repo != tt.repo || pkg != tt.pkg || rule != tt.rule { 53 t.Errorf("%d. ParseLabel(%q) => (%q, %q, %q), want (%q, %q, %q)", 54 i, tt.in, repo, pkg, rule, tt.repo, tt.pkg, tt.rule) 55 } 56 } 57 } 58 59 var shortenLabelTests = []struct { 60 in string 61 pkg string 62 result string 63 }{ 64 {"//devtools/buildozer:rule", "devtools/buildozer", ":rule"}, 65 {"@//devtools/buildozer:rule", "devtools/buildozer", ":rule"}, 66 {"//devtools/buildozer:rule", "devtools", "//devtools/buildozer:rule"}, 67 {"//base:rule", "devtools", "//base:rule"}, 68 {"//base:base", "devtools", "//base"}, 69 {"//base", "base", ":base"}, 70 {"//devtools/buildozer:buildozer", "", "//devtools/buildozer"}, 71 {"@r//devtools/buildozer:buildozer", "devtools/buildozer", "@r//devtools/buildozer"}, 72 {"@r//devtools/buildozer", "devtools/buildozer", "@r//devtools/buildozer"}, 73 {"@r//devtools", "devtools", "@r//devtools"}, 74 {"@r:rule", "", "@r:rule"}, 75 {"@r", "", "@r"}, 76 {"@foo//:foo", "", "@foo"}, 77 {"@foo//devtools:foo", "", "@foo//devtools:foo"}, 78 {"@foo//devtools:foo", "devtools", "@foo//devtools:foo"}, 79 {"@foo//foo:foo", "", "@foo//foo"}, 80 {":local", "", ":local"}, 81 {"something else", "", "something else"}, 82 {"/path/to/file", "path/to", "/path/to/file"}, 83 } 84 85 func TestShortenLabel(t *testing.T) { 86 for i, tt := range shortenLabelTests { 87 result := ShortenLabel(tt.in, tt.pkg) 88 if result != tt.result { 89 t.Errorf("%d. ShortenLabel(%q, %q) => %q, want %q", 90 i, tt.in, tt.pkg, result, tt.result) 91 } 92 } 93 } 94 95 var labelsEqualTests = []struct { 96 label1 string 97 label2 string 98 pkg string 99 expected bool 100 }{ 101 {"//devtools/buildozer:rule", "rule", "devtools/buildozer", true}, 102 {"//devtools/buildozer:rule", "rule:jar", "devtools", false}, 103 } 104 105 func TestLabelsEqual(t *testing.T) { 106 for i, tt := range labelsEqualTests { 107 if got := LabelsEqual(tt.label1, tt.label2, tt.pkg); got != tt.expected { 108 t.Errorf("%d. LabelsEqual(%q, %q, %q) => %v, want %v", 109 i, tt.label1, tt.label2, tt.pkg, got, tt.expected) 110 } 111 } 112 } 113 114 var splitOnSpacesTests = []struct { 115 in string 116 out []string 117 }{ 118 {"a", []string{"a"}}, 119 {" abc def ", []string{"abc", "def"}}, 120 {` abc\ def `, []string{"abc def"}}, 121 {" abc def\nghi", []string{"abc", "def", "ghi"}}, 122 } 123 124 func TestSplitOnSpaces(t *testing.T) { 125 for i, tt := range splitOnSpacesTests { 126 result := SplitOnSpaces(tt.in) 127 if !reflect.DeepEqual(result, tt.out) { 128 t.Errorf("%d. SplitOnSpaces(%q) => %q, want %q", 129 i, tt.in, result, tt.out) 130 } 131 } 132 } 133 134 func TestInsertLoad(t *testing.T) { 135 tests := []struct{ input, expected string }{ 136 {``, `load("location", "symbol")`}, 137 {`load("location", "symbol")`, `load("location", "symbol")`}, 138 {`load("location", "other", "symbol")`, `load("location", "other", "symbol")`}, 139 {`load("location", "other")`, `load("location", "other", "symbol")`}, 140 { 141 `load("other loc", "symbol")`, 142 `load("location", "symbol") 143 load("other loc", "symbol")`, 144 }, 145 } 146 147 for _, tst := range tests { 148 bld, err := build.Parse("BUILD", []byte(tst.input)) 149 if err != nil { 150 t.Error(err) 151 continue 152 } 153 bld.Stmt = InsertLoad(bld.Stmt, "location", []string{"symbol"}, []string{"symbol"}) 154 got := strings.TrimSpace(string(build.Format(bld))) 155 if got != tst.expected { 156 t.Errorf("maybeInsertLoad(%s): got %s, expected %s", tst.input, got, tst.expected) 157 } 158 } 159 } 160 161 func TestReplaceLoad(t *testing.T) { 162 tests := []struct{ input, expected string }{ 163 { 164 ``, 165 `load("new_location", "symbol")`, 166 }, 167 { 168 `load("location", "symbol")`, 169 `load("new_location", "symbol")`, 170 }, 171 { 172 `load("location", "other", "symbol")`, 173 `load("new_location", "symbol") 174 load("location", "other")`, 175 }, 176 { 177 `load("location", symbol = "other")`, 178 `load("new_location", "symbol")`, 179 }, 180 { 181 `load("other loc", "symbol") 182 load("location", "symbol")`, 183 `load("new_location", "symbol")`, 184 }, 185 } 186 187 for _, tst := range tests { 188 bld, err := build.Parse("BUILD", []byte(tst.input)) 189 if err != nil { 190 t.Error(err) 191 continue 192 } 193 bld.Stmt = ReplaceLoad(bld.Stmt, "new_location", []string{"symbol"}, []string{"symbol"}) 194 got := strings.TrimSpace(string(build.Format(bld))) 195 if got != tst.expected { 196 t.Errorf("maybeReplaceLoad(%s): got %s, expected %s", tst.input, got, tst.expected) 197 } 198 } 199 } 200 201 func TestAddValueToListAttribute(t *testing.T) { 202 tests := []struct{ input, expected string }{ 203 {`rule(name="rule")`, `rule(name="rule", attr=["foo"])`}, 204 {`rule(name="rule", attr=["foo"])`, `rule(name="rule", attr=["foo"])`}, 205 {`rule(name="rule", attr=IDENT)`, `rule(name="rule", attr=IDENT+["foo"])`}, 206 {`rule(name="rule", attr=["foo"] + IDENT)`, `rule(name="rule", attr=["foo"] + IDENT)`}, 207 {`rule(name="rule", attr=["bar"] + IDENT)`, `rule(name="rule", attr=["bar", "foo"] + IDENT)`}, 208 {`rule(name="rule", attr=IDENT + ["foo"])`, `rule(name="rule", attr=IDENT + ["foo"])`}, 209 {`rule(name="rule", attr=IDENT + ["bar"])`, `rule(name="rule", attr=IDENT + ["bar", "foo"])`}, 210 } 211 212 for _, tst := range tests { 213 bld, err := build.Parse("BUILD", []byte(tst.input)) 214 if err != nil { 215 t.Error(err) 216 continue 217 } 218 rule := bld.RuleAt(1) 219 AddValueToListAttribute(rule, "attr", "", &build.StringExpr{Value: "foo"}, nil) 220 got := strings.TrimSpace(string(build.Format(bld))) 221 222 wantBld, err := build.Parse("BUILD", []byte(tst.expected)) 223 if err != nil { 224 t.Error(err) 225 continue 226 } 227 want := strings.TrimSpace(string(build.Format(wantBld))) 228 if got != want { 229 t.Errorf("AddValueToListAttribute(%s): got %s, expected %s", tst.input, got, want) 230 } 231 } 232 } 233 234 func TestSelectListsIntersection(t *testing.T) { 235 tests := []struct { 236 input string 237 expected []build.Expr 238 }{ 239 {`rule( 240 name = "rule", 241 attr = select() 242 )`, nil}, 243 {`rule( 244 name = "rule", 245 attr = select({}) 246 )`, nil}, 247 {`rule( 248 name = "rule", 249 attr = select(CONFIGS) 250 )`, nil}, 251 {`rule( 252 name = "rule", 253 attr = select({ 254 "config": "string", 255 "DEFAULT": "default" 256 }) 257 )`, nil}, 258 {`rule( 259 name = "rule", 260 attr = select({ 261 "config": LIST, 262 "DEFAULT": DEFAULT 263 }) 264 )`, nil}, 265 {`rule( 266 name = "rule", 267 attr = select({ 268 "config": ":1 :2 :3".split(" "), 269 "DEFAULT": ":2 :3".split(" ") 270 }) 271 )`, nil}, 272 {`rule( 273 name = "rule", 274 attr = select({ 275 "config1": [":1"], 276 "config2": [":2"], 277 "DEFAULT": [] 278 }) 279 )`, []build.Expr{}}, 280 {`rule( 281 name = "rule", 282 attr = select({ 283 "config1": [], 284 "config2": [":1"], 285 "DEFAULT": [":1"] 286 }) 287 )`, []build.Expr{}}, 288 {`rule( 289 name = "rule", 290 attr = select({ 291 "config1": [":1", ":2", ":3"], 292 "config2": [":2"], 293 "config3": [":2", ":3"], 294 "DEFAULT": [":1", ":2"] 295 }) 296 )`, []build.Expr{&build.StringExpr{Value: ":2"}}}, 297 {`rule( 298 name = "rule", 299 attr = select({ 300 "config1": [":4", ":3", ":1", ":5", ":2", ":6"], 301 "config2": [":5", ":2", ":6", ":1"], 302 "config3": [":1", ":2", ":3", ":4", ":5", ":6"], 303 "config4": [":2", ":1"], 304 "DEFAULT": [":3", ":4", ":1", ":2"] 305 }) 306 )`, []build.Expr{&build.StringExpr{Value: ":1"}, &build.StringExpr{Value: ":2"}}}, 307 } 308 309 for _, tst := range tests { 310 bld, err := build.Parse("BUILD", []byte(tst.input)) 311 if err != nil { 312 t.Error(err) 313 continue 314 } 315 rule := bld.RuleAt(1) 316 317 got := SelectListsIntersection(rule.Attr("attr").(*build.CallExpr), "") 318 errStr := fmt.Sprintf("TestSelectListsIntersection(%s): got %s, expected %s", tst.input, got, tst.expected) 319 320 if len(got) != len(tst.expected) { 321 t.Error(errStr) 322 } 323 324 for i := range got { 325 if got[i].(*build.StringExpr).Value != tst.expected[i].(*build.StringExpr).Value { 326 t.Error(errStr) 327 } 328 } 329 } 330 } 331 332 func TestRemoveEmptySelectsAndConcatLists(t *testing.T) { 333 tests := []struct{ input, expected string }{ 334 {`rule( 335 name = "rule", 336 attr = select({ 337 "config1": [], 338 "config2": [], 339 "DEFAULT": [] 340 }) 341 )`, `rule( 342 name = "rule", 343 attr = [] 344 )`}, 345 {`rule( 346 name = "rule", 347 attr = select({}) + select() + select({ 348 "config1": [], 349 "config2": [], 350 "DEFAULT": [] 351 }) 352 )`, `rule( 353 name = "rule", 354 attr = [] 355 )`}, 356 {`rule( 357 name = "rule", 358 attr = select({ 359 "config1": [], 360 "config2": [], 361 "DEFAULT": [] 362 }) + select(CONFIGS) 363 )`, `rule( 364 name = "rule", 365 attr = select(CONFIGS) 366 )`}, 367 {`rule( 368 name = "rule", 369 attr = [":1"] + select({ 370 "config1": [], 371 "config2": [], 372 "DEFAULT": [] 373 }) + [":2"] 374 )`, `rule( 375 name = "rule", 376 attr = [":1", ":2"] 377 )`}, 378 {`rule( 379 name = "rule", 380 attr = [":1"] + select({ 381 "config1": [], 382 "config2": [], 383 "DEFAULT": [] 384 }) + LIST + [":2"] 385 )`, `rule( 386 name = "rule", 387 attr = [":1"] + LIST + [":2"] 388 )`}, 389 {`rule( 390 name = "rule", 391 attr = [":1"] + [":2", ":3"] + select({ 392 "config1": [":4"], 393 "config2": [], 394 "DEFAULT": [] 395 }) + [] 396 )`, `rule( 397 name = "rule", 398 attr = [":1", ":2", ":3"] + select({ 399 "config1": [":4"], 400 "config2": [], 401 "DEFAULT": [] 402 }) 403 )`}, 404 {`rule( 405 name = "rule", 406 attr = [":1"] + [":2", ":3"] + select({ 407 "config1": [":4"], 408 "config2": [], 409 "DEFAULT": [] 410 }) + [] + select({ 411 "config": LIST, 412 "DEFAULT": DEFAULT, 413 }) 414 )`, `rule( 415 name = "rule", 416 attr = [":1", ":2", ":3"] + select({ 417 "config1": [":4"], 418 "config2": [], 419 "DEFAULT": [] 420 }) + select({ 421 "config": LIST, 422 "DEFAULT": DEFAULT, 423 }) 424 )`}, 425 } 426 427 for _, tst := range tests { 428 bld, err := build.Parse("BUILD", []byte(tst.input)) 429 if err != nil { 430 t.Error(err) 431 continue 432 } 433 rule := bld.RuleAt(1) 434 rule.SetAttr("attr", RemoveEmptySelectsAndConcatLists(rule.Attr("attr"))) 435 got := strings.TrimSpace(string(build.Format(bld))) 436 437 wantBld, err := build.Parse("BUILD", []byte(tst.expected)) 438 if err != nil { 439 t.Error(err) 440 continue 441 } 442 want := strings.TrimSpace(string(build.Format(wantBld))) 443 if got != want { 444 t.Errorf("RemoveEmptySelectsAndConcatLists(%s):\n got: %s,\n expected: %s", tst.input, got, want) 445 } 446 } 447 } 448 449 func TestResolveAttr(t *testing.T) { 450 tests := []struct{ input, expected string }{ 451 {`rule( 452 name = "rule", 453 attr = select({ 454 "config1": [":1"], 455 "config2": [":1"], 456 "DEFAULT": [":1"] 457 }) 458 )`, `rule( 459 name = "rule", 460 attr = [":1"] 461 )`}, 462 {`rule( 463 name = "rule", 464 attr = select({ 465 "config1": [":1"], 466 "config2": [":1"], 467 "DEFAULT": [":1"] 468 }) + select() + select({}) 469 )`, `rule( 470 name = "rule", 471 attr = [":1"] 472 )`}, 473 {`rule( 474 name = "rule", 475 attr = select({ 476 "config1": [":1"], 477 "config2": [":1"], 478 "DEFAULT": [":1"] 479 }) + LIST 480 )`, `rule( 481 name = "rule", 482 attr = LIST + [":1"] 483 )`}, 484 {`rule( 485 name = "rule", 486 attr = select({ 487 "config1": [":1"], 488 "config2": [":1"], 489 "DEFAULT": [":1"] 490 }) + select({ 491 "config": LIST, 492 "DEFAULT": DEFAULT 493 }) + select({ 494 "config": ":2 :3".split(" "), 495 "DEFAULT": ":3".split(" ") 496 }) 497 )`, `rule( 498 name = "rule", 499 attr = select({ 500 "config": LIST, 501 "DEFAULT": DEFAULT 502 }) + select({ 503 "config": ":2 :3".split(" "), 504 "DEFAULT": ":3".split(" ") 505 }) + [":1"] 506 )`}, 507 {`rule( 508 name = "rule", 509 attr = [":1"] + select({ 510 "config1": [":2"], 511 "config2": [":2"], 512 "DEFAULT": [":2"] 513 }) + [":3"] + select({ 514 "config1": [":4", ":2"], 515 "DEFAULT": [":2"] 516 }) 517 )`, `rule( 518 name = "rule", 519 attr = [":1", ":2", ":3"] + select({ 520 "config1": [":4"], 521 "DEFAULT": [] 522 }) 523 )`}, 524 {`rule( 525 name = "rule", 526 attr = [":1"] + select({ 527 "config1": [":2"], 528 "config2": [":2"], 529 "DEFAULT": [":2"] 530 }) + [":3"] + select({ 531 "config1": [":4", ":2"], 532 "DEFAULT": [":4", ":2"] 533 }) 534 )`, `rule( 535 name = "rule", 536 attr = [":1", ":2", ":4", ":3"] 537 )`}, 538 } 539 540 for _, tst := range tests { 541 bld, err := build.Parse("BUILD", []byte(tst.input)) 542 if err != nil { 543 t.Error(err) 544 continue 545 } 546 rule := bld.RuleAt(1) 547 ResolveAttr(rule, "attr", "") 548 got := strings.TrimSpace(string(build.Format(bld))) 549 550 wantBld, err := build.Parse("BUILD", []byte(tst.expected)) 551 if err != nil { 552 t.Error(err) 553 continue 554 } 555 want := strings.TrimSpace(string(build.Format(wantBld))) 556 if got != want { 557 t.Errorf("ResolveAttr(%s):\n got: %s\n expected: %s", tst.input, got, want) 558 } 559 } 560 } 561 562 func TestListSubstitute(t *testing.T) { 563 tests := []struct { 564 desc, input, oldPattern, newTemplate, want string 565 }{ 566 { 567 desc: "no_match", 568 input: `["abc"]`, 569 oldPattern: `!!`, 570 newTemplate: `xx`, 571 want: `["abc"]`, 572 }, { 573 desc: "full_match", 574 input: `["abc"]`, 575 oldPattern: `.*`, 576 newTemplate: `xx`, 577 want: `["xx"]`, 578 }, { 579 desc: "partial_match", 580 input: `["abcde"]`, 581 oldPattern: `bcd`, 582 newTemplate: `xyz`, 583 want: `["axyze"]`, 584 }, { 585 desc: "number_group", 586 input: `["abcde"]`, 587 oldPattern: `a(bcd)`, 588 newTemplate: `$1 $1`, 589 want: `["bcd bcde"]`, 590 }, { 591 desc: "name_group", 592 input: `["abcde"]`, 593 oldPattern: `a(?P<x>bcd)`, 594 newTemplate: `$x $x`, 595 want: `["bcd bcde"]`, 596 }, 597 } 598 599 for _, tst := range tests { 600 t.Run(tst.desc, func(t *testing.T) { 601 f, err := build.ParseBuild("BUILD", []byte(tst.input)) 602 if err != nil { 603 t.Fatalf("parse error: %v", err) 604 } 605 lst := f.Stmt[0] 606 oldRegexp, err := regexp.Compile(tst.oldPattern) 607 if err != nil { 608 t.Fatalf("error compiling regexp %q: %v", tst.oldPattern, err) 609 } 610 ListSubstitute(lst, oldRegexp, tst.newTemplate) 611 if got := build.FormatString(lst); got != tst.want { 612 t.Errorf("ListSubstitute(%q, %q, %q) = %q ; want %q", tst.input, tst.oldPattern, tst.newTemplate, got, tst.want) 613 } 614 }) 615 } 616 } 617 618 func compareKeyValue(a, b build.Expr) bool { 619 if a == nil && b == nil { 620 return true 621 } 622 if a == nil || b == nil { 623 return false 624 } 625 aKeyVal := a.(*build.KeyValueExpr) 626 bKeyVal := b.(*build.KeyValueExpr) 627 return aKeyVal.Key.(*build.StringExpr).Value == bKeyVal.Key.(*build.StringExpr).Value && 628 aKeyVal.Value.(*build.StringExpr).Value == bKeyVal.Value.(*build.StringExpr).Value 629 } 630 631 func TestDictionaryDelete(t *testing.T) { 632 tests := []struct { 633 input, expected string 634 expectedReturn build.Expr 635 }{ 636 { 637 `rule(attr = {"deletekey": "value"})`, 638 `rule(attr = {})`, 639 &build.KeyValueExpr{ 640 Key: &build.StringExpr{Value: "deletekey"}, 641 Value: &build.StringExpr{Value: "value"}, 642 }, 643 }, { 644 `rule(attr = {"nodeletekey": "value", "deletekey": "value"})`, 645 `rule(attr = {"nodeletekey": "value"})`, 646 &build.KeyValueExpr{ 647 Key: &build.StringExpr{Value: "deletekey"}, 648 Value: &build.StringExpr{Value: "value"}, 649 }, 650 }, { 651 `rule(attr = {"nodeletekey": "value"})`, 652 `rule(attr = {"nodeletekey": "value"})`, 653 nil, 654 }, 655 } 656 657 for _, tst := range tests { 658 bld, err := build.ParseBuild("BUILD", []byte(tst.input)) 659 if err != nil { 660 t.Error(err) 661 continue 662 } 663 rule := bld.RuleAt(1) 664 dict := rule.Call.List[0].(*build.AssignExpr).RHS.(*build.DictExpr) 665 returnVal := DictionaryDelete(dict, "deletekey") 666 got := strings.TrimSpace(string(build.Format(bld))) 667 wantBld, err := build.Parse("BUILD", []byte(tst.expected)) 668 if err != nil { 669 t.Error(err) 670 continue 671 } 672 want := strings.TrimSpace(string(build.Format(wantBld))) 673 if got != want { 674 t.Errorf("TestDictionaryDelete(%s): got %s, expected %s", tst.input, got, want) 675 } 676 if !compareKeyValue(returnVal, tst.expectedReturn) { 677 t.Errorf("TestDictionaryDelete(%s): returned %v, expected %v", tst.input, returnVal, tst.expectedReturn) 678 } 679 } 680 } 681 682 func TestPackageDeclaration(t *testing.T) { 683 tests := []struct{ input, expected string }{ 684 {``, `package(attr = "val")`}, 685 {`"""Docstring.""" 686 687 load(":path.bzl", "x") 688 689 # package() comes here 690 691 x = 2`, 692 `"""Docstring.""" 693 694 load(":path.bzl", "x") 695 696 # package() comes here 697 698 package(attr = "val") 699 700 x = 2`, 701 }, 702 } 703 704 for _, tst := range tests { 705 bld, err := build.Parse("BUILD", []byte(tst.input)) 706 if err != nil { 707 t.Error(err) 708 continue 709 } 710 pkg := PackageDeclaration(bld) 711 pkg.SetAttr("attr", &build.StringExpr{Value: "val"}) 712 got := strings.TrimSpace(string(build.Format(bld))) 713 want := strings.TrimSpace(tst.expected) 714 715 if got != want { 716 t.Errorf("TestPackageDeclaration: got:\n%s\nexpected:\n%s", got, want) 717 } 718 } 719 } 720 721 type testCase struct { 722 inputRoot, inputTarget string 723 expectedBuildFile, expectedPkg, expectedRule string 724 } 725 726 func runTestInterpretLabelForWorkspaceLocation(t *testing.T, buildFileName string) { 727 tmp, err := ioutil.TempDir("", "") 728 if err != nil { 729 t.Fatal(err) 730 } 731 defer os.RemoveAll(tmp) 732 if err := os.MkdirAll(filepath.Join(tmp, "a", "b"), 0755); err != nil { 733 t.Fatal(err) 734 } 735 if err := ioutil.WriteFile(filepath.Join(tmp, "WORKSPACE"), nil, 0755); err != nil { 736 t.Fatal(err) 737 } 738 if err := ioutil.WriteFile(filepath.Join(tmp, buildFileName), nil, 0755); err != nil { 739 t.Fatal(err) 740 } 741 if err := ioutil.WriteFile(filepath.Join(tmp, "a", buildFileName), nil, 0755); err != nil { 742 t.Fatal(err) 743 } 744 if err := ioutil.WriteFile(filepath.Join(tmp, "a", "b", buildFileName), nil, 0755); err != nil { 745 t.Fatal(err) 746 } 747 748 for _, tc := range []testCase{ 749 {tmp, "//", filepath.Join(tmp, buildFileName), "", "."}, 750 {tmp, "//a", filepath.Join(tmp, "a", buildFileName), "a", "a"}, 751 {tmp, "//a:a", filepath.Join(tmp, "a", buildFileName), "a", "a"}, 752 {tmp, "//a/b", filepath.Join(tmp, "a", "b", buildFileName), "a/b", "b"}, 753 {tmp, "//a/b:b", filepath.Join(tmp, "a", "b", buildFileName), "a/b", "b"}, 754 } { 755 buildFile, pkg, rule := InterpretLabelForWorkspaceLocation(tc.inputRoot, tc.inputTarget) 756 if buildFile != tc.expectedBuildFile || pkg != tc.expectedPkg || rule != tc.expectedRule { 757 t.Errorf("InterpretLabelForWorkspaceLocation(%q, %q) = %q, %q, %q; want %q, %q, %q", tc.inputRoot, tc.inputTarget, buildFile, pkg, rule, tc.expectedBuildFile, tc.expectedPkg, tc.expectedRule) 758 } 759 } 760 } 761 762 func TestInterpretLabelForWorkspaceLocation(t *testing.T) { 763 runTestInterpretLabelForWorkspaceLocation(t, "BUILD") 764 runTestInterpretLabelForWorkspaceLocation(t, "BUILD.bazel") 765 }