...

Source file src/cuelang.org/go/mod/module/module_test.go

Documentation: cuelang.org/go/mod/module

     1  // Copyright 2018 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  package module
     6  
     7  import (
     8  	"testing"
     9  
    10  	"github.com/go-quicktest/qt"
    11  )
    12  
    13  var checkTests = []struct {
    14  	path    string
    15  	version string
    16  	ok      bool
    17  }{
    18  	{"rsc.io/quote@v0", "0.1.0", false},
    19  	{"rsc io/quote", "v1.0.0", false},
    20  
    21  	{"github.com/go-yaml/yaml@v0", "v0.8.0", true},
    22  	{"github.com/go-yaml/yaml@v1", "v1.0.0", true},
    23  	{"github.com/go-yaml/yaml", "v2.0.0", false},
    24  	{"github.com/go-yaml/yaml@v1", "v2.1.5", false},
    25  	{"github.com/go-yaml/yaml@v3.0", "v3.0.0", false},
    26  
    27  	{"github.com/go-yaml/yaml@v2", "v1.0.0", false},
    28  	{"github.com/go-yaml/yaml@v2", "v2.0.0", true},
    29  	{"github.com/go-yaml/yaml@v2", "v2.1.5", true},
    30  	{"github.com/go-yaml/yaml@v2", "v3.0.0", false},
    31  
    32  	{"rsc.io/quote", "v17.0.0", false},
    33  }
    34  
    35  func TestCheck(t *testing.T) {
    36  	for _, tt := range checkTests {
    37  		err := Check(tt.path, tt.version)
    38  		if tt.ok && err != nil {
    39  			t.Errorf("Check(%q, %q) = %v, wanted nil error", tt.path, tt.version, err)
    40  		} else if !tt.ok && err == nil {
    41  			t.Errorf("Check(%q, %q) succeeded, wanted error", tt.path, tt.version)
    42  		}
    43  	}
    44  }
    45  
    46  var checkPathWithoutVersionTests = []struct {
    47  	path    string
    48  	wantErr string
    49  }{{
    50  	path:    "rsc io/quote",
    51  	wantErr: `invalid char ' '`,
    52  }, {
    53  	path:    "foo.com@v0",
    54  	wantErr: `module path inappropriately contains major version`,
    55  }, {
    56  	path: "foo.com/bar/baz",
    57  }}
    58  
    59  func TestCheckPathWithoutVersion(t *testing.T) {
    60  	for _, test := range checkPathWithoutVersionTests {
    61  		t.Run(test.path, func(t *testing.T) {
    62  			err := CheckPathWithoutVersion(test.path)
    63  			if test.wantErr != "" {
    64  				qt.Assert(t, qt.ErrorMatches(err, test.wantErr))
    65  				return
    66  			}
    67  			qt.Assert(t, qt.IsNil(err))
    68  		})
    69  	}
    70  }
    71  
    72  var newVersionTests = []struct {
    73  	path, vers   string
    74  	wantError    string
    75  	wantPath     string
    76  	wantBasePath string
    77  }{{
    78  	path:         "github.com/foo/bar@v0",
    79  	vers:         "v0.1.2",
    80  	wantPath:     "github.com/foo/bar@v0",
    81  	wantBasePath: "github.com/foo/bar",
    82  }, {
    83  	path:         "github.com/foo/bar",
    84  	vers:         "v3.1.2",
    85  	wantPath:     "github.com/foo/bar@v3",
    86  	wantBasePath: "github.com/foo/bar",
    87  }, {
    88  	path:         "github.com/foo/bar@v1",
    89  	vers:         "",
    90  	wantPath:     "github.com/foo/bar@v1",
    91  	wantBasePath: "github.com/foo/bar",
    92  }, {
    93  	path:      "github.com/foo/bar@v1",
    94  	vers:      "v3.1.2",
    95  	wantError: `mismatched major version suffix in "github.com/foo/bar@v1" \(version v3\.1\.2\)`,
    96  }, {
    97  	path:      "github.com/foo/bar@v1",
    98  	vers:      "v3.1",
    99  	wantError: `version "v3.1" \(of module "github.com/foo/bar@v1"\) is not canonical`,
   100  }, {
   101  	path:      "github.com/foo/bar@v1",
   102  	vers:      "v3.10.4+build",
   103  	wantError: `version "v3.10.4\+build" \(of module "github.com/foo/bar@v1"\) is not canonical`,
   104  }, {
   105  	path:      "something/bad@v1",
   106  	vers:      "v1.2.3",
   107  	wantError: `malformed module path "something/bad@v1": missing dot in first path element`,
   108  }, {
   109  	path:      "foo.com/bar",
   110  	vers:      "",
   111  	wantError: `path "foo.com/bar" has no major version`,
   112  }, {
   113  	path:      "x.com",
   114  	vers:      "bad",
   115  	wantError: `version "bad" \(of module "x.com"\) is not well formed`,
   116  }, {
   117  	path:         "local",
   118  	vers:         "",
   119  	wantPath:     "local",
   120  	wantBasePath: "local",
   121  }, {
   122  	path:      "local",
   123  	vers:      "v0.1.2",
   124  	wantError: `module 'local' cannot have version`,
   125  }, {
   126  	path:      "local@v1",
   127  	vers:      "",
   128  	wantError: `module 'local' cannot have version`,
   129  }}
   130  
   131  func TestNewVersion(t *testing.T) {
   132  	for _, test := range newVersionTests {
   133  		t.Run(test.path+"@"+test.vers, func(t *testing.T) {
   134  			v, err := NewVersion(test.path, test.vers)
   135  			if test.wantError != "" {
   136  				qt.Assert(t, qt.ErrorMatches(err, test.wantError))
   137  				return
   138  			}
   139  			qt.Assert(t, qt.IsNil(err))
   140  			qt.Assert(t, qt.Equals(v.Path(), test.wantPath))
   141  			qt.Assert(t, qt.Equals(v.BasePath(), test.wantBasePath))
   142  			qt.Assert(t, qt.Equals(v.Version(), test.vers))
   143  		})
   144  	}
   145  }
   146  
   147  var parseVersionTests = []struct {
   148  	s         string
   149  	wantError string
   150  }{{
   151  	s: "github.com/foo/bar@v0.1.2",
   152  }}
   153  
   154  func TestParseVersion(t *testing.T) {
   155  	for _, test := range parseVersionTests {
   156  		t.Run(test.s, func(t *testing.T) {
   157  			v, err := ParseVersion(test.s)
   158  			if test.wantError != "" {
   159  				qt.Assert(t, qt.ErrorMatches(err, test.wantError))
   160  				return
   161  			}
   162  			qt.Assert(t, qt.IsNil(err))
   163  			qt.Assert(t, qt.Equals(v.String(), test.s))
   164  		})
   165  	}
   166  }
   167  
   168  var escapeVersionTests = []struct {
   169  	v   string
   170  	esc string // empty means same as path
   171  }{
   172  	{v: "v1.2.3-alpha"},
   173  	{v: "v3"},
   174  	{v: "v2.3.1-ABcD", esc: "v2.3.1-!a!bc!d"},
   175  }
   176  
   177  func TestEscapeVersion(t *testing.T) {
   178  	for _, tt := range escapeVersionTests {
   179  		esc, err := EscapeVersion(tt.v)
   180  		if err != nil {
   181  			t.Errorf("EscapeVersion(%q): unexpected error: %v", tt.v, err)
   182  			continue
   183  		}
   184  		want := tt.esc
   185  		if want == "" {
   186  			want = tt.v
   187  		}
   188  		if esc != want {
   189  			t.Errorf("EscapeVersion(%q) = %q, want %q", tt.v, esc, want)
   190  		}
   191  	}
   192  }
   193  
   194  func TestEscapePath(t *testing.T) {
   195  	// Check invalid paths.
   196  	for _, tt := range checkPathWithoutVersionTests {
   197  		if tt.wantErr != "" {
   198  			_, err := EscapePath(tt.path)
   199  			if err == nil {
   200  				t.Errorf("EscapePath(%q): succeeded, want error (invalid path)", tt.path)
   201  			}
   202  		}
   203  	}
   204  	path := "foo.com/bar"
   205  	esc, err := EscapePath(path)
   206  	if err != nil {
   207  		t.Fatal(err)
   208  	}
   209  	if esc != path {
   210  		t.Fatalf("EscapePath(%q) = %q, want %q", path, esc, path)
   211  	}
   212  }
   213  
   214  var parseImportPathTests = []struct {
   215  	testName      string
   216  	path          string
   217  	want          ImportPath
   218  	wantCanonical string
   219  }{{
   220  	testName: "StdlibLikeWithSlash",
   221  	path:     "stdlib/path",
   222  	want: ImportPath{
   223  		Path:      "stdlib/path",
   224  		Qualifier: "path",
   225  	},
   226  }, {
   227  	testName: "StdlibLikeNoSlash",
   228  	path:     "math",
   229  	want: ImportPath{
   230  		Path:      "math",
   231  		Qualifier: "math",
   232  	},
   233  }, {
   234  	testName: "StdlibLikeExplicitQualifier",
   235  	path:     "stdlib/path:other",
   236  	want: ImportPath{
   237  		Path:              "stdlib/path",
   238  		ExplicitQualifier: true,
   239  		Qualifier:         "other",
   240  	},
   241  }, {
   242  	testName: "StdlibLikeExplicitQualifierNoSlash",
   243  	path:     "math:other",
   244  	want: ImportPath{
   245  		Path:              "math",
   246  		ExplicitQualifier: true,
   247  		Qualifier:         "other",
   248  	},
   249  }, {
   250  	testName: "WithMajorVersion",
   251  	path:     "foo.com/bar@v0",
   252  	want: ImportPath{
   253  		Path:      "foo.com/bar",
   254  		Version:   "v0",
   255  		Qualifier: "bar",
   256  	},
   257  }, {
   258  	testName: "WithMajorVersionNoSlash",
   259  	path:     "main.test@v0",
   260  	want: ImportPath{
   261  		Path:      "main.test",
   262  		Version:   "v0",
   263  		Qualifier: "main.test",
   264  	},
   265  }, {
   266  	testName: "WithMajorVersionAndExplicitQualifier",
   267  	path:     "foo.com/bar@v0:other",
   268  	want: ImportPath{
   269  		Path:              "foo.com/bar",
   270  		Version:           "v0",
   271  		ExplicitQualifier: true,
   272  		Qualifier:         "other",
   273  	},
   274  }, {
   275  	testName: "WithMajorVersionAndNoQualifier",
   276  	path:     "foo.com/bar@v0",
   277  	want: ImportPath{
   278  		Path:      "foo.com/bar",
   279  		Version:   "v0",
   280  		Qualifier: "bar",
   281  	},
   282  }, {
   283  	testName: "WithRedundantQualifier",
   284  	path:     "foo.com/bar@v0:bar",
   285  	want: ImportPath{
   286  		Path:              "foo.com/bar",
   287  		Version:           "v0",
   288  		ExplicitQualifier: true,
   289  		Qualifier:         "bar",
   290  	},
   291  	wantCanonical: "foo.com/bar@v0",
   292  }}
   293  
   294  func TestParseImportPath(t *testing.T) {
   295  	for _, test := range parseImportPathTests {
   296  		t.Run(test.testName, func(t *testing.T) {
   297  			parts := ParseImportPath(test.path)
   298  			qt.Assert(t, qt.DeepEquals(parts, test.want))
   299  			qt.Assert(t, qt.Equals(parts.String(), test.path))
   300  			if test.wantCanonical == "" {
   301  				test.wantCanonical = test.path
   302  			}
   303  			qt.Assert(t, qt.Equals(parts.Canonical().String(), test.wantCanonical))
   304  		})
   305  	}
   306  }
   307  

View as plain text