github.com/please-build/puku@v1.7.3-0.20240516143641-f7d7f4941f57/generate/generate_test.go (about) 1 package generate 2 3 import ( 4 "testing" 5 6 "github.com/stretchr/testify/assert" 7 "github.com/stretchr/testify/require" 8 9 "github.com/please-build/puku/config" 10 "github.com/please-build/puku/edit" 11 "github.com/please-build/puku/kinds" 12 "github.com/please-build/puku/please" 13 ) 14 15 func TestAllocateSources(t *testing.T) { 16 foo := newRule(edit.NewRuleExpr("go_library", "foo"), kinds.DefaultKinds["go_library"], "") 17 fooTest := newRule(edit.NewRuleExpr("go_test", "foo_test"), kinds.DefaultKinds["go_test"], "") 18 19 foo.addSrc("foo.go") 20 fooTest.addSrc("foo_test.go") 21 22 rules := []*rule{foo, fooTest} 23 24 files := map[string]*GoFile{ 25 "bar.go": { 26 Name: "foo", 27 FileName: "bar.go", 28 }, 29 "bar_test.go": { 30 Name: "foo", 31 FileName: "bar_test.go", 32 }, 33 "external_test.go": { 34 Name: "foo_test", 35 FileName: "external_test.go", 36 }, 37 "foo.go": { 38 Name: "foo", 39 FileName: "foo.go", 40 }, 41 "foo_test.go": { 42 Name: "foo", 43 FileName: "foo_test.go", 44 }, 45 } 46 47 u := newUpdater(new(please.Config)) 48 conf := &config.Config{PleasePath: "plz"} 49 newRules, err := u.allocateSources(conf, "foo", files, rules) 50 require.NoError(t, err) 51 52 require.Len(t, newRules, 1) 53 assert.Equal(t, "foo_test", newRules[0].Name()) 54 assert.ElementsMatch(t, []string{"external_test.go"}, mustGetSources(t, u, newRules[0])) 55 56 assert.ElementsMatch(t, []string{"foo.go", "bar.go"}, mustGetSources(t, u, rules[0])) 57 assert.ElementsMatch(t, []string{"foo_test.go", "bar_test.go"}, mustGetSources(t, u, rules[1])) 58 } 59 60 func TestAddingLibDepToTest(t *testing.T) { 61 foo := newRule(edit.NewRuleExpr("go_library", "foo"), kinds.DefaultKinds["go_library"], "") 62 fooTest := newRule(edit.NewRuleExpr("go_test", "foo_test"), kinds.DefaultKinds["go_test"], "") 63 64 files := map[string]*GoFile{ 65 "foo.go": { 66 Name: "foo", 67 FileName: "foo.go", 68 }, 69 "foo_test.go": { 70 Name: "foo", 71 FileName: "foo_test.go", 72 }, 73 } 74 75 foo.SetAttr(foo.SrcsAttr(), edit.NewStringList([]string{"foo.go"})) 76 fooTest.SetAttr(fooTest.SrcsAttr(), edit.NewStringList([]string{"foo_test.go"})) 77 78 u := newUpdater(new(please.Config)) 79 conf := &config.Config{PleasePath: "plz"} 80 err := u.updateRuleDeps(conf, fooTest, []*rule{foo, fooTest}, files) 81 require.NoError(t, err) 82 83 assert.Equal(t, fooTest.AttrStrings("deps"), []string{":foo"}) 84 } 85 86 func TestAllocateSourcesToCustomKind(t *testing.T) { 87 exampleKind := &kinds.Kind{ 88 Name: "go_example_lib", 89 Type: kinds.Lib, 90 SrcsAttr: "go_srcs", 91 } 92 93 satKind := &kinds.Kind{ 94 Name: "service_acceptance_test", 95 Type: kinds.Test, 96 } 97 98 foo := newRule(edit.NewRuleExpr("go_example_lib", "foo"), exampleKind, "") 99 fooTest := newRule(edit.NewRuleExpr("go_test", "foo_test"), satKind, "") 100 101 foo.addSrc("foo.go") 102 fooTest.addSrc("foo_test.go") 103 104 rules := []*rule{foo, fooTest} 105 106 files := map[string]*GoFile{ 107 "bar.go": { 108 Name: "foo", 109 FileName: "bar.go", 110 }, 111 "bar_test.go": { 112 Name: "foo", 113 FileName: "bar_test.go", 114 }, 115 "foo.go": { 116 Name: "foo", 117 FileName: "foo.go", 118 }, 119 "foo_test.go": { 120 Name: "foo", 121 FileName: "foo_test.go", 122 }, 123 } 124 125 u := newUpdater(new(please.Config)) 126 conf := &config.Config{PleasePath: "plz"} 127 newRules, err := u.allocateSources(conf, "foo", files, rules) 128 require.NoError(t, err) 129 130 assert.Len(t, newRules, 0) 131 132 assert.ElementsMatch(t, []string{"foo.go", "bar.go"}, mustGetSources(t, u, rules[0])) 133 assert.Equal(t, rules[0].SrcsAttr(), exampleKind.SrcsAttr) 134 assert.ElementsMatch(t, []string{"foo_test.go", "bar_test.go"}, mustGetSources(t, u, rules[1])) 135 } 136 137 func TestAllocateSourcesToNonGoKind(t *testing.T) { 138 exampleKind := &kinds.Kind{ 139 Name: "go_example_lib", 140 Type: kinds.Lib, 141 NonGoSources: true, 142 } 143 144 foo := newRule(edit.NewRuleExpr("go_example_lib", "nogo"), exampleKind, "") 145 146 rules := []*rule{foo} 147 148 files := map[string]*GoFile{ 149 "foo.go": { 150 Name: "foo", 151 FileName: "foo.go", 152 }, 153 } 154 155 u := newUpdater(new(please.Config)) 156 u.plzConf = &please.Config{} 157 newRules, err := u.allocateSources(new(config.Config), "foo", files, rules) 158 require.NoError(t, err) 159 160 require.Len(t, newRules, 1) 161 162 assert.ElementsMatch(t, []string{}, mustGetSources(t, u, foo)) 163 assert.Equal(t, "go_library", newRules[0].Kind()) 164 assert.ElementsMatch(t, []string{"foo.go"}, mustGetSources(t, u, newRules[0])) 165 } 166 167 func TestUpdateDeps(t *testing.T) { 168 type ruleKind struct { 169 kind *kinds.Kind 170 srcs []string 171 } 172 173 testCases := []struct { 174 name string 175 srcs []*GoFile 176 rule *ruleKind 177 expectedDeps []string 178 modules []string 179 installs map[string]string 180 conf *config.Config 181 proxy FakeProxy 182 }{ 183 { 184 name: "adds import from known module", 185 srcs: []*GoFile{ 186 { 187 FileName: "foo.go", 188 Imports: []string{"github.com/example/module/foo"}, 189 Name: "foo", 190 }, 191 }, 192 modules: []string{"github.com/example/module"}, 193 rule: &ruleKind{ 194 srcs: []string{"foo.go"}, 195 kind: kinds.DefaultKinds["go_library"], 196 }, 197 expectedDeps: []string{"///third_party/go/github.com_example_module//foo"}, 198 }, 199 { 200 name: "handles installs", 201 srcs: []*GoFile{ 202 { 203 FileName: "foo.go", 204 Imports: []string{ 205 "github.com/example/module1/foo", 206 "github.com/example/module2/foo/bar/baz", 207 }, 208 Name: "foo", 209 }, 210 }, 211 modules: []string{}, 212 installs: map[string]string{ 213 "github.com/example/module1/foo": "//third_party/go:module1", 214 "github.com/example/module2/...": "//third_party/go:module2", 215 }, 216 rule: &ruleKind{ 217 srcs: []string{"foo.go"}, 218 kind: kinds.DefaultKinds["go_library"], 219 }, 220 221 expectedDeps: []string{"//third_party/go:module1", "//third_party/go:module2"}, 222 }, 223 { 224 name: "handles custom kinds", 225 srcs: []*GoFile{ 226 { 227 FileName: "foo.go", 228 Imports: []string{ 229 "github.com/example/module/foo", 230 "github.com/example/module/bar", 231 }, 232 Name: "foo", 233 }, 234 }, 235 modules: []string{"github.com/example/module"}, 236 rule: &ruleKind{ 237 srcs: []string{"foo.go"}, 238 kind: &kinds.Kind{ 239 Name: "example_library", 240 Type: kinds.Lib, 241 ProvidedDeps: []string{"///third_party/go/github.com_example_module//foo"}, 242 }, 243 }, 244 expectedDeps: []string{"///third_party/go/github.com_example_module//bar"}, 245 }, 246 { 247 name: "handles missing src", 248 srcs: []*GoFile{}, 249 modules: []string{"github.com/example/module"}, 250 rule: &ruleKind{ 251 srcs: []string{"foo.go"}, 252 kind: &kinds.Kind{ 253 Name: "example_library", 254 Type: kinds.Lib, 255 ProvidedDeps: []string{"///third_party/go/github.com_example_module//foo"}, 256 }, 257 }, 258 expectedDeps: []string{}, 259 }, 260 } 261 262 for _, tc := range testCases { 263 t.Run(tc.name, func(t *testing.T) { 264 plzConf := new(please.Config) 265 plzConf.Plugin.Go.ImportPath = []string{"github.com/this/module"} 266 u := newUpdater(plzConf) 267 u.modules = tc.modules 268 u.proxy = tc.proxy 269 270 for path, value := range tc.installs { 271 u.installs.Add(path, value) 272 } 273 274 conf := tc.conf 275 if conf == nil { 276 conf = new(config.Config) 277 } 278 279 r := newRule(edit.NewRuleExpr(tc.rule.kind.Name, "rule"), tc.rule.kind, "") 280 for _, src := range tc.rule.srcs { 281 r.addSrc(src) 282 } 283 284 files := make(map[string]*GoFile, len(tc.srcs)) 285 srcNames := make([]string, 0, len(tc.srcs)) 286 for _, f := range tc.srcs { 287 files[f.FileName] = f 288 srcNames = append(srcNames, f.FileName) 289 } 290 291 err := u.updateRuleDeps(conf, r, []*rule{}, files) 292 require.NoError(t, err) 293 assert.ElementsMatch(t, tc.expectedDeps, r.AttrStrings("deps")) 294 assert.ElementsMatch(t, srcNames, r.AttrStrings(r.SrcsAttr())) 295 }) 296 } 297 } 298 299 func mustGetSources(t *testing.T, u *updater, rule *rule) []string { 300 t.Helper() 301 302 srcs, err := u.eval.EvalGlobs(rule.dir, rule.Rule, rule.SrcsAttr()) 303 require.NoError(t, err) 304 return srcs 305 }