GoPLS Viewer

Home|gopls/cmd/fiximports/main_test.go
1// Copyright 2015 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// No testdata on Android.
6
7//go:build !android
8// +build !android
9
10package main
11
12import (
13    "bytes"
14    "log"
15    "os"
16    "path/filepath"
17    "runtime"
18    "strings"
19    "testing"
20
21    "golang.org/x/tools/internal/testenv"
22)
23
24// TODO(adonovan):
25// - test introduction of renaming imports.
26// - test induced failures of rewriteFile.
27
28// Guide to the test packages:
29//
30// new.com/one        -- canonical name for old.com/one
31// old.com/one        -- non-canonical; has import comment "new.com/one"
32// old.com/bad        -- has a parse error
33// fruit.io/orange    \
34// fruit.io/banana     } orange -> pear -> banana -> titanic.biz/bar
35// fruit.io/pear    /
36// titanic.biz/bar    -- domain is sinking; package has jumped ship to new.com/bar
37// titanic.biz/foo    -- domain is sinking but package has no import comment yet
38
39var gopath = filepath.Join(cwd"testdata")
40
41func init() {
42    if err := os.Setenv("GOPATH"gopath); err != nil {
43        log.Fatal(err)
44    }
45
46    // This test currently requires GOPATH mode.
47    // Explicitly disabling module mode should suffix, but
48    // we'll also turn off GOPROXY just for good measure.
49    if err := os.Setenv("GO111MODULE""off"); err != nil {
50        log.Fatal(err)
51    }
52    if err := os.Setenv("GOPROXY""off"); err != nil {
53        log.Fatal(err)
54    }
55}
56
57func TestFixImports(t *testing.T) {
58    if os.Getenv("GO_BUILDER_NAME") == "plan9-arm" {
59        t.Skipf("skipping test that times out on plan9-arm; see https://go.dev/issue/50775")
60    }
61    testenv.NeedsTool(t"go")
62
63    defer func() {
64        stderr = os.Stderr
65        *badDomains = "code.google.com"
66        *replaceFlag = ""
67    }()
68
69    for itest := range []struct {
70        packages    []string // packages to rewrite, "go list" syntax
71        badDomains  string   // -baddomains flag
72        replaceFlag string   // -replace flag
73        wantOK      bool
74        wantStderr  string
75        wantRewrite map[string]string
76    }{
77        // #0. No errors.
78        {
79            packages:   []string{"all"},
80            badDomains"code.google.com",
81            wantOK:     true,
82            wantStderr`
83testdata/src/old.com/bad/bad.go:2:43: expected 'package', found 'EOF'
84fruit.io/banana
85    fixed: old.com/one -> new.com/one
86    fixed: titanic.biz/bar -> new.com/bar
87`,
88            wantRewrite: map[string]string{
89                "$GOPATH/src/fruit.io/banana/banana.go"`package banana
90
91import (
92    _ "new.com/bar"
93    _ "new.com/one"
94    _ "titanic.biz/foo"
95)`,
96            },
97        },
98        // #1. No packages needed rewriting.
99        {
100            packages:   []string{"titanic.biz/...""old.com/...""new.com/..."},
101            badDomains"code.google.com",
102            wantOK:     true,
103            wantStderr`
104testdata/src/old.com/bad/bad.go:2:43: expected 'package', found 'EOF'
105`,
106        },
107        // #2. Some packages without import comments matched bad domains.
108        {
109            packages:   []string{"all"},
110            badDomains"titanic.biz",
111            wantOK:     false,
112            wantStderr`
113testdata/src/old.com/bad/bad.go:2:43: expected 'package', found 'EOF'
114fruit.io/banana
115    testdata/src/fruit.io/banana/banana.go:6: import "titanic.biz/foo"
116    fixed: old.com/one -> new.com/one
117    fixed: titanic.biz/bar -> new.com/bar
118    ERROR: titanic.biz/foo has no import comment
119    imported directly by:
120        fruit.io/pear
121    imported indirectly by:
122        fruit.io/orange
123`,
124            wantRewrite: map[string]string{
125                "$GOPATH/src/fruit.io/banana/banana.go"`package banana
126
127import (
128    _ "new.com/bar"
129    _ "new.com/one"
130    _ "titanic.biz/foo"
131)`,
132            },
133        },
134        // #3. The -replace flag lets user supply missing import comments.
135        {
136            packages:    []string{"all"},
137            replaceFlag"titanic.biz/foo=new.com/foo",
138            wantOK:      true,
139            wantStderr`
140testdata/src/old.com/bad/bad.go:2:43: expected 'package', found 'EOF'
141fruit.io/banana
142    fixed: old.com/one -> new.com/one
143    fixed: titanic.biz/bar -> new.com/bar
144    fixed: titanic.biz/foo -> new.com/foo
145`,
146            wantRewrite: map[string]string{
147                "$GOPATH/src/fruit.io/banana/banana.go"`package banana
148
149import (
150    _ "new.com/bar"
151    _ "new.com/foo"
152    _ "new.com/one"
153)`,
154            },
155        },
156        // #4. The -replace flag supports wildcards.
157        //     An explicit import comment takes precedence.
158        {
159            packages:    []string{"all"},
160            replaceFlag"titanic.biz/...=new.com/...",
161            wantOK:      true,
162            wantStderr`
163testdata/src/old.com/bad/bad.go:2:43: expected 'package', found 'EOF'
164fruit.io/banana
165    fixed: old.com/one -> new.com/one
166    fixed: titanic.biz/bar -> new.com/bar
167    fixed: titanic.biz/foo -> new.com/foo
168`,
169            wantRewrite: map[string]string{
170                "$GOPATH/src/fruit.io/banana/banana.go"`package banana
171
172import (
173    _ "new.com/bar"
174    _ "new.com/foo"
175    _ "new.com/one"
176)`,
177            },
178        },
179        // #5. The -replace flag trumps -baddomains.
180        {
181            packages:    []string{"all"},
182            badDomains:  "titanic.biz",
183            replaceFlag"titanic.biz/foo=new.com/foo",
184            wantOK:      true,
185            wantStderr`
186testdata/src/old.com/bad/bad.go:2:43: expected 'package', found 'EOF'
187fruit.io/banana
188    fixed: old.com/one -> new.com/one
189    fixed: titanic.biz/bar -> new.com/bar
190    fixed: titanic.biz/foo -> new.com/foo
191`,
192            wantRewrite: map[string]string{
193                "$GOPATH/src/fruit.io/banana/banana.go"`package banana
194
195import (
196    _ "new.com/bar"
197    _ "new.com/foo"
198    _ "new.com/one"
199)`,
200            },
201        },
202    } {
203        *badDomains = test.badDomains
204        *replaceFlag = test.replaceFlag
205
206        stderr = new(bytes.Buffer)
207        gotRewrite := make(map[string]string)
208        writeFile = func(filename stringcontent []bytemode os.FileModeerror {
209            filename = strings.Replace(filenamegopath"$GOPATH"1)
210            filename = filepath.ToSlash(filename)
211            gotRewrite[filename] = string(bytes.TrimSpace(content))
212            return nil
213        }
214
215        if runtime.GOOS == "windows" {
216            test.wantStderr = strings.Replace(test.wantStderr`testdata/src/old.com/bad/bad.go``testdata\src\old.com\bad\bad.go`, -1)
217            test.wantStderr = strings.Replace(test.wantStderr`testdata/src/fruit.io/banana/banana.go``testdata\src\fruit.io\banana\banana.go`, -1)
218        }
219        test.wantStderr = strings.TrimSpace(test.wantStderr)
220
221        // Check status code.
222        if fiximports(test.packages...) != test.wantOK {
223            t.Errorf("#%d. fiximports() = %t"i, !test.wantOK)
224        }
225
226        // Compare stderr output.
227        if got := strings.TrimSpace(stderr.(*bytes.Buffer).String()); got != test.wantStderr {
228            if strings.Contains(got"vendor/golang_org/x/text/unicode/norm") {
229                t.Skip("skipping known-broken test; see golang.org/issue/17417")
230            }
231            t.Errorf("#%d. stderr: got <<\n%s\n>>, want <<\n%s\n>>",
232                igottest.wantStderr)
233        }
234
235        // Compare rewrites.
236        for kv := range gotRewrite {
237            if test.wantRewrite[k] != v {
238                t.Errorf("#%d. rewrite[%s] = <<%s>>, want <<%s>>",
239                    ikvtest.wantRewrite[k])
240            }
241            delete(test.wantRewritek)
242        }
243        for kv := range test.wantRewrite {
244            t.Errorf("#%d. rewrite[%s] missing, want <<%s>>"ikv)
245        }
246    }
247}
248
249// TestDryRun tests that the -n flag suppresses calls to writeFile.
250func TestDryRun(t *testing.T) {
251    if os.Getenv("GO_BUILDER_NAME") == "plan9-arm" {
252        t.Skipf("skipping test that times out on plan9-arm; see https://go.dev/issue/50775")
253    }
254    testenv.NeedsTool(t"go")
255
256    *dryrun = true
257    defer func() { *dryrun = false }() // restore
258    stderr = new(bytes.Buffer)
259    writeFile = func(filename stringcontent []bytemode os.FileModeerror {
260        t.Fatalf("writeFile(%s) called in dryrun mode"filename)
261        return nil
262    }
263
264    if !fiximports("all") {
265        t.Fatalf("fiximports failed: %s"stderr)
266    }
267}
268
MembersX
testenv
TestFixImports
TestFixImports.RangeStmt_1673.i
TestFixImports.RangeStmt_1673.BlockStmt.RangeStmt_6388.k
TestFixImports.RangeStmt_1673.BlockStmt.RangeStmt_6388.v
TestFixImports.RangeStmt_1673.BlockStmt.RangeStmt_6584.v
testing
TestFixImports.RangeStmt_1673.BlockStmt.gotRewrite
TestFixImports.RangeStmt_1673.BlockStmt.RangeStmt_6584.k
TestDryRun.t
TestFixImports.RangeStmt_1673.test
runtime
init
init.err
TestFixImports.t
TestFixImports.RangeStmt_1673.BlockStmt.got
TestDryRun
Members
X