diff options
author | Ramon Fernandez <ramon@mongodb.com> | 2016-08-25 16:34:34 -0400 |
---|---|---|
committer | Ramon Fernandez <ramon@mongodb.com> | 2016-08-25 16:54:18 -0400 |
commit | c330c9991ab45e7d0685d53e699ef26dba065660 (patch) | |
tree | 3dc5cd06b5f6c7eaaa4cb20cbe763504c14a772b /src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock | |
parent | eb62b862d5ebf179a1bcd9f394070e69c30188ab (diff) | |
download | mongo-c330c9991ab45e7d0685d53e699ef26dba065660.tar.gz |
Import tools: 5b883d86fdb4df55036d5dba2ca6f9dfa0750b44 from branch v3.3
ref: 1ac1389bda..5b883d86fd
for: 3.3.12
SERVER-25814 Initial vendor import: tools
Diffstat (limited to 'src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock')
44 files changed, 7237 insertions, 0 deletions
diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/.gitignore b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/.gitignore new file mode 100644 index 00000000000..dd8fc7468f4 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/.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/oglemock/.travis.yml b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/.travis.yml new file mode 100644 index 00000000000..b97211926e8 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/.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/oglemock/LICENSE b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/LICENSE new file mode 100644 index 00000000000..d6456956733 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/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/oglemock/README.md b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/README.md new file mode 100644 index 00000000000..c5cb5c06b33 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/README.md @@ -0,0 +1,103 @@ +[![GoDoc](https://godoc.org/github.com/smartystreets/assertions/internal/oglemock?status.svg)](https://godoc.org/github.com/smartystreets/assertions/internal/oglemock) + +`oglemock` is a mocking framework for the Go programming language with the +following features: + + * An extensive and extensible set of matchers for expressing call + expectations (provided by the [oglematchers][] package). + + * Clean, readable output that tells you exactly what you need to know. + + * Style and semantics similar to [Google Mock][googlemock] and + [Google JS Test][google-js-test]. + + * Seamless integration with the [ogletest][] unit testing framework. + +It can be integrated into any testing framework (including Go's `testing` +package), but out of the box support is built in to [ogletest][] and that is the +easiest place to use it. + + +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 `oglemock` and its dependencies, and to +keep them up to date: + + go get -u github.com/smartystreets/assertions/internal/oglemock + go get -u github.com/smartystreets/assertions/internal/oglemock/createmock + +Those commands will install the `oglemock` package itself, along with the +`createmock` tool that is used to auto-generate mock types. + + +Generating and using mock types +------------------------------- + +Automatically generating a mock implementation of an interface is easy. If you +want to mock interfaces `Bar` and `Baz` from package `foo`, simply run the +following: + + createmock foo Bar Baz + +That will print source code that can be saved to a file and used in your tests. +For example, to create a `mock_io` package containing mock implementations of +`io.Reader` and `io.Writer`: + + mkdir mock_io + createmock io Reader Writer > mock_io/mock_io.go + +The new package will be named `mock_io`, and contain types called `MockReader` +and `MockWriter`, which implement `io.Reader` and `io.Writer` respectively. + +For each generated mock type, there is a corresponding function for creating an +instance of that type given a `Controller` object (see below). For example, to +create a mock reader: + +```go +someController := [...] // See next section. +someReader := mock_io.NewMockReader(someController, "Mock file reader") +``` + +The snippet above creates a mock `io.Reader` that reports failures to +`someController`. The reader can subsequently have expectations set up and be +passed to your code under test that uses an `io.Reader`. + + +Getting ahold of a controller +----------------------------- + +[oglemock.Controller][controller-ref] is used to create mock objects, and to set +up and verify expectations for them. You can create one by calling +`NewController` with an `ErrorReporter`, which is the basic type used to +interface between `oglemock` and the testing framework within which it is being +used. + +If you are using [ogletest][] you don't need to worry about any of this, since +the `TestInfo` struct provided to your test's `SetUp` function already contains +a working `Controller` that you can use to create mock object, and you can use +the built-in `ExpectCall` function for setting expectations. (See the +[ogletest documentation][ogletest-docs] for more info.) Otherwise, you will need +to implement the simple [ErrorReporter interface][reporter-ref] for your test +environment. + + +Documentation +------------- + +For thorough documentation, including information on how to set up expectations, +see [here][oglemock-docs]. + + +[controller-ref]: http://godoc.org/github.com/smartystreets/assertions/internal/oglemock#Controller +[reporter-ref]: http://godoc.org/github.com/smartystreets/assertions/internal/oglemock#ErrorReporter +[golang-install]: http://golang.org/doc/install.html +[google-js-test]: http://code.google.com/p/google-js-test/ +[googlemock]: http://code.google.com/p/googlemock/ +[oglematchers]: https://github.com/smartystreets/assertions/internal/oglematchers +[oglemock-docs]: http://godoc.org/github.com/smartystreets/assertions/internal/oglemock +[ogletest]: https://github.com/smartystreets/assertions/internal/ogletest +[ogletest-docs]: http://godoc.org/github.com/smartystreets/assertions/internal/ogletest diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/action.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/action.go new file mode 100644 index 00000000000..9fd40d81fe8 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/action.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 oglemock + +import ( + "reflect" +) + +// Action represents an action to be taken in response to a call to a mock +// method. +type Action interface { + // Set the signature of the function with which this action is being used. + // This must be called before Invoke is called. + SetSignature(signature reflect.Type) error + + // Invoke runs the specified action, given the arguments to the mock method. + // It returns zero or more values that may be treated as the return values of + // the method. If the action doesn't return any values, it may return the nil + // slice. + // + // You must call SetSignature before calling Invoke. + Invoke(methodArgs []interface{}) []interface{} +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/controller.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/controller.go new file mode 100644 index 00000000000..93a1d6239e1 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/controller.go @@ -0,0 +1,480 @@ +// 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 oglemock + +import ( + "errors" + "fmt" + "log" + "math" + "reflect" + "sync" +) + +// PartialExpecation is a function that should be called exactly once with +// expected arguments or matchers in order to set up an expected method call. +// See Controller.ExpectMethodCall below. It returns an expectation that can be +// further modified (e.g. by calling WillOnce). +// +// If the arguments are of the wrong type, the function reports a fatal error +// and returns nil. +type PartialExpecation func(...interface{}) Expectation + +// Controller represents an object that implements the central logic of +// oglemock: recording and verifying expectations, responding to mock method +// calls, and so on. +type Controller interface { + // ExpectCall expresses an expectation that the method of the given name + // should be called on the supplied mock object. It returns a function that + // should be called with the expected arguments, matchers for the arguments, + // or a mix of both. + // + // fileName and lineNumber should indicate the line on which the expectation + // was made, if known. + // + // For example: + // + // mockWriter := [...] + // controller.ExpectCall(mockWriter, "Write", "foo.go", 17)(ElementsAre(0x1)) + // .WillOnce(Return(1, nil)) + // + // If the mock object doesn't have a method of the supplied name, the + // function reports a fatal error and returns nil. + ExpectCall( + o MockObject, + methodName string, + fileName string, + lineNumber int) PartialExpecation + + // Finish causes the controller to check for any unsatisfied expectations, + // and report them as errors if they exist. + // + // The controller may panic if any of its methods (including this one) are + // called after Finish is called. + Finish() + + // HandleMethodCall looks for a registered expectation matching the call of + // the given method on mock object o, invokes the appropriate action (if + // any), and returns the values returned by that action (if any). + // + // If the action returns nothing, the controller returns zero values. If + // there is no matching expectation, the controller reports an error and + // returns zero values. + // + // If the mock object doesn't have a method of the supplied name, the + // arguments are of the wrong type, or the action returns the wrong types, + // the function reports a fatal error. + // + // HandleMethodCall is exported for the sake of mock implementations, and + // should not be used directly. + HandleMethodCall( + o MockObject, + methodName string, + fileName string, + lineNumber int, + args []interface{}) []interface{} +} + +// methodMap represents a map from method name to set of expectations for that +// method. +type methodMap map[string][]*InternalExpectation + +// objectMap represents a map from mock object ID to a methodMap for that object. +type objectMap map[uintptr]methodMap + +// NewController sets up a fresh controller, without any expectations set, and +// configures the controller to use the supplied error reporter. +func NewController(reporter ErrorReporter) Controller { + return &controllerImpl{reporter, sync.RWMutex{}, objectMap{}} +} + +type controllerImpl struct { + reporter ErrorReporter + + mutex sync.RWMutex + expectationsByObject objectMap // Protected by mutex +} + +// Return the list of registered expectations for the named method of the +// supplied object, or an empty slice if none have been registered. When this +// method returns, it is guaranteed that c.expectationsByObject has an entry +// for the object. +// +// c.mutex must be held for reading. +func (c *controllerImpl) getExpectationsLocked( + o MockObject, + methodName string) []*InternalExpectation { + id := o.Oglemock_Id() + + // Look up the mock object. + expectationsByMethod, ok := c.expectationsByObject[id] + if !ok { + expectationsByMethod = methodMap{} + c.expectationsByObject[id] = expectationsByMethod + } + + result, ok := expectationsByMethod[methodName] + if !ok { + return []*InternalExpectation{} + } + + return result +} + +// Add an expectation to the list registered for the named method of the +// supplied mock object. +// +// c.mutex must be held for writing. +func (c *controllerImpl) addExpectationLocked( + o MockObject, + methodName string, + exp *InternalExpectation) { + // Get the existing list. + existing := c.getExpectationsLocked(o, methodName) + + // Store a modified list. + id := o.Oglemock_Id() + c.expectationsByObject[id][methodName] = append(existing, exp) +} + +func (c *controllerImpl) ExpectCall( + o MockObject, + methodName string, + fileName string, + lineNumber int) PartialExpecation { + // Find the signature for the requested method. + ov := reflect.ValueOf(o) + method := ov.MethodByName(methodName) + if method.Kind() == reflect.Invalid { + c.reporter.ReportFatalError( + fileName, + lineNumber, + errors.New("Unknown method: "+methodName)) + return nil + } + + partialAlreadyCalled := false // Protected by c.mutex + return func(args ...interface{}) Expectation { + c.mutex.Lock() + defer c.mutex.Unlock() + + // This function should only be called once. + if partialAlreadyCalled { + c.reporter.ReportFatalError( + fileName, + lineNumber, + errors.New("Partial expectation called more than once.")) + return nil + } + + partialAlreadyCalled = true + + // Make sure that the number of args is legal. Keep in mind that the + // method's type has an extra receiver arg. + if len(args) != method.Type().NumIn() { + c.reporter.ReportFatalError( + fileName, + lineNumber, + errors.New( + fmt.Sprintf( + "Expectation for %s given wrong number of arguments: "+ + "expected %d, got %d.", + methodName, + method.Type().NumIn(), + len(args)))) + return nil + } + + // Create an expectation and insert it into the controller's map. + exp := InternalNewExpectation( + c.reporter, + method.Type(), + args, + fileName, + lineNumber) + + c.addExpectationLocked(o, methodName, exp) + + // Return the expectation to the user. + return exp + } +} + +func (c *controllerImpl) Finish() { + c.mutex.Lock() + defer c.mutex.Unlock() + + // Check whether the minimum cardinality for each registered expectation has + // been satisfied. + for _, expectationsByMethod := range c.expectationsByObject { + for methodName, expectations := range expectationsByMethod { + for _, exp := range expectations { + exp.mutex.Lock() + defer exp.mutex.Unlock() + + minCardinality, _ := computeCardinalityLocked(exp) + if exp.NumMatches < minCardinality { + c.reporter.ReportError( + exp.FileName, + exp.LineNumber, + errors.New( + fmt.Sprintf( + "Unsatisfied expectation; expected %s to be called "+ + "at least %d times; called %d times.", + methodName, + minCardinality, + exp.NumMatches))) + } + } + } + } +} + +// expectationMatches checks the matchers for the expectation against the +// supplied arguments. +func expectationMatches(exp *InternalExpectation, args []interface{}) bool { + matchers := exp.ArgMatchers + if len(args) != len(matchers) { + panic("expectationMatches: len(args)") + } + + // Check each matcher. + for i, matcher := range matchers { + if err := matcher.Matches(args[i]); err != nil { + return false + } + } + + return true +} + +// Return the expectation that matches the supplied arguments. If there is more +// than one such expectation, the one furthest along in the list for the method +// is returned. If there is no such expectation, nil is returned. +// +// c.mutex must be held for reading. +func (c *controllerImpl) chooseExpectationLocked( + o MockObject, + methodName string, + args []interface{}) *InternalExpectation { + // Do we have any expectations for this method? + expectations := c.getExpectationsLocked(o, methodName) + if len(expectations) == 0 { + return nil + } + + for i := len(expectations) - 1; i >= 0; i-- { + if expectationMatches(expectations[i], args) { + return expectations[i] + } + } + + return nil +} + +// makeZeroReturnValues creates a []interface{} containing appropriate zero +// values for returning from the supplied method type. +func makeZeroReturnValues(signature reflect.Type) []interface{} { + result := make([]interface{}, signature.NumOut()) + + for i, _ := range result { + outType := signature.Out(i) + zeroVal := reflect.Zero(outType) + result[i] = zeroVal.Interface() + } + + return result +} + +// computeCardinality decides on the [min, max] range of the number of expected +// matches for the supplied expectations, according to the rules documented in +// expectation.go. +// +// exp.mutex must be held for reading. +func computeCardinalityLocked(exp *InternalExpectation) (min, max uint) { + // Explicit cardinality. + if exp.ExpectedNumMatches >= 0 { + min = uint(exp.ExpectedNumMatches) + max = min + return + } + + // Implicit count based on one-time actions. + if len(exp.OneTimeActions) != 0 { + min = uint(len(exp.OneTimeActions)) + max = min + + // If there is a fallback action, this is only a lower bound. + if exp.FallbackAction != nil { + max = math.MaxUint32 + } + + return + } + + // Implicit lack of restriction based on a fallback action being configured. + if exp.FallbackAction != nil { + min = 0 + max = math.MaxUint32 + return + } + + // Implicit cardinality of one. + min = 1 + max = 1 + return +} + +// chooseAction returns the action that should be invoked for the i'th match to +// the supplied expectation (counting from zero). If the implicit "return zero +// values" action should be used, it returns nil. +// +// exp.mutex must be held for reading. +func chooseActionLocked(i uint, exp *InternalExpectation) Action { + // Exhaust one-time actions first. + if i < uint(len(exp.OneTimeActions)) { + return exp.OneTimeActions[i] + } + + // Fallback action (or nil if none is configured). + return exp.FallbackAction +} + +// Find an action for the method call, updating expectation match state in the +// process. Return either an action that should be invoked or a set of zero +// values to return immediately. +// +// This is split out from HandleMethodCall in order to more easily avoid +// invoking the action with locks held. +func (c *controllerImpl) chooseActionAndUpdateExpectations( + o MockObject, + methodName string, + fileName string, + lineNumber int, + args []interface{}, +) (action Action, zeroVals []interface{}) { + c.mutex.Lock() + defer c.mutex.Unlock() + + // Find the signature for the requested method. + ov := reflect.ValueOf(o) + method := ov.MethodByName(methodName) + if method.Kind() == reflect.Invalid { + c.reporter.ReportFatalError( + fileName, + lineNumber, + errors.New("Unknown method: "+methodName), + ) + + // Should never get here in real code. + log.Println("ReportFatalError unexpectedly returned.") + return + } + + // HACK(jacobsa): Make sure we got the correct number of arguments. This will + // need to be refined when issue #5 (variadic methods) is handled. + if len(args) != method.Type().NumIn() { + c.reporter.ReportFatalError( + fileName, + lineNumber, + errors.New( + fmt.Sprintf( + "Wrong number of arguments: expected %d; got %d", + method.Type().NumIn(), + len(args), + ), + ), + ) + + // Should never get here in real code. + log.Println("ReportFatalError unexpectedly returned.") + return + } + + // Find an expectation matching this call. + expectation := c.chooseExpectationLocked(o, methodName, args) + if expectation == nil { + c.reporter.ReportError( + fileName, + lineNumber, + errors.New( + fmt.Sprintf("Unexpected call to %s with args: %v", methodName, args), + ), + ) + + zeroVals = makeZeroReturnValues(method.Type()) + return + } + + expectation.mutex.Lock() + defer expectation.mutex.Unlock() + + // Increase the number of matches recorded, and check whether we're over the + // number expected. + expectation.NumMatches++ + _, maxCardinality := computeCardinalityLocked(expectation) + if expectation.NumMatches > maxCardinality { + c.reporter.ReportError( + expectation.FileName, + expectation.LineNumber, + errors.New( + fmt.Sprintf( + "Unexpected call to %s: "+ + "expected to be called at most %d times; called %d times.", + methodName, + maxCardinality, + expectation.NumMatches, + ), + ), + ) + + zeroVals = makeZeroReturnValues(method.Type()) + return + } + + // Choose an action to invoke. If there is none, just return zero values. + action = chooseActionLocked(expectation.NumMatches-1, expectation) + if action == nil { + zeroVals = makeZeroReturnValues(method.Type()) + return + } + + // Let the action take over. + return +} + +func (c *controllerImpl) HandleMethodCall( + o MockObject, + methodName string, + fileName string, + lineNumber int, + args []interface{}, +) []interface{} { + // Figure out whether to invoke an action or return zero values. + action, zeroVals := c.chooseActionAndUpdateExpectations( + o, + methodName, + fileName, + lineNumber, + args, + ) + + if action != nil { + return action.Invoke(args) + } + + return zeroVals +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/controller_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/controller_test.go new file mode 100644 index 00000000000..0ff5e5c41bb --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/controller_test.go @@ -0,0 +1,1249 @@ +// 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 oglemock_test + +import ( + . "github.com/smartystreets/assertions/internal/oglematchers" + . "github.com/smartystreets/assertions/internal/oglemock" + . "github.com/smartystreets/assertions/internal/ogletest" + "reflect" +) + +//////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////// + +type errorReport struct { + fileName string + lineNumber int + err error +} + +type fakeErrorReporter struct { + errors []errorReport + fatalErrors []errorReport +} + +func (r *fakeErrorReporter) ReportError(fileName string, lineNumber int, err error) { + report := errorReport{fileName, lineNumber, err} + r.errors = append(r.errors, report) +} + +func (r *fakeErrorReporter) ReportFatalError(fileName string, lineNumber int, err error) { + report := errorReport{fileName, lineNumber, err} + r.fatalErrors = append(r.fatalErrors, report) +} + +type trivialMockObject struct { + id uintptr + desc string +} + +func (o *trivialMockObject) Oglemock_Id() uintptr { + return o.id +} + +func (o *trivialMockObject) Oglemock_Description() string { + return o.desc +} + +// Method being mocked +func (o *trivialMockObject) StringToInt(s string) int { + return 0 +} + +// Method being mocked +func (o *trivialMockObject) TwoIntsToString(i, j int) string { + return "" +} + +type ControllerTest struct { + reporter fakeErrorReporter + controller Controller + + mock1 MockObject + mock2 MockObject +} + +func (t *ControllerTest) SetUp(c *TestInfo) { + t.reporter.errors = make([]errorReport, 0) + t.reporter.fatalErrors = make([]errorReport, 0) + t.controller = NewController(&t.reporter) + + t.mock1 = &trivialMockObject{17, "taco"} + t.mock2 = &trivialMockObject{19, "burrito"} +} + +func init() { RegisterTestSuite(&ControllerTest{}) } + +//////////////////////////////////////////////////////////// +// Tests +//////////////////////////////////////////////////////////// + +func (t *ControllerTest) FinishWithoutAnyEvents() { + t.controller.Finish() + ExpectEq(0, len(t.reporter.errors)) + ExpectEq(0, len(t.reporter.fatalErrors)) +} + +func (t *ControllerTest) HandleCallForUnknownObject() { + p := []byte{255} + t.controller.HandleMethodCall( + t.mock1, + "StringToInt", + "taco.go", + 112, + []interface{}{p}) + + // The error should be reported immediately. + AssertEq(1, len(t.reporter.errors)) + AssertEq(0, len(t.reporter.fatalErrors)) + + ExpectEq("taco.go", t.reporter.errors[0].fileName) + ExpectEq(112, t.reporter.errors[0].lineNumber) + ExpectThat(t.reporter.errors[0].err, Error(HasSubstr("Unexpected"))) + ExpectThat(t.reporter.errors[0].err, Error(HasSubstr("StringToInt"))) + ExpectThat(t.reporter.errors[0].err, Error(HasSubstr("[255]"))) + + // Finish should change nothing. + t.controller.Finish() + + ExpectEq(1, len(t.reporter.errors)) + ExpectEq(0, len(t.reporter.fatalErrors)) +} + +func (t *ControllerTest) ExpectCallForUnknownMethod() { + ExpectEq( + nil, + t.controller.ExpectCall(t.mock1, "Frobnicate", "burrito.go", 117)) + + // A fatal error should be reported immediately. + AssertEq(0, len(t.reporter.errors)) + AssertEq(1, len(t.reporter.fatalErrors)) + + report := t.reporter.fatalErrors[0] + ExpectEq("burrito.go", report.fileName) + ExpectEq(117, report.lineNumber) + ExpectThat(report.err, Error(HasSubstr("Unknown method"))) + ExpectThat(report.err, Error(HasSubstr("Frobnicate"))) +} + +func (t *ControllerTest) PartialExpectationGivenWrongNumberOfArgs() { + ExpectEq( + nil, + t.controller.ExpectCall(t.mock1, "TwoIntsToString", "burrito.go", 117)( + 17, 19, 23)) + + // A fatal error should be reported immediately. + AssertEq(0, len(t.reporter.errors)) + AssertEq(1, len(t.reporter.fatalErrors)) + + report := t.reporter.fatalErrors[0] + ExpectEq("burrito.go", report.fileName) + ExpectEq(117, report.lineNumber) + ExpectThat(report.err, Error(HasSubstr("TwoIntsToString"))) + ExpectThat(report.err, Error(HasSubstr("arguments"))) + ExpectThat(report.err, Error(HasSubstr("expected 2"))) + ExpectThat(report.err, Error(HasSubstr("got 3"))) +} + +func (t *ControllerTest) PartialExpectationCalledTwice() { + partial := t.controller.ExpectCall(t.mock1, "StringToInt", "burrito.go", 117) + AssertNe(nil, partial("taco")) + ExpectEq(nil, partial("taco")) + + // A fatal error should be reported immediately. + AssertEq(0, len(t.reporter.errors)) + AssertEq(1, len(t.reporter.fatalErrors)) + + report := t.reporter.fatalErrors[0] + ExpectEq("burrito.go", report.fileName) + ExpectEq(117, report.lineNumber) + ExpectThat(report.err, Error(HasSubstr("called more than once"))) +} + +func (t *ControllerTest) HandleMethodCallForUnknownMethod() { + ExpectEq( + nil, + t.controller.HandleMethodCall( + t.mock1, + "Frobnicate", + "burrito.go", + 117, + []interface{}{})) + + // A fatal error should be reported immediately. + AssertEq(0, len(t.reporter.errors)) + AssertEq(1, len(t.reporter.fatalErrors)) + + report := t.reporter.fatalErrors[0] + ExpectEq("burrito.go", report.fileName) + ExpectEq(117, report.lineNumber) + ExpectThat(report.err, Error(HasSubstr("Unknown method"))) + ExpectThat(report.err, Error(HasSubstr("Frobnicate"))) +} + +func (t *ControllerTest) HandleMethodCallGivenWrongNumberOfArgs() { + t.controller.ExpectCall(t.mock1, "TwoIntsToString", "", 0)(17, 19) + + ExpectEq( + nil, + t.controller.HandleMethodCall( + t.mock1, + "TwoIntsToString", + "burrito.go", + 117, + []interface{}{17, 19, 23})) + + // A fatal error should be reported immediately. + AssertEq(0, len(t.reporter.errors)) + AssertEq(1, len(t.reporter.fatalErrors)) + + report := t.reporter.fatalErrors[0] + ExpectEq("burrito.go", report.fileName) + ExpectEq(117, report.lineNumber) + ExpectThat(report.err, Error(HasSubstr("arguments"))) + ExpectThat(report.err, Error(HasSubstr("expected 2"))) + ExpectThat(report.err, Error(HasSubstr("got 3"))) +} + +func (t *ControllerTest) ExpectThenNonMatchingCall() { + // Expectation -- set up a fallback action to make it optional. + partial := t.controller.ExpectCall( + t.mock1, + "TwoIntsToString", + "burrito.go", + 117) + + exp := partial(LessThan(10), Equals(2)) + exp.WillRepeatedly(Return("")) + + // Call + t.controller.HandleMethodCall( + t.mock1, + "TwoIntsToString", + "taco.go", + 112, + []interface{}{8, 1}) + + // The error should be reported immediately. + AssertEq(1, len(t.reporter.errors)) + AssertEq(0, len(t.reporter.fatalErrors)) + + ExpectEq("taco.go", t.reporter.errors[0].fileName) + ExpectEq(112, t.reporter.errors[0].lineNumber) + ExpectThat(t.reporter.errors[0].err, Error(HasSubstr("Unexpected"))) + ExpectThat(t.reporter.errors[0].err, Error(HasSubstr("TwoIntsToString"))) + ExpectThat(t.reporter.errors[0].err, Error(HasSubstr("[8 1]"))) + + // Finish should change nothing. + t.controller.Finish() + + ExpectEq(1, len(t.reporter.errors)) + ExpectEq(0, len(t.reporter.fatalErrors)) +} + +func (t *ControllerTest) ExplicitCardinalityNotSatisfied() { + // Expectation -- set up an explicit cardinality of three. + partial := t.controller.ExpectCall( + t.mock1, + "StringToInt", + "burrito.go", + 117) + + exp := partial(HasSubstr("")) + exp.Times(3) + + // Call twice. + t.controller.HandleMethodCall( + t.mock1, + "StringToInt", + "", + 0, + []interface{}{""}) + + t.controller.HandleMethodCall( + t.mock1, + "StringToInt", + "", + 0, + []interface{}{""}) + + // The error should not yet be reported. + ExpectEq(0, len(t.reporter.errors)) + ExpectEq(0, len(t.reporter.fatalErrors)) + + // Finish should cause the error to be reported. + t.controller.Finish() + + AssertEq(1, len(t.reporter.errors)) + AssertEq(0, len(t.reporter.fatalErrors)) + + ExpectEq("burrito.go", t.reporter.errors[0].fileName) + ExpectEq(117, t.reporter.errors[0].lineNumber) + ExpectThat(t.reporter.errors[0].err, Error(HasSubstr("Unsatisfied"))) + ExpectThat(t.reporter.errors[0].err, Error(HasSubstr("StringToInt"))) + ExpectThat(t.reporter.errors[0].err, Error(HasSubstr("at least 3 times"))) + ExpectThat(t.reporter.errors[0].err, Error(HasSubstr("called 2 times"))) +} + +func (t *ControllerTest) ImplicitOneTimeActionCountNotSatisfied() { + // Expectation -- add three one-time actions. + partial := t.controller.ExpectCall( + t.mock1, + "StringToInt", + "burrito.go", + 117) + + exp := partial(HasSubstr("")) + exp.WillOnce(Return(0)) + exp.WillOnce(Return(1)) + exp.WillOnce(Return(2)) + + // Call twice. + t.controller.HandleMethodCall( + t.mock1, + "StringToInt", + "", + 0, + []interface{}{""}) + + t.controller.HandleMethodCall( + t.mock1, + "StringToInt", + "", + 0, + []interface{}{""}) + + // The error should not yet be reported. + ExpectEq(0, len(t.reporter.errors)) + ExpectEq(0, len(t.reporter.fatalErrors)) + + // Finish should cause the error to be reported. + t.controller.Finish() + + AssertEq(1, len(t.reporter.errors)) + AssertEq(0, len(t.reporter.fatalErrors)) + + ExpectEq("burrito.go", t.reporter.errors[0].fileName) + ExpectEq(117, t.reporter.errors[0].lineNumber) + ExpectThat(t.reporter.errors[0].err, Error(HasSubstr("Unsatisfied"))) + ExpectThat(t.reporter.errors[0].err, Error(HasSubstr("StringToInt"))) + ExpectThat(t.reporter.errors[0].err, Error(HasSubstr("at least 3 times"))) + ExpectThat(t.reporter.errors[0].err, Error(HasSubstr("called 2 times"))) +} + +func (t *ControllerTest) ImplicitOneTimeActionLowerBoundNotSatisfied() { + // Expectation -- add three one-time actions and a fallback. + partial := t.controller.ExpectCall( + t.mock1, + "StringToInt", + "burrito.go", + 117) + + exp := partial(HasSubstr("")) + exp.WillOnce(Return(0)) + exp.WillOnce(Return(1)) + exp.WillOnce(Return(2)) + exp.WillRepeatedly(Return(3)) + + // Call twice. + t.controller.HandleMethodCall( + t.mock1, + "StringToInt", + "", + 0, + []interface{}{""}) + + t.controller.HandleMethodCall( + t.mock1, + "StringToInt", + "", + 0, + []interface{}{""}) + + // The error should not yet be reported. + ExpectEq(0, len(t.reporter.errors)) + ExpectEq(0, len(t.reporter.fatalErrors)) + + // Finish should cause the error to be reported. + t.controller.Finish() + + AssertEq(1, len(t.reporter.errors)) + AssertEq(0, len(t.reporter.fatalErrors)) + + ExpectEq("burrito.go", t.reporter.errors[0].fileName) + ExpectEq(117, t.reporter.errors[0].lineNumber) + ExpectThat(t.reporter.errors[0].err, Error(HasSubstr("Unsatisfied"))) + ExpectThat(t.reporter.errors[0].err, Error(HasSubstr("StringToInt"))) + ExpectThat(t.reporter.errors[0].err, Error(HasSubstr("at least 3 times"))) + ExpectThat(t.reporter.errors[0].err, Error(HasSubstr("called 2 times"))) +} + +func (t *ControllerTest) ImplicitCardinalityOfOneNotSatisfied() { + // Expectation -- add no actions. + partial := t.controller.ExpectCall( + t.mock1, + "StringToInt", + "burrito.go", + 117) + + partial(HasSubstr("")) + + // Don't call. + + // The error should not yet be reported. + ExpectEq(0, len(t.reporter.errors)) + ExpectEq(0, len(t.reporter.fatalErrors)) + + // Finish should cause the error to be reported. + t.controller.Finish() + + AssertEq(1, len(t.reporter.errors)) + AssertEq(0, len(t.reporter.fatalErrors)) + + ExpectEq("burrito.go", t.reporter.errors[0].fileName) + ExpectEq(117, t.reporter.errors[0].lineNumber) + ExpectThat(t.reporter.errors[0].err, Error(HasSubstr("Unsatisfied"))) + ExpectThat(t.reporter.errors[0].err, Error(HasSubstr("StringToInt"))) + ExpectThat(t.reporter.errors[0].err, Error(HasSubstr("at least 1 time"))) + ExpectThat(t.reporter.errors[0].err, Error(HasSubstr("called 0 times"))) +} + +func (t *ControllerTest) ExplicitCardinalityOverrun() { + // Expectation -- call times(2). + partial := t.controller.ExpectCall( + t.mock1, + "StringToInt", + "burrito.go", + 117) + + exp := partial(HasSubstr("")) + exp.Times(2) + + // Call three times. + t.controller.HandleMethodCall( + t.mock1, + "StringToInt", + "", + 0, + []interface{}{""}) + + t.controller.HandleMethodCall( + t.mock1, + "StringToInt", + "", + 0, + []interface{}{""}) + + t.controller.HandleMethodCall( + t.mock1, + "StringToInt", + "", + 0, + []interface{}{""}) + + // The error should be reported immediately. + AssertEq(1, len(t.reporter.errors)) + AssertEq(0, len(t.reporter.fatalErrors)) + + ExpectEq("burrito.go", t.reporter.errors[0].fileName) + ExpectEq(117, t.reporter.errors[0].lineNumber) + ExpectThat(t.reporter.errors[0].err, Error(HasSubstr("Unexpected"))) + ExpectThat(t.reporter.errors[0].err, Error(HasSubstr("StringToInt"))) + ExpectThat(t.reporter.errors[0].err, Error(HasSubstr("at most 2 times"))) + ExpectThat(t.reporter.errors[0].err, Error(HasSubstr("called 3 times"))) + + // Finish should change nothing. + t.controller.Finish() + + ExpectEq(1, len(t.reporter.errors)) + ExpectEq(0, len(t.reporter.fatalErrors)) +} + +func (t *ControllerTest) ImplicitOneTimeActionCountOverrun() { + // Expectation -- add a one-time action. + partial := t.controller.ExpectCall( + t.mock1, + "StringToInt", + "burrito.go", + 117) + + exp := partial(HasSubstr("")) + exp.WillOnce(Return(0)) + + // Call twice. + t.controller.HandleMethodCall( + t.mock1, + "StringToInt", + "", + 0, + []interface{}{""}) + + t.controller.HandleMethodCall( + t.mock1, + "StringToInt", + "", + 0, + []interface{}{""}) + + // The error should be reported immediately. + AssertEq(1, len(t.reporter.errors)) + AssertEq(0, len(t.reporter.fatalErrors)) + + ExpectEq("burrito.go", t.reporter.errors[0].fileName) + ExpectEq(117, t.reporter.errors[0].lineNumber) + ExpectThat(t.reporter.errors[0].err, Error(HasSubstr("Unexpected"))) + ExpectThat(t.reporter.errors[0].err, Error(HasSubstr("StringToInt"))) + ExpectThat(t.reporter.errors[0].err, Error(HasSubstr("at most 1 time"))) + ExpectThat(t.reporter.errors[0].err, Error(HasSubstr("called 2 times"))) + + // Finish should change nothing. + t.controller.Finish() + + ExpectEq(1, len(t.reporter.errors)) + ExpectEq(0, len(t.reporter.fatalErrors)) +} + +func (t *ControllerTest) ImplicitCardinalityOfOneOverrun() { + // Expectation -- don't add any actions. + partial := t.controller.ExpectCall( + t.mock1, + "StringToInt", + "burrito.go", + 117) + + partial(HasSubstr("")) + + // Call twice. + t.controller.HandleMethodCall( + t.mock1, + "StringToInt", + "", + 0, + []interface{}{""}) + + t.controller.HandleMethodCall( + t.mock1, + "StringToInt", + "", + 0, + []interface{}{""}) + + // The error should be reported immediately. + AssertEq(1, len(t.reporter.errors)) + AssertEq(0, len(t.reporter.fatalErrors)) + + ExpectEq("burrito.go", t.reporter.errors[0].fileName) + ExpectEq(117, t.reporter.errors[0].lineNumber) + ExpectThat(t.reporter.errors[0].err, Error(HasSubstr("Unexpected"))) + ExpectThat(t.reporter.errors[0].err, Error(HasSubstr("StringToInt"))) + ExpectThat(t.reporter.errors[0].err, Error(HasSubstr("at most 1 time"))) + ExpectThat(t.reporter.errors[0].err, Error(HasSubstr("called 2 times"))) + + // Finish should change nothing. + t.controller.Finish() + + ExpectEq(1, len(t.reporter.errors)) + ExpectEq(0, len(t.reporter.fatalErrors)) +} + +func (t *ControllerTest) ExplicitCardinalitySatisfied() { + // Expectation -- set up an explicit cardinality of two. + partial := t.controller.ExpectCall( + t.mock1, + "StringToInt", + "burrito.go", + 117) + + exp := partial(HasSubstr("")) + exp.Times(2) + + // Call twice. + t.controller.HandleMethodCall( + t.mock1, + "StringToInt", + "", + 0, + []interface{}{""}) + + t.controller.HandleMethodCall( + t.mock1, + "StringToInt", + "", + 0, + []interface{}{""}) + + // There should be no errors. + t.controller.Finish() + + ExpectEq(0, len(t.reporter.errors)) + ExpectEq(0, len(t.reporter.fatalErrors)) +} + +func (t *ControllerTest) ImplicitOneTimeActionCountSatisfied() { + // Expectation -- set up two one-time actions. + partial := t.controller.ExpectCall( + t.mock1, + "StringToInt", + "burrito.go", + 117) + + exp := partial(HasSubstr("")) + exp.WillOnce(Return(0)) + exp.WillOnce(Return(1)) + + // Call twice. + t.controller.HandleMethodCall( + t.mock1, + "StringToInt", + "", + 0, + []interface{}{""}) + + t.controller.HandleMethodCall( + t.mock1, + "StringToInt", + "", + 0, + []interface{}{""}) + + // There should be no errors. + t.controller.Finish() + + ExpectEq(0, len(t.reporter.errors)) + ExpectEq(0, len(t.reporter.fatalErrors)) +} + +func (t *ControllerTest) ImplicitOneTimeActionLowerBoundJustSatisfied() { + // Expectation -- set up two one-time actions and a fallback. + partial := t.controller.ExpectCall( + t.mock1, + "StringToInt", + "burrito.go", + 117) + + exp := partial(HasSubstr("")) + exp.WillOnce(Return(0)) + exp.WillOnce(Return(1)) + exp.WillRepeatedly(Return(2)) + + // Call twice. + t.controller.HandleMethodCall( + t.mock1, + "StringToInt", + "", + 0, + []interface{}{""}) + + t.controller.HandleMethodCall( + t.mock1, + "StringToInt", + "", + 0, + []interface{}{""}) + + // There should be no errors. + t.controller.Finish() + + ExpectEq(0, len(t.reporter.errors)) + ExpectEq(0, len(t.reporter.fatalErrors)) +} + +func (t *ControllerTest) ImplicitOneTimeActionLowerBoundMoreThanSatisfied() { + // Expectation -- set up two one-time actions and a fallback. + partial := t.controller.ExpectCall( + t.mock1, + "StringToInt", + "burrito.go", + 117) + + exp := partial(HasSubstr("")) + exp.WillOnce(Return(0)) + exp.WillOnce(Return(1)) + exp.WillRepeatedly(Return(2)) + + // Call four times. + t.controller.HandleMethodCall( + t.mock1, + "StringToInt", + "", + 0, + []interface{}{""}) + + t.controller.HandleMethodCall( + t.mock1, + "StringToInt", + "", + 0, + []interface{}{""}) + + t.controller.HandleMethodCall( + t.mock1, + "StringToInt", + "", + 0, + []interface{}{""}) + + t.controller.HandleMethodCall( + t.mock1, + "StringToInt", + "", + 0, + []interface{}{""}) + + // There should be no errors. + t.controller.Finish() + + ExpectEq(0, len(t.reporter.errors)) + ExpectEq(0, len(t.reporter.fatalErrors)) +} + +func (t *ControllerTest) FallbackActionConfiguredWithZeroCalls() { + // Expectation -- set up a fallback action. + partial := t.controller.ExpectCall( + t.mock1, + "StringToInt", + "burrito.go", + 117) + + exp := partial(HasSubstr("")) + exp.WillRepeatedly(Return(0)) + + // Don't call. + + // There should be no errors. + t.controller.Finish() + + ExpectEq(0, len(t.reporter.errors)) + ExpectEq(0, len(t.reporter.fatalErrors)) +} + +func (t *ControllerTest) FallbackActionConfiguredWithMultipleCalls() { + // Expectation -- set up a fallback action. + partial := t.controller.ExpectCall( + t.mock1, + "StringToInt", + "burrito.go", + 117) + + exp := partial(HasSubstr("")) + exp.WillRepeatedly(Return(0)) + + // Call twice. + t.controller.HandleMethodCall( + t.mock1, + "StringToInt", + "", + 0, + []interface{}{""}) + + t.controller.HandleMethodCall( + t.mock1, + "StringToInt", + "", + 0, + []interface{}{""}) + + // There should be no errors. + t.controller.Finish() + + ExpectEq(0, len(t.reporter.errors)) + ExpectEq(0, len(t.reporter.fatalErrors)) +} + +func (t *ControllerTest) ImplicitCardinalityOfOneSatisfied() { + // Expectation -- don't add actions. + partial := t.controller.ExpectCall( + t.mock1, + "StringToInt", + "burrito.go", + 117) + + partial(HasSubstr("")) + + // Call once. + t.controller.HandleMethodCall( + t.mock1, + "StringToInt", + "", + 0, + []interface{}{""}) + + // There should be no errors. + t.controller.Finish() + + ExpectEq(0, len(t.reporter.errors)) + ExpectEq(0, len(t.reporter.fatalErrors)) +} + +func (t *ControllerTest) InvokesOneTimeActions() { + var res []interface{} + + // Expectation -- set up two one-time actions. + partial := t.controller.ExpectCall( + t.mock1, + "StringToInt", + "burrito.go", + 117) + + suppliedArg := "" + expectedReturn := 17 + + f := func(s string) int { + suppliedArg = s + return expectedReturn + } + + exp := partial(HasSubstr("")) + exp.WillOnce(Invoke(f)) + exp.WillOnce(Return(1)) + + AssertThat(t.reporter.fatalErrors, ElementsAre()) + + // Call 0 + res = t.controller.HandleMethodCall( + t.mock1, + "StringToInt", + "", + 0, + []interface{}{"taco"}) + + ExpectEq("taco", suppliedArg) + ExpectThat(res, ElementsAre(IdenticalTo(expectedReturn))) + + // Call 1 + res = t.controller.HandleMethodCall( + t.mock1, + "StringToInt", + "", + 0, + []interface{}{""}) + + ExpectThat(len(res), Equals(1)) + ExpectThat(res[0], Equals(1)) +} + +func (t *ControllerTest) InvokesFallbackActionAfterOneTimeActions() { + var res []interface{} + + // Expectation -- set up two one-time actions and a fallback. + partial := t.controller.ExpectCall( + t.mock1, + "StringToInt", + "burrito.go", + 117) + + exp := partial(HasSubstr("")) + exp.WillOnce(Return(0)) + exp.WillOnce(Return(1)) + exp.WillRepeatedly(Return(2)) + + // Call 0 + res = t.controller.HandleMethodCall( + t.mock1, + "StringToInt", + "", + 0, + []interface{}{""}) + + ExpectThat(len(res), Equals(1)) + ExpectThat(res[0], Equals(0)) + + // Call 1 + res = t.controller.HandleMethodCall( + t.mock1, + "StringToInt", + "", + 0, + []interface{}{""}) + + ExpectThat(len(res), Equals(1)) + ExpectThat(res[0], Equals(1)) + + // Call 2 + res = t.controller.HandleMethodCall( + t.mock1, + "StringToInt", + "", + 0, + []interface{}{""}) + + ExpectThat(len(res), Equals(1)) + ExpectThat(res[0], Equals(2)) + + // Call 3 + res = t.controller.HandleMethodCall( + t.mock1, + "StringToInt", + "", + 0, + []interface{}{""}) + + ExpectThat(len(res), Equals(1)) + ExpectThat(res[0], Equals(2)) +} + +func (t *ControllerTest) InvokesFallbackActionWithoutOneTimeActions() { + var res []interface{} + + // Expectation -- set up only a fallback action. + partial := t.controller.ExpectCall( + t.mock1, + "StringToInt", + "burrito.go", + 117) + + exp := partial(HasSubstr("")) + exp.WillRepeatedly(Return(2)) + + // Call 0 + res = t.controller.HandleMethodCall( + t.mock1, + "StringToInt", + "", + 0, + []interface{}{""}) + + ExpectThat(len(res), Equals(1)) + ExpectThat(res[0], Equals(2)) + + // Call 1 + res = t.controller.HandleMethodCall( + t.mock1, + "StringToInt", + "", + 0, + []interface{}{""}) + + ExpectThat(len(res), Equals(1)) + ExpectThat(res[0], Equals(2)) + + // Call 2 + res = t.controller.HandleMethodCall( + t.mock1, + "StringToInt", + "", + 0, + []interface{}{""}) + + ExpectThat(len(res), Equals(1)) + ExpectThat(res[0], Equals(2)) +} + +func (t *ControllerTest) ImplicitActionReturnsZeroInts() { + var res []interface{} + + // Expectation -- set up a cardinality of two. + partial := t.controller.ExpectCall( + t.mock1, + "StringToInt", + "burrito.go", + 117) + + exp := partial(HasSubstr("")) + exp.Times(2) + + // Call 0 + res = t.controller.HandleMethodCall( + t.mock1, + "StringToInt", + "", + 0, + []interface{}{""}) + + ExpectThat(len(res), Equals(1)) + ExpectThat(reflect.TypeOf(res[0]), Equals(reflect.TypeOf(int(0)))) + ExpectThat(res[0], Equals(0)) + + // Call 1 + res = t.controller.HandleMethodCall( + t.mock1, + "StringToInt", + "", + 0, + []interface{}{""}) + + ExpectThat(len(res), Equals(1)) + ExpectThat(reflect.TypeOf(res[0]), Equals(reflect.TypeOf(int(0)))) + ExpectThat(res[0], Equals(0)) +} + +func (t *ControllerTest) ImplicitActionReturnsEmptyStrings() { + var res []interface{} + + // Expectation -- set up a cardinality of two. + partial := t.controller.ExpectCall( + t.mock1, + "TwoIntsToString", + "burrito.go", + 117) + + exp := partial(LessThan(100), LessThan(100)) + exp.Times(2) + + // Call 0 + res = t.controller.HandleMethodCall( + t.mock1, + "TwoIntsToString", + "", + 0, + []interface{}{0, 0}) + + ExpectThat(len(res), Equals(1)) + ExpectThat(res[0], Equals("")) + + // Call 1 + res = t.controller.HandleMethodCall( + t.mock1, + "TwoIntsToString", + "", + 0, + []interface{}{0, 0}) + + ExpectThat(len(res), Equals(1)) + ExpectThat(res[0], Equals("")) +} + +func (t *ControllerTest) ExpectationsAreMatchedLastToFirst() { + var res []interface{} + + // General expectation + partial := t.controller.ExpectCall( + t.mock1, + "StringToInt", + "burrito.go", + 117) + + exp := partial(HasSubstr("")) + exp.WillRepeatedly(Return(17)) + + // More specific expectation + partial = t.controller.ExpectCall( + t.mock1, + "StringToInt", + "burrito.go", + 117) + + exp = partial(Equals("taco")) + exp.WillRepeatedly(Return(19)) + + // Call -- the second expectation should match. + res = t.controller.HandleMethodCall( + t.mock1, + "StringToInt", + "", + 0, + []interface{}{"taco"}) + + ExpectThat(len(res), Equals(1)) + ExpectThat(res[0], Equals(19)) + + // Call -- the first expectation should match because the second doesn't. + res = t.controller.HandleMethodCall( + t.mock1, + "StringToInt", + "", + 0, + []interface{}{"burrito"}) + + ExpectThat(len(res), Equals(1)) + ExpectThat(res[0], Equals(17)) +} + +func (t *ControllerTest) ExpectationsAreSegregatedByMockObject() { + var res []interface{} + + // Expectation for mock1 -- return 17. + partial := t.controller.ExpectCall( + t.mock1, + "StringToInt", + "burrito.go", + 117) + + exp := partial(HasSubstr("")) + exp.WillRepeatedly(Return(17)) + + // Expectation for mock2 -- return 19. + partial = t.controller.ExpectCall( + t.mock2, + "StringToInt", + "burrito.go", + 117) + + exp = partial(HasSubstr("")) + exp.WillRepeatedly(Return(19)) + + // Call mock1. + res = t.controller.HandleMethodCall( + t.mock1, + "StringToInt", + "", + 0, + []interface{}{""}) + + ExpectThat(len(res), Equals(1)) + ExpectThat(res[0], Equals(17)) + + // Call mock2. + res = t.controller.HandleMethodCall( + t.mock2, + "StringToInt", + "", + 0, + []interface{}{""}) + + ExpectThat(len(res), Equals(1)) + ExpectThat(res[0], Equals(19)) +} + +func (t *ControllerTest) ExpectationsAreSegregatedByMethodName() { + var res []interface{} + + // Expectation for StringToInt + partial := t.controller.ExpectCall( + t.mock1, + "StringToInt", + "burrito.go", + 117) + + exp := partial(HasSubstr("")) + exp.WillRepeatedly(Return(17)) + + // Expectation for TwoIntsToString + partial = t.controller.ExpectCall( + t.mock1, + "TwoIntsToString", + "burrito.go", + 117) + + exp = partial(1, 2) + exp.WillRepeatedly(Return("taco")) + + // Call StringToInt. + res = t.controller.HandleMethodCall( + t.mock1, + "StringToInt", + "", + 0, + []interface{}{""}) + + ExpectThat(len(res), Equals(1)) + ExpectThat(res[0], Equals(17)) + + // Call TwoIntsToString. + res = t.controller.HandleMethodCall( + t.mock1, + "TwoIntsToString", + "", + 0, + []interface{}{1, 2}) + + ExpectThat(len(res), Equals(1)) + ExpectThat(res[0], Equals("taco")) +} + +func (t *ControllerTest) ActionCallsAgainMatchingDifferentExpectation() { + var res []interface{} + + // Expectation for StringToInt + partial := t.controller.ExpectCall( + t.mock1, + "StringToInt", + "burrito.go", + 117) + + exp := partial(HasSubstr("")) + exp.WillOnce(Return(17)) + + // Expectation for TwoIntsToString -- pretend we call StringToInt. + partial = t.controller.ExpectCall( + t.mock1, + "TwoIntsToString", + "burrito.go", + 117) + + exp = partial(1, 2) + exp.WillOnce(Invoke(func(int, int) string { + t.controller.HandleMethodCall( + t.mock1, + "StringToInt", + "taco.go", + 112, + []interface{}{""}) + + return "queso" + })) + + // Call TwoIntsToString. + res = t.controller.HandleMethodCall( + t.mock1, + "TwoIntsToString", + "", + 0, + []interface{}{1, 2}) + + AssertThat(res, ElementsAre("queso")) + + // Finish. Everything should be satisfied. + t.controller.Finish() + + ExpectThat(t.reporter.errors, ElementsAre()) + ExpectThat(t.reporter.fatalErrors, ElementsAre()) +} + +func (t *ControllerTest) ActionCallsAgainMatchingSameExpectation() { + var res []interface{} + + // Expectation for StringToInt -- should be called twice. The first time it + // should call itself. + partial := t.controller.ExpectCall( + t.mock1, + "StringToInt", + "burrito.go", + 117) + + exp := partial(HasSubstr("")) + exp.Times(2) + exp.WillOnce(Invoke(func(string) int { + subCallRes := t.controller.HandleMethodCall( + t.mock1, + "StringToInt", + "taco.go", + 112, + []interface{}{""}) + + return subCallRes[0].(int) + 19 + })) + + exp.WillOnce(Return(17)) + + // Call. + res = t.controller.HandleMethodCall( + t.mock1, + "StringToInt", + "", + 0, + []interface{}{""}) + + AssertThat(res, ElementsAre(17+19)) + + // Finish. Everything should be satisfied. + t.controller.Finish() + + ExpectThat(t.reporter.errors, ElementsAre()) + ExpectThat(t.reporter.fatalErrors, ElementsAre()) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/createmock/createmock.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/createmock/createmock.go new file mode 100644 index 00000000000..c5427dc8ba9 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/createmock/createmock.go @@ -0,0 +1,245 @@ +// 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. + +// createmock is used to generate source code for mock versions of interfaces +// from installed packages. +package main + +import ( + "errors" + "flag" + "fmt" + "go/build" + "io/ioutil" + "log" + "os" + "os/exec" + "path" + "regexp" + "text/template" + + // Ensure that the generate package, which is used by the generated code, is + // installed by goinstall. + _ "github.com/smartystreets/assertions/internal/oglemock/generate" +) + +var fSamePackage = flag.Bool( + "same_package", + false, + "Generate output appropriate for including in the same package as the "+ + "mocked interfaces.") + +// A template for generated code that is used to print the result. +const tmplStr = ` +{{$interfacePkgPath := .InterfacePkgPath}} + +package main + +import ( + {{range $identifier, $import := .Imports}} + {{$identifier}} "{{$import}}" + {{end}} +) + +func getTypeForPtr(ptr interface{}) reflect.Type { + return reflect.TypeOf(ptr).Elem() +} + +func main() { + // Reduce noise in logging output. + log.SetFlags(0) + + interfaces := []reflect.Type{ + {{range $typeName := .TypeNames}} + getTypeForPtr((*{{pathBase $interfacePkgPath}}.{{$typeName}})(nil)), + {{end}} + } + + err := generate.GenerateMockSource( + os.Stdout, + "{{.OutputPkgPath}}", + interfaces) + + if err != nil { + log.Fatalf("Error generating mock source: %v", err) + } +} +` + +// A map from import identifier to package to use that identifier for, +// containing elements for each import needed by the generated code. +type importMap map[string]string + +type tmplArg struct { + // The full path of the package from which the interfaces come. + InterfacePkgPath string + + // The package path to assume for the generated code. + OutputPkgPath string + + // Imports needed by the generated code. + Imports importMap + + // Types to be mocked, relative to their package's name. + TypeNames []string +} + +var unknownPackageRegexp = regexp.MustCompile( + `tool\.go:\d+:\d+: cannot find package "([^"]+)"`) + +var undefinedInterfaceRegexp = regexp.MustCompile(`tool\.go:\d+: undefined: [\pL_0-9]+\.([\pL_0-9]+)`) + +// Does the 'go build' output indicate that a package wasn't found? If so, +// return the name of the package. +func findUnknownPackage(output []byte) *string { + if match := unknownPackageRegexp.FindSubmatch(output); match != nil { + res := string(match[1]) + return &res + } + + return nil +} + +// Does the 'go build' output indicate that an interface wasn't found? If so, +// return the name of the interface. +func findUndefinedInterface(output []byte) *string { + if match := undefinedInterfaceRegexp.FindSubmatch(output); match != nil { + res := string(match[1]) + return &res + } + + return nil +} + +// Split out from main so that deferred calls are executed even in the event of +// an error. +func run() error { + // Reduce noise in logging output. + log.SetFlags(0) + + // Check the command-line arguments. + flag.Parse() + + cmdLineArgs := flag.Args() + if len(cmdLineArgs) < 2 { + return errors.New("Usage: createmock [package] [interface ...]") + } + + // Create a temporary directory inside of $GOPATH to hold generated code. + buildPkg, err := build.Import("github.com/smartystreets/assertions/internal/oglemock", "", build.FindOnly) + if err != nil { + return errors.New(fmt.Sprintf("Couldn't find oglemock in $GOPATH: %v", err)) + } + + tmpDir, err := ioutil.TempDir(buildPkg.SrcRoot, "tmp-createmock-") + if err != nil { + return errors.New(fmt.Sprintf("Creating temp dir: %v", err)) + } + + defer os.RemoveAll(tmpDir) + + // Create a file to hold generated code. + codeFile, err := os.Create(path.Join(tmpDir, "tool.go")) + if err != nil { + return errors.New(fmt.Sprintf("Couldn't create a file to hold code: %v", err)) + } + + // Create an appropriate path for the built binary. + binaryPath := path.Join(tmpDir, "tool") + + // Create an appropriate template argument. + arg := tmplArg{ + InterfacePkgPath: cmdLineArgs[0], + TypeNames: cmdLineArgs[1:], + } + + if *fSamePackage { + arg.OutputPkgPath = arg.InterfacePkgPath + } else { + arg.OutputPkgPath = "mock_" + path.Base(arg.InterfacePkgPath) + } + + arg.Imports = make(importMap) + arg.Imports[path.Base(arg.InterfacePkgPath)] = arg.InterfacePkgPath + arg.Imports["generate"] = "github.com/smartystreets/assertions/internal/oglemock/generate" + arg.Imports["log"] = "log" + arg.Imports["os"] = "os" + arg.Imports["reflect"] = "reflect" + + // Execute the template to generate code that will itself generate the mock + // code. Write the code to the temp file. + tmpl := template.Must( + template.New("code").Funcs( + template.FuncMap{ + "pathBase": path.Base, + }).Parse(tmplStr)) + if err := tmpl.Execute(codeFile, arg); err != nil { + return errors.New(fmt.Sprintf("Error executing template: %v", err)) + } + + codeFile.Close() + + // Attempt to build the code. + cmd := exec.Command("go", "build", "-o", binaryPath) + cmd.Dir = tmpDir + buildOutput, err := cmd.CombinedOutput() + + if err != nil { + // Did the compilation fail due to the user-specified package not being found? + pkg := findUnknownPackage(buildOutput) + if pkg != nil && *pkg == arg.InterfacePkgPath { + return errors.New(fmt.Sprintf("Unknown package: %s", *pkg)) + } + + // Did the compilation fail due to an unknown interface? + if in := findUndefinedInterface(buildOutput); in != nil { + return errors.New(fmt.Sprintf("Unknown interface: %s", *in)) + } + + // Otherwise return a generic error. + return errors.New(fmt.Sprintf( + "%s\n\nError building generated code:\n\n"+ + " %v\n\nPlease report this oglemock bug.", + buildOutput, + err)) + } + + // Run the binary. + cmd = exec.Command(binaryPath) + binaryOutput, err := cmd.CombinedOutput() + + if err != nil { + return errors.New(fmt.Sprintf( + "%s\n\nError running generated code:\n\n"+ + " %v\n\n Please report this oglemock bug.", + binaryOutput, + err)) + } + + // Copy its output. + _, err = os.Stdout.Write(binaryOutput) + if err != nil { + return errors.New(fmt.Sprintf("Error copying binary output: %v", err)) + } + + return nil +} + +func main() { + if err := run(); err != nil { + fmt.Fprintf(os.Stderr, "%s\n", err.Error()) + os.Exit(1) + } +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/createmock/createmock_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/createmock/createmock_test.go new file mode 100644 index 00000000000..ddfc07a3e8d --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/createmock/createmock_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 main + +import ( + "bytes" + "flag" + "fmt" + "go/build" + "io/ioutil" + "os" + "os/exec" + "path" + "syscall" + "testing" + + . "github.com/smartystreets/assertions/internal/ogletest" +) + +var dumpNew = flag.Bool("dump_new", false, "Dump new golden files.") + +//////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////// + +var tempDir string +var createmockPath string + +type CreateMockTest struct { +} + +func TestOgletest(t *testing.T) { RunTests(t) } +func init() { RegisterTestSuite(&CreateMockTest{}) } + +func (t *CreateMockTest) SetUpTestSuite() { + // Create a temporary file to hold the built createmock binary. + tempDir, err := ioutil.TempDir("", "createmock-") + if err != nil { + panic("Creating temporary directory: " + err.Error()) + } + + createmockPath = path.Join(tempDir, "createmock") + + // Build the createmock tool so that it can be used in the tests below. + cmd := exec.Command("go", "build", "-o", createmockPath, "github.com/smartystreets/assertions/internal/oglemock/createmock") + if output, err := cmd.CombinedOutput(); err != nil { + panic(fmt.Sprintf("Error building createmock: %v\n\n%s", err, output)) + } +} + +func (t *CreateMockTest) TearDownTestSuite() { + // Delete the createmock binary we built above. + os.RemoveAll(tempDir) + tempDir = "" + createmockPath = "" +} + +func (t *CreateMockTest) runGoldenTest( + caseName string, + expectedReturnCode int, + createmockArgs ...string) { + // Run createmock. + cmd := exec.Command(createmockPath, createmockArgs...) + output, err := cmd.CombinedOutput() + + // Make sure the process actually exited. + exitError, ok := err.(*exec.ExitError) + if err != nil && (!ok || !exitError.Exited()) { + panic("exec.Command.CombinedOutput: " + err.Error()) + } + + // Extract a return code. + var actualReturnCode int + if exitError != nil { + actualReturnCode = exitError.Sys().(syscall.WaitStatus).ExitStatus() + } + + // Make sure the return code is correct. + ExpectEq(expectedReturnCode, actualReturnCode) + + // Read the golden file. + goldenPath := path.Join("testdata", "golden."+caseName) + goldenData := readFileOrDie(goldenPath) + + // Compare the two. + identical := (string(output) == string(goldenData)) + ExpectTrue(identical, "Output doesn't match for case '%s'.", caseName) + + // Write out a new golden file if requested. + if !identical && *dumpNew { + writeContentsToFileOrDie(output, goldenPath) + } +} + +// Ensure that when createmock is run with the supplied args, it produces +// output that can be compiled. +func (t *CreateMockTest) runCompilationTest(createmockArgs ...string) { + // Create a temporary directory inside of $GOPATH to hold generated code. + buildPkg, err := build.Import("github.com/smartystreets/assertions/internal/oglemock", "", build.FindOnly) + AssertEq(nil, err) + + tmpDir, err := ioutil.TempDir(buildPkg.SrcRoot, "tmp-createmock_test-") + AssertEq(nil, err) + defer os.RemoveAll(tmpDir) + + // Create a file to hold the mock code. + codeFile, err := os.Create(path.Join(tmpDir, "mock.go")) + AssertEq(nil, err) + + // Run createmock and save its output to the file created above. + stdErrBuf := new(bytes.Buffer) + + cmd := exec.Command(createmockPath, createmockArgs...) + cmd.Stdout = codeFile + cmd.Stderr = stdErrBuf + + err = cmd.Run() + AssertEq(nil, err, "createmock stderr output:\n\n%s", stdErrBuf.String()) + codeFile.Close() + + // Run 'go build' in the directory and make sure it exits with return code + // zero. + cmd = exec.Command("go", "build") + cmd.Dir = tmpDir + output, err := cmd.CombinedOutput() + + ExpectEq(nil, err, "go build output:\n\n%s", output) +} + +func writeContentsToFileOrDie(contents []byte, path string) { + if err := ioutil.WriteFile(path, contents, 0600); err != nil { + panic("ioutil.WriteFile: " + err.Error()) + } +} + +func readFileOrDie(path string) []byte { + contents, err := ioutil.ReadFile(path) + if err != nil { + panic("ioutil.ReadFile: " + err.Error()) + } + + return contents +} + +//////////////////////////////////////////////////////////// +// Tests +//////////////////////////////////////////////////////////// + +func (t *CreateMockTest) NoPackage() { + t.runGoldenTest( + "no_package", + 1) +} + +func (t *CreateMockTest) NoInterfaces() { + t.runGoldenTest( + "no_interfaces", + 1, + "io") +} + +func (t *CreateMockTest) UnknownPackage() { + t.runGoldenTest( + "unknown_package", + 1, + "foo/bar", + "Reader") +} + +func (t *CreateMockTest) UnknownInterface() { + t.runGoldenTest( + "unknown_interface", + 1, + "io", + "Frobnicator") +} + +func (t *CreateMockTest) GCSBucket() { + t.runGoldenTest( + "gcs_bucket", + 0, + "github.com/smartystreets/assertions/internal/oglemock/createmock/testdata/gcs", + "Bucket") +} + +func (t *CreateMockTest) GCSBucket_SamePackage() { + t.runGoldenTest( + "gcs_bucket_same_package", + 0, + "--same_package", + "github.com/smartystreets/assertions/internal/oglemock/createmock/testdata/gcs", + "Bucket") +} + +func (t *CreateMockTest) IoReaderAndWriter() { + t.runCompilationTest( + "io", + "Reader", + "Writer") +} + +func (t *CreateMockTest) OsFileInfo() { + // Note that os is also used by the code that createmock generates; there + // should be no conflict. + t.runCompilationTest( + "os", + "FileInfo") +} + +func (t *CreateMockTest) ComplicatedSamplePackage() { + t.runCompilationTest( + "github.com/smartystreets/assertions/internal/oglemock/generate/testdata/complicated_pkg", + "ComplicatedThing") +} + +func (t *CreateMockTest) RenamedSamplePackage() { + t.runCompilationTest( + "github.com/smartystreets/assertions/internal/oglemock/generate/testdata/renamed_pkg", + "SomeInterface") +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/createmock/testdata/gcs/bucket.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/createmock/testdata/gcs/bucket.go new file mode 100644 index 00000000000..da714f305c5 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/createmock/testdata/gcs/bucket.go @@ -0,0 +1,23 @@ +package gcs + +import "golang.org/x/net/context" + +type Bucket interface { + Name() string + CreateObject(context.Context, *CreateObjectRequest) (*Object, error) + CopyObject(ctx context.Context, req *CopyObjectRequest) (o *Object, err error) +} + +type Object struct { +} + +type CreateObjectRequest struct { +} + +type CopyObjectRequest struct { +} + +type Int int +type Array []int +type Chan <-chan int +type Ptr *int diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/createmock/testdata/golden.gcs_bucket b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/createmock/testdata/golden.gcs_bucket new file mode 100644 index 00000000000..05a5114546c --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/createmock/testdata/golden.gcs_bucket @@ -0,0 +1,125 @@ +// This file was auto-generated using createmock. See the following page for +// more information: +// +// https://github.com/smartystreets/assertions/internal/oglemock +// + +package mock_gcs + +import ( + fmt "fmt" + oglemock "github.com/smartystreets/assertions/internal/oglemock" + gcs "github.com/smartystreets/assertions/internal/oglemock/createmock/testdata/gcs" + context "golang.org/x/net/context" + runtime "runtime" + unsafe "unsafe" +) + +type MockBucket interface { + gcs.Bucket + oglemock.MockObject +} + +type mockBucket struct { + controller oglemock.Controller + description string +} + +func NewMockBucket( + c oglemock.Controller, + desc string) MockBucket { + return &mockBucket{ + controller: c, + description: desc, + } +} + +func (m *mockBucket) Oglemock_Id() uintptr { + return uintptr(unsafe.Pointer(m)) +} + +func (m *mockBucket) Oglemock_Description() string { + return m.description +} + +func (m *mockBucket) CopyObject(p0 context.Context, p1 *gcs.CopyObjectRequest) (o0 *gcs.Object, o1 error) { + // Get a file name and line number for the caller. + _, file, line, _ := runtime.Caller(1) + + // Hand the call off to the controller, which does most of the work. + retVals := m.controller.HandleMethodCall( + m, + "CopyObject", + file, + line, + []interface{}{p0, p1}) + + if len(retVals) != 2 { + panic(fmt.Sprintf("mockBucket.CopyObject: invalid return values: %v", retVals)) + } + + // o0 *gcs.Object + if retVals[0] != nil { + o0 = retVals[0].(*gcs.Object) + } + + // o1 error + if retVals[1] != nil { + o1 = retVals[1].(error) + } + + return +} + +func (m *mockBucket) CreateObject(p0 context.Context, p1 *gcs.CreateObjectRequest) (o0 *gcs.Object, o1 error) { + // Get a file name and line number for the caller. + _, file, line, _ := runtime.Caller(1) + + // Hand the call off to the controller, which does most of the work. + retVals := m.controller.HandleMethodCall( + m, + "CreateObject", + file, + line, + []interface{}{p0, p1}) + + if len(retVals) != 2 { + panic(fmt.Sprintf("mockBucket.CreateObject: invalid return values: %v", retVals)) + } + + // o0 *gcs.Object + if retVals[0] != nil { + o0 = retVals[0].(*gcs.Object) + } + + // o1 error + if retVals[1] != nil { + o1 = retVals[1].(error) + } + + return +} + +func (m *mockBucket) Name() (o0 string) { + // Get a file name and line number for the caller. + _, file, line, _ := runtime.Caller(1) + + // Hand the call off to the controller, which does most of the work. + retVals := m.controller.HandleMethodCall( + m, + "Name", + file, + line, + []interface{}{}) + + if len(retVals) != 1 { + panic(fmt.Sprintf("mockBucket.Name: invalid return values: %v", retVals)) + } + + // o0 string + if retVals[0] != nil { + o0 = retVals[0].(string) + } + + return +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/createmock/testdata/golden.gcs_bucket_same_package b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/createmock/testdata/golden.gcs_bucket_same_package new file mode 100644 index 00000000000..d78819076f5 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/createmock/testdata/golden.gcs_bucket_same_package @@ -0,0 +1,124 @@ +// This file was auto-generated using createmock. See the following page for +// more information: +// +// https://github.com/smartystreets/assertions/internal/oglemock +// + +package gcs + +import ( + fmt "fmt" + oglemock "github.com/smartystreets/assertions/internal/oglemock" + context "golang.org/x/net/context" + runtime "runtime" + unsafe "unsafe" +) + +type MockBucket interface { + Bucket + oglemock.MockObject +} + +type mockBucket struct { + controller oglemock.Controller + description string +} + +func NewMockBucket( + c oglemock.Controller, + desc string) MockBucket { + return &mockBucket{ + controller: c, + description: desc, + } +} + +func (m *mockBucket) Oglemock_Id() uintptr { + return uintptr(unsafe.Pointer(m)) +} + +func (m *mockBucket) Oglemock_Description() string { + return m.description +} + +func (m *mockBucket) CopyObject(p0 context.Context, p1 *CopyObjectRequest) (o0 *Object, o1 error) { + // Get a file name and line number for the caller. + _, file, line, _ := runtime.Caller(1) + + // Hand the call off to the controller, which does most of the work. + retVals := m.controller.HandleMethodCall( + m, + "CopyObject", + file, + line, + []interface{}{p0, p1}) + + if len(retVals) != 2 { + panic(fmt.Sprintf("mockBucket.CopyObject: invalid return values: %v", retVals)) + } + + // o0 *Object + if retVals[0] != nil { + o0 = retVals[0].(*Object) + } + + // o1 error + if retVals[1] != nil { + o1 = retVals[1].(error) + } + + return +} + +func (m *mockBucket) CreateObject(p0 context.Context, p1 *CreateObjectRequest) (o0 *Object, o1 error) { + // Get a file name and line number for the caller. + _, file, line, _ := runtime.Caller(1) + + // Hand the call off to the controller, which does most of the work. + retVals := m.controller.HandleMethodCall( + m, + "CreateObject", + file, + line, + []interface{}{p0, p1}) + + if len(retVals) != 2 { + panic(fmt.Sprintf("mockBucket.CreateObject: invalid return values: %v", retVals)) + } + + // o0 *Object + if retVals[0] != nil { + o0 = retVals[0].(*Object) + } + + // o1 error + if retVals[1] != nil { + o1 = retVals[1].(error) + } + + return +} + +func (m *mockBucket) Name() (o0 string) { + // Get a file name and line number for the caller. + _, file, line, _ := runtime.Caller(1) + + // Hand the call off to the controller, which does most of the work. + retVals := m.controller.HandleMethodCall( + m, + "Name", + file, + line, + []interface{}{}) + + if len(retVals) != 1 { + panic(fmt.Sprintf("mockBucket.Name: invalid return values: %v", retVals)) + } + + // o0 string + if retVals[0] != nil { + o0 = retVals[0].(string) + } + + return +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/createmock/testdata/golden.no_interfaces b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/createmock/testdata/golden.no_interfaces new file mode 100644 index 00000000000..b70535fae6b --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/createmock/testdata/golden.no_interfaces @@ -0,0 +1 @@ +Usage: createmock [package] [interface ...] diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/createmock/testdata/golden.no_package b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/createmock/testdata/golden.no_package new file mode 100644 index 00000000000..b70535fae6b --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/createmock/testdata/golden.no_package @@ -0,0 +1 @@ +Usage: createmock [package] [interface ...] diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/createmock/testdata/golden.unknown_interface b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/createmock/testdata/golden.unknown_interface new file mode 100644 index 00000000000..c32950a1790 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/createmock/testdata/golden.unknown_interface @@ -0,0 +1 @@ +Unknown interface: Frobnicator diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/createmock/testdata/golden.unknown_package b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/createmock/testdata/golden.unknown_package new file mode 100644 index 00000000000..d07e915d2cf --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/createmock/testdata/golden.unknown_package @@ -0,0 +1 @@ +Unknown package: foo/bar diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/do_all.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/do_all.go new file mode 100644 index 00000000000..c0cd3ffbd69 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/do_all.go @@ -0,0 +1,53 @@ +// 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 oglemock + +import ( + "fmt" + "reflect" +) + +// Create an Action that invokes the supplied actions one after another. The +// return values from the final action are used; others are ignored. +func DoAll(first Action, others ...Action) Action { + return &doAll{ + wrapped: append([]Action{first}, others...), + } +} + +type doAll struct { + wrapped []Action +} + +func (a *doAll) SetSignature(signature reflect.Type) (err error) { + for i, w := range a.wrapped { + err = w.SetSignature(signature) + if err != nil { + err = fmt.Errorf("Action %v: %v", i, err) + return + } + } + + return +} + +func (a *doAll) Invoke(methodArgs []interface{}) (rets []interface{}) { + for _, w := range a.wrapped { + rets = w.Invoke(methodArgs) + } + + return +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/do_all_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/do_all_test.go new file mode 100644 index 00000000000..f835b66c7c5 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/do_all_test.go @@ -0,0 +1,90 @@ +// 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 oglemock_test + +import ( + "reflect" + "testing" + + . "github.com/smartystreets/assertions/internal/oglematchers" + "github.com/smartystreets/assertions/internal/oglemock" + . "github.com/smartystreets/assertions/internal/ogletest" +) + +func TestDoAll(t *testing.T) { RunTests(t) } + +//////////////////////////////////////////////////////////// +// Boilerplate +//////////////////////////////////////////////////////////// + +type DoAllTest struct { +} + +func init() { RegisterTestSuite(&DoAllTest{}) } + +//////////////////////////////////////////////////////////// +// Test functions +//////////////////////////////////////////////////////////// + +func (t *DoAllTest) FirstActionDoesntLikeSignature() { + f := func(a int, b string) {} + + a0 := oglemock.Invoke(func() {}) + a1 := oglemock.Invoke(f) + a2 := oglemock.Return() + + err := oglemock.DoAll(a0, a1, a2).SetSignature(reflect.TypeOf(f)) + ExpectThat(err, Error(HasSubstr("Action 0"))) + ExpectThat(err, Error(HasSubstr("func()"))) +} + +func (t *DoAllTest) LastActionDoesntLikeSignature() { + f := func(a int, b string) {} + + a0 := oglemock.Invoke(f) + a1 := oglemock.Invoke(f) + a2 := oglemock.Return(17) + + err := oglemock.DoAll(a0, a1, a2).SetSignature(reflect.TypeOf(f)) + ExpectThat(err, Error(HasSubstr("Action 2"))) + ExpectThat(err, Error(HasSubstr("1 vals; expected 0"))) +} + +func (t *DoAllTest) SingleAction() { + f := func(a int) string { return "" } + a0 := oglemock.Return("taco") + + action := oglemock.DoAll(a0) + AssertEq(nil, action.SetSignature(reflect.TypeOf(f))) + + rets := action.Invoke([]interface{}{17}) + ExpectThat(rets, ElementsAre("taco")) +} + +func (t *DoAllTest) MultipleActions() { + f := func(a int) string { return "" } + + var saved int + a0 := oglemock.SaveArg(0, &saved) + a1 := oglemock.Return("taco") + + action := oglemock.DoAll(a0, a1) + AssertEq(nil, action.SetSignature(reflect.TypeOf(f))) + + rets := action.Invoke([]interface{}{17}) + ExpectEq(17, saved) + ExpectThat(rets, ElementsAre("taco")) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/doc.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/doc.go new file mode 100644 index 00000000000..d397f652033 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/doc.go @@ -0,0 +1,28 @@ +// 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 oglemock provides a mocking framework for unit tests. +// +// Among its features are the following: +// +// * An extensive and extensible set of matchers for expressing call +// expectations (provided by the oglematchers package). +// +// * Style and semantics similar to Google Mock and Google JS Test. +// +// * Easy integration with the ogletest unit testing framework. +// +// See https://github.com/smartystreets/assertions/internal/oglemock for more information. +package oglemock diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/error_reporter.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/error_reporter.go new file mode 100644 index 00000000000..0c3a65ee187 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/error_reporter.go @@ -0,0 +1,29 @@ +// 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 oglemock + +// ErrorReporter is an interface that wraps methods for reporting errors that +// should cause test failures. +type ErrorReporter interface { + // Report that some failure (e.g. an unsatisfied expectation) occurred. If + // known, fileName and lineNumber should contain information about where it + // occurred. The test may continue if the test framework supports it. + ReportError(fileName string, lineNumber int, err error) + + // Like ReportError, but the test should be halted immediately. It is assumed + // that this method does not return. + ReportFatalError(fileName string, lineNumber int, err error) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/expectation.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/expectation.go new file mode 100644 index 00000000000..d18bfb8bce9 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/expectation.go @@ -0,0 +1,59 @@ +// 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 oglemock + +// Expectation is an expectation for zero or more calls to a mock method with +// particular arguments or sets of arguments. +type Expectation interface { + // Times expresses that a matching method call should happen exactly N times. + // Times must not be called more than once, and must not be called after + // WillOnce or WillRepeatedly. + // + // The full rules for the cardinality of an expectation are as follows: + // + // 1. If an explicit cardinality is set with Times(N), then anything other + // than exactly N matching calls will cause a test failure. + // + // 2. Otherwise, if there are any one-time actions set up, then it is + // expected there will be at least that many matching calls. If there is + // not also a fallback action, then it is expected that there will be + // exactly that many. + // + // 3. Otherwise, if there is a fallback action configured, any number of + // matching calls (including zero) is allowed. + // + // 4. Otherwise, the implicit cardinality is one. + // + Times(n uint) Expectation + + // WillOnce configures a "one-time action". WillOnce can be called zero or + // more times, but must be called after any call to Times and before any call + // to WillRepeatedly. + // + // When matching method calls are made on the mock object, one-time actions + // are invoked one per matching call in the order that they were set up until + // they are exhausted. Afterward the fallback action, if any, will be used. + WillOnce(a Action) Expectation + + // WillRepeatedly configures a "fallback action". WillRepeatedly can be + // called zero or one times, and must not be called before Times or WillOnce. + // + // Once all one-time actions are exhausted (see above), the fallback action + // will be invoked for any further method calls. If WillRepeatedly is not + // called, the fallback action is implicitly an action that returns zero + // values for the method's return values. + WillRepeatedly(a Action) Expectation +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/generate/generate.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/generate/generate.go new file mode 100644 index 00000000000..aca3de5541b --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/generate/generate.go @@ -0,0 +1,369 @@ +// 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 generate implements code generation for mock classes. This is an +// implementation detail of the createmock command, which you probably want to +// use directly instead. +package generate + +import ( + "bytes" + "errors" + "fmt" + "go/ast" + "go/parser" + "go/printer" + "go/token" + "io" + "path" + "reflect" + "regexp" + "text/template" +) + +const gTmplStr = ` +// This file was auto-generated using createmock. See the following page for +// more information: +// +// https://github.com/smartystreets/assertions/internal/oglemock +// + +package {{pathBase .OutputPkgPath}} + +import ( + {{range $identifier, $import := .Imports}}{{$identifier}} "{{$import}}" + {{end}} +) + +{{range .Interfaces}} + {{$interfaceName := printf "Mock%s" .Name}} + {{$structName := printf "mock%s" .Name}} + + type {{$interfaceName}} interface { + {{getTypeString .}} + oglemock.MockObject + } + + type {{$structName}} struct { + controller oglemock.Controller + description string + } + + func New{{printf "Mock%s" .Name}}( + c oglemock.Controller, + desc string) {{$interfaceName}} { + return &{{$structName}}{ + controller: c, + description: desc, + } + } + + func (m *{{$structName}}) Oglemock_Id() uintptr { + return uintptr(unsafe.Pointer(m)) + } + + func (m *{{$structName}}) Oglemock_Description() string { + return m.description + } + + {{range getMethods .}} + {{$funcType := .Type}} + {{$inputTypes := getInputs $funcType}} + {{$outputTypes := getOutputs $funcType}} + + func (m *{{$structName}}) {{.Name}}({{range $i, $type := $inputTypes}}p{{$i}} {{getInputTypeString $i $funcType}}, {{end}}) ({{range $i, $type := $outputTypes}}o{{$i}} {{getTypeString $type}}, {{end}}) { + // Get a file name and line number for the caller. + _, file, line, _ := runtime.Caller(1) + + // Hand the call off to the controller, which does most of the work. + retVals := m.controller.HandleMethodCall( + m, + "{{.Name}}", + file, + line, + []interface{}{ {{range $i, $type := $inputTypes}}p{{$i}}, {{end}} }) + + if len(retVals) != {{len $outputTypes}} { + panic(fmt.Sprintf("{{$structName}}.{{.Name}}: invalid return values: %v", retVals)) + } + + {{range $i, $type := $outputTypes}} + // o{{$i}} {{getTypeString $type}} + if retVals[{{$i}}] != nil { + o{{$i}} = retVals[{{$i}}].({{getTypeString $type}}) + } + {{end}} + + return + } + {{end}} +{{end}} +` + +type tmplArg struct { + // The set of interfaces to mock, and the full name of the package from which + // they all come. + Interfaces []reflect.Type + InterfacePkgPath string + + // The package path for the generate code. + OutputPkgPath string + + // Imports needed by the interfaces. + Imports importMap +} + +func (a *tmplArg) getInputTypeString(i int, ft reflect.Type) string { + numInputs := ft.NumIn() + if i == numInputs-1 && ft.IsVariadic() { + return "..." + a.getTypeString(ft.In(i).Elem()) + } + + return a.getTypeString(ft.In(i)) +} + +func (a *tmplArg) getTypeString(t reflect.Type) string { + return typeString(t, a.OutputPkgPath) +} + +func getMethods(it reflect.Type) []reflect.Method { + numMethods := it.NumMethod() + methods := make([]reflect.Method, numMethods) + + for i := 0; i < numMethods; i++ { + methods[i] = it.Method(i) + } + + return methods +} + +func getInputs(ft reflect.Type) []reflect.Type { + numIn := ft.NumIn() + inputs := make([]reflect.Type, numIn) + + for i := 0; i < numIn; i++ { + inputs[i] = ft.In(i) + } + + return inputs +} + +func getOutputs(ft reflect.Type) []reflect.Type { + numOut := ft.NumOut() + outputs := make([]reflect.Type, numOut) + + for i := 0; i < numOut; i++ { + outputs[i] = ft.Out(i) + } + + return outputs +} + +// A map from import identifier to package to use that identifier for, +// containing elements for each import needed by a set of mocked interfaces. +type importMap map[string]string + +var typePackageIdentifierRegexp = regexp.MustCompile(`^([\pL_0-9]+)\.[\pL_0-9]+$`) + +// Add an import for the supplied type, without recursing. +func addImportForType(imports importMap, t reflect.Type) { + // If there is no package path, this is a built-in type and we don't need an + // import. + pkgPath := t.PkgPath() + if pkgPath == "" { + return + } + + // Work around a bug in Go: + // + // http://code.google.com/p/go/issues/detail?id=2660 + // + var errorPtr *error + if t == reflect.TypeOf(errorPtr).Elem() { + return + } + + // Use the identifier that's part of the type's string representation as the + // import identifier. This means that we'll do the right thing for package + // "foo/bar" with declaration "package baz". + match := typePackageIdentifierRegexp.FindStringSubmatch(t.String()) + if match == nil { + return + } + + imports[match[1]] = pkgPath +} + +// Add all necessary imports for the type, recursing as appropriate. +func addImportsForType(imports importMap, t reflect.Type) { + // Add any import needed for the type itself. + addImportForType(imports, t) + + // Handle special cases where recursion is needed. + switch t.Kind() { + case reflect.Array, reflect.Chan, reflect.Ptr, reflect.Slice: + addImportsForType(imports, t.Elem()) + + case reflect.Func: + // Input parameters. + for i := 0; i < t.NumIn(); i++ { + addImportsForType(imports, t.In(i)) + } + + // Return values. + for i := 0; i < t.NumOut(); i++ { + addImportsForType(imports, t.Out(i)) + } + + case reflect.Map: + addImportsForType(imports, t.Key()) + addImportsForType(imports, t.Elem()) + } +} + +// Add imports for each of the methods of the interface, but not the interface +// itself. +func addImportsForInterfaceMethods(imports importMap, it reflect.Type) { + // Handle each method. + for i := 0; i < it.NumMethod(); i++ { + m := it.Method(i) + addImportsForType(imports, m.Type) + } +} + +// Given a set of interfaces, return a map from import identifier to package to +// use that identifier for, containing elements for each import needed by the +// mock versions of those interfaces in a package with the given path. +func getImports( + interfaces []reflect.Type, + pkgPath string) importMap { + imports := make(importMap) + for _, it := range interfaces { + addImportForType(imports, it) + addImportsForInterfaceMethods(imports, it) + } + + // Make sure there are imports for other types used by the generated code + // itself. + imports["fmt"] = "fmt" + imports["oglemock"] = "github.com/smartystreets/assertions/internal/oglemock" + imports["runtime"] = "runtime" + imports["unsafe"] = "unsafe" + + // Remove any self-imports generated above. + for k, v := range imports { + if v == pkgPath { + delete(imports, k) + } + } + + return imports +} + +// Given a set of interfaces to mock, write out source code suitable for +// inclusion in a package with the supplied full package path containing mock +// implementations of those interfaces. +func GenerateMockSource( + w io.Writer, + outputPkgPath string, + interfaces []reflect.Type) (err error) { + // Sanity-check arguments. + if outputPkgPath == "" { + return errors.New("Package path must be non-empty.") + } + + if len(interfaces) == 0 { + return errors.New("List of interfaces must be non-empty.") + } + + // Make sure each type is indeed an interface. + for _, it := range interfaces { + if it.Kind() != reflect.Interface { + return errors.New("Invalid type: " + it.String()) + } + } + + // Make sure each interface is from the same package. + interfacePkgPath := interfaces[0].PkgPath() + for _, t := range interfaces { + if t.PkgPath() != interfacePkgPath { + err = fmt.Errorf( + "Package path mismatch: %q vs. %q", + interfacePkgPath, + t.PkgPath()) + + return + } + } + + // Set up an appropriate template arg. + arg := tmplArg{ + Interfaces: interfaces, + InterfacePkgPath: interfacePkgPath, + OutputPkgPath: outputPkgPath, + Imports: getImports(interfaces, outputPkgPath), + } + + // Configure and parse the template. + tmpl := template.New("code") + tmpl.Funcs(template.FuncMap{ + "pathBase": path.Base, + "getMethods": getMethods, + "getInputs": getInputs, + "getOutputs": getOutputs, + "getInputTypeString": arg.getInputTypeString, + "getTypeString": arg.getTypeString, + }) + + _, err = tmpl.Parse(gTmplStr) + if err != nil { + err = fmt.Errorf("Parse: %v", err) + return + } + + // Execute the template, collecting the raw output into a buffer. + buf := new(bytes.Buffer) + if err := tmpl.Execute(buf, arg); err != nil { + return err + } + + // Parse the output. + fset := token.NewFileSet() + astFile, err := parser.ParseFile( + fset, + path.Base(outputPkgPath+".go"), + buf, + parser.ParseComments) + + if err != nil { + err = fmt.Errorf("parser.ParseFile: %v", err) + return + } + + // Sort the import lines in the AST in the same way that gofmt does. + ast.SortImports(fset, astFile) + + // Pretty-print the AST, using the same options that gofmt does by default. + cfg := &printer.Config{ + Mode: printer.UseSpaces | printer.TabIndent, + Tabwidth: 8, + } + + if err = cfg.Fprint(w, fset, astFile); err != nil { + return errors.New("Error pretty printing: " + err.Error()) + } + + return nil +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/generate/generate_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/generate/generate_test.go new file mode 100644 index 00000000000..8347e4d030b --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/generate/generate_test.go @@ -0,0 +1,168 @@ +// 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 generate_test + +import ( + "bytes" + "flag" + "image" + "io" + "io/ioutil" + "path" + "reflect" + "testing" + + . "github.com/smartystreets/assertions/internal/oglematchers" + "github.com/smartystreets/assertions/internal/oglemock/generate" + "github.com/smartystreets/assertions/internal/oglemock/generate/testdata/complicated_pkg" + "github.com/smartystreets/assertions/internal/oglemock/generate/testdata/renamed_pkg" + . "github.com/smartystreets/assertions/internal/ogletest" +) + +var dumpNew = flag.Bool("dump_new", false, "Dump new golden files.") + +//////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////// + +type GenerateTest struct { +} + +func TestOgletest(t *testing.T) { RunTests(t) } +func init() { RegisterTestSuite(&GenerateTest{}) } + +func (t *GenerateTest) runGoldenTest( + caseName string, + outputPkgPath string, + nilPtrs ...interface{}) { + // Make a slice of interface types to give to GenerateMockSource. + interfaces := make([]reflect.Type, len(nilPtrs)) + for i, ptr := range nilPtrs { + interfaces[i] = reflect.TypeOf(ptr).Elem() + } + + // Create the mock source. + buf := new(bytes.Buffer) + err := generate.GenerateMockSource(buf, outputPkgPath, interfaces) + AssertEq(nil, err, "Error from GenerateMockSource: %v", err) + + // Read the golden file. + goldenPath := path.Join("testdata", "golden."+caseName+".go") + goldenData := readFileOrDie(goldenPath) + + // Compare the two. + identical := (buf.String() == string(goldenData)) + ExpectTrue(identical, "Output doesn't match for case '%s'.", caseName) + + // Write out a new golden file if requested. + if !identical && *dumpNew { + writeContentsToFileOrDie(buf.Bytes(), goldenPath) + } +} + +func writeContentsToFileOrDie(contents []byte, path string) { + if err := ioutil.WriteFile(path, contents, 0600); err != nil { + panic("ioutil.WriteFile: " + err.Error()) + } +} + +func readFileOrDie(path string) []byte { + contents, err := ioutil.ReadFile(path) + if err != nil { + panic("ioutil.ReadFile: " + err.Error()) + } + + return contents +} + +//////////////////////////////////////////////////////////// +// Tests +//////////////////////////////////////////////////////////// + +func (t *GenerateTest) EmptyOutputPackagePath() { + err := generate.GenerateMockSource( + new(bytes.Buffer), + "", + []reflect.Type{ + reflect.TypeOf((*io.Reader)(nil)).Elem(), + }) + + ExpectThat(err, Error(HasSubstr("Package path"))) + ExpectThat(err, Error(HasSubstr("non-empty"))) +} + +func (t *GenerateTest) EmptySetOfInterfaces() { + err := generate.GenerateMockSource( + new(bytes.Buffer), + "foo", + []reflect.Type{}) + + ExpectThat(err, Error(HasSubstr("interfaces"))) + ExpectThat(err, Error(HasSubstr("non-empty"))) +} + +func (t *GenerateTest) NonInterfaceType() { + err := generate.GenerateMockSource( + new(bytes.Buffer), + "foo", + []reflect.Type{ + reflect.TypeOf((*io.Reader)(nil)).Elem(), + reflect.TypeOf(17), + reflect.TypeOf((*io.Writer)(nil)).Elem(), + }) + + ExpectThat(err, Error(HasSubstr("Invalid type"))) +} + +func (t *GenerateTest) IoReaderAndWriter() { + // Mock io.Reader and io.Writer. + t.runGoldenTest( + "io_reader_writer", + "some/pkg", + (*io.Reader)(nil), + (*io.Writer)(nil)) +} + +func (t *GenerateTest) IoReaderAndWriter_SamePackage() { + // Mock io.Reader and io.Writer. + t.runGoldenTest( + "io_reader_writer_same_package", + "io", + (*io.Reader)(nil), + (*io.Writer)(nil)) +} + +func (t *GenerateTest) Image() { + t.runGoldenTest( + "image", + "some/pkg", + (*image.Image)(nil), + (*image.PalettedImage)(nil)) +} + +func (t *GenerateTest) ComplicatedPackage() { + t.runGoldenTest( + "complicated_pkg", + "some/pkg", + (*complicated_pkg.ComplicatedThing)(nil)) +} + +func (t *GenerateTest) RenamedPackage() { + t.runGoldenTest( + "renamed_pkg", + "some/pkg", + (*tony.SomeInterface)(nil)) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/generate/testdata/complicated_pkg/complicated_pkg.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/generate/testdata/complicated_pkg/complicated_pkg.go new file mode 100644 index 00000000000..acc054370d5 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/generate/testdata/complicated_pkg/complicated_pkg.go @@ -0,0 +1,41 @@ +// 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 complicated_pkg contains an interface with lots of interesting +// cases, for use in integration testing. +package complicated_pkg + +import ( + "image" + "io" + "net" + + "github.com/smartystreets/assertions/internal/oglemock/generate/testdata/renamed_pkg" +) + +type Byte uint8 + +type ComplicatedThing interface { + Channels(a chan chan<- <-chan net.Conn) chan int + Pointers(a *int, b *net.Conn, c **io.Reader) (*int, error) + Functions(a func(int, image.Image) int) func(string, int) net.Conn + Maps(a map[string]*int) (map[int]*string, error) + Arrays(a [3]string) ([3]int, error) + Slices(a []string) ([]int, error) + NamedScalarType(a Byte) ([]Byte, error) + EmptyInterface(a interface{}) (interface{}, error) + RenamedPackage(a tony.SomeUint8Alias) + Variadic(a int, b ...net.Conn) int +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/generate/testdata/golden.complicated_pkg.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/generate/testdata/golden.complicated_pkg.go new file mode 100644 index 00000000000..6bcf1979837 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/generate/testdata/golden.complicated_pkg.go @@ -0,0 +1,311 @@ +// This file was auto-generated using createmock. See the following page for +// more information: +// +// https://github.com/smartystreets/assertions/internal/oglemock +// + +package pkg + +import ( + fmt "fmt" + oglemock "github.com/smartystreets/assertions/internal/oglemock" + complicated_pkg "github.com/smartystreets/assertions/internal/oglemock/generate/testdata/complicated_pkg" + tony "github.com/smartystreets/assertions/internal/oglemock/generate/testdata/renamed_pkg" + image "image" + io "io" + net "net" + runtime "runtime" + unsafe "unsafe" +) + +type MockComplicatedThing interface { + complicated_pkg.ComplicatedThing + oglemock.MockObject +} + +type mockComplicatedThing struct { + controller oglemock.Controller + description string +} + +func NewMockComplicatedThing( + c oglemock.Controller, + desc string) MockComplicatedThing { + return &mockComplicatedThing{ + controller: c, + description: desc, + } +} + +func (m *mockComplicatedThing) Oglemock_Id() uintptr { + return uintptr(unsafe.Pointer(m)) +} + +func (m *mockComplicatedThing) Oglemock_Description() string { + return m.description +} + +func (m *mockComplicatedThing) Arrays(p0 [3]string) (o0 [3]int, o1 error) { + // Get a file name and line number for the caller. + _, file, line, _ := runtime.Caller(1) + + // Hand the call off to the controller, which does most of the work. + retVals := m.controller.HandleMethodCall( + m, + "Arrays", + file, + line, + []interface{}{p0}) + + if len(retVals) != 2 { + panic(fmt.Sprintf("mockComplicatedThing.Arrays: invalid return values: %v", retVals)) + } + + // o0 [3]int + if retVals[0] != nil { + o0 = retVals[0].([3]int) + } + + // o1 error + if retVals[1] != nil { + o1 = retVals[1].(error) + } + + return +} + +func (m *mockComplicatedThing) Channels(p0 chan chan<- <-chan net.Conn) (o0 chan int) { + // Get a file name and line number for the caller. + _, file, line, _ := runtime.Caller(1) + + // Hand the call off to the controller, which does most of the work. + retVals := m.controller.HandleMethodCall( + m, + "Channels", + file, + line, + []interface{}{p0}) + + if len(retVals) != 1 { + panic(fmt.Sprintf("mockComplicatedThing.Channels: invalid return values: %v", retVals)) + } + + // o0 chan int + if retVals[0] != nil { + o0 = retVals[0].(chan int) + } + + return +} + +func (m *mockComplicatedThing) EmptyInterface(p0 interface{}) (o0 interface{}, o1 error) { + // Get a file name and line number for the caller. + _, file, line, _ := runtime.Caller(1) + + // Hand the call off to the controller, which does most of the work. + retVals := m.controller.HandleMethodCall( + m, + "EmptyInterface", + file, + line, + []interface{}{p0}) + + if len(retVals) != 2 { + panic(fmt.Sprintf("mockComplicatedThing.EmptyInterface: invalid return values: %v", retVals)) + } + + // o0 interface { } + if retVals[0] != nil { + o0 = retVals[0].(interface{}) + } + + // o1 error + if retVals[1] != nil { + o1 = retVals[1].(error) + } + + return +} + +func (m *mockComplicatedThing) Functions(p0 func(int, image.Image) int) (o0 func(string, int) net.Conn) { + // Get a file name and line number for the caller. + _, file, line, _ := runtime.Caller(1) + + // Hand the call off to the controller, which does most of the work. + retVals := m.controller.HandleMethodCall( + m, + "Functions", + file, + line, + []interface{}{p0}) + + if len(retVals) != 1 { + panic(fmt.Sprintf("mockComplicatedThing.Functions: invalid return values: %v", retVals)) + } + + // o0 func(string, int) (net.Conn) + if retVals[0] != nil { + o0 = retVals[0].(func(string, int) net.Conn) + } + + return +} + +func (m *mockComplicatedThing) Maps(p0 map[string]*int) (o0 map[int]*string, o1 error) { + // Get a file name and line number for the caller. + _, file, line, _ := runtime.Caller(1) + + // Hand the call off to the controller, which does most of the work. + retVals := m.controller.HandleMethodCall( + m, + "Maps", + file, + line, + []interface{}{p0}) + + if len(retVals) != 2 { + panic(fmt.Sprintf("mockComplicatedThing.Maps: invalid return values: %v", retVals)) + } + + // o0 map[int]*string + if retVals[0] != nil { + o0 = retVals[0].(map[int]*string) + } + + // o1 error + if retVals[1] != nil { + o1 = retVals[1].(error) + } + + return +} + +func (m *mockComplicatedThing) NamedScalarType(p0 complicated_pkg.Byte) (o0 []complicated_pkg.Byte, o1 error) { + // Get a file name and line number for the caller. + _, file, line, _ := runtime.Caller(1) + + // Hand the call off to the controller, which does most of the work. + retVals := m.controller.HandleMethodCall( + m, + "NamedScalarType", + file, + line, + []interface{}{p0}) + + if len(retVals) != 2 { + panic(fmt.Sprintf("mockComplicatedThing.NamedScalarType: invalid return values: %v", retVals)) + } + + // o0 []complicated_pkg.Byte + if retVals[0] != nil { + o0 = retVals[0].([]complicated_pkg.Byte) + } + + // o1 error + if retVals[1] != nil { + o1 = retVals[1].(error) + } + + return +} + +func (m *mockComplicatedThing) Pointers(p0 *int, p1 *net.Conn, p2 **io.Reader) (o0 *int, o1 error) { + // Get a file name and line number for the caller. + _, file, line, _ := runtime.Caller(1) + + // Hand the call off to the controller, which does most of the work. + retVals := m.controller.HandleMethodCall( + m, + "Pointers", + file, + line, + []interface{}{p0, p1, p2}) + + if len(retVals) != 2 { + panic(fmt.Sprintf("mockComplicatedThing.Pointers: invalid return values: %v", retVals)) + } + + // o0 *int + if retVals[0] != nil { + o0 = retVals[0].(*int) + } + + // o1 error + if retVals[1] != nil { + o1 = retVals[1].(error) + } + + return +} + +func (m *mockComplicatedThing) RenamedPackage(p0 tony.SomeUint8Alias) { + // Get a file name and line number for the caller. + _, file, line, _ := runtime.Caller(1) + + // Hand the call off to the controller, which does most of the work. + retVals := m.controller.HandleMethodCall( + m, + "RenamedPackage", + file, + line, + []interface{}{p0}) + + if len(retVals) != 0 { + panic(fmt.Sprintf("mockComplicatedThing.RenamedPackage: invalid return values: %v", retVals)) + } + + return +} + +func (m *mockComplicatedThing) Slices(p0 []string) (o0 []int, o1 error) { + // Get a file name and line number for the caller. + _, file, line, _ := runtime.Caller(1) + + // Hand the call off to the controller, which does most of the work. + retVals := m.controller.HandleMethodCall( + m, + "Slices", + file, + line, + []interface{}{p0}) + + if len(retVals) != 2 { + panic(fmt.Sprintf("mockComplicatedThing.Slices: invalid return values: %v", retVals)) + } + + // o0 []int + if retVals[0] != nil { + o0 = retVals[0].([]int) + } + + // o1 error + if retVals[1] != nil { + o1 = retVals[1].(error) + } + + return +} + +func (m *mockComplicatedThing) Variadic(p0 int, p1 ...net.Conn) (o0 int) { + // Get a file name and line number for the caller. + _, file, line, _ := runtime.Caller(1) + + // Hand the call off to the controller, which does most of the work. + retVals := m.controller.HandleMethodCall( + m, + "Variadic", + file, + line, + []interface{}{p0, p1}) + + if len(retVals) != 1 { + panic(fmt.Sprintf("mockComplicatedThing.Variadic: invalid return values: %v", retVals)) + } + + // o0 int + if retVals[0] != nil { + o0 = retVals[0].(int) + } + + return +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/generate/testdata/golden.image.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/generate/testdata/golden.image.go new file mode 100644 index 00000000000..dd083e2930e --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/generate/testdata/golden.image.go @@ -0,0 +1,238 @@ +// This file was auto-generated using createmock. See the following page for +// more information: +// +// https://github.com/smartystreets/assertions/internal/oglemock +// + +package pkg + +import ( + fmt "fmt" + oglemock "github.com/smartystreets/assertions/internal/oglemock" + image "image" + color "image/color" + runtime "runtime" + unsafe "unsafe" +) + +type MockImage interface { + image.Image + oglemock.MockObject +} + +type mockImage struct { + controller oglemock.Controller + description string +} + +func NewMockImage( + c oglemock.Controller, + desc string) MockImage { + return &mockImage{ + controller: c, + description: desc, + } +} + +func (m *mockImage) Oglemock_Id() uintptr { + return uintptr(unsafe.Pointer(m)) +} + +func (m *mockImage) Oglemock_Description() string { + return m.description +} + +func (m *mockImage) At(p0 int, p1 int) (o0 color.Color) { + // Get a file name and line number for the caller. + _, file, line, _ := runtime.Caller(1) + + // Hand the call off to the controller, which does most of the work. + retVals := m.controller.HandleMethodCall( + m, + "At", + file, + line, + []interface{}{p0, p1}) + + if len(retVals) != 1 { + panic(fmt.Sprintf("mockImage.At: invalid return values: %v", retVals)) + } + + // o0 color.Color + if retVals[0] != nil { + o0 = retVals[0].(color.Color) + } + + return +} + +func (m *mockImage) Bounds() (o0 image.Rectangle) { + // Get a file name and line number for the caller. + _, file, line, _ := runtime.Caller(1) + + // Hand the call off to the controller, which does most of the work. + retVals := m.controller.HandleMethodCall( + m, + "Bounds", + file, + line, + []interface{}{}) + + if len(retVals) != 1 { + panic(fmt.Sprintf("mockImage.Bounds: invalid return values: %v", retVals)) + } + + // o0 image.Rectangle + if retVals[0] != nil { + o0 = retVals[0].(image.Rectangle) + } + + return +} + +func (m *mockImage) ColorModel() (o0 color.Model) { + // Get a file name and line number for the caller. + _, file, line, _ := runtime.Caller(1) + + // Hand the call off to the controller, which does most of the work. + retVals := m.controller.HandleMethodCall( + m, + "ColorModel", + file, + line, + []interface{}{}) + + if len(retVals) != 1 { + panic(fmt.Sprintf("mockImage.ColorModel: invalid return values: %v", retVals)) + } + + // o0 color.Model + if retVals[0] != nil { + o0 = retVals[0].(color.Model) + } + + return +} + +type MockPalettedImage interface { + image.PalettedImage + oglemock.MockObject +} + +type mockPalettedImage struct { + controller oglemock.Controller + description string +} + +func NewMockPalettedImage( + c oglemock.Controller, + desc string) MockPalettedImage { + return &mockPalettedImage{ + controller: c, + description: desc, + } +} + +func (m *mockPalettedImage) Oglemock_Id() uintptr { + return uintptr(unsafe.Pointer(m)) +} + +func (m *mockPalettedImage) Oglemock_Description() string { + return m.description +} + +func (m *mockPalettedImage) At(p0 int, p1 int) (o0 color.Color) { + // Get a file name and line number for the caller. + _, file, line, _ := runtime.Caller(1) + + // Hand the call off to the controller, which does most of the work. + retVals := m.controller.HandleMethodCall( + m, + "At", + file, + line, + []interface{}{p0, p1}) + + if len(retVals) != 1 { + panic(fmt.Sprintf("mockPalettedImage.At: invalid return values: %v", retVals)) + } + + // o0 color.Color + if retVals[0] != nil { + o0 = retVals[0].(color.Color) + } + + return +} + +func (m *mockPalettedImage) Bounds() (o0 image.Rectangle) { + // Get a file name and line number for the caller. + _, file, line, _ := runtime.Caller(1) + + // Hand the call off to the controller, which does most of the work. + retVals := m.controller.HandleMethodCall( + m, + "Bounds", + file, + line, + []interface{}{}) + + if len(retVals) != 1 { + panic(fmt.Sprintf("mockPalettedImage.Bounds: invalid return values: %v", retVals)) + } + + // o0 image.Rectangle + if retVals[0] != nil { + o0 = retVals[0].(image.Rectangle) + } + + return +} + +func (m *mockPalettedImage) ColorIndexAt(p0 int, p1 int) (o0 uint8) { + // Get a file name and line number for the caller. + _, file, line, _ := runtime.Caller(1) + + // Hand the call off to the controller, which does most of the work. + retVals := m.controller.HandleMethodCall( + m, + "ColorIndexAt", + file, + line, + []interface{}{p0, p1}) + + if len(retVals) != 1 { + panic(fmt.Sprintf("mockPalettedImage.ColorIndexAt: invalid return values: %v", retVals)) + } + + // o0 uint8 + if retVals[0] != nil { + o0 = retVals[0].(uint8) + } + + return +} + +func (m *mockPalettedImage) ColorModel() (o0 color.Model) { + // Get a file name and line number for the caller. + _, file, line, _ := runtime.Caller(1) + + // Hand the call off to the controller, which does most of the work. + retVals := m.controller.HandleMethodCall( + m, + "ColorModel", + file, + line, + []interface{}{}) + + if len(retVals) != 1 { + panic(fmt.Sprintf("mockPalettedImage.ColorModel: invalid return values: %v", retVals)) + } + + // o0 color.Model + if retVals[0] != nil { + o0 = retVals[0].(color.Model) + } + + return +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/generate/testdata/golden.io_reader_writer.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/generate/testdata/golden.io_reader_writer.go new file mode 100644 index 00000000000..2d1c7df0490 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/generate/testdata/golden.io_reader_writer.go @@ -0,0 +1,127 @@ +// This file was auto-generated using createmock. See the following page for +// more information: +// +// https://github.com/smartystreets/assertions/internal/oglemock +// + +package pkg + +import ( + fmt "fmt" + oglemock "github.com/smartystreets/assertions/internal/oglemock" + io "io" + runtime "runtime" + unsafe "unsafe" +) + +type MockReader interface { + io.Reader + oglemock.MockObject +} + +type mockReader struct { + controller oglemock.Controller + description string +} + +func NewMockReader( + c oglemock.Controller, + desc string) MockReader { + return &mockReader{ + controller: c, + description: desc, + } +} + +func (m *mockReader) Oglemock_Id() uintptr { + return uintptr(unsafe.Pointer(m)) +} + +func (m *mockReader) Oglemock_Description() string { + return m.description +} + +func (m *mockReader) Read(p0 []uint8) (o0 int, o1 error) { + // Get a file name and line number for the caller. + _, file, line, _ := runtime.Caller(1) + + // Hand the call off to the controller, which does most of the work. + retVals := m.controller.HandleMethodCall( + m, + "Read", + file, + line, + []interface{}{p0}) + + if len(retVals) != 2 { + panic(fmt.Sprintf("mockReader.Read: invalid return values: %v", retVals)) + } + + // o0 int + if retVals[0] != nil { + o0 = retVals[0].(int) + } + + // o1 error + if retVals[1] != nil { + o1 = retVals[1].(error) + } + + return +} + +type MockWriter interface { + io.Writer + oglemock.MockObject +} + +type mockWriter struct { + controller oglemock.Controller + description string +} + +func NewMockWriter( + c oglemock.Controller, + desc string) MockWriter { + return &mockWriter{ + controller: c, + description: desc, + } +} + +func (m *mockWriter) Oglemock_Id() uintptr { + return uintptr(unsafe.Pointer(m)) +} + +func (m *mockWriter) Oglemock_Description() string { + return m.description +} + +func (m *mockWriter) Write(p0 []uint8) (o0 int, o1 error) { + // Get a file name and line number for the caller. + _, file, line, _ := runtime.Caller(1) + + // Hand the call off to the controller, which does most of the work. + retVals := m.controller.HandleMethodCall( + m, + "Write", + file, + line, + []interface{}{p0}) + + if len(retVals) != 2 { + panic(fmt.Sprintf("mockWriter.Write: invalid return values: %v", retVals)) + } + + // o0 int + if retVals[0] != nil { + o0 = retVals[0].(int) + } + + // o1 error + if retVals[1] != nil { + o1 = retVals[1].(error) + } + + return +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/generate/testdata/golden.io_reader_writer_same_package.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/generate/testdata/golden.io_reader_writer_same_package.go new file mode 100644 index 00000000000..86c4b0391e6 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/generate/testdata/golden.io_reader_writer_same_package.go @@ -0,0 +1,126 @@ +// This file was auto-generated using createmock. See the following page for +// more information: +// +// https://github.com/smartystreets/assertions/internal/oglemock +// + +package io + +import ( + fmt "fmt" + oglemock "github.com/smartystreets/assertions/internal/oglemock" + runtime "runtime" + unsafe "unsafe" +) + +type MockReader interface { + Reader + oglemock.MockObject +} + +type mockReader struct { + controller oglemock.Controller + description string +} + +func NewMockReader( + c oglemock.Controller, + desc string) MockReader { + return &mockReader{ + controller: c, + description: desc, + } +} + +func (m *mockReader) Oglemock_Id() uintptr { + return uintptr(unsafe.Pointer(m)) +} + +func (m *mockReader) Oglemock_Description() string { + return m.description +} + +func (m *mockReader) Read(p0 []uint8) (o0 int, o1 error) { + // Get a file name and line number for the caller. + _, file, line, _ := runtime.Caller(1) + + // Hand the call off to the controller, which does most of the work. + retVals := m.controller.HandleMethodCall( + m, + "Read", + file, + line, + []interface{}{p0}) + + if len(retVals) != 2 { + panic(fmt.Sprintf("mockReader.Read: invalid return values: %v", retVals)) + } + + // o0 int + if retVals[0] != nil { + o0 = retVals[0].(int) + } + + // o1 error + if retVals[1] != nil { + o1 = retVals[1].(error) + } + + return +} + +type MockWriter interface { + Writer + oglemock.MockObject +} + +type mockWriter struct { + controller oglemock.Controller + description string +} + +func NewMockWriter( + c oglemock.Controller, + desc string) MockWriter { + return &mockWriter{ + controller: c, + description: desc, + } +} + +func (m *mockWriter) Oglemock_Id() uintptr { + return uintptr(unsafe.Pointer(m)) +} + +func (m *mockWriter) Oglemock_Description() string { + return m.description +} + +func (m *mockWriter) Write(p0 []uint8) (o0 int, o1 error) { + // Get a file name and line number for the caller. + _, file, line, _ := runtime.Caller(1) + + // Hand the call off to the controller, which does most of the work. + retVals := m.controller.HandleMethodCall( + m, + "Write", + file, + line, + []interface{}{p0}) + + if len(retVals) != 2 { + panic(fmt.Sprintf("mockWriter.Write: invalid return values: %v", retVals)) + } + + // o0 int + if retVals[0] != nil { + o0 = retVals[0].(int) + } + + // o1 error + if retVals[1] != nil { + o1 = retVals[1].(error) + } + + return +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/generate/testdata/golden.renamed_pkg.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/generate/testdata/golden.renamed_pkg.go new file mode 100644 index 00000000000..fe3d313007a --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/generate/testdata/golden.renamed_pkg.go @@ -0,0 +1,66 @@ +// This file was auto-generated using createmock. See the following page for +// more information: +// +// https://github.com/smartystreets/assertions/internal/oglemock +// + +package pkg + +import ( + fmt "fmt" + oglemock "github.com/smartystreets/assertions/internal/oglemock" + tony "github.com/smartystreets/assertions/internal/oglemock/generate/testdata/renamed_pkg" + runtime "runtime" + unsafe "unsafe" +) + +type MockSomeInterface interface { + tony.SomeInterface + oglemock.MockObject +} + +type mockSomeInterface struct { + controller oglemock.Controller + description string +} + +func NewMockSomeInterface( + c oglemock.Controller, + desc string) MockSomeInterface { + return &mockSomeInterface{ + controller: c, + description: desc, + } +} + +func (m *mockSomeInterface) Oglemock_Id() uintptr { + return uintptr(unsafe.Pointer(m)) +} + +func (m *mockSomeInterface) Oglemock_Description() string { + return m.description +} + +func (m *mockSomeInterface) DoFoo(p0 int) (o0 int) { + // Get a file name and line number for the caller. + _, file, line, _ := runtime.Caller(1) + + // Hand the call off to the controller, which does most of the work. + retVals := m.controller.HandleMethodCall( + m, + "DoFoo", + file, + line, + []interface{}{p0}) + + if len(retVals) != 1 { + panic(fmt.Sprintf("mockSomeInterface.DoFoo: invalid return values: %v", retVals)) + } + + // o0 int + if retVals[0] != nil { + o0 = retVals[0].(int) + } + + return +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/generate/testdata/renamed_pkg/renamed_pkg.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/generate/testdata/renamed_pkg/renamed_pkg.go new file mode 100644 index 00000000000..1461cd6960d --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/generate/testdata/renamed_pkg/renamed_pkg.go @@ -0,0 +1,24 @@ +// 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. + +// A package that calls itself something different than its package path would +// have you believe. +package tony + +type SomeUint8Alias uint8 + +type SomeInterface interface { + DoFoo(a int) int +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/generate/type_string.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/generate/type_string.go new file mode 100644 index 00000000000..c4d46e718d9 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/generate/type_string.go @@ -0,0 +1,147 @@ +// 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 generate + +import ( + "fmt" + "log" + "reflect" + "strings" +) + +// Return the string that should be used to refer to the supplied type within +// the given package. The output is not guaranteed to be pretty, and should be +// run through a tool like gofmt afterward. +// +// For example, a pointer to an io.Reader may be rendered as "*Reader" or +// "*io.Reader" depending on whether the package path is "io" or not. +func typeString( + t reflect.Type, + pkgPath string) (s string) { + // Is this type named? If so we use its name, possibly with a package prefix. + // + // Examples: + // + // int + // string + // error + // gcs.Bucket + // + if t.Name() != "" { + if t.PkgPath() == pkgPath { + s = t.Name() + } else { + s = t.String() + } + + return + } + + // This type is unnamed. Recurse. + switch t.Kind() { + case reflect.Array: + s = fmt.Sprintf("[%d]%s", t.Len(), typeString(t.Elem(), pkgPath)) + + case reflect.Chan: + s = fmt.Sprintf("%s %s", t.ChanDir(), typeString(t.Elem(), pkgPath)) + + case reflect.Func: + s = typeString_Func(t, pkgPath) + + case reflect.Interface: + s = typeString_Interface(t, pkgPath) + + case reflect.Map: + s = fmt.Sprintf( + "map[%s]%s", + typeString(t.Key(), pkgPath), + typeString(t.Elem(), pkgPath)) + + case reflect.Ptr: + s = fmt.Sprintf("*%s", typeString(t.Elem(), pkgPath)) + + case reflect.Slice: + s = fmt.Sprintf("[]%s", typeString(t.Elem(), pkgPath)) + + case reflect.Struct: + s = typeString_Struct(t, pkgPath) + + default: + log.Panicf("Unhandled kind %v for type: %v", t.Kind(), t) + } + + return +} + +func typeString_FuncOrMethod( + name string, + t reflect.Type, + pkgPath string) (s string) { + // Deal with input types. + var in []string + for i := 0; i < t.NumIn(); i++ { + in = append(in, typeString(t.In(i), pkgPath)) + } + + // And output types. + var out []string + for i := 0; i < t.NumOut(); i++ { + out = append(out, typeString(t.Out(i), pkgPath)) + } + + // Put it all together. + s = fmt.Sprintf( + "%s(%s) (%s)", + name, + strings.Join(in, ", "), + strings.Join(out, ", ")) + + return +} + +func typeString_Func( + t reflect.Type, + pkgPath string) (s string) { + return typeString_FuncOrMethod("func", t, pkgPath) +} + +func typeString_Struct( + t reflect.Type, + pkgPath string) (s string) { + var fields []string + for i := 0; i < t.NumField(); i++ { + f := t.Field(i) + fString := fmt.Sprintf("%s %s", f.Name, typeString(f.Type, pkgPath)) + fields = append(fields, fString) + } + + s = fmt.Sprintf("struct { %s }", strings.Join(fields, "; ")) + return +} + +func typeString_Interface( + t reflect.Type, + pkgPath string) (s string) { + var methods []string + for i := 0; i < t.NumMethod(); i++ { + m := t.Method(i) + mString := typeString_FuncOrMethod(m.Name, m.Type, pkgPath) + methods = append(methods, mString) + } + + s = fmt.Sprintf("interface { %s }", strings.Join(methods, "; ")) + return +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/generate/type_string_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/generate/type_string_test.go new file mode 100644 index 00000000000..7d13c4e177e --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/generate/type_string_test.go @@ -0,0 +1,220 @@ +// 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 generate + +import ( + "io" + "reflect" + "testing" + "unsafe" + + "github.com/smartystreets/assertions/internal/oglemock/createmock/testdata/gcs" + . "github.com/smartystreets/assertions/internal/ogletest" +) + +func TestTypeString(t *testing.T) { RunTests(t) } + +//////////////////////////////////////////////////////////////////////// +// Boilerplate +//////////////////////////////////////////////////////////////////////// + +type TypeStringTest struct { +} + +func init() { RegisterTestSuite(&TypeStringTest{}) } + +//////////////////////////////////////////////////////////////////////// +// Test functions +//////////////////////////////////////////////////////////////////////// + +func (t *TypeStringTest) TestCases() { + const gcsPkgPath = "github.com/smartystreets/assertions/internal/oglemock/createmock/testdata/gcs" + to := reflect.TypeOf + + testCases := []struct { + t reflect.Type + pkgPath string + expected string + }{ + ///////////////////////// + // Scalar types + ///////////////////////// + + 0: {to(true), "", "bool"}, + 1: {to(true), "some/pkg", "bool"}, + 2: {to(int(17)), "some/pkg", "int"}, + 3: {to(int32(17)), "some/pkg", "int32"}, + 4: {to(uint(17)), "some/pkg", "uint"}, + 5: {to(uint32(17)), "some/pkg", "uint32"}, + 6: {to(uintptr(17)), "some/pkg", "uintptr"}, + 7: {to(float32(17)), "some/pkg", "float32"}, + 8: {to(complex64(17)), "some/pkg", "complex64"}, + + ///////////////////////// + // Structs + ///////////////////////// + + 9: {to(gcs.Object{}), "some/pkg", "gcs.Object"}, + 10: {to(gcs.Object{}), gcsPkgPath, "Object"}, + + 11: { + to(struct { + a int + b gcs.Object + }{}), + "some/pkg", + "struct { a int; b gcs.Object }", + }, + + 12: { + to(struct { + a int + b gcs.Object + }{}), + gcsPkgPath, + "struct { a int; b Object }", + }, + + ///////////////////////// + // Pointers + ///////////////////////// + + 13: {to((*int)(nil)), gcsPkgPath, "*int"}, + 14: {to((*gcs.Object)(nil)), "some/pkg", "*gcs.Object"}, + 15: {to((*gcs.Object)(nil)), gcsPkgPath, "*Object"}, + + ///////////////////////// + // Arrays + ///////////////////////// + + 16: {to([3]int{}), "some/pkg", "[3]int"}, + 17: {to([3]gcs.Object{}), gcsPkgPath, "[3]Object"}, + + ///////////////////////// + // Channels + ///////////////////////// + + 18: {to((chan int)(nil)), "some/pkg", "chan int"}, + 19: {to((<-chan int)(nil)), "some/pkg", "<-chan int"}, + 20: {to((chan<- int)(nil)), "some/pkg", "chan<- int"}, + 21: {to((<-chan gcs.Object)(nil)), gcsPkgPath, "<-chan Object"}, + + ///////////////////////// + // Functions + ///////////////////////// + + 22: { + to(func(int, gcs.Object) {}), + gcsPkgPath, + "func(int, Object) ()", + }, + + 23: { + to(func() (*gcs.Object, error) { return nil, nil }), + gcsPkgPath, + "func() (*Object, error)", + }, + + 24: { + to(func(int, gcs.Object) (*gcs.Object, error) { return nil, nil }), + gcsPkgPath, + "func(int, Object) (*Object, error)", + }, + + ///////////////////////// + // Interfaces + ///////////////////////// + + 25: {to((*error)(nil)).Elem(), "some/pkg", "error"}, + 26: {to((*io.Reader)(nil)).Elem(), "some/pkg", "io.Reader"}, + 27: {to((*io.Reader)(nil)).Elem(), "io", "Reader"}, + + 28: { + to((*interface{})(nil)).Elem(), + "some/pkg", + "interface { }", + }, + + 29: { + to((*interface { + Foo(int) + Bar(gcs.Object) + })(nil)).Elem(), + "some/pkg", + "interface { Bar(gcs.Object) (); Foo(int) () }", + }, + + 30: { + to((*interface { + Foo(int) + Bar(gcs.Object) + })(nil)).Elem(), + gcsPkgPath, + "interface { Bar(Object) (); Foo(int) () }", + }, + + ///////////////////////// + // Maps + ///////////////////////// + + 31: {to(map[*gcs.Object]gcs.Object{}), gcsPkgPath, "map[*Object]Object"}, + + ///////////////////////// + // Slices + ///////////////////////// + + 32: {to([]int{}), "some/pkg", "[]int"}, + 33: {to([]gcs.Object{}), gcsPkgPath, "[]Object"}, + + ///////////////////////// + // Strings + ///////////////////////// + + 34: {to(""), gcsPkgPath, "string"}, + + ///////////////////////// + // Unsafe pointer + ///////////////////////// + + 35: {to(unsafe.Pointer(nil)), gcsPkgPath, "unsafe.Pointer"}, + + ///////////////////////// + // Other named types + ///////////////////////// + + 36: {to(gcs.Int(17)), "some/pkg", "gcs.Int"}, + 37: {to(gcs.Int(17)), gcsPkgPath, "Int"}, + + 38: {to(gcs.Array{}), "some/pkg", "gcs.Array"}, + 39: {to(gcs.Array{}), gcsPkgPath, "Array"}, + + 40: {to(gcs.Chan(nil)), "some/pkg", "gcs.Chan"}, + 41: {to(gcs.Chan(nil)), gcsPkgPath, "Chan"}, + + 42: {to(gcs.Ptr(nil)), "some/pkg", "gcs.Ptr"}, + 43: {to(gcs.Ptr(nil)), gcsPkgPath, "Ptr"}, + + 44: {to((*gcs.Int)(nil)), "some/pkg", "*gcs.Int"}, + 45: {to((*gcs.Int)(nil)), gcsPkgPath, "*Int"}, + } + + for i, tc := range testCases { + ExpectEq( + tc.expected, + typeString(tc.t, tc.pkgPath), + "Case %d: %v, %q", i, tc.t, tc.pkgPath) + } +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/integration_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/integration_test.go new file mode 100644 index 00000000000..e72f0cbb13b --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/integration_test.go @@ -0,0 +1,129 @@ +// 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 oglemock_test + +import ( + "errors" + . "github.com/smartystreets/assertions/internal/oglematchers" + "github.com/smartystreets/assertions/internal/oglemock" + "github.com/smartystreets/assertions/internal/oglemock/sample/mock_io" + . "github.com/smartystreets/assertions/internal/ogletest" + "path" + "runtime" +) + +//////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////// + +func getLineNumber() int { + _, _, line, _ := runtime.Caller(1) + return line +} + +type IntegrationTest struct { + reporter fakeErrorReporter + controller oglemock.Controller + + reader mock_io.MockReader +} + +func init() { RegisterTestSuite(&IntegrationTest{}) } + +func (t *IntegrationTest) SetUp(c *TestInfo) { + t.reporter.errors = make([]errorReport, 0) + t.reporter.fatalErrors = make([]errorReport, 0) + t.controller = oglemock.NewController(&t.reporter) + + t.reader = mock_io.NewMockReader(t.controller, "") +} + +//////////////////////////////////////////////////////////// +// Tests +//////////////////////////////////////////////////////////// + +func (t *IntegrationTest) UnexpectedCall() { + t.reader.Read([]uint8{1, 2, 3}) + expectedLine := getLineNumber() - 1 + + // An error should have been reported. + AssertEq(1, len(t.reporter.errors), "%v", t.reporter.errors) + AssertEq(0, len(t.reporter.fatalErrors), "%v", t.reporter.fatalErrors) + + r := t.reporter.errors[0] + ExpectEq("integration_test.go", path.Base(r.fileName)) + ExpectEq(expectedLine, r.lineNumber) + ExpectThat(r.err, Error(HasSubstr("Unexpected"))) + ExpectThat(r.err, Error(HasSubstr("Read"))) + ExpectThat(r.err, Error(HasSubstr("[1 2 3]"))) +} + +func (t *IntegrationTest) ZeroValues() { + // Make an unexpected call. + n, err := t.reader.Read([]uint8{}) + + // Check the return values. + ExpectEq(0, n) + ExpectEq(nil, err) +} + +func (t *IntegrationTest) ExpectedCalls() { + // Expectations + t.controller.ExpectCall(t.reader, "Read", "", 112)(nil). + WillOnce(oglemock.Return(17, nil)). + WillOnce(oglemock.Return(19, nil)) + + t.controller.ExpectCall(t.reader, "Read", "", 112)(Not(Equals(nil))). + WillOnce(oglemock.Return(23, errors.New("taco"))) + + // Calls + var n int + var err error + + n, err = t.reader.Read(nil) + ExpectEq(17, n) + ExpectEq(nil, err) + + n, err = t.reader.Read([]byte{}) + ExpectEq(23, n) + ExpectThat(err, Error(Equals("taco"))) + + n, err = t.reader.Read(nil) + ExpectEq(19, n) + ExpectEq(nil, err) + + // Errors + AssertEq(0, len(t.reporter.errors), "%v", t.reporter.errors) + AssertEq(0, len(t.reporter.fatalErrors), "%v", t.reporter.fatalErrors) +} + +func (t *IntegrationTest) WrongTypeForReturn() { + t.controller.ExpectCall(t.reader, "Read", "foo.go", 112)(nil). + WillOnce(oglemock.Return(0, errors.New(""))). + WillOnce(oglemock.Return("taco", errors.New(""))) + + // Errors + AssertEq(0, len(t.reporter.errors), "%v", t.reporter.errors) + AssertEq(1, len(t.reporter.fatalErrors), "%v", t.reporter.fatalErrors) + + r := t.reporter.fatalErrors[0] + ExpectEq("foo.go", r.fileName) + ExpectEq(112, r.lineNumber) + ExpectThat(r.err, Error(HasSubstr("Return"))) + ExpectThat(r.err, Error(HasSubstr("arg 0"))) + ExpectThat(r.err, Error(HasSubstr("int"))) + ExpectThat(r.err, Error(HasSubstr("string"))) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/internal_expectation.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/internal_expectation.go new file mode 100644 index 00000000000..8fa8aeafa42 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/internal_expectation.go @@ -0,0 +1,180 @@ +// 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 oglemock + +import ( + "errors" + "fmt" + "github.com/smartystreets/assertions/internal/oglematchers" + "reflect" + "sync" +) + +// InternalExpectation is exported for purposes of testing only. You should not +// touch it. +// +// InternalExpectation represents an expectation for zero or more calls to a +// mock method, and a set of actions to be taken when those calls are received. +type InternalExpectation struct { + // The signature of the method to which this expectation is bound, for + // checking action types. + methodSignature reflect.Type + + // An error reporter to use for reporting errors in the way that expectations + // are set. + errorReporter ErrorReporter + + // A mutex protecting mutable fields of the struct. + mutex sync.Mutex + + // Matchers that the arguments to the mock method must satisfy in order to + // match this expectation. + ArgMatchers []oglematchers.Matcher + + // The name of the file in which this expectation was expressed. + FileName string + + // The line number at which this expectation was expressed. + LineNumber int + + // The number of times this expectation should be matched, as explicitly + // listed by the user. If there was no explicit number expressed, this is -1. + ExpectedNumMatches int + + // Actions to be taken for the first N calls, one per call in order, where N + // is the length of this slice. + OneTimeActions []Action + + // An action to be taken when the one-time actions have expired, or nil if + // there is no such action. + FallbackAction Action + + // The number of times this expectation has been matched so far. + NumMatches uint +} + +// InternalNewExpectation is exported for purposes of testing only. You should +// not touch it. +func InternalNewExpectation( + reporter ErrorReporter, + methodSignature reflect.Type, + args []interface{}, + fileName string, + lineNumber int) *InternalExpectation { + result := &InternalExpectation{} + + // Store fields that can be stored directly. + result.methodSignature = methodSignature + result.errorReporter = reporter + result.FileName = fileName + result.LineNumber = lineNumber + + // Set up defaults. + result.ExpectedNumMatches = -1 + result.OneTimeActions = make([]Action, 0) + + // Set up the ArgMatchers slice, using Equals(x) for each x that is not a + // matcher itself. + result.ArgMatchers = make([]oglematchers.Matcher, len(args)) + for i, x := range args { + if matcher, ok := x.(oglematchers.Matcher); ok { + result.ArgMatchers[i] = matcher + } else { + result.ArgMatchers[i] = oglematchers.Equals(x) + } + } + + return result +} + +func (e *InternalExpectation) Times(n uint) Expectation { + e.mutex.Lock() + defer e.mutex.Unlock() + + // It is illegal to call this more than once. + if e.ExpectedNumMatches != -1 { + e.reportFatalError("Times called more than once.") + return nil + } + + // It is illegal to call this after any actions are configured. + if len(e.OneTimeActions) != 0 { + e.reportFatalError("Times called after WillOnce.") + return nil + } + + if e.FallbackAction != nil { + e.reportFatalError("Times called after WillRepeatedly.") + return nil + } + + // Make sure the number is reasonable (and will fit in an int). + if n > 1000 { + e.reportFatalError("Expectation.Times: N must be at most 1000") + return nil + } + + e.ExpectedNumMatches = int(n) + return e +} + +func (e *InternalExpectation) WillOnce(a Action) Expectation { + e.mutex.Lock() + defer e.mutex.Unlock() + + // It is illegal to call this after WillRepeatedly. + if e.FallbackAction != nil { + e.reportFatalError("WillOnce called after WillRepeatedly.") + return nil + } + + // Tell the action about the method's signature. + if err := a.SetSignature(e.methodSignature); err != nil { + e.reportFatalError(fmt.Sprintf("WillOnce given invalid action: %v", err)) + return nil + } + + // Store the action. + e.OneTimeActions = append(e.OneTimeActions, a) + + return e +} + +func (e *InternalExpectation) WillRepeatedly(a Action) Expectation { + e.mutex.Lock() + defer e.mutex.Unlock() + + // It is illegal to call this twice. + if e.FallbackAction != nil { + e.reportFatalError("WillRepeatedly called more than once.") + return nil + } + + // Tell the action about the method's signature. + if err := a.SetSignature(e.methodSignature); err != nil { + e.reportFatalError(fmt.Sprintf("WillRepeatedly given invalid action: %v", err)) + return nil + } + + // Store the action. + e.FallbackAction = a + + return e +} + +func (e *InternalExpectation) reportFatalError(errorText string) { + e.errorReporter.ReportFatalError(e.FileName, e.LineNumber, errors.New(errorText)) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/internal_expectation_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/internal_expectation_test.go new file mode 100644 index 00000000000..977fe1ac3f7 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/internal_expectation_test.go @@ -0,0 +1,265 @@ +// 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 oglemock_test + +import ( + . "github.com/smartystreets/assertions/internal/oglematchers" + . "github.com/smartystreets/assertions/internal/oglemock" + . "github.com/smartystreets/assertions/internal/ogletest" + "reflect" +) + +//////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////// + +var emptyReturnSig reflect.Type = reflect.TypeOf(func(i int) {}) +var float64ReturnSig reflect.Type = reflect.TypeOf(func(i int) float64 { return 17.0 }) + +type InternalExpectationTest struct { + reporter fakeErrorReporter +} + +func init() { RegisterTestSuite(&InternalExpectationTest{}) } + +func (t *InternalExpectationTest) SetUp(c *TestInfo) { + t.reporter.errors = make([]errorReport, 0) + t.reporter.fatalErrors = make([]errorReport, 0) +} + +func (t *InternalExpectationTest) makeExpectation( + sig reflect.Type, + args []interface{}, + fileName string, + lineNumber int) *InternalExpectation { + return InternalNewExpectation(&t.reporter, sig, args, fileName, lineNumber) +} + +//////////////////////////////////////////////////////////// +// Tests +//////////////////////////////////////////////////////////// + +func (t *InternalExpectationTest) StoresFileNameAndLineNumber() { + args := []interface{}{} + exp := t.makeExpectation(emptyReturnSig, args, "taco", 17) + + ExpectThat(exp.FileName, Equals("taco")) + ExpectThat(exp.LineNumber, Equals(17)) +} + +func (t *InternalExpectationTest) NoArgs() { + args := []interface{}{} + exp := t.makeExpectation(emptyReturnSig, args, "", 0) + + ExpectThat(len(exp.ArgMatchers), Equals(0)) +} + +func (t *InternalExpectationTest) MixOfMatchersAndNonMatchers() { + args := []interface{}{Equals(17), 19, Equals(23)} + exp := t.makeExpectation(emptyReturnSig, args, "", 0) + + // Matcher args + ExpectThat(len(exp.ArgMatchers), Equals(3)) + ExpectThat(exp.ArgMatchers[0], Equals(args[0])) + ExpectThat(exp.ArgMatchers[2], Equals(args[2])) + + // Non-matcher arg + var err error + matcher1 := exp.ArgMatchers[1] + + err = matcher1.Matches(17) + ExpectNe(nil, err) + + err = matcher1.Matches(19) + ExpectEq(nil, err) + + err = matcher1.Matches(23) + ExpectNe(nil, err) +} + +func (t *InternalExpectationTest) NoTimes() { + exp := t.makeExpectation(emptyReturnSig, []interface{}{}, "", 0) + + ExpectThat(exp.ExpectedNumMatches, Equals(-1)) +} + +func (t *InternalExpectationTest) TimesN() { + exp := t.makeExpectation(emptyReturnSig, []interface{}{}, "", 0) + exp.Times(17) + + ExpectThat(exp.ExpectedNumMatches, Equals(17)) +} + +func (t *InternalExpectationTest) NoActions() { + exp := t.makeExpectation(emptyReturnSig, []interface{}{}, "", 0) + + ExpectThat(len(exp.OneTimeActions), Equals(0)) + ExpectThat(exp.FallbackAction, Equals(nil)) +} + +func (t *InternalExpectationTest) WillOnce() { + action0 := Return(17.0) + action1 := Return(19.0) + + exp := t.makeExpectation(float64ReturnSig, []interface{}{}, "", 0) + exp.WillOnce(action0).WillOnce(action1) + + ExpectThat(len(exp.OneTimeActions), Equals(2)) + ExpectThat(exp.OneTimeActions[0], Equals(action0)) + ExpectThat(exp.OneTimeActions[1], Equals(action1)) +} + +func (t *InternalExpectationTest) WillRepeatedly() { + action := Return(17.0) + + exp := t.makeExpectation(float64ReturnSig, []interface{}{}, "", 0) + exp.WillRepeatedly(action) + + ExpectThat(exp.FallbackAction, Equals(action)) +} + +func (t *InternalExpectationTest) BothKindsOfAction() { + action0 := Return(17.0) + action1 := Return(19.0) + action2 := Return(23.0) + + exp := t.makeExpectation(float64ReturnSig, []interface{}{}, "", 0) + exp.WillOnce(action0).WillOnce(action1).WillRepeatedly(action2) + + ExpectThat(len(exp.OneTimeActions), Equals(2)) + ExpectThat(exp.OneTimeActions[0], Equals(action0)) + ExpectThat(exp.OneTimeActions[1], Equals(action1)) + ExpectThat(exp.FallbackAction, Equals(action2)) +} + +func (t *InternalExpectationTest) TimesCalledWithHugeNumber() { + exp := t.makeExpectation(emptyReturnSig, []interface{}{}, "taco.go", 112) + exp.Times(1 << 30) + + AssertEq(1, len(t.reporter.fatalErrors)) + AssertEq(0, len(t.reporter.errors)) + + r := t.reporter.fatalErrors[0] + ExpectEq("taco.go", r.fileName) + ExpectEq(112, r.lineNumber) + ExpectThat(r.err, Error(HasSubstr("Times"))) + ExpectThat(r.err, Error(HasSubstr("N must be at most 1000"))) +} + +func (t *InternalExpectationTest) TimesCalledTwice() { + exp := t.makeExpectation(emptyReturnSig, []interface{}{}, "taco.go", 112) + exp.Times(17) + exp.Times(17) + + AssertEq(1, len(t.reporter.fatalErrors)) + AssertEq(0, len(t.reporter.errors)) + + r := t.reporter.fatalErrors[0] + ExpectEq("taco.go", r.fileName) + ExpectEq(112, r.lineNumber) + ExpectThat(r.err, Error(HasSubstr("Times"))) + ExpectThat(r.err, Error(HasSubstr("more than once"))) +} + +func (t *InternalExpectationTest) TimesCalledAfterWillOnce() { + exp := t.makeExpectation(emptyReturnSig, []interface{}{}, "taco.go", 112) + exp.WillOnce(Return()) + exp.Times(17) + + AssertEq(1, len(t.reporter.fatalErrors)) + AssertEq(0, len(t.reporter.errors)) + + r := t.reporter.fatalErrors[0] + ExpectEq("taco.go", r.fileName) + ExpectEq(112, r.lineNumber) + ExpectThat(r.err, Error(HasSubstr("Times"))) + ExpectThat(r.err, Error(HasSubstr("after WillOnce"))) +} + +func (t *InternalExpectationTest) TimesCalledAfterWillRepeatedly() { + exp := t.makeExpectation(emptyReturnSig, []interface{}{}, "taco.go", 112) + exp.WillRepeatedly(Return()) + exp.Times(17) + + AssertEq(1, len(t.reporter.fatalErrors)) + AssertEq(0, len(t.reporter.errors)) + + r := t.reporter.fatalErrors[0] + ExpectEq("taco.go", r.fileName) + ExpectEq(112, r.lineNumber) + ExpectThat(r.err, Error(HasSubstr("Times"))) + ExpectThat(r.err, Error(HasSubstr("after WillRepeatedly"))) +} + +func (t *InternalExpectationTest) WillOnceCalledAfterWillRepeatedly() { + exp := t.makeExpectation(emptyReturnSig, []interface{}{}, "taco.go", 112) + exp.WillRepeatedly(Return()) + exp.WillOnce(Return()) + + AssertEq(1, len(t.reporter.fatalErrors)) + AssertEq(0, len(t.reporter.errors)) + + r := t.reporter.fatalErrors[0] + ExpectEq("taco.go", r.fileName) + ExpectEq(112, r.lineNumber) + ExpectThat(r.err, Error(HasSubstr("WillOnce"))) + ExpectThat(r.err, Error(HasSubstr("after WillRepeatedly"))) +} + +func (t *InternalExpectationTest) OneTimeActionRejectsSignature() { + exp := t.makeExpectation(float64ReturnSig, []interface{}{}, "taco.go", 112) + exp.WillOnce(Return("taco")) + + AssertEq(1, len(t.reporter.fatalErrors)) + AssertEq(0, len(t.reporter.errors)) + + r := t.reporter.fatalErrors[0] + ExpectEq("taco.go", r.fileName) + ExpectEq(112, r.lineNumber) + ExpectThat(r.err, Error(HasSubstr("arg 0"))) + ExpectThat(r.err, Error(HasSubstr("expected float64"))) + ExpectThat(r.err, Error(HasSubstr("given string"))) +} + +func (t *InternalExpectationTest) WillRepeatedlyCalledTwice() { + exp := t.makeExpectation(emptyReturnSig, []interface{}{}, "taco.go", 112) + exp.WillRepeatedly(Return()) + exp.WillRepeatedly(Return()) + + AssertEq(1, len(t.reporter.fatalErrors)) + AssertEq(0, len(t.reporter.errors)) + + r := t.reporter.fatalErrors[0] + ExpectEq("taco.go", r.fileName) + ExpectEq(112, r.lineNumber) + ExpectThat(r.err, Error(HasSubstr("WillRepeatedly"))) + ExpectThat(r.err, Error(HasSubstr("once"))) +} + +func (t *InternalExpectationTest) FallbackActionRejectsSignature() { + exp := t.makeExpectation(float64ReturnSig, []interface{}{}, "taco.go", 112) + exp.WillRepeatedly(Return("taco")) + + AssertEq(1, len(t.reporter.fatalErrors)) + AssertEq(0, len(t.reporter.errors)) + + r := t.reporter.fatalErrors[0] + ExpectEq("taco.go", r.fileName) + ExpectEq(112, r.lineNumber) + ExpectThat(r.err, Error(HasSubstr("arg 0"))) + ExpectThat(r.err, Error(HasSubstr("expected float64"))) + ExpectThat(r.err, Error(HasSubstr("given string"))) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/invoke.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/invoke.go new file mode 100644 index 00000000000..07630cbbb7e --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/invoke.go @@ -0,0 +1,73 @@ +// 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 oglemock + +import ( + "errors" + "fmt" + "reflect" +) + +// Create an Action that invokes the supplied function, returning whatever it +// returns. The signature of the function must match that of the mocked method +// exactly. +func Invoke(f interface{}) Action { + // Make sure f is a function. + fv := reflect.ValueOf(f) + fk := fv.Kind() + + if fk != reflect.Func { + desc := "<nil>" + if fk != reflect.Invalid { + desc = fv.Type().String() + } + + panic(fmt.Sprintf("Invoke: expected function, got %s", desc)) + } + + return &invokeAction{fv} +} + +type invokeAction struct { + f reflect.Value +} + +func (a *invokeAction) SetSignature(signature reflect.Type) error { + // The signature must match exactly. + ft := a.f.Type() + if ft != signature { + return errors.New(fmt.Sprintf("Invoke: expected %v, got %v", signature, ft)) + } + + return nil +} + +func (a *invokeAction) Invoke(vals []interface{}) []interface{} { + // Create a slice of args for the function. + in := make([]reflect.Value, len(vals)) + for i, x := range vals { + in[i] = reflect.ValueOf(x) + } + + // Call the function and return its return values. + out := a.f.Call(in) + result := make([]interface{}, len(out)) + for i, v := range out { + result[i] = v.Interface() + } + + return result +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/invoke_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/invoke_test.go new file mode 100644 index 00000000000..9e1478ba8cc --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/invoke_test.go @@ -0,0 +1,110 @@ +// 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 oglemock_test + +import ( + . "github.com/smartystreets/assertions/internal/oglematchers" + "github.com/smartystreets/assertions/internal/oglemock" + . "github.com/smartystreets/assertions/internal/ogletest" + "reflect" +) + +//////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////// + +type InvokeTest struct { +} + +func init() { RegisterTestSuite(&InvokeTest{}) } + +//////////////////////////////////////////////////////////// +// Tests +//////////////////////////////////////////////////////////// + +func (t *InvokeTest) ArgumentIsNil() { + f := func() { oglemock.Invoke(nil) } + ExpectThat(f, Panics(MatchesRegexp("Invoke.*function.*<nil>"))) +} + +func (t *InvokeTest) ArgumentIsInt() { + f := func() { oglemock.Invoke(17) } + ExpectThat(f, Panics(MatchesRegexp("Invoke.*function.*int"))) +} + +func (t *InvokeTest) FunctionHasOneWrongInputType() { + f := func(a int, b int32, c string) {} + g := func(a int, b int, c string) {} + + err := oglemock.Invoke(f).SetSignature(reflect.TypeOf(g)) + ExpectThat(err, Error(HasSubstr("func(int, int32, string)"))) + ExpectThat(err, Error(HasSubstr("func(int, int, string)"))) +} + +func (t *InvokeTest) FunctionHasOneWrongOutputType() { + f := func() (int32, string) { return 0, "" } + g := func() (int, string) { return 0, "" } + + err := oglemock.Invoke(f).SetSignature(reflect.TypeOf(g)) + ExpectThat(err, Error(HasSubstr("func() (int32, string)"))) + ExpectThat(err, Error(HasSubstr("func() (int, string)"))) +} + +func (t *InvokeTest) CallsFunction() { + var actualArg0, actualArg1 interface{} + + f := func(a uintptr, b int8) { + actualArg0 = a + actualArg1 = b + } + + a := oglemock.Invoke(f) + + // Set signature. + AssertEq(nil, a.SetSignature(reflect.TypeOf(f))) + + // Call the action. + expectedArg0 := uintptr(17) + expectedArg1 := int8(-7) + + a.Invoke([]interface{}{expectedArg0, expectedArg1}) + + ExpectThat(actualArg0, IdenticalTo(expectedArg0)) + ExpectThat(actualArg1, IdenticalTo(expectedArg1)) +} + +func (t *InvokeTest) ReturnsFunctionResult() { + expectedReturn0 := int16(3) + expectedReturn1 := "taco" + + f := func() (int16, string) { + return expectedReturn0, expectedReturn1 + } + + a := oglemock.Invoke(f) + + // Set signature. + AssertEq(nil, a.SetSignature(reflect.TypeOf(f))) + + // Call the action. + res := a.Invoke([]interface{}{}) + + ExpectThat( + res, + ElementsAre( + IdenticalTo(expectedReturn0), + IdenticalTo(expectedReturn1))) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/mock_object.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/mock_object.go new file mode 100644 index 00000000000..de995efc667 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/mock_object.go @@ -0,0 +1,30 @@ +// 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 oglemock + +// MockObject is an interface that mock object implementations must conform to +// in order to register expectations with and hand off calls to a +// MockController. Users should not interact with this interface directly. +type MockObject interface { + // Oglemock_Id returns an identifier for the mock object that is guaranteed + // to be unique within the process at least until the mock object is garbage + // collected. + Oglemock_Id() uintptr + + // Oglemock_Description returns a description of the mock object that may be + // helpful in test failure messages. + Oglemock_Description() string +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/return.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/return.go new file mode 100644 index 00000000000..c66d248f44a --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/return.go @@ -0,0 +1,251 @@ +// 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 oglemock + +import ( + "errors" + "fmt" + "math" + "reflect" +) + +var intType = reflect.TypeOf(int(0)) +var float64Type = reflect.TypeOf(float64(0)) +var complex128Type = reflect.TypeOf(complex128(0)) + +// Return creates an Action that returns the values passed to Return as +// arguments, after suitable legal type conversions. The following rules apply. +// Given an argument x to Return and a corresponding type T in the method's +// signature, at least one of the following must hold: +// +// * x is assignable to T. (See "Assignability" in the language spec.) Note +// that this in particular applies that x may be a type that implements an +// interface T. It also implies that the nil literal can be used if T is a +// pointer, function, interface, slice, channel, or map type. +// +// * T is any numeric type, and x is an int that is in-range for that type. +// This facilities using raw integer constants: Return(17). +// +// * T is a floating-point or complex number type, and x is a float64. This +// facilities using raw floating-point constants: Return(17.5). +// +// * T is a complex number type, and x is a complex128. This facilities using +// raw complex constants: Return(17+2i). +// +func Return(vals ...interface{}) Action { + return &returnAction{vals, nil} +} + +type returnAction struct { + returnVals []interface{} + signature reflect.Type +} + +func (a *returnAction) Invoke(vals []interface{}) []interface{} { + if a.signature == nil { + panic("You must first call SetSignature with a valid signature.") + } + + res, err := a.buildInvokeResult(a.signature) + if err != nil { + panic(err) + } + + return res +} + +func (a *returnAction) SetSignature(signature reflect.Type) error { + if _, err := a.buildInvokeResult(signature); err != nil { + return err + } + + a.signature = signature + return nil +} + +// A version of Invoke that does error checking, used by both public methods. +func (a *returnAction) buildInvokeResult( + sig reflect.Type) (res []interface{}, err error) { + // Check the length of the return value. + numOut := sig.NumOut() + numVals := len(a.returnVals) + + if numOut != numVals { + err = errors.New( + fmt.Sprintf("Return given %d vals; expected %d.", numVals, numOut)) + return + } + + // Attempt to coerce each return value. + res = make([]interface{}, numOut) + + for i, val := range a.returnVals { + resType := sig.Out(i) + res[i], err = a.coerce(val, resType) + + if err != nil { + res = nil + err = errors.New(fmt.Sprintf("Return: arg %d: %v", i, err)) + return + } + } + + return +} + +func (a *returnAction) coerce(x interface{}, t reflect.Type) (interface{}, error) { + xv := reflect.ValueOf(x) + rv := reflect.New(t).Elem() + + // Special case: the language spec says that the predeclared identifier nil + // is assignable to pointers, functions, interface, slices, channels, and map + // types. However, reflect.ValueOf(nil) returns an invalid value that will + // not cooperate below. So handle invalid values here, assuming that they + // resulted from Return(nil). + if !xv.IsValid() { + switch t.Kind() { + case reflect.Ptr, reflect.Func, reflect.Interface, reflect.Chan, reflect.Slice, reflect.Map, reflect.UnsafePointer: + return rv.Interface(), nil + } + + return nil, errors.New(fmt.Sprintf("expected %v, given <nil>", t)) + } + + // If x is assignable to type t, let the reflect package do the heavy + // lifting. + if reflect.TypeOf(x).AssignableTo(t) { + rv.Set(xv) + return rv.Interface(), nil + } + + // Handle numeric types as described in the documentation on Return. + switch { + case xv.Type() == intType && a.isNumeric(t): + return a.coerceInt(xv.Int(), t) + + case xv.Type() == float64Type && (a.isFloatingPoint(t) || a.isComplex(t)): + return a.coerceFloat(xv.Float(), t) + + case xv.Type() == complex128Type && a.isComplex(t): + return a.coerceComplex(xv.Complex(), t) + } + + // The value wasn't of a legal type. + return nil, errors.New(fmt.Sprintf("expected %v, given %v", t, xv.Type())) +} + +func (a *returnAction) isNumeric(t reflect.Type) bool { + return (t.Kind() >= reflect.Int && t.Kind() <= reflect.Uint64) || + a.isFloatingPoint(t) || + a.isComplex(t) +} + +func (a *returnAction) isFloatingPoint(t reflect.Type) bool { + return t.Kind() == reflect.Float32 || t.Kind() == reflect.Float64 +} + +func (a *returnAction) isComplex(t reflect.Type) bool { + return t.Kind() == reflect.Complex64 || t.Kind() == reflect.Complex128 +} + +func (a *returnAction) coerceInt(x int64, t reflect.Type) (interface{}, error) { + k := t.Kind() + + // Floating point and complex numbers: promote appropriately. + if a.isFloatingPoint(t) || a.isComplex(t) { + return a.coerceFloat(float64(x), t) + } + + // Integers: range check. + var min, max int64 + unsigned := false + + switch k { + case reflect.Int8: + min = math.MinInt8 + max = math.MaxInt8 + + case reflect.Int16: + min = math.MinInt16 + max = math.MaxInt16 + + case reflect.Int32: + min = math.MinInt32 + max = math.MaxInt32 + + case reflect.Int64: + min = math.MinInt64 + max = math.MaxInt64 + + case reflect.Uint: + unsigned = true + min = 0 + max = math.MaxUint32 + + case reflect.Uint8: + unsigned = true + min = 0 + max = math.MaxUint8 + + case reflect.Uint16: + unsigned = true + min = 0 + max = math.MaxUint16 + + case reflect.Uint32: + unsigned = true + min = 0 + max = math.MaxUint32 + + case reflect.Uint64: + unsigned = true + min = 0 + max = math.MaxInt64 + + default: + panic(fmt.Sprintf("Unexpected type: %v", t)) + } + + if x < min || x > max { + return nil, errors.New("int value out of range") + } + + rv := reflect.New(t).Elem() + if unsigned { + rv.SetUint(uint64(x)) + } else { + rv.SetInt(x) + } + + return rv.Interface(), nil +} + +func (a *returnAction) coerceFloat(x float64, t reflect.Type) (interface{}, error) { + // Promote complex numbers. + if a.isComplex(t) { + return a.coerceComplex(complex(x, 0), t) + } + + rv := reflect.New(t).Elem() + rv.SetFloat(x) + return rv.Interface(), nil +} + +func (a *returnAction) coerceComplex(x complex128, t reflect.Type) (interface{}, error) { + rv := reflect.New(t).Elem() + rv.SetComplex(x) + return rv.Interface(), nil +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/return_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/return_test.go new file mode 100644 index 00000000000..f1794bd764a --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/return_test.go @@ -0,0 +1,978 @@ +// 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 oglemock_test + +import ( + "bytes" + . "github.com/smartystreets/assertions/internal/oglematchers" + "github.com/smartystreets/assertions/internal/oglemock" + . "github.com/smartystreets/assertions/internal/ogletest" + "io" + "math" + "reflect" + "testing" + "unsafe" +) + +//////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////// + +var someInt int = 17 + +type ReturnTest struct { +} + +func init() { RegisterTestSuite(&ReturnTest{}) } +func TestOgletest(t *testing.T) { RunTests(t) } + +type returnTestCase struct { + suppliedVal interface{} + expectedVal interface{} + expectedSetSignatureErrorSubstring string +} + +func (t *ReturnTest) runTestCases(signature reflect.Type, cases []returnTestCase) { + for i, c := range cases { + a := oglemock.Return(c.suppliedVal) + + // SetSignature + err := a.SetSignature(signature) + if c.expectedSetSignatureErrorSubstring == "" { + ExpectEq(nil, err, "Test case %d: %v", i, c) + + if err != nil { + continue + } + } else { + ExpectThat(err, Error(HasSubstr(c.expectedSetSignatureErrorSubstring)), + "Test case %d: %v", i, c) + continue + } + + // Invoke + res := a.Invoke([]interface{}{}) + AssertThat(res, ElementsAre(Any())) + ExpectThat(res[0], IdenticalTo(c.expectedVal), "Test case %d: %v", i, c) + } +} + +//////////////////////////////////////////////////////////// +// Tests +//////////////////////////////////////////////////////////// + +func (t *ReturnTest) SetSignatureNotCalled() { + a := oglemock.Return() + f := func() { a.Invoke([]interface{}{}) } + ExpectThat(f, Panics(MatchesRegexp("first call SetSignature"))) +} + +func (t *ReturnTest) NoReturnValues() { + sig := reflect.TypeOf(func() {}) + var a oglemock.Action + var err error + var vals []interface{} + + // No values. + a = oglemock.Return() + err = a.SetSignature(sig) + AssertEq(nil, err) + + vals = a.Invoke([]interface{}{}) + ExpectThat(vals, ElementsAre()) + + // One value. + a = oglemock.Return(17) + err = a.SetSignature(sig) + ExpectThat(err, Error(HasSubstr("given 1 val"))) + ExpectThat(err, Error(HasSubstr("expected 0"))) + + // Two values. + a = oglemock.Return(17, 19) + err = a.SetSignature(sig) + ExpectThat(err, Error(HasSubstr("given 2 vals"))) + ExpectThat(err, Error(HasSubstr("expected 0"))) +} + +func (t *ReturnTest) MultipleReturnValues() { + sig := reflect.TypeOf(func() (int, string) { return 0, "" }) + var a oglemock.Action + var err error + var vals []interface{} + + // No values. + a = oglemock.Return() + err = a.SetSignature(sig) + ExpectThat(err, Error(HasSubstr("given 0 vals"))) + ExpectThat(err, Error(HasSubstr("expected 2"))) + + // One value. + a = oglemock.Return(17) + err = a.SetSignature(sig) + ExpectThat(err, Error(HasSubstr("given 1 val"))) + ExpectThat(err, Error(HasSubstr("expected 2"))) + + // Two values. + a = oglemock.Return(17, "taco") + err = a.SetSignature(sig) + AssertEq(nil, err) + + vals = a.Invoke([]interface{}{}) + ExpectThat(vals, ElementsAre(IdenticalTo(int(17)), "taco")) +} + +func (t *ReturnTest) Bool() { + sig := reflect.TypeOf(func() bool { return false }) + cases := []returnTestCase{ + // Identical types. + {bool(true), bool(true), ""}, + {bool(false), bool(false), ""}, + + // Wrong types. + {nil, nil, "given <nil>"}, + {int(1), nil, "given int"}, + {float64(1), nil, "given float64"}, + {complex128(1), nil, "given complex128"}, + {&someInt, nil, "given *int"}, + {make(chan int), nil, "given chan int"}, + } + + t.runTestCases(sig, cases) +} + +func (t *ReturnTest) Int() { + sig := reflect.TypeOf(func() int { return 0 }) + cases := []returnTestCase{ + // Identical types. + {int(math.MinInt32), int(math.MinInt32), ""}, + {int(math.MaxInt32), int(math.MaxInt32), ""}, + + // Wrong types. + {nil, nil, "given <nil>"}, + {int16(1), nil, "given int16"}, + {float64(1), nil, "given float64"}, + {complex128(1), nil, "given complex128"}, + {&someInt, nil, "given *int"}, + {make(chan int), nil, "given chan int"}, + } + + t.runTestCases(sig, cases) +} + +func (t *ReturnTest) Int8() { + sig := reflect.TypeOf(func() int8 { return 0 }) + cases := []returnTestCase{ + // Identical types. + {int8(math.MinInt8), int8(math.MinInt8), ""}, + {int8(math.MaxInt8), int8(math.MaxInt8), ""}, + + // In-range ints. + {int(math.MinInt8), int8(math.MinInt8), ""}, + {int(math.MaxInt8), int8(math.MaxInt8), ""}, + + // Out of range ints. + {int(math.MinInt8 - 1), nil, "out of range"}, + {int(math.MaxInt8 + 1), nil, "out of range"}, + + // Wrong types. + {nil, nil, "given <nil>"}, + {int16(1), nil, "given int16"}, + {float64(1), nil, "given float64"}, + {complex128(1), nil, "given complex128"}, + {&someInt, nil, "given *int"}, + {make(chan int), nil, "given chan int"}, + } + + t.runTestCases(sig, cases) +} + +func (t *ReturnTest) Int16() { + sig := reflect.TypeOf(func() int16 { return 0 }) + cases := []returnTestCase{ + // Identical types. + {int16(math.MinInt16), int16(math.MinInt16), ""}, + {int16(math.MaxInt16), int16(math.MaxInt16), ""}, + + // In-range ints. + {int(math.MinInt16), int16(math.MinInt16), ""}, + {int(math.MaxInt16), int16(math.MaxInt16), ""}, + + // Out of range ints. + {int(math.MinInt16 - 1), nil, "out of range"}, + {int(math.MaxInt16 + 1), nil, "out of range"}, + + // Wrong types. + {nil, nil, "given <nil>"}, + {int8(1), nil, "given int8"}, + {float64(1), nil, "given float64"}, + {complex128(1), nil, "given complex128"}, + {&someInt, nil, "given *int"}, + {make(chan int), nil, "given chan int"}, + } + + t.runTestCases(sig, cases) +} + +func (t *ReturnTest) Int32() { + sig := reflect.TypeOf(func() int32 { return 0 }) + cases := []returnTestCase{ + // Identical types. + {int32(math.MinInt32), int32(math.MinInt32), ""}, + {int32(math.MaxInt32), int32(math.MaxInt32), ""}, + + // Aliased version of type. + {rune(17), int32(17), ""}, + + // In-range ints. + {int(math.MinInt32), int32(math.MinInt32), ""}, + {int(math.MaxInt32), int32(math.MaxInt32), ""}, + + // Wrong types. + {nil, nil, "given <nil>"}, + {int16(1), nil, "given int16"}, + {float64(1), nil, "given float64"}, + {complex128(1), nil, "given complex128"}, + {&someInt, nil, "given *int"}, + {make(chan int), nil, "given chan int"}, + } + + t.runTestCases(sig, cases) +} + +func (t *ReturnTest) Rune() { + sig := reflect.TypeOf(func() rune { return 0 }) + cases := []returnTestCase{ + // Identical types. + {rune(math.MinInt32), rune(math.MinInt32), ""}, + {rune(math.MaxInt32), rune(math.MaxInt32), ""}, + + // Aliased version of type. + {int32(17), rune(17), ""}, + + // In-range ints. + {int(math.MinInt32), rune(math.MinInt32), ""}, + {int(math.MaxInt32), rune(math.MaxInt32), ""}, + + // Wrong types. + {nil, nil, "given <nil>"}, + {int16(1), nil, "given int16"}, + {float64(1), nil, "given float64"}, + {complex128(1), nil, "given complex128"}, + {&someInt, nil, "given *int"}, + {make(chan int), nil, "given chan int"}, + } + + t.runTestCases(sig, cases) +} + +func (t *ReturnTest) Int64() { + sig := reflect.TypeOf(func() int64 { return 0 }) + cases := []returnTestCase{ + // Identical types. + {int64(math.MinInt64), int64(math.MinInt64), ""}, + {int64(math.MaxInt64), int64(math.MaxInt64), ""}, + + // In-range ints. + {int(math.MinInt32), int64(math.MinInt32), ""}, + {int(math.MaxInt32), int64(math.MaxInt32), ""}, + + // Wrong types. + {nil, nil, "given <nil>"}, + {int16(1), nil, "given int16"}, + {float64(1), nil, "given float64"}, + {complex128(1), nil, "given complex128"}, + {&someInt, nil, "given *int"}, + {make(chan int), nil, "given chan int"}, + } + + t.runTestCases(sig, cases) +} + +func (t *ReturnTest) Uint() { + sig := reflect.TypeOf(func() uint { return 0 }) + cases := []returnTestCase{ + // Identical types. + {uint(0), uint(0), ""}, + {uint(math.MaxUint32), uint(math.MaxUint32), ""}, + + // In-range ints. + {int(0), uint(0), ""}, + {int(math.MaxInt32), uint(math.MaxInt32), ""}, + + // Out of range ints. + {int(-1), nil, "out of range"}, + + // Wrong types. + {nil, nil, "given <nil>"}, + {int16(1), nil, "given int16"}, + {float64(1), nil, "given float64"}, + {complex128(1), nil, "given complex128"}, + {&someInt, nil, "given *int"}, + {make(chan int), nil, "given chan int"}, + } + + t.runTestCases(sig, cases) +} + +func (t *ReturnTest) Uint8() { + sig := reflect.TypeOf(func() uint8 { return 0 }) + cases := []returnTestCase{ + // Identical types. + {uint8(0), uint8(0), ""}, + {uint8(math.MaxUint8), uint8(math.MaxUint8), ""}, + + // Aliased version of type. + {byte(17), uint8(17), ""}, + + // In-range ints. + {int(0), uint8(0), ""}, + {int(math.MaxUint8), uint8(math.MaxUint8), ""}, + + // Out of range ints. + {int(-1), nil, "out of range"}, + {int(math.MaxUint8 + 1), nil, "out of range"}, + + // Wrong types. + {nil, nil, "given <nil>"}, + {int16(1), nil, "given int16"}, + {float64(1), nil, "given float64"}, + {complex128(1), nil, "given complex128"}, + {&someInt, nil, "given *int"}, + {make(chan int), nil, "given chan int"}, + } + + t.runTestCases(sig, cases) +} + +func (t *ReturnTest) Byte() { + sig := reflect.TypeOf(func() byte { return 0 }) + cases := []returnTestCase{ + // Identical types. + {byte(0), byte(0), ""}, + {byte(math.MaxUint8), byte(math.MaxUint8), ""}, + + // Aliased version of type. + {uint8(17), byte(17), ""}, + + // In-range ints. + {int(0), byte(0), ""}, + {int(math.MaxUint8), byte(math.MaxUint8), ""}, + + // Out of range ints. + {int(-1), nil, "out of range"}, + {int(math.MaxUint8 + 1), nil, "out of range"}, + + // Wrong types. + {nil, nil, "given <nil>"}, + {int16(1), nil, "given int16"}, + {float64(1), nil, "given float64"}, + {complex128(1), nil, "given complex128"}, + {&someInt, nil, "given *int"}, + {make(chan int), nil, "given chan int"}, + } + + t.runTestCases(sig, cases) +} + +func (t *ReturnTest) Uint16() { + sig := reflect.TypeOf(func() uint16 { return 0 }) + cases := []returnTestCase{ + // Identical types. + {uint16(0), uint16(0), ""}, + {uint16(math.MaxUint16), uint16(math.MaxUint16), ""}, + + // In-range ints. + {int(0), uint16(0), ""}, + {int(math.MaxUint16), uint16(math.MaxUint16), ""}, + + // Out of range ints. + {int(-1), nil, "out of range"}, + {int(math.MaxUint16 + 1), nil, "out of range"}, + + // Wrong types. + {nil, nil, "given <nil>"}, + {int16(1), nil, "given int16"}, + {float64(1), nil, "given float64"}, + {complex128(1), nil, "given complex128"}, + {&someInt, nil, "given *int"}, + {make(chan int), nil, "given chan int"}, + } + + t.runTestCases(sig, cases) +} + +func (t *ReturnTest) Uint32() { + sig := reflect.TypeOf(func() uint32 { return 0 }) + cases := []returnTestCase{ + // Identical types. + {uint32(0), uint32(0), ""}, + {uint32(math.MaxUint32), uint32(math.MaxUint32), ""}, + + // In-range ints. + {int(0), uint32(0), ""}, + {int(math.MaxInt32), uint32(math.MaxInt32), ""}, + + // Out of range ints. + {int(-1), nil, "out of range"}, + + // Wrong types. + {nil, nil, "given <nil>"}, + {int16(1), nil, "given int16"}, + {float64(1), nil, "given float64"}, + {complex128(1), nil, "given complex128"}, + {&someInt, nil, "given *int"}, + {make(chan int), nil, "given chan int"}, + } + + t.runTestCases(sig, cases) +} + +func (t *ReturnTest) Uint64() { + sig := reflect.TypeOf(func() uint64 { return 0 }) + cases := []returnTestCase{ + // Identical types. + {uint64(0), uint64(0), ""}, + {uint64(math.MaxUint64), uint64(math.MaxUint64), ""}, + + // In-range ints. + {int(0), uint64(0), ""}, + {int(math.MaxInt32), uint64(math.MaxInt32), ""}, + + // Out of range ints. + {int(-1), nil, "out of range"}, + + // Wrong types. + {nil, nil, "given <nil>"}, + {int16(1), nil, "given int16"}, + {float64(1), nil, "given float64"}, + {complex128(1), nil, "given complex128"}, + {&someInt, nil, "given *int"}, + {make(chan int), nil, "given chan int"}, + } + + t.runTestCases(sig, cases) +} + +func (t *ReturnTest) Uintptr() { + sig := reflect.TypeOf(func() uintptr { return 0 }) + cases := []returnTestCase{ + // Identical types. + {uintptr(17), uintptr(17), ""}, + + // Wrong types. + {nil, nil, "given <nil>"}, + {int(1), nil, "given int"}, + {float64(1), nil, "given float64"}, + {complex128(1), nil, "given complex128"}, + {&someInt, nil, "given *int"}, + {make(chan int), nil, "given chan int"}, + } + + t.runTestCases(sig, cases) +} + +func (t *ReturnTest) Float32() { + sig := reflect.TypeOf(func() float32 { return 0 }) + cases := []returnTestCase{ + // Identical types. + {float32(-17.5), float32(-17.5), ""}, + {float32(17.5), float32(17.5), ""}, + + // In-range ints. + {int(-17), float32(-17), ""}, + {int(17), float32(17), ""}, + + // Float64s + {float64(-17.5), float32(-17.5), ""}, + {float64(17.5), float32(17.5), ""}, + + // Wrong types. + {nil, nil, "given <nil>"}, + {int16(1), nil, "given int16"}, + {complex128(1), nil, "given complex128"}, + {&someInt, nil, "given *int"}, + {make(chan int), nil, "given chan int"}, + } + + t.runTestCases(sig, cases) +} + +func (t *ReturnTest) Float64() { + sig := reflect.TypeOf(func() float64 { return 0 }) + cases := []returnTestCase{ + // Identical types. + {float64(-17.5), float64(-17.5), ""}, + {float64(17.5), float64(17.5), ""}, + + // In-range ints. + {int(-17), float64(-17), ""}, + {int(17), float64(17), ""}, + + // Wrong types. + {nil, nil, "given <nil>"}, + {int16(1), nil, "given int16"}, + {float32(1), nil, "given float32"}, + {complex128(1), nil, "given complex128"}, + {&someInt, nil, "given *int"}, + {make(chan int), nil, "given chan int"}, + } + + t.runTestCases(sig, cases) +} + +func (t *ReturnTest) Complex64() { + sig := reflect.TypeOf(func() complex64 { return 0 }) + cases := []returnTestCase{ + // Identical types. + {complex64(-17.5 - 1i), complex64(-17.5 - 1i), ""}, + {complex64(17.5 + 1i), complex64(17.5 + 1i), ""}, + + // In-range ints. + {int(-17), complex64(-17), ""}, + {int(17), complex64(17), ""}, + + // Float64s + {float64(-17.5), complex64(-17.5), ""}, + {float64(17.5), complex64(17.5), ""}, + + // Complex128s + {complex128(-17.5 - 1i), complex64(-17.5 - 1i), ""}, + {complex128(17.5 + 1i), complex64(17.5 + 1i), ""}, + + // Wrong types. + {nil, nil, "given <nil>"}, + {int16(1), nil, "given int16"}, + {float32(1), nil, "given float32"}, + {&someInt, nil, "given *int"}, + {make(chan int), nil, "given chan int"}, + } + + t.runTestCases(sig, cases) +} + +func (t *ReturnTest) Complex128() { + sig := reflect.TypeOf(func() complex128 { return 0 }) + cases := []returnTestCase{ + // Identical types. + {complex128(-17.5 - 1i), complex128(-17.5 - 1i), ""}, + {complex128(17.5 + 1i), complex128(17.5 + 1i), ""}, + + // In-range ints. + {int(-17), complex128(-17), ""}, + {int(17), complex128(17), ""}, + + // Float64s + {float64(-17.5), complex128(-17.5), ""}, + {float64(17.5), complex128(17.5), ""}, + + // Wrong types. + {nil, nil, "given <nil>"}, + {int16(1), nil, "given int16"}, + {float32(1), nil, "given float32"}, + {complex64(1), nil, "given complex64"}, + {&someInt, nil, "given *int"}, + {make(chan int), nil, "given chan int"}, + } + + t.runTestCases(sig, cases) +} + +func (t *ReturnTest) ArrayOfInt() { + type namedElemType int + + sig := reflect.TypeOf(func() [2]int { return [2]int{0, 0} }) + cases := []returnTestCase{ + // Identical types. + {[2]int{19, 23}, [2]int{19, 23}, ""}, + + // Wrong length. + {[1]int{17}, nil, "given [1]int"}, + + // Wrong element types. + {[2]namedElemType{19, 23}, nil, "given [2]oglemock_test.namedElemType"}, + {[2]string{"", ""}, nil, "given [2]string"}, + + // Wrong types. + {nil, nil, "given <nil>"}, + {int(1), nil, "given int"}, + {float64(1), nil, "given float64"}, + {complex128(1), nil, "given complex128"}, + {&someInt, nil, "given *int"}, + {make(chan int), nil, "given chan int"}, + } + + t.runTestCases(sig, cases) +} + +func (t *ReturnTest) ChanOfInt() { + type namedElemType int + someChan := make(chan int) + + sig := reflect.TypeOf(func() chan int { return nil }) + cases := []returnTestCase{ + // Identical types. + {someChan, someChan, ""}, + + // Nil values. + {(interface{})(nil), (chan int)(nil), ""}, + {(chan int)(nil), (chan int)(nil), ""}, + + // Wrong element types. + {make(chan string), nil, "given chan string"}, + {make(chan namedElemType), nil, "given chan oglemock_test.namedElemType"}, + + // Wrong direction + {(<-chan int)(someChan), nil, "given <-chan int"}, + {(chan<- int)(someChan), nil, "given chan<- int"}, + + // Wrong types. + {(func())(nil), nil, "given func()"}, + {int(1), nil, "given int"}, + {float64(1), nil, "given float64"}, + {complex128(1), nil, "given complex128"}, + {&someInt, nil, "given *int"}, + } + + t.runTestCases(sig, cases) +} + +func (t *ReturnTest) SendChanOfInt() { + type namedElemType int + + someChan := make(chan<- int) + someBidirectionalChannel := make(chan int) + + sig := reflect.TypeOf(func() chan<- int { return nil }) + cases := []returnTestCase{ + // Identical types. + {someChan, someChan, ""}, + + // Nil values. + {(interface{})(nil), (chan<- int)(nil), ""}, + {(chan int)(nil), (chan<- int)(nil), ""}, + + // Bidirectional channel + {someBidirectionalChannel, (chan<- int)(someBidirectionalChannel), ""}, + + // Wrong direction + {(<-chan int)(someBidirectionalChannel), nil, "given <-chan int"}, + + // Wrong element types. + {make(chan string), nil, "given chan string"}, + {make(chan namedElemType), nil, "given chan oglemock_test.namedElemType"}, + + // Wrong types. + {(func())(nil), nil, "given func()"}, + {int(1), nil, "given int"}, + {float64(1), nil, "given float64"}, + {complex128(1), nil, "given complex128"}, + {&someInt, nil, "given *int"}, + } + + t.runTestCases(sig, cases) +} + +func (t *ReturnTest) RecvChanOfInt() { + type namedElemType int + + someChan := make(<-chan int) + someBidirectionalChannel := make(chan int) + + sig := reflect.TypeOf(func() <-chan int { return nil }) + cases := []returnTestCase{ + // Identical types. + {someChan, someChan, ""}, + + // Nil values. + {(interface{})(nil), (<-chan int)(nil), ""}, + {(chan int)(nil), (<-chan int)(nil), ""}, + + // Bidirectional channel + {someBidirectionalChannel, (<-chan int)(someBidirectionalChannel), ""}, + + // Wrong direction + {(chan<- int)(someBidirectionalChannel), nil, "given chan<- int"}, + + // Wrong element types. + {make(chan string), nil, "given chan string"}, + {make(chan namedElemType), nil, "given chan oglemock_test.namedElemType"}, + + // Wrong types. + {(func())(nil), nil, "given func()"}, + {int(1), nil, "given int"}, + {float64(1), nil, "given float64"}, + {complex128(1), nil, "given complex128"}, + {&someInt, nil, "given *int"}, + } + + t.runTestCases(sig, cases) +} + +func (t *ReturnTest) Func() { + someFunc := func(string) int { return 0 } + + sig := reflect.TypeOf(func() func(string) int { return nil }) + cases := []returnTestCase{ + // Identical types. + {someFunc, someFunc, ""}, + + // Nil values. + {(interface{})(nil), (func(string) int)(nil), ""}, + {(func(string) int)(nil), (func(string) int)(nil), ""}, + + // Wrong parameter and return types. + {func(int) int { return 0 }, nil, "given func(int) int"}, + {func(string) string { return "" }, nil, "given func(string) string"}, + + // Wrong types. + {int(1), nil, "given int"}, + {float64(1), nil, "given float64"}, + {complex128(1), nil, "given complex128"}, + {&someInt, nil, "given *int"}, + {(chan int)(nil), nil, "given chan int"}, + } + + t.runTestCases(sig, cases) +} + +func (t *ReturnTest) Interface() { + sig := reflect.TypeOf(func() io.Reader { return nil }) + + someBuffer := new(bytes.Buffer) + + cases := []returnTestCase{ + // Type that implements interface. + {someBuffer, someBuffer, ""}, + + // Nil value. + {(interface{})(nil), (interface{})(nil), ""}, + + // Non-implementing types. + {(chan int)(nil), nil, "given chan int"}, + {int(1), nil, "given int"}, + {float64(1), nil, "given float64"}, + {complex128(1), nil, "given complex128"}, + {&someInt, nil, "given *int"}, + } + + t.runTestCases(sig, cases) +} + +func (t *ReturnTest) MapFromStringToInt() { + type namedElemType string + + someMap := make(map[string]int) + + sig := reflect.TypeOf(func() map[string]int { return nil }) + cases := []returnTestCase{ + // Identical types. + {someMap, someMap, ""}, + + // Nil values. + {(interface{})(nil), (map[string]int)(nil), ""}, + {(map[string]int)(nil), (map[string]int)(nil), ""}, + + // Wrong element types. + {make(map[int]int), nil, "given map[int]int"}, + {make(map[namedElemType]int), nil, "given map[oglemock_test.namedElemType]int"}, + {make(map[string]string), nil, "given map[string]string"}, + + // Wrong types. + {(func())(nil), nil, "given func()"}, + {int(1), nil, "given int"}, + {float64(1), nil, "given float64"}, + {complex128(1), nil, "given complex128"}, + {&someInt, nil, "given *int"}, + } + + t.runTestCases(sig, cases) +} + +func (t *ReturnTest) PointerToString() { + type namedElemType string + + someStr := "" + + sig := reflect.TypeOf(func() *string { return nil }) + cases := []returnTestCase{ + // Identical types. + {(*string)(&someStr), (*string)(&someStr), ""}, + + // Nil values. + {(interface{})(nil), (*string)(nil), ""}, + {(*string)(nil), (*string)(nil), ""}, + + // Wrong element types. + {&someInt, nil, "given *int"}, + + // Wrong types. + {(func())(nil), nil, "given func()"}, + {int(1), nil, "given int"}, + {float64(1), nil, "given float64"}, + {complex128(1), nil, "given complex128"}, + {unsafe.Pointer(&someStr), nil, "given unsafe.Pointer"}, + } + + t.runTestCases(sig, cases) +} + +func (t *ReturnTest) SliceOfInts() { + type namedElemType int + + someSlice := make([]int, 1) + + sig := reflect.TypeOf(func() []int { return nil }) + cases := []returnTestCase{ + // Identical types. + {someSlice, someSlice, ""}, + + // Nil values. + {(interface{})(nil), ([]int)(nil), ""}, + {([]int)(nil), ([]int)(nil), ""}, + + // Wrong element types. + {make([]string, 1), nil, "given []string"}, + {make([]namedElemType, 1), nil, "given []oglemock_test.namedElemType"}, + + // Wrong types. + {(func())(nil), nil, "given func()"}, + {int(1), nil, "given int"}, + {float64(1), nil, "given float64"}, + {complex128(1), nil, "given complex128"}, + {&someInt, nil, "given *int"}, + } + + t.runTestCases(sig, cases) +} + +func (t *ReturnTest) String() { + sig := reflect.TypeOf(func() string { return "" }) + cases := []returnTestCase{ + // Identical types. + {string(""), string(""), ""}, + {string("taco"), string("taco"), ""}, + + // Wrong types. + {nil, nil, "given <nil>"}, + {int(1), nil, "given int"}, + {float64(1), nil, "given float64"}, + {complex128(1), nil, "given complex128"}, + {&someInt, nil, "given *int"}, + {make(chan int), nil, "given chan int"}, + } + + t.runTestCases(sig, cases) +} + +func (t *ReturnTest) Struct() { + type myStruct struct { + a int + } + + type otherStruct struct{} + + sig := reflect.TypeOf(func() myStruct { return myStruct{0} }) + cases := []returnTestCase{ + // Identical types. + {myStruct{17}, myStruct{17}, ""}, + + // Wrong field types. + {otherStruct{}, nil, "given oglemock_test.otherStruct"}, + + // Wrong types. + {nil, nil, "given <nil>"}, + {int(1), nil, "given int"}, + {float64(1), nil, "given float64"}, + {complex128(1), nil, "given complex128"}, + {&someInt, nil, "given *int"}, + {make(chan int), nil, "given chan int"}, + } + + t.runTestCases(sig, cases) +} + +func (t *ReturnTest) UnsafePointer() { + someStr := "" + + sig := reflect.TypeOf(func() unsafe.Pointer { return nil }) + cases := []returnTestCase{ + // Identical types. + {unsafe.Pointer(&someStr), unsafe.Pointer(&someStr), ""}, + + // Nil values. + {(interface{})(nil), unsafe.Pointer(nil), ""}, + {unsafe.Pointer(nil), unsafe.Pointer(nil), ""}, + + // Wrong types. + {(func())(nil), nil, "given func()"}, + {int(1), nil, "given int"}, + {float64(1), nil, "given float64"}, + {complex128(1), nil, "given complex128"}, + {(*string)(&someStr), nil, "given *string"}, + } + + t.runTestCases(sig, cases) +} + +func (t *ReturnTest) UserDefinedNumericType() { + type myType int16 + + sig := reflect.TypeOf(func() myType { return 0 }) + cases := []returnTestCase{ + // Identical types. + {myType(math.MinInt16), myType(math.MinInt16), ""}, + {myType(math.MaxInt16), myType(math.MaxInt16), ""}, + + // In-range ints. + {int(math.MinInt16), myType(math.MinInt16), ""}, + {int(math.MaxInt16), myType(math.MaxInt16), ""}, + + // Out of range ints. + {int(math.MinInt16 - 1), nil, "out of range"}, + {int(math.MaxInt16 + 1), nil, "out of range"}, + + // Wrong types. + {nil, nil, "given <nil>"}, + {int16(1), nil, "given int16"}, + {float64(1), nil, "given float64"}, + {complex128(1), nil, "given complex128"}, + {&someInt, nil, "given *int"}, + {make(chan int), nil, "given chan int"}, + } + + t.runTestCases(sig, cases) +} + +func (t *ReturnTest) UserDefinedNonNumericType() { + type myType string + + sig := reflect.TypeOf(func() myType { return "" }) + cases := []returnTestCase{ + // Identical types. + {myType("taco"), myType("taco"), ""}, + + // Wrong types. + {nil, nil, "given <nil>"}, + {int(1), nil, "given int"}, + {float64(1), nil, "given float64"}, + {complex128(1), nil, "given complex128"}, + {string(""), nil, "given string"}, + {&someInt, nil, "given *int"}, + {make(chan int), nil, "given chan int"}, + } + + t.runTestCases(sig, cases) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/sample/README.markdown b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/sample/README.markdown new file mode 100644 index 00000000000..60d5d2cb1ab --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/sample/README.markdown @@ -0,0 +1,6 @@ +This directory contains sample code generated with the `createmock` command. For +example, the file `mock_io.go` can be regenerated with: + + createmock io Reader > sample/mock_io/mock_io.go + +The files are also used by `integration_test.go`. diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/sample/mock_io/mock_io.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/sample/mock_io/mock_io.go new file mode 100644 index 00000000000..76e8f00056d --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/sample/mock_io/mock_io.go @@ -0,0 +1,71 @@ +// This file was auto-generated using createmock. See the following page for +// more information: +// +// https://github.com/smartystreets/assertions/internal/oglemock +// + +package mock_io + +import ( + fmt "fmt" + oglemock "github.com/smartystreets/assertions/internal/oglemock" + io "io" + runtime "runtime" + unsafe "unsafe" +) + +type MockReader interface { + io.Reader + oglemock.MockObject +} + +type mockReader struct { + controller oglemock.Controller + description string +} + +func NewMockReader( + c oglemock.Controller, + desc string) MockReader { + return &mockReader{ + controller: c, + description: desc, + } +} + +func (m *mockReader) Oglemock_Id() uintptr { + return uintptr(unsafe.Pointer(m)) +} + +func (m *mockReader) Oglemock_Description() string { + return m.description +} + +func (m *mockReader) Read(p0 []uint8) (o0 int, o1 error) { + // Get a file name and line number for the caller. + _, file, line, _ := runtime.Caller(1) + + // Hand the call off to the controller, which does most of the work. + retVals := m.controller.HandleMethodCall( + m, + "Read", + file, + line, + []interface{}{p0}) + + if len(retVals) != 2 { + panic(fmt.Sprintf("mockReader.Read: invalid return values: %v", retVals)) + } + + // o0 int + if retVals[0] != nil { + o0 = retVals[0].(int) + } + + // o1 error + if retVals[1] != nil { + o1 = retVals[1].(error) + } + + return +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/save_arg.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/save_arg.go new file mode 100644 index 00000000000..27cfcf6193b --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/save_arg.go @@ -0,0 +1,83 @@ +// 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 oglemock + +import ( + "fmt" + "reflect" +) + +// Create an Action that saves the argument at the given zero-based index to +// the supplied destination, which must be a pointer to a type that is +// assignable from the argument type. +func SaveArg(index int, dst interface{}) Action { + return &saveArg{ + index: index, + dstPointer: dst, + } +} + +type saveArg struct { + index int + dstPointer interface{} + + // Set by SetSignature. + dstValue reflect.Value +} + +func (a *saveArg) SetSignature(signature reflect.Type) (err error) { + // Extract the source type. + if a.index >= signature.NumIn() { + err = fmt.Errorf( + "Out of range argument index %v for function type %v", + a.index, + signature) + return + } + + srcType := signature.In(a.index) + + // The destination must be a pointer. + v := reflect.ValueOf(a.dstPointer) + if v.Kind() != reflect.Ptr { + err = fmt.Errorf("Destination is %v, not a pointer", v.Kind()) + return + } + + // Dereference the pointer. + if v.IsNil() { + err = fmt.Errorf("Destination pointer must be non-nil") + return + } + + a.dstValue = v.Elem() + + // The destination must be assignable from the source. + if !srcType.AssignableTo(a.dstValue.Type()) { + err = fmt.Errorf( + "%v is not assignable to %v", + srcType, + a.dstValue.Type()) + return + } + + return +} + +func (a *saveArg) Invoke(methodArgs []interface{}) (rets []interface{}) { + a.dstValue.Set(reflect.ValueOf(methodArgs[a.index])) + return +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/save_arg_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/save_arg_test.go new file mode 100644 index 00000000000..4051907e0dd --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglemock/save_arg_test.go @@ -0,0 +1,132 @@ +// 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 oglemock_test + +import ( + "io" + "os" + "reflect" + "testing" + + . "github.com/smartystreets/assertions/internal/oglematchers" + "github.com/smartystreets/assertions/internal/oglemock" + . "github.com/smartystreets/assertions/internal/ogletest" +) + +func TestSaveArg(t *testing.T) { RunTests(t) } + +//////////////////////////////////////////////////////////// +// Boilerplate +//////////////////////////////////////////////////////////// + +type SaveArgTest struct { +} + +func init() { RegisterTestSuite(&SaveArgTest{}) } + +//////////////////////////////////////////////////////////// +// Test functions +//////////////////////////////////////////////////////////// + +func (t *SaveArgTest) FunctionHasNoArguments() { + const index = 0 + var dst int + f := func() (int, string) { return 0, "" } + + err := oglemock.SaveArg(index, &dst).SetSignature(reflect.TypeOf(f)) + ExpectThat(err, Error(HasSubstr("index 0"))) + ExpectThat(err, Error(HasSubstr("Out of range"))) + ExpectThat(err, Error(HasSubstr("func() (int, string)"))) +} + +func (t *SaveArgTest) ArgumentIndexOutOfRange() { + const index = 2 + var dst int + f := func(a int, b int) {} + + err := oglemock.SaveArg(index, &dst).SetSignature(reflect.TypeOf(f)) + ExpectThat(err, Error(HasSubstr("index 2"))) + ExpectThat(err, Error(HasSubstr("Out of range"))) + ExpectThat(err, Error(HasSubstr("func(int, int)"))) +} + +func (t *SaveArgTest) DestinationIsLiteralNil() { + const index = 0 + f := func(a int, b int) {} + + err := oglemock.SaveArg(index, nil).SetSignature(reflect.TypeOf(f)) + ExpectThat(err, Error(HasSubstr("not a pointer"))) +} + +func (t *SaveArgTest) DestinationIsNotAPointer() { + const index = 0 + f := func(a int, b int) {} + + err := oglemock.SaveArg(index, uint(17)).SetSignature(reflect.TypeOf(f)) + ExpectThat(err, Error(HasSubstr("pointer"))) + ExpectThat(err, Error(HasSubstr("uint"))) +} + +func (t *SaveArgTest) DestinationIsNilPointer() { + const index = 1 + var dst *int + f := func(a int, b int) {} + + err := oglemock.SaveArg(index, dst).SetSignature(reflect.TypeOf(f)) + ExpectThat(err, Error(HasSubstr("pointer"))) + ExpectThat(err, Error(HasSubstr("non-nil"))) +} + +func (t *SaveArgTest) DestinationNotAssignableFromSource() { + const index = 1 + var dst int + f := func(a int, b string) {} + + err := oglemock.SaveArg(index, &dst).SetSignature(reflect.TypeOf(f)) + ExpectThat(err, Error(HasSubstr("int"))) + ExpectThat(err, Error(HasSubstr("assignable"))) + ExpectThat(err, Error(HasSubstr("string"))) +} + +func (t *SaveArgTest) ExactTypeMatch() { + const index = 1 + var dst int + f := func(a int, b int) {} + + action := oglemock.SaveArg(index, &dst) + AssertEq(nil, action.SetSignature(reflect.TypeOf(f))) + + var a int = 17 + var b int = 19 + _ = action.Invoke([]interface{}{a, b}) + + ExpectEq(19, dst) +} + +func (t *SaveArgTest) AssignableTypeMatch() { + const index = 1 + var dst io.Reader + f := func(a int, b *os.File) {} + + action := oglemock.SaveArg(index, &dst) + AssertEq(nil, action.SetSignature(reflect.TypeOf(f))) + + var a int = 17 + var b *os.File = os.Stdout + _ = action.Invoke([]interface{}{a, b}) + + ExpectEq(os.Stdout, dst) +} |