github.com/golang/dep@v0.5.4/internal/importers/base/importer_test.go (about)

     1  // Copyright 2016 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 base
     6  
     7  import (
     8  	"fmt"
     9  	"log"
    10  	"testing"
    11  
    12  	"github.com/golang/dep"
    13  	"github.com/golang/dep/gps"
    14  	"github.com/golang/dep/internal/importers/importertest"
    15  	"github.com/golang/dep/internal/test"
    16  )
    17  
    18  func TestBaseImporter_IsTag(t *testing.T) {
    19  	testcases := map[string]struct {
    20  		input     string
    21  		wantIsTag bool
    22  		wantTag   gps.Version
    23  	}{
    24  		"non-semver tag": {
    25  			input:     importertest.Beta1Tag,
    26  			wantIsTag: true,
    27  			wantTag:   gps.NewVersion(importertest.Beta1Tag).Pair(importertest.Beta1Rev),
    28  		},
    29  		"semver-tag": {
    30  			input:     importertest.V1PatchTag,
    31  			wantIsTag: true,
    32  			wantTag:   gps.NewVersion(importertest.V1PatchTag).Pair(importertest.V1PatchRev)},
    33  		"untagged revision": {
    34  			input:     importertest.UntaggedRev,
    35  			wantIsTag: false,
    36  		},
    37  		"branch name": {
    38  			input:     importertest.V2Branch,
    39  			wantIsTag: false,
    40  		},
    41  		"empty": {
    42  			input:     "",
    43  			wantIsTag: false,
    44  		},
    45  	}
    46  
    47  	pi := gps.ProjectIdentifier{ProjectRoot: importertest.Project}
    48  
    49  	for name, tc := range testcases {
    50  		name := name
    51  		tc := tc
    52  		t.Run(name, func(t *testing.T) {
    53  			h := test.NewHelper(t)
    54  			defer h.Cleanup()
    55  			// Disable parallel tests until we can resolve this error on the Windows builds:
    56  			// "remote repository at https://github.com/carolynvs/deptest-importers does not exist, or is inaccessible"
    57  			//h.Parallel()
    58  
    59  			ctx := importertest.NewTestContext(h)
    60  			sm, err := ctx.SourceManager()
    61  			h.Must(err)
    62  			defer sm.Release()
    63  
    64  			i := NewImporter(ctx.Err, ctx.Verbose, sm)
    65  			gotIsTag, gotTag, err := i.isTag(pi, tc.input)
    66  			h.Must(err)
    67  
    68  			if tc.wantIsTag != gotIsTag {
    69  				t.Fatalf("unexpected isTag result for %v: \n\t(GOT) %v \n\t(WNT) %v",
    70  					tc.input, gotIsTag, tc.wantIsTag)
    71  			}
    72  
    73  			if tc.wantTag != gotTag {
    74  				t.Fatalf("unexpected tag for %v: \n\t(GOT) %v \n\t(WNT) %v",
    75  					tc.input, gotTag, tc.wantTag)
    76  			}
    77  		})
    78  	}
    79  }
    80  
    81  func TestBaseImporter_LookupVersionForLockedProject(t *testing.T) {
    82  	testcases := map[string]struct {
    83  		revision    gps.Revision
    84  		constraint  gps.Constraint
    85  		wantVersion string
    86  	}{
    87  		"match revision to tag": {
    88  			revision:    importertest.V1PatchRev,
    89  			wantVersion: importertest.V1PatchTag,
    90  		},
    91  		"match revision with multiple tags using constraint": {
    92  			revision:    importertest.MultiTaggedRev,
    93  			constraint:  gps.NewVersion(importertest.MultiTaggedPlainTag),
    94  			wantVersion: importertest.MultiTaggedPlainTag,
    95  		},
    96  		"revision with multiple tags with no constraint defaults to best match": {
    97  			revision:    importertest.MultiTaggedRev,
    98  			wantVersion: importertest.MultiTaggedSemverTag,
    99  		},
   100  		"revision with multiple tags with nonmatching constraint defaults to best match": {
   101  			revision:    importertest.MultiTaggedRev,
   102  			constraint:  gps.NewVersion("thismatchesnothing"),
   103  			wantVersion: importertest.MultiTaggedSemverTag,
   104  		},
   105  		"untagged revision fallback to branch constraint": {
   106  			revision:    importertest.UntaggedRev,
   107  			constraint:  gps.NewBranch("master"),
   108  			wantVersion: "master",
   109  		},
   110  		"fallback to revision": {
   111  			revision:    importertest.UntaggedRev,
   112  			wantVersion: importertest.UntaggedRev,
   113  		},
   114  	}
   115  
   116  	pi := gps.ProjectIdentifier{ProjectRoot: importertest.Project}
   117  
   118  	for name, tc := range testcases {
   119  		name := name
   120  		tc := tc
   121  		t.Run(name, func(t *testing.T) {
   122  			h := test.NewHelper(t)
   123  			defer h.Cleanup()
   124  			// Disable parallel tests until we can resolve this error on the Windows builds:
   125  			// "remote repository at https://github.com/carolynvs/deptest-importers does not exist, or is inaccessible"
   126  			//h.Parallel()
   127  
   128  			ctx := importertest.NewTestContext(h)
   129  			sm, err := ctx.SourceManager()
   130  			h.Must(err)
   131  			defer sm.Release()
   132  
   133  			i := NewImporter(ctx.Err, ctx.Verbose, sm)
   134  			v, err := i.lookupVersionForLockedProject(pi, tc.constraint, tc.revision)
   135  			h.Must(err)
   136  
   137  			gotVersion := v.String()
   138  			if gotVersion != tc.wantVersion {
   139  				t.Fatalf("unexpected locked version: \n\t(GOT) %v\n\t(WNT) %v", gotVersion, tc.wantVersion)
   140  			}
   141  		})
   142  	}
   143  }
   144  
   145  func TestBaseImporter_ImportProjects(t *testing.T) {
   146  	testcases := map[string]struct {
   147  		importertest.TestCase
   148  		projects []ImportedPackage
   149  	}{
   150  		"tag constraints are skipped": {
   151  			importertest.TestCase{
   152  				WantVersion:  importertest.Beta1Tag,
   153  				WantRevision: importertest.Beta1Rev,
   154  			},
   155  			[]ImportedPackage{
   156  				{
   157  					Name:           importertest.Project,
   158  					LockHint:       importertest.Beta1Rev,
   159  					ConstraintHint: importertest.Beta1Tag,
   160  				},
   161  			},
   162  		},
   163  		"tag lock hints Lock to tagged revision": {
   164  			importertest.TestCase{
   165  				WantVersion:  importertest.Beta1Tag,
   166  				WantRevision: importertest.Beta1Rev,
   167  			},
   168  			[]ImportedPackage{
   169  				{
   170  					Name:     importertest.Project,
   171  					LockHint: importertest.Beta1Tag,
   172  				},
   173  			},
   174  		},
   175  		"untagged revision ignores range constraint": {
   176  			importertest.TestCase{
   177  				WantRevision: importertest.UntaggedRev,
   178  			},
   179  			[]ImportedPackage{
   180  				{
   181  					Name:           importertest.Project,
   182  					LockHint:       importertest.UntaggedRev,
   183  					ConstraintHint: importertest.V1Constraint,
   184  				},
   185  			},
   186  		},
   187  		"untagged revision keeps branch constraint": {
   188  			importertest.TestCase{
   189  				WantConstraint: "master",
   190  				WantVersion:    "master",
   191  				WantRevision:   importertest.UntaggedRev,
   192  			},
   193  			[]ImportedPackage{
   194  				{
   195  					Name:           importertest.Project,
   196  					LockHint:       importertest.UntaggedRev,
   197  					ConstraintHint: "master",
   198  				},
   199  			},
   200  		},
   201  		"HEAD revisions default constraint to the matching branch": {
   202  			importertest.TestCase{
   203  				DefaultConstraintFromLock: true,
   204  				WantConstraint:            importertest.V2Branch,
   205  				WantVersion:               importertest.V2Branch,
   206  				WantRevision:              importertest.V2Rev,
   207  			},
   208  			[]ImportedPackage{
   209  				{
   210  					Name:     importertest.Project,
   211  					LockHint: importertest.V2Rev,
   212  				},
   213  			},
   214  		},
   215  		"Semver tagged revisions default to ^VERSION": {
   216  			importertest.TestCase{
   217  				DefaultConstraintFromLock: true,
   218  				WantConstraint:            importertest.V1Constraint,
   219  				WantVersion:               importertest.V1Tag,
   220  				WantRevision:              importertest.V1Rev,
   221  			},
   222  			[]ImportedPackage{
   223  				{
   224  					Name:     importertest.Project,
   225  					LockHint: importertest.V1Rev,
   226  				},
   227  			},
   228  		},
   229  		"Semver lock hint defaults constraint to ^VERSION": {
   230  			importertest.TestCase{
   231  				DefaultConstraintFromLock: true,
   232  				WantConstraint:            importertest.V1Constraint,
   233  				WantVersion:               importertest.V1Tag,
   234  				WantRevision:              importertest.V1Rev,
   235  			},
   236  			[]ImportedPackage{
   237  				{
   238  					Name:     importertest.Project,
   239  					LockHint: importertest.V1Tag,
   240  				},
   241  			},
   242  		},
   243  		"Semver constraint hint": {
   244  			importertest.TestCase{
   245  				WantConstraint: importertest.V1Constraint,
   246  				WantVersion:    importertest.V1PatchTag,
   247  				WantRevision:   importertest.V1PatchRev,
   248  			},
   249  			[]ImportedPackage{
   250  				{
   251  					Name:           importertest.Project,
   252  					LockHint:       importertest.V1PatchRev,
   253  					ConstraintHint: importertest.V1Constraint,
   254  				},
   255  			},
   256  		},
   257  		"Semver prerelease lock hint": {
   258  			importertest.TestCase{
   259  				WantConstraint: importertest.V2Branch,
   260  				WantVersion:    importertest.V2PatchTag,
   261  				WantRevision:   importertest.V2PatchRev,
   262  			},
   263  			[]ImportedPackage{
   264  				{
   265  					Name:           importertest.Project,
   266  					LockHint:       importertest.V2PatchRev,
   267  					ConstraintHint: importertest.V2Branch,
   268  				},
   269  			},
   270  		},
   271  		"Revision constraints are skipped": {
   272  			importertest.TestCase{
   273  				WantVersion:  importertest.V1Tag,
   274  				WantRevision: importertest.V1Rev,
   275  			},
   276  			[]ImportedPackage{
   277  				{
   278  					Name:           importertest.Project,
   279  					LockHint:       importertest.V1Rev,
   280  					ConstraintHint: importertest.V1Rev,
   281  				},
   282  			},
   283  		},
   284  		"Branch constraint hint": {
   285  			importertest.TestCase{
   286  				WantConstraint: "master",
   287  				WantVersion:    importertest.V1Tag,
   288  				WantRevision:   importertest.V1Rev,
   289  			},
   290  			[]ImportedPackage{
   291  				{
   292  					Name:           importertest.Project,
   293  					LockHint:       importertest.V1Rev,
   294  					ConstraintHint: "master",
   295  				},
   296  			},
   297  		},
   298  		"Non-matching semver constraint is skipped": {
   299  			importertest.TestCase{
   300  				WantVersion:  importertest.V1Tag,
   301  				WantRevision: importertest.V1Rev,
   302  			},
   303  			[]ImportedPackage{
   304  				{
   305  					Name:           importertest.Project,
   306  					LockHint:       importertest.V1Rev,
   307  					ConstraintHint: "^2.0.0",
   308  				},
   309  			},
   310  		},
   311  		"git describe constraint is skipped": {
   312  			importertest.TestCase{
   313  				WantRevision: importertest.UntaggedRev,
   314  			},
   315  			[]ImportedPackage{
   316  				{
   317  					Name:           importertest.Project,
   318  					LockHint:       importertest.UntaggedRev,
   319  					ConstraintHint: importertest.UntaggedRevAbbrv,
   320  				},
   321  			},
   322  		},
   323  		"consolidate subpackages under root": {
   324  			importertest.TestCase{
   325  				WantConstraint: "master",
   326  				WantVersion:    "master",
   327  				WantRevision:   importertest.UntaggedRev,
   328  			},
   329  			[]ImportedPackage{
   330  				{
   331  					Name:           importertest.Project + "/subpkA",
   332  					ConstraintHint: "master",
   333  				},
   334  				{
   335  					Name:     importertest.Project,
   336  					LockHint: importertest.UntaggedRev,
   337  				},
   338  			},
   339  		},
   340  		"skip duplicate packages": {
   341  			importertest.TestCase{
   342  				WantRevision: importertest.UntaggedRev,
   343  			},
   344  			[]ImportedPackage{
   345  				{
   346  					Name:     importertest.Project + "/subpkgA",
   347  					LockHint: importertest.UntaggedRev, // first wins
   348  				},
   349  				{
   350  					Name:     importertest.Project + "/subpkgB",
   351  					LockHint: importertest.V1Rev,
   352  				},
   353  			},
   354  		},
   355  		"skip empty lock hints": {
   356  			importertest.TestCase{
   357  				WantRevision: "",
   358  			},
   359  			[]ImportedPackage{
   360  				{
   361  					Name:     importertest.Project,
   362  					LockHint: "",
   363  				},
   364  			},
   365  		},
   366  		"alternate source": {
   367  			importertest.TestCase{
   368  				WantConstraint: "*",
   369  				WantSourceRepo: importertest.ProjectSrc,
   370  			},
   371  			[]ImportedPackage{
   372  				{
   373  					Name:   importertest.Project,
   374  					Source: importertest.ProjectSrc,
   375  				},
   376  			},
   377  		},
   378  		"skip default source": {
   379  			importertest.TestCase{
   380  				WantSourceRepo: "",
   381  			},
   382  			[]ImportedPackage{
   383  				{
   384  					Name:   importertest.Project,
   385  					Source: "https://" + importertest.Project,
   386  				},
   387  			},
   388  		},
   389  		"skip vendored source": {
   390  			importertest.TestCase{
   391  				WantSourceRepo: "",
   392  				WantWarning:    "vendored sources aren't supported",
   393  			},
   394  			[]ImportedPackage{
   395  				{
   396  					Name:   importertest.Project,
   397  					Source: "example.com/vendor/" + importertest.Project,
   398  				},
   399  			},
   400  		},
   401  		"invalid project root": {
   402  			importertest.TestCase{
   403  				WantSourceRepo: "",
   404  				WantWarning:    "Warning: Skipping project. Cannot determine the project root for invalid-project",
   405  			},
   406  			[]ImportedPackage{
   407  				{
   408  					Name: "invalid-project",
   409  				},
   410  			},
   411  		},
   412  		"nonexistent project": {
   413  			importertest.TestCase{
   414  				WantSourceRepo: "",
   415  				WantWarning: fmt.Sprintf(
   416  					"Warning: Skipping project. Unable to import lock %q for %s",
   417  					importertest.V1Tag, importertest.NonexistentPrj,
   418  				),
   419  			},
   420  			[]ImportedPackage{
   421  				{
   422  					Name:     importertest.NonexistentPrj,
   423  					LockHint: importertest.V1Tag,
   424  				},
   425  			},
   426  		},
   427  	}
   428  
   429  	for name, tc := range testcases {
   430  		name := name
   431  		tc := tc
   432  		t.Run(name, func(t *testing.T) {
   433  			err := tc.Execute(t, func(logger *log.Logger, sm gps.SourceManager) (*dep.Manifest, *dep.Lock) {
   434  				i := NewImporter(logger, true, sm)
   435  				i.ImportPackages(tc.projects, tc.DefaultConstraintFromLock)
   436  				return i.Manifest, i.Lock
   437  			})
   438  			if err != nil {
   439  				t.Fatalf("%#v", err)
   440  			}
   441  		})
   442  	}
   443  }