github.com/wolfd/bazel-gazelle@v0.14.0/internal/language/go/fix_test.go (about)

     1  /* Copyright 2017 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 golang
    17  
    18  import (
    19  	"testing"
    20  
    21  	"github.com/bazelbuild/bazel-gazelle/internal/merger"
    22  	"github.com/bazelbuild/bazel-gazelle/internal/rule"
    23  )
    24  
    25  type fixTestCase struct {
    26  	desc, old, want string
    27  }
    28  
    29  func TestFixFile(t *testing.T) {
    30  	for _, tc := range []fixTestCase{
    31  		// migrateLibraryEmbed tests
    32  		{
    33  			desc: "library migrated to embed",
    34  			old: `load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
    35  
    36  go_library(
    37      name = "go_default_library",
    38      srcs = ["foo.go"],
    39  )
    40  
    41  go_test(
    42      name = "go_default_test",
    43      srcs = ["foo_test.go"],
    44      library = ":go_default_library",
    45  )
    46  `,
    47  			want: `load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
    48  
    49  go_library(
    50      name = "go_default_library",
    51      srcs = ["foo.go"],
    52  )
    53  
    54  go_test(
    55      name = "go_default_test",
    56      srcs = ["foo_test.go"],
    57      embed = [":go_default_library"],
    58  )
    59  `,
    60  		}, {
    61  			// verifies #211
    62  			desc: "other library not migrated",
    63  			old: `
    64  gomock(
    65      name = "stripe_mock",
    66      out = "stripe_mock_test.go",
    67      library = ":go_default_library",
    68      interfaces = [
    69          "stSubscriptions",
    70          "stCustomers",
    71      ],
    72      package = "main",
    73      source = "stripe.go",
    74  )
    75  `,
    76  			want: `
    77  gomock(
    78      name = "stripe_mock",
    79      out = "stripe_mock_test.go",
    80      library = ":go_default_library",
    81      interfaces = [
    82          "stSubscriptions",
    83          "stCustomers",
    84      ],
    85      package = "main",
    86      source = "stripe.go",
    87  )
    88  `,
    89  		},
    90  		// migrateGrpcCompilers tests
    91  		{
    92  			desc: "go_grpc_library migrated to compilers",
    93  			old: `load("@io_bazel_rules_go//proto:def.bzl", "go_grpc_library")
    94  
    95  proto_library(
    96      name = "foo_proto",
    97      srcs = ["foo.proto"],
    98      visibility = ["//visibility:public"],
    99  )
   100  
   101  go_grpc_library(
   102      name = "foo_go_proto",
   103      importpath = "example.com/repo",
   104      proto = ":foo_proto",
   105      visibility = ["//visibility:public"],
   106  )
   107  `,
   108  			want: `load("@io_bazel_rules_go//proto:def.bzl", "go_grpc_library")
   109  
   110  proto_library(
   111      name = "foo_proto",
   112      srcs = ["foo.proto"],
   113      visibility = ["//visibility:public"],
   114  )
   115  
   116  go_proto_library(
   117      name = "foo_go_proto",
   118      compilers = ["@io_bazel_rules_go//proto:go_grpc"],
   119      importpath = "example.com/repo",
   120      proto = ":foo_proto",
   121      visibility = ["//visibility:public"],
   122  )
   123  `,
   124  		},
   125  		// flattenSrcs tests
   126  		{
   127  			desc: "flatten srcs",
   128  			old: `load("@io_bazel_rules_go//go:def.bzl", "go_library")
   129  
   130  go_library(
   131      name = "go_default_library",
   132      srcs = [
   133          "gen.go",
   134      ] + select({
   135          "@io_bazel_rules_go//platform:darwin_amd64": [
   136              # darwin
   137              "foo.go", # keep
   138          ],
   139          "@io_bazel_rules_go//platform:linux_amd64": [
   140              # linux
   141              "foo.go", # keep
   142          ],
   143      }),
   144  )
   145  `,
   146  			want: `load("@io_bazel_rules_go//go:def.bzl", "go_library")
   147  
   148  go_library(
   149      name = "go_default_library",
   150      srcs = [
   151          # darwin
   152          # linux
   153          "foo.go",  # keep
   154          "gen.go",
   155      ],
   156  )
   157  `,
   158  		},
   159  		// squashCgoLibrary tests
   160  		{
   161  			desc: "no cgo_library",
   162  			old: `load("@io_bazel_rules_go//go:def.bzl", "go_library")
   163  
   164  go_library(
   165      name = "go_default_library",
   166  )
   167  `,
   168  			want: `load("@io_bazel_rules_go//go:def.bzl", "go_library")
   169  
   170  go_library(
   171      name = "go_default_library",
   172  )
   173  `,
   174  		},
   175  		{
   176  			desc: "non-default cgo_library not removed",
   177  			old: `load("@io_bazel_rules_go//go:def.bzl", "cgo_library")
   178  
   179  cgo_library(
   180      name = "something_else",
   181  )
   182  `,
   183  			want: `load("@io_bazel_rules_go//go:def.bzl", "cgo_library")
   184  
   185  cgo_library(
   186      name = "something_else",
   187  )
   188  `,
   189  		},
   190  		{
   191  			desc: "unlinked cgo_library removed",
   192  			old: `load("@io_bazel_rules_go//go:def.bzl", "cgo_library", "go_library")
   193  
   194  go_library(
   195      name = "go_default_library",
   196      library = ":something_else",
   197  )
   198  
   199  cgo_library(
   200      name = "cgo_default_library",
   201  )
   202  `,
   203  			want: `load("@io_bazel_rules_go//go:def.bzl", "cgo_library", "go_library")
   204  
   205  go_library(
   206      name = "go_default_library",
   207      cgo = True,
   208  )
   209  `,
   210  		},
   211  		{
   212  			desc: "cgo_library replaced with go_library",
   213  			old: `load("@io_bazel_rules_go//go:def.bzl", "cgo_library")
   214  
   215  # before comment
   216  cgo_library(
   217      name = "cgo_default_library",
   218      cdeps = ["cdeps"],
   219      clinkopts = ["clinkopts"],
   220      copts = ["copts"],
   221      data = ["data"],
   222      deps = ["deps"],
   223      gc_goopts = ["gc_goopts"],
   224      srcs = [
   225          "foo.go"  # keep
   226      ],
   227      visibility = ["//visibility:private"],    
   228  )
   229  # after comment
   230  `,
   231  			want: `load("@io_bazel_rules_go//go:def.bzl", "cgo_library")
   232  
   233  # before comment
   234  go_library(
   235      name = "go_default_library",
   236      srcs = [
   237          "foo.go",  # keep
   238      ],
   239      cdeps = ["cdeps"],
   240      cgo = True,
   241      clinkopts = ["clinkopts"],
   242      copts = ["copts"],
   243      data = ["data"],
   244      gc_goopts = ["gc_goopts"],
   245      visibility = ["//visibility:private"],
   246      deps = ["deps"],
   247  )
   248  # after comment
   249  `,
   250  		}, {
   251  			desc: "cgo_library merged with go_library",
   252  			old: `load("@io_bazel_rules_go//go:def.bzl", "go_library")
   253  
   254  # before go_library
   255  go_library(
   256      name = "go_default_library",
   257      srcs = ["pure.go"],
   258      deps = ["pure_deps"],
   259      data = ["pure_data"],
   260      gc_goopts = ["pure_gc_goopts"],
   261      library = ":cgo_default_library",
   262      cgo = False,
   263  )
   264  # after go_library
   265  
   266  # before cgo_library
   267  cgo_library(
   268      name = "cgo_default_library",
   269      srcs = ["cgo.go"],
   270      deps = ["cgo_deps"],
   271      data = ["cgo_data"],
   272      gc_goopts = ["cgo_gc_goopts"],
   273      copts = ["copts"],
   274      cdeps = ["cdeps"],
   275  )
   276  # after cgo_library
   277  `,
   278  			want: `load("@io_bazel_rules_go//go:def.bzl", "go_library")
   279  
   280  # before go_library
   281  # before cgo_library
   282  go_library(
   283      name = "go_default_library",
   284      srcs = [
   285          "cgo.go",
   286          "pure.go",
   287      ],
   288      cdeps = ["cdeps"],
   289      cgo = True,
   290      copts = ["copts"],
   291      data = [
   292          "cgo_data",
   293          "pure_data",
   294      ],
   295      gc_goopts = [
   296          "cgo_gc_goopts",
   297          "pure_gc_goopts",
   298      ],
   299      deps = [
   300          "cgo_deps",
   301          "pure_deps",
   302      ],
   303  )
   304  # after go_library
   305  # after cgo_library
   306  `,
   307  		},
   308  		// squashXtest tests
   309  		{
   310  			desc: "rename xtest",
   311  			old: `load("@io_bazel_rules_go//go:def.bzl", "go_test")
   312  go_test(
   313      name = "go_default_xtest",
   314      srcs = ["x_test.go"],
   315  )
   316  `,
   317  			want: `load("@io_bazel_rules_go//go:def.bzl", "go_test")
   318  
   319  go_test(
   320      name = "go_default_test",
   321      srcs = ["x_test.go"],
   322  )
   323  `,
   324  		}, {
   325  			desc: "squash xtest",
   326  			old: `load("@io_bazel_rules_go//go:def.bzl", "go_test")
   327  
   328  go_test(
   329      name = "go_default_test",
   330      srcs = ["i_test.go"],
   331      deps = [
   332          ":i_dep",
   333          ":shared_dep",
   334      ],
   335      visibility = ["//visibility:public"],
   336  )
   337  
   338  go_test(
   339      name = "go_default_xtest",
   340      srcs = ["x_test.go"],
   341      deps = [
   342          ":x_dep",
   343          ":shared_dep",
   344      ],
   345      visibility = ["//visibility:public"],
   346  )
   347  `,
   348  			want: `load("@io_bazel_rules_go//go:def.bzl", "go_test")
   349  
   350  go_test(
   351      name = "go_default_test",
   352      srcs = [
   353          "i_test.go",
   354          "x_test.go",
   355      ],
   356      visibility = ["//visibility:public"],
   357      deps = [
   358          ":i_dep",
   359          ":shared_dep",
   360          ":x_dep",
   361      ],
   362  )
   363  `,
   364  		},
   365  		// removeLegacyProto tests
   366  		{
   367  			desc: "current proto preserved",
   368  			old: `load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
   369  
   370  go_proto_library(
   371      name = "foo_go_proto",
   372      proto = ":foo_proto",
   373  )
   374  `,
   375  			want: `load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
   376  
   377  go_proto_library(
   378      name = "foo_go_proto",
   379      proto = ":foo_proto",
   380  )
   381  `,
   382  		},
   383  		{
   384  			desc: "load and proto removed",
   385  			old: `load("@io_bazel_rules_go//proto:go_proto_library.bzl", "go_proto_library")
   386  
   387  go_proto_library(
   388      name = "go_default_library_protos",
   389      srcs = ["foo.proto"],
   390      visibility = ["//visibility:private"],
   391  )
   392  `,
   393  			want: "",
   394  		},
   395  		{
   396  			desc: "proto filegroup removed",
   397  			old: `filegroup(
   398      name = "go_default_library_protos",
   399      srcs = ["foo.proto"],
   400  )
   401  
   402  go_proto_library(name = "foo_proto")
   403  `,
   404  			want: `go_proto_library(name = "foo_proto")
   405  `,
   406  		},
   407  	} {
   408  		t.Run(tc.desc, func(t *testing.T) {
   409  			testFix(t, tc, func(f *rule.File) {
   410  				c, _, _ := testConfig()
   411  				c.ShouldFix = true
   412  				lang := New()
   413  				lang.Fix(c, f)
   414  			})
   415  		})
   416  	}
   417  }
   418  
   419  func TestFixLoads(t *testing.T) {
   420  	for _, tc := range []fixTestCase{
   421  		{
   422  			desc: "empty file",
   423  			old:  "",
   424  			want: "",
   425  		}, {
   426  			desc: "non-Go file",
   427  			old: `load("@io_bazel_rules_intercal//intercal:def.bzl", "intercal_library")
   428  
   429  intercal_library(
   430      name = "intercal_default_library",
   431      srcs = ["foo.ic"],
   432  )
   433  `,
   434  			want: `load("@io_bazel_rules_intercal//intercal:def.bzl", "intercal_library")
   435  
   436  intercal_library(
   437      name = "intercal_default_library",
   438      srcs = ["foo.ic"],
   439  )
   440  `,
   441  		}, {
   442  			desc: "empty Go load",
   443  			old: `load("@io_bazel_rules_go//go:def.bzl")
   444  `,
   445  			want: "",
   446  		}, {
   447  			desc: "add and remove loaded symbols",
   448  			old: `load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
   449  
   450  go_library(name = "go_default_library")
   451  
   452  go_binary(name = "cmd")
   453  `,
   454  			want: `load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
   455  
   456  go_library(name = "go_default_library")
   457  
   458  go_binary(name = "cmd")
   459  `,
   460  		}, {
   461  			desc: "consolidate load statements",
   462  			old: `load("@io_bazel_rules_go//go:def.bzl", "go_library")
   463  load("@io_bazel_rules_go//go:def.bzl", "go_library")
   464  load("@io_bazel_rules_go//go:def.bzl", "go_test")
   465  
   466  go_library(name = "go_default_library")
   467  
   468  go_test(name = "go_default_test")
   469  `,
   470  			want: `load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
   471  
   472  go_library(name = "go_default_library")
   473  
   474  go_test(name = "go_default_test")
   475  `,
   476  		}, {
   477  			desc: "new load statement",
   478  			old: `go_library(
   479      name = "go_default_library",
   480  )
   481  
   482  go_embed_data(
   483      name = "data",
   484  )
   485  `,
   486  			want: `load("@io_bazel_rules_go//go:def.bzl", "go_library")
   487  
   488  go_library(
   489      name = "go_default_library",
   490  )
   491  
   492  go_embed_data(
   493      name = "data",
   494  )
   495  `,
   496  		}, {
   497  			desc: "proto symbols",
   498  			old: `go_proto_library(
   499      name = "foo_proto",
   500  )
   501  
   502  go_grpc_library(
   503      name = "bar_proto",
   504  )
   505  `,
   506  			want: `load("@io_bazel_rules_go//proto:def.bzl", "go_grpc_library", "go_proto_library")
   507  
   508  go_proto_library(
   509      name = "foo_proto",
   510  )
   511  
   512  go_grpc_library(
   513      name = "bar_proto",
   514  )
   515  `,
   516  		}, {
   517  			desc: "fixLoad doesn't touch other symbols or loads",
   518  			old: `load(
   519      "@io_bazel_rules_go//go:def.bzl",
   520      "go_embed_data",  # embed
   521      "go_test",
   522      foo = "go_binary",  # binary
   523  )
   524  load("@io_bazel_rules_go//proto:go_proto_library.bzl", "go_proto_library")
   525  
   526  go_library(
   527      name = "go_default_library",
   528  )
   529  `,
   530  			want: `load(
   531      "@io_bazel_rules_go//go:def.bzl",
   532      "go_embed_data",  # embed
   533      "go_library",
   534      foo = "go_binary",  # binary
   535  )
   536  load("@io_bazel_rules_go//proto:go_proto_library.bzl", "go_proto_library")
   537  
   538  go_library(
   539      name = "go_default_library",
   540  )
   541  `,
   542  		}, {
   543  			desc: "fixLoad doesn't touch loads from other files",
   544  			old: `load(
   545      "@com_github_pubref_rules_protobuf//go:rules.bzl",
   546      "go_proto_library",
   547      go_grpc_library = "go_proto_library",
   548  )
   549  
   550  go_proto_library(
   551      name = "foo_go_proto",
   552  )
   553  
   554  grpc_proto_library(
   555      name = "bar_go_proto",
   556  )
   557  `,
   558  			want: `load(
   559      "@com_github_pubref_rules_protobuf//go:rules.bzl",
   560      "go_proto_library",
   561      go_grpc_library = "go_proto_library",
   562  )
   563  
   564  go_proto_library(
   565      name = "foo_go_proto",
   566  )
   567  
   568  grpc_proto_library(
   569      name = "bar_go_proto",
   570  )
   571  `,
   572  		}, {
   573  			desc: "moved symbol",
   574  			old: `
   575  load("@io_bazel_rules_go//go:def.bzl", "go_repository")
   576  
   577  go_repository(name = "foo")
   578  `,
   579  			want: `
   580  load("@bazel_gazelle//:deps.bzl", "go_repository")
   581  
   582  go_repository(name = "foo")
   583  `,
   584  		}, {
   585  			desc: "moved symbols with others",
   586  			old: `
   587  load("@io_bazel_rules_go//go:def.bzl", "go_rules_dependencies", "go_repository")
   588  
   589  go_rules_dependencies()
   590  
   591  go_repository(name = "foo")
   592  `,
   593  			want: `
   594  load("@io_bazel_rules_go//go:def.bzl", "go_rules_dependencies")
   595  
   596  go_rules_dependencies()
   597  
   598  load("@bazel_gazelle//:deps.bzl", "go_repository")
   599  
   600  go_repository(name = "foo")
   601  `,
   602  		}, {
   603  			desc: "load after",
   604  			old: `
   605  load("@io_bazel_rules_go//go:def.bzl", "go_rules_dependencies", "go_register_toolchains")
   606  
   607  go_rules_dependencies()
   608  
   609  go_register_toolchains()
   610  
   611  go_repository(name = "foo")
   612  `,
   613  			want: `
   614  load("@io_bazel_rules_go//go:def.bzl", "go_rules_dependencies", "go_register_toolchains")
   615  
   616  go_rules_dependencies()
   617  
   618  go_register_toolchains()
   619  
   620  load("@bazel_gazelle//:deps.bzl", "go_repository")
   621  
   622  go_repository(name = "foo")
   623  `,
   624  		},
   625  	} {
   626  		t.Run(tc.desc, func(t *testing.T) {
   627  			testFix(t, tc, func(f *rule.File) {
   628  				merger.FixLoads(f, goLoads)
   629  			})
   630  		})
   631  	}
   632  }
   633  
   634  func testFix(t *testing.T, tc fixTestCase, fix func(*rule.File)) {
   635  	f, err := rule.LoadData("old", "", []byte(tc.old))
   636  	if err != nil {
   637  		t.Fatalf("%s: parse error: %v", tc.desc, err)
   638  	}
   639  	fix(f)
   640  	want := tc.want
   641  	if len(want) > 0 && want[0] == '\n' {
   642  		// Strip leading newline, added for readability
   643  		want = want[1:]
   644  	}
   645  	if got := string(f.Format()); got != want {
   646  		t.Fatalf("%s: got %s; want %s", tc.desc, got, want)
   647  	}
   648  }