...

Source file src/cuelang.org/go/internal/mod/modpkgload/pkgload_test.go

Documentation: cuelang.org/go/internal/mod/modpkgload

     1  package modpkgload
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"fmt"
     7  	"io/fs"
     8  	"path"
     9  	"path/filepath"
    10  	"strings"
    11  	"testing"
    12  
    13  	"github.com/go-quicktest/qt"
    14  	"github.com/google/go-cmp/cmp"
    15  	"golang.org/x/tools/txtar"
    16  
    17  	"cuelang.org/go/internal/mod/modrequirements"
    18  	"cuelang.org/go/internal/txtarfs"
    19  	"cuelang.org/go/mod/modfile"
    20  	"cuelang.org/go/mod/module"
    21  )
    22  
    23  func TestLoadPackages(t *testing.T) {
    24  	files, err := filepath.Glob("testdata/*.txtar")
    25  	qt.Assert(t, qt.IsNil(err))
    26  	for _, f := range files {
    27  		ar, err := txtar.ParseFile(f)
    28  		qt.Assert(t, qt.IsNil(err))
    29  		tfs := txtarfs.FS(ar)
    30  		reg := testRegistry{tfs}
    31  		testDirs, _ := fs.Glob(tfs, "test[0-9]*")
    32  		for _, testDir := range testDirs {
    33  			testName := strings.TrimSuffix(filepath.Base(f), ".txtar")
    34  			t.Run(testName, func(t *testing.T) {
    35  				t.Logf("test file: %v", f)
    36  				readTestFile := func(name string) string {
    37  					data, err := fs.ReadFile(tfs, path.Join(testDir, name))
    38  					qt.Assert(t, qt.IsNil(err))
    39  					return string(data)
    40  				}
    41  
    42  				initialRequirementsStr := strings.Fields(readTestFile("initial-requirements"))
    43  				mainModulePath, moduleVersions := initialRequirementsStr[0], mapSlice(initialRequirementsStr[1:], module.MustParseVersion)
    44  				defaultMajorVersions := make(map[string]string)
    45  				for _, f := range strings.Fields(readTestFile("default-major-versions")) {
    46  					p, v, ok := strings.Cut(f, "@")
    47  					qt.Assert(t, qt.IsTrue(ok))
    48  					defaultMajorVersions[p] = v
    49  				}
    50  				initialRequirements := modrequirements.NewRequirements(mainModulePath, reg, moduleVersions, defaultMajorVersions)
    51  
    52  				rootPackages := strings.Fields(readTestFile("root-packages"))
    53  				want := readTestFile("want")
    54  
    55  				var out strings.Builder
    56  				printf := func(f string, a ...any) {
    57  					fmt.Fprintf(&out, f, a...)
    58  				}
    59  				pkgs := LoadPackages(
    60  					context.Background(),
    61  					mainModulePath,
    62  					module.SourceLoc{FS: tfs, Dir: "."},
    63  					initialRequirements,
    64  					reg,
    65  					rootPackages,
    66  				)
    67  				for _, pkg := range pkgs.All() {
    68  					printf("%s\n", pkg.ImportPath())
    69  					printf("\tflags: %v\n", pkg.Flags())
    70  					if pkg.Error() != nil {
    71  						printf("\terror: %v\n", pkg.Error())
    72  						printf("\tmissing: %v\n", errors.As(pkg.Error(), new(*ImportMissingError)))
    73  					} else {
    74  						printf("\tmod: %v\n", pkg.Mod())
    75  						for _, loc := range pkg.Locations() {
    76  							printf("\tlocation: %v\n", loc.Dir)
    77  						}
    78  						if imps := pkg.Imports(); len(imps) > 0 {
    79  							printf("\timports:\n")
    80  							for _, imp := range imps {
    81  								printf("\t\t%v\n", imp.ImportPath())
    82  							}
    83  						}
    84  					}
    85  				}
    86  				if diff := cmp.Diff(string(want), out.String()); diff != "" {
    87  					t.Logf("actual result:\n%s", out.String())
    88  					t.Fatalf("unexpected results (-want +got):\n%s", diff)
    89  				}
    90  			})
    91  		}
    92  	}
    93  }
    94  
    95  type testRegistry struct {
    96  	fs fs.FS
    97  }
    98  
    99  func (r testRegistry) Fetch(ctx context.Context, m module.Version) (module.SourceLoc, error) {
   100  	mpath := r.modpath(m)
   101  	info, err := fs.Stat(r.fs, mpath)
   102  	if err != nil || !info.IsDir() {
   103  		return module.SourceLoc{}, fmt.Errorf("module %v not found at %v", m, mpath)
   104  	}
   105  	return module.SourceLoc{
   106  		FS:  r.fs,
   107  		Dir: mpath,
   108  	}, nil
   109  }
   110  
   111  func (r testRegistry) Requirements(ctx context.Context, m module.Version) ([]module.Version, error) {
   112  	mpath := path.Join(r.modpath(m), "cue.mod/module.cue")
   113  	data, err := fs.ReadFile(r.fs, mpath)
   114  	if err != nil {
   115  		return nil, err
   116  	}
   117  	mf, err := modfile.Parse(data, mpath)
   118  	if err != nil {
   119  		return nil, fmt.Errorf("cannot parse module file from %v: %v", m, err)
   120  	}
   121  	return mf.DepVersions(), nil
   122  }
   123  
   124  func (r testRegistry) modpath(m module.Version) string {
   125  	mpath, _, _ := module.SplitPathVersion(m.Path())
   126  	return path.Join("_registry", strings.ReplaceAll(mpath, "/", "_")+"_"+m.Version())
   127  }
   128  
   129  func mapSlice[From, To any](ss []From, f func(From) To) []To {
   130  	ts := make([]To, len(ss))
   131  	for i := range ss {
   132  		ts[i] = f(ss[i])
   133  	}
   134  	return ts
   135  }
   136  

View as plain text