internal/importers/base/importer_test.go

Summary

Maintainability
A
0 mins
Test Coverage
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package base

import (
    "fmt"
    "log"
    "testing"

    "github.com/golang/dep"
    "github.com/golang/dep/gps"
    "github.com/golang/dep/internal/importers/importertest"
    "github.com/golang/dep/internal/test"
)

func TestBaseImporter_IsTag(t *testing.T) {
    testcases := map[string]struct {
        input     string
        wantIsTag bool
        wantTag   gps.Version
    }{
        "non-semver tag": {
            input:     importertest.Beta1Tag,
            wantIsTag: true,
            wantTag:   gps.NewVersion(importertest.Beta1Tag).Pair(importertest.Beta1Rev),
        },
        "semver-tag": {
            input:     importertest.V1PatchTag,
            wantIsTag: true,
            wantTag:   gps.NewVersion(importertest.V1PatchTag).Pair(importertest.V1PatchRev)},
        "untagged revision": {
            input:     importertest.UntaggedRev,
            wantIsTag: false,
        },
        "branch name": {
            input:     importertest.V2Branch,
            wantIsTag: false,
        },
        "empty": {
            input:     "",
            wantIsTag: false,
        },
    }

    pi := gps.ProjectIdentifier{ProjectRoot: importertest.Project}

    for name, tc := range testcases {
        name := name
        tc := tc
        t.Run(name, func(t *testing.T) {
            h := test.NewHelper(t)
            defer h.Cleanup()
            // Disable parallel tests until we can resolve this error on the Windows builds:
            // "remote repository at https://github.com/carolynvs/deptest-importers does not exist, or is inaccessible"
            //h.Parallel()

            ctx := importertest.NewTestContext(h)
            sm, err := ctx.SourceManager()
            h.Must(err)
            defer sm.Release()

            i := NewImporter(ctx.Err, ctx.Verbose, sm)
            gotIsTag, gotTag, err := i.isTag(pi, tc.input)
            h.Must(err)

            if tc.wantIsTag != gotIsTag {
                t.Fatalf("unexpected isTag result for %v: \n\t(GOT) %v \n\t(WNT) %v",
                    tc.input, gotIsTag, tc.wantIsTag)
            }

            if tc.wantTag != gotTag {
                t.Fatalf("unexpected tag for %v: \n\t(GOT) %v \n\t(WNT) %v",
                    tc.input, gotTag, tc.wantTag)
            }
        })
    }
}

func TestBaseImporter_LookupVersionForLockedProject(t *testing.T) {
    testcases := map[string]struct {
        revision    gps.Revision
        constraint  gps.Constraint
        wantVersion string
    }{
        "match revision to tag": {
            revision:    importertest.V1PatchRev,
            wantVersion: importertest.V1PatchTag,
        },
        "match revision with multiple tags using constraint": {
            revision:    importertest.MultiTaggedRev,
            constraint:  gps.NewVersion(importertest.MultiTaggedPlainTag),
            wantVersion: importertest.MultiTaggedPlainTag,
        },
        "revision with multiple tags with no constraint defaults to best match": {
            revision:    importertest.MultiTaggedRev,
            wantVersion: importertest.MultiTaggedSemverTag,
        },
        "revision with multiple tags with nonmatching constraint defaults to best match": {
            revision:    importertest.MultiTaggedRev,
            constraint:  gps.NewVersion("thismatchesnothing"),
            wantVersion: importertest.MultiTaggedSemverTag,
        },
        "untagged revision fallback to branch constraint": {
            revision:    importertest.UntaggedRev,
            constraint:  gps.NewBranch("master"),
            wantVersion: "master",
        },
        "fallback to revision": {
            revision:    importertest.UntaggedRev,
            wantVersion: importertest.UntaggedRev,
        },
    }

    pi := gps.ProjectIdentifier{ProjectRoot: importertest.Project}

    for name, tc := range testcases {
        name := name
        tc := tc
        t.Run(name, func(t *testing.T) {
            h := test.NewHelper(t)
            defer h.Cleanup()
            // Disable parallel tests until we can resolve this error on the Windows builds:
            // "remote repository at https://github.com/carolynvs/deptest-importers does not exist, or is inaccessible"
            //h.Parallel()

            ctx := importertest.NewTestContext(h)
            sm, err := ctx.SourceManager()
            h.Must(err)
            defer sm.Release()

            i := NewImporter(ctx.Err, ctx.Verbose, sm)
            v, err := i.lookupVersionForLockedProject(pi, tc.constraint, tc.revision)
            h.Must(err)

            gotVersion := v.String()
            if gotVersion != tc.wantVersion {
                t.Fatalf("unexpected locked version: \n\t(GOT) %v\n\t(WNT) %v", gotVersion, tc.wantVersion)
            }
        })
    }
}

func TestBaseImporter_ImportProjects(t *testing.T) {
    testcases := map[string]struct {
        importertest.TestCase
        projects []ImportedPackage
    }{
        "tag constraints are skipped": {
            importertest.TestCase{
                WantVersion:  importertest.Beta1Tag,
                WantRevision: importertest.Beta1Rev,
            },
            []ImportedPackage{
                {
                    Name:           importertest.Project,
                    LockHint:       importertest.Beta1Rev,
                    ConstraintHint: importertest.Beta1Tag,
                },
            },
        },
        "tag lock hints Lock to tagged revision": {
            importertest.TestCase{
                WantVersion:  importertest.Beta1Tag,
                WantRevision: importertest.Beta1Rev,
            },
            []ImportedPackage{
                {
                    Name:     importertest.Project,
                    LockHint: importertest.Beta1Tag,
                },
            },
        },
        "untagged revision ignores range constraint": {
            importertest.TestCase{
                WantRevision: importertest.UntaggedRev,
            },
            []ImportedPackage{
                {
                    Name:           importertest.Project,
                    LockHint:       importertest.UntaggedRev,
                    ConstraintHint: importertest.V1Constraint,
                },
            },
        },
        "untagged revision keeps branch constraint": {
            importertest.TestCase{
                WantConstraint: "master",
                WantVersion:    "master",
                WantRevision:   importertest.UntaggedRev,
            },
            []ImportedPackage{
                {
                    Name:           importertest.Project,
                    LockHint:       importertest.UntaggedRev,
                    ConstraintHint: "master",
                },
            },
        },
        "HEAD revisions default constraint to the matching branch": {
            importertest.TestCase{
                DefaultConstraintFromLock: true,
                WantConstraint:            importertest.V2Branch,
                WantVersion:               importertest.V2Branch,
                WantRevision:              importertest.V2Rev,
            },
            []ImportedPackage{
                {
                    Name:     importertest.Project,
                    LockHint: importertest.V2Rev,
                },
            },
        },
        "Semver tagged revisions default to ^VERSION": {
            importertest.TestCase{
                DefaultConstraintFromLock: true,
                WantConstraint:            importertest.V1Constraint,
                WantVersion:               importertest.V1Tag,
                WantRevision:              importertest.V1Rev,
            },
            []ImportedPackage{
                {
                    Name:     importertest.Project,
                    LockHint: importertest.V1Rev,
                },
            },
        },
        "Semver lock hint defaults constraint to ^VERSION": {
            importertest.TestCase{
                DefaultConstraintFromLock: true,
                WantConstraint:            importertest.V1Constraint,
                WantVersion:               importertest.V1Tag,
                WantRevision:              importertest.V1Rev,
            },
            []ImportedPackage{
                {
                    Name:     importertest.Project,
                    LockHint: importertest.V1Tag,
                },
            },
        },
        "Semver constraint hint": {
            importertest.TestCase{
                WantConstraint: importertest.V1Constraint,
                WantVersion:    importertest.V1PatchTag,
                WantRevision:   importertest.V1PatchRev,
            },
            []ImportedPackage{
                {
                    Name:           importertest.Project,
                    LockHint:       importertest.V1PatchRev,
                    ConstraintHint: importertest.V1Constraint,
                },
            },
        },
        "Semver prerelease lock hint": {
            importertest.TestCase{
                WantConstraint: importertest.V2Branch,
                WantVersion:    importertest.V2PatchTag,
                WantRevision:   importertest.V2PatchRev,
            },
            []ImportedPackage{
                {
                    Name:           importertest.Project,
                    LockHint:       importertest.V2PatchRev,
                    ConstraintHint: importertest.V2Branch,
                },
            },
        },
        "Revision constraints are skipped": {
            importertest.TestCase{
                WantVersion:  importertest.V1Tag,
                WantRevision: importertest.V1Rev,
            },
            []ImportedPackage{
                {
                    Name:           importertest.Project,
                    LockHint:       importertest.V1Rev,
                    ConstraintHint: importertest.V1Rev,
                },
            },
        },
        "Branch constraint hint": {
            importertest.TestCase{
                WantConstraint: "master",
                WantVersion:    importertest.V1Tag,
                WantRevision:   importertest.V1Rev,
            },
            []ImportedPackage{
                {
                    Name:           importertest.Project,
                    LockHint:       importertest.V1Rev,
                    ConstraintHint: "master",
                },
            },
        },
        "Non-matching semver constraint is skipped": {
            importertest.TestCase{
                WantVersion:  importertest.V1Tag,
                WantRevision: importertest.V1Rev,
            },
            []ImportedPackage{
                {
                    Name:           importertest.Project,
                    LockHint:       importertest.V1Rev,
                    ConstraintHint: "^2.0.0",
                },
            },
        },
        "git describe constraint is skipped": {
            importertest.TestCase{
                WantRevision: importertest.UntaggedRev,
            },
            []ImportedPackage{
                {
                    Name:           importertest.Project,
                    LockHint:       importertest.UntaggedRev,
                    ConstraintHint: importertest.UntaggedRevAbbrv,
                },
            },
        },
        "consolidate subpackages under root": {
            importertest.TestCase{
                WantConstraint: "master",
                WantVersion:    "master",
                WantRevision:   importertest.UntaggedRev,
            },
            []ImportedPackage{
                {
                    Name:           importertest.Project + "/subpkA",
                    ConstraintHint: "master",
                },
                {
                    Name:     importertest.Project,
                    LockHint: importertest.UntaggedRev,
                },
            },
        },
        "skip duplicate packages": {
            importertest.TestCase{
                WantRevision: importertest.UntaggedRev,
            },
            []ImportedPackage{
                {
                    Name:     importertest.Project + "/subpkgA",
                    LockHint: importertest.UntaggedRev, // first wins
                },
                {
                    Name:     importertest.Project + "/subpkgB",
                    LockHint: importertest.V1Rev,
                },
            },
        },
        "skip empty lock hints": {
            importertest.TestCase{
                WantRevision: "",
            },
            []ImportedPackage{
                {
                    Name:     importertest.Project,
                    LockHint: "",
                },
            },
        },
        "alternate source": {
            importertest.TestCase{
                WantConstraint: "*",
                WantSourceRepo: importertest.ProjectSrc,
            },
            []ImportedPackage{
                {
                    Name:   importertest.Project,
                    Source: importertest.ProjectSrc,
                },
            },
        },
        "skip default source": {
            importertest.TestCase{
                WantSourceRepo: "",
            },
            []ImportedPackage{
                {
                    Name:   importertest.Project,
                    Source: "https://" + importertest.Project,
                },
            },
        },
        "skip vendored source": {
            importertest.TestCase{
                WantSourceRepo: "",
                WantWarning:    "vendored sources aren't supported",
            },
            []ImportedPackage{
                {
                    Name:   importertest.Project,
                    Source: "example.com/vendor/" + importertest.Project,
                },
            },
        },
        "invalid project root": {
            importertest.TestCase{
                WantSourceRepo: "",
                WantWarning:    "Warning: Skipping project. Cannot determine the project root for invalid-project",
            },
            []ImportedPackage{
                {
                    Name: "invalid-project",
                },
            },
        },
        "nonexistent project": {
            importertest.TestCase{
                WantSourceRepo: "",
                WantWarning: fmt.Sprintf(
                    "Warning: Skipping project. Unable to import lock %q for %s",
                    importertest.V1Tag, importertest.NonexistentPrj,
                ),
            },
            []ImportedPackage{
                {
                    Name:     importertest.NonexistentPrj,
                    LockHint: importertest.V1Tag,
                },
            },
        },
    }

    for name, tc := range testcases {
        name := name
        tc := tc
        t.Run(name, func(t *testing.T) {
            err := tc.Execute(t, func(logger *log.Logger, sm gps.SourceManager) (*dep.Manifest, *dep.Lock) {
                i := NewImporter(logger, true, sm)
                i.ImportPackages(tc.projects, tc.DefaultConstraintFromLock)
                return i.Manifest, i.Lock
            })
            if err != nil {
                t.Fatalf("%#v", err)
            }
        })
    }
}