Selective export (#770)

This commit is contained in:
WithoutPants
2020-09-15 17:28:53 +10:00
committed by GitHub
parent 03f5e1a442
commit 03d4826c85
280 changed files with 40619 additions and 13035 deletions

13
vendor/github.com/stretchr/objx/.codeclimate.yml generated vendored Normal file
View File

@@ -0,0 +1,13 @@
engines:
gofmt:
enabled: true
golint:
enabled: true
govet:
enabled: true
exclude_patterns:
- ".github/"
- "vendor/"
- "codegen/"
- "doc.go"

11
vendor/github.com/stretchr/objx/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,11 @@
# Binaries for programs and plugins
*.exe
*.dll
*.so
*.dylib
# Test binary, build with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out

25
vendor/github.com/stretchr/objx/.travis.yml generated vendored Normal file
View File

@@ -0,0 +1,25 @@
language: go
go:
- 1.8
- 1.9
- tip
env:
global:
- CC_TEST_REPORTER_ID=68feaa3410049ce73e145287acbcdacc525087a30627f96f04e579e75bd71c00
before_script:
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
- chmod +x ./cc-test-reporter
- ./cc-test-reporter before-build
install:
- go get github.com/go-task/task/cmd/task
script:
- task dl-deps
- task lint
- task test-coverage
after_script:
- ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT

30
vendor/github.com/stretchr/objx/Gopkg.lock generated vendored Normal file
View File

@@ -0,0 +1,30 @@
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
[[projects]]
name = "github.com/davecgh/go-spew"
packages = ["spew"]
revision = "346938d642f2ec3594ed81d874461961cd0faa76"
version = "v1.1.0"
[[projects]]
name = "github.com/pmezard/go-difflib"
packages = ["difflib"]
revision = "792786c7400a136282c1664665ae0a8db921c6c2"
version = "v1.0.0"
[[projects]]
name = "github.com/stretchr/testify"
packages = [
"assert",
"require"
]
revision = "b91bfb9ebec76498946beb6af7c0230c7cc7ba6c"
version = "v1.2.0"
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
inputs-digest = "2d160a7dea4ffd13c6c31dab40373822f9d78c73beba016d662bef8f7a998876"
solver-name = "gps-cdcl"
solver-version = 1

8
vendor/github.com/stretchr/objx/Gopkg.toml generated vendored Normal file
View File

@@ -0,0 +1,8 @@
[prune]
unused-packages = true
non-go = true
go-tests = true
[[constraint]]
name = "github.com/stretchr/testify"
version = "~1.2.0"

22
vendor/github.com/stretchr/objx/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,22 @@
The MIT License
Copyright (c) 2014 Stretchr, Inc.
Copyright (c) 2017-2018 objx contributors
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.

80
vendor/github.com/stretchr/objx/README.md generated vendored Normal file
View File

@@ -0,0 +1,80 @@
# Objx
[![Build Status](https://travis-ci.org/stretchr/objx.svg?branch=master)](https://travis-ci.org/stretchr/objx)
[![Go Report Card](https://goreportcard.com/badge/github.com/stretchr/objx)](https://goreportcard.com/report/github.com/stretchr/objx)
[![Maintainability](https://api.codeclimate.com/v1/badges/1d64bc6c8474c2074f2b/maintainability)](https://codeclimate.com/github/stretchr/objx/maintainability)
[![Test Coverage](https://api.codeclimate.com/v1/badges/1d64bc6c8474c2074f2b/test_coverage)](https://codeclimate.com/github/stretchr/objx/test_coverage)
[![Sourcegraph](https://sourcegraph.com/github.com/stretchr/objx/-/badge.svg)](https://sourcegraph.com/github.com/stretchr/objx)
[![GoDoc](https://godoc.org/github.com/stretchr/objx?status.svg)](https://godoc.org/github.com/stretchr/objx)
Objx - Go package for dealing with maps, slices, JSON and other data.
Get started:
- Install Objx with [one line of code](#installation), or [update it with another](#staying-up-to-date)
- Check out the API Documentation http://godoc.org/github.com/stretchr/objx
## Overview
Objx provides the `objx.Map` type, which is a `map[string]interface{}` that exposes a powerful `Get` method (among others) that allows you to easily and quickly get access to data within the map, without having to worry too much about type assertions, missing data, default values etc.
### Pattern
Objx uses a preditable pattern to make access data from within `map[string]interface{}` easy. Call one of the `objx.` functions to create your `objx.Map` to get going:
m, err := objx.FromJSON(json)
NOTE: Any methods or functions with the `Must` prefix will panic if something goes wrong, the rest will be optimistic and try to figure things out without panicking.
Use `Get` to access the value you're interested in. You can use dot and array
notation too:
m.Get("places[0].latlng")
Once you have sought the `Value` you're interested in, you can use the `Is*` methods to determine its type.
if m.Get("code").IsStr() { // Your code... }
Or you can just assume the type, and use one of the strong type methods to extract the real value:
m.Get("code").Int()
If there's no value there (or if it's the wrong type) then a default value will be returned, or you can be explicit about the default value.
Get("code").Int(-1)
If you're dealing with a slice of data as a value, Objx provides many useful methods for iterating, manipulating and selecting that data. You can find out more by exploring the index below.
### Reading data
A simple example of how to use Objx:
// Use MustFromJSON to make an objx.Map from some JSON
m := objx.MustFromJSON(`{"name": "Mat", "age": 30}`)
// Get the details
name := m.Get("name").Str()
age := m.Get("age").Int()
// Get their nickname (or use their name if they don't have one)
nickname := m.Get("nickname").Str(name)
### Ranging
Since `objx.Map` is a `map[string]interface{}` you can treat it as such. For example, to `range` the data, do what you would expect:
m := objx.MustFromJSON(json)
for key, value := range m {
// Your code...
}
## Installation
To install Objx, use go get:
go get github.com/stretchr/objx
### Staying up to date
To update Objx to the latest version, run:
go get -u github.com/stretchr/objx
### Supported go versions
We support the lastest two major Go versions, which are 1.8 and 1.9 at the moment.
## Contributing
Please feel free to submit issues, fork the repository and send pull requests!

32
vendor/github.com/stretchr/objx/Taskfile.yml generated vendored Normal file
View File

@@ -0,0 +1,32 @@
default:
deps: [test]
dl-deps:
desc: Downloads cli dependencies
cmds:
- go get -u github.com/golang/lint/golint
- go get -u github.com/golang/dep/cmd/dep
update-deps:
desc: Updates dependencies
cmds:
- dep ensure
- dep ensure -update
lint:
desc: Runs golint
cmds:
- go fmt $(go list ./... | grep -v /vendor/)
- go vet $(go list ./... | grep -v /vendor/)
- golint $(ls *.go | grep -v "doc.go")
silent: true
test:
desc: Runs go tests
cmds:
- go test -race .
test-coverage:
desc: Runs go tests and calucates test coverage
cmds:
- go test -coverprofile=c.out .

148
vendor/github.com/stretchr/objx/accessors.go generated vendored Normal file
View File

@@ -0,0 +1,148 @@
package objx
import (
"regexp"
"strconv"
"strings"
)
// arrayAccesRegexString is the regex used to extract the array number
// from the access path
const arrayAccesRegexString = `^(.+)\[([0-9]+)\]$`
// arrayAccesRegex is the compiled arrayAccesRegexString
var arrayAccesRegex = regexp.MustCompile(arrayAccesRegexString)
// Get gets the value using the specified selector and
// returns it inside a new Obj object.
//
// If it cannot find the value, Get will return a nil
// value inside an instance of Obj.
//
// Get can only operate directly on map[string]interface{} and []interface.
//
// Example
//
// To access the title of the third chapter of the second book, do:
//
// o.Get("books[1].chapters[2].title")
func (m Map) Get(selector string) *Value {
rawObj := access(m, selector, nil, false)
return &Value{data: rawObj}
}
// Set sets the value using the specified selector and
// returns the object on which Set was called.
//
// Set can only operate directly on map[string]interface{} and []interface
//
// Example
//
// To set the title of the third chapter of the second book, do:
//
// o.Set("books[1].chapters[2].title","Time to Go")
func (m Map) Set(selector string, value interface{}) Map {
access(m, selector, value, true)
return m
}
// access accesses the object using the selector and performs the
// appropriate action.
func access(current, selector, value interface{}, isSet bool) interface{} {
switch selector.(type) {
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
if array, ok := current.([]interface{}); ok {
index := intFromInterface(selector)
if index >= len(array) {
return nil
}
return array[index]
}
return nil
case string:
selStr := selector.(string)
selSegs := strings.SplitN(selStr, PathSeparator, 2)
thisSel := selSegs[0]
index := -1
var err error
if strings.Contains(thisSel, "[") {
arrayMatches := arrayAccesRegex.FindStringSubmatch(thisSel)
if len(arrayMatches) > 0 {
// Get the key into the map
thisSel = arrayMatches[1]
// Get the index into the array at the key
index, err = strconv.Atoi(arrayMatches[2])
if err != nil {
// This should never happen. If it does, something has gone
// seriously wrong. Panic.
panic("objx: Array index is not an integer. Must use array[int].")
}
}
}
if curMap, ok := current.(Map); ok {
current = map[string]interface{}(curMap)
}
// get the object in question
switch current.(type) {
case map[string]interface{}:
curMSI := current.(map[string]interface{})
if len(selSegs) <= 1 && isSet {
curMSI[thisSel] = value
return nil
}
current = curMSI[thisSel]
default:
current = nil
}
// do we need to access the item of an array?
if index > -1 {
if array, ok := current.([]interface{}); ok {
if index < len(array) {
current = array[index]
} else {
current = nil
}
}
}
if len(selSegs) > 1 {
current = access(current, selSegs[1], value, isSet)
}
}
return current
}
// intFromInterface converts an interface object to the largest
// representation of an unsigned integer using a type switch and
// assertions
func intFromInterface(selector interface{}) int {
var value int
switch selector.(type) {
case int:
value = selector.(int)
case int8:
value = int(selector.(int8))
case int16:
value = int(selector.(int16))
case int32:
value = int(selector.(int32))
case int64:
value = int(selector.(int64))
case uint:
value = int(selector.(uint))
case uint8:
value = int(selector.(uint8))
case uint16:
value = int(selector.(uint16))
case uint32:
value = int(selector.(uint32))
case uint64:
value = int(selector.(uint64))
default:
return 0
}
return value
}

13
vendor/github.com/stretchr/objx/constants.go generated vendored Normal file
View File

@@ -0,0 +1,13 @@
package objx
const (
// PathSeparator is the character used to separate the elements
// of the keypath.
//
// For example, `location.address.city`
PathSeparator string = "."
// SignatureSeparator is the character that is used to
// separate the Base64 string from the security signature.
SignatureSeparator = "_"
)

108
vendor/github.com/stretchr/objx/conversions.go generated vendored Normal file
View File

@@ -0,0 +1,108 @@
package objx
import (
"bytes"
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"net/url"
)
// JSON converts the contained object to a JSON string
// representation
func (m Map) JSON() (string, error) {
result, err := json.Marshal(m)
if err != nil {
err = errors.New("objx: JSON encode failed with: " + err.Error())
}
return string(result), err
}
// MustJSON converts the contained object to a JSON string
// representation and panics if there is an error
func (m Map) MustJSON() string {
result, err := m.JSON()
if err != nil {
panic(err.Error())
}
return result
}
// Base64 converts the contained object to a Base64 string
// representation of the JSON string representation
func (m Map) Base64() (string, error) {
var buf bytes.Buffer
jsonData, err := m.JSON()
if err != nil {
return "", err
}
encoder := base64.NewEncoder(base64.StdEncoding, &buf)
_, err = encoder.Write([]byte(jsonData))
if err != nil {
return "", err
}
_ = encoder.Close()
return buf.String(), nil
}
// MustBase64 converts the contained object to a Base64 string
// representation of the JSON string representation and panics
// if there is an error
func (m Map) MustBase64() string {
result, err := m.Base64()
if err != nil {
panic(err.Error())
}
return result
}
// SignedBase64 converts the contained object to a Base64 string
// representation of the JSON string representation and signs it
// using the provided key.
func (m Map) SignedBase64(key string) (string, error) {
base64, err := m.Base64()
if err != nil {
return "", err
}
sig := HashWithKey(base64, key)
return base64 + SignatureSeparator + sig, nil
}
// MustSignedBase64 converts the contained object to a Base64 string
// representation of the JSON string representation and signs it
// using the provided key and panics if there is an error
func (m Map) MustSignedBase64(key string) string {
result, err := m.SignedBase64(key)
if err != nil {
panic(err.Error())
}
return result
}
/*
URL Query
------------------------------------------------
*/
// URLValues creates a url.Values object from an Obj. This
// function requires that the wrapped object be a map[string]interface{}
func (m Map) URLValues() url.Values {
vals := make(url.Values)
for k, v := range m {
//TODO: can this be done without sprintf?
vals.Set(k, fmt.Sprintf("%v", v))
}
return vals
}
// URLQuery gets an encoded URL query representing the given
// Obj. This function requires that the wrapped object be a
// map[string]interface{}
func (m Map) URLQuery() (string, error) {
return m.URLValues().Encode(), nil
}

66
vendor/github.com/stretchr/objx/doc.go generated vendored Normal file
View File

@@ -0,0 +1,66 @@
/*
Objx - Go package for dealing with maps, slices, JSON and other data.
Overview
Objx provides the `objx.Map` type, which is a `map[string]interface{}` that exposes
a powerful `Get` method (among others) that allows you to easily and quickly get
access to data within the map, without having to worry too much about type assertions,
missing data, default values etc.
Pattern
Objx uses a preditable pattern to make access data from within `map[string]interface{}` easy.
Call one of the `objx.` functions to create your `objx.Map` to get going:
m, err := objx.FromJSON(json)
NOTE: Any methods or functions with the `Must` prefix will panic if something goes wrong,
the rest will be optimistic and try to figure things out without panicking.
Use `Get` to access the value you're interested in. You can use dot and array
notation too:
m.Get("places[0].latlng")
Once you have sought the `Value` you're interested in, you can use the `Is*` methods to determine its type.
if m.Get("code").IsStr() { // Your code... }
Or you can just assume the type, and use one of the strong type methods to extract the real value:
m.Get("code").Int()
If there's no value there (or if it's the wrong type) then a default value will be returned,
or you can be explicit about the default value.
Get("code").Int(-1)
If you're dealing with a slice of data as a value, Objx provides many useful methods for iterating,
manipulating and selecting that data. You can find out more by exploring the index below.
Reading data
A simple example of how to use Objx:
// Use MustFromJSON to make an objx.Map from some JSON
m := objx.MustFromJSON(`{"name": "Mat", "age": 30}`)
// Get the details
name := m.Get("name").Str()
age := m.Get("age").Int()
// Get their nickname (or use their name if they don't have one)
nickname := m.Get("nickname").Str(name)
Ranging
Since `objx.Map` is a `map[string]interface{}` you can treat it as such.
For example, to `range` the data, do what you would expect:
m := objx.MustFromJSON(json)
for key, value := range m {
// Your code...
}
*/
package objx

190
vendor/github.com/stretchr/objx/map.go generated vendored Normal file
View File

@@ -0,0 +1,190 @@
package objx
import (
"encoding/base64"
"encoding/json"
"errors"
"io/ioutil"
"net/url"
"strings"
)
// MSIConvertable is an interface that defines methods for converting your
// custom types to a map[string]interface{} representation.
type MSIConvertable interface {
// MSI gets a map[string]interface{} (msi) representing the
// object.
MSI() map[string]interface{}
}
// Map provides extended functionality for working with
// untyped data, in particular map[string]interface (msi).
type Map map[string]interface{}
// Value returns the internal value instance
func (m Map) Value() *Value {
return &Value{data: m}
}
// Nil represents a nil Map.
var Nil = New(nil)
// New creates a new Map containing the map[string]interface{} in the data argument.
// If the data argument is not a map[string]interface, New attempts to call the
// MSI() method on the MSIConvertable interface to create one.
func New(data interface{}) Map {
if _, ok := data.(map[string]interface{}); !ok {
if converter, ok := data.(MSIConvertable); ok {
data = converter.MSI()
} else {
return nil
}
}
return Map(data.(map[string]interface{}))
}
// MSI creates a map[string]interface{} and puts it inside a new Map.
//
// The arguments follow a key, value pattern.
//
//
// Returns nil if any key argument is non-string or if there are an odd number of arguments.
//
// Example
//
// To easily create Maps:
//
// m := objx.MSI("name", "Mat", "age", 29, "subobj", objx.MSI("active", true))
//
// // creates an Map equivalent to
// m := objx.Map{"name": "Mat", "age": 29, "subobj": objx.Map{"active": true}}
func MSI(keyAndValuePairs ...interface{}) Map {
newMap := Map{}
keyAndValuePairsLen := len(keyAndValuePairs)
if keyAndValuePairsLen%2 != 0 {
return nil
}
for i := 0; i < keyAndValuePairsLen; i = i + 2 {
key := keyAndValuePairs[i]
value := keyAndValuePairs[i+1]
// make sure the key is a string
keyString, keyStringOK := key.(string)
if !keyStringOK {
return nil
}
newMap[keyString] = value
}
return newMap
}
// ****** Conversion Constructors
// MustFromJSON creates a new Map containing the data specified in the
// jsonString.
//
// Panics if the JSON is invalid.
func MustFromJSON(jsonString string) Map {
o, err := FromJSON(jsonString)
if err != nil {
panic("objx: MustFromJSON failed with error: " + err.Error())
}
return o
}
// FromJSON creates a new Map containing the data specified in the
// jsonString.
//
// Returns an error if the JSON is invalid.
func FromJSON(jsonString string) (Map, error) {
var data interface{}
err := json.Unmarshal([]byte(jsonString), &data)
if err != nil {
return Nil, err
}
return New(data), nil
}
// FromBase64 creates a new Obj containing the data specified
// in the Base64 string.
//
// The string is an encoded JSON string returned by Base64
func FromBase64(base64String string) (Map, error) {
decoder := base64.NewDecoder(base64.StdEncoding, strings.NewReader(base64String))
decoded, err := ioutil.ReadAll(decoder)
if err != nil {
return nil, err
}
return FromJSON(string(decoded))
}
// MustFromBase64 creates a new Obj containing the data specified
// in the Base64 string and panics if there is an error.
//
// The string is an encoded JSON string returned by Base64
func MustFromBase64(base64String string) Map {
result, err := FromBase64(base64String)
if err != nil {
panic("objx: MustFromBase64 failed with error: " + err.Error())
}
return result
}
// FromSignedBase64 creates a new Obj containing the data specified
// in the Base64 string.
//
// The string is an encoded JSON string returned by SignedBase64
func FromSignedBase64(base64String, key string) (Map, error) {
parts := strings.Split(base64String, SignatureSeparator)
if len(parts) != 2 {
return nil, errors.New("objx: Signed base64 string is malformed")
}
sig := HashWithKey(parts[0], key)
if parts[1] != sig {
return nil, errors.New("objx: Signature for base64 data does not match")
}
return FromBase64(parts[0])
}
// MustFromSignedBase64 creates a new Obj containing the data specified
// in the Base64 string and panics if there is an error.
//
// The string is an encoded JSON string returned by Base64
func MustFromSignedBase64(base64String, key string) Map {
result, err := FromSignedBase64(base64String, key)
if err != nil {
panic("objx: MustFromSignedBase64 failed with error: " + err.Error())
}
return result
}
// FromURLQuery generates a new Obj by parsing the specified
// query.
//
// For queries with multiple values, the first value is selected.
func FromURLQuery(query string) (Map, error) {
vals, err := url.ParseQuery(query)
if err != nil {
return nil, err
}
m := Map{}
for k, vals := range vals {
m[k] = vals[0]
}
return m, nil
}
// MustFromURLQuery generates a new Obj by parsing the specified
// query.
//
// For queries with multiple values, the first value is selected.
//
// Panics if it encounters an error
func MustFromURLQuery(query string) Map {
o, err := FromURLQuery(query)
if err != nil {
panic("objx: MustFromURLQuery failed with error: " + err.Error())
}
return o
}

77
vendor/github.com/stretchr/objx/mutations.go generated vendored Normal file
View File

@@ -0,0 +1,77 @@
package objx
// Exclude returns a new Map with the keys in the specified []string
// excluded.
func (m Map) Exclude(exclude []string) Map {
excluded := make(Map)
for k, v := range m {
if !contains(exclude, k) {
excluded[k] = v
}
}
return excluded
}
// Copy creates a shallow copy of the Obj.
func (m Map) Copy() Map {
copied := Map{}
for k, v := range m {
copied[k] = v
}
return copied
}
// Merge blends the specified map with a copy of this map and returns the result.
//
// Keys that appear in both will be selected from the specified map.
// This method requires that the wrapped object be a map[string]interface{}
func (m Map) Merge(merge Map) Map {
return m.Copy().MergeHere(merge)
}
// MergeHere blends the specified map with this map and returns the current map.
//
// Keys that appear in both will be selected from the specified map. The original map
// will be modified. This method requires that
// the wrapped object be a map[string]interface{}
func (m Map) MergeHere(merge Map) Map {
for k, v := range merge {
m[k] = v
}
return m
}
// Transform builds a new Obj giving the transformer a chance
// to change the keys and values as it goes. This method requires that
// the wrapped object be a map[string]interface{}
func (m Map) Transform(transformer func(key string, value interface{}) (string, interface{})) Map {
newMap := Map{}
for k, v := range m {
modifiedKey, modifiedVal := transformer(k, v)
newMap[modifiedKey] = modifiedVal
}
return newMap
}
// TransformKeys builds a new map using the specified key mapping.
//
// Unspecified keys will be unaltered.
// This method requires that the wrapped object be a map[string]interface{}
func (m Map) TransformKeys(mapping map[string]string) Map {
return m.Transform(func(key string, value interface{}) (string, interface{}) {
if newKey, ok := mapping[key]; ok {
return newKey, value
}
return key, value
})
}
// Checks if a string slice contains a string
func contains(s []string, e string) bool {
for _, a := range s {
if a == e {
return true
}
}
return false
}

12
vendor/github.com/stretchr/objx/security.go generated vendored Normal file
View File

@@ -0,0 +1,12 @@
package objx
import (
"crypto/sha1"
"encoding/hex"
)
// HashWithKey hashes the specified string using the security key
func HashWithKey(data, key string) string {
d := sha1.Sum([]byte(data + ":" + key))
return hex.EncodeToString(d[:])
}

17
vendor/github.com/stretchr/objx/tests.go generated vendored Normal file
View File

@@ -0,0 +1,17 @@
package objx
// Has gets whether there is something at the specified selector
// or not.
//
// If m is nil, Has will always return false.
func (m Map) Has(selector string) bool {
if m == nil {
return false
}
return !m.Get(selector).IsNil()
}
// IsNil gets whether the data is nil or not.
func (v *Value) IsNil() bool {
return v == nil || v.data == nil
}

2501
vendor/github.com/stretchr/objx/type_specific_codegen.go generated vendored Normal file

File diff suppressed because it is too large Load Diff

53
vendor/github.com/stretchr/objx/value.go generated vendored Normal file
View File

@@ -0,0 +1,53 @@
package objx
import (
"fmt"
"strconv"
)
// Value provides methods for extracting interface{} data in various
// types.
type Value struct {
// data contains the raw data being managed by this Value
data interface{}
}
// Data returns the raw data contained by this Value
func (v *Value) Data() interface{} {
return v.data
}
// String returns the value always as a string
func (v *Value) String() string {
switch {
case v.IsStr():
return v.Str()
case v.IsBool():
return strconv.FormatBool(v.Bool())
case v.IsFloat32():
return strconv.FormatFloat(float64(v.Float32()), 'f', -1, 32)
case v.IsFloat64():
return strconv.FormatFloat(v.Float64(), 'f', -1, 64)
case v.IsInt():
return strconv.FormatInt(int64(v.Int()), 10)
case v.IsInt8():
return strconv.FormatInt(int64(v.Int8()), 10)
case v.IsInt16():
return strconv.FormatInt(int64(v.Int16()), 10)
case v.IsInt32():
return strconv.FormatInt(int64(v.Int32()), 10)
case v.IsInt64():
return strconv.FormatInt(v.Int64(), 10)
case v.IsUint():
return strconv.FormatUint(uint64(v.Uint()), 10)
case v.IsUint8():
return strconv.FormatUint(uint64(v.Uint8()), 10)
case v.IsUint16():
return strconv.FormatUint(uint64(v.Uint16()), 10)
case v.IsUint32():
return strconv.FormatUint(uint64(v.Uint32()), 10)
case v.IsUint64():
return strconv.FormatUint(v.Uint64(), 10)
}
return fmt.Sprintf("%#v", v.Data())
}

44
vendor/github.com/stretchr/testify/mock/doc.go generated vendored Normal file
View File

@@ -0,0 +1,44 @@
// Package mock provides a system by which it is possible to mock your objects
// and verify calls are happening as expected.
//
// Example Usage
//
// The mock package provides an object, Mock, that tracks activity on another object. It is usually
// embedded into a test object as shown below:
//
// type MyTestObject struct {
// // add a Mock object instance
// mock.Mock
//
// // other fields go here as normal
// }
//
// When implementing the methods of an interface, you wire your functions up
// to call the Mock.Called(args...) method, and return the appropriate values.
//
// For example, to mock a method that saves the name and age of a person and returns
// the year of their birth or an error, you might write this:
//
// func (o *MyTestObject) SavePersonDetails(firstname, lastname string, age int) (int, error) {
// args := o.Called(firstname, lastname, age)
// return args.Int(0), args.Error(1)
// }
//
// The Int, Error and Bool methods are examples of strongly typed getters that take the argument
// index position. Given this argument list:
//
// (12, true, "Something")
//
// You could read them out strongly typed like this:
//
// args.Int(0)
// args.Bool(1)
// args.String(2)
//
// For objects of your own type, use the generic Arguments.Get(index) method and make a type assertion:
//
// return args.Get(0).(*MyObject), args.Get(1).(*AnotherObjectOfMine)
//
// This may cause a panic if the object you are getting is nil (the type assertion will fail), in those
// cases you should check for nil first.
package mock

917
vendor/github.com/stretchr/testify/mock/mock.go generated vendored Normal file
View File

@@ -0,0 +1,917 @@
package mock
import (
"errors"
"fmt"
"reflect"
"regexp"
"runtime"
"strings"
"sync"
"time"
"github.com/davecgh/go-spew/spew"
"github.com/pmezard/go-difflib/difflib"
"github.com/stretchr/objx"
"github.com/stretchr/testify/assert"
)
// TestingT is an interface wrapper around *testing.T
type TestingT interface {
Logf(format string, args ...interface{})
Errorf(format string, args ...interface{})
FailNow()
}
/*
Call
*/
// Call represents a method call and is used for setting expectations,
// as well as recording activity.
type Call struct {
Parent *Mock
// The name of the method that was or will be called.
Method string
// Holds the arguments of the method.
Arguments Arguments
// Holds the arguments that should be returned when
// this method is called.
ReturnArguments Arguments
// Holds the caller info for the On() call
callerInfo []string
// The number of times to return the return arguments when setting
// expectations. 0 means to always return the value.
Repeatability int
// Amount of times this call has been called
totalCalls int
// Call to this method can be optional
optional bool
// Holds a channel that will be used to block the Return until it either
// receives a message or is closed. nil means it returns immediately.
WaitFor <-chan time.Time
waitTime time.Duration
// Holds a handler used to manipulate arguments content that are passed by
// reference. It's useful when mocking methods such as unmarshalers or
// decoders.
RunFn func(Arguments)
}
func newCall(parent *Mock, methodName string, callerInfo []string, methodArguments ...interface{}) *Call {
return &Call{
Parent: parent,
Method: methodName,
Arguments: methodArguments,
ReturnArguments: make([]interface{}, 0),
callerInfo: callerInfo,
Repeatability: 0,
WaitFor: nil,
RunFn: nil,
}
}
func (c *Call) lock() {
c.Parent.mutex.Lock()
}
func (c *Call) unlock() {
c.Parent.mutex.Unlock()
}
// Return specifies the return arguments for the expectation.
//
// Mock.On("DoSomething").Return(errors.New("failed"))
func (c *Call) Return(returnArguments ...interface{}) *Call {
c.lock()
defer c.unlock()
c.ReturnArguments = returnArguments
return c
}
// Once indicates that that the mock should only return the value once.
//
// Mock.On("MyMethod", arg1, arg2).Return(returnArg1, returnArg2).Once()
func (c *Call) Once() *Call {
return c.Times(1)
}
// Twice indicates that that the mock should only return the value twice.
//
// Mock.On("MyMethod", arg1, arg2).Return(returnArg1, returnArg2).Twice()
func (c *Call) Twice() *Call {
return c.Times(2)
}
// Times indicates that that the mock should only return the indicated number
// of times.
//
// Mock.On("MyMethod", arg1, arg2).Return(returnArg1, returnArg2).Times(5)
func (c *Call) Times(i int) *Call {
c.lock()
defer c.unlock()
c.Repeatability = i
return c
}
// WaitUntil sets the channel that will block the mock's return until its closed
// or a message is received.
//
// Mock.On("MyMethod", arg1, arg2).WaitUntil(time.After(time.Second))
func (c *Call) WaitUntil(w <-chan time.Time) *Call {
c.lock()
defer c.unlock()
c.WaitFor = w
return c
}
// After sets how long to block until the call returns
//
// Mock.On("MyMethod", arg1, arg2).After(time.Second)
func (c *Call) After(d time.Duration) *Call {
c.lock()
defer c.unlock()
c.waitTime = d
return c
}
// Run sets a handler to be called before returning. It can be used when
// mocking a method (such as an unmarshaler) that takes a pointer to a struct and
// sets properties in such struct
//
// Mock.On("Unmarshal", AnythingOfType("*map[string]interface{}").Return().Run(func(args Arguments) {
// arg := args.Get(0).(*map[string]interface{})
// arg["foo"] = "bar"
// })
func (c *Call) Run(fn func(args Arguments)) *Call {
c.lock()
defer c.unlock()
c.RunFn = fn
return c
}
// Maybe allows the method call to be optional. Not calling an optional method
// will not cause an error while asserting expectations
func (c *Call) Maybe() *Call {
c.lock()
defer c.unlock()
c.optional = true
return c
}
// On chains a new expectation description onto the mocked interface. This
// allows syntax like.
//
// Mock.
// On("MyMethod", 1).Return(nil).
// On("MyOtherMethod", 'a', 'b', 'c').Return(errors.New("Some Error"))
//go:noinline
func (c *Call) On(methodName string, arguments ...interface{}) *Call {
return c.Parent.On(methodName, arguments...)
}
// Mock is the workhorse used to track activity on another object.
// For an example of its usage, refer to the "Example Usage" section at the top
// of this document.
type Mock struct {
// Represents the calls that are expected of
// an object.
ExpectedCalls []*Call
// Holds the calls that were made to this mocked object.
Calls []Call
// test is An optional variable that holds the test struct, to be used when an
// invalid mock call was made.
test TestingT
// TestData holds any data that might be useful for testing. Testify ignores
// this data completely allowing you to do whatever you like with it.
testData objx.Map
mutex sync.Mutex
}
// TestData holds any data that might be useful for testing. Testify ignores
// this data completely allowing you to do whatever you like with it.
func (m *Mock) TestData() objx.Map {
if m.testData == nil {
m.testData = make(objx.Map)
}
return m.testData
}
/*
Setting expectations
*/
// Test sets the test struct variable of the mock object
func (m *Mock) Test(t TestingT) {
m.mutex.Lock()
defer m.mutex.Unlock()
m.test = t
}
// fail fails the current test with the given formatted format and args.
// In case that a test was defined, it uses the test APIs for failing a test,
// otherwise it uses panic.
func (m *Mock) fail(format string, args ...interface{}) {
m.mutex.Lock()
defer m.mutex.Unlock()
if m.test == nil {
panic(fmt.Sprintf(format, args...))
}
m.test.Errorf(format, args...)
m.test.FailNow()
}
// On starts a description of an expectation of the specified method
// being called.
//
// Mock.On("MyMethod", arg1, arg2)
func (m *Mock) On(methodName string, arguments ...interface{}) *Call {
for _, arg := range arguments {
if v := reflect.ValueOf(arg); v.Kind() == reflect.Func {
panic(fmt.Sprintf("cannot use Func in expectations. Use mock.AnythingOfType(\"%T\")", arg))
}
}
m.mutex.Lock()
defer m.mutex.Unlock()
c := newCall(m, methodName, assert.CallerInfo(), arguments...)
m.ExpectedCalls = append(m.ExpectedCalls, c)
return c
}
// /*
// Recording and responding to activity
// */
func (m *Mock) findExpectedCall(method string, arguments ...interface{}) (int, *Call) {
var expectedCall *Call
for i, call := range m.ExpectedCalls {
if call.Method == method {
_, diffCount := call.Arguments.Diff(arguments)
if diffCount == 0 {
expectedCall = call
if call.Repeatability > -1 {
return i, call
}
}
}
}
return -1, expectedCall
}
func (m *Mock) findClosestCall(method string, arguments ...interface{}) (*Call, string) {
var diffCount int
var closestCall *Call
var err string
for _, call := range m.expectedCalls() {
if call.Method == method {
errInfo, tempDiffCount := call.Arguments.Diff(arguments)
if tempDiffCount < diffCount || diffCount == 0 {
diffCount = tempDiffCount
closestCall = call
err = errInfo
}
}
}
return closestCall, err
}
func callString(method string, arguments Arguments, includeArgumentValues bool) string {
var argValsString string
if includeArgumentValues {
var argVals []string
for argIndex, arg := range arguments {
argVals = append(argVals, fmt.Sprintf("%d: %#v", argIndex, arg))
}
argValsString = fmt.Sprintf("\n\t\t%s", strings.Join(argVals, "\n\t\t"))
}
return fmt.Sprintf("%s(%s)%s", method, arguments.String(), argValsString)
}
// Called tells the mock object that a method has been called, and gets an array
// of arguments to return. Panics if the call is unexpected (i.e. not preceded by
// appropriate .On .Return() calls)
// If Call.WaitFor is set, blocks until the channel is closed or receives a message.
func (m *Mock) Called(arguments ...interface{}) Arguments {
// get the calling function's name
pc, _, _, ok := runtime.Caller(1)
if !ok {
panic("Couldn't get the caller information")
}
functionPath := runtime.FuncForPC(pc).Name()
//Next four lines are required to use GCCGO function naming conventions.
//For Ex: github_com_docker_libkv_store_mock.WatchTree.pN39_github_com_docker_libkv_store_mock.Mock
//uses interface information unlike golang github.com/docker/libkv/store/mock.(*Mock).WatchTree
//With GCCGO we need to remove interface information starting from pN<dd>.
re := regexp.MustCompile("\\.pN\\d+_")
if re.MatchString(functionPath) {
functionPath = re.Split(functionPath, -1)[0]
}
parts := strings.Split(functionPath, ".")
functionName := parts[len(parts)-1]
return m.MethodCalled(functionName, arguments...)
}
// MethodCalled tells the mock object that the given method has been called, and gets
// an array of arguments to return. Panics if the call is unexpected (i.e. not preceded
// by appropriate .On .Return() calls)
// If Call.WaitFor is set, blocks until the channel is closed or receives a message.
func (m *Mock) MethodCalled(methodName string, arguments ...interface{}) Arguments {
m.mutex.Lock()
//TODO: could combine expected and closes in single loop
found, call := m.findExpectedCall(methodName, arguments...)
if found < 0 {
// expected call found but it has already been called with repeatable times
if call != nil {
m.mutex.Unlock()
m.fail("\nassert: mock: The method has been called over %d times.\n\tEither do one more Mock.On(\"%s\").Return(...), or remove extra call.\n\tThis call was unexpected:\n\t\t%s\n\tat: %s", call.totalCalls, methodName, callString(methodName, arguments, true), assert.CallerInfo())
}
// we have to fail here - because we don't know what to do
// as the return arguments. This is because:
//
// a) this is a totally unexpected call to this method,
// b) the arguments are not what was expected, or
// c) the developer has forgotten to add an accompanying On...Return pair.
closestCall, mismatch := m.findClosestCall(methodName, arguments...)
m.mutex.Unlock()
if closestCall != nil {
m.fail("\n\nmock: Unexpected Method Call\n-----------------------------\n\n%s\n\nThe closest call I have is: \n\n%s\n\n%s\nDiff: %s",
callString(methodName, arguments, true),
callString(methodName, closestCall.Arguments, true),
diffArguments(closestCall.Arguments, arguments),
strings.TrimSpace(mismatch),
)
} else {
m.fail("\nassert: mock: I don't know what to return because the method call was unexpected.\n\tEither do Mock.On(\"%s\").Return(...) first, or remove the %s() call.\n\tThis method was unexpected:\n\t\t%s\n\tat: %s", methodName, methodName, callString(methodName, arguments, true), assert.CallerInfo())
}
}
if call.Repeatability == 1 {
call.Repeatability = -1
} else if call.Repeatability > 1 {
call.Repeatability--
}
call.totalCalls++
// add the call
m.Calls = append(m.Calls, *newCall(m, methodName, assert.CallerInfo(), arguments...))
m.mutex.Unlock()
// block if specified
if call.WaitFor != nil {
<-call.WaitFor
} else {
time.Sleep(call.waitTime)
}
m.mutex.Lock()
runFn := call.RunFn
m.mutex.Unlock()
if runFn != nil {
runFn(arguments)
}
m.mutex.Lock()
returnArgs := call.ReturnArguments
m.mutex.Unlock()
return returnArgs
}
/*
Assertions
*/
type assertExpectationser interface {
AssertExpectations(TestingT) bool
}
// AssertExpectationsForObjects asserts that everything specified with On and Return
// of the specified objects was in fact called as expected.
//
// Calls may have occurred in any order.
func AssertExpectationsForObjects(t TestingT, testObjects ...interface{}) bool {
if h, ok := t.(tHelper); ok {
h.Helper()
}
for _, obj := range testObjects {
if m, ok := obj.(Mock); ok {
t.Logf("Deprecated mock.AssertExpectationsForObjects(myMock.Mock) use mock.AssertExpectationsForObjects(myMock)")
obj = &m
}
m := obj.(assertExpectationser)
if !m.AssertExpectations(t) {
t.Logf("Expectations didn't match for Mock: %+v", reflect.TypeOf(m))
return false
}
}
return true
}
// AssertExpectations asserts that everything specified with On and Return was
// in fact called as expected. Calls may have occurred in any order.
func (m *Mock) AssertExpectations(t TestingT) bool {
if h, ok := t.(tHelper); ok {
h.Helper()
}
m.mutex.Lock()
defer m.mutex.Unlock()
var somethingMissing bool
var failedExpectations int
// iterate through each expectation
expectedCalls := m.expectedCalls()
for _, expectedCall := range expectedCalls {
if !expectedCall.optional && !m.methodWasCalled(expectedCall.Method, expectedCall.Arguments) && expectedCall.totalCalls == 0 {
somethingMissing = true
failedExpectations++
t.Logf("FAIL:\t%s(%s)\n\t\tat: %s", expectedCall.Method, expectedCall.Arguments.String(), expectedCall.callerInfo)
} else {
if expectedCall.Repeatability > 0 {
somethingMissing = true
failedExpectations++
t.Logf("FAIL:\t%s(%s)\n\t\tat: %s", expectedCall.Method, expectedCall.Arguments.String(), expectedCall.callerInfo)
} else {
t.Logf("PASS:\t%s(%s)", expectedCall.Method, expectedCall.Arguments.String())
}
}
}
if somethingMissing {
t.Errorf("FAIL: %d out of %d expectation(s) were met.\n\tThe code you are testing needs to make %d more call(s).\n\tat: %s", len(expectedCalls)-failedExpectations, len(expectedCalls), failedExpectations, assert.CallerInfo())
}
return !somethingMissing
}
// AssertNumberOfCalls asserts that the method was called expectedCalls times.
func (m *Mock) AssertNumberOfCalls(t TestingT, methodName string, expectedCalls int) bool {
if h, ok := t.(tHelper); ok {
h.Helper()
}
m.mutex.Lock()
defer m.mutex.Unlock()
var actualCalls int
for _, call := range m.calls() {
if call.Method == methodName {
actualCalls++
}
}
return assert.Equal(t, expectedCalls, actualCalls, fmt.Sprintf("Expected number of calls (%d) does not match the actual number of calls (%d).", expectedCalls, actualCalls))
}
// AssertCalled asserts that the method was called.
// It can produce a false result when an argument is a pointer type and the underlying value changed after calling the mocked method.
func (m *Mock) AssertCalled(t TestingT, methodName string, arguments ...interface{}) bool {
if h, ok := t.(tHelper); ok {
h.Helper()
}
m.mutex.Lock()
defer m.mutex.Unlock()
if !m.methodWasCalled(methodName, arguments) {
var calledWithArgs []string
for _, call := range m.calls() {
calledWithArgs = append(calledWithArgs, fmt.Sprintf("%v", call.Arguments))
}
if len(calledWithArgs) == 0 {
return assert.Fail(t, "Should have called with given arguments",
fmt.Sprintf("Expected %q to have been called with:\n%v\nbut no actual calls happened", methodName, arguments))
}
return assert.Fail(t, "Should have called with given arguments",
fmt.Sprintf("Expected %q to have been called with:\n%v\nbut actual calls were:\n %v", methodName, arguments, strings.Join(calledWithArgs, "\n")))
}
return true
}
// AssertNotCalled asserts that the method was not called.
// It can produce a false result when an argument is a pointer type and the underlying value changed after calling the mocked method.
func (m *Mock) AssertNotCalled(t TestingT, methodName string, arguments ...interface{}) bool {
if h, ok := t.(tHelper); ok {
h.Helper()
}
m.mutex.Lock()
defer m.mutex.Unlock()
if m.methodWasCalled(methodName, arguments) {
return assert.Fail(t, "Should not have called with given arguments",
fmt.Sprintf("Expected %q to not have been called with:\n%v\nbut actually it was.", methodName, arguments))
}
return true
}
func (m *Mock) methodWasCalled(methodName string, expected []interface{}) bool {
for _, call := range m.calls() {
if call.Method == methodName {
_, differences := Arguments(expected).Diff(call.Arguments)
if differences == 0 {
// found the expected call
return true
}
}
}
// we didn't find the expected call
return false
}
func (m *Mock) expectedCalls() []*Call {
return append([]*Call{}, m.ExpectedCalls...)
}
func (m *Mock) calls() []Call {
return append([]Call{}, m.Calls...)
}
/*
Arguments
*/
// Arguments holds an array of method arguments or return values.
type Arguments []interface{}
const (
// Anything is used in Diff and Assert when the argument being tested
// shouldn't be taken into consideration.
Anything = "mock.Anything"
)
// AnythingOfTypeArgument is a string that contains the type of an argument
// for use when type checking. Used in Diff and Assert.
type AnythingOfTypeArgument string
// AnythingOfType returns an AnythingOfTypeArgument object containing the
// name of the type to check for. Used in Diff and Assert.
//
// For example:
// Assert(t, AnythingOfType("string"), AnythingOfType("int"))
func AnythingOfType(t string) AnythingOfTypeArgument {
return AnythingOfTypeArgument(t)
}
// IsTypeArgument is a struct that contains the type of an argument
// for use when type checking. This is an alternative to AnythingOfType.
// Used in Diff and Assert.
type IsTypeArgument struct {
t interface{}
}
// IsType returns an IsTypeArgument object containing the type to check for.
// You can provide a zero-value of the type to check. This is an
// alternative to AnythingOfType. Used in Diff and Assert.
//
// For example:
// Assert(t, IsType(""), IsType(0))
func IsType(t interface{}) *IsTypeArgument {
return &IsTypeArgument{t: t}
}
// argumentMatcher performs custom argument matching, returning whether or
// not the argument is matched by the expectation fixture function.
type argumentMatcher struct {
// fn is a function which accepts one argument, and returns a bool.
fn reflect.Value
}
func (f argumentMatcher) Matches(argument interface{}) bool {
expectType := f.fn.Type().In(0)
expectTypeNilSupported := false
switch expectType.Kind() {
case reflect.Interface, reflect.Chan, reflect.Func, reflect.Map, reflect.Slice, reflect.Ptr:
expectTypeNilSupported = true
}
argType := reflect.TypeOf(argument)
var arg reflect.Value
if argType == nil {
arg = reflect.New(expectType).Elem()
} else {
arg = reflect.ValueOf(argument)
}
if argType == nil && !expectTypeNilSupported {
panic(errors.New("attempting to call matcher with nil for non-nil expected type"))
}
if argType == nil || argType.AssignableTo(expectType) {
result := f.fn.Call([]reflect.Value{arg})
return result[0].Bool()
}
return false
}
func (f argumentMatcher) String() string {
return fmt.Sprintf("func(%s) bool", f.fn.Type().In(0).Name())
}
// MatchedBy can be used to match a mock call based on only certain properties
// from a complex struct or some calculation. It takes a function that will be
// evaluated with the called argument and will return true when there's a match
// and false otherwise.
//
// Example:
// m.On("Do", MatchedBy(func(req *http.Request) bool { return req.Host == "example.com" }))
//
// |fn|, must be a function accepting a single argument (of the expected type)
// which returns a bool. If |fn| doesn't match the required signature,
// MatchedBy() panics.
func MatchedBy(fn interface{}) argumentMatcher {
fnType := reflect.TypeOf(fn)
if fnType.Kind() != reflect.Func {
panic(fmt.Sprintf("assert: arguments: %s is not a func", fn))
}
if fnType.NumIn() != 1 {
panic(fmt.Sprintf("assert: arguments: %s does not take exactly one argument", fn))
}
if fnType.NumOut() != 1 || fnType.Out(0).Kind() != reflect.Bool {
panic(fmt.Sprintf("assert: arguments: %s does not return a bool", fn))
}
return argumentMatcher{fn: reflect.ValueOf(fn)}
}
// Get Returns the argument at the specified index.
func (args Arguments) Get(index int) interface{} {
if index+1 > len(args) {
panic(fmt.Sprintf("assert: arguments: Cannot call Get(%d) because there are %d argument(s).", index, len(args)))
}
return args[index]
}
// Is gets whether the objects match the arguments specified.
func (args Arguments) Is(objects ...interface{}) bool {
for i, obj := range args {
if obj != objects[i] {
return false
}
}
return true
}
// Diff gets a string describing the differences between the arguments
// and the specified objects.
//
// Returns the diff string and number of differences found.
func (args Arguments) Diff(objects []interface{}) (string, int) {
//TODO: could return string as error and nil for No difference
var output = "\n"
var differences int
var maxArgCount = len(args)
if len(objects) > maxArgCount {
maxArgCount = len(objects)
}
for i := 0; i < maxArgCount; i++ {
var actual, expected interface{}
var actualFmt, expectedFmt string
if len(objects) <= i {
actual = "(Missing)"
actualFmt = "(Missing)"
} else {
actual = objects[i]
actualFmt = fmt.Sprintf("(%[1]T=%[1]v)", actual)
}
if len(args) <= i {
expected = "(Missing)"
expectedFmt = "(Missing)"
} else {
expected = args[i]
expectedFmt = fmt.Sprintf("(%[1]T=%[1]v)", expected)
}
if matcher, ok := expected.(argumentMatcher); ok {
if matcher.Matches(actual) {
output = fmt.Sprintf("%s\t%d: PASS: %s matched by %s\n", output, i, actualFmt, matcher)
} else {
differences++
output = fmt.Sprintf("%s\t%d: FAIL: %s not matched by %s\n", output, i, actualFmt, matcher)
}
} else if reflect.TypeOf(expected) == reflect.TypeOf((*AnythingOfTypeArgument)(nil)).Elem() {
// type checking
if reflect.TypeOf(actual).Name() != string(expected.(AnythingOfTypeArgument)) && reflect.TypeOf(actual).String() != string(expected.(AnythingOfTypeArgument)) {
// not match
differences++
output = fmt.Sprintf("%s\t%d: FAIL: type %s != type %s - %s\n", output, i, expected, reflect.TypeOf(actual).Name(), actualFmt)
}
} else if reflect.TypeOf(expected) == reflect.TypeOf((*IsTypeArgument)(nil)) {
t := expected.(*IsTypeArgument).t
if reflect.TypeOf(t) != reflect.TypeOf(actual) {
differences++
output = fmt.Sprintf("%s\t%d: FAIL: type %s != type %s - %s\n", output, i, reflect.TypeOf(t).Name(), reflect.TypeOf(actual).Name(), actualFmt)
}
} else {
// normal checking
if assert.ObjectsAreEqual(expected, Anything) || assert.ObjectsAreEqual(actual, Anything) || assert.ObjectsAreEqual(actual, expected) {
// match
output = fmt.Sprintf("%s\t%d: PASS: %s == %s\n", output, i, actualFmt, expectedFmt)
} else {
// not match
differences++
output = fmt.Sprintf("%s\t%d: FAIL: %s != %s\n", output, i, actualFmt, expectedFmt)
}
}
}
if differences == 0 {
return "No differences.", differences
}
return output, differences
}
// Assert compares the arguments with the specified objects and fails if
// they do not exactly match.
func (args Arguments) Assert(t TestingT, objects ...interface{}) bool {
if h, ok := t.(tHelper); ok {
h.Helper()
}
// get the differences
diff, diffCount := args.Diff(objects)
if diffCount == 0 {
return true
}
// there are differences... report them...
t.Logf(diff)
t.Errorf("%sArguments do not match.", assert.CallerInfo())
return false
}
// String gets the argument at the specified index. Panics if there is no argument, or
// if the argument is of the wrong type.
//
// If no index is provided, String() returns a complete string representation
// of the arguments.
func (args Arguments) String(indexOrNil ...int) string {
if len(indexOrNil) == 0 {
// normal String() method - return a string representation of the args
var argsStr []string
for _, arg := range args {
argsStr = append(argsStr, fmt.Sprintf("%s", reflect.TypeOf(arg)))
}
return strings.Join(argsStr, ",")
} else if len(indexOrNil) == 1 {
// Index has been specified - get the argument at that index
var index = indexOrNil[0]
var s string
var ok bool
if s, ok = args.Get(index).(string); !ok {
panic(fmt.Sprintf("assert: arguments: String(%d) failed because object wasn't correct type: %s", index, args.Get(index)))
}
return s
}
panic(fmt.Sprintf("assert: arguments: Wrong number of arguments passed to String. Must be 0 or 1, not %d", len(indexOrNil)))
}
// Int gets the argument at the specified index. Panics if there is no argument, or
// if the argument is of the wrong type.
func (args Arguments) Int(index int) int {
var s int
var ok bool
if s, ok = args.Get(index).(int); !ok {
panic(fmt.Sprintf("assert: arguments: Int(%d) failed because object wasn't correct type: %v", index, args.Get(index)))
}
return s
}
// Error gets the argument at the specified index. Panics if there is no argument, or
// if the argument is of the wrong type.
func (args Arguments) Error(index int) error {
obj := args.Get(index)
var s error
var ok bool
if obj == nil {
return nil
}
if s, ok = obj.(error); !ok {
panic(fmt.Sprintf("assert: arguments: Error(%d) failed because object wasn't correct type: %v", index, args.Get(index)))
}
return s
}
// Bool gets the argument at the specified index. Panics if there is no argument, or
// if the argument is of the wrong type.
func (args Arguments) Bool(index int) bool {
var s bool
var ok bool
if s, ok = args.Get(index).(bool); !ok {
panic(fmt.Sprintf("assert: arguments: Bool(%d) failed because object wasn't correct type: %v", index, args.Get(index)))
}
return s
}
func typeAndKind(v interface{}) (reflect.Type, reflect.Kind) {
t := reflect.TypeOf(v)
k := t.Kind()
if k == reflect.Ptr {
t = t.Elem()
k = t.Kind()
}
return t, k
}
func diffArguments(expected Arguments, actual Arguments) string {
if len(expected) != len(actual) {
return fmt.Sprintf("Provided %v arguments, mocked for %v arguments", len(expected), len(actual))
}
for x := range expected {
if diffString := diff(expected[x], actual[x]); diffString != "" {
return fmt.Sprintf("Difference found in argument %v:\n\n%s", x, diffString)
}
}
return ""
}
// diff returns a diff of both values as long as both are of the same type and
// are a struct, map, slice or array. Otherwise it returns an empty string.
func diff(expected interface{}, actual interface{}) string {
if expected == nil || actual == nil {
return ""
}
et, ek := typeAndKind(expected)
at, _ := typeAndKind(actual)
if et != at {
return ""
}
if ek != reflect.Struct && ek != reflect.Map && ek != reflect.Slice && ek != reflect.Array {
return ""
}
e := spewConfig.Sdump(expected)
a := spewConfig.Sdump(actual)
diff, _ := difflib.GetUnifiedDiffString(difflib.UnifiedDiff{
A: difflib.SplitLines(e),
B: difflib.SplitLines(a),
FromFile: "Expected",
FromDate: "",
ToFile: "Actual",
ToDate: "",
Context: 1,
})
return diff
}
var spewConfig = spew.ConfigState{
Indent: " ",
DisablePointerAddresses: true,
DisableCapacities: true,
SortKeys: true,
}
type tHelper interface {
Helper()
}