github.com/afking/bazel-gazelle@v0.0.0-20180301150245-c02bc0f529e8/internal/merger/merger_test.go (about)

     1  /* Copyright 2016 The Bazel Authors. All rights reserved.
     2  
     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  
     7     http://www.apache.org/licenses/LICENSE-2.0
     8  
     9  Unless required by applicable law or agreed to in writing, software
    10  distributed under the License is distributed on an "AS IS" BASIS,
    11  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  See the License for the specific language governing permissions and
    13  limitations under the License.
    14  */
    15  
    16  package merger
    17  
    18  import (
    19  	"testing"
    20  
    21  	bf "github.com/bazelbuild/buildtools/build"
    22  )
    23  
    24  // should fix
    25  // * updated srcs from new
    26  // * data and size preserved from old
    27  // * load stmt fixed to those in use and sorted
    28  
    29  type testCase struct {
    30  	desc, previous, current, empty, expected string
    31  	ignore                                   bool
    32  }
    33  
    34  var testCases = []testCase{
    35  	{
    36  		desc: "basic functionality",
    37  		previous: `
    38  load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_prefix", "go_test")
    39  
    40  go_prefix("github.com/jr_hacker/tools")
    41  
    42  go_library(
    43      name = "go_default_library",
    44      srcs = [
    45          "lex.go",
    46          "print.go",
    47          "debug.go",
    48      ],
    49  )
    50  
    51  go_test(
    52      name = "go_default_test",
    53      size = "small",
    54      srcs = [
    55          "gen_test.go",  # keep
    56          "parse_test.go",
    57      ],
    58      data = glob(["testdata/*"]),
    59      embed = [":go_default_library"],
    60  )
    61  `,
    62  		current: `
    63  load("@io_bazel_rules_go//go:def.bzl", "go_test", "go_library")
    64  
    65  go_prefix("")
    66  
    67  go_library(
    68      name = "go_default_library",
    69      srcs = [
    70          "lex.go",
    71          "print.go",
    72      ],
    73  )
    74  
    75  go_test(
    76      name = "go_default_test",
    77      srcs = [
    78          "parse_test.go",
    79          "print_test.go",
    80      ],
    81      embed = [":go_default_library"],
    82  )
    83  `,
    84  		expected: `
    85  load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_prefix", "go_test")
    86  
    87  go_prefix("github.com/jr_hacker/tools")
    88  
    89  go_library(
    90      name = "go_default_library",
    91      srcs = [
    92          "lex.go",
    93          "print.go",
    94      ],
    95  )
    96  
    97  go_test(
    98      name = "go_default_test",
    99      size = "small",
   100      srcs = [
   101          "gen_test.go",  # keep
   102          "parse_test.go",
   103          "print_test.go",
   104      ],
   105      data = glob(["testdata/*"]),
   106      embed = [":go_default_library"],
   107  )
   108  `}, {
   109  		desc: "merge dicts",
   110  		previous: `
   111  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   112  
   113  go_library(
   114      name = "go_default_library",
   115      srcs = select({
   116          "darwin_amd64": [
   117              "foo_darwin_amd64.go", # keep
   118              "bar_darwin_amd64.go",
   119          ],
   120          "linux_arm": [
   121              "foo_linux_arm.go", # keep
   122              "bar_linux_arm.go",
   123          ],
   124      }),
   125  )
   126  `,
   127  		current: `
   128  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   129  
   130  go_library(
   131      name = "go_default_library",
   132      srcs = select({
   133          "linux_arm": ["baz_linux_arm.go"],
   134          "darwin_amd64": ["baz_darwin_amd64.go"],
   135          "//conditions:default": [],
   136      }),
   137  )
   138  `,
   139  		expected: `
   140  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   141  
   142  go_library(
   143      name = "go_default_library",
   144      srcs = select({
   145          "darwin_amd64": [
   146              "foo_darwin_amd64.go",  # keep
   147              "baz_darwin_amd64.go",
   148          ],
   149          "linux_arm": [
   150              "foo_linux_arm.go",  # keep
   151              "baz_linux_arm.go",
   152          ],
   153          "//conditions:default": [],
   154      }),
   155  )
   156  `,
   157  	}, {
   158  		desc: "merge old dict with gen list",
   159  		previous: `
   160  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   161  
   162  go_library(
   163      name = "go_default_library",
   164      srcs = select({
   165          "linux_arm": [
   166              "foo_linux_arm.go", # keep
   167              "bar_linux_arm.go", # keep
   168          ],
   169          "darwin_amd64": [
   170              "bar_darwin_amd64.go",
   171          ],
   172      }),
   173  )
   174  `,
   175  		current: `
   176  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   177  
   178  go_library(
   179      name = "go_default_library",
   180      srcs = ["baz.go"],
   181  )
   182  `,
   183  		expected: `
   184  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   185  
   186  go_library(
   187      name = "go_default_library",
   188      srcs = [
   189          "baz.go",
   190      ] + select({
   191          "linux_arm": [
   192              "foo_linux_arm.go",  # keep
   193              "bar_linux_arm.go",  # keep
   194          ],
   195      }),
   196  )
   197  `,
   198  	}, {
   199  		desc: "merge old list with gen dict",
   200  		previous: `
   201  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   202  
   203  go_library(
   204      name = "go_default_library",
   205      srcs = [
   206          "foo.go", # keep
   207          "bar.go", # keep
   208      ],
   209  )
   210  `,
   211  		current: `
   212  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   213  
   214  go_library(
   215      name = "go_default_library",
   216      srcs = select({
   217          "linux_arm": [
   218              "foo_linux_arm.go",
   219              "bar_linux_arm.go",
   220          ],
   221          "darwin_amd64": [
   222              "bar_darwin_amd64.go",
   223          ],
   224          "//conditions:default": [],
   225      }),
   226  )
   227  `,
   228  		expected: `
   229  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   230  
   231  go_library(
   232      name = "go_default_library",
   233      srcs = [
   234          "foo.go",  # keep
   235          "bar.go",  # keep
   236      ] + select({
   237          "linux_arm": [
   238              "foo_linux_arm.go",
   239              "bar_linux_arm.go",
   240          ],
   241          "darwin_amd64": [
   242              "bar_darwin_amd64.go",
   243          ],
   244          "//conditions:default": [],
   245      }),
   246  )
   247  `,
   248  	}, {
   249  		desc: "merge old list and dict with gen list and dict",
   250  		previous: `
   251  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   252  
   253  go_library(
   254      name = "go_default_library",
   255      srcs = [
   256          "foo.go",  # keep
   257          "bar.go",
   258      ] + select({
   259          "linux_arm": [
   260              "foo_linux_arm.go",  # keep
   261          ],
   262          "//conditions:default": [],
   263      }),
   264  )
   265  `,
   266  		current: `
   267  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   268  
   269  go_library(
   270      name = "go_default_library",
   271      srcs = ["baz.go"] + select({
   272          "linux_arm": ["bar_linux_arm.go"],
   273          "darwin_amd64": ["foo_darwin_amd64.go"],
   274          "//conditions:default": [],
   275      }),
   276  )
   277  `,
   278  		expected: `
   279  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   280  
   281  go_library(
   282      name = "go_default_library",
   283      srcs = [
   284          "foo.go",  # keep
   285          "baz.go",
   286      ] + select({
   287          "darwin_amd64": ["foo_darwin_amd64.go"],
   288          "linux_arm": [
   289              "foo_linux_arm.go",  # keep
   290              "bar_linux_arm.go",
   291          ],
   292          "//conditions:default": [],
   293      }),
   294  )
   295  `,
   296  	}, {
   297  		desc: "os and arch",
   298  		previous: `
   299  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   300  
   301  go_library(
   302      name = "go_default_library",
   303      srcs = [
   304          "generic_1.go",
   305      ] + select({
   306          "@io_bazel_rules_go//go/platform:linux": [
   307              "os_linux.go",  # keep
   308          ],
   309          "//conditions:default": [],
   310      }),
   311  )
   312  `,
   313  		current: `
   314  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   315  
   316  go_library(
   317      name = "go_default_library",
   318      srcs = [
   319          "generic_2.go",
   320      ] + select({
   321          "@io_bazel_rules_go//go/platform:amd64": ["arch_amd64.go"],
   322          "//conditions:default": [],
   323      }),
   324  )
   325  `,
   326  		expected: `
   327  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   328  
   329  go_library(
   330      name = "go_default_library",
   331      srcs = [
   332          "generic_2.go",
   333      ] + select({
   334          "@io_bazel_rules_go//go/platform:linux": [
   335              "os_linux.go",  # keep
   336          ],
   337          "//conditions:default": [],
   338      }) + select({
   339          "@io_bazel_rules_go//go/platform:amd64": ["arch_amd64.go"],
   340          "//conditions:default": [],
   341      }),
   342  )
   343  `,
   344  	}, {
   345  		desc: "merge error keeps old",
   346  		previous: `
   347  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   348  
   349  go_library(
   350      name = "go_default_library",
   351      srcs = glob(["*.go"]),
   352  )
   353  `,
   354  		current: `
   355  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   356  
   357  go_library(
   358      name = "go_default_library",
   359      srcs = ["foo.go"],
   360  )
   361  `,
   362  		expected: `
   363  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   364  
   365  go_library(
   366      name = "go_default_library",
   367      srcs = glob(["*.go"]),
   368  )
   369  `,
   370  	}, {
   371  		desc: "delete empty list",
   372  		previous: `
   373  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   374  
   375  go_library(
   376      name = "go_default_library",
   377      srcs = ["deleted.go"],
   378  )
   379  `,
   380  		current: `
   381  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   382  
   383  go_library(
   384      name = "go_default_library",
   385      srcs = select({
   386          "linux_arm": ["foo_linux_arm.go"],
   387      }),
   388  )
   389  `,
   390  		expected: `
   391  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   392  
   393  go_library(
   394      name = "go_default_library",
   395      srcs = select({
   396          "linux_arm": ["foo_linux_arm.go"],
   397      }),
   398  )
   399  `,
   400  	}, {
   401  		desc: "delete empty dict",
   402  		previous: `
   403  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   404  
   405  go_library(
   406      name = "go_default_library",
   407      srcs = select({
   408          "linux_arm": ["foo_linux_arm.go"],
   409          "//conditions:default": [],
   410      }),
   411  )
   412  `,
   413  		current: `
   414  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   415  
   416  go_library(
   417      name = "go_default_library",
   418      srcs = ["foo.go"],
   419  )
   420  `,
   421  		expected: `
   422  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   423  
   424  go_library(
   425      name = "go_default_library",
   426      srcs = ["foo.go"],
   427  )
   428  `,
   429  	}, {
   430  		desc: "delete empty attr",
   431  		previous: `
   432  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   433  
   434  go_library(
   435      name = "go_default_library",
   436      srcs = ["foo.go"],
   437      embed = ["deleted"],
   438  )
   439  `,
   440  		current: `
   441  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   442  
   443  go_library(
   444      name = "go_default_library",
   445      srcs = ["foo.go"],
   446  )
   447  `,
   448  		expected: `
   449  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   450  
   451  go_library(
   452      name = "go_default_library",
   453      srcs = ["foo.go"],
   454  )
   455  `,
   456  	}, {
   457  		desc: "merge comments",
   458  		previous: `
   459  # load
   460  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   461  
   462  # rule
   463  go_library(
   464      # unmerged attr
   465      name = "go_default_library",
   466      # merged attr
   467      srcs = ["foo.go"],
   468  )
   469  `,
   470  		current: `
   471  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   472  
   473  go_library(
   474      name = "go_default_library",
   475      srcs = ["foo.go"],
   476  )
   477  `,
   478  		expected: `
   479  # load
   480  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   481  
   482  # rule
   483  go_library(
   484      # unmerged attr
   485      name = "go_default_library",
   486      # merged attr
   487      srcs = ["foo.go"],
   488  )
   489  `,
   490  	}, {
   491  		desc: "preserve comments",
   492  		previous: `
   493  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   494  
   495  go_library(
   496      name = "go_default_library",
   497      srcs = [
   498          "a.go",  # preserve
   499          "b.go",  # comments
   500      ],
   501  )
   502  `,
   503  		current: `
   504  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   505  
   506  go_library(
   507      name = "go_default_library",
   508      srcs = ["a.go", "b.go"],
   509  )
   510  `,
   511  		expected: `
   512  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   513  
   514  go_library(
   515      name = "go_default_library",
   516      srcs = [
   517          "a.go",  # preserve
   518          "b.go",  # comments
   519      ],
   520  )
   521  `,
   522  	}, {
   523  		desc: "merge copts and clinkopts",
   524  		previous: `
   525  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   526  
   527  go_library(
   528      name = "cgo_default_library",
   529      copts = [
   530          "-O0",
   531          "-g",  # keep
   532      ],
   533      clinkopts = [
   534          "-lX11",
   535      ],
   536  )
   537  `,
   538  		current: `
   539  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   540  
   541  go_library(
   542      name = "cgo_default_library",
   543      cgo = True,
   544      copts = [
   545          "-O2",
   546      ],
   547      clinkopts = [
   548          "-lpng",
   549      ],
   550  )
   551  `,
   552  		expected: `
   553  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   554  
   555  go_library(
   556      name = "cgo_default_library",
   557      copts = [
   558          "-g",  # keep
   559          "-O2",
   560      ],
   561      clinkopts = [
   562          "-lpng",
   563      ],
   564      cgo = True,
   565  )
   566  `,
   567  	}, {
   568  		desc: "keep scalar attr",
   569  		previous: `
   570  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   571  
   572  go_library(
   573      name = "go_default_library",
   574      embed = [":lib"],  # keep
   575  )
   576  `,
   577  		current: `
   578  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   579  
   580  go_library(
   581      name = "go_default_library",
   582  )
   583  `,
   584  		expected: `
   585  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   586  
   587  go_library(
   588      name = "go_default_library",
   589      embed = [":lib"],  # keep
   590  )
   591  `,
   592  	}, {
   593  		desc: "don't delete list with keep",
   594  		previous: `
   595  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   596  
   597  go_library(
   598      name = "go_default_library",
   599      srcs = [
   600          "one.go",  # keep
   601      ],
   602  )
   603  `,
   604  		current: `
   605  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   606  
   607  go_library(
   608      name = "go_default_library",
   609  )
   610  `,
   611  		expected: `
   612  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   613  
   614  go_library(
   615      name = "go_default_library",
   616      srcs = [
   617          "one.go",  # keep
   618      ],
   619  )
   620  `,
   621  	}, {
   622  		desc: "keep list multiline",
   623  		previous: `
   624  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   625  
   626  go_library(
   627      name = "go_default_library",
   628      srcs = [
   629          "one.go",  # keep
   630          "two.go",
   631      ],
   632  )
   633  `,
   634  		current: `
   635  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   636  
   637  go_library(
   638      name = "go_default_library",
   639  )
   640  `,
   641  		expected: `
   642  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   643  
   644  go_library(
   645      name = "go_default_library",
   646      srcs = [
   647          "one.go",  # keep
   648      ],
   649  )
   650  `,
   651  	}, {
   652  		desc: "keep dict list multiline",
   653  		previous: `
   654  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   655  
   656  go_library(
   657      name = "go_default_library",
   658      srcs = select({
   659          "darwin_amd64": [
   660              "one_darwin.go",  # keep
   661          ],
   662          "linux_arm": [
   663              "one_linux.go",  # keep
   664              "two_linux.go",
   665          ],
   666      }),
   667  )
   668  `,
   669  		current: `
   670  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   671  
   672  go_library(
   673      name = "go_default_library",
   674  )
   675  `,
   676  		expected: `
   677  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   678  
   679  go_library(
   680      name = "go_default_library",
   681      srcs = select({
   682          "darwin_amd64": [
   683              "one_darwin.go",  # keep
   684          ],
   685          "linux_arm": [
   686              "one_linux.go",  # keep
   687          ],
   688      }),
   689  )
   690  `,
   691  	}, {
   692  		desc: "keep prevents delete",
   693  		previous: `
   694  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   695  
   696  # keep
   697  go_library(
   698      name = "go_default_library",
   699      srcs = ["lib.go"],
   700  )
   701  `,
   702  		empty: `
   703  go_library(name = "go_default_library")
   704  `,
   705  		expected: `
   706  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   707  
   708  # keep
   709  go_library(
   710      name = "go_default_library",
   711      srcs = ["lib.go"],
   712  )
   713  `,
   714  	}, {
   715  		desc: "keep prevents merge",
   716  		previous: `
   717  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   718  
   719  # keep
   720  go_library(
   721      name = "go_default_library",
   722      srcs = ["old.go"],
   723  )
   724  `,
   725  		current: `
   726  go_library(
   727      name = "go_default_library",
   728      srcs = ["new.go"],
   729  )
   730  `,
   731  		expected: `
   732  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   733  
   734  # keep
   735  go_library(
   736      name = "go_default_library",
   737      srcs = ["old.go"],
   738  )
   739  `,
   740  	}, {
   741  		desc: "delete empty rule",
   742  		previous: `
   743  load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
   744  
   745  go_library(
   746      name = "go_default_library",
   747      srcs = ["lib.go"],
   748  )
   749  
   750  go_binary(
   751      name = "old",
   752      srcs = ["bin.go"],
   753      embed = [":go_default_library"],
   754      importpath = "foo",
   755  )
   756  `,
   757  		current: `
   758  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   759  
   760  go_library(
   761      name = "go_default_library",
   762      srcs = ["lib.go"],
   763  )
   764  `,
   765  		empty: `
   766  go_binary(name = "old")
   767  `,
   768  		expected: `
   769  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   770  
   771  go_library(
   772      name = "go_default_library",
   773      srcs = ["lib.go"],
   774  )
   775  `,
   776  	}, {
   777  		desc: "don't delete kept rule",
   778  		previous: `
   779  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   780  
   781  go_library(
   782      name = "go_default_library",
   783      srcs = [
   784          "lib.go",  # keep
   785      ],
   786  )
   787  `,
   788  		empty: `go_library(name = "go_default_library")`,
   789  		expected: `
   790  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   791  
   792  go_library(
   793      name = "go_default_library",
   794      srcs = [
   795          "lib.go",  # keep
   796      ],
   797  )
   798  `,
   799  	}, {
   800  		desc: "match and rename",
   801  		previous: `
   802  load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
   803  load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
   804  
   805  go_binary(
   806      name = "custom_bin",
   807      embed = [":custom_library"],
   808  )
   809  
   810  go_library(
   811      name = "custom_library",
   812      embed = [":custom_proto_library"],
   813      importpath = "example.com/repo/foo",
   814  )
   815  
   816  go_proto_library(
   817      name = "custom_proto_library",
   818      importpath = "example.com/repo/foo",
   819      proto = ":foo_proto",
   820  )
   821  `,
   822  		current: `
   823  go_binary(
   824      name = "bin",
   825      srcs = ["bin.go"],
   826      embed = [":go_default_library"],
   827  )
   828  
   829  go_library(
   830      name = "go_default_library",
   831      srcs = ["lib.go"],
   832      embed = [":foo_proto_library"],
   833      importpath = "example.com/repo/foo",
   834  )
   835  
   836  go_proto_library(
   837      name = "foo_proto_library",
   838      importpath = "example.com/repo/foo",
   839      proto = ":foo_proto",
   840  )
   841  `,
   842  		expected: `
   843  load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
   844  load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
   845  
   846  go_binary(
   847      name = "custom_bin",
   848      embed = [":custom_library"],
   849      srcs = ["bin.go"],
   850  )
   851  
   852  go_library(
   853      name = "custom_library",
   854      embed = [":custom_proto_library"],
   855      importpath = "example.com/repo/foo",
   856      srcs = ["lib.go"],
   857  )
   858  
   859  go_proto_library(
   860      name = "custom_proto_library",
   861      importpath = "example.com/repo/foo",
   862      proto = ":foo_proto",
   863  )
   864  `,
   865  	},
   866  }
   867  
   868  func TestMergeFile(t *testing.T) {
   869  	for _, tc := range testCases {
   870  		t.Run(tc.desc, func(t *testing.T) {
   871  			genFile, err := bf.Parse("current", []byte(tc.current))
   872  			if err != nil {
   873  				t.Fatalf("%s: %v", tc.desc, err)
   874  			}
   875  			oldFile, err := bf.Parse("previous", []byte(tc.previous))
   876  			if err != nil {
   877  				t.Fatalf("%s: %v", tc.desc, err)
   878  			}
   879  			emptyFile, err := bf.Parse("empty", []byte(tc.empty))
   880  			if err != nil {
   881  				t.Fatalf("%s: %v", tc.desc, err)
   882  			}
   883  			mergedFile, _ := MergeFile(genFile.Stmt, emptyFile.Stmt, oldFile, PreResolveAttrs)
   884  			if mergedFile == nil {
   885  				if !tc.ignore {
   886  					t.Errorf("%s: got nil; want file", tc.desc)
   887  				}
   888  				return
   889  			}
   890  			if mergedFile != nil && tc.ignore {
   891  				t.Fatalf("%s: got file; want nil", tc.desc)
   892  			}
   893  			mergedFile = FixLoads(mergedFile)
   894  
   895  			want := tc.expected
   896  			if len(want) > 0 && want[0] == '\n' {
   897  				want = want[1:]
   898  			}
   899  
   900  			if got := string(bf.Format(mergedFile)); got != want {
   901  				t.Fatalf("%s: got %s; want %s", tc.desc, got, want)
   902  			}
   903  		})
   904  	}
   905  }
   906  
   907  func TestMatch(t *testing.T) {
   908  	for _, tc := range []struct {
   909  		desc, gen, old string
   910  		wantIndex      int
   911  		wantError      bool
   912  	}{
   913  		{
   914  			desc:      "no_match",
   915  			gen:       `go_library(name = "lib")`,
   916  			wantIndex: -1,
   917  		}, {
   918  			desc:      "name_match",
   919  			gen:       `go_library(name = "lib")`,
   920  			old:       `go_library(name = "lib", srcs = ["lib.go"])`,
   921  			wantIndex: 0,
   922  		}, {
   923  			desc:      "name_match_kind_different",
   924  			gen:       `go_library(name = "lib")`,
   925  			old:       `cc_library(name = "lib")`,
   926  			wantError: true,
   927  		}, {
   928  			desc: "multiple_name_match",
   929  			gen:  `go_library(name = "lib")`,
   930  			old: `
   931  go_library(name = "lib")
   932  go_library(name = "lib")
   933  `,
   934  			wantError: true,
   935  		}, {
   936  			desc:      "attr_match",
   937  			gen:       `go_library(name = "x", importpath = "foo")`,
   938  			old:       `go_library(name = "y", importpath = "foo")`,
   939  			wantIndex: 0,
   940  		}, {
   941  			desc: "multiple_attr_match",
   942  			gen:  `go_library(name = "x", importpath = "foo")`,
   943  			old: `
   944  go_library(name = "y", importpath = "foo")
   945  go_library(name = "z", importpath = "foo")
   946  `,
   947  			wantError: true,
   948  		}, {
   949  			desc:      "any_match",
   950  			gen:       `go_binary(name = "x")`,
   951  			old:       `go_binary(name = "y")`,
   952  			wantIndex: 0,
   953  		}, {
   954  			desc: "multiple_any_match",
   955  			gen:  `go_binary(name = "x")`,
   956  			old: `
   957  go_binary(name = "y")
   958  go_binary(name = "z")
   959  `,
   960  			wantError: true,
   961  		},
   962  	} {
   963  		t.Run(tc.desc, func(t *testing.T) {
   964  			genFile, err := bf.Parse("gen", []byte(tc.gen))
   965  			if err != nil {
   966  				t.Fatal(err)
   967  			}
   968  			oldFile, err := bf.Parse("old", []byte(tc.old))
   969  			if err != nil {
   970  				t.Fatal(err)
   971  			}
   972  			if _, gotIndex, gotErr := match(oldFile.Stmt, genFile.Stmt[0].(*bf.CallExpr)); gotErr != nil {
   973  				if !tc.wantError {
   974  					t.Fatalf("unexpected error: %v", gotErr)
   975  				}
   976  			} else if tc.wantError {
   977  				t.Fatal("unexpected success")
   978  			} else if gotIndex != tc.wantIndex {
   979  				t.Fatalf("got index %d ; want %d", gotIndex, tc.wantIndex)
   980  			}
   981  		})
   982  	}
   983  }