github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/review/git-codereview/gofmt_test.go (about) 1 // Copyright 2014 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package main 6 7 import ( 8 "fmt" 9 "io/ioutil" 10 "os" 11 "strings" 12 "testing" 13 ) 14 15 const ( 16 goodGo = "package good\n" 17 badGo = " package bad1 " 18 badGoFixed = "package bad1\n" 19 bad2Go = " package bad2 " 20 bad2GoFixed = "package bad2\n" 21 brokenGo = "package B R O K E N" 22 ) 23 24 func TestGofmt(t *testing.T) { 25 // Test of basic operations. 26 gt := newGitTest(t) 27 defer gt.done() 28 29 gt.work(t) 30 31 if err := os.MkdirAll(gt.client+"/test/bench", 0755); err != nil { 32 t.Fatal(err) 33 } 34 write(t, gt.client+"/bad.go", badGo) 35 write(t, gt.client+"/good.go", goodGo) 36 write(t, gt.client+"/test/bad.go", badGo) 37 write(t, gt.client+"/test/good.go", goodGo) 38 write(t, gt.client+"/test/bench/bad.go", badGo) 39 write(t, gt.client+"/test/bench/good.go", goodGo) 40 trun(t, gt.client, "git", "add", ".") // make files tracked 41 42 testMain(t, "gofmt", "-l") 43 testPrintedStdout(t, "bad.go\n", "!good.go", fromSlash("!test/bad"), fromSlash("test/bench/bad.go")) 44 45 testMain(t, "gofmt", "-l") 46 testPrintedStdout(t, "bad.go\n", "!good.go", fromSlash("!test/bad"), fromSlash("test/bench/bad.go")) 47 48 testMain(t, "gofmt") 49 testNoStdout(t) 50 51 testMain(t, "gofmt", "-l") 52 testNoStdout(t) 53 54 write(t, gt.client+"/bad.go", badGo) 55 write(t, gt.client+"/broken.go", brokenGo) 56 trun(t, gt.client, "git", "add", ".") 57 testMainDied(t, "gofmt", "-l") 58 testPrintedStdout(t, "bad.go") 59 testPrintedStderr(t, "gofmt reported errors", "broken.go") 60 } 61 62 func TestGofmtSubdir(t *testing.T) { 63 // Check that gofmt prints relative paths for files in or below the current directory. 64 gt := newGitTest(t) 65 defer gt.done() 66 67 gt.work(t) 68 69 mkdir(t, gt.client+"/dir1") 70 mkdir(t, gt.client+"/longnamedir2") 71 write(t, gt.client+"/dir1/bad1.go", badGo) 72 write(t, gt.client+"/longnamedir2/bad2.go", badGo) 73 trun(t, gt.client, "git", "add", ".") // make files tracked 74 75 chdir(t, gt.client) 76 testMain(t, "gofmt", "-l") 77 testPrintedStdout(t, fromSlash("dir1/bad1.go"), fromSlash("longnamedir2/bad2.go")) 78 79 chdir(t, gt.client+"/dir1") 80 testMain(t, "gofmt", "-l") 81 testPrintedStdout(t, "bad1.go", fromSlash("!/bad1.go"), fromSlash("longnamedir2/bad2.go")) 82 83 chdir(t, gt.client+"/longnamedir2") 84 testMain(t, "gofmt", "-l") 85 testPrintedStdout(t, "bad2.go", fromSlash("!/bad2.go"), fromSlash("dir1/bad1.go")) 86 87 mkdir(t, gt.client+"/z") 88 chdir(t, gt.client+"/z") 89 testMain(t, "gofmt", "-l") 90 testPrintedStdout(t, fromSlash("longnamedir2/bad2.go"), fromSlash("dir1/bad1.go")) 91 } 92 93 func TestGofmtSubdirIndexCheckout(t *testing.T) { 94 // Like TestGofmtSubdir but bad Go files are only in index, not working copy. 95 // Check also that prints a correct path (relative or absolute) for files outside the 96 // current directory, even when running with Git before 2.3.0 which doesn't 97 // handle those right in git checkout-index --temp. 98 99 gt := newGitTest(t) 100 defer gt.done() 101 102 gt.work(t) 103 104 mkdir(t, gt.client+"/dir1") 105 mkdir(t, gt.client+"/longnamedir2") 106 write(t, gt.client+"/dir1/bad1.go", badGo) 107 write(t, gt.client+"/longnamedir2/bad2.go", badGo) 108 trun(t, gt.client, "git", "add", ".") // put files in index 109 write(t, gt.client+"/dir1/bad1.go", goodGo) 110 write(t, gt.client+"/longnamedir2/bad2.go", goodGo) 111 112 chdir(t, gt.client) 113 testMain(t, "gofmt", "-l") 114 testPrintedStdout(t, fromSlash("dir1/bad1.go (staged)"), fromSlash("longnamedir2/bad2.go (staged)")) 115 116 chdir(t, gt.client+"/dir1") 117 testMain(t, "gofmt", "-l") 118 testPrintedStdout(t, "bad1.go (staged)", fromSlash("!/bad1.go"), fromSlash("longnamedir2/bad2.go (staged)")) 119 120 chdir(t, gt.client+"/longnamedir2") 121 testMain(t, "gofmt", "-l") 122 testPrintedStdout(t, "bad2.go (staged)", fromSlash("!/bad2.go"), fromSlash("dir1/bad1.go (staged)")) 123 124 mkdir(t, gt.client+"/z") 125 chdir(t, gt.client+"/z") 126 testMain(t, "gofmt", "-l") 127 testPrintedStdout(t, fromSlash("longnamedir2/bad2.go (staged)"), fromSlash("dir1/bad1.go (staged)")) 128 } 129 130 func TestGofmtUnstaged(t *testing.T) { 131 // Test when unstaged files are different from staged ones. 132 // See TestHookPreCommitUnstaged for an explanation. 133 // In this test we use two different kinds of bad files, so that 134 // we can test having a bad file in the index and a different 135 // bad file in the working directory. 136 137 gt := newGitTest(t) 138 defer gt.done() 139 gt.work(t) 140 141 name := []string{"good", "bad", "bad2", "broken"} 142 orig := []string{goodGo, badGo, bad2Go, brokenGo} 143 fixed := []string{goodGo, badGoFixed, bad2GoFixed, brokenGo} 144 const N = 4 145 146 var allFiles, wantOut, wantErr []string 147 writeFiles := func(n int) { 148 allFiles = nil 149 wantOut = nil 150 wantErr = nil 151 for i := 0; i < N*N*N; i++ { 152 // determine n'th digit of 3-digit base-N value i 153 j := i 154 for k := 0; k < (3 - 1 - n); k++ { 155 j /= N 156 } 157 text := orig[j%N] 158 file := fmt.Sprintf("%s-%s-%s.go", name[i/N/N], name[(i/N)%N], name[i%N]) 159 allFiles = append(allFiles, file) 160 write(t, gt.client+"/"+file, text) 161 162 if (i/N)%N != i%N { 163 staged := file + " (staged)" 164 switch { 165 case strings.Contains(file, "-bad-"), strings.Contains(file, "-bad2-"): 166 wantOut = append(wantOut, staged) 167 wantErr = append(wantErr, "!"+staged) 168 case strings.Contains(file, "-broken-"): 169 wantOut = append(wantOut, "!"+staged) 170 wantErr = append(wantErr, staged) 171 default: 172 wantOut = append(wantOut, "!"+staged) 173 wantErr = append(wantErr, "!"+staged) 174 } 175 } 176 switch { 177 case strings.Contains(file, "-bad.go"), strings.Contains(file, "-bad2.go"): 178 if (i/N)%N != i%N { 179 file += " (unstaged)" 180 } 181 wantOut = append(wantOut, file+"\n") 182 wantErr = append(wantErr, "!"+file+":", "!"+file+" (unstaged)") 183 case strings.Contains(file, "-broken.go"): 184 wantOut = append(wantOut, "!"+file+"\n", "!"+file+" (unstaged)") 185 wantErr = append(wantErr, file+":") 186 default: 187 wantOut = append(wantOut, "!"+file+"\n", "!"+file+":", "!"+file+" (unstaged)") 188 wantErr = append(wantErr, "!"+file+"\n", "!"+file+":", "!"+file+" (unstaged)") 189 } 190 } 191 } 192 193 // committed files 194 writeFiles(0) 195 trun(t, gt.client, "git", "add", ".") 196 trun(t, gt.client, "git", "commit", "-m", "msg") 197 198 // staged files 199 writeFiles(1) 200 trun(t, gt.client, "git", "add", ".") 201 202 // unstaged files 203 writeFiles(2) 204 205 // Check that gofmt -l shows the right output and errors. 206 testMainDied(t, "gofmt", "-l") 207 testPrintedStdout(t, wantOut...) 208 testPrintedStderr(t, wantErr...) 209 210 // Again (last command should not have written anything). 211 testMainDied(t, "gofmt", "-l") 212 testPrintedStdout(t, wantOut...) 213 testPrintedStderr(t, wantErr...) 214 215 // Reformat in place. 216 testMainDied(t, "gofmt") 217 testNoStdout(t) 218 testPrintedStderr(t, wantErr...) 219 220 // Read files to make sure unstaged did not bleed into staged. 221 for i, file := range allFiles { 222 if data, err := ioutil.ReadFile(gt.client + "/" + file); err != nil { 223 t.Errorf("%v", err) 224 } else if want := fixed[i%N]; string(data) != want { 225 t.Errorf("%s: working tree = %q, want %q", file, string(data), want) 226 } 227 if data, want := trun(t, gt.client, "git", "show", ":"+file), fixed[i/N%N]; data != want { 228 t.Errorf("%s: index = %q, want %q", file, data, want) 229 } 230 if data, want := trun(t, gt.client, "git", "show", "HEAD:"+file), orig[i/N/N]; data != want { 231 t.Errorf("%s: commit = %q, want %q", file, data, want) 232 } 233 } 234 235 // Check that gofmt -l still shows the errors. 236 testMainDied(t, "gofmt", "-l") 237 testNoStdout(t) 238 testPrintedStderr(t, wantErr...) 239 } 240 241 func TestGofmtAmbiguousRevision(t *testing.T) { 242 gt := newGitTest(t) 243 defer gt.done() 244 245 t.Logf("creating file that conflicts with revision parameter") 246 write(t, gt.client+"/HEAD", "foo") 247 248 testMain(t, "gofmt") 249 } 250 251 func TestGofmtFastForwardMerge(t *testing.T) { 252 gt := newGitTest(t) 253 defer gt.done() 254 255 // merge dev.branch into master 256 write(t, gt.server+"/file", "more work") 257 trun(t, gt.server, "git", "commit", "-m", "work", "file") 258 trun(t, gt.server, "git", "merge", "-m", "merge", "dev.branch") 259 260 // add bad go file on master 261 write(t, gt.server+"/bad.go", "package {\n") 262 trun(t, gt.server, "git", "add", "bad.go") 263 trun(t, gt.server, "git", "commit", "-m", "bad go") 264 265 // update client 266 trun(t, gt.client, "git", "checkout", "master") 267 trun(t, gt.client, "git", "pull") 268 testMain(t, "change", "dev.branch") 269 trun(t, gt.client, "git", "pull") 270 271 // merge master into dev.branch, fast forward merge 272 trun(t, gt.client, "git", "merge", "--ff-only", "master") 273 274 // verify that now client is in a state where just the tag is changing; there's no new commit. 275 masterHash := strings.TrimSpace(trun(t, gt.server, "git", "rev-parse", "master")) 276 devHash := strings.TrimSpace(trun(t, gt.client, "git", "rev-parse", "HEAD")) 277 278 if masterHash != devHash { 279 t.Logf("branches:\n%s", trun(t, gt.client, "git", "branch", "-a", "-v")) 280 t.Logf("log:\n%s", trun(t, gt.client, "git", "log", "--graph", "--decorate")) 281 t.Fatalf("setup wrong - got different commit hashes on master and dev branch") 282 } 283 284 // check that gofmt finds nothing to do, ignoring the bad (but committed) file1.go. 285 testMain(t, "gofmt") 286 testNoStdout(t) 287 testNoStderr(t) 288 }