github.com/munnerz/test-infra@v0.0.0-20190108210205-ce3d181dc989/prow/plugins/golint/golint_test.go (about) 1 /* 2 Copyright 2017 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package golint 18 19 import ( 20 "fmt" 21 "reflect" 22 "strings" 23 "testing" 24 25 "github.com/sirupsen/logrus" 26 27 "k8s.io/test-infra/prow/git/localgit" 28 "k8s.io/test-infra/prow/github" 29 "k8s.io/test-infra/prow/plugins" 30 ) 31 32 var initialFiles = map[string][]byte{ 33 "bar.go": []byte(`// Package bar does an interesting thing. 34 package bar 35 36 // Foo does a thing. 37 func Foo(wow int) int { 38 return 42 + wow 39 } 40 `), 41 } 42 43 var pullFiles = map[string][]byte{ 44 "qux.go": []byte(`package bar 45 46 func Qux() error { 47 return nil 48 } 49 `), 50 "zz_generated.wowza.go": []byte(`package bar 51 52 func Qux() error { 53 return nil 54 } 55 `), 56 } 57 58 type ghc struct { 59 genfile []byte 60 pr github.PullRequest 61 changes []github.PullRequestChange 62 oldComments []github.ReviewComment 63 comment github.DraftReview 64 } 65 66 func (g *ghc) GetPullRequestChanges(org, repo string, number int) ([]github.PullRequestChange, error) { 67 return g.changes, nil 68 } 69 70 func (g *ghc) CreateReview(org, repo string, number int, r github.DraftReview) error { 71 g.comment = r 72 return nil 73 } 74 75 func (g *ghc) ListPullRequestComments(org, repo string, number int) ([]github.ReviewComment, error) { 76 return g.oldComments, nil 77 } 78 79 func (g *ghc) GetFile(org, repo, filepath, commit string) ([]byte, error) { 80 return g.genfile, nil 81 } 82 83 func (g *ghc) GetPullRequest(org, repo string, number int) (*github.PullRequest, error) { 84 return &g.pr, nil 85 } 86 87 var e = &github.GenericCommentEvent{ 88 Action: github.GenericCommentActionCreated, 89 IssueState: "open", 90 Body: "/lint", 91 User: github.User{Login: "cjwagner"}, 92 Number: 42, 93 IsPR: true, 94 Repo: github.Repo{ 95 Owner: github.User{Login: "foo"}, 96 Name: "bar", 97 FullName: "foo/bar", 98 }, 99 } 100 101 func TestMinConfidence(t *testing.T) { 102 zero := float64(0) 103 half := 0.5 104 cases := []struct { 105 name string 106 golint *plugins.Golint 107 expected float64 108 }{ 109 { 110 name: "nothing set", 111 expected: defaultConfidence, 112 }, 113 { 114 name: "no confidence set", 115 golint: &plugins.Golint{}, 116 expected: defaultConfidence, 117 }, 118 { 119 name: "confidence set to zero", 120 golint: &plugins.Golint{MinimumConfidence: &zero}, 121 expected: zero, 122 }, 123 { 124 name: "confidence set positive", 125 golint: &plugins.Golint{MinimumConfidence: &half}, 126 expected: half, 127 }, 128 } 129 for _, tc := range cases { 130 t.Run(tc.name, func(t *testing.T) { 131 actual := minConfidence(tc.golint) 132 if actual != tc.expected { 133 t.Errorf("minimum confidence %f != expected %f", actual, tc.expected) 134 } 135 }) 136 } 137 } 138 139 func TestLint(t *testing.T) { 140 lg, c, err := localgit.New() 141 if err != nil { 142 t.Fatalf("Making localgit: %v", err) 143 } 144 defer func() { 145 if err := lg.Clean(); err != nil { 146 t.Errorf("Cleaning up localgit: %v", err) 147 } 148 if err := c.Clean(); err != nil { 149 t.Errorf("Cleaning up client: %v", err) 150 } 151 }() 152 if err := lg.MakeFakeRepo("foo", "bar"); err != nil { 153 t.Fatalf("Making fake repo: %v", err) 154 } 155 if err := lg.AddCommit("foo", "bar", initialFiles); err != nil { 156 t.Fatalf("Adding initial commit: %v", err) 157 } 158 if err := lg.CheckoutNewBranch("foo", "bar", "pull/42/head"); err != nil { 159 t.Fatalf("Checking out pull branch: %v", err) 160 } 161 if err := lg.AddCommit("foo", "bar", pullFiles); err != nil { 162 t.Fatalf("Adding PR commit: %v", err) 163 } 164 165 gh := &ghc{ 166 genfile: []byte("file-prefix zz_generated"), 167 changes: []github.PullRequestChange{ 168 { 169 Filename: "qux.go", 170 Patch: "@@ -0,0 +1,5 @@\n+package bar\n+\n+func Qux() error {\n+ return nil\n+}", 171 }, 172 { 173 Filename: "zz_generated.wowza.go", 174 Patch: "@@ -0,0 +1,5 @@\n+package bar\n+\n+func Qux2() error {\n+ return nil\n+}", 175 }, 176 }, 177 } 178 if err := handle(0, gh, c, logrus.NewEntry(logrus.New()), e); err != nil { 179 t.Fatalf("Got error from handle: %v", err) 180 } 181 if len(gh.comment.Comments) != 2 { 182 t.Fatalf("Expected two comments, got %d: %v.", len(gh.comment.Comments), gh.comment.Comments) 183 } 184 for _, c := range gh.comment.Comments { 185 pos := c.Position 186 gh.oldComments = append(gh.oldComments, github.ReviewComment{ 187 Path: c.Path, 188 Position: &pos, 189 Body: c.Body, 190 }) 191 } 192 if err := handle(0, gh, c, logrus.NewEntry(logrus.New()), e); err != nil { 193 t.Fatalf("Got error from handle on second try: %v", err) 194 } 195 if len(gh.comment.Comments) != 0 { 196 t.Fatalf("Expected no comments, got %d: %v", len(gh.comment.Comments), gh.comment.Comments) 197 } 198 199 // Test that we limit comments. 200 badFileLines := []string{"package baz", ""} 201 for i := 0; i < maxComments+5; i++ { 202 badFileLines = append(badFileLines, fmt.Sprintf("type PublicType%d int", i)) 203 } 204 gh.changes = append(gh.changes, github.PullRequestChange{ 205 Filename: "baz.go", 206 Patch: fmt.Sprintf("@@ -0,0 +1,%d @@\n+%s", len(badFileLines), strings.Join(badFileLines, "\n+")), 207 }) 208 if err := lg.AddCommit("foo", "bar", map[string][]byte{"baz.go": []byte(strings.Join(badFileLines, "\n"))}); err != nil { 209 t.Fatalf("Adding PR commit: %v", err) 210 } 211 gh.oldComments = nil 212 if err := handle(0, gh, c, logrus.NewEntry(logrus.New()), e); err != nil { 213 t.Fatalf("Got error from handle on third try: %v", err) 214 } 215 if len(gh.comment.Comments) != maxComments { 216 t.Fatalf("Expected %d comments, got %d: %v", maxComments, len(gh.comment.Comments), gh.comment.Comments) 217 } 218 } 219 220 func TestLintCodeSuggestion(t *testing.T) { 221 222 var testcases = []struct { 223 name string 224 codeChange string 225 pullFiles map[string][]byte 226 comment string 227 }{ 228 { 229 name: "Check names with underscore", 230 codeChange: "@@ -0,0 +1,7 @@\n+// Package bar comment\n+package bar\n+\n+// Qux_1 comment\n+func Qux_1_Func() error {\n+ return nil\n+}", 231 pullFiles: map[string][]byte{ 232 "qux.go": []byte("// Package bar comment\npackage bar\n\n// Qux_1 comment\nfunc Qux_1() error {\n return nil\n}\n"), 233 }, 234 comment: "```suggestion\nfunc Qux1() error {\n```\nGolint naming: don't use underscores in Go names; func Qux_1 should be Qux1. [More info](http://golang.org/doc/effective_go.html#mixed-caps). <!-- golint -->", 235 }, 236 { 237 name: "Check names with all caps", 238 codeChange: "@@ -0,0 +1,7 @@\n+// Package bar comment\n+package bar\n+\n+// QUX_FUNC comment\n+func QUX_FUNC() error {\n+ return nil\n+}", 239 pullFiles: map[string][]byte{ 240 "qux.go": []byte("// Package bar comment\npackage bar\n\n// QUX_FUNC comment\nfunc QUX_FUNC() error {\n return nil\n}\n"), 241 }, 242 comment: "```suggestion\nfunc QuxFunc() error {\n```\nGolint naming: don't use ALL_CAPS in Go names; use CamelCase. [More info](https://golang.org/wiki/CodeReviewComments#mixed-caps). <!-- golint -->", 243 }, 244 { 245 name: "Correct function name", 246 codeChange: "@@ -0,0 +1,7 @@\n+// Package bar comment\n+package bar\n+\n+// QuxFunc comment\n+func QuxFunc() error {\n+ return nil\n+}", 247 pullFiles: map[string][]byte{ 248 "qux.go": []byte("// Package bar comment\npackage bar\n\n// QuxFunc comment\nfunc QuxFunc() error {\n return nil\n}\n"), 249 }, 250 comment: "", 251 }, 252 { 253 name: "Check stutter in function names", 254 codeChange: "@@ -0,0 +1,9 @@\n+/*\n+Package bar comment\n+*/\n+package bar\n+\n+// BarFunc comment\n+func BarFunc() error {\n+ return nil\n+}", 255 pullFiles: map[string][]byte{ 256 "qux.go": []byte("/*\nPackage bar comment\n*/\npackage bar\n\n// BarFunc comment\nfunc BarFunc() error {\n return nil\n}"), 257 }, 258 comment: "```suggestion\nfunc Func() error {\n```\nGolint naming: func name will be used as bar.BarFunc by other packages, and that stutters; consider calling this Func. [More info](https://golang.org/wiki/CodeReviewComments#package-names). <!-- golint -->", 259 }, 260 { 261 name: "Check stutter in type names", 262 codeChange: "@@ -0,0 +1,8 @@\n+/*\n+Package bar comment\n+*/\n+package bar\n+\n+// BarMaker comment\n+type BarMaker struct{}\n+", 263 pullFiles: map[string][]byte{ 264 "qux.go": []byte("/*\nPackage bar comment\n*/\npackage bar\n\n// BarMaker comment\ntype BarMaker struct{}\n"), 265 }, 266 comment: "```suggestion\ntype Maker struct{}\n```\nGolint naming: type name will be used as bar.BarMaker by other packages, and that stutters; consider calling this Maker. [More info](https://golang.org/wiki/CodeReviewComments#package-names). <!-- golint -->", 267 }, 268 { 269 name: "Check stutter: no stutter", 270 codeChange: "@@ -0,0 +1,8 @@\n+/*\n+Package bar comment\n+*/\n+package bar\n+\n+// barMaker comment\n+type barMaker struct{}\n+", 271 pullFiles: map[string][]byte{ 272 "qux.go": []byte("/*\nPackage bar comment\n*/\npackage bar\n\n// barMaker comment\ntype barMaker struct{}\n"), 273 }, 274 comment: "", 275 }, 276 { 277 name: "Check errorf with errors", 278 codeChange: "@@ -0,0 +1,14 @@\n+/*\n+Package bar comment\n+*/\n+package bar\n+\n+import (\n+ \"errors\"\n+ \"fmt\"\n+)\n+\n+func f(x int) error {\n+ return errors.New(fmt.Sprintf(\"something %d\", x))\n+}\n+", 279 pullFiles: map[string][]byte{ 280 "qux.go": []byte("/*\nPackage bar comment\n*/\npackage bar\n\nimport (\n \"errors\"\n \"fmt\"\n)\n\nfunc f(x int) error {\n return errors.New(fmt.Sprintf(\"something %d\", x))\n}\n"), 281 }, 282 comment: "```suggestion\n return fmt.Errorf(\"something %d\", x)\n```\nGolint errors: should replace errors.New(fmt.Sprintf(...)) with fmt.Errorf(...). <!-- golint -->", 283 }, 284 { 285 name: "Check errorf: no error", 286 codeChange: "@@ -0,0 +1,14 @@\n+/*\n+Package bar comment\n+*/\n+package bar\n+\n+import (\n+ \"errors\"\n+ \"fmt\"\n+)\n+\n+func f(x int) error {\n+ return fmt.Errorf(\"something %!d(MISSING)\", x)\n+}\n+", 287 pullFiles: map[string][]byte{ 288 "qux.go": []byte("/*\nPackage bar comment\n*/\npackage bar\n\nimport (\n \"errors\"\n \"fmt\"\n)\n\nfunc f(x int) error { return fmt.Errorf(\"something %!d(MISSING)\", x)\n}\n"), 289 }, 290 comment: "", 291 }, 292 { 293 name: "Check loop range: omit values", 294 codeChange: "@@ -0,0 +1,10 @@\n+/*\n+Package bar comment\n+*/\n+package bar\n+\n+func f() {\n+for _ = range m {\n+}\n+}\n+", 295 pullFiles: map[string][]byte{ 296 "qux.go": []byte("/*\nPackage bar comment\n*/\npackage bar\n\nfunc f() {\nfor _ = range m {\n}\n}\n"), 297 }, 298 comment: "```suggestion\nfor range m {\n```\nGolint range-loop: should omit values from range; this loop is equivalent to `for range ...`. <!-- golint -->", 299 }, 300 { 301 name: "Check loop range: omit two values", 302 codeChange: "@@ -0,0 +1,10 @@\n+/*\n+Package bar comment\n+*/\n+package bar\n+\n+func f() {\n+for _, _ = range m {\n+}\n+}\n+", 303 pullFiles: map[string][]byte{ 304 "qux.go": []byte("/*\nPackage bar comment\n*/\npackage bar\n\nfunc f() {\nfor _, _ = range m {\n}\n}\n"), 305 }, 306 comment: "```suggestion\nfor range m {\n```\nGolint range-loop: should omit values from range; this loop is equivalent to `for range ...`. <!-- golint -->", 307 }, 308 { 309 name: "Check loop range: omit 2nd value with =", 310 codeChange: "@@ -0,0 +1,11 @@\n+/*\n+Package bar comment\n+*/\n+package bar\n+\n+func f() {\n+var y = 0\n+for y, _ = range m {\n+}\n+}\n+", 311 pullFiles: map[string][]byte{ 312 "qux.go": []byte("/*\nPackage bar comment\n*/\npackage bar\n\nfunc f() {\nvar y = 0\nfor y, _ = range m {\n}\n}\n"), 313 }, 314 comment: "```suggestion\nfor y = range m {\n```\nGolint range-loop: should omit 2nd value from range; this loop is equivalent to `for y = range ...`. <!-- golint -->", 315 }, 316 { 317 name: "Check loop range: omit 2nd value with :=", 318 codeChange: "@@ -0,0 +1,10 @@\n+/*\n+Package bar comment\n+*/\n+package bar\n+\n+func f() {\n+for y, _ := range m {\n+}\n+}\n+", 319 pullFiles: map[string][]byte{ 320 "qux.go": []byte("/*\nPackage bar comment\n*/\npackage bar\n\nfunc f() {\nfor y, _ := range m {\n}\n}\n"), 321 }, 322 comment: "```suggestion\nfor y := range m {\n```\nGolint range-loop: should omit 2nd value from range; this loop is equivalent to `for y := range ...`. <!-- golint -->", 323 }, 324 { 325 name: "Check loop range: no error", 326 codeChange: "@@ -0,0 +1,10 @@\n+/*\n+Package bar comment\n+*/\n+package bar\n+\n+func f() {\n+for y := range m {\n+}\n+}\n+", 327 pullFiles: map[string][]byte{ 328 "qux.go": []byte("/*\nPackage bar comment\n*/\npackage bar\n\nfunc f() {\nfor y := range m {\n}\n}\n"), 329 }, 330 comment: "", 331 }, 332 } 333 334 lg, c, err := localgit.New() 335 if err != nil { 336 t.Fatalf("Making localgit: %v", err) 337 } 338 defer func() { 339 if err := lg.Clean(); err != nil { 340 t.Errorf("Cleaning up localgit: %v", err) 341 } 342 if err := c.Clean(); err != nil { 343 t.Errorf("Cleaning up client: %v", err) 344 } 345 }() 346 if err := lg.MakeFakeRepo("foo", "bar"); err != nil { 347 t.Fatalf("Making fake repo: %v", err) 348 } 349 if err := lg.AddCommit("foo", "bar", initialFiles); err != nil { 350 t.Fatalf("Adding initial commit: %v", err) 351 } 352 if err := lg.CheckoutNewBranch("foo", "bar", "pull/42/head"); err != nil { 353 t.Fatalf("Checking out pull branch: %v", err) 354 } 355 356 for _, test := range testcases { 357 t.Logf("Running test case %q...", test.name) 358 if err := lg.AddCommit("foo", "bar", test.pullFiles); err != nil { 359 t.Fatalf("Adding PR commit: %v", err) 360 } 361 gh := &ghc{ 362 changes: []github.PullRequestChange{ 363 { 364 Filename: "qux.go", 365 Patch: test.codeChange, 366 }, 367 }, 368 } 369 if err := handle(0, gh, c, logrus.NewEntry(logrus.New()), e); err != nil { 370 t.Fatalf("Got error from handle: %v", err) 371 } 372 373 if test.comment == "" { 374 if len(gh.comment.Comments) > 0 { 375 t.Fatalf("Expected no comment, got %d: %v.", len(gh.comment.Comments), gh.comment.Comments) 376 } 377 } else { 378 if len(gh.comment.Comments) != 1 { 379 t.Fatalf("Expected one comments, got %d: %v.", len(gh.comment.Comments), gh.comment.Comments) 380 } 381 if test.comment != gh.comment.Comments[0].Body { 382 t.Fatalf("Expected\n" + test.comment + "\n but got\n" + gh.comment.Comments[0].Body) 383 } 384 } 385 } 386 } 387 388 func TestAddedLines(t *testing.T) { 389 var testcases = []struct { 390 patch string 391 lines map[int]int 392 err bool 393 }{ 394 { 395 patch: "@@ -0,0 +1,5 @@\n+package bar\n+\n+func Qux() error {\n+ return nil\n+}", 396 lines: map[int]int{1: 1, 2: 2, 3: 3, 4: 4, 5: 5}, 397 }, 398 { 399 patch: "@@ -29,12 +29,14 @@ import (\n \t\"github.com/sirupsen/logrus\"\n \t\"sigs.k8s.io/yaml\"\n \n+\t\"k8s.io/test-infra/prow/config\"\n \t\"k8s.io/test-infra/prow/jenkins\"\n \t\"k8s.io/test-infra/prow/kube\"\n \t\"k8s.io/test-infra/prow/plank\"\n )\n \n var (\n+\tconfigPath = flag.String(\"config-path\", \"/etc/config/config\", \"Path to config.yaml.\")\n \tbuildCluster = flag.String(\"build-cluster\", \"\", \"Path to file containing a YAML-marshalled kube.Cluster object. If empty, uses the local cluster.\")\n \n \tjenkinsURL = flag.String(\"jenkins-url\", \"\", \"Jenkins URL\")\n@@ -47,18 +49,22 @@ var objReg = regexp.MustCompile(`^[\\w-]+$`)\n \n func main() {\n \tflag.Parse()\n-\n \tlogrus.SetFormatter(&logrus.JSONFormatter{})\n \n-\tkc, err := kube.NewClientInCluster(kube.ProwNamespace)\n+\tconfigAgent := &config.Agent{}\n+\tif err := configAgent.Start(*configPath); err != nil {\n+\t\tlogrus.WithError(err).Fatal(\"Error starting config agent.\")\n+\t}\n+\n+\tkc, err := kube.NewClientInCluster(configAgent.Config().ProwJobNamespace)\n \tif err != nil {\n \t\tlogrus.WithError(err).Fatal(\"Error getting client.\")\n \t}\n \tvar pkc *kube.Client\n \tif *buildCluster == \"\" {\n-\t\tpkc = kc.Namespace(kube.TestPodNamespace)\n+\t\tpkc = kc.Namespace(configAgent.Config().PodNamespace)\n \t} else {\n-\t\tpkc, err = kube.NewClientFromFile(*buildCluster, kube.TestPodNamespace)\n+\t\tpkc, err = kube.NewClientFromFile(*buildCluster, configAgent.Config().PodNamespace)\n \t\tif err != nil {\n \t\t\tlogrus.WithError(err).Fatal(\"Error getting kube client to build cluster.\")\n \t\t}", 400 lines: map[int]int{4: 32, 11: 39, 23: 54, 24: 55, 25: 56, 26: 57, 27: 58, 28: 59, 35: 65, 38: 67}, 401 }, 402 { 403 patch: "@@ -1 +0,0 @@\n-such", 404 }, 405 { 406 patch: "@@ -1,3 +0,0 @@\n-such\n-a\n-doge", 407 }, 408 { 409 patch: "@@ -0,0 +1 @@\n+wow", 410 lines: map[int]int{1: 1}, 411 }, 412 { 413 patch: "@@ -0,0 +1 @@\n+wow\n\\ No newline at end of file", 414 lines: map[int]int{1: 1}, 415 }, 416 { 417 patch: "@@ -1 +1 @@\n-doge\n+wow", 418 lines: map[int]int{2: 1}, 419 }, 420 { 421 patch: "something strange", 422 err: true, 423 }, 424 { 425 patch: "@@ -a,3 +0,0 @@\n-wow", 426 err: true, 427 }, 428 { 429 patch: "@@ -1 +1 @@", 430 err: true, 431 }, 432 { 433 patch: "", 434 }, 435 } 436 for _, tc := range testcases { 437 als, err := AddedLines(tc.patch) 438 if err == nil == tc.err { 439 t.Errorf("For patch %s\nExpected error %v, got error %v", tc.patch, tc.err, err) 440 continue 441 } 442 if len(als) != len(tc.lines) { 443 t.Errorf("For patch %s\nAdded lines has wrong length. Got %v, expected %v", tc.patch, als, tc.lines) 444 } 445 for pl, l := range tc.lines { 446 if als[l] != pl { 447 t.Errorf("For patch %s\nExpected added line %d to be %d, but got %d", tc.patch, l, pl, als[l]) 448 } 449 } 450 } 451 } 452 453 func TestModifiedGoFiles(t *testing.T) { 454 lg, c, err := localgit.New() 455 if err != nil { 456 t.Fatalf("Making localgit: %v", err) 457 } 458 defer func() { 459 if err := lg.Clean(); err != nil { 460 t.Errorf("Cleaning up localgit: %v", err) 461 } 462 if err := c.Clean(); err != nil { 463 t.Errorf("Cleaning up client: %v", err) 464 } 465 }() 466 if err := lg.MakeFakeRepo("foo", "bar"); err != nil { 467 t.Fatalf("Making fake repo: %v", err) 468 } 469 if err := lg.AddCommit("foo", "bar", initialFiles); err != nil { 470 t.Fatalf("Adding initial commit: %v", err) 471 } 472 if err := lg.CheckoutNewBranch("foo", "bar", "pull/42/head"); err != nil { 473 t.Fatalf("Checking out pull branch: %v", err) 474 } 475 if err := lg.AddCommit("foo", "bar", pullFiles); err != nil { 476 t.Fatalf("Adding PR commit: %v", err) 477 } 478 479 var testcases = []struct { 480 name string 481 gh *ghc 482 expectedModifiedFiles map[string]string 483 }{ 484 { 485 name: "modified files include vendor file", 486 gh: &ghc{ 487 changes: []github.PullRequestChange{ 488 { 489 Filename: "qux.go", 490 Patch: "@@ -0,0 +1,5 @@\n+package bar\n+\n+func Qux() error {\n+ return nil\n+}", 491 }, 492 { 493 Filename: "vendor/foo/bar.go", 494 Patch: "@@ -0,0 +1,5 @@\n+package bar\n+\n+func Qux2() error {\n+ return nil\n+}", 495 }, 496 }, 497 }, 498 expectedModifiedFiles: map[string]string{ 499 "qux.go": "@@ -0,0 +1,5 @@\n+package bar\n+\n+func Qux() error {\n+ return nil\n+}", 500 }, 501 }, 502 { 503 name: "modified files include non go file", 504 gh: &ghc{ 505 changes: []github.PullRequestChange{ 506 { 507 Filename: "qux.go", 508 Patch: "@@ -0,0 +1,5 @@\n+package bar\n+\n+func Qux() error {\n+ return nil\n+}", 509 }, 510 { 511 Filename: "foo.md", 512 Patch: "@@ -1,3 +1,4 @@\n+TODO", 513 }, 514 }, 515 }, 516 expectedModifiedFiles: map[string]string{ 517 "qux.go": "@@ -0,0 +1,5 @@\n+package bar\n+\n+func Qux() error {\n+ return nil\n+}", 518 }, 519 }, 520 { 521 name: "modified files include generated file", 522 gh: &ghc{ 523 genfile: []byte("file-prefix zz_generated"), 524 changes: []github.PullRequestChange{ 525 { 526 Filename: "qux.go", 527 Patch: "@@ -0,0 +1,5 @@\n+package bar\n+\n+func Qux() error {\n+ return nil\n+}", 528 }, 529 { 530 Filename: "zz_generated.wowza.go", 531 Patch: "@@ -0,0 +1,5 @@\n+package bar\n+\n+func Qux2() error {\n+ return nil\n+}", 532 }, 533 }, 534 }, 535 expectedModifiedFiles: map[string]string{ 536 "qux.go": "@@ -0,0 +1,5 @@\n+package bar\n+\n+func Qux() error {\n+ return nil\n+}", 537 }, 538 }, 539 { 540 name: "modified files include removed file", 541 gh: &ghc{ 542 changes: []github.PullRequestChange{ 543 { 544 Filename: "qux.go", 545 Patch: "@@ -0,0 +1,5 @@\n+package bar\n+\n+func Qux() error {\n+ return nil\n+}", 546 }, 547 { 548 Filename: "bar.go", 549 Status: github.PullRequestFileRemoved, 550 Patch: "@@ -1,5 +0,0 @@\n-package bar\n-\n-func Qux() error {\n- return nil\n-}", 551 }, 552 }, 553 }, 554 expectedModifiedFiles: map[string]string{ 555 "qux.go": "@@ -0,0 +1,5 @@\n+package bar\n+\n+func Qux() error {\n+ return nil\n+}", 556 }, 557 }, 558 { 559 name: "modified files include renamed file", 560 gh: &ghc{ 561 changes: []github.PullRequestChange{ 562 { 563 Filename: "qux.go", 564 Patch: "@@ -0,0 +1,5 @@\n+package bar\n+\n+func Qux() error {\n+ return nil\n+}", 565 }, 566 { 567 Filename: "bar.go", 568 Status: github.PullRequestFileRenamed, 569 }, 570 }, 571 }, 572 expectedModifiedFiles: map[string]string{ 573 "qux.go": "@@ -0,0 +1,5 @@\n+package bar\n+\n+func Qux() error {\n+ return nil\n+}", 574 }, 575 }, 576 { 577 name: "added and modified files", 578 gh: &ghc{ 579 changes: []github.PullRequestChange{ 580 { 581 Filename: "qux.go", 582 Status: github.PullRequestFileAdded, 583 Patch: "@@ -0,0 +1,5 @@\n+package bar\n+\n+func Qux() error {\n+ return nil\n+}", 584 }, 585 { 586 Filename: "bar.go", 587 Patch: "@@ -0,0 +1,5 @@\n+package baz\n+\n+func Bar() error {\n+ return nil\n+}", 588 }, 589 }, 590 }, 591 expectedModifiedFiles: map[string]string{ 592 "qux.go": "@@ -0,0 +1,5 @@\n+package bar\n+\n+func Qux() error {\n+ return nil\n+}", 593 "bar.go": "@@ -0,0 +1,5 @@\n+package baz\n+\n+func Bar() error {\n+ return nil\n+}", 594 }, 595 }, 596 { 597 name: "removed and renamed files", 598 gh: &ghc{ 599 changes: []github.PullRequestChange{ 600 { 601 Filename: "qux.go", 602 Status: github.PullRequestFileRemoved, 603 Patch: "@@ -1,5 +0,0 @@\n-package bar\n-\n-func Qux() error {\n- return nil\n-}", 604 }, 605 { 606 Filename: "bar.go", 607 Status: github.PullRequestFileRenamed, 608 }, 609 }, 610 }, 611 expectedModifiedFiles: map[string]string{}, 612 }, 613 } 614 for _, tc := range testcases { 615 actualModifiedFiles, _ := modifiedGoFiles(tc.gh, "foo", "bar", 9527, "0ebb33b") 616 if !reflect.DeepEqual(tc.expectedModifiedFiles, actualModifiedFiles) { 617 t.Errorf("Expected: %#v, Got %#v in case %s.", tc.expectedModifiedFiles, actualModifiedFiles, tc.name) 618 } 619 } 620 }