1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
|
package extract
import (
"bytes"
"os"
"path"
"strings"
"testing"
)
var expectedOutput = `// Code generated by 'yaegi extract guthib.com/baz'. DO NOT EDIT.
package bar
import (
"guthib.com/baz"
"reflect"
)
func init() {
Symbols["guthib.com/baz/baz"] = map[string]reflect.Value{
// function, constant and variable definitions
"Hello": reflect.ValueOf(baz.Hello),
}
}
`
func TestPackages(t *testing.T) {
testCases := []struct {
desc string
moduleOn string
wd string
arg string
importPath string
expected string
contains string
dest string
}{
{
desc: "stdlib math pkg, using go/importer",
dest: "math",
arg: "math",
// We check this one because it shows both defects when we break it: the value
// gets corrupted, and the type becomes token.INT
// TODO(mpl): if the ident between key and value becomes annoying, be smarter about it.
contains: `"MaxFloat32": reflect.ValueOf(constant.MakeFromLiteral("340282346638528859811704183484516925440", token.FLOAT, 0)),`,
},
{
desc: "using relative path, using go.mod",
wd: "./testdata/1/src/guthib.com/bar",
arg: "../baz",
expected: expectedOutput,
},
{
desc: "using relative path, manual import path",
wd: "./testdata/2/src/guthib.com/bar",
arg: "../baz",
importPath: "guthib.com/baz",
expected: expectedOutput,
},
{
desc: "using relative path, go.mod is ignored, because manual path",
wd: "./testdata/3/src/guthib.com/bar",
arg: "../baz",
importPath: "guthib.com/baz",
expected: expectedOutput,
},
{
desc: "using relative path, dep in vendor, using go.mod",
wd: "./testdata/4/src/guthib.com/bar",
arg: "./vendor/guthib.com/baz",
expected: expectedOutput,
},
{
desc: "using relative path, dep in vendor, manual import path",
wd: "./testdata/5/src/guthib.com/bar",
arg: "./vendor/guthib.com/baz",
importPath: "guthib.com/baz",
expected: expectedOutput,
},
{
desc: "using relative path, package name is not same as import path",
wd: "./testdata/6/src/guthib.com/bar",
arg: "../baz-baz",
importPath: "guthib.com/baz",
expected: expectedOutput,
},
{
desc: "using relative path, interface method parameter is variadic",
wd: "./testdata/7/src/guthib.com/variadic",
arg: "../variadic",
importPath: "guthib.com/variadic",
expected: `
// Code generated by 'yaegi extract guthib.com/variadic'. DO NOT EDIT.
package variadic
import (
"guthib.com/variadic"
"reflect"
)
func init() {
Symbols["guthib.com/variadic/variadic"] = map[string]reflect.Value{
// type definitions
"Variadic": reflect.ValueOf((*variadic.Variadic)(nil)),
// interface wrapper definitions
"_Variadic": reflect.ValueOf((*_guthib_com_variadic_Variadic)(nil)),
}
}
// _guthib_com_variadic_Variadic is an interface wrapper for Variadic type
type _guthib_com_variadic_Variadic struct {
IValue interface{}
WCall func(method string, args ...[]interface{}) (interface{}, error)
}
func (W _guthib_com_variadic_Variadic) Call(method string, args ...[]interface{}) (interface{}, error) {
return W.WCall(method, args...)
}
`[1:],
},
}
for _, test := range testCases {
test := test
t.Run(test.desc, func(t *testing.T) {
cwd, err := os.Getwd()
if err != nil {
t.Fatal(err)
}
wd := test.wd
if wd == "" {
wd = cwd
} else {
if err := os.Chdir(wd); err != nil {
t.Fatal(err)
}
defer func() {
if err := os.Chdir(cwd); err != nil {
t.Fatal(err)
}
}()
}
dest := path.Base(wd)
if test.dest != "" {
dest = test.dest
}
ext := Extractor{
Dest: dest,
}
var out bytes.Buffer
if _, err := ext.Extract(test.arg, test.importPath, &out); err != nil {
t.Fatal(err)
}
if test.expected != "" {
if out.String() != test.expected {
t.Fatalf("\nGot:\n%q\nWant: \n%q", out.String(), test.expected)
}
}
if test.contains != "" {
if !strings.Contains(out.String(), test.contains) {
t.Fatalf("Missing expected part: %s in %s", test.contains, out.String())
}
}
})
}
}
|