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

     1  // Copyright 2017 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 vndr
     6  
     7  import (
     8  	"bytes"
     9  	"fmt"
    10  	"log"
    11  	"path/filepath"
    12  	"reflect"
    13  	"testing"
    14  
    15  	"github.com/golang/dep"
    16  	"github.com/golang/dep/gps"
    17  	"github.com/golang/dep/internal/importers/importertest"
    18  	"github.com/golang/dep/internal/test"
    19  	"github.com/pkg/errors"
    20  )
    21  
    22  func TestVndrConfig_Convert(t *testing.T) {
    23  	testCases := map[string]struct {
    24  		packages []vndrPackage
    25  		importertest.TestCase
    26  	}{
    27  		"package": {
    28  			[]vndrPackage{{
    29  				importPath: importertest.Project,
    30  				reference:  importertest.V1Rev,
    31  				repository: importertest.ProjectSrc,
    32  			}},
    33  			importertest.TestCase{
    34  				WantSourceRepo: importertest.ProjectSrc,
    35  				WantConstraint: importertest.V1Constraint,
    36  				WantRevision:   importertest.V1Rev,
    37  				WantVersion:    importertest.V1Tag,
    38  			},
    39  		},
    40  		"missing importPath": {
    41  			[]vndrPackage{{
    42  				reference: importertest.V1Tag,
    43  			}},
    44  			importertest.TestCase{
    45  				WantWarning: "Warning: Skipping project. Invalid vndr configuration, import path is required",
    46  			},
    47  		},
    48  		"missing reference": {
    49  			[]vndrPackage{{
    50  				importPath: importertest.Project,
    51  			}},
    52  			importertest.TestCase{
    53  				WantWarning: fmt.Sprintf(
    54  					"Warning: Invalid vndr configuration, reference not found for import path %q",
    55  					importertest.Project,
    56  				),
    57  			},
    58  		},
    59  	}
    60  
    61  	for name, testCase := range testCases {
    62  		name := name
    63  		testCase := testCase
    64  		t.Run(name, func(t *testing.T) {
    65  			err := testCase.Execute(t, func(logger *log.Logger, sm gps.SourceManager) (*dep.Manifest, *dep.Lock) {
    66  				g := NewImporter(logger, true, sm)
    67  				g.packages = testCase.packages
    68  				return g.convert(importertest.RootProject)
    69  			})
    70  			if err != nil {
    71  				t.Fatalf("%#v", err)
    72  			}
    73  		})
    74  	}
    75  }
    76  
    77  func TestVndrConfig_Import(t *testing.T) {
    78  	h := test.NewHelper(t)
    79  	defer h.Cleanup()
    80  
    81  	ctx := importertest.NewTestContext(h)
    82  	sm, err := ctx.SourceManager()
    83  	h.Must(err)
    84  	defer sm.Release()
    85  
    86  	h.TempDir(filepath.Join("src", importertest.RootProject))
    87  	h.TempCopy(vndrFile(importertest.RootProject), "vendor.conf")
    88  	projectRoot := h.Path(importertest.RootProject)
    89  
    90  	logOutput := bytes.NewBuffer(nil)
    91  	ctx.Err = log.New(logOutput, "", 0)
    92  
    93  	v := NewImporter(ctx.Err, false, sm)
    94  	if !v.HasDepMetadata(projectRoot) {
    95  		t.Fatal("Expected the importer to detect vndr configuration file")
    96  	}
    97  
    98  	m, l, err := v.Import(projectRoot, importertest.RootProject)
    99  	h.Must(err)
   100  
   101  	wantM := dep.NewManifest()
   102  	c1, _ := gps.NewSemverConstraint("^0.8.1")
   103  	wantM.Constraints["github.com/sdboyer/deptest"] = gps.ProjectProperties{
   104  		Source:     "https://github.com/sdboyer/deptest.git",
   105  		Constraint: c1,
   106  	}
   107  	c2, _ := gps.NewSemverConstraint("^2.0.0")
   108  	wantM.Constraints["github.com/sdboyer/deptestdos"] = gps.ProjectProperties{
   109  		Constraint: c2,
   110  	}
   111  	if !reflect.DeepEqual(wantM, m) {
   112  		t.Errorf("unexpected manifest\nhave=%+v\nwant=%+v", m, wantM)
   113  	}
   114  
   115  	wantL := &dep.Lock{
   116  		P: []gps.LockedProject{
   117  			gps.NewLockedProject(
   118  				gps.ProjectIdentifier{
   119  					ProjectRoot: "github.com/sdboyer/deptest",
   120  					Source:      "https://github.com/sdboyer/deptest.git",
   121  				},
   122  				gps.NewVersion("v0.8.1").Pair("3f4c3bea144e112a69bbe5d8d01c1b09a544253f"),
   123  				nil,
   124  			),
   125  			gps.NewLockedProject(
   126  				gps.ProjectIdentifier{
   127  					ProjectRoot: "github.com/sdboyer/deptestdos",
   128  				},
   129  				gps.NewVersion("v2.0.0").Pair("5c607206be5decd28e6263ffffdcee067266015e"),
   130  				nil,
   131  			),
   132  		},
   133  	}
   134  	if !reflect.DeepEqual(wantL, l) {
   135  		t.Errorf("unexpected lock\nhave=%+v\nwant=%+v", l, wantL)
   136  	}
   137  
   138  	goldenFile := "golden.txt"
   139  	got := logOutput.String()
   140  	want := h.GetTestFileString(goldenFile)
   141  	if want != got {
   142  		if *test.UpdateGolden {
   143  			if err := h.WriteTestFile(goldenFile, got); err != nil {
   144  				t.Fatalf("%+v", errors.Wrapf(err, "Unable to write updated golden file %s", goldenFile))
   145  			}
   146  		} else {
   147  			t.Fatalf("expected %s, got %s", want, got)
   148  		}
   149  	}
   150  }
   151  
   152  func TestParseVndrLine(t *testing.T) {
   153  	testcase := func(in string, wantPkg *vndrPackage, wantErr error) func(*testing.T) {
   154  		return func(t *testing.T) {
   155  			havePkg, haveErr := parseVndrLine(in)
   156  			switch {
   157  			case wantPkg == nil:
   158  				if havePkg != nil {
   159  					t.Errorf("expected nil package, have %v", havePkg)
   160  				}
   161  			case havePkg == nil:
   162  				if wantPkg != nil {
   163  					t.Errorf("expected non-nil package %v, have nil", wantPkg)
   164  				}
   165  			default:
   166  				if !reflect.DeepEqual(havePkg, wantPkg) {
   167  					t.Errorf("unexpected package, have=%v, want=%v", *havePkg, *wantPkg)
   168  				}
   169  			}
   170  
   171  			switch {
   172  			case wantErr == nil:
   173  				if haveErr != nil {
   174  					t.Errorf("expected nil err, have %v", haveErr)
   175  				}
   176  			case haveErr == nil:
   177  				if wantErr != nil {
   178  					t.Errorf("expected non-nil err %v, have nil", wantErr)
   179  				}
   180  			default:
   181  				if haveErr.Error() != wantErr.Error() {
   182  					t.Errorf("expected err=%q, have err=%q", wantErr.Error(), haveErr.Error())
   183  				}
   184  			}
   185  		}
   186  	}
   187  	t.Run("normal line",
   188  		testcase("github.com/golang/notreal v1.0.0",
   189  			&vndrPackage{
   190  				importPath: "github.com/golang/notreal",
   191  				reference:  "v1.0.0",
   192  			}, nil))
   193  
   194  	t.Run("with repo",
   195  		testcase("github.com/golang/notreal v1.0.0 https://github.com/golang/notreal",
   196  			&vndrPackage{
   197  				importPath: "github.com/golang/notreal",
   198  				reference:  "v1.0.0",
   199  				repository: "https://github.com/golang/notreal",
   200  			}, nil))
   201  
   202  	t.Run("trailing comment",
   203  		testcase("github.com/golang/notreal v1.0.0 https://github.com/golang/notreal  # cool comment",
   204  			&vndrPackage{
   205  				importPath: "github.com/golang/notreal",
   206  				reference:  "v1.0.0",
   207  				repository: "https://github.com/golang/notreal",
   208  			}, nil))
   209  
   210  	t.Run("empty line", testcase("", nil, nil))
   211  	t.Run("comment line", testcase("# comment", nil, nil))
   212  	t.Run("comment line with leading whitespace", testcase("  # comment", nil, nil))
   213  
   214  	t.Run("missing revision",
   215  		testcase("github.com/golang/notreal", nil,
   216  			errors.New("invalid config format: \"github.com/golang/notreal\""),
   217  		))
   218  }