github.com/traefik/yaegi@v0.15.1/example/pkg/pkg_test.go (about)

     1  package pkg
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"os"
     7  	"path/filepath"
     8  	"testing"
     9  
    10  	"github.com/traefik/yaegi/interp"
    11  	"github.com/traefik/yaegi/stdlib"
    12  )
    13  
    14  func TestPackages(t *testing.T) {
    15  	testCases := []struct {
    16  		desc      string
    17  		goPath    string
    18  		expected  string
    19  		topImport string
    20  		evalFile  string
    21  	}{
    22  		{
    23  			desc:     "vendor",
    24  			goPath:   "./_pkg/",
    25  			expected: "root Fromage",
    26  		},
    27  		{
    28  			desc:     "sub-subpackage",
    29  			goPath:   "./_pkg0/",
    30  			expected: "root Fromage Cheese",
    31  		},
    32  		{
    33  			desc:     "subpackage",
    34  			goPath:   "./_pkg1/",
    35  			expected: "root Fromage!",
    36  		},
    37  		{
    38  			desc:     "multiple vendor folders",
    39  			goPath:   "./_pkg2/",
    40  			expected: "root Fromage Cheese!",
    41  		},
    42  		{
    43  			desc:     "multiple vendor folders and subpackage in vendor",
    44  			goPath:   "./_pkg3/",
    45  			expected: "root Fromage Couteau Cheese!",
    46  		},
    47  		{
    48  			desc:     "multiple vendor folders and multiple subpackages in vendor",
    49  			goPath:   "./_pkg4/",
    50  			expected: "root Fromage Cheese Vin! Couteau",
    51  		},
    52  		{
    53  			desc:     "vendor flat",
    54  			goPath:   "./_pkg5/",
    55  			expected: "root Fromage Cheese Vin! Couteau",
    56  		},
    57  		{
    58  			desc:     "fallback to GOPATH",
    59  			goPath:   "./_pkg6/",
    60  			expected: "root Fromage Cheese Vin! Couteau",
    61  		},
    62  		{
    63  			desc:     "recursive vendor",
    64  			goPath:   "./_pkg7/",
    65  			expected: "root vin cheese fromage",
    66  		},
    67  		{
    68  			desc:     "named subpackage",
    69  			goPath:   "./_pkg8/",
    70  			expected: "root Fromage!",
    71  		},
    72  		{
    73  			desc:      "at the project root",
    74  			goPath:    "./_pkg10/",
    75  			expected:  "root Fromage",
    76  			topImport: "github.com/foo",
    77  		},
    78  		{
    79  			desc:     "eval main that has vendored dep",
    80  			goPath:   "./_pkg11/",
    81  			expected: "Fromage",
    82  			evalFile: "./_pkg11/src/foo/foo.go",
    83  		},
    84  		{
    85  			desc:      "vendor dir is a sibling or an uncle",
    86  			goPath:    "./_pkg12/",
    87  			expected:  "Yo hello",
    88  			topImport: "guthib.com/foo/pkg",
    89  		},
    90  		{
    91  			desc:     "eval main with vendor as a sibling",
    92  			goPath:   "./_pkg12/",
    93  			expected: "Yo hello",
    94  			evalFile: "./_pkg12/src/guthib.com/foo/main.go",
    95  		},
    96  		{
    97  			desc:     "eval main with vendor",
    98  			goPath:   "./_pkg13/",
    99  			expected: "foobar",
   100  			evalFile: "./_pkg13/src/guthib.com/foo/bar/main.go",
   101  		},
   102  	}
   103  
   104  	for _, test := range testCases {
   105  		test := test
   106  		t.Run(test.desc, func(t *testing.T) {
   107  			goPath, err := filepath.Abs(filepath.FromSlash(test.goPath))
   108  			if err != nil {
   109  				t.Fatal(err)
   110  			}
   111  
   112  			var stdout, stderr bytes.Buffer
   113  			i := interp.New(interp.Options{GoPath: goPath, Stdout: &stdout, Stderr: &stderr})
   114  			// Use binary standard library
   115  			if err := i.Use(stdlib.Symbols); err != nil {
   116  				t.Fatal(err)
   117  			}
   118  
   119  			var msg string
   120  			if test.evalFile != "" {
   121  				if _, err := i.EvalPath(filepath.FromSlash(test.evalFile)); err != nil {
   122  					fatalStderrf(t, "%v", err)
   123  				}
   124  				msg = stdout.String()
   125  			} else {
   126  				// Load pkg from sources
   127  				topImport := "github.com/foo/pkg"
   128  				if test.topImport != "" {
   129  					topImport = test.topImport
   130  				}
   131  				if _, err = i.Eval(fmt.Sprintf(`import "%s"`, topImport)); err != nil {
   132  					t.Fatal(err)
   133  				}
   134  				value, err := i.Eval(`pkg.NewSample()`)
   135  				if err != nil {
   136  					t.Fatal(err)
   137  				}
   138  
   139  				fn := value.Interface().(func() string)
   140  
   141  				msg = fn()
   142  			}
   143  
   144  			if msg != test.expected {
   145  				fatalStderrf(t, "Got %q, want %q", msg, test.expected)
   146  			}
   147  		})
   148  	}
   149  }
   150  
   151  func fatalStderrf(t *testing.T, format string, args ...interface{}) {
   152  	t.Helper()
   153  
   154  	fmt.Fprintf(os.Stderr, format+"\n", args...)
   155  	t.FailNow()
   156  }
   157  
   158  func TestPackagesError(t *testing.T) {
   159  	testCases := []struct {
   160  		desc     string
   161  		goPath   string
   162  		expected string
   163  	}{
   164  		{
   165  			desc:     "different packages in the same directory",
   166  			goPath:   "./_pkg9/",
   167  			expected: `1:21: import "github.com/foo/pkg" error: found packages pkg and pkgfalse in ` + filepath.FromSlash("_pkg9/src/github.com/foo/pkg"),
   168  		},
   169  	}
   170  
   171  	for _, test := range testCases {
   172  		test := test
   173  		t.Run(test.desc, func(t *testing.T) {
   174  			// Init go interpreter
   175  			i := interp.New(interp.Options{GoPath: test.goPath})
   176  			// Use binary standard library
   177  			if err := i.Use(stdlib.Symbols); err != nil {
   178  				t.Fatal(err)
   179  			}
   180  
   181  			// Load pkg from sources
   182  			_, err := i.Eval(`import "github.com/foo/pkg"`)
   183  			if err == nil {
   184  				t.Fatalf("got no error, want %q", test.expected)
   185  			}
   186  
   187  			if err.Error() != test.expected {
   188  				t.Errorf("got %q, want %q", err.Error(), test.expected)
   189  			}
   190  		})
   191  	}
   192  }