github.com/april1989/origin-go-tools@v0.0.32/cmd/fiximports/main_test.go (about)

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