github.com/gmemcc/yaegi@v0.12.1-0.20221128122509-aa99124c5d16/extract/extract_test.go (about)

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