diff options
52 files changed, 150 insertions, 4803 deletions
@@ -84,14 +84,6 @@ version = "v1.7.0" [[projects]] - digest = "1:7f89e0c888fb99c61055c646f5678aae645b0b0a1443d9b2dcd9964d850827ce" - name = "github.com/go-test/deep" - packages = ["."] - pruneopts = "UT" - revision = "6592d9cc0a499ad2d5f574fde80a2b5c5cc3b4f5" - version = "v1.0.1" - -[[projects]] digest = "1:97df918963298c287643883209a2c3f642e6593379f97ab400c2a2e219ab647d" name = "github.com/golang/protobuf" packages = ["proto"] @@ -100,19 +92,6 @@ version = "v1.2.0" [[projects]] - digest = "1:2e3c336fc7fde5c984d2841455a658a6d626450b1754a854b3b32e7a8f49a07a" - name = "github.com/google/go-cmp" - packages = [ - "cmp", - "cmp/internal/diff", - "cmp/internal/function", - "cmp/internal/value", - ] - pruneopts = "UT" - revision = "3af367b6b30c263d47e8895973edcca9a49cf029" - version = "v0.2.0" - -[[projects]] digest = "1:c79fb010be38a59d657c48c6ba1d003a8aa651fa56b579d959d74573b7dff8e1" name = "github.com/gorilla/context" packages = ["."] @@ -440,20 +419,6 @@ revision = "5420a8b6744d3b0345ab293f6fcba19c978f1183" version = "v2.2.1" -[[projects]] - digest = "1:225f565dc88a02cebe329d3a49d0ca125789091af952a5cc4fde6312c34ce44d" - name = "gotest.tools" - packages = [ - "assert", - "assert/cmp", - "internal/difflib", - "internal/format", - "internal/source", - ] - pruneopts = "UT" - revision = "b6e20af1ed078cd01a6413b734051a292450b4cb" - version = "v2.1.0" - [solve-meta] analyzer-name = "dep" analyzer-version = 1 @@ -466,7 +431,6 @@ "github.com/cheekybits/genny/generic", "github.com/dustin/go-humanize", "github.com/fatih/color", - "github.com/go-test/deep", "github.com/gorilla/mux", "github.com/icrowley/fake", "github.com/mattn/go-runewidth", @@ -486,7 +450,6 @@ "github.com/vektah/gqlparser/ast", "golang.org/x/crypto/ssh/terminal", "golang.org/x/oauth2", - "gotest.tools/assert", ] solver-name = "gps-cdcl" solver-version = 1 diff --git a/bug/bug_actions_test.go b/bug/bug_actions_test.go index 95ca01c9..af561bf6 100644 --- a/bug/bug_actions_test.go +++ b/bug/bug_actions_test.go @@ -50,7 +50,7 @@ func cleanupRepo(repo repository.Repo) error { func setupRepos(t testing.TB) (repoA, repoB, remote *repository.GitRepo) { repoA = createRepo(false) repoB = createRepo(false) - remote = createRepo(false) + remote = createRepo(true) remoteAddr := "file://" + remote.GetPath() diff --git a/bug/op_create_test.go b/bug/op_create_test.go index 31693a4a..065b81c5 100644 --- a/bug/op_create_test.go +++ b/bug/op_create_test.go @@ -6,7 +6,6 @@ import ( "time" "github.com/MichaelMure/git-bug/identity" - "github.com/go-test/deep" "github.com/stretchr/testify/assert" ) @@ -22,9 +21,7 @@ func TestCreate(t *testing.T) { create.Apply(&snapshot) hash, err := create.Hash() - if err != nil { - t.Fatal(err) - } + assert.NoError(t, err) comment := Comment{Author: rene, Message: "message", UnixTime: Timestamp(create.UnixTime)} @@ -42,10 +39,7 @@ func TestCreate(t *testing.T) { }, } - deep.CompareUnexportedFields = true - if diff := deep.Equal(snapshot, expected); diff != nil { - t.Fatal(diff) - } + assert.Equal(t, expected, snapshot) } func TestCreateSerialize(t *testing.T) { diff --git a/bug/operation_pack.go b/bug/operation_pack.go index 18b2a478..1ffc1d1a 100644 --- a/bug/operation_pack.go +++ b/bug/operation_pack.go @@ -139,6 +139,12 @@ func (opp *OperationPack) Validate() error { // Write will serialize and store the OperationPack as a git blob and return // its hash func (opp *OperationPack) Write(repo repository.Repo) (git.Hash, error) { + // make sure we don't write invalid data + err := opp.Validate() + if err != nil { + return "", errors.Wrap(err, "validation error") + } + // First, make sure that all the identities are properly Commit as well for _, op := range opp.Operations { err := op.base().Author.Commit(repo) diff --git a/bug/operation_pack_test.go b/bug/operation_pack_test.go index 48f9f80c..8a8c7e62 100644 --- a/bug/operation_pack_test.go +++ b/bug/operation_pack_test.go @@ -5,7 +5,7 @@ import ( "testing" "github.com/MichaelMure/git-bug/util/git" - "github.com/go-test/deep" + "github.com/stretchr/testify/assert" ) func TestOperationPackSerialize(t *testing.T) { @@ -21,9 +21,7 @@ func TestOperationPackSerialize(t *testing.T) { opMeta.SetMetadata("key", "value") opp.Append(opMeta) - if len(opMeta.Metadata) != 1 { - t.Fatal() - } + assert.Equal(t, 1, len(opMeta.Metadata)) opFile := NewCreateOp(rene, unix, "title", "message", []git.Hash{ "abcdef", @@ -31,23 +29,14 @@ func TestOperationPackSerialize(t *testing.T) { }) opp.Append(opFile) - if len(opFile.Files) != 2 { - t.Fatal() - } + assert.Equal(t, 2, len(opFile.Files)) data, err := json.Marshal(opp) - if err != nil { - t.Fatal(err) - } + assert.NoError(t, err) var opp2 *OperationPack err = json.Unmarshal(data, &opp2) - if err != nil { - t.Fatal(err) - } - - deep.CompareUnexportedFields = false - if diff := deep.Equal(opp, opp2); diff != nil { - t.Fatal(diff) - } + + assert.NoError(t, err) + assert.Equal(t, opp, opp2) } diff --git a/cache/bug_cache.go b/cache/bug_cache.go index 53c5c7d9..53c1db64 100644 --- a/cache/bug_cache.go +++ b/cache/bug_cache.go @@ -93,7 +93,7 @@ func (c *BugCache) AddComment(message string) error { } func (c *BugCache) AddCommentWithFiles(message string, files []git.Hash) error { - author, err := identity.GetIdentity(c.repoCache.repo) + author, err := identity.GetUserIdentity(c.repoCache.repo) if err != nil { return err } @@ -115,7 +115,7 @@ func (c *BugCache) AddCommentRaw(author *identity.Identity, unixTime int64, mess } func (c *BugCache) ChangeLabels(added []string, removed []string) ([]bug.LabelChangeResult, error) { - author, err := identity.GetIdentity(c.repoCache.repo) + author, err := identity.GetUserIdentity(c.repoCache.repo) if err != nil { return nil, err } @@ -142,7 +142,7 @@ func (c *BugCache) ChangeLabelsRaw(author *identity.Identity, unixTime int64, ad } func (c *BugCache) Open() error { - author, err := identity.GetIdentity(c.repoCache.repo) + author, err := identity.GetUserIdentity(c.repoCache.repo) if err != nil { return err } @@ -164,7 +164,7 @@ func (c *BugCache) OpenRaw(author *identity.Identity, unixTime int64, metadata m } func (c *BugCache) Close() error { - author, err := identity.GetIdentity(c.repoCache.repo) + author, err := identity.GetUserIdentity(c.repoCache.repo) if err != nil { return err } @@ -186,7 +186,7 @@ func (c *BugCache) CloseRaw(author *identity.Identity, unixTime int64, metadata } func (c *BugCache) SetTitle(title string) error { - author, err := identity.GetIdentity(c.repoCache.repo) + author, err := identity.GetUserIdentity(c.repoCache.repo) if err != nil { return err } @@ -208,7 +208,7 @@ func (c *BugCache) SetTitleRaw(author *identity.Identity, unixTime int64, title } func (c *BugCache) EditComment(target git.Hash, message string) error { - author, err := identity.GetIdentity(c.repoCache.repo) + author, err := identity.GetUserIdentity(c.repoCache.repo) if err != nil { return err } diff --git a/cache/bug_excerpt.go b/cache/bug_excerpt.go index f5844b64..daf89c4f 100644 --- a/cache/bug_excerpt.go +++ b/cache/bug_excerpt.go @@ -3,8 +3,6 @@ package cache import ( "encoding/gob" - "github.com/MichaelMure/git-bug/identity" - "github.com/MichaelMure/git-bug/bug" "github.com/MichaelMure/git-bug/util/lamport" ) @@ -20,12 +18,17 @@ type BugExcerpt struct { EditUnixTime int64 Status bug.Status - Author identity.Interface + Author AuthorExcerpt Labels []bug.Label CreateMetadata map[string]string } +type AuthorExcerpt struct { + Name string + Login string +} + func NewBugExcerpt(b bug.Interface, snap *bug.Snapshot) *BugExcerpt { return &BugExcerpt{ Id: b.Id(), @@ -34,9 +37,12 @@ func NewBugExcerpt(b bug.Interface, snap *bug.Snapshot) *BugExcerpt { CreateUnixTime: b.FirstOp().GetUnixTime(), EditUnixTime: snap.LastEditUnix(), Status: snap.Status, - Author: snap.Author, - Labels: snap.Labels, - CreateMetadata: b.FirstOp().AllMetadata(), + Author: AuthorExcerpt{ + Login: snap.Author.Login(), + Name: snap.Author.Name(), + }, + Labels: snap.Labels, + CreateMetadata: b.FirstOp().AllMetadata(), } } diff --git a/cache/filter.go b/cache/filter.go index 033df131..3cf4a991 100644 --- a/cache/filter.go +++ b/cache/filter.go @@ -1,6 +1,8 @@ package cache import ( + "strings" + "github.com/MichaelMure/git-bug/bug" ) @@ -22,7 +24,10 @@ func StatusFilter(query string) (Filter, error) { // AuthorFilter return a Filter that match a bug author func AuthorFilter(query string) Filter { return func(excerpt *BugExcerpt) bool { - return excerpt.Author.Match(query) + query = strings.ToLower(query) + + return strings.Contains(strings.ToLower(excerpt.Author.Name), query) || + strings.Contains(strings.ToLower(excerpt.Author.Login), query) } } diff --git a/cache/repo_cache.go b/cache/repo_cache.go index e1a3d8f8..3d8b352b 100644 --- a/cache/repo_cache.go +++ b/cache/repo_cache.go @@ -394,7 +394,7 @@ func (c *RepoCache) NewBug(title string, message string) (*BugCache, error) { // NewBugWithFiles create a new bug with attached files for the message // The new bug is written in the repository (commit) func (c *RepoCache) NewBugWithFiles(title string, message string, files []git.Hash) (*BugCache, error) { - author, err := identity.GetIdentity(c.repo) + author, err := identity.GetUserIdentity(c.repo) if err != nil { return nil, err } diff --git a/commands/id.go b/commands/id.go index 44294132..19d040ee 100644 --- a/commands/id.go +++ b/commands/id.go @@ -19,7 +19,7 @@ func runId(cmd *cobra.Command, args []string) error { if len(args) == 1 { id, err = identity.Read(repo, args[0]) } else { - id, err = identity.GetIdentity(repo) + id, err = identity.GetUserIdentity(repo) } if err != nil { diff --git a/graphql/schema/bug.graphql b/graphql/schema/bug.graphql index 9530c576..7e1c57b5 100644 --- a/graphql/schema/bug.graphql +++ b/graphql/schema/bug.graphql @@ -105,4 +105,3 @@ type Repository { ): BugConnection! bug(prefix: String!): Bug } - diff --git a/graphql/schema/identity.graphql b/graphql/schema/identity.graphql index 9e76d885..7c5ef126 100644 --- a/graphql/schema/identity.graphql +++ b/graphql/schema/identity.graphql @@ -10,4 +10,4 @@ type Identity { displayName: String! """An url to an avatar""" avatarUrl: String -}
\ No newline at end of file +} diff --git a/graphql/schema/operations.graphql b/graphql/schema/operations.graphql index 2b206418..d37df2e2 100644 --- a/graphql/schema/operations.graphql +++ b/graphql/schema/operations.graphql @@ -97,4 +97,4 @@ type LabelChangeOperation implements Operation & Authored { added: [Label!]! removed: [Label!]! -}
\ No newline at end of file +} diff --git a/graphql/schema/root.graphql b/graphql/schema/root.graphql index 56558f7c..7b43366f 100644 --- a/graphql/schema/root.graphql +++ b/graphql/schema/root.graphql @@ -35,4 +35,4 @@ type Mutation { setTitle(repoRef: String, prefix: String!, title: String!): Bug! commit(repoRef: String, prefix: String!): Bug! -}
\ No newline at end of file +} diff --git a/graphql/schema/timeline.graphql b/graphql/schema/timeline.graphql index 29ed6e60..35bb88bf 100644 --- a/graphql/schema/timeline.graphql +++ b/graphql/schema/timeline.graphql @@ -83,4 +83,4 @@ type SetTitleTimelineItem implements TimelineItem { date: Time! title: String! was: String! -}
\ No newline at end of file +} diff --git a/identity/bare.go b/identity/bare.go index 729dc2e0..5aaa0166 100644 --- a/identity/bare.go +++ b/identity/bare.go @@ -34,7 +34,7 @@ func NewBareFull(name string, email string, login string, avatarUrl string) *Bar return &Bare{name: name, email: email, login: login, avatarUrl: avatarUrl} } -type bareIdentityJson struct { +type bareIdentityJSON struct { Name string `json:"name,omitempty"` Email string `json:"email,omitempty"` Login string `json:"login,omitempty"` @@ -42,7 +42,7 @@ type bareIdentityJson struct { } func (i *Bare) MarshalJSON() ([]byte, error) { - return json.Marshal(bareIdentityJson{ + return json.Marshal(bareIdentityJSON{ Name: i.name, Email: i.email, Login: i.login, @@ -51,7 +51,7 @@ func (i *Bare) MarshalJSON() ([]byte, error) { } func (i *Bare) UnmarshalJSON(data []byte) error { - aux := bareIdentityJson{} + aux := bareIdentityJSON{} if err := json.Unmarshal(data, &aux); err != nil { return err @@ -125,14 +125,6 @@ func (i *Bare) DisplayName() string { panic("invalid person data") } -// Match tell is the Person match the given query string -func (i *Bare) Match(query string) bool { - query = strings.ToLower(query) - - return strings.Contains(strings.ToLower(i.name), query) || - strings.Contains(strings.ToLower(i.login), query) -} - // Validate check if the Identity data is valid func (i *Bare) Validate() error { if text.Empty(i.name) && text.Empty(i.login) { diff --git a/identity/bare_test.go b/identity/bare_test.go index 1458107a..4b28c7ad 100644 --- a/identity/bare_test.go +++ b/identity/bare_test.go @@ -3,7 +3,7 @@ package identity import ( "testing" - "github.com/magiconair/properties/assert" + "github.com/stretchr/testify/assert" ) func TestBare_Id(t *testing.T) { diff --git a/identity/common.go b/identity/common.go index 32dd3d9e..5301471a 100644 --- a/identity/common.go +++ b/identity/common.go @@ -51,3 +51,7 @@ func UnmarshalJSON(raw json.RawMessage) (Interface, error) { return nil, fmt.Errorf("unknown identity type") } + +type Resolver interface { + ResolveIdentity(id string) (Interface, error) +} diff --git a/identity/identity.go b/identity/identity.go index 38729e37..2a422789 100644 --- a/identity/identity.go +++ b/identity/identity.go @@ -4,7 +4,6 @@ package identity import ( "encoding/json" "fmt" - "strings" "github.com/MichaelMure/git-bug/repository" "github.com/MichaelMure/git-bug/util/git" @@ -49,13 +48,13 @@ func NewIdentityFull(name string, email string, login string, avatarUrl string) } } -type identityJson struct { +type identityJSON struct { Id string `json:"id"` } // MarshalJSON will only serialize the id func (i *Identity) MarshalJSON() ([]byte, error) { - return json.Marshal(identityJson{ + return json.Marshal(identityJSON{ Id: i.Id(), }) } @@ -64,7 +63,7 @@ func (i *Identity) MarshalJSON() ([]byte, error) { // Users of this package are expected to run Load() to load // the remaining data from the identities data in git. func (i *Identity) UnmarshalJSON(data []byte) error { - aux := identityJson{} + aux := identityJSON{} if err := json.Unmarshal(data, &aux); err != nil { return err @@ -164,35 +163,13 @@ func NewFromGitUser(repo repository.Repo) (*Identity, error) { return NewIdentity(name, email), nil } -// BuildFromGit will query the repository for user detail and -// build the corresponding Identity -/*func BuildFromGit(repo repository.Repo) *Identity { - version := Version{} - - name, err := repo.GetUserName() - if err == nil { - version.Name = name - } - - email, err := repo.GetUserEmail() - if err == nil { - version.Email = email - } - - return &Identity{ - Versions: []Version{ - version, - }, - } -}*/ - -// SetIdentity store the user identity's id in the git config -func SetIdentity(repo repository.RepoCommon, identity Identity) error { +// SetUserIdentity store the user identity's id in the git config +func SetUserIdentity(repo repository.RepoCommon, identity Identity) error { return repo.StoreConfig(identityConfigKey, identity.Id()) } -// GetIdentity read the current user identity, set with a git config entry -func GetIdentity(repo repository.Repo) (*Identity, error) { +// GetUserIdentity read the current user identity, set with a git config entry +func GetUserIdentity(repo repository.Repo) (*Identity, error) { configs, err := repo.ReadConfigs(identityConfigKey) if err != nil { return nil, err @@ -299,14 +276,6 @@ func (i *Identity) Validate() error { return nil } -func (i *Identity) firstVersion() *Version { - if len(i.Versions) <= 0 { - panic("no version at all") - } - - return i.Versions[0] -} - func (i *Identity) lastVersion() *Version { if len(i.Versions) <= 0 { panic("no version at all") @@ -372,14 +341,6 @@ func (i *Identity) ValidKeysAtTime(time lamport.Time) []Key { return result } -// Match tell is the Identity match the given query string -func (i *Identity) Match(query string) bool { - query = strings.ToLower(query) - - return strings.Contains(strings.ToLower(i.Name()), query) || - strings.Contains(strings.ToLower(i.Login()), query) -} - // DisplayName return a non-empty string to display, representing the // identity, based on the non-empty values. func (i *Identity) DisplayName() string { diff --git a/identity/identity_test.go b/identity/identity_test.go index 914126be..afb804fc 100644 --- a/identity/identity_test.go +++ b/identity/identity_test.go @@ -8,12 +8,13 @@ import ( "github.com/stretchr/testify/require" ) +// Test the commit and load of an Identity with multiple versions func TestIdentityCommitLoad(t *testing.T) { mockRepo := repository.NewMockRepoForTest() // single version - identity := Identity{ + identity := &Identity{ Versions: []*Version{ { Name: "René Descartes", @@ -30,11 +31,11 @@ func TestIdentityCommitLoad(t *testing.T) { loaded, err := Read(mockRepo, identity.id) assert.Nil(t, err) commitsAreSet(t, loaded) - equivalentIdentity(t, &identity, loaded) + equivalentIdentity(t, identity, loaded) // multiple version - identity = Identity{ + identity = &Identity{ Versions: []*Version{ { Time: 100, @@ -71,7 +72,7 @@ func TestIdentityCommitLoad(t *testing.T) { loaded, err = Read(mockRepo, identity.id) assert.Nil(t, err) commitsAreSet(t, loaded) - equivalentIdentity(t, &identity, loaded) + equivalentIdentity(t, identity, loaded) // add more version @@ -101,7 +102,7 @@ func TestIdentityCommitLoad(t *testing.T) { loaded, err = Read(mockRepo, identity.id) assert.Nil(t, err) commitsAreSet(t, loaded) - equivalentIdentity(t, &identity, loaded) + equivalentIdentity(t, identity, loaded) } func commitsAreSet(t *testing.T, identity *Identity) { @@ -120,6 +121,7 @@ func equivalentIdentity(t *testing.T, expected, actual *Identity) { assert.Equal(t, expected, actual) } +// Test that the correct crypto keys are returned for a given lamport time func TestIdentity_ValidKeysAtTime(t *testing.T) { identity := Identity{ Versions: []*Version{ @@ -176,6 +178,7 @@ func TestIdentity_ValidKeysAtTime(t *testing.T) { assert.Equal(t, identity.ValidKeysAtTime(3000), []Key{{PubKey: "pubkeyE"}}) } +// Test the immutable or mutable metadata search func TestMetadata(t *testing.T) { mockRepo := repository.NewMockRepoForTest() diff --git a/identity/interface.go b/identity/interface.go index c784a7a6..1d534eb8 100644 --- a/identity/interface.go +++ b/identity/interface.go @@ -23,9 +23,6 @@ type Interface interface { // identity, based on the non-empty values. DisplayName() string - // Match tell is the Person match the given query string - Match(query string) bool - // Validate check if the Identity data is valid Validate() error diff --git a/identity/key.go b/identity/key.go index c498ec09..90edfb60 100644 --- a/identity/key.go +++ b/identity/key.go @@ -5,3 +5,9 @@ type Key struct { Fingerprint string `json:"fingerprint"` PubKey string `json:"pub_key"` } + +func (k *Key) Validate() error { + // Todo + + return nil +} diff --git a/identity/version.go b/identity/version.go index bc4561d9..d4afc893 100644 --- a/identity/version.go +++ b/identity/version.go @@ -10,34 +10,88 @@ import ( "github.com/MichaelMure/git-bug/util/git" "github.com/MichaelMure/git-bug/util/lamport" "github.com/MichaelMure/git-bug/util/text" + "github.com/pkg/errors" ) +const formatVersion = 1 + // Version is a complete set of information about an Identity at a point in time. type Version struct { - // Private field so not serialized + // Not serialized commitHash git.Hash // The lamport time at which this version become effective // The reference time is the bug edition lamport clock - Time lamport.Time `json:"time"` + Time lamport.Time - Name string `json:"name"` - Email string `json:"email"` - Login string `json:"login"` - AvatarUrl string `json:"avatar_url"` + Name string + Email string + Login string + AvatarUrl string // The set of keys valid at that time, from this version onward, until they get removed // in a new version. This allow to have multiple key for the same identity (e.g. one per // device) as well as revoke key. - Keys []Key `json:"pub_keys"` + Keys []Key // This optional array is here to ensure a better randomness of the identity id to avoid collisions. // It has no functional purpose and should be ignored. // It is advised to fill this array if there is not enough entropy, e.g. if there is no keys. - Nonce []byte `json:"nonce,omitempty"` + Nonce []byte // A set of arbitrary key/value to store metadata about a version or about an Identity in general. - Metadata map[string]string `json:"metadata,omitempty"` + Metadata map[string]string +} + +type VersionJSON struct { + // Additional field to version the data + FormatVersion uint `json:"version"` + + Time lamport.Time `json:"time"` + Name string `json:"name"` + Email string `json:"email"` + Login string `json:"login"` + AvatarUrl string `json:"avatar_url"` + Keys []Key `json:"pub_keys"` + Nonce []byte `json:"nonce,omitempty"` + Metadata map[string]string `json:"metadata,omitempty"` +} + +func (v *Version) MarshalJSON() ([]byte, error) { + return json.Marshal(VersionJSON{ + FormatVersion: formatVersion, + Time: v.Time, + Name: v.Name, + Email: v.Email, + Login: v.Login, + AvatarUrl: v.AvatarUrl, + Keys: v.Keys, + Nonce: v.Nonce, + Metadata: v.Metadata, + }) +} + +func (v *Version) UnmarshalJSON(data []byte) error { + var aux VersionJSON + + if err := json.Unmarshal(data, &aux); err != nil { + return err + } + + if aux.FormatVersion != formatVersion { + return fmt.Errorf("unknown format version %v", aux.FormatVersion) + } + + v.Time = aux.Time + v.Name = aux.Name + v.Email = aux.Email + v.Login = aux.Login + v.AvatarUrl = aux.AvatarUrl + v.Keys = aux.Keys + v.Nonce = aux.Nonce + v.Metadata = aux.Metadata + + return nil } func (v *Version) Validate() error { @@ -77,12 +131,24 @@ func (v *Version) Validate() error { return fmt.Errorf("nonce is too big") } + for _, k := range v.Keys { + if err := k.Validate(); err != nil { + return errors.Wrap(err, "invalid key") + } + } + return nil } // Write will serialize and store the Version as a git blob and return // its hash func (v *Version) Write(repo repository.Repo) (git.Hash, error) { + // make sure we don't write invalid data + err := v.Validate() + if err != nil { + return "", errors.Wrap(err, "validation error") + } + data, err := json.Marshal(v) if err != nil { diff --git a/vendor/github.com/go-test/deep/.gitignore b/vendor/github.com/go-test/deep/.gitignore deleted file mode 100644 index 53f12f0f..00000000 --- a/vendor/github.com/go-test/deep/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*.swp -*.out diff --git a/vendor/github.com/go-test/deep/.travis.yml b/vendor/github.com/go-test/deep/.travis.yml deleted file mode 100644 index 2279c614..00000000 --- a/vendor/github.com/go-test/deep/.travis.yml +++ /dev/null @@ -1,13 +0,0 @@ -language: go - -go: - - 1.7 - - 1.8 - - 1.9 - -before_install: - - go get github.com/mattn/goveralls - - go get golang.org/x/tools/cover - -script: - - $HOME/gopath/bin/goveralls -service=travis-ci diff --git a/vendor/github.com/go-test/deep/CHANGES.md b/vendor/github.com/go-test/deep/CHANGES.md deleted file mode 100644 index 4351819d..00000000 --- a/vendor/github.com/go-test/deep/CHANGES.md +++ /dev/null @@ -1,9 +0,0 @@ -# go-test/deep Changelog - -## v1.0.1 released 2018-01-28 - -* Fixed #12: Arrays are not properly compared (samlitowitz) - -## v1.0.0 releaesd 2017-10-27 - -* First release diff --git a/vendor/github.com/go-test/deep/LICENSE b/vendor/github.com/go-test/deep/LICENSE deleted file mode 100644 index 228ef16f..00000000 --- a/vendor/github.com/go-test/deep/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright 2015-2017 Daniel Nichter - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/go-test/deep/README.md b/vendor/github.com/go-test/deep/README.md deleted file mode 100644 index 3b78eac7..00000000 --- a/vendor/github.com/go-test/deep/README.md +++ /dev/null @@ -1,51 +0,0 @@ -# Deep Variable Equality for Humans - -[![Go Report Card](https://goreportcard.com/badge/github.com/go-test/deep)](https://goreportcard.com/report/github.com/go-test/deep) [![Build Status](https://travis-ci.org/go-test/deep.svg?branch=master)](https://travis-ci.org/go-test/deep) [![Coverage Status](https://coveralls.io/repos/github/go-test/deep/badge.svg?branch=master)](https://coveralls.io/github/go-test/deep?branch=master) [![GoDoc](https://godoc.org/github.com/go-test/deep?status.svg)](https://godoc.org/github.com/go-test/deep) - -This package provides a single function: `deep.Equal`. It's like [reflect.DeepEqual](http://golang.org/pkg/reflect/#DeepEqual) but much friendlier to humans (or any sentient being) for two reason: - -* `deep.Equal` returns a list of differences -* `deep.Equal` does not compare unexported fields (by default) - -`reflect.DeepEqual` is good (like all things Golang!), but it's a game of [Hunt the Wumpus](https://en.wikipedia.org/wiki/Hunt_the_Wumpus). For large maps, slices, and structs, finding the difference is difficult. - -`deep.Equal` doesn't play games with you, it lists the differences: - -```go -package main_test - -import ( - "testing" - "github.com/go-test/deep" -) - -type T struct { - Name string - Numbers []float64 -} - -func TestDeepEqual(t *testing.T) { - // Can you spot the difference? - t1 := T{ - Name: "Isabella", - Numbers: []float64{1.13459, 2.29343, 3.010100010}, - } - t2 := T{ - Name: "Isabella", - Numbers: []float64{1.13459, 2.29843, 3.010100010}, - } - - if diff := deep.Equal(t1, t2); diff != nil { - t.Error(diff) - } -} -``` - - -``` -$ go test ---- FAIL: TestDeepEqual (0.00s) - main_test.go:25: [Numbers.slice[1]: 2.29343 != 2.29843] -``` - -The difference is in `Numbers.slice[1]`: the two values aren't equal using Go `==`. diff --git a/vendor/github.com/go-test/deep/deep.go b/vendor/github.com/go-test/deep/deep.go deleted file mode 100644 index 4ea14cb0..00000000 --- a/vendor/github.com/go-test/deep/deep.go +++ /dev/null @@ -1,352 +0,0 @@ -// Package deep provides function deep.Equal which is like reflect.DeepEqual but -// returns a list of differences. This is helpful when comparing complex types -// like structures and maps. -package deep - -import ( - "errors" - "fmt" - "log" - "reflect" - "strings" -) - -var ( - // FloatPrecision is the number of decimal places to round float values - // to when comparing. - FloatPrecision = 10 - - // MaxDiff specifies the maximum number of differences to return. - MaxDiff = 10 - - // MaxDepth specifies the maximum levels of a struct to recurse into. - MaxDepth = 10 - - // LogErrors causes errors to be logged to STDERR when true. - LogErrors = false - - // CompareUnexportedFields causes unexported struct fields, like s in - // T{s int}, to be comparsed when true. - CompareUnexportedFields = false -) - -var ( - // ErrMaxRecursion is logged when MaxDepth is reached. - ErrMaxRecursion = errors.New("recursed to MaxDepth") - - // ErrTypeMismatch is logged when Equal passed two different types of values. - ErrTypeMismatch = errors.New("variables are different reflect.Type") - - // ErrNotHandled is logged when a primitive Go kind is not handled. - ErrNotHandled = errors.New("cannot compare the reflect.Kind") -) - -type cmp struct { - diff []string - buff []string - floatFormat string -} - -var errorType = reflect.TypeOf((*error)(nil)).Elem() - -// Equal compares variables a and b, recursing into their structure up to -// MaxDepth levels deep, and returns a list of differences, or nil if there are -// none. Some differences may not be found if an error is also returned. -// -// If a type has an Equal method, like time.Equal, it is called to check for -// equality. -func Equal(a, b interface{}) []string { - aVal := reflect.ValueOf(a) - bVal := reflect.ValueOf(b) - c := &cmp{ - diff: []string{}, - buff: []string{}, - floatFormat: fmt.Sprintf("%%.%df", FloatPrecision), - } - if a == nil && b == nil { - return nil - } else if a == nil && b != nil { - c.saveDiff(b, "<nil pointer>") - } else if a != nil && b == nil { - c.saveDiff(a, "<nil pointer>") - } - if len(c.diff) > 0 { - return c.diff - } - - c.equals(aVal, bVal, 0) - if len(c.diff) > 0 { - return c.diff // diffs - } - return nil // no diffs -} - -func (c *cmp) equals(a, b reflect.Value, level int) { - if level > MaxDepth { - logError(ErrMaxRecursion) - return - } - - // Check if one value is nil, e.g. T{x: *X} and T.x is nil - if !a.IsValid() || !b.IsValid() { - if a.IsValid() && !b.IsValid() { - c.saveDiff(a.Type(), "<nil pointer>") - } else if !a.IsValid() && b.IsValid() { - c.saveDiff("<nil pointer>", b.Type()) - } - return - } - - // If differenet types, they can't be equal - aType := a.Type() - bType := b.Type() - if aType != bType { - c.saveDiff(aType, bType) - logError(ErrTypeMismatch) - return - } - - // Primitive https://golang.org/pkg/reflect/#Kind - aKind := a.Kind() - bKind := b.Kind() - - // If both types implement the error interface, compare the error strings. - // This must be done before dereferencing because the interface is on a - // pointer receiver. - if aType.Implements(errorType) && bType.Implements(errorType) { - if a.Elem().IsValid() && b.Elem().IsValid() { // both err != nil - aString := a.MethodByName("Error").Call(nil)[0].String() - bString := b.MethodByName("Error").Call(nil)[0].String() - if aString != bString { - c.saveDiff(aString, bString) - } - return - } - } - - // Dereference pointers and interface{} - if aElem, bElem := (aKind == reflect.Ptr || aKind == reflect.Interface), - (bKind == reflect.Ptr || bKind == reflect.Interface); aElem || bElem { - - if aElem { - a = a.Elem() - } - - if bElem { - b = b.Elem() - } - - c.equals(a, b, level+1) - return - } - - // Types with an Equal(), like time.Time. - eqFunc := a.MethodByName("Equal") - if eqFunc.IsValid() { - retVals := eqFunc.Call([]reflect.Value{b}) - if !retVals[0].Bool() { - c.saveDiff(a, b) - } - return - } - - switch aKind { - - ///////////////////////////////////////////////////////////////////// - // Iterable kinds - ///////////////////////////////////////////////////////////////////// - - case reflect.Struct: - /* - The variables are structs like: - type T struct { - FirstName string - LastName string - } - Type = <pkg>.T, Kind = reflect.Struct - - Iterate through the fields (FirstName, LastName), recurse into their values. - */ - for i := 0; i < a.NumField(); i++ { - if aType.Field(i).PkgPath != "" && !CompareUnexportedFields { - continue // skip unexported field, e.g. s in type T struct {s string} - } - - c.push(aType.Field(i).Name) // push field name to buff - - // Get the Value for each field, e.g. FirstName has Type = string, - // Kind = reflect.String. - af := a.Field(i) - bf := b.Field(i) - - // Recurse to compare the field values - c.equals(af, bf, level+1) - - c.pop() // pop field name from buff - - if len(c.diff) >= MaxDiff { - break - } - } - case reflect.Map: - /* - The variables are maps like: - map[string]int{ - "foo": 1, - "bar": 2, - } - Type = map[string]int, Kind = reflect.Map - - Or: - type T map[string]int{} - Type = <pkg>.T, Kind = reflect.Map - - Iterate through the map keys (foo, bar), recurse into their values. - */ - - if a.IsNil() || b.IsNil() { - if a.IsNil() && !b.IsNil() { - c.saveDiff("<nil map>", b) - } else if !a.IsNil() && b.IsNil() { - c.saveDiff(a, "<nil map>") - } - return - } - - if a.Pointer() == b.Pointer() { - return - } - - for _, key := range a.MapKeys() { - c.push(fmt.Sprintf("map[%s]", key)) - - aVal := a.MapIndex(key) - bVal := b.MapIndex(key) - if bVal.IsValid() { - c.equals(aVal, bVal, level+1) - } else { - c.saveDiff(aVal, "<does not have key>") - } - - c.pop() - - if len(c.diff) >= MaxDiff { - return - } - } - - for _, key := range b.MapKeys() { - if aVal := a.MapIndex(key); aVal.IsValid() { - continue - } - - c.push(fmt.Sprintf("map[%s]", key)) - c.saveDiff("<does not have key>", b.MapIndex(key)) - c.pop() - if len(c.diff) >= MaxDiff { - return - } - } - case reflect.Array: - n := a.Len() - for i := 0; i < n; i++ { - c.push(fmt.Sprintf("array[%d]", i)) - c.equals(a.Index(i), b.Index(i), level+1) - c.pop() - if len(c.diff) >= MaxDiff { - break - } - } - case reflect.Slice: - if a.IsNil() || b.IsNil() { - if a.IsNil() && !b.IsNil() { - c.saveDiff("<nil slice>", b) - } else if !a.IsNil() && b.IsNil() { - c.saveDiff(a, "<nil slice>") - } - return - } - - if a.Pointer() == b.Pointer() { - return - } - - aLen := a.Len() - bLen := b.Len() - n := aLen - if bLen > aLen { - n = bLen - } - for i := 0; i < n; i++ { - c.push(fmt.Sprintf("slice[%d]", i)) - if i < aLen && i < bLen { - c.equals(a.Index(i), b.Index(i), level+1) - } else if i < aLen { - c.saveDiff(a.Index(i), "<no value>") - } else { - c.saveDiff("<no value>", b.Index(i)) - } - c.pop() - if len(c.diff) >= MaxDiff { - break - } - } - - ///////////////////////////////////////////////////////////////////// - // Primitive kinds - ///////////////////////////////////////////////////////////////////// - - case reflect.Float32, reflect.Float64: - // Avoid 0.04147685731961082 != 0.041476857319611 - // 6 decimal places is close enough - aval := fmt.Sprintf(c.floatFormat, a.Float()) - bval := fmt.Sprintf(c.floatFormat, b.Float()) - if aval != bval { - c.saveDiff(a.Float(), b.Float()) - } - case reflect.Bool: - if a.Bool() != b.Bool() { - c.saveDiff(a.Bool(), b.Bool()) - } - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - if a.Int() != b.Int() { - c.saveDiff(a.Int(), b.Int()) - } - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - if a.Uint() != b.Uint() { - c.saveDiff(a.Uint(), b.Uint()) - } - case reflect.String: - if a.String() != b.String() { - c.saveDiff(a.String(), b.String()) - } - - default: - logError(ErrNotHandled) - } -} - -func (c *cmp) push(name string) { - c.buff = append(c.buff, name) -} - -func (c *cmp) pop() { - if len(c.buff) > 0 { - c.buff = c.buff[0 : len(c.buff)-1] - } -} - -func (c *cmp) saveDiff(aval, bval interface{}) { - if len(c.buff) > 0 { - varName := strings.Join(c.buff, ".") - c.diff = append(c.diff, fmt.Sprintf("%s: %v != %v", varName, aval, bval)) - } else { - c.diff = append(c.diff, fmt.Sprintf("%v != %v", aval, bval)) - } -} - -func logError(err error) { - if LogErrors { - log.Println(err) - } -} diff --git a/vendor/github.com/google/go-cmp/LICENSE b/vendor/github.com/google/go-cmp/LICENSE deleted file mode 100644 index 32017f8f..00000000 --- a/vendor/github.com/google/go-cmp/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2017 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/google/go-cmp/cmp/compare.go b/vendor/github.com/google/go-cmp/cmp/compare.go deleted file mode 100644 index 7e215f22..00000000 --- a/vendor/github.com/google/go-cmp/cmp/compare.go +++ /dev/null @@ -1,553 +0,0 @@ -// 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.md file. - -// Package cmp determines equality of values. -// -// This package is intended to be a more powerful and safer alternative to -// reflect.DeepEqual for comparing whether two values are semantically equal. -// -// The primary features of cmp are: -// -// • When the default behavior of equality does not suit the needs of the test, -// custom equality functions can override the equality operation. -// For example, an equality function may report floats as equal so long as they -// are within some tolerance of each other. -// -// • Types that have an Equal method may use that method to determine equality. -// This allows package authors to determine the equality operation for the types -// that they define. -// -// • If no custom equality functions are used and no Equal method is defined, -// equality is determined by recursively comparing the primitive kinds on both -// values, much like reflect.DeepEqual. Unlike reflect.DeepEqual, unexported -// fields are not compared by default; they result in panics unless suppressed -// by using an Ignore option (see cmpopts.IgnoreUnexported) or explicitly compared -// using the AllowUnexported option. -package cmp - -import ( - "fmt" - "reflect" - - "github.com/google/go-cmp/cmp/internal/diff" - "github.com/google/go-cmp/cmp/internal/function" - "github.com/google/go-cmp/cmp/internal/value" -) - -// BUG(dsnet): Maps with keys containing NaN values cannot be properly compared due to -// the reflection package's inability to retrieve such entries. Equal will panic -// anytime it comes across a NaN key, but this behavior may change. -// -// See https://golang.org/issue/11104 for more details. - -var nothing = reflect.Value{} - -// Equal reports whether x and y are equal by recursively applying the -// following rules in the given order to x and y and all of their sub-values: -// -// • If two values are not of the same type, then they are never equal -// and the overall result is false. -// -// • Let S be the set of all Ignore, Transformer, and Comparer options that -// remain after applying all path filters, value filters, and type filters. -// If at least one Ignore exists in S, then the comparison is ignored. -// If the number of Transformer and Comparer options in S is greater than one, -// then Equal panics because it is ambiguous which option to use. -// If S contains a single Transformer, then use that to transform the current -// values and recursively call Equal on the output values. -// If S contains a single Comparer, then use that to compare the current values. -// Otherwise, evaluation proceeds to the next rule. -// -// • If the values have an Equal method of the form "(T) Equal(T) bool" or -// "(T) Equal(I) bool" where T is assignable to I, then use the result of -// x.Equal(y) even if x or y is nil. -// Otherwise, no such method exists and evaluation proceeds to the next rule. -// -// • Lastly, try to compare x and y based on their basic kinds. -// Simple kinds like booleans, integers, floats, complex numbers, strings, and -// channels are compared using the equivalent of the == operator in Go. -// Functions are only equal if they are both nil, otherwise they are unequal. -// Pointers are equal if the underlying values they point to are also equal. -// Interfaces are equal if their underlying concrete values are also equal. -// -// Structs are equal if all of their fields are equal. If a struct contains -// unexported fields, Equal panics unless the AllowUnexported option is used or -// an Ignore option (e.g., cmpopts.IgnoreUnexported) ignores that field. -// -// Arrays, slices, and maps are equal if they are both nil or both non-nil -// with the same length and the elements at each index or key are equal. -// Note that a non-nil empty slice and a nil slice are not equal. -// To equate empty slices and maps, consider using cmpopts.EquateEmpty. -// Map keys are equal according to the == operator. -// To use custom comparisons for map keys, consider using cmpopts.SortMaps. -func Equal(x, y interface{}, opts ...Option) bool { - s := newState(opts) - s.compareAny(reflect.ValueOf(x), reflect.ValueOf(y)) - return s.result.Equal() -} - -// Diff returns a human-readable report of the differences between two values. -// It returns an empty string if and only if Equal returns true for the same -// input values and options. The output string will use the "-" symbol to -// indicate elements removed from x, and the "+" symbol to indicate elements -// added to y. -// -// Do not depend on this output being stable. -func Diff(x, y interface{}, opts ...Option) string { - r := new(defaultReporter) - opts = Options{Options(opts), r} - eq := Equal(x, y, opts...) - d := r.String() - if (d == "") != eq { - panic("inconsistent difference and equality results") - } - return d -} - -type state struct { - // These fields represent the "comparison state". - // Calling statelessCompare must not result in observable changes to these. - result diff.Result // The current result of comparison - curPath Path // The current path in the value tree - reporter reporter // Optional reporter used for difference formatting - - // dynChecker triggers pseudo-random checks for option correctness. - // It is safe for statelessCompare to mutate this value. - dynChecker dynChecker - - // These fields, once set by processOption, will not change. - exporters map[reflect.Type]bool // Set of structs with unexported field visibility - opts Options // List of all fundamental and filter options -} - -func newState(opts []Option) *state { - s := new(state) - for _, opt := range opts { - s.processOption(opt) - } - return s -} - -func (s *state) processOption(opt Option) { - switch opt := opt.(type) { - case nil: - case Options: - for _, o := range opt { - s.processOption(o) - } - case coreOption: - type filtered interface { - isFiltered() bool - } - if fopt, ok := opt.(filtered); ok && !fopt.isFiltered() { - panic(fmt.Sprintf("cannot use an unfiltered option: %v", opt)) - } - s.opts = append(s.opts, opt) - case visibleStructs: - if s.exporters == nil { - s.exporters = make(map[reflect.Type]bool) - } - for t := range opt { - s.exporters[t] = true - } - case reporter: - if s.reporter != nil { - panic("difference reporter already registered") - } - s.reporter = opt - default: - panic(fmt.Sprintf("unknown option %T", opt)) - } -} - -// statelessCompare compares two values and returns the result. -// This function is stateless in that it does not alter the current result, -// or output to any registered reporters. -func (s *state) statelessCompare(vx, vy reflect.Value) diff.Result { - // We do not save and restore the curPath because all of the compareX - // methods should properly push and pop from the path. - // It is an implementation bug if the contents of curPath differs from - // when calling this function to when returning from it. - - oldResult, oldReporter := s.result, s.reporter - s.result = diff.Result{} // Reset result - s.reporter = nil // Remove reporter to avoid spurious printouts - s.compareAny(vx, vy) - res := s.result - s.result, s.reporter = oldResult, oldReporter - return res -} - -func (s *state) compareAny(vx, vy reflect.Value) { - // TODO: Support cyclic data structures. - - // Rule 0: Differing types are never equal. - if !vx.IsValid() || !vy.IsValid() { - s.report(vx.IsValid() == vy.IsValid(), vx, vy) - return - } - if vx.Type() != vy.Type() { - s.report(false, vx, vy) // Possible for path to be empty - return - } - t := vx.Type() - if len(s.curPath) == 0 { - s.curPath.push(&pathStep{typ: t}) - defer s.curPath.pop() - } - vx, vy = s.tryExporting(vx, vy) - - // Rule 1: Check whether an option applies on this node in the value tree. - if s.tryOptions(vx, vy, t) { - return - } - - // Rule 2: Check whether the type has a valid Equal method. - if s.tryMethod(vx, vy, t) { - return - } - - // Rule 3: Recursively descend into each value's underlying kind. - switch t.Kind() { - case reflect.Bool: - s.report(vx.Bool() == vy.Bool(), vx, vy) - return - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - s.report(vx.Int() == vy.Int(), vx, vy) - return - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - s.report(vx.Uint() == vy.Uint(), vx, vy) - return - case reflect.Float32, reflect.Float64: - s.report(vx.Float() == vy.Float(), vx, vy) - return - case reflect.Complex64, reflect.Complex128: - s.report(vx.Complex() == vy.Complex(), vx, vy) - return - case reflect.String: - s.report(vx.String() == vy.String(), vx, vy) - return - case reflect.Chan, reflect.UnsafePointer: - s.report(vx.Pointer() == vy.Pointer(), vx, vy) - return - case reflect.Func: - s.report(vx.IsNil() && vy.IsNil(), vx, vy) - return - case reflect.Ptr: - if vx.IsNil() || vy.IsNil() { - s.report(vx.IsNil() && vy.IsNil(), vx, vy) - return - } - s.curPath.push(&indirect{pathStep{t.Elem()}}) - defer s.curPath.pop() - s.compareAny(vx.Elem(), vy.Elem()) - return - case reflect.Interface: - if vx.IsNil() || vy.IsNil() { - s.report(vx.IsNil() && vy.IsNil(), vx, vy) - return - } - if vx.Elem().Type() != vy.Elem().Type() { - s.report(false, vx.Elem(), vy.Elem()) - return - } - s.curPath.push(&typeAssertion{pathStep{vx.Elem().Type()}}) - defer s.curPath.pop() - s.compareAny(vx.Elem(), vy.Elem()) - return - case reflect.Slice: - if vx.IsNil() || vy.IsNil() { - s.report(vx.IsNil() && vy.IsNil(), vx, vy) - return - } - fallthrough - case reflect.Array: - s.compareArray(vx, vy, t) - return - case reflect.Map: - s.compareMap(vx, vy, t) - return - case reflect.Struct: - s.compareStruct(vx, vy, t) - return - default: - panic(fmt.Sprintf("%v kind not handled", t.Kind())) - } -} - -func (s *state) tryExporting(vx, vy reflect.Value) (reflect.Value, reflect.Value) { - if sf, ok := s.curPath[len(s.curPath)-1].(*structField); ok && sf.unexported { - if sf.force { - // Use unsafe pointer arithmetic to get read-write access to an - // unexported field in the struct. - vx = unsafeRetrieveField(sf.pvx, sf.field) - vy = unsafeRetrieveField(sf.pvy, sf.field) - } else { - // We are not allowed to export the value, so invalidate them - // so that tryOptions can panic later if not explicitly ignored. - vx = nothing - vy = nothing - } - } - return vx, vy -} - -func (s *state) tryOptions(vx, vy reflect.Value, t reflect.Type) bool { - // If there were no FilterValues, we will not detect invalid inputs, - // so manually check for them and append invalid if necessary. - // We still evaluate the options since an ignore can override invalid. - opts := s.opts - if !vx.IsValid() || !vy.IsValid() { - opts = Options{opts, invalid{}} - } - - // Evaluate all filters and apply the remaining options. - if opt := opts.filter(s, vx, vy, t); opt != nil { - opt.apply(s, vx, vy) - return true - } - return false -} - -func (s *state) tryMethod(vx, vy reflect.Value, t reflect.Type) bool { - // Check if this type even has an Equal method. - m, ok := t.MethodByName("Equal") - if !ok || !function.IsType(m.Type, function.EqualAssignable) { - return false - } - - eq := s.callTTBFunc(m.Func, vx, vy) - s.report(eq, vx, vy) - return true -} - -func (s *state) callTRFunc(f, v reflect.Value) reflect.Value { - v = sanitizeValue(v, f.Type().In(0)) - if !s.dynChecker.Next() { - return f.Call([]reflect.Value{v})[0] - } - - // Run the function twice and ensure that we get the same results back. - // We run in goroutines so that the race detector (if enabled) can detect - // unsafe mutations to the input. - c := make(chan reflect.Value) - go detectRaces(c, f, v) - want := f.Call([]reflect.Value{v})[0] - if got := <-c; !s.statelessCompare(got, want).Equal() { - // To avoid false-positives with non-reflexive equality operations, - // we sanity check whether a value is equal to itself. - if !s.statelessCompare(want, want).Equal() { - return want - } - fn := getFuncName(f.Pointer()) - panic(fmt.Sprintf("non-deterministic function detected: %s", fn)) - } - return want -} - -func (s *state) callTTBFunc(f, x, y reflect.Value) bool { - x = sanitizeValue(x, f.Type().In(0)) - y = sanitizeValue(y, f.Type().In(1)) - if !s.dynChecker.Next() { - return f.Call([]reflect.Value{x, y})[0].Bool() - } - - // Swapping the input arguments is sufficient to check that - // f is symmetric and deterministic. - // We run in goroutines so that the race detector (if enabled) can detect - // unsafe mutations to the input. - c := make(chan reflect.Value) - go detectRaces(c, f, y, x) - want := f.Call([]reflect.Value{x, y})[0].Bool() - if got := <-c; !got.IsValid() || got.Bool() != want { - fn := getFuncName(f.Pointer()) - panic(fmt.Sprintf("non-deterministic or non-symmetric function detected: %s", fn)) - } - return want -} - -func detectRaces(c chan<- reflect.Value, f reflect.Value, vs ...reflect.Value) { - var ret reflect.Value - defer func() { - recover() // Ignore panics, let the other call to f panic instead - c <- ret - }() - ret = f.Call(vs)[0] -} - -// sanitizeValue converts nil interfaces of type T to those of type R, -// assuming that T is assignable to R. -// Otherwise, it returns the input value as is. -func sanitizeValue(v reflect.Value, t reflect.Type) reflect.Value { - // TODO(dsnet): Remove this hacky workaround. - // See https://golang.org/issue/22143 - if v.Kind() == reflect.Interface && v.IsNil() && v.Type() != t { - return reflect.New(t).Elem() - } - return v -} - -func (s *state) compareArray(vx, vy reflect.Value, t reflect.Type) { - step := &sliceIndex{pathStep{t.Elem()}, 0, 0} - s.curPath.push(step) - - // Compute an edit-script for slices vx and vy. - es := diff.Difference(vx.Len(), vy.Len(), func(ix, iy int) diff.Result { - step.xkey, step.ykey = ix, iy - return s.statelessCompare(vx.Index(ix), vy.Index(iy)) - }) - - // Report the entire slice as is if the arrays are of primitive kind, - // and the arrays are different enough. - isPrimitive := false - switch t.Elem().Kind() { - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, - reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, - reflect.Bool, reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128: - isPrimitive = true - } - if isPrimitive && es.Dist() > (vx.Len()+vy.Len())/4 { - s.curPath.pop() // Pop first since we are reporting the whole slice - s.report(false, vx, vy) - return - } - - // Replay the edit-script. - var ix, iy int - for _, e := range es { - switch e { - case diff.UniqueX: - step.xkey, step.ykey = ix, -1 - s.report(false, vx.Index(ix), nothing) - ix++ - case diff.UniqueY: - step.xkey, step.ykey = -1, iy - s.report(false, nothing, vy.Index(iy)) - iy++ - default: - step.xkey, step.ykey = ix, iy - if e == diff.Identity { - s.report(true, vx.Index(ix), vy.Index(iy)) - } else { - s.compareAny(vx.Index(ix), vy.Index(iy)) - } - ix++ - iy++ - } - } - s.curPath.pop() - return -} - -func (s *state) compareMap(vx, vy reflect.Value, t reflect.Type) { - if vx.IsNil() || vy.IsNil() { - s.report(vx.IsNil() && vy.IsNil(), vx, vy) - return - } - - // We combine and sort the two map keys so that we can perform the - // comparisons in a deterministic order. - step := &mapIndex{pathStep: pathStep{t.Elem()}} - s.curPath.push(step) - defer s.curPath.pop() - for _, k := range value.SortKeys(append(vx.MapKeys(), vy.MapKeys()...)) { - step.key = k - vvx := vx.MapIndex(k) - vvy := vy.MapIndex(k) - switch { - case vvx.IsValid() && vvy.IsValid(): - s.compareAny(vvx, vvy) - case vvx.IsValid() && !vvy.IsValid(): - s.report(false, vvx, nothing) - case !vvx.IsValid() && vvy.IsValid(): - s.report(false, nothing, vvy) - default: - // It is possible for both vvx and vvy to be invalid if the - // key contained a NaN value in it. There is no way in - // reflection to be able to retrieve these values. - // See https://golang.org/issue/11104 - panic(fmt.Sprintf("%#v has map key with NaNs", s.curPath)) - } - } -} - -func (s *state) compareStruct(vx, vy reflect.Value, t reflect.Type) { - var vax, vay reflect.Value // Addressable versions of vx and vy - - step := &structField{} - s.curPath.push(step) - defer s.curPath.pop() - for i := 0; i < t.NumField(); i++ { - vvx := vx.Field(i) - vvy := vy.Field(i) - step.typ = t.Field(i).Type - step.name = t.Field(i).Name - step.idx = i - step.unexported = !isExported(step.name) - if step.unexported { - // Defer checking of unexported fields until later to give an - // Ignore a chance to ignore the field. - if !vax.IsValid() || !vay.IsValid() { - // For unsafeRetrieveField to work, the parent struct must - // be addressable. Create a new copy of the values if - // necessary to make them addressable. - vax = makeAddressable(vx) - vay = makeAddressable(vy) - } - step.force = s.exporters[t] - step.pvx = vax - step.pvy = vay - step.field = t.Field(i) - } - s.compareAny(vvx, vvy) - } -} - -// report records the result of a single comparison. -// It also calls Report if any reporter is registered. -func (s *state) report(eq bool, vx, vy reflect.Value) { - if eq { - s.result.NSame++ - } else { - s.result.NDiff++ - } - if s.reporter != nil { - s.reporter.Report(vx, vy, eq, s.curPath) - } -} - -// dynChecker tracks the state needed to periodically perform checks that -// user provided functions are symmetric and deterministic. -// The zero value is safe for immediate use. -type dynChecker struct{ curr, next int } - -// Next increments the state and reports whether a check should be performed. -// -// Checks occur every Nth function call, where N is a triangular number: -// 0 1 3 6 10 15 21 28 36 45 55 66 78 91 105 120 136 153 171 190 ... -// See https://en.wikipedia.org/wiki/Triangular_number -// -// This sequence ensures that the cost of checks drops significantly as -// the number of functions calls grows larger. -func (dc *dynChecker) Next() bool { - ok := dc.curr == dc.next - if ok { - dc.curr = 0 - dc.next++ - } - dc.curr++ - return ok -} - -// makeAddressable returns a value that is always addressable. -// It returns the input verbatim if it is already addressable, -// otherwise it creates a new value and returns an addressable copy. -func makeAddressable(v reflect.Value) reflect.Value { - if v.CanAddr() { - return v - } - vc := reflect.New(v.Type()).Elem() - vc.Set(v) - return vc -} diff --git a/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_disable.go b/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_disable.go deleted file mode 100644 index 42afa496..00000000 --- a/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_disable.go +++ /dev/null @@ -1,17 +0,0 @@ -// 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.md file. - -// +build !debug - -package diff - -var debug debugger - -type debugger struct{} - -func (debugger) Begin(_, _ int, f EqualFunc, _, _ *EditScript) EqualFunc { - return f -} -func (debugger) Update() {} -func (debugger) Finish() {} diff --git a/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_enable.go b/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_enable.go deleted file mode 100644 index fd9f7f17..00000000 --- a/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_enable.go +++ /dev/null @@ -1,122 +0,0 @@ -// 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.md file. - -// +build debug - -package diff - -import ( - "fmt" - "strings" - "sync" - "time" -) - -// The algorithm can be seen running in real-time by enabling debugging: -// go test -tags=debug -v -// -// Example output: -// === RUN TestDifference/#34 -// ┌───────────────────────────────┐ -// │ \ · · · · · · · · · · · · · · │ -// │ · # · · · · · · · · · · · · · │ -// │ · \ · · · · · · · · · · · · · │ -// │ · · \ · · · · · · · · · · · · │ -// │ · · · X # · · · · · · · · · · │ -// │ · · · # \ · · · · · · · · · · │ -// │ · · · · · # # · · · · · · · · │ -// │ · · · · · # \ · · · · · · · · │ -// │ · · · · · · · \ · · · · · · · │ -// │ · · · · · · · · \ · · · · · · │ -// │ · · · · · · · · · \ · · · · · │ -// │ · · · · · · · · · · \ · · # · │ -// │ · · · · · · · · · · · \ # # · │ -// │ · · · · · · · · · · · # # # · │ -// │ · · · · · · · · · · # # # # · │ -// │ · · · · · · · · · # # # # # · │ -// │ · · · · · · · · · · · · · · \ │ -// └───────────────────────────────┘ -// [.Y..M.XY......YXYXY.|] -// -// The grid represents the edit-graph where the horizontal axis represents -// list X and the vertical axis represents list Y. The start of the two lists -// is the top-left, while the ends are the bottom-right. The '·' represents -// an unexplored node in the graph. The '\' indicates that the two symbols -// from list X and Y are equal. The 'X' indicates that two symbols are similar -// (but not exactly equal) to each other. The '#' indicates that the two symbols -// are different (and not similar). The algorithm traverses this graph trying to -// make the paths starting in the top-left and the bottom-right connect. -// -// The series of '.', 'X', 'Y', and 'M' characters at the bottom represents -// the currently established path from the forward and reverse searches, -// separated by a '|' character. - -const ( - updateDelay = 100 * time.Millisecond - finishDelay = 500 * time.Millisecond - ansiTerminal = true // ANSI escape codes used to move terminal cursor -) - -var debug debugger - -type debugger struct { - sync.Mutex - p1, p2 EditScript - fwdPath, revPath *EditScript - grid []byte - lines int -} - -func (dbg *debugger) Begin(nx, ny int, f EqualFunc, p1, p2 *EditScript) EqualFunc { - dbg.Lock() - dbg.fwdPath, dbg.revPath = p1, p2 - top := "┌─" + strings.Repeat("──", nx) + "┐\n" - row := "│ " + strings.Repeat("· ", nx) + "│\n" - btm := "└─" + strings.Repeat("──", nx) + "┘\n" - dbg.grid = []byte(top + strings.Repeat(row, ny) + btm) - dbg.lines = strings.Count(dbg.String(), "\n") - fmt.Print(dbg) - - // Wrap the EqualFunc so that we can intercept each result. - return func(ix, iy int) (r Result) { - cell := dbg.grid[len(top)+iy*len(row):][len("│ ")+len("· ")*ix:][:len("·")] - for i := range cell { - cell[i] = 0 // Zero out the multiple bytes of UTF-8 middle-dot - } - switch r = f(ix, iy); { - case r.Equal(): - cell[0] = '\\' - case r.Similar(): - cell[0] = 'X' - default: - cell[0] = '#' - } - return - } -} - -func (dbg *debugger) Update() { - dbg.print(updateDelay) -} - -func (dbg *debugger) Finish() { - dbg.print(finishDelay) - dbg.Unlock() -} - -func (dbg *debugger) String() string { - dbg.p1, dbg.p2 = *dbg.fwdPath, dbg.p2[:0] - for i := len(*dbg.revPath) - 1; i >= 0; i-- { - dbg.p2 = append(dbg.p2, (*dbg.revPath)[i]) - } - return fmt.Sprintf("%s[%v|%v]\n\n", dbg.grid, dbg.p1, dbg.p2) -} - -func (dbg *debugger) print(d time.Duration) { - if ansiTerminal { - fmt.Printf("\x1b[%dA", dbg.lines) // Reset terminal cursor - } - fmt.Print(dbg) - time.Sleep(d) -} diff --git a/vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go b/vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go deleted file mode 100644 index 260befea..00000000 --- a/vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go +++ /dev/null @@ -1,363 +0,0 @@ -// 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.md file. - -// Package diff implements an algorithm for producing edit-scripts. -// The edit-script is a sequence of operations needed to transform one list -// of symbols into another (or vice-versa). The edits allowed are insertions, -// deletions, and modifications. The summation of all edits is called the -// Levenshtein distance as this problem is well-known in computer science. -// -// This package prioritizes performance over accuracy. That is, the run time -// is more important than obtaining a minimal Levenshtein distance. -package diff - -// EditType represents a single operation within an edit-script. -type EditType uint8 - -const ( - // Identity indicates that a symbol pair is identical in both list X and Y. - Identity EditType = iota - // UniqueX indicates that a symbol only exists in X and not Y. - UniqueX - // UniqueY indicates that a symbol only exists in Y and not X. - UniqueY - // Modified indicates that a symbol pair is a modification of each other. - Modified -) - -// EditScript represents the series of differences between two lists. -type EditScript []EditType - -// String returns a human-readable string representing the edit-script where -// Identity, UniqueX, UniqueY, and Modified are represented by the -// '.', 'X', 'Y', and 'M' characters, respectively. -func (es EditScript) String() string { - b := make([]byte, len(es)) - for i, e := range es { - switch e { - case Identity: - b[i] = '.' - case UniqueX: - b[i] = 'X' - case UniqueY: - b[i] = 'Y' - case Modified: - b[i] = 'M' - default: - panic("invalid edit-type") - } - } - return string(b) -} - -// stats returns a histogram of the number of each type of edit operation. -func (es EditScript) stats() (s struct{ NI, NX, NY, NM int }) { - for _, e := range es { - switch e { - case Identity: - s.NI++ - case UniqueX: - s.NX++ - case UniqueY: - s.NY++ - case Modified: - s.NM++ - default: - panic("invalid edit-type") - } - } - return -} - -// Dist is the Levenshtein distance and is guaranteed to be 0 if and only if -// lists X and Y are equal. -func (es EditScript) Dist() int { return len(es) - es.stats().NI } - -// LenX is the length of the X list. -func (es EditScript) LenX() int { return len(es) - es.stats().NY } - -// LenY is the length of the Y list. -func (es EditScript) LenY() int { return len(es) - es.stats().NX } - -// EqualFunc reports whether the symbols at indexes ix and iy are equal. -// When called by Difference, the index is guaranteed to be within nx and ny. -type EqualFunc func(ix int, iy int) Result - -// Result is the result of comparison. -// NSame is the number of sub-elements that are equal. -// NDiff is the number of sub-elements that are not equal. -type Result struct{ NSame, NDiff int } - -// Equal indicates whether the symbols are equal. Two symbols are equal -// if and only if NDiff == 0. If Equal, then they are also Similar. -func (r Result) Equal() bool { return r.NDiff == 0 } - -// Similar indicates whether two symbols are similar and may be represented -// by using the Modified type. As a special case, we consider binary comparisons -// (i.e., those that return Result{1, 0} or Result{0, 1}) to be similar. -// -// The exact ratio of NSame to NDiff to determine similarity may change. -func (r Result) Similar() bool { - // Use NSame+1 to offset NSame so that binary comparisons are similar. - return r.NSame+1 >= r.NDiff -} - -// Difference reports whether two lists of lengths nx and ny are equal -// given the definition of equality provided as f. -// -// This function returns an edit-script, which is a sequence of operations -// needed to convert one list into the other. The following invariants for -// the edit-script are maintained: -// • eq == (es.Dist()==0) -// • nx == es.LenX() -// • ny == es.LenY() -// -// This algorithm is not guaranteed to be an optimal solution (i.e., one that -// produces an edit-script with a minimal Levenshtein distance). This algorithm -// favors performance over optimality. The exact output is not guaranteed to -// be stable and may change over time. -func Difference(nx, ny int, f EqualFunc) (es EditScript) { - // This algorithm is based on traversing what is known as an "edit-graph". - // See Figure 1 from "An O(ND) Difference Algorithm and Its Variations" - // by Eugene W. Myers. Since D can be as large as N itself, this is - // effectively O(N^2). Unlike the algorithm from that paper, we are not - // interested in the optimal path, but at least some "decent" path. - // - // For example, let X and Y be lists of symbols: - // X = [A B C A B B A] - // Y = [C B A B A C] - // - // The edit-graph can be drawn as the following: - // A B C A B B A - // ┌─────────────┐ - // C │_|_|\|_|_|_|_│ 0 - // B │_|\|_|_|\|\|_│ 1 - // A │\|_|_|\|_|_|\│ 2 - // B │_|\|_|_|\|\|_│ 3 - // A │\|_|_|\|_|_|\│ 4 - // C │ | |\| | | | │ 5 - // └─────────────┘ 6 - // 0 1 2 3 4 5 6 7 - // - // List X is written along the horizontal axis, while list Y is written - // along the vertical axis. At any point on this grid, if the symbol in - // list X matches the corresponding symbol in list Y, then a '\' is drawn. - // The goal of any minimal edit-script algorithm is to find a path from the - // top-left corner to the bottom-right corner, while traveling through the - // fewest horizontal or vertical edges. - // A horizontal edge is equivalent to inserting a symbol from list X. - // A vertical edge is equivalent to inserting a symbol from list Y. - // A diagonal edge is equivalent to a matching symbol between both X and Y. - - // Invariants: - // • 0 ≤ fwdPath.X ≤ (fwdFrontier.X, revFrontier.X) ≤ revPath.X ≤ nx - // • 0 ≤ fwdPath.Y ≤ (fwdFrontier.Y, revFrontier.Y) ≤ revPath.Y ≤ ny - // - // In general: - // • fwdFrontier.X < revFrontier.X - // • fwdFrontier.Y < revFrontier.Y - // Unless, it is time for the algorithm to terminate. - fwdPath := path{+1, point{0, 0}, make(EditScript, 0, (nx+ny)/2)} - revPath := path{-1, point{nx, ny}, make(EditScript, 0)} - fwdFrontier := fwdPath.point // Forward search frontier - revFrontier := revPath.point // Reverse search frontier - - // Search budget bounds the cost of searching for better paths. - // The longest sequence of non-matching symbols that can be tolerated is - // approximately the square-root of the search budget. - searchBudget := 4 * (nx + ny) // O(n) - - // The algorithm below is a greedy, meet-in-the-middle algorithm for - // computing sub-optimal edit-scripts between two lists. - // - // The algorithm is approximately as follows: - // • Searching for differences switches back-and-forth between - // a search that starts at the beginning (the top-left corner), and - // a search that starts at the end (the bottom-right corner). The goal of - // the search is connect with the search from the opposite corner. - // • As we search, we build a path in a greedy manner, where the first - // match seen is added to the path (this is sub-optimal, but provides a - // decent result in practice). When matches are found, we try the next pair - // of symbols in the lists and follow all matches as far as possible. - // • When searching for matches, we search along a diagonal going through - // through the "frontier" point. If no matches are found, we advance the - // frontier towards the opposite corner. - // • This algorithm terminates when either the X coordinates or the - // Y coordinates of the forward and reverse frontier points ever intersect. - // - // This algorithm is correct even if searching only in the forward direction - // or in the reverse direction. We do both because it is commonly observed - // that two lists commonly differ because elements were added to the front - // or end of the other list. - // - // Running the tests with the "debug" build tag prints a visualization of - // the algorithm running in real-time. This is educational for understanding - // how the algorithm works. See debug_enable.go. - f = debug.Begin(nx, ny, f, &fwdPath.es, &revPath.es) - for { - // Forward search from the beginning. - if fwdFrontier.X >= revFrontier.X || fwdFrontier.Y >= revFrontier.Y || searchBudget == 0 { - break - } - for stop1, stop2, i := false, false, 0; !(stop1 && stop2) && searchBudget > 0; i++ { - // Search in a diagonal pattern for a match. - z := zigzag(i) - p := point{fwdFrontier.X + z, fwdFrontier.Y - z} - switch { - case p.X >= revPath.X || p.Y < fwdPath.Y: - stop1 = true // Hit top-right corner - case p.Y >= revPath.Y || p.X < fwdPath.X: - stop2 = true // Hit bottom-left corner - case f(p.X, p.Y).Equal(): - // Match found, so connect the path to this point. - fwdPath.connect(p, f) - fwdPath.append(Identity) - // Follow sequence of matches as far as possible. - for fwdPath.X < revPath.X && fwdPath.Y < revPath.Y { - if !f(fwdPath.X, fwdPath.Y).Equal() { - break - } - fwdPath.append(Identity) - } - fwdFrontier = fwdPath.point - stop1, stop2 = true, true - default: - searchBudget-- // Match not found - } - debug.Update() - } - // Advance the frontier towards reverse point. - if revPath.X-fwdFrontier.X >= revPath.Y-fwdFrontier.Y { - fwdFrontier.X++ - } else { - fwdFrontier.Y++ - } - - // Reverse search from the end. - if fwdFrontier.X >= revFrontier.X || fwdFrontier.Y >= revFrontier.Y || searchBudget == 0 { - break - } - for stop1, stop2, i := false, false, 0; !(stop1 && stop2) && searchBudget > 0; i++ { - // Search in a diagonal pattern for a match. - z := zigzag(i) - p := point{revFrontier.X - z, revFrontier.Y + z} - switch { - case fwdPath.X >= p.X || revPath.Y < p.Y: - stop1 = true // Hit bottom-left corner - case fwdPath.Y >= p.Y || revPath.X < p.X: - stop2 = true // Hit top-right corner - case f(p.X-1, p.Y-1).Equal(): - // Match found, so connect the path to this point. - revPath.connect(p, f) - revPath.append(Identity) - // Follow sequence of matches as far as possible. - for fwdPath.X < revPath.X && fwdPath.Y < revPath.Y { - if !f(revPath.X-1, revPath.Y-1).Equal() { - break - } - revPath.append(Identity) - } - revFrontier = revPath.point - stop1, stop2 = true, true - default: - searchBudget-- // Match not found - } - debug.Update() - } - // Advance the frontier towards forward point. - if revFrontier.X-fwdPath.X >= revFrontier.Y-fwdPath.Y { - revFrontier.X-- - } else { - revFrontier.Y-- - } - } - - // Join the forward and reverse paths and then append the reverse path. - fwdPath.connect(revPath.point, f) - for i := len(revPath.es) - 1; i >= 0; i-- { - t := revPath.es[i] - revPath.es = revPath.es[:i] - fwdPath.append(t) - } - debug.Finish() - return fwdPath.es -} - -type path struct { - dir int // +1 if forward, -1 if reverse - point // Leading point of the EditScript path - es EditScript -} - -// connect appends any necessary Identity, Modified, UniqueX, or UniqueY types -// to the edit-script to connect p.point to dst. -func (p *path) connect(dst point, f EqualFunc) { - if p.dir > 0 { - // Connect in forward direction. - for dst.X > p.X && dst.Y > p.Y { - switch r := f(p.X, p.Y); { - case r.Equal(): - p.append(Identity) - case r.Similar(): - p.append(Modified) - case dst.X-p.X >= dst.Y-p.Y: - p.append(UniqueX) - default: - p.append(UniqueY) - } - } - for dst.X > p.X { - p.append(UniqueX) - } - for dst.Y > p.Y { - p.append(UniqueY) - } - } else { - // Connect in reverse direction. - for p.X > dst.X && p.Y > dst.Y { - switch r := f(p.X-1, p.Y-1); { - case r.Equal(): - p.append(Identity) - case r.Similar(): - p.append(Modified) - case p.Y-dst.Y >= p.X-dst.X: - p.append(UniqueY) - default: - p.append(UniqueX) - } - } - for p.X > dst.X { - p.append(UniqueX) - } - for p.Y > dst.Y { - p.append(UniqueY) - } - } -} - -func (p *path) append(t EditType) { - p.es = append(p.es, t) - switch t { - case Identity, Modified: - p.add(p.dir, p.dir) - case UniqueX: - p.add(p.dir, 0) - case UniqueY: - p.add(0, p.dir) - } - debug.Update() -} - -type point struct{ X, Y int } - -func (p *point) add(dx, dy int) { p.X += dx; p.Y += dy } - -// zigzag maps a consecutive sequence of integers to a zig-zag sequence. -// [0 1 2 3 4 5 ...] => [0 -1 +1 -2 +2 ...] -func zigzag(x int) int { - if x&1 != 0 { - x = ^x - } - return x >> 1 -} diff --git a/vendor/github.com/google/go-cmp/cmp/internal/function/func.go b/vendor/github.com/google/go-cmp/cmp/internal/function/func.go deleted file mode 100644 index 4c35ff11..00000000 --- a/vendor/github.com/google/go-cmp/cmp/internal/function/func.go +++ /dev/null @@ -1,49 +0,0 @@ -// 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.md file. - -// Package function identifies function types. -package function - -import "reflect" - -type funcType int - -const ( - _ funcType = iota - - ttbFunc // func(T, T) bool - tibFunc // func(T, I) bool - trFunc // func(T) R - - Equal = ttbFunc // func(T, T) bool - EqualAssignable = tibFunc // func(T, I) bool; encapsulates func(T, T) bool - Transformer = trFunc // func(T) R - ValueFilter = ttbFunc // func(T, T) bool - Less = ttbFunc // func(T, T) bool -) - -var boolType = reflect.TypeOf(true) - -// IsType reports whether the reflect.Type is of the specified function type. -func IsType(t reflect.Type, ft funcType) bool { - if t == nil || t.Kind() != reflect.Func || t.IsVariadic() { - return false - } - ni, no := t.NumIn(), t.NumOut() - switch ft { - case ttbFunc: // func(T, T) bool - if ni == 2 && no == 1 && t.In(0) == t.In(1) && t.Out(0) == boolType { - return true - } - case tibFunc: // func(T, I) bool - if ni == 2 && no == 1 && t.In(0).AssignableTo(t.In(1)) && t.Out(0) == boolType { - return true - } - case trFunc: // func(T) R - if ni == 1 && no == 1 { - return true - } - } - return false -} diff --git a/vendor/github.com/google/go-cmp/cmp/internal/value/format.go b/vendor/github.com/google/go-cmp/cmp/internal/value/format.go deleted file mode 100644 index 657e5087..00000000 --- a/vendor/github.com/google/go-cmp/cmp/internal/value/format.go +++ /dev/null @@ -1,277 +0,0 @@ -// 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.md file. - -// Package value provides functionality for reflect.Value types. -package value - -import ( - "fmt" - "reflect" - "strconv" - "strings" - "unicode" -) - -var stringerIface = reflect.TypeOf((*fmt.Stringer)(nil)).Elem() - -// Format formats the value v as a string. -// -// This is similar to fmt.Sprintf("%+v", v) except this: -// * Prints the type unless it can be elided -// * Avoids printing struct fields that are zero -// * Prints a nil-slice as being nil, not empty -// * Prints map entries in deterministic order -func Format(v reflect.Value, conf FormatConfig) string { - conf.printType = true - conf.followPointers = true - conf.realPointers = true - return formatAny(v, conf, nil) -} - -type FormatConfig struct { - UseStringer bool // Should the String method be used if available? - printType bool // Should we print the type before the value? - PrintPrimitiveType bool // Should we print the type of primitives? - followPointers bool // Should we recursively follow pointers? - realPointers bool // Should we print the real address of pointers? -} - -func formatAny(v reflect.Value, conf FormatConfig, visited map[uintptr]bool) string { - // TODO: Should this be a multi-line printout in certain situations? - - if !v.IsValid() { - return "<non-existent>" - } - if conf.UseStringer && v.Type().Implements(stringerIface) && v.CanInterface() { - if (v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface) && v.IsNil() { - return "<nil>" - } - - const stringerPrefix = "s" // Indicates that the String method was used - s := v.Interface().(fmt.Stringer).String() - return stringerPrefix + formatString(s) - } - - switch v.Kind() { - case reflect.Bool: - return formatPrimitive(v.Type(), v.Bool(), conf) - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return formatPrimitive(v.Type(), v.Int(), conf) - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - if v.Type().PkgPath() == "" || v.Kind() == reflect.Uintptr { - // Unnamed uints are usually bytes or words, so use hexadecimal. - return formatPrimitive(v.Type(), formatHex(v.Uint()), conf) - } - return formatPrimitive(v.Type(), v.Uint(), conf) - case reflect.Float32, reflect.Float64: - return formatPrimitive(v.Type(), v.Float(), conf) - case reflect.Complex64, reflect.Complex128: - return formatPrimitive(v.Type(), v.Complex(), conf) - case reflect.String: - return formatPrimitive(v.Type(), formatString(v.String()), conf) - case reflect.UnsafePointer, reflect.Chan, reflect.Func: - return formatPointer(v, conf) - case reflect.Ptr: - if v.IsNil() { - if conf.printType { - return fmt.Sprintf("(%v)(nil)", v.Type()) - } - return "<nil>" - } - if visited[v.Pointer()] || !conf.followPointers { - return formatPointer(v, conf) - } - visited = insertPointer(visited, v.Pointer()) - return "&" + formatAny(v.Elem(), conf, visited) - case reflect.Interface: - if v.IsNil() { - if conf.printType { - return fmt.Sprintf("%v(nil)", v.Type()) - } - return "<nil>" - } - return formatAny(v.Elem(), conf, visited) - case reflect.Slice: - if v.IsNil() { - if conf.printType { - return fmt.Sprintf("%v(nil)", v.Type()) - } - return "<nil>" - } - if visited[v.Pointer()] { - return formatPointer(v, conf) - } - visited = insertPointer(visited, v.Pointer()) - fallthrough - case reflect.Array: - var ss []string - subConf := conf - subConf.printType = v.Type().Elem().Kind() == reflect.Interface - for i := 0; i < v.Len(); i++ { - s := formatAny(v.Index(i), subConf, visited) - ss = append(ss, s) - } - s := fmt.Sprintf("{%s}", strings.Join(ss, ", ")) - if conf.printType { - return v.Type().String() + s - } - return s - case reflect.Map: - if v.IsNil() { - if conf.printType { - return fmt.Sprintf("%v(nil)", v.Type()) - } - return "<nil>" - } - if visited[v.Pointer()] { - return formatPointer(v, conf) - } - visited = insertPointer(visited, v.Pointer()) - - var ss []string - keyConf, valConf := conf, conf - keyConf.printType = v.Type().Key().Kind() == reflect.Interface - keyConf.followPointers = false - valConf.printType = v.Type().Elem().Kind() == reflect.Interface - for _, k := range SortKeys(v.MapKeys()) { - sk := formatAny(k, keyConf, visited) - sv := formatAny(v.MapIndex(k), valConf, visited) - ss = append(ss, fmt.Sprintf("%s: %s", sk, sv)) - } - s := fmt.Sprintf("{%s}", strings.Join(ss, ", ")) - if conf.printType { - return v.Type().String() + s - } - return s - case reflect.Struct: - var ss []string - subConf := conf - subConf.printType = true - for i := 0; i < v.NumField(); i++ { - vv := v.Field(i) - if isZero(vv) { - continue // Elide zero value fields - } - name := v.Type().Field(i).Name - subConf.UseStringer = conf.UseStringer - s := formatAny(vv, subConf, visited) - ss = append(ss, fmt.Sprintf("%s: %s", name, s)) - } - s := fmt.Sprintf("{%s}", strings.Join(ss, ", ")) - if conf.printType { - return v.Type().String() + s - } - return s - default: - panic(fmt.Sprintf("%v kind not handled", v.Kind())) - } -} - -func formatString(s string) string { - // Use quoted string if it the same length as a raw string literal. - // Otherwise, attempt to use the raw string form. - qs := strconv.Quote(s) - if len(qs) == 1+len(s)+1 { - return qs - } - - // Disallow newlines to ensure output is a single line. - // Only allow printable runes for readability purposes. - rawInvalid := func(r rune) bool { - return r == '`' || r == '\n' || !unicode.IsPrint(r) - } - if strings.IndexFunc(s, rawInvalid) < 0 { - return "`" + s + "`" - } - return qs -} - -func formatPrimitive(t reflect.Type, v interface{}, conf FormatConfig) string { - if conf.printType && (conf.PrintPrimitiveType || t.PkgPath() != "") { - return fmt.Sprintf("%v(%v)", t, v) - } - return fmt.Sprintf("%v", v) -} - -func formatPointer(v reflect.Value, conf FormatConfig) string { - p := v.Pointer() - if !conf.realPointers { - p = 0 // For deterministic printing purposes - } - s := formatHex(uint64(p)) - if conf.printType { - return fmt.Sprintf("(%v)(%s)", v.Type(), s) - } - return s -} - -func formatHex(u uint64) string { - var f string - switch { - case u <= 0xff: - f = "0x%02x" - case u <= 0xffff: - f = "0x%04x" - case u <= 0xffffff: - f = "0x%06x" - case u <= 0xffffffff: - f = "0x%08x" - case u <= 0xffffffffff: - f = "0x%010x" - case u <= 0xffffffffffff: - f = "0x%012x" - case u <= 0xffffffffffffff: - f = "0x%014x" - case u <= 0xffffffffffffffff: - f = "0x%016x" - } - return fmt.Sprintf(f, u) -} - -// insertPointer insert p into m, allocating m if necessary. -func insertPointer(m map[uintptr]bool, p uintptr) map[uintptr]bool { - if m == nil { - m = make(map[uintptr]bool) - } - m[p] = true - return m -} - -// isZero reports whether v is the zero value. -// This does not rely on Interface and so can be used on unexported fields. -func isZero(v reflect.Value) bool { - switch v.Kind() { - case reflect.Bool: - return v.Bool() == false - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return v.Int() == 0 - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - return v.Uint() == 0 - case reflect.Float32, reflect.Float64: - return v.Float() == 0 - case reflect.Complex64, reflect.Complex128: - return v.Complex() == 0 - case reflect.String: - return v.String() == "" - case reflect.UnsafePointer: - return v.Pointer() == 0 - case reflect.Chan, reflect.Func, reflect.Interface, reflect.Ptr, reflect.Map, reflect.Slice: - return v.IsNil() - case reflect.Array: - for i := 0; i < v.Len(); i++ { - if !isZero(v.Index(i)) { - return false - } - } - return true - case reflect.Struct: - for i := 0; i < v.NumField(); i++ { - if !isZero(v.Field(i)) { - return false - } - } - return true - } - return false -} diff --git a/vendor/github.com/google/go-cmp/cmp/internal/value/sort.go b/vendor/github.com/google/go-cmp/cmp/internal/value/sort.go deleted file mode 100644 index fe8aa27a..00000000 --- a/vendor/github.com/google/go-cmp/cmp/internal/value/sort.go +++ /dev/null @@ -1,111 +0,0 @@ -// 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.md file. - -package value - -import ( - "fmt" - "math" - "reflect" - "sort" -) - -// SortKeys sorts a list of map keys, deduplicating keys if necessary. -// The type of each value must be comparable. -func SortKeys(vs []reflect.Value) []reflect.Value { - if len(vs) == 0 { - return vs - } - - // Sort the map keys. - sort.Sort(valueSorter(vs)) - - // Deduplicate keys (fails for NaNs). - vs2 := vs[:1] - for _, v := range vs[1:] { - if isLess(vs2[len(vs2)-1], v) { - vs2 = append(vs2, v) - } - } - return vs2 -} - -// TODO: Use sort.Slice once Google AppEngine is on Go1.8 or above. -type valueSorter []reflect.Value - -func (vs valueSorter) Len() int { return len(vs) } -func (vs valueSorter) Less(i, j int) bool { return isLess(vs[i], vs[j]) } -func (vs valueSorter) Swap(i, j int) { vs[i], vs[j] = vs[j], vs[i] } - -// isLess is a generic function for sorting arbitrary map keys. -// The inputs must be of the same type and must be comparable. -func isLess(x, y reflect.Value) bool { - switch x.Type().Kind() { - case reflect.Bool: - return !x.Bool() && y.Bool() - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return x.Int() < y.Int() - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - return x.Uint() < y.Uint() - case reflect.Float32, reflect.Float64: - fx, fy := x.Float(), y.Float() - return fx < fy || math.IsNaN(fx) && !math.IsNaN(fy) - case reflect.Complex64, reflect.Complex128: - cx, cy := x.Complex(), y.Complex() - rx, ix, ry, iy := real(cx), imag(cx), real(cy), imag(cy) - if rx == ry || (math.IsNaN(rx) && math.IsNaN(ry)) { - return ix < iy || math.IsNaN(ix) && !math.IsNaN(iy) - } - return rx < ry || math.IsNaN(rx) && !math.IsNaN(ry) - case reflect.Ptr, reflect.UnsafePointer, reflect.Chan: - return x.Pointer() < y.Pointer() - case reflect.String: - return x.String() < y.String() - case reflect.Array: - for i := 0; i < x.Len(); i++ { - if isLess(x.Index(i), y.Index(i)) { - return true - } - if isLess(y.Index(i), x.Index(i)) { - return false - } - } - return false - case reflect.Struct: - for i := 0; i < x.NumField(); i++ { - if isLess(x.Field(i), y.Field(i)) { - return true - } - if isLess(y.Field(i), x.Field(i)) { - return false - } - } - return false - case reflect.Interface: - vx, vy := x.Elem(), y.Elem() - if !vx.IsValid() || !vy.IsValid() { - return !vx.IsValid() && vy.IsValid() - } - tx, ty := vx.Type(), vy.Type() - if tx == ty { - return isLess(x.Elem(), y.Elem()) - } - if tx.Kind() != ty.Kind() { - return vx.Kind() < vy.Kind() - } - if tx.String() != ty.String() { - return tx.String() < ty.String() - } - if tx.PkgPath() != ty.PkgPath() { - return tx.PkgPath() < ty.PkgPath() - } - // This can happen in rare situations, so we fallback to just comparing - // the unique pointer for a reflect.Type. This guarantees deterministic - // ordering within a program, but it is obviously not stable. - return reflect.ValueOf(vx.Type()).Pointer() < reflect.ValueOf(vy.Type()).Pointer() - default: - // Must be Func, Map, or Slice; which are not comparable. - panic(fmt.Sprintf("%T is not comparable", x.Type())) - } -} diff --git a/vendor/github.com/google/go-cmp/cmp/options.go b/vendor/github.com/google/go-cmp/cmp/options.go deleted file mode 100644 index 91d4b066..00000000 --- a/vendor/github.com/google/go-cmp/cmp/options.go +++ /dev/null @@ -1,453 +0,0 @@ -// 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.md file. - -package cmp - -import ( - "fmt" - "reflect" - "runtime" - "strings" - - "github.com/google/go-cmp/cmp/internal/function" -) - -// Option configures for specific behavior of Equal and Diff. In particular, -// the fundamental Option functions (Ignore, Transformer, and Comparer), -// configure how equality is determined. -// -// The fundamental options may be composed with filters (FilterPath and -// FilterValues) to control the scope over which they are applied. -// -// The cmp/cmpopts package provides helper functions for creating options that -// may be used with Equal and Diff. -type Option interface { - // filter applies all filters and returns the option that remains. - // Each option may only read s.curPath and call s.callTTBFunc. - // - // An Options is returned only if multiple comparers or transformers - // can apply simultaneously and will only contain values of those types - // or sub-Options containing values of those types. - filter(s *state, vx, vy reflect.Value, t reflect.Type) applicableOption -} - -// applicableOption represents the following types: -// Fundamental: ignore | invalid | *comparer | *transformer -// Grouping: Options -type applicableOption interface { - Option - - // apply executes the option, which may mutate s or panic. - apply(s *state, vx, vy reflect.Value) -} - -// coreOption represents the following types: -// Fundamental: ignore | invalid | *comparer | *transformer -// Filters: *pathFilter | *valuesFilter -type coreOption interface { - Option - isCore() -} - -type core struct{} - -func (core) isCore() {} - -// Options is a list of Option values that also satisfies the Option interface. -// Helper comparison packages may return an Options value when packing multiple -// Option values into a single Option. When this package processes an Options, -// it will be implicitly expanded into a flat list. -// -// Applying a filter on an Options is equivalent to applying that same filter -// on all individual options held within. -type Options []Option - -func (opts Options) filter(s *state, vx, vy reflect.Value, t reflect.Type) (out applicableOption) { - for _, opt := range opts { - switch opt := opt.filter(s, vx, vy, t); opt.(type) { - case ignore: - return ignore{} // Only ignore can short-circuit evaluation - case invalid: - out = invalid{} // Takes precedence over comparer or transformer - case *comparer, *transformer, Options: - switch out.(type) { - case nil: - out = opt - case invalid: - // Keep invalid - case *comparer, *transformer, Options: - out = Options{out, opt} // Conflicting comparers or transformers - } - } - } - return out -} - -func (opts Options) apply(s *state, _, _ reflect.Value) { - const warning = "ambiguous set of applicable options" - const help = "consider using filters to ensure at most one Comparer or Transformer may apply" - var ss []string - for _, opt := range flattenOptions(nil, opts) { - ss = append(ss, fmt.Sprint(opt)) - } - set := strings.Join(ss, "\n\t") - panic(fmt.Sprintf("%s at %#v:\n\t%s\n%s", warning, s.curPath, set, help)) -} - -func (opts Options) String() string { - var ss []string - for _, opt := range opts { - ss = append(ss, fmt.Sprint(opt)) - } - return fmt.Sprintf("Options{%s}", strings.Join(ss, ", ")) -} - -// FilterPath returns a new Option where opt is only evaluated if filter f -// returns true for the current Path in the value tree. -// -// The option passed in may be an Ignore, Transformer, Comparer, Options, or -// a previously filtered Option. -func FilterPath(f func(Path) bool, opt Option) Option { - if f == nil { - panic("invalid path filter function") - } - if opt := normalizeOption(opt); opt != nil { - return &pathFilter{fnc: f, opt: opt} - } - return nil -} - -type pathFilter struct { - core - fnc func(Path) bool - opt Option -} - -func (f pathFilter) filter(s *state, vx, vy reflect.Value, t reflect.Type) applicableOption { - if f.fnc(s.curPath) { - return f.opt.filter(s, vx, vy, t) - } - return nil -} - -func (f pathFilter) String() string { - fn := getFuncName(reflect.ValueOf(f.fnc).Pointer()) - return fmt.Sprintf("FilterPath(%s, %v)", fn, f.opt) -} - -// FilterValues returns a new Option where opt is only evaluated if filter f, -// which is a function of the form "func(T, T) bool", returns true for the -// current pair of values being compared. If the type of the values is not -// assignable to T, then this filter implicitly returns false. -// -// The filter function must be -// symmetric (i.e., agnostic to the order of the inputs) and -// deterministic (i.e., produces the same result when given the same inputs). -// If T is an interface, it is possible that f is called with two values with -// different concrete types that both implement T. -// -// The option passed in may be an Ignore, Transformer, Comparer, Options, or -// a previously filtered Option. -func FilterValues(f interface{}, opt Option) Option { - v := reflect.ValueOf(f) - if !function.IsType(v.Type(), function.ValueFilter) || v.IsNil() { - panic(fmt.Sprintf("invalid values filter function: %T", f)) - } - if opt := normalizeOption(opt); opt != nil { - vf := &valuesFilter{fnc: v, opt: opt} - if ti := v.Type().In(0); ti.Kind() != reflect.Interface || ti.NumMethod() > 0 { - vf.typ = ti - } - return vf - } - return nil -} - -type valuesFilter struct { - core - typ reflect.Type // T - fnc reflect.Value // func(T, T) bool - opt Option -} - -func (f valuesFilter) filter(s *state, vx, vy reflect.Value, t reflect.Type) applicableOption { - if !vx.IsValid() || !vy.IsValid() { - return invalid{} - } - if (f.typ == nil || t.AssignableTo(f.typ)) && s.callTTBFunc(f.fnc, vx, vy) { - return f.opt.filter(s, vx, vy, t) - } - return nil -} - -func (f valuesFilter) String() string { - fn := getFuncName(f.fnc.Pointer()) - return fmt.Sprintf("FilterValues(%s, %v)", fn, f.opt) -} - -// Ignore is an Option that causes all comparisons to be ignored. -// This value is intended to be combined with FilterPath or FilterValues. -// It is an error to pass an unfiltered Ignore option to Equal. -func Ignore() Option { return ignore{} } - -type ignore struct{ core } - -func (ignore) isFiltered() bool { return false } -func (ignore) filter(_ *state, _, _ reflect.Value, _ reflect.Type) applicableOption { return ignore{} } -func (ignore) apply(_ *state, _, _ reflect.Value) { return } -func (ignore) String() string { return "Ignore()" } - -// invalid is a sentinel Option type to indicate that some options could not -// be evaluated due to unexported fields. -type invalid struct{ core } - -func (invalid) filter(_ *state, _, _ reflect.Value, _ reflect.Type) applicableOption { return invalid{} } -func (invalid) apply(s *state, _, _ reflect.Value) { - const help = "consider using AllowUnexported or cmpopts.IgnoreUnexported" - panic(fmt.Sprintf("cannot handle unexported field: %#v\n%s", s.curPath, help)) -} - -// Transformer returns an Option that applies a transformation function that -// converts values of a certain type into that of another. -// -// The transformer f must be a function "func(T) R" that converts values of -// type T to those of type R and is implicitly filtered to input values -// assignable to T. The transformer must not mutate T in any way. -// -// To help prevent some cases of infinite recursive cycles applying the -// same transform to the output of itself (e.g., in the case where the -// input and output types are the same), an implicit filter is added such that -// a transformer is applicable only if that exact transformer is not already -// in the tail of the Path since the last non-Transform step. -// -// The name is a user provided label that is used as the Transform.Name in the -// transformation PathStep. If empty, an arbitrary name is used. -func Transformer(name string, f interface{}) Option { - v := reflect.ValueOf(f) - if !function.IsType(v.Type(), function.Transformer) || v.IsNil() { - panic(fmt.Sprintf("invalid transformer function: %T", f)) - } - if name == "" { - name = "λ" // Lambda-symbol as place-holder for anonymous transformer - } - if !isValid(name) { - panic(fmt.Sprintf("invalid name: %q", name)) - } - tr := &transformer{name: name, fnc: reflect.ValueOf(f)} - if ti := v.Type().In(0); ti.Kind() != reflect.Interface || ti.NumMethod() > 0 { - tr.typ = ti - } - return tr -} - -type transformer struct { - core - name string - typ reflect.Type // T - fnc reflect.Value // func(T) R -} - -func (tr *transformer) isFiltered() bool { return tr.typ != nil } - -func (tr *transformer) filter(s *state, _, _ reflect.Value, t reflect.Type) applicableOption { - for i := len(s.curPath) - 1; i >= 0; i-- { - if t, ok := s.curPath[i].(*transform); !ok { - break // Hit most recent non-Transform step - } else if tr == t.trans { - return nil // Cannot directly use same Transform - } - } - if tr.typ == nil || t.AssignableTo(tr.typ) { - return tr - } - return nil -} - -func (tr *transformer) apply(s *state, vx, vy reflect.Value) { - // Update path before calling the Transformer so that dynamic checks - // will use the updated path. - s.curPath.push(&transform{pathStep{tr.fnc.Type().Out(0)}, tr}) - defer s.curPath.pop() - - vx = s.callTRFunc(tr.fnc, vx) - vy = s.callTRFunc(tr.fnc, vy) - s.compareAny(vx, vy) -} - -func (tr transformer) String() string { - return fmt.Sprintf("Transformer(%s, %s)", tr.name, getFuncName(tr.fnc.Pointer())) -} - -// Comparer returns an Option that determines whether two values are equal -// to each other. -// -// The comparer f must be a function "func(T, T) bool" and is implicitly -// filtered to input values assignable to T. If T is an interface, it is -// possible that f is called with two values of different concrete types that -// both implement T. -// -// The equality function must be: -// • Symmetric: equal(x, y) == equal(y, x) -// • Deterministic: equal(x, y) == equal(x, y) -// • Pure: equal(x, y) does not modify x or y -func Comparer(f interface{}) Option { - v := reflect.ValueOf(f) - if !function.IsType(v.Type(), function.Equal) || v.IsNil() { - panic(fmt.Sprintf("invalid comparer function: %T", f)) - } - cm := &comparer{fnc: v} - if ti := v.Type().In(0); ti.Kind() != reflect.Interface || ti.NumMethod() > 0 { - cm.typ = ti - } - return cm -} - -type comparer struct { - core - typ reflect.Type // T - fnc reflect.Value // func(T, T) bool -} - -func (cm *comparer) isFiltered() bool { return cm.typ != nil } - -func (cm *comparer) filter(_ *state, _, _ reflect.Value, t reflect.Type) applicableOption { - if cm.typ == nil || t.AssignableTo(cm.typ) { - return cm - } - return nil -} - -func (cm *comparer) apply(s *state, vx, vy reflect.Value) { - eq := s.callTTBFunc(cm.fnc, vx, vy) - s.report(eq, vx, vy) -} - -func (cm comparer) String() string { - return fmt.Sprintf("Comparer(%s)", getFuncName(cm.fnc.Pointer())) -} - -// AllowUnexported returns an Option that forcibly allows operations on -// unexported fields in certain structs, which are specified by passing in a -// value of each struct type. -// -// Users of this option must understand that comparing on unexported fields -// from external packages is not safe since changes in the internal -// implementation of some external package may cause the result of Equal -// to unexpectedly change. However, it may be valid to use this option on types -// defined in an internal package where the semantic meaning of an unexported -// field is in the control of the user. -// -// For some cases, a custom Comparer should be used instead that defines -// equality as a function of the public API of a type rather than the underlying -// unexported implementation. -// -// For example, the reflect.Type documentation defines equality to be determined -// by the == operator on the interface (essentially performing a shallow pointer -// comparison) and most attempts to compare *regexp.Regexp types are interested -// in only checking that the regular expression strings are equal. -// Both of these are accomplished using Comparers: -// -// Comparer(func(x, y reflect.Type) bool { return x == y }) -// Comparer(func(x, y *regexp.Regexp) bool { return x.String() == y.String() }) -// -// In other cases, the cmpopts.IgnoreUnexported option can be used to ignore -// all unexported fields on specified struct types. -func AllowUnexported(types ...interface{}) Option { - if !supportAllowUnexported { - panic("AllowUnexported is not supported on purego builds, Google App Engine Standard, or GopherJS") - } - m := make(map[reflect.Type]bool) - for _, typ := range types { - t := reflect.TypeOf(typ) - if t.Kind() != reflect.Struct { - panic(fmt.Sprintf("invalid struct type: %T", typ)) - } - m[t] = true - } - return visibleStructs(m) -} - -type visibleStructs map[reflect.Type]bool - -func (visibleStructs) filter(_ *state, _, _ reflect.Value, _ reflect.Type) applicableOption { - panic("not implemented") -} - -// reporter is an Option that configures how differences are reported. -type reporter interface { - // TODO: Not exported yet. - // - // Perhaps add PushStep and PopStep and change Report to only accept - // a PathStep instead of the full-path? Adding a PushStep and PopStep makes - // it clear that we are traversing the value tree in a depth-first-search - // manner, which has an effect on how values are printed. - - Option - - // Report is called for every comparison made and will be provided with - // the two values being compared, the equality result, and the - // current path in the value tree. It is possible for x or y to be an - // invalid reflect.Value if one of the values is non-existent; - // which is possible with maps and slices. - Report(x, y reflect.Value, eq bool, p Path) -} - -// normalizeOption normalizes the input options such that all Options groups -// are flattened and groups with a single element are reduced to that element. -// Only coreOptions and Options containing coreOptions are allowed. -func normalizeOption(src Option) Option { - switch opts := flattenOptions(nil, Options{src}); len(opts) { - case 0: - return nil - case 1: - return opts[0] - default: - return opts - } -} - -// flattenOptions copies all options in src to dst as a flat list. -// Only coreOptions and Options containing coreOptions are allowed. -func flattenOptions(dst, src Options) Options { - for _, opt := range src { - switch opt := opt.(type) { - case nil: - continue - case Options: - dst = flattenOptions(dst, opt) - case coreOption: - dst = append(dst, opt) - default: - panic(fmt.Sprintf("invalid option type: %T", opt)) - } - } - return dst -} - -// getFuncName returns a short function name from the pointer. -// The string parsing logic works up until Go1.9. -func getFuncName(p uintptr) string { - fnc := runtime.FuncForPC(p) - if fnc == nil { - return "<unknown>" - } - name := fnc.Name() // E.g., "long/path/name/mypkg.(mytype).(long/path/name/mypkg.myfunc)-fm" - if strings.HasSuffix(name, ")-fm") || strings.HasSuffix(name, ")·fm") { - // Strip the package name from method name. - name = strings.TrimSuffix(name, ")-fm") - name = strings.TrimSuffix(name, ")·fm") - if i := strings.LastIndexByte(name, '('); i >= 0 { - methodName := name[i+1:] // E.g., "long/path/name/mypkg.myfunc" - if j := strings.LastIndexByte(methodName, '.'); j >= 0 { - methodName = methodName[j+1:] // E.g., "myfunc" - } - name = name[:i] + methodName // E.g., "long/path/name/mypkg.(mytype)." + "myfunc" - } - } - if i := strings.LastIndexByte(name, '/'); i >= 0 { - // Strip the package name. - name = name[i+1:] // E.g., "mypkg.(mytype).myfunc" - } - return name -} diff --git a/vendor/github.com/google/go-cmp/cmp/path.go b/vendor/github.com/google/go-cmp/cmp/path.go deleted file mode 100644 index c08a3cf8..00000000 --- a/vendor/github.com/google/go-cmp/cmp/path.go +++ /dev/null @@ -1,309 +0,0 @@ -// 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.md file. - -package cmp - -import ( - "fmt" - "reflect" - "strings" - "unicode" - "unicode/utf8" -) - -type ( - // Path is a list of PathSteps describing the sequence of operations to get - // from some root type to the current position in the value tree. - // The first Path element is always an operation-less PathStep that exists - // simply to identify the initial type. - // - // When traversing structs with embedded structs, the embedded struct will - // always be accessed as a field before traversing the fields of the - // embedded struct themselves. That is, an exported field from the - // embedded struct will never be accessed directly from the parent struct. - Path []PathStep - - // PathStep is a union-type for specific operations to traverse - // a value's tree structure. Users of this package never need to implement - // these types as values of this type will be returned by this package. - PathStep interface { - String() string - Type() reflect.Type // Resulting type after performing the path step - isPathStep() - } - - // SliceIndex is an index operation on a slice or array at some index Key. - SliceIndex interface { - PathStep - Key() int // May return -1 if in a split state - - // SplitKeys returns the indexes for indexing into slices in the - // x and y values, respectively. These indexes may differ due to the - // insertion or removal of an element in one of the slices, causing - // all of the indexes to be shifted. If an index is -1, then that - // indicates that the element does not exist in the associated slice. - // - // Key is guaranteed to return -1 if and only if the indexes returned - // by SplitKeys are not the same. SplitKeys will never return -1 for - // both indexes. - SplitKeys() (x int, y int) - - isSliceIndex() - } - // MapIndex is an index operation on a map at some index Key. - MapIndex interface { - PathStep - Key() reflect.Value - isMapIndex() - } - // TypeAssertion represents a type assertion on an interface. - TypeAssertion interface { - PathStep - isTypeAssertion() - } - // StructField represents a struct field access on a field called Name. - StructField interface { - PathStep - Name() string - Index() int - isStructField() - } - // Indirect represents pointer indirection on the parent type. - Indirect interface { - PathStep - isIndirect() - } - // Transform is a transformation from the parent type to the current type. - Transform interface { - PathStep - Name() string - Func() reflect.Value - - // Option returns the originally constructed Transformer option. - // The == operator can be used to detect the exact option used. - Option() Option - - isTransform() - } -) - -func (pa *Path) push(s PathStep) { - *pa = append(*pa, s) -} - -func (pa *Path) pop() { - *pa = (*pa)[:len(*pa)-1] -} - -// Last returns the last PathStep in the Path. -// If the path is empty, this returns a non-nil PathStep that reports a nil Type. -func (pa Path) Last() PathStep { - return pa.Index(-1) -} - -// Index returns the ith step in the Path and supports negative indexing. -// A negative index starts counting from the tail of the Path such that -1 -// refers to the last step, -2 refers to the second-to-last step, and so on. -// If index is invalid, this returns a non-nil PathStep that reports a nil Type. -func (pa Path) Index(i int) PathStep { - if i < 0 { - i = len(pa) + i - } - if i < 0 || i >= len(pa) { - return pathStep{} - } - return pa[i] -} - -// String returns the simplified path to a node. -// The simplified path only contains struct field accesses. -// -// For example: -// MyMap.MySlices.MyField -func (pa Path) String() string { - var ss []string - for _, s := range pa { - if _, ok := s.(*structField); ok { - ss = append(ss, s.String()) - } - } - return strings.TrimPrefix(strings.Join(ss, ""), ".") -} - -// GoString returns the path to a specific node using Go syntax. -// -// For example: -// (*root.MyMap["key"].(*mypkg.MyStruct).MySlices)[2][3].MyField -func (pa Path) GoString() string { - var ssPre, ssPost []string - var numIndirect int - for i, s := range pa { - var nextStep PathStep - if i+1 < len(pa) { - nextStep = pa[i+1] - } - switch s := s.(type) { - case *indirect: - numIndirect++ - pPre, pPost := "(", ")" - switch nextStep.(type) { - case *indirect: - continue // Next step is indirection, so let them batch up - case *structField: - numIndirect-- // Automatic indirection on struct fields - case nil: - pPre, pPost = "", "" // Last step; no need for parenthesis - } - if numIndirect > 0 { - ssPre = append(ssPre, pPre+strings.Repeat("*", numIndirect)) - ssPost = append(ssPost, pPost) - } - numIndirect = 0 - continue - case *transform: - ssPre = append(ssPre, s.trans.name+"(") - ssPost = append(ssPost, ")") - continue - case *typeAssertion: - // As a special-case, elide type assertions on anonymous types - // since they are typically generated dynamically and can be very - // verbose. For example, some transforms return interface{} because - // of Go's lack of generics, but typically take in and return the - // exact same concrete type. - if s.Type().PkgPath() == "" { - continue - } - } - ssPost = append(ssPost, s.String()) - } - for i, j := 0, len(ssPre)-1; i < j; i, j = i+1, j-1 { - ssPre[i], ssPre[j] = ssPre[j], ssPre[i] - } - return strings.Join(ssPre, "") + strings.Join(ssPost, "") -} - -type ( - pathStep struct { - typ reflect.Type - } - - sliceIndex struct { - pathStep - xkey, ykey int - } - mapIndex struct { - pathStep - key reflect.Value - } - typeAssertion struct { - pathStep - } - structField struct { - pathStep - name string - idx int - - // These fields are used for forcibly accessing an unexported field. - // pvx, pvy, and field are only valid if unexported is true. - unexported bool - force bool // Forcibly allow visibility - pvx, pvy reflect.Value // Parent values - field reflect.StructField // Field information - } - indirect struct { - pathStep - } - transform struct { - pathStep - trans *transformer - } -) - -func (ps pathStep) Type() reflect.Type { return ps.typ } -func (ps pathStep) String() string { - if ps.typ == nil { - return "<nil>" - } - s := ps.typ.String() - if s == "" || strings.ContainsAny(s, "{}\n") { - return "root" // Type too simple or complex to print - } - return fmt.Sprintf("{%s}", s) -} - -func (si sliceIndex) String() string { - switch { - case si.xkey == si.ykey: - return fmt.Sprintf("[%d]", si.xkey) - case si.ykey == -1: - // [5->?] means "I don't know where X[5] went" - return fmt.Sprintf("[%d->?]", si.xkey) - case si.xkey == -1: - // [?->3] means "I don't know where Y[3] came from" - return fmt.Sprintf("[?->%d]", si.ykey) - default: - // [5->3] means "X[5] moved to Y[3]" - return fmt.Sprintf("[%d->%d]", si.xkey, si.ykey) - } -} -func (mi mapIndex) String() string { return fmt.Sprintf("[%#v]", mi.key) } -func (ta typeAssertion) String() string { return fmt.Sprintf(".(%v)", ta.typ) } -func (sf structField) String() string { return fmt.Sprintf(".%s", sf.name) } -func (in indirect) String() string { return "*" } -func (tf transform) String() string { return fmt.Sprintf("%s()", tf.trans.name) } - -func (si sliceIndex) Key() int { - if si.xkey != si.ykey { - return -1 - } - return si.xkey -} -func (si sliceIndex) SplitKeys() (x, y int) { return si.xkey, si.ykey } -func (mi mapIndex) Key() reflect.Value { return mi.key } -func (sf structField) Name() string { return sf.name } -func (sf structField) Index() int { return sf.idx } -func (tf transform) Name() string { return tf.trans.name } -func (tf transform) Func() reflect.Value { return tf.trans.fnc } -func (tf transform) Option() Option { return tf.trans } - -func (pathStep) isPathStep() {} -func (sliceIndex) isSliceIndex() {} -func (mapIndex) isMapIndex() {} -func (typeAssertion) isTypeAssertion() {} -func (structField) isStructField() {} -func (indirect) isIndirect() {} -func (transform) isTransform() {} - -var ( - _ SliceIndex = sliceIndex{} - _ MapIndex = mapIndex{} - _ TypeAssertion = typeAssertion{} - _ StructField = structField{} - _ Indirect = indirect{} - _ Transform = transform{} - - _ PathStep = sliceIndex{} - _ PathStep = mapIndex{} - _ PathStep = typeAssertion{} - _ PathStep = structField{} - _ PathStep = indirect{} - _ PathStep = transform{} -) - -// isExported reports whether the identifier is exported. -func isExported(id string) bool { - r, _ := utf8.DecodeRuneInString(id) - return unicode.IsUpper(r) -} - -// isValid reports whether the identifier is valid. -// Empty and underscore-only strings are not valid. -func isValid(id string) bool { - ok := id != "" && id != "_" - for j, c := range id { - ok = ok && (j > 0 || !unicode.IsDigit(c)) - ok = ok && (c == '_' || unicode.IsLetter(c) || unicode.IsDigit(c)) - } - return ok -} diff --git a/vendor/github.com/google/go-cmp/cmp/reporter.go b/vendor/github.com/google/go-cmp/cmp/reporter.go deleted file mode 100644 index 20e9f18e..00000000 --- a/vendor/github.com/google/go-cmp/cmp/reporter.go +++ /dev/null @@ -1,53 +0,0 @@ -// 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.md file. - -package cmp - -import ( - "fmt" - "reflect" - "strings" - - "github.com/google/go-cmp/cmp/internal/value" -) - -type defaultReporter struct { - Option - diffs []string // List of differences, possibly truncated - ndiffs int // Total number of differences - nbytes int // Number of bytes in diffs - nlines int // Number of lines in diffs -} - -var _ reporter = (*defaultReporter)(nil) - -func (r *defaultReporter) Report(x, y reflect.Value, eq bool, p Path) { - if eq { - return // Ignore equal results - } - const maxBytes = 4096 - const maxLines = 256 - r.ndiffs++ - if r.nbytes < maxBytes && r.nlines < maxLines { - sx := value.Format(x, value.FormatConfig{UseStringer: true}) - sy := value.Format(y, value.FormatConfig{UseStringer: true}) - if sx == sy { - // Unhelpful output, so use more exact formatting. - sx = value.Format(x, value.FormatConfig{PrintPrimitiveType: true}) - sy = value.Format(y, value.FormatConfig{PrintPrimitiveType: true}) - } - s := fmt.Sprintf("%#v:\n\t-: %s\n\t+: %s\n", p, sx, sy) - r.diffs = append(r.diffs, s) - r.nbytes += len(s) - r.nlines += strings.Count(s, "\n") - } -} - -func (r *defaultReporter) String() string { - s := strings.Join(r.diffs, "") - if r.ndiffs == len(r.diffs) { - return s - } - return fmt.Sprintf("%s... %d more differences ...", s, r.ndiffs-len(r.diffs)) -} diff --git a/vendor/github.com/google/go-cmp/cmp/unsafe_panic.go b/vendor/github.com/google/go-cmp/cmp/unsafe_panic.go deleted file mode 100644 index d1518eb3..00000000 --- a/vendor/github.com/google/go-cmp/cmp/unsafe_panic.go +++ /dev/null @@ -1,15 +0,0 @@ -// 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.md file. - -// +build purego appengine js - -package cmp - -import "reflect" - -const supportAllowUnexported = false - -func unsafeRetrieveField(reflect.Value, reflect.StructField) reflect.Value { - panic("unsafeRetrieveField is not implemented") -} diff --git a/vendor/github.com/google/go-cmp/cmp/unsafe_reflect.go b/vendor/github.com/google/go-cmp/cmp/unsafe_reflect.go deleted file mode 100644 index 579b6550..00000000 --- a/vendor/github.com/google/go-cmp/cmp/unsafe_reflect.go +++ /dev/null @@ -1,23 +0,0 @@ -// 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.md file. - -// +build !purego,!appengine,!js - -package cmp - -import ( - "reflect" - "unsafe" -) - -const supportAllowUnexported = true - -// unsafeRetrieveField uses unsafe to forcibly retrieve any field from a struct -// such that the value has read-write permissions. -// -// The parent struct, v, must be addressable, while f must be a StructField -// describing the field to retrieve. -func unsafeRetrieveField(v reflect.Value, f reflect.StructField) reflect.Value { - return reflect.NewAt(f.Type, unsafe.Pointer(v.UnsafeAddr()+f.Offset)).Elem() -} diff --git a/vendor/gotest.tools/LICENSE b/vendor/gotest.tools/LICENSE deleted file mode 100644 index d6456956..00000000 --- a/vendor/gotest.tools/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/gotest.tools/assert/assert.go b/vendor/gotest.tools/assert/assert.go deleted file mode 100644 index 05d66354..00000000 --- a/vendor/gotest.tools/assert/assert.go +++ /dev/null @@ -1,311 +0,0 @@ -/*Package assert provides assertions for comparing expected values to actual -values. When an assertion fails a helpful error message is printed. - -Assert and Check - -Assert() and Check() both accept a Comparison, and fail the test when the -comparison fails. The one difference is that Assert() will end the test execution -immediately (using t.FailNow()) whereas Check() will fail the test (using t.Fail()), -return the value of the comparison, then proceed with the rest of the test case. - -Example usage - -The example below shows assert used with some common types. - - - import ( - "testing" - - "gotest.tools/assert" - is "gotest.tools/assert/cmp" - ) - - func TestEverything(t *testing.T) { - // booleans - assert.Assert(t, ok) - assert.Assert(t, !missing) - - // primitives - assert.Equal(t, count, 1) - assert.Equal(t, msg, "the message") - assert.Assert(t, total != 10) // NotEqual - - // errors - assert.NilError(t, closer.Close()) - assert.Error(t, err, "the exact error message") - assert.ErrorContains(t, err, "includes this") - assert.ErrorType(t, err, os.IsNotExist) - - // complex types - assert.DeepEqual(t, result, myStruct{Name: "title"}) - assert.Assert(t, is.Len(items, 3)) - assert.Assert(t, len(sequence) != 0) // NotEmpty - assert.Assert(t, is.Contains(mapping, "key")) - - // pointers and interface - assert.Assert(t, is.Nil(ref)) - assert.Assert(t, ref != nil) // NotNil - } - -Comparisons - -Package https://godoc.org/gotest.tools/assert/cmp provides -many common comparisons. Additional comparisons can be written to compare -values in other ways. See the example Assert (CustomComparison). - -Automated migration from testify - -gty-migrate-from-testify is a binary which can update source code which uses -testify assertions to use the assertions provided by this package. - -See http://bit.do/cmd-gty-migrate-from-testify. - - -*/ -package assert // import "gotest.tools/assert" - -import ( - "fmt" - "go/ast" - "go/token" - - gocmp "github.com/google/go-cmp/cmp" - "gotest.tools/assert/cmp" - "gotest.tools/internal/format" - "gotest.tools/internal/source" -) - -// BoolOrComparison can be a bool, or cmp.Comparison. See Assert() for usage. -type BoolOrComparison interface{} - -// TestingT is the subset of testing.T used by the assert package. -type TestingT interface { - FailNow() - Fail() - Log(args ...interface{}) -} - -type helperT interface { - Helper() -} - -const failureMessage = "assertion failed: " - -// nolint: gocyclo -func assert( - t TestingT, - failer func(), - argSelector argSelector, - comparison BoolOrComparison, - msgAndArgs ...interface{}, -) bool { - if ht, ok := t.(helperT); ok { - ht.Helper() - } - var success bool - switch check := comparison.(type) { - case bool: - if check { - return true - } - logFailureFromBool(t, msgAndArgs...) - - // Undocumented legacy comparison without Result type - case func() (success bool, message string): - success = runCompareFunc(t, check, msgAndArgs...) - - case nil: - return true - - case error: - msg := "error is not nil: " - t.Log(format.WithCustomMessage(failureMessage+msg+check.Error(), msgAndArgs...)) - - case cmp.Comparison: - success = runComparison(t, argSelector, check, msgAndArgs...) - - case func() cmp.Result: - success = runComparison(t, argSelector, check, msgAndArgs...) - - default: - t.Log(fmt.Sprintf("invalid Comparison: %v (%T)", check, check)) - } - - if success { - return true - } - failer() - return false -} - -func runCompareFunc( - t TestingT, - f func() (success bool, message string), - msgAndArgs ...interface{}, -) bool { - if ht, ok := t.(helperT); ok { - ht.Helper() - } - if success, message := f(); !success { - t.Log(format.WithCustomMessage(failureMessage+message, msgAndArgs...)) - return false - } - return true -} - -func logFailureFromBool(t TestingT, msgAndArgs ...interface{}) { - if ht, ok := t.(helperT); ok { - ht.Helper() - } - const stackIndex = 3 // Assert()/Check(), assert(), formatFailureFromBool() - const comparisonArgPos = 1 - args, err := source.CallExprArgs(stackIndex) - if err != nil { - t.Log(err.Error()) - return - } - - msg, err := boolFailureMessage(args[comparisonArgPos]) - if err != nil { - t.Log(err.Error()) - msg = "expression is false" - } - - t.Log(format.WithCustomMessage(failureMessage+msg, msgAndArgs...)) -} - -func boolFailureMessage(expr ast.Expr) (string, error) { - if binaryExpr, ok := expr.(*ast.BinaryExpr); ok && binaryExpr.Op == token.NEQ { - x, err := source.FormatNode(binaryExpr.X) - if err != nil { - return "", err - } - y, err := source.FormatNode(binaryExpr.Y) - if err != nil { - return "", err - } - return x + " is " + y, nil - } - - if unaryExpr, ok := expr.(*ast.UnaryExpr); ok && unaryExpr.Op == token.NOT { - x, err := source.FormatNode(unaryExpr.X) - if err != nil { - return "", err - } - return x + " is true", nil - } - - formatted, err := source.FormatNode(expr) - if err != nil { - return "", err - } - return "expression is false: " + formatted, nil -} - -// Assert performs a comparison. If the comparison fails the test is marked as -// failed, a failure message is logged, and execution is stopped immediately. -// -// The comparison argument may be one of three types: bool, cmp.Comparison or -// error. -// When called with a bool the failure message will contain the literal source -// code of the expression. -// When called with a cmp.Comparison the comparison is responsible for producing -// a helpful failure message. -// When called with an error a nil value is considered success. A non-nil error -// is a failure, and Error() is used as the failure message. -func Assert(t TestingT, comparison BoolOrComparison, msgAndArgs ...interface{}) { - if ht, ok := t.(helperT); ok { - ht.Helper() - } - assert(t, t.FailNow, argsFromComparisonCall, comparison, msgAndArgs...) -} - -// Check performs a comparison. If the comparison fails the test is marked as -// failed, a failure message is logged, and Check returns false. Otherwise returns -// true. -// -// See Assert for details about the comparison arg and failure messages. -func Check(t TestingT, comparison BoolOrComparison, msgAndArgs ...interface{}) bool { - if ht, ok := t.(helperT); ok { - ht.Helper() - } - return assert(t, t.Fail, argsFromComparisonCall, comparison, msgAndArgs...) -} - -// NilError fails the test immediately if err is not nil. -// This is equivalent to Assert(t, err) -func NilError(t TestingT, err error, msgAndArgs ...interface{}) { - if ht, ok := t.(helperT); ok { - ht.Helper() - } - assert(t, t.FailNow, argsAfterT, err, msgAndArgs...) -} - -// Equal uses the == operator to assert two values are equal and fails the test -// if they are not equal. -// -// If the comparison fails Equal will use the variable names for x and y as part -// of the failure message to identify the actual and expected values. -// -// If either x or y are a multi-line string the failure message will include a -// unified diff of the two values. If the values only differ by whitespace -// the unified diff will be augmented by replacing whitespace characters with -// visible characters to identify the whitespace difference. -// -// This is equivalent to Assert(t, cmp.Equal(x, y)). -func Equal(t TestingT, x, y interface{}, msgAndArgs ...interface{}) { - if ht, ok := t.(helperT); ok { - ht.Helper() - } - assert(t, t.FailNow, argsAfterT, cmp.Equal(x, y), msgAndArgs...) -} - -// DeepEqual uses google/go-cmp (http://bit.do/go-cmp) to assert two values are -// equal and fails the test if they are not equal. -// -// Package https://godoc.org/gotest.tools/assert/opt provides some additional -// commonly used Options. -// -// This is equivalent to Assert(t, cmp.DeepEqual(x, y)). -func DeepEqual(t TestingT, x, y interface{}, opts ...gocmp.Option) { - if ht, ok := t.(helperT); ok { - ht.Helper() - } - assert(t, t.FailNow, argsAfterT, cmp.DeepEqual(x, y, opts...)) -} - -// Error fails the test if err is nil, or the error message is not the expected -// message. -// Equivalent to Assert(t, cmp.Error(err, message)). -func Error(t TestingT, err error, message string, msgAndArgs ...interface{}) { - if ht, ok := t.(helperT); ok { - ht.Helper() - } - assert(t, t.FailNow, argsAfterT, cmp.Error(err, message), msgAndArgs...) -} - -// ErrorContains fails the test if err is nil, or the error message does not -// contain the expected substring. -// Equivalent to Assert(t, cmp.ErrorContains(err, substring)). -func ErrorContains(t TestingT, err error, substring string, msgAndArgs ...interface{}) { - if ht, ok := t.(helperT); ok { - ht.Helper() - } - assert(t, t.FailNow, argsAfterT, cmp.ErrorContains(err, substring), msgAndArgs...) -} - -// ErrorType fails the test if err is nil, or err is not the expected type. -// -// Expected can be one of: -// a func(error) bool which returns true if the error is the expected type, -// an instance of (or a pointer to) a struct of the expected type, -// a pointer to an interface the error is expected to implement, -// a reflect.Type of the expected struct or interface. -// -// Equivalent to Assert(t, cmp.ErrorType(err, expected)). -func ErrorType(t TestingT, err error, expected interface{}, msgAndArgs ...interface{}) { - if ht, ok := t.(helperT); ok { - ht.Helper() - } - assert(t, t.FailNow, argsAfterT, cmp.ErrorType(err, expected), msgAndArgs...) -} diff --git a/vendor/gotest.tools/assert/cmp/compare.go b/vendor/gotest.tools/assert/cmp/compare.go deleted file mode 100644 index ae03749e..00000000 --- a/vendor/gotest.tools/assert/cmp/compare.go +++ /dev/null @@ -1,312 +0,0 @@ -/*Package cmp provides Comparisons for Assert and Check*/ -package cmp // import "gotest.tools/assert/cmp" - -import ( - "fmt" - "reflect" - "strings" - - "github.com/google/go-cmp/cmp" - "gotest.tools/internal/format" -) - -// Comparison is a function which compares values and returns ResultSuccess if -// the actual value matches the expected value. If the values do not match the -// Result will contain a message about why it failed. -type Comparison func() Result - -// DeepEqual compares two values using google/go-cmp (http://bit.do/go-cmp) -// and succeeds if the values are equal. -// -// The comparison can be customized using comparison Options. -// Package https://godoc.org/gotest.tools/assert/opt provides some additional -// commonly used Options. -func DeepEqual(x, y interface{}, opts ...cmp.Option) Comparison { - return func() (result Result) { - defer func() { - if panicmsg, handled := handleCmpPanic(recover()); handled { - result = ResultFailure(panicmsg) - } - }() - diff := cmp.Diff(x, y, opts...) - if diff == "" { - return ResultSuccess - } - return multiLineDiffResult(diff) - } -} - -func handleCmpPanic(r interface{}) (string, bool) { - if r == nil { - return "", false - } - panicmsg, ok := r.(string) - if !ok { - panic(r) - } - switch { - case strings.HasPrefix(panicmsg, "cannot handle unexported field"): - return panicmsg, true - } - panic(r) -} - -func toResult(success bool, msg string) Result { - if success { - return ResultSuccess - } - return ResultFailure(msg) -} - -// Equal succeeds if x == y. See assert.Equal for full documentation. -func Equal(x, y interface{}) Comparison { - return func() Result { - switch { - case x == y: - return ResultSuccess - case isMultiLineStringCompare(x, y): - diff := format.UnifiedDiff(format.DiffConfig{A: x.(string), B: y.(string)}) - return multiLineDiffResult(diff) - } - return ResultFailureTemplate(` - {{- .Data.x}} ( - {{- with callArg 0 }}{{ formatNode . }} {{end -}} - {{- printf "%T" .Data.x -}} - ) != {{ .Data.y}} ( - {{- with callArg 1 }}{{ formatNode . }} {{end -}} - {{- printf "%T" .Data.y -}} - )`, - map[string]interface{}{"x": x, "y": y}) - } -} - -func isMultiLineStringCompare(x, y interface{}) bool { - strX, ok := x.(string) - if !ok { - return false - } - strY, ok := y.(string) - if !ok { - return false - } - return strings.Contains(strX, "\n") || strings.Contains(strY, "\n") -} - -func multiLineDiffResult(diff string) Result { - return ResultFailureTemplate(` ---- {{ with callArg 0 }}{{ formatNode . }}{{else}}←{{end}} -+++ {{ with callArg 1 }}{{ formatNode . }}{{else}}→{{end}} -{{ .Data.diff }}`, - map[string]interface{}{"diff": diff}) -} - -// Len succeeds if the sequence has the expected length. -func Len(seq interface{}, expected int) Comparison { - return func() (result Result) { - defer func() { - if e := recover(); e != nil { - result = ResultFailure(fmt.Sprintf("type %T does not have a length", seq)) - } - }() - value := reflect.ValueOf(seq) - length := value.Len() - if length == expected { - return ResultSuccess - } - msg := fmt.Sprintf("expected %s (length %d) to have length %d", seq, length, expected) - return ResultFailure(msg) - } -} - -// Contains succeeds if item is in collection. Collection may be a string, map, -// slice, or array. -// -// If collection is a string, item must also be a string, and is compared using -// strings.Contains(). -// If collection is a Map, contains will succeed if item is a key in the map. -// If collection is a slice or array, item is compared to each item in the -// sequence using reflect.DeepEqual(). -func Contains(collection interface{}, item interface{}) Comparison { - return func() Result { - colValue := reflect.ValueOf(collection) - if !colValue.IsValid() { - return ResultFailure(fmt.Sprintf("nil does not contain items")) - } - msg := fmt.Sprintf("%v does not contain %v", collection, item) - - itemValue := reflect.ValueOf(item) - switch colValue.Type().Kind() { - case reflect.String: - if itemValue.Type().Kind() != reflect.String { - return ResultFailure("string may only contain strings") - } - return toResult( - strings.Contains(colValue.String(), itemValue.String()), - fmt.Sprintf("string %q does not contain %q", collection, item)) - - case reflect.Map: - if itemValue.Type() != colValue.Type().Key() { - return ResultFailure(fmt.Sprintf( - "%v can not contain a %v key", colValue.Type(), itemValue.Type())) - } - return toResult(colValue.MapIndex(itemValue).IsValid(), msg) - - case reflect.Slice, reflect.Array: - for i := 0; i < colValue.Len(); i++ { - if reflect.DeepEqual(colValue.Index(i).Interface(), item) { - return ResultSuccess - } - } - return ResultFailure(msg) - default: - return ResultFailure(fmt.Sprintf("type %T does not contain items", collection)) - } - } -} - -// Panics succeeds if f() panics. -func Panics(f func()) Comparison { - return func() (result Result) { - defer func() { - if err := recover(); err != nil { - result = ResultSuccess - } - }() - f() - return ResultFailure("did not panic") - } -} - -// Error succeeds if err is a non-nil error, and the error message equals the -// expected message. -func Error(err error, message string) Comparison { - return func() Result { - switch { - case err == nil: - return ResultFailure("expected an error, got nil") - case err.Error() != message: - return ResultFailure(fmt.Sprintf( - "expected error %q, got %+v", message, err)) - } - return ResultSuccess - } -} - -// ErrorContains succeeds if err is a non-nil error, and the error message contains -// the expected substring. -func ErrorContains(err error, substring string) Comparison { - return func() Result { - switch { - case err == nil: - return ResultFailure("expected an error, got nil") - case !strings.Contains(err.Error(), substring): - return ResultFailure(fmt.Sprintf( - "expected error to contain %q, got %+v", substring, err)) - } - return ResultSuccess - } -} - -// Nil succeeds if obj is a nil interface, pointer, or function. -// -// Use NilError() for comparing errors. Use Len(obj, 0) for comparing slices, -// maps, and channels. -func Nil(obj interface{}) Comparison { - msgFunc := func(value reflect.Value) string { - return fmt.Sprintf("%v (type %s) is not nil", reflect.Indirect(value), value.Type()) - } - return isNil(obj, msgFunc) -} - -func isNil(obj interface{}, msgFunc func(reflect.Value) string) Comparison { - return func() Result { - if obj == nil { - return ResultSuccess - } - value := reflect.ValueOf(obj) - kind := value.Type().Kind() - if kind >= reflect.Chan && kind <= reflect.Slice { - if value.IsNil() { - return ResultSuccess - } - return ResultFailure(msgFunc(value)) - } - - return ResultFailure(fmt.Sprintf("%v (type %s) can not be nil", value, value.Type())) - } -} - -// ErrorType succeeds if err is not nil and is of the expected type. -// -// Expected can be one of: -// a func(error) bool which returns true if the error is the expected type, -// an instance of (or a pointer to) a struct of the expected type, -// a pointer to an interface the error is expected to implement, -// a reflect.Type of the expected struct or interface. -func ErrorType(err error, expected interface{}) Comparison { - return func() Result { - switch expectedType := expected.(type) { - case func(error) bool: - return cmpErrorTypeFunc(err, expectedType) - case reflect.Type: - if expectedType.Kind() == reflect.Interface { - return cmpErrorTypeImplementsType(err, expectedType) - } - return cmpErrorTypeEqualType(err, expectedType) - case nil: - return ResultFailure(fmt.Sprintf("invalid type for expected: nil")) - } - - expectedType := reflect.TypeOf(expected) - switch { - case expectedType.Kind() == reflect.Struct, isPtrToStruct(expectedType): - return cmpErrorTypeEqualType(err, expectedType) - case isPtrToInterface(expectedType): - return cmpErrorTypeImplementsType(err, expectedType.Elem()) - } - return ResultFailure(fmt.Sprintf("invalid type for expected: %T", expected)) - } -} - -func cmpErrorTypeFunc(err error, f func(error) bool) Result { - if f(err) { - return ResultSuccess - } - actual := "nil" - if err != nil { - actual = fmt.Sprintf("%s (%T)", err, err) - } - return ResultFailureTemplate(`error is {{ .Data.actual }} - {{- with callArg 1 }}, not {{ formatNode . }}{{end -}}`, - map[string]interface{}{"actual": actual}) -} - -func cmpErrorTypeEqualType(err error, expectedType reflect.Type) Result { - if err == nil { - return ResultFailure(fmt.Sprintf("error is nil, not %s", expectedType)) - } - errValue := reflect.ValueOf(err) - if errValue.Type() == expectedType { - return ResultSuccess - } - return ResultFailure(fmt.Sprintf("error is %s (%T), not %s", err, err, expectedType)) -} - -func cmpErrorTypeImplementsType(err error, expectedType reflect.Type) Result { - if err == nil { - return ResultFailure(fmt.Sprintf("error is nil, not %s", expectedType)) - } - errValue := reflect.ValueOf(err) - if errValue.Type().Implements(expectedType) { - return ResultSuccess - } - return ResultFailure(fmt.Sprintf("error is %s (%T), not %s", err, err, expectedType)) -} - -func isPtrToInterface(typ reflect.Type) bool { - return typ.Kind() == reflect.Ptr && typ.Elem().Kind() == reflect.Interface -} - -func isPtrToStruct(typ reflect.Type) bool { - return typ.Kind() == reflect.Ptr && typ.Elem().Kind() == reflect.Struct -} diff --git a/vendor/gotest.tools/assert/cmp/result.go b/vendor/gotest.tools/assert/cmp/result.go deleted file mode 100644 index 7c3c37dd..00000000 --- a/vendor/gotest.tools/assert/cmp/result.go +++ /dev/null @@ -1,94 +0,0 @@ -package cmp - -import ( - "bytes" - "fmt" - "go/ast" - "text/template" - - "gotest.tools/internal/source" -) - -// Result of a Comparison. -type Result interface { - Success() bool -} - -type result struct { - success bool - message string -} - -func (r result) Success() bool { - return r.success -} - -func (r result) FailureMessage() string { - return r.message -} - -// ResultSuccess is a constant which is returned by a ComparisonWithResult to -// indicate success. -var ResultSuccess = result{success: true} - -// ResultFailure returns a failed Result with a failure message. -func ResultFailure(message string) Result { - return result{message: message} -} - -// ResultFromError returns ResultSuccess if err is nil. Otherwise ResultFailure -// is returned with the error message as the failure message. -func ResultFromError(err error) Result { - if err == nil { - return ResultSuccess - } - return ResultFailure(err.Error()) -} - -type templatedResult struct { - success bool - template string - data map[string]interface{} -} - -func (r templatedResult) Success() bool { - return r.success -} - -func (r templatedResult) FailureMessage(args []ast.Expr) string { - msg, err := renderMessage(r, args) - if err != nil { - return fmt.Sprintf("failed to render failure message: %s", err) - } - return msg -} - -// ResultFailureTemplate returns a Result with a template string and data which -// can be used to format a failure message. The template may access data from .Data, -// the comparison args with the callArg function, and the formatNode function may -// be used to format the call args. -func ResultFailureTemplate(template string, data map[string]interface{}) Result { - return templatedResult{template: template, data: data} -} - -func renderMessage(result templatedResult, args []ast.Expr) (string, error) { - tmpl := template.New("failure").Funcs(template.FuncMap{ - "formatNode": source.FormatNode, - "callArg": func(index int) ast.Expr { - if index >= len(args) { - return nil - } - return args[index] - }, - }) - var err error - tmpl, err = tmpl.Parse(result.template) - if err != nil { - return "", err - } - buf := new(bytes.Buffer) - err = tmpl.Execute(buf, map[string]interface{}{ - "Data": result.data, - }) - return buf.String(), err -} diff --git a/vendor/gotest.tools/assert/result.go b/vendor/gotest.tools/assert/result.go deleted file mode 100644 index 3900264d..00000000 --- a/vendor/gotest.tools/assert/result.go +++ /dev/null @@ -1,107 +0,0 @@ -package assert - -import ( - "fmt" - "go/ast" - - "gotest.tools/assert/cmp" - "gotest.tools/internal/format" - "gotest.tools/internal/source" -) - -func runComparison( - t TestingT, - argSelector argSelector, - f cmp.Comparison, - msgAndArgs ...interface{}, -) bool { - if ht, ok := t.(helperT); ok { - ht.Helper() - } - result := f() - if result.Success() { - return true - } - - var message string - switch typed := result.(type) { - case resultWithComparisonArgs: - const stackIndex = 3 // Assert/Check, assert, runComparison - args, err := source.CallExprArgs(stackIndex) - if err != nil { - t.Log(err.Error()) - } - message = typed.FailureMessage(filterPrintableExpr(argSelector(args))) - case resultBasic: - message = typed.FailureMessage() - default: - message = fmt.Sprintf("comparison returned invalid Result type: %T", result) - } - - t.Log(format.WithCustomMessage(failureMessage+message, msgAndArgs...)) - return false -} - -type resultWithComparisonArgs interface { - FailureMessage(args []ast.Expr) string -} - -type resultBasic interface { - FailureMessage() string -} - -// filterPrintableExpr filters the ast.Expr slice to only include Expr that are -// easy to read when printed and contain relevant information to an assertion. -// -// Ident and SelectorExpr are included because they print nicely and the variable -// names may provide additional context to their values. -// BasicLit and CompositeLit are excluded because their source is equivalent to -// their value, which is already available. -// Other types are ignored for now, but could be added if they are relevant. -func filterPrintableExpr(args []ast.Expr) []ast.Expr { - result := make([]ast.Expr, len(args)) - for i, arg := range args { - if isShortPrintableExpr(arg) { - result[i] = arg - continue - } - - if starExpr, ok := arg.(*ast.StarExpr); ok { - result[i] = starExpr.X - continue - } - result[i] = nil - } - return result -} - -func isShortPrintableExpr(expr ast.Expr) bool { - switch expr.(type) { - case *ast.Ident, *ast.SelectorExpr, *ast.IndexExpr, *ast.SliceExpr: - return true - case *ast.BinaryExpr, *ast.UnaryExpr: - return true - default: - // CallExpr, ParenExpr, TypeAssertExpr, KeyValueExpr, StarExpr - return false - } -} - -type argSelector func([]ast.Expr) []ast.Expr - -func argsAfterT(args []ast.Expr) []ast.Expr { - if len(args) < 1 { - return nil - } - return args[1:] -} - -func argsFromComparisonCall(args []ast.Expr) []ast.Expr { - if len(args) < 1 { - return nil - } - if callExpr, ok := args[1].(*ast.CallExpr); ok { - return callExpr.Args - } - return nil -} diff --git a/vendor/gotest.tools/internal/difflib/LICENSE b/vendor/gotest.tools/internal/difflib/LICENSE deleted file mode 100644 index c67dad61..00000000 --- a/vendor/gotest.tools/internal/difflib/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2013, Patrick Mezard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - The names of its contributors may not be used to endorse or promote -products derived from this software without specific prior written -permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED -TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/gotest.tools/internal/difflib/difflib.go b/vendor/gotest.tools/internal/difflib/difflib.go deleted file mode 100644 index 5efa99c1..00000000 --- a/vendor/gotest.tools/internal/difflib/difflib.go +++ /dev/null @@ -1,420 +0,0 @@ -/* Package difflib is a partial port of Python difflib module. - -Original source: https://github.com/pmezard/go-difflib - -This file is trimmed to only the parts used by this repository. -*/ -package difflib // import "gotest.tools/internal/difflib" - -func min(a, b int) int { - if a < b { - return a - } - return b -} - -func max(a, b int) int { - if a > b { - return a - } - return b -} - -type Match struct { - A int - B int - Size int -} - -type OpCode struct { - Tag byte - I1 int - I2 int - J1 int - J2 int -} - -// SequenceMatcher compares sequence of strings. The basic -// algorithm predates, and is a little fancier than, an algorithm -// published in the late 1980's by Ratcliff and Obershelp under the -// hyperbolic name "gestalt pattern matching". The basic idea is to find -// the longest contiguous matching subsequence that contains no "junk" -// elements (R-O doesn't address junk). The same idea is then applied -// recursively to the pieces of the sequences to the left and to the right -// of the matching subsequence. This does not yield minimal edit -// sequences, but does tend to yield matches that "look right" to people. -// -// SequenceMatcher tries to compute a "human-friendly diff" between two -// sequences. Unlike e.g. UNIX(tm) diff, the fundamental notion is the -// longest *contiguous* & junk-free matching subsequence. That's what -// catches peoples' eyes. The Windows(tm) windiff has another interesting -// notion, pairing up elements that appear uniquely in each sequence. -// That, and the method here, appear to yield more intuitive difference -// reports than does diff. This method appears to be the least vulnerable -// to synching up on blocks of "junk lines", though (like blank lines in -// ordinary text files, or maybe "<P>" lines in HTML files). That may be -// because this is the only method of the 3 that has a *concept* of -// "junk" <wink>. -// -// Timing: Basic R-O is cubic time worst case and quadratic time expected -// case. SequenceMatcher is quadratic time for the worst case and has -// expected-case behavior dependent in a complicated way on how many -// elements the sequences have in common; best case time is linear. -type SequenceMatcher struct { - a []string - b []string - b2j map[string][]int - IsJunk func(string) bool - autoJunk bool - bJunk map[string]struct{} - matchingBlocks []Match - fullBCount map[string]int - bPopular map[string]struct{} - opCodes []OpCode -} - -func NewMatcher(a, b []string) *SequenceMatcher { - m := SequenceMatcher{autoJunk: true} - m.SetSeqs(a, b) - return &m -} - -// Set two sequences to be compared. -func (m *SequenceMatcher) SetSeqs(a, b []string) { - m.SetSeq1(a) - m.SetSeq2(b) -} - -// Set the first sequence to be compared. The second sequence to be compared is -// not changed. -// -// SequenceMatcher computes and caches detailed information about the second -// sequence, so if you want to compare one sequence S against many sequences, -// use .SetSeq2(s) once and call .SetSeq1(x) repeatedly for each of the other -// sequences. -// -// See also SetSeqs() and SetSeq2(). -func (m *SequenceMatcher) SetSeq1(a []string) { - if &a == &m.a { - return - } - m.a = a - m.matchingBlocks = nil - m.opCodes = nil -} - -// Set the second sequence to be compared. The first sequence to be compared is -// not changed. -func (m *SequenceMatcher) SetSeq2(b []string) { - if &b == &m.b { - return - } - m.b = b - m.matchingBlocks = nil - m.opCodes = nil - m.fullBCount = nil - m.chainB() -} - -func (m *SequenceMatcher) chainB() { - // Populate line -> index mapping - b2j := map[string][]int{} - for i, s := range m.b { - indices := b2j[s] - indices = append(indices, i) - b2j[s] = indices - } - - // Purge junk elements - m.bJunk = map[string]struct{}{} - if m.IsJunk != nil { - junk := m.bJunk - for s, _ := range b2j { - if m.IsJunk(s) { - junk[s] = struct{}{} - } - } - for s, _ := range junk { - delete(b2j, s) - } - } - - // Purge remaining popular elements - popular := map[string]struct{}{} - n := len(m.b) - if m.autoJunk && n >= 200 { - ntest := n/100 + 1 - for s, indices := range b2j { - if len(indices) > ntest { - popular[s] = struct{}{} - } - } - for s, _ := range popular { - delete(b2j, s) - } - } - m.bPopular = popular - m.b2j = b2j -} - -func (m *SequenceMatcher) isBJunk(s string) bool { - _, ok := m.bJunk[s] - return ok -} - -// Find longest matching block in a[alo:ahi] and b[blo:bhi]. -// -// If IsJunk is not defined: -// -// Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where -// alo <= i <= i+k <= ahi -// blo <= j <= j+k <= bhi -// and for all (i',j',k') meeting those conditions, -// k >= k' -// i <= i' -// and if i == i', j <= j' -// -// In other words, of all maximal matching blocks, return one that -// starts earliest in a, and of all those maximal matching blocks that -// start earliest in a, return the one that starts earliest in b. -// -// If IsJunk is defined, first the longest matching block is -// determined as above, but with the additional restriction that no -// junk element appears in the block. Then that block is extended as -// far as possible by matching (only) junk elements on both sides. So -// the resulting block never matches on junk except as identical junk -// happens to be adjacent to an "interesting" match. -// -// If no blocks match, return (alo, blo, 0). -func (m *SequenceMatcher) findLongestMatch(alo, ahi, blo, bhi int) Match { - // CAUTION: stripping common prefix or suffix would be incorrect. - // E.g., - // ab - // acab - // Longest matching block is "ab", but if common prefix is - // stripped, it's "a" (tied with "b"). UNIX(tm) diff does so - // strip, so ends up claiming that ab is changed to acab by - // inserting "ca" in the middle. That's minimal but unintuitive: - // "it's obvious" that someone inserted "ac" at the front. - // Windiff ends up at the same place as diff, but by pairing up - // the unique 'b's and then matching the first two 'a's. - besti, bestj, bestsize := alo, blo, 0 - - // find longest junk-free match - // during an iteration of the loop, j2len[j] = length of longest - // junk-free match ending with a[i-1] and b[j] - j2len := map[int]int{} - for i := alo; i != ahi; i++ { - // look at all instances of a[i] in b; note that because - // b2j has no junk keys, the loop is skipped if a[i] is junk - newj2len := map[int]int{} - for _, j := range m.b2j[m.a[i]] { - // a[i] matches b[j] - if j < blo { - continue - } - if j >= bhi { - break - } - k := j2len[j-1] + 1 - newj2len[j] = k - if k > bestsize { - besti, bestj, bestsize = i-k+1, j-k+1, k - } - } - j2len = newj2len - } - - // Extend the best by non-junk elements on each end. In particular, - // "popular" non-junk elements aren't in b2j, which greatly speeds - // the inner loop above, but also means "the best" match so far - // doesn't contain any junk *or* popular non-junk elements. - for besti > alo && bestj > blo && !m.isBJunk(m.b[bestj-1]) && - m.a[besti-1] == m.b[bestj-1] { - besti, bestj, bestsize = besti-1, bestj-1, bestsize+1 - } - for besti+bestsize < ahi && bestj+bestsize < bhi && - !m.isBJunk(m.b[bestj+bestsize]) && - m.a[besti+bestsize] == m.b[bestj+bestsize] { - bestsize += 1 - } - - // Now that we have a wholly interesting match (albeit possibly - // empty!), we may as well suck up the matching junk on each - // side of it too. Can't think of a good reason not to, and it - // saves post-processing the (possibly considerable) expense of - // figuring out what to do with it. In the case of an empty - // interesting match, this is clearly the right thing to do, - // because no other kind of match is possible in the regions. - for besti > alo && bestj > blo && m.isBJunk(m.b[bestj-1]) && - m.a[besti-1] == m.b[bestj-1] { - besti, bestj, bestsize = besti-1, bestj-1, bestsize+1 - } - for besti+bestsize < ahi && bestj+bestsize < bhi && - m.isBJunk(m.b[bestj+bestsize]) && - m.a[besti+bestsize] == m.b[bestj+bestsize] { - bestsize += 1 - } - - return Match{A: besti, B: bestj, Size: bestsize} -} - -// Return list of triples describing matching subsequences. -// -// Each triple is of the form (i, j, n), and means that -// a[i:i+n] == b[j:j+n]. The triples are monotonically increasing in -// i and in j. It's also guaranteed that if (i, j, n) and (i', j', n') are -// adjacent triples in the list, and the second is not the last triple in the -// list, then i+n != i' or j+n != j'. IOW, adjacent triples never describe -// adjacent equal blocks. -// -// The last triple is a dummy, (len(a), len(b), 0), and is the only -// triple with n==0. -func (m *SequenceMatcher) GetMatchingBlocks() []Match { - if m.matchingBlocks != nil { - return m.matchingBlocks - } - - var matchBlocks func(alo, ahi, blo, bhi int, matched []Match) []Match - matchBlocks = func(alo, ahi, blo, bhi int, matched []Match) []Match { - match := m.findLongestMatch(alo, ahi, blo, bhi) - i, j, k := match.A, match.B, match.Size - if match.Size > 0 { - if alo < i && blo < j { - matched = matchBlocks(alo, i, blo, j, matched) - } - matched = append(matched, match) - if i+k < ahi && j+k < bhi { - matched = matchBlocks(i+k, ahi, j+k, bhi, matched) - } - } - return matched - } - matched := matchBlocks(0, len(m.a), 0, len(m.b), nil) - - // It's possible that we have adjacent equal blocks in the - // matching_blocks list now. - nonAdjacent := []Match{} - i1, j1, k1 := 0, 0, 0 - for _, b := range matched { - // Is this block adjacent to i1, j1, k1? - i2, j2, k2 := b.A, b.B, b.Size - if i1+k1 == i2 && j1+k1 == j2 { - // Yes, so collapse them -- this just increases the length of - // the first block by the length of the second, and the first - // block so lengthened remains the block to compare against. - k1 += k2 - } else { - // Not adjacent. Remember the first block (k1==0 means it's - // the dummy we started with), and make the second block the - // new block to compare against. - if k1 > 0 { - nonAdjacent = append(nonAdjacent, Match{i1, j1, k1}) - } - i1, j1, k1 = i2, j2, k2 - } - } - if k1 > 0 { - nonAdjacent = append(nonAdjacent, Match{i1, j1, k1}) - } - - nonAdjacent = append(nonAdjacent, Match{len(m.a), len(m.b), 0}) - m.matchingBlocks = nonAdjacent - return m.matchingBlocks -} - -// Return list of 5-tuples describing how to turn a into b. -// -// Each tuple is of the form (tag, i1, i2, j1, j2). The first tuple -// has i1 == j1 == 0, and remaining tuples have i1 == the i2 from the -// tuple preceding it, and likewise for j1 == the previous j2. -// -// The tags are characters, with these meanings: -// -// 'r' (replace): a[i1:i2] should be replaced by b[j1:j2] -// -// 'd' (delete): a[i1:i2] should be deleted, j1==j2 in this case. -// -// 'i' (insert): b[j1:j2] should be inserted at a[i1:i1], i1==i2 in this case. -// -// 'e' (equal): a[i1:i2] == b[j1:j2] -func (m *SequenceMatcher) GetOpCodes() []OpCode { - if m.opCodes != nil { - return m.opCodes - } - i, j := 0, 0 - matching := m.GetMatchingBlocks() - opCodes := make([]OpCode, 0, len(matching)) - for _, m := range matching { - // invariant: we've pumped out correct diffs to change - // a[:i] into b[:j], and the next matching block is - // a[ai:ai+size] == b[bj:bj+size]. So we need to pump - // out a diff to change a[i:ai] into b[j:bj], pump out - // the matching block, and move (i,j) beyond the match - ai, bj, size := m.A, m.B, m.Size - tag := byte(0) - if i < ai && j < bj { - tag = 'r' - } else if i < ai { - tag = 'd' - } else if j < bj { - tag = 'i' - } - if tag > 0 { - opCodes = append(opCodes, OpCode{tag, i, ai, j, bj}) - } - i, j = ai+size, bj+size - // the list of matching blocks is terminated by a - // sentinel with size 0 - if size > 0 { - opCodes = append(opCodes, OpCode{'e', ai, i, bj, j}) - } - } - m.opCodes = opCodes - return m.opCodes -} - -// Isolate change clusters by eliminating ranges with no changes. -// -// Return a generator of groups with up to n lines of context. -// Each group is in the same format as returned by GetOpCodes(). -func (m *SequenceMatcher) GetGroupedOpCodes(n int) [][]OpCode { - if n < 0 { - n = 3 - } - codes := m.GetOpCodes() - if len(codes) == 0 { - codes = []OpCode{OpCode{'e', 0, 1, 0, 1}} - } - // Fixup leading and trailing groups if they show no changes. - if codes[0].Tag == 'e' { - c := codes[0] - i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 - codes[0] = OpCode{c.Tag, max(i1, i2-n), i2, max(j1, j2-n), j2} - } - if codes[len(codes)-1].Tag == 'e' { - c := codes[len(codes)-1] - i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 - codes[len(codes)-1] = OpCode{c.Tag, i1, min(i2, i1+n), j1, min(j2, j1+n)} - } - nn := n + n - groups := [][]OpCode{} - group := []OpCode{} - for _, c := range codes { - i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 - // End the current group and start a new one whenever - // there is a large range with no changes. - if c.Tag == 'e' && i2-i1 > nn { - group = append(group, OpCode{c.Tag, i1, min(i2, i1+n), - j1, min(j2, j1+n)}) - groups = append(groups, group) - group = []OpCode{} - i1, j1 = max(i1, i2-n), max(j1, j2-n) - } - group = append(group, OpCode{c.Tag, i1, i2, j1, j2}) - } - if len(group) > 0 && !(len(group) == 1 && group[0].Tag == 'e') { - groups = append(groups, group) - } - return groups -} diff --git a/vendor/gotest.tools/internal/format/diff.go b/vendor/gotest.tools/internal/format/diff.go deleted file mode 100644 index c938c97b..00000000 --- a/vendor/gotest.tools/internal/format/diff.go +++ /dev/null @@ -1,161 +0,0 @@ -package format - -import ( - "bytes" - "fmt" - "strings" - "unicode" - - "gotest.tools/internal/difflib" -) - -const ( - contextLines = 2 -) - -// DiffConfig for a unified diff -type DiffConfig struct { - A string - B string - From string - To string -} - -// UnifiedDiff is a modified version of difflib.WriteUnifiedDiff with better -// support for showing the whitespace differences. -func UnifiedDiff(conf DiffConfig) string { - a := strings.SplitAfter(conf.A, "\n") - b := strings.SplitAfter(conf.B, "\n") - groups := difflib.NewMatcher(a, b).GetGroupedOpCodes(contextLines) - if len(groups) == 0 { - return "" - } - - buf := new(bytes.Buffer) - writeFormat := func(format string, args ...interface{}) { - buf.WriteString(fmt.Sprintf(format, args...)) - } - writeLine := func(prefix string, s string) { - buf.WriteString(prefix + s) - } - if hasWhitespaceDiffLines(groups, a, b) { - writeLine = visibleWhitespaceLine(writeLine) - } - formatHeader(writeFormat, conf) - for _, group := range groups { - formatRangeLine(writeFormat, group) - for _, opCode := range group { - in, out := a[opCode.I1:opCode.I2], b[opCode.J1:opCode.J2] - switch opCode.Tag { - case 'e': - formatLines(writeLine, " ", in) - case 'r': - formatLines(writeLine, "-", in) - formatLines(writeLine, "+", out) - case 'd': - formatLines(writeLine, "-", in) - case 'i': - formatLines(writeLine, "+", out) - } - } - } - return buf.String() -} - -// hasWhitespaceDiffLines returns true if any diff groups is only different -// because of whitespace characters. -func hasWhitespaceDiffLines(groups [][]difflib.OpCode, a, b []string) bool { - for _, group := range groups { - in, out := new(bytes.Buffer), new(bytes.Buffer) - for _, opCode := range group { - if opCode.Tag == 'e' { - continue - } - for _, line := range a[opCode.I1:opCode.I2] { - in.WriteString(line) - } - for _, line := range b[opCode.J1:opCode.J2] { - out.WriteString(line) - } - } - if removeWhitespace(in.String()) == removeWhitespace(out.String()) { - return true - } - } - return false -} - -func removeWhitespace(s string) string { - var result []rune - for _, r := range s { - if !unicode.IsSpace(r) { - result = append(result, r) - } - } - return string(result) -} - -func visibleWhitespaceLine(ws func(string, string)) func(string, string) { - mapToVisibleSpace := func(r rune) rune { - switch r { - case '\n': - case ' ': - return '·' - case '\t': - return '▷' - case '\v': - return '▽' - case '\r': - return '↵' - case '\f': - return '↓' - default: - if unicode.IsSpace(r) { - return '�' - } - } - return r - } - return func(prefix, s string) { - ws(prefix, strings.Map(mapToVisibleSpace, s)) - } -} - -func formatHeader(wf func(string, ...interface{}), conf DiffConfig) { - if conf.From != "" || conf.To != "" { - wf("--- %s\n", conf.From) - wf("+++ %s\n", conf.To) - } -} - -func formatRangeLine(wf func(string, ...interface{}), group []difflib.OpCode) { - first, last := group[0], group[len(group)-1] - range1 := formatRangeUnified(first.I1, last.I2) - range2 := formatRangeUnified(first.J1, last.J2) - wf("@@ -%s +%s @@\n", range1, range2) -} - -// Convert range to the "ed" format -func formatRangeUnified(start, stop int) string { - // Per the diff spec at http://www.unix.org/single_unix_specification/ - beginning := start + 1 // lines start numbering with one - length := stop - start - if length == 1 { - return fmt.Sprintf("%d", beginning) - } - if length == 0 { - beginning-- // empty ranges begin at line just before the range - } - return fmt.Sprintf("%d,%d", beginning, length) -} - -func formatLines(writeLine func(string, string), prefix string, lines []string) { - for _, line := range lines { - writeLine(prefix, line) - } - // Add a newline if the last line is missing one so that the diff displays - // properly. - if !strings.HasSuffix(lines[len(lines)-1], "\n") { - writeLine("", "\n") - } -} diff --git a/vendor/gotest.tools/internal/format/format.go b/vendor/gotest.tools/internal/format/format.go deleted file mode 100644 index 8f6494f9..00000000 --- a/vendor/gotest.tools/internal/format/format.go +++ /dev/null @@ -1,27 +0,0 @@ -package format // import "gotest.tools/internal/format" - -import "fmt" - -// Message accepts a msgAndArgs varargs and formats it using fmt.Sprintf -func Message(msgAndArgs ...interface{}) string { - switch len(msgAndArgs) { - case 0: - return "" - case 1: - return fmt.Sprintf("%v", msgAndArgs[0]) - default: - return fmt.Sprintf(msgAndArgs[0].(string), msgAndArgs[1:]...) - } -} - -// WithCustomMessage accepts one or two messages and formats them appropriately -func WithCustomMessage(source string, msgAndArgs ...interface{}) string { - custom := Message(msgAndArgs...) - switch { - case custom == "": - return source - case source == "": - return custom - } - return fmt.Sprintf("%s: %s", source, custom) -} diff --git a/vendor/gotest.tools/internal/source/source.go b/vendor/gotest.tools/internal/source/source.go deleted file mode 100644 index a05933cc..00000000 --- a/vendor/gotest.tools/internal/source/source.go +++ /dev/null @@ -1,163 +0,0 @@ -package source // import "gotest.tools/internal/source" - -import ( - "bytes" - "fmt" - "go/ast" - "go/format" - "go/parser" - "go/token" - "os" - "runtime" - "strconv" - "strings" - - "github.com/pkg/errors" -) - -const baseStackIndex = 1 - -// FormattedCallExprArg returns the argument from an ast.CallExpr at the -// index in the call stack. The argument is formatted using FormatNode. -func FormattedCallExprArg(stackIndex int, argPos int) (string, error) { - args, err := CallExprArgs(stackIndex + 1) - if err != nil { - return "", err - } - return FormatNode(args[argPos]) -} - -func getNodeAtLine(filename string, lineNum int) (ast.Node, error) { - fileset := token.NewFileSet() - astFile, err := parser.ParseFile(fileset, filename, nil, parser.AllErrors) - if err != nil { - return nil, errors.Wrapf(err, "failed to parse source file: %s", filename) - } - - node := scanToLine(fileset, astFile, lineNum) - if node == nil { - return nil, errors.Errorf( - "failed to find an expression on line %d in %s", lineNum, filename) - } - return node, nil -} - -func scanToLine(fileset *token.FileSet, node ast.Node, lineNum int) ast.Node { - v := &scanToLineVisitor{lineNum: lineNum, fileset: fileset} - ast.Walk(v, node) - return v.matchedNode -} - -type scanToLineVisitor struct { - lineNum int - matchedNode ast.Node - fileset *token.FileSet -} - -func (v *scanToLineVisitor) Visit(node ast.Node) ast.Visitor { - if node == nil || v.matchedNode != nil { - return nil - } - if v.nodePosition(node).Line == v.lineNum { - v.matchedNode = node - return nil - } - return v -} - -// In golang 1.9 the line number changed from being the line where the statement -// ended to the line where the statement began. -func (v *scanToLineVisitor) nodePosition(node ast.Node) token.Position { - if goVersionBefore19 { - return v.fileset.Position(node.End()) - } - return v.fileset.Position(node.Pos()) -} - -var goVersionBefore19 = isGOVersionBefore19() - -func isGOVersionBefore19() bool { - version := runtime.Version() - // not a release version - if !strings.HasPrefix(version, "go") { - return false - } - version = strings.TrimPrefix(version, "go") - parts := strings.Split(version, ".") - if len(parts) < 2 { - return false - } - minor, err := strconv.ParseInt(parts[1], 10, 32) - return err == nil && parts[0] == "1" && minor < 9 -} - -func getCallExprArgs(node ast.Node) ([]ast.Expr, error) { - visitor := &callExprVisitor{} - ast.Walk(visitor, node) - if visitor.expr == nil { - return nil, errors.New("failed to find call expression") - } - return visitor.expr.Args, nil -} - -type callExprVisitor struct { - expr *ast.CallExpr -} - -func (v *callExprVisitor) Visit(node ast.Node) ast.Visitor { - if v.expr != nil || node == nil { - return nil - } - debug("visit (%T): %s", node, debugFormatNode{node}) - - if callExpr, ok := node.(*ast.CallExpr); ok { - v.expr = callExpr - return nil - } - return v -} - -// FormatNode using go/format.Node and return the result as a string -func FormatNode(node ast.Node) (string, error) { - buf := new(bytes.Buffer) - err := format.Node(buf, token.NewFileSet(), node) - return buf.String(), err -} - -// CallExprArgs returns the ast.Expr slice for the args of an ast.CallExpr at -// the index in the call stack. -func CallExprArgs(stackIndex int) ([]ast.Expr, error) { - _, filename, lineNum, ok := runtime.Caller(baseStackIndex + stackIndex) - if !ok { - return nil, errors.New("failed to get call stack") - } - debug("call stack position: %s:%d", filename, lineNum) - - node, err := getNodeAtLine(filename, lineNum) - if err != nil { - return nil, err - } - debug("found node (%T): %s", node, debugFormatNode{node}) - - return getCallExprArgs(node) -} - -var debugEnabled = os.Getenv("GOTESTYOURSELF_DEBUG") != "" - -func debug(format string, args ...interface{}) { - if debugEnabled { - fmt.Fprintf(os.Stderr, "DEBUG: "+format+"\n", args...) - } -} - -type debugFormatNode struct { - ast.Node -} - -func (n debugFormatNode) String() string { - out, err := FormatNode(n.Node) - if err != nil { - return fmt.Sprintf("failed to format %s: %s", n.Node, err) - } - return out -} |