diff options
Diffstat (limited to 'src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers')
45 files changed, 13181 insertions, 0 deletions
diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/.gitignore b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/.gitignore new file mode 100644 index 00000000000..dd8fc7468f4 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/.gitignore @@ -0,0 +1,5 @@ +*.6 +6.out +_obj/ +_test/ +_testmain.go diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/.travis.yml b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/.travis.yml new file mode 100644 index 00000000000..b97211926e8 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/.travis.yml @@ -0,0 +1,4 @@ +# Cf. http://docs.travis-ci.com/user/getting-started/ +# Cf. http://docs.travis-ci.com/user/languages/go/ + +language: go diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/LICENSE b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/LICENSE new file mode 100644 index 00000000000..d6456956733 --- /dev/null +++ b/src/mongo/gotools/vendor/src/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/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/README.md b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/README.md new file mode 100644 index 00000000000..215a2bb7a8b --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/README.md @@ -0,0 +1,58 @@ +[![GoDoc](https://godoc.org/github.com/smartystreets/assertions/internal/oglematchers?status.svg)](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/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/all_of.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/all_of.go new file mode 100644 index 00000000000..d93a9740443 --- /dev/null +++ b/src/mongo/gotools/vendor/src/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/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/all_of_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/all_of_test.go new file mode 100644 index 00000000000..0f9d198fcbe --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/all_of_test.go @@ -0,0 +1,110 @@ +// 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_test + +import ( + . "github.com/smartystreets/assertions/internal/oglematchers" + . "github.com/smartystreets/assertions/internal/ogletest" + "errors" +) + +//////////////////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////////////////// + +type allOfFakeMatcher struct { + desc string + err error +} + +func (m *allOfFakeMatcher) Matches(c interface{}) error { + return m.err +} + +func (m *allOfFakeMatcher) Description() string { + return m.desc +} + +type AllOfTest struct { +} + +func init() { RegisterTestSuite(&AllOfTest{}) } + +//////////////////////////////////////////////////////////////////////// +// Tests +//////////////////////////////////////////////////////////////////////// + +func (t *AllOfTest) DescriptionWithEmptySet() { + m := AllOf() + ExpectEq("is anything", m.Description()) +} + +func (t *AllOfTest) DescriptionWithOneMatcher() { + m := AllOf(&allOfFakeMatcher{"taco", errors.New("")}) + ExpectEq("taco", m.Description()) +} + +func (t *AllOfTest) DescriptionWithMultipleMatchers() { + m := AllOf( + &allOfFakeMatcher{"taco", errors.New("")}, + &allOfFakeMatcher{"burrito", errors.New("")}, + &allOfFakeMatcher{"enchilada", errors.New("")}) + + ExpectEq("taco, and burrito, and enchilada", m.Description()) +} + +func (t *AllOfTest) EmptySet() { + m := AllOf() + err := m.Matches(17) + + ExpectEq(nil, err) +} + +func (t *AllOfTest) OneMatcherReturnsFatalErrorAndSomeOthersFail() { + m := AllOf( + &allOfFakeMatcher{"", errors.New("")}, + &allOfFakeMatcher{"", NewFatalError("taco")}, + &allOfFakeMatcher{"", errors.New("")}, + &allOfFakeMatcher{"", nil}) + + err := m.Matches(17) + + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("taco"))) +} + +func (t *AllOfTest) OneMatcherReturnsNonFatalAndOthersSayTrue() { + m := AllOf( + &allOfFakeMatcher{"", nil}, + &allOfFakeMatcher{"", errors.New("taco")}, + &allOfFakeMatcher{"", nil}) + + err := m.Matches(17) + + ExpectFalse(isFatal(err)) + ExpectThat(err, Error(Equals("taco"))) +} + +func (t *AllOfTest) AllMatchersSayTrue() { + m := AllOf( + &allOfFakeMatcher{"", nil}, + &allOfFakeMatcher{"", nil}, + &allOfFakeMatcher{"", nil}) + + err := m.Matches(17) + + ExpectEq(nil, err) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/any.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/any.go new file mode 100644 index 00000000000..f6991ec1020 --- /dev/null +++ b/src/mongo/gotools/vendor/src/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/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/any_of.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/any_of.go new file mode 100644 index 00000000000..2918b51f21a --- /dev/null +++ b/src/mongo/gotools/vendor/src/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/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/any_of_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/any_of_test.go new file mode 100644 index 00000000000..f0b5025406f --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/any_of_test.go @@ -0,0 +1,139 @@ +// 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_test + +import ( + "errors" + + . "github.com/smartystreets/assertions/internal/oglematchers" + . "github.com/smartystreets/assertions/internal/ogletest" +) + +//////////////////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////////////////// + +type fakeAnyOfMatcher struct { + desc string + err error +} + +func (m *fakeAnyOfMatcher) Matches(c interface{}) error { + return m.err +} + +func (m *fakeAnyOfMatcher) Description() string { + return m.desc +} + +type AnyOfTest struct { +} + +func init() { RegisterTestSuite(&AnyOfTest{}) } + +//////////////////////////////////////////////////////////////////////// +// Tests +//////////////////////////////////////////////////////////////////////// + +func (t *AnyOfTest) EmptySet() { + matcher := AnyOf() + + err := matcher.Matches(0) + ExpectThat(err, Error(Equals(""))) +} + +func (t *AnyOfTest) OneTrue() { + matcher := AnyOf( + &fakeAnyOfMatcher{"", NewFatalError("foo")}, + 17, + &fakeAnyOfMatcher{"", errors.New("foo")}, + &fakeAnyOfMatcher{"", nil}, + &fakeAnyOfMatcher{"", errors.New("foo")}, + ) + + err := matcher.Matches(0) + ExpectEq(nil, err) +} + +func (t *AnyOfTest) OneEqual() { + matcher := AnyOf( + &fakeAnyOfMatcher{"", NewFatalError("foo")}, + &fakeAnyOfMatcher{"", errors.New("foo")}, + 13, + "taco", + 19, + &fakeAnyOfMatcher{"", errors.New("foo")}, + ) + + err := matcher.Matches("taco") + ExpectEq(nil, err) +} + +func (t *AnyOfTest) OneFatal() { + matcher := AnyOf( + &fakeAnyOfMatcher{"", errors.New("foo")}, + 17, + &fakeAnyOfMatcher{"", NewFatalError("taco")}, + &fakeAnyOfMatcher{"", errors.New("foo")}, + ) + + err := matcher.Matches(0) + ExpectThat(err, Error(Equals("taco"))) +} + +func (t *AnyOfTest) OneNil() { + var err error + matcher := AnyOf( + 13, + nil, + 19, + ) + + // No match + err = matcher.Matches(14) + ExpectNe(nil, err) + + // Match + err = matcher.Matches(nil) + ExpectEq(nil, err) +} + +func (t *AnyOfTest) AllFalseAndNotEqual() { + matcher := AnyOf( + &fakeAnyOfMatcher{"", errors.New("foo")}, + 17, + &fakeAnyOfMatcher{"", errors.New("foo")}, + 19, + ) + + err := matcher.Matches(0) + ExpectThat(err, Error(Equals(""))) +} + +func (t *AnyOfTest) DescriptionForEmptySet() { + matcher := AnyOf() + ExpectEq("or()", matcher.Description()) +} + +func (t *AnyOfTest) DescriptionForNonEmptySet() { + matcher := AnyOf( + &fakeAnyOfMatcher{"taco", nil}, + "burrito", + &fakeAnyOfMatcher{"enchilada", nil}, + ) + + ExpectEq("or(taco, burrito, enchilada)", matcher.Description()) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/any_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/any_test.go new file mode 100644 index 00000000000..410cc12825e --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/any_test.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_test + +import ( + . "github.com/smartystreets/assertions/internal/oglematchers" + . "github.com/smartystreets/assertions/internal/ogletest" +) + +//////////////////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////////////////// + +type AnyTest struct { +} + +func init() { RegisterTestSuite(&AnyTest{}) } + +//////////////////////////////////////////////////////////////////////// +// Tests +//////////////////////////////////////////////////////////////////////// + +func (t *AnyTest) Description() { + m := Any() + ExpectEq("is anything", m.Description()) +} + +func (t *AnyTest) Matches() { + var err error + m := Any() + + err = m.Matches(nil) + ExpectEq(nil, err) + + err = m.Matches(17) + ExpectEq(nil, err) + + err = m.Matches("taco") + ExpectEq(nil, err) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/contains.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/contains.go new file mode 100644 index 00000000000..2f326dbc5d6 --- /dev/null +++ b/src/mongo/gotools/vendor/src/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/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/contains_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/contains_test.go new file mode 100644 index 00000000000..dfc981c1488 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/contains_test.go @@ -0,0 +1,233 @@ +// 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_test + +import ( + . "github.com/smartystreets/assertions/internal/oglematchers" + . "github.com/smartystreets/assertions/internal/ogletest" +) + +//////////////////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////////////////// + +type ContainsTest struct {} +func init() { RegisterTestSuite(&ContainsTest{}) } + +//////////////////////////////////////////////////////////////////////// +// Tests +//////////////////////////////////////////////////////////////////////// + +func (t *ContainsTest) WrongTypeCandidates() { + m := Contains("") + ExpectEq("contains: ", m.Description()) + + var err error + + // Nil candidate + err = m.Matches(nil) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(HasSubstr("array"))) + ExpectThat(err, Error(HasSubstr("slice"))) + + // String candidate + err = m.Matches("") + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(HasSubstr("array"))) + ExpectThat(err, Error(HasSubstr("slice"))) + + // Map candidate + err = m.Matches(make(map[string]string)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(HasSubstr("array"))) + ExpectThat(err, Error(HasSubstr("slice"))) +} + +func (t *ContainsTest) NilArgument() { + m := Contains(nil) + ExpectEq("contains: is nil", m.Description()) + + var c interface{} + var err error + + // Empty array of pointers + c = [...]*int{} + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) + + // Empty slice of pointers + c = []*int{} + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) + + // Non-empty array of integers + c = [...]int{17, 0, 19} + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) + + // Non-empty slice of integers + c = []int{17, 0, 19} + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) + + // Non-matching array of pointers + c = [...]*int{new(int), new(int)} + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) + + // Non-matching slice of pointers + c = []*int{new(int), new(int)} + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) + + // Matching array of pointers + c = [...]*int{new(int), nil, new(int)} + err = m.Matches(c) + ExpectEq(nil, err) + + // Matching slice of pointers + c = []*int{new(int), nil, new(int)} + err = m.Matches(c) + ExpectEq(nil, err) + + // Non-matching slice of pointers from matching array + someArray := [...]*int{new(int), nil, new(int)} + c = someArray[0:1] + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) +} + +func (t *ContainsTest) StringArgument() { + m := Contains("taco") + ExpectEq("contains: taco", m.Description()) + + var c interface{} + var err error + + // Non-matching array of strings + c = [...]string{"burrito", "enchilada"} + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) + + // Non-matching slice of strings + c = []string{"burrito", "enchilada"} + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) + + // Matching array of strings + c = [...]string{"burrito", "taco", "enchilada"} + err = m.Matches(c) + ExpectEq(nil, err) + + // Matching slice of strings + c = []string{"burrito", "taco", "enchilada"} + err = m.Matches(c) + ExpectEq(nil, err) + + // Non-matching slice of strings from matching array + someArray := [...]string{"burrito", "taco", "enchilada"} + c = someArray[0:1] + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) +} + +func (t *ContainsTest) IntegerArgument() { + m := Contains(int(17)) + ExpectEq("contains: 17", m.Description()) + + var c interface{} + var err error + + // Non-matching array of integers + c = [...]int{13, 19} + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) + + // Non-matching slice of integers + c = []int{13, 19} + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) + + // Matching array of integers + c = [...]int{13, 17, 19} + err = m.Matches(c) + ExpectEq(nil, err) + + // Matching slice of integers + c = []int{13, 17, 19} + err = m.Matches(c) + ExpectEq(nil, err) + + // Non-matching slice of integers from matching array + someArray := [...]int{13, 17, 19} + c = someArray[0:1] + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) + + // Non-matching array of floats + c = [...]float32{13, 17.5, 19} + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) + + // Non-matching slice of floats + c = []float32{13, 17.5, 19} + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) + + // Matching array of floats + c = [...]float32{13, 17, 19} + err = m.Matches(c) + ExpectEq(nil, err) + + // Matching slice of floats + c = []float32{13, 17, 19} + err = m.Matches(c) + ExpectEq(nil, err) +} + +func (t *ContainsTest) MatcherArgument() { + m := Contains(HasSubstr("ac")) + ExpectEq("contains: has substring \"ac\"", m.Description()) + + var c interface{} + var err error + + // Non-matching array of strings + c = [...]string{"burrito", "enchilada"} + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) + + // Non-matching slice of strings + c = []string{"burrito", "enchilada"} + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) + + // Matching array of strings + c = [...]string{"burrito", "taco", "enchilada"} + err = m.Matches(c) + ExpectEq(nil, err) + + // Matching slice of strings + c = []string{"burrito", "taco", "enchilada"} + err = m.Matches(c) + ExpectEq(nil, err) + + // Non-matching slice of strings from matching array + someArray := [...]string{"burrito", "taco", "enchilada"} + c = someArray[0:1] + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/deep_equals.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/deep_equals.go new file mode 100644 index 00000000000..1d91baef32e --- /dev/null +++ b/src/mongo/gotools/vendor/src/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/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/deep_equals_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/deep_equals_test.go new file mode 100644 index 00000000000..a28113aaa6b --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/deep_equals_test.go @@ -0,0 +1,343 @@ +// 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_test + +import ( + . "github.com/smartystreets/assertions/internal/oglematchers" + . "github.com/smartystreets/assertions/internal/ogletest" + "bytes" + "testing" +) + +//////////////////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////////////////// + +type DeepEqualsTest struct {} +func init() { RegisterTestSuite(&DeepEqualsTest{}) } + +//////////////////////////////////////////////////////////////////////// +// Tests +//////////////////////////////////////////////////////////////////////// + +func (t *DeepEqualsTest) WrongTypeCandidateWithScalarValue() { + var x int = 17 + m := DeepEquals(x) + + var err error + + // Nil candidate. + err = m.Matches(nil) + AssertNe(nil, err) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(HasSubstr("type"))) + ExpectThat(err, Error(HasSubstr("<nil>"))) + + // Int alias candidate. + type intAlias int + err = m.Matches(intAlias(x)) + AssertNe(nil, err) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(HasSubstr("type"))) + ExpectThat(err, Error(HasSubstr("intAlias"))) + + // String candidate. + err = m.Matches("taco") + AssertNe(nil, err) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(HasSubstr("type"))) + ExpectThat(err, Error(HasSubstr("string"))) + + // Byte slice candidate. + err = m.Matches([]byte{}) + AssertNe(nil, err) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(HasSubstr("type"))) + ExpectThat(err, Error(HasSubstr("[]uint8"))) + + // Other slice candidate. + err = m.Matches([]uint16{}) + AssertNe(nil, err) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(HasSubstr("type"))) + ExpectThat(err, Error(HasSubstr("[]uint16"))) + + // Unsigned int candidate. + err = m.Matches(uint(17)) + AssertNe(nil, err) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(HasSubstr("type"))) + ExpectThat(err, Error(HasSubstr("uint"))) +} + +func (t *DeepEqualsTest) WrongTypeCandidateWithByteSliceValue() { + x := []byte{} + m := DeepEquals(x) + + var err error + + // Nil candidate. + err = m.Matches(nil) + AssertNe(nil, err) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(HasSubstr("type"))) + ExpectThat(err, Error(HasSubstr("<nil>"))) + + // String candidate. + err = m.Matches("taco") + AssertNe(nil, err) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(HasSubstr("type"))) + ExpectThat(err, Error(HasSubstr("string"))) + + // Slice candidate with wrong value type. + err = m.Matches([]uint16{}) + AssertNe(nil, err) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(HasSubstr("type"))) + ExpectThat(err, Error(HasSubstr("[]uint16"))) +} + +func (t *DeepEqualsTest) WrongTypeCandidateWithOtherSliceValue() { + x := []uint16{} + m := DeepEquals(x) + + var err error + + // Nil candidate. + err = m.Matches(nil) + AssertNe(nil, err) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(HasSubstr("type"))) + ExpectThat(err, Error(HasSubstr("<nil>"))) + + // String candidate. + err = m.Matches("taco") + AssertNe(nil, err) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(HasSubstr("type"))) + ExpectThat(err, Error(HasSubstr("string"))) + + // Byte slice candidate with wrong value type. + err = m.Matches([]byte{}) + AssertNe(nil, err) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(HasSubstr("type"))) + ExpectThat(err, Error(HasSubstr("[]uint8"))) + + // Other slice candidate with wrong value type. + err = m.Matches([]uint32{}) + AssertNe(nil, err) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(HasSubstr("type"))) + ExpectThat(err, Error(HasSubstr("[]uint32"))) +} + +func (t *DeepEqualsTest) WrongTypeCandidateWithNilLiteralValue() { + m := DeepEquals(nil) + + var err error + + // String candidate. + err = m.Matches("taco") + AssertNe(nil, err) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(HasSubstr("type"))) + ExpectThat(err, Error(HasSubstr("string"))) + + // Nil byte slice candidate. + err = m.Matches([]byte(nil)) + AssertNe(nil, err) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(HasSubstr("type"))) + ExpectThat(err, Error(HasSubstr("[]uint8"))) + + // Nil other slice candidate. + err = m.Matches([]uint16(nil)) + AssertNe(nil, err) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(HasSubstr("type"))) + ExpectThat(err, Error(HasSubstr("[]uint16"))) +} + +func (t *DeepEqualsTest) NilLiteralValue() { + m := DeepEquals(nil) + ExpectEq("deep equals: <nil>", m.Description()) + + var c interface{} + var err error + + // Nil literal candidate. + c = nil + err = m.Matches(c) + ExpectEq(nil, err) +} + +func (t *DeepEqualsTest) IntValue() { + m := DeepEquals(int(17)) + ExpectEq("deep equals: 17", m.Description()) + + var c interface{} + var err error + + // Matching int. + c = int(17) + err = m.Matches(c) + ExpectEq(nil, err) + + // Non-matching int. + c = int(18) + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) +} + +func (t *DeepEqualsTest) ByteSliceValue() { + x := []byte{17, 19} + m := DeepEquals(x) + ExpectEq("deep equals: [17 19]", m.Description()) + + var c []byte + var err error + + // Matching. + c = make([]byte, len(x)) + AssertEq(len(x), copy(c, x)) + + err = m.Matches(c) + ExpectEq(nil, err) + + // Nil slice. + c = []byte(nil) + err = m.Matches(c) + ExpectThat(err, Error(Equals("which is nil"))) + + // Prefix. + AssertGt(len(x), 1) + c = make([]byte, len(x)-1) + AssertEq(len(x)-1, copy(c, x)) + + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) + + // Suffix. + c = make([]byte, len(x)+1) + AssertEq(len(x), copy(c, x)) + + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) +} + +func (t *DeepEqualsTest) OtherSliceValue() { + x := []uint16{17, 19} + m := DeepEquals(x) + ExpectEq("deep equals: [17 19]", m.Description()) + + var c []uint16 + var err error + + // Matching. + c = make([]uint16, len(x)) + AssertEq(len(x), copy(c, x)) + + err = m.Matches(c) + ExpectEq(nil, err) + + // Nil slice. + c = []uint16(nil) + err = m.Matches(c) + ExpectThat(err, Error(Equals("which is nil"))) + + // Prefix. + AssertGt(len(x), 1) + c = make([]uint16, len(x)-1) + AssertEq(len(x)-1, copy(c, x)) + + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) + + // Suffix. + c = make([]uint16, len(x)+1) + AssertEq(len(x), copy(c, x)) + + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) +} + +func (t *DeepEqualsTest) NilByteSliceValue() { + x := []byte(nil) + m := DeepEquals(x) + ExpectEq("deep equals: <nil slice>", m.Description()) + + var c []byte + var err error + + // Nil slice. + c = []byte(nil) + err = m.Matches(c) + ExpectEq(nil, err) + + // Non-nil slice. + c = []byte{} + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) +} + +func (t *DeepEqualsTest) NilOtherSliceValue() { + x := []uint16(nil) + m := DeepEquals(x) + ExpectEq("deep equals: <nil slice>", m.Description()) + + var c []uint16 + var err error + + // Nil slice. + c = []uint16(nil) + err = m.Matches(c) + ExpectEq(nil, err) + + // Non-nil slice. + c = []uint16{} + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) +} + +//////////////////////////////////////////////////////////////////////// +// Benchmarks +//////////////////////////////////////////////////////////////////////// + +func benchmarkWithSize(b *testing.B, size int) { + b.StopTimer() + buf := bytes.Repeat([]byte{0x01}, size) + bufCopy := make([]byte, size) + copy(bufCopy, buf) + + matcher := DeepEquals(buf) + b.StartTimer() + + for i := 0; i < b.N; i++ { + matcher.Matches(bufCopy) + } + + b.SetBytes(int64(size)) +} + +func BenchmarkShortByteSlice(b *testing.B) { + benchmarkWithSize(b, 256) +} + +func BenchmarkLongByteSlice(b *testing.B) { + benchmarkWithSize(b, 1<<24) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/elements_are.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/elements_are.go new file mode 100644 index 00000000000..2941847c705 --- /dev/null +++ b/src/mongo/gotools/vendor/src/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/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/elements_are_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/elements_are_test.go new file mode 100644 index 00000000000..172584fa140 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/elements_are_test.go @@ -0,0 +1,208 @@ +// 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_test + +import ( + . "github.com/smartystreets/assertions/internal/oglematchers" + . "github.com/smartystreets/assertions/internal/ogletest" +) + +//////////////////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////////////////// + +type ElementsAreTest struct { +} + +func init() { RegisterTestSuite(&ElementsAreTest{}) } + +//////////////////////////////////////////////////////////////////////// +// Tests +//////////////////////////////////////////////////////////////////////// + +func (t *ElementsAreTest) EmptySet() { + m := ElementsAre() + ExpectEq("elements are: []", m.Description()) + + var c []interface{} + var err error + + // No candidates. + c = []interface{}{} + err = m.Matches(c) + ExpectEq(nil, err) + + // One candidate. + c = []interface{}{17} + err = m.Matches(c) + ExpectThat(err, Error(HasSubstr("length 1"))) +} + +func (t *ElementsAreTest) OneMatcher() { + m := ElementsAre(LessThan(17)) + ExpectEq("elements are: [less than 17]", m.Description()) + + var c []interface{} + var err error + + // No candidates. + c = []interface{}{} + err = m.Matches(c) + ExpectThat(err, Error(HasSubstr("length 0"))) + + // Matching candidate. + c = []interface{}{16} + err = m.Matches(c) + ExpectEq(nil, err) + + // Non-matching candidate. + c = []interface{}{19} + err = m.Matches(c) + ExpectNe(nil, err) + + // Two candidates. + c = []interface{}{17, 19} + err = m.Matches(c) + ExpectThat(err, Error(HasSubstr("length 2"))) +} + +func (t *ElementsAreTest) OneValue() { + m := ElementsAre(17) + ExpectEq("elements are: [17]", m.Description()) + + var c []interface{} + var err error + + // No candidates. + c = []interface{}{} + err = m.Matches(c) + ExpectThat(err, Error(HasSubstr("length 0"))) + + // Matching int. + c = []interface{}{int(17)} + err = m.Matches(c) + ExpectEq(nil, err) + + // Matching float. + c = []interface{}{float32(17)} + err = m.Matches(c) + ExpectEq(nil, err) + + // Non-matching candidate. + c = []interface{}{19} + err = m.Matches(c) + ExpectNe(nil, err) + + // Two candidates. + c = []interface{}{17, 19} + err = m.Matches(c) + ExpectThat(err, Error(HasSubstr("length 2"))) +} + +func (t *ElementsAreTest) MultipleElements() { + m := ElementsAre("taco", LessThan(17)) + ExpectEq("elements are: [taco, less than 17]", m.Description()) + + var c []interface{} + var err error + + // One candidate. + c = []interface{}{17} + err = m.Matches(c) + ExpectThat(err, Error(HasSubstr("length 1"))) + + // Both matching. + c = []interface{}{"taco", 16} + err = m.Matches(c) + ExpectEq(nil, err) + + // First non-matching. + c = []interface{}{"burrito", 16} + err = m.Matches(c) + ExpectThat(err, Error(Equals("whose element 0 doesn't match"))) + + // Second non-matching. + c = []interface{}{"taco", 17} + err = m.Matches(c) + ExpectThat(err, Error(Equals("whose element 1 doesn't match"))) + + // Three candidates. + c = []interface{}{"taco", 17, 19} + err = m.Matches(c) + ExpectThat(err, Error(HasSubstr("length 3"))) +} + +func (t *ElementsAreTest) ArrayCandidates() { + m := ElementsAre("taco", LessThan(17)) + + var err error + + // One candidate. + err = m.Matches([1]interface{}{"taco"}) + ExpectThat(err, Error(HasSubstr("length 1"))) + + // Both matching. + err = m.Matches([2]interface{}{"taco", 16}) + ExpectEq(nil, err) + + // First non-matching. + err = m.Matches([2]interface{}{"burrito", 16}) + ExpectThat(err, Error(Equals("whose element 0 doesn't match"))) +} + +func (t *ElementsAreTest) WrongTypeCandidate() { + m := ElementsAre("taco") + + var err error + + // String candidate. + err = m.Matches("taco") + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(HasSubstr("array"))) + ExpectThat(err, Error(HasSubstr("slice"))) + + // Map candidate. + err = m.Matches(map[string]string{}) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(HasSubstr("array"))) + ExpectThat(err, Error(HasSubstr("slice"))) + + // Nil candidate. + err = m.Matches(nil) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(HasSubstr("array"))) + ExpectThat(err, Error(HasSubstr("slice"))) +} + +func (t *ElementsAreTest) PropagatesFatality() { + m := ElementsAre(LessThan(17)) + ExpectEq("elements are: [less than 17]", m.Description()) + + var c []interface{} + var err error + + // Non-fatal error. + c = []interface{}{19} + err = m.Matches(c) + AssertNe(nil, err) + ExpectFalse(isFatal(err)) + + // Fatal error. + c = []interface{}{"taco"} + err = m.Matches(c) + AssertNe(nil, err) + ExpectTrue(isFatal(err)) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/equals.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/equals.go new file mode 100644 index 00000000000..a510707b3c7 --- /dev/null +++ b/src/mongo/gotools/vendor/src/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/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/equals_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/equals_test.go new file mode 100644 index 00000000000..6ac5df27329 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/equals_test.go @@ -0,0 +1,3864 @@ +// 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_test + +import ( + "fmt" + "math" + "unsafe" + + . "github.com/smartystreets/assertions/internal/oglematchers" + . "github.com/smartystreets/assertions/internal/ogletest" +) + +var someInt int = -17 + +//////////////////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////////////////// + +type EqualsTest struct { +} + +func init() { RegisterTestSuite(&EqualsTest{}) } + +type equalsTestCase struct { + candidate interface{} + expectedResult bool + shouldBeFatal bool + expectedError string +} + +func (t *EqualsTest) checkTestCases(matcher Matcher, cases []equalsTestCase) { + for i, c := range cases { + err := matcher.Matches(c.candidate) + ExpectEq( + c.expectedResult, + (err == nil), + "Result for case %d: %v (Error: %v)", i, c, err) + + if err == nil { + continue + } + + _, isFatal := err.(*FatalError) + ExpectEq(c.shouldBeFatal, isFatal, "Fatality for case %d: %v", i, c) + + ExpectThat(err, Error(Equals(c.expectedError)), "Case %d: %v", i, c) + } +} + +//////////////////////////////////////////////////////////////////////// +// nil +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) EqualsNil() { + matcher := Equals(nil) + ExpectEq("is nil", matcher.Description()) + + cases := []equalsTestCase{ + // Legal types + equalsTestCase{nil, true, false, ""}, + equalsTestCase{chan int(nil), true, false, ""}, + equalsTestCase{(func())(nil), true, false, ""}, + equalsTestCase{interface{}(nil), true, false, ""}, + equalsTestCase{map[int]int(nil), true, false, ""}, + equalsTestCase{(*int)(nil), true, false, ""}, + equalsTestCase{[]int(nil), true, false, ""}, + + equalsTestCase{make(chan int), false, false, ""}, + equalsTestCase{func() {}, false, false, ""}, + equalsTestCase{map[int]int{}, false, false, ""}, + equalsTestCase{&someInt, false, false, ""}, + equalsTestCase{[]int{}, false, false, ""}, + + // Illegal types + equalsTestCase{17, false, true, "which cannot be compared to nil"}, + equalsTestCase{int8(17), false, true, "which cannot be compared to nil"}, + equalsTestCase{uintptr(17), false, true, "which cannot be compared to nil"}, + equalsTestCase{[...]int{}, false, true, "which cannot be compared to nil"}, + equalsTestCase{"taco", false, true, "which cannot be compared to nil"}, + equalsTestCase{equalsTestCase{}, false, true, "which cannot be compared to nil"}, + equalsTestCase{unsafe.Pointer(&someInt), false, true, "which cannot be compared to nil"}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// Integer literals +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) NegativeIntegerLiteral() { + // -2^30 + matcher := Equals(-1073741824) + ExpectEq("-1073741824", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of -1073741824. + equalsTestCase{-1073741824, true, false, ""}, + equalsTestCase{-1073741824.0, true, false, ""}, + equalsTestCase{-1073741824 + 0i, true, false, ""}, + equalsTestCase{int(-1073741824), true, false, ""}, + equalsTestCase{int32(-1073741824), true, false, ""}, + equalsTestCase{int64(-1073741824), true, false, ""}, + equalsTestCase{float32(-1073741824), true, false, ""}, + equalsTestCase{float64(-1073741824), true, false, ""}, + equalsTestCase{complex64(-1073741824), true, false, ""}, + equalsTestCase{complex128(-1073741824), true, false, ""}, + equalsTestCase{interface{}(int(-1073741824)), true, false, ""}, + + // Values that would be -1073741824 in two's complement. + equalsTestCase{uint((1 << 32) - 1073741824), false, false, ""}, + equalsTestCase{uint32((1 << 32) - 1073741824), false, false, ""}, + equalsTestCase{uint64((1 << 64) - 1073741824), false, false, ""}, + equalsTestCase{uintptr((1 << 64) - 1073741824), false, false, ""}, + + // Non-equal values of signed integer type. + equalsTestCase{int(-1073741823), false, false, ""}, + equalsTestCase{int32(-1073741823), false, false, ""}, + equalsTestCase{int64(-1073741823), false, false, ""}, + + // Non-equal values of other numeric types. + equalsTestCase{float64(-1073741824.1), false, false, ""}, + equalsTestCase{float64(-1073741823.9), false, false, ""}, + equalsTestCase{complex128(-1073741823), false, false, ""}, + equalsTestCase{complex128(-1073741824 + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) PositiveIntegerLiteral() { + // 2^30 + matcher := Equals(1073741824) + ExpectEq("1073741824", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of 1073741824. + equalsTestCase{1073741824, true, false, ""}, + equalsTestCase{1073741824.0, true, false, ""}, + equalsTestCase{1073741824 + 0i, true, false, ""}, + equalsTestCase{int(1073741824), true, false, ""}, + equalsTestCase{uint(1073741824), true, false, ""}, + equalsTestCase{int32(1073741824), true, false, ""}, + equalsTestCase{int64(1073741824), true, false, ""}, + equalsTestCase{uint32(1073741824), true, false, ""}, + equalsTestCase{uint64(1073741824), true, false, ""}, + equalsTestCase{uintptr(1073741824), true, false, ""}, + equalsTestCase{float32(1073741824), true, false, ""}, + equalsTestCase{float64(1073741824), true, false, ""}, + equalsTestCase{complex64(1073741824), true, false, ""}, + equalsTestCase{complex128(1073741824), true, false, ""}, + equalsTestCase{interface{}(int(1073741824)), true, false, ""}, + equalsTestCase{interface{}(uint(1073741824)), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int(1073741823), false, false, ""}, + equalsTestCase{int32(1073741823), false, false, ""}, + equalsTestCase{int64(1073741823), false, false, ""}, + equalsTestCase{float64(1073741824.1), false, false, ""}, + equalsTestCase{float64(1073741823.9), false, false, ""}, + equalsTestCase{complex128(1073741823), false, false, ""}, + equalsTestCase{complex128(1073741824 + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// Floating point literals +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) NegativeIntegralFloatingPointLiteral() { + // -2^30 + matcher := Equals(-1073741824.0) + ExpectEq("-1.073741824e+09", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of -1073741824. + equalsTestCase{-1073741824, true, false, ""}, + equalsTestCase{-1073741824.0, true, false, ""}, + equalsTestCase{-1073741824 + 0i, true, false, ""}, + equalsTestCase{int(-1073741824), true, false, ""}, + equalsTestCase{int32(-1073741824), true, false, ""}, + equalsTestCase{int64(-1073741824), true, false, ""}, + equalsTestCase{float32(-1073741824), true, false, ""}, + equalsTestCase{float64(-1073741824), true, false, ""}, + equalsTestCase{complex64(-1073741824), true, false, ""}, + equalsTestCase{complex128(-1073741824), true, false, ""}, + equalsTestCase{interface{}(int(-1073741824)), true, false, ""}, + equalsTestCase{interface{}(float64(-1073741824)), true, false, ""}, + + // Values that would be -1073741824 in two's complement. + equalsTestCase{uint((1 << 32) - 1073741824), false, false, ""}, + equalsTestCase{uint32((1 << 32) - 1073741824), false, false, ""}, + equalsTestCase{uint64((1 << 64) - 1073741824), false, false, ""}, + equalsTestCase{uintptr((1 << 64) - 1073741824), false, false, ""}, + + // Non-equal values of signed integer type. + equalsTestCase{int(-1073741823), false, false, ""}, + equalsTestCase{int32(-1073741823), false, false, ""}, + equalsTestCase{int64(-1073741823), false, false, ""}, + + // Non-equal values of other numeric types. + equalsTestCase{float64(-1073741824.1), false, false, ""}, + equalsTestCase{float64(-1073741823.9), false, false, ""}, + equalsTestCase{complex128(-1073741823), false, false, ""}, + equalsTestCase{complex128(-1073741824 + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) PositiveIntegralFloatingPointLiteral() { + // 2^30 + matcher := Equals(1073741824.0) + ExpectEq("1.073741824e+09", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of 1073741824. + equalsTestCase{1073741824, true, false, ""}, + equalsTestCase{1073741824.0, true, false, ""}, + equalsTestCase{1073741824 + 0i, true, false, ""}, + equalsTestCase{int(1073741824), true, false, ""}, + equalsTestCase{int32(1073741824), true, false, ""}, + equalsTestCase{int64(1073741824), true, false, ""}, + equalsTestCase{uint(1073741824), true, false, ""}, + equalsTestCase{uint32(1073741824), true, false, ""}, + equalsTestCase{uint64(1073741824), true, false, ""}, + equalsTestCase{float32(1073741824), true, false, ""}, + equalsTestCase{float64(1073741824), true, false, ""}, + equalsTestCase{complex64(1073741824), true, false, ""}, + equalsTestCase{complex128(1073741824), true, false, ""}, + equalsTestCase{interface{}(int(1073741824)), true, false, ""}, + equalsTestCase{interface{}(float64(1073741824)), true, false, ""}, + + // Values that would be 1073741824 in two's complement. + equalsTestCase{uint((1 << 32) - 1073741824), false, false, ""}, + equalsTestCase{uint32((1 << 32) - 1073741824), false, false, ""}, + equalsTestCase{uint64((1 << 64) - 1073741824), false, false, ""}, + equalsTestCase{uintptr((1 << 64) - 1073741824), false, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int(1073741823), false, false, ""}, + equalsTestCase{int32(1073741823), false, false, ""}, + equalsTestCase{int64(1073741823), false, false, ""}, + equalsTestCase{uint(1073741823), false, false, ""}, + equalsTestCase{uint32(1073741823), false, false, ""}, + equalsTestCase{uint64(1073741823), false, false, ""}, + equalsTestCase{float64(1073741824.1), false, false, ""}, + equalsTestCase{float64(1073741823.9), false, false, ""}, + equalsTestCase{complex128(1073741823), false, false, ""}, + equalsTestCase{complex128(1073741824 + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) NonIntegralFloatingPointLiteral() { + matcher := Equals(17.1) + ExpectEq("17.1", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of 17.1. + equalsTestCase{17.1, true, false, ""}, + equalsTestCase{17.1, true, false, ""}, + equalsTestCase{17.1 + 0i, true, false, ""}, + equalsTestCase{float32(17.1), true, false, ""}, + equalsTestCase{float64(17.1), true, false, ""}, + equalsTestCase{complex64(17.1), true, false, ""}, + equalsTestCase{complex128(17.1), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{17, false, false, ""}, + equalsTestCase{17.2, false, false, ""}, + equalsTestCase{18, false, false, ""}, + equalsTestCase{int(17), false, false, ""}, + equalsTestCase{int(18), false, false, ""}, + equalsTestCase{int32(17), false, false, ""}, + equalsTestCase{int64(17), false, false, ""}, + equalsTestCase{uint(17), false, false, ""}, + equalsTestCase{uint32(17), false, false, ""}, + equalsTestCase{uint64(17), false, false, ""}, + equalsTestCase{uintptr(17), false, false, ""}, + equalsTestCase{complex128(17.1 + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// bool +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) False() { + matcher := Equals(false) + ExpectEq("false", matcher.Description()) + + cases := []equalsTestCase{ + // bools + equalsTestCase{false, true, false, ""}, + equalsTestCase{bool(false), true, false, ""}, + + equalsTestCase{true, false, false, ""}, + equalsTestCase{bool(true), false, false, ""}, + + // Other types. + equalsTestCase{int(0), false, true, "which is not a bool"}, + equalsTestCase{int8(0), false, true, "which is not a bool"}, + equalsTestCase{int16(0), false, true, "which is not a bool"}, + equalsTestCase{int32(0), false, true, "which is not a bool"}, + equalsTestCase{int64(0), false, true, "which is not a bool"}, + equalsTestCase{uint(0), false, true, "which is not a bool"}, + equalsTestCase{uint8(0), false, true, "which is not a bool"}, + equalsTestCase{uint16(0), false, true, "which is not a bool"}, + equalsTestCase{uint32(0), false, true, "which is not a bool"}, + equalsTestCase{uint64(0), false, true, "which is not a bool"}, + equalsTestCase{uintptr(0), false, true, "which is not a bool"}, + equalsTestCase{[...]int{}, false, true, "which is not a bool"}, + equalsTestCase{make(chan int), false, true, "which is not a bool"}, + equalsTestCase{func() {}, false, true, "which is not a bool"}, + equalsTestCase{map[int]int{}, false, true, "which is not a bool"}, + equalsTestCase{&someInt, false, true, "which is not a bool"}, + equalsTestCase{[]int{}, false, true, "which is not a bool"}, + equalsTestCase{"taco", false, true, "which is not a bool"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not a bool"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) True() { + matcher := Equals(true) + ExpectEq("true", matcher.Description()) + + cases := []equalsTestCase{ + // bools + equalsTestCase{true, true, false, ""}, + equalsTestCase{bool(true), true, false, ""}, + + equalsTestCase{false, false, false, ""}, + equalsTestCase{bool(false), false, false, ""}, + + // Other types. + equalsTestCase{int(1), false, true, "which is not a bool"}, + equalsTestCase{int8(1), false, true, "which is not a bool"}, + equalsTestCase{int16(1), false, true, "which is not a bool"}, + equalsTestCase{int32(1), false, true, "which is not a bool"}, + equalsTestCase{int64(1), false, true, "which is not a bool"}, + equalsTestCase{uint(1), false, true, "which is not a bool"}, + equalsTestCase{uint8(1), false, true, "which is not a bool"}, + equalsTestCase{uint16(1), false, true, "which is not a bool"}, + equalsTestCase{uint32(1), false, true, "which is not a bool"}, + equalsTestCase{uint64(1), false, true, "which is not a bool"}, + equalsTestCase{uintptr(1), false, true, "which is not a bool"}, + equalsTestCase{[...]int{}, false, true, "which is not a bool"}, + equalsTestCase{make(chan int), false, true, "which is not a bool"}, + equalsTestCase{func() {}, false, true, "which is not a bool"}, + equalsTestCase{map[int]int{}, false, true, "which is not a bool"}, + equalsTestCase{&someInt, false, true, "which is not a bool"}, + equalsTestCase{[]int{}, false, true, "which is not a bool"}, + equalsTestCase{"taco", false, true, "which is not a bool"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not a bool"}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// int +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) NegativeInt() { + // -2^30 + matcher := Equals(int(-1073741824)) + ExpectEq("-1073741824", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of -1073741824. + equalsTestCase{-1073741824, true, false, ""}, + equalsTestCase{-1073741824.0, true, false, ""}, + equalsTestCase{-1073741824 + 0i, true, false, ""}, + equalsTestCase{int(-1073741824), true, false, ""}, + equalsTestCase{int32(-1073741824), true, false, ""}, + equalsTestCase{int64(-1073741824), true, false, ""}, + equalsTestCase{float32(-1073741824), true, false, ""}, + equalsTestCase{float64(-1073741824), true, false, ""}, + equalsTestCase{complex64(-1073741824), true, false, ""}, + equalsTestCase{complex128(-1073741824), true, false, ""}, + equalsTestCase{interface{}(int(-1073741824)), true, false, ""}, + + // Values that would be -1073741824 in two's complement. + equalsTestCase{uint((1 << 32) - 1073741824), false, false, ""}, + equalsTestCase{uint32((1 << 32) - 1073741824), false, false, ""}, + equalsTestCase{uint64((1 << 64) - 1073741824), false, false, ""}, + equalsTestCase{uintptr((1 << 64) - 1073741824), false, false, ""}, + + // Non-equal values of signed integer type. + equalsTestCase{int(-1073741823), false, false, ""}, + equalsTestCase{int32(-1073741823), false, false, ""}, + equalsTestCase{int64(-1073741823), false, false, ""}, + + // Non-equal values of other numeric types. + equalsTestCase{float64(-1073741824.1), false, false, ""}, + equalsTestCase{float64(-1073741823.9), false, false, ""}, + equalsTestCase{complex128(-1073741823), false, false, ""}, + equalsTestCase{complex128(-1073741824 + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) PositiveInt() { + // 2^30 + matcher := Equals(int(1073741824)) + ExpectEq("1073741824", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of 1073741824. + equalsTestCase{1073741824, true, false, ""}, + equalsTestCase{1073741824.0, true, false, ""}, + equalsTestCase{1073741824 + 0i, true, false, ""}, + equalsTestCase{int(1073741824), true, false, ""}, + equalsTestCase{uint(1073741824), true, false, ""}, + equalsTestCase{int32(1073741824), true, false, ""}, + equalsTestCase{int64(1073741824), true, false, ""}, + equalsTestCase{uint32(1073741824), true, false, ""}, + equalsTestCase{uint64(1073741824), true, false, ""}, + equalsTestCase{uintptr(1073741824), true, false, ""}, + equalsTestCase{float32(1073741824), true, false, ""}, + equalsTestCase{float64(1073741824), true, false, ""}, + equalsTestCase{complex64(1073741824), true, false, ""}, + equalsTestCase{complex128(1073741824), true, false, ""}, + equalsTestCase{interface{}(int(1073741824)), true, false, ""}, + equalsTestCase{interface{}(uint(1073741824)), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int(1073741823), false, false, ""}, + equalsTestCase{int32(1073741823), false, false, ""}, + equalsTestCase{int64(1073741823), false, false, ""}, + equalsTestCase{float64(1073741824.1), false, false, ""}, + equalsTestCase{float64(1073741823.9), false, false, ""}, + equalsTestCase{complex128(1073741823), false, false, ""}, + equalsTestCase{complex128(1073741824 + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// int8 +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) NegativeInt8() { + matcher := Equals(int8(-17)) + ExpectEq("-17", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of -17. + equalsTestCase{-17, true, false, ""}, + equalsTestCase{-17.0, true, false, ""}, + equalsTestCase{-17 + 0i, true, false, ""}, + equalsTestCase{int(-17), true, false, ""}, + equalsTestCase{int8(-17), true, false, ""}, + equalsTestCase{int16(-17), true, false, ""}, + equalsTestCase{int32(-17), true, false, ""}, + equalsTestCase{int64(-17), true, false, ""}, + equalsTestCase{float32(-17), true, false, ""}, + equalsTestCase{float64(-17), true, false, ""}, + equalsTestCase{complex64(-17), true, false, ""}, + equalsTestCase{complex128(-17), true, false, ""}, + equalsTestCase{interface{}(int(-17)), true, false, ""}, + + // Values that would be -17 in two's complement. + equalsTestCase{uint((1 << 32) - 17), false, false, ""}, + equalsTestCase{uint8((1 << 8) - 17), false, false, ""}, + equalsTestCase{uint16((1 << 16) - 17), false, false, ""}, + equalsTestCase{uint32((1 << 32) - 17), false, false, ""}, + equalsTestCase{uint64((1 << 64) - 17), false, false, ""}, + equalsTestCase{uintptr((1 << 64) - 17), false, false, ""}, + + // Non-equal values of signed integer type. + equalsTestCase{int(-16), false, false, ""}, + equalsTestCase{int8(-16), false, false, ""}, + equalsTestCase{int16(-16), false, false, ""}, + equalsTestCase{int32(-16), false, false, ""}, + equalsTestCase{int64(-16), false, false, ""}, + + // Non-equal values of other numeric types. + equalsTestCase{float32(-17.1), false, false, ""}, + equalsTestCase{float32(-16.9), false, false, ""}, + equalsTestCase{complex64(-16), false, false, ""}, + equalsTestCase{complex64(-17 + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{-17}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{-17}, false, true, "which is not numeric"}, + equalsTestCase{"-17", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) ZeroInt8() { + matcher := Equals(int8(0)) + ExpectEq("0", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of 0. + equalsTestCase{0, true, false, ""}, + equalsTestCase{0.0, true, false, ""}, + equalsTestCase{0 + 0i, true, false, ""}, + equalsTestCase{int(0), true, false, ""}, + equalsTestCase{int8(0), true, false, ""}, + equalsTestCase{int16(0), true, false, ""}, + equalsTestCase{int32(0), true, false, ""}, + equalsTestCase{int64(0), true, false, ""}, + equalsTestCase{float32(0), true, false, ""}, + equalsTestCase{float64(0), true, false, ""}, + equalsTestCase{complex64(0), true, false, ""}, + equalsTestCase{complex128(0), true, false, ""}, + equalsTestCase{interface{}(int(0)), true, false, ""}, + equalsTestCase{uint(0), true, false, ""}, + equalsTestCase{uint8(0), true, false, ""}, + equalsTestCase{uint16(0), true, false, ""}, + equalsTestCase{uint32(0), true, false, ""}, + equalsTestCase{uint64(0), true, false, ""}, + equalsTestCase{uintptr(0), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int(1), false, false, ""}, + equalsTestCase{int8(1), false, false, ""}, + equalsTestCase{int16(1), false, false, ""}, + equalsTestCase{int32(1), false, false, ""}, + equalsTestCase{int64(1), false, false, ""}, + equalsTestCase{float32(-0.1), false, false, ""}, + equalsTestCase{float32(0.1), false, false, ""}, + equalsTestCase{complex64(1), false, false, ""}, + equalsTestCase{complex64(0 + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{0}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{0}, false, true, "which is not numeric"}, + equalsTestCase{"0", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) PositiveInt8() { + matcher := Equals(int8(17)) + ExpectEq("17", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of 17. + equalsTestCase{17, true, false, ""}, + equalsTestCase{17.0, true, false, ""}, + equalsTestCase{17 + 0i, true, false, ""}, + equalsTestCase{int(17), true, false, ""}, + equalsTestCase{int8(17), true, false, ""}, + equalsTestCase{int16(17), true, false, ""}, + equalsTestCase{int32(17), true, false, ""}, + equalsTestCase{int64(17), true, false, ""}, + equalsTestCase{float32(17), true, false, ""}, + equalsTestCase{float64(17), true, false, ""}, + equalsTestCase{complex64(17), true, false, ""}, + equalsTestCase{complex128(17), true, false, ""}, + equalsTestCase{interface{}(int(17)), true, false, ""}, + equalsTestCase{uint(17), true, false, ""}, + equalsTestCase{uint8(17), true, false, ""}, + equalsTestCase{uint16(17), true, false, ""}, + equalsTestCase{uint32(17), true, false, ""}, + equalsTestCase{uint64(17), true, false, ""}, + equalsTestCase{uintptr(17), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int(16), false, false, ""}, + equalsTestCase{int8(16), false, false, ""}, + equalsTestCase{int16(16), false, false, ""}, + equalsTestCase{int32(16), false, false, ""}, + equalsTestCase{int64(16), false, false, ""}, + equalsTestCase{float32(16.9), false, false, ""}, + equalsTestCase{float32(17.1), false, false, ""}, + equalsTestCase{complex64(16), false, false, ""}, + equalsTestCase{complex64(17 + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{17}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{17}, false, true, "which is not numeric"}, + equalsTestCase{"17", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// int16 +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) NegativeInt16() { + matcher := Equals(int16(-32766)) + ExpectEq("-32766", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of -32766. + equalsTestCase{-32766, true, false, ""}, + equalsTestCase{-32766.0, true, false, ""}, + equalsTestCase{-32766 + 0i, true, false, ""}, + equalsTestCase{int(-32766), true, false, ""}, + equalsTestCase{int16(-32766), true, false, ""}, + equalsTestCase{int32(-32766), true, false, ""}, + equalsTestCase{int64(-32766), true, false, ""}, + equalsTestCase{float32(-32766), true, false, ""}, + equalsTestCase{float64(-32766), true, false, ""}, + equalsTestCase{complex64(-32766), true, false, ""}, + equalsTestCase{complex128(-32766), true, false, ""}, + equalsTestCase{interface{}(int(-32766)), true, false, ""}, + + // Values that would be -32766 in two's complement. + equalsTestCase{uint((1 << 32) - 32766), false, false, ""}, + equalsTestCase{uint16((1 << 16) - 32766), false, false, ""}, + equalsTestCase{uint32((1 << 32) - 32766), false, false, ""}, + equalsTestCase{uint64((1 << 64) - 32766), false, false, ""}, + equalsTestCase{uintptr((1 << 64) - 32766), false, false, ""}, + + // Non-equal values of signed integer type. + equalsTestCase{int(-16), false, false, ""}, + equalsTestCase{int8(-16), false, false, ""}, + equalsTestCase{int16(-16), false, false, ""}, + equalsTestCase{int32(-16), false, false, ""}, + equalsTestCase{int64(-16), false, false, ""}, + + // Non-equal values of other numeric types. + equalsTestCase{float32(-32766.1), false, false, ""}, + equalsTestCase{float32(-32765.9), false, false, ""}, + equalsTestCase{complex64(-32766.1), false, false, ""}, + equalsTestCase{complex64(-32766 + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{-32766}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{-32766}, false, true, "which is not numeric"}, + equalsTestCase{"-32766", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) ZeroInt16() { + matcher := Equals(int16(0)) + ExpectEq("0", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of 0. + equalsTestCase{0, true, false, ""}, + equalsTestCase{0.0, true, false, ""}, + equalsTestCase{0 + 0i, true, false, ""}, + equalsTestCase{int(0), true, false, ""}, + equalsTestCase{int8(0), true, false, ""}, + equalsTestCase{int16(0), true, false, ""}, + equalsTestCase{int32(0), true, false, ""}, + equalsTestCase{int64(0), true, false, ""}, + equalsTestCase{float32(0), true, false, ""}, + equalsTestCase{float64(0), true, false, ""}, + equalsTestCase{complex64(0), true, false, ""}, + equalsTestCase{complex128(0), true, false, ""}, + equalsTestCase{interface{}(int(0)), true, false, ""}, + equalsTestCase{uint(0), true, false, ""}, + equalsTestCase{uint8(0), true, false, ""}, + equalsTestCase{uint16(0), true, false, ""}, + equalsTestCase{uint32(0), true, false, ""}, + equalsTestCase{uint64(0), true, false, ""}, + equalsTestCase{uintptr(0), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int(1), false, false, ""}, + equalsTestCase{int8(1), false, false, ""}, + equalsTestCase{int16(1), false, false, ""}, + equalsTestCase{int32(1), false, false, ""}, + equalsTestCase{int64(1), false, false, ""}, + equalsTestCase{float32(-0.1), false, false, ""}, + equalsTestCase{float32(0.1), false, false, ""}, + equalsTestCase{complex64(1), false, false, ""}, + equalsTestCase{complex64(0 + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{0}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{0}, false, true, "which is not numeric"}, + equalsTestCase{"0", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) PositiveInt16() { + matcher := Equals(int16(32765)) + ExpectEq("32765", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of 32765. + equalsTestCase{32765, true, false, ""}, + equalsTestCase{32765.0, true, false, ""}, + equalsTestCase{32765 + 0i, true, false, ""}, + equalsTestCase{int(32765), true, false, ""}, + equalsTestCase{int16(32765), true, false, ""}, + equalsTestCase{int32(32765), true, false, ""}, + equalsTestCase{int64(32765), true, false, ""}, + equalsTestCase{float32(32765), true, false, ""}, + equalsTestCase{float64(32765), true, false, ""}, + equalsTestCase{complex64(32765), true, false, ""}, + equalsTestCase{complex128(32765), true, false, ""}, + equalsTestCase{interface{}(int(32765)), true, false, ""}, + equalsTestCase{uint(32765), true, false, ""}, + equalsTestCase{uint16(32765), true, false, ""}, + equalsTestCase{uint32(32765), true, false, ""}, + equalsTestCase{uint64(32765), true, false, ""}, + equalsTestCase{uintptr(32765), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int(32764), false, false, ""}, + equalsTestCase{int16(32764), false, false, ""}, + equalsTestCase{int32(32764), false, false, ""}, + equalsTestCase{int64(32764), false, false, ""}, + equalsTestCase{float32(32764.9), false, false, ""}, + equalsTestCase{float32(32765.1), false, false, ""}, + equalsTestCase{complex64(32765.9), false, false, ""}, + equalsTestCase{complex64(32765 + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{32765}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{32765}, false, true, "which is not numeric"}, + equalsTestCase{"32765", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// int32 +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) NegativeInt32() { + // -2^30 + matcher := Equals(int32(-1073741824)) + ExpectEq("-1073741824", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of -1073741824. + equalsTestCase{-1073741824, true, false, ""}, + equalsTestCase{-1073741824.0, true, false, ""}, + equalsTestCase{-1073741824 + 0i, true, false, ""}, + equalsTestCase{int(-1073741824), true, false, ""}, + equalsTestCase{int32(-1073741824), true, false, ""}, + equalsTestCase{int64(-1073741824), true, false, ""}, + equalsTestCase{float32(-1073741824), true, false, ""}, + equalsTestCase{float64(-1073741824), true, false, ""}, + equalsTestCase{complex64(-1073741824), true, false, ""}, + equalsTestCase{complex128(-1073741824), true, false, ""}, + equalsTestCase{interface{}(int(-1073741824)), true, false, ""}, + + // Values that would be -1073741824 in two's complement. + equalsTestCase{uint((1 << 32) - 1073741824), false, false, ""}, + equalsTestCase{uint32((1 << 32) - 1073741824), false, false, ""}, + equalsTestCase{uint64((1 << 64) - 1073741824), false, false, ""}, + equalsTestCase{uintptr((1 << 64) - 1073741824), false, false, ""}, + + // Non-equal values of signed integer type. + equalsTestCase{int(-1073741823), false, false, ""}, + equalsTestCase{int32(-1073741823), false, false, ""}, + equalsTestCase{int64(-1073741823), false, false, ""}, + + // Non-equal values of other numeric types. + equalsTestCase{float64(-1073741824.1), false, false, ""}, + equalsTestCase{float64(-1073741823.9), false, false, ""}, + equalsTestCase{complex128(-1073741823), false, false, ""}, + equalsTestCase{complex128(-1073741824 + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) PositiveInt32() { + // 2^30 + matcher := Equals(int32(1073741824)) + ExpectEq("1073741824", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of 1073741824. + equalsTestCase{1073741824, true, false, ""}, + equalsTestCase{1073741824.0, true, false, ""}, + equalsTestCase{1073741824 + 0i, true, false, ""}, + equalsTestCase{int(1073741824), true, false, ""}, + equalsTestCase{uint(1073741824), true, false, ""}, + equalsTestCase{int32(1073741824), true, false, ""}, + equalsTestCase{int64(1073741824), true, false, ""}, + equalsTestCase{uint32(1073741824), true, false, ""}, + equalsTestCase{uint64(1073741824), true, false, ""}, + equalsTestCase{uintptr(1073741824), true, false, ""}, + equalsTestCase{float32(1073741824), true, false, ""}, + equalsTestCase{float64(1073741824), true, false, ""}, + equalsTestCase{complex64(1073741824), true, false, ""}, + equalsTestCase{complex128(1073741824), true, false, ""}, + equalsTestCase{interface{}(int(1073741824)), true, false, ""}, + equalsTestCase{interface{}(uint(1073741824)), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int(1073741823), false, false, ""}, + equalsTestCase{int32(1073741823), false, false, ""}, + equalsTestCase{int64(1073741823), false, false, ""}, + equalsTestCase{float64(1073741824.1), false, false, ""}, + equalsTestCase{float64(1073741823.9), false, false, ""}, + equalsTestCase{complex128(1073741823), false, false, ""}, + equalsTestCase{complex128(1073741824 + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// int64 +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) NegativeInt64() { + // -2^40 + matcher := Equals(int64(-1099511627776)) + ExpectEq("-1099511627776", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of -1099511627776. + equalsTestCase{-1099511627776.0, true, false, ""}, + equalsTestCase{-1099511627776 + 0i, true, false, ""}, + equalsTestCase{int64(-1099511627776), true, false, ""}, + equalsTestCase{float32(-1099511627776), true, false, ""}, + equalsTestCase{float64(-1099511627776), true, false, ""}, + equalsTestCase{complex64(-1099511627776), true, false, ""}, + equalsTestCase{complex128(-1099511627776), true, false, ""}, + equalsTestCase{interface{}(int64(-1099511627776)), true, false, ""}, + + // Values that would be -1099511627776 in two's complement. + equalsTestCase{uint64((1 << 64) - 1099511627776), false, false, ""}, + + // Non-equal values of signed integer type. + equalsTestCase{int64(-1099511627775), false, false, ""}, + + // Non-equal values of other numeric types. + equalsTestCase{float64(-1099511627776.1), false, false, ""}, + equalsTestCase{float64(-1099511627775.9), false, false, ""}, + equalsTestCase{complex128(-1099511627775), false, false, ""}, + equalsTestCase{complex128(-1099511627776 + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) PositiveInt64() { + // 2^40 + matcher := Equals(int64(1099511627776)) + ExpectEq("1099511627776", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of 1099511627776. + equalsTestCase{1099511627776.0, true, false, ""}, + equalsTestCase{1099511627776 + 0i, true, false, ""}, + equalsTestCase{int64(1099511627776), true, false, ""}, + equalsTestCase{uint64(1099511627776), true, false, ""}, + equalsTestCase{uintptr(1099511627776), true, false, ""}, + equalsTestCase{float32(1099511627776), true, false, ""}, + equalsTestCase{float64(1099511627776), true, false, ""}, + equalsTestCase{complex64(1099511627776), true, false, ""}, + equalsTestCase{complex128(1099511627776), true, false, ""}, + equalsTestCase{interface{}(int64(1099511627776)), true, false, ""}, + equalsTestCase{interface{}(uint64(1099511627776)), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int64(1099511627775), false, false, ""}, + equalsTestCase{uint64(1099511627775), false, false, ""}, + equalsTestCase{float64(1099511627776.1), false, false, ""}, + equalsTestCase{float64(1099511627775.9), false, false, ""}, + equalsTestCase{complex128(1099511627775), false, false, ""}, + equalsTestCase{complex128(1099511627776 + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) Int64NotExactlyRepresentableBySinglePrecision() { + // Single-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo25 = 1 << 25 + matcher := Equals(int64(kTwoTo25 + 1)) + ExpectEq("33554433", matcher.Description()) + + cases := []equalsTestCase{ + // Integers. + equalsTestCase{int64(kTwoTo25 + 0), false, false, ""}, + equalsTestCase{int64(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{int64(kTwoTo25 + 2), false, false, ""}, + + equalsTestCase{uint64(kTwoTo25 + 0), false, false, ""}, + equalsTestCase{uint64(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{uint64(kTwoTo25 + 2), false, false, ""}, + + // Single-precision floating point. + equalsTestCase{float32(kTwoTo25 - 2), false, false, ""}, + equalsTestCase{float32(kTwoTo25 - 1), true, false, ""}, + equalsTestCase{float32(kTwoTo25 + 0), true, false, ""}, + equalsTestCase{float32(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{float32(kTwoTo25 + 2), true, false, ""}, + equalsTestCase{float32(kTwoTo25 + 3), false, false, ""}, + + equalsTestCase{complex64(kTwoTo25 - 2), false, false, ""}, + equalsTestCase{complex64(kTwoTo25 - 1), true, false, ""}, + equalsTestCase{complex64(kTwoTo25 + 0), true, false, ""}, + equalsTestCase{complex64(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{complex64(kTwoTo25 + 2), true, false, ""}, + equalsTestCase{complex64(kTwoTo25 + 3), false, false, ""}, + + // Double-precision floating point. + equalsTestCase{float64(kTwoTo25 + 0), false, false, ""}, + equalsTestCase{float64(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{float64(kTwoTo25 + 2), false, false, ""}, + + equalsTestCase{complex128(kTwoTo25 + 0), false, false, ""}, + equalsTestCase{complex128(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{complex128(kTwoTo25 + 2), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) Int64NotExactlyRepresentableByDoublePrecision() { + // Double-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^54-1, 2^54+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo54 = 1 << 54 + matcher := Equals(int64(kTwoTo54 + 1)) + ExpectEq("18014398509481985", matcher.Description()) + + cases := []equalsTestCase{ + // Integers. + equalsTestCase{int64(kTwoTo54 + 0), false, false, ""}, + equalsTestCase{int64(kTwoTo54 + 1), true, false, ""}, + equalsTestCase{int64(kTwoTo54 + 2), false, false, ""}, + + equalsTestCase{uint64(kTwoTo54 + 0), false, false, ""}, + equalsTestCase{uint64(kTwoTo54 + 1), true, false, ""}, + equalsTestCase{uint64(kTwoTo54 + 2), false, false, ""}, + + // Double-precision floating point. + equalsTestCase{float64(kTwoTo54 - 2), false, false, ""}, + equalsTestCase{float64(kTwoTo54 - 1), true, false, ""}, + equalsTestCase{float64(kTwoTo54 + 0), true, false, ""}, + equalsTestCase{float64(kTwoTo54 + 1), true, false, ""}, + equalsTestCase{float64(kTwoTo54 + 2), true, false, ""}, + equalsTestCase{float64(kTwoTo54 + 3), false, false, ""}, + + equalsTestCase{complex128(kTwoTo54 - 2), false, false, ""}, + equalsTestCase{complex128(kTwoTo54 - 1), true, false, ""}, + equalsTestCase{complex128(kTwoTo54 + 0), true, false, ""}, + equalsTestCase{complex128(kTwoTo54 + 1), true, false, ""}, + equalsTestCase{complex128(kTwoTo54 + 2), true, false, ""}, + equalsTestCase{complex128(kTwoTo54 + 3), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// uint +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) SmallUint() { + const kExpected = 17 + matcher := Equals(uint(kExpected)) + ExpectEq("17", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of the expected value. + equalsTestCase{17, true, false, ""}, + equalsTestCase{17.0, true, false, ""}, + equalsTestCase{17 + 0i, true, false, ""}, + equalsTestCase{int(kExpected), true, false, ""}, + equalsTestCase{int8(kExpected), true, false, ""}, + equalsTestCase{int16(kExpected), true, false, ""}, + equalsTestCase{int32(kExpected), true, false, ""}, + equalsTestCase{int64(kExpected), true, false, ""}, + equalsTestCase{uint(kExpected), true, false, ""}, + equalsTestCase{uint8(kExpected), true, false, ""}, + equalsTestCase{uint16(kExpected), true, false, ""}, + equalsTestCase{uint32(kExpected), true, false, ""}, + equalsTestCase{uint64(kExpected), true, false, ""}, + equalsTestCase{uintptr(kExpected), true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric types. + equalsTestCase{kExpected + 1, false, false, ""}, + equalsTestCase{int(kExpected + 1), false, false, ""}, + equalsTestCase{int8(kExpected + 1), false, false, ""}, + equalsTestCase{int16(kExpected + 1), false, false, ""}, + equalsTestCase{int32(kExpected + 1), false, false, ""}, + equalsTestCase{int64(kExpected + 1), false, false, ""}, + equalsTestCase{uint(kExpected + 1), false, false, ""}, + equalsTestCase{uint8(kExpected + 1), false, false, ""}, + equalsTestCase{uint16(kExpected + 1), false, false, ""}, + equalsTestCase{uint32(kExpected + 1), false, false, ""}, + equalsTestCase{uint64(kExpected + 1), false, false, ""}, + equalsTestCase{uintptr(kExpected + 1), false, false, ""}, + equalsTestCase{float32(kExpected + 1), false, false, ""}, + equalsTestCase{float64(kExpected + 1), false, false, ""}, + equalsTestCase{complex64(kExpected + 2i), false, false, ""}, + equalsTestCase{complex64(kExpected + 1), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + equalsTestCase{complex128(kExpected + 1), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) LargeUint() { + const kExpected = (1 << 16) + 17 + matcher := Equals(uint(kExpected)) + ExpectEq("65553", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of the expected value. + equalsTestCase{65553, true, false, ""}, + equalsTestCase{65553.0, true, false, ""}, + equalsTestCase{65553 + 0i, true, false, ""}, + equalsTestCase{int32(kExpected), true, false, ""}, + equalsTestCase{int64(kExpected), true, false, ""}, + equalsTestCase{uint32(kExpected), true, false, ""}, + equalsTestCase{uint64(kExpected), true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric types. + equalsTestCase{int16(17), false, false, ""}, + equalsTestCase{int32(kExpected + 1), false, false, ""}, + equalsTestCase{int64(kExpected + 1), false, false, ""}, + equalsTestCase{uint16(17), false, false, ""}, + equalsTestCase{uint32(kExpected + 1), false, false, ""}, + equalsTestCase{uint64(kExpected + 1), false, false, ""}, + equalsTestCase{float64(kExpected + 1), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + equalsTestCase{complex128(kExpected + 1), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) UintNotExactlyRepresentableBySinglePrecision() { + // Single-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo25 = 1 << 25 + matcher := Equals(uint(kTwoTo25 + 1)) + ExpectEq("33554433", matcher.Description()) + + cases := []equalsTestCase{ + // Integers. + equalsTestCase{int64(kTwoTo25 + 0), false, false, ""}, + equalsTestCase{int64(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{int64(kTwoTo25 + 2), false, false, ""}, + + equalsTestCase{uint64(kTwoTo25 + 0), false, false, ""}, + equalsTestCase{uint64(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{uint64(kTwoTo25 + 2), false, false, ""}, + + // Single-precision floating point. + equalsTestCase{float32(kTwoTo25 - 2), false, false, ""}, + equalsTestCase{float32(kTwoTo25 - 1), true, false, ""}, + equalsTestCase{float32(kTwoTo25 + 0), true, false, ""}, + equalsTestCase{float32(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{float32(kTwoTo25 + 2), true, false, ""}, + equalsTestCase{float32(kTwoTo25 + 3), false, false, ""}, + + equalsTestCase{complex64(kTwoTo25 - 2), false, false, ""}, + equalsTestCase{complex64(kTwoTo25 - 1), true, false, ""}, + equalsTestCase{complex64(kTwoTo25 + 0), true, false, ""}, + equalsTestCase{complex64(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{complex64(kTwoTo25 + 2), true, false, ""}, + equalsTestCase{complex64(kTwoTo25 + 3), false, false, ""}, + + // Double-precision floating point. + equalsTestCase{float64(kTwoTo25 + 0), false, false, ""}, + equalsTestCase{float64(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{float64(kTwoTo25 + 2), false, false, ""}, + + equalsTestCase{complex128(kTwoTo25 + 0), false, false, ""}, + equalsTestCase{complex128(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{complex128(kTwoTo25 + 2), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// uint8 +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) SmallUint8() { + const kExpected = 17 + matcher := Equals(uint8(kExpected)) + ExpectEq("17", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of the expected value. + equalsTestCase{17, true, false, ""}, + equalsTestCase{17.0, true, false, ""}, + equalsTestCase{17 + 0i, true, false, ""}, + equalsTestCase{int(kExpected), true, false, ""}, + equalsTestCase{int8(kExpected), true, false, ""}, + equalsTestCase{int16(kExpected), true, false, ""}, + equalsTestCase{int32(kExpected), true, false, ""}, + equalsTestCase{int64(kExpected), true, false, ""}, + equalsTestCase{uint(kExpected), true, false, ""}, + equalsTestCase{uint8(kExpected), true, false, ""}, + equalsTestCase{uint16(kExpected), true, false, ""}, + equalsTestCase{uint32(kExpected), true, false, ""}, + equalsTestCase{uint64(kExpected), true, false, ""}, + equalsTestCase{uintptr(kExpected), true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric types. + equalsTestCase{kExpected + 1, false, false, ""}, + equalsTestCase{int(kExpected + 1), false, false, ""}, + equalsTestCase{int8(kExpected + 1), false, false, ""}, + equalsTestCase{int16(kExpected + 1), false, false, ""}, + equalsTestCase{int32(kExpected + 1), false, false, ""}, + equalsTestCase{int64(kExpected + 1), false, false, ""}, + equalsTestCase{uint(kExpected + 1), false, false, ""}, + equalsTestCase{uint8(kExpected + 1), false, false, ""}, + equalsTestCase{uint16(kExpected + 1), false, false, ""}, + equalsTestCase{uint32(kExpected + 1), false, false, ""}, + equalsTestCase{uint64(kExpected + 1), false, false, ""}, + equalsTestCase{uintptr(kExpected + 1), false, false, ""}, + equalsTestCase{float32(kExpected + 1), false, false, ""}, + equalsTestCase{float64(kExpected + 1), false, false, ""}, + equalsTestCase{complex64(kExpected + 2i), false, false, ""}, + equalsTestCase{complex64(kExpected + 1), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + equalsTestCase{complex128(kExpected + 1), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// uint16 +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) SmallUint16() { + const kExpected = 17 + matcher := Equals(uint16(kExpected)) + ExpectEq("17", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of the expected value. + equalsTestCase{17, true, false, ""}, + equalsTestCase{17.0, true, false, ""}, + equalsTestCase{17 + 0i, true, false, ""}, + equalsTestCase{int(kExpected), true, false, ""}, + equalsTestCase{int8(kExpected), true, false, ""}, + equalsTestCase{int16(kExpected), true, false, ""}, + equalsTestCase{int32(kExpected), true, false, ""}, + equalsTestCase{int64(kExpected), true, false, ""}, + equalsTestCase{uint(kExpected), true, false, ""}, + equalsTestCase{uint8(kExpected), true, false, ""}, + equalsTestCase{uint16(kExpected), true, false, ""}, + equalsTestCase{uint32(kExpected), true, false, ""}, + equalsTestCase{uint64(kExpected), true, false, ""}, + equalsTestCase{uintptr(kExpected), true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric types. + equalsTestCase{kExpected + 1, false, false, ""}, + equalsTestCase{int(kExpected + 1), false, false, ""}, + equalsTestCase{int8(kExpected + 1), false, false, ""}, + equalsTestCase{int16(kExpected + 1), false, false, ""}, + equalsTestCase{int32(kExpected + 1), false, false, ""}, + equalsTestCase{int64(kExpected + 1), false, false, ""}, + equalsTestCase{uint(kExpected + 1), false, false, ""}, + equalsTestCase{uint8(kExpected + 1), false, false, ""}, + equalsTestCase{uint16(kExpected + 1), false, false, ""}, + equalsTestCase{uint32(kExpected + 1), false, false, ""}, + equalsTestCase{uint64(kExpected + 1), false, false, ""}, + equalsTestCase{uintptr(kExpected + 1), false, false, ""}, + equalsTestCase{float32(kExpected + 1), false, false, ""}, + equalsTestCase{float64(kExpected + 1), false, false, ""}, + equalsTestCase{complex64(kExpected + 2i), false, false, ""}, + equalsTestCase{complex64(kExpected + 1), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + equalsTestCase{complex128(kExpected + 1), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) LargeUint16() { + const kExpected = (1 << 8) + 17 + matcher := Equals(uint16(kExpected)) + ExpectEq("273", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of the expected value. + equalsTestCase{273, true, false, ""}, + equalsTestCase{273.0, true, false, ""}, + equalsTestCase{273 + 0i, true, false, ""}, + equalsTestCase{int16(kExpected), true, false, ""}, + equalsTestCase{int32(kExpected), true, false, ""}, + equalsTestCase{int64(kExpected), true, false, ""}, + equalsTestCase{uint16(kExpected), true, false, ""}, + equalsTestCase{uint32(kExpected), true, false, ""}, + equalsTestCase{uint64(kExpected), true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric types. + equalsTestCase{int8(17), false, false, ""}, + equalsTestCase{int16(kExpected + 1), false, false, ""}, + equalsTestCase{int32(kExpected + 1), false, false, ""}, + equalsTestCase{int64(kExpected + 1), false, false, ""}, + equalsTestCase{uint8(17), false, false, ""}, + equalsTestCase{uint16(kExpected + 1), false, false, ""}, + equalsTestCase{uint32(kExpected + 1), false, false, ""}, + equalsTestCase{uint64(kExpected + 1), false, false, ""}, + equalsTestCase{float64(kExpected + 1), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + equalsTestCase{complex128(kExpected + 1), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// uint32 +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) SmallUint32() { + const kExpected = 17 + matcher := Equals(uint32(kExpected)) + ExpectEq("17", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of the expected value. + equalsTestCase{17, true, false, ""}, + equalsTestCase{17.0, true, false, ""}, + equalsTestCase{17 + 0i, true, false, ""}, + equalsTestCase{int(kExpected), true, false, ""}, + equalsTestCase{int8(kExpected), true, false, ""}, + equalsTestCase{int16(kExpected), true, false, ""}, + equalsTestCase{int32(kExpected), true, false, ""}, + equalsTestCase{int64(kExpected), true, false, ""}, + equalsTestCase{uint(kExpected), true, false, ""}, + equalsTestCase{uint8(kExpected), true, false, ""}, + equalsTestCase{uint16(kExpected), true, false, ""}, + equalsTestCase{uint32(kExpected), true, false, ""}, + equalsTestCase{uint64(kExpected), true, false, ""}, + equalsTestCase{uintptr(kExpected), true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric types. + equalsTestCase{kExpected + 1, false, false, ""}, + equalsTestCase{int(kExpected + 1), false, false, ""}, + equalsTestCase{int8(kExpected + 1), false, false, ""}, + equalsTestCase{int16(kExpected + 1), false, false, ""}, + equalsTestCase{int32(kExpected + 1), false, false, ""}, + equalsTestCase{int64(kExpected + 1), false, false, ""}, + equalsTestCase{uint(kExpected + 1), false, false, ""}, + equalsTestCase{uint8(kExpected + 1), false, false, ""}, + equalsTestCase{uint16(kExpected + 1), false, false, ""}, + equalsTestCase{uint32(kExpected + 1), false, false, ""}, + equalsTestCase{uint64(kExpected + 1), false, false, ""}, + equalsTestCase{uintptr(kExpected + 1), false, false, ""}, + equalsTestCase{float32(kExpected + 1), false, false, ""}, + equalsTestCase{float64(kExpected + 1), false, false, ""}, + equalsTestCase{complex64(kExpected + 2i), false, false, ""}, + equalsTestCase{complex64(kExpected + 1), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + equalsTestCase{complex128(kExpected + 1), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) LargeUint32() { + const kExpected = (1 << 16) + 17 + matcher := Equals(uint32(kExpected)) + ExpectEq("65553", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of the expected value. + equalsTestCase{65553, true, false, ""}, + equalsTestCase{65553.0, true, false, ""}, + equalsTestCase{65553 + 0i, true, false, ""}, + equalsTestCase{int32(kExpected), true, false, ""}, + equalsTestCase{int64(kExpected), true, false, ""}, + equalsTestCase{uint32(kExpected), true, false, ""}, + equalsTestCase{uint64(kExpected), true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric types. + equalsTestCase{int16(17), false, false, ""}, + equalsTestCase{int32(kExpected + 1), false, false, ""}, + equalsTestCase{int64(kExpected + 1), false, false, ""}, + equalsTestCase{uint16(17), false, false, ""}, + equalsTestCase{uint32(kExpected + 1), false, false, ""}, + equalsTestCase{uint64(kExpected + 1), false, false, ""}, + equalsTestCase{float64(kExpected + 1), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + equalsTestCase{complex128(kExpected + 1), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) Uint32NotExactlyRepresentableBySinglePrecision() { + // Single-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo25 = 1 << 25 + matcher := Equals(uint32(kTwoTo25 + 1)) + ExpectEq("33554433", matcher.Description()) + + cases := []equalsTestCase{ + // Integers. + equalsTestCase{int64(kTwoTo25 + 0), false, false, ""}, + equalsTestCase{int64(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{int64(kTwoTo25 + 2), false, false, ""}, + + equalsTestCase{uint64(kTwoTo25 + 0), false, false, ""}, + equalsTestCase{uint64(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{uint64(kTwoTo25 + 2), false, false, ""}, + + // Single-precision floating point. + equalsTestCase{float32(kTwoTo25 - 2), false, false, ""}, + equalsTestCase{float32(kTwoTo25 - 1), true, false, ""}, + equalsTestCase{float32(kTwoTo25 + 0), true, false, ""}, + equalsTestCase{float32(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{float32(kTwoTo25 + 2), true, false, ""}, + equalsTestCase{float32(kTwoTo25 + 3), false, false, ""}, + + equalsTestCase{complex64(kTwoTo25 - 2), false, false, ""}, + equalsTestCase{complex64(kTwoTo25 - 1), true, false, ""}, + equalsTestCase{complex64(kTwoTo25 + 0), true, false, ""}, + equalsTestCase{complex64(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{complex64(kTwoTo25 + 2), true, false, ""}, + equalsTestCase{complex64(kTwoTo25 + 3), false, false, ""}, + + // Double-precision floating point. + equalsTestCase{float64(kTwoTo25 + 0), false, false, ""}, + equalsTestCase{float64(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{float64(kTwoTo25 + 2), false, false, ""}, + + equalsTestCase{complex128(kTwoTo25 + 0), false, false, ""}, + equalsTestCase{complex128(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{complex128(kTwoTo25 + 2), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// uint64 +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) SmallUint64() { + const kExpected = 17 + matcher := Equals(uint64(kExpected)) + ExpectEq("17", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of the expected value. + equalsTestCase{17, true, false, ""}, + equalsTestCase{17.0, true, false, ""}, + equalsTestCase{17 + 0i, true, false, ""}, + equalsTestCase{int(kExpected), true, false, ""}, + equalsTestCase{int8(kExpected), true, false, ""}, + equalsTestCase{int16(kExpected), true, false, ""}, + equalsTestCase{int32(kExpected), true, false, ""}, + equalsTestCase{int64(kExpected), true, false, ""}, + equalsTestCase{uint(kExpected), true, false, ""}, + equalsTestCase{uint8(kExpected), true, false, ""}, + equalsTestCase{uint16(kExpected), true, false, ""}, + equalsTestCase{uint32(kExpected), true, false, ""}, + equalsTestCase{uint64(kExpected), true, false, ""}, + equalsTestCase{uintptr(kExpected), true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric types. + equalsTestCase{kExpected + 1, false, false, ""}, + equalsTestCase{int(kExpected + 1), false, false, ""}, + equalsTestCase{int8(kExpected + 1), false, false, ""}, + equalsTestCase{int16(kExpected + 1), false, false, ""}, + equalsTestCase{int32(kExpected + 1), false, false, ""}, + equalsTestCase{int64(kExpected + 1), false, false, ""}, + equalsTestCase{uint(kExpected + 1), false, false, ""}, + equalsTestCase{uint8(kExpected + 1), false, false, ""}, + equalsTestCase{uint16(kExpected + 1), false, false, ""}, + equalsTestCase{uint32(kExpected + 1), false, false, ""}, + equalsTestCase{uint64(kExpected + 1), false, false, ""}, + equalsTestCase{uintptr(kExpected + 1), false, false, ""}, + equalsTestCase{float32(kExpected + 1), false, false, ""}, + equalsTestCase{float64(kExpected + 1), false, false, ""}, + equalsTestCase{complex64(kExpected + 2i), false, false, ""}, + equalsTestCase{complex64(kExpected + 1), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + equalsTestCase{complex128(kExpected + 1), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) LargeUint64() { + const kExpected = (1 << 32) + 17 + matcher := Equals(uint64(kExpected)) + ExpectEq("4294967313", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of the expected value. + equalsTestCase{4294967313.0, true, false, ""}, + equalsTestCase{4294967313 + 0i, true, false, ""}, + equalsTestCase{int64(kExpected), true, false, ""}, + equalsTestCase{uint64(kExpected), true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric types. + equalsTestCase{int(17), false, false, ""}, + equalsTestCase{int32(17), false, false, ""}, + equalsTestCase{int64(kExpected + 1), false, false, ""}, + equalsTestCase{uint(17), false, false, ""}, + equalsTestCase{uint32(17), false, false, ""}, + equalsTestCase{uint64(kExpected + 1), false, false, ""}, + equalsTestCase{float64(kExpected + 1), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + equalsTestCase{complex128(kExpected + 1), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) Uint64NotExactlyRepresentableBySinglePrecision() { + // Single-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo25 = 1 << 25 + matcher := Equals(uint64(kTwoTo25 + 1)) + ExpectEq("33554433", matcher.Description()) + + cases := []equalsTestCase{ + // Integers. + equalsTestCase{int64(kTwoTo25 + 0), false, false, ""}, + equalsTestCase{int64(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{int64(kTwoTo25 + 2), false, false, ""}, + + equalsTestCase{uint64(kTwoTo25 + 0), false, false, ""}, + equalsTestCase{uint64(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{uint64(kTwoTo25 + 2), false, false, ""}, + + // Single-precision floating point. + equalsTestCase{float32(kTwoTo25 - 2), false, false, ""}, + equalsTestCase{float32(kTwoTo25 - 1), true, false, ""}, + equalsTestCase{float32(kTwoTo25 + 0), true, false, ""}, + equalsTestCase{float32(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{float32(kTwoTo25 + 2), true, false, ""}, + equalsTestCase{float32(kTwoTo25 + 3), false, false, ""}, + + equalsTestCase{complex64(kTwoTo25 - 2), false, false, ""}, + equalsTestCase{complex64(kTwoTo25 - 1), true, false, ""}, + equalsTestCase{complex64(kTwoTo25 + 0), true, false, ""}, + equalsTestCase{complex64(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{complex64(kTwoTo25 + 2), true, false, ""}, + equalsTestCase{complex64(kTwoTo25 + 3), false, false, ""}, + + // Double-precision floating point. + equalsTestCase{float64(kTwoTo25 + 0), false, false, ""}, + equalsTestCase{float64(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{float64(kTwoTo25 + 2), false, false, ""}, + + equalsTestCase{complex128(kTwoTo25 + 0), false, false, ""}, + equalsTestCase{complex128(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{complex128(kTwoTo25 + 2), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) Uint64NotExactlyRepresentableByDoublePrecision() { + // Double-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^54-1, 2^54+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo54 = 1 << 54 + matcher := Equals(uint64(kTwoTo54 + 1)) + ExpectEq("18014398509481985", matcher.Description()) + + cases := []equalsTestCase{ + // Integers. + equalsTestCase{int64(kTwoTo54 + 0), false, false, ""}, + equalsTestCase{int64(kTwoTo54 + 1), true, false, ""}, + equalsTestCase{int64(kTwoTo54 + 2), false, false, ""}, + + equalsTestCase{uint64(kTwoTo54 + 0), false, false, ""}, + equalsTestCase{uint64(kTwoTo54 + 1), true, false, ""}, + equalsTestCase{uint64(kTwoTo54 + 2), false, false, ""}, + + // Double-precision floating point. + equalsTestCase{float64(kTwoTo54 - 2), false, false, ""}, + equalsTestCase{float64(kTwoTo54 - 1), true, false, ""}, + equalsTestCase{float64(kTwoTo54 + 0), true, false, ""}, + equalsTestCase{float64(kTwoTo54 + 1), true, false, ""}, + equalsTestCase{float64(kTwoTo54 + 2), true, false, ""}, + equalsTestCase{float64(kTwoTo54 + 3), false, false, ""}, + + equalsTestCase{complex128(kTwoTo54 - 2), false, false, ""}, + equalsTestCase{complex128(kTwoTo54 - 1), true, false, ""}, + equalsTestCase{complex128(kTwoTo54 + 0), true, false, ""}, + equalsTestCase{complex128(kTwoTo54 + 1), true, false, ""}, + equalsTestCase{complex128(kTwoTo54 + 2), true, false, ""}, + equalsTestCase{complex128(kTwoTo54 + 3), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// uintptr +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) SmallUintptr() { + const kExpected = 17 + matcher := Equals(uintptr(kExpected)) + ExpectEq("17", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of the expected value. + equalsTestCase{17, true, false, ""}, + equalsTestCase{17.0, true, false, ""}, + equalsTestCase{17 + 0i, true, false, ""}, + equalsTestCase{int(kExpected), true, false, ""}, + equalsTestCase{int8(kExpected), true, false, ""}, + equalsTestCase{int16(kExpected), true, false, ""}, + equalsTestCase{int32(kExpected), true, false, ""}, + equalsTestCase{int64(kExpected), true, false, ""}, + equalsTestCase{uint(kExpected), true, false, ""}, + equalsTestCase{uint8(kExpected), true, false, ""}, + equalsTestCase{uint16(kExpected), true, false, ""}, + equalsTestCase{uint32(kExpected), true, false, ""}, + equalsTestCase{uint64(kExpected), true, false, ""}, + equalsTestCase{uintptr(kExpected), true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric types. + equalsTestCase{kExpected + 1, false, false, ""}, + equalsTestCase{int(kExpected + 1), false, false, ""}, + equalsTestCase{int8(kExpected + 1), false, false, ""}, + equalsTestCase{int16(kExpected + 1), false, false, ""}, + equalsTestCase{int32(kExpected + 1), false, false, ""}, + equalsTestCase{int64(kExpected + 1), false, false, ""}, + equalsTestCase{uint(kExpected + 1), false, false, ""}, + equalsTestCase{uint8(kExpected + 1), false, false, ""}, + equalsTestCase{uint16(kExpected + 1), false, false, ""}, + equalsTestCase{uint32(kExpected + 1), false, false, ""}, + equalsTestCase{uint64(kExpected + 1), false, false, ""}, + equalsTestCase{uintptr(kExpected + 1), false, false, ""}, + equalsTestCase{float32(kExpected + 1), false, false, ""}, + equalsTestCase{float64(kExpected + 1), false, false, ""}, + equalsTestCase{complex64(kExpected + 2i), false, false, ""}, + equalsTestCase{complex64(kExpected + 1), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + equalsTestCase{complex128(kExpected + 1), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) LargeUintptr() { + const kExpected = (1 << 32) + 17 + matcher := Equals(uintptr(kExpected)) + ExpectEq("4294967313", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of the expected value. + equalsTestCase{4294967313.0, true, false, ""}, + equalsTestCase{4294967313 + 0i, true, false, ""}, + equalsTestCase{int64(kExpected), true, false, ""}, + equalsTestCase{uint64(kExpected), true, false, ""}, + equalsTestCase{uintptr(kExpected), true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric types. + equalsTestCase{int(17), false, false, ""}, + equalsTestCase{int32(17), false, false, ""}, + equalsTestCase{int64(kExpected + 1), false, false, ""}, + equalsTestCase{uint(17), false, false, ""}, + equalsTestCase{uint32(17), false, false, ""}, + equalsTestCase{uint64(kExpected + 1), false, false, ""}, + equalsTestCase{uintptr(kExpected + 1), false, false, ""}, + equalsTestCase{float64(kExpected + 1), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + equalsTestCase{complex128(kExpected + 1), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// float32 +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) NegativeIntegralFloat32() { + matcher := Equals(float32(-32769)) + ExpectEq("-32769", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of -32769. + equalsTestCase{-32769.0, true, false, ""}, + equalsTestCase{-32769 + 0i, true, false, ""}, + equalsTestCase{int32(-32769), true, false, ""}, + equalsTestCase{int64(-32769), true, false, ""}, + equalsTestCase{float32(-32769), true, false, ""}, + equalsTestCase{float64(-32769), true, false, ""}, + equalsTestCase{complex64(-32769), true, false, ""}, + equalsTestCase{complex128(-32769), true, false, ""}, + equalsTestCase{interface{}(float32(-32769)), true, false, ""}, + equalsTestCase{interface{}(int64(-32769)), true, false, ""}, + + // Values that would be -32769 in two's complement. + equalsTestCase{uint64((1 << 64) - 32769), false, false, ""}, + equalsTestCase{uintptr((1 << 64) - 32769), false, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int64(-32770), false, false, ""}, + equalsTestCase{float32(-32769.1), false, false, ""}, + equalsTestCase{float32(-32768.9), false, false, ""}, + equalsTestCase{float64(-32769.1), false, false, ""}, + equalsTestCase{float64(-32768.9), false, false, ""}, + equalsTestCase{complex128(-32768), false, false, ""}, + equalsTestCase{complex128(-32769 + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) NegativeNonIntegralFloat32() { + matcher := Equals(float32(-32769.1)) + ExpectEq("-32769.1", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of -32769.1. + equalsTestCase{-32769.1, true, false, ""}, + equalsTestCase{-32769.1 + 0i, true, false, ""}, + equalsTestCase{float32(-32769.1), true, false, ""}, + equalsTestCase{float64(-32769.1), true, false, ""}, + equalsTestCase{complex64(-32769.1), true, false, ""}, + equalsTestCase{complex128(-32769.1), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int32(-32769), false, false, ""}, + equalsTestCase{int32(-32770), false, false, ""}, + equalsTestCase{int64(-32769), false, false, ""}, + equalsTestCase{int64(-32770), false, false, ""}, + equalsTestCase{float32(-32769.2), false, false, ""}, + equalsTestCase{float32(-32769.0), false, false, ""}, + equalsTestCase{float64(-32769.2), false, false, ""}, + equalsTestCase{complex128(-32769.1 + 2i), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) LargeNegativeFloat32() { + const kExpected = -1 * (1 << 65) + matcher := Equals(float32(kExpected)) + ExpectEq("-3.689349e+19", matcher.Description()) + + floatExpected := float32(kExpected) + castedInt := int64(floatExpected) + + cases := []equalsTestCase{ + // Equal values of numeric type. + equalsTestCase{kExpected + 0i, true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{castedInt, false, false, ""}, + equalsTestCase{int64(0), false, false, ""}, + equalsTestCase{int64(math.MinInt64), false, false, ""}, + equalsTestCase{int64(math.MaxInt64), false, false, ""}, + equalsTestCase{float32(kExpected / 2), false, false, ""}, + equalsTestCase{float64(kExpected / 2), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) ZeroFloat32() { + matcher := Equals(float32(0)) + ExpectEq("0", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of zero. + equalsTestCase{0.0, true, false, ""}, + equalsTestCase{0 + 0i, true, false, ""}, + equalsTestCase{int(0), true, false, ""}, + equalsTestCase{int8(0), true, false, ""}, + equalsTestCase{int16(0), true, false, ""}, + equalsTestCase{int32(0), true, false, ""}, + equalsTestCase{int64(0), true, false, ""}, + equalsTestCase{uint(0), true, false, ""}, + equalsTestCase{uint8(0), true, false, ""}, + equalsTestCase{uint16(0), true, false, ""}, + equalsTestCase{uint32(0), true, false, ""}, + equalsTestCase{uint64(0), true, false, ""}, + equalsTestCase{uintptr(0), true, false, ""}, + equalsTestCase{float32(0), true, false, ""}, + equalsTestCase{float64(0), true, false, ""}, + equalsTestCase{complex64(0), true, false, ""}, + equalsTestCase{complex128(0), true, false, ""}, + equalsTestCase{interface{}(float32(0)), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int64(1), false, false, ""}, + equalsTestCase{int64(-1), false, false, ""}, + equalsTestCase{float32(1), false, false, ""}, + equalsTestCase{float32(-1), false, false, ""}, + equalsTestCase{complex128(0 + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) PositiveIntegralFloat32() { + matcher := Equals(float32(32769)) + ExpectEq("32769", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of 32769. + equalsTestCase{32769.0, true, false, ""}, + equalsTestCase{32769 + 0i, true, false, ""}, + equalsTestCase{int(32769), true, false, ""}, + equalsTestCase{int32(32769), true, false, ""}, + equalsTestCase{int64(32769), true, false, ""}, + equalsTestCase{uint(32769), true, false, ""}, + equalsTestCase{uint32(32769), true, false, ""}, + equalsTestCase{uint64(32769), true, false, ""}, + equalsTestCase{uintptr(32769), true, false, ""}, + equalsTestCase{float32(32769), true, false, ""}, + equalsTestCase{float64(32769), true, false, ""}, + equalsTestCase{complex64(32769), true, false, ""}, + equalsTestCase{complex128(32769), true, false, ""}, + equalsTestCase{interface{}(float32(32769)), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int64(32770), false, false, ""}, + equalsTestCase{uint64(32770), false, false, ""}, + equalsTestCase{float32(32769.1), false, false, ""}, + equalsTestCase{float32(32768.9), false, false, ""}, + equalsTestCase{float64(32769.1), false, false, ""}, + equalsTestCase{float64(32768.9), false, false, ""}, + equalsTestCase{complex128(32768), false, false, ""}, + equalsTestCase{complex128(32769 + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) PositiveNonIntegralFloat32() { + matcher := Equals(float32(32769.1)) + ExpectEq("32769.1", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of 32769.1. + equalsTestCase{32769.1, true, false, ""}, + equalsTestCase{32769.1 + 0i, true, false, ""}, + equalsTestCase{float32(32769.1), true, false, ""}, + equalsTestCase{float64(32769.1), true, false, ""}, + equalsTestCase{complex64(32769.1), true, false, ""}, + equalsTestCase{complex128(32769.1), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int32(32769), false, false, ""}, + equalsTestCase{int32(32770), false, false, ""}, + equalsTestCase{uint64(32769), false, false, ""}, + equalsTestCase{uint64(32770), false, false, ""}, + equalsTestCase{float32(32769.2), false, false, ""}, + equalsTestCase{float32(32769.0), false, false, ""}, + equalsTestCase{float64(32769.2), false, false, ""}, + equalsTestCase{complex128(32769.1 + 2i), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) LargePositiveFloat32() { + const kExpected = 1 << 65 + matcher := Equals(float32(kExpected)) + ExpectEq("3.689349e+19", matcher.Description()) + + floatExpected := float32(kExpected) + castedInt := uint64(floatExpected) + + cases := []equalsTestCase{ + // Equal values of numeric type. + equalsTestCase{kExpected + 0i, true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{castedInt, false, false, ""}, + equalsTestCase{int64(0), false, false, ""}, + equalsTestCase{int64(math.MinInt64), false, false, ""}, + equalsTestCase{int64(math.MaxInt64), false, false, ""}, + equalsTestCase{uint64(0), false, false, ""}, + equalsTestCase{uint64(math.MaxUint64), false, false, ""}, + equalsTestCase{float32(kExpected / 2), false, false, ""}, + equalsTestCase{float64(kExpected / 2), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) Float32AboveExactIntegerRange() { + // Single-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo25 = 1 << 25 + matcher := Equals(float32(kTwoTo25 + 1)) + ExpectEq("3.3554432e+07", matcher.Description()) + + cases := []equalsTestCase{ + // Integers. + equalsTestCase{int64(kTwoTo25 - 2), false, false, ""}, + equalsTestCase{int64(kTwoTo25 - 1), true, false, ""}, + equalsTestCase{int64(kTwoTo25 + 0), true, false, ""}, + equalsTestCase{int64(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{int64(kTwoTo25 + 2), true, false, ""}, + equalsTestCase{int64(kTwoTo25 + 3), false, false, ""}, + + equalsTestCase{uint64(kTwoTo25 - 2), false, false, ""}, + equalsTestCase{uint64(kTwoTo25 - 1), true, false, ""}, + equalsTestCase{uint64(kTwoTo25 + 0), true, false, ""}, + equalsTestCase{uint64(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{uint64(kTwoTo25 + 2), true, false, ""}, + equalsTestCase{uint64(kTwoTo25 + 3), false, false, ""}, + + // Single-precision floating point. + equalsTestCase{float32(kTwoTo25 - 2), false, false, ""}, + equalsTestCase{float32(kTwoTo25 - 1), true, false, ""}, + equalsTestCase{float32(kTwoTo25 + 0), true, false, ""}, + equalsTestCase{float32(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{float32(kTwoTo25 + 2), true, false, ""}, + equalsTestCase{float32(kTwoTo25 + 3), false, false, ""}, + + equalsTestCase{complex64(kTwoTo25 - 2), false, false, ""}, + equalsTestCase{complex64(kTwoTo25 - 1), true, false, ""}, + equalsTestCase{complex64(kTwoTo25 + 0), true, false, ""}, + equalsTestCase{complex64(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{complex64(kTwoTo25 + 2), true, false, ""}, + equalsTestCase{complex64(kTwoTo25 + 3), false, false, ""}, + + // Double-precision floating point. + equalsTestCase{float64(kTwoTo25 - 2), false, false, ""}, + equalsTestCase{float64(kTwoTo25 - 1), true, false, ""}, + equalsTestCase{float64(kTwoTo25 + 0), true, false, ""}, + equalsTestCase{float64(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{float64(kTwoTo25 + 2), true, false, ""}, + equalsTestCase{float64(kTwoTo25 + 3), false, false, ""}, + + equalsTestCase{complex128(kTwoTo25 - 2), false, false, ""}, + equalsTestCase{complex128(kTwoTo25 - 1), true, false, ""}, + equalsTestCase{complex128(kTwoTo25 + 0), true, false, ""}, + equalsTestCase{complex128(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{complex128(kTwoTo25 + 2), true, false, ""}, + equalsTestCase{complex128(kTwoTo25 + 3), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// float64 +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) NegativeIntegralFloat64() { + const kExpected = -(1 << 50) + matcher := Equals(float64(kExpected)) + ExpectEq("-1.125899906842624e+15", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of the expected value. + equalsTestCase{-1125899906842624.0, true, false, ""}, + equalsTestCase{-1125899906842624.0 + 0i, true, false, ""}, + equalsTestCase{int64(kExpected), true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + equalsTestCase{interface{}(float64(kExpected)), true, false, ""}, + + // Values that would be kExpected in two's complement. + equalsTestCase{uint64((1 << 64) + kExpected), false, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int64(kExpected + 1), false, false, ""}, + equalsTestCase{float32(kExpected - (1 << 30)), false, false, ""}, + equalsTestCase{float32(kExpected + (1 << 30)), false, false, ""}, + equalsTestCase{float64(kExpected - 0.5), false, false, ""}, + equalsTestCase{float64(kExpected + 0.5), false, false, ""}, + equalsTestCase{complex128(kExpected - 1), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) NegativeNonIntegralFloat64() { + const kTwoTo50 = 1 << 50 + const kExpected = -kTwoTo50 - 0.25 + + matcher := Equals(float64(kExpected)) + ExpectEq("-1.1258999068426242e+15", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of the expected value. + equalsTestCase{kExpected, true, false, ""}, + equalsTestCase{kExpected + 0i, true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int64(-kTwoTo50), false, false, ""}, + equalsTestCase{int64(-kTwoTo50 - 1), false, false, ""}, + equalsTestCase{float32(kExpected - (1 << 30)), false, false, ""}, + equalsTestCase{float64(kExpected - 0.25), false, false, ""}, + equalsTestCase{float64(kExpected + 0.25), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) LargeNegativeFloat64() { + const kExpected = -1 * (1 << 65) + matcher := Equals(float64(kExpected)) + ExpectEq("-3.6893488147419103e+19", matcher.Description()) + + floatExpected := float64(kExpected) + castedInt := int64(floatExpected) + + cases := []equalsTestCase{ + // Equal values of numeric type. + equalsTestCase{kExpected + 0i, true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{castedInt, false, false, ""}, + equalsTestCase{int64(0), false, false, ""}, + equalsTestCase{int64(math.MinInt64), false, false, ""}, + equalsTestCase{int64(math.MaxInt64), false, false, ""}, + equalsTestCase{float32(kExpected / 2), false, false, ""}, + equalsTestCase{float64(kExpected / 2), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) ZeroFloat64() { + matcher := Equals(float64(0)) + ExpectEq("0", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of zero. + equalsTestCase{0.0, true, false, ""}, + equalsTestCase{0 + 0i, true, false, ""}, + equalsTestCase{int(0), true, false, ""}, + equalsTestCase{int8(0), true, false, ""}, + equalsTestCase{int16(0), true, false, ""}, + equalsTestCase{int32(0), true, false, ""}, + equalsTestCase{int64(0), true, false, ""}, + equalsTestCase{uint(0), true, false, ""}, + equalsTestCase{uint8(0), true, false, ""}, + equalsTestCase{uint16(0), true, false, ""}, + equalsTestCase{uint32(0), true, false, ""}, + equalsTestCase{uint64(0), true, false, ""}, + equalsTestCase{uintptr(0), true, false, ""}, + equalsTestCase{float32(0), true, false, ""}, + equalsTestCase{float64(0), true, false, ""}, + equalsTestCase{complex64(0), true, false, ""}, + equalsTestCase{complex128(0), true, false, ""}, + equalsTestCase{interface{}(float32(0)), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int64(1), false, false, ""}, + equalsTestCase{int64(-1), false, false, ""}, + equalsTestCase{float32(1), false, false, ""}, + equalsTestCase{float32(-1), false, false, ""}, + equalsTestCase{complex128(0 + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) PositiveIntegralFloat64() { + const kExpected = 1 << 50 + matcher := Equals(float64(kExpected)) + ExpectEq("1.125899906842624e+15", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of 32769. + equalsTestCase{1125899906842624.0, true, false, ""}, + equalsTestCase{1125899906842624.0 + 0i, true, false, ""}, + equalsTestCase{int64(kExpected), true, false, ""}, + equalsTestCase{uint64(kExpected), true, false, ""}, + equalsTestCase{uintptr(kExpected), true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + equalsTestCase{interface{}(float64(kExpected)), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int64(kExpected + 1), false, false, ""}, + equalsTestCase{uint64(kExpected + 1), false, false, ""}, + equalsTestCase{uintptr(kExpected + 1), false, false, ""}, + equalsTestCase{float32(kExpected - (1 << 30)), false, false, ""}, + equalsTestCase{float32(kExpected + (1 << 30)), false, false, ""}, + equalsTestCase{float64(kExpected - 0.5), false, false, ""}, + equalsTestCase{float64(kExpected + 0.5), false, false, ""}, + equalsTestCase{complex128(kExpected - 1), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) PositiveNonIntegralFloat64() { + const kTwoTo50 = 1 << 50 + const kExpected = kTwoTo50 + 0.25 + matcher := Equals(float64(kExpected)) + ExpectEq("1.1258999068426242e+15", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of the expected value. + equalsTestCase{kExpected, true, false, ""}, + equalsTestCase{kExpected + 0i, true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int64(kTwoTo50), false, false, ""}, + equalsTestCase{int64(kTwoTo50 - 1), false, false, ""}, + equalsTestCase{float64(kExpected - 0.25), false, false, ""}, + equalsTestCase{float64(kExpected + 0.25), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) LargePositiveFloat64() { + const kExpected = 1 << 65 + matcher := Equals(float64(kExpected)) + ExpectEq("3.6893488147419103e+19", matcher.Description()) + + floatExpected := float64(kExpected) + castedInt := uint64(floatExpected) + + cases := []equalsTestCase{ + // Equal values of numeric type. + equalsTestCase{kExpected + 0i, true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{castedInt, false, false, ""}, + equalsTestCase{int64(0), false, false, ""}, + equalsTestCase{int64(math.MinInt64), false, false, ""}, + equalsTestCase{int64(math.MaxInt64), false, false, ""}, + equalsTestCase{uint64(0), false, false, ""}, + equalsTestCase{uint64(math.MaxUint64), false, false, ""}, + equalsTestCase{float32(kExpected / 2), false, false, ""}, + equalsTestCase{float64(kExpected / 2), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) Float64AboveExactIntegerRange() { + // Double-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^54-1, 2^54+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo54 = 1 << 54 + matcher := Equals(float64(kTwoTo54 + 1)) + ExpectEq("1.8014398509481984e+16", matcher.Description()) + + cases := []equalsTestCase{ + // Integers. + equalsTestCase{int64(kTwoTo54 - 2), false, false, ""}, + equalsTestCase{int64(kTwoTo54 - 1), true, false, ""}, + equalsTestCase{int64(kTwoTo54 + 0), true, false, ""}, + equalsTestCase{int64(kTwoTo54 + 1), true, false, ""}, + equalsTestCase{int64(kTwoTo54 + 2), true, false, ""}, + equalsTestCase{int64(kTwoTo54 + 3), false, false, ""}, + + equalsTestCase{uint64(kTwoTo54 - 2), false, false, ""}, + equalsTestCase{uint64(kTwoTo54 - 1), true, false, ""}, + equalsTestCase{uint64(kTwoTo54 + 0), true, false, ""}, + equalsTestCase{uint64(kTwoTo54 + 1), true, false, ""}, + equalsTestCase{uint64(kTwoTo54 + 2), true, false, ""}, + equalsTestCase{uint64(kTwoTo54 + 3), false, false, ""}, + + // Double-precision floating point. + equalsTestCase{float64(kTwoTo54 - 2), false, false, ""}, + equalsTestCase{float64(kTwoTo54 - 1), true, false, ""}, + equalsTestCase{float64(kTwoTo54 + 0), true, false, ""}, + equalsTestCase{float64(kTwoTo54 + 1), true, false, ""}, + equalsTestCase{float64(kTwoTo54 + 2), true, false, ""}, + equalsTestCase{float64(kTwoTo54 + 3), false, false, ""}, + + equalsTestCase{complex128(kTwoTo54 - 2), false, false, ""}, + equalsTestCase{complex128(kTwoTo54 - 1), true, false, ""}, + equalsTestCase{complex128(kTwoTo54 + 0), true, false, ""}, + equalsTestCase{complex128(kTwoTo54 + 1), true, false, ""}, + equalsTestCase{complex128(kTwoTo54 + 2), true, false, ""}, + equalsTestCase{complex128(kTwoTo54 + 3), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// complex64 +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) NegativeIntegralComplex64() { + const kExpected = -32769 + matcher := Equals(complex64(kExpected)) + ExpectEq("(-32769+0i)", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of the expected value. + equalsTestCase{-32769.0, true, false, ""}, + equalsTestCase{-32769.0 + 0i, true, false, ""}, + equalsTestCase{int(kExpected), true, false, ""}, + equalsTestCase{int32(kExpected), true, false, ""}, + equalsTestCase{int64(kExpected), true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + equalsTestCase{interface{}(float64(kExpected)), true, false, ""}, + + // Values that would be kExpected in two's complement. + equalsTestCase{uint32((1 << 32) + kExpected), false, false, ""}, + equalsTestCase{uint64((1 << 64) + kExpected), false, false, ""}, + equalsTestCase{uintptr((1 << 64) + kExpected), false, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int64(kExpected + 1), false, false, ""}, + equalsTestCase{float32(kExpected - (1 << 30)), false, false, ""}, + equalsTestCase{float32(kExpected + (1 << 30)), false, false, ""}, + equalsTestCase{float64(kExpected - 0.5), false, false, ""}, + equalsTestCase{float64(kExpected + 0.5), false, false, ""}, + equalsTestCase{complex64(kExpected - 1), false, false, ""}, + equalsTestCase{complex64(kExpected + 2i), false, false, ""}, + equalsTestCase{complex128(kExpected - 1), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) NegativeNonIntegralComplex64() { + const kTwoTo20 = 1 << 20 + const kExpected = -kTwoTo20 - 0.25 + + matcher := Equals(complex64(kExpected)) + ExpectEq("(-1.0485762e+06+0i)", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of the expected value. + equalsTestCase{kExpected, true, false, ""}, + equalsTestCase{kExpected + 0i, true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int(-kTwoTo20), false, false, ""}, + equalsTestCase{int(-kTwoTo20 - 1), false, false, ""}, + equalsTestCase{int32(-kTwoTo20), false, false, ""}, + equalsTestCase{int32(-kTwoTo20 - 1), false, false, ""}, + equalsTestCase{int64(-kTwoTo20), false, false, ""}, + equalsTestCase{int64(-kTwoTo20 - 1), false, false, ""}, + equalsTestCase{float32(kExpected - (1 << 30)), false, false, ""}, + equalsTestCase{float64(kExpected - 0.25), false, false, ""}, + equalsTestCase{float64(kExpected + 0.25), false, false, ""}, + equalsTestCase{complex64(kExpected - 0.75), false, false, ""}, + equalsTestCase{complex64(kExpected + 2i), false, false, ""}, + equalsTestCase{complex128(kExpected - 0.75), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) LargeNegativeComplex64() { + const kExpected = -1 * (1 << 65) + matcher := Equals(complex64(kExpected)) + ExpectEq("(-3.689349e+19+0i)", matcher.Description()) + + floatExpected := float64(kExpected) + castedInt := int64(floatExpected) + + cases := []equalsTestCase{ + // Equal values of numeric type. + equalsTestCase{kExpected + 0i, true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{castedInt, false, false, ""}, + equalsTestCase{int64(0), false, false, ""}, + equalsTestCase{int64(math.MinInt64), false, false, ""}, + equalsTestCase{int64(math.MaxInt64), false, false, ""}, + equalsTestCase{float32(kExpected / 2), false, false, ""}, + equalsTestCase{float64(kExpected / 2), false, false, ""}, + equalsTestCase{complex64(kExpected + 2i), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) ZeroComplex64() { + matcher := Equals(complex64(0)) + ExpectEq("(0+0i)", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of zero. + equalsTestCase{0.0, true, false, ""}, + equalsTestCase{0 + 0i, true, false, ""}, + equalsTestCase{int(0), true, false, ""}, + equalsTestCase{int8(0), true, false, ""}, + equalsTestCase{int16(0), true, false, ""}, + equalsTestCase{int32(0), true, false, ""}, + equalsTestCase{int64(0), true, false, ""}, + equalsTestCase{uint(0), true, false, ""}, + equalsTestCase{uint8(0), true, false, ""}, + equalsTestCase{uint16(0), true, false, ""}, + equalsTestCase{uint32(0), true, false, ""}, + equalsTestCase{uint64(0), true, false, ""}, + equalsTestCase{uintptr(0), true, false, ""}, + equalsTestCase{float32(0), true, false, ""}, + equalsTestCase{float64(0), true, false, ""}, + equalsTestCase{complex64(0), true, false, ""}, + equalsTestCase{complex128(0), true, false, ""}, + equalsTestCase{interface{}(float32(0)), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int64(1), false, false, ""}, + equalsTestCase{int64(-1), false, false, ""}, + equalsTestCase{float32(1), false, false, ""}, + equalsTestCase{float32(-1), false, false, ""}, + equalsTestCase{float64(1), false, false, ""}, + equalsTestCase{float64(-1), false, false, ""}, + equalsTestCase{complex64(0 + 2i), false, false, ""}, + equalsTestCase{complex128(0 + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) PositiveIntegralComplex64() { + const kExpected = 1 << 20 + matcher := Equals(complex64(kExpected)) + ExpectEq("(1.048576e+06+0i)", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of 32769. + equalsTestCase{1048576.0, true, false, ""}, + equalsTestCase{1048576.0 + 0i, true, false, ""}, + equalsTestCase{int(kExpected), true, false, ""}, + equalsTestCase{int32(kExpected), true, false, ""}, + equalsTestCase{int64(kExpected), true, false, ""}, + equalsTestCase{uint(kExpected), true, false, ""}, + equalsTestCase{uint32(kExpected), true, false, ""}, + equalsTestCase{uint64(kExpected), true, false, ""}, + equalsTestCase{uintptr(kExpected), true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + equalsTestCase{interface{}(float64(kExpected)), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int(kExpected + 1), false, false, ""}, + equalsTestCase{int32(kExpected + 1), false, false, ""}, + equalsTestCase{int64(kExpected + 1), false, false, ""}, + equalsTestCase{uint(kExpected + 1), false, false, ""}, + equalsTestCase{uint32(kExpected + 1), false, false, ""}, + equalsTestCase{uint64(kExpected + 1), false, false, ""}, + equalsTestCase{uintptr(kExpected + 1), false, false, ""}, + equalsTestCase{float32(kExpected - (1 << 30)), false, false, ""}, + equalsTestCase{float32(kExpected + (1 << 30)), false, false, ""}, + equalsTestCase{float64(kExpected - 0.5), false, false, ""}, + equalsTestCase{float64(kExpected + 0.5), false, false, ""}, + equalsTestCase{complex128(kExpected - 1), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) PositiveNonIntegralComplex64() { + const kTwoTo20 = 1 << 20 + const kExpected = kTwoTo20 + 0.25 + matcher := Equals(complex64(kExpected)) + ExpectEq("(1.0485762e+06+0i)", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of the expected value. + equalsTestCase{kExpected, true, false, ""}, + equalsTestCase{kExpected + 0i, true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int64(kTwoTo20), false, false, ""}, + equalsTestCase{int64(kTwoTo20 - 1), false, false, ""}, + equalsTestCase{uint64(kTwoTo20), false, false, ""}, + equalsTestCase{uint64(kTwoTo20 - 1), false, false, ""}, + equalsTestCase{float32(kExpected - 1), false, false, ""}, + equalsTestCase{float32(kExpected + 1), false, false, ""}, + equalsTestCase{float64(kExpected - 0.25), false, false, ""}, + equalsTestCase{float64(kExpected + 0.25), false, false, ""}, + equalsTestCase{complex64(kExpected - 1), false, false, ""}, + equalsTestCase{complex64(kExpected - 1i), false, false, ""}, + equalsTestCase{complex128(kExpected - 1), false, false, ""}, + equalsTestCase{complex128(kExpected - 1i), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) LargePositiveComplex64() { + const kExpected = 1 << 65 + matcher := Equals(complex64(kExpected)) + ExpectEq("(3.689349e+19+0i)", matcher.Description()) + + floatExpected := float64(kExpected) + castedInt := uint64(floatExpected) + + cases := []equalsTestCase{ + // Equal values of numeric type. + equalsTestCase{kExpected + 0i, true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{castedInt, false, false, ""}, + equalsTestCase{int64(0), false, false, ""}, + equalsTestCase{int64(math.MinInt64), false, false, ""}, + equalsTestCase{int64(math.MaxInt64), false, false, ""}, + equalsTestCase{uint64(0), false, false, ""}, + equalsTestCase{uint64(math.MaxUint64), false, false, ""}, + equalsTestCase{float32(kExpected / 2), false, false, ""}, + equalsTestCase{float64(kExpected / 2), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) Complex64AboveExactIntegerRange() { + // Single-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo25 = 1 << 25 + matcher := Equals(complex64(kTwoTo25 + 1)) + ExpectEq("(3.3554432e+07+0i)", matcher.Description()) + + cases := []equalsTestCase{ + // Integers. + equalsTestCase{int64(kTwoTo25 - 2), false, false, ""}, + equalsTestCase{int64(kTwoTo25 - 1), true, false, ""}, + equalsTestCase{int64(kTwoTo25 + 0), true, false, ""}, + equalsTestCase{int64(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{int64(kTwoTo25 + 2), true, false, ""}, + equalsTestCase{int64(kTwoTo25 + 3), false, false, ""}, + + equalsTestCase{uint64(kTwoTo25 - 2), false, false, ""}, + equalsTestCase{uint64(kTwoTo25 - 1), true, false, ""}, + equalsTestCase{uint64(kTwoTo25 + 0), true, false, ""}, + equalsTestCase{uint64(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{uint64(kTwoTo25 + 2), true, false, ""}, + equalsTestCase{uint64(kTwoTo25 + 3), false, false, ""}, + + // Single-precision floating point. + equalsTestCase{float32(kTwoTo25 - 2), false, false, ""}, + equalsTestCase{float32(kTwoTo25 - 1), true, false, ""}, + equalsTestCase{float32(kTwoTo25 + 0), true, false, ""}, + equalsTestCase{float32(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{float32(kTwoTo25 + 2), true, false, ""}, + equalsTestCase{float32(kTwoTo25 + 3), false, false, ""}, + + equalsTestCase{complex64(kTwoTo25 - 2), false, false, ""}, + equalsTestCase{complex64(kTwoTo25 - 1), true, false, ""}, + equalsTestCase{complex64(kTwoTo25 + 0), true, false, ""}, + equalsTestCase{complex64(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{complex64(kTwoTo25 + 2), true, false, ""}, + equalsTestCase{complex64(kTwoTo25 + 3), false, false, ""}, + + // Double-precision floating point. + equalsTestCase{float64(kTwoTo25 - 2), false, false, ""}, + equalsTestCase{float64(kTwoTo25 - 1), true, false, ""}, + equalsTestCase{float64(kTwoTo25 + 0), true, false, ""}, + equalsTestCase{float64(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{float64(kTwoTo25 + 2), true, false, ""}, + equalsTestCase{float64(kTwoTo25 + 3), false, false, ""}, + + equalsTestCase{complex128(kTwoTo25 - 2), false, false, ""}, + equalsTestCase{complex128(kTwoTo25 - 1), true, false, ""}, + equalsTestCase{complex128(kTwoTo25 + 0), true, false, ""}, + equalsTestCase{complex128(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{complex128(kTwoTo25 + 2), true, false, ""}, + equalsTestCase{complex128(kTwoTo25 + 3), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) Complex64WithNonZeroImaginaryPart() { + const kRealPart = 17 + const kImagPart = 0.25i + const kExpected = kRealPart + kImagPart + matcher := Equals(complex64(kExpected)) + ExpectEq("(17+0.25i)", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of the expected value. + equalsTestCase{kExpected, true, false, ""}, + equalsTestCase{kRealPart + kImagPart, true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int(kRealPart), false, false, ""}, + equalsTestCase{int8(kRealPart), false, false, ""}, + equalsTestCase{int16(kRealPart), false, false, ""}, + equalsTestCase{int32(kRealPart), false, false, ""}, + equalsTestCase{int64(kRealPart), false, false, ""}, + equalsTestCase{uint(kRealPart), false, false, ""}, + equalsTestCase{uint8(kRealPart), false, false, ""}, + equalsTestCase{uint16(kRealPart), false, false, ""}, + equalsTestCase{uint32(kRealPart), false, false, ""}, + equalsTestCase{uint64(kRealPart), false, false, ""}, + equalsTestCase{float32(kRealPart), false, false, ""}, + equalsTestCase{float64(kRealPart), false, false, ""}, + equalsTestCase{complex64(kRealPart), false, false, ""}, + equalsTestCase{complex64(kRealPart + kImagPart + 0.5), false, false, ""}, + equalsTestCase{complex64(kRealPart + kImagPart + 0.5i), false, false, ""}, + equalsTestCase{complex128(kRealPart), false, false, ""}, + equalsTestCase{complex128(kRealPart + kImagPart + 0.5), false, false, ""}, + equalsTestCase{complex128(kRealPart + kImagPart + 0.5i), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// complex128 +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) NegativeIntegralComplex128() { + const kExpected = -32769 + matcher := Equals(complex128(kExpected)) + ExpectEq("(-32769+0i)", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of the expected value. + equalsTestCase{-32769.0, true, false, ""}, + equalsTestCase{-32769.0 + 0i, true, false, ""}, + equalsTestCase{int(kExpected), true, false, ""}, + equalsTestCase{int32(kExpected), true, false, ""}, + equalsTestCase{int64(kExpected), true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + equalsTestCase{interface{}(float64(kExpected)), true, false, ""}, + + // Values that would be kExpected in two's complement. + equalsTestCase{uint32((1 << 32) + kExpected), false, false, ""}, + equalsTestCase{uint64((1 << 64) + kExpected), false, false, ""}, + equalsTestCase{uintptr((1 << 64) + kExpected), false, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int64(kExpected + 1), false, false, ""}, + equalsTestCase{float32(kExpected - (1 << 30)), false, false, ""}, + equalsTestCase{float32(kExpected + (1 << 30)), false, false, ""}, + equalsTestCase{float64(kExpected - 0.5), false, false, ""}, + equalsTestCase{float64(kExpected + 0.5), false, false, ""}, + equalsTestCase{complex64(kExpected - 1), false, false, ""}, + equalsTestCase{complex64(kExpected + 2i), false, false, ""}, + equalsTestCase{complex128(kExpected - 1), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) NegativeNonIntegralComplex128() { + const kTwoTo20 = 1 << 20 + const kExpected = -kTwoTo20 - 0.25 + + matcher := Equals(complex128(kExpected)) + ExpectEq("(-1.04857625e+06+0i)", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of the expected value. + equalsTestCase{kExpected, true, false, ""}, + equalsTestCase{kExpected + 0i, true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int(-kTwoTo20), false, false, ""}, + equalsTestCase{int(-kTwoTo20 - 1), false, false, ""}, + equalsTestCase{int32(-kTwoTo20), false, false, ""}, + equalsTestCase{int32(-kTwoTo20 - 1), false, false, ""}, + equalsTestCase{int64(-kTwoTo20), false, false, ""}, + equalsTestCase{int64(-kTwoTo20 - 1), false, false, ""}, + equalsTestCase{float32(kExpected - (1 << 30)), false, false, ""}, + equalsTestCase{float64(kExpected - 0.25), false, false, ""}, + equalsTestCase{float64(kExpected + 0.25), false, false, ""}, + equalsTestCase{complex64(kExpected - 0.75), false, false, ""}, + equalsTestCase{complex64(kExpected + 2i), false, false, ""}, + equalsTestCase{complex128(kExpected - 0.75), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) LargeNegativeComplex128() { + const kExpected = -1 * (1 << 65) + matcher := Equals(complex128(kExpected)) + ExpectEq("(-3.6893488147419103e+19+0i)", matcher.Description()) + + floatExpected := float64(kExpected) + castedInt := int64(floatExpected) + + cases := []equalsTestCase{ + // Equal values of numeric type. + equalsTestCase{kExpected + 0i, true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{castedInt, false, false, ""}, + equalsTestCase{int64(0), false, false, ""}, + equalsTestCase{int64(math.MinInt64), false, false, ""}, + equalsTestCase{int64(math.MaxInt64), false, false, ""}, + equalsTestCase{float32(kExpected / 2), false, false, ""}, + equalsTestCase{float64(kExpected / 2), false, false, ""}, + equalsTestCase{complex64(kExpected + 2i), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) ZeroComplex128() { + matcher := Equals(complex128(0)) + ExpectEq("(0+0i)", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of zero. + equalsTestCase{0.0, true, false, ""}, + equalsTestCase{0 + 0i, true, false, ""}, + equalsTestCase{int(0), true, false, ""}, + equalsTestCase{int8(0), true, false, ""}, + equalsTestCase{int16(0), true, false, ""}, + equalsTestCase{int32(0), true, false, ""}, + equalsTestCase{int64(0), true, false, ""}, + equalsTestCase{uint(0), true, false, ""}, + equalsTestCase{uint8(0), true, false, ""}, + equalsTestCase{uint16(0), true, false, ""}, + equalsTestCase{uint32(0), true, false, ""}, + equalsTestCase{uint64(0), true, false, ""}, + equalsTestCase{uintptr(0), true, false, ""}, + equalsTestCase{float32(0), true, false, ""}, + equalsTestCase{float64(0), true, false, ""}, + equalsTestCase{complex64(0), true, false, ""}, + equalsTestCase{complex128(0), true, false, ""}, + equalsTestCase{interface{}(float32(0)), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int64(1), false, false, ""}, + equalsTestCase{int64(-1), false, false, ""}, + equalsTestCase{float32(1), false, false, ""}, + equalsTestCase{float32(-1), false, false, ""}, + equalsTestCase{float64(1), false, false, ""}, + equalsTestCase{float64(-1), false, false, ""}, + equalsTestCase{complex64(0 + 2i), false, false, ""}, + equalsTestCase{complex128(0 + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) PositiveIntegralComplex128() { + const kExpected = 1 << 20 + matcher := Equals(complex128(kExpected)) + ExpectEq("(1.048576e+06+0i)", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of 32769. + equalsTestCase{1048576.0, true, false, ""}, + equalsTestCase{1048576.0 + 0i, true, false, ""}, + equalsTestCase{int(kExpected), true, false, ""}, + equalsTestCase{int32(kExpected), true, false, ""}, + equalsTestCase{int64(kExpected), true, false, ""}, + equalsTestCase{uint(kExpected), true, false, ""}, + equalsTestCase{uint32(kExpected), true, false, ""}, + equalsTestCase{uint64(kExpected), true, false, ""}, + equalsTestCase{uintptr(kExpected), true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + equalsTestCase{interface{}(float64(kExpected)), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int(kExpected + 1), false, false, ""}, + equalsTestCase{int32(kExpected + 1), false, false, ""}, + equalsTestCase{int64(kExpected + 1), false, false, ""}, + equalsTestCase{uint(kExpected + 1), false, false, ""}, + equalsTestCase{uint32(kExpected + 1), false, false, ""}, + equalsTestCase{uint64(kExpected + 1), false, false, ""}, + equalsTestCase{uintptr(kExpected + 1), false, false, ""}, + equalsTestCase{float32(kExpected - (1 << 30)), false, false, ""}, + equalsTestCase{float32(kExpected + (1 << 30)), false, false, ""}, + equalsTestCase{float64(kExpected - 0.5), false, false, ""}, + equalsTestCase{float64(kExpected + 0.5), false, false, ""}, + equalsTestCase{complex128(kExpected - 1), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) PositiveNonIntegralComplex128() { + const kTwoTo20 = 1 << 20 + const kExpected = kTwoTo20 + 0.25 + matcher := Equals(complex128(kExpected)) + ExpectEq("(1.04857625e+06+0i)", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of the expected value. + equalsTestCase{kExpected, true, false, ""}, + equalsTestCase{kExpected + 0i, true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int64(kTwoTo20), false, false, ""}, + equalsTestCase{int64(kTwoTo20 - 1), false, false, ""}, + equalsTestCase{uint64(kTwoTo20), false, false, ""}, + equalsTestCase{uint64(kTwoTo20 - 1), false, false, ""}, + equalsTestCase{float32(kExpected - 1), false, false, ""}, + equalsTestCase{float32(kExpected + 1), false, false, ""}, + equalsTestCase{float64(kExpected - 0.25), false, false, ""}, + equalsTestCase{float64(kExpected + 0.25), false, false, ""}, + equalsTestCase{complex64(kExpected - 1), false, false, ""}, + equalsTestCase{complex64(kExpected - 1i), false, false, ""}, + equalsTestCase{complex128(kExpected - 1), false, false, ""}, + equalsTestCase{complex128(kExpected - 1i), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) LargePositiveComplex128() { + const kExpected = 1 << 65 + matcher := Equals(complex128(kExpected)) + ExpectEq("(3.6893488147419103e+19+0i)", matcher.Description()) + + floatExpected := float64(kExpected) + castedInt := uint64(floatExpected) + + cases := []equalsTestCase{ + // Equal values of numeric type. + equalsTestCase{kExpected + 0i, true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{castedInt, false, false, ""}, + equalsTestCase{int64(0), false, false, ""}, + equalsTestCase{int64(math.MinInt64), false, false, ""}, + equalsTestCase{int64(math.MaxInt64), false, false, ""}, + equalsTestCase{uint64(0), false, false, ""}, + equalsTestCase{uint64(math.MaxUint64), false, false, ""}, + equalsTestCase{float32(kExpected / 2), false, false, ""}, + equalsTestCase{float64(kExpected / 2), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) Complex128AboveExactIntegerRange() { + // Double-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^54-1, 2^54+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo54 = 1 << 54 + matcher := Equals(complex128(kTwoTo54 + 1)) + ExpectEq("(1.8014398509481984e+16+0i)", matcher.Description()) + + cases := []equalsTestCase{ + // Integers. + equalsTestCase{int64(kTwoTo54 - 2), false, false, ""}, + equalsTestCase{int64(kTwoTo54 - 1), true, false, ""}, + equalsTestCase{int64(kTwoTo54 + 0), true, false, ""}, + equalsTestCase{int64(kTwoTo54 + 1), true, false, ""}, + equalsTestCase{int64(kTwoTo54 + 2), true, false, ""}, + equalsTestCase{int64(kTwoTo54 + 3), false, false, ""}, + + equalsTestCase{uint64(kTwoTo54 - 2), false, false, ""}, + equalsTestCase{uint64(kTwoTo54 - 1), true, false, ""}, + equalsTestCase{uint64(kTwoTo54 + 0), true, false, ""}, + equalsTestCase{uint64(kTwoTo54 + 1), true, false, ""}, + equalsTestCase{uint64(kTwoTo54 + 2), true, false, ""}, + equalsTestCase{uint64(kTwoTo54 + 3), false, false, ""}, + + // Double-precision floating point. + equalsTestCase{float64(kTwoTo54 - 2), false, false, ""}, + equalsTestCase{float64(kTwoTo54 - 1), true, false, ""}, + equalsTestCase{float64(kTwoTo54 + 0), true, false, ""}, + equalsTestCase{float64(kTwoTo54 + 1), true, false, ""}, + equalsTestCase{float64(kTwoTo54 + 2), true, false, ""}, + equalsTestCase{float64(kTwoTo54 + 3), false, false, ""}, + + equalsTestCase{complex128(kTwoTo54 - 2), false, false, ""}, + equalsTestCase{complex128(kTwoTo54 - 1), true, false, ""}, + equalsTestCase{complex128(kTwoTo54 + 0), true, false, ""}, + equalsTestCase{complex128(kTwoTo54 + 1), true, false, ""}, + equalsTestCase{complex128(kTwoTo54 + 2), true, false, ""}, + equalsTestCase{complex128(kTwoTo54 + 3), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) Complex128WithNonZeroImaginaryPart() { + const kRealPart = 17 + const kImagPart = 0.25i + const kExpected = kRealPart + kImagPart + matcher := Equals(complex128(kExpected)) + ExpectEq("(17+0.25i)", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of the expected value. + equalsTestCase{kExpected, true, false, ""}, + equalsTestCase{kRealPart + kImagPart, true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int(kRealPart), false, false, ""}, + equalsTestCase{int8(kRealPart), false, false, ""}, + equalsTestCase{int16(kRealPart), false, false, ""}, + equalsTestCase{int32(kRealPart), false, false, ""}, + equalsTestCase{int64(kRealPart), false, false, ""}, + equalsTestCase{uint(kRealPart), false, false, ""}, + equalsTestCase{uint8(kRealPart), false, false, ""}, + equalsTestCase{uint16(kRealPart), false, false, ""}, + equalsTestCase{uint32(kRealPart), false, false, ""}, + equalsTestCase{uint64(kRealPart), false, false, ""}, + equalsTestCase{float32(kRealPart), false, false, ""}, + equalsTestCase{float64(kRealPart), false, false, ""}, + equalsTestCase{complex64(kRealPart), false, false, ""}, + equalsTestCase{complex64(kRealPart + kImagPart + 0.5), false, false, ""}, + equalsTestCase{complex64(kRealPart + kImagPart + 0.5i), false, false, ""}, + equalsTestCase{complex128(kRealPart), false, false, ""}, + equalsTestCase{complex128(kRealPart + kImagPart + 0.5), false, false, ""}, + equalsTestCase{complex128(kRealPart + kImagPart + 0.5i), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// Arrays +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) ArrayOfComparableType() { + expected := [3]uint{17, 19, 23} + + matcher := Equals(expected) + ExpectEq("[17 19 23]", matcher.Description()) + + // To defeat constant de-duping by the compiler. + makeArray := func(i, j, k uint) [3]uint { return [3]uint{i, j, k} } + + type arrayAlias [3]uint + type uintAlias uint + + cases := []equalsTestCase{ + // Correct types, equal. + equalsTestCase{expected, true, false, ""}, + equalsTestCase{[3]uint{17, 19, 23}, true, false, ""}, + equalsTestCase{makeArray(17, 19, 23), true, false, ""}, + + // Correct types, not equal. + equalsTestCase{[3]uint{0, 0, 0}, false, false, ""}, + equalsTestCase{[3]uint{18, 19, 23}, false, false, ""}, + equalsTestCase{[3]uint{17, 20, 23}, false, false, ""}, + equalsTestCase{[3]uint{17, 19, 22}, false, false, ""}, + + // Other types. + equalsTestCase{0, false, true, "which is not [3]uint"}, + equalsTestCase{bool(false), false, true, "which is not [3]uint"}, + equalsTestCase{int(0), false, true, "which is not [3]uint"}, + equalsTestCase{int8(0), false, true, "which is not [3]uint"}, + equalsTestCase{int16(0), false, true, "which is not [3]uint"}, + equalsTestCase{int32(0), false, true, "which is not [3]uint"}, + equalsTestCase{int64(0), false, true, "which is not [3]uint"}, + equalsTestCase{uint(0), false, true, "which is not [3]uint"}, + equalsTestCase{uint8(0), false, true, "which is not [3]uint"}, + equalsTestCase{uint16(0), false, true, "which is not [3]uint"}, + equalsTestCase{uint32(0), false, true, "which is not [3]uint"}, + equalsTestCase{uint64(0), false, true, "which is not [3]uint"}, + equalsTestCase{true, false, true, "which is not [3]uint"}, + equalsTestCase{[...]int{}, false, true, "which is not [3]uint"}, + equalsTestCase{func() {}, false, true, "which is not [3]uint"}, + equalsTestCase{map[int]int{}, false, true, "which is not [3]uint"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not [3]uint"}, + equalsTestCase{[2]uint{17, 19}, false, true, "which is not [3]uint"}, + equalsTestCase{[4]uint{17, 19, 23, 0}, false, true, "which is not [3]uint"}, + equalsTestCase{arrayAlias{17, 19, 23}, false, true, "which is not [3]uint"}, + equalsTestCase{[3]uintAlias{17, 19, 23}, false, true, "which is not [3]uint"}, + equalsTestCase{[3]int32{17, 19, 23}, false, true, "which is not [3]uint"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) ArrayOfNonComparableType() { + type nonComparableArray [2]map[string]string + f := func() { + ExpectEq(nonComparableArray{}, nonComparableArray{}) + } + + ExpectThat(f, Panics(MatchesRegexp("uncomparable.*nonComparableArray"))) +} + +//////////////////////////////////////////////////////////////////////// +// chan +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) NilChan() { + var nilChan1 chan int + var nilChan2 chan int + var nilChan3 chan uint + var nonNilChan1 chan int = make(chan int) + var nonNilChan2 chan uint = make(chan uint) + + matcher := Equals(nilChan1) + ExpectEq("<nil>", matcher.Description()) + + cases := []equalsTestCase{ + // int channels + equalsTestCase{nilChan1, true, false, ""}, + equalsTestCase{nilChan2, true, false, ""}, + equalsTestCase{nonNilChan1, false, false, ""}, + + // uint channels + equalsTestCase{nilChan3, false, true, "which is not a chan int"}, + equalsTestCase{nonNilChan2, false, true, "which is not a chan int"}, + + // Other types. + equalsTestCase{0, false, true, "which is not a chan int"}, + equalsTestCase{bool(false), false, true, "which is not a chan int"}, + equalsTestCase{int(0), false, true, "which is not a chan int"}, + equalsTestCase{int8(0), false, true, "which is not a chan int"}, + equalsTestCase{int16(0), false, true, "which is not a chan int"}, + equalsTestCase{int32(0), false, true, "which is not a chan int"}, + equalsTestCase{int64(0), false, true, "which is not a chan int"}, + equalsTestCase{uint(0), false, true, "which is not a chan int"}, + equalsTestCase{uint8(0), false, true, "which is not a chan int"}, + equalsTestCase{uint16(0), false, true, "which is not a chan int"}, + equalsTestCase{uint32(0), false, true, "which is not a chan int"}, + equalsTestCase{uint64(0), false, true, "which is not a chan int"}, + equalsTestCase{true, false, true, "which is not a chan int"}, + equalsTestCase{[...]int{}, false, true, "which is not a chan int"}, + equalsTestCase{func() {}, false, true, "which is not a chan int"}, + equalsTestCase{map[int]int{}, false, true, "which is not a chan int"}, + equalsTestCase{&someInt, false, true, "which is not a chan int"}, + equalsTestCase{[]int{}, false, true, "which is not a chan int"}, + equalsTestCase{"taco", false, true, "which is not a chan int"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not a chan int"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) NonNilChan() { + var nilChan1 chan int + var nilChan2 chan uint + var nonNilChan1 chan int = make(chan int) + var nonNilChan2 chan int = make(chan int) + var nonNilChan3 chan uint = make(chan uint) + + matcher := Equals(nonNilChan1) + ExpectEq(fmt.Sprintf("%v", nonNilChan1), matcher.Description()) + + cases := []equalsTestCase{ + // int channels + equalsTestCase{nonNilChan1, true, false, ""}, + equalsTestCase{nonNilChan2, false, false, ""}, + equalsTestCase{nilChan1, false, false, ""}, + + // uint channels + equalsTestCase{nilChan2, false, true, "which is not a chan int"}, + equalsTestCase{nonNilChan3, false, true, "which is not a chan int"}, + + // Other types. + equalsTestCase{0, false, true, "which is not a chan int"}, + equalsTestCase{bool(false), false, true, "which is not a chan int"}, + equalsTestCase{int(0), false, true, "which is not a chan int"}, + equalsTestCase{int8(0), false, true, "which is not a chan int"}, + equalsTestCase{int16(0), false, true, "which is not a chan int"}, + equalsTestCase{int32(0), false, true, "which is not a chan int"}, + equalsTestCase{int64(0), false, true, "which is not a chan int"}, + equalsTestCase{uint(0), false, true, "which is not a chan int"}, + equalsTestCase{uint8(0), false, true, "which is not a chan int"}, + equalsTestCase{uint16(0), false, true, "which is not a chan int"}, + equalsTestCase{uint32(0), false, true, "which is not a chan int"}, + equalsTestCase{uint64(0), false, true, "which is not a chan int"}, + equalsTestCase{true, false, true, "which is not a chan int"}, + equalsTestCase{[...]int{}, false, true, "which is not a chan int"}, + equalsTestCase{func() {}, false, true, "which is not a chan int"}, + equalsTestCase{map[int]int{}, false, true, "which is not a chan int"}, + equalsTestCase{&someInt, false, true, "which is not a chan int"}, + equalsTestCase{[]int{}, false, true, "which is not a chan int"}, + equalsTestCase{"taco", false, true, "which is not a chan int"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not a chan int"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) ChanDirection() { + var chan1 chan<- int + var chan2 <-chan int + var chan3 chan int + + matcher := Equals(chan1) + ExpectEq(fmt.Sprintf("%v", chan1), matcher.Description()) + + cases := []equalsTestCase{ + equalsTestCase{chan1, true, false, ""}, + equalsTestCase{chan2, false, true, "which is not a chan<- int"}, + equalsTestCase{chan3, false, true, "which is not a chan<- int"}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// func +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) Functions() { + func1 := func() {} + func2 := func() {} + func3 := func(x int) {} + + matcher := Equals(func1) + ExpectEq(fmt.Sprintf("%v", func1), matcher.Description()) + + cases := []equalsTestCase{ + // Functions. + equalsTestCase{func1, true, false, ""}, + equalsTestCase{func2, false, false, ""}, + equalsTestCase{func3, false, false, ""}, + + // Other types. + equalsTestCase{0, false, true, "which is not a function"}, + equalsTestCase{bool(false), false, true, "which is not a function"}, + equalsTestCase{int(0), false, true, "which is not a function"}, + equalsTestCase{int8(0), false, true, "which is not a function"}, + equalsTestCase{int16(0), false, true, "which is not a function"}, + equalsTestCase{int32(0), false, true, "which is not a function"}, + equalsTestCase{int64(0), false, true, "which is not a function"}, + equalsTestCase{uint(0), false, true, "which is not a function"}, + equalsTestCase{uint8(0), false, true, "which is not a function"}, + equalsTestCase{uint16(0), false, true, "which is not a function"}, + equalsTestCase{uint32(0), false, true, "which is not a function"}, + equalsTestCase{uint64(0), false, true, "which is not a function"}, + equalsTestCase{true, false, true, "which is not a function"}, + equalsTestCase{[...]int{}, false, true, "which is not a function"}, + equalsTestCase{map[int]int{}, false, true, "which is not a function"}, + equalsTestCase{&someInt, false, true, "which is not a function"}, + equalsTestCase{[]int{}, false, true, "which is not a function"}, + equalsTestCase{"taco", false, true, "which is not a function"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not a function"}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// map +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) NilMap() { + var nilMap1 map[int]int + var nilMap2 map[int]int + var nilMap3 map[int]uint + var nonNilMap1 map[int]int = make(map[int]int) + var nonNilMap2 map[int]uint = make(map[int]uint) + + matcher := Equals(nilMap1) + ExpectEq("map[]", matcher.Description()) + + cases := []equalsTestCase{ + // Correct type. + equalsTestCase{nilMap1, true, false, ""}, + equalsTestCase{nilMap2, true, false, ""}, + equalsTestCase{nilMap3, true, false, ""}, + equalsTestCase{nonNilMap1, false, false, ""}, + equalsTestCase{nonNilMap2, false, false, ""}, + + // Other types. + equalsTestCase{0, false, true, "which is not a map"}, + equalsTestCase{bool(false), false, true, "which is not a map"}, + equalsTestCase{int(0), false, true, "which is not a map"}, + equalsTestCase{int8(0), false, true, "which is not a map"}, + equalsTestCase{int16(0), false, true, "which is not a map"}, + equalsTestCase{int32(0), false, true, "which is not a map"}, + equalsTestCase{int64(0), false, true, "which is not a map"}, + equalsTestCase{uint(0), false, true, "which is not a map"}, + equalsTestCase{uint8(0), false, true, "which is not a map"}, + equalsTestCase{uint16(0), false, true, "which is not a map"}, + equalsTestCase{uint32(0), false, true, "which is not a map"}, + equalsTestCase{uint64(0), false, true, "which is not a map"}, + equalsTestCase{true, false, true, "which is not a map"}, + equalsTestCase{[...]int{}, false, true, "which is not a map"}, + equalsTestCase{func() {}, false, true, "which is not a map"}, + equalsTestCase{&someInt, false, true, "which is not a map"}, + equalsTestCase{[]int{}, false, true, "which is not a map"}, + equalsTestCase{"taco", false, true, "which is not a map"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not a map"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) NonNilMap() { + var nilMap1 map[int]int + var nilMap2 map[int]uint + var nonNilMap1 map[int]int = make(map[int]int) + var nonNilMap2 map[int]int = make(map[int]int) + var nonNilMap3 map[int]uint = make(map[int]uint) + + matcher := Equals(nonNilMap1) + ExpectEq("map[]", matcher.Description()) + + cases := []equalsTestCase{ + // Correct type. + equalsTestCase{nonNilMap1, true, false, ""}, + equalsTestCase{nonNilMap2, false, false, ""}, + equalsTestCase{nonNilMap3, false, false, ""}, + equalsTestCase{nilMap1, false, false, ""}, + equalsTestCase{nilMap2, false, false, ""}, + + // Other types. + equalsTestCase{0, false, true, "which is not a map"}, + equalsTestCase{bool(false), false, true, "which is not a map"}, + equalsTestCase{int(0), false, true, "which is not a map"}, + equalsTestCase{int8(0), false, true, "which is not a map"}, + equalsTestCase{int16(0), false, true, "which is not a map"}, + equalsTestCase{int32(0), false, true, "which is not a map"}, + equalsTestCase{int64(0), false, true, "which is not a map"}, + equalsTestCase{uint(0), false, true, "which is not a map"}, + equalsTestCase{uint8(0), false, true, "which is not a map"}, + equalsTestCase{uint16(0), false, true, "which is not a map"}, + equalsTestCase{uint32(0), false, true, "which is not a map"}, + equalsTestCase{uint64(0), false, true, "which is not a map"}, + equalsTestCase{true, false, true, "which is not a map"}, + equalsTestCase{[...]int{}, false, true, "which is not a map"}, + equalsTestCase{func() {}, false, true, "which is not a map"}, + equalsTestCase{&someInt, false, true, "which is not a map"}, + equalsTestCase{[]int{}, false, true, "which is not a map"}, + equalsTestCase{"taco", false, true, "which is not a map"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not a map"}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// Pointers +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) NilPointer() { + var someInt int = 17 + var someUint uint = 17 + + var nilInt1 *int + var nilInt2 *int + var nilUint *uint + var nonNilInt *int = &someInt + var nonNilUint *uint = &someUint + + matcher := Equals(nilInt1) + ExpectEq("<nil>", matcher.Description()) + + cases := []equalsTestCase{ + // Correct type. + equalsTestCase{nilInt1, true, false, ""}, + equalsTestCase{nilInt2, true, false, ""}, + equalsTestCase{nonNilInt, false, false, ""}, + + // Incorrect type. + equalsTestCase{nilUint, false, true, "which is not a *int"}, + equalsTestCase{nonNilUint, false, true, "which is not a *int"}, + + // Other types. + equalsTestCase{0, false, true, "which is not a *int"}, + equalsTestCase{bool(false), false, true, "which is not a *int"}, + equalsTestCase{int(0), false, true, "which is not a *int"}, + equalsTestCase{int8(0), false, true, "which is not a *int"}, + equalsTestCase{int16(0), false, true, "which is not a *int"}, + equalsTestCase{int32(0), false, true, "which is not a *int"}, + equalsTestCase{int64(0), false, true, "which is not a *int"}, + equalsTestCase{uint(0), false, true, "which is not a *int"}, + equalsTestCase{uint8(0), false, true, "which is not a *int"}, + equalsTestCase{uint16(0), false, true, "which is not a *int"}, + equalsTestCase{uint32(0), false, true, "which is not a *int"}, + equalsTestCase{uint64(0), false, true, "which is not a *int"}, + equalsTestCase{true, false, true, "which is not a *int"}, + equalsTestCase{[...]int{}, false, true, "which is not a *int"}, + equalsTestCase{func() {}, false, true, "which is not a *int"}, + equalsTestCase{map[int]int{}, false, true, "which is not a *int"}, + equalsTestCase{[]int{}, false, true, "which is not a *int"}, + equalsTestCase{"taco", false, true, "which is not a *int"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not a *int"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) NonNilPointer() { + var someInt int = 17 + var someOtherInt int = 17 + var someUint uint = 17 + + var nilInt *int + var nilUint *uint + var nonNilInt1 *int = &someInt + var nonNilInt2 *int = &someOtherInt + var nonNilUint *uint = &someUint + + matcher := Equals(nonNilInt1) + ExpectEq(fmt.Sprintf("%v", nonNilInt1), matcher.Description()) + + cases := []equalsTestCase{ + // Correct type. + equalsTestCase{nonNilInt1, true, false, ""}, + equalsTestCase{nonNilInt2, false, false, ""}, + equalsTestCase{nilInt, false, false, ""}, + + // Incorrect type. + equalsTestCase{nilUint, false, true, "which is not a *int"}, + equalsTestCase{nonNilUint, false, true, "which is not a *int"}, + + // Other types. + equalsTestCase{0, false, true, "which is not a *int"}, + equalsTestCase{bool(false), false, true, "which is not a *int"}, + equalsTestCase{int(0), false, true, "which is not a *int"}, + equalsTestCase{int8(0), false, true, "which is not a *int"}, + equalsTestCase{int16(0), false, true, "which is not a *int"}, + equalsTestCase{int32(0), false, true, "which is not a *int"}, + equalsTestCase{int64(0), false, true, "which is not a *int"}, + equalsTestCase{uint(0), false, true, "which is not a *int"}, + equalsTestCase{uint8(0), false, true, "which is not a *int"}, + equalsTestCase{uint16(0), false, true, "which is not a *int"}, + equalsTestCase{uint32(0), false, true, "which is not a *int"}, + equalsTestCase{uint64(0), false, true, "which is not a *int"}, + equalsTestCase{true, false, true, "which is not a *int"}, + equalsTestCase{[...]int{}, false, true, "which is not a *int"}, + equalsTestCase{func() {}, false, true, "which is not a *int"}, + equalsTestCase{map[int]int{}, false, true, "which is not a *int"}, + equalsTestCase{[]int{}, false, true, "which is not a *int"}, + equalsTestCase{"taco", false, true, "which is not a *int"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not a *int"}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// Slices +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) NilSlice() { + var nilInt1 []int + var nilInt2 []int + var nilUint []uint + + var nonNilInt []int = make([]int, 0) + var nonNilUint []uint = make([]uint, 0) + + matcher := Equals(nilInt1) + ExpectEq("[]", matcher.Description()) + + cases := []equalsTestCase{ + // Correct type. + equalsTestCase{nilInt1, true, false, ""}, + equalsTestCase{nilInt2, true, false, ""}, + equalsTestCase{nonNilInt, false, false, ""}, + + // Incorrect type. + equalsTestCase{nilUint, false, true, "which is not a []int"}, + equalsTestCase{nonNilUint, false, true, "which is not a []int"}, + + // Other types. + equalsTestCase{0, false, true, "which is not a []int"}, + equalsTestCase{bool(false), false, true, "which is not a []int"}, + equalsTestCase{int(0), false, true, "which is not a []int"}, + equalsTestCase{int8(0), false, true, "which is not a []int"}, + equalsTestCase{int16(0), false, true, "which is not a []int"}, + equalsTestCase{int32(0), false, true, "which is not a []int"}, + equalsTestCase{int64(0), false, true, "which is not a []int"}, + equalsTestCase{uint(0), false, true, "which is not a []int"}, + equalsTestCase{uint8(0), false, true, "which is not a []int"}, + equalsTestCase{uint16(0), false, true, "which is not a []int"}, + equalsTestCase{uint32(0), false, true, "which is not a []int"}, + equalsTestCase{uint64(0), false, true, "which is not a []int"}, + equalsTestCase{true, false, true, "which is not a []int"}, + equalsTestCase{[...]int{}, false, true, "which is not a []int"}, + equalsTestCase{func() {}, false, true, "which is not a []int"}, + equalsTestCase{map[int]int{}, false, true, "which is not a []int"}, + equalsTestCase{"taco", false, true, "which is not a []int"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not a []int"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) NonNilSlice() { + nonNil := make([]int, 0) + f := func() { Equals(nonNil) } + ExpectThat(f, Panics(HasSubstr("non-nil slice"))) +} + +//////////////////////////////////////////////////////////////////////// +// string +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) String() { + partial := "taco" + expected := fmt.Sprintf("%s%d", partial, 1) + + matcher := Equals(expected) + ExpectEq("taco1", matcher.Description()) + + type stringAlias string + + cases := []equalsTestCase{ + // Correct types. + equalsTestCase{"taco1", true, false, ""}, + equalsTestCase{"taco" + "1", true, false, ""}, + equalsTestCase{expected, true, false, ""}, + equalsTestCase{stringAlias("taco1"), true, false, ""}, + + equalsTestCase{"", false, false, ""}, + equalsTestCase{"taco", false, false, ""}, + equalsTestCase{"taco1\x00", false, false, ""}, + equalsTestCase{"taco2", false, false, ""}, + equalsTestCase{stringAlias("taco2"), false, false, ""}, + + // Other types. + equalsTestCase{0, false, true, "which is not a string"}, + equalsTestCase{bool(false), false, true, "which is not a string"}, + equalsTestCase{int(0), false, true, "which is not a string"}, + equalsTestCase{int8(0), false, true, "which is not a string"}, + equalsTestCase{int16(0), false, true, "which is not a string"}, + equalsTestCase{int32(0), false, true, "which is not a string"}, + equalsTestCase{int64(0), false, true, "which is not a string"}, + equalsTestCase{uint(0), false, true, "which is not a string"}, + equalsTestCase{uint8(0), false, true, "which is not a string"}, + equalsTestCase{uint16(0), false, true, "which is not a string"}, + equalsTestCase{uint32(0), false, true, "which is not a string"}, + equalsTestCase{uint64(0), false, true, "which is not a string"}, + equalsTestCase{true, false, true, "which is not a string"}, + equalsTestCase{[...]int{}, false, true, "which is not a string"}, + equalsTestCase{func() {}, false, true, "which is not a string"}, + equalsTestCase{map[int]int{}, false, true, "which is not a string"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not a string"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) StringAlias() { + type stringAlias string + + matcher := Equals(stringAlias("taco")) + ExpectEq("taco", matcher.Description()) + + cases := []equalsTestCase{ + // Correct types. + equalsTestCase{stringAlias("taco"), true, false, ""}, + equalsTestCase{"taco", true, false, ""}, + + equalsTestCase{"burrito", false, false, ""}, + equalsTestCase{stringAlias("burrito"), false, false, ""}, + + // Other types. + equalsTestCase{0, false, true, "which is not a string"}, + equalsTestCase{bool(false), false, true, "which is not a string"}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// struct +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) Struct() { + type someStruct struct{ foo uint } + f := func() { Equals(someStruct{17}) } + ExpectThat(f, Panics(HasSubstr("unsupported kind struct"))) +} + +//////////////////////////////////////////////////////////////////////// +// unsafe.Pointer +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) NilUnsafePointer() { + someInt := int(17) + + var nilPtr1 unsafe.Pointer + var nilPtr2 unsafe.Pointer + var nonNilPtr unsafe.Pointer = unsafe.Pointer(&someInt) + + matcher := Equals(nilPtr1) + ExpectEq("<nil>", matcher.Description()) + + cases := []equalsTestCase{ + // Correct type. + equalsTestCase{nilPtr1, true, false, ""}, + equalsTestCase{nilPtr2, true, false, ""}, + equalsTestCase{nonNilPtr, false, false, ""}, + + // Other types. + equalsTestCase{0, false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{bool(false), false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{int(0), false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{int8(0), false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{int16(0), false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{int32(0), false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{int64(0), false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{uint(0), false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{uint8(0), false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{uint16(0), false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{uint32(0), false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{uint64(0), false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{true, false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{[...]int{}, false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{make(chan int), false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{func() {}, false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{map[int]int{}, false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{&someInt, false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{[]int{}, false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{"taco", false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not a unsafe.Pointer"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) NonNilUnsafePointer() { + someInt := int(17) + someOtherInt := int(17) + + var nilPtr unsafe.Pointer + var nonNilPtr1 unsafe.Pointer = unsafe.Pointer(&someInt) + var nonNilPtr2 unsafe.Pointer = unsafe.Pointer(&someOtherInt) + + matcher := Equals(nonNilPtr1) + ExpectEq(fmt.Sprintf("%v", nonNilPtr1), matcher.Description()) + + cases := []equalsTestCase{ + // Correct type. + equalsTestCase{nonNilPtr1, true, false, ""}, + equalsTestCase{nonNilPtr2, false, false, ""}, + equalsTestCase{nilPtr, false, false, ""}, + + // Other types. + equalsTestCase{0, false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{bool(false), false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{int(0), false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{int8(0), false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{int16(0), false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{int32(0), false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{int64(0), false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{uint(0), false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{uint8(0), false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{uint16(0), false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{uint32(0), false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{uint64(0), false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{true, false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{[...]int{}, false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{make(chan int), false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{func() {}, false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{map[int]int{}, false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{&someInt, false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{[]int{}, false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{"taco", false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not a unsafe.Pointer"}, + } + + t.checkTestCases(matcher, cases) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/error.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/error.go new file mode 100644 index 00000000000..8a078e36d86 --- /dev/null +++ b/src/mongo/gotools/vendor/src/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/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/error_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/error_test.go new file mode 100644 index 00000000000..f92167cad1d --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/error_test.go @@ -0,0 +1,92 @@ +// 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_test + +import ( + "errors" + . "github.com/smartystreets/assertions/internal/oglematchers" + . "github.com/smartystreets/assertions/internal/ogletest" +) + +//////////////////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////////////////// + +type ErrorTest struct { + matcherCalled bool + suppliedCandidate interface{} + wrappedError error + + matcher Matcher +} + +func init() { RegisterTestSuite(&ErrorTest{}) } + +func (t *ErrorTest) SetUp(i *TestInfo) { + wrapped := &fakeMatcher{ + func(c interface{}) error { + t.matcherCalled = true + t.suppliedCandidate = c + return t.wrappedError + }, + "is foo", + } + + t.matcher = Error(wrapped) +} + +func isFatal(err error) bool { + _, isFatal := err.(*FatalError) + return isFatal +} + +//////////////////////////////////////////////////////////////////////// +// Tests +//////////////////////////////////////////////////////////////////////// + +func (t *ErrorTest) Description() { + ExpectThat(t.matcher.Description(), Equals("error is foo")) +} + +func (t *ErrorTest) CandidateIsNil() { + err := t.matcher.Matches(nil) + + ExpectThat(t.matcherCalled, Equals(false)) + ExpectThat(err.Error(), Equals("which is not an error")) + ExpectTrue(isFatal(err)) +} + +func (t *ErrorTest) CandidateIsString() { + err := t.matcher.Matches("taco") + + ExpectThat(t.matcherCalled, Equals(false)) + ExpectThat(err.Error(), Equals("which is not an error")) + ExpectTrue(isFatal(err)) +} + +func (t *ErrorTest) CallsWrappedMatcher() { + candidate := errors.New("taco") + t.matcher.Matches(candidate) + + ExpectThat(t.matcherCalled, Equals(true)) + ExpectThat(t.suppliedCandidate, Equals("taco")) +} + +func (t *ErrorTest) ReturnsWrappedMatcherResult() { + t.wrappedError = errors.New("burrito") + err := t.matcher.Matches(errors.New("")) + ExpectThat(err, Equals(t.wrappedError)) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/greater_or_equal.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/greater_or_equal.go new file mode 100644 index 00000000000..4b9d103a381 --- /dev/null +++ b/src/mongo/gotools/vendor/src/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/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/greater_or_equal_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/greater_or_equal_test.go new file mode 100644 index 00000000000..f5e29d1ce59 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/greater_or_equal_test.go @@ -0,0 +1,1101 @@ +// 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_test + +import ( + "math" + + . "github.com/smartystreets/assertions/internal/oglematchers" + . "github.com/smartystreets/assertions/internal/ogletest" +) + +//////////////////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////////////////// + +type GreaterOrEqualTest struct { +} + +func init() { RegisterTestSuite(&GreaterOrEqualTest{}) } + +type geTestCase struct { + candidate interface{} + expectedResult bool + shouldBeFatal bool + expectedError string +} + +func (t *GreaterOrEqualTest) checkTestCases(matcher Matcher, cases []geTestCase) { + for i, c := range cases { + err := matcher.Matches(c.candidate) + + ExpectThat( + (err == nil), + Equals(c.expectedResult), + "Case %d (candidate %v)", + i, + c.candidate) + + if err == nil { + continue + } + + _, isFatal := err.(*FatalError) + ExpectEq( + c.shouldBeFatal, + isFatal, + "Case %d (candidate %v)", + i, + c.candidate) + + ExpectThat( + err, + Error(Equals(c.expectedError)), + "Case %d (candidate %v)", + i, + c.candidate) + } +} + +//////////////////////////////////////////////////////////////////////// +// Integer literals +//////////////////////////////////////////////////////////////////////// + +func (t *GreaterOrEqualTest) IntegerCandidateBadTypes() { + matcher := GreaterOrEqual(int(-150)) + + cases := []geTestCase{ + geTestCase{true, false, true, "which is not comparable"}, + geTestCase{complex64(-151), false, true, "which is not comparable"}, + geTestCase{complex128(-151), false, true, "which is not comparable"}, + geTestCase{[...]int{-151}, false, true, "which is not comparable"}, + geTestCase{make(chan int), false, true, "which is not comparable"}, + geTestCase{func() {}, false, true, "which is not comparable"}, + geTestCase{map[int]int{}, false, true, "which is not comparable"}, + geTestCase{&geTestCase{}, false, true, "which is not comparable"}, + geTestCase{make([]int, 0), false, true, "which is not comparable"}, + geTestCase{"-151", false, true, "which is not comparable"}, + geTestCase{geTestCase{}, false, true, "which is not comparable"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterOrEqualTest) FloatCandidateBadTypes() { + matcher := GreaterOrEqual(float32(-150)) + + cases := []geTestCase{ + geTestCase{true, false, true, "which is not comparable"}, + geTestCase{complex64(-151), false, true, "which is not comparable"}, + geTestCase{complex128(-151), false, true, "which is not comparable"}, + geTestCase{[...]int{-151}, false, true, "which is not comparable"}, + geTestCase{make(chan int), false, true, "which is not comparable"}, + geTestCase{func() {}, false, true, "which is not comparable"}, + geTestCase{map[int]int{}, false, true, "which is not comparable"}, + geTestCase{&geTestCase{}, false, true, "which is not comparable"}, + geTestCase{make([]int, 0), false, true, "which is not comparable"}, + geTestCase{"-151", false, true, "which is not comparable"}, + geTestCase{geTestCase{}, false, true, "which is not comparable"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterOrEqualTest) StringCandidateBadTypes() { + matcher := GreaterOrEqual("17") + + cases := []geTestCase{ + geTestCase{true, false, true, "which is not comparable"}, + geTestCase{int(0), false, true, "which is not comparable"}, + geTestCase{int8(0), false, true, "which is not comparable"}, + geTestCase{int16(0), false, true, "which is not comparable"}, + geTestCase{int32(0), false, true, "which is not comparable"}, + geTestCase{int64(0), false, true, "which is not comparable"}, + geTestCase{uint(0), false, true, "which is not comparable"}, + geTestCase{uint8(0), false, true, "which is not comparable"}, + geTestCase{uint16(0), false, true, "which is not comparable"}, + geTestCase{uint32(0), false, true, "which is not comparable"}, + geTestCase{uint64(0), false, true, "which is not comparable"}, + geTestCase{float32(0), false, true, "which is not comparable"}, + geTestCase{float64(0), false, true, "which is not comparable"}, + geTestCase{complex64(-151), false, true, "which is not comparable"}, + geTestCase{complex128(-151), false, true, "which is not comparable"}, + geTestCase{[...]int{-151}, false, true, "which is not comparable"}, + geTestCase{make(chan int), false, true, "which is not comparable"}, + geTestCase{func() {}, false, true, "which is not comparable"}, + geTestCase{map[int]int{}, false, true, "which is not comparable"}, + geTestCase{&geTestCase{}, false, true, "which is not comparable"}, + geTestCase{make([]int, 0), false, true, "which is not comparable"}, + geTestCase{geTestCase{}, false, true, "which is not comparable"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterOrEqualTest) BadArgument() { + panicked := false + + defer func() { + ExpectThat(panicked, Equals(true)) + }() + + defer func() { + if r := recover(); r != nil { + panicked = true + } + }() + + GreaterOrEqual(complex128(0)) +} + +//////////////////////////////////////////////////////////////////////// +// Integer literals +//////////////////////////////////////////////////////////////////////// + +func (t *GreaterOrEqualTest) NegativeIntegerLiteral() { + matcher := GreaterOrEqual(-150) + desc := matcher.Description() + expectedDesc := "greater than or equal to -150" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []geTestCase{ + // Signed integers. + geTestCase{-(1 << 30), false, false, ""}, + geTestCase{-151, false, false, ""}, + geTestCase{-150, true, false, ""}, + geTestCase{0, true, false, ""}, + geTestCase{17, true, false, ""}, + + geTestCase{int(-(1 << 30)), false, false, ""}, + geTestCase{int(-151), false, false, ""}, + geTestCase{int(-150), true, false, ""}, + geTestCase{int(0), true, false, ""}, + geTestCase{int(17), true, false, ""}, + + geTestCase{int8(-127), true, false, ""}, + geTestCase{int8(0), true, false, ""}, + geTestCase{int8(17), true, false, ""}, + + geTestCase{int16(-(1 << 14)), false, false, ""}, + geTestCase{int16(-151), false, false, ""}, + geTestCase{int16(-150), true, false, ""}, + geTestCase{int16(0), true, false, ""}, + geTestCase{int16(17), true, false, ""}, + + geTestCase{int32(-(1 << 30)), false, false, ""}, + geTestCase{int32(-151), false, false, ""}, + geTestCase{int32(-150), true, false, ""}, + geTestCase{int32(0), true, false, ""}, + geTestCase{int32(17), true, false, ""}, + + geTestCase{int64(-(1 << 30)), false, false, ""}, + geTestCase{int64(-151), false, false, ""}, + geTestCase{int64(-150), true, false, ""}, + geTestCase{int64(0), true, false, ""}, + geTestCase{int64(17), true, false, ""}, + + // Unsigned integers. + geTestCase{uint((1 << 32) - 151), true, false, ""}, + geTestCase{uint(0), true, false, ""}, + geTestCase{uint(17), true, false, ""}, + + geTestCase{uint8(0), true, false, ""}, + geTestCase{uint8(17), true, false, ""}, + geTestCase{uint8(253), true, false, ""}, + + geTestCase{uint16((1 << 16) - 151), true, false, ""}, + geTestCase{uint16(0), true, false, ""}, + geTestCase{uint16(17), true, false, ""}, + + geTestCase{uint32((1 << 32) - 151), true, false, ""}, + geTestCase{uint32(0), true, false, ""}, + geTestCase{uint32(17), true, false, ""}, + + geTestCase{uint64((1 << 64) - 151), true, false, ""}, + geTestCase{uint64(0), true, false, ""}, + geTestCase{uint64(17), true, false, ""}, + + geTestCase{uintptr((1 << 64) - 151), true, false, ""}, + geTestCase{uintptr(0), true, false, ""}, + geTestCase{uintptr(17), true, false, ""}, + + // Floating point. + geTestCase{float32(-(1 << 30)), false, false, ""}, + geTestCase{float32(-151), false, false, ""}, + geTestCase{float32(-150.1), false, false, ""}, + geTestCase{float32(-150), true, false, ""}, + geTestCase{float32(-149.9), true, false, ""}, + geTestCase{float32(0), true, false, ""}, + geTestCase{float32(17), true, false, ""}, + geTestCase{float32(160), true, false, ""}, + + geTestCase{float64(-(1 << 30)), false, false, ""}, + geTestCase{float64(-151), false, false, ""}, + geTestCase{float64(-150.1), false, false, ""}, + geTestCase{float64(-150), true, false, ""}, + geTestCase{float64(-149.9), true, false, ""}, + geTestCase{float64(0), true, false, ""}, + geTestCase{float64(17), true, false, ""}, + geTestCase{float64(160), true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterOrEqualTest) ZeroIntegerLiteral() { + matcher := GreaterOrEqual(0) + desc := matcher.Description() + expectedDesc := "greater than or equal to 0" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []geTestCase{ + // Signed integers. + geTestCase{-(1 << 30), false, false, ""}, + geTestCase{-1, false, false, ""}, + geTestCase{0, true, false, ""}, + geTestCase{1, true, false, ""}, + geTestCase{17, true, false, ""}, + geTestCase{(1 << 30), true, false, ""}, + + geTestCase{int(-(1 << 30)), false, false, ""}, + geTestCase{int(-1), false, false, ""}, + geTestCase{int(0), true, false, ""}, + geTestCase{int(1), true, false, ""}, + geTestCase{int(17), true, false, ""}, + + geTestCase{int8(-1), false, false, ""}, + geTestCase{int8(0), true, false, ""}, + geTestCase{int8(1), true, false, ""}, + + geTestCase{int16(-(1 << 14)), false, false, ""}, + geTestCase{int16(-1), false, false, ""}, + geTestCase{int16(0), true, false, ""}, + geTestCase{int16(1), true, false, ""}, + geTestCase{int16(17), true, false, ""}, + + geTestCase{int32(-(1 << 30)), false, false, ""}, + geTestCase{int32(-1), false, false, ""}, + geTestCase{int32(0), true, false, ""}, + geTestCase{int32(1), true, false, ""}, + geTestCase{int32(17), true, false, ""}, + + geTestCase{int64(-(1 << 30)), false, false, ""}, + geTestCase{int64(-1), false, false, ""}, + geTestCase{int64(0), true, false, ""}, + geTestCase{int64(1), true, false, ""}, + geTestCase{int64(17), true, false, ""}, + + // Unsigned integers. + geTestCase{uint((1 << 32) - 1), true, false, ""}, + geTestCase{uint(0), true, false, ""}, + geTestCase{uint(17), true, false, ""}, + + geTestCase{uint8(0), true, false, ""}, + geTestCase{uint8(17), true, false, ""}, + geTestCase{uint8(253), true, false, ""}, + + geTestCase{uint16((1 << 16) - 1), true, false, ""}, + geTestCase{uint16(0), true, false, ""}, + geTestCase{uint16(17), true, false, ""}, + + geTestCase{uint32((1 << 32) - 1), true, false, ""}, + geTestCase{uint32(0), true, false, ""}, + geTestCase{uint32(17), true, false, ""}, + + geTestCase{uint64((1 << 64) - 1), true, false, ""}, + geTestCase{uint64(0), true, false, ""}, + geTestCase{uint64(17), true, false, ""}, + + geTestCase{uintptr((1 << 64) - 1), true, false, ""}, + geTestCase{uintptr(0), true, false, ""}, + geTestCase{uintptr(17), true, false, ""}, + + // Floating point. + geTestCase{float32(-(1 << 30)), false, false, ""}, + geTestCase{float32(-1), false, false, ""}, + geTestCase{float32(-0.1), false, false, ""}, + geTestCase{float32(-0.0), true, false, ""}, + geTestCase{float32(0), true, false, ""}, + geTestCase{float32(0.1), true, false, ""}, + geTestCase{float32(17), true, false, ""}, + geTestCase{float32(160), true, false, ""}, + + geTestCase{float64(-(1 << 30)), false, false, ""}, + geTestCase{float64(-1), false, false, ""}, + geTestCase{float64(-0.1), false, false, ""}, + geTestCase{float64(-0), true, false, ""}, + geTestCase{float64(0), true, false, ""}, + geTestCase{float64(17), true, false, ""}, + geTestCase{float64(160), true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterOrEqualTest) PositiveIntegerLiteral() { + matcher := GreaterOrEqual(150) + desc := matcher.Description() + expectedDesc := "greater than or equal to 150" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []geTestCase{ + // Signed integers. + geTestCase{-1, false, false, ""}, + geTestCase{149, false, false, ""}, + geTestCase{150, true, false, ""}, + geTestCase{151, true, false, ""}, + + geTestCase{int(-1), false, false, ""}, + geTestCase{int(149), false, false, ""}, + geTestCase{int(150), true, false, ""}, + geTestCase{int(151), true, false, ""}, + + geTestCase{int8(-1), false, false, ""}, + geTestCase{int8(0), false, false, ""}, + geTestCase{int8(17), false, false, ""}, + geTestCase{int8(127), false, false, ""}, + + geTestCase{int16(-1), false, false, ""}, + geTestCase{int16(149), false, false, ""}, + geTestCase{int16(150), true, false, ""}, + geTestCase{int16(151), true, false, ""}, + + geTestCase{int32(-1), false, false, ""}, + geTestCase{int32(149), false, false, ""}, + geTestCase{int32(150), true, false, ""}, + geTestCase{int32(151), true, false, ""}, + + geTestCase{int64(-1), false, false, ""}, + geTestCase{int64(149), false, false, ""}, + geTestCase{int64(150), true, false, ""}, + geTestCase{int64(151), true, false, ""}, + + // Unsigned integers. + geTestCase{uint(0), false, false, ""}, + geTestCase{uint(149), false, false, ""}, + geTestCase{uint(150), true, false, ""}, + geTestCase{uint(151), true, false, ""}, + + geTestCase{uint8(0), false, false, ""}, + geTestCase{uint8(127), false, false, ""}, + + geTestCase{uint16(0), false, false, ""}, + geTestCase{uint16(149), false, false, ""}, + geTestCase{uint16(150), true, false, ""}, + geTestCase{uint16(151), true, false, ""}, + + geTestCase{uint32(0), false, false, ""}, + geTestCase{uint32(149), false, false, ""}, + geTestCase{uint32(150), true, false, ""}, + geTestCase{uint32(151), true, false, ""}, + + geTestCase{uint64(0), false, false, ""}, + geTestCase{uint64(149), false, false, ""}, + geTestCase{uint64(150), true, false, ""}, + geTestCase{uint64(151), true, false, ""}, + + geTestCase{uintptr(0), false, false, ""}, + geTestCase{uintptr(149), false, false, ""}, + geTestCase{uintptr(150), true, false, ""}, + geTestCase{uintptr(151), true, false, ""}, + + // Floating point. + geTestCase{float32(-1), false, false, ""}, + geTestCase{float32(149), false, false, ""}, + geTestCase{float32(149.9), false, false, ""}, + geTestCase{float32(150), true, false, ""}, + geTestCase{float32(150.1), true, false, ""}, + geTestCase{float32(151), true, false, ""}, + + geTestCase{float64(-1), false, false, ""}, + geTestCase{float64(149), false, false, ""}, + geTestCase{float64(149.9), false, false, ""}, + geTestCase{float64(150), true, false, ""}, + geTestCase{float64(150.1), true, false, ""}, + geTestCase{float64(151), true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// Float literals +//////////////////////////////////////////////////////////////////////// + +func (t *GreaterOrEqualTest) NegativeFloatLiteral() { + matcher := GreaterOrEqual(-150.1) + desc := matcher.Description() + expectedDesc := "greater than or equal to -150.1" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []geTestCase{ + // Signed integers. + geTestCase{-(1 << 30), false, false, ""}, + geTestCase{-151, false, false, ""}, + geTestCase{-150, true, false, ""}, + geTestCase{0, true, false, ""}, + geTestCase{17, true, false, ""}, + + geTestCase{int(-(1 << 30)), false, false, ""}, + geTestCase{int(-151), false, false, ""}, + geTestCase{int(-150), true, false, ""}, + geTestCase{int(0), true, false, ""}, + geTestCase{int(17), true, false, ""}, + + geTestCase{int8(-127), true, false, ""}, + geTestCase{int8(0), true, false, ""}, + geTestCase{int8(17), true, false, ""}, + + geTestCase{int16(-(1 << 14)), false, false, ""}, + geTestCase{int16(-151), false, false, ""}, + geTestCase{int16(-150), true, false, ""}, + geTestCase{int16(0), true, false, ""}, + geTestCase{int16(17), true, false, ""}, + + geTestCase{int32(-(1 << 30)), false, false, ""}, + geTestCase{int32(-151), false, false, ""}, + geTestCase{int32(-150), true, false, ""}, + geTestCase{int32(0), true, false, ""}, + geTestCase{int32(17), true, false, ""}, + + geTestCase{int64(-(1 << 30)), false, false, ""}, + geTestCase{int64(-151), false, false, ""}, + geTestCase{int64(-150), true, false, ""}, + geTestCase{int64(0), true, false, ""}, + geTestCase{int64(17), true, false, ""}, + + // Unsigned integers. + geTestCase{uint((1 << 32) - 151), true, false, ""}, + geTestCase{uint(0), true, false, ""}, + geTestCase{uint(17), true, false, ""}, + + geTestCase{uint8(0), true, false, ""}, + geTestCase{uint8(17), true, false, ""}, + geTestCase{uint8(253), true, false, ""}, + + geTestCase{uint16((1 << 16) - 151), true, false, ""}, + geTestCase{uint16(0), true, false, ""}, + geTestCase{uint16(17), true, false, ""}, + + geTestCase{uint32((1 << 32) - 151), true, false, ""}, + geTestCase{uint32(0), true, false, ""}, + geTestCase{uint32(17), true, false, ""}, + + geTestCase{uint64((1 << 64) - 151), true, false, ""}, + geTestCase{uint64(0), true, false, ""}, + geTestCase{uint64(17), true, false, ""}, + + geTestCase{uintptr((1 << 64) - 151), true, false, ""}, + geTestCase{uintptr(0), true, false, ""}, + geTestCase{uintptr(17), true, false, ""}, + + // Floating point. + geTestCase{float32(-(1 << 30)), false, false, ""}, + geTestCase{float32(-151), false, false, ""}, + geTestCase{float32(-150.2), false, false, ""}, + geTestCase{float32(-150.1), true, false, ""}, + geTestCase{float32(-150), true, false, ""}, + geTestCase{float32(0), true, false, ""}, + geTestCase{float32(17), true, false, ""}, + geTestCase{float32(160), true, false, ""}, + + geTestCase{float64(-(1 << 30)), false, false, ""}, + geTestCase{float64(-151), false, false, ""}, + geTestCase{float64(-150.2), false, false, ""}, + geTestCase{float64(-150.1), true, false, ""}, + geTestCase{float64(-150), true, false, ""}, + geTestCase{float64(0), true, false, ""}, + geTestCase{float64(17), true, false, ""}, + geTestCase{float64(160), true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterOrEqualTest) PositiveFloatLiteral() { + matcher := GreaterOrEqual(149.9) + desc := matcher.Description() + expectedDesc := "greater than or equal to 149.9" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []geTestCase{ + // Signed integers. + geTestCase{-1, false, false, ""}, + geTestCase{149, false, false, ""}, + geTestCase{150, true, false, ""}, + geTestCase{151, true, false, ""}, + + geTestCase{int(-1), false, false, ""}, + geTestCase{int(149), false, false, ""}, + geTestCase{int(150), true, false, ""}, + geTestCase{int(151), true, false, ""}, + + geTestCase{int8(-1), false, false, ""}, + geTestCase{int8(0), false, false, ""}, + geTestCase{int8(17), false, false, ""}, + geTestCase{int8(127), false, false, ""}, + + geTestCase{int16(-1), false, false, ""}, + geTestCase{int16(149), false, false, ""}, + geTestCase{int16(150), true, false, ""}, + geTestCase{int16(151), true, false, ""}, + + geTestCase{int32(-1), false, false, ""}, + geTestCase{int32(149), false, false, ""}, + geTestCase{int32(150), true, false, ""}, + geTestCase{int32(151), true, false, ""}, + + geTestCase{int64(-1), false, false, ""}, + geTestCase{int64(149), false, false, ""}, + geTestCase{int64(150), true, false, ""}, + geTestCase{int64(151), true, false, ""}, + + // Unsigned integers. + geTestCase{uint(0), false, false, ""}, + geTestCase{uint(149), false, false, ""}, + geTestCase{uint(150), true, false, ""}, + geTestCase{uint(151), true, false, ""}, + + geTestCase{uint8(0), false, false, ""}, + geTestCase{uint8(127), false, false, ""}, + + geTestCase{uint16(0), false, false, ""}, + geTestCase{uint16(149), false, false, ""}, + geTestCase{uint16(150), true, false, ""}, + geTestCase{uint16(151), true, false, ""}, + + geTestCase{uint32(0), false, false, ""}, + geTestCase{uint32(149), false, false, ""}, + geTestCase{uint32(150), true, false, ""}, + geTestCase{uint32(151), true, false, ""}, + + geTestCase{uint64(0), false, false, ""}, + geTestCase{uint64(149), false, false, ""}, + geTestCase{uint64(150), true, false, ""}, + geTestCase{uint64(151), true, false, ""}, + + geTestCase{uintptr(0), false, false, ""}, + geTestCase{uintptr(149), false, false, ""}, + geTestCase{uintptr(150), true, false, ""}, + geTestCase{uintptr(151), true, false, ""}, + + // Floating point. + geTestCase{float32(-1), false, false, ""}, + geTestCase{float32(149), false, false, ""}, + geTestCase{float32(149.8), false, false, ""}, + geTestCase{float32(149.9), true, false, ""}, + geTestCase{float32(150), true, false, ""}, + geTestCase{float32(151), true, false, ""}, + + geTestCase{float64(-1), false, false, ""}, + geTestCase{float64(149), false, false, ""}, + geTestCase{float64(149.8), false, false, ""}, + geTestCase{float64(149.9), true, false, ""}, + geTestCase{float64(150), true, false, ""}, + geTestCase{float64(151), true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// Subtle cases +//////////////////////////////////////////////////////////////////////// + +func (t *GreaterOrEqualTest) Int64NotExactlyRepresentableBySinglePrecision() { + // Single-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo25 = 1 << 25 + matcher := GreaterOrEqual(int64(kTwoTo25 + 1)) + + desc := matcher.Description() + expectedDesc := "greater than or equal to 33554433" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []geTestCase{ + // Signed integers. + geTestCase{-1, false, false, ""}, + geTestCase{kTwoTo25 + 0, false, false, ""}, + geTestCase{kTwoTo25 + 1, true, false, ""}, + geTestCase{kTwoTo25 + 2, true, false, ""}, + + geTestCase{int(-1), false, false, ""}, + geTestCase{int(kTwoTo25 + 0), false, false, ""}, + geTestCase{int(kTwoTo25 + 1), true, false, ""}, + geTestCase{int(kTwoTo25 + 2), true, false, ""}, + + geTestCase{int8(-1), false, false, ""}, + geTestCase{int8(127), false, false, ""}, + + geTestCase{int16(-1), false, false, ""}, + geTestCase{int16(0), false, false, ""}, + geTestCase{int16(32767), false, false, ""}, + + geTestCase{int32(-1), false, false, ""}, + geTestCase{int32(kTwoTo25 + 0), false, false, ""}, + geTestCase{int32(kTwoTo25 + 1), true, false, ""}, + geTestCase{int32(kTwoTo25 + 2), true, false, ""}, + + geTestCase{int64(-1), false, false, ""}, + geTestCase{int64(kTwoTo25 + 0), false, false, ""}, + geTestCase{int64(kTwoTo25 + 1), true, false, ""}, + geTestCase{int64(kTwoTo25 + 2), true, false, ""}, + + // Unsigned integers. + geTestCase{uint(0), false, false, ""}, + geTestCase{uint(kTwoTo25 + 0), false, false, ""}, + geTestCase{uint(kTwoTo25 + 1), true, false, ""}, + geTestCase{uint(kTwoTo25 + 2), true, false, ""}, + + geTestCase{uint8(0), false, false, ""}, + geTestCase{uint8(255), false, false, ""}, + + geTestCase{uint16(0), false, false, ""}, + geTestCase{uint16(65535), false, false, ""}, + + geTestCase{uint32(0), false, false, ""}, + geTestCase{uint32(kTwoTo25 + 0), false, false, ""}, + geTestCase{uint32(kTwoTo25 + 1), true, false, ""}, + geTestCase{uint32(kTwoTo25 + 2), true, false, ""}, + + geTestCase{uint64(0), false, false, ""}, + geTestCase{uint64(kTwoTo25 + 0), false, false, ""}, + geTestCase{uint64(kTwoTo25 + 1), true, false, ""}, + geTestCase{uint64(kTwoTo25 + 2), true, false, ""}, + + geTestCase{uintptr(0), false, false, ""}, + geTestCase{uintptr(kTwoTo25 + 0), false, false, ""}, + geTestCase{uintptr(kTwoTo25 + 1), true, false, ""}, + geTestCase{uintptr(kTwoTo25 + 2), true, false, ""}, + + // Floating point. + geTestCase{float32(-1), false, false, ""}, + geTestCase{float32(kTwoTo25 - 2), false, false, ""}, + geTestCase{float32(kTwoTo25 - 1), true, false, ""}, + geTestCase{float32(kTwoTo25 + 0), true, false, ""}, + geTestCase{float32(kTwoTo25 + 1), true, false, ""}, + geTestCase{float32(kTwoTo25 + 2), true, false, ""}, + geTestCase{float32(kTwoTo25 + 3), true, false, ""}, + + geTestCase{float64(-1), false, false, ""}, + geTestCase{float64(kTwoTo25 - 2), false, false, ""}, + geTestCase{float64(kTwoTo25 - 1), false, false, ""}, + geTestCase{float64(kTwoTo25 + 0), false, false, ""}, + geTestCase{float64(kTwoTo25 + 1), true, false, ""}, + geTestCase{float64(kTwoTo25 + 2), true, false, ""}, + geTestCase{float64(kTwoTo25 + 3), true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterOrEqualTest) Int64NotExactlyRepresentableByDoublePrecision() { + // Double-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^54-1, 2^54+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo54 = 1 << 54 + matcher := GreaterOrEqual(int64(kTwoTo54 + 1)) + + desc := matcher.Description() + expectedDesc := "greater than or equal to 18014398509481985" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []geTestCase{ + // Signed integers. + geTestCase{-1, false, false, ""}, + geTestCase{1 << 30, false, false, ""}, + + geTestCase{int(-1), false, false, ""}, + geTestCase{int(math.MaxInt32), false, false, ""}, + + geTestCase{int8(-1), false, false, ""}, + geTestCase{int8(127), false, false, ""}, + + geTestCase{int16(-1), false, false, ""}, + geTestCase{int16(0), false, false, ""}, + geTestCase{int16(32767), false, false, ""}, + + geTestCase{int32(-1), false, false, ""}, + geTestCase{int32(math.MaxInt32), false, false, ""}, + + geTestCase{int64(-1), false, false, ""}, + geTestCase{int64(kTwoTo54 - 1), false, false, ""}, + geTestCase{int64(kTwoTo54 + 0), false, false, ""}, + geTestCase{int64(kTwoTo54 + 1), true, false, ""}, + geTestCase{int64(kTwoTo54 + 2), true, false, ""}, + + // Unsigned integers. + geTestCase{uint(0), false, false, ""}, + geTestCase{uint(math.MaxUint32), false, false, ""}, + + geTestCase{uint8(0), false, false, ""}, + geTestCase{uint8(255), false, false, ""}, + + geTestCase{uint16(0), false, false, ""}, + geTestCase{uint16(65535), false, false, ""}, + + geTestCase{uint32(0), false, false, ""}, + geTestCase{uint32(math.MaxUint32), false, false, ""}, + + geTestCase{uint64(0), false, false, ""}, + geTestCase{uint64(kTwoTo54 - 1), false, false, ""}, + geTestCase{uint64(kTwoTo54 + 0), false, false, ""}, + geTestCase{uint64(kTwoTo54 + 1), true, false, ""}, + geTestCase{uint64(kTwoTo54 + 2), true, false, ""}, + + geTestCase{uintptr(0), false, false, ""}, + geTestCase{uintptr(kTwoTo54 - 1), false, false, ""}, + geTestCase{uintptr(kTwoTo54 + 0), false, false, ""}, + geTestCase{uintptr(kTwoTo54 + 1), true, false, ""}, + geTestCase{uintptr(kTwoTo54 + 2), true, false, ""}, + + // Floating point. + geTestCase{float64(-1), false, false, ""}, + geTestCase{float64(kTwoTo54 - 2), false, false, ""}, + geTestCase{float64(kTwoTo54 - 1), true, false, ""}, + geTestCase{float64(kTwoTo54 + 0), true, false, ""}, + geTestCase{float64(kTwoTo54 + 1), true, false, ""}, + geTestCase{float64(kTwoTo54 + 2), true, false, ""}, + geTestCase{float64(kTwoTo54 + 3), true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterOrEqualTest) Uint64NotExactlyRepresentableBySinglePrecision() { + // Single-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo25 = 1 << 25 + matcher := GreaterOrEqual(uint64(kTwoTo25 + 1)) + + desc := matcher.Description() + expectedDesc := "greater than or equal to 33554433" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []geTestCase{ + // Signed integers. + geTestCase{-1, false, false, ""}, + geTestCase{kTwoTo25 + 0, false, false, ""}, + geTestCase{kTwoTo25 + 1, true, false, ""}, + geTestCase{kTwoTo25 + 2, true, false, ""}, + + geTestCase{int(-1), false, false, ""}, + geTestCase{int(kTwoTo25 + 0), false, false, ""}, + geTestCase{int(kTwoTo25 + 1), true, false, ""}, + geTestCase{int(kTwoTo25 + 2), true, false, ""}, + + geTestCase{int8(-1), false, false, ""}, + geTestCase{int8(127), false, false, ""}, + + geTestCase{int16(-1), false, false, ""}, + geTestCase{int16(0), false, false, ""}, + geTestCase{int16(32767), false, false, ""}, + + geTestCase{int32(-1), false, false, ""}, + geTestCase{int32(kTwoTo25 + 0), false, false, ""}, + geTestCase{int32(kTwoTo25 + 1), true, false, ""}, + geTestCase{int32(kTwoTo25 + 2), true, false, ""}, + + geTestCase{int64(-1), false, false, ""}, + geTestCase{int64(kTwoTo25 + 0), false, false, ""}, + geTestCase{int64(kTwoTo25 + 1), true, false, ""}, + geTestCase{int64(kTwoTo25 + 2), true, false, ""}, + + // Unsigned integers. + geTestCase{uint(0), false, false, ""}, + geTestCase{uint(kTwoTo25 + 0), false, false, ""}, + geTestCase{uint(kTwoTo25 + 1), true, false, ""}, + geTestCase{uint(kTwoTo25 + 2), true, false, ""}, + + geTestCase{uint8(0), false, false, ""}, + geTestCase{uint8(255), false, false, ""}, + + geTestCase{uint16(0), false, false, ""}, + geTestCase{uint16(65535), false, false, ""}, + + geTestCase{uint32(0), false, false, ""}, + geTestCase{uint32(kTwoTo25 + 0), false, false, ""}, + geTestCase{uint32(kTwoTo25 + 1), true, false, ""}, + geTestCase{uint32(kTwoTo25 + 2), true, false, ""}, + + geTestCase{uint64(0), false, false, ""}, + geTestCase{uint64(kTwoTo25 + 0), false, false, ""}, + geTestCase{uint64(kTwoTo25 + 1), true, false, ""}, + geTestCase{uint64(kTwoTo25 + 2), true, false, ""}, + + geTestCase{uintptr(0), false, false, ""}, + geTestCase{uintptr(kTwoTo25 + 0), false, false, ""}, + geTestCase{uintptr(kTwoTo25 + 1), true, false, ""}, + geTestCase{uintptr(kTwoTo25 + 2), true, false, ""}, + + // Floating point. + geTestCase{float32(-1), false, false, ""}, + geTestCase{float32(kTwoTo25 - 2), false, false, ""}, + geTestCase{float32(kTwoTo25 - 1), true, false, ""}, + geTestCase{float32(kTwoTo25 + 0), true, false, ""}, + geTestCase{float32(kTwoTo25 + 1), true, false, ""}, + geTestCase{float32(kTwoTo25 + 2), true, false, ""}, + geTestCase{float32(kTwoTo25 + 3), true, false, ""}, + + geTestCase{float64(-1), false, false, ""}, + geTestCase{float64(kTwoTo25 - 2), false, false, ""}, + geTestCase{float64(kTwoTo25 - 1), false, false, ""}, + geTestCase{float64(kTwoTo25 + 0), false, false, ""}, + geTestCase{float64(kTwoTo25 + 1), true, false, ""}, + geTestCase{float64(kTwoTo25 + 2), true, false, ""}, + geTestCase{float64(kTwoTo25 + 3), true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterOrEqualTest) Uint64NotExactlyRepresentableByDoublePrecision() { + // Double-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^54-1, 2^54+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo54 = 1 << 54 + matcher := GreaterOrEqual(uint64(kTwoTo54 + 1)) + + desc := matcher.Description() + expectedDesc := "greater than or equal to 18014398509481985" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []geTestCase{ + // Signed integers. + geTestCase{-1, false, false, ""}, + geTestCase{1 << 30, false, false, ""}, + + geTestCase{int(-1), false, false, ""}, + geTestCase{int(math.MaxInt32), false, false, ""}, + + geTestCase{int8(-1), false, false, ""}, + geTestCase{int8(127), false, false, ""}, + + geTestCase{int16(-1), false, false, ""}, + geTestCase{int16(0), false, false, ""}, + geTestCase{int16(32767), false, false, ""}, + + geTestCase{int32(-1), false, false, ""}, + geTestCase{int32(math.MaxInt32), false, false, ""}, + + geTestCase{int64(-1), false, false, ""}, + geTestCase{int64(kTwoTo54 - 1), false, false, ""}, + geTestCase{int64(kTwoTo54 + 0), false, false, ""}, + geTestCase{int64(kTwoTo54 + 1), true, false, ""}, + geTestCase{int64(kTwoTo54 + 2), true, false, ""}, + + // Unsigned integers. + geTestCase{uint(0), false, false, ""}, + geTestCase{uint(math.MaxUint32), false, false, ""}, + + geTestCase{uint8(0), false, false, ""}, + geTestCase{uint8(255), false, false, ""}, + + geTestCase{uint16(0), false, false, ""}, + geTestCase{uint16(65535), false, false, ""}, + + geTestCase{uint32(0), false, false, ""}, + geTestCase{uint32(math.MaxUint32), false, false, ""}, + + geTestCase{uint64(0), false, false, ""}, + geTestCase{uint64(kTwoTo54 - 1), false, false, ""}, + geTestCase{uint64(kTwoTo54 + 0), false, false, ""}, + geTestCase{uint64(kTwoTo54 + 1), true, false, ""}, + geTestCase{uint64(kTwoTo54 + 2), true, false, ""}, + + geTestCase{uintptr(0), false, false, ""}, + geTestCase{uintptr(kTwoTo54 - 1), false, false, ""}, + geTestCase{uintptr(kTwoTo54 + 0), false, false, ""}, + geTestCase{uintptr(kTwoTo54 + 1), true, false, ""}, + geTestCase{uintptr(kTwoTo54 + 2), true, false, ""}, + + // Floating point. + geTestCase{float64(-1), false, false, ""}, + geTestCase{float64(kTwoTo54 - 2), false, false, ""}, + geTestCase{float64(kTwoTo54 - 1), true, false, ""}, + geTestCase{float64(kTwoTo54 + 0), true, false, ""}, + geTestCase{float64(kTwoTo54 + 1), true, false, ""}, + geTestCase{float64(kTwoTo54 + 2), true, false, ""}, + geTestCase{float64(kTwoTo54 + 3), true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterOrEqualTest) Float32AboveExactIntegerRange() { + // Single-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo25 = 1 << 25 + matcher := GreaterOrEqual(float32(kTwoTo25 + 1)) + + desc := matcher.Description() + expectedDesc := "greater than or equal to 3.3554432e+07" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []geTestCase{ + // Signed integers. + geTestCase{int64(-1), false, false, ""}, + geTestCase{int64(kTwoTo25 - 2), false, false, ""}, + geTestCase{int64(kTwoTo25 - 1), true, false, ""}, + geTestCase{int64(kTwoTo25 + 0), true, false, ""}, + geTestCase{int64(kTwoTo25 + 1), true, false, ""}, + geTestCase{int64(kTwoTo25 + 2), true, false, ""}, + geTestCase{int64(kTwoTo25 + 3), true, false, ""}, + + // Unsigned integers. + geTestCase{uint64(0), false, false, ""}, + geTestCase{uint64(kTwoTo25 - 2), false, false, ""}, + geTestCase{uint64(kTwoTo25 - 1), true, false, ""}, + geTestCase{uint64(kTwoTo25 + 0), true, false, ""}, + geTestCase{uint64(kTwoTo25 + 1), true, false, ""}, + geTestCase{uint64(kTwoTo25 + 2), true, false, ""}, + geTestCase{uint64(kTwoTo25 + 3), true, false, ""}, + + // Floating point. + geTestCase{float32(-1), false, false, ""}, + geTestCase{float32(kTwoTo25 - 2), false, false, ""}, + geTestCase{float32(kTwoTo25 - 1), true, false, ""}, + geTestCase{float32(kTwoTo25 + 0), true, false, ""}, + geTestCase{float32(kTwoTo25 + 1), true, false, ""}, + geTestCase{float32(kTwoTo25 + 2), true, false, ""}, + geTestCase{float32(kTwoTo25 + 3), true, false, ""}, + + geTestCase{float64(-1), false, false, ""}, + geTestCase{float64(kTwoTo25 - 2), false, false, ""}, + geTestCase{float64(kTwoTo25 - 1), true, false, ""}, + geTestCase{float64(kTwoTo25 + 0), true, false, ""}, + geTestCase{float64(kTwoTo25 + 1), true, false, ""}, + geTestCase{float64(kTwoTo25 + 2), true, false, ""}, + geTestCase{float64(kTwoTo25 + 3), true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterOrEqualTest) Float64AboveExactIntegerRange() { + // Double-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^54-1, 2^54+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo54 = 1 << 54 + matcher := GreaterOrEqual(float64(kTwoTo54 + 1)) + + desc := matcher.Description() + expectedDesc := "greater than or equal to 1.8014398509481984e+16" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []geTestCase{ + // Signed integers. + geTestCase{int64(-1), false, false, ""}, + geTestCase{int64(kTwoTo54 - 2), false, false, ""}, + geTestCase{int64(kTwoTo54 - 1), true, false, ""}, + geTestCase{int64(kTwoTo54 + 0), true, false, ""}, + geTestCase{int64(kTwoTo54 + 1), true, false, ""}, + geTestCase{int64(kTwoTo54 + 2), true, false, ""}, + geTestCase{int64(kTwoTo54 + 3), true, false, ""}, + + // Unsigned integers. + geTestCase{uint64(0), false, false, ""}, + geTestCase{uint64(kTwoTo54 - 2), false, false, ""}, + geTestCase{uint64(kTwoTo54 - 1), true, false, ""}, + geTestCase{uint64(kTwoTo54 + 0), true, false, ""}, + geTestCase{uint64(kTwoTo54 + 1), true, false, ""}, + geTestCase{uint64(kTwoTo54 + 2), true, false, ""}, + geTestCase{uint64(kTwoTo54 + 3), true, false, ""}, + + // Floating point. + geTestCase{float64(-1), false, false, ""}, + geTestCase{float64(kTwoTo54 - 2), false, false, ""}, + geTestCase{float64(kTwoTo54 - 1), true, false, ""}, + geTestCase{float64(kTwoTo54 + 0), true, false, ""}, + geTestCase{float64(kTwoTo54 + 1), true, false, ""}, + geTestCase{float64(kTwoTo54 + 2), true, false, ""}, + geTestCase{float64(kTwoTo54 + 3), true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// String literals +//////////////////////////////////////////////////////////////////////// + +func (t *GreaterOrEqualTest) EmptyString() { + matcher := GreaterOrEqual("") + desc := matcher.Description() + expectedDesc := "greater than or equal to \"\"" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []geTestCase{ + geTestCase{"", true, false, ""}, + geTestCase{"\x00", true, false, ""}, + geTestCase{"a", true, false, ""}, + geTestCase{"foo", true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterOrEqualTest) SingleNullByte() { + matcher := GreaterOrEqual("\x00") + desc := matcher.Description() + expectedDesc := "greater than or equal to \"\x00\"" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []geTestCase{ + geTestCase{"", false, false, ""}, + geTestCase{"\x00", true, false, ""}, + geTestCase{"a", true, false, ""}, + geTestCase{"foo", true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterOrEqualTest) LongerString() { + matcher := GreaterOrEqual("foo\x00") + desc := matcher.Description() + expectedDesc := "greater than or equal to \"foo\x00\"" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []geTestCase{ + geTestCase{"", false, false, ""}, + geTestCase{"\x00", false, false, ""}, + geTestCase{"bar", false, false, ""}, + geTestCase{"foo", false, false, ""}, + geTestCase{"foo\x00", true, false, ""}, + geTestCase{"fooa", true, false, ""}, + geTestCase{"qux", true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/greater_than.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/greater_than.go new file mode 100644 index 00000000000..3eef32178f8 --- /dev/null +++ b/src/mongo/gotools/vendor/src/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/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/greater_than_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/greater_than_test.go new file mode 100644 index 00000000000..bf70fe56633 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/greater_than_test.go @@ -0,0 +1,1077 @@ +// 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_test + +import ( + "math" + + . "github.com/smartystreets/assertions/internal/oglematchers" + . "github.com/smartystreets/assertions/internal/ogletest" +) + +//////////////////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////////////////// + +type GreaterThanTest struct { +} + +func init() { RegisterTestSuite(&GreaterThanTest{}) } + +type gtTestCase struct { + candidate interface{} + expectedResult bool + shouldBeFatal bool + expectedError string +} + +func (t *GreaterThanTest) checkTestCases(matcher Matcher, cases []gtTestCase) { + for i, c := range cases { + err := matcher.Matches(c.candidate) + + ExpectThat( + (err == nil), + Equals(c.expectedResult), + "Case %d (candidate %v)", + i, + c.candidate) + + if err == nil { + continue + } + + _, isFatal := err.(*FatalError) + ExpectEq( + c.shouldBeFatal, + isFatal, + "Case %d (candidate %v)", + i, + c.candidate) + + ExpectThat( + err, + Error(Equals(c.expectedError)), + "Case %d (candidate %v)", + i, + c.candidate) + } +} + +//////////////////////////////////////////////////////////////////////// +// Integer literals +//////////////////////////////////////////////////////////////////////// + +func (t *GreaterThanTest) IntegerCandidateBadTypes() { + matcher := GreaterThan(int(-150)) + + cases := []gtTestCase{ + gtTestCase{true, false, true, "which is not comparable"}, + gtTestCase{complex64(-151), false, true, "which is not comparable"}, + gtTestCase{complex128(-151), false, true, "which is not comparable"}, + gtTestCase{[...]int{-151}, false, true, "which is not comparable"}, + gtTestCase{make(chan int), false, true, "which is not comparable"}, + gtTestCase{func() {}, false, true, "which is not comparable"}, + gtTestCase{map[int]int{}, false, true, "which is not comparable"}, + gtTestCase{>TestCase{}, false, true, "which is not comparable"}, + gtTestCase{make([]int, 0), false, true, "which is not comparable"}, + gtTestCase{"-151", false, true, "which is not comparable"}, + gtTestCase{gtTestCase{}, false, true, "which is not comparable"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterThanTest) FloatCandidateBadTypes() { + matcher := GreaterThan(float32(-150)) + + cases := []gtTestCase{ + gtTestCase{true, false, true, "which is not comparable"}, + gtTestCase{complex64(-151), false, true, "which is not comparable"}, + gtTestCase{complex128(-151), false, true, "which is not comparable"}, + gtTestCase{[...]int{-151}, false, true, "which is not comparable"}, + gtTestCase{make(chan int), false, true, "which is not comparable"}, + gtTestCase{func() {}, false, true, "which is not comparable"}, + gtTestCase{map[int]int{}, false, true, "which is not comparable"}, + gtTestCase{>TestCase{}, false, true, "which is not comparable"}, + gtTestCase{make([]int, 0), false, true, "which is not comparable"}, + gtTestCase{"-151", false, true, "which is not comparable"}, + gtTestCase{gtTestCase{}, false, true, "which is not comparable"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterThanTest) StringCandidateBadTypes() { + matcher := GreaterThan("17") + + cases := []gtTestCase{ + gtTestCase{true, false, true, "which is not comparable"}, + gtTestCase{int(0), false, true, "which is not comparable"}, + gtTestCase{int8(0), false, true, "which is not comparable"}, + gtTestCase{int16(0), false, true, "which is not comparable"}, + gtTestCase{int32(0), false, true, "which is not comparable"}, + gtTestCase{int64(0), false, true, "which is not comparable"}, + gtTestCase{uint(0), false, true, "which is not comparable"}, + gtTestCase{uint8(0), false, true, "which is not comparable"}, + gtTestCase{uint16(0), false, true, "which is not comparable"}, + gtTestCase{uint32(0), false, true, "which is not comparable"}, + gtTestCase{uint64(0), false, true, "which is not comparable"}, + gtTestCase{float32(0), false, true, "which is not comparable"}, + gtTestCase{float64(0), false, true, "which is not comparable"}, + gtTestCase{complex64(-151), false, true, "which is not comparable"}, + gtTestCase{complex128(-151), false, true, "which is not comparable"}, + gtTestCase{[...]int{-151}, false, true, "which is not comparable"}, + gtTestCase{make(chan int), false, true, "which is not comparable"}, + gtTestCase{func() {}, false, true, "which is not comparable"}, + gtTestCase{map[int]int{}, false, true, "which is not comparable"}, + gtTestCase{>TestCase{}, false, true, "which is not comparable"}, + gtTestCase{make([]int, 0), false, true, "which is not comparable"}, + gtTestCase{gtTestCase{}, false, true, "which is not comparable"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterThanTest) BadArgument() { + panicked := false + + defer func() { + ExpectThat(panicked, Equals(true)) + }() + + defer func() { + if r := recover(); r != nil { + panicked = true + } + }() + + GreaterThan(complex128(0)) +} + +//////////////////////////////////////////////////////////////////////// +// Integer literals +//////////////////////////////////////////////////////////////////////// + +func (t *GreaterThanTest) NegativeIntegerLiteral() { + matcher := GreaterThan(-150) + desc := matcher.Description() + expectedDesc := "greater than -150" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []gtTestCase{ + // Signed integers. + gtTestCase{-(1 << 30), false, false, ""}, + gtTestCase{-151, false, false, ""}, + gtTestCase{-150, false, false, ""}, + gtTestCase{-149, true, false, ""}, + gtTestCase{0, true, false, ""}, + gtTestCase{17, true, false, ""}, + + gtTestCase{int(-(1 << 30)), false, false, ""}, + gtTestCase{int(-151), false, false, ""}, + gtTestCase{int(-150), false, false, ""}, + gtTestCase{int(-149), true, false, ""}, + gtTestCase{int(0), true, false, ""}, + gtTestCase{int(17), true, false, ""}, + + gtTestCase{int8(-127), true, false, ""}, + gtTestCase{int8(0), true, false, ""}, + gtTestCase{int8(17), true, false, ""}, + + gtTestCase{int16(-(1 << 14)), false, false, ""}, + gtTestCase{int16(-151), false, false, ""}, + gtTestCase{int16(-150), false, false, ""}, + gtTestCase{int16(-149), true, false, ""}, + gtTestCase{int16(0), true, false, ""}, + gtTestCase{int16(17), true, false, ""}, + + gtTestCase{int32(-(1 << 30)), false, false, ""}, + gtTestCase{int32(-151), false, false, ""}, + gtTestCase{int32(-150), false, false, ""}, + gtTestCase{int32(-149), true, false, ""}, + gtTestCase{int32(0), true, false, ""}, + gtTestCase{int32(17), true, false, ""}, + + gtTestCase{int64(-(1 << 30)), false, false, ""}, + gtTestCase{int64(-151), false, false, ""}, + gtTestCase{int64(-150), false, false, ""}, + gtTestCase{int64(-149), true, false, ""}, + gtTestCase{int64(0), true, false, ""}, + gtTestCase{int64(17), true, false, ""}, + + // Unsigned integers. + gtTestCase{uint((1 << 32) - 151), true, false, ""}, + gtTestCase{uint(0), true, false, ""}, + gtTestCase{uint(17), true, false, ""}, + + gtTestCase{uint8(0), true, false, ""}, + gtTestCase{uint8(17), true, false, ""}, + gtTestCase{uint8(253), true, false, ""}, + + gtTestCase{uint16((1 << 16) - 151), true, false, ""}, + gtTestCase{uint16(0), true, false, ""}, + gtTestCase{uint16(17), true, false, ""}, + + gtTestCase{uint32((1 << 32) - 151), true, false, ""}, + gtTestCase{uint32(0), true, false, ""}, + gtTestCase{uint32(17), true, false, ""}, + + gtTestCase{uint64((1 << 64) - 151), true, false, ""}, + gtTestCase{uint64(0), true, false, ""}, + gtTestCase{uint64(17), true, false, ""}, + + // Floating point. + gtTestCase{float32(-(1 << 30)), false, false, ""}, + gtTestCase{float32(-151), false, false, ""}, + gtTestCase{float32(-150.1), false, false, ""}, + gtTestCase{float32(-150), false, false, ""}, + gtTestCase{float32(-149.9), true, false, ""}, + gtTestCase{float32(0), true, false, ""}, + gtTestCase{float32(17), true, false, ""}, + gtTestCase{float32(160), true, false, ""}, + + gtTestCase{float64(-(1 << 30)), false, false, ""}, + gtTestCase{float64(-151), false, false, ""}, + gtTestCase{float64(-150.1), false, false, ""}, + gtTestCase{float64(-150), false, false, ""}, + gtTestCase{float64(-149.9), true, false, ""}, + gtTestCase{float64(0), true, false, ""}, + gtTestCase{float64(17), true, false, ""}, + gtTestCase{float64(160), true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterThanTest) ZeroIntegerLiteral() { + matcher := GreaterThan(0) + desc := matcher.Description() + expectedDesc := "greater than 0" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []gtTestCase{ + // Signed integers. + gtTestCase{-(1 << 30), false, false, ""}, + gtTestCase{-1, false, false, ""}, + gtTestCase{0, false, false, ""}, + gtTestCase{1, true, false, ""}, + gtTestCase{17, true, false, ""}, + gtTestCase{(1 << 30), true, false, ""}, + + gtTestCase{int(-(1 << 30)), false, false, ""}, + gtTestCase{int(-1), false, false, ""}, + gtTestCase{int(0), false, false, ""}, + gtTestCase{int(1), true, false, ""}, + gtTestCase{int(17), true, false, ""}, + + gtTestCase{int8(-1), false, false, ""}, + gtTestCase{int8(0), false, false, ""}, + gtTestCase{int8(1), true, false, ""}, + + gtTestCase{int16(-(1 << 14)), false, false, ""}, + gtTestCase{int16(-1), false, false, ""}, + gtTestCase{int16(0), false, false, ""}, + gtTestCase{int16(1), true, false, ""}, + gtTestCase{int16(17), true, false, ""}, + + gtTestCase{int32(-(1 << 30)), false, false, ""}, + gtTestCase{int32(-1), false, false, ""}, + gtTestCase{int32(0), false, false, ""}, + gtTestCase{int32(1), true, false, ""}, + gtTestCase{int32(17), true, false, ""}, + + gtTestCase{int64(-(1 << 30)), false, false, ""}, + gtTestCase{int64(-1), false, false, ""}, + gtTestCase{int64(0), false, false, ""}, + gtTestCase{int64(1), true, false, ""}, + gtTestCase{int64(17), true, false, ""}, + + // Unsigned integers. + gtTestCase{uint((1 << 32) - 1), true, false, ""}, + gtTestCase{uint(0), false, false, ""}, + gtTestCase{uint(1), true, false, ""}, + gtTestCase{uint(17), true, false, ""}, + + gtTestCase{uint8(0), false, false, ""}, + gtTestCase{uint8(1), true, false, ""}, + gtTestCase{uint8(17), true, false, ""}, + gtTestCase{uint8(253), true, false, ""}, + + gtTestCase{uint16((1 << 16) - 1), true, false, ""}, + gtTestCase{uint16(0), false, false, ""}, + gtTestCase{uint16(1), true, false, ""}, + gtTestCase{uint16(17), true, false, ""}, + + gtTestCase{uint32((1 << 32) - 1), true, false, ""}, + gtTestCase{uint32(0), false, false, ""}, + gtTestCase{uint32(1), true, false, ""}, + gtTestCase{uint32(17), true, false, ""}, + + gtTestCase{uint64((1 << 64) - 1), true, false, ""}, + gtTestCase{uint64(0), false, false, ""}, + gtTestCase{uint64(1), true, false, ""}, + gtTestCase{uint64(17), true, false, ""}, + + // Floating point. + gtTestCase{float32(-(1 << 30)), false, false, ""}, + gtTestCase{float32(-1), false, false, ""}, + gtTestCase{float32(-0.1), false, false, ""}, + gtTestCase{float32(-0.0), false, false, ""}, + gtTestCase{float32(0), false, false, ""}, + gtTestCase{float32(0.1), true, false, ""}, + gtTestCase{float32(17), true, false, ""}, + gtTestCase{float32(160), true, false, ""}, + + gtTestCase{float64(-(1 << 30)), false, false, ""}, + gtTestCase{float64(-1), false, false, ""}, + gtTestCase{float64(-0.1), false, false, ""}, + gtTestCase{float64(-0), false, false, ""}, + gtTestCase{float64(0), false, false, ""}, + gtTestCase{float64(0.1), true, false, ""}, + gtTestCase{float64(17), true, false, ""}, + gtTestCase{float64(160), true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterThanTest) PositiveIntegerLiteral() { + matcher := GreaterThan(150) + desc := matcher.Description() + expectedDesc := "greater than 150" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []gtTestCase{ + // Signed integers. + gtTestCase{-1, false, false, ""}, + gtTestCase{149, false, false, ""}, + gtTestCase{150, false, false, ""}, + gtTestCase{151, true, false, ""}, + + gtTestCase{int(-1), false, false, ""}, + gtTestCase{int(149), false, false, ""}, + gtTestCase{int(150), false, false, ""}, + gtTestCase{int(151), true, false, ""}, + + gtTestCase{int8(-1), false, false, ""}, + gtTestCase{int8(0), false, false, ""}, + gtTestCase{int8(17), false, false, ""}, + gtTestCase{int8(127), false, false, ""}, + + gtTestCase{int16(-1), false, false, ""}, + gtTestCase{int16(149), false, false, ""}, + gtTestCase{int16(150), false, false, ""}, + gtTestCase{int16(151), true, false, ""}, + + gtTestCase{int32(-1), false, false, ""}, + gtTestCase{int32(149), false, false, ""}, + gtTestCase{int32(150), false, false, ""}, + gtTestCase{int32(151), true, false, ""}, + + gtTestCase{int64(-1), false, false, ""}, + gtTestCase{int64(149), false, false, ""}, + gtTestCase{int64(150), false, false, ""}, + gtTestCase{int64(151), true, false, ""}, + + // Unsigned integers. + gtTestCase{uint(0), false, false, ""}, + gtTestCase{uint(149), false, false, ""}, + gtTestCase{uint(150), false, false, ""}, + gtTestCase{uint(151), true, false, ""}, + + gtTestCase{uint8(0), false, false, ""}, + gtTestCase{uint8(127), false, false, ""}, + + gtTestCase{uint16(0), false, false, ""}, + gtTestCase{uint16(149), false, false, ""}, + gtTestCase{uint16(150), false, false, ""}, + gtTestCase{uint16(151), true, false, ""}, + + gtTestCase{uint32(0), false, false, ""}, + gtTestCase{uint32(149), false, false, ""}, + gtTestCase{uint32(150), false, false, ""}, + gtTestCase{uint32(151), true, false, ""}, + + gtTestCase{uint64(0), false, false, ""}, + gtTestCase{uint64(149), false, false, ""}, + gtTestCase{uint64(150), false, false, ""}, + gtTestCase{uint64(151), true, false, ""}, + + // Floating point. + gtTestCase{float32(-1), false, false, ""}, + gtTestCase{float32(149), false, false, ""}, + gtTestCase{float32(149.9), false, false, ""}, + gtTestCase{float32(150), false, false, ""}, + gtTestCase{float32(150.1), true, false, ""}, + gtTestCase{float32(151), true, false, ""}, + + gtTestCase{float64(-1), false, false, ""}, + gtTestCase{float64(149), false, false, ""}, + gtTestCase{float64(149.9), false, false, ""}, + gtTestCase{float64(150), false, false, ""}, + gtTestCase{float64(150.1), true, false, ""}, + gtTestCase{float64(151), true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// Float literals +//////////////////////////////////////////////////////////////////////// + +func (t *GreaterThanTest) NegativeFloatLiteral() { + matcher := GreaterThan(-150.1) + desc := matcher.Description() + expectedDesc := "greater than -150.1" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []gtTestCase{ + // Signed integers. + gtTestCase{-(1 << 30), false, false, ""}, + gtTestCase{-151, false, false, ""}, + gtTestCase{-150.1, false, false, ""}, + gtTestCase{-150, true, false, ""}, + gtTestCase{-149, true, false, ""}, + gtTestCase{0, true, false, ""}, + gtTestCase{17, true, false, ""}, + + gtTestCase{int(-(1 << 30)), false, false, ""}, + gtTestCase{int(-151), false, false, ""}, + gtTestCase{int(-150), true, false, ""}, + gtTestCase{int(-149), true, false, ""}, + gtTestCase{int(0), true, false, ""}, + gtTestCase{int(17), true, false, ""}, + + gtTestCase{int8(-127), true, false, ""}, + gtTestCase{int8(0), true, false, ""}, + gtTestCase{int8(17), true, false, ""}, + + gtTestCase{int16(-(1 << 14)), false, false, ""}, + gtTestCase{int16(-151), false, false, ""}, + gtTestCase{int16(-150), true, false, ""}, + gtTestCase{int16(-149), true, false, ""}, + gtTestCase{int16(0), true, false, ""}, + gtTestCase{int16(17), true, false, ""}, + + gtTestCase{int32(-(1 << 30)), false, false, ""}, + gtTestCase{int32(-151), false, false, ""}, + gtTestCase{int32(-150), true, false, ""}, + gtTestCase{int32(-149), true, false, ""}, + gtTestCase{int32(0), true, false, ""}, + gtTestCase{int32(17), true, false, ""}, + + gtTestCase{int64(-(1 << 30)), false, false, ""}, + gtTestCase{int64(-151), false, false, ""}, + gtTestCase{int64(-150), true, false, ""}, + gtTestCase{int64(-149), true, false, ""}, + gtTestCase{int64(0), true, false, ""}, + gtTestCase{int64(17), true, false, ""}, + + // Unsigned integers. + gtTestCase{uint((1 << 32) - 151), true, false, ""}, + gtTestCase{uint(0), true, false, ""}, + gtTestCase{uint(17), true, false, ""}, + + gtTestCase{uint8(0), true, false, ""}, + gtTestCase{uint8(17), true, false, ""}, + gtTestCase{uint8(253), true, false, ""}, + + gtTestCase{uint16((1 << 16) - 151), true, false, ""}, + gtTestCase{uint16(0), true, false, ""}, + gtTestCase{uint16(17), true, false, ""}, + + gtTestCase{uint32((1 << 32) - 151), true, false, ""}, + gtTestCase{uint32(0), true, false, ""}, + gtTestCase{uint32(17), true, false, ""}, + + gtTestCase{uint64((1 << 64) - 151), true, false, ""}, + gtTestCase{uint64(0), true, false, ""}, + gtTestCase{uint64(17), true, false, ""}, + + // Floating point. + gtTestCase{float32(-(1 << 30)), false, false, ""}, + gtTestCase{float32(-151), false, false, ""}, + gtTestCase{float32(-150.2), false, false, ""}, + gtTestCase{float32(-150.1), false, false, ""}, + gtTestCase{float32(-150), true, false, ""}, + gtTestCase{float32(0), true, false, ""}, + gtTestCase{float32(17), true, false, ""}, + gtTestCase{float32(160), true, false, ""}, + + gtTestCase{float64(-(1 << 30)), false, false, ""}, + gtTestCase{float64(-151), false, false, ""}, + gtTestCase{float64(-150.2), false, false, ""}, + gtTestCase{float64(-150.1), false, false, ""}, + gtTestCase{float64(-150), true, false, ""}, + gtTestCase{float64(0), true, false, ""}, + gtTestCase{float64(17), true, false, ""}, + gtTestCase{float64(160), true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterThanTest) PositiveFloatLiteral() { + matcher := GreaterThan(149.9) + desc := matcher.Description() + expectedDesc := "greater than 149.9" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []gtTestCase{ + // Signed integers. + gtTestCase{-1, false, false, ""}, + gtTestCase{149, false, false, ""}, + gtTestCase{149.9, false, false, ""}, + gtTestCase{150, true, false, ""}, + gtTestCase{151, true, false, ""}, + + gtTestCase{int(-1), false, false, ""}, + gtTestCase{int(149), false, false, ""}, + gtTestCase{int(150), true, false, ""}, + gtTestCase{int(151), true, false, ""}, + + gtTestCase{int8(-1), false, false, ""}, + gtTestCase{int8(0), false, false, ""}, + gtTestCase{int8(17), false, false, ""}, + gtTestCase{int8(127), false, false, ""}, + + gtTestCase{int16(-1), false, false, ""}, + gtTestCase{int16(149), false, false, ""}, + gtTestCase{int16(150), true, false, ""}, + gtTestCase{int16(151), true, false, ""}, + + gtTestCase{int32(-1), false, false, ""}, + gtTestCase{int32(149), false, false, ""}, + gtTestCase{int32(150), true, false, ""}, + gtTestCase{int32(151), true, false, ""}, + + gtTestCase{int64(-1), false, false, ""}, + gtTestCase{int64(149), false, false, ""}, + gtTestCase{int64(150), true, false, ""}, + gtTestCase{int64(151), true, false, ""}, + + // Unsigned integers. + gtTestCase{uint(0), false, false, ""}, + gtTestCase{uint(149), false, false, ""}, + gtTestCase{uint(150), true, false, ""}, + gtTestCase{uint(151), true, false, ""}, + + gtTestCase{uint8(0), false, false, ""}, + gtTestCase{uint8(127), false, false, ""}, + + gtTestCase{uint16(0), false, false, ""}, + gtTestCase{uint16(149), false, false, ""}, + gtTestCase{uint16(150), true, false, ""}, + gtTestCase{uint16(151), true, false, ""}, + + gtTestCase{uint32(0), false, false, ""}, + gtTestCase{uint32(149), false, false, ""}, + gtTestCase{uint32(150), true, false, ""}, + gtTestCase{uint32(151), true, false, ""}, + + gtTestCase{uint64(0), false, false, ""}, + gtTestCase{uint64(149), false, false, ""}, + gtTestCase{uint64(150), true, false, ""}, + gtTestCase{uint64(151), true, false, ""}, + + // Floating point. + gtTestCase{float32(-1), false, false, ""}, + gtTestCase{float32(149), false, false, ""}, + gtTestCase{float32(149.8), false, false, ""}, + gtTestCase{float32(149.9), false, false, ""}, + gtTestCase{float32(150), true, false, ""}, + gtTestCase{float32(151), true, false, ""}, + + gtTestCase{float64(-1), false, false, ""}, + gtTestCase{float64(149), false, false, ""}, + gtTestCase{float64(149.8), false, false, ""}, + gtTestCase{float64(149.9), false, false, ""}, + gtTestCase{float64(150), true, false, ""}, + gtTestCase{float64(151), true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// Subtle cases +//////////////////////////////////////////////////////////////////////// + +func (t *GreaterThanTest) Int64NotExactlyRepresentableBySinglePrecision() { + // Single-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo25 = 1 << 25 + matcher := GreaterThan(int64(kTwoTo25 + 1)) + + desc := matcher.Description() + expectedDesc := "greater than 33554433" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []gtTestCase{ + // Signed integers. + gtTestCase{-1, false, false, ""}, + gtTestCase{kTwoTo25 + 0, false, false, ""}, + gtTestCase{kTwoTo25 + 1, false, false, ""}, + gtTestCase{kTwoTo25 + 2, true, false, ""}, + + gtTestCase{int(-1), false, false, ""}, + gtTestCase{int(kTwoTo25 + 0), false, false, ""}, + gtTestCase{int(kTwoTo25 + 1), false, false, ""}, + gtTestCase{int(kTwoTo25 + 2), true, false, ""}, + + gtTestCase{int8(-1), false, false, ""}, + gtTestCase{int8(127), false, false, ""}, + + gtTestCase{int16(-1), false, false, ""}, + gtTestCase{int16(0), false, false, ""}, + gtTestCase{int16(32767), false, false, ""}, + + gtTestCase{int32(-1), false, false, ""}, + gtTestCase{int32(kTwoTo25 + 0), false, false, ""}, + gtTestCase{int32(kTwoTo25 + 1), false, false, ""}, + gtTestCase{int32(kTwoTo25 + 2), true, false, ""}, + + gtTestCase{int64(-1), false, false, ""}, + gtTestCase{int64(kTwoTo25 + 0), false, false, ""}, + gtTestCase{int64(kTwoTo25 + 1), false, false, ""}, + gtTestCase{int64(kTwoTo25 + 2), true, false, ""}, + + // Unsigned integers. + gtTestCase{uint(0), false, false, ""}, + gtTestCase{uint(kTwoTo25 + 0), false, false, ""}, + gtTestCase{uint(kTwoTo25 + 1), false, false, ""}, + gtTestCase{uint(kTwoTo25 + 2), true, false, ""}, + + gtTestCase{uint8(0), false, false, ""}, + gtTestCase{uint8(255), false, false, ""}, + + gtTestCase{uint16(0), false, false, ""}, + gtTestCase{uint16(65535), false, false, ""}, + + gtTestCase{uint32(0), false, false, ""}, + gtTestCase{uint32(kTwoTo25 + 0), false, false, ""}, + gtTestCase{uint32(kTwoTo25 + 1), false, false, ""}, + gtTestCase{uint32(kTwoTo25 + 2), true, false, ""}, + + gtTestCase{uint64(0), false, false, ""}, + gtTestCase{uint64(kTwoTo25 + 0), false, false, ""}, + gtTestCase{uint64(kTwoTo25 + 1), false, false, ""}, + gtTestCase{uint64(kTwoTo25 + 2), true, false, ""}, + + // Floating point. + gtTestCase{float32(-1), false, false, ""}, + gtTestCase{float32(kTwoTo25 - 2), false, false, ""}, + gtTestCase{float32(kTwoTo25 - 1), false, false, ""}, + gtTestCase{float32(kTwoTo25 + 0), false, false, ""}, + gtTestCase{float32(kTwoTo25 + 1), false, false, ""}, + gtTestCase{float32(kTwoTo25 + 2), false, false, ""}, + gtTestCase{float32(kTwoTo25 + 3), true, false, ""}, + + gtTestCase{float64(-1), false, false, ""}, + gtTestCase{float64(kTwoTo25 - 2), false, false, ""}, + gtTestCase{float64(kTwoTo25 - 1), false, false, ""}, + gtTestCase{float64(kTwoTo25 + 0), false, false, ""}, + gtTestCase{float64(kTwoTo25 + 1), false, false, ""}, + gtTestCase{float64(kTwoTo25 + 2), true, false, ""}, + gtTestCase{float64(kTwoTo25 + 3), true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterThanTest) Int64NotExactlyRepresentableByDoublePrecision() { + // Double-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^54-1, 2^54+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo54 = 1 << 54 + matcher := GreaterThan(int64(kTwoTo54 + 1)) + + desc := matcher.Description() + expectedDesc := "greater than 18014398509481985" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []gtTestCase{ + // Signed integers. + gtTestCase{-1, false, false, ""}, + gtTestCase{1 << 30, false, false, ""}, + + gtTestCase{int(-1), false, false, ""}, + gtTestCase{int(math.MaxInt32), false, false, ""}, + + gtTestCase{int8(-1), false, false, ""}, + gtTestCase{int8(127), false, false, ""}, + + gtTestCase{int16(-1), false, false, ""}, + gtTestCase{int16(0), false, false, ""}, + gtTestCase{int16(32767), false, false, ""}, + + gtTestCase{int32(-1), false, false, ""}, + gtTestCase{int32(math.MaxInt32), false, false, ""}, + + gtTestCase{int64(-1), false, false, ""}, + gtTestCase{int64(kTwoTo54 - 1), false, false, ""}, + gtTestCase{int64(kTwoTo54 + 0), false, false, ""}, + gtTestCase{int64(kTwoTo54 + 1), false, false, ""}, + gtTestCase{int64(kTwoTo54 + 2), true, false, ""}, + + // Unsigned integers. + gtTestCase{uint(0), false, false, ""}, + gtTestCase{uint(math.MaxUint32), false, false, ""}, + + gtTestCase{uint8(0), false, false, ""}, + gtTestCase{uint8(255), false, false, ""}, + + gtTestCase{uint16(0), false, false, ""}, + gtTestCase{uint16(65535), false, false, ""}, + + gtTestCase{uint32(0), false, false, ""}, + gtTestCase{uint32(math.MaxUint32), false, false, ""}, + + gtTestCase{uint64(0), false, false, ""}, + gtTestCase{uint64(kTwoTo54 - 1), false, false, ""}, + gtTestCase{uint64(kTwoTo54 + 0), false, false, ""}, + gtTestCase{uint64(kTwoTo54 + 1), false, false, ""}, + gtTestCase{uint64(kTwoTo54 + 2), true, false, ""}, + + // Floating point. + gtTestCase{float64(-1), false, false, ""}, + gtTestCase{float64(kTwoTo54 - 2), false, false, ""}, + gtTestCase{float64(kTwoTo54 - 1), false, false, ""}, + gtTestCase{float64(kTwoTo54 + 0), false, false, ""}, + gtTestCase{float64(kTwoTo54 + 1), false, false, ""}, + gtTestCase{float64(kTwoTo54 + 2), false, false, ""}, + gtTestCase{float64(kTwoTo54 + 3), true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterThanTest) Uint64NotExactlyRepresentableBySinglePrecision() { + // Single-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo25 = 1 << 25 + matcher := GreaterThan(uint64(kTwoTo25 + 1)) + + desc := matcher.Description() + expectedDesc := "greater than 33554433" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []gtTestCase{ + // Signed integers. + gtTestCase{-1, false, false, ""}, + gtTestCase{kTwoTo25 + 0, false, false, ""}, + gtTestCase{kTwoTo25 + 1, false, false, ""}, + gtTestCase{kTwoTo25 + 2, true, false, ""}, + + gtTestCase{int(-1), false, false, ""}, + gtTestCase{int(kTwoTo25 + 0), false, false, ""}, + gtTestCase{int(kTwoTo25 + 1), false, false, ""}, + gtTestCase{int(kTwoTo25 + 2), true, false, ""}, + + gtTestCase{int8(-1), false, false, ""}, + gtTestCase{int8(127), false, false, ""}, + + gtTestCase{int16(-1), false, false, ""}, + gtTestCase{int16(0), false, false, ""}, + gtTestCase{int16(32767), false, false, ""}, + + gtTestCase{int32(-1), false, false, ""}, + gtTestCase{int32(kTwoTo25 + 0), false, false, ""}, + gtTestCase{int32(kTwoTo25 + 1), false, false, ""}, + gtTestCase{int32(kTwoTo25 + 2), true, false, ""}, + + gtTestCase{int64(-1), false, false, ""}, + gtTestCase{int64(kTwoTo25 + 0), false, false, ""}, + gtTestCase{int64(kTwoTo25 + 1), false, false, ""}, + gtTestCase{int64(kTwoTo25 + 2), true, false, ""}, + + // Unsigned integers. + gtTestCase{uint(0), false, false, ""}, + gtTestCase{uint(kTwoTo25 + 0), false, false, ""}, + gtTestCase{uint(kTwoTo25 + 1), false, false, ""}, + gtTestCase{uint(kTwoTo25 + 2), true, false, ""}, + + gtTestCase{uint8(0), false, false, ""}, + gtTestCase{uint8(255), false, false, ""}, + + gtTestCase{uint16(0), false, false, ""}, + gtTestCase{uint16(65535), false, false, ""}, + + gtTestCase{uint32(0), false, false, ""}, + gtTestCase{uint32(kTwoTo25 + 0), false, false, ""}, + gtTestCase{uint32(kTwoTo25 + 1), false, false, ""}, + gtTestCase{uint32(kTwoTo25 + 2), true, false, ""}, + + gtTestCase{uint64(0), false, false, ""}, + gtTestCase{uint64(kTwoTo25 + 0), false, false, ""}, + gtTestCase{uint64(kTwoTo25 + 1), false, false, ""}, + gtTestCase{uint64(kTwoTo25 + 2), true, false, ""}, + + // Floating point. + gtTestCase{float32(-1), false, false, ""}, + gtTestCase{float32(kTwoTo25 - 2), false, false, ""}, + gtTestCase{float32(kTwoTo25 - 1), false, false, ""}, + gtTestCase{float32(kTwoTo25 + 0), false, false, ""}, + gtTestCase{float32(kTwoTo25 + 1), false, false, ""}, + gtTestCase{float32(kTwoTo25 + 2), false, false, ""}, + gtTestCase{float32(kTwoTo25 + 3), true, false, ""}, + + gtTestCase{float64(-1), false, false, ""}, + gtTestCase{float64(kTwoTo25 - 2), false, false, ""}, + gtTestCase{float64(kTwoTo25 - 1), false, false, ""}, + gtTestCase{float64(kTwoTo25 + 0), false, false, ""}, + gtTestCase{float64(kTwoTo25 + 1), false, false, ""}, + gtTestCase{float64(kTwoTo25 + 2), true, false, ""}, + gtTestCase{float64(kTwoTo25 + 3), true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterThanTest) Uint64NotExactlyRepresentableByDoublePrecision() { + // Double-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^54-1, 2^54+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo54 = 1 << 54 + matcher := GreaterThan(uint64(kTwoTo54 + 1)) + + desc := matcher.Description() + expectedDesc := "greater than 18014398509481985" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []gtTestCase{ + // Signed integers. + gtTestCase{-1, false, false, ""}, + gtTestCase{1 << 30, false, false, ""}, + + gtTestCase{int(-1), false, false, ""}, + gtTestCase{int(math.MaxInt32), false, false, ""}, + + gtTestCase{int8(-1), false, false, ""}, + gtTestCase{int8(127), false, false, ""}, + + gtTestCase{int16(-1), false, false, ""}, + gtTestCase{int16(0), false, false, ""}, + gtTestCase{int16(32767), false, false, ""}, + + gtTestCase{int32(-1), false, false, ""}, + gtTestCase{int32(math.MaxInt32), false, false, ""}, + + gtTestCase{int64(-1), false, false, ""}, + gtTestCase{int64(kTwoTo54 - 1), false, false, ""}, + gtTestCase{int64(kTwoTo54 + 0), false, false, ""}, + gtTestCase{int64(kTwoTo54 + 1), false, false, ""}, + gtTestCase{int64(kTwoTo54 + 2), true, false, ""}, + + // Unsigned integers. + gtTestCase{uint(0), false, false, ""}, + gtTestCase{uint(math.MaxUint32), false, false, ""}, + + gtTestCase{uint8(0), false, false, ""}, + gtTestCase{uint8(255), false, false, ""}, + + gtTestCase{uint16(0), false, false, ""}, + gtTestCase{uint16(65535), false, false, ""}, + + gtTestCase{uint32(0), false, false, ""}, + gtTestCase{uint32(math.MaxUint32), false, false, ""}, + + gtTestCase{uint64(0), false, false, ""}, + gtTestCase{uint64(kTwoTo54 - 1), false, false, ""}, + gtTestCase{uint64(kTwoTo54 + 0), false, false, ""}, + gtTestCase{uint64(kTwoTo54 + 1), false, false, ""}, + gtTestCase{uint64(kTwoTo54 + 2), true, false, ""}, + + // Floating point. + gtTestCase{float64(-1), false, false, ""}, + gtTestCase{float64(kTwoTo54 - 2), false, false, ""}, + gtTestCase{float64(kTwoTo54 - 1), false, false, ""}, + gtTestCase{float64(kTwoTo54 + 0), false, false, ""}, + gtTestCase{float64(kTwoTo54 + 1), false, false, ""}, + gtTestCase{float64(kTwoTo54 + 2), false, false, ""}, + gtTestCase{float64(kTwoTo54 + 3), true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterThanTest) Float32AboveExactIntegerRange() { + // Single-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo25 = 1 << 25 + matcher := GreaterThan(float32(kTwoTo25 + 1)) + + desc := matcher.Description() + expectedDesc := "greater than 3.3554432e+07" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []gtTestCase{ + // Signed integers. + gtTestCase{int64(-1), false, false, ""}, + gtTestCase{int64(kTwoTo25 - 2), false, false, ""}, + gtTestCase{int64(kTwoTo25 - 1), false, false, ""}, + gtTestCase{int64(kTwoTo25 + 0), false, false, ""}, + gtTestCase{int64(kTwoTo25 + 1), false, false, ""}, + gtTestCase{int64(kTwoTo25 + 2), false, false, ""}, + gtTestCase{int64(kTwoTo25 + 3), true, false, ""}, + + // Unsigned integers. + gtTestCase{uint64(0), false, false, ""}, + gtTestCase{uint64(kTwoTo25 - 2), false, false, ""}, + gtTestCase{uint64(kTwoTo25 - 1), false, false, ""}, + gtTestCase{uint64(kTwoTo25 + 0), false, false, ""}, + gtTestCase{uint64(kTwoTo25 + 1), false, false, ""}, + gtTestCase{uint64(kTwoTo25 + 2), false, false, ""}, + gtTestCase{uint64(kTwoTo25 + 3), true, false, ""}, + + // Floating point. + gtTestCase{float32(-1), false, false, ""}, + gtTestCase{float32(kTwoTo25 - 2), false, false, ""}, + gtTestCase{float32(kTwoTo25 - 1), false, false, ""}, + gtTestCase{float32(kTwoTo25 + 0), false, false, ""}, + gtTestCase{float32(kTwoTo25 + 1), false, false, ""}, + gtTestCase{float32(kTwoTo25 + 2), false, false, ""}, + gtTestCase{float32(kTwoTo25 + 3), true, false, ""}, + + gtTestCase{float64(-1), false, false, ""}, + gtTestCase{float64(kTwoTo25 - 2), false, false, ""}, + gtTestCase{float64(kTwoTo25 - 1), false, false, ""}, + gtTestCase{float64(kTwoTo25 + 0), false, false, ""}, + gtTestCase{float64(kTwoTo25 + 1), false, false, ""}, + gtTestCase{float64(kTwoTo25 + 2), false, false, ""}, + gtTestCase{float64(kTwoTo25 + 3), true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterThanTest) Float64AboveExactIntegerRange() { + // Double-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^54-1, 2^54+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo54 = 1 << 54 + matcher := GreaterThan(float64(kTwoTo54 + 1)) + + desc := matcher.Description() + expectedDesc := "greater than 1.8014398509481984e+16" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []gtTestCase{ + // Signed integers. + gtTestCase{int64(-1), false, false, ""}, + gtTestCase{int64(kTwoTo54 - 2), false, false, ""}, + gtTestCase{int64(kTwoTo54 - 1), false, false, ""}, + gtTestCase{int64(kTwoTo54 + 0), false, false, ""}, + gtTestCase{int64(kTwoTo54 + 1), false, false, ""}, + gtTestCase{int64(kTwoTo54 + 2), false, false, ""}, + gtTestCase{int64(kTwoTo54 + 3), true, false, ""}, + + // Unsigned integers. + gtTestCase{uint64(0), false, false, ""}, + gtTestCase{uint64(kTwoTo54 - 2), false, false, ""}, + gtTestCase{uint64(kTwoTo54 - 1), false, false, ""}, + gtTestCase{uint64(kTwoTo54 + 0), false, false, ""}, + gtTestCase{uint64(kTwoTo54 + 1), false, false, ""}, + gtTestCase{uint64(kTwoTo54 + 2), false, false, ""}, + gtTestCase{uint64(kTwoTo54 + 3), true, false, ""}, + + // Floating point. + gtTestCase{float64(-1), false, false, ""}, + gtTestCase{float64(kTwoTo54 - 2), false, false, ""}, + gtTestCase{float64(kTwoTo54 - 1), false, false, ""}, + gtTestCase{float64(kTwoTo54 + 0), false, false, ""}, + gtTestCase{float64(kTwoTo54 + 1), false, false, ""}, + gtTestCase{float64(kTwoTo54 + 2), false, false, ""}, + gtTestCase{float64(kTwoTo54 + 3), true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// String literals +//////////////////////////////////////////////////////////////////////// + +func (t *GreaterThanTest) EmptyString() { + matcher := GreaterThan("") + desc := matcher.Description() + expectedDesc := "greater than \"\"" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []gtTestCase{ + gtTestCase{"", false, false, ""}, + gtTestCase{"\x00", true, false, ""}, + gtTestCase{"a", true, false, ""}, + gtTestCase{"foo", true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterThanTest) SingleNullByte() { + matcher := GreaterThan("\x00") + desc := matcher.Description() + expectedDesc := "greater than \"\x00\"" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []gtTestCase{ + gtTestCase{"", false, false, ""}, + gtTestCase{"\x00", false, false, ""}, + gtTestCase{"\x00\x00", true, false, ""}, + gtTestCase{"a", true, false, ""}, + gtTestCase{"foo", true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterThanTest) LongerString() { + matcher := GreaterThan("foo\x00") + desc := matcher.Description() + expectedDesc := "greater than \"foo\x00\"" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []gtTestCase{ + gtTestCase{"", false, false, ""}, + gtTestCase{"\x00", false, false, ""}, + gtTestCase{"bar", false, false, ""}, + gtTestCase{"foo", false, false, ""}, + gtTestCase{"foo\x00", false, false, ""}, + gtTestCase{"foo\x00\x00", true, false, ""}, + gtTestCase{"fooa", true, false, ""}, + gtTestCase{"qux", true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/has_same_type_as.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/has_same_type_as.go new file mode 100644 index 00000000000..3b286f73218 --- /dev/null +++ b/src/mongo/gotools/vendor/src/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/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/has_same_type_as_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/has_same_type_as_test.go new file mode 100644 index 00000000000..a4a3e308aa3 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/has_same_type_as_test.go @@ -0,0 +1,181 @@ +// 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_test + +import ( + "io" + "testing" + + . "github.com/smartystreets/assertions/internal/oglematchers" + . "github.com/smartystreets/assertions/internal/ogletest" +) + +func TestHasSameTypeAs(t *testing.T) { RunTests(t) } + +//////////////////////////////////////////////////////////////////////// +// Boilerplate +//////////////////////////////////////////////////////////////////////// + +type HasSameTypeAsTest struct { +} + +func init() { RegisterTestSuite(&HasSameTypeAsTest{}) } + +//////////////////////////////////////////////////////////////////////// +// Tests +//////////////////////////////////////////////////////////////////////// + +func (t *HasSameTypeAsTest) CandidateIsLiteralNil() { + matcher := HasSameTypeAs(nil) + var err error + + // Description + ExpectEq("has type <nil>", matcher.Description()) + + // Literal nil + err = matcher.Matches(nil) + ExpectEq(nil, err) + + // nil in interface variable + var r io.Reader + err = matcher.Matches(r) + ExpectEq(nil, err) + + // int + err = matcher.Matches(17) + AssertNe(nil, err) + ExpectThat(err, Error(Equals("which has type int"))) + + // string + err = matcher.Matches("") + AssertNe(nil, err) + ExpectThat(err, Error(Equals("which has type string"))) + + // nil map + var m map[string]string + err = matcher.Matches(m) + + AssertNe(nil, err) + ExpectThat(err, Error(Equals("which has type map[string]string"))) + + // Non-nil map + m = make(map[string]string) + err = matcher.Matches(m) + + AssertNe(nil, err) + ExpectThat(err, Error(Equals("which has type map[string]string"))) +} + +func (t *HasSameTypeAsTest) CandidateIsNilMap() { + var m map[string]string + matcher := HasSameTypeAs(m) + var err error + + // Description + ExpectEq("has type map[string]string", matcher.Description()) + + // nil map + m = nil + err = matcher.Matches(m) + ExpectEq(nil, err) + + // Non-nil map + m = make(map[string]string) + err = matcher.Matches(m) + ExpectEq(nil, err) + + // Literal nil + err = matcher.Matches(nil) + AssertNe(nil, err) + ExpectThat(err, Error(Equals("which has type <nil>"))) + + // int + err = matcher.Matches(17) + AssertNe(nil, err) + ExpectThat(err, Error(Equals("which has type int"))) + + // string + err = matcher.Matches("") + AssertNe(nil, err) + ExpectThat(err, Error(Equals("which has type string"))) +} + +func (t *HasSameTypeAsTest) CandidateIsNilInInterfaceVariable() { + var r io.Reader + matcher := HasSameTypeAs(r) + var err error + + // Description + ExpectEq("has type <nil>", matcher.Description()) + + // nil in interface variable + r = nil + err = matcher.Matches(r) + ExpectEq(nil, err) + + // Literal nil + err = matcher.Matches(nil) + ExpectEq(nil, err) + + // int + err = matcher.Matches(17) + AssertNe(nil, err) + ExpectThat(err, Error(Equals("which has type int"))) +} + +func (t *HasSameTypeAsTest) CandidateIsString() { + matcher := HasSameTypeAs("") + var err error + + // Description + ExpectEq("has type string", matcher.Description()) + + // string + err = matcher.Matches("taco") + ExpectEq(nil, err) + + // string alias + type Foo string + err = matcher.Matches(Foo("taco")) + ExpectThat(err, Error(MatchesRegexp("which has type .*Foo"))) + + // Literal nil + err = matcher.Matches(nil) + AssertNe(nil, err) + ExpectThat(err, Error(Equals("which has type <nil>"))) + + // int + err = matcher.Matches(17) + AssertNe(nil, err) + ExpectThat(err, Error(Equals("which has type int"))) +} + +func (t *HasSameTypeAsTest) CandidateIsStringAlias() { + type Foo string + matcher := HasSameTypeAs(Foo("")) + var err error + + // Description + ExpectThat(matcher.Description(), MatchesRegexp("has type .*Foo")) + + // string alias + err = matcher.Matches(Foo("taco")) + ExpectEq(nil, err) + + // string + err = matcher.Matches("taco") + ExpectThat(err, Error(Equals("which has type string"))) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/has_substr.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/has_substr.go new file mode 100644 index 00000000000..bf5bd6ae6d3 --- /dev/null +++ b/src/mongo/gotools/vendor/src/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/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/has_substr_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/has_substr_test.go new file mode 100644 index 00000000000..6fc913a2490 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/has_substr_test.go @@ -0,0 +1,93 @@ +// 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_test + +import ( + . "github.com/smartystreets/assertions/internal/oglematchers" + . "github.com/smartystreets/assertions/internal/ogletest" +) + +//////////////////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////////////////// + +type HasSubstrTest struct { + +} + +func init() { RegisterTestSuite(&HasSubstrTest{}) } + +//////////////////////////////////////////////////////////////////////// +// Tests +//////////////////////////////////////////////////////////////////////// + +func (t *HasSubstrTest) Description() { + matcher := HasSubstr("taco") + ExpectThat(matcher.Description(), Equals("has substring \"taco\"")) +} + +func (t *HasSubstrTest) CandidateIsNil() { + matcher := HasSubstr("") + err := matcher.Matches(nil) + + ExpectThat(err, Error(Equals("which is not a string"))) + ExpectTrue(isFatal(err)) +} + +func (t *HasSubstrTest) CandidateIsInteger() { + matcher := HasSubstr("") + err := matcher.Matches(17) + + ExpectThat(err, Error(Equals("which is not a string"))) + ExpectTrue(isFatal(err)) +} + +func (t *HasSubstrTest) CandidateIsByteSlice() { + matcher := HasSubstr("") + err := matcher.Matches([]byte{17}) + + ExpectThat(err, Error(Equals("which is not a string"))) + ExpectTrue(isFatal(err)) +} + +func (t *HasSubstrTest) CandidateDoesntHaveSubstring() { + matcher := HasSubstr("taco") + err := matcher.Matches("tac") + + ExpectThat(err, Error(Equals(""))) + ExpectFalse(isFatal(err)) +} + +func (t *HasSubstrTest) CandidateEqualsArg() { + matcher := HasSubstr("taco") + err := matcher.Matches("taco") + + ExpectThat(err, Equals(nil)) +} + +func (t *HasSubstrTest) CandidateHasProperSubstring() { + matcher := HasSubstr("taco") + err := matcher.Matches("burritos and tacos") + + ExpectThat(err, Equals(nil)) +} + +func (t *HasSubstrTest) EmptyStringIsAlwaysSubString() { + matcher := HasSubstr("") + err := matcher.Matches("asdf") + + ExpectThat(err, Equals(nil)) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/identical_to.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/identical_to.go new file mode 100644 index 00000000000..ae6460ed966 --- /dev/null +++ b/src/mongo/gotools/vendor/src/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/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/identical_to_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/identical_to_test.go new file mode 100644 index 00000000000..cc03b214ad6 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/identical_to_test.go @@ -0,0 +1,849 @@ +// 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_test + +import ( + . "github.com/smartystreets/assertions/internal/oglematchers" + . "github.com/smartystreets/assertions/internal/ogletest" + "fmt" + "io" + "unsafe" +) + +//////////////////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////////////////// + +type IdenticalToTest struct { +} + +func init() { RegisterTestSuite(&IdenticalToTest{}) } + +//////////////////////////////////////////////////////////////////////// +// Tests +//////////////////////////////////////////////////////////////////////// + +func (t *IdenticalToTest) TypesNotIdentical() { + var m Matcher + var err error + + type intAlias int + + // Type alias expected value + m = IdenticalTo(intAlias(17)) + err = m.Matches(int(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type int"))) + + // Type alias candidate + m = IdenticalTo(int(17)) + err = m.Matches(intAlias(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type oglematchers_test.intAlias"))) + + // int and uint + m = IdenticalTo(int(17)) + err = m.Matches(uint(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type uint"))) +} + +func (t *IdenticalToTest) PredeclaredNilIdentifier() { + var m Matcher + var err error + + // Nil literal + m = IdenticalTo(nil) + err = m.Matches(nil) + ExpectEq(nil, err) + + // Zero interface var (which is the same as above since IdenticalTo takes an + // interface{} as an arg) + var nilReader io.Reader + var nilWriter io.Writer + + m = IdenticalTo(nilReader) + err = m.Matches(nilWriter) + ExpectEq(nil, err) + + // Typed nil value. + m = IdenticalTo(nil) + err = m.Matches((chan int)(nil)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type chan int"))) + + // Non-nil value. + m = IdenticalTo(nil) + err = m.Matches("taco") + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type string"))) +} + +func (t *IdenticalToTest) Slices() { + var m Matcher + var err error + + // Nil expected value + m = IdenticalTo(([]int)(nil)) + ExpectEq("identical to <[]int> []", m.Description()) + + err = m.Matches(([]int)(nil)) + ExpectEq(nil, err) + + err = m.Matches([]int{}) + ExpectThat(err, Error(Equals("which is not an identical reference"))) + + // Non-nil expected value + o1 := make([]int, 1) + o2 := make([]int, 1) + m = IdenticalTo(o1) + ExpectEq(fmt.Sprintf("identical to <[]int> %v", o1), m.Description()) + + err = m.Matches(o1) + ExpectEq(nil, err) + + err = m.Matches(o2) + ExpectThat(err, Error(Equals("which is not an identical reference"))) +} + +func (t *IdenticalToTest) Maps() { + var m Matcher + var err error + + // Nil expected value + m = IdenticalTo((map[int]int)(nil)) + ExpectEq("identical to <map[int]int> map[]", m.Description()) + + err = m.Matches((map[int]int)(nil)) + ExpectEq(nil, err) + + err = m.Matches(map[int]int{}) + ExpectThat(err, Error(Equals("which is not an identical reference"))) + + // Non-nil expected value + o1 := map[int]int{} + o2 := map[int]int{} + m = IdenticalTo(o1) + ExpectEq(fmt.Sprintf("identical to <map[int]int> %v", o1), m.Description()) + + err = m.Matches(o1) + ExpectEq(nil, err) + + err = m.Matches(o2) + ExpectThat(err, Error(Equals("which is not an identical reference"))) +} + +func (t *IdenticalToTest) Functions() { + var m Matcher + var err error + + // Nil expected value + m = IdenticalTo((func())(nil)) + ExpectEq("identical to <func()> <nil>", m.Description()) + + err = m.Matches((func())(nil)) + ExpectEq(nil, err) + + err = m.Matches(func(){}) + ExpectThat(err, Error(Equals("which is not an identical reference"))) + + // Non-nil expected value + o1 := func() {} + o2 := func() {} + m = IdenticalTo(o1) + ExpectEq(fmt.Sprintf("identical to <func()> %v", o1), m.Description()) + + err = m.Matches(o1) + ExpectEq(nil, err) + + err = m.Matches(o2) + ExpectThat(err, Error(Equals("which is not an identical reference"))) +} + +func (t *IdenticalToTest) Channels() { + var m Matcher + var err error + + // Nil expected value + m = IdenticalTo((chan int)(nil)) + ExpectEq("identical to <chan int> <nil>", m.Description()) + + err = m.Matches((chan int)(nil)) + ExpectEq(nil, err) + + err = m.Matches(make(chan int)) + ExpectThat(err, Error(Equals("which is not an identical reference"))) + + // Non-nil expected value + o1 := make(chan int) + o2 := make(chan int) + m = IdenticalTo(o1) + ExpectEq(fmt.Sprintf("identical to <chan int> %v", o1), m.Description()) + + err = m.Matches(o1) + ExpectEq(nil, err) + + err = m.Matches(o2) + ExpectThat(err, Error(Equals("which is not an identical reference"))) +} + +func (t *IdenticalToTest) Bools() { + var m Matcher + var err error + + // false + m = IdenticalTo(false) + ExpectEq("identical to <bool> false", m.Description()) + + err = m.Matches(false) + ExpectEq(nil, err) + + err = m.Matches(true) + ExpectThat(err, Error(Equals(""))) + + // true + m = IdenticalTo(true) + ExpectEq("identical to <bool> true", m.Description()) + + err = m.Matches(false) + ExpectThat(err, Error(Equals(""))) + + err = m.Matches(true) + ExpectEq(nil, err) +} + +func (t *IdenticalToTest) Ints() { + var m Matcher + var err error + + m = IdenticalTo(int(17)) + ExpectEq("identical to <int> 17", m.Description()) + + // Identical value + err = m.Matches(int(17)) + ExpectEq(nil, err) + + // Type alias + type myType int + err = m.Matches(myType(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) + + // Completely wrong type + err = m.Matches(int32(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type int32"))) +} + +func (t *IdenticalToTest) Int8s() { + var m Matcher + var err error + + m = IdenticalTo(int8(17)) + ExpectEq("identical to <int8> 17", m.Description()) + + // Identical value + err = m.Matches(int8(17)) + ExpectEq(nil, err) + + // Type alias + type myType int8 + err = m.Matches(myType(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) + + // Completely wrong type + err = m.Matches(int32(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type int32"))) +} + +func (t *IdenticalToTest) Int16s() { + var m Matcher + var err error + + m = IdenticalTo(int16(17)) + ExpectEq("identical to <int16> 17", m.Description()) + + // Identical value + err = m.Matches(int16(17)) + ExpectEq(nil, err) + + // Type alias + type myType int16 + err = m.Matches(myType(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) + + // Completely wrong type + err = m.Matches(int32(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type int32"))) +} + +func (t *IdenticalToTest) Int32s() { + var m Matcher + var err error + + m = IdenticalTo(int32(17)) + ExpectEq("identical to <int32> 17", m.Description()) + + // Identical value + err = m.Matches(int32(17)) + ExpectEq(nil, err) + + // Type alias + type myType int32 + err = m.Matches(myType(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) + + // Completely wrong type + err = m.Matches(int16(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type int16"))) +} + +func (t *IdenticalToTest) Int64s() { + var m Matcher + var err error + + m = IdenticalTo(int64(17)) + ExpectEq("identical to <int64> 17", m.Description()) + + // Identical value + err = m.Matches(int64(17)) + ExpectEq(nil, err) + + // Type alias + type myType int64 + err = m.Matches(myType(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) + + // Completely wrong type + err = m.Matches(int32(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type int32"))) +} + +func (t *IdenticalToTest) Uints() { + var m Matcher + var err error + + m = IdenticalTo(uint(17)) + ExpectEq("identical to <uint> 17", m.Description()) + + // Identical value + err = m.Matches(uint(17)) + ExpectEq(nil, err) + + // Type alias + type myType uint + err = m.Matches(myType(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) + + // Completely wrong type + err = m.Matches(int32(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type int32"))) +} + +func (t *IdenticalToTest) Uint8s() { + var m Matcher + var err error + + m = IdenticalTo(uint8(17)) + ExpectEq("identical to <uint8> 17", m.Description()) + + // Identical value + err = m.Matches(uint8(17)) + ExpectEq(nil, err) + + // Type alias + type myType uint8 + err = m.Matches(myType(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) + + // Completely wrong type + err = m.Matches(int32(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type int32"))) +} + +func (t *IdenticalToTest) Uint16s() { + var m Matcher + var err error + + m = IdenticalTo(uint16(17)) + ExpectEq("identical to <uint16> 17", m.Description()) + + // Identical value + err = m.Matches(uint16(17)) + ExpectEq(nil, err) + + // Type alias + type myType uint16 + err = m.Matches(myType(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) + + // Completely wrong type + err = m.Matches(int32(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type int32"))) +} + +func (t *IdenticalToTest) Uint32s() { + var m Matcher + var err error + + m = IdenticalTo(uint32(17)) + ExpectEq("identical to <uint32> 17", m.Description()) + + // Identical value + err = m.Matches(uint32(17)) + ExpectEq(nil, err) + + // Type alias + type myType uint32 + err = m.Matches(myType(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) + + // Completely wrong type + err = m.Matches(int32(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type int32"))) +} + +func (t *IdenticalToTest) Uint64s() { + var m Matcher + var err error + + m = IdenticalTo(uint64(17)) + ExpectEq("identical to <uint64> 17", m.Description()) + + // Identical value + err = m.Matches(uint64(17)) + ExpectEq(nil, err) + + // Type alias + type myType uint64 + err = m.Matches(myType(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) + + // Completely wrong type + err = m.Matches(int32(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type int32"))) +} + +func (t *IdenticalToTest) Uintptrs() { + var m Matcher + var err error + + m = IdenticalTo(uintptr(17)) + ExpectEq("identical to <uintptr> 17", m.Description()) + + // Identical value + err = m.Matches(uintptr(17)) + ExpectEq(nil, err) + + // Type alias + type myType uintptr + err = m.Matches(myType(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) + + // Completely wrong type + err = m.Matches(int32(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type int32"))) +} + +func (t *IdenticalToTest) Float32s() { + var m Matcher + var err error + + m = IdenticalTo(float32(17)) + ExpectEq("identical to <float32> 17", m.Description()) + + // Identical value + err = m.Matches(float32(17)) + ExpectEq(nil, err) + + // Type alias + type myType float32 + err = m.Matches(myType(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) + + // Completely wrong type + err = m.Matches(int32(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type int32"))) +} + +func (t *IdenticalToTest) Float64s() { + var m Matcher + var err error + + m = IdenticalTo(float64(17)) + ExpectEq("identical to <float64> 17", m.Description()) + + // Identical value + err = m.Matches(float64(17)) + ExpectEq(nil, err) + + // Type alias + type myType float64 + err = m.Matches(myType(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) + + // Completely wrong type + err = m.Matches(int32(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type int32"))) +} + +func (t *IdenticalToTest) Complex64s() { + var m Matcher + var err error + + m = IdenticalTo(complex64(17)) + ExpectEq("identical to <complex64> (17+0i)", m.Description()) + + // Identical value + err = m.Matches(complex64(17)) + ExpectEq(nil, err) + + // Type alias + type myType complex64 + err = m.Matches(myType(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) + + // Completely wrong type + err = m.Matches(int32(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type int32"))) +} + +func (t *IdenticalToTest) Complex128s() { + var m Matcher + var err error + + m = IdenticalTo(complex128(17)) + ExpectEq("identical to <complex128> (17+0i)", m.Description()) + + // Identical value + err = m.Matches(complex128(17)) + ExpectEq(nil, err) + + // Type alias + type myType complex128 + err = m.Matches(myType(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) + + // Completely wrong type + err = m.Matches(int32(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type int32"))) +} + +func (t *IdenticalToTest) EmptyComparableArrays() { + var m Matcher + var err error + + m = IdenticalTo([0]int{}) + ExpectEq("identical to <[0]int> []", m.Description()) + + // Identical value + err = m.Matches([0]int{}) + ExpectEq(nil, err) + + // Length too long + err = m.Matches([1]int{17}) + ExpectThat(err, Error(Equals("which is of type [1]int"))) + + // Element type alias + type myType int + err = m.Matches([0]myType{}) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type [0]oglematchers_test.myType"))) + + // Completely wrong element type + err = m.Matches([0]int32{}) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type [0]int32"))) +} + +func (t *IdenticalToTest) NonEmptyComparableArrays() { + var m Matcher + var err error + + m = IdenticalTo([2]int{17, 19}) + ExpectEq("identical to <[2]int> [17 19]", m.Description()) + + // Identical value + err = m.Matches([2]int{17, 19}) + ExpectEq(nil, err) + + // Length too short + err = m.Matches([1]int{17}) + ExpectThat(err, Error(Equals("which is of type [1]int"))) + + // Length too long + err = m.Matches([3]int{17, 19, 23}) + ExpectThat(err, Error(Equals("which is of type [3]int"))) + + // First element different + err = m.Matches([2]int{13, 19}) + ExpectThat(err, Error(Equals(""))) + + // Second element different + err = m.Matches([2]int{17, 23}) + ExpectThat(err, Error(Equals(""))) + + // Element type alias + type myType int + err = m.Matches([2]myType{17, 19}) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type [2]oglematchers_test.myType"))) + + // Completely wrong element type + err = m.Matches([2]int32{17, 19}) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type [2]int32"))) +} + +func (t *IdenticalToTest) NonEmptyArraysOfComparableArrays() { + var m Matcher + var err error + + x := [2][2]int{ + [2]int{17, 19}, + [2]int{23, 29}, + } + m = IdenticalTo(x) + ExpectEq("identical to <[2][2]int> [[17 19] [23 29]]", m.Description()) + + // Identical value + err = m.Matches([2][2]int{[2]int{17, 19}, [2]int{23, 29}}) + ExpectEq(nil, err) + + // Outer length too short + err = m.Matches([1][2]int{[2]int{17, 19}}) + ExpectThat(err, Error(Equals("which is of type [1][2]int"))) + + // Inner length too short + err = m.Matches([2][1]int{[1]int{17}, [1]int{23}}) + ExpectThat(err, Error(Equals("which is of type [2][1]int"))) + + // First element different + err = m.Matches([2][2]int{[2]int{13, 19}, [2]int{23, 29}}) + ExpectThat(err, Error(Equals(""))) + + // Element type alias + type myType int + err = m.Matches([2][2]myType{[2]myType{17, 19}, [2]myType{23, 29}}) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type [2][2]oglematchers_test.myType"))) +} + +func (t *IdenticalToTest) NonComparableArrays() { + x := [0]func(){} + f := func() { IdenticalTo(x) } + ExpectThat(f, Panics(HasSubstr("is not comparable"))) +} + +func (t *IdenticalToTest) ArraysOfNonComparableArrays() { + x := [0][0]func(){} + f := func() { IdenticalTo(x) } + ExpectThat(f, Panics(HasSubstr("is not comparable"))) +} + +func (t *IdenticalToTest) Strings() { + var m Matcher + var err error + + m = IdenticalTo("taco") + ExpectEq("identical to <string> taco", m.Description()) + + // Identical value + err = m.Matches("ta" + "co") + ExpectEq(nil, err) + + // Type alias + type myType string + err = m.Matches(myType("taco")) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) + + // Completely wrong type + err = m.Matches(int32(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type int32"))) +} + +func (t *IdenticalToTest) ComparableStructs() { + var m Matcher + var err error + + type subStruct struct { + i int + } + + type myStruct struct { + u uint + s subStruct + } + + x := myStruct{17, subStruct{19}} + m = IdenticalTo(x) + ExpectEq("identical to <oglematchers_test.myStruct> {17 {19}}", m.Description()) + + // Identical value + err = m.Matches(myStruct{17, subStruct{19}}) + ExpectEq(nil, err) + + // Wrong outer field + err = m.Matches(myStruct{13, subStruct{19}}) + ExpectThat(err, Error(Equals(""))) + + // Wrong inner field + err = m.Matches(myStruct{17, subStruct{23}}) + ExpectThat(err, Error(Equals(""))) + + // Type alias + type myType myStruct + err = m.Matches(myType{17, subStruct{19}}) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) + + // Completely wrong type + err = m.Matches(int32(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type int32"))) +} + +func (t *IdenticalToTest) NonComparableStructs() { + type subStruct struct { + s []int + } + + type myStruct struct { + u uint + s subStruct + } + + x := myStruct{17, subStruct{[]int{19}}} + f := func() { IdenticalTo(x) } + ExpectThat(f, Panics(AllOf(HasSubstr("IdenticalTo"), HasSubstr("comparable")))) +} + +func (t *IdenticalToTest) NilUnsafePointer() { + var m Matcher + var err error + + x := unsafe.Pointer(nil) + m = IdenticalTo(x) + ExpectEq(fmt.Sprintf("identical to <unsafe.Pointer> %v", x), m.Description()) + + // Identical value + err = m.Matches(unsafe.Pointer(nil)) + ExpectEq(nil, err) + + // Wrong value + j := 17 + err = m.Matches(unsafe.Pointer(&j)) + ExpectThat(err, Error(Equals(""))) + + // Type alias + type myType unsafe.Pointer + err = m.Matches(myType(unsafe.Pointer(nil))) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) + + // Completely wrong type + err = m.Matches(int32(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type int32"))) +} + +func (t *IdenticalToTest) NonNilUnsafePointer() { + var m Matcher + var err error + + i := 17 + x := unsafe.Pointer(&i) + m = IdenticalTo(x) + ExpectEq(fmt.Sprintf("identical to <unsafe.Pointer> %v", x), m.Description()) + + // Identical value + err = m.Matches(unsafe.Pointer(&i)) + ExpectEq(nil, err) + + // Nil value + err = m.Matches(unsafe.Pointer(nil)) + ExpectThat(err, Error(Equals(""))) + + // Wrong value + j := 17 + err = m.Matches(unsafe.Pointer(&j)) + ExpectThat(err, Error(Equals(""))) + + // Type alias + type myType unsafe.Pointer + err = m.Matches(myType(unsafe.Pointer(&i))) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) + + // Completely wrong type + err = m.Matches(int32(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type int32"))) +} + +func (t *IdenticalToTest) IntAlias() { + var m Matcher + var err error + + type intAlias int + + m = IdenticalTo(intAlias(17)) + ExpectEq("identical to <oglematchers_test.intAlias> 17", m.Description()) + + // Identical value + err = m.Matches(intAlias(17)) + ExpectEq(nil, err) + + // Int + err = m.Matches(int(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type int"))) + + // Completely wrong type + err = m.Matches(int32(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type int32"))) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/less_or_equal.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/less_or_equal.go new file mode 100644 index 00000000000..8402cdeaf09 --- /dev/null +++ b/src/mongo/gotools/vendor/src/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/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/less_or_equal_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/less_or_equal_test.go new file mode 100644 index 00000000000..a1a2ae7d60e --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/less_or_equal_test.go @@ -0,0 +1,1077 @@ +// 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_test + +import ( + "math" + + . "github.com/smartystreets/assertions/internal/oglematchers" + . "github.com/smartystreets/assertions/internal/ogletest" +) + +//////////////////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////////////////// + +type LessOrEqualTest struct { +} + +func init() { RegisterTestSuite(&LessOrEqualTest{}) } + +type leTestCase struct { + candidate interface{} + expectedResult bool + shouldBeFatal bool + expectedError string +} + +func (t *LessOrEqualTest) checkTestCases(matcher Matcher, cases []leTestCase) { + for i, c := range cases { + err := matcher.Matches(c.candidate) + + ExpectThat( + (err == nil), + Equals(c.expectedResult), + "Case %d (candidate %v)", + i, + c.candidate) + + if err == nil { + continue + } + + _, isFatal := err.(*FatalError) + ExpectEq( + c.shouldBeFatal, + isFatal, + "Case %d (candidate %v)", + i, + c.candidate) + + ExpectThat( + err, + Error(Equals(c.expectedError)), + "Case %d (candidate %v)", + i, + c.candidate) + } +} + +//////////////////////////////////////////////////////////////////////// +// Integer literals +//////////////////////////////////////////////////////////////////////// + +func (t *LessOrEqualTest) IntegerCandidateBadTypes() { + matcher := LessOrEqual(int(-150)) + + cases := []leTestCase{ + leTestCase{true, false, true, "which is not comparable"}, + leTestCase{complex64(-151), false, true, "which is not comparable"}, + leTestCase{complex128(-151), false, true, "which is not comparable"}, + leTestCase{[...]int{-151}, false, true, "which is not comparable"}, + leTestCase{make(chan int), false, true, "which is not comparable"}, + leTestCase{func() {}, false, true, "which is not comparable"}, + leTestCase{map[int]int{}, false, true, "which is not comparable"}, + leTestCase{&leTestCase{}, false, true, "which is not comparable"}, + leTestCase{make([]int, 0), false, true, "which is not comparable"}, + leTestCase{"-151", false, true, "which is not comparable"}, + leTestCase{leTestCase{}, false, true, "which is not comparable"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessOrEqualTest) FloatCandidateBadTypes() { + matcher := LessOrEqual(float32(-150)) + + cases := []leTestCase{ + leTestCase{true, false, true, "which is not comparable"}, + leTestCase{complex64(-151), false, true, "which is not comparable"}, + leTestCase{complex128(-151), false, true, "which is not comparable"}, + leTestCase{[...]int{-151}, false, true, "which is not comparable"}, + leTestCase{make(chan int), false, true, "which is not comparable"}, + leTestCase{func() {}, false, true, "which is not comparable"}, + leTestCase{map[int]int{}, false, true, "which is not comparable"}, + leTestCase{&leTestCase{}, false, true, "which is not comparable"}, + leTestCase{make([]int, 0), false, true, "which is not comparable"}, + leTestCase{"-151", false, true, "which is not comparable"}, + leTestCase{leTestCase{}, false, true, "which is not comparable"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessOrEqualTest) StringCandidateBadTypes() { + matcher := LessOrEqual("17") + + cases := []leTestCase{ + leTestCase{true, false, true, "which is not comparable"}, + leTestCase{int(0), false, true, "which is not comparable"}, + leTestCase{int8(0), false, true, "which is not comparable"}, + leTestCase{int16(0), false, true, "which is not comparable"}, + leTestCase{int32(0), false, true, "which is not comparable"}, + leTestCase{int64(0), false, true, "which is not comparable"}, + leTestCase{uint(0), false, true, "which is not comparable"}, + leTestCase{uint8(0), false, true, "which is not comparable"}, + leTestCase{uint16(0), false, true, "which is not comparable"}, + leTestCase{uint32(0), false, true, "which is not comparable"}, + leTestCase{uint64(0), false, true, "which is not comparable"}, + leTestCase{float32(0), false, true, "which is not comparable"}, + leTestCase{float64(0), false, true, "which is not comparable"}, + leTestCase{complex64(-151), false, true, "which is not comparable"}, + leTestCase{complex128(-151), false, true, "which is not comparable"}, + leTestCase{[...]int{-151}, false, true, "which is not comparable"}, + leTestCase{make(chan int), false, true, "which is not comparable"}, + leTestCase{func() {}, false, true, "which is not comparable"}, + leTestCase{map[int]int{}, false, true, "which is not comparable"}, + leTestCase{&leTestCase{}, false, true, "which is not comparable"}, + leTestCase{make([]int, 0), false, true, "which is not comparable"}, + leTestCase{leTestCase{}, false, true, "which is not comparable"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessOrEqualTest) BadArgument() { + panicked := false + + defer func() { + ExpectThat(panicked, Equals(true)) + }() + + defer func() { + if r := recover(); r != nil { + panicked = true + } + }() + + LessOrEqual(complex128(0)) +} + +//////////////////////////////////////////////////////////////////////// +// Integer literals +//////////////////////////////////////////////////////////////////////// + +func (t *LessOrEqualTest) NegativeIntegerLiteral() { + matcher := LessOrEqual(-150) + desc := matcher.Description() + expectedDesc := "less than or equal to -150" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []leTestCase{ + // Signed integers. + leTestCase{-(1 << 30), true, false, ""}, + leTestCase{-151, true, false, ""}, + leTestCase{-150, true, false, ""}, + leTestCase{-149, false, false, ""}, + leTestCase{0, false, false, ""}, + leTestCase{17, false, false, ""}, + + leTestCase{int(-(1 << 30)), true, false, ""}, + leTestCase{int(-151), true, false, ""}, + leTestCase{int(-150), true, false, ""}, + leTestCase{int(-149), false, false, ""}, + leTestCase{int(0), false, false, ""}, + leTestCase{int(17), false, false, ""}, + + leTestCase{int8(-127), false, false, ""}, + leTestCase{int8(0), false, false, ""}, + leTestCase{int8(17), false, false, ""}, + + leTestCase{int16(-(1 << 14)), true, false, ""}, + leTestCase{int16(-151), true, false, ""}, + leTestCase{int16(-150), true, false, ""}, + leTestCase{int16(-149), false, false, ""}, + leTestCase{int16(0), false, false, ""}, + leTestCase{int16(17), false, false, ""}, + + leTestCase{int32(-(1 << 30)), true, false, ""}, + leTestCase{int32(-151), true, false, ""}, + leTestCase{int32(-150), true, false, ""}, + leTestCase{int32(-149), false, false, ""}, + leTestCase{int32(0), false, false, ""}, + leTestCase{int32(17), false, false, ""}, + + leTestCase{int64(-(1 << 30)), true, false, ""}, + leTestCase{int64(-151), true, false, ""}, + leTestCase{int64(-150), true, false, ""}, + leTestCase{int64(-149), false, false, ""}, + leTestCase{int64(0), false, false, ""}, + leTestCase{int64(17), false, false, ""}, + + // Unsigned integers. + leTestCase{uint((1 << 32) - 151), false, false, ""}, + leTestCase{uint(0), false, false, ""}, + leTestCase{uint(17), false, false, ""}, + + leTestCase{uint8(0), false, false, ""}, + leTestCase{uint8(17), false, false, ""}, + leTestCase{uint8(253), false, false, ""}, + + leTestCase{uint16((1 << 16) - 151), false, false, ""}, + leTestCase{uint16(0), false, false, ""}, + leTestCase{uint16(17), false, false, ""}, + + leTestCase{uint32((1 << 32) - 151), false, false, ""}, + leTestCase{uint32(0), false, false, ""}, + leTestCase{uint32(17), false, false, ""}, + + leTestCase{uint64((1 << 64) - 151), false, false, ""}, + leTestCase{uint64(0), false, false, ""}, + leTestCase{uint64(17), false, false, ""}, + + // Floating point. + leTestCase{float32(-(1 << 30)), true, false, ""}, + leTestCase{float32(-151), true, false, ""}, + leTestCase{float32(-150.1), true, false, ""}, + leTestCase{float32(-150), true, false, ""}, + leTestCase{float32(-149.9), false, false, ""}, + leTestCase{float32(0), false, false, ""}, + leTestCase{float32(17), false, false, ""}, + leTestCase{float32(160), false, false, ""}, + + leTestCase{float64(-(1 << 30)), true, false, ""}, + leTestCase{float64(-151), true, false, ""}, + leTestCase{float64(-150.1), true, false, ""}, + leTestCase{float64(-150), true, false, ""}, + leTestCase{float64(-149.9), false, false, ""}, + leTestCase{float64(0), false, false, ""}, + leTestCase{float64(17), false, false, ""}, + leTestCase{float64(160), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessOrEqualTest) ZeroIntegerLiteral() { + matcher := LessOrEqual(0) + desc := matcher.Description() + expectedDesc := "less than or equal to 0" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []leTestCase{ + // Signed integers. + leTestCase{-(1 << 30), true, false, ""}, + leTestCase{-1, true, false, ""}, + leTestCase{0, true, false, ""}, + leTestCase{1, false, false, ""}, + leTestCase{17, false, false, ""}, + leTestCase{(1 << 30), false, false, ""}, + + leTestCase{int(-(1 << 30)), true, false, ""}, + leTestCase{int(-1), true, false, ""}, + leTestCase{int(0), true, false, ""}, + leTestCase{int(1), false, false, ""}, + leTestCase{int(17), false, false, ""}, + + leTestCase{int8(-1), true, false, ""}, + leTestCase{int8(0), true, false, ""}, + leTestCase{int8(1), false, false, ""}, + + leTestCase{int16(-(1 << 14)), true, false, ""}, + leTestCase{int16(-1), true, false, ""}, + leTestCase{int16(0), true, false, ""}, + leTestCase{int16(1), false, false, ""}, + leTestCase{int16(17), false, false, ""}, + + leTestCase{int32(-(1 << 30)), true, false, ""}, + leTestCase{int32(-1), true, false, ""}, + leTestCase{int32(0), true, false, ""}, + leTestCase{int32(1), false, false, ""}, + leTestCase{int32(17), false, false, ""}, + + leTestCase{int64(-(1 << 30)), true, false, ""}, + leTestCase{int64(-1), true, false, ""}, + leTestCase{int64(0), true, false, ""}, + leTestCase{int64(1), false, false, ""}, + leTestCase{int64(17), false, false, ""}, + + // Unsigned integers. + leTestCase{uint((1 << 32) - 1), false, false, ""}, + leTestCase{uint(0), true, false, ""}, + leTestCase{uint(1), false, false, ""}, + leTestCase{uint(17), false, false, ""}, + + leTestCase{uint8(0), true, false, ""}, + leTestCase{uint8(1), false, false, ""}, + leTestCase{uint8(17), false, false, ""}, + leTestCase{uint8(253), false, false, ""}, + + leTestCase{uint16((1 << 16) - 1), false, false, ""}, + leTestCase{uint16(0), true, false, ""}, + leTestCase{uint16(1), false, false, ""}, + leTestCase{uint16(17), false, false, ""}, + + leTestCase{uint32((1 << 32) - 1), false, false, ""}, + leTestCase{uint32(0), true, false, ""}, + leTestCase{uint32(1), false, false, ""}, + leTestCase{uint32(17), false, false, ""}, + + leTestCase{uint64((1 << 64) - 1), false, false, ""}, + leTestCase{uint64(0), true, false, ""}, + leTestCase{uint64(1), false, false, ""}, + leTestCase{uint64(17), false, false, ""}, + + // Floating point. + leTestCase{float32(-(1 << 30)), true, false, ""}, + leTestCase{float32(-1), true, false, ""}, + leTestCase{float32(-0.1), true, false, ""}, + leTestCase{float32(-0.0), true, false, ""}, + leTestCase{float32(0), true, false, ""}, + leTestCase{float32(0.1), false, false, ""}, + leTestCase{float32(17), false, false, ""}, + leTestCase{float32(160), false, false, ""}, + + leTestCase{float64(-(1 << 30)), true, false, ""}, + leTestCase{float64(-1), true, false, ""}, + leTestCase{float64(-0.1), true, false, ""}, + leTestCase{float64(-0), true, false, ""}, + leTestCase{float64(0), true, false, ""}, + leTestCase{float64(0.1), false, false, ""}, + leTestCase{float64(17), false, false, ""}, + leTestCase{float64(160), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessOrEqualTest) PositiveIntegerLiteral() { + matcher := LessOrEqual(150) + desc := matcher.Description() + expectedDesc := "less than or equal to 150" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []leTestCase{ + // Signed integers. + leTestCase{-1, true, false, ""}, + leTestCase{149, true, false, ""}, + leTestCase{150, true, false, ""}, + leTestCase{151, false, false, ""}, + + leTestCase{int(-1), true, false, ""}, + leTestCase{int(149), true, false, ""}, + leTestCase{int(150), true, false, ""}, + leTestCase{int(151), false, false, ""}, + + leTestCase{int8(-1), true, false, ""}, + leTestCase{int8(0), true, false, ""}, + leTestCase{int8(17), true, false, ""}, + leTestCase{int8(127), true, false, ""}, + + leTestCase{int16(-1), true, false, ""}, + leTestCase{int16(149), true, false, ""}, + leTestCase{int16(150), true, false, ""}, + leTestCase{int16(151), false, false, ""}, + + leTestCase{int32(-1), true, false, ""}, + leTestCase{int32(149), true, false, ""}, + leTestCase{int32(150), true, false, ""}, + leTestCase{int32(151), false, false, ""}, + + leTestCase{int64(-1), true, false, ""}, + leTestCase{int64(149), true, false, ""}, + leTestCase{int64(150), true, false, ""}, + leTestCase{int64(151), false, false, ""}, + + // Unsigned integers. + leTestCase{uint(0), true, false, ""}, + leTestCase{uint(149), true, false, ""}, + leTestCase{uint(150), true, false, ""}, + leTestCase{uint(151), false, false, ""}, + + leTestCase{uint8(0), true, false, ""}, + leTestCase{uint8(127), true, false, ""}, + + leTestCase{uint16(0), true, false, ""}, + leTestCase{uint16(149), true, false, ""}, + leTestCase{uint16(150), true, false, ""}, + leTestCase{uint16(151), false, false, ""}, + + leTestCase{uint32(0), true, false, ""}, + leTestCase{uint32(149), true, false, ""}, + leTestCase{uint32(150), true, false, ""}, + leTestCase{uint32(151), false, false, ""}, + + leTestCase{uint64(0), true, false, ""}, + leTestCase{uint64(149), true, false, ""}, + leTestCase{uint64(150), true, false, ""}, + leTestCase{uint64(151), false, false, ""}, + + // Floating point. + leTestCase{float32(-1), true, false, ""}, + leTestCase{float32(149), true, false, ""}, + leTestCase{float32(149.9), true, false, ""}, + leTestCase{float32(150), true, false, ""}, + leTestCase{float32(150.1), false, false, ""}, + leTestCase{float32(151), false, false, ""}, + + leTestCase{float64(-1), true, false, ""}, + leTestCase{float64(149), true, false, ""}, + leTestCase{float64(149.9), true, false, ""}, + leTestCase{float64(150), true, false, ""}, + leTestCase{float64(150.1), false, false, ""}, + leTestCase{float64(151), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// Float literals +//////////////////////////////////////////////////////////////////////// + +func (t *LessOrEqualTest) NegativeFloatLiteral() { + matcher := LessOrEqual(-150.1) + desc := matcher.Description() + expectedDesc := "less than or equal to -150.1" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []leTestCase{ + // Signed integers. + leTestCase{-(1 << 30), true, false, ""}, + leTestCase{-151, true, false, ""}, + leTestCase{-150.1, true, false, ""}, + leTestCase{-150, false, false, ""}, + leTestCase{-149, false, false, ""}, + leTestCase{0, false, false, ""}, + leTestCase{17, false, false, ""}, + + leTestCase{int(-(1 << 30)), true, false, ""}, + leTestCase{int(-151), true, false, ""}, + leTestCase{int(-150), false, false, ""}, + leTestCase{int(-149), false, false, ""}, + leTestCase{int(0), false, false, ""}, + leTestCase{int(17), false, false, ""}, + + leTestCase{int8(-127), false, false, ""}, + leTestCase{int8(0), false, false, ""}, + leTestCase{int8(17), false, false, ""}, + + leTestCase{int16(-(1 << 14)), true, false, ""}, + leTestCase{int16(-151), true, false, ""}, + leTestCase{int16(-150), false, false, ""}, + leTestCase{int16(-149), false, false, ""}, + leTestCase{int16(0), false, false, ""}, + leTestCase{int16(17), false, false, ""}, + + leTestCase{int32(-(1 << 30)), true, false, ""}, + leTestCase{int32(-151), true, false, ""}, + leTestCase{int32(-150), false, false, ""}, + leTestCase{int32(-149), false, false, ""}, + leTestCase{int32(0), false, false, ""}, + leTestCase{int32(17), false, false, ""}, + + leTestCase{int64(-(1 << 30)), true, false, ""}, + leTestCase{int64(-151), true, false, ""}, + leTestCase{int64(-150), false, false, ""}, + leTestCase{int64(-149), false, false, ""}, + leTestCase{int64(0), false, false, ""}, + leTestCase{int64(17), false, false, ""}, + + // Unsigned integers. + leTestCase{uint((1 << 32) - 151), false, false, ""}, + leTestCase{uint(0), false, false, ""}, + leTestCase{uint(17), false, false, ""}, + + leTestCase{uint8(0), false, false, ""}, + leTestCase{uint8(17), false, false, ""}, + leTestCase{uint8(253), false, false, ""}, + + leTestCase{uint16((1 << 16) - 151), false, false, ""}, + leTestCase{uint16(0), false, false, ""}, + leTestCase{uint16(17), false, false, ""}, + + leTestCase{uint32((1 << 32) - 151), false, false, ""}, + leTestCase{uint32(0), false, false, ""}, + leTestCase{uint32(17), false, false, ""}, + + leTestCase{uint64((1 << 64) - 151), false, false, ""}, + leTestCase{uint64(0), false, false, ""}, + leTestCase{uint64(17), false, false, ""}, + + // Floating point. + leTestCase{float32(-(1 << 30)), true, false, ""}, + leTestCase{float32(-151), true, false, ""}, + leTestCase{float32(-150.2), true, false, ""}, + leTestCase{float32(-150.1), true, false, ""}, + leTestCase{float32(-150), false, false, ""}, + leTestCase{float32(0), false, false, ""}, + leTestCase{float32(17), false, false, ""}, + leTestCase{float32(160), false, false, ""}, + + leTestCase{float64(-(1 << 30)), true, false, ""}, + leTestCase{float64(-151), true, false, ""}, + leTestCase{float64(-150.2), true, false, ""}, + leTestCase{float64(-150.1), true, false, ""}, + leTestCase{float64(-150), false, false, ""}, + leTestCase{float64(0), false, false, ""}, + leTestCase{float64(17), false, false, ""}, + leTestCase{float64(160), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessOrEqualTest) PositiveFloatLiteral() { + matcher := LessOrEqual(149.9) + desc := matcher.Description() + expectedDesc := "less than or equal to 149.9" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []leTestCase{ + // Signed integers. + leTestCase{-1, true, false, ""}, + leTestCase{149, true, false, ""}, + leTestCase{149.9, true, false, ""}, + leTestCase{150, false, false, ""}, + leTestCase{151, false, false, ""}, + + leTestCase{int(-1), true, false, ""}, + leTestCase{int(149), true, false, ""}, + leTestCase{int(150), false, false, ""}, + leTestCase{int(151), false, false, ""}, + + leTestCase{int8(-1), true, false, ""}, + leTestCase{int8(0), true, false, ""}, + leTestCase{int8(17), true, false, ""}, + leTestCase{int8(127), true, false, ""}, + + leTestCase{int16(-1), true, false, ""}, + leTestCase{int16(149), true, false, ""}, + leTestCase{int16(150), false, false, ""}, + leTestCase{int16(151), false, false, ""}, + + leTestCase{int32(-1), true, false, ""}, + leTestCase{int32(149), true, false, ""}, + leTestCase{int32(150), false, false, ""}, + leTestCase{int32(151), false, false, ""}, + + leTestCase{int64(-1), true, false, ""}, + leTestCase{int64(149), true, false, ""}, + leTestCase{int64(150), false, false, ""}, + leTestCase{int64(151), false, false, ""}, + + // Unsigned integers. + leTestCase{uint(0), true, false, ""}, + leTestCase{uint(149), true, false, ""}, + leTestCase{uint(150), false, false, ""}, + leTestCase{uint(151), false, false, ""}, + + leTestCase{uint8(0), true, false, ""}, + leTestCase{uint8(127), true, false, ""}, + + leTestCase{uint16(0), true, false, ""}, + leTestCase{uint16(149), true, false, ""}, + leTestCase{uint16(150), false, false, ""}, + leTestCase{uint16(151), false, false, ""}, + + leTestCase{uint32(0), true, false, ""}, + leTestCase{uint32(149), true, false, ""}, + leTestCase{uint32(150), false, false, ""}, + leTestCase{uint32(151), false, false, ""}, + + leTestCase{uint64(0), true, false, ""}, + leTestCase{uint64(149), true, false, ""}, + leTestCase{uint64(150), false, false, ""}, + leTestCase{uint64(151), false, false, ""}, + + // Floating point. + leTestCase{float32(-1), true, false, ""}, + leTestCase{float32(149), true, false, ""}, + leTestCase{float32(149.8), true, false, ""}, + leTestCase{float32(149.9), true, false, ""}, + leTestCase{float32(150), false, false, ""}, + leTestCase{float32(151), false, false, ""}, + + leTestCase{float64(-1), true, false, ""}, + leTestCase{float64(149), true, false, ""}, + leTestCase{float64(149.8), true, false, ""}, + leTestCase{float64(149.9), true, false, ""}, + leTestCase{float64(150), false, false, ""}, + leTestCase{float64(151), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// Subtle cases +//////////////////////////////////////////////////////////////////////// + +func (t *LessOrEqualTest) Int64NotExactlyRepresentableBySinglePrecision() { + // Single-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo25 = 1 << 25 + matcher := LessOrEqual(int64(kTwoTo25 + 1)) + + desc := matcher.Description() + expectedDesc := "less than or equal to 33554433" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []leTestCase{ + // Signed integers. + leTestCase{-1, true, false, ""}, + leTestCase{kTwoTo25 + 0, true, false, ""}, + leTestCase{kTwoTo25 + 1, true, false, ""}, + leTestCase{kTwoTo25 + 2, false, false, ""}, + + leTestCase{int(-1), true, false, ""}, + leTestCase{int(kTwoTo25 + 0), true, false, ""}, + leTestCase{int(kTwoTo25 + 1), true, false, ""}, + leTestCase{int(kTwoTo25 + 2), false, false, ""}, + + leTestCase{int8(-1), true, false, ""}, + leTestCase{int8(127), true, false, ""}, + + leTestCase{int16(-1), true, false, ""}, + leTestCase{int16(0), true, false, ""}, + leTestCase{int16(32767), true, false, ""}, + + leTestCase{int32(-1), true, false, ""}, + leTestCase{int32(kTwoTo25 + 0), true, false, ""}, + leTestCase{int32(kTwoTo25 + 1), true, false, ""}, + leTestCase{int32(kTwoTo25 + 2), false, false, ""}, + + leTestCase{int64(-1), true, false, ""}, + leTestCase{int64(kTwoTo25 + 0), true, false, ""}, + leTestCase{int64(kTwoTo25 + 1), true, false, ""}, + leTestCase{int64(kTwoTo25 + 2), false, false, ""}, + + // Unsigned integers. + leTestCase{uint(0), true, false, ""}, + leTestCase{uint(kTwoTo25 + 0), true, false, ""}, + leTestCase{uint(kTwoTo25 + 1), true, false, ""}, + leTestCase{uint(kTwoTo25 + 2), false, false, ""}, + + leTestCase{uint8(0), true, false, ""}, + leTestCase{uint8(255), true, false, ""}, + + leTestCase{uint16(0), true, false, ""}, + leTestCase{uint16(65535), true, false, ""}, + + leTestCase{uint32(0), true, false, ""}, + leTestCase{uint32(kTwoTo25 + 0), true, false, ""}, + leTestCase{uint32(kTwoTo25 + 1), true, false, ""}, + leTestCase{uint32(kTwoTo25 + 2), false, false, ""}, + + leTestCase{uint64(0), true, false, ""}, + leTestCase{uint64(kTwoTo25 + 0), true, false, ""}, + leTestCase{uint64(kTwoTo25 + 1), true, false, ""}, + leTestCase{uint64(kTwoTo25 + 2), false, false, ""}, + + // Floating point. + leTestCase{float32(-1), true, false, ""}, + leTestCase{float32(kTwoTo25 - 2), true, false, ""}, + leTestCase{float32(kTwoTo25 - 1), true, false, ""}, + leTestCase{float32(kTwoTo25 + 0), true, false, ""}, + leTestCase{float32(kTwoTo25 + 1), true, false, ""}, + leTestCase{float32(kTwoTo25 + 2), true, false, ""}, + leTestCase{float32(kTwoTo25 + 3), false, false, ""}, + + leTestCase{float64(-1), true, false, ""}, + leTestCase{float64(kTwoTo25 - 2), true, false, ""}, + leTestCase{float64(kTwoTo25 - 1), true, false, ""}, + leTestCase{float64(kTwoTo25 + 0), true, false, ""}, + leTestCase{float64(kTwoTo25 + 1), true, false, ""}, + leTestCase{float64(kTwoTo25 + 2), false, false, ""}, + leTestCase{float64(kTwoTo25 + 3), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessOrEqualTest) Int64NotExactlyRepresentableByDoublePrecision() { + // Double-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^54-1, 2^54+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo54 = 1 << 54 + matcher := LessOrEqual(int64(kTwoTo54 + 1)) + + desc := matcher.Description() + expectedDesc := "less than or equal to 18014398509481985" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []leTestCase{ + // Signed integers. + leTestCase{-1, true, false, ""}, + leTestCase{1 << 30, true, false, ""}, + + leTestCase{int(-1), true, false, ""}, + leTestCase{int(math.MaxInt32), true, false, ""}, + + leTestCase{int8(-1), true, false, ""}, + leTestCase{int8(127), true, false, ""}, + + leTestCase{int16(-1), true, false, ""}, + leTestCase{int16(0), true, false, ""}, + leTestCase{int16(32767), true, false, ""}, + + leTestCase{int32(-1), true, false, ""}, + leTestCase{int32(math.MaxInt32), true, false, ""}, + + leTestCase{int64(-1), true, false, ""}, + leTestCase{int64(kTwoTo54 - 1), true, false, ""}, + leTestCase{int64(kTwoTo54 + 0), true, false, ""}, + leTestCase{int64(kTwoTo54 + 1), true, false, ""}, + leTestCase{int64(kTwoTo54 + 2), false, false, ""}, + + // Unsigned integers. + leTestCase{uint(0), true, false, ""}, + leTestCase{uint(math.MaxUint32), true, false, ""}, + + leTestCase{uint8(0), true, false, ""}, + leTestCase{uint8(255), true, false, ""}, + + leTestCase{uint16(0), true, false, ""}, + leTestCase{uint16(65535), true, false, ""}, + + leTestCase{uint32(0), true, false, ""}, + leTestCase{uint32(math.MaxUint32), true, false, ""}, + + leTestCase{uint64(0), true, false, ""}, + leTestCase{uint64(kTwoTo54 - 1), true, false, ""}, + leTestCase{uint64(kTwoTo54 + 0), true, false, ""}, + leTestCase{uint64(kTwoTo54 + 1), true, false, ""}, + leTestCase{uint64(kTwoTo54 + 2), false, false, ""}, + + // Floating point. + leTestCase{float64(-1), true, false, ""}, + leTestCase{float64(kTwoTo54 - 2), true, false, ""}, + leTestCase{float64(kTwoTo54 - 1), true, false, ""}, + leTestCase{float64(kTwoTo54 + 0), true, false, ""}, + leTestCase{float64(kTwoTo54 + 1), true, false, ""}, + leTestCase{float64(kTwoTo54 + 2), true, false, ""}, + leTestCase{float64(kTwoTo54 + 3), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessOrEqualTest) Uint64NotExactlyRepresentableBySinglePrecision() { + // Single-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo25 = 1 << 25 + matcher := LessOrEqual(uint64(kTwoTo25 + 1)) + + desc := matcher.Description() + expectedDesc := "less than or equal to 33554433" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []leTestCase{ + // Signed integers. + leTestCase{-1, true, false, ""}, + leTestCase{kTwoTo25 + 0, true, false, ""}, + leTestCase{kTwoTo25 + 1, true, false, ""}, + leTestCase{kTwoTo25 + 2, false, false, ""}, + + leTestCase{int(-1), true, false, ""}, + leTestCase{int(kTwoTo25 + 0), true, false, ""}, + leTestCase{int(kTwoTo25 + 1), true, false, ""}, + leTestCase{int(kTwoTo25 + 2), false, false, ""}, + + leTestCase{int8(-1), true, false, ""}, + leTestCase{int8(127), true, false, ""}, + + leTestCase{int16(-1), true, false, ""}, + leTestCase{int16(0), true, false, ""}, + leTestCase{int16(32767), true, false, ""}, + + leTestCase{int32(-1), true, false, ""}, + leTestCase{int32(kTwoTo25 + 0), true, false, ""}, + leTestCase{int32(kTwoTo25 + 1), true, false, ""}, + leTestCase{int32(kTwoTo25 + 2), false, false, ""}, + + leTestCase{int64(-1), true, false, ""}, + leTestCase{int64(kTwoTo25 + 0), true, false, ""}, + leTestCase{int64(kTwoTo25 + 1), true, false, ""}, + leTestCase{int64(kTwoTo25 + 2), false, false, ""}, + + // Unsigned integers. + leTestCase{uint(0), true, false, ""}, + leTestCase{uint(kTwoTo25 + 0), true, false, ""}, + leTestCase{uint(kTwoTo25 + 1), true, false, ""}, + leTestCase{uint(kTwoTo25 + 2), false, false, ""}, + + leTestCase{uint8(0), true, false, ""}, + leTestCase{uint8(255), true, false, ""}, + + leTestCase{uint16(0), true, false, ""}, + leTestCase{uint16(65535), true, false, ""}, + + leTestCase{uint32(0), true, false, ""}, + leTestCase{uint32(kTwoTo25 + 0), true, false, ""}, + leTestCase{uint32(kTwoTo25 + 1), true, false, ""}, + leTestCase{uint32(kTwoTo25 + 2), false, false, ""}, + + leTestCase{uint64(0), true, false, ""}, + leTestCase{uint64(kTwoTo25 + 0), true, false, ""}, + leTestCase{uint64(kTwoTo25 + 1), true, false, ""}, + leTestCase{uint64(kTwoTo25 + 2), false, false, ""}, + + // Floating point. + leTestCase{float32(-1), true, false, ""}, + leTestCase{float32(kTwoTo25 - 2), true, false, ""}, + leTestCase{float32(kTwoTo25 - 1), true, false, ""}, + leTestCase{float32(kTwoTo25 + 0), true, false, ""}, + leTestCase{float32(kTwoTo25 + 1), true, false, ""}, + leTestCase{float32(kTwoTo25 + 2), true, false, ""}, + leTestCase{float32(kTwoTo25 + 3), false, false, ""}, + + leTestCase{float64(-1), true, false, ""}, + leTestCase{float64(kTwoTo25 - 2), true, false, ""}, + leTestCase{float64(kTwoTo25 - 1), true, false, ""}, + leTestCase{float64(kTwoTo25 + 0), true, false, ""}, + leTestCase{float64(kTwoTo25 + 1), true, false, ""}, + leTestCase{float64(kTwoTo25 + 2), false, false, ""}, + leTestCase{float64(kTwoTo25 + 3), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessOrEqualTest) Uint64NotExactlyRepresentableByDoublePrecision() { + // Double-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^54-1, 2^54+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo54 = 1 << 54 + matcher := LessOrEqual(uint64(kTwoTo54 + 1)) + + desc := matcher.Description() + expectedDesc := "less than or equal to 18014398509481985" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []leTestCase{ + // Signed integers. + leTestCase{-1, true, false, ""}, + leTestCase{1 << 30, true, false, ""}, + + leTestCase{int(-1), true, false, ""}, + leTestCase{int(math.MaxInt32), true, false, ""}, + + leTestCase{int8(-1), true, false, ""}, + leTestCase{int8(127), true, false, ""}, + + leTestCase{int16(-1), true, false, ""}, + leTestCase{int16(0), true, false, ""}, + leTestCase{int16(32767), true, false, ""}, + + leTestCase{int32(-1), true, false, ""}, + leTestCase{int32(math.MaxInt32), true, false, ""}, + + leTestCase{int64(-1), true, false, ""}, + leTestCase{int64(kTwoTo54 - 1), true, false, ""}, + leTestCase{int64(kTwoTo54 + 0), true, false, ""}, + leTestCase{int64(kTwoTo54 + 1), true, false, ""}, + leTestCase{int64(kTwoTo54 + 2), false, false, ""}, + + // Unsigned integers. + leTestCase{uint(0), true, false, ""}, + leTestCase{uint(math.MaxUint32), true, false, ""}, + + leTestCase{uint8(0), true, false, ""}, + leTestCase{uint8(255), true, false, ""}, + + leTestCase{uint16(0), true, false, ""}, + leTestCase{uint16(65535), true, false, ""}, + + leTestCase{uint32(0), true, false, ""}, + leTestCase{uint32(math.MaxUint32), true, false, ""}, + + leTestCase{uint64(0), true, false, ""}, + leTestCase{uint64(kTwoTo54 - 1), true, false, ""}, + leTestCase{uint64(kTwoTo54 + 0), true, false, ""}, + leTestCase{uint64(kTwoTo54 + 1), true, false, ""}, + leTestCase{uint64(kTwoTo54 + 2), false, false, ""}, + + // Floating point. + leTestCase{float64(-1), true, false, ""}, + leTestCase{float64(kTwoTo54 - 2), true, false, ""}, + leTestCase{float64(kTwoTo54 - 1), true, false, ""}, + leTestCase{float64(kTwoTo54 + 0), true, false, ""}, + leTestCase{float64(kTwoTo54 + 1), true, false, ""}, + leTestCase{float64(kTwoTo54 + 2), true, false, ""}, + leTestCase{float64(kTwoTo54 + 3), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessOrEqualTest) Float32AboveExactIntegerRange() { + // Single-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo25 = 1 << 25 + matcher := LessOrEqual(float32(kTwoTo25 + 1)) + + desc := matcher.Description() + expectedDesc := "less than or equal to 3.3554432e+07" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []leTestCase{ + // Signed integers. + leTestCase{int64(-1), true, false, ""}, + leTestCase{int64(kTwoTo25 - 2), true, false, ""}, + leTestCase{int64(kTwoTo25 - 1), true, false, ""}, + leTestCase{int64(kTwoTo25 + 0), true, false, ""}, + leTestCase{int64(kTwoTo25 + 1), true, false, ""}, + leTestCase{int64(kTwoTo25 + 2), true, false, ""}, + leTestCase{int64(kTwoTo25 + 3), false, false, ""}, + + // Unsigned integers. + leTestCase{uint64(0), true, false, ""}, + leTestCase{uint64(kTwoTo25 - 2), true, false, ""}, + leTestCase{uint64(kTwoTo25 - 1), true, false, ""}, + leTestCase{uint64(kTwoTo25 + 0), true, false, ""}, + leTestCase{uint64(kTwoTo25 + 1), true, false, ""}, + leTestCase{uint64(kTwoTo25 + 2), true, false, ""}, + leTestCase{uint64(kTwoTo25 + 3), false, false, ""}, + + // Floating point. + leTestCase{float32(-1), true, false, ""}, + leTestCase{float32(kTwoTo25 - 2), true, false, ""}, + leTestCase{float32(kTwoTo25 - 1), true, false, ""}, + leTestCase{float32(kTwoTo25 + 0), true, false, ""}, + leTestCase{float32(kTwoTo25 + 1), true, false, ""}, + leTestCase{float32(kTwoTo25 + 2), true, false, ""}, + leTestCase{float32(kTwoTo25 + 3), false, false, ""}, + + leTestCase{float64(-1), true, false, ""}, + leTestCase{float64(kTwoTo25 - 2), true, false, ""}, + leTestCase{float64(kTwoTo25 - 1), true, false, ""}, + leTestCase{float64(kTwoTo25 + 0), true, false, ""}, + leTestCase{float64(kTwoTo25 + 1), true, false, ""}, + leTestCase{float64(kTwoTo25 + 2), true, false, ""}, + leTestCase{float64(kTwoTo25 + 3), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessOrEqualTest) Float64AboveExactIntegerRange() { + // Double-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^54-1, 2^54+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo54 = 1 << 54 + matcher := LessOrEqual(float64(kTwoTo54 + 1)) + + desc := matcher.Description() + expectedDesc := "less than or equal to 1.8014398509481984e+16" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []leTestCase{ + // Signed integers. + leTestCase{int64(-1), true, false, ""}, + leTestCase{int64(kTwoTo54 - 2), true, false, ""}, + leTestCase{int64(kTwoTo54 - 1), true, false, ""}, + leTestCase{int64(kTwoTo54 + 0), true, false, ""}, + leTestCase{int64(kTwoTo54 + 1), true, false, ""}, + leTestCase{int64(kTwoTo54 + 2), true, false, ""}, + leTestCase{int64(kTwoTo54 + 3), false, false, ""}, + + // Unsigned integers. + leTestCase{uint64(0), true, false, ""}, + leTestCase{uint64(kTwoTo54 - 2), true, false, ""}, + leTestCase{uint64(kTwoTo54 - 1), true, false, ""}, + leTestCase{uint64(kTwoTo54 + 0), true, false, ""}, + leTestCase{uint64(kTwoTo54 + 1), true, false, ""}, + leTestCase{uint64(kTwoTo54 + 2), true, false, ""}, + leTestCase{uint64(kTwoTo54 + 3), false, false, ""}, + + // Floating point. + leTestCase{float64(-1), true, false, ""}, + leTestCase{float64(kTwoTo54 - 2), true, false, ""}, + leTestCase{float64(kTwoTo54 - 1), true, false, ""}, + leTestCase{float64(kTwoTo54 + 0), true, false, ""}, + leTestCase{float64(kTwoTo54 + 1), true, false, ""}, + leTestCase{float64(kTwoTo54 + 2), true, false, ""}, + leTestCase{float64(kTwoTo54 + 3), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// String literals +//////////////////////////////////////////////////////////////////////// + +func (t *LessOrEqualTest) EmptyString() { + matcher := LessOrEqual("") + desc := matcher.Description() + expectedDesc := "less than or equal to \"\"" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []leTestCase{ + leTestCase{"", true, false, ""}, + leTestCase{"\x00", false, false, ""}, + leTestCase{"a", false, false, ""}, + leTestCase{"foo", false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessOrEqualTest) SingleNullByte() { + matcher := LessOrEqual("\x00") + desc := matcher.Description() + expectedDesc := "less than or equal to \"\x00\"" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []leTestCase{ + leTestCase{"", true, false, ""}, + leTestCase{"\x00", true, false, ""}, + leTestCase{"\x00\x00", false, false, ""}, + leTestCase{"a", false, false, ""}, + leTestCase{"foo", false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessOrEqualTest) LongerString() { + matcher := LessOrEqual("foo\x00") + desc := matcher.Description() + expectedDesc := "less than or equal to \"foo\x00\"" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []leTestCase{ + leTestCase{"", true, false, ""}, + leTestCase{"\x00", true, false, ""}, + leTestCase{"bar", true, false, ""}, + leTestCase{"foo", true, false, ""}, + leTestCase{"foo\x00", true, false, ""}, + leTestCase{"foo\x00\x00", false, false, ""}, + leTestCase{"fooa", false, false, ""}, + leTestCase{"qux", false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/less_than.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/less_than.go new file mode 100644 index 00000000000..8258e45d99d --- /dev/null +++ b/src/mongo/gotools/vendor/src/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/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/less_than_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/less_than_test.go new file mode 100644 index 00000000000..59f5b7f56bd --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/less_than_test.go @@ -0,0 +1,1057 @@ +// 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_test + +import ( + "math" + + . "github.com/smartystreets/assertions/internal/oglematchers" + . "github.com/smartystreets/assertions/internal/ogletest" +) + +//////////////////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////////////////// + +type LessThanTest struct { +} + +func init() { RegisterTestSuite(&LessThanTest{}) } + +type ltTestCase struct { + candidate interface{} + expectedResult bool + shouldBeFatal bool + expectedError string +} + +func (t *LessThanTest) checkTestCases(matcher Matcher, cases []ltTestCase) { + for i, c := range cases { + err := matcher.Matches(c.candidate) + + ExpectThat( + (err == nil), + Equals(c.expectedResult), + "Case %d (candidate %v)", + i, + c.candidate) + + if err == nil { + continue + } + + _, isFatal := err.(*FatalError) + ExpectEq( + c.shouldBeFatal, + isFatal, + "Case %d (candidate %v)", + i, + c.candidate) + + ExpectThat( + err, + Error(Equals(c.expectedError)), + "Case %d (candidate %v)", + i, + c.candidate) + } +} + +//////////////////////////////////////////////////////////////////////// +// Integer literals +//////////////////////////////////////////////////////////////////////// + +func (t *LessThanTest) IntegerCandidateBadTypes() { + matcher := LessThan(int(-150)) + + cases := []ltTestCase{ + ltTestCase{true, false, true, "which is not comparable"}, + ltTestCase{complex64(-151), false, true, "which is not comparable"}, + ltTestCase{complex128(-151), false, true, "which is not comparable"}, + ltTestCase{[...]int{-151}, false, true, "which is not comparable"}, + ltTestCase{make(chan int), false, true, "which is not comparable"}, + ltTestCase{func() {}, false, true, "which is not comparable"}, + ltTestCase{map[int]int{}, false, true, "which is not comparable"}, + ltTestCase{<TestCase{}, false, true, "which is not comparable"}, + ltTestCase{make([]int, 0), false, true, "which is not comparable"}, + ltTestCase{"-151", false, true, "which is not comparable"}, + ltTestCase{ltTestCase{}, false, true, "which is not comparable"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessThanTest) FloatCandidateBadTypes() { + matcher := LessThan(float32(-150)) + + cases := []ltTestCase{ + ltTestCase{true, false, true, "which is not comparable"}, + ltTestCase{complex64(-151), false, true, "which is not comparable"}, + ltTestCase{complex128(-151), false, true, "which is not comparable"}, + ltTestCase{[...]int{-151}, false, true, "which is not comparable"}, + ltTestCase{make(chan int), false, true, "which is not comparable"}, + ltTestCase{func() {}, false, true, "which is not comparable"}, + ltTestCase{map[int]int{}, false, true, "which is not comparable"}, + ltTestCase{<TestCase{}, false, true, "which is not comparable"}, + ltTestCase{make([]int, 0), false, true, "which is not comparable"}, + ltTestCase{"-151", false, true, "which is not comparable"}, + ltTestCase{ltTestCase{}, false, true, "which is not comparable"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessThanTest) StringCandidateBadTypes() { + matcher := LessThan("17") + + cases := []ltTestCase{ + ltTestCase{true, false, true, "which is not comparable"}, + ltTestCase{int(0), false, true, "which is not comparable"}, + ltTestCase{int8(0), false, true, "which is not comparable"}, + ltTestCase{int16(0), false, true, "which is not comparable"}, + ltTestCase{int32(0), false, true, "which is not comparable"}, + ltTestCase{int64(0), false, true, "which is not comparable"}, + ltTestCase{uint(0), false, true, "which is not comparable"}, + ltTestCase{uint8(0), false, true, "which is not comparable"}, + ltTestCase{uint16(0), false, true, "which is not comparable"}, + ltTestCase{uint32(0), false, true, "which is not comparable"}, + ltTestCase{uint64(0), false, true, "which is not comparable"}, + ltTestCase{float32(0), false, true, "which is not comparable"}, + ltTestCase{float64(0), false, true, "which is not comparable"}, + ltTestCase{complex64(-151), false, true, "which is not comparable"}, + ltTestCase{complex128(-151), false, true, "which is not comparable"}, + ltTestCase{[...]int{-151}, false, true, "which is not comparable"}, + ltTestCase{make(chan int), false, true, "which is not comparable"}, + ltTestCase{func() {}, false, true, "which is not comparable"}, + ltTestCase{map[int]int{}, false, true, "which is not comparable"}, + ltTestCase{<TestCase{}, false, true, "which is not comparable"}, + ltTestCase{make([]int, 0), false, true, "which is not comparable"}, + ltTestCase{ltTestCase{}, false, true, "which is not comparable"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessThanTest) BadArgument() { + panicked := false + + defer func() { + ExpectThat(panicked, Equals(true)) + }() + + defer func() { + if r := recover(); r != nil { + panicked = true + } + }() + + LessThan(complex128(0)) +} + +//////////////////////////////////////////////////////////////////////// +// Integer literals +//////////////////////////////////////////////////////////////////////// + +func (t *LessThanTest) NegativeIntegerLiteral() { + matcher := LessThan(-150) + desc := matcher.Description() + expectedDesc := "less than -150" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []ltTestCase{ + // Signed integers. + ltTestCase{-(1 << 30), true, false, ""}, + ltTestCase{-151, true, false, ""}, + ltTestCase{-150, false, false, ""}, + ltTestCase{0, false, false, ""}, + ltTestCase{17, false, false, ""}, + + ltTestCase{int(-(1 << 30)), true, false, ""}, + ltTestCase{int(-151), true, false, ""}, + ltTestCase{int(-150), false, false, ""}, + ltTestCase{int(0), false, false, ""}, + ltTestCase{int(17), false, false, ""}, + + ltTestCase{int8(-127), false, false, ""}, + ltTestCase{int8(0), false, false, ""}, + ltTestCase{int8(17), false, false, ""}, + + ltTestCase{int16(-(1 << 14)), true, false, ""}, + ltTestCase{int16(-151), true, false, ""}, + ltTestCase{int16(-150), false, false, ""}, + ltTestCase{int16(0), false, false, ""}, + ltTestCase{int16(17), false, false, ""}, + + ltTestCase{int32(-(1 << 30)), true, false, ""}, + ltTestCase{int32(-151), true, false, ""}, + ltTestCase{int32(-150), false, false, ""}, + ltTestCase{int32(0), false, false, ""}, + ltTestCase{int32(17), false, false, ""}, + + ltTestCase{int64(-(1 << 30)), true, false, ""}, + ltTestCase{int64(-151), true, false, ""}, + ltTestCase{int64(-150), false, false, ""}, + ltTestCase{int64(0), false, false, ""}, + ltTestCase{int64(17), false, false, ""}, + + // Unsigned integers. + ltTestCase{uint((1 << 32) - 151), false, false, ""}, + ltTestCase{uint(0), false, false, ""}, + ltTestCase{uint(17), false, false, ""}, + + ltTestCase{uint8(0), false, false, ""}, + ltTestCase{uint8(17), false, false, ""}, + ltTestCase{uint8(253), false, false, ""}, + + ltTestCase{uint16((1 << 16) - 151), false, false, ""}, + ltTestCase{uint16(0), false, false, ""}, + ltTestCase{uint16(17), false, false, ""}, + + ltTestCase{uint32((1 << 32) - 151), false, false, ""}, + ltTestCase{uint32(0), false, false, ""}, + ltTestCase{uint32(17), false, false, ""}, + + ltTestCase{uint64((1 << 64) - 151), false, false, ""}, + ltTestCase{uint64(0), false, false, ""}, + ltTestCase{uint64(17), false, false, ""}, + + // Floating point. + ltTestCase{float32(-(1 << 30)), true, false, ""}, + ltTestCase{float32(-151), true, false, ""}, + ltTestCase{float32(-150.1), true, false, ""}, + ltTestCase{float32(-150), false, false, ""}, + ltTestCase{float32(-149.9), false, false, ""}, + ltTestCase{float32(0), false, false, ""}, + ltTestCase{float32(17), false, false, ""}, + ltTestCase{float32(160), false, false, ""}, + + ltTestCase{float64(-(1 << 30)), true, false, ""}, + ltTestCase{float64(-151), true, false, ""}, + ltTestCase{float64(-150.1), true, false, ""}, + ltTestCase{float64(-150), false, false, ""}, + ltTestCase{float64(-149.9), false, false, ""}, + ltTestCase{float64(0), false, false, ""}, + ltTestCase{float64(17), false, false, ""}, + ltTestCase{float64(160), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessThanTest) ZeroIntegerLiteral() { + matcher := LessThan(0) + desc := matcher.Description() + expectedDesc := "less than 0" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []ltTestCase{ + // Signed integers. + ltTestCase{-(1 << 30), true, false, ""}, + ltTestCase{-1, true, false, ""}, + ltTestCase{0, false, false, ""}, + ltTestCase{1, false, false, ""}, + ltTestCase{17, false, false, ""}, + ltTestCase{(1 << 30), false, false, ""}, + + ltTestCase{int(-(1 << 30)), true, false, ""}, + ltTestCase{int(-1), true, false, ""}, + ltTestCase{int(0), false, false, ""}, + ltTestCase{int(1), false, false, ""}, + ltTestCase{int(17), false, false, ""}, + + ltTestCase{int8(-1), true, false, ""}, + ltTestCase{int8(0), false, false, ""}, + ltTestCase{int8(1), false, false, ""}, + + ltTestCase{int16(-(1 << 14)), true, false, ""}, + ltTestCase{int16(-1), true, false, ""}, + ltTestCase{int16(0), false, false, ""}, + ltTestCase{int16(1), false, false, ""}, + ltTestCase{int16(17), false, false, ""}, + + ltTestCase{int32(-(1 << 30)), true, false, ""}, + ltTestCase{int32(-1), true, false, ""}, + ltTestCase{int32(0), false, false, ""}, + ltTestCase{int32(1), false, false, ""}, + ltTestCase{int32(17), false, false, ""}, + + ltTestCase{int64(-(1 << 30)), true, false, ""}, + ltTestCase{int64(-1), true, false, ""}, + ltTestCase{int64(0), false, false, ""}, + ltTestCase{int64(1), false, false, ""}, + ltTestCase{int64(17), false, false, ""}, + + // Unsigned integers. + ltTestCase{uint((1 << 32) - 1), false, false, ""}, + ltTestCase{uint(0), false, false, ""}, + ltTestCase{uint(17), false, false, ""}, + + ltTestCase{uint8(0), false, false, ""}, + ltTestCase{uint8(17), false, false, ""}, + ltTestCase{uint8(253), false, false, ""}, + + ltTestCase{uint16((1 << 16) - 1), false, false, ""}, + ltTestCase{uint16(0), false, false, ""}, + ltTestCase{uint16(17), false, false, ""}, + + ltTestCase{uint32((1 << 32) - 1), false, false, ""}, + ltTestCase{uint32(0), false, false, ""}, + ltTestCase{uint32(17), false, false, ""}, + + ltTestCase{uint64((1 << 64) - 1), false, false, ""}, + ltTestCase{uint64(0), false, false, ""}, + ltTestCase{uint64(17), false, false, ""}, + + // Floating point. + ltTestCase{float32(-(1 << 30)), true, false, ""}, + ltTestCase{float32(-1), true, false, ""}, + ltTestCase{float32(-0.1), true, false, ""}, + ltTestCase{float32(-0.0), false, false, ""}, + ltTestCase{float32(0), false, false, ""}, + ltTestCase{float32(0.1), false, false, ""}, + ltTestCase{float32(17), false, false, ""}, + ltTestCase{float32(160), false, false, ""}, + + ltTestCase{float64(-(1 << 30)), true, false, ""}, + ltTestCase{float64(-1), true, false, ""}, + ltTestCase{float64(-0.1), true, false, ""}, + ltTestCase{float64(-0), false, false, ""}, + ltTestCase{float64(0), false, false, ""}, + ltTestCase{float64(17), false, false, ""}, + ltTestCase{float64(160), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessThanTest) PositiveIntegerLiteral() { + matcher := LessThan(150) + desc := matcher.Description() + expectedDesc := "less than 150" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []ltTestCase{ + // Signed integers. + ltTestCase{-1, true, false, ""}, + ltTestCase{149, true, false, ""}, + ltTestCase{150, false, false, ""}, + ltTestCase{151, false, false, ""}, + + ltTestCase{int(-1), true, false, ""}, + ltTestCase{int(149), true, false, ""}, + ltTestCase{int(150), false, false, ""}, + ltTestCase{int(151), false, false, ""}, + + ltTestCase{int8(-1), true, false, ""}, + ltTestCase{int8(0), true, false, ""}, + ltTestCase{int8(17), true, false, ""}, + ltTestCase{int8(127), true, false, ""}, + + ltTestCase{int16(-1), true, false, ""}, + ltTestCase{int16(149), true, false, ""}, + ltTestCase{int16(150), false, false, ""}, + ltTestCase{int16(151), false, false, ""}, + + ltTestCase{int32(-1), true, false, ""}, + ltTestCase{int32(149), true, false, ""}, + ltTestCase{int32(150), false, false, ""}, + ltTestCase{int32(151), false, false, ""}, + + ltTestCase{int64(-1), true, false, ""}, + ltTestCase{int64(149), true, false, ""}, + ltTestCase{int64(150), false, false, ""}, + ltTestCase{int64(151), false, false, ""}, + + // Unsigned integers. + ltTestCase{uint(0), true, false, ""}, + ltTestCase{uint(149), true, false, ""}, + ltTestCase{uint(150), false, false, ""}, + ltTestCase{uint(151), false, false, ""}, + + ltTestCase{uint8(0), true, false, ""}, + ltTestCase{uint8(127), true, false, ""}, + + ltTestCase{uint16(0), true, false, ""}, + ltTestCase{uint16(149), true, false, ""}, + ltTestCase{uint16(150), false, false, ""}, + ltTestCase{uint16(151), false, false, ""}, + + ltTestCase{uint32(0), true, false, ""}, + ltTestCase{uint32(149), true, false, ""}, + ltTestCase{uint32(150), false, false, ""}, + ltTestCase{uint32(151), false, false, ""}, + + ltTestCase{uint64(0), true, false, ""}, + ltTestCase{uint64(149), true, false, ""}, + ltTestCase{uint64(150), false, false, ""}, + ltTestCase{uint64(151), false, false, ""}, + + // Floating point. + ltTestCase{float32(-1), true, false, ""}, + ltTestCase{float32(149), true, false, ""}, + ltTestCase{float32(149.9), true, false, ""}, + ltTestCase{float32(150), false, false, ""}, + ltTestCase{float32(150.1), false, false, ""}, + ltTestCase{float32(151), false, false, ""}, + + ltTestCase{float64(-1), true, false, ""}, + ltTestCase{float64(149), true, false, ""}, + ltTestCase{float64(149.9), true, false, ""}, + ltTestCase{float64(150), false, false, ""}, + ltTestCase{float64(150.1), false, false, ""}, + ltTestCase{float64(151), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// Float literals +//////////////////////////////////////////////////////////////////////// + +func (t *LessThanTest) NegativeFloatLiteral() { + matcher := LessThan(-150.1) + desc := matcher.Description() + expectedDesc := "less than -150.1" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []ltTestCase{ + // Signed integers. + ltTestCase{-(1 << 30), true, false, ""}, + ltTestCase{-151, true, false, ""}, + ltTestCase{-150, false, false, ""}, + ltTestCase{0, false, false, ""}, + ltTestCase{17, false, false, ""}, + + ltTestCase{int(-(1 << 30)), true, false, ""}, + ltTestCase{int(-151), true, false, ""}, + ltTestCase{int(-150), false, false, ""}, + ltTestCase{int(0), false, false, ""}, + ltTestCase{int(17), false, false, ""}, + + ltTestCase{int8(-127), false, false, ""}, + ltTestCase{int8(0), false, false, ""}, + ltTestCase{int8(17), false, false, ""}, + + ltTestCase{int16(-(1 << 14)), true, false, ""}, + ltTestCase{int16(-151), true, false, ""}, + ltTestCase{int16(-150), false, false, ""}, + ltTestCase{int16(0), false, false, ""}, + ltTestCase{int16(17), false, false, ""}, + + ltTestCase{int32(-(1 << 30)), true, false, ""}, + ltTestCase{int32(-151), true, false, ""}, + ltTestCase{int32(-150), false, false, ""}, + ltTestCase{int32(0), false, false, ""}, + ltTestCase{int32(17), false, false, ""}, + + ltTestCase{int64(-(1 << 30)), true, false, ""}, + ltTestCase{int64(-151), true, false, ""}, + ltTestCase{int64(-150), false, false, ""}, + ltTestCase{int64(0), false, false, ""}, + ltTestCase{int64(17), false, false, ""}, + + // Unsigned integers. + ltTestCase{uint((1 << 32) - 151), false, false, ""}, + ltTestCase{uint(0), false, false, ""}, + ltTestCase{uint(17), false, false, ""}, + + ltTestCase{uint8(0), false, false, ""}, + ltTestCase{uint8(17), false, false, ""}, + ltTestCase{uint8(253), false, false, ""}, + + ltTestCase{uint16((1 << 16) - 151), false, false, ""}, + ltTestCase{uint16(0), false, false, ""}, + ltTestCase{uint16(17), false, false, ""}, + + ltTestCase{uint32((1 << 32) - 151), false, false, ""}, + ltTestCase{uint32(0), false, false, ""}, + ltTestCase{uint32(17), false, false, ""}, + + ltTestCase{uint64((1 << 64) - 151), false, false, ""}, + ltTestCase{uint64(0), false, false, ""}, + ltTestCase{uint64(17), false, false, ""}, + + // Floating point. + ltTestCase{float32(-(1 << 30)), true, false, ""}, + ltTestCase{float32(-151), true, false, ""}, + ltTestCase{float32(-150.2), true, false, ""}, + ltTestCase{float32(-150.1), false, false, ""}, + ltTestCase{float32(-150), false, false, ""}, + ltTestCase{float32(0), false, false, ""}, + ltTestCase{float32(17), false, false, ""}, + ltTestCase{float32(160), false, false, ""}, + + ltTestCase{float64(-(1 << 30)), true, false, ""}, + ltTestCase{float64(-151), true, false, ""}, + ltTestCase{float64(-150.2), true, false, ""}, + ltTestCase{float64(-150.1), false, false, ""}, + ltTestCase{float64(-150), false, false, ""}, + ltTestCase{float64(0), false, false, ""}, + ltTestCase{float64(17), false, false, ""}, + ltTestCase{float64(160), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessThanTest) PositiveFloatLiteral() { + matcher := LessThan(149.9) + desc := matcher.Description() + expectedDesc := "less than 149.9" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []ltTestCase{ + // Signed integers. + ltTestCase{-1, true, false, ""}, + ltTestCase{149, true, false, ""}, + ltTestCase{150, false, false, ""}, + ltTestCase{151, false, false, ""}, + + ltTestCase{int(-1), true, false, ""}, + ltTestCase{int(149), true, false, ""}, + ltTestCase{int(150), false, false, ""}, + ltTestCase{int(151), false, false, ""}, + + ltTestCase{int8(-1), true, false, ""}, + ltTestCase{int8(0), true, false, ""}, + ltTestCase{int8(17), true, false, ""}, + ltTestCase{int8(127), true, false, ""}, + + ltTestCase{int16(-1), true, false, ""}, + ltTestCase{int16(149), true, false, ""}, + ltTestCase{int16(150), false, false, ""}, + ltTestCase{int16(151), false, false, ""}, + + ltTestCase{int32(-1), true, false, ""}, + ltTestCase{int32(149), true, false, ""}, + ltTestCase{int32(150), false, false, ""}, + ltTestCase{int32(151), false, false, ""}, + + ltTestCase{int64(-1), true, false, ""}, + ltTestCase{int64(149), true, false, ""}, + ltTestCase{int64(150), false, false, ""}, + ltTestCase{int64(151), false, false, ""}, + + // Unsigned integers. + ltTestCase{uint(0), true, false, ""}, + ltTestCase{uint(149), true, false, ""}, + ltTestCase{uint(150), false, false, ""}, + ltTestCase{uint(151), false, false, ""}, + + ltTestCase{uint8(0), true, false, ""}, + ltTestCase{uint8(127), true, false, ""}, + + ltTestCase{uint16(0), true, false, ""}, + ltTestCase{uint16(149), true, false, ""}, + ltTestCase{uint16(150), false, false, ""}, + ltTestCase{uint16(151), false, false, ""}, + + ltTestCase{uint32(0), true, false, ""}, + ltTestCase{uint32(149), true, false, ""}, + ltTestCase{uint32(150), false, false, ""}, + ltTestCase{uint32(151), false, false, ""}, + + ltTestCase{uint64(0), true, false, ""}, + ltTestCase{uint64(149), true, false, ""}, + ltTestCase{uint64(150), false, false, ""}, + ltTestCase{uint64(151), false, false, ""}, + + // Floating point. + ltTestCase{float32(-1), true, false, ""}, + ltTestCase{float32(149), true, false, ""}, + ltTestCase{float32(149.8), true, false, ""}, + ltTestCase{float32(149.9), false, false, ""}, + ltTestCase{float32(150), false, false, ""}, + ltTestCase{float32(151), false, false, ""}, + + ltTestCase{float64(-1), true, false, ""}, + ltTestCase{float64(149), true, false, ""}, + ltTestCase{float64(149.8), true, false, ""}, + ltTestCase{float64(149.9), false, false, ""}, + ltTestCase{float64(150), false, false, ""}, + ltTestCase{float64(151), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// Subtle cases +//////////////////////////////////////////////////////////////////////// + +func (t *LessThanTest) Int64NotExactlyRepresentableBySinglePrecision() { + // Single-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo25 = 1 << 25 + matcher := LessThan(int64(kTwoTo25 + 1)) + + desc := matcher.Description() + expectedDesc := "less than 33554433" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []ltTestCase{ + // Signed integers. + ltTestCase{-1, true, false, ""}, + ltTestCase{kTwoTo25 + 0, true, false, ""}, + ltTestCase{kTwoTo25 + 1, false, false, ""}, + ltTestCase{kTwoTo25 + 2, false, false, ""}, + + ltTestCase{int(-1), true, false, ""}, + ltTestCase{int(kTwoTo25 + 0), true, false, ""}, + ltTestCase{int(kTwoTo25 + 1), false, false, ""}, + ltTestCase{int(kTwoTo25 + 2), false, false, ""}, + + ltTestCase{int8(-1), true, false, ""}, + ltTestCase{int8(127), true, false, ""}, + + ltTestCase{int16(-1), true, false, ""}, + ltTestCase{int16(0), true, false, ""}, + ltTestCase{int16(32767), true, false, ""}, + + ltTestCase{int32(-1), true, false, ""}, + ltTestCase{int32(kTwoTo25 + 0), true, false, ""}, + ltTestCase{int32(kTwoTo25 + 1), false, false, ""}, + ltTestCase{int32(kTwoTo25 + 2), false, false, ""}, + + ltTestCase{int64(-1), true, false, ""}, + ltTestCase{int64(kTwoTo25 + 0), true, false, ""}, + ltTestCase{int64(kTwoTo25 + 1), false, false, ""}, + ltTestCase{int64(kTwoTo25 + 2), false, false, ""}, + + // Unsigned integers. + ltTestCase{uint(0), true, false, ""}, + ltTestCase{uint(kTwoTo25 + 0), true, false, ""}, + ltTestCase{uint(kTwoTo25 + 1), false, false, ""}, + ltTestCase{uint(kTwoTo25 + 2), false, false, ""}, + + ltTestCase{uint8(0), true, false, ""}, + ltTestCase{uint8(255), true, false, ""}, + + ltTestCase{uint16(0), true, false, ""}, + ltTestCase{uint16(65535), true, false, ""}, + + ltTestCase{uint32(0), true, false, ""}, + ltTestCase{uint32(kTwoTo25 + 0), true, false, ""}, + ltTestCase{uint32(kTwoTo25 + 1), false, false, ""}, + ltTestCase{uint32(kTwoTo25 + 2), false, false, ""}, + + ltTestCase{uint64(0), true, false, ""}, + ltTestCase{uint64(kTwoTo25 + 0), true, false, ""}, + ltTestCase{uint64(kTwoTo25 + 1), false, false, ""}, + ltTestCase{uint64(kTwoTo25 + 2), false, false, ""}, + + // Floating point. + ltTestCase{float32(-1), true, false, ""}, + ltTestCase{float32(kTwoTo25 - 2), true, false, ""}, + ltTestCase{float32(kTwoTo25 - 1), false, false, ""}, + ltTestCase{float32(kTwoTo25 + 0), false, false, ""}, + ltTestCase{float32(kTwoTo25 + 1), false, false, ""}, + ltTestCase{float32(kTwoTo25 + 2), false, false, ""}, + ltTestCase{float32(kTwoTo25 + 3), false, false, ""}, + + ltTestCase{float64(-1), true, false, ""}, + ltTestCase{float64(kTwoTo25 - 2), true, false, ""}, + ltTestCase{float64(kTwoTo25 - 1), true, false, ""}, + ltTestCase{float64(kTwoTo25 + 0), true, false, ""}, + ltTestCase{float64(kTwoTo25 + 1), false, false, ""}, + ltTestCase{float64(kTwoTo25 + 2), false, false, ""}, + ltTestCase{float64(kTwoTo25 + 3), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessThanTest) Int64NotExactlyRepresentableByDoublePrecision() { + // Double-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^54-1, 2^54+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo54 = 1 << 54 + matcher := LessThan(int64(kTwoTo54 + 1)) + + desc := matcher.Description() + expectedDesc := "less than 18014398509481985" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []ltTestCase{ + // Signed integers. + ltTestCase{-1, true, false, ""}, + ltTestCase{1 << 30, true, false, ""}, + + ltTestCase{int(-1), true, false, ""}, + ltTestCase{int(math.MaxInt32), true, false, ""}, + + ltTestCase{int8(-1), true, false, ""}, + ltTestCase{int8(127), true, false, ""}, + + ltTestCase{int16(-1), true, false, ""}, + ltTestCase{int16(0), true, false, ""}, + ltTestCase{int16(32767), true, false, ""}, + + ltTestCase{int32(-1), true, false, ""}, + ltTestCase{int32(math.MaxInt32), true, false, ""}, + + ltTestCase{int64(-1), true, false, ""}, + ltTestCase{int64(kTwoTo54 - 1), true, false, ""}, + ltTestCase{int64(kTwoTo54 + 0), true, false, ""}, + ltTestCase{int64(kTwoTo54 + 1), false, false, ""}, + ltTestCase{int64(kTwoTo54 + 2), false, false, ""}, + + // Unsigned integers. + ltTestCase{uint(0), true, false, ""}, + ltTestCase{uint(math.MaxUint32), true, false, ""}, + + ltTestCase{uint8(0), true, false, ""}, + ltTestCase{uint8(255), true, false, ""}, + + ltTestCase{uint16(0), true, false, ""}, + ltTestCase{uint16(65535), true, false, ""}, + + ltTestCase{uint32(0), true, false, ""}, + ltTestCase{uint32(math.MaxUint32), true, false, ""}, + + ltTestCase{uint64(0), true, false, ""}, + ltTestCase{uint64(kTwoTo54 - 1), true, false, ""}, + ltTestCase{uint64(kTwoTo54 + 0), true, false, ""}, + ltTestCase{uint64(kTwoTo54 + 1), false, false, ""}, + ltTestCase{uint64(kTwoTo54 + 2), false, false, ""}, + + // Floating point. + ltTestCase{float64(-1), true, false, ""}, + ltTestCase{float64(kTwoTo54 - 2), true, false, ""}, + ltTestCase{float64(kTwoTo54 - 1), false, false, ""}, + ltTestCase{float64(kTwoTo54 + 0), false, false, ""}, + ltTestCase{float64(kTwoTo54 + 1), false, false, ""}, + ltTestCase{float64(kTwoTo54 + 2), false, false, ""}, + ltTestCase{float64(kTwoTo54 + 3), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessThanTest) Uint64NotExactlyRepresentableBySinglePrecision() { + // Single-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo25 = 1 << 25 + matcher := LessThan(uint64(kTwoTo25 + 1)) + + desc := matcher.Description() + expectedDesc := "less than 33554433" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []ltTestCase{ + // Signed integers. + ltTestCase{-1, true, false, ""}, + ltTestCase{kTwoTo25 + 0, true, false, ""}, + ltTestCase{kTwoTo25 + 1, false, false, ""}, + ltTestCase{kTwoTo25 + 2, false, false, ""}, + + ltTestCase{int(-1), true, false, ""}, + ltTestCase{int(kTwoTo25 + 0), true, false, ""}, + ltTestCase{int(kTwoTo25 + 1), false, false, ""}, + ltTestCase{int(kTwoTo25 + 2), false, false, ""}, + + ltTestCase{int8(-1), true, false, ""}, + ltTestCase{int8(127), true, false, ""}, + + ltTestCase{int16(-1), true, false, ""}, + ltTestCase{int16(0), true, false, ""}, + ltTestCase{int16(32767), true, false, ""}, + + ltTestCase{int32(-1), true, false, ""}, + ltTestCase{int32(kTwoTo25 + 0), true, false, ""}, + ltTestCase{int32(kTwoTo25 + 1), false, false, ""}, + ltTestCase{int32(kTwoTo25 + 2), false, false, ""}, + + ltTestCase{int64(-1), true, false, ""}, + ltTestCase{int64(kTwoTo25 + 0), true, false, ""}, + ltTestCase{int64(kTwoTo25 + 1), false, false, ""}, + ltTestCase{int64(kTwoTo25 + 2), false, false, ""}, + + // Unsigned integers. + ltTestCase{uint(0), true, false, ""}, + ltTestCase{uint(kTwoTo25 + 0), true, false, ""}, + ltTestCase{uint(kTwoTo25 + 1), false, false, ""}, + ltTestCase{uint(kTwoTo25 + 2), false, false, ""}, + + ltTestCase{uint8(0), true, false, ""}, + ltTestCase{uint8(255), true, false, ""}, + + ltTestCase{uint16(0), true, false, ""}, + ltTestCase{uint16(65535), true, false, ""}, + + ltTestCase{uint32(0), true, false, ""}, + ltTestCase{uint32(kTwoTo25 + 0), true, false, ""}, + ltTestCase{uint32(kTwoTo25 + 1), false, false, ""}, + ltTestCase{uint32(kTwoTo25 + 2), false, false, ""}, + + ltTestCase{uint64(0), true, false, ""}, + ltTestCase{uint64(kTwoTo25 + 0), true, false, ""}, + ltTestCase{uint64(kTwoTo25 + 1), false, false, ""}, + ltTestCase{uint64(kTwoTo25 + 2), false, false, ""}, + + // Floating point. + ltTestCase{float32(-1), true, false, ""}, + ltTestCase{float32(kTwoTo25 - 2), true, false, ""}, + ltTestCase{float32(kTwoTo25 - 1), false, false, ""}, + ltTestCase{float32(kTwoTo25 + 0), false, false, ""}, + ltTestCase{float32(kTwoTo25 + 1), false, false, ""}, + ltTestCase{float32(kTwoTo25 + 2), false, false, ""}, + ltTestCase{float32(kTwoTo25 + 3), false, false, ""}, + + ltTestCase{float64(-1), true, false, ""}, + ltTestCase{float64(kTwoTo25 - 2), true, false, ""}, + ltTestCase{float64(kTwoTo25 - 1), true, false, ""}, + ltTestCase{float64(kTwoTo25 + 0), true, false, ""}, + ltTestCase{float64(kTwoTo25 + 1), false, false, ""}, + ltTestCase{float64(kTwoTo25 + 2), false, false, ""}, + ltTestCase{float64(kTwoTo25 + 3), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessThanTest) Uint64NotExactlyRepresentableByDoublePrecision() { + // Double-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^54-1, 2^54+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo54 = 1 << 54 + matcher := LessThan(uint64(kTwoTo54 + 1)) + + desc := matcher.Description() + expectedDesc := "less than 18014398509481985" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []ltTestCase{ + // Signed integers. + ltTestCase{-1, true, false, ""}, + ltTestCase{1 << 30, true, false, ""}, + + ltTestCase{int(-1), true, false, ""}, + ltTestCase{int(math.MaxInt32), true, false, ""}, + + ltTestCase{int8(-1), true, false, ""}, + ltTestCase{int8(127), true, false, ""}, + + ltTestCase{int16(-1), true, false, ""}, + ltTestCase{int16(0), true, false, ""}, + ltTestCase{int16(32767), true, false, ""}, + + ltTestCase{int32(-1), true, false, ""}, + ltTestCase{int32(math.MaxInt32), true, false, ""}, + + ltTestCase{int64(-1), true, false, ""}, + ltTestCase{int64(kTwoTo54 - 1), true, false, ""}, + ltTestCase{int64(kTwoTo54 + 0), true, false, ""}, + ltTestCase{int64(kTwoTo54 + 1), false, false, ""}, + ltTestCase{int64(kTwoTo54 + 2), false, false, ""}, + + // Unsigned integers. + ltTestCase{uint(0), true, false, ""}, + ltTestCase{uint(math.MaxUint32), true, false, ""}, + + ltTestCase{uint8(0), true, false, ""}, + ltTestCase{uint8(255), true, false, ""}, + + ltTestCase{uint16(0), true, false, ""}, + ltTestCase{uint16(65535), true, false, ""}, + + ltTestCase{uint32(0), true, false, ""}, + ltTestCase{uint32(math.MaxUint32), true, false, ""}, + + ltTestCase{uint64(0), true, false, ""}, + ltTestCase{uint64(kTwoTo54 - 1), true, false, ""}, + ltTestCase{uint64(kTwoTo54 + 0), true, false, ""}, + ltTestCase{uint64(kTwoTo54 + 1), false, false, ""}, + ltTestCase{uint64(kTwoTo54 + 2), false, false, ""}, + + // Floating point. + ltTestCase{float64(-1), true, false, ""}, + ltTestCase{float64(kTwoTo54 - 2), true, false, ""}, + ltTestCase{float64(kTwoTo54 - 1), false, false, ""}, + ltTestCase{float64(kTwoTo54 + 0), false, false, ""}, + ltTestCase{float64(kTwoTo54 + 1), false, false, ""}, + ltTestCase{float64(kTwoTo54 + 2), false, false, ""}, + ltTestCase{float64(kTwoTo54 + 3), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessThanTest) Float32AboveExactIntegerRange() { + // Single-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo25 = 1 << 25 + matcher := LessThan(float32(kTwoTo25 + 1)) + + desc := matcher.Description() + expectedDesc := "less than 3.3554432e+07" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []ltTestCase{ + // Signed integers. + ltTestCase{int64(-1), true, false, ""}, + ltTestCase{int64(kTwoTo25 - 2), true, false, ""}, + ltTestCase{int64(kTwoTo25 - 1), false, false, ""}, + ltTestCase{int64(kTwoTo25 + 0), false, false, ""}, + ltTestCase{int64(kTwoTo25 + 1), false, false, ""}, + ltTestCase{int64(kTwoTo25 + 2), false, false, ""}, + ltTestCase{int64(kTwoTo25 + 3), false, false, ""}, + + // Unsigned integers. + ltTestCase{uint64(0), true, false, ""}, + ltTestCase{uint64(kTwoTo25 - 2), true, false, ""}, + ltTestCase{uint64(kTwoTo25 - 1), false, false, ""}, + ltTestCase{uint64(kTwoTo25 + 0), false, false, ""}, + ltTestCase{uint64(kTwoTo25 + 1), false, false, ""}, + ltTestCase{uint64(kTwoTo25 + 2), false, false, ""}, + ltTestCase{uint64(kTwoTo25 + 3), false, false, ""}, + + // Floating point. + ltTestCase{float32(-1), true, false, ""}, + ltTestCase{float32(kTwoTo25 - 2), true, false, ""}, + ltTestCase{float32(kTwoTo25 - 1), false, false, ""}, + ltTestCase{float32(kTwoTo25 + 0), false, false, ""}, + ltTestCase{float32(kTwoTo25 + 1), false, false, ""}, + ltTestCase{float32(kTwoTo25 + 2), false, false, ""}, + ltTestCase{float32(kTwoTo25 + 3), false, false, ""}, + + ltTestCase{float64(-1), true, false, ""}, + ltTestCase{float64(kTwoTo25 - 2), true, false, ""}, + ltTestCase{float64(kTwoTo25 - 1), false, false, ""}, + ltTestCase{float64(kTwoTo25 + 0), false, false, ""}, + ltTestCase{float64(kTwoTo25 + 1), false, false, ""}, + ltTestCase{float64(kTwoTo25 + 2), false, false, ""}, + ltTestCase{float64(kTwoTo25 + 3), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessThanTest) Float64AboveExactIntegerRange() { + // Double-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^54-1, 2^54+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo54 = 1 << 54 + matcher := LessThan(float64(kTwoTo54 + 1)) + + desc := matcher.Description() + expectedDesc := "less than 1.8014398509481984e+16" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []ltTestCase{ + // Signed integers. + ltTestCase{int64(-1), true, false, ""}, + ltTestCase{int64(kTwoTo54 - 2), true, false, ""}, + ltTestCase{int64(kTwoTo54 - 1), false, false, ""}, + ltTestCase{int64(kTwoTo54 + 0), false, false, ""}, + ltTestCase{int64(kTwoTo54 + 1), false, false, ""}, + ltTestCase{int64(kTwoTo54 + 2), false, false, ""}, + ltTestCase{int64(kTwoTo54 + 3), false, false, ""}, + + // Unsigned integers. + ltTestCase{uint64(0), true, false, ""}, + ltTestCase{uint64(kTwoTo54 - 2), true, false, ""}, + ltTestCase{uint64(kTwoTo54 - 1), false, false, ""}, + ltTestCase{uint64(kTwoTo54 + 0), false, false, ""}, + ltTestCase{uint64(kTwoTo54 + 1), false, false, ""}, + ltTestCase{uint64(kTwoTo54 + 2), false, false, ""}, + ltTestCase{uint64(kTwoTo54 + 3), false, false, ""}, + + // Floating point. + ltTestCase{float64(-1), true, false, ""}, + ltTestCase{float64(kTwoTo54 - 2), true, false, ""}, + ltTestCase{float64(kTwoTo54 - 1), false, false, ""}, + ltTestCase{float64(kTwoTo54 + 0), false, false, ""}, + ltTestCase{float64(kTwoTo54 + 1), false, false, ""}, + ltTestCase{float64(kTwoTo54 + 2), false, false, ""}, + ltTestCase{float64(kTwoTo54 + 3), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// String literals +//////////////////////////////////////////////////////////////////////// + +func (t *LessThanTest) EmptyString() { + matcher := LessThan("") + desc := matcher.Description() + expectedDesc := "less than \"\"" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []ltTestCase{ + ltTestCase{"", false, false, ""}, + ltTestCase{"\x00", false, false, ""}, + ltTestCase{"a", false, false, ""}, + ltTestCase{"foo", false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessThanTest) SingleNullByte() { + matcher := LessThan("\x00") + desc := matcher.Description() + expectedDesc := "less than \"\x00\"" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []ltTestCase{ + ltTestCase{"", true, false, ""}, + ltTestCase{"\x00", false, false, ""}, + ltTestCase{"a", false, false, ""}, + ltTestCase{"foo", false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessThanTest) LongerString() { + matcher := LessThan("foo\x00") + desc := matcher.Description() + expectedDesc := "less than \"foo\x00\"" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []ltTestCase{ + ltTestCase{"", true, false, ""}, + ltTestCase{"\x00", true, false, ""}, + ltTestCase{"bar", true, false, ""}, + ltTestCase{"foo", true, false, ""}, + ltTestCase{"foo\x00", false, false, ""}, + ltTestCase{"fooa", false, false, ""}, + ltTestCase{"qux", false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/matcher.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/matcher.go new file mode 100644 index 00000000000..78159a0727c --- /dev/null +++ b/src/mongo/gotools/vendor/src/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/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/matches_regexp.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/matches_regexp.go new file mode 100644 index 00000000000..1ed63f30c4e --- /dev/null +++ b/src/mongo/gotools/vendor/src/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/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/matches_regexp_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/matches_regexp_test.go new file mode 100644 index 00000000000..031c6cb3eff --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/matches_regexp_test.go @@ -0,0 +1,92 @@ +// 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_test + +import ( + . "github.com/smartystreets/assertions/internal/oglematchers" + . "github.com/smartystreets/assertions/internal/ogletest" +) + +//////////////////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////////////////// + +type MatchesRegexpTest struct { +} + +func init() { RegisterTestSuite(&MatchesRegexpTest{}) } + +//////////////////////////////////////////////////////////////////////// +// Tests +//////////////////////////////////////////////////////////////////////// + +func (t *MatchesRegexpTest) Description() { + m := MatchesRegexp("foo.*bar") + ExpectEq("matches regexp \"foo.*bar\"", m.Description()) +} + +func (t *MatchesRegexpTest) InvalidRegexp() { + ExpectThat( + func() { MatchesRegexp("(foo") }, + Panics(HasSubstr("missing closing )"))) +} + +func (t *MatchesRegexpTest) CandidateIsNil() { + m := MatchesRegexp("") + err := m.Matches(nil) + + ExpectThat(err, Error(Equals("which is not a string or []byte"))) + ExpectTrue(isFatal(err)) +} + +func (t *MatchesRegexpTest) CandidateIsInteger() { + m := MatchesRegexp("") + err := m.Matches(17) + + ExpectThat(err, Error(Equals("which is not a string or []byte"))) + ExpectTrue(isFatal(err)) +} + +func (t *MatchesRegexpTest) NonMatchingCandidates() { + m := MatchesRegexp("fo[op]\\s+x") + var err error + + err = m.Matches("fon x") + ExpectThat(err, Error(Equals(""))) + ExpectFalse(isFatal(err)) + + err = m.Matches("fopx") + ExpectThat(err, Error(Equals(""))) + ExpectFalse(isFatal(err)) + + err = m.Matches("fop ") + ExpectThat(err, Error(Equals(""))) + ExpectFalse(isFatal(err)) +} + +func (t *MatchesRegexpTest) MatchingCandidates() { + m := MatchesRegexp("fo[op]\\s+x") + var err error + + err = m.Matches("foo x") + ExpectEq(nil, err) + + err = m.Matches("fop x") + ExpectEq(nil, err) + + err = m.Matches("blah blah foo x blah blah") + ExpectEq(nil, err) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/new_matcher.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/new_matcher.go new file mode 100644 index 00000000000..c9d8398ee63 --- /dev/null +++ b/src/mongo/gotools/vendor/src/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/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/not.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/not.go new file mode 100644 index 00000000000..623789fe28a --- /dev/null +++ b/src/mongo/gotools/vendor/src/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/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/not_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/not_test.go new file mode 100644 index 00000000000..9c65b85ef87 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/not_test.go @@ -0,0 +1,108 @@ +// 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_test + +import ( + "errors" + . "github.com/smartystreets/assertions/internal/oglematchers" + . "github.com/smartystreets/assertions/internal/ogletest" + "testing" +) + +//////////////////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////////////////// + +type fakeMatcher struct { + matchFunc func(interface{}) error + description string +} + +func (m *fakeMatcher) Matches(c interface{}) error { + return m.matchFunc(c) +} + +func (m *fakeMatcher) Description() string { + return m.description +} + +type NotTest struct { + +} + +func init() { RegisterTestSuite(&NotTest{}) } +func TestOgletest(t *testing.T) { RunTests(t) } + +//////////////////////////////////////////////////////////////////////// +// Tests +//////////////////////////////////////////////////////////////////////// + +func (t *NotTest) CallsWrapped() { + var suppliedCandidate interface{} + matchFunc := func(c interface{}) error { + suppliedCandidate = c + return nil + } + + wrapped := &fakeMatcher{matchFunc, ""} + matcher := Not(wrapped) + + matcher.Matches(17) + ExpectThat(suppliedCandidate, Equals(17)) +} + +func (t *NotTest) WrappedReturnsTrue() { + matchFunc := func(c interface{}) error { + return nil + } + + wrapped := &fakeMatcher{matchFunc, ""} + matcher := Not(wrapped) + + err := matcher.Matches(0) + ExpectThat(err, Error(Equals(""))) +} + +func (t *NotTest) WrappedReturnsNonFatalError() { + matchFunc := func(c interface{}) error { + return errors.New("taco") + } + + wrapped := &fakeMatcher{matchFunc, ""} + matcher := Not(wrapped) + + err := matcher.Matches(0) + ExpectEq(nil, err) +} + +func (t *NotTest) WrappedReturnsFatalError() { + matchFunc := func(c interface{}) error { + return NewFatalError("taco") + } + + wrapped := &fakeMatcher{matchFunc, ""} + matcher := Not(wrapped) + + err := matcher.Matches(0) + ExpectThat(err, Error(Equals("taco"))) +} + +func (t *NotTest) Description() { + wrapped := &fakeMatcher{nil, "taco"} + matcher := Not(wrapped) + + ExpectEq("not(taco)", matcher.Description()) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/panics.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/panics.go new file mode 100644 index 00000000000..d2cfc97869b --- /dev/null +++ b/src/mongo/gotools/vendor/src/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/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/panics_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/panics_test.go new file mode 100644 index 00000000000..fbb66bf31e2 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/panics_test.go @@ -0,0 +1,141 @@ +// 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_test + +import ( + "errors" + . "github.com/smartystreets/assertions/internal/oglematchers" + . "github.com/smartystreets/assertions/internal/ogletest" +) + +//////////////////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////////////////// + +type PanicsTest struct { + matcherCalled bool + suppliedCandidate interface{} + wrappedError error + + matcher Matcher +} + +func init() { RegisterTestSuite(&PanicsTest{}) } + +func (t *PanicsTest) SetUp(i *TestInfo) { + wrapped := &fakeMatcher{ + func(c interface{}) error { + t.matcherCalled = true + t.suppliedCandidate = c + return t.wrappedError + }, + "foo", + } + + t.matcher = Panics(wrapped) +} + +//////////////////////////////////////////////////////////////////////// +// Tests +//////////////////////////////////////////////////////////////////////// + +func (t *PanicsTest) Description() { + ExpectThat(t.matcher.Description(), Equals("panics with: foo")) +} + +func (t *PanicsTest) CandidateIsNil() { + err := t.matcher.Matches(nil) + + ExpectThat(err, Error(Equals("which is not a zero-arg function"))) + ExpectTrue(isFatal(err)) +} + +func (t *PanicsTest) CandidateIsString() { + err := t.matcher.Matches("taco") + + ExpectThat(err, Error(Equals("which is not a zero-arg function"))) + ExpectTrue(isFatal(err)) +} + +func (t *PanicsTest) CandidateTakesArgs() { + err := t.matcher.Matches(func(i int) string { return "" }) + + ExpectThat(err, Error(Equals("which is not a zero-arg function"))) + ExpectTrue(isFatal(err)) +} + +func (t *PanicsTest) CallsFunction() { + callCount := 0 + t.matcher.Matches(func() string { + callCount++ + return "" + }) + + ExpectThat(callCount, Equals(1)) +} + +func (t *PanicsTest) FunctionDoesntPanic() { + err := t.matcher.Matches(func() {}) + + ExpectThat(err, Error(Equals("which didn't panic"))) + ExpectFalse(isFatal(err)) +} + +func (t *PanicsTest) CallsWrappedMatcher() { + expectedErr := 17 + t.wrappedError = errors.New("") + t.matcher.Matches(func() { panic(expectedErr) }) + + ExpectThat(t.suppliedCandidate, Equals(expectedErr)) +} + +func (t *PanicsTest) WrappedReturnsTrue() { + err := t.matcher.Matches(func() { panic("") }) + + ExpectEq(nil, err) +} + +func (t *PanicsTest) WrappedReturnsFatalErrorWithoutText() { + t.wrappedError = NewFatalError("") + err := t.matcher.Matches(func() { panic(17) }) + + ExpectThat(err, Error(Equals("which panicked with: 17"))) + ExpectFalse(isFatal(err)) +} + +func (t *PanicsTest) WrappedReturnsFatalErrorWithText() { + t.wrappedError = NewFatalError("which blah") + err := t.matcher.Matches(func() { panic(17) }) + + ExpectThat(err, Error(Equals("which panicked with: 17, which blah"))) + ExpectFalse(isFatal(err)) +} + +func (t *PanicsTest) WrappedReturnsNonFatalErrorWithoutText() { + t.wrappedError = errors.New("") + err := t.matcher.Matches(func() { panic(17) }) + + ExpectThat(err, Error(Equals("which panicked with: 17"))) + ExpectFalse(isFatal(err)) +} + +func (t *PanicsTest) WrappedReturnsNonFatalErrorWithText() { + t.wrappedError = errors.New("which blah") + err := t.matcher.Matches(func() { panic(17) }) + + ExpectThat(err, Error(Equals("which panicked with: 17, which blah"))) + ExpectFalse(isFatal(err)) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/pointee.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/pointee.go new file mode 100644 index 00000000000..c5383f2402f --- /dev/null +++ b/src/mongo/gotools/vendor/src/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/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/pointee_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/pointee_test.go new file mode 100644 index 00000000000..3bb72a702be --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/pointee_test.go @@ -0,0 +1,152 @@ +// 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_test + +import ( + "errors" + . "github.com/smartystreets/assertions/internal/oglematchers" + . "github.com/smartystreets/assertions/internal/ogletest" + "testing" +) + +//////////////////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////////////////// + +type PointeeTest struct {} +func init() { RegisterTestSuite(&PointeeTest{}) } + +func TestPointee(t *testing.T) { RunTests(t) } + +//////////////////////////////////////////////////////////////////////// +// Tests +//////////////////////////////////////////////////////////////////////// + +func (t *PointeeTest) Description() { + wrapped := &fakeMatcher{nil, "taco"} + matcher := Pointee(wrapped) + + ExpectEq("pointee(taco)", matcher.Description()) +} + +func (t *PointeeTest) CandidateIsNotAPointer() { + matcher := Pointee(HasSubstr("")) + err := matcher.Matches([]byte{}) + + ExpectThat(err, Error(Equals("which is not a pointer"))) + ExpectTrue(isFatal(err)) +} + +func (t *PointeeTest) CandidateIsANilLiteral() { + matcher := Pointee(HasSubstr("")) + err := matcher.Matches(nil) + + ExpectThat(err, Error(Equals("which is not a pointer"))) + ExpectTrue(isFatal(err)) +} + +func (t *PointeeTest) CandidateIsANilPointer() { + matcher := Pointee(HasSubstr("")) + err := matcher.Matches((*int)(nil)) + + ExpectThat(err, Error(Equals(""))) + ExpectTrue(isFatal(err)) +} + +func (t *PointeeTest) CallsWrapped() { + var suppliedCandidate interface{} + matchFunc := func(c interface{}) error { + suppliedCandidate = c + return nil + } + + wrapped := &fakeMatcher{matchFunc, ""} + matcher := Pointee(wrapped) + + someSlice := []byte{} + matcher.Matches(&someSlice) + ExpectThat(suppliedCandidate, IdenticalTo(someSlice)) +} + +func (t *PointeeTest) WrappedReturnsOkay() { + matchFunc := func(c interface{}) error { + return nil + } + + wrapped := &fakeMatcher{matchFunc, ""} + matcher := Pointee(wrapped) + + err := matcher.Matches(new(int)) + ExpectEq(nil, err) +} + +func (t *PointeeTest) WrappedReturnsNonFatalNonEmptyError() { + matchFunc := func(c interface{}) error { + return errors.New("taco") + } + + wrapped := &fakeMatcher{matchFunc, ""} + matcher := Pointee(wrapped) + + i := 17 + err := matcher.Matches(&i) + ExpectFalse(isFatal(err)) + ExpectThat(err, Error(Equals("taco"))) +} + +func (t *PointeeTest) WrappedReturnsNonFatalEmptyError() { + matchFunc := func(c interface{}) error { + return errors.New("") + } + + wrapped := &fakeMatcher{matchFunc, ""} + matcher := Pointee(wrapped) + + i := 17 + err := matcher.Matches(&i) + ExpectFalse(isFatal(err)) + ExpectThat(err, Error(HasSubstr("whose pointee"))) + ExpectThat(err, Error(HasSubstr("17"))) +} + +func (t *PointeeTest) WrappedReturnsFatalNonEmptyError() { + matchFunc := func(c interface{}) error { + return NewFatalError("taco") + } + + wrapped := &fakeMatcher{matchFunc, ""} + matcher := Pointee(wrapped) + + i := 17 + err := matcher.Matches(&i) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("taco"))) +} + +func (t *PointeeTest) WrappedReturnsFatalEmptyError() { + matchFunc := func(c interface{}) error { + return NewFatalError("") + } + + wrapped := &fakeMatcher{matchFunc, ""} + matcher := Pointee(wrapped) + + i := 17 + err := matcher.Matches(&i) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(HasSubstr("whose pointee"))) + ExpectThat(err, Error(HasSubstr("17"))) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/transform_description.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/transform_description.go new file mode 100644 index 00000000000..f79d0c03db1 --- /dev/null +++ b/src/mongo/gotools/vendor/src/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) +} |