| // Copyright 2017 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 gps |
| |
| import ( |
| "bytes" |
| "context" |
| "errors" |
| "fmt" |
| "net/url" |
| "reflect" |
| "testing" |
| ) |
| |
| type pathDeductionFixture struct { |
| in string |
| root string |
| rerr error |
| mb maybeSources |
| srcerr error |
| } |
| |
| // helper func to generate testing *url.URLs, panicking on err |
| func mkurl(s string) (u *url.URL) { |
| var err error |
| u, err = url.Parse(s) |
| if err != nil { |
| panic(fmt.Sprint("string is not a valid URL:", s)) |
| } |
| return |
| } |
| |
| var pathDeductionFixtures = map[string][]pathDeductionFixture{ |
| "github": { |
| { |
| in: "github.com/sdboyer/gps", |
| root: "github.com/sdboyer/gps", |
| mb: maybeSources{ |
| maybeGitSource{url: mkurl("https://github.com/sdboyer/gps")}, |
| maybeGitSource{url: mkurl("ssh://git@github.com/sdboyer/gps")}, |
| maybeGitSource{url: mkurl("git://github.com/sdboyer/gps")}, |
| maybeGitSource{url: mkurl("http://github.com/sdboyer/gps")}, |
| }, |
| }, |
| { |
| in: "github.com/sdboyer/gps/foo", |
| root: "github.com/sdboyer/gps", |
| mb: maybeSources{ |
| maybeGitSource{url: mkurl("https://github.com/sdboyer/gps")}, |
| maybeGitSource{url: mkurl("ssh://git@github.com/sdboyer/gps")}, |
| maybeGitSource{url: mkurl("git://github.com/sdboyer/gps")}, |
| maybeGitSource{url: mkurl("http://github.com/sdboyer/gps")}, |
| }, |
| }, |
| { |
| // TODO(sdboyer) is this a problem for enforcing uniqueness? do we |
| // need to collapse these extensions? |
| in: "github.com/sdboyer/gps.git/foo", |
| root: "github.com/sdboyer/gps.git", |
| mb: maybeSources{ |
| maybeGitSource{url: mkurl("https://github.com/sdboyer/gps.git")}, |
| maybeGitSource{url: mkurl("ssh://git@github.com/sdboyer/gps.git")}, |
| maybeGitSource{url: mkurl("git://github.com/sdboyer/gps.git")}, |
| maybeGitSource{url: mkurl("http://github.com/sdboyer/gps.git")}, |
| }, |
| }, |
| { |
| in: "git@github.com:sdboyer/gps", |
| root: "github.com/sdboyer/gps", |
| mb: maybeSources{ |
| maybeGitSource{url: mkurl("ssh://git@github.com/sdboyer/gps")}, |
| }, |
| }, |
| { |
| in: "https://github.com/sdboyer/gps", |
| root: "github.com/sdboyer/gps", |
| mb: maybeSources{ |
| maybeGitSource{url: mkurl("https://github.com/sdboyer/gps")}, |
| }, |
| }, |
| { |
| in: "https://github.com/sdboyer/gps/foo/bar", |
| root: "github.com/sdboyer/gps", |
| mb: maybeSources{ |
| maybeGitSource{url: mkurl("https://github.com/sdboyer/gps")}, |
| }, |
| }, |
| { |
| in: "github.com/sdboyer-/gps/foo", |
| root: "github.com/sdboyer-/gps", |
| mb: maybeSources{ |
| maybeGitSource{url: mkurl("https://github.com/sdboyer-/gps")}, |
| maybeGitSource{url: mkurl("ssh://git@github.com/sdboyer-/gps")}, |
| maybeGitSource{url: mkurl("git://github.com/sdboyer-/gps")}, |
| maybeGitSource{url: mkurl("http://github.com/sdboyer-/gps")}, |
| }, |
| }, |
| { |
| in: "github.com/a/gps/foo", |
| root: "github.com/a/gps", |
| mb: maybeSources{ |
| maybeGitSource{url: mkurl("https://github.com/a/gps")}, |
| maybeGitSource{url: mkurl("ssh://git@github.com/a/gps")}, |
| maybeGitSource{url: mkurl("git://github.com/a/gps")}, |
| maybeGitSource{url: mkurl("http://github.com/a/gps")}, |
| }, |
| }, |
| // some invalid github username patterns |
| { |
| in: "github.com/-sdboyer/gps/foo", |
| rerr: errors.New("github.com/-sdboyer/gps/foo is not a valid path for a source on github.com"), |
| }, |
| { |
| in: "github.com/sdbo.yer/gps/foo", |
| rerr: errors.New("github.com/sdbo.yer/gps/foo is not a valid path for a source on github.com"), |
| }, |
| { |
| in: "github.com/sdbo_yer/gps/foo", |
| rerr: errors.New("github.com/sdbo_yer/gps/foo is not a valid path for a source on github.com"), |
| }, |
| // Regression - gh does allow two-letter usernames |
| { |
| in: "github.com/kr/pretty", |
| root: "github.com/kr/pretty", |
| mb: maybeSources{ |
| maybeGitSource{url: mkurl("https://github.com/kr/pretty")}, |
| maybeGitSource{url: mkurl("ssh://git@github.com/kr/pretty")}, |
| maybeGitSource{url: mkurl("git://github.com/kr/pretty")}, |
| maybeGitSource{url: mkurl("http://github.com/kr/pretty")}, |
| }, |
| }, |
| }, |
| "gopkg.in": { |
| { |
| in: "gopkg.in/sdboyer/gps.v0", |
| root: "gopkg.in/sdboyer/gps.v0", |
| mb: maybeSources{ |
| maybeGopkginSource{opath: "gopkg.in/sdboyer/gps.v0", url: mkurl("https://github.com/sdboyer/gps"), major: 0}, |
| maybeGopkginSource{opath: "gopkg.in/sdboyer/gps.v0", url: mkurl("http://github.com/sdboyer/gps"), major: 0}, |
| }, |
| }, |
| { |
| in: "gopkg.in/sdboyer/gps.v0/foo", |
| root: "gopkg.in/sdboyer/gps.v0", |
| mb: maybeSources{ |
| maybeGopkginSource{opath: "gopkg.in/sdboyer/gps.v0", url: mkurl("https://github.com/sdboyer/gps"), major: 0}, |
| maybeGopkginSource{opath: "gopkg.in/sdboyer/gps.v0", url: mkurl("http://github.com/sdboyer/gps"), major: 0}, |
| }, |
| }, |
| { |
| in: "gopkg.in/sdboyer/gps.v1/foo/bar", |
| root: "gopkg.in/sdboyer/gps.v1", |
| mb: maybeSources{ |
| maybeGopkginSource{opath: "gopkg.in/sdboyer/gps.v1", url: mkurl("https://github.com/sdboyer/gps"), major: 1}, |
| maybeGopkginSource{opath: "gopkg.in/sdboyer/gps.v1", url: mkurl("http://github.com/sdboyer/gps"), major: 1}, |
| }, |
| }, |
| { |
| in: "gopkg.in/yaml.v1", |
| root: "gopkg.in/yaml.v1", |
| mb: maybeSources{ |
| maybeGopkginSource{opath: "gopkg.in/yaml.v1", url: mkurl("https://github.com/go-yaml/yaml"), major: 1}, |
| maybeGopkginSource{opath: "gopkg.in/yaml.v1", url: mkurl("http://github.com/go-yaml/yaml"), major: 1}, |
| }, |
| }, |
| { |
| in: "gopkg.in/yaml.v1/foo/bar", |
| root: "gopkg.in/yaml.v1", |
| mb: maybeSources{ |
| |
| maybeGopkginSource{opath: "gopkg.in/yaml.v1", url: mkurl("https://github.com/go-yaml/yaml"), major: 1}, |
| maybeGopkginSource{opath: "gopkg.in/yaml.v1", url: mkurl("http://github.com/go-yaml/yaml"), major: 1}, |
| }, |
| }, |
| { |
| in: "gopkg.in/inf.v0", |
| root: "gopkg.in/inf.v0", |
| mb: maybeSources{ |
| maybeGopkginSource{opath: "gopkg.in/inf.v0", url: mkurl("https://github.com/go-inf/inf"), major: 0}, |
| maybeGopkginSource{opath: "gopkg.in/inf.v0", url: mkurl("http://github.com/go-inf/inf"), major: 0}, |
| }, |
| }, |
| { |
| // gopkg.in only allows specifying major version in import path |
| in: "gopkg.in/yaml.v1.2", |
| rerr: errors.New("gopkg.in/yaml.v1.2 is not a valid import path; gopkg.in only allows major versions (\"v1\" instead of \"v1.2\")"), |
| }, |
| }, |
| "jazz": { |
| // IBM hub devops services - fixtures borrowed from go get |
| { |
| in: "hub.jazz.net/git/user1/pkgname", |
| root: "hub.jazz.net/git/user1/pkgname", |
| mb: maybeSources{ |
| maybeGitSource{url: mkurl("https://hub.jazz.net/git/user1/pkgname")}, |
| }, |
| }, |
| { |
| in: "hub.jazz.net/git/user1/pkgname/submodule/submodule/submodule", |
| root: "hub.jazz.net/git/user1/pkgname", |
| mb: maybeSources{ |
| maybeGitSource{url: mkurl("https://hub.jazz.net/git/user1/pkgname")}, |
| }, |
| }, |
| { |
| in: "hub.jazz.net/someotherprefix", |
| rerr: errors.New("hub.jazz.net/someotherprefix is not a valid path for a source on hub.jazz.net"), |
| }, |
| { |
| in: "hub.jazz.net/someotherprefix/user1/packagename", |
| rerr: errors.New("hub.jazz.net/someotherprefix/user1/packagename is not a valid path for a source on hub.jazz.net"), |
| }, |
| // Spaces are not valid in user names or package names |
| { |
| in: "hub.jazz.net/git/User 1/pkgname", |
| rerr: errors.New("hub.jazz.net/git/User 1/pkgname is not a valid path for a source on hub.jazz.net"), |
| }, |
| { |
| in: "hub.jazz.net/git/user1/pkg name", |
| rerr: errors.New("hub.jazz.net/git/user1/pkg name is not a valid path for a source on hub.jazz.net"), |
| }, |
| // Dots are not valid in user names |
| { |
| in: "hub.jazz.net/git/user.1/pkgname", |
| rerr: errors.New("hub.jazz.net/git/user.1/pkgname is not a valid path for a source on hub.jazz.net"), |
| }, |
| { |
| in: "hub.jazz.net/git/user1/pkg.name", |
| root: "hub.jazz.net/git/user1/pkg.name", |
| mb: maybeSources{ |
| maybeGitSource{url: mkurl("https://hub.jazz.net/git/user1/pkg.name")}, |
| }, |
| }, |
| // User names cannot have uppercase letters |
| { |
| in: "hub.jazz.net/git/USER/pkgname", |
| rerr: errors.New("hub.jazz.net/git/USER/pkgname is not a valid path for a source on hub.jazz.net"), |
| }, |
| }, |
| "bitbucket": { |
| { |
| in: "bitbucket.org/sdboyer/reporoot", |
| root: "bitbucket.org/sdboyer/reporoot", |
| mb: maybeSources{ |
| maybeHgSource{url: mkurl("https://bitbucket.org/sdboyer/reporoot")}, |
| maybeHgSource{url: mkurl("ssh://hg@bitbucket.org/sdboyer/reporoot")}, |
| maybeHgSource{url: mkurl("http://bitbucket.org/sdboyer/reporoot")}, |
| maybeGitSource{url: mkurl("https://bitbucket.org/sdboyer/reporoot")}, |
| maybeGitSource{url: mkurl("ssh://git@bitbucket.org/sdboyer/reporoot")}, |
| maybeGitSource{url: mkurl("git://bitbucket.org/sdboyer/reporoot")}, |
| maybeGitSource{url: mkurl("http://bitbucket.org/sdboyer/reporoot")}, |
| }, |
| }, |
| { |
| in: "bitbucket.org/sdboyer/reporoot/foo/bar", |
| root: "bitbucket.org/sdboyer/reporoot", |
| mb: maybeSources{ |
| maybeHgSource{url: mkurl("https://bitbucket.org/sdboyer/reporoot")}, |
| maybeHgSource{url: mkurl("ssh://hg@bitbucket.org/sdboyer/reporoot")}, |
| maybeHgSource{url: mkurl("http://bitbucket.org/sdboyer/reporoot")}, |
| maybeGitSource{url: mkurl("https://bitbucket.org/sdboyer/reporoot")}, |
| maybeGitSource{url: mkurl("ssh://git@bitbucket.org/sdboyer/reporoot")}, |
| maybeGitSource{url: mkurl("git://bitbucket.org/sdboyer/reporoot")}, |
| maybeGitSource{url: mkurl("http://bitbucket.org/sdboyer/reporoot")}, |
| }, |
| }, |
| { |
| in: "https://bitbucket.org/sdboyer/reporoot/foo/bar", |
| root: "bitbucket.org/sdboyer/reporoot", |
| mb: maybeSources{ |
| maybeHgSource{url: mkurl("https://bitbucket.org/sdboyer/reporoot")}, |
| maybeGitSource{url: mkurl("https://bitbucket.org/sdboyer/reporoot")}, |
| }, |
| }, |
| // Less standard behaviors possible due to the hg/git ambiguity |
| { |
| in: "bitbucket.org/sdboyer/reporoot.git", |
| root: "bitbucket.org/sdboyer/reporoot.git", |
| mb: maybeSources{ |
| maybeGitSource{url: mkurl("https://bitbucket.org/sdboyer/reporoot.git")}, |
| maybeGitSource{url: mkurl("ssh://git@bitbucket.org/sdboyer/reporoot.git")}, |
| maybeGitSource{url: mkurl("git://bitbucket.org/sdboyer/reporoot.git")}, |
| maybeGitSource{url: mkurl("http://bitbucket.org/sdboyer/reporoot.git")}, |
| }, |
| }, |
| { |
| in: "git@bitbucket.org:sdboyer/reporoot.git", |
| root: "bitbucket.org/sdboyer/reporoot.git", |
| mb: maybeSources{ |
| maybeGitSource{url: mkurl("ssh://git@bitbucket.org/sdboyer/reporoot.git")}, |
| }, |
| }, |
| { |
| in: "bitbucket.org/sdboyer/reporoot.hg", |
| root: "bitbucket.org/sdboyer/reporoot.hg", |
| mb: maybeSources{ |
| maybeHgSource{url: mkurl("https://bitbucket.org/sdboyer/reporoot.hg")}, |
| maybeHgSource{url: mkurl("ssh://hg@bitbucket.org/sdboyer/reporoot.hg")}, |
| maybeHgSource{url: mkurl("http://bitbucket.org/sdboyer/reporoot.hg")}, |
| }, |
| }, |
| { |
| in: "hg@bitbucket.org:sdboyer/reporoot", |
| root: "bitbucket.org/sdboyer/reporoot", |
| mb: maybeSources{ |
| maybeHgSource{url: mkurl("ssh://hg@bitbucket.org/sdboyer/reporoot")}, |
| }, |
| }, |
| { |
| in: "git://bitbucket.org/sdboyer/reporoot.hg", |
| root: "bitbucket.org/sdboyer/reporoot.hg", |
| srcerr: errors.New("git is not a valid scheme for accessing an hg repository"), |
| }, |
| }, |
| "launchpad": { |
| // tests for launchpad, mostly bazaar |
| // TODO(sdboyer) need more tests to deal w/launchpad's oddities |
| { |
| in: "launchpad.net/govcstestbzrrepo", |
| root: "launchpad.net/govcstestbzrrepo", |
| mb: maybeSources{ |
| maybeBzrSource{url: mkurl("https://launchpad.net/govcstestbzrrepo")}, |
| maybeBzrSource{url: mkurl("bzr+ssh://launchpad.net/govcstestbzrrepo")}, |
| maybeBzrSource{url: mkurl("bzr://launchpad.net/govcstestbzrrepo")}, |
| maybeBzrSource{url: mkurl("http://launchpad.net/govcstestbzrrepo")}, |
| }, |
| }, |
| { |
| in: "launchpad.net/govcstestbzrrepo/foo/bar", |
| root: "launchpad.net/govcstestbzrrepo", |
| mb: maybeSources{ |
| maybeBzrSource{url: mkurl("https://launchpad.net/govcstestbzrrepo")}, |
| maybeBzrSource{url: mkurl("bzr+ssh://launchpad.net/govcstestbzrrepo")}, |
| maybeBzrSource{url: mkurl("bzr://launchpad.net/govcstestbzrrepo")}, |
| maybeBzrSource{url: mkurl("http://launchpad.net/govcstestbzrrepo")}, |
| }, |
| }, |
| { |
| in: "launchpad.net/repo root", |
| rerr: errors.New("launchpad.net/repo root is not a valid path for a source on launchpad.net"), |
| }, |
| }, |
| "git.launchpad": { |
| { |
| in: "git.launchpad.net/reporoot", |
| root: "git.launchpad.net/reporoot", |
| mb: maybeSources{ |
| maybeGitSource{url: mkurl("https://git.launchpad.net/reporoot")}, |
| maybeGitSource{url: mkurl("ssh://git.launchpad.net/reporoot")}, |
| maybeGitSource{url: mkurl("git://git.launchpad.net/reporoot")}, |
| maybeGitSource{url: mkurl("http://git.launchpad.net/reporoot")}, |
| }, |
| }, |
| { |
| in: "git.launchpad.net/reporoot/foo/bar", |
| root: "git.launchpad.net/reporoot", |
| mb: maybeSources{ |
| maybeGitSource{url: mkurl("https://git.launchpad.net/reporoot")}, |
| maybeGitSource{url: mkurl("ssh://git.launchpad.net/reporoot")}, |
| maybeGitSource{url: mkurl("git://git.launchpad.net/reporoot")}, |
| maybeGitSource{url: mkurl("http://git.launchpad.net/reporoot")}, |
| }, |
| }, |
| { |
| in: "git.launchpad.net/repo root", |
| rerr: errors.New("git.launchpad.net/repo root is not a valid path for a source on git.launchpad.net"), |
| }, |
| }, |
| "apache": { |
| { |
| in: "git.apache.org/package-name.git", |
| root: "git.apache.org/package-name.git", |
| mb: maybeSources{ |
| maybeGitSource{url: mkurl("https://git.apache.org/package-name.git")}, |
| maybeGitSource{url: mkurl("ssh://git.apache.org/package-name.git")}, |
| maybeGitSource{url: mkurl("git://git.apache.org/package-name.git")}, |
| maybeGitSource{url: mkurl("http://git.apache.org/package-name.git")}, |
| }, |
| }, |
| { |
| in: "git.apache.org/package-name.git/foo/bar", |
| root: "git.apache.org/package-name.git", |
| mb: maybeSources{ |
| maybeGitSource{url: mkurl("https://git.apache.org/package-name.git")}, |
| maybeGitSource{url: mkurl("ssh://git.apache.org/package-name.git")}, |
| maybeGitSource{url: mkurl("git://git.apache.org/package-name.git")}, |
| maybeGitSource{url: mkurl("http://git.apache.org/package-name.git")}, |
| }, |
| }, |
| }, |
| "vcsext": { |
| // VCS extension-based syntax |
| { |
| in: "foobar.com/baz.git", |
| root: "foobar.com/baz.git", |
| mb: maybeSources{ |
| maybeGitSource{url: mkurl("https://foobar.com/baz.git")}, |
| maybeGitSource{url: mkurl("ssh://foobar.com/baz.git")}, |
| maybeGitSource{url: mkurl("git://foobar.com/baz.git")}, |
| maybeGitSource{url: mkurl("http://foobar.com/baz.git")}, |
| }, |
| }, |
| { |
| in: "foobar.com/baz.git/extra/path", |
| root: "foobar.com/baz.git", |
| mb: maybeSources{ |
| maybeGitSource{url: mkurl("https://foobar.com/baz.git")}, |
| maybeGitSource{url: mkurl("ssh://foobar.com/baz.git")}, |
| maybeGitSource{url: mkurl("git://foobar.com/baz.git")}, |
| maybeGitSource{url: mkurl("http://foobar.com/baz.git")}, |
| }, |
| }, |
| { |
| in: "foobar.com/baz.bzr", |
| root: "foobar.com/baz.bzr", |
| mb: maybeSources{ |
| maybeBzrSource{url: mkurl("https://foobar.com/baz.bzr")}, |
| maybeBzrSource{url: mkurl("bzr+ssh://foobar.com/baz.bzr")}, |
| maybeBzrSource{url: mkurl("bzr://foobar.com/baz.bzr")}, |
| maybeBzrSource{url: mkurl("http://foobar.com/baz.bzr")}, |
| }, |
| }, |
| { |
| in: "foo-bar.com/baz.hg", |
| root: "foo-bar.com/baz.hg", |
| mb: maybeSources{ |
| maybeHgSource{url: mkurl("https://foo-bar.com/baz.hg")}, |
| maybeHgSource{url: mkurl("ssh://foo-bar.com/baz.hg")}, |
| maybeHgSource{url: mkurl("http://foo-bar.com/baz.hg")}, |
| }, |
| }, |
| { |
| in: "git@foobar.com:baz.git", |
| root: "foobar.com/baz.git", |
| mb: maybeSources{ |
| maybeGitSource{url: mkurl("ssh://git@foobar.com/baz.git")}, |
| }, |
| }, |
| { |
| in: "bzr+ssh://foobar.com/baz.bzr", |
| root: "foobar.com/baz.bzr", |
| mb: maybeSources{ |
| maybeBzrSource{url: mkurl("bzr+ssh://foobar.com/baz.bzr")}, |
| }, |
| }, |
| { |
| in: "ssh://foobar.com/baz.bzr", |
| root: "foobar.com/baz.bzr", |
| mb: maybeSources{ |
| maybeBzrSource{url: mkurl("ssh://foobar.com/baz.bzr")}, |
| }, |
| }, |
| { |
| in: "https://foobar.com/baz.hg", |
| root: "foobar.com/baz.hg", |
| mb: maybeSources{ |
| maybeHgSource{url: mkurl("https://foobar.com/baz.hg")}, |
| }, |
| }, |
| { |
| in: "git://foobar.com/baz.hg", |
| root: "foobar.com/baz.hg", |
| srcerr: errors.New("git is not a valid scheme for accessing hg repositories (path foobar.com/baz.hg)"), |
| }, |
| // who knows why anyone would do this, but having a second vcs ext |
| // shouldn't throw us off - only the first one counts |
| { |
| in: "foobar.com/baz.git/quark/quizzle.bzr/quorum", |
| root: "foobar.com/baz.git", |
| mb: maybeSources{ |
| maybeGitSource{url: mkurl("https://foobar.com/baz.git")}, |
| maybeGitSource{url: mkurl("ssh://foobar.com/baz.git")}, |
| maybeGitSource{url: mkurl("git://foobar.com/baz.git")}, |
| maybeGitSource{url: mkurl("http://foobar.com/baz.git")}, |
| }, |
| }, |
| }, |
| "vanity": { |
| // Vanity imports |
| { |
| in: "golang.org/x/exp", |
| root: "golang.org/x/exp", |
| mb: maybeSources{ |
| maybeGitSource{url: mkurl("https://go.googlesource.com/exp")}, |
| }, |
| }, |
| { |
| in: "golang.org/x/exp/inotify", |
| root: "golang.org/x/exp", |
| mb: maybeSources{ |
| maybeGitSource{url: mkurl("https://go.googlesource.com/exp")}, |
| }, |
| }, |
| { |
| in: "golang.org/x/net/html", |
| root: "golang.org/x/net", |
| mb: maybeSources{ |
| maybeGitSource{url: mkurl("https://go.googlesource.com/net")}, |
| }, |
| }, |
| }, |
| } |
| |
| func TestDeduceFromPath(t *testing.T) { |
| do := func(typ string, fixtures []pathDeductionFixture, t *testing.T) { |
| t.Run(typ, func(t *testing.T) { |
| t.Parallel() |
| |
| var deducer pathDeducer |
| switch typ { |
| case "github": |
| deducer = githubDeducer{regexp: ghRegex} |
| case "gopkg.in": |
| deducer = gopkginDeducer{regexp: gpinNewRegex} |
| case "jazz": |
| deducer = jazzDeducer{regexp: jazzRegex} |
| case "bitbucket": |
| deducer = bitbucketDeducer{regexp: bbRegex} |
| case "launchpad": |
| deducer = launchpadDeducer{regexp: lpRegex} |
| case "git.launchpad": |
| deducer = launchpadGitDeducer{regexp: glpRegex} |
| case "apache": |
| deducer = apacheDeducer{regexp: apacheRegex} |
| case "vcsext": |
| deducer = vcsExtensionDeducer{regexp: vcsExtensionRegex} |
| default: |
| // Should just be the vanity imports, which we do elsewhere |
| t.Log("skipping") |
| t.SkipNow() |
| } |
| |
| printmb := func(mb maybeSources) string { |
| var buf bytes.Buffer |
| fmt.Fprintf(&buf, "%v maybeSources:", len(mb)) |
| for _, elem := range mb { |
| fmt.Fprintf(&buf, "\n\t\t%s", elem) |
| } |
| return buf.String() |
| } |
| |
| for _, fix := range fixtures { |
| fix := fix |
| t.Run(fix.in, func(t *testing.T) { |
| t.Parallel() |
| u, in, uerr := normalizeURI(fix.in) |
| if uerr != nil { |
| if fix.rerr == nil { |
| t.Errorf("bad input URI %s", uerr) |
| } |
| t.SkipNow() |
| } |
| |
| root, rerr := deducer.deduceRoot(in) |
| if fix.rerr != nil { |
| if rerr == nil { |
| t.Errorf("Expected error on deducing root, got none:\n\t(WNT) %s", fix.rerr) |
| } else if fix.rerr.Error() != rerr.Error() { |
| t.Errorf("Got unexpected error on deducing root:\n\t(GOT) %s\n\t(WNT) %s", rerr, fix.rerr) |
| } |
| } else if rerr != nil { |
| t.Errorf("Got unexpected error on deducing root:\n\t(GOT) %s", rerr) |
| } else if root != fix.root { |
| t.Errorf("Deducer did not return expected root:\n\t(GOT) %s\n\t(WNT) %s", root, fix.root) |
| } |
| |
| mb, mberr := deducer.deduceSource(in, u) |
| if fix.srcerr != nil { |
| if mberr == nil { |
| t.Errorf("Expected error on deducing source, got none:\n\t(WNT) %s", fix.srcerr) |
| } else if fix.srcerr.Error() != mberr.Error() { |
| t.Errorf("Got unexpected error on deducing source:\n\t(GOT) %s\n\t(WNT) %s", mberr, fix.srcerr) |
| } |
| } else if mberr != nil { |
| // don't complain the fix already expected an rerr |
| if fix.rerr == nil { |
| t.Errorf("Got unexpected error on deducing source:\n\t(GOT) %s", mberr) |
| } |
| } else if !reflect.DeepEqual(mb, fix.mb) { |
| if mb == nil { |
| t.Errorf("Deducer returned source maybes, but none expected:\n\t(GOT) (none)\n\t(WNT) %s", printmb(fix.mb)) |
| } else if fix.mb == nil { |
| t.Errorf("Deducer returned source maybes, but none expected:\n\t(GOT) %s\n\t(WNT) (none)", printmb(mb)) |
| } else { |
| t.Errorf("Deducer did not return expected source:\n\t(GOT) %s\n\t(WNT) %s", printmb(mb), printmb(fix.mb)) |
| } |
| } |
| }) |
| } |
| }) |
| } |
| runSet := func(t *testing.T) { |
| for typ, fixtures := range pathDeductionFixtures { |
| do(typ, fixtures, t) |
| } |
| } |
| t.Run("first", runSet) |
| |
| // Run the test set twice to ensure results are correct for both cached |
| // and uncached deductions. |
| t.Run("second", runSet) |
| } |
| |
| func TestVanityDeduction(t *testing.T) { |
| if testing.Short() { |
| t.Skip("Skipping slow test in short mode") |
| } |
| |
| sm, clean := mkNaiveSM(t) |
| defer clean() |
| |
| vanities := pathDeductionFixtures["vanity"] |
| // group to avoid sourcemanager cleanup |
| ctx := context.Background() |
| do := func(t *testing.T) { |
| for _, fix := range vanities { |
| fix := fix |
| t.Run(fix.in, func(t *testing.T) { |
| t.Parallel() |
| |
| pr, err := sm.DeduceProjectRoot(fix.in) |
| if err != nil { |
| t.Errorf("Unexpected err on deducing project root: %s", err) |
| return |
| } else if string(pr) != fix.root { |
| t.Errorf("Deducer did not return expected root:\n\t(GOT) %s\n\t(WNT) %s", pr, fix.root) |
| } |
| |
| pd, err := sm.deduceCoord.deduceRootPath(ctx, fix.in) |
| if err != nil { |
| t.Errorf("Unexpected err on deducing source: %s", err) |
| return |
| } |
| |
| if len(pd.mb) != 1 { |
| t.Errorf("Expected single maybeSource, but found: %d", len(pd.mb)) |
| return |
| } |
| |
| goturl, wanturl := pd.mb[0].(maybeGitSource).url.String(), fix.mb[0].(maybeGitSource).url.String() |
| if goturl != wanturl { |
| t.Errorf("Deduced repo ident does not match fixture:\n\t(GOT) %s\n\t(WNT) %s", goturl, wanturl) |
| } |
| |
| urls, err := sm.SourceURLsForPath(fix.in) |
| if err != nil { |
| t.Errorf("Unexpected err on deducing source urls: %s", err) |
| return |
| } |
| if len(urls) != 1 { |
| t.Errorf("Deduced source URLs count for a vanity import should be 1, got %d", len(urls)) |
| } |
| goturl = urls[0].String() |
| if goturl != wanturl { |
| t.Errorf("Deduced source URL does not match fixture:\n\t(GOT) %s\n\t(WNT) %s", goturl, wanturl) |
| } |
| }) |
| } |
| } |
| |
| // Run twice, to ensure correctness of cache |
| t.Run("first", do) |
| t.Run("second", do) |
| } |
| |
| func TestVanityDeductionSchemeMismatch(t *testing.T) { |
| if testing.Short() { |
| t.Skip("Skipping slow test in short mode") |
| } |
| |
| ctx := context.Background() |
| cm := newSupervisor(ctx) |
| dc := newDeductionCoordinator(cm) |
| _, err := dc.deduceRootPath(ctx, "ssh://golang.org/exp") |
| // TODO(sdboyer) this is not actually the error that it should be |
| if err == nil { |
| t.Error("should have errored on scheme mismatch between input and go-get metadata") |
| } |
| } |