diff options
author | Unknwon <u@gogs.io> | 2017-02-09 19:48:13 -0500 |
---|---|---|
committer | Unknwon <u@gogs.io> | 2017-02-09 19:48:13 -0500 |
commit | 2fd69f13d9599a6c58b47225565163fd7d87889f (patch) | |
tree | fd19e868e1c2e95a5fb83a268f6e393669d6ee79 /vendor/github.com/smartystreets/assertions | |
parent | eb66060cd7b9bce996b1d75ae80ce1ef31d5ce62 (diff) |
vendor: check in vendors
Bye bye glide...
Diffstat (limited to 'vendor/github.com/smartystreets/assertions')
40 files changed, 4769 insertions, 0 deletions
diff --git a/vendor/github.com/smartystreets/assertions/LICENSE.md b/vendor/github.com/smartystreets/assertions/LICENSE.md new file mode 100644 index 00000000..48a3731c --- /dev/null +++ b/vendor/github.com/smartystreets/assertions/LICENSE.md @@ -0,0 +1,23 @@ +Copyright (c) 2015 SmartyStreets, LLC + +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. + +NOTE: Various optional and subordinate components carry their own licensing +requirements and restrictions. Use of those components is subject to the terms +and conditions outlined the respective license of each component. diff --git a/vendor/github.com/smartystreets/assertions/README.md b/vendor/github.com/smartystreets/assertions/README.md new file mode 100644 index 00000000..58383bb0 --- /dev/null +++ b/vendor/github.com/smartystreets/assertions/README.md @@ -0,0 +1,575 @@ +# assertions +-- + import "github.com/smartystreets/assertions" + +Package assertions contains the implementations for all assertions which are +referenced in goconvey's `convey` package +(github.com/smartystreets/goconvey/convey) and gunit +(github.com/smartystreets/gunit) for use with the So(...) method. They can also +be used in traditional Go test functions and even in applications. + +Many of the assertions lean heavily on work done by Aaron Jacobs in his +excellent oglematchers library. (https://github.com/jacobsa/oglematchers) The +ShouldResemble assertion leans heavily on work done by Daniel Jacques in his +very helpful go-render library. (https://github.com/luci/go-render) + +## Usage + +#### func GoConveyMode + +```go +func GoConveyMode(yes bool) +``` +GoConveyMode provides control over JSON serialization of failures. When using +the assertions in this package from the convey package JSON results are very +helpful and can be rendered in a DIFF view. In that case, this function will be +called with a true value to enable the JSON serialization. By default, the +assertions in this package will not serializer a JSON result, making standalone +ussage more convenient. + +#### func ShouldAlmostEqual + +```go +func ShouldAlmostEqual(actual interface{}, expected ...interface{}) string +``` +ShouldAlmostEqual makes sure that two parameters are close enough to being +equal. The acceptable delta may be specified with a third argument, or a very +small default delta will be used. + +#### func ShouldBeBetween + +```go +func ShouldBeBetween(actual interface{}, expected ...interface{}) string +``` +ShouldBeBetween receives exactly three parameters: an actual value, a lower +bound, and an upper bound. It ensures that the actual value is between both +bounds (but not equal to either of them). + +#### func ShouldBeBetweenOrEqual + +```go +func ShouldBeBetweenOrEqual(actual interface{}, expected ...interface{}) string +``` +ShouldBeBetweenOrEqual receives exactly three parameters: an actual value, a +lower bound, and an upper bound. It ensures that the actual value is between +both bounds or equal to one of them. + +#### func ShouldBeBlank + +```go +func ShouldBeBlank(actual interface{}, expected ...interface{}) string +``` +ShouldBeBlank receives exactly 1 string parameter and ensures that it is equal +to "". + +#### func ShouldBeChronological + +```go +func ShouldBeChronological(actual interface{}, expected ...interface{}) string +``` +ShouldBeChronological receives a []time.Time slice and asserts that the are in +chronological order starting with the first time.Time as the earliest. + +#### func ShouldBeEmpty + +```go +func ShouldBeEmpty(actual interface{}, expected ...interface{}) string +``` +ShouldBeEmpty receives a single parameter (actual) and determines whether or not +calling len(actual) would return `0`. It obeys the rules specified by the len +function for determining length: http://golang.org/pkg/builtin/#len + +#### func ShouldBeFalse + +```go +func ShouldBeFalse(actual interface{}, expected ...interface{}) string +``` +ShouldBeFalse receives a single parameter and ensures that it is false. + +#### func ShouldBeGreaterThan + +```go +func ShouldBeGreaterThan(actual interface{}, expected ...interface{}) string +``` +ShouldBeGreaterThan receives exactly two parameters and ensures that the first +is greater than the second. + +#### func ShouldBeGreaterThanOrEqualTo + +```go +func ShouldBeGreaterThanOrEqualTo(actual interface{}, expected ...interface{}) string +``` +ShouldBeGreaterThanOrEqualTo receives exactly two parameters and ensures that +the first is greater than or equal to the second. + +#### func ShouldBeIn + +```go +func ShouldBeIn(actual interface{}, expected ...interface{}) string +``` +ShouldBeIn receives at least 2 parameters. The first is a proposed member of the +collection that is passed in either as the second parameter, or of the +collection that is comprised of all the remaining parameters. This assertion +ensures that the proposed member is in the collection (using ShouldEqual). + +#### func ShouldBeLessThan + +```go +func ShouldBeLessThan(actual interface{}, expected ...interface{}) string +``` +ShouldBeLessThan receives exactly two parameters and ensures that the first is +less than the second. + +#### func ShouldBeLessThanOrEqualTo + +```go +func ShouldBeLessThanOrEqualTo(actual interface{}, expected ...interface{}) string +``` +ShouldBeLessThan receives exactly two parameters and ensures that the first is +less than or equal to the second. + +#### func ShouldBeNil + +```go +func ShouldBeNil(actual interface{}, expected ...interface{}) string +``` +ShouldBeNil receives a single parameter and ensures that it is nil. + +#### func ShouldBeTrue + +```go +func ShouldBeTrue(actual interface{}, expected ...interface{}) string +``` +ShouldBeTrue receives a single parameter and ensures that it is true. + +#### func ShouldBeZeroValue + +```go +func ShouldBeZeroValue(actual interface{}, expected ...interface{}) string +``` +ShouldBeZeroValue receives a single parameter and ensures that it is the Go +equivalent of the default value, or "zero" value. + +#### func ShouldContain + +```go +func ShouldContain(actual interface{}, expected ...interface{}) string +``` +ShouldContain receives exactly two parameters. The first is a slice and the +second is a proposed member. Membership is determined using ShouldEqual. + +#### func ShouldContainKey + +```go +func ShouldContainKey(actual interface{}, expected ...interface{}) string +``` +ShouldContainKey receives exactly two parameters. The first is a map and the +second is a proposed key. Keys are compared with a simple '=='. + +#### func ShouldContainSubstring + +```go +func ShouldContainSubstring(actual interface{}, expected ...interface{}) string +``` +ShouldContainSubstring receives exactly 2 string parameters and ensures that the +first contains the second as a substring. + +#### func ShouldEndWith + +```go +func ShouldEndWith(actual interface{}, expected ...interface{}) string +``` +ShouldEndWith receives exactly 2 string parameters and ensures that the first +ends with the second. + +#### func ShouldEqual + +```go +func ShouldEqual(actual interface{}, expected ...interface{}) string +``` +ShouldEqual receives exactly two parameters and does an equality check. + +#### func ShouldEqualTrimSpace + +```go +func ShouldEqualTrimSpace(actual interface{}, expected ...interface{}) string +``` +ShouldEqualTrimSpace receives exactly 2 string parameters and ensures that the +first is equal to the second after removing all leading and trailing whitespace +using strings.TrimSpace(first). + +#### func ShouldEqualWithout + +```go +func ShouldEqualWithout(actual interface{}, expected ...interface{}) string +``` +ShouldEqualWithout receives exactly 3 string parameters and ensures that the +first is equal to the second after removing all instances of the third from the +first using strings.Replace(first, third, "", -1). + +#### func ShouldHappenAfter + +```go +func ShouldHappenAfter(actual interface{}, expected ...interface{}) string +``` +ShouldHappenAfter receives exactly 2 time.Time arguments and asserts that the +first happens after the second. + +#### func ShouldHappenBefore + +```go +func ShouldHappenBefore(actual interface{}, expected ...interface{}) string +``` +ShouldHappenBefore receives exactly 2 time.Time arguments and asserts that the +first happens before the second. + +#### func ShouldHappenBetween + +```go +func ShouldHappenBetween(actual interface{}, expected ...interface{}) string +``` +ShouldHappenBetween receives exactly 3 time.Time arguments and asserts that the +first happens between (not on) the second and third. + +#### func ShouldHappenOnOrAfter + +```go +func ShouldHappenOnOrAfter(actual interface{}, expected ...interface{}) string +``` +ShouldHappenOnOrAfter receives exactly 2 time.Time arguments and asserts that +the first happens on or after the second. + +#### func ShouldHappenOnOrBefore + +```go +func ShouldHappenOnOrBefore(actual interface{}, expected ...interface{}) string +``` +ShouldHappenOnOrBefore receives exactly 2 time.Time arguments and asserts that +the first happens on or before the second. + +#### func ShouldHappenOnOrBetween + +```go +func ShouldHappenOnOrBetween(actual interface{}, expected ...interface{}) string +``` +ShouldHappenOnOrBetween receives exactly 3 time.Time arguments and asserts that +the first happens between or on the second and third. + +#### func ShouldHappenWithin + +```go +func ShouldHappenWithin(actual interface{}, expected ...interface{}) string +``` +ShouldHappenWithin receives a time.Time, a time.Duration, and a time.Time (3 +arguments) and asserts that the first time.Time happens within or on the +duration specified relative to the other time.Time. + +#### func ShouldHaveLength + +```go +func ShouldHaveLength(actual interface{}, expected ...interface{}) string +``` +ShouldHaveLength receives 2 parameters. The first is a collection to check the +length of, the second being the expected length. It obeys the rules specified by +the len function for determining length: http://golang.org/pkg/builtin/#len + +#### func ShouldHaveSameTypeAs + +```go +func ShouldHaveSameTypeAs(actual interface{}, expected ...interface{}) string +``` +ShouldHaveSameTypeAs receives exactly two parameters and compares their +underlying types for equality. + +#### func ShouldImplement + +```go +func ShouldImplement(actual interface{}, expectedList ...interface{}) string +``` +ShouldImplement receives exactly two parameters and ensures that the first +implements the interface type of the second. + +#### func ShouldNotAlmostEqual + +```go +func ShouldNotAlmostEqual(actual interface{}, expected ...interface{}) string +``` +ShouldNotAlmostEqual is the inverse of ShouldAlmostEqual + +#### func ShouldNotBeBetween + +```go +func ShouldNotBeBetween(actual interface{}, expected ...interface{}) string +``` +ShouldNotBeBetween receives exactly three parameters: an actual value, a lower +bound, and an upper bound. It ensures that the actual value is NOT between both +bounds. + +#### func ShouldNotBeBetweenOrEqual + +```go +func ShouldNotBeBetweenOrEqual(actual interface{}, expected ...interface{}) string +``` +ShouldNotBeBetweenOrEqual receives exactly three parameters: an actual value, a +lower bound, and an upper bound. It ensures that the actual value is nopt +between the bounds nor equal to either of them. + +#### func ShouldNotBeBlank + +```go +func ShouldNotBeBlank(actual interface{}, expected ...interface{}) string +``` +ShouldNotBeBlank receives exactly 1 string parameter and ensures that it is +equal to "". + +#### func ShouldNotBeEmpty + +```go +func ShouldNotBeEmpty(actual interface{}, expected ...interface{}) string +``` +ShouldNotBeEmpty receives a single parameter (actual) and determines whether or +not calling len(actual) would return a value greater than zero. It obeys the +rules specified by the `len` function for determining length: +http://golang.org/pkg/builtin/#len + +#### func ShouldNotBeIn + +```go +func ShouldNotBeIn(actual interface{}, expected ...interface{}) string +``` +ShouldNotBeIn receives at least 2 parameters. The first is a proposed member of +the collection that is passed in either as the second parameter, or of the +collection that is comprised of all the remaining parameters. This assertion +ensures that the proposed member is NOT in the collection (using ShouldEqual). + +#### func ShouldNotBeNil + +```go +func ShouldNotBeNil(actual interface{}, expected ...interface{}) string +``` +ShouldNotBeNil receives a single parameter and ensures that it is not nil. + +#### func ShouldNotContain + +```go +func ShouldNotContain(actual interface{}, expected ...interface{}) string +``` +ShouldNotContain receives exactly two parameters. The first is a slice and the +second is a proposed member. Membership is determinied using ShouldEqual. + +#### func ShouldNotContainKey + +```go +func ShouldNotContainKey(actual interface{}, expected ...interface{}) string +``` +ShouldNotContainKey receives exactly two parameters. The first is a map and the +second is a proposed absent key. Keys are compared with a simple '=='. + +#### func ShouldNotContainSubstring + +```go +func ShouldNotContainSubstring(actual interface{}, expected ...interface{}) string +``` +ShouldNotContainSubstring receives exactly 2 string parameters and ensures that +the first does NOT contain the second as a substring. + +#### func ShouldNotEndWith + +```go +func ShouldNotEndWith(actual interface{}, expected ...interface{}) string +``` +ShouldEndWith receives exactly 2 string parameters and ensures that the first +does not end with the second. + +#### func ShouldNotEqual + +```go +func ShouldNotEqual(actual interface{}, expected ...interface{}) string +``` +ShouldNotEqual receives exactly two parameters and does an inequality check. + +#### func ShouldNotHappenOnOrBetween + +```go +func ShouldNotHappenOnOrBetween(actual interface{}, expected ...interface{}) string +``` +ShouldNotHappenOnOrBetween receives exactly 3 time.Time arguments and asserts +that the first does NOT happen between or on the second or third. + +#### func ShouldNotHappenWithin + +```go +func ShouldNotHappenWithin(actual interface{}, expected ...interface{}) string +``` +ShouldNotHappenWithin receives a time.Time, a time.Duration, and a time.Time (3 +arguments) and asserts that the first time.Time does NOT happen within or on the +duration specified relative to the other time.Time. + +#### func ShouldNotHaveSameTypeAs + +```go +func ShouldNotHaveSameTypeAs(actual interface{}, expected ...interface{}) string +``` +ShouldNotHaveSameTypeAs receives exactly two parameters and compares their +underlying types for inequality. + +#### func ShouldNotImplement + +```go +func ShouldNotImplement(actual interface{}, expectedList ...interface{}) string +``` +ShouldNotImplement receives exactly two parameters and ensures that the first +does NOT implement the interface type of the second. + +#### func ShouldNotPanic + +```go +func ShouldNotPanic(actual interface{}, expected ...interface{}) (message string) +``` +ShouldNotPanic receives a void, niladic function and expects to execute the +function without any panic. + +#### func ShouldNotPanicWith + +```go +func ShouldNotPanicWith(actual interface{}, expected ...interface{}) (message string) +``` +ShouldNotPanicWith receives a void, niladic function and expects to recover a +panic whose content differs from the second argument. + +#### func ShouldNotPointTo + +```go +func ShouldNotPointTo(actual interface{}, expected ...interface{}) string +``` +ShouldNotPointTo receives exactly two parameters and checks to see that they +point to different addresess. + +#### func ShouldNotResemble + +```go +func ShouldNotResemble(actual interface{}, expected ...interface{}) string +``` +ShouldNotResemble receives exactly two parameters and does an inverse deep equal +check (see reflect.DeepEqual) + +#### func ShouldNotStartWith + +```go +func ShouldNotStartWith(actual interface{}, expected ...interface{}) string +``` +ShouldNotStartWith receives exactly 2 string parameters and ensures that the +first does not start with the second. + +#### func ShouldPanic + +```go +func ShouldPanic(actual interface{}, expected ...interface{}) (message string) +``` +ShouldPanic receives a void, niladic function and expects to recover a panic. + +#### func ShouldPanicWith + +```go +func ShouldPanicWith(actual interface{}, expected ...interface{}) (message string) +``` +ShouldPanicWith receives a void, niladic function and expects to recover a panic +with the second argument as the content. + +#### func ShouldPointTo + +```go +func ShouldPointTo(actual interface{}, expected ...interface{}) string +``` +ShouldPointTo receives exactly two parameters and checks to see that they point +to the same address. + +#### func ShouldResemble + +```go +func ShouldResemble(actual interface{}, expected ...interface{}) string +``` +ShouldResemble receives exactly two parameters and does a deep equal check (see +reflect.DeepEqual) + +#### func ShouldStartWith + +```go +func ShouldStartWith(actual interface{}, expected ...interface{}) string +``` +ShouldStartWith receives exactly 2 string parameters and ensures that the first +starts with the second. + +#### func So + +```go +func So(actual interface{}, assert assertion, expected ...interface{}) (bool, string) +``` +So is a convenience function (as opposed to an inconvenience function?) for +running assertions on arbitrary arguments in any context, be it for testing or +even application logging. It allows you to perform assertion-like behavior (and +get nicely formatted messages detailing discrepancies) but without the program +blowing up or panicking. All that is required is to import this package and call +`So` with one of the assertions exported by this package as the second +parameter. The first return parameter is a boolean indicating if the assertion +was true. The second return parameter is the well-formatted message showing why +an assertion was incorrect, or blank if the assertion was correct. + +Example: + + if ok, message := So(x, ShouldBeGreaterThan, y); !ok { + log.Println(message) + } + +#### type Assertion + +```go +type Assertion struct { +} +``` + + +#### func New + +```go +func New(t testingT) *Assertion +``` +New swallows the *testing.T struct and prints failed assertions using t.Error. +Example: assertions.New(t).So(1, should.Equal, 1) + +#### func (*Assertion) Failed + +```go +func (this *Assertion) Failed() bool +``` +Failed reports whether any calls to So (on this Assertion instance) have failed. + +#### func (*Assertion) So + +```go +func (this *Assertion) So(actual interface{}, assert assertion, expected ...interface{}) bool +``` +So calls the standalone So function and additionally, calls t.Error in failure +scenarios. + +#### type FailureView + +```go +type FailureView struct { + Message string `json:"Message"` + Expected string `json:"Expected"` + Actual string `json:"Actual"` +} +``` + +This struct is also declared in +github.com/smartystreets/goconvey/convey/reporting. The json struct tags should +be equal in both declarations. + +#### type Serializer + +```go +type Serializer interface { + // contains filtered or unexported methods +} +``` diff --git a/vendor/github.com/smartystreets/assertions/assertions.goconvey b/vendor/github.com/smartystreets/assertions/assertions.goconvey new file mode 100644 index 00000000..e76cf275 --- /dev/null +++ b/vendor/github.com/smartystreets/assertions/assertions.goconvey @@ -0,0 +1,3 @@ +#ignore +-timeout=1s +-coverpkg=github.com/smartystreets/assertions,github.com/smartystreets/assertions/internal/oglematchers
\ No newline at end of file diff --git a/vendor/github.com/smartystreets/assertions/collections.go b/vendor/github.com/smartystreets/assertions/collections.go new file mode 100644 index 00000000..d7f407e9 --- /dev/null +++ b/vendor/github.com/smartystreets/assertions/collections.go @@ -0,0 +1,244 @@ +package assertions + +import ( + "fmt" + "reflect" + + "github.com/smartystreets/assertions/internal/oglematchers" +) + +// ShouldContain receives exactly two parameters. The first is a slice and the +// second is a proposed member. Membership is determined using ShouldEqual. +func ShouldContain(actual interface{}, expected ...interface{}) string { + if fail := need(1, expected); fail != success { + return fail + } + + if matchError := oglematchers.Contains(expected[0]).Matches(actual); matchError != nil { + typeName := reflect.TypeOf(actual) + + if fmt.Sprintf("%v", matchError) == "which is not a slice or array" { + return fmt.Sprintf(shouldHaveBeenAValidCollection, typeName) + } + return fmt.Sprintf(shouldHaveContained, typeName, expected[0]) + } + return success +} + +// ShouldNotContain receives exactly two parameters. The first is a slice and the +// second is a proposed member. Membership is determinied using ShouldEqual. +func ShouldNotContain(actual interface{}, expected ...interface{}) string { + if fail := need(1, expected); fail != success { + return fail + } + typeName := reflect.TypeOf(actual) + + if matchError := oglematchers.Contains(expected[0]).Matches(actual); matchError != nil { + if fmt.Sprintf("%v", matchError) == "which is not a slice or array" { + return fmt.Sprintf(shouldHaveBeenAValidCollection, typeName) + } + return success + } + return fmt.Sprintf(shouldNotHaveContained, typeName, expected[0]) +} + +// ShouldContainKey receives exactly two parameters. The first is a map and the +// second is a proposed key. Keys are compared with a simple '=='. +func ShouldContainKey(actual interface{}, expected ...interface{}) string { + if fail := need(1, expected); fail != success { + return fail + } + + keys, isMap := mapKeys(actual) + if !isMap { + return fmt.Sprintf(shouldHaveBeenAValidMap, reflect.TypeOf(actual)) + } + + if !keyFound(keys, expected[0]) { + return fmt.Sprintf(shouldHaveContainedKey, reflect.TypeOf(actual), expected) + } + + return "" +} + +// ShouldNotContainKey receives exactly two parameters. The first is a map and the +// second is a proposed absent key. Keys are compared with a simple '=='. +func ShouldNotContainKey(actual interface{}, expected ...interface{}) string { + if fail := need(1, expected); fail != success { + return fail + } + + keys, isMap := mapKeys(actual) + if !isMap { + return fmt.Sprintf(shouldHaveBeenAValidMap, reflect.TypeOf(actual)) + } + + if keyFound(keys, expected[0]) { + return fmt.Sprintf(shouldNotHaveContainedKey, reflect.TypeOf(actual), expected) + } + + return "" +} + +func mapKeys(m interface{}) ([]reflect.Value, bool) { + value := reflect.ValueOf(m) + if value.Kind() != reflect.Map { + return nil, false + } + return value.MapKeys(), true +} +func keyFound(keys []reflect.Value, expectedKey interface{}) bool { + found := false + for _, key := range keys { + if key.Interface() == expectedKey { + found = true + } + } + return found +} + +// ShouldBeIn receives at least 2 parameters. The first is a proposed member of the collection +// that is passed in either as the second parameter, or of the collection that is comprised +// of all the remaining parameters. This assertion ensures that the proposed member is in +// the collection (using ShouldEqual). +func ShouldBeIn(actual interface{}, expected ...interface{}) string { + if fail := atLeast(1, expected); fail != success { + return fail + } + + if len(expected) == 1 { + return shouldBeIn(actual, expected[0]) + } + return shouldBeIn(actual, expected) +} +func shouldBeIn(actual interface{}, expected interface{}) string { + if matchError := oglematchers.Contains(actual).Matches(expected); matchError != nil { + return fmt.Sprintf(shouldHaveBeenIn, actual, reflect.TypeOf(expected)) + } + return success +} + +// ShouldNotBeIn receives at least 2 parameters. The first is a proposed member of the collection +// that is passed in either as the second parameter, or of the collection that is comprised +// of all the remaining parameters. This assertion ensures that the proposed member is NOT in +// the collection (using ShouldEqual). +func ShouldNotBeIn(actual interface{}, expected ...interface{}) string { + if fail := atLeast(1, expected); fail != success { + return fail + } + + if len(expected) == 1 { + return shouldNotBeIn(actual, expected[0]) + } + return shouldNotBeIn(actual, expected) +} +func shouldNotBeIn(actual interface{}, expected interface{}) string { + if matchError := oglematchers.Contains(actual).Matches(expected); matchError == nil { + return fmt.Sprintf(shouldNotHaveBeenIn, actual, reflect.TypeOf(expected)) + } + return success +} + +// ShouldBeEmpty receives a single parameter (actual) and determines whether or not +// calling len(actual) would return `0`. It obeys the rules specified by the len +// function for determining length: http://golang.org/pkg/builtin/#len +func ShouldBeEmpty(actual interface{}, expected ...interface{}) string { + if fail := need(0, expected); fail != success { + return fail + } + + if actual == nil { + return success + } + + value := reflect.ValueOf(actual) + switch value.Kind() { + case reflect.Slice: + if value.Len() == 0 { + return success + } + case reflect.Chan: + if value.Len() == 0 { + return success + } + case reflect.Map: + if value.Len() == 0 { + return success + } + case reflect.String: + if value.Len() == 0 { + return success + } + case reflect.Ptr: + elem := value.Elem() + kind := elem.Kind() + if (kind == reflect.Slice || kind == reflect.Array) && elem.Len() == 0 { + return success + } + } + + return fmt.Sprintf(shouldHaveBeenEmpty, actual) +} + +// ShouldNotBeEmpty receives a single parameter (actual) and determines whether or not +// calling len(actual) would return a value greater than zero. It obeys the rules +// specified by the `len` function for determining length: http://golang.org/pkg/builtin/#len +func ShouldNotBeEmpty(actual interface{}, expected ...interface{}) string { + if fail := need(0, expected); fail != success { + return fail + } + + if empty := ShouldBeEmpty(actual, expected...); empty != success { + return success + } + return fmt.Sprintf(shouldNotHaveBeenEmpty, actual) +} + +// ShouldHaveLength receives 2 parameters. The first is a collection to check +// the length of, the second being the expected length. It obeys the rules +// specified by the len function for determining length: +// http://golang.org/pkg/builtin/#len +func ShouldHaveLength(actual interface{}, expected ...interface{}) string { + if fail := need(1, expected); fail != success { + return fail + } + + var expectedLen int64 + lenValue := reflect.ValueOf(expected[0]) + switch lenValue.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + expectedLen = lenValue.Int() + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + expectedLen = int64(lenValue.Uint()) + default: + return fmt.Sprintf(shouldHaveBeenAValidInteger, reflect.TypeOf(expected[0])) + } + + if expectedLen < 0 { + return fmt.Sprintf(shouldHaveBeenAValidLength, expected[0]) + } + + value := reflect.ValueOf(actual) + switch value.Kind() { + case reflect.Slice, + reflect.Chan, + reflect.Map, + reflect.String: + if int64(value.Len()) == expectedLen { + return success + } else { + return fmt.Sprintf(shouldHaveHadLength, actual, value.Len(), expectedLen) + } + case reflect.Ptr: + elem := value.Elem() + kind := elem.Kind() + if kind == reflect.Slice || kind == reflect.Array { + if int64(elem.Len()) == expectedLen { + return success + } else { + return fmt.Sprintf(shouldHaveHadLength, actual, elem.Len(), expectedLen) + } + } + } + return fmt.Sprintf(shouldHaveBeenAValidCollection, reflect.TypeOf(actual)) +} diff --git a/vendor/github.com/smartystreets/assertions/doc.go b/vendor/github.com/smartystreets/assertions/doc.go new file mode 100644 index 00000000..5720fc29 --- /dev/null +++ b/vendor/github.com/smartystreets/assertions/doc.go @@ -0,0 +1,105 @@ +// Package assertions contains the implementations for all assertions which +// are referenced in goconvey's `convey` package +// (github.com/smartystreets/goconvey/convey) and gunit (github.com/smartystreets/gunit) +// for use with the So(...) method. +// They can also be used in traditional Go test functions and even in +// applications. +// +// Many of the assertions lean heavily on work done by Aaron Jacobs in his excellent oglematchers library. +// (https://github.com/jacobsa/oglematchers) +// The ShouldResemble assertion leans heavily on work done by Daniel Jacques in his very helpful go-render library. +// (https://github.com/luci/go-render) +package assertions + +import ( + "fmt" + "runtime" +) + +// By default we use a no-op serializer. The actual Serializer provides a JSON +// representation of failure results on selected assertions so the goconvey +// web UI can display a convenient diff. +var serializer Serializer = new(noopSerializer) + +// GoConveyMode provides control over JSON serialization of failures. When +// using the assertions in this package from the convey package JSON results +// are very helpful and can be rendered in a DIFF view. In that case, this function +// will be called with a true value to enable the JSON serialization. By default, +// the assertions in this package will not serializer a JSON result, making +// standalone ussage more convenient. +func GoConveyMode(yes bool) { + if yes { + serializer = newSerializer() + } else { + serializer = new(noopSerializer) + } +} + +type testingT interface { + Error(args ...interface{}) +} + +type Assertion struct { + t testingT + failed bool +} + +// New swallows the *testing.T struct and prints failed assertions using t.Error. +// Example: assertions.New(t).So(1, should.Equal, 1) +func New(t testingT) *Assertion { + return &Assertion{t: t} +} + +// Failed reports whether any calls to So (on this Assertion instance) have failed. +func (this *Assertion) Failed() bool { + return this.failed +} + +// So calls the standalone So function and additionally, calls t.Error in failure scenarios. +func (this *Assertion) So(actual interface{}, assert assertion, expected ...interface{}) bool { + ok, result := So(actual, assert, expected...) + if !ok { + this.failed = true + _, file, line, _ := runtime.Caller(1) + this.t.Error(fmt.Sprintf("\n%s:%d\n%s", file, line, result)) + } + return ok +} + +// So is a convenience function (as opposed to an inconvenience function?) +// for running assertions on arbitrary arguments in any context, be it for testing or even +// application logging. It allows you to perform assertion-like behavior (and get nicely +// formatted messages detailing discrepancies) but without the program blowing up or panicking. +// All that is required is to import this package and call `So` with one of the assertions +// exported by this package as the second parameter. +// The first return parameter is a boolean indicating if the assertion was true. The second +// return parameter is the well-formatted message showing why an assertion was incorrect, or +// blank if the assertion was correct. +// +// Example: +// +// if ok, message := So(x, ShouldBeGreaterThan, y); !ok { +// log.Println(message) +// } +// +func So(actual interface{}, assert assertion, expected ...interface{}) (bool, string) { + if result := so(actual, assert, expected...); len(result) == 0 { + return true, result + } else { + return false, result + } +} + +// so is like So, except that it only returns the string message, which is blank if the +// assertion passed. Used to facilitate testing. +func so(actual interface{}, assert func(interface{}, ...interface{}) string, expected ...interface{}) string { + return assert(actual, expected...) +} + +// assertion is an alias for a function with a signature that the So() +// function can handle. Any future or custom assertions should conform to this +// method signature. The return value should be an empty string if the assertion +// passes and a well-formed failure message if not. +type assertion func(actual interface{}, expected ...interface{}) string + +//////////////////////////////////////////////////////////////////////////// diff --git a/vendor/github.com/smartystreets/assertions/equality.go b/vendor/github.com/smartystreets/assertions/equality.go new file mode 100644 index 00000000..2b6049c3 --- /dev/null +++ b/vendor/github.com/smartystreets/assertions/equality.go @@ -0,0 +1,280 @@ +package assertions + +import ( + "errors" + "fmt" + "math" + "reflect" + "strings" + + "github.com/smartystreets/assertions/internal/oglematchers" + "github.com/smartystreets/assertions/internal/go-render/render" +) + +// default acceptable delta for ShouldAlmostEqual +const defaultDelta = 0.0000000001 + +// ShouldEqual receives exactly two parameters and does an equality check. +func ShouldEqual(actual interface{}, expected ...interface{}) string { + if message := need(1, expected); message != success { + return message + } + return shouldEqual(actual, expected[0]) +} +func shouldEqual(actual, expected interface{}) (message string) { + defer func() { + if r := recover(); r != nil { + message = serializer.serialize(expected, actual, fmt.Sprintf(shouldHaveBeenEqual, expected, actual)) + return + } + }() + + if matchError := oglematchers.Equals(expected).Matches(actual); matchError != nil { + expectedSyntax := fmt.Sprintf("%v", expected) + actualSyntax := fmt.Sprintf("%v", actual) + if expectedSyntax == actualSyntax && reflect.TypeOf(expected) != reflect.TypeOf(actual) { + message = fmt.Sprintf(shouldHaveBeenEqualTypeMismatch, expected, expected, actual, actual) + } else { + message = fmt.Sprintf(shouldHaveBeenEqual, expected, actual) + } + message = serializer.serialize(expected, actual, message) + return + } + + return success +} + +// ShouldNotEqual receives exactly two parameters and does an inequality check. +func ShouldNotEqual(actual interface{}, expected ...interface{}) string { + if fail := need(1, expected); fail != success { + return fail + } else if ShouldEqual(actual, expected[0]) == success { + return fmt.Sprintf(shouldNotHaveBeenEqual, actual, expected[0]) + } + return success +} + +// ShouldAlmostEqual makes sure that two parameters are close enough to being equal. +// The acceptable delta may be specified with a third argument, +// or a very small default delta will be used. +func ShouldAlmostEqual(actual interface{}, expected ...interface{}) string { + actualFloat, expectedFloat, deltaFloat, err := cleanAlmostEqualInput(actual, expected...) + + if err != "" { + return err + } + + if math.Abs(actualFloat-expectedFloat) <= deltaFloat { + return success + } else { + return fmt.Sprintf(shouldHaveBeenAlmostEqual, actualFloat, expectedFloat) + } +} + +// ShouldNotAlmostEqual is the inverse of ShouldAlmostEqual +func ShouldNotAlmostEqual(actual interface{}, expected ...interface{}) string { + actualFloat, expectedFloat, deltaFloat, err := cleanAlmostEqualInput(actual, expected...) + + if err != "" { + return err + } + + if math.Abs(actualFloat-expectedFloat) > deltaFloat { + return success + } else { + return fmt.Sprintf(shouldHaveNotBeenAlmostEqual, actualFloat, expectedFloat) + } +} + +func cleanAlmostEqualInput(actual interface{}, expected ...interface{}) (float64, float64, float64, string) { + deltaFloat := 0.0000000001 + + if len(expected) == 0 { + return 0.0, 0.0, 0.0, "This assertion requires exactly one comparison value and an optional delta (you provided neither)" + } else if len(expected) == 2 { + delta, err := getFloat(expected[1]) + + if err != nil { + return 0.0, 0.0, 0.0, "delta must be a numerical type" + } + + deltaFloat = delta + } else if len(expected) > 2 { + return 0.0, 0.0, 0.0, "This assertion requires exactly one comparison value and an optional delta (you provided more values)" + } + + actualFloat, err := getFloat(actual) + + if err != nil { + return 0.0, 0.0, 0.0, err.Error() + } + + expectedFloat, err := getFloat(expected[0]) + + if err != nil { + return 0.0, 0.0, 0.0, err.Error() + } + + return actualFloat, expectedFloat, deltaFloat, "" +} + +// returns the float value of any real number, or error if it is not a numerical type +func getFloat(num interface{}) (float64, error) { + numValue := reflect.ValueOf(num) + numKind := numValue.Kind() + + if numKind == reflect.Int || + numKind == reflect.Int8 || + numKind == reflect.Int16 || + numKind == reflect.Int32 || + numKind == reflect.Int64 { + return float64(numValue.Int()), nil + } else if numKind == reflect.Uint || + numKind == reflect.Uint8 || + numKind == reflect.Uint16 || + numKind == reflect.Uint32 || + numKind == reflect.Uint64 { + return float64(numValue.Uint()), nil + } else if numKind == reflect.Float32 || + numKind == reflect.Float64 { + return numValue.Float(), nil + } else { + return 0.0, errors.New("must be a numerical type, but was " + numKind.String()) + } +} + +// ShouldResemble receives exactly two parameters and does a deep equal check (see reflect.DeepEqual) +func ShouldResemble(actual interface{}, expected ...interface{}) string { + if message := need(1, expected); message != success { + return message + } + + if matchError := oglematchers.DeepEquals(expected[0]).Matches(actual); matchError != nil { + return serializer.serializeDetailed(expected[0], actual, + fmt.Sprintf(shouldHaveResembled, render.Render(expected[0]), render.Render(actual))) + } + + return success +} + +// ShouldNotResemble receives exactly two parameters and does an inverse deep equal check (see reflect.DeepEqual) +func ShouldNotResemble(actual interface{}, expected ...interface{}) string { + if message := need(1, expected); message != success { + return message + } else if ShouldResemble(actual, expected[0]) == success { + return fmt.Sprintf(shouldNotHaveResembled, render.Render(actual), render.Render(expected[0])) + } + return success +} + +// ShouldPointTo receives exactly two parameters and checks to see that they point to the same address. +func ShouldPointTo(actual interface{}, expected ...interface{}) string { + if message := need(1, expected); message != success { + return message + } + return shouldPointTo(actual, expected[0]) + +} +func shouldPointTo(actual, expected interface{}) string { + actualValue := reflect.ValueOf(actual) + expectedValue := reflect.ValueOf(expected) + + if ShouldNotBeNil(actual) != success { + return fmt.Sprintf(shouldHaveBeenNonNilPointer, "first", "nil") + } else if ShouldNotBeNil(expected) != success { + return fmt.Sprintf(shouldHaveBeenNonNilPointer, "second", "nil") + } else if actualValue.Kind() != reflect.Ptr { + return fmt.Sprintf(shouldHaveBeenNonNilPointer, "first", "not") + } else if expectedValue.Kind() != reflect.Ptr { + return fmt.Sprintf(shouldHaveBeenNonNilPointer, "second", "not") + } else if ShouldEqual(actualValue.Pointer(), expectedValue.Pointer()) != success { + actualAddress := reflect.ValueOf(actual).Pointer() + expectedAddress := reflect.ValueOf(expected).Pointer() + return serializer.serialize(expectedAddress, actualAddress, fmt.Sprintf(shouldHavePointedTo, + actual, actualAddress, + expected, expectedAddress)) + } + return success +} + +// ShouldNotPointTo receives exactly two parameters and checks to see that they point to different addresess. +func ShouldNotPointTo(actual interface{}, expected ...interface{}) string { + if message := need(1, expected); message != success { + return message + } + compare := ShouldPointTo(actual, expected[0]) + if strings.HasPrefix(compare, shouldBePointers) { + return compare + } else if compare == success { + return fmt.Sprintf(shouldNotHavePointedTo, actual, expected[0], reflect.ValueOf(actual).Pointer()) + } + return success +} + +// ShouldBeNil receives a single parameter and ensures that it is nil. +func ShouldBeNil(actual interface{}, expected ...interface{}) string { + if fail := need(0, expected); fail != success { + return fail + } else if actual == nil { + return success + } else if interfaceHasNilValue(actual) { + return success + } + return fmt.Sprintf(shouldHaveBeenNil, actual) +} +func interfaceHasNilValue(actual interface{}) bool { + value := reflect.ValueOf(actual) + kind := value.Kind() + nilable := kind == reflect.Slice || + kind == reflect.Chan || + kind == reflect.Func || + kind == reflect.Ptr || + kind == reflect.Map + + // Careful: reflect.Value.IsNil() will panic unless it's an interface, chan, map, func, slice, or ptr + // Reference: http://golang.org/pkg/reflect/#Value.IsNil + return nilable && value.IsNil() +} + +// ShouldNotBeNil receives a single parameter and ensures that it is not nil. +func ShouldNotBeNil(actual interface{}, expected ...interface{}) string { + if fail := need(0, expected); fail != success { + return fail + } else if ShouldBeNil(actual) == success { + return fmt.Sprintf(shouldNotHaveBeenNil, actual) + } + return success +} + +// ShouldBeTrue receives a single parameter and ensures that it is true. +func ShouldBeTrue(actual interface{}, expected ...interface{}) string { + if fail := need(0, expected); fail != success { + return fail + } else if actual != true { + return fmt.Sprintf(shouldHaveBeenTrue, actual) + } + return success +} + +// ShouldBeFalse receives a single parameter and ensures that it is false. +func ShouldBeFalse(actual interface{}, expected ...interface{}) string { + if fail := need(0, expected); fail != success { + return fail + } else if actual != false { + return fmt.Sprintf(shouldHaveBeenFalse, actual) + } + return success +} + +// ShouldBeZeroValue receives a single parameter and ensures that it is +// the Go equivalent of the default value, or "zero" value. +func ShouldBeZeroValue(actual interface{}, expected ...interface{}) string { + if fail := need(0, expected); fail != success { + return fail + } + zeroVal := reflect.Zero(reflect.TypeOf(actual)).Interface() + if !reflect.DeepEqual(zeroVal, actual) { + return serializer.serialize(zeroVal, actual, fmt.Sprintf(shouldHaveBeenZeroValue, actual)) + } + return success +} diff --git a/vendor/github.com/smartystreets/assertions/filter.go b/vendor/github.com/smartystreets/assertions/filter.go new file mode 100644 index 00000000..ee368a97 --- /dev/null +++ b/vendor/github.com/smartystreets/assertions/filter.go @@ -0,0 +1,23 @@ +package assertions + +import "fmt" + +const ( + success = "" + needExactValues = "This assertion requires exactly %d comparison values (you provided %d)." + needNonEmptyCollection = "This assertion requires at least 1 comparison value (you provided 0)." +) + +func need(needed int, expected []interface{}) string { + if len(expected) != needed { + return fmt.Sprintf(needExactValues, needed, len(expected)) + } + return success +} + +func atLeast(minimum int, expected []interface{}) string { + if len(expected) < 1 { + return needNonEmptyCollection + } + return success +} diff --git a/vendor/github.com/smartystreets/assertions/internal/go-render/LICENSE b/vendor/github.com/smartystreets/assertions/internal/go-render/LICENSE new file mode 100644 index 00000000..6280ff0e --- /dev/null +++ b/vendor/github.com/smartystreets/assertions/internal/go-render/LICENSE @@ -0,0 +1,27 @@ +// Copyright (c) 2015 The Chromium 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/smartystreets/assertions/internal/go-render/render/render.go b/vendor/github.com/smartystreets/assertions/internal/go-render/render/render.go new file mode 100644 index 00000000..e070a6b3 --- /dev/null +++ b/vendor/github.com/smartystreets/assertions/internal/go-render/render/render.go @@ -0,0 +1,327 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package render + +import ( + "bytes" + "fmt" + "reflect" + "sort" + "strconv" +) + +var implicitTypeMap = map[reflect.Kind]string{ + reflect.Bool: "bool", + reflect.String: "string", + reflect.Int: "int", + reflect.Int8: "int8", + reflect.Int16: "int16", + reflect.Int32: "int32", + reflect.Int64: "int64", + reflect.Uint: "uint", + reflect.Uint8: "uint8", + reflect.Uint16: "uint16", + reflect.Uint32: "uint32", + reflect.Uint64: "uint64", + reflect.Float32: "float32", + reflect.Float64: "float64", + reflect.Complex64: "complex64", + reflect.Complex128: "complex128", +} + +// Render converts a structure to a string representation. Unline the "%#v" +// format string, this resolves pointer types' contents in structs, maps, and +// slices/arrays and prints their field values. +func Render(v interface{}) string { + buf := bytes.Buffer{} + s := (*traverseState)(nil) + s.render(&buf, 0, reflect.ValueOf(v)) + return buf.String() +} + +// renderPointer is called to render a pointer value. +// +// This is overridable so that the test suite can have deterministic pointer +// values in its expectations. +var renderPointer = func(buf *bytes.Buffer, p uintptr) { + fmt.Fprintf(buf, "0x%016x", p) +} + +// traverseState is used to note and avoid recursion as struct members are being +// traversed. +// +// traverseState is allowed to be nil. Specifically, the root state is nil. +type traverseState struct { + parent *traverseState + ptr uintptr +} + +func (s *traverseState) forkFor(ptr uintptr) *traverseState { + for cur := s; cur != nil; cur = cur.parent { + if ptr == cur.ptr { + return nil + } + } + + fs := &traverseState{ + parent: s, + ptr: ptr, + } + return fs +} + +func (s *traverseState) render(buf *bytes.Buffer, ptrs int, v reflect.Value) { + if v.Kind() == reflect.Invalid { + buf.WriteString("nil") + return + } + vt := v.Type() + + // If the type being rendered is a potentially recursive type (a type that + // can contain itself as a member), we need to avoid recursion. + // + // If we've already seen this type before, mark that this is the case and + // write a recursion placeholder instead of actually rendering it. + // + // If we haven't seen it before, fork our `seen` tracking so any higher-up + // renderers will also render it at least once, then mark that we've seen it + // to avoid recursing on lower layers. + pe := uintptr(0) + vk := vt.Kind() + switch vk { + case reflect.Ptr: + // Since structs and arrays aren't pointers, they can't directly be + // recursed, but they can contain pointers to themselves. Record their + // pointer to avoid this. + switch v.Elem().Kind() { + case reflect.Struct, reflect.Array: + pe = v.Pointer() + } + + case reflect.Slice, reflect.Map: + pe = v.Pointer() + } + if pe != 0 { + s = s.forkFor(pe) + if s == nil { + buf.WriteString("<REC(") + writeType(buf, ptrs, vt) + buf.WriteString(")>") + return + } + } + + switch vk { + case reflect.Struct: + writeType(buf, ptrs, vt) + buf.WriteRune('{') + for i := 0; i < vt.NumField(); i++ { + if i > 0 { + buf.WriteString(", ") + } + buf.WriteString(vt.Field(i).Name) + buf.WriteRune(':') + + s.render(buf, 0, v.Field(i)) + } + buf.WriteRune('}') + + case reflect.Slice: + if v.IsNil() { + writeType(buf, ptrs, vt) + buf.WriteString("(nil)") + return + } + fallthrough + + case reflect.Array: + writeType(buf, ptrs, vt) + buf.WriteString("{") + for i := 0; i < v.Len(); i++ { + if i > 0 { + buf.WriteString(", ") + } + + s.render(buf, 0, v.Index(i)) + } + buf.WriteRune('}') + + case reflect.Map: + writeType(buf, ptrs, vt) + if v.IsNil() { + buf.WriteString("(nil)") + } else { + buf.WriteString("{") + + mkeys := v.MapKeys() + tryAndSortMapKeys(vt, mkeys) + + for i, mk := range mkeys { + if i > 0 { + buf.WriteString(", ") + } + + s.render(buf, 0, mk) + buf.WriteString(":") + s.render(buf, 0, v.MapIndex(mk)) + } + buf.WriteRune('}') + } + + case reflect.Ptr: + ptrs++ + fallthrough + case reflect.Interface: + if v.IsNil() { + writeType(buf, ptrs, v.Type()) + buf.WriteRune('(') + fmt.Fprint(buf, "nil") + buf.WriteRune(')') + } else { + s.render(buf, ptrs, v.Elem()) + } + + case reflect.Chan, reflect.Func, reflect.UnsafePointer: + writeType(buf, ptrs, vt) + buf.WriteRune('(') + renderPointer(buf, v.Pointer()) + buf.WriteRune(')') + + default: + tstr := vt.String() + implicit := ptrs == 0 && implicitTypeMap[vk] == tstr + if !implicit { + writeType(buf, ptrs, vt) + buf.WriteRune('(') + } + + switch vk { + case reflect.String: + fmt.Fprintf(buf, "%q", v.String()) + case reflect.Bool: + fmt.Fprintf(buf, "%v", v.Bool()) + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + fmt.Fprintf(buf, "%d", v.Int()) + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + fmt.Fprintf(buf, "%d", v.Uint()) + + case reflect.Float32, reflect.Float64: + fmt.Fprintf(buf, "%g", v.Float()) + + case reflect.Complex64, reflect.Complex128: + fmt.Fprintf(buf, "%g", v.Complex()) + } + + if !implicit { + buf.WriteRune(')') + } + } +} + +func writeType(buf *bytes.Buffer, ptrs int, t reflect.Type) { + parens := ptrs > 0 + switch t.Kind() { + case reflect.Chan, reflect.Func, reflect.UnsafePointer: + parens = true + } + + if parens { + buf.WriteRune('(') + for i := 0; i < ptrs; i++ { + buf.WriteRune('*') + } + } + + switch t.Kind() { + case reflect.Ptr: + if ptrs == 0 { + // This pointer was referenced from within writeType (e.g., as part of + // rendering a list), and so hasn't had its pointer asterisk accounted + // for. + buf.WriteRune('*') + } + writeType(buf, 0, t.Elem()) + + case reflect.Interface: + if n := t.Name(); n != "" { + buf.WriteString(t.String()) + } else { + buf.WriteString("interface{}") + } + + case reflect.Array: + buf.WriteRune('[') + buf.WriteString(strconv.FormatInt(int64(t.Len()), 10)) + buf.WriteRune(']') + writeType(buf, 0, t.Elem()) + + case reflect.Slice: + if t == reflect.SliceOf(t.Elem()) { + buf.WriteString("[]") + writeType(buf, 0, t.Elem()) + } else { + // Custom slice type, use type name. + buf.WriteString(t.String()) + } + + case reflect.Map: + if t == reflect.MapOf(t.Key(), t.Elem()) { + buf.WriteString("map[") + writeType(buf, 0, t.Key()) + buf.WriteRune(']') + writeType(buf, 0, t.Elem()) + } else { + // Custom map type, use type name. + buf.WriteString(t.String()) + } + + default: + buf.WriteString(t.String()) + } + + if parens { + buf.WriteRune(')') + } +} + +type sortableValueSlice struct { + kind reflect.Kind + elements []reflect.Value +} + +func (s *sortableValueSlice) Len() int { + return len(s.elements) +} + +func (s *sortableValueSlice) Less(i, j int) bool { + switch s.kind { + case reflect.String: + return s.elements[i].String() < s.elements[j].String() + + case reflect.Int: + return s.elements[i].Int() < s.elements[j].Int() + + default: + panic(fmt.Errorf("unsupported sort kind: %s", s.kind)) + } +} + +func (s *sortableValueSlice) Swap(i, j int) { + s.elements[i], s.elements[j] = s.elements[j], s.elements[i] +} + +func tryAndSortMapKeys(mt reflect.Type, k []reflect.Value) { + // Try our stock sortable values. + switch mt.Key().Kind() { + case reflect.String, reflect.Int: + vs := &sortableValueSlice{ + kind: mt.Key().Kind(), + elements: k, + } + sort.Sort(vs) + } +} diff --git a/vendor/github.com/smartystreets/assertions/internal/oglematchers/LICENSE b/vendor/github.com/smartystreets/assertions/internal/oglematchers/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/vendor/github.com/smartystreets/assertions/internal/oglematchers/LICENSE @@ -0,0 +1,202 @@ + + 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/github.com/smartystreets/assertions/internal/oglematchers/README.md b/vendor/github.com/smartystreets/assertions/internal/oglematchers/README.md new file mode 100644 index 00000000..215a2bb7 --- /dev/null +++ b/vendor/github.com/smartystreets/assertions/internal/oglematchers/README.md @@ -0,0 +1,58 @@ +[](https://godoc.org/github.com/smartystreets/assertions/internal/oglematchers) + +`oglematchers` is a package for the Go programming language containing a set of +matchers, useful in a testing or mocking framework, inspired by and mostly +compatible with [Google Test][googletest] for C++ and +[Google JS Test][google-js-test]. The package is used by the +[ogletest][ogletest] testing framework and [oglemock][oglemock] mocking +framework, which may be more directly useful to you, but can be generically used +elsewhere as well. + +A "matcher" is simply an object with a `Matches` method defining a set of golang +values matched by the matcher, and a `Description` method describing that set. +For example, here are some matchers: + +```go +// Numbers +Equals(17.13) +LessThan(19) + +// Strings +Equals("taco") +HasSubstr("burrito") +MatchesRegex("t.*o") + +// Combining matchers +AnyOf(LessThan(17), GreaterThan(19)) +``` + +There are lots more; see [here][reference] for a reference. You can also add +your own simply by implementing the `oglematchers.Matcher` interface. + + +Installation +------------ + +First, make sure you have installed Go 1.0.2 or newer. See +[here][golang-install] for instructions. + +Use the following command to install `oglematchers` and keep it up to date: + + go get -u github.com/smartystreets/assertions/internal/oglematchers + + +Documentation +------------- + +See [here][reference] for documentation. Alternatively, you can install the +package and then use `godoc`: + + godoc github.com/smartystreets/assertions/internal/oglematchers + + +[reference]: http://godoc.org/github.com/smartystreets/assertions/internal/oglematchers +[golang-install]: http://golang.org/doc/install.html +[googletest]: http://code.google.com/p/googletest/ +[google-js-test]: http://code.google.com/p/google-js-test/ +[ogletest]: http://github.com/smartystreets/assertions/internal/ogletest +[oglemock]: http://github.com/smartystreets/assertions/internal/oglemock diff --git a/vendor/github.com/smartystreets/assertions/internal/oglematchers/all_of.go b/vendor/github.com/smartystreets/assertions/internal/oglematchers/all_of.go new file mode 100644 index 00000000..d93a9740 --- /dev/null +++ b/vendor/github.com/smartystreets/assertions/internal/oglematchers/all_of.go @@ -0,0 +1,70 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// 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. + +package oglematchers + +import ( + "strings" +) + +// AllOf accepts a set of matchers S and returns a matcher that follows the +// algorithm below when considering a candidate c: +// +// 1. Return true if for every Matcher m in S, m matches c. +// +// 2. Otherwise, if there is a matcher m in S such that m returns a fatal +// error for c, return that matcher's error message. +// +// 3. Otherwise, return false with the error from some wrapped matcher. +// +// This is akin to a logical AND operation for matchers. +func AllOf(matchers ...Matcher) Matcher { + return &allOfMatcher{matchers} +} + +type allOfMatcher struct { + wrappedMatchers []Matcher +} + +func (m *allOfMatcher) Description() string { + // Special case: the empty set. + if len(m.wrappedMatchers) == 0 { + return "is anything" + } + + // Join the descriptions for the wrapped matchers. + wrappedDescs := make([]string, len(m.wrappedMatchers)) + for i, wrappedMatcher := range m.wrappedMatchers { + wrappedDescs[i] = wrappedMatcher.Description() + } + + return strings.Join(wrappedDescs, ", and ") +} + +func (m *allOfMatcher) Matches(c interface{}) (err error) { + for _, wrappedMatcher := range m.wrappedMatchers { + if wrappedErr := wrappedMatcher.Matches(c); wrappedErr != nil { + err = wrappedErr + + // If the error is fatal, return immediately with this error. + _, ok := wrappedErr.(*FatalError) + if ok { + return + } + } + } + + return +} diff --git a/vendor/github.com/smartystreets/assertions/internal/oglematchers/any.go b/vendor/github.com/smartystreets/assertions/internal/oglematchers/any.go new file mode 100644 index 00000000..f6991ec1 --- /dev/null +++ b/vendor/github.com/smartystreets/assertions/internal/oglematchers/any.go @@ -0,0 +1,32 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// 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. + +package oglematchers + +// Any returns a matcher that matches any value. +func Any() Matcher { + return &anyMatcher{} +} + +type anyMatcher struct { +} + +func (m *anyMatcher) Description() string { + return "is anything" +} + +func (m *anyMatcher) Matches(c interface{}) error { + return nil +} diff --git a/vendor/github.com/smartystreets/assertions/internal/oglematchers/any_of.go b/vendor/github.com/smartystreets/assertions/internal/oglematchers/any_of.go new file mode 100644 index 00000000..2918b51f --- /dev/null +++ b/vendor/github.com/smartystreets/assertions/internal/oglematchers/any_of.go @@ -0,0 +1,94 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// 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. + +package oglematchers + +import ( + "errors" + "fmt" + "reflect" + "strings" +) + +// AnyOf accepts a set of values S and returns a matcher that follows the +// algorithm below when considering a candidate c: +// +// 1. If there exists a value m in S such that m implements the Matcher +// interface and m matches c, return true. +// +// 2. Otherwise, if there exists a value v in S such that v does not implement +// the Matcher interface and the matcher Equals(v) matches c, return true. +// +// 3. Otherwise, if there is a value m in S such that m implements the Matcher +// interface and m returns a fatal error for c, return that fatal error. +// +// 4. Otherwise, return false. +// +// This is akin to a logical OR operation for matchers, with non-matchers x +// being treated as Equals(x). +func AnyOf(vals ...interface{}) Matcher { + // Get ahold of a type variable for the Matcher interface. + var dummy *Matcher + matcherType := reflect.TypeOf(dummy).Elem() + + // Create a matcher for each value, or use the value itself if it's already a + // matcher. + wrapped := make([]Matcher, len(vals)) + for i, v := range vals { + t := reflect.TypeOf(v) + if t != nil && t.Implements(matcherType) { + wrapped[i] = v.(Matcher) + } else { + wrapped[i] = Equals(v) + } + } + + return &anyOfMatcher{wrapped} +} + +type anyOfMatcher struct { + wrapped []Matcher +} + +func (m *anyOfMatcher) Description() string { + wrappedDescs := make([]string, len(m.wrapped)) + for i, matcher := range m.wrapped { + wrappedDescs[i] = matcher.Description() + } + + return fmt.Sprintf("or(%s)", strings.Join(wrappedDescs, ", ")) +} + +func (m *anyOfMatcher) Matches(c interface{}) (err error) { + err = errors.New("") + + // Try each matcher in turn. + for _, matcher := range m.wrapped { + wrappedErr := matcher.Matches(c) + + // Return immediately if there's a match. + if wrappedErr == nil { + err = nil + return + } + + // Note the fatal error, if any. + if _, isFatal := wrappedErr.(*FatalError); isFatal { + err = wrappedErr + } + } + + return +} diff --git a/vendor/github.com/smartystreets/assertions/internal/oglematchers/contains.go b/vendor/github.com/smartystreets/assertions/internal/oglematchers/contains.go new file mode 100644 index 00000000..2f326dbc --- /dev/null +++ b/vendor/github.com/smartystreets/assertions/internal/oglematchers/contains.go @@ -0,0 +1,61 @@ +// Copyright 2012 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// 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. + +package oglematchers + +import ( + "fmt" + "reflect" +) + +// Return a matcher that matches arrays slices with at least one element that +// matches the supplied argument. If the argument x is not itself a Matcher, +// this is equivalent to Contains(Equals(x)). +func Contains(x interface{}) Matcher { + var result containsMatcher + var ok bool + + if result.elementMatcher, ok = x.(Matcher); !ok { + result.elementMatcher = Equals(x) + } + + return &result +} + +type containsMatcher struct { + elementMatcher Matcher +} + +func (m *containsMatcher) Description() string { + return fmt.Sprintf("contains: %s", m.elementMatcher.Description()) +} + +func (m *containsMatcher) Matches(candidate interface{}) error { + // The candidate must be a slice or an array. + v := reflect.ValueOf(candidate) + if v.Kind() != reflect.Slice && v.Kind() != reflect.Array { + return NewFatalError("which is not a slice or array") + } + + // Check each element. + for i := 0; i < v.Len(); i++ { + elem := v.Index(i) + if matchErr := m.elementMatcher.Matches(elem.Interface()); matchErr == nil { + return nil + } + } + + return fmt.Errorf("") +} diff --git a/vendor/github.com/smartystreets/assertions/internal/oglematchers/deep_equals.go b/vendor/github.com/smartystreets/assertions/internal/oglematchers/deep_equals.go new file mode 100644 index 00000000..1d91baef --- /dev/null +++ b/vendor/github.com/smartystreets/assertions/internal/oglematchers/deep_equals.go @@ -0,0 +1,88 @@ +// Copyright 2012 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// 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. + +package oglematchers + +import ( + "bytes" + "errors" + "fmt" + "reflect" +) + +var byteSliceType reflect.Type = reflect.TypeOf([]byte{}) + +// DeepEquals returns a matcher that matches based on 'deep equality', as +// defined by the reflect package. This matcher requires that values have +// identical types to x. +func DeepEquals(x interface{}) Matcher { + return &deepEqualsMatcher{x} +} + +type deepEqualsMatcher struct { + x interface{} +} + +func (m *deepEqualsMatcher) Description() string { + xDesc := fmt.Sprintf("%v", m.x) + xValue := reflect.ValueOf(m.x) + + // Special case: fmt.Sprintf presents nil slices as "[]", but + // reflect.DeepEqual makes a distinction between nil and empty slices. Make + // this less confusing. + if xValue.Kind() == reflect.Slice && xValue.IsNil() { + xDesc = "<nil slice>" + } + + return fmt.Sprintf("deep equals: %s", xDesc) +} + +func (m *deepEqualsMatcher) Matches(c interface{}) error { + // Make sure the types match. + ct := reflect.TypeOf(c) + xt := reflect.TypeOf(m.x) + + if ct != xt { + return NewFatalError(fmt.Sprintf("which is of type %v", ct)) + } + + // Special case: handle byte slices more efficiently. + cValue := reflect.ValueOf(c) + xValue := reflect.ValueOf(m.x) + + if ct == byteSliceType && !cValue.IsNil() && !xValue.IsNil() { + xBytes := m.x.([]byte) + cBytes := c.([]byte) + + if bytes.Equal(cBytes, xBytes) { + return nil + } + + return errors.New("") + } + + // Defer to the reflect package. + if reflect.DeepEqual(m.x, c) { + return nil + } + + // Special case: if the comparison failed because c is the nil slice, given + // an indication of this (since its value is printed as "[]"). + if cValue.Kind() == reflect.Slice && cValue.IsNil() { + return errors.New("which is nil") + } + + return errors.New("") +} diff --git a/vendor/github.com/smartystreets/assertions/internal/oglematchers/elements_are.go b/vendor/github.com/smartystreets/assertions/internal/oglematchers/elements_are.go new file mode 100644 index 00000000..2941847c --- /dev/null +++ b/vendor/github.com/smartystreets/assertions/internal/oglematchers/elements_are.go @@ -0,0 +1,91 @@ +// Copyright 2012 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// 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. + +package oglematchers + +import ( + "errors" + "fmt" + "reflect" + "strings" +) + +// Given a list of arguments M, ElementsAre returns a matcher that matches +// arrays and slices A where all of the following hold: +// +// * A is the same length as M. +// +// * For each i < len(A) where M[i] is a matcher, A[i] matches M[i]. +// +// * For each i < len(A) where M[i] is not a matcher, A[i] matches +// Equals(M[i]). +// +func ElementsAre(M ...interface{}) Matcher { + // Copy over matchers, or convert to Equals(x) for non-matcher x. + subMatchers := make([]Matcher, len(M)) + for i, x := range M { + if matcher, ok := x.(Matcher); ok { + subMatchers[i] = matcher + continue + } + + subMatchers[i] = Equals(x) + } + + return &elementsAreMatcher{subMatchers} +} + +type elementsAreMatcher struct { + subMatchers []Matcher +} + +func (m *elementsAreMatcher) Description() string { + subDescs := make([]string, len(m.subMatchers)) + for i, sm := range m.subMatchers { + subDescs[i] = sm.Description() + } + + return fmt.Sprintf("elements are: [%s]", strings.Join(subDescs, ", ")) +} + +func (m *elementsAreMatcher) Matches(candidates interface{}) error { + // The candidate must be a slice or an array. + v := reflect.ValueOf(candidates) + if v.Kind() != reflect.Slice && v.Kind() != reflect.Array { + return NewFatalError("which is not a slice or array") + } + + // The length must be correct. + if v.Len() != len(m.subMatchers) { + return errors.New(fmt.Sprintf("which is of length %d", v.Len())) + } + + // Check each element. + for i, subMatcher := range m.subMatchers { + c := v.Index(i) + if matchErr := subMatcher.Matches(c.Interface()); matchErr != nil { + // Return an errors indicating which element doesn't match. If the + // matcher error was fatal, make this one fatal too. + err := errors.New(fmt.Sprintf("whose element %d doesn't match", i)) + if _, isFatal := matchErr.(*FatalError); isFatal { + err = NewFatalError(err.Error()) + } + + return err + } + } + + return nil +} diff --git a/vendor/github.com/smartystreets/assertions/internal/oglematchers/equals.go b/vendor/github.com/smartystreets/assertions/internal/oglematchers/equals.go new file mode 100644 index 00000000..a510707b --- /dev/null +++ b/vendor/github.com/smartystreets/assertions/internal/oglematchers/equals.go @@ -0,0 +1,541 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// 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. + +package oglematchers + +import ( + "errors" + "fmt" + "math" + "reflect" +) + +// Equals(x) returns a matcher that matches values v such that v and x are +// equivalent. This includes the case when the comparison v == x using Go's +// built-in comparison operator is legal (except for structs, which this +// matcher does not support), but for convenience the following rules also +// apply: +// +// * Type checking is done based on underlying types rather than actual +// types, so that e.g. two aliases for string can be compared: +// +// type stringAlias1 string +// type stringAlias2 string +// +// a := "taco" +// b := stringAlias1("taco") +// c := stringAlias2("taco") +// +// ExpectTrue(a == b) // Legal, passes +// ExpectTrue(b == c) // Illegal, doesn't compile +// +// ExpectThat(a, Equals(b)) // Passes +// ExpectThat(b, Equals(c)) // Passes +// +// * Values of numeric type are treated as if they were abstract numbers, and +// compared accordingly. Therefore Equals(17) will match int(17), +// int16(17), uint(17), float32(17), complex64(17), and so on. +// +// If you want a stricter matcher that contains no such cleverness, see +// IdenticalTo instead. +// +// Arrays are supported by this matcher, but do not participate in the +// exceptions above. Two arrays compared with this matcher must have identical +// types, and their element type must itself be comparable according to Go's == +// operator. +func Equals(x interface{}) Matcher { + v := reflect.ValueOf(x) + + // This matcher doesn't support structs. + if v.Kind() == reflect.Struct { + panic(fmt.Sprintf("oglematchers.Equals: unsupported kind %v", v.Kind())) + } + + // The == operator is not defined for non-nil slices. + if v.Kind() == reflect.Slice && v.Pointer() != uintptr(0) { + panic(fmt.Sprintf("oglematchers.Equals: non-nil slice")) + } + + return &equalsMatcher{v} +} + +type equalsMatcher struct { + expectedValue reflect.Value +} + +//////////////////////////////////////////////////////////////////////// +// Numeric types +//////////////////////////////////////////////////////////////////////// + +func isSignedInteger(v reflect.Value) bool { + k := v.Kind() + return k >= reflect.Int && k <= reflect.Int64 +} + +func isUnsignedInteger(v reflect.Value) bool { + k := v.Kind() + return k >= reflect.Uint && k <= reflect.Uintptr +} + +func isInteger(v reflect.Value) bool { + return isSignedInteger(v) || isUnsignedInteger(v) +} + +func isFloat(v reflect.Value) bool { + k := v.Kind() + return k == reflect.Float32 || k == reflect.Float64 +} + +func isComplex(v reflect.Value) bool { + k := v.Kind() + return k == reflect.Complex64 || k == reflect.Complex128 +} + +func checkAgainstInt64(e int64, c reflect.Value) (err error) { + err = errors.New("") + + switch { + case isSignedInteger(c): + if c.Int() == e { + err = nil + } + + case isUnsignedInteger(c): + u := c.Uint() + if u <= math.MaxInt64 && int64(u) == e { + err = nil + } + + // Turn around the various floating point types so that the checkAgainst* + // functions for them can deal with precision issues. + case isFloat(c), isComplex(c): + return Equals(c.Interface()).Matches(e) + + default: + err = NewFatalError("which is not numeric") + } + + return +} + +func checkAgainstUint64(e uint64, c reflect.Value) (err error) { + err = errors.New("") + + switch { + case isSignedInteger(c): + i := c.Int() + if i >= 0 && uint64(i) == e { + err = nil + } + + case isUnsignedInteger(c): + if c.Uint() == e { + err = nil + } + + // Turn around the various floating point types so that the checkAgainst* + // functions for them can deal with precision issues. + case isFloat(c), isComplex(c): + return Equals(c.Interface()).Matches(e) + + default: + err = NewFatalError("which is not numeric") + } + + return +} + +func checkAgainstFloat32(e float32, c reflect.Value) (err error) { + err = errors.New("") + + switch { + case isSignedInteger(c): + if float32(c.Int()) == e { + err = nil + } + + case isUnsignedInteger(c): + if float32(c.Uint()) == e { + err = nil + } + + case isFloat(c): + // Compare using float32 to avoid a false sense of precision; otherwise + // e.g. Equals(float32(0.1)) won't match float32(0.1). + if float32(c.Float()) == e { + err = nil + } + + case isComplex(c): + comp := c.Complex() + rl := real(comp) + im := imag(comp) + + // Compare using float32 to avoid a false sense of precision; otherwise + // e.g. Equals(float32(0.1)) won't match (0.1 + 0i). + if im == 0 && float32(rl) == e { + err = nil + } + + default: + err = NewFatalError("which is not numeric") + } + + return +} + +func checkAgainstFloat64(e float64, c reflect.Value) (err error) { + err = errors.New("") + + ck := c.Kind() + + switch { + case isSignedInteger(c): + if float64(c.Int()) == e { + err = nil + } + + case isUnsignedInteger(c): + if float64(c.Uint()) == e { + err = nil + } + + // If the actual value is lower precision, turn the comparison around so we + // apply the low-precision rules. Otherwise, e.g. Equals(0.1) may not match + // float32(0.1). + case ck == reflect.Float32 || ck == reflect.Complex64: + return Equals(c.Interface()).Matches(e) + + // Otherwise, compare with double precision. + case isFloat(c): + if c.Float() == e { + err = nil + } + + case isComplex(c): + comp := c.Complex() + rl := real(comp) + im := imag(comp) + + if im == 0 && rl == e { + err = nil + } + + default: + err = NewFatalError("which is not numeric") + } + + return +} + +func checkAgainstComplex64(e complex64, c reflect.Value) (err error) { + err = errors.New("") + realPart := real(e) + imaginaryPart := imag(e) + + switch { + case isInteger(c) || isFloat(c): + // If we have no imaginary part, then we should just compare against the + // real part. Otherwise, we can't be equal. + if imaginaryPart != 0 { + return + } + + return checkAgainstFloat32(realPart, c) + + case isComplex(c): + // Compare using complex64 to avoid a false sense of precision; otherwise + // e.g. Equals(0.1 + 0i) won't match float32(0.1). + if complex64(c.Complex()) == e { + err = nil + } + + default: + err = NewFatalError("which is not numeric") + } + + return +} + +func checkAgainstComplex128(e complex128, c reflect.Value) (err error) { + err = errors.New("") + realPart := real(e) + imaginaryPart := imag(e) + + switch { + case isInteger(c) || isFloat(c): + // If we have no imaginary part, then we should just compare against the + // real part. Otherwise, we can't be equal. + if imaginaryPart != 0 { + return + } + + return checkAgainstFloat64(realPart, c) + + case isComplex(c): + if c.Complex() == e { + err = nil + } + + default: + err = NewFatalError("which is not numeric") + } + + return +} + +//////////////////////////////////////////////////////////////////////// +// Other types +//////////////////////////////////////////////////////////////////////// + +func checkAgainstBool(e bool, c reflect.Value) (err error) { + if c.Kind() != reflect.Bool { + err = NewFatalError("which is not a bool") + return + } + + err = errors.New("") + if c.Bool() == e { + err = nil + } + return +} + +func checkAgainstChan(e reflect.Value, c reflect.Value) (err error) { + // Create a description of e's type, e.g. "chan int". + typeStr := fmt.Sprintf("%s %s", e.Type().ChanDir(), e.Type().Elem()) + + // Make sure c is a chan of the correct type. + if c.Kind() != reflect.Chan || + c.Type().ChanDir() != e.Type().ChanDir() || + c.Type().Elem() != e.Type().Elem() { + err = NewFatalError(fmt.Sprintf("which is not a %s", typeStr)) + return + } + + err = errors.New("") + if c.Pointer() == e.Pointer() { + err = nil + } + return +} + +func checkAgainstFunc(e reflect.Value, c reflect.Value) (err error) { + // Make sure c is a function. + if c.Kind() != reflect.Func { + err = NewFatalError("which is not a function") + return + } + + err = errors.New("") + if c.Pointer() == e.Pointer() { + err = nil + } + return +} + +func checkAgainstMap(e reflect.Value, c reflect.Value) (err error) { + // Make sure c is a map. + if c.Kind() != reflect.Map { + err = NewFatalError("which is not a map") + return + } + + err = errors.New("") + if c.Pointer() == e.Pointer() { + err = nil + } + return +} + +func checkAgainstPtr(e reflect.Value, c reflect.Value) (err error) { + // Create a description of e's type, e.g. "*int". + typeStr := fmt.Sprintf("*%v", e.Type().Elem()) + + // Make sure c is a pointer of the correct type. + if c.Kind() != reflect.Ptr || + c.Type().Elem() != e.Type().Elem() { + err = NewFatalError(fmt.Sprintf("which is not a %s", typeStr)) + return + } + + err = errors.New("") + if c.Pointer() == e.Pointer() { + err = nil + } + return +} + +func checkAgainstSlice(e reflect.Value, c reflect.Value) (err error) { + // Create a description of e's type, e.g. "[]int". + typeStr := fmt.Sprintf("[]%v", e.Type().Elem()) + + // Make sure c is a slice of the correct type. + if c.Kind() != reflect.Slice || + c.Type().Elem() != e.Type().Elem() { + err = NewFatalError(fmt.Sprintf("which is not a %s", typeStr)) + return + } + + err = errors.New("") + if c.Pointer() == e.Pointer() { + err = nil + } + return +} + +func checkAgainstString(e reflect.Value, c reflect.Value) (err error) { + // Make sure c is a string. + if c.Kind() != reflect.String { + err = NewFatalError("which is not a string") + return + } + + err = errors.New("") + if c.String() == e.String() { + err = nil + } + return +} + +func checkAgainstArray(e reflect.Value, c reflect.Value) (err error) { + // Create a description of e's type, e.g. "[2]int". + typeStr := fmt.Sprintf("%v", e.Type()) + + // Make sure c is the correct type. + if c.Type() != e.Type() { + err = NewFatalError(fmt.Sprintf("which is not %s", typeStr)) + return + } + + // Check for equality. + if e.Interface() != c.Interface() { + err = errors.New("") + return + } + + return +} + +func checkAgainstUnsafePointer(e reflect.Value, c reflect.Value) (err error) { + // Make sure c is a pointer. + if c.Kind() != reflect.UnsafePointer { + err = NewFatalError("which is not a unsafe.Pointer") + return + } + + err = errors.New("") + if c.Pointer() == e.Pointer() { + err = nil + } + return +} + +func checkForNil(c reflect.Value) (err error) { + err = errors.New("") + + // Make sure it is legal to call IsNil. + switch c.Kind() { + case reflect.Invalid: + case reflect.Chan: + case reflect.Func: + case reflect.Interface: + case reflect.Map: + case reflect.Ptr: + case reflect.Slice: + + default: + err = NewFatalError("which cannot be compared to nil") + return + } + + // Ask whether the value is nil. Handle a nil literal (kind Invalid) + // specially, since it's not legal to call IsNil there. + if c.Kind() == reflect.Invalid || c.IsNil() { + err = nil + } + return +} + +//////////////////////////////////////////////////////////////////////// +// Public implementation +//////////////////////////////////////////////////////////////////////// + +func (m *equalsMatcher) Matches(candidate interface{}) error { + e := m.expectedValue + c := reflect.ValueOf(candidate) + ek := e.Kind() + + switch { + case ek == reflect.Bool: + return checkAgainstBool(e.Bool(), c) + + case isSignedInteger(e): + return checkAgainstInt64(e.Int(), c) + + case isUnsignedInteger(e): + return checkAgainstUint64(e.Uint(), c) + + case ek == reflect.Float32: + return checkAgainstFloat32(float32(e.Float()), c) + + case ek == reflect.Float64: + return checkAgainstFloat64(e.Float(), c) + + case ek == reflect.Complex64: + return checkAgainstComplex64(complex64(e.Complex()), c) + + case ek == reflect.Complex128: + return checkAgainstComplex128(complex128(e.Complex()), c) + + case ek == reflect.Chan: + return checkAgainstChan(e, c) + + case ek == reflect.Func: + return checkAgainstFunc(e, c) + + case ek == reflect.Map: + return checkAgainstMap(e, c) + + case ek == reflect.Ptr: + return checkAgainstPtr(e, c) + + case ek == reflect.Slice: + return checkAgainstSlice(e, c) + + case ek == reflect.String: + return checkAgainstString(e, c) + + case ek == reflect.Array: + return checkAgainstArray(e, c) + + case ek == reflect.UnsafePointer: + return checkAgainstUnsafePointer(e, c) + + case ek == reflect.Invalid: + return checkForNil(c) + } + + panic(fmt.Sprintf("equalsMatcher.Matches: unexpected kind: %v", ek)) +} + +func (m *equalsMatcher) Description() string { + // Special case: handle nil. + if !m.expectedValue.IsValid() { + return "is nil" + } + + return fmt.Sprintf("%v", m.expectedValue.Interface()) +} diff --git a/vendor/github.com/smartystreets/assertions/internal/oglematchers/error.go b/vendor/github.com/smartystreets/assertions/internal/oglematchers/error.go new file mode 100644 index 00000000..8a078e36 --- /dev/null +++ b/vendor/github.com/smartystreets/assertions/internal/oglematchers/error.go @@ -0,0 +1,51 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// 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. + +package oglematchers + +// Error returns a matcher that matches non-nil values implementing the +// built-in error interface for whom the return value of Error() matches the +// supplied matcher. +// +// For example: +// +// err := errors.New("taco burrito") +// +// Error(Equals("taco burrito")) // matches err +// Error(HasSubstr("taco")) // matches err +// Error(HasSubstr("enchilada")) // doesn't match err +// +func Error(m Matcher) Matcher { + return &errorMatcher{m} +} + +type errorMatcher struct { + wrappedMatcher Matcher +} + +func (m *errorMatcher) Description() string { + return "error " + m.wrappedMatcher.Description() +} + +func (m *errorMatcher) Matches(c interface{}) error { + // Make sure that c is an error. + e, ok := c.(error) + if !ok { + return NewFatalError("which is not an error") + } + + // Pass on the error text to the wrapped matcher. + return m.wrappedMatcher.Matches(e.Error()) +} diff --git a/vendor/github.com/smartystreets/assertions/internal/oglematchers/greater_or_equal.go b/vendor/github.com/smartystreets/assertions/internal/oglematchers/greater_or_equal.go new file mode 100644 index 00000000..4b9d103a --- /dev/null +++ b/vendor/github.com/smartystreets/assertions/internal/oglematchers/greater_or_equal.go @@ -0,0 +1,39 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// 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. + +package oglematchers + +import ( + "fmt" + "reflect" +) + +// GreaterOrEqual returns a matcher that matches integer, floating point, or +// strings values v such that v >= x. Comparison is not defined between numeric +// and string types, but is defined between all integer and floating point +// types. +// +// x must itself be an integer, floating point, or string type; otherwise, +// GreaterOrEqual will panic. +func GreaterOrEqual(x interface{}) Matcher { + desc := fmt.Sprintf("greater than or equal to %v", x) + + // Special case: make it clear that strings are strings. + if reflect.TypeOf(x).Kind() == reflect.String { + desc = fmt.Sprintf("greater than or equal to \"%s\"", x) + } + + return transformDescription(Not(LessThan(x)), desc) +} diff --git a/vendor/github.com/smartystreets/assertions/internal/oglematchers/greater_than.go b/vendor/github.com/smartystreets/assertions/internal/oglematchers/greater_than.go new file mode 100644 index 00000000..3eef3217 --- /dev/null +++ b/vendor/github.com/smartystreets/assertions/internal/oglematchers/greater_than.go @@ -0,0 +1,39 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// 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. + +package oglematchers + +import ( + "fmt" + "reflect" +) + +// GreaterThan returns a matcher that matches integer, floating point, or +// strings values v such that v > x. Comparison is not defined between numeric +// and string types, but is defined between all integer and floating point +// types. +// +// x must itself be an integer, floating point, or string type; otherwise, +// GreaterThan will panic. +func GreaterThan(x interface{}) Matcher { + desc := fmt.Sprintf("greater than %v", x) + + // Special case: make it clear that strings are strings. + if reflect.TypeOf(x).Kind() == reflect.String { + desc = fmt.Sprintf("greater than \"%s\"", x) + } + + return transformDescription(Not(LessOrEqual(x)), desc) +} diff --git a/vendor/github.com/smartystreets/assertions/internal/oglematchers/has_same_type_as.go b/vendor/github.com/smartystreets/assertions/internal/oglematchers/has_same_type_as.go new file mode 100644 index 00000000..3b286f73 --- /dev/null +++ b/vendor/github.com/smartystreets/assertions/internal/oglematchers/has_same_type_as.go @@ -0,0 +1,37 @@ +// Copyright 2015 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// 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. + +package oglematchers + +import ( + "fmt" + "reflect" +) + +// HasSameTypeAs returns a matcher that matches values with exactly the same +// type as the supplied prototype. +func HasSameTypeAs(p interface{}) Matcher { + expected := reflect.TypeOf(p) + pred := func(c interface{}) error { + actual := reflect.TypeOf(c) + if actual != expected { + return fmt.Errorf("which has type %v", actual) + } + + return nil + } + + return NewMatcher(pred, fmt.Sprintf("has type %v", expected)) +} diff --git a/vendor/github.com/smartystreets/assertions/internal/oglematchers/has_substr.go b/vendor/github.com/smartystreets/assertions/internal/oglematchers/has_substr.go new file mode 100644 index 00000000..bf5bd6ae --- /dev/null +++ b/vendor/github.com/smartystreets/assertions/internal/oglematchers/has_substr.go @@ -0,0 +1,46 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// 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. + +package oglematchers + +import ( + "errors" + "fmt" + "reflect" + "strings" +) + +// HasSubstr returns a matcher that matches strings containing s as a +// substring. +func HasSubstr(s string) Matcher { + return NewMatcher( + func(c interface{}) error { return hasSubstr(s, c) }, + fmt.Sprintf("has substring \"%s\"", s)) +} + +func hasSubstr(needle string, c interface{}) error { + v := reflect.ValueOf(c) + if v.Kind() != reflect.String { + return NewFatalError("which is not a string") + } + + // Perform the substring search. + haystack := v.String() + if strings.Contains(haystack, needle) { + return nil + } + + return errors.New("") +} diff --git a/vendor/github.com/smartystreets/assertions/internal/oglematchers/identical_to.go b/vendor/github.com/smartystreets/assertions/internal/oglematchers/identical_to.go new file mode 100644 index 00000000..ae6460ed --- /dev/null +++ b/vendor/github.com/smartystreets/assertions/internal/oglematchers/identical_to.go @@ -0,0 +1,134 @@ +// Copyright 2012 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// 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. + +package oglematchers + +import ( + "errors" + "fmt" + "reflect" +) + +// Is the type comparable according to the definition here? +// +// http://weekly.golang.org/doc/go_spec.html#Comparison_operators +// +func isComparable(t reflect.Type) bool { + switch t.Kind() { + case reflect.Array: + return isComparable(t.Elem()) + + case reflect.Struct: + for i := 0; i < t.NumField(); i++ { + if !isComparable(t.Field(i).Type) { + return false + } + } + + return true + + case reflect.Slice, reflect.Map, reflect.Func: + return false + } + + return true +} + +// Should the supplied type be allowed as an argument to IdenticalTo? +func isLegalForIdenticalTo(t reflect.Type) (bool, error) { + // Allow the zero type. + if t == nil { + return true, nil + } + + // Reference types are always okay; we compare pointers. + switch t.Kind() { + case reflect.Slice, reflect.Map, reflect.Func, reflect.Chan: + return true, nil + } + + // Reject other non-comparable types. + if !isComparable(t) { + return false, errors.New(fmt.Sprintf("%v is not comparable", t)) + } + + return true, nil +} + +// IdenticalTo(x) returns a matcher that matches values v with type identical +// to x such that: +// +// 1. If v and x are of a reference type (slice, map, function, channel), then +// they are either both nil or are references to the same object. +// +// 2. Otherwise, if v and x are not of a reference type but have a valid type, +// then v == x. +// +// If v and x are both the invalid type (which results from the predeclared nil +// value, or from nil interface variables), then the matcher is satisfied. +// +// This function will panic if x is of a value type that is not comparable. For +// example, x cannot be an array of functions. +func IdenticalTo(x interface{}) Matcher { + t := reflect.TypeOf(x) + + // Reject illegal arguments. + if ok, err := isLegalForIdenticalTo(t); !ok { + panic("IdenticalTo: " + err.Error()) + } + + return &identicalToMatcher{x} +} + +type identicalToMatcher struct { + x interface{} +} + +func (m *identicalToMatcher) Description() string { + t := reflect.TypeOf(m.x) + return fmt.Sprintf("identical to <%v> %v", t, m.x) +} + +func (m *identicalToMatcher) Matches(c interface{}) error { + // Make sure the candidate's type is correct. + t := reflect.TypeOf(m.x) + if ct := reflect.TypeOf(c); t != ct { + return NewFatalError(fmt.Sprintf("which is of type %v", ct)) + } + + // Special case: two values of the invalid type are always identical. + if t == nil { + return nil + } + + // Handle reference types. + switch t.Kind() { + case reflect.Slice, reflect.Map, reflect.Func, reflect.Chan: + xv := reflect.ValueOf(m.x) + cv := reflect.ValueOf(c) + if xv.Pointer() == cv.Pointer() { + return nil + } + + return errors.New("which is not an identical reference") + } + + // Are the values equal? + if m.x == c { + return nil + } + + return errors.New("") +} diff --git a/vendor/github.com/smartystreets/assertions/internal/oglematchers/less_or_equal.go b/vendor/github.com/smartystreets/assertions/internal/oglematchers/less_or_equal.go new file mode 100644 index 00000000..8402cdea --- /dev/null +++ b/vendor/github.com/smartystreets/assertions/internal/oglematchers/less_or_equal.go @@ -0,0 +1,41 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// 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. + +package oglematchers + +import ( + "fmt" + "reflect" +) + +// LessOrEqual returns a matcher that matches integer, floating point, or +// strings values v such that v <= x. Comparison is not defined between numeric +// and string types, but is defined between all integer and floating point +// types. +// +// x must itself be an integer, floating point, or string type; otherwise, +// LessOrEqual will panic. +func LessOrEqual(x interface{}) Matcher { + desc := fmt.Sprintf("less than or equal to %v", x) + + // Special case: make it clear that strings are strings. + if reflect.TypeOf(x).Kind() == reflect.String { + desc = fmt.Sprintf("less than or equal to \"%s\"", x) + } + + // Put LessThan last so that its error messages will be used in the event of + // failure. + return transformDescription(AnyOf(Equals(x), LessThan(x)), desc) +} diff --git a/vendor/github.com/smartystreets/assertions/internal/oglematchers/less_than.go b/vendor/github.com/smartystreets/assertions/internal/oglematchers/less_than.go new file mode 100644 index 00000000..8258e45d --- /dev/null +++ b/vendor/github.com/smartystreets/assertions/internal/oglematchers/less_than.go @@ -0,0 +1,152 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// 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. + +package oglematchers + +import ( + "errors" + "fmt" + "math" + "reflect" +) + +// LessThan returns a matcher that matches integer, floating point, or strings +// values v such that v < x. Comparison is not defined between numeric and +// string types, but is defined between all integer and floating point types. +// +// x must itself be an integer, floating point, or string type; otherwise, +// LessThan will panic. +func LessThan(x interface{}) Matcher { + v := reflect.ValueOf(x) + kind := v.Kind() + + switch { + case isInteger(v): + case isFloat(v): + case kind == reflect.String: + + default: + panic(fmt.Sprintf("LessThan: unexpected kind %v", kind)) + } + + return &lessThanMatcher{v} +} + +type lessThanMatcher struct { + limit reflect.Value +} + +func (m *lessThanMatcher) Description() string { + // Special case: make it clear that strings are strings. + if m.limit.Kind() == reflect.String { + return fmt.Sprintf("less than \"%s\"", m.limit.String()) + } + + return fmt.Sprintf("less than %v", m.limit.Interface()) +} + +func compareIntegers(v1, v2 reflect.Value) (err error) { + err = errors.New("") + + switch { + case isSignedInteger(v1) && isSignedInteger(v2): + if v1.Int() < v2.Int() { + err = nil + } + return + + case isSignedInteger(v1) && isUnsignedInteger(v2): + if v1.Int() < 0 || uint64(v1.Int()) < v2.Uint() { + err = nil + } + return + + case isUnsignedInteger(v1) && isSignedInteger(v2): + if v1.Uint() <= math.MaxInt64 && int64(v1.Uint()) < v2.Int() { + err = nil + } + return + + case isUnsignedInteger(v1) && isUnsignedInteger(v2): + if v1.Uint() < v2.Uint() { + err = nil + } + return + } + + panic(fmt.Sprintf("compareIntegers: %v %v", v1, v2)) +} + +func getFloat(v reflect.Value) float64 { + switch { + case isSignedInteger(v): + return float64(v.Int()) + + case isUnsignedInteger(v): + return float64(v.Uint()) + + case isFloat(v): + return v.Float() + } + + panic(fmt.Sprintf("getFloat: %v", v)) +} + +func (m *lessThanMatcher) Matches(c interface{}) (err error) { + v1 := reflect.ValueOf(c) + v2 := m.limit + + err = errors.New("") + + // Handle strings as a special case. + if v1.Kind() == reflect.String && v2.Kind() == reflect.String { + if v1.String() < v2.String() { + err = nil + } + return + } + + // If we get here, we require that we are dealing with integers or floats. + v1Legal := isInteger(v1) || isFloat(v1) + v2Legal := isInteger(v2) || isFloat(v2) + if !v1Legal || !v2Legal { + err = NewFatalError("which is not comparable") + return + } + + // Handle the various comparison cases. + switch { + // Both integers + case isInteger(v1) && isInteger(v2): + return compareIntegers(v1, v2) + + // At least one float32 + case v1.Kind() == reflect.Float32 || v2.Kind() == reflect.Float32: + if float32(getFloat(v1)) < float32(getFloat(v2)) { + err = nil + } + return + + // At least one float64 + case v1.Kind() == reflect.Float64 || v2.Kind() == reflect.Float64: + if getFloat(v1) < getFloat(v2) { + err = nil + } + return + } + + // We shouldn't get here. + panic(fmt.Sprintf("lessThanMatcher.Matches: Shouldn't get here: %v %v", v1, v2)) +} diff --git a/vendor/github.com/smartystreets/assertions/internal/oglematchers/matcher.go b/vendor/github.com/smartystreets/assertions/internal/oglematchers/matcher.go new file mode 100644 index 00000000..78159a07 --- /dev/null +++ b/vendor/github.com/smartystreets/assertions/internal/oglematchers/matcher.go @@ -0,0 +1,86 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// 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. + +// Package oglematchers provides a set of matchers useful in a testing or +// mocking framework. These matchers are inspired by and mostly compatible with +// Google Test for C++ and Google JS Test. +// +// This package is used by github.com/smartystreets/assertions/internal/ogletest and +// github.com/smartystreets/assertions/internal/oglemock, which may be more directly useful if you're not +// writing your own testing package or defining your own matchers. +package oglematchers + +// A Matcher is some predicate implicitly defining a set of values that it +// matches. For example, GreaterThan(17) matches all numeric values greater +// than 17, and HasSubstr("taco") matches all strings with the substring +// "taco". +// +// Matchers are typically exposed to tests via constructor functions like +// HasSubstr. In order to implement such a function you can either define your +// own matcher type or use NewMatcher. +type Matcher interface { + // Check whether the supplied value belongs to the the set defined by the + // matcher. Return a non-nil error if and only if it does not. + // + // The error describes why the value doesn't match. The error text is a + // relative clause that is suitable for being placed after the value. For + // example, a predicate that matches strings with a particular substring may, + // when presented with a numerical value, return the following error text: + // + // "which is not a string" + // + // Then the failure message may look like: + // + // Expected: has substring "taco" + // Actual: 17, which is not a string + // + // If the error is self-apparent based on the description of the matcher, the + // error text may be empty (but the error still non-nil). For example: + // + // Expected: 17 + // Actual: 19 + // + // If you are implementing a new matcher, see also the documentation on + // FatalError. + Matches(candidate interface{}) error + + // Description returns a string describing the property that values matching + // this matcher have, as a verb phrase where the subject is the value. For + // example, "is greather than 17" or "has substring "taco"". + Description() string +} + +// FatalError is an implementation of the error interface that may be returned +// from matchers, indicating the error should be propagated. Returning a +// *FatalError indicates that the matcher doesn't process values of the +// supplied type, or otherwise doesn't know how to handle the value. +// +// For example, if GreaterThan(17) returned false for the value "taco" without +// a fatal error, then Not(GreaterThan(17)) would return true. This is +// technically correct, but is surprising and may mask failures where the wrong +// sort of matcher is accidentally used. Instead, GreaterThan(17) can return a +// fatal error, which will be propagated by Not(). +type FatalError struct { + errorText string +} + +// NewFatalError creates a FatalError struct with the supplied error text. +func NewFatalError(s string) *FatalError { + return &FatalError{s} +} + +func (e *FatalError) Error() string { + return e.errorText +} diff --git a/vendor/github.com/smartystreets/assertions/internal/oglematchers/matches_regexp.go b/vendor/github.com/smartystreets/assertions/internal/oglematchers/matches_regexp.go new file mode 100644 index 00000000..1ed63f30 --- /dev/null +++ b/vendor/github.com/smartystreets/assertions/internal/oglematchers/matches_regexp.go @@ -0,0 +1,69 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// 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. + +package oglematchers + +import ( + "errors" + "fmt" + "reflect" + "regexp" +) + +// MatchesRegexp returns a matcher that matches strings and byte slices whose +// contents match the supplied regular expression. The semantics are those of +// regexp.Match. In particular, that means the match is not implicitly anchored +// to the ends of the string: MatchesRegexp("bar") will match "foo bar baz". +func MatchesRegexp(pattern string) Matcher { + re, err := regexp.Compile(pattern) + if err != nil { + panic("MatchesRegexp: " + err.Error()) + } + + return &matchesRegexpMatcher{re} +} + +type matchesRegexpMatcher struct { + re *regexp.Regexp +} + +func (m *matchesRegexpMatcher) Description() string { + return fmt.Sprintf("matches regexp \"%s\"", m.re.String()) +} + +func (m *matchesRegexpMatcher) Matches(c interface{}) (err error) { + v := reflect.ValueOf(c) + isString := v.Kind() == reflect.String + isByteSlice := v.Kind() == reflect.Slice && v.Elem().Kind() == reflect.Uint8 + + err = errors.New("") + + switch { + case isString: + if m.re.MatchString(v.String()) { + err = nil + } + + case isByteSlice: + if m.re.Match(v.Bytes()) { + err = nil + } + + default: + err = NewFatalError("which is not a string or []byte") + } + + return +} diff --git a/vendor/github.com/smartystreets/assertions/internal/oglematchers/new_matcher.go b/vendor/github.com/smartystreets/assertions/internal/oglematchers/new_matcher.go new file mode 100644 index 00000000..c9d8398e --- /dev/null +++ b/vendor/github.com/smartystreets/assertions/internal/oglematchers/new_matcher.go @@ -0,0 +1,43 @@ +// Copyright 2015 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// 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. + +package oglematchers + +// Create a matcher with the given description and predicate function, which +// will be invoked to handle calls to Matchers. +// +// Using this constructor may be a convenience over defining your own type that +// implements Matcher if you do not need any logic in your Description method. +func NewMatcher( + predicate func(interface{}) error, + description string) Matcher { + return &predicateMatcher{ + predicate: predicate, + description: description, + } +} + +type predicateMatcher struct { + predicate func(interface{}) error + description string +} + +func (pm *predicateMatcher) Matches(c interface{}) error { + return pm.predicate(c) +} + +func (pm *predicateMatcher) Description() string { + return pm.description +} diff --git a/vendor/github.com/smartystreets/assertions/internal/oglematchers/not.go b/vendor/github.com/smartystreets/assertions/internal/oglematchers/not.go new file mode 100644 index 00000000..623789fe --- /dev/null +++ b/vendor/github.com/smartystreets/assertions/internal/oglematchers/not.go @@ -0,0 +1,53 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// 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. + +package oglematchers + +import ( + "errors" + "fmt" +) + +// Not returns a matcher that inverts the set of values matched by the wrapped +// matcher. It does not transform the result for values for which the wrapped +// matcher returns a fatal error. +func Not(m Matcher) Matcher { + return ¬Matcher{m} +} + +type notMatcher struct { + wrapped Matcher +} + +func (m *notMatcher) Matches(c interface{}) (err error) { + err = m.wrapped.Matches(c) + + // Did the wrapped matcher say yes? + if err == nil { + return errors.New("") + } + + // Did the wrapped matcher return a fatal error? + if _, isFatal := err.(*FatalError); isFatal { + return err + } + + // The wrapped matcher returned a non-fatal error. + return nil +} + +func (m *notMatcher) Description() string { + return fmt.Sprintf("not(%s)", m.wrapped.Description()) +} diff --git a/vendor/github.com/smartystreets/assertions/internal/oglematchers/panics.go b/vendor/github.com/smartystreets/assertions/internal/oglematchers/panics.go new file mode 100644 index 00000000..d2cfc978 --- /dev/null +++ b/vendor/github.com/smartystreets/assertions/internal/oglematchers/panics.go @@ -0,0 +1,74 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// 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. + +package oglematchers + +import ( + "errors" + "fmt" + "reflect" +) + +// Panics matches zero-arg functions which, when invoked, panic with an error +// that matches the supplied matcher. +// +// NOTE(jacobsa): This matcher cannot detect the case where the function panics +// using panic(nil), by design of the language. See here for more info: +// +// http://goo.gl/9aIQL +// +func Panics(m Matcher) Matcher { + return &panicsMatcher{m} +} + +type panicsMatcher struct { + wrappedMatcher Matcher +} + +func (m *panicsMatcher) Description() string { + return "panics with: " + m.wrappedMatcher.Description() +} + +func (m *panicsMatcher) Matches(c interface{}) (err error) { + // Make sure c is a zero-arg function. + v := reflect.ValueOf(c) + if v.Kind() != reflect.Func || v.Type().NumIn() != 0 { + err = NewFatalError("which is not a zero-arg function") + return + } + + // Call the function and check its panic error. + defer func() { + if e := recover(); e != nil { + err = m.wrappedMatcher.Matches(e) + + // Set a clearer error message if the matcher said no. + if err != nil { + wrappedClause := "" + if err.Error() != "" { + wrappedClause = ", " + err.Error() + } + + err = errors.New(fmt.Sprintf("which panicked with: %v%s", e, wrappedClause)) + } + } + }() + + v.Call([]reflect.Value{}) + + // If we get here, the function didn't panic. + err = errors.New("which didn't panic") + return +} diff --git a/vendor/github.com/smartystreets/assertions/internal/oglematchers/pointee.go b/vendor/github.com/smartystreets/assertions/internal/oglematchers/pointee.go new file mode 100644 index 00000000..c5383f24 --- /dev/null +++ b/vendor/github.com/smartystreets/assertions/internal/oglematchers/pointee.go @@ -0,0 +1,65 @@ +// Copyright 2012 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// 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. + +package oglematchers + +import ( + "errors" + "fmt" + "reflect" +) + +// Return a matcher that matches non-nil pointers whose pointee matches the +// wrapped matcher. +func Pointee(m Matcher) Matcher { + return &pointeeMatcher{m} +} + +type pointeeMatcher struct { + wrapped Matcher +} + +func (m *pointeeMatcher) Matches(c interface{}) (err error) { + // Make sure the candidate is of the appropriate type. + cv := reflect.ValueOf(c) + if !cv.IsValid() || cv.Kind() != reflect.Ptr { + return NewFatalError("which is not a pointer") + } + + // Make sure the candidate is non-nil. + if cv.IsNil() { + return NewFatalError("") + } + + // Defer to the wrapped matcher. Fix up empty errors so that failure messages + // are more helpful than just printing a pointer for "Actual". + pointee := cv.Elem().Interface() + err = m.wrapped.Matches(pointee) + if err != nil && err.Error() == "" { + s := fmt.Sprintf("whose pointee is %v", pointee) + + if _, ok := err.(*FatalError); ok { + err = NewFatalError(s) + } else { + err = errors.New(s) + } + } + + return err +} + +func (m *pointeeMatcher) Description() string { + return fmt.Sprintf("pointee(%s)", m.wrapped.Description()) +} diff --git a/vendor/github.com/smartystreets/assertions/internal/oglematchers/transform_description.go b/vendor/github.com/smartystreets/assertions/internal/oglematchers/transform_description.go new file mode 100644 index 00000000..f79d0c03 --- /dev/null +++ b/vendor/github.com/smartystreets/assertions/internal/oglematchers/transform_description.go @@ -0,0 +1,36 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// 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. + +package oglematchers + +// transformDescription returns a matcher that is equivalent to the supplied +// one, except that it has the supplied description instead of the one attached +// to the existing matcher. +func transformDescription(m Matcher, newDesc string) Matcher { + return &transformDescriptionMatcher{newDesc, m} +} + +type transformDescriptionMatcher struct { + desc string + wrappedMatcher Matcher +} + +func (m *transformDescriptionMatcher) Description() string { + return m.desc +} + +func (m *transformDescriptionMatcher) Matches(c interface{}) error { + return m.wrappedMatcher.Matches(c) +} diff --git a/vendor/github.com/smartystreets/assertions/messages.go b/vendor/github.com/smartystreets/assertions/messages.go new file mode 100644 index 00000000..ae1a1511 --- /dev/null +++ b/vendor/github.com/smartystreets/assertions/messages.go @@ -0,0 +1,94 @@ +package assertions + +const ( // equality + shouldHaveBeenEqual = "Expected: '%v'\nActual: '%v'\n(Should be equal)" + shouldNotHaveBeenEqual = "Expected '%v'\nto NOT equal '%v'\n(but it did)!" + shouldHaveBeenEqualTypeMismatch = "Expected: '%v' (%T)\nActual: '%v' (%T)\n(Should be equal, type mismatch)" + shouldHaveBeenAlmostEqual = "Expected '%v' to almost equal '%v' (but it didn't)!" + shouldHaveNotBeenAlmostEqual = "Expected '%v' to NOT almost equal '%v' (but it did)!" + shouldHaveResembled = "Expected: '%#v'\nActual: '%#v'\n(Should resemble)!" + shouldHaveResembledTypeMismatch = "Expected: '%#v' (%T)\nActual: '%#v' (%T)\n(Should resemble, type mismatch)" + shouldNotHaveResembled = "Expected '%#v'\nto NOT resemble '%#v'\n(but it did)!" + shouldBePointers = "Both arguments should be pointers " + shouldHaveBeenNonNilPointer = shouldBePointers + "(the %s was %s)!" + shouldHavePointedTo = "Expected '%+v' (address: '%v') and '%+v' (address: '%v') to be the same address (but their weren't)!" + shouldNotHavePointedTo = "Expected '%+v' and '%+v' to be different references (but they matched: '%v')!" + shouldHaveBeenNil = "Expected: nil\nActual: '%v'" + shouldNotHaveBeenNil = "Expected '%+v' to NOT be nil (but it was)!" + shouldHaveBeenTrue = "Expected: true\nActual: %v" + shouldHaveBeenFalse = "Expected: false\nActual: %v" + shouldHaveBeenZeroValue = "'%+v' should have been the zero value" //"Expected: (zero value)\nActual: %v" +) + +const ( // quantity comparisons + shouldHaveBeenGreater = "Expected '%v' to be greater than '%v' (but it wasn't)!" + shouldHaveBeenGreaterOrEqual = "Expected '%v' to be greater than or equal to '%v' (but it wasn't)!" + shouldHaveBeenLess = "Expected '%v' to be less than '%v' (but it wasn't)!" + shouldHaveBeenLessOrEqual = "Expected '%v' to be less than or equal to '%v' (but it wasn't)!" + shouldHaveBeenBetween = "Expected '%v' to be between '%v' and '%v' (but it wasn't)!" + shouldNotHaveBeenBetween = "Expected '%v' NOT to be between '%v' and '%v' (but it was)!" + shouldHaveDifferentUpperAndLower = "The lower and upper bounds must be different values (they were both '%v')." + shouldHaveBeenBetweenOrEqual = "Expected '%v' to be between '%v' and '%v' or equal to one of them (but it wasn't)!" + shouldNotHaveBeenBetweenOrEqual = "Expected '%v' NOT to be between '%v' and '%v' or equal to one of them (but it was)!" +) + +const ( // collections + shouldHaveContained = "Expected the container (%v) to contain: '%v' (but it didn't)!" + shouldNotHaveContained = "Expected the container (%v) NOT to contain: '%v' (but it did)!" + shouldHaveContainedKey = "Expected the %v to contain the key: %v (but it didn't)!" + shouldNotHaveContainedKey = "Expected the %v NOT to contain the key: %v (but it did)!" + shouldHaveBeenIn = "Expected '%v' to be in the container (%v), but it wasn't!" + shouldNotHaveBeenIn = "Expected '%v' NOT to be in the container (%v), but it was!" + shouldHaveBeenAValidCollection = "You must provide a valid container (was %v)!" + shouldHaveBeenAValidMap = "You must provide a valid map type (was %v)!" + shouldHaveBeenEmpty = "Expected %+v to be empty (but it wasn't)!" + shouldNotHaveBeenEmpty = "Expected %+v to NOT be empty (but it was)!" + shouldHaveBeenAValidInteger = "You must provide a valid integer (was %v)!" + shouldHaveBeenAValidLength = "You must provide a valid positive integer (was %v)!" + shouldHaveHadLength = "Expected %+v (length: %v) to have length equal to '%v', but it wasn't!" +) + +const ( // strings + shouldHaveStartedWith = "Expected '%v'\nto start with '%v'\n(but it didn't)!" + shouldNotHaveStartedWith = "Expected '%v'\nNOT to start with '%v'\n(but it did)!" + shouldHaveEndedWith = "Expected '%v'\nto end with '%v'\n(but it didn't)!" + shouldNotHaveEndedWith = "Expected '%v'\nNOT to end with '%v'\n(but it did)!" + shouldAllBeStrings = "All arguments to this assertion must be strings (you provided: %v)." + shouldBothBeStrings = "Both arguments to this assertion must be strings (you provided %v and %v)." + shouldBeString = "The argument to this assertion must be a string (you provided %v)." + shouldHaveContainedSubstring = "Expected '%s' to contain substring '%s' (but it didn't)!" + shouldNotHaveContainedSubstring = "Expected '%s' NOT to contain substring '%s' (but it did)!" + shouldHaveBeenBlank = "Expected '%s' to be blank (but it wasn't)!" + shouldNotHaveBeenBlank = "Expected value to NOT be blank (but it was)!" +) + +const ( // panics + shouldUseVoidNiladicFunction = "You must provide a void, niladic function as the first argument!" + shouldHavePanickedWith = "Expected func() to panic with '%v' (but it panicked with '%v')!" + shouldHavePanicked = "Expected func() to panic (but it didn't)!" + shouldNotHavePanicked = "Expected func() NOT to panic (error: '%+v')!" + shouldNotHavePanickedWith = "Expected func() NOT to panic with '%v' (but it did)!" +) + +const ( // type checking + shouldHaveBeenA = "Expected '%v' to be: '%v' (but was: '%v')!" + shouldNotHaveBeenA = "Expected '%v' to NOT be: '%v' (but it was)!" + + shouldHaveImplemented = "Expected: '%v interface support'\nActual: '%v' does not implement the interface!" + shouldNotHaveImplemented = "Expected '%v'\nto NOT implement '%v'\n(but it did)!" + shouldCompareWithInterfacePointer = "The expected value must be a pointer to an interface type (eg. *fmt.Stringer)" + shouldNotBeNilActual = "The actual value was 'nil' and should be a value or a pointer to a value!" +) + +const ( // time comparisons + shouldUseTimes = "You must provide time instances as arguments to this assertion." + shouldUseTimeSlice = "You must provide a slice of time instances as the first argument to this assertion." + shouldUseDurationAndTime = "You must provide a duration and a time as arguments to this assertion." + shouldHaveHappenedBefore = "Expected '%v' to happen before '%v' (it happened '%v' after)!" + shouldHaveHappenedAfter = "Expected '%v' to happen after '%v' (it happened '%v' before)!" + shouldHaveHappenedBetween = "Expected '%v' to happen between '%v' and '%v' (it happened '%v' outside threshold)!" + shouldNotHaveHappenedOnOrBetween = "Expected '%v' to NOT happen on or between '%v' and '%v' (but it did)!" + + // format params: incorrect-index, previous-index, previous-time, incorrect-index, incorrect-time + shouldHaveBeenChronological = "The 'Time' at index [%d] should have happened after the previous one (but it didn't!):\n [%d]: %s\n [%d]: %s (see, it happened before!)" +) diff --git a/vendor/github.com/smartystreets/assertions/panic.go b/vendor/github.com/smartystreets/assertions/panic.go new file mode 100644 index 00000000..7e75db17 --- /dev/null +++ b/vendor/github.com/smartystreets/assertions/panic.go @@ -0,0 +1,115 @@ +package assertions + +import "fmt" + +// ShouldPanic receives a void, niladic function and expects to recover a panic. +func ShouldPanic(actual interface{}, expected ...interface{}) (message string) { + if fail := need(0, expected); fail != success { + return fail + } + + action, _ := actual.(func()) + + if action == nil { + message = shouldUseVoidNiladicFunction + return + } + + defer func() { + recovered := recover() + if recovered == nil { + message = shouldHavePanicked + } else { + message = success + } + }() + action() + + return +} + +// ShouldNotPanic receives a void, niladic function and expects to execute the function without any panic. +func ShouldNotPanic(actual interface{}, expected ...interface{}) (message string) { + if fail := need(0, expected); fail != success { + return fail + } + + action, _ := actual.(func()) + + if action == nil { + message = shouldUseVoidNiladicFunction + return + } + + defer func() { + recovered := recover() + if recovered != nil { + message = fmt.Sprintf(shouldNotHavePanicked, recovered) + } else { + message = success + } + }() + action() + + return +} + +// ShouldPanicWith receives a void, niladic function and expects to recover a panic with the second argument as the content. +func ShouldPanicWith(actual interface{}, expected ...interface{}) (message string) { + if fail := need(1, expected); fail != success { + return fail + } + + action, _ := actual.(func()) + + if action == nil { + message = shouldUseVoidNiladicFunction + return + } + + defer func() { + recovered := recover() + if recovered == nil { + message = shouldHavePanicked + } else { + if equal := ShouldEqual(recovered, expected[0]); equal != success { + message = serializer.serialize(expected[0], recovered, fmt.Sprintf(shouldHavePanickedWith, expected[0], recovered)) + } else { + message = success + } + } + }() + action() + + return +} + +// ShouldNotPanicWith receives a void, niladic function and expects to recover a panic whose content differs from the second argument. +func ShouldNotPanicWith(actual interface{}, expected ...interface{}) (message string) { + if fail := need(1, expected); fail != success { + return fail + } + + action, _ := actual.(func()) + + if action == nil { + message = shouldUseVoidNiladicFunction + return + } + + defer func() { + recovered := recover() + if recovered == nil { + message = success + } else { + if equal := ShouldEqual(recovered, expected[0]); equal == success { + message = fmt.Sprintf(shouldNotHavePanickedWith, expected[0]) + } else { + message = success + } + } + }() + action() + + return +} diff --git a/vendor/github.com/smartystreets/assertions/quantity.go b/vendor/github.com/smartystreets/assertions/quantity.go new file mode 100644 index 00000000..80789f0c --- /dev/null +++ b/vendor/github.com/smartystreets/assertions/quantity.go @@ -0,0 +1,141 @@ +package assertions + +import ( + "fmt" + + "github.com/smartystreets/assertions/internal/oglematchers" +) + +// ShouldBeGreaterThan receives exactly two parameters and ensures that the first is greater than the second. +func ShouldBeGreaterThan(actual interface{}, expected ...interface{}) string { + if fail := need(1, expected); fail != success { + return fail + } + + if matchError := oglematchers.GreaterThan(expected[0]).Matches(actual); matchError != nil { + return fmt.Sprintf(shouldHaveBeenGreater, actual, expected[0]) + } + return success +} + +// ShouldBeGreaterThanOrEqualTo receives exactly two parameters and ensures that the first is greater than or equal to the second. +func ShouldBeGreaterThanOrEqualTo(actual interface{}, expected ...interface{}) string { + if fail := need(1, expected); fail != success { + return fail + } else if matchError := oglematchers.GreaterOrEqual(expected[0]).Matches(actual); matchError != nil { + return fmt.Sprintf(shouldHaveBeenGreaterOrEqual, actual, expected[0]) + } + return success +} + +// ShouldBeLessThan receives exactly two parameters and ensures that the first is less than the second. +func ShouldBeLessThan(actual interface{}, expected ...interface{}) string { + if fail := need(1, expected); fail != success { + return fail + } else if matchError := oglematchers.LessThan(expected[0]).Matches(actual); matchError != nil { + return fmt.Sprintf(shouldHaveBeenLess, actual, expected[0]) + } + return success +} + +// ShouldBeLessThan receives exactly two parameters and ensures that the first is less than or equal to the second. +func ShouldBeLessThanOrEqualTo(actual interface{}, expected ...interface{}) string { + if fail := need(1, expected); fail != success { + return fail + } else if matchError := oglematchers.LessOrEqual(expected[0]).Matches(actual); matchError != nil { + return fmt.Sprintf(shouldHaveBeenLess, actual, expected[0]) + } + return success +} + +// ShouldBeBetween receives exactly three parameters: an actual value, a lower bound, and an upper bound. +// It ensures that the actual value is between both bounds (but not equal to either of them). +func ShouldBeBetween(actual interface{}, expected ...interface{}) string { + if fail := need(2, expected); fail != success { + return fail + } + lower, upper, fail := deriveBounds(expected) + + if fail != success { + return fail + } else if !isBetween(actual, lower, upper) { + return fmt.Sprintf(shouldHaveBeenBetween, actual, lower, upper) + } + return success +} + +// ShouldNotBeBetween receives exactly three parameters: an actual value, a lower bound, and an upper bound. +// It ensures that the actual value is NOT between both bounds. +func ShouldNotBeBetween(actual interface{}, expected ...interface{}) string { + if fail := need(2, expected); fail != success { + return fail + } + lower, upper, fail := deriveBounds(expected) + + if fail != success { + return fail + } else if isBetween(actual, lower, upper) { + return fmt.Sprintf(shouldNotHaveBeenBetween, actual, lower, upper) + } + return success +} +func deriveBounds(values []interface{}) (lower interface{}, upper interface{}, fail string) { + lower = values[0] + upper = values[1] + + if ShouldNotEqual(lower, upper) != success { + return nil, nil, fmt.Sprintf(shouldHaveDifferentUpperAndLower, lower) + } else if ShouldBeLessThan(lower, upper) != success { + lower, upper = upper, lower + } + return lower, upper, success +} +func isBetween(value, lower, upper interface{}) bool { + if ShouldBeGreaterThan(value, lower) != success { + return false + } else if ShouldBeLessThan(value, upper) != success { + return false + } + return true +} + +// ShouldBeBetweenOrEqual receives exactly three parameters: an actual value, a lower bound, and an upper bound. +// It ensures that the actual value is between both bounds or equal to one of them. +func ShouldBeBetweenOrEqual(actual interface{}, expected ...interface{}) string { + if fail := need(2, expected); fail != success { + return fail + } + lower, upper, fail := deriveBounds(expected) + + if fail != success { + return fail + } else if !isBetweenOrEqual(actual, lower, upper) { + return fmt.Sprintf(shouldHaveBeenBetweenOrEqual, actual, lower, upper) + } + return success +} + +// ShouldNotBeBetweenOrEqual receives exactly three parameters: an actual value, a lower bound, and an upper bound. +// It ensures that the actual value is nopt between the bounds nor equal to either of them. +func ShouldNotBeBetweenOrEqual(actual interface{}, expected ...interface{}) string { + if fail := need(2, expected); fail != success { + return fail + } + lower, upper, fail := deriveBounds(expected) + + if fail != success { + return fail + } else if isBetweenOrEqual(actual, lower, upper) { + return fmt.Sprintf(shouldNotHaveBeenBetweenOrEqual, actual, lower, upper) + } + return success +} + +func isBetweenOrEqual(value, lower, upper interface{}) bool { + if ShouldBeGreaterThanOrEqualTo(value, lower) != success { + return false + } else if ShouldBeLessThanOrEqualTo(value, upper) != success { + return false + } + return true +} diff --git a/vendor/github.com/smartystreets/assertions/serializer.go b/vendor/github.com/smartystreets/assertions/serializer.go new file mode 100644 index 00000000..90ae3e3b --- /dev/null +++ b/vendor/github.com/smartystreets/assertions/serializer.go @@ -0,0 +1,69 @@ +package assertions + +import ( + "encoding/json" + "fmt" + + "github.com/smartystreets/assertions/internal/go-render/render" +) + +type Serializer interface { + serialize(expected, actual interface{}, message string) string + serializeDetailed(expected, actual interface{}, message string) string +} + +type failureSerializer struct{} + +func (self *failureSerializer) serializeDetailed(expected, actual interface{}, message string) string { + view := FailureView{ + Message: message, + Expected: render.Render(expected), + Actual: render.Render(actual), + } + serialized, err := json.Marshal(view) + if err != nil { + return message + } + return string(serialized) +} + +func (self *failureSerializer) serialize(expected, actual interface{}, message string) string { + view := FailureView{ + Message: message, + Expected: fmt.Sprintf("%+v", expected), + Actual: fmt.Sprintf("%+v", actual), + } + serialized, err := json.Marshal(view) + if err != nil { + return message + } + return string(serialized) +} + +func newSerializer() *failureSerializer { + return &failureSerializer{} +} + +/////////////////////////////////////////////////////////////////////////////// + +// This struct is also declared in github.com/smartystreets/goconvey/convey/reporting. +// The json struct tags should be equal in both declarations. +type FailureView struct { + Message string `json:"Message"` + Expected string `json:"Expected"` + Actual string `json:"Actual"` +} + +/////////////////////////////////////////////////////// + +// noopSerializer just gives back the original message. This is useful when we are using +// the assertions from a context other than the web UI, that requires the JSON structure +// provided by the failureSerializer. +type noopSerializer struct{} + +func (self *noopSerializer) serialize(expected, actual interface{}, message string) string { + return message +} +func (self *noopSerializer) serializeDetailed(expected, actual interface{}, message string) string { + return message +} diff --git a/vendor/github.com/smartystreets/assertions/strings.go b/vendor/github.com/smartystreets/assertions/strings.go new file mode 100644 index 00000000..dbc3f047 --- /dev/null +++ b/vendor/github.com/smartystreets/assertions/strings.go @@ -0,0 +1,227 @@ +package assertions + +import ( + "fmt" + "reflect" + "strings" +) + +// ShouldStartWith receives exactly 2 string parameters and ensures that the first starts with the second. +func ShouldStartWith(actual interface{}, expected ...interface{}) string { + if fail := need(1, expected); fail != success { + return fail + } + + value, valueIsString := actual.(string) + prefix, prefixIsString := expected[0].(string) + + if !valueIsString || !prefixIsString { + return fmt.Sprintf(shouldBothBeStrings, reflect.TypeOf(actual), reflect.TypeOf(expected[0])) + } + + return shouldStartWith(value, prefix) +} +func shouldStartWith(value, prefix string) string { + if !strings.HasPrefix(value, prefix) { + shortval := value + if len(shortval) > len(prefix) { + shortval = shortval[:len(prefix)] + "..." + } + return serializer.serialize(prefix, shortval, fmt.Sprintf(shouldHaveStartedWith, value, prefix)) + } + return success +} + +// ShouldNotStartWith receives exactly 2 string parameters and ensures that the first does not start with the second. +func ShouldNotStartWith(actual interface{}, expected ...interface{}) string { + if fail := need(1, expected); fail != success { + return fail + } + + value, valueIsString := actual.(string) + prefix, prefixIsString := expected[0].(string) + + if !valueIsString || !prefixIsString { + return fmt.Sprintf(shouldBothBeStrings, reflect.TypeOf(actual), reflect.TypeOf(expected[0])) + } + + return shouldNotStartWith(value, prefix) +} +func shouldNotStartWith(value, prefix string) string { + if strings.HasPrefix(value, prefix) { + if value == "" { + value = "<empty>" + } + if prefix == "" { + prefix = "<empty>" + } + return fmt.Sprintf(shouldNotHaveStartedWith, value, prefix) + } + return success +} + +// ShouldEndWith receives exactly 2 string parameters and ensures that the first ends with the second. +func ShouldEndWith(actual interface{}, expected ...interface{}) string { + if fail := need(1, expected); fail != success { + return fail + } + + value, valueIsString := actual.(string) + suffix, suffixIsString := expected[0].(string) + + if !valueIsString || !suffixIsString { + return fmt.Sprintf(shouldBothBeStrings, reflect.TypeOf(actual), reflect.TypeOf(expected[0])) + } + + return shouldEndWith(value, suffix) +} +func shouldEndWith(value, suffix string) string { + if !strings.HasSuffix(value, suffix) { + shortval := value + if len(shortval) > len(suffix) { + shortval = "..." + shortval[len(shortval)-len(suffix):] + } + return serializer.serialize(suffix, shortval, fmt.Sprintf(shouldHaveEndedWith, value, suffix)) + } + return success +} + +// ShouldEndWith receives exactly 2 string parameters and ensures that the first does not end with the second. +func ShouldNotEndWith(actual interface{}, expected ...interface{}) string { + if fail := need(1, expected); fail != success { + return fail + } + + value, valueIsString := actual.(string) + suffix, suffixIsString := expected[0].(string) + + if !valueIsString || !suffixIsString { + return fmt.Sprintf(shouldBothBeStrings, reflect.TypeOf(actual), reflect.TypeOf(expected[0])) + } + + return shouldNotEndWith(value, suffix) +} +func shouldNotEndWith(value, suffix string) string { + if strings.HasSuffix(value, suffix) { + if value == "" { + value = "<empty>" + } + if suffix == "" { + suffix = "<empty>" + } + return fmt.Sprintf(shouldNotHaveEndedWith, value, suffix) + } + return success +} + +// ShouldContainSubstring receives exactly 2 string parameters and ensures that the first contains the second as a substring. +func ShouldContainSubstring(actual interface{}, expected ...interface{}) string { + if fail := need(1, expected); fail != success { + return fail + } + + long, longOk := actual.(string) + short, shortOk := expected[0].(string) + + if !longOk || !shortOk { + return fmt.Sprintf(shouldBothBeStrings, reflect.TypeOf(actual), reflect.TypeOf(expected[0])) + } + + if !strings.Contains(long, short) { + return serializer.serialize(expected[0], actual, fmt.Sprintf(shouldHaveContainedSubstring, long, short)) + } + return success +} + +// ShouldNotContainSubstring receives exactly 2 string parameters and ensures that the first does NOT contain the second as a substring. +func ShouldNotContainSubstring(actual interface{}, expected ...interface{}) string { + if fail := need(1, expected); fail != success { + return fail + } + + long, longOk := actual.(string) + short, shortOk := expected[0].(string) + + if !longOk || !shortOk { + return fmt.Sprintf(shouldBothBeStrings, reflect.TypeOf(actual), reflect.TypeOf(expected[0])) + } + + if strings.Contains(long, short) { + return fmt.Sprintf(shouldNotHaveContainedSubstring, long, short) + } + return success +} + +// ShouldBeBlank receives exactly 1 string parameter and ensures that it is equal to "". +func ShouldBeBlank(actual interface{}, expected ...interface{}) string { + if fail := need(0, expected); fail != success { + return fail + } + value, ok := actual.(string) + if !ok { + return fmt.Sprintf(shouldBeString, reflect.TypeOf(actual)) + } + if value != "" { + return serializer.serialize("", value, fmt.Sprintf(shouldHaveBeenBlank, value)) + } + return success +} + +// ShouldNotBeBlank receives exactly 1 string parameter and ensures that it is equal to "". +func ShouldNotBeBlank(actual interface{}, expected ...interface{}) string { + if fail := need(0, expected); fail != success { + return fail + } + value, ok := actual.(string) + if !ok { + return fmt.Sprintf(shouldBeString, reflect.TypeOf(actual)) + } + if value == "" { + return shouldNotHaveBeenBlank + } + return success +} + +// ShouldEqualWithout receives exactly 3 string parameters and ensures that the first is equal to the second +// after removing all instances of the third from the first using strings.Replace(first, third, "", -1). +func ShouldEqualWithout(actual interface{}, expected ...interface{}) string { + if fail := need(2, expected); fail != success { + return fail + } + actualString, ok1 := actual.(string) + expectedString, ok2 := expected[0].(string) + replace, ok3 := expected[1].(string) + + if !ok1 || !ok2 || !ok3 { + return fmt.Sprintf(shouldAllBeStrings, []reflect.Type{ + reflect.TypeOf(actual), + reflect.TypeOf(expected[0]), + reflect.TypeOf(expected[1]), + }) + } + + replaced := strings.Replace(actualString, replace, "", -1) + if replaced == expectedString { + return "" + } + + return fmt.Sprintf("Expected '%s' to equal '%s' but without any '%s' (but it didn't).", actualString, expectedString, replace) +} + +// ShouldEqualTrimSpace receives exactly 2 string parameters and ensures that the first is equal to the second +// after removing all leading and trailing whitespace using strings.TrimSpace(first). +func ShouldEqualTrimSpace(actual interface{}, expected ...interface{}) string { + if fail := need(1, expected); fail != success { + return fail + } + + actualString, valueIsString := actual.(string) + _, value2IsString := expected[0].(string) + + if !valueIsString || !value2IsString { + return fmt.Sprintf(shouldBothBeStrings, reflect.TypeOf(actual), reflect.TypeOf(expected[0])) + } + + actualString = strings.TrimSpace(actualString) + return ShouldEqual(actualString, expected[0]) +} diff --git a/vendor/github.com/smartystreets/assertions/time.go b/vendor/github.com/smartystreets/assertions/time.go new file mode 100644 index 00000000..7e050261 --- /dev/null +++ b/vendor/github.com/smartystreets/assertions/time.go @@ -0,0 +1,202 @@ +package assertions + +import ( + "fmt" + "time" +) + +// ShouldHappenBefore receives exactly 2 time.Time arguments and asserts that the first happens before the second. +func ShouldHappenBefore(actual interface{}, expected ...interface{}) string { + if fail := need(1, expected); fail != success { + return fail + } + actualTime, firstOk := actual.(time.Time) + expectedTime, secondOk := expected[0].(time.Time) + + if !firstOk || !secondOk { + return shouldUseTimes + } + + if !actualTime.Before(expectedTime) { + return fmt.Sprintf(shouldHaveHappenedBefore, actualTime, expectedTime, actualTime.Sub(expectedTime)) + } + + return success +} + +// ShouldHappenOnOrBefore receives exactly 2 time.Time arguments and asserts that the first happens on or before the second. +func ShouldHappenOnOrBefore(actual interface{}, expected ...interface{}) string { + if fail := need(1, expected); fail != success { + return fail + } + actualTime, firstOk := actual.(time.Time) + expectedTime, secondOk := expected[0].(time.Time) + + if !firstOk || !secondOk { + return shouldUseTimes + } + + if actualTime.Equal(expectedTime) { + return success + } + return ShouldHappenBefore(actualTime, expectedTime) +} + +// ShouldHappenAfter receives exactly 2 time.Time arguments and asserts that the first happens after the second. +func ShouldHappenAfter(actual interface{}, expected ...interface{}) string { + if fail := need(1, expected); fail != success { + return fail + } + actualTime, firstOk := actual.(time.Time) + expectedTime, secondOk := expected[0].(time.Time) + + if !firstOk || !secondOk { + return shouldUseTimes + } + if !actualTime.After(expectedTime) { + return fmt.Sprintf(shouldHaveHappenedAfter, actualTime, expectedTime, expectedTime.Sub(actualTime)) + } + return success +} + +// ShouldHappenOnOrAfter receives exactly 2 time.Time arguments and asserts that the first happens on or after the second. +func ShouldHappenOnOrAfter(actual interface{}, expected ...interface{}) string { + if fail := need(1, expected); fail != success { + return fail + } + actualTime, firstOk := actual.(time.Time) + expectedTime, secondOk := expected[0].(time.Time) + + if !firstOk || !secondOk { + return shouldUseTimes + } + if actualTime.Equal(expectedTime) { + return success + } + return ShouldHappenAfter(actualTime, expectedTime) +} + +// ShouldHappenBetween receives exactly 3 time.Time arguments and asserts that the first happens between (not on) the second and third. +func ShouldHappenBetween(actual interface{}, expected ...interface{}) string { + if fail := need(2, expected); fail != success { + return fail + } + actualTime, firstOk := actual.(time.Time) + min, secondOk := expected[0].(time.Time) + max, thirdOk := expected[1].(time.Time) + + if !firstOk || !secondOk || !thirdOk { + return shouldUseTimes + } + + if !actualTime.After(min) { + return fmt.Sprintf(shouldHaveHappenedBetween, actualTime, min, max, min.Sub(actualTime)) + } + if !actualTime.Before(max) { + return fmt.Sprintf(shouldHaveHappenedBetween, actualTime, min, max, actualTime.Sub(max)) + } + return success +} + +// ShouldHappenOnOrBetween receives exactly 3 time.Time arguments and asserts that the first happens between or on the second and third. +func ShouldHappenOnOrBetween(actual interface{}, expected ...interface{}) string { + if fail := need(2, expected); fail != success { + return fail + } + actualTime, firstOk := actual.(time.Time) + min, secondOk := expected[0].(time.Time) + max, thirdOk := expected[1].(time.Time) + + if !firstOk || !secondOk || !thirdOk { + return shouldUseTimes + } + if actualTime.Equal(min) || actualTime.Equal(max) { + return success + } + return ShouldHappenBetween(actualTime, min, max) +} + +// ShouldNotHappenOnOrBetween receives exactly 3 time.Time arguments and asserts that the first +// does NOT happen between or on the second or third. +func ShouldNotHappenOnOrBetween(actual interface{}, expected ...interface{}) string { + if fail := need(2, expected); fail != success { + return fail + } + actualTime, firstOk := actual.(time.Time) + min, secondOk := expected[0].(time.Time) + max, thirdOk := expected[1].(time.Time) + + if !firstOk || !secondOk || !thirdOk { + return shouldUseTimes + } + if actualTime.Equal(min) || actualTime.Equal(max) { + return fmt.Sprintf(shouldNotHaveHappenedOnOrBetween, actualTime, min, max) + } + if actualTime.After(min) && actualTime.Before(max) { + return fmt.Sprintf(shouldNotHaveHappenedOnOrBetween, actualTime, min, max) + } + return success +} + +// ShouldHappenWithin receives a time.Time, a time.Duration, and a time.Time (3 arguments) +// and asserts that the first time.Time happens within or on the duration specified relative to +// the other time.Time. +func ShouldHappenWithin(actual interface{}, expected ...interface{}) string { + if fail := need(2, expected); fail != success { + return fail + } + actualTime, firstOk := actual.(time.Time) + tolerance, secondOk := expected[0].(time.Duration) + threshold, thirdOk := expected[1].(time.Time) + + if !firstOk || !secondOk || !thirdOk { + return shouldUseDurationAndTime + } + + min := threshold.Add(-tolerance) + max := threshold.Add(tolerance) + return ShouldHappenOnOrBetween(actualTime, min, max) +} + +// ShouldNotHappenWithin receives a time.Time, a time.Duration, and a time.Time (3 arguments) +// and asserts that the first time.Time does NOT happen within or on the duration specified relative to +// the other time.Time. +func ShouldNotHappenWithin(actual interface{}, expected ...interface{}) string { + if fail := need(2, expected); fail != success { + return fail + } + actualTime, firstOk := actual.(time.Time) + tolerance, secondOk := expected[0].(time.Duration) + threshold, thirdOk := expected[1].(time.Time) + + if !firstOk || !secondOk || !thirdOk { + return shouldUseDurationAndTime + } + + min := threshold.Add(-tolerance) + max := threshold.Add(tolerance) + return ShouldNotHappenOnOrBetween(actualTime, min, max) +} + +// ShouldBeChronological receives a []time.Time slice and asserts that the are +// in chronological order starting with the first time.Time as the earliest. +func ShouldBeChronological(actual interface{}, expected ...interface{}) string { + if fail := need(0, expected); fail != success { + return fail + } + + times, ok := actual.([]time.Time) + if !ok { + return shouldUseTimeSlice + } + + var previous time.Time + for i, current := range times { + if i > 0 && current.Before(previous) { + return fmt.Sprintf(shouldHaveBeenChronological, + i, i-1, previous.String(), i, current.String()) + } + previous = current + } + return "" +} diff --git a/vendor/github.com/smartystreets/assertions/type.go b/vendor/github.com/smartystreets/assertions/type.go new file mode 100644 index 00000000..3fc00f68 --- /dev/null +++ b/vendor/github.com/smartystreets/assertions/type.go @@ -0,0 +1,112 @@ +package assertions + +import ( + "fmt" + "reflect" +) + +// ShouldHaveSameTypeAs receives exactly two parameters and compares their underlying types for equality. +func ShouldHaveSameTypeAs(actual interface{}, expected ...interface{}) string { + if fail := need(1, expected); fail != success { + return fail + } + + first := reflect.TypeOf(actual) + second := reflect.TypeOf(expected[0]) + + if equal := ShouldEqual(first, second); equal != success { + return serializer.serialize(second, first, fmt.Sprintf(shouldHaveBeenA, actual, second, first)) + } + return success +} + +// ShouldNotHaveSameTypeAs receives exactly two parameters and compares their underlying types for inequality. +func ShouldNotHaveSameTypeAs(actual interface{}, expected ...interface{}) string { + if fail := need(1, expected); fail != success { + return fail + } + + first := reflect.TypeOf(actual) + second := reflect.TypeOf(expected[0]) + + if equal := ShouldEqual(first, second); equal == success { + return fmt.Sprintf(shouldNotHaveBeenA, actual, second) + } + return success +} + +// ShouldImplement receives exactly two parameters and ensures +// that the first implements the interface type of the second. +func ShouldImplement(actual interface{}, expectedList ...interface{}) string { + if fail := need(1, expectedList); fail != success { + return fail + } + + expected := expectedList[0] + if fail := ShouldBeNil(expected); fail != success { + return shouldCompareWithInterfacePointer + } + + if fail := ShouldNotBeNil(actual); fail != success { + return shouldNotBeNilActual + } + + var actualType reflect.Type + if reflect.TypeOf(actual).Kind() != reflect.Ptr { + actualType = reflect.PtrTo(reflect.TypeOf(actual)) + } else { + actualType = reflect.TypeOf(actual) + } + + expectedType := reflect.TypeOf(expected) + if fail := ShouldNotBeNil(expectedType); fail != success { + return shouldCompareWithInterfacePointer + } + + expectedInterface := expectedType.Elem() + + if actualType == nil { + return fmt.Sprintf(shouldHaveImplemented, expectedInterface, actual) + } + + if !actualType.Implements(expectedInterface) { + return fmt.Sprintf(shouldHaveImplemented, expectedInterface, actualType) + } + return success +} + +// ShouldNotImplement receives exactly two parameters and ensures +// that the first does NOT implement the interface type of the second. +func ShouldNotImplement(actual interface{}, expectedList ...interface{}) string { + if fail := need(1, expectedList); fail != success { + return fail + } + + expected := expectedList[0] + if fail := ShouldBeNil(expected); fail != success { + return shouldCompareWithInterfacePointer + } + + if fail := ShouldNotBeNil(actual); fail != success { + return shouldNotBeNilActual + } + + var actualType reflect.Type + if reflect.TypeOf(actual).Kind() != reflect.Ptr { + actualType = reflect.PtrTo(reflect.TypeOf(actual)) + } else { + actualType = reflect.TypeOf(actual) + } + + expectedType := reflect.TypeOf(expected) + if fail := ShouldNotBeNil(expectedType); fail != success { + return shouldCompareWithInterfacePointer + } + + expectedInterface := expectedType.Elem() + + if actualType.Implements(expectedInterface) { + return fmt.Sprintf(shouldNotHaveImplemented, actualType, expectedInterface) + } + return success +} |