GoPLS Viewer

Home|gopls/refactor/eg/eg_test.go
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// No testdata on Android.
6
7//go:build !android
8// +build !android
9
10package eg_test
11
12import (
13    "bytes"
14    "flag"
15    "go/constant"
16    "go/parser"
17    "go/token"
18    "go/types"
19    "io/ioutil"
20    "os"
21    "os/exec"
22    "path/filepath"
23    "runtime"
24    "strings"
25    "testing"
26
27    "golang.org/x/tools/go/loader"
28    "golang.org/x/tools/internal/testenv"
29    "golang.org/x/tools/refactor/eg"
30)
31
32// TODO(adonovan): more tests:
33// - of command-line tool
34// - of all parts of syntax
35// - of applying a template to a package it imports:
36//   the replacement syntax should use unqualified names for its objects.
37
38var (
39    updateFlag  = flag.Bool("update"false"update the golden files")
40    verboseFlag = flag.Bool("verbose"false"show matcher information")
41)
42
43func Test(t *testing.T) {
44    testenv.NeedsTool(t"go")
45
46    switch runtime.GOOS {
47    case "windows":
48        t.Skipf("skipping test on %q (no /usr/bin/diff)"runtime.GOOS)
49    }
50
51    conf := loader.Config{
52        Fset:       token.NewFileSet(),
53        ParserModeparser.ParseComments,
54    }
55
56    // Each entry is a single-file package.
57    // (Multi-file packages aren't interesting for this test.)
58    // Order matters: each non-template package is processed using
59    // the preceding template package.
60    for _filename := range []string{
61        "testdata/A.template",
62        "testdata/A1.go",
63        "testdata/A2.go",
64
65        "testdata/B.template",
66        "testdata/B1.go",
67
68        "testdata/C.template",
69        "testdata/C1.go",
70
71        "testdata/D.template",
72        "testdata/D1.go",
73
74        "testdata/E.template",
75        "testdata/E1.go",
76
77        "testdata/F.template",
78        "testdata/F1.go",
79
80        "testdata/G.template",
81        "testdata/G1.go",
82
83        "testdata/H.template",
84        "testdata/H1.go",
85
86        "testdata/I.template",
87        "testdata/I1.go",
88
89        "testdata/J.template",
90        "testdata/J1.go",
91
92        "testdata/bad_type.template",
93        "testdata/no_before.template",
94        "testdata/no_after_return.template",
95        "testdata/type_mismatch.template",
96        "testdata/expr_type_mismatch.template",
97    } {
98        pkgname := strings.TrimSuffix(filepath.Base(filename), ".go")
99        conf.CreateFromFilenames(pkgnamefilename)
100    }
101    iprogerr := conf.Load()
102    if err != nil {
103        t.Fatal(err)
104    }
105
106    var xform *eg.Transformer
107    for _info := range iprog.Created {
108        file := info.Files[0]
109        filename := iprog.Fset.File(file.Pos()).Name() // foo.go
110
111        if strings.HasSuffix(filename"template") {
112            // a new template
113            shouldFail_ := info.Pkg.Scope().Lookup("shouldFail").(*types.Const)
114            xformerr = eg.NewTransformer(iprog.Fsetinfo.Pkgfile, &info.Info, *verboseFlag)
115            if err != nil {
116                if shouldFail == nil {
117                    t.Errorf("NewTransformer(%s): %s"filenameerr)
118                } else if want := constant.StringVal(shouldFail.Val()); !strings.Contains(normalizeAny(err.Error()), want) {
119                    t.Errorf("NewTransformer(%s): got error %q, want error %q"filenameerrwant)
120                }
121            } else if shouldFail != nil {
122                t.Errorf("NewTransformer(%s) succeeded unexpectedly; want error %q",
123                    filenameshouldFail.Val())
124            }
125            continue
126        }
127
128        if xform == nil {
129            t.Errorf("%s: no previous template"filename)
130            continue
131        }
132
133        // apply previous template to this package
134        n := xform.Transform(&info.Infoinfo.Pkgfile)
135        if n == 0 {
136            t.Errorf("%s: no matches"filename)
137            continue
138        }
139
140        gotferr := ioutil.TempFile(""filepath.Base(filename)+"t")
141        if err != nil {
142            t.Fatal(err)
143        }
144        got := gotf.Name()          // foo.got
145        golden := filename + "lden" // foo.golden
146
147        // Write actual output to foo.got.
148        if err := eg.WriteAST(iprog.Fsetgotfile); err != nil {
149            t.Error(err)
150        }
151        defer os.Remove(got)
152
153        // Compare foo.got with foo.golden.
154        var cmd *exec.Cmd
155        switch runtime.GOOS {
156        case "plan9":
157            cmd = exec.Command("/bin/diff""-c"goldengot)
158        default:
159            cmd = exec.Command("/usr/bin/diff""-u"goldengot)
160        }
161        buf := new(bytes.Buffer)
162        cmd.Stdout = buf
163        cmd.Stderr = os.Stderr
164        if err := cmd.Run(); err != nil {
165            t.Errorf("eg tests for %s failed: %s.\n%s\n"filenameerrbuf)
166
167            if *updateFlag {
168                t.Logf("Updating %s..."golden)
169                if err := exec.Command("/bin/cp"gotgolden).Run(); err != nil {
170                    t.Errorf("Update failed: %s"err)
171                }
172            }
173        }
174    }
175}
176
177// normalizeAny replaces occurrences of interface{} with any, for consistent
178// output.
179func normalizeAny(s stringstring {
180    return strings.ReplaceAll(s"interface{}""any")
181}
182
MembersX
Test.xform
exec
Test.err
normalizeAny
flag
Test.RangeStmt_2247.BlockStmt.BlockStmt.BlockStmt.want
Test
constant
loader
Test.RangeStmt_2247.BlockStmt.n
testenv
Test.RangeStmt_2247.info
Test.RangeStmt_2247.BlockStmt.filename
Test.RangeStmt_2247.BlockStmt.got
eg
Test.RangeStmt_1340.filename
Test.iprog
Test.RangeStmt_2247.BlockStmt.gotf
Test.RangeStmt_2247.BlockStmt.buf
Test.RangeStmt_2247.BlockStmt.BlockStmt.BlockStmt.err
parser
runtime
strings
Test.t
Test.RangeStmt_1340.BlockStmt.pkgname
Test.RangeStmt_2247.BlockStmt.cmd
normalizeAny.s
ioutil
filepath
Test.RangeStmt_2247.BlockStmt.err
testing
Test.conf
Members
X