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 }