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

     1  /* Copyright 2018 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 rule
    17  
    18  import (
    19  	"reflect"
    20  	"strings"
    21  	"testing"
    22  
    23  	bzl "github.com/bazelbuild/buildtools/build"
    24  )
    25  
    26  // This file contains tests for File, Load, Rule, and related functions.
    27  // Tests only cover some basic functionality and a few non-obvious cases.
    28  // Most test coverage will come from clients of this package.
    29  
    30  func TestEditAndSync(t *testing.T) {
    31  	old := []byte(`
    32  load("a.bzl", "x_library")
    33  
    34  x_library(name = "foo")
    35  
    36  load("b.bzl", y_library = "y")
    37  
    38  y_library(name = "bar")
    39  `)
    40  	f, err := LoadData("old", "", old)
    41  	if err != nil {
    42  		t.Fatal(err)
    43  	}
    44  
    45  	loadA := f.Loads[0]
    46  	loadA.Delete()
    47  	loadB := f.Loads[1]
    48  	loadB.Add("x_library")
    49  	loadB.Remove("y_library")
    50  	loadC := NewLoad("c.bzl")
    51  	loadC.Add("z_library")
    52  	loadC.Add("y_library")
    53  	loadC.Insert(f, 3)
    54  
    55  	foo := f.Rules[0]
    56  	foo.Delete()
    57  	bar := f.Rules[1]
    58  	bar.SetAttr("srcs", []string{"bar.y"})
    59  	baz := NewRule("z_library", "baz")
    60  	baz.Insert(f)
    61  
    62  	got := strings.TrimSpace(string(f.Format()))
    63  	want := strings.TrimSpace(`
    64  load("b.bzl", "x_library")
    65  load("c.bzl", "y_library", "z_library")
    66  
    67  y_library(
    68      name = "bar",
    69      srcs = ["bar.y"],
    70  )
    71  
    72  z_library(name = "baz")
    73  `)
    74  	if got != want {
    75  		t.Errorf("got:\n%s\nwant:\n%s", got, want)
    76  	}
    77  }
    78  
    79  func TestDeleteSyncDelete(t *testing.T) {
    80  	old := []byte(`
    81  x_library(name = "foo")
    82  
    83  # comment
    84  
    85  x_library(name = "bar")
    86  `)
    87  	f, err := LoadData("old", "", old)
    88  	if err != nil {
    89  		t.Fatal(err)
    90  	}
    91  
    92  	foo := f.Rules[0]
    93  	bar := f.Rules[1]
    94  	foo.Delete()
    95  	f.Sync()
    96  	bar.Delete()
    97  	f.Sync()
    98  	got := strings.TrimSpace(string(f.Format()))
    99  	want := strings.TrimSpace(`# comment`)
   100  	if got != want {
   101  		t.Errorf("got:\n%s\nwant:%s", got, want)
   102  	}
   103  }
   104  
   105  func TestSymbolsReturnsKeys(t *testing.T) {
   106  	f, err := LoadData("load", "", []byte(`load("a.bzl", "y", z = "a")`))
   107  	if err != nil {
   108  		t.Fatal(err)
   109  	}
   110  	got := f.Loads[0].Symbols()
   111  	want := []string{"y", "z"}
   112  	if !reflect.DeepEqual(got, want) {
   113  		t.Errorf("got %#v; want %#v", got, want)
   114  	}
   115  }
   116  
   117  func TestKeepRule(t *testing.T) {
   118  	for _, tc := range []struct {
   119  		desc, src string
   120  		want      bool
   121  	}{
   122  		{
   123  			desc: "prefix",
   124  			src: `
   125  # keep
   126  x_library(name = "x")
   127  `,
   128  			want: true,
   129  		}, {
   130  			desc: "compact_suffix",
   131  			src: `
   132  x_library(name = "x") # keep
   133  `,
   134  			want: true,
   135  		}, {
   136  			desc: "multiline_internal",
   137  			src: `
   138  x_library( # keep
   139      name = "x",
   140  )
   141  `,
   142  			want: false,
   143  		}, {
   144  			desc: "multiline_suffix",
   145  			src: `
   146  x_library(
   147      name = "x",
   148  ) # keep
   149  `,
   150  			want: true,
   151  		}, {
   152  			desc: "after",
   153  			src: `
   154  x_library(name = "x")
   155  # keep
   156  `,
   157  			want: false,
   158  		},
   159  	} {
   160  		t.Run(tc.desc, func(t *testing.T) {
   161  			f, err := LoadData(tc.desc, "", []byte(tc.src))
   162  			if err != nil {
   163  				t.Fatal(err)
   164  			}
   165  			if got := f.Rules[0].ShouldKeep(); got != tc.want {
   166  				t.Errorf("got %v; want %v", got, tc.want)
   167  			}
   168  		})
   169  	}
   170  }
   171  
   172  func TestShouldKeepExpr(t *testing.T) {
   173  	for _, tc := range []struct {
   174  		desc, src string
   175  		path      func(e bzl.Expr) bzl.Expr
   176  		want      bool
   177  	}{
   178  		{
   179  			desc: "before",
   180  			src: `
   181  # keep
   182  "s"
   183  `,
   184  			want: true,
   185  		}, {
   186  			desc: "suffix",
   187  			src: `
   188  "s" # keep
   189  `,
   190  			want: true,
   191  		}, {
   192  			desc: "after",
   193  			src: `
   194  "s"
   195  # keep
   196  `,
   197  			want: false,
   198  		}, {
   199  			desc: "list_elem_prefix",
   200  			src: `
   201  [
   202      # keep
   203      "s",
   204  ]
   205  `,
   206  			path: func(e bzl.Expr) bzl.Expr { return e.(*bzl.ListExpr).List[0] },
   207  			want: true,
   208  		}, {
   209  			desc: "list_elem_suffix",
   210  			src: `
   211  [
   212      "s", # keep
   213  ]
   214  `,
   215  			path: func(e bzl.Expr) bzl.Expr { return e.(*bzl.ListExpr).List[0] },
   216  			want: true,
   217  		},
   218  	} {
   219  		t.Run(tc.desc, func(t *testing.T) {
   220  			ast, err := bzl.Parse(tc.desc, []byte(tc.src))
   221  			if err != nil {
   222  				t.Fatal(err)
   223  			}
   224  			expr := ast.Stmt[0]
   225  			if tc.path != nil {
   226  				expr = tc.path(expr)
   227  			}
   228  			got := ShouldKeep(expr)
   229  			if got != tc.want {
   230  				t.Errorf("got %v; want %v", got, tc.want)
   231  			}
   232  		})
   233  	}
   234  }