diff options
Diffstat (limited to 'src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal')
142 files changed, 25462 insertions, 0 deletions
diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/Makefile b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/Makefile new file mode 100644 index 00000000000..0894b82bd81 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/Makefile @@ -0,0 +1,23 @@ +# This Makefile pulls the latest oglematchers (with dependencies), +# rewrites the imports to match this location, +# and ensures that all the tests pass. + +go: clean clone rewrite + +clean: + rm -rf ogle* + rm -rf reqtrace + rm -rf go-render + +clone: + git clone https://github.com/jacobsa/ogletest.git && rm -rf ogletest/.git + git clone https://github.com/jacobsa/oglemock.git && rm -rf oglemock/.git + git clone https://github.com/jacobsa/oglematchers.git && rm -rf oglematchers/.git + git clone https://github.com/jacobsa/reqtrace.git && rm -rf reqtrace/.git + git clone https://github.com/luci/go-render.git && rm -rf go-render/.git + +rewrite: + grep -rl --exclude Makefile 'github.com/jacobsa' . | xargs sed -i '' 's#github.com/jacobsa#github.com/smartystreets/assertions/internal#g' + +test: + go test github.com/smartystreets/assertions/... diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/go-render/.travis.yml b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/go-render/.travis.yml new file mode 100644 index 00000000000..5a19a5faf38 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/go-render/.travis.yml @@ -0,0 +1,21 @@ +# Copyright (c) 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# {sudo: required, dist: trusty} is the magic incantation to pick the trusty +# beta environment, which is the only environment we can get that has >4GB +# memory. Currently the `go test -race` tests that we run will peak at just +# over 4GB, which results in everything getting OOM-killed. +sudo: required +dist: trusty + +language: go + +go: +- 1.4.2 + +before_install: + - go get github.com/maruel/pre-commit-go/cmd/pcg + +script: + - pcg diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/go-render/LICENSE b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/go-render/LICENSE new file mode 100644 index 00000000000..6280ff0e06b --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/go-render/LICENSE @@ -0,0 +1,27 @@ +// Copyright (c) 2015 The Chromium Authors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/go-render/PRESUBMIT.py b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/go-render/PRESUBMIT.py new file mode 100644 index 00000000000..d05f0cd8734 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/go-render/PRESUBMIT.py @@ -0,0 +1,109 @@ +# Copyright 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Top-level presubmit script. + +See https://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts for +details on the presubmit API built into depot_tools. +""" + +import os +import sys + + +def PreCommitGo(input_api, output_api, pcg_mode): + """Run go-specific checks via pre-commit-go (pcg) if it's in PATH.""" + if input_api.is_committing: + error_type = output_api.PresubmitError + else: + error_type = output_api.PresubmitPromptWarning + + exe = 'pcg.exe' if sys.platform == 'win32' else 'pcg' + pcg = None + for p in os.environ['PATH'].split(os.pathsep): + pcg = os.path.join(p, exe) + if os.access(pcg, os.X_OK): + break + else: + return [ + error_type( + 'pre-commit-go executable (pcg) could not be found in PATH. All Go ' + 'checks are skipped. See https://github.com/maruel/pre-commit-go.') + ] + + cmd = [pcg, 'run', '-m', ','.join(pcg_mode)] + if input_api.verbose: + cmd.append('-v') + # pcg can figure out what files to check on its own based on upstream ref, + # but on PRESUBMIT try builder upsteram isn't set, and it's just 1 commit. + if os.getenv('PRESUBMIT_BUILDER', ''): + cmd.extend(['-r', 'HEAD~1']) + return input_api.RunTests([ + input_api.Command( + name='pre-commit-go: %s' % ', '.join(pcg_mode), + cmd=cmd, + kwargs={}, + message=error_type), + ]) + + +def header(input_api): + """Returns the expected license header regexp for this project.""" + current_year = int(input_api.time.strftime('%Y')) + allowed_years = (str(s) for s in reversed(xrange(2011, current_year + 1))) + years_re = '(' + '|'.join(allowed_years) + ')' + license_header = ( + r'.*? Copyright %(year)s The Chromium Authors\. ' + r'All rights reserved\.\n' + r'.*? Use of this source code is governed by a BSD-style license ' + r'that can be\n' + r'.*? found in the LICENSE file\.(?: \*/)?\n' + ) % { + 'year': years_re, + } + return license_header + + +def source_file_filter(input_api): + """Returns filter that selects source code files only.""" + bl = list(input_api.DEFAULT_BLACK_LIST) + [ + r'.+\.pb\.go$', + r'.+_string\.go$', + ] + wl = list(input_api.DEFAULT_WHITE_LIST) + [ + r'.+\.go$', + ] + return lambda x: input_api.FilterSourceFile(x, white_list=wl, black_list=bl) + + +def CommonChecks(input_api, output_api): + results = [] + results.extend( + input_api.canned_checks.CheckChangeHasNoStrayWhitespace( + input_api, output_api, + source_file_filter=source_file_filter(input_api))) + results.extend( + input_api.canned_checks.CheckLicense( + input_api, output_api, header(input_api), + source_file_filter=source_file_filter(input_api))) + return results + + +def CheckChangeOnUpload(input_api, output_api): + results = CommonChecks(input_api, output_api) + results.extend(PreCommitGo(input_api, output_api, ['lint', 'pre-commit'])) + return results + + +def CheckChangeOnCommit(input_api, output_api): + results = CommonChecks(input_api, output_api) + results.extend(input_api.canned_checks.CheckChangeHasDescription( + input_api, output_api)) + results.extend(input_api.canned_checks.CheckDoNotSubmitInDescription( + input_api, output_api)) + results.extend(input_api.canned_checks.CheckDoNotSubmitInFiles( + input_api, output_api)) + results.extend(PreCommitGo( + input_api, output_api, ['continuous-integration'])) + return results diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/go-render/README.md b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/go-render/README.md new file mode 100644 index 00000000000..a85380c421a --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/go-render/README.md @@ -0,0 +1,78 @@ +go-render: A verbose recursive Go type-to-string conversion library. +==================================================================== + +[![GoDoc](https://godoc.org/github.com/luci/go-render?status.svg)](https://godoc.org/github.com/luci/go-render) +[![Build Status](https://travis-ci.org/luci/go-render.svg)](https://travis-ci.org/luci/go-render) + +This is not an official Google product. + +## Overview + +The *render* package implements a more verbose form of the standard Go string +formatter, `fmt.Sprintf("%#v", value)`, adding: + - Pointer recursion. Normally, Go stops at the first pointer and prints its + address. The *render* package will recurse and continue to render pointer + values. + - Recursion loop detection. Recursion is nice, but if a recursion path detects + a loop, *render* will note this and move on. + - Custom type name rendering. + - Deterministic key sorting for `string`- and `int`-keyed maps. + - Testing! + +Call `render.Render` and pass it an `interface{}`. + +For example: + +```Go +type customType int +type testStruct struct { + S string + V *map[string]int + I interface{} +} + +a := testStruct{ + S: "hello", + V: &map[string]int{"foo": 0, "bar": 1}, + I: customType(42), +} + +fmt.Println("Render test:") +fmt.Printf("fmt.Printf: %#v\n", a))) +fmt.Printf("render.Render: %s\n", Render(a)) +``` + +Yields: +``` +fmt.Printf: render.testStruct{S:"hello", V:(*map[string]int)(0x600dd065), I:42} +render.Render: render.testStruct{S:"hello", V:(*map[string]int){"bar":1, "foo":0}, I:render.customType(42)} +``` + +This is not intended to be a high-performance library, but it's not terrible +either. + +Contributing +------------ + + * Sign the [Google CLA](https://cla.developers.google.com/clas). + * Make sure your `user.email` and `user.name` are configured in `git config`. + * Install the [pcg](https://github.com/maruel/pre-commit-go) git hook: + `go get -u github.com/maruel/pre-commit-go/cmd/... && pcg` + +Run the following to setup the code review tool and create your first review: + + git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git $HOME/src/depot_tools + export PATH="$PATH:$HOME/src/depot_tools" + cd $GOROOT/github.com/luci/go-render + git checkout -b work origin/master + + # hack hack + + git commit -a -m "This is awesome\nR=joe@example.com" + # This will ask for your Google Account credentials. + git cl upload -s + # Wait for LGTM over email. + # Check the commit queue box in codereview website. + # Wait for the change to be tested and landed automatically. + +Use `git cl help` and `git cl help <cmd>` for more details. diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/go-render/WATCHLISTS b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/go-render/WATCHLISTS new file mode 100644 index 00000000000..e4172088dd3 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/go-render/WATCHLISTS @@ -0,0 +1,26 @@ +# Copyright 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# Watchlist Rules +# Refer: http://dev.chromium.org/developers/contributing-code/watchlists + +{ + + 'WATCHLIST_DEFINITIONS': { + 'all': { + 'filepath': '.+', + }, + }, + + 'WATCHLISTS': { + 'all': [ + # Add yourself here to get explicitly spammed. + 'maruel@chromium.org', + 'tandrii+luci-go@chromium.org', + 'todd@cloudera.com', + 'andrew.wang@cloudera.com', + ], + }, + +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/go-render/pre-commit-go.yml b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/go-render/pre-commit-go.yml new file mode 100644 index 00000000000..074ee1f84df --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/go-render/pre-commit-go.yml @@ -0,0 +1,78 @@ +# https://github.com/maruel/pre-commit-go configuration file to run checks +# automatically on commit, on push and on continuous integration service after +# a push or on merge of a pull request. +# +# See https://godoc.org/github.com/maruel/pre-commit-go/checks for more +# information. + +min_version: 0.4.7 +modes: + continuous-integration: + checks: + build: + - build_all: false + extra_args: [] + coverage: + - use_global_inference: false + use_coveralls: true + global: + min_coverage: 50 + max_coverage: 100 + per_dir_default: + min_coverage: 1 + max_coverage: 100 + per_dir: {} + gofmt: + - {} + goimports: + - {} + test: + - extra_args: + - -v + - -race + max_duration: 600 + lint: + checks: + golint: + - blacklist: [] + govet: + - blacklist: + - ' composite literal uses unkeyed fields' + max_duration: 15 + pre-commit: + checks: + build: + - build_all: false + extra_args: [] + gofmt: + - {} + test: + - extra_args: + - -short + max_duration: 35 + pre-push: + checks: + coverage: + - use_global_inference: false + use_coveralls: false + global: + min_coverage: 50 + max_coverage: 100 + per_dir_default: + min_coverage: 1 + max_coverage: 100 + per_dir: {} + goimports: + - {} + test: + - extra_args: + - -v + - -race + max_duration: 35 + +ignore_patterns: +- .* +- _* +- '*.pb.go' +- '*_string.go' +- '*-gen.go' diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/go-render/render/render.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/go-render/render/render.go new file mode 100644 index 00000000000..e070a6b3b58 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/go-render/render/render.go @@ -0,0 +1,327 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package render + +import ( + "bytes" + "fmt" + "reflect" + "sort" + "strconv" +) + +var implicitTypeMap = map[reflect.Kind]string{ + reflect.Bool: "bool", + reflect.String: "string", + reflect.Int: "int", + reflect.Int8: "int8", + reflect.Int16: "int16", + reflect.Int32: "int32", + reflect.Int64: "int64", + reflect.Uint: "uint", + reflect.Uint8: "uint8", + reflect.Uint16: "uint16", + reflect.Uint32: "uint32", + reflect.Uint64: "uint64", + reflect.Float32: "float32", + reflect.Float64: "float64", + reflect.Complex64: "complex64", + reflect.Complex128: "complex128", +} + +// Render converts a structure to a string representation. Unline the "%#v" +// format string, this resolves pointer types' contents in structs, maps, and +// slices/arrays and prints their field values. +func Render(v interface{}) string { + buf := bytes.Buffer{} + s := (*traverseState)(nil) + s.render(&buf, 0, reflect.ValueOf(v)) + return buf.String() +} + +// renderPointer is called to render a pointer value. +// +// This is overridable so that the test suite can have deterministic pointer +// values in its expectations. +var renderPointer = func(buf *bytes.Buffer, p uintptr) { + fmt.Fprintf(buf, "0x%016x", p) +} + +// traverseState is used to note and avoid recursion as struct members are being +// traversed. +// +// traverseState is allowed to be nil. Specifically, the root state is nil. +type traverseState struct { + parent *traverseState + ptr uintptr +} + +func (s *traverseState) forkFor(ptr uintptr) *traverseState { + for cur := s; cur != nil; cur = cur.parent { + if ptr == cur.ptr { + return nil + } + } + + fs := &traverseState{ + parent: s, + ptr: ptr, + } + return fs +} + +func (s *traverseState) render(buf *bytes.Buffer, ptrs int, v reflect.Value) { + if v.Kind() == reflect.Invalid { + buf.WriteString("nil") + return + } + vt := v.Type() + + // If the type being rendered is a potentially recursive type (a type that + // can contain itself as a member), we need to avoid recursion. + // + // If we've already seen this type before, mark that this is the case and + // write a recursion placeholder instead of actually rendering it. + // + // If we haven't seen it before, fork our `seen` tracking so any higher-up + // renderers will also render it at least once, then mark that we've seen it + // to avoid recursing on lower layers. + pe := uintptr(0) + vk := vt.Kind() + switch vk { + case reflect.Ptr: + // Since structs and arrays aren't pointers, they can't directly be + // recursed, but they can contain pointers to themselves. Record their + // pointer to avoid this. + switch v.Elem().Kind() { + case reflect.Struct, reflect.Array: + pe = v.Pointer() + } + + case reflect.Slice, reflect.Map: + pe = v.Pointer() + } + if pe != 0 { + s = s.forkFor(pe) + if s == nil { + buf.WriteString("<REC(") + writeType(buf, ptrs, vt) + buf.WriteString(")>") + return + } + } + + switch vk { + case reflect.Struct: + writeType(buf, ptrs, vt) + buf.WriteRune('{') + for i := 0; i < vt.NumField(); i++ { + if i > 0 { + buf.WriteString(", ") + } + buf.WriteString(vt.Field(i).Name) + buf.WriteRune(':') + + s.render(buf, 0, v.Field(i)) + } + buf.WriteRune('}') + + case reflect.Slice: + if v.IsNil() { + writeType(buf, ptrs, vt) + buf.WriteString("(nil)") + return + } + fallthrough + + case reflect.Array: + writeType(buf, ptrs, vt) + buf.WriteString("{") + for i := 0; i < v.Len(); i++ { + if i > 0 { + buf.WriteString(", ") + } + + s.render(buf, 0, v.Index(i)) + } + buf.WriteRune('}') + + case reflect.Map: + writeType(buf, ptrs, vt) + if v.IsNil() { + buf.WriteString("(nil)") + } else { + buf.WriteString("{") + + mkeys := v.MapKeys() + tryAndSortMapKeys(vt, mkeys) + + for i, mk := range mkeys { + if i > 0 { + buf.WriteString(", ") + } + + s.render(buf, 0, mk) + buf.WriteString(":") + s.render(buf, 0, v.MapIndex(mk)) + } + buf.WriteRune('}') + } + + case reflect.Ptr: + ptrs++ + fallthrough + case reflect.Interface: + if v.IsNil() { + writeType(buf, ptrs, v.Type()) + buf.WriteRune('(') + fmt.Fprint(buf, "nil") + buf.WriteRune(')') + } else { + s.render(buf, ptrs, v.Elem()) + } + + case reflect.Chan, reflect.Func, reflect.UnsafePointer: + writeType(buf, ptrs, vt) + buf.WriteRune('(') + renderPointer(buf, v.Pointer()) + buf.WriteRune(')') + + default: + tstr := vt.String() + implicit := ptrs == 0 && implicitTypeMap[vk] == tstr + if !implicit { + writeType(buf, ptrs, vt) + buf.WriteRune('(') + } + + switch vk { + case reflect.String: + fmt.Fprintf(buf, "%q", v.String()) + case reflect.Bool: + fmt.Fprintf(buf, "%v", v.Bool()) + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + fmt.Fprintf(buf, "%d", v.Int()) + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + fmt.Fprintf(buf, "%d", v.Uint()) + + case reflect.Float32, reflect.Float64: + fmt.Fprintf(buf, "%g", v.Float()) + + case reflect.Complex64, reflect.Complex128: + fmt.Fprintf(buf, "%g", v.Complex()) + } + + if !implicit { + buf.WriteRune(')') + } + } +} + +func writeType(buf *bytes.Buffer, ptrs int, t reflect.Type) { + parens := ptrs > 0 + switch t.Kind() { + case reflect.Chan, reflect.Func, reflect.UnsafePointer: + parens = true + } + + if parens { + buf.WriteRune('(') + for i := 0; i < ptrs; i++ { + buf.WriteRune('*') + } + } + + switch t.Kind() { + case reflect.Ptr: + if ptrs == 0 { + // This pointer was referenced from within writeType (e.g., as part of + // rendering a list), and so hasn't had its pointer asterisk accounted + // for. + buf.WriteRune('*') + } + writeType(buf, 0, t.Elem()) + + case reflect.Interface: + if n := t.Name(); n != "" { + buf.WriteString(t.String()) + } else { + buf.WriteString("interface{}") + } + + case reflect.Array: + buf.WriteRune('[') + buf.WriteString(strconv.FormatInt(int64(t.Len()), 10)) + buf.WriteRune(']') + writeType(buf, 0, t.Elem()) + + case reflect.Slice: + if t == reflect.SliceOf(t.Elem()) { + buf.WriteString("[]") + writeType(buf, 0, t.Elem()) + } else { + // Custom slice type, use type name. + buf.WriteString(t.String()) + } + + case reflect.Map: + if t == reflect.MapOf(t.Key(), t.Elem()) { + buf.WriteString("map[") + writeType(buf, 0, t.Key()) + buf.WriteRune(']') + writeType(buf, 0, t.Elem()) + } else { + // Custom map type, use type name. + buf.WriteString(t.String()) + } + + default: + buf.WriteString(t.String()) + } + + if parens { + buf.WriteRune(')') + } +} + +type sortableValueSlice struct { + kind reflect.Kind + elements []reflect.Value +} + +func (s *sortableValueSlice) Len() int { + return len(s.elements) +} + +func (s *sortableValueSlice) Less(i, j int) bool { + switch s.kind { + case reflect.String: + return s.elements[i].String() < s.elements[j].String() + + case reflect.Int: + return s.elements[i].Int() < s.elements[j].Int() + + default: + panic(fmt.Errorf("unsupported sort kind: %s", s.kind)) + } +} + +func (s *sortableValueSlice) Swap(i, j int) { + s.elements[i], s.elements[j] = s.elements[j], s.elements[i] +} + +func tryAndSortMapKeys(mt reflect.Type, k []reflect.Value) { + // Try our stock sortable values. + switch mt.Key().Kind() { + case reflect.String, reflect.Int: + vs := &sortableValueSlice{ + kind: mt.Key().Kind(), + elements: k, + } + sort.Sort(vs) + } +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/go-render/render/render_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/go-render/render/render_test.go new file mode 100644 index 00000000000..1737cb702ae --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/go-render/render/render_test.go @@ -0,0 +1,170 @@ +// Copyright 2015 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package render + +import ( + "bytes" + "fmt" + "regexp" + "runtime" + "testing" +) + +func init() { + // For testing purposes, pointers will render as "PTR" so that they are + // deterministic. + renderPointer = func(buf *bytes.Buffer, p uintptr) { + buf.WriteString("PTR") + } +} + +func assertRendersLike(t *testing.T, name string, v interface{}, exp string) { + act := Render(v) + if act != exp { + _, _, line, _ := runtime.Caller(1) + t.Errorf("On line #%d, [%s] did not match expectations:\nExpected: %s\nActual : %s\n", line, name, exp, act) + } +} + +func TestRenderList(t *testing.T) { + t.Parallel() + + // Note that we make some of the fields exportable. This is to avoid a fun case + // where the first reflect.Value has a read-only bit set, but follow-on values + // do not, so recursion tests are off by one. + type testStruct struct { + Name string + I interface{} + + m string + } + + type myStringSlice []string + type myStringMap map[string]string + type myIntType int + type myStringType string + + s0 := "string0" + s0P := &s0 + mit := myIntType(42) + stringer := fmt.Stringer(nil) + + for i, tc := range []struct { + a interface{} + s string + }{ + {nil, `nil`}, + {make(chan int), `(chan int)(PTR)`}, + {&stringer, `(*fmt.Stringer)(nil)`}, + {123, `123`}, + {"hello", `"hello"`}, + {(*testStruct)(nil), `(*render.testStruct)(nil)`}, + {(**testStruct)(nil), `(**render.testStruct)(nil)`}, + {[]***testStruct(nil), `[]***render.testStruct(nil)`}, + {testStruct{Name: "foo", I: &testStruct{Name: "baz"}}, + `render.testStruct{Name:"foo", I:(*render.testStruct){Name:"baz", I:interface{}(nil), m:""}, m:""}`}, + {[]byte(nil), `[]uint8(nil)`}, + {[]byte{}, `[]uint8{}`}, + {map[string]string(nil), `map[string]string(nil)`}, + {[]*testStruct{ + {Name: "foo"}, + {Name: "bar"}, + }, `[]*render.testStruct{(*render.testStruct){Name:"foo", I:interface{}(nil), m:""}, ` + + `(*render.testStruct){Name:"bar", I:interface{}(nil), m:""}}`}, + {myStringSlice{"foo", "bar"}, `render.myStringSlice{"foo", "bar"}`}, + {myStringMap{"foo": "bar"}, `render.myStringMap{"foo":"bar"}`}, + {myIntType(12), `render.myIntType(12)`}, + {&mit, `(*render.myIntType)(42)`}, + {myStringType("foo"), `render.myStringType("foo")`}, + {struct { + a int + b string + }{123, "foo"}, `struct { a int; b string }{a:123, b:"foo"}`}, + {[]string{"foo", "foo", "bar", "baz", "qux", "qux"}, + `[]string{"foo", "foo", "bar", "baz", "qux", "qux"}`}, + {[...]int{1, 2, 3}, `[3]int{1, 2, 3}`}, + {map[string]bool{ + "foo": true, + "bar": false, + }, `map[string]bool{"bar":false, "foo":true}`}, + {map[int]string{1: "foo", 2: "bar"}, `map[int]string{1:"foo", 2:"bar"}`}, + {uint32(1337), `1337`}, + {3.14, `3.14`}, + {complex(3, 0.14), `(3+0.14i)`}, + {&s0, `(*string)("string0")`}, + {&s0P, `(**string)("string0")`}, + {[]interface{}{nil, 1, 2, nil}, `[]interface{}{interface{}(nil), 1, 2, interface{}(nil)}`}, + } { + assertRendersLike(t, fmt.Sprintf("Input #%d", i), tc.a, tc.s) + } +} + +func TestRenderRecursiveStruct(t *testing.T) { + type testStruct struct { + Name string + I interface{} + } + + s := &testStruct{ + Name: "recursive", + } + s.I = s + + assertRendersLike(t, "Recursive struct", s, + `(*render.testStruct){Name:"recursive", I:<REC(*render.testStruct)>}`) +} + +func TestRenderRecursiveArray(t *testing.T) { + a := [2]interface{}{} + a[0] = &a + a[1] = &a + + assertRendersLike(t, "Recursive array", &a, + `(*[2]interface{}){<REC(*[2]interface{})>, <REC(*[2]interface{})>}`) +} + +func TestRenderRecursiveMap(t *testing.T) { + m := map[string]interface{}{} + foo := "foo" + m["foo"] = m + m["bar"] = [](*string){&foo, &foo} + v := []map[string]interface{}{m, m} + + assertRendersLike(t, "Recursive map", v, + `[]map[string]interface{}{map[string]interface{}{`+ + `"bar":[]*string{(*string)("foo"), (*string)("foo")}, `+ + `"foo":<REC(map[string]interface{})>}, `+ + `map[string]interface{}{`+ + `"bar":[]*string{(*string)("foo"), (*string)("foo")}, `+ + `"foo":<REC(map[string]interface{})>}}`) +} + +func ExampleInReadme() { + type customType int + type testStruct struct { + S string + V *map[string]int + I interface{} + } + + a := testStruct{ + S: "hello", + V: &map[string]int{"foo": 0, "bar": 1}, + I: customType(42), + } + + fmt.Println("Render test:") + fmt.Printf("fmt.Printf: %s\n", sanitizePointer(fmt.Sprintf("%#v", a))) + fmt.Printf("render.Render: %s\n", Render(a)) + // Output: Render test: + // fmt.Printf: render.testStruct{S:"hello", V:(*map[string]int)(0x600dd065), I:42} + // render.Render: render.testStruct{S:"hello", V:(*map[string]int){"bar":1, "foo":0}, I:render.customType(42)} +} + +var pointerRE = regexp.MustCompile(`\(0x[a-f0-9]+\)`) + +func sanitizePointer(s string) string { + return pointerRE.ReplaceAllString(s, "(0x600dd065)") +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/.gitignore b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/.gitignore new file mode 100644 index 00000000000..dd8fc7468f4 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/.gitignore @@ -0,0 +1,5 @@ +*.6 +6.out +_obj/ +_test/ +_testmain.go diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/.travis.yml b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/.travis.yml new file mode 100644 index 00000000000..b97211926e8 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/.travis.yml @@ -0,0 +1,4 @@ +# Cf. http://docs.travis-ci.com/user/getting-started/ +# Cf. http://docs.travis-ci.com/user/languages/go/ + +language: go diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/LICENSE b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/LICENSE new file mode 100644 index 00000000000..d6456956733 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/README.md b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/README.md new file mode 100644 index 00000000000..215a2bb7a8b --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/README.md @@ -0,0 +1,58 @@ +[![GoDoc](https://godoc.org/github.com/smartystreets/assertions/internal/oglematchers?status.svg)](https://godoc.org/github.com/smartystreets/assertions/internal/oglematchers) + +`oglematchers` is a package for the Go programming language containing a set of +matchers, useful in a testing or mocking framework, inspired by and mostly +compatible with [Google Test][googletest] for C++ and +[Google JS Test][google-js-test]. The package is used by the +[ogletest][ogletest] testing framework and [oglemock][oglemock] mocking +framework, which may be more directly useful to you, but can be generically used +elsewhere as well. + +A "matcher" is simply an object with a `Matches` method defining a set of golang +values matched by the matcher, and a `Description` method describing that set. +For example, here are some matchers: + +```go +// Numbers +Equals(17.13) +LessThan(19) + +// Strings +Equals("taco") +HasSubstr("burrito") +MatchesRegex("t.*o") + +// Combining matchers +AnyOf(LessThan(17), GreaterThan(19)) +``` + +There are lots more; see [here][reference] for a reference. You can also add +your own simply by implementing the `oglematchers.Matcher` interface. + + +Installation +------------ + +First, make sure you have installed Go 1.0.2 or newer. See +[here][golang-install] for instructions. + +Use the following command to install `oglematchers` and keep it up to date: + + go get -u github.com/smartystreets/assertions/internal/oglematchers + + +Documentation +------------- + +See [here][reference] for documentation. Alternatively, you can install the +package and then use `godoc`: + + godoc github.com/smartystreets/assertions/internal/oglematchers + + +[reference]: http://godoc.org/github.com/smartystreets/assertions/internal/oglematchers +[golang-install]: http://golang.org/doc/install.html +[googletest]: http://code.google.com/p/googletest/ +[google-js-test]: http://code.google.com/p/google-js-test/ +[ogletest]: http://github.com/smartystreets/assertions/internal/ogletest +[oglemock]: http://github.com/smartystreets/assertions/internal/oglemock diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/all_of.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/all_of.go new file mode 100644 index 00000000000..d93a9740443 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/all_of.go @@ -0,0 +1,70 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package oglematchers + +import ( + "strings" +) + +// AllOf accepts a set of matchers S and returns a matcher that follows the +// algorithm below when considering a candidate c: +// +// 1. Return true if for every Matcher m in S, m matches c. +// +// 2. Otherwise, if there is a matcher m in S such that m returns a fatal +// error for c, return that matcher's error message. +// +// 3. Otherwise, return false with the error from some wrapped matcher. +// +// This is akin to a logical AND operation for matchers. +func AllOf(matchers ...Matcher) Matcher { + return &allOfMatcher{matchers} +} + +type allOfMatcher struct { + wrappedMatchers []Matcher +} + +func (m *allOfMatcher) Description() string { + // Special case: the empty set. + if len(m.wrappedMatchers) == 0 { + return "is anything" + } + + // Join the descriptions for the wrapped matchers. + wrappedDescs := make([]string, len(m.wrappedMatchers)) + for i, wrappedMatcher := range m.wrappedMatchers { + wrappedDescs[i] = wrappedMatcher.Description() + } + + return strings.Join(wrappedDescs, ", and ") +} + +func (m *allOfMatcher) Matches(c interface{}) (err error) { + for _, wrappedMatcher := range m.wrappedMatchers { + if wrappedErr := wrappedMatcher.Matches(c); wrappedErr != nil { + err = wrappedErr + + // If the error is fatal, return immediately with this error. + _, ok := wrappedErr.(*FatalError) + if ok { + return + } + } + } + + return +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/all_of_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/all_of_test.go new file mode 100644 index 00000000000..0f9d198fcbe --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/all_of_test.go @@ -0,0 +1,110 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package oglematchers_test + +import ( + . "github.com/smartystreets/assertions/internal/oglematchers" + . "github.com/smartystreets/assertions/internal/ogletest" + "errors" +) + +//////////////////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////////////////// + +type allOfFakeMatcher struct { + desc string + err error +} + +func (m *allOfFakeMatcher) Matches(c interface{}) error { + return m.err +} + +func (m *allOfFakeMatcher) Description() string { + return m.desc +} + +type AllOfTest struct { +} + +func init() { RegisterTestSuite(&AllOfTest{}) } + +//////////////////////////////////////////////////////////////////////// +// Tests +//////////////////////////////////////////////////////////////////////// + +func (t *AllOfTest) DescriptionWithEmptySet() { + m := AllOf() + ExpectEq("is anything", m.Description()) +} + +func (t *AllOfTest) DescriptionWithOneMatcher() { + m := AllOf(&allOfFakeMatcher{"taco", errors.New("")}) + ExpectEq("taco", m.Description()) +} + +func (t *AllOfTest) DescriptionWithMultipleMatchers() { + m := AllOf( + &allOfFakeMatcher{"taco", errors.New("")}, + &allOfFakeMatcher{"burrito", errors.New("")}, + &allOfFakeMatcher{"enchilada", errors.New("")}) + + ExpectEq("taco, and burrito, and enchilada", m.Description()) +} + +func (t *AllOfTest) EmptySet() { + m := AllOf() + err := m.Matches(17) + + ExpectEq(nil, err) +} + +func (t *AllOfTest) OneMatcherReturnsFatalErrorAndSomeOthersFail() { + m := AllOf( + &allOfFakeMatcher{"", errors.New("")}, + &allOfFakeMatcher{"", NewFatalError("taco")}, + &allOfFakeMatcher{"", errors.New("")}, + &allOfFakeMatcher{"", nil}) + + err := m.Matches(17) + + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("taco"))) +} + +func (t *AllOfTest) OneMatcherReturnsNonFatalAndOthersSayTrue() { + m := AllOf( + &allOfFakeMatcher{"", nil}, + &allOfFakeMatcher{"", errors.New("taco")}, + &allOfFakeMatcher{"", nil}) + + err := m.Matches(17) + + ExpectFalse(isFatal(err)) + ExpectThat(err, Error(Equals("taco"))) +} + +func (t *AllOfTest) AllMatchersSayTrue() { + m := AllOf( + &allOfFakeMatcher{"", nil}, + &allOfFakeMatcher{"", nil}, + &allOfFakeMatcher{"", nil}) + + err := m.Matches(17) + + ExpectEq(nil, err) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/any.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/any.go new file mode 100644 index 00000000000..f6991ec1020 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/any.go @@ -0,0 +1,32 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package oglematchers + +// Any returns a matcher that matches any value. +func Any() Matcher { + return &anyMatcher{} +} + +type anyMatcher struct { +} + +func (m *anyMatcher) Description() string { + return "is anything" +} + +func (m *anyMatcher) Matches(c interface{}) error { + return nil +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/any_of.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/any_of.go new file mode 100644 index 00000000000..2918b51f21a --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/any_of.go @@ -0,0 +1,94 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package oglematchers + +import ( + "errors" + "fmt" + "reflect" + "strings" +) + +// AnyOf accepts a set of values S and returns a matcher that follows the +// algorithm below when considering a candidate c: +// +// 1. If there exists a value m in S such that m implements the Matcher +// interface and m matches c, return true. +// +// 2. Otherwise, if there exists a value v in S such that v does not implement +// the Matcher interface and the matcher Equals(v) matches c, return true. +// +// 3. Otherwise, if there is a value m in S such that m implements the Matcher +// interface and m returns a fatal error for c, return that fatal error. +// +// 4. Otherwise, return false. +// +// This is akin to a logical OR operation for matchers, with non-matchers x +// being treated as Equals(x). +func AnyOf(vals ...interface{}) Matcher { + // Get ahold of a type variable for the Matcher interface. + var dummy *Matcher + matcherType := reflect.TypeOf(dummy).Elem() + + // Create a matcher for each value, or use the value itself if it's already a + // matcher. + wrapped := make([]Matcher, len(vals)) + for i, v := range vals { + t := reflect.TypeOf(v) + if t != nil && t.Implements(matcherType) { + wrapped[i] = v.(Matcher) + } else { + wrapped[i] = Equals(v) + } + } + + return &anyOfMatcher{wrapped} +} + +type anyOfMatcher struct { + wrapped []Matcher +} + +func (m *anyOfMatcher) Description() string { + wrappedDescs := make([]string, len(m.wrapped)) + for i, matcher := range m.wrapped { + wrappedDescs[i] = matcher.Description() + } + + return fmt.Sprintf("or(%s)", strings.Join(wrappedDescs, ", ")) +} + +func (m *anyOfMatcher) Matches(c interface{}) (err error) { + err = errors.New("") + + // Try each matcher in turn. + for _, matcher := range m.wrapped { + wrappedErr := matcher.Matches(c) + + // Return immediately if there's a match. + if wrappedErr == nil { + err = nil + return + } + + // Note the fatal error, if any. + if _, isFatal := wrappedErr.(*FatalError); isFatal { + err = wrappedErr + } + } + + return +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/any_of_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/any_of_test.go new file mode 100644 index 00000000000..f0b5025406f --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/any_of_test.go @@ -0,0 +1,139 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package oglematchers_test + +import ( + "errors" + + . "github.com/smartystreets/assertions/internal/oglematchers" + . "github.com/smartystreets/assertions/internal/ogletest" +) + +//////////////////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////////////////// + +type fakeAnyOfMatcher struct { + desc string + err error +} + +func (m *fakeAnyOfMatcher) Matches(c interface{}) error { + return m.err +} + +func (m *fakeAnyOfMatcher) Description() string { + return m.desc +} + +type AnyOfTest struct { +} + +func init() { RegisterTestSuite(&AnyOfTest{}) } + +//////////////////////////////////////////////////////////////////////// +// Tests +//////////////////////////////////////////////////////////////////////// + +func (t *AnyOfTest) EmptySet() { + matcher := AnyOf() + + err := matcher.Matches(0) + ExpectThat(err, Error(Equals(""))) +} + +func (t *AnyOfTest) OneTrue() { + matcher := AnyOf( + &fakeAnyOfMatcher{"", NewFatalError("foo")}, + 17, + &fakeAnyOfMatcher{"", errors.New("foo")}, + &fakeAnyOfMatcher{"", nil}, + &fakeAnyOfMatcher{"", errors.New("foo")}, + ) + + err := matcher.Matches(0) + ExpectEq(nil, err) +} + +func (t *AnyOfTest) OneEqual() { + matcher := AnyOf( + &fakeAnyOfMatcher{"", NewFatalError("foo")}, + &fakeAnyOfMatcher{"", errors.New("foo")}, + 13, + "taco", + 19, + &fakeAnyOfMatcher{"", errors.New("foo")}, + ) + + err := matcher.Matches("taco") + ExpectEq(nil, err) +} + +func (t *AnyOfTest) OneFatal() { + matcher := AnyOf( + &fakeAnyOfMatcher{"", errors.New("foo")}, + 17, + &fakeAnyOfMatcher{"", NewFatalError("taco")}, + &fakeAnyOfMatcher{"", errors.New("foo")}, + ) + + err := matcher.Matches(0) + ExpectThat(err, Error(Equals("taco"))) +} + +func (t *AnyOfTest) OneNil() { + var err error + matcher := AnyOf( + 13, + nil, + 19, + ) + + // No match + err = matcher.Matches(14) + ExpectNe(nil, err) + + // Match + err = matcher.Matches(nil) + ExpectEq(nil, err) +} + +func (t *AnyOfTest) AllFalseAndNotEqual() { + matcher := AnyOf( + &fakeAnyOfMatcher{"", errors.New("foo")}, + 17, + &fakeAnyOfMatcher{"", errors.New("foo")}, + 19, + ) + + err := matcher.Matches(0) + ExpectThat(err, Error(Equals(""))) +} + +func (t *AnyOfTest) DescriptionForEmptySet() { + matcher := AnyOf() + ExpectEq("or()", matcher.Description()) +} + +func (t *AnyOfTest) DescriptionForNonEmptySet() { + matcher := AnyOf( + &fakeAnyOfMatcher{"taco", nil}, + "burrito", + &fakeAnyOfMatcher{"enchilada", nil}, + ) + + ExpectEq("or(taco, burrito, enchilada)", matcher.Description()) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/any_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/any_test.go new file mode 100644 index 00000000000..410cc12825e --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/any_test.go @@ -0,0 +1,53 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package oglematchers_test + +import ( + . "github.com/smartystreets/assertions/internal/oglematchers" + . "github.com/smartystreets/assertions/internal/ogletest" +) + +//////////////////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////////////////// + +type AnyTest struct { +} + +func init() { RegisterTestSuite(&AnyTest{}) } + +//////////////////////////////////////////////////////////////////////// +// Tests +//////////////////////////////////////////////////////////////////////// + +func (t *AnyTest) Description() { + m := Any() + ExpectEq("is anything", m.Description()) +} + +func (t *AnyTest) Matches() { + var err error + m := Any() + + err = m.Matches(nil) + ExpectEq(nil, err) + + err = m.Matches(17) + ExpectEq(nil, err) + + err = m.Matches("taco") + ExpectEq(nil, err) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/contains.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/contains.go new file mode 100644 index 00000000000..2f326dbc5d6 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/contains.go @@ -0,0 +1,61 @@ +// Copyright 2012 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package oglematchers + +import ( + "fmt" + "reflect" +) + +// Return a matcher that matches arrays slices with at least one element that +// matches the supplied argument. If the argument x is not itself a Matcher, +// this is equivalent to Contains(Equals(x)). +func Contains(x interface{}) Matcher { + var result containsMatcher + var ok bool + + if result.elementMatcher, ok = x.(Matcher); !ok { + result.elementMatcher = Equals(x) + } + + return &result +} + +type containsMatcher struct { + elementMatcher Matcher +} + +func (m *containsMatcher) Description() string { + return fmt.Sprintf("contains: %s", m.elementMatcher.Description()) +} + +func (m *containsMatcher) Matches(candidate interface{}) error { + // The candidate must be a slice or an array. + v := reflect.ValueOf(candidate) + if v.Kind() != reflect.Slice && v.Kind() != reflect.Array { + return NewFatalError("which is not a slice or array") + } + + // Check each element. + for i := 0; i < v.Len(); i++ { + elem := v.Index(i) + if matchErr := m.elementMatcher.Matches(elem.Interface()); matchErr == nil { + return nil + } + } + + return fmt.Errorf("") +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/contains_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/contains_test.go new file mode 100644 index 00000000000..dfc981c1488 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/contains_test.go @@ -0,0 +1,233 @@ +// Copyright 2012 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package oglematchers_test + +import ( + . "github.com/smartystreets/assertions/internal/oglematchers" + . "github.com/smartystreets/assertions/internal/ogletest" +) + +//////////////////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////////////////// + +type ContainsTest struct {} +func init() { RegisterTestSuite(&ContainsTest{}) } + +//////////////////////////////////////////////////////////////////////// +// Tests +//////////////////////////////////////////////////////////////////////// + +func (t *ContainsTest) WrongTypeCandidates() { + m := Contains("") + ExpectEq("contains: ", m.Description()) + + var err error + + // Nil candidate + err = m.Matches(nil) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(HasSubstr("array"))) + ExpectThat(err, Error(HasSubstr("slice"))) + + // String candidate + err = m.Matches("") + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(HasSubstr("array"))) + ExpectThat(err, Error(HasSubstr("slice"))) + + // Map candidate + err = m.Matches(make(map[string]string)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(HasSubstr("array"))) + ExpectThat(err, Error(HasSubstr("slice"))) +} + +func (t *ContainsTest) NilArgument() { + m := Contains(nil) + ExpectEq("contains: is nil", m.Description()) + + var c interface{} + var err error + + // Empty array of pointers + c = [...]*int{} + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) + + // Empty slice of pointers + c = []*int{} + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) + + // Non-empty array of integers + c = [...]int{17, 0, 19} + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) + + // Non-empty slice of integers + c = []int{17, 0, 19} + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) + + // Non-matching array of pointers + c = [...]*int{new(int), new(int)} + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) + + // Non-matching slice of pointers + c = []*int{new(int), new(int)} + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) + + // Matching array of pointers + c = [...]*int{new(int), nil, new(int)} + err = m.Matches(c) + ExpectEq(nil, err) + + // Matching slice of pointers + c = []*int{new(int), nil, new(int)} + err = m.Matches(c) + ExpectEq(nil, err) + + // Non-matching slice of pointers from matching array + someArray := [...]*int{new(int), nil, new(int)} + c = someArray[0:1] + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) +} + +func (t *ContainsTest) StringArgument() { + m := Contains("taco") + ExpectEq("contains: taco", m.Description()) + + var c interface{} + var err error + + // Non-matching array of strings + c = [...]string{"burrito", "enchilada"} + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) + + // Non-matching slice of strings + c = []string{"burrito", "enchilada"} + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) + + // Matching array of strings + c = [...]string{"burrito", "taco", "enchilada"} + err = m.Matches(c) + ExpectEq(nil, err) + + // Matching slice of strings + c = []string{"burrito", "taco", "enchilada"} + err = m.Matches(c) + ExpectEq(nil, err) + + // Non-matching slice of strings from matching array + someArray := [...]string{"burrito", "taco", "enchilada"} + c = someArray[0:1] + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) +} + +func (t *ContainsTest) IntegerArgument() { + m := Contains(int(17)) + ExpectEq("contains: 17", m.Description()) + + var c interface{} + var err error + + // Non-matching array of integers + c = [...]int{13, 19} + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) + + // Non-matching slice of integers + c = []int{13, 19} + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) + + // Matching array of integers + c = [...]int{13, 17, 19} + err = m.Matches(c) + ExpectEq(nil, err) + + // Matching slice of integers + c = []int{13, 17, 19} + err = m.Matches(c) + ExpectEq(nil, err) + + // Non-matching slice of integers from matching array + someArray := [...]int{13, 17, 19} + c = someArray[0:1] + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) + + // Non-matching array of floats + c = [...]float32{13, 17.5, 19} + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) + + // Non-matching slice of floats + c = []float32{13, 17.5, 19} + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) + + // Matching array of floats + c = [...]float32{13, 17, 19} + err = m.Matches(c) + ExpectEq(nil, err) + + // Matching slice of floats + c = []float32{13, 17, 19} + err = m.Matches(c) + ExpectEq(nil, err) +} + +func (t *ContainsTest) MatcherArgument() { + m := Contains(HasSubstr("ac")) + ExpectEq("contains: has substring \"ac\"", m.Description()) + + var c interface{} + var err error + + // Non-matching array of strings + c = [...]string{"burrito", "enchilada"} + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) + + // Non-matching slice of strings + c = []string{"burrito", "enchilada"} + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) + + // Matching array of strings + c = [...]string{"burrito", "taco", "enchilada"} + err = m.Matches(c) + ExpectEq(nil, err) + + // Matching slice of strings + c = []string{"burrito", "taco", "enchilada"} + err = m.Matches(c) + ExpectEq(nil, err) + + // Non-matching slice of strings from matching array + someArray := [...]string{"burrito", "taco", "enchilada"} + c = someArray[0:1] + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/deep_equals.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/deep_equals.go new file mode 100644 index 00000000000..1d91baef32e --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/deep_equals.go @@ -0,0 +1,88 @@ +// Copyright 2012 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package oglematchers + +import ( + "bytes" + "errors" + "fmt" + "reflect" +) + +var byteSliceType reflect.Type = reflect.TypeOf([]byte{}) + +// DeepEquals returns a matcher that matches based on 'deep equality', as +// defined by the reflect package. This matcher requires that values have +// identical types to x. +func DeepEquals(x interface{}) Matcher { + return &deepEqualsMatcher{x} +} + +type deepEqualsMatcher struct { + x interface{} +} + +func (m *deepEqualsMatcher) Description() string { + xDesc := fmt.Sprintf("%v", m.x) + xValue := reflect.ValueOf(m.x) + + // Special case: fmt.Sprintf presents nil slices as "[]", but + // reflect.DeepEqual makes a distinction between nil and empty slices. Make + // this less confusing. + if xValue.Kind() == reflect.Slice && xValue.IsNil() { + xDesc = "<nil slice>" + } + + return fmt.Sprintf("deep equals: %s", xDesc) +} + +func (m *deepEqualsMatcher) Matches(c interface{}) error { + // Make sure the types match. + ct := reflect.TypeOf(c) + xt := reflect.TypeOf(m.x) + + if ct != xt { + return NewFatalError(fmt.Sprintf("which is of type %v", ct)) + } + + // Special case: handle byte slices more efficiently. + cValue := reflect.ValueOf(c) + xValue := reflect.ValueOf(m.x) + + if ct == byteSliceType && !cValue.IsNil() && !xValue.IsNil() { + xBytes := m.x.([]byte) + cBytes := c.([]byte) + + if bytes.Equal(cBytes, xBytes) { + return nil + } + + return errors.New("") + } + + // Defer to the reflect package. + if reflect.DeepEqual(m.x, c) { + return nil + } + + // Special case: if the comparison failed because c is the nil slice, given + // an indication of this (since its value is printed as "[]"). + if cValue.Kind() == reflect.Slice && cValue.IsNil() { + return errors.New("which is nil") + } + + return errors.New("") +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/deep_equals_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/deep_equals_test.go new file mode 100644 index 00000000000..a28113aaa6b --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/deep_equals_test.go @@ -0,0 +1,343 @@ +// Copyright 2012 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package oglematchers_test + +import ( + . "github.com/smartystreets/assertions/internal/oglematchers" + . "github.com/smartystreets/assertions/internal/ogletest" + "bytes" + "testing" +) + +//////////////////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////////////////// + +type DeepEqualsTest struct {} +func init() { RegisterTestSuite(&DeepEqualsTest{}) } + +//////////////////////////////////////////////////////////////////////// +// Tests +//////////////////////////////////////////////////////////////////////// + +func (t *DeepEqualsTest) WrongTypeCandidateWithScalarValue() { + var x int = 17 + m := DeepEquals(x) + + var err error + + // Nil candidate. + err = m.Matches(nil) + AssertNe(nil, err) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(HasSubstr("type"))) + ExpectThat(err, Error(HasSubstr("<nil>"))) + + // Int alias candidate. + type intAlias int + err = m.Matches(intAlias(x)) + AssertNe(nil, err) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(HasSubstr("type"))) + ExpectThat(err, Error(HasSubstr("intAlias"))) + + // String candidate. + err = m.Matches("taco") + AssertNe(nil, err) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(HasSubstr("type"))) + ExpectThat(err, Error(HasSubstr("string"))) + + // Byte slice candidate. + err = m.Matches([]byte{}) + AssertNe(nil, err) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(HasSubstr("type"))) + ExpectThat(err, Error(HasSubstr("[]uint8"))) + + // Other slice candidate. + err = m.Matches([]uint16{}) + AssertNe(nil, err) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(HasSubstr("type"))) + ExpectThat(err, Error(HasSubstr("[]uint16"))) + + // Unsigned int candidate. + err = m.Matches(uint(17)) + AssertNe(nil, err) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(HasSubstr("type"))) + ExpectThat(err, Error(HasSubstr("uint"))) +} + +func (t *DeepEqualsTest) WrongTypeCandidateWithByteSliceValue() { + x := []byte{} + m := DeepEquals(x) + + var err error + + // Nil candidate. + err = m.Matches(nil) + AssertNe(nil, err) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(HasSubstr("type"))) + ExpectThat(err, Error(HasSubstr("<nil>"))) + + // String candidate. + err = m.Matches("taco") + AssertNe(nil, err) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(HasSubstr("type"))) + ExpectThat(err, Error(HasSubstr("string"))) + + // Slice candidate with wrong value type. + err = m.Matches([]uint16{}) + AssertNe(nil, err) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(HasSubstr("type"))) + ExpectThat(err, Error(HasSubstr("[]uint16"))) +} + +func (t *DeepEqualsTest) WrongTypeCandidateWithOtherSliceValue() { + x := []uint16{} + m := DeepEquals(x) + + var err error + + // Nil candidate. + err = m.Matches(nil) + AssertNe(nil, err) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(HasSubstr("type"))) + ExpectThat(err, Error(HasSubstr("<nil>"))) + + // String candidate. + err = m.Matches("taco") + AssertNe(nil, err) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(HasSubstr("type"))) + ExpectThat(err, Error(HasSubstr("string"))) + + // Byte slice candidate with wrong value type. + err = m.Matches([]byte{}) + AssertNe(nil, err) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(HasSubstr("type"))) + ExpectThat(err, Error(HasSubstr("[]uint8"))) + + // Other slice candidate with wrong value type. + err = m.Matches([]uint32{}) + AssertNe(nil, err) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(HasSubstr("type"))) + ExpectThat(err, Error(HasSubstr("[]uint32"))) +} + +func (t *DeepEqualsTest) WrongTypeCandidateWithNilLiteralValue() { + m := DeepEquals(nil) + + var err error + + // String candidate. + err = m.Matches("taco") + AssertNe(nil, err) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(HasSubstr("type"))) + ExpectThat(err, Error(HasSubstr("string"))) + + // Nil byte slice candidate. + err = m.Matches([]byte(nil)) + AssertNe(nil, err) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(HasSubstr("type"))) + ExpectThat(err, Error(HasSubstr("[]uint8"))) + + // Nil other slice candidate. + err = m.Matches([]uint16(nil)) + AssertNe(nil, err) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(HasSubstr("type"))) + ExpectThat(err, Error(HasSubstr("[]uint16"))) +} + +func (t *DeepEqualsTest) NilLiteralValue() { + m := DeepEquals(nil) + ExpectEq("deep equals: <nil>", m.Description()) + + var c interface{} + var err error + + // Nil literal candidate. + c = nil + err = m.Matches(c) + ExpectEq(nil, err) +} + +func (t *DeepEqualsTest) IntValue() { + m := DeepEquals(int(17)) + ExpectEq("deep equals: 17", m.Description()) + + var c interface{} + var err error + + // Matching int. + c = int(17) + err = m.Matches(c) + ExpectEq(nil, err) + + // Non-matching int. + c = int(18) + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) +} + +func (t *DeepEqualsTest) ByteSliceValue() { + x := []byte{17, 19} + m := DeepEquals(x) + ExpectEq("deep equals: [17 19]", m.Description()) + + var c []byte + var err error + + // Matching. + c = make([]byte, len(x)) + AssertEq(len(x), copy(c, x)) + + err = m.Matches(c) + ExpectEq(nil, err) + + // Nil slice. + c = []byte(nil) + err = m.Matches(c) + ExpectThat(err, Error(Equals("which is nil"))) + + // Prefix. + AssertGt(len(x), 1) + c = make([]byte, len(x)-1) + AssertEq(len(x)-1, copy(c, x)) + + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) + + // Suffix. + c = make([]byte, len(x)+1) + AssertEq(len(x), copy(c, x)) + + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) +} + +func (t *DeepEqualsTest) OtherSliceValue() { + x := []uint16{17, 19} + m := DeepEquals(x) + ExpectEq("deep equals: [17 19]", m.Description()) + + var c []uint16 + var err error + + // Matching. + c = make([]uint16, len(x)) + AssertEq(len(x), copy(c, x)) + + err = m.Matches(c) + ExpectEq(nil, err) + + // Nil slice. + c = []uint16(nil) + err = m.Matches(c) + ExpectThat(err, Error(Equals("which is nil"))) + + // Prefix. + AssertGt(len(x), 1) + c = make([]uint16, len(x)-1) + AssertEq(len(x)-1, copy(c, x)) + + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) + + // Suffix. + c = make([]uint16, len(x)+1) + AssertEq(len(x), copy(c, x)) + + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) +} + +func (t *DeepEqualsTest) NilByteSliceValue() { + x := []byte(nil) + m := DeepEquals(x) + ExpectEq("deep equals: <nil slice>", m.Description()) + + var c []byte + var err error + + // Nil slice. + c = []byte(nil) + err = m.Matches(c) + ExpectEq(nil, err) + + // Non-nil slice. + c = []byte{} + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) +} + +func (t *DeepEqualsTest) NilOtherSliceValue() { + x := []uint16(nil) + m := DeepEquals(x) + ExpectEq("deep equals: <nil slice>", m.Description()) + + var c []uint16 + var err error + + // Nil slice. + c = []uint16(nil) + err = m.Matches(c) + ExpectEq(nil, err) + + // Non-nil slice. + c = []uint16{} + err = m.Matches(c) + ExpectThat(err, Error(Equals(""))) +} + +//////////////////////////////////////////////////////////////////////// +// Benchmarks +//////////////////////////////////////////////////////////////////////// + +func benchmarkWithSize(b *testing.B, size int) { + b.StopTimer() + buf := bytes.Repeat([]byte{0x01}, size) + bufCopy := make([]byte, size) + copy(bufCopy, buf) + + matcher := DeepEquals(buf) + b.StartTimer() + + for i := 0; i < b.N; i++ { + matcher.Matches(bufCopy) + } + + b.SetBytes(int64(size)) +} + +func BenchmarkShortByteSlice(b *testing.B) { + benchmarkWithSize(b, 256) +} + +func BenchmarkLongByteSlice(b *testing.B) { + benchmarkWithSize(b, 1<<24) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/elements_are.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/elements_are.go new file mode 100644 index 00000000000..2941847c705 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/elements_are.go @@ -0,0 +1,91 @@ +// Copyright 2012 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package oglematchers + +import ( + "errors" + "fmt" + "reflect" + "strings" +) + +// Given a list of arguments M, ElementsAre returns a matcher that matches +// arrays and slices A where all of the following hold: +// +// * A is the same length as M. +// +// * For each i < len(A) where M[i] is a matcher, A[i] matches M[i]. +// +// * For each i < len(A) where M[i] is not a matcher, A[i] matches +// Equals(M[i]). +// +func ElementsAre(M ...interface{}) Matcher { + // Copy over matchers, or convert to Equals(x) for non-matcher x. + subMatchers := make([]Matcher, len(M)) + for i, x := range M { + if matcher, ok := x.(Matcher); ok { + subMatchers[i] = matcher + continue + } + + subMatchers[i] = Equals(x) + } + + return &elementsAreMatcher{subMatchers} +} + +type elementsAreMatcher struct { + subMatchers []Matcher +} + +func (m *elementsAreMatcher) Description() string { + subDescs := make([]string, len(m.subMatchers)) + for i, sm := range m.subMatchers { + subDescs[i] = sm.Description() + } + + return fmt.Sprintf("elements are: [%s]", strings.Join(subDescs, ", ")) +} + +func (m *elementsAreMatcher) Matches(candidates interface{}) error { + // The candidate must be a slice or an array. + v := reflect.ValueOf(candidates) + if v.Kind() != reflect.Slice && v.Kind() != reflect.Array { + return NewFatalError("which is not a slice or array") + } + + // The length must be correct. + if v.Len() != len(m.subMatchers) { + return errors.New(fmt.Sprintf("which is of length %d", v.Len())) + } + + // Check each element. + for i, subMatcher := range m.subMatchers { + c := v.Index(i) + if matchErr := subMatcher.Matches(c.Interface()); matchErr != nil { + // Return an errors indicating which element doesn't match. If the + // matcher error was fatal, make this one fatal too. + err := errors.New(fmt.Sprintf("whose element %d doesn't match", i)) + if _, isFatal := matchErr.(*FatalError); isFatal { + err = NewFatalError(err.Error()) + } + + return err + } + } + + return nil +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/elements_are_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/elements_are_test.go new file mode 100644 index 00000000000..172584fa140 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/elements_are_test.go @@ -0,0 +1,208 @@ +// Copyright 2012 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package oglematchers_test + +import ( + . "github.com/smartystreets/assertions/internal/oglematchers" + . "github.com/smartystreets/assertions/internal/ogletest" +) + +//////////////////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////////////////// + +type ElementsAreTest struct { +} + +func init() { RegisterTestSuite(&ElementsAreTest{}) } + +//////////////////////////////////////////////////////////////////////// +// Tests +//////////////////////////////////////////////////////////////////////// + +func (t *ElementsAreTest) EmptySet() { + m := ElementsAre() + ExpectEq("elements are: []", m.Description()) + + var c []interface{} + var err error + + // No candidates. + c = []interface{}{} + err = m.Matches(c) + ExpectEq(nil, err) + + // One candidate. + c = []interface{}{17} + err = m.Matches(c) + ExpectThat(err, Error(HasSubstr("length 1"))) +} + +func (t *ElementsAreTest) OneMatcher() { + m := ElementsAre(LessThan(17)) + ExpectEq("elements are: [less than 17]", m.Description()) + + var c []interface{} + var err error + + // No candidates. + c = []interface{}{} + err = m.Matches(c) + ExpectThat(err, Error(HasSubstr("length 0"))) + + // Matching candidate. + c = []interface{}{16} + err = m.Matches(c) + ExpectEq(nil, err) + + // Non-matching candidate. + c = []interface{}{19} + err = m.Matches(c) + ExpectNe(nil, err) + + // Two candidates. + c = []interface{}{17, 19} + err = m.Matches(c) + ExpectThat(err, Error(HasSubstr("length 2"))) +} + +func (t *ElementsAreTest) OneValue() { + m := ElementsAre(17) + ExpectEq("elements are: [17]", m.Description()) + + var c []interface{} + var err error + + // No candidates. + c = []interface{}{} + err = m.Matches(c) + ExpectThat(err, Error(HasSubstr("length 0"))) + + // Matching int. + c = []interface{}{int(17)} + err = m.Matches(c) + ExpectEq(nil, err) + + // Matching float. + c = []interface{}{float32(17)} + err = m.Matches(c) + ExpectEq(nil, err) + + // Non-matching candidate. + c = []interface{}{19} + err = m.Matches(c) + ExpectNe(nil, err) + + // Two candidates. + c = []interface{}{17, 19} + err = m.Matches(c) + ExpectThat(err, Error(HasSubstr("length 2"))) +} + +func (t *ElementsAreTest) MultipleElements() { + m := ElementsAre("taco", LessThan(17)) + ExpectEq("elements are: [taco, less than 17]", m.Description()) + + var c []interface{} + var err error + + // One candidate. + c = []interface{}{17} + err = m.Matches(c) + ExpectThat(err, Error(HasSubstr("length 1"))) + + // Both matching. + c = []interface{}{"taco", 16} + err = m.Matches(c) + ExpectEq(nil, err) + + // First non-matching. + c = []interface{}{"burrito", 16} + err = m.Matches(c) + ExpectThat(err, Error(Equals("whose element 0 doesn't match"))) + + // Second non-matching. + c = []interface{}{"taco", 17} + err = m.Matches(c) + ExpectThat(err, Error(Equals("whose element 1 doesn't match"))) + + // Three candidates. + c = []interface{}{"taco", 17, 19} + err = m.Matches(c) + ExpectThat(err, Error(HasSubstr("length 3"))) +} + +func (t *ElementsAreTest) ArrayCandidates() { + m := ElementsAre("taco", LessThan(17)) + + var err error + + // One candidate. + err = m.Matches([1]interface{}{"taco"}) + ExpectThat(err, Error(HasSubstr("length 1"))) + + // Both matching. + err = m.Matches([2]interface{}{"taco", 16}) + ExpectEq(nil, err) + + // First non-matching. + err = m.Matches([2]interface{}{"burrito", 16}) + ExpectThat(err, Error(Equals("whose element 0 doesn't match"))) +} + +func (t *ElementsAreTest) WrongTypeCandidate() { + m := ElementsAre("taco") + + var err error + + // String candidate. + err = m.Matches("taco") + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(HasSubstr("array"))) + ExpectThat(err, Error(HasSubstr("slice"))) + + // Map candidate. + err = m.Matches(map[string]string{}) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(HasSubstr("array"))) + ExpectThat(err, Error(HasSubstr("slice"))) + + // Nil candidate. + err = m.Matches(nil) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(HasSubstr("array"))) + ExpectThat(err, Error(HasSubstr("slice"))) +} + +func (t *ElementsAreTest) PropagatesFatality() { + m := ElementsAre(LessThan(17)) + ExpectEq("elements are: [less than 17]", m.Description()) + + var c []interface{} + var err error + + // Non-fatal error. + c = []interface{}{19} + err = m.Matches(c) + AssertNe(nil, err) + ExpectFalse(isFatal(err)) + + // Fatal error. + c = []interface{}{"taco"} + err = m.Matches(c) + AssertNe(nil, err) + ExpectTrue(isFatal(err)) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/equals.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/equals.go new file mode 100644 index 00000000000..a510707b3c7 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/equals.go @@ -0,0 +1,541 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package oglematchers + +import ( + "errors" + "fmt" + "math" + "reflect" +) + +// Equals(x) returns a matcher that matches values v such that v and x are +// equivalent. This includes the case when the comparison v == x using Go's +// built-in comparison operator is legal (except for structs, which this +// matcher does not support), but for convenience the following rules also +// apply: +// +// * Type checking is done based on underlying types rather than actual +// types, so that e.g. two aliases for string can be compared: +// +// type stringAlias1 string +// type stringAlias2 string +// +// a := "taco" +// b := stringAlias1("taco") +// c := stringAlias2("taco") +// +// ExpectTrue(a == b) // Legal, passes +// ExpectTrue(b == c) // Illegal, doesn't compile +// +// ExpectThat(a, Equals(b)) // Passes +// ExpectThat(b, Equals(c)) // Passes +// +// * Values of numeric type are treated as if they were abstract numbers, and +// compared accordingly. Therefore Equals(17) will match int(17), +// int16(17), uint(17), float32(17), complex64(17), and so on. +// +// If you want a stricter matcher that contains no such cleverness, see +// IdenticalTo instead. +// +// Arrays are supported by this matcher, but do not participate in the +// exceptions above. Two arrays compared with this matcher must have identical +// types, and their element type must itself be comparable according to Go's == +// operator. +func Equals(x interface{}) Matcher { + v := reflect.ValueOf(x) + + // This matcher doesn't support structs. + if v.Kind() == reflect.Struct { + panic(fmt.Sprintf("oglematchers.Equals: unsupported kind %v", v.Kind())) + } + + // The == operator is not defined for non-nil slices. + if v.Kind() == reflect.Slice && v.Pointer() != uintptr(0) { + panic(fmt.Sprintf("oglematchers.Equals: non-nil slice")) + } + + return &equalsMatcher{v} +} + +type equalsMatcher struct { + expectedValue reflect.Value +} + +//////////////////////////////////////////////////////////////////////// +// Numeric types +//////////////////////////////////////////////////////////////////////// + +func isSignedInteger(v reflect.Value) bool { + k := v.Kind() + return k >= reflect.Int && k <= reflect.Int64 +} + +func isUnsignedInteger(v reflect.Value) bool { + k := v.Kind() + return k >= reflect.Uint && k <= reflect.Uintptr +} + +func isInteger(v reflect.Value) bool { + return isSignedInteger(v) || isUnsignedInteger(v) +} + +func isFloat(v reflect.Value) bool { + k := v.Kind() + return k == reflect.Float32 || k == reflect.Float64 +} + +func isComplex(v reflect.Value) bool { + k := v.Kind() + return k == reflect.Complex64 || k == reflect.Complex128 +} + +func checkAgainstInt64(e int64, c reflect.Value) (err error) { + err = errors.New("") + + switch { + case isSignedInteger(c): + if c.Int() == e { + err = nil + } + + case isUnsignedInteger(c): + u := c.Uint() + if u <= math.MaxInt64 && int64(u) == e { + err = nil + } + + // Turn around the various floating point types so that the checkAgainst* + // functions for them can deal with precision issues. + case isFloat(c), isComplex(c): + return Equals(c.Interface()).Matches(e) + + default: + err = NewFatalError("which is not numeric") + } + + return +} + +func checkAgainstUint64(e uint64, c reflect.Value) (err error) { + err = errors.New("") + + switch { + case isSignedInteger(c): + i := c.Int() + if i >= 0 && uint64(i) == e { + err = nil + } + + case isUnsignedInteger(c): + if c.Uint() == e { + err = nil + } + + // Turn around the various floating point types so that the checkAgainst* + // functions for them can deal with precision issues. + case isFloat(c), isComplex(c): + return Equals(c.Interface()).Matches(e) + + default: + err = NewFatalError("which is not numeric") + } + + return +} + +func checkAgainstFloat32(e float32, c reflect.Value) (err error) { + err = errors.New("") + + switch { + case isSignedInteger(c): + if float32(c.Int()) == e { + err = nil + } + + case isUnsignedInteger(c): + if float32(c.Uint()) == e { + err = nil + } + + case isFloat(c): + // Compare using float32 to avoid a false sense of precision; otherwise + // e.g. Equals(float32(0.1)) won't match float32(0.1). + if float32(c.Float()) == e { + err = nil + } + + case isComplex(c): + comp := c.Complex() + rl := real(comp) + im := imag(comp) + + // Compare using float32 to avoid a false sense of precision; otherwise + // e.g. Equals(float32(0.1)) won't match (0.1 + 0i). + if im == 0 && float32(rl) == e { + err = nil + } + + default: + err = NewFatalError("which is not numeric") + } + + return +} + +func checkAgainstFloat64(e float64, c reflect.Value) (err error) { + err = errors.New("") + + ck := c.Kind() + + switch { + case isSignedInteger(c): + if float64(c.Int()) == e { + err = nil + } + + case isUnsignedInteger(c): + if float64(c.Uint()) == e { + err = nil + } + + // If the actual value is lower precision, turn the comparison around so we + // apply the low-precision rules. Otherwise, e.g. Equals(0.1) may not match + // float32(0.1). + case ck == reflect.Float32 || ck == reflect.Complex64: + return Equals(c.Interface()).Matches(e) + + // Otherwise, compare with double precision. + case isFloat(c): + if c.Float() == e { + err = nil + } + + case isComplex(c): + comp := c.Complex() + rl := real(comp) + im := imag(comp) + + if im == 0 && rl == e { + err = nil + } + + default: + err = NewFatalError("which is not numeric") + } + + return +} + +func checkAgainstComplex64(e complex64, c reflect.Value) (err error) { + err = errors.New("") + realPart := real(e) + imaginaryPart := imag(e) + + switch { + case isInteger(c) || isFloat(c): + // If we have no imaginary part, then we should just compare against the + // real part. Otherwise, we can't be equal. + if imaginaryPart != 0 { + return + } + + return checkAgainstFloat32(realPart, c) + + case isComplex(c): + // Compare using complex64 to avoid a false sense of precision; otherwise + // e.g. Equals(0.1 + 0i) won't match float32(0.1). + if complex64(c.Complex()) == e { + err = nil + } + + default: + err = NewFatalError("which is not numeric") + } + + return +} + +func checkAgainstComplex128(e complex128, c reflect.Value) (err error) { + err = errors.New("") + realPart := real(e) + imaginaryPart := imag(e) + + switch { + case isInteger(c) || isFloat(c): + // If we have no imaginary part, then we should just compare against the + // real part. Otherwise, we can't be equal. + if imaginaryPart != 0 { + return + } + + return checkAgainstFloat64(realPart, c) + + case isComplex(c): + if c.Complex() == e { + err = nil + } + + default: + err = NewFatalError("which is not numeric") + } + + return +} + +//////////////////////////////////////////////////////////////////////// +// Other types +//////////////////////////////////////////////////////////////////////// + +func checkAgainstBool(e bool, c reflect.Value) (err error) { + if c.Kind() != reflect.Bool { + err = NewFatalError("which is not a bool") + return + } + + err = errors.New("") + if c.Bool() == e { + err = nil + } + return +} + +func checkAgainstChan(e reflect.Value, c reflect.Value) (err error) { + // Create a description of e's type, e.g. "chan int". + typeStr := fmt.Sprintf("%s %s", e.Type().ChanDir(), e.Type().Elem()) + + // Make sure c is a chan of the correct type. + if c.Kind() != reflect.Chan || + c.Type().ChanDir() != e.Type().ChanDir() || + c.Type().Elem() != e.Type().Elem() { + err = NewFatalError(fmt.Sprintf("which is not a %s", typeStr)) + return + } + + err = errors.New("") + if c.Pointer() == e.Pointer() { + err = nil + } + return +} + +func checkAgainstFunc(e reflect.Value, c reflect.Value) (err error) { + // Make sure c is a function. + if c.Kind() != reflect.Func { + err = NewFatalError("which is not a function") + return + } + + err = errors.New("") + if c.Pointer() == e.Pointer() { + err = nil + } + return +} + +func checkAgainstMap(e reflect.Value, c reflect.Value) (err error) { + // Make sure c is a map. + if c.Kind() != reflect.Map { + err = NewFatalError("which is not a map") + return + } + + err = errors.New("") + if c.Pointer() == e.Pointer() { + err = nil + } + return +} + +func checkAgainstPtr(e reflect.Value, c reflect.Value) (err error) { + // Create a description of e's type, e.g. "*int". + typeStr := fmt.Sprintf("*%v", e.Type().Elem()) + + // Make sure c is a pointer of the correct type. + if c.Kind() != reflect.Ptr || + c.Type().Elem() != e.Type().Elem() { + err = NewFatalError(fmt.Sprintf("which is not a %s", typeStr)) + return + } + + err = errors.New("") + if c.Pointer() == e.Pointer() { + err = nil + } + return +} + +func checkAgainstSlice(e reflect.Value, c reflect.Value) (err error) { + // Create a description of e's type, e.g. "[]int". + typeStr := fmt.Sprintf("[]%v", e.Type().Elem()) + + // Make sure c is a slice of the correct type. + if c.Kind() != reflect.Slice || + c.Type().Elem() != e.Type().Elem() { + err = NewFatalError(fmt.Sprintf("which is not a %s", typeStr)) + return + } + + err = errors.New("") + if c.Pointer() == e.Pointer() { + err = nil + } + return +} + +func checkAgainstString(e reflect.Value, c reflect.Value) (err error) { + // Make sure c is a string. + if c.Kind() != reflect.String { + err = NewFatalError("which is not a string") + return + } + + err = errors.New("") + if c.String() == e.String() { + err = nil + } + return +} + +func checkAgainstArray(e reflect.Value, c reflect.Value) (err error) { + // Create a description of e's type, e.g. "[2]int". + typeStr := fmt.Sprintf("%v", e.Type()) + + // Make sure c is the correct type. + if c.Type() != e.Type() { + err = NewFatalError(fmt.Sprintf("which is not %s", typeStr)) + return + } + + // Check for equality. + if e.Interface() != c.Interface() { + err = errors.New("") + return + } + + return +} + +func checkAgainstUnsafePointer(e reflect.Value, c reflect.Value) (err error) { + // Make sure c is a pointer. + if c.Kind() != reflect.UnsafePointer { + err = NewFatalError("which is not a unsafe.Pointer") + return + } + + err = errors.New("") + if c.Pointer() == e.Pointer() { + err = nil + } + return +} + +func checkForNil(c reflect.Value) (err error) { + err = errors.New("") + + // Make sure it is legal to call IsNil. + switch c.Kind() { + case reflect.Invalid: + case reflect.Chan: + case reflect.Func: + case reflect.Interface: + case reflect.Map: + case reflect.Ptr: + case reflect.Slice: + + default: + err = NewFatalError("which cannot be compared to nil") + return + } + + // Ask whether the value is nil. Handle a nil literal (kind Invalid) + // specially, since it's not legal to call IsNil there. + if c.Kind() == reflect.Invalid || c.IsNil() { + err = nil + } + return +} + +//////////////////////////////////////////////////////////////////////// +// Public implementation +//////////////////////////////////////////////////////////////////////// + +func (m *equalsMatcher) Matches(candidate interface{}) error { + e := m.expectedValue + c := reflect.ValueOf(candidate) + ek := e.Kind() + + switch { + case ek == reflect.Bool: + return checkAgainstBool(e.Bool(), c) + + case isSignedInteger(e): + return checkAgainstInt64(e.Int(), c) + + case isUnsignedInteger(e): + return checkAgainstUint64(e.Uint(), c) + + case ek == reflect.Float32: + return checkAgainstFloat32(float32(e.Float()), c) + + case ek == reflect.Float64: + return checkAgainstFloat64(e.Float(), c) + + case ek == reflect.Complex64: + return checkAgainstComplex64(complex64(e.Complex()), c) + + case ek == reflect.Complex128: + return checkAgainstComplex128(complex128(e.Complex()), c) + + case ek == reflect.Chan: + return checkAgainstChan(e, c) + + case ek == reflect.Func: + return checkAgainstFunc(e, c) + + case ek == reflect.Map: + return checkAgainstMap(e, c) + + case ek == reflect.Ptr: + return checkAgainstPtr(e, c) + + case ek == reflect.Slice: + return checkAgainstSlice(e, c) + + case ek == reflect.String: + return checkAgainstString(e, c) + + case ek == reflect.Array: + return checkAgainstArray(e, c) + + case ek == reflect.UnsafePointer: + return checkAgainstUnsafePointer(e, c) + + case ek == reflect.Invalid: + return checkForNil(c) + } + + panic(fmt.Sprintf("equalsMatcher.Matches: unexpected kind: %v", ek)) +} + +func (m *equalsMatcher) Description() string { + // Special case: handle nil. + if !m.expectedValue.IsValid() { + return "is nil" + } + + return fmt.Sprintf("%v", m.expectedValue.Interface()) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/equals_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/equals_test.go new file mode 100644 index 00000000000..6ac5df27329 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/equals_test.go @@ -0,0 +1,3864 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package oglematchers_test + +import ( + "fmt" + "math" + "unsafe" + + . "github.com/smartystreets/assertions/internal/oglematchers" + . "github.com/smartystreets/assertions/internal/ogletest" +) + +var someInt int = -17 + +//////////////////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////////////////// + +type EqualsTest struct { +} + +func init() { RegisterTestSuite(&EqualsTest{}) } + +type equalsTestCase struct { + candidate interface{} + expectedResult bool + shouldBeFatal bool + expectedError string +} + +func (t *EqualsTest) checkTestCases(matcher Matcher, cases []equalsTestCase) { + for i, c := range cases { + err := matcher.Matches(c.candidate) + ExpectEq( + c.expectedResult, + (err == nil), + "Result for case %d: %v (Error: %v)", i, c, err) + + if err == nil { + continue + } + + _, isFatal := err.(*FatalError) + ExpectEq(c.shouldBeFatal, isFatal, "Fatality for case %d: %v", i, c) + + ExpectThat(err, Error(Equals(c.expectedError)), "Case %d: %v", i, c) + } +} + +//////////////////////////////////////////////////////////////////////// +// nil +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) EqualsNil() { + matcher := Equals(nil) + ExpectEq("is nil", matcher.Description()) + + cases := []equalsTestCase{ + // Legal types + equalsTestCase{nil, true, false, ""}, + equalsTestCase{chan int(nil), true, false, ""}, + equalsTestCase{(func())(nil), true, false, ""}, + equalsTestCase{interface{}(nil), true, false, ""}, + equalsTestCase{map[int]int(nil), true, false, ""}, + equalsTestCase{(*int)(nil), true, false, ""}, + equalsTestCase{[]int(nil), true, false, ""}, + + equalsTestCase{make(chan int), false, false, ""}, + equalsTestCase{func() {}, false, false, ""}, + equalsTestCase{map[int]int{}, false, false, ""}, + equalsTestCase{&someInt, false, false, ""}, + equalsTestCase{[]int{}, false, false, ""}, + + // Illegal types + equalsTestCase{17, false, true, "which cannot be compared to nil"}, + equalsTestCase{int8(17), false, true, "which cannot be compared to nil"}, + equalsTestCase{uintptr(17), false, true, "which cannot be compared to nil"}, + equalsTestCase{[...]int{}, false, true, "which cannot be compared to nil"}, + equalsTestCase{"taco", false, true, "which cannot be compared to nil"}, + equalsTestCase{equalsTestCase{}, false, true, "which cannot be compared to nil"}, + equalsTestCase{unsafe.Pointer(&someInt), false, true, "which cannot be compared to nil"}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// Integer literals +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) NegativeIntegerLiteral() { + // -2^30 + matcher := Equals(-1073741824) + ExpectEq("-1073741824", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of -1073741824. + equalsTestCase{-1073741824, true, false, ""}, + equalsTestCase{-1073741824.0, true, false, ""}, + equalsTestCase{-1073741824 + 0i, true, false, ""}, + equalsTestCase{int(-1073741824), true, false, ""}, + equalsTestCase{int32(-1073741824), true, false, ""}, + equalsTestCase{int64(-1073741824), true, false, ""}, + equalsTestCase{float32(-1073741824), true, false, ""}, + equalsTestCase{float64(-1073741824), true, false, ""}, + equalsTestCase{complex64(-1073741824), true, false, ""}, + equalsTestCase{complex128(-1073741824), true, false, ""}, + equalsTestCase{interface{}(int(-1073741824)), true, false, ""}, + + // Values that would be -1073741824 in two's complement. + equalsTestCase{uint((1 << 32) - 1073741824), false, false, ""}, + equalsTestCase{uint32((1 << 32) - 1073741824), false, false, ""}, + equalsTestCase{uint64((1 << 64) - 1073741824), false, false, ""}, + equalsTestCase{uintptr((1 << 64) - 1073741824), false, false, ""}, + + // Non-equal values of signed integer type. + equalsTestCase{int(-1073741823), false, false, ""}, + equalsTestCase{int32(-1073741823), false, false, ""}, + equalsTestCase{int64(-1073741823), false, false, ""}, + + // Non-equal values of other numeric types. + equalsTestCase{float64(-1073741824.1), false, false, ""}, + equalsTestCase{float64(-1073741823.9), false, false, ""}, + equalsTestCase{complex128(-1073741823), false, false, ""}, + equalsTestCase{complex128(-1073741824 + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) PositiveIntegerLiteral() { + // 2^30 + matcher := Equals(1073741824) + ExpectEq("1073741824", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of 1073741824. + equalsTestCase{1073741824, true, false, ""}, + equalsTestCase{1073741824.0, true, false, ""}, + equalsTestCase{1073741824 + 0i, true, false, ""}, + equalsTestCase{int(1073741824), true, false, ""}, + equalsTestCase{uint(1073741824), true, false, ""}, + equalsTestCase{int32(1073741824), true, false, ""}, + equalsTestCase{int64(1073741824), true, false, ""}, + equalsTestCase{uint32(1073741824), true, false, ""}, + equalsTestCase{uint64(1073741824), true, false, ""}, + equalsTestCase{uintptr(1073741824), true, false, ""}, + equalsTestCase{float32(1073741824), true, false, ""}, + equalsTestCase{float64(1073741824), true, false, ""}, + equalsTestCase{complex64(1073741824), true, false, ""}, + equalsTestCase{complex128(1073741824), true, false, ""}, + equalsTestCase{interface{}(int(1073741824)), true, false, ""}, + equalsTestCase{interface{}(uint(1073741824)), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int(1073741823), false, false, ""}, + equalsTestCase{int32(1073741823), false, false, ""}, + equalsTestCase{int64(1073741823), false, false, ""}, + equalsTestCase{float64(1073741824.1), false, false, ""}, + equalsTestCase{float64(1073741823.9), false, false, ""}, + equalsTestCase{complex128(1073741823), false, false, ""}, + equalsTestCase{complex128(1073741824 + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// Floating point literals +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) NegativeIntegralFloatingPointLiteral() { + // -2^30 + matcher := Equals(-1073741824.0) + ExpectEq("-1.073741824e+09", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of -1073741824. + equalsTestCase{-1073741824, true, false, ""}, + equalsTestCase{-1073741824.0, true, false, ""}, + equalsTestCase{-1073741824 + 0i, true, false, ""}, + equalsTestCase{int(-1073741824), true, false, ""}, + equalsTestCase{int32(-1073741824), true, false, ""}, + equalsTestCase{int64(-1073741824), true, false, ""}, + equalsTestCase{float32(-1073741824), true, false, ""}, + equalsTestCase{float64(-1073741824), true, false, ""}, + equalsTestCase{complex64(-1073741824), true, false, ""}, + equalsTestCase{complex128(-1073741824), true, false, ""}, + equalsTestCase{interface{}(int(-1073741824)), true, false, ""}, + equalsTestCase{interface{}(float64(-1073741824)), true, false, ""}, + + // Values that would be -1073741824 in two's complement. + equalsTestCase{uint((1 << 32) - 1073741824), false, false, ""}, + equalsTestCase{uint32((1 << 32) - 1073741824), false, false, ""}, + equalsTestCase{uint64((1 << 64) - 1073741824), false, false, ""}, + equalsTestCase{uintptr((1 << 64) - 1073741824), false, false, ""}, + + // Non-equal values of signed integer type. + equalsTestCase{int(-1073741823), false, false, ""}, + equalsTestCase{int32(-1073741823), false, false, ""}, + equalsTestCase{int64(-1073741823), false, false, ""}, + + // Non-equal values of other numeric types. + equalsTestCase{float64(-1073741824.1), false, false, ""}, + equalsTestCase{float64(-1073741823.9), false, false, ""}, + equalsTestCase{complex128(-1073741823), false, false, ""}, + equalsTestCase{complex128(-1073741824 + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) PositiveIntegralFloatingPointLiteral() { + // 2^30 + matcher := Equals(1073741824.0) + ExpectEq("1.073741824e+09", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of 1073741824. + equalsTestCase{1073741824, true, false, ""}, + equalsTestCase{1073741824.0, true, false, ""}, + equalsTestCase{1073741824 + 0i, true, false, ""}, + equalsTestCase{int(1073741824), true, false, ""}, + equalsTestCase{int32(1073741824), true, false, ""}, + equalsTestCase{int64(1073741824), true, false, ""}, + equalsTestCase{uint(1073741824), true, false, ""}, + equalsTestCase{uint32(1073741824), true, false, ""}, + equalsTestCase{uint64(1073741824), true, false, ""}, + equalsTestCase{float32(1073741824), true, false, ""}, + equalsTestCase{float64(1073741824), true, false, ""}, + equalsTestCase{complex64(1073741824), true, false, ""}, + equalsTestCase{complex128(1073741824), true, false, ""}, + equalsTestCase{interface{}(int(1073741824)), true, false, ""}, + equalsTestCase{interface{}(float64(1073741824)), true, false, ""}, + + // Values that would be 1073741824 in two's complement. + equalsTestCase{uint((1 << 32) - 1073741824), false, false, ""}, + equalsTestCase{uint32((1 << 32) - 1073741824), false, false, ""}, + equalsTestCase{uint64((1 << 64) - 1073741824), false, false, ""}, + equalsTestCase{uintptr((1 << 64) - 1073741824), false, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int(1073741823), false, false, ""}, + equalsTestCase{int32(1073741823), false, false, ""}, + equalsTestCase{int64(1073741823), false, false, ""}, + equalsTestCase{uint(1073741823), false, false, ""}, + equalsTestCase{uint32(1073741823), false, false, ""}, + equalsTestCase{uint64(1073741823), false, false, ""}, + equalsTestCase{float64(1073741824.1), false, false, ""}, + equalsTestCase{float64(1073741823.9), false, false, ""}, + equalsTestCase{complex128(1073741823), false, false, ""}, + equalsTestCase{complex128(1073741824 + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) NonIntegralFloatingPointLiteral() { + matcher := Equals(17.1) + ExpectEq("17.1", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of 17.1. + equalsTestCase{17.1, true, false, ""}, + equalsTestCase{17.1, true, false, ""}, + equalsTestCase{17.1 + 0i, true, false, ""}, + equalsTestCase{float32(17.1), true, false, ""}, + equalsTestCase{float64(17.1), true, false, ""}, + equalsTestCase{complex64(17.1), true, false, ""}, + equalsTestCase{complex128(17.1), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{17, false, false, ""}, + equalsTestCase{17.2, false, false, ""}, + equalsTestCase{18, false, false, ""}, + equalsTestCase{int(17), false, false, ""}, + equalsTestCase{int(18), false, false, ""}, + equalsTestCase{int32(17), false, false, ""}, + equalsTestCase{int64(17), false, false, ""}, + equalsTestCase{uint(17), false, false, ""}, + equalsTestCase{uint32(17), false, false, ""}, + equalsTestCase{uint64(17), false, false, ""}, + equalsTestCase{uintptr(17), false, false, ""}, + equalsTestCase{complex128(17.1 + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// bool +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) False() { + matcher := Equals(false) + ExpectEq("false", matcher.Description()) + + cases := []equalsTestCase{ + // bools + equalsTestCase{false, true, false, ""}, + equalsTestCase{bool(false), true, false, ""}, + + equalsTestCase{true, false, false, ""}, + equalsTestCase{bool(true), false, false, ""}, + + // Other types. + equalsTestCase{int(0), false, true, "which is not a bool"}, + equalsTestCase{int8(0), false, true, "which is not a bool"}, + equalsTestCase{int16(0), false, true, "which is not a bool"}, + equalsTestCase{int32(0), false, true, "which is not a bool"}, + equalsTestCase{int64(0), false, true, "which is not a bool"}, + equalsTestCase{uint(0), false, true, "which is not a bool"}, + equalsTestCase{uint8(0), false, true, "which is not a bool"}, + equalsTestCase{uint16(0), false, true, "which is not a bool"}, + equalsTestCase{uint32(0), false, true, "which is not a bool"}, + equalsTestCase{uint64(0), false, true, "which is not a bool"}, + equalsTestCase{uintptr(0), false, true, "which is not a bool"}, + equalsTestCase{[...]int{}, false, true, "which is not a bool"}, + equalsTestCase{make(chan int), false, true, "which is not a bool"}, + equalsTestCase{func() {}, false, true, "which is not a bool"}, + equalsTestCase{map[int]int{}, false, true, "which is not a bool"}, + equalsTestCase{&someInt, false, true, "which is not a bool"}, + equalsTestCase{[]int{}, false, true, "which is not a bool"}, + equalsTestCase{"taco", false, true, "which is not a bool"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not a bool"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) True() { + matcher := Equals(true) + ExpectEq("true", matcher.Description()) + + cases := []equalsTestCase{ + // bools + equalsTestCase{true, true, false, ""}, + equalsTestCase{bool(true), true, false, ""}, + + equalsTestCase{false, false, false, ""}, + equalsTestCase{bool(false), false, false, ""}, + + // Other types. + equalsTestCase{int(1), false, true, "which is not a bool"}, + equalsTestCase{int8(1), false, true, "which is not a bool"}, + equalsTestCase{int16(1), false, true, "which is not a bool"}, + equalsTestCase{int32(1), false, true, "which is not a bool"}, + equalsTestCase{int64(1), false, true, "which is not a bool"}, + equalsTestCase{uint(1), false, true, "which is not a bool"}, + equalsTestCase{uint8(1), false, true, "which is not a bool"}, + equalsTestCase{uint16(1), false, true, "which is not a bool"}, + equalsTestCase{uint32(1), false, true, "which is not a bool"}, + equalsTestCase{uint64(1), false, true, "which is not a bool"}, + equalsTestCase{uintptr(1), false, true, "which is not a bool"}, + equalsTestCase{[...]int{}, false, true, "which is not a bool"}, + equalsTestCase{make(chan int), false, true, "which is not a bool"}, + equalsTestCase{func() {}, false, true, "which is not a bool"}, + equalsTestCase{map[int]int{}, false, true, "which is not a bool"}, + equalsTestCase{&someInt, false, true, "which is not a bool"}, + equalsTestCase{[]int{}, false, true, "which is not a bool"}, + equalsTestCase{"taco", false, true, "which is not a bool"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not a bool"}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// int +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) NegativeInt() { + // -2^30 + matcher := Equals(int(-1073741824)) + ExpectEq("-1073741824", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of -1073741824. + equalsTestCase{-1073741824, true, false, ""}, + equalsTestCase{-1073741824.0, true, false, ""}, + equalsTestCase{-1073741824 + 0i, true, false, ""}, + equalsTestCase{int(-1073741824), true, false, ""}, + equalsTestCase{int32(-1073741824), true, false, ""}, + equalsTestCase{int64(-1073741824), true, false, ""}, + equalsTestCase{float32(-1073741824), true, false, ""}, + equalsTestCase{float64(-1073741824), true, false, ""}, + equalsTestCase{complex64(-1073741824), true, false, ""}, + equalsTestCase{complex128(-1073741824), true, false, ""}, + equalsTestCase{interface{}(int(-1073741824)), true, false, ""}, + + // Values that would be -1073741824 in two's complement. + equalsTestCase{uint((1 << 32) - 1073741824), false, false, ""}, + equalsTestCase{uint32((1 << 32) - 1073741824), false, false, ""}, + equalsTestCase{uint64((1 << 64) - 1073741824), false, false, ""}, + equalsTestCase{uintptr((1 << 64) - 1073741824), false, false, ""}, + + // Non-equal values of signed integer type. + equalsTestCase{int(-1073741823), false, false, ""}, + equalsTestCase{int32(-1073741823), false, false, ""}, + equalsTestCase{int64(-1073741823), false, false, ""}, + + // Non-equal values of other numeric types. + equalsTestCase{float64(-1073741824.1), false, false, ""}, + equalsTestCase{float64(-1073741823.9), false, false, ""}, + equalsTestCase{complex128(-1073741823), false, false, ""}, + equalsTestCase{complex128(-1073741824 + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) PositiveInt() { + // 2^30 + matcher := Equals(int(1073741824)) + ExpectEq("1073741824", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of 1073741824. + equalsTestCase{1073741824, true, false, ""}, + equalsTestCase{1073741824.0, true, false, ""}, + equalsTestCase{1073741824 + 0i, true, false, ""}, + equalsTestCase{int(1073741824), true, false, ""}, + equalsTestCase{uint(1073741824), true, false, ""}, + equalsTestCase{int32(1073741824), true, false, ""}, + equalsTestCase{int64(1073741824), true, false, ""}, + equalsTestCase{uint32(1073741824), true, false, ""}, + equalsTestCase{uint64(1073741824), true, false, ""}, + equalsTestCase{uintptr(1073741824), true, false, ""}, + equalsTestCase{float32(1073741824), true, false, ""}, + equalsTestCase{float64(1073741824), true, false, ""}, + equalsTestCase{complex64(1073741824), true, false, ""}, + equalsTestCase{complex128(1073741824), true, false, ""}, + equalsTestCase{interface{}(int(1073741824)), true, false, ""}, + equalsTestCase{interface{}(uint(1073741824)), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int(1073741823), false, false, ""}, + equalsTestCase{int32(1073741823), false, false, ""}, + equalsTestCase{int64(1073741823), false, false, ""}, + equalsTestCase{float64(1073741824.1), false, false, ""}, + equalsTestCase{float64(1073741823.9), false, false, ""}, + equalsTestCase{complex128(1073741823), false, false, ""}, + equalsTestCase{complex128(1073741824 + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// int8 +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) NegativeInt8() { + matcher := Equals(int8(-17)) + ExpectEq("-17", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of -17. + equalsTestCase{-17, true, false, ""}, + equalsTestCase{-17.0, true, false, ""}, + equalsTestCase{-17 + 0i, true, false, ""}, + equalsTestCase{int(-17), true, false, ""}, + equalsTestCase{int8(-17), true, false, ""}, + equalsTestCase{int16(-17), true, false, ""}, + equalsTestCase{int32(-17), true, false, ""}, + equalsTestCase{int64(-17), true, false, ""}, + equalsTestCase{float32(-17), true, false, ""}, + equalsTestCase{float64(-17), true, false, ""}, + equalsTestCase{complex64(-17), true, false, ""}, + equalsTestCase{complex128(-17), true, false, ""}, + equalsTestCase{interface{}(int(-17)), true, false, ""}, + + // Values that would be -17 in two's complement. + equalsTestCase{uint((1 << 32) - 17), false, false, ""}, + equalsTestCase{uint8((1 << 8) - 17), false, false, ""}, + equalsTestCase{uint16((1 << 16) - 17), false, false, ""}, + equalsTestCase{uint32((1 << 32) - 17), false, false, ""}, + equalsTestCase{uint64((1 << 64) - 17), false, false, ""}, + equalsTestCase{uintptr((1 << 64) - 17), false, false, ""}, + + // Non-equal values of signed integer type. + equalsTestCase{int(-16), false, false, ""}, + equalsTestCase{int8(-16), false, false, ""}, + equalsTestCase{int16(-16), false, false, ""}, + equalsTestCase{int32(-16), false, false, ""}, + equalsTestCase{int64(-16), false, false, ""}, + + // Non-equal values of other numeric types. + equalsTestCase{float32(-17.1), false, false, ""}, + equalsTestCase{float32(-16.9), false, false, ""}, + equalsTestCase{complex64(-16), false, false, ""}, + equalsTestCase{complex64(-17 + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{-17}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{-17}, false, true, "which is not numeric"}, + equalsTestCase{"-17", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) ZeroInt8() { + matcher := Equals(int8(0)) + ExpectEq("0", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of 0. + equalsTestCase{0, true, false, ""}, + equalsTestCase{0.0, true, false, ""}, + equalsTestCase{0 + 0i, true, false, ""}, + equalsTestCase{int(0), true, false, ""}, + equalsTestCase{int8(0), true, false, ""}, + equalsTestCase{int16(0), true, false, ""}, + equalsTestCase{int32(0), true, false, ""}, + equalsTestCase{int64(0), true, false, ""}, + equalsTestCase{float32(0), true, false, ""}, + equalsTestCase{float64(0), true, false, ""}, + equalsTestCase{complex64(0), true, false, ""}, + equalsTestCase{complex128(0), true, false, ""}, + equalsTestCase{interface{}(int(0)), true, false, ""}, + equalsTestCase{uint(0), true, false, ""}, + equalsTestCase{uint8(0), true, false, ""}, + equalsTestCase{uint16(0), true, false, ""}, + equalsTestCase{uint32(0), true, false, ""}, + equalsTestCase{uint64(0), true, false, ""}, + equalsTestCase{uintptr(0), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int(1), false, false, ""}, + equalsTestCase{int8(1), false, false, ""}, + equalsTestCase{int16(1), false, false, ""}, + equalsTestCase{int32(1), false, false, ""}, + equalsTestCase{int64(1), false, false, ""}, + equalsTestCase{float32(-0.1), false, false, ""}, + equalsTestCase{float32(0.1), false, false, ""}, + equalsTestCase{complex64(1), false, false, ""}, + equalsTestCase{complex64(0 + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{0}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{0}, false, true, "which is not numeric"}, + equalsTestCase{"0", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) PositiveInt8() { + matcher := Equals(int8(17)) + ExpectEq("17", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of 17. + equalsTestCase{17, true, false, ""}, + equalsTestCase{17.0, true, false, ""}, + equalsTestCase{17 + 0i, true, false, ""}, + equalsTestCase{int(17), true, false, ""}, + equalsTestCase{int8(17), true, false, ""}, + equalsTestCase{int16(17), true, false, ""}, + equalsTestCase{int32(17), true, false, ""}, + equalsTestCase{int64(17), true, false, ""}, + equalsTestCase{float32(17), true, false, ""}, + equalsTestCase{float64(17), true, false, ""}, + equalsTestCase{complex64(17), true, false, ""}, + equalsTestCase{complex128(17), true, false, ""}, + equalsTestCase{interface{}(int(17)), true, false, ""}, + equalsTestCase{uint(17), true, false, ""}, + equalsTestCase{uint8(17), true, false, ""}, + equalsTestCase{uint16(17), true, false, ""}, + equalsTestCase{uint32(17), true, false, ""}, + equalsTestCase{uint64(17), true, false, ""}, + equalsTestCase{uintptr(17), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int(16), false, false, ""}, + equalsTestCase{int8(16), false, false, ""}, + equalsTestCase{int16(16), false, false, ""}, + equalsTestCase{int32(16), false, false, ""}, + equalsTestCase{int64(16), false, false, ""}, + equalsTestCase{float32(16.9), false, false, ""}, + equalsTestCase{float32(17.1), false, false, ""}, + equalsTestCase{complex64(16), false, false, ""}, + equalsTestCase{complex64(17 + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{17}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{17}, false, true, "which is not numeric"}, + equalsTestCase{"17", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// int16 +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) NegativeInt16() { + matcher := Equals(int16(-32766)) + ExpectEq("-32766", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of -32766. + equalsTestCase{-32766, true, false, ""}, + equalsTestCase{-32766.0, true, false, ""}, + equalsTestCase{-32766 + 0i, true, false, ""}, + equalsTestCase{int(-32766), true, false, ""}, + equalsTestCase{int16(-32766), true, false, ""}, + equalsTestCase{int32(-32766), true, false, ""}, + equalsTestCase{int64(-32766), true, false, ""}, + equalsTestCase{float32(-32766), true, false, ""}, + equalsTestCase{float64(-32766), true, false, ""}, + equalsTestCase{complex64(-32766), true, false, ""}, + equalsTestCase{complex128(-32766), true, false, ""}, + equalsTestCase{interface{}(int(-32766)), true, false, ""}, + + // Values that would be -32766 in two's complement. + equalsTestCase{uint((1 << 32) - 32766), false, false, ""}, + equalsTestCase{uint16((1 << 16) - 32766), false, false, ""}, + equalsTestCase{uint32((1 << 32) - 32766), false, false, ""}, + equalsTestCase{uint64((1 << 64) - 32766), false, false, ""}, + equalsTestCase{uintptr((1 << 64) - 32766), false, false, ""}, + + // Non-equal values of signed integer type. + equalsTestCase{int(-16), false, false, ""}, + equalsTestCase{int8(-16), false, false, ""}, + equalsTestCase{int16(-16), false, false, ""}, + equalsTestCase{int32(-16), false, false, ""}, + equalsTestCase{int64(-16), false, false, ""}, + + // Non-equal values of other numeric types. + equalsTestCase{float32(-32766.1), false, false, ""}, + equalsTestCase{float32(-32765.9), false, false, ""}, + equalsTestCase{complex64(-32766.1), false, false, ""}, + equalsTestCase{complex64(-32766 + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{-32766}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{-32766}, false, true, "which is not numeric"}, + equalsTestCase{"-32766", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) ZeroInt16() { + matcher := Equals(int16(0)) + ExpectEq("0", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of 0. + equalsTestCase{0, true, false, ""}, + equalsTestCase{0.0, true, false, ""}, + equalsTestCase{0 + 0i, true, false, ""}, + equalsTestCase{int(0), true, false, ""}, + equalsTestCase{int8(0), true, false, ""}, + equalsTestCase{int16(0), true, false, ""}, + equalsTestCase{int32(0), true, false, ""}, + equalsTestCase{int64(0), true, false, ""}, + equalsTestCase{float32(0), true, false, ""}, + equalsTestCase{float64(0), true, false, ""}, + equalsTestCase{complex64(0), true, false, ""}, + equalsTestCase{complex128(0), true, false, ""}, + equalsTestCase{interface{}(int(0)), true, false, ""}, + equalsTestCase{uint(0), true, false, ""}, + equalsTestCase{uint8(0), true, false, ""}, + equalsTestCase{uint16(0), true, false, ""}, + equalsTestCase{uint32(0), true, false, ""}, + equalsTestCase{uint64(0), true, false, ""}, + equalsTestCase{uintptr(0), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int(1), false, false, ""}, + equalsTestCase{int8(1), false, false, ""}, + equalsTestCase{int16(1), false, false, ""}, + equalsTestCase{int32(1), false, false, ""}, + equalsTestCase{int64(1), false, false, ""}, + equalsTestCase{float32(-0.1), false, false, ""}, + equalsTestCase{float32(0.1), false, false, ""}, + equalsTestCase{complex64(1), false, false, ""}, + equalsTestCase{complex64(0 + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{0}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{0}, false, true, "which is not numeric"}, + equalsTestCase{"0", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) PositiveInt16() { + matcher := Equals(int16(32765)) + ExpectEq("32765", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of 32765. + equalsTestCase{32765, true, false, ""}, + equalsTestCase{32765.0, true, false, ""}, + equalsTestCase{32765 + 0i, true, false, ""}, + equalsTestCase{int(32765), true, false, ""}, + equalsTestCase{int16(32765), true, false, ""}, + equalsTestCase{int32(32765), true, false, ""}, + equalsTestCase{int64(32765), true, false, ""}, + equalsTestCase{float32(32765), true, false, ""}, + equalsTestCase{float64(32765), true, false, ""}, + equalsTestCase{complex64(32765), true, false, ""}, + equalsTestCase{complex128(32765), true, false, ""}, + equalsTestCase{interface{}(int(32765)), true, false, ""}, + equalsTestCase{uint(32765), true, false, ""}, + equalsTestCase{uint16(32765), true, false, ""}, + equalsTestCase{uint32(32765), true, false, ""}, + equalsTestCase{uint64(32765), true, false, ""}, + equalsTestCase{uintptr(32765), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int(32764), false, false, ""}, + equalsTestCase{int16(32764), false, false, ""}, + equalsTestCase{int32(32764), false, false, ""}, + equalsTestCase{int64(32764), false, false, ""}, + equalsTestCase{float32(32764.9), false, false, ""}, + equalsTestCase{float32(32765.1), false, false, ""}, + equalsTestCase{complex64(32765.9), false, false, ""}, + equalsTestCase{complex64(32765 + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{32765}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{32765}, false, true, "which is not numeric"}, + equalsTestCase{"32765", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// int32 +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) NegativeInt32() { + // -2^30 + matcher := Equals(int32(-1073741824)) + ExpectEq("-1073741824", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of -1073741824. + equalsTestCase{-1073741824, true, false, ""}, + equalsTestCase{-1073741824.0, true, false, ""}, + equalsTestCase{-1073741824 + 0i, true, false, ""}, + equalsTestCase{int(-1073741824), true, false, ""}, + equalsTestCase{int32(-1073741824), true, false, ""}, + equalsTestCase{int64(-1073741824), true, false, ""}, + equalsTestCase{float32(-1073741824), true, false, ""}, + equalsTestCase{float64(-1073741824), true, false, ""}, + equalsTestCase{complex64(-1073741824), true, false, ""}, + equalsTestCase{complex128(-1073741824), true, false, ""}, + equalsTestCase{interface{}(int(-1073741824)), true, false, ""}, + + // Values that would be -1073741824 in two's complement. + equalsTestCase{uint((1 << 32) - 1073741824), false, false, ""}, + equalsTestCase{uint32((1 << 32) - 1073741824), false, false, ""}, + equalsTestCase{uint64((1 << 64) - 1073741824), false, false, ""}, + equalsTestCase{uintptr((1 << 64) - 1073741824), false, false, ""}, + + // Non-equal values of signed integer type. + equalsTestCase{int(-1073741823), false, false, ""}, + equalsTestCase{int32(-1073741823), false, false, ""}, + equalsTestCase{int64(-1073741823), false, false, ""}, + + // Non-equal values of other numeric types. + equalsTestCase{float64(-1073741824.1), false, false, ""}, + equalsTestCase{float64(-1073741823.9), false, false, ""}, + equalsTestCase{complex128(-1073741823), false, false, ""}, + equalsTestCase{complex128(-1073741824 + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) PositiveInt32() { + // 2^30 + matcher := Equals(int32(1073741824)) + ExpectEq("1073741824", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of 1073741824. + equalsTestCase{1073741824, true, false, ""}, + equalsTestCase{1073741824.0, true, false, ""}, + equalsTestCase{1073741824 + 0i, true, false, ""}, + equalsTestCase{int(1073741824), true, false, ""}, + equalsTestCase{uint(1073741824), true, false, ""}, + equalsTestCase{int32(1073741824), true, false, ""}, + equalsTestCase{int64(1073741824), true, false, ""}, + equalsTestCase{uint32(1073741824), true, false, ""}, + equalsTestCase{uint64(1073741824), true, false, ""}, + equalsTestCase{uintptr(1073741824), true, false, ""}, + equalsTestCase{float32(1073741824), true, false, ""}, + equalsTestCase{float64(1073741824), true, false, ""}, + equalsTestCase{complex64(1073741824), true, false, ""}, + equalsTestCase{complex128(1073741824), true, false, ""}, + equalsTestCase{interface{}(int(1073741824)), true, false, ""}, + equalsTestCase{interface{}(uint(1073741824)), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int(1073741823), false, false, ""}, + equalsTestCase{int32(1073741823), false, false, ""}, + equalsTestCase{int64(1073741823), false, false, ""}, + equalsTestCase{float64(1073741824.1), false, false, ""}, + equalsTestCase{float64(1073741823.9), false, false, ""}, + equalsTestCase{complex128(1073741823), false, false, ""}, + equalsTestCase{complex128(1073741824 + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// int64 +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) NegativeInt64() { + // -2^40 + matcher := Equals(int64(-1099511627776)) + ExpectEq("-1099511627776", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of -1099511627776. + equalsTestCase{-1099511627776.0, true, false, ""}, + equalsTestCase{-1099511627776 + 0i, true, false, ""}, + equalsTestCase{int64(-1099511627776), true, false, ""}, + equalsTestCase{float32(-1099511627776), true, false, ""}, + equalsTestCase{float64(-1099511627776), true, false, ""}, + equalsTestCase{complex64(-1099511627776), true, false, ""}, + equalsTestCase{complex128(-1099511627776), true, false, ""}, + equalsTestCase{interface{}(int64(-1099511627776)), true, false, ""}, + + // Values that would be -1099511627776 in two's complement. + equalsTestCase{uint64((1 << 64) - 1099511627776), false, false, ""}, + + // Non-equal values of signed integer type. + equalsTestCase{int64(-1099511627775), false, false, ""}, + + // Non-equal values of other numeric types. + equalsTestCase{float64(-1099511627776.1), false, false, ""}, + equalsTestCase{float64(-1099511627775.9), false, false, ""}, + equalsTestCase{complex128(-1099511627775), false, false, ""}, + equalsTestCase{complex128(-1099511627776 + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) PositiveInt64() { + // 2^40 + matcher := Equals(int64(1099511627776)) + ExpectEq("1099511627776", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of 1099511627776. + equalsTestCase{1099511627776.0, true, false, ""}, + equalsTestCase{1099511627776 + 0i, true, false, ""}, + equalsTestCase{int64(1099511627776), true, false, ""}, + equalsTestCase{uint64(1099511627776), true, false, ""}, + equalsTestCase{uintptr(1099511627776), true, false, ""}, + equalsTestCase{float32(1099511627776), true, false, ""}, + equalsTestCase{float64(1099511627776), true, false, ""}, + equalsTestCase{complex64(1099511627776), true, false, ""}, + equalsTestCase{complex128(1099511627776), true, false, ""}, + equalsTestCase{interface{}(int64(1099511627776)), true, false, ""}, + equalsTestCase{interface{}(uint64(1099511627776)), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int64(1099511627775), false, false, ""}, + equalsTestCase{uint64(1099511627775), false, false, ""}, + equalsTestCase{float64(1099511627776.1), false, false, ""}, + equalsTestCase{float64(1099511627775.9), false, false, ""}, + equalsTestCase{complex128(1099511627775), false, false, ""}, + equalsTestCase{complex128(1099511627776 + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) Int64NotExactlyRepresentableBySinglePrecision() { + // Single-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo25 = 1 << 25 + matcher := Equals(int64(kTwoTo25 + 1)) + ExpectEq("33554433", matcher.Description()) + + cases := []equalsTestCase{ + // Integers. + equalsTestCase{int64(kTwoTo25 + 0), false, false, ""}, + equalsTestCase{int64(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{int64(kTwoTo25 + 2), false, false, ""}, + + equalsTestCase{uint64(kTwoTo25 + 0), false, false, ""}, + equalsTestCase{uint64(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{uint64(kTwoTo25 + 2), false, false, ""}, + + // Single-precision floating point. + equalsTestCase{float32(kTwoTo25 - 2), false, false, ""}, + equalsTestCase{float32(kTwoTo25 - 1), true, false, ""}, + equalsTestCase{float32(kTwoTo25 + 0), true, false, ""}, + equalsTestCase{float32(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{float32(kTwoTo25 + 2), true, false, ""}, + equalsTestCase{float32(kTwoTo25 + 3), false, false, ""}, + + equalsTestCase{complex64(kTwoTo25 - 2), false, false, ""}, + equalsTestCase{complex64(kTwoTo25 - 1), true, false, ""}, + equalsTestCase{complex64(kTwoTo25 + 0), true, false, ""}, + equalsTestCase{complex64(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{complex64(kTwoTo25 + 2), true, false, ""}, + equalsTestCase{complex64(kTwoTo25 + 3), false, false, ""}, + + // Double-precision floating point. + equalsTestCase{float64(kTwoTo25 + 0), false, false, ""}, + equalsTestCase{float64(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{float64(kTwoTo25 + 2), false, false, ""}, + + equalsTestCase{complex128(kTwoTo25 + 0), false, false, ""}, + equalsTestCase{complex128(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{complex128(kTwoTo25 + 2), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) Int64NotExactlyRepresentableByDoublePrecision() { + // Double-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^54-1, 2^54+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo54 = 1 << 54 + matcher := Equals(int64(kTwoTo54 + 1)) + ExpectEq("18014398509481985", matcher.Description()) + + cases := []equalsTestCase{ + // Integers. + equalsTestCase{int64(kTwoTo54 + 0), false, false, ""}, + equalsTestCase{int64(kTwoTo54 + 1), true, false, ""}, + equalsTestCase{int64(kTwoTo54 + 2), false, false, ""}, + + equalsTestCase{uint64(kTwoTo54 + 0), false, false, ""}, + equalsTestCase{uint64(kTwoTo54 + 1), true, false, ""}, + equalsTestCase{uint64(kTwoTo54 + 2), false, false, ""}, + + // Double-precision floating point. + equalsTestCase{float64(kTwoTo54 - 2), false, false, ""}, + equalsTestCase{float64(kTwoTo54 - 1), true, false, ""}, + equalsTestCase{float64(kTwoTo54 + 0), true, false, ""}, + equalsTestCase{float64(kTwoTo54 + 1), true, false, ""}, + equalsTestCase{float64(kTwoTo54 + 2), true, false, ""}, + equalsTestCase{float64(kTwoTo54 + 3), false, false, ""}, + + equalsTestCase{complex128(kTwoTo54 - 2), false, false, ""}, + equalsTestCase{complex128(kTwoTo54 - 1), true, false, ""}, + equalsTestCase{complex128(kTwoTo54 + 0), true, false, ""}, + equalsTestCase{complex128(kTwoTo54 + 1), true, false, ""}, + equalsTestCase{complex128(kTwoTo54 + 2), true, false, ""}, + equalsTestCase{complex128(kTwoTo54 + 3), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// uint +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) SmallUint() { + const kExpected = 17 + matcher := Equals(uint(kExpected)) + ExpectEq("17", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of the expected value. + equalsTestCase{17, true, false, ""}, + equalsTestCase{17.0, true, false, ""}, + equalsTestCase{17 + 0i, true, false, ""}, + equalsTestCase{int(kExpected), true, false, ""}, + equalsTestCase{int8(kExpected), true, false, ""}, + equalsTestCase{int16(kExpected), true, false, ""}, + equalsTestCase{int32(kExpected), true, false, ""}, + equalsTestCase{int64(kExpected), true, false, ""}, + equalsTestCase{uint(kExpected), true, false, ""}, + equalsTestCase{uint8(kExpected), true, false, ""}, + equalsTestCase{uint16(kExpected), true, false, ""}, + equalsTestCase{uint32(kExpected), true, false, ""}, + equalsTestCase{uint64(kExpected), true, false, ""}, + equalsTestCase{uintptr(kExpected), true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric types. + equalsTestCase{kExpected + 1, false, false, ""}, + equalsTestCase{int(kExpected + 1), false, false, ""}, + equalsTestCase{int8(kExpected + 1), false, false, ""}, + equalsTestCase{int16(kExpected + 1), false, false, ""}, + equalsTestCase{int32(kExpected + 1), false, false, ""}, + equalsTestCase{int64(kExpected + 1), false, false, ""}, + equalsTestCase{uint(kExpected + 1), false, false, ""}, + equalsTestCase{uint8(kExpected + 1), false, false, ""}, + equalsTestCase{uint16(kExpected + 1), false, false, ""}, + equalsTestCase{uint32(kExpected + 1), false, false, ""}, + equalsTestCase{uint64(kExpected + 1), false, false, ""}, + equalsTestCase{uintptr(kExpected + 1), false, false, ""}, + equalsTestCase{float32(kExpected + 1), false, false, ""}, + equalsTestCase{float64(kExpected + 1), false, false, ""}, + equalsTestCase{complex64(kExpected + 2i), false, false, ""}, + equalsTestCase{complex64(kExpected + 1), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + equalsTestCase{complex128(kExpected + 1), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) LargeUint() { + const kExpected = (1 << 16) + 17 + matcher := Equals(uint(kExpected)) + ExpectEq("65553", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of the expected value. + equalsTestCase{65553, true, false, ""}, + equalsTestCase{65553.0, true, false, ""}, + equalsTestCase{65553 + 0i, true, false, ""}, + equalsTestCase{int32(kExpected), true, false, ""}, + equalsTestCase{int64(kExpected), true, false, ""}, + equalsTestCase{uint32(kExpected), true, false, ""}, + equalsTestCase{uint64(kExpected), true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric types. + equalsTestCase{int16(17), false, false, ""}, + equalsTestCase{int32(kExpected + 1), false, false, ""}, + equalsTestCase{int64(kExpected + 1), false, false, ""}, + equalsTestCase{uint16(17), false, false, ""}, + equalsTestCase{uint32(kExpected + 1), false, false, ""}, + equalsTestCase{uint64(kExpected + 1), false, false, ""}, + equalsTestCase{float64(kExpected + 1), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + equalsTestCase{complex128(kExpected + 1), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) UintNotExactlyRepresentableBySinglePrecision() { + // Single-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo25 = 1 << 25 + matcher := Equals(uint(kTwoTo25 + 1)) + ExpectEq("33554433", matcher.Description()) + + cases := []equalsTestCase{ + // Integers. + equalsTestCase{int64(kTwoTo25 + 0), false, false, ""}, + equalsTestCase{int64(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{int64(kTwoTo25 + 2), false, false, ""}, + + equalsTestCase{uint64(kTwoTo25 + 0), false, false, ""}, + equalsTestCase{uint64(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{uint64(kTwoTo25 + 2), false, false, ""}, + + // Single-precision floating point. + equalsTestCase{float32(kTwoTo25 - 2), false, false, ""}, + equalsTestCase{float32(kTwoTo25 - 1), true, false, ""}, + equalsTestCase{float32(kTwoTo25 + 0), true, false, ""}, + equalsTestCase{float32(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{float32(kTwoTo25 + 2), true, false, ""}, + equalsTestCase{float32(kTwoTo25 + 3), false, false, ""}, + + equalsTestCase{complex64(kTwoTo25 - 2), false, false, ""}, + equalsTestCase{complex64(kTwoTo25 - 1), true, false, ""}, + equalsTestCase{complex64(kTwoTo25 + 0), true, false, ""}, + equalsTestCase{complex64(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{complex64(kTwoTo25 + 2), true, false, ""}, + equalsTestCase{complex64(kTwoTo25 + 3), false, false, ""}, + + // Double-precision floating point. + equalsTestCase{float64(kTwoTo25 + 0), false, false, ""}, + equalsTestCase{float64(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{float64(kTwoTo25 + 2), false, false, ""}, + + equalsTestCase{complex128(kTwoTo25 + 0), false, false, ""}, + equalsTestCase{complex128(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{complex128(kTwoTo25 + 2), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// uint8 +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) SmallUint8() { + const kExpected = 17 + matcher := Equals(uint8(kExpected)) + ExpectEq("17", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of the expected value. + equalsTestCase{17, true, false, ""}, + equalsTestCase{17.0, true, false, ""}, + equalsTestCase{17 + 0i, true, false, ""}, + equalsTestCase{int(kExpected), true, false, ""}, + equalsTestCase{int8(kExpected), true, false, ""}, + equalsTestCase{int16(kExpected), true, false, ""}, + equalsTestCase{int32(kExpected), true, false, ""}, + equalsTestCase{int64(kExpected), true, false, ""}, + equalsTestCase{uint(kExpected), true, false, ""}, + equalsTestCase{uint8(kExpected), true, false, ""}, + equalsTestCase{uint16(kExpected), true, false, ""}, + equalsTestCase{uint32(kExpected), true, false, ""}, + equalsTestCase{uint64(kExpected), true, false, ""}, + equalsTestCase{uintptr(kExpected), true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric types. + equalsTestCase{kExpected + 1, false, false, ""}, + equalsTestCase{int(kExpected + 1), false, false, ""}, + equalsTestCase{int8(kExpected + 1), false, false, ""}, + equalsTestCase{int16(kExpected + 1), false, false, ""}, + equalsTestCase{int32(kExpected + 1), false, false, ""}, + equalsTestCase{int64(kExpected + 1), false, false, ""}, + equalsTestCase{uint(kExpected + 1), false, false, ""}, + equalsTestCase{uint8(kExpected + 1), false, false, ""}, + equalsTestCase{uint16(kExpected + 1), false, false, ""}, + equalsTestCase{uint32(kExpected + 1), false, false, ""}, + equalsTestCase{uint64(kExpected + 1), false, false, ""}, + equalsTestCase{uintptr(kExpected + 1), false, false, ""}, + equalsTestCase{float32(kExpected + 1), false, false, ""}, + equalsTestCase{float64(kExpected + 1), false, false, ""}, + equalsTestCase{complex64(kExpected + 2i), false, false, ""}, + equalsTestCase{complex64(kExpected + 1), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + equalsTestCase{complex128(kExpected + 1), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// uint16 +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) SmallUint16() { + const kExpected = 17 + matcher := Equals(uint16(kExpected)) + ExpectEq("17", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of the expected value. + equalsTestCase{17, true, false, ""}, + equalsTestCase{17.0, true, false, ""}, + equalsTestCase{17 + 0i, true, false, ""}, + equalsTestCase{int(kExpected), true, false, ""}, + equalsTestCase{int8(kExpected), true, false, ""}, + equalsTestCase{int16(kExpected), true, false, ""}, + equalsTestCase{int32(kExpected), true, false, ""}, + equalsTestCase{int64(kExpected), true, false, ""}, + equalsTestCase{uint(kExpected), true, false, ""}, + equalsTestCase{uint8(kExpected), true, false, ""}, + equalsTestCase{uint16(kExpected), true, false, ""}, + equalsTestCase{uint32(kExpected), true, false, ""}, + equalsTestCase{uint64(kExpected), true, false, ""}, + equalsTestCase{uintptr(kExpected), true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric types. + equalsTestCase{kExpected + 1, false, false, ""}, + equalsTestCase{int(kExpected + 1), false, false, ""}, + equalsTestCase{int8(kExpected + 1), false, false, ""}, + equalsTestCase{int16(kExpected + 1), false, false, ""}, + equalsTestCase{int32(kExpected + 1), false, false, ""}, + equalsTestCase{int64(kExpected + 1), false, false, ""}, + equalsTestCase{uint(kExpected + 1), false, false, ""}, + equalsTestCase{uint8(kExpected + 1), false, false, ""}, + equalsTestCase{uint16(kExpected + 1), false, false, ""}, + equalsTestCase{uint32(kExpected + 1), false, false, ""}, + equalsTestCase{uint64(kExpected + 1), false, false, ""}, + equalsTestCase{uintptr(kExpected + 1), false, false, ""}, + equalsTestCase{float32(kExpected + 1), false, false, ""}, + equalsTestCase{float64(kExpected + 1), false, false, ""}, + equalsTestCase{complex64(kExpected + 2i), false, false, ""}, + equalsTestCase{complex64(kExpected + 1), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + equalsTestCase{complex128(kExpected + 1), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) LargeUint16() { + const kExpected = (1 << 8) + 17 + matcher := Equals(uint16(kExpected)) + ExpectEq("273", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of the expected value. + equalsTestCase{273, true, false, ""}, + equalsTestCase{273.0, true, false, ""}, + equalsTestCase{273 + 0i, true, false, ""}, + equalsTestCase{int16(kExpected), true, false, ""}, + equalsTestCase{int32(kExpected), true, false, ""}, + equalsTestCase{int64(kExpected), true, false, ""}, + equalsTestCase{uint16(kExpected), true, false, ""}, + equalsTestCase{uint32(kExpected), true, false, ""}, + equalsTestCase{uint64(kExpected), true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric types. + equalsTestCase{int8(17), false, false, ""}, + equalsTestCase{int16(kExpected + 1), false, false, ""}, + equalsTestCase{int32(kExpected + 1), false, false, ""}, + equalsTestCase{int64(kExpected + 1), false, false, ""}, + equalsTestCase{uint8(17), false, false, ""}, + equalsTestCase{uint16(kExpected + 1), false, false, ""}, + equalsTestCase{uint32(kExpected + 1), false, false, ""}, + equalsTestCase{uint64(kExpected + 1), false, false, ""}, + equalsTestCase{float64(kExpected + 1), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + equalsTestCase{complex128(kExpected + 1), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// uint32 +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) SmallUint32() { + const kExpected = 17 + matcher := Equals(uint32(kExpected)) + ExpectEq("17", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of the expected value. + equalsTestCase{17, true, false, ""}, + equalsTestCase{17.0, true, false, ""}, + equalsTestCase{17 + 0i, true, false, ""}, + equalsTestCase{int(kExpected), true, false, ""}, + equalsTestCase{int8(kExpected), true, false, ""}, + equalsTestCase{int16(kExpected), true, false, ""}, + equalsTestCase{int32(kExpected), true, false, ""}, + equalsTestCase{int64(kExpected), true, false, ""}, + equalsTestCase{uint(kExpected), true, false, ""}, + equalsTestCase{uint8(kExpected), true, false, ""}, + equalsTestCase{uint16(kExpected), true, false, ""}, + equalsTestCase{uint32(kExpected), true, false, ""}, + equalsTestCase{uint64(kExpected), true, false, ""}, + equalsTestCase{uintptr(kExpected), true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric types. + equalsTestCase{kExpected + 1, false, false, ""}, + equalsTestCase{int(kExpected + 1), false, false, ""}, + equalsTestCase{int8(kExpected + 1), false, false, ""}, + equalsTestCase{int16(kExpected + 1), false, false, ""}, + equalsTestCase{int32(kExpected + 1), false, false, ""}, + equalsTestCase{int64(kExpected + 1), false, false, ""}, + equalsTestCase{uint(kExpected + 1), false, false, ""}, + equalsTestCase{uint8(kExpected + 1), false, false, ""}, + equalsTestCase{uint16(kExpected + 1), false, false, ""}, + equalsTestCase{uint32(kExpected + 1), false, false, ""}, + equalsTestCase{uint64(kExpected + 1), false, false, ""}, + equalsTestCase{uintptr(kExpected + 1), false, false, ""}, + equalsTestCase{float32(kExpected + 1), false, false, ""}, + equalsTestCase{float64(kExpected + 1), false, false, ""}, + equalsTestCase{complex64(kExpected + 2i), false, false, ""}, + equalsTestCase{complex64(kExpected + 1), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + equalsTestCase{complex128(kExpected + 1), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) LargeUint32() { + const kExpected = (1 << 16) + 17 + matcher := Equals(uint32(kExpected)) + ExpectEq("65553", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of the expected value. + equalsTestCase{65553, true, false, ""}, + equalsTestCase{65553.0, true, false, ""}, + equalsTestCase{65553 + 0i, true, false, ""}, + equalsTestCase{int32(kExpected), true, false, ""}, + equalsTestCase{int64(kExpected), true, false, ""}, + equalsTestCase{uint32(kExpected), true, false, ""}, + equalsTestCase{uint64(kExpected), true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric types. + equalsTestCase{int16(17), false, false, ""}, + equalsTestCase{int32(kExpected + 1), false, false, ""}, + equalsTestCase{int64(kExpected + 1), false, false, ""}, + equalsTestCase{uint16(17), false, false, ""}, + equalsTestCase{uint32(kExpected + 1), false, false, ""}, + equalsTestCase{uint64(kExpected + 1), false, false, ""}, + equalsTestCase{float64(kExpected + 1), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + equalsTestCase{complex128(kExpected + 1), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) Uint32NotExactlyRepresentableBySinglePrecision() { + // Single-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo25 = 1 << 25 + matcher := Equals(uint32(kTwoTo25 + 1)) + ExpectEq("33554433", matcher.Description()) + + cases := []equalsTestCase{ + // Integers. + equalsTestCase{int64(kTwoTo25 + 0), false, false, ""}, + equalsTestCase{int64(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{int64(kTwoTo25 + 2), false, false, ""}, + + equalsTestCase{uint64(kTwoTo25 + 0), false, false, ""}, + equalsTestCase{uint64(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{uint64(kTwoTo25 + 2), false, false, ""}, + + // Single-precision floating point. + equalsTestCase{float32(kTwoTo25 - 2), false, false, ""}, + equalsTestCase{float32(kTwoTo25 - 1), true, false, ""}, + equalsTestCase{float32(kTwoTo25 + 0), true, false, ""}, + equalsTestCase{float32(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{float32(kTwoTo25 + 2), true, false, ""}, + equalsTestCase{float32(kTwoTo25 + 3), false, false, ""}, + + equalsTestCase{complex64(kTwoTo25 - 2), false, false, ""}, + equalsTestCase{complex64(kTwoTo25 - 1), true, false, ""}, + equalsTestCase{complex64(kTwoTo25 + 0), true, false, ""}, + equalsTestCase{complex64(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{complex64(kTwoTo25 + 2), true, false, ""}, + equalsTestCase{complex64(kTwoTo25 + 3), false, false, ""}, + + // Double-precision floating point. + equalsTestCase{float64(kTwoTo25 + 0), false, false, ""}, + equalsTestCase{float64(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{float64(kTwoTo25 + 2), false, false, ""}, + + equalsTestCase{complex128(kTwoTo25 + 0), false, false, ""}, + equalsTestCase{complex128(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{complex128(kTwoTo25 + 2), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// uint64 +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) SmallUint64() { + const kExpected = 17 + matcher := Equals(uint64(kExpected)) + ExpectEq("17", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of the expected value. + equalsTestCase{17, true, false, ""}, + equalsTestCase{17.0, true, false, ""}, + equalsTestCase{17 + 0i, true, false, ""}, + equalsTestCase{int(kExpected), true, false, ""}, + equalsTestCase{int8(kExpected), true, false, ""}, + equalsTestCase{int16(kExpected), true, false, ""}, + equalsTestCase{int32(kExpected), true, false, ""}, + equalsTestCase{int64(kExpected), true, false, ""}, + equalsTestCase{uint(kExpected), true, false, ""}, + equalsTestCase{uint8(kExpected), true, false, ""}, + equalsTestCase{uint16(kExpected), true, false, ""}, + equalsTestCase{uint32(kExpected), true, false, ""}, + equalsTestCase{uint64(kExpected), true, false, ""}, + equalsTestCase{uintptr(kExpected), true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric types. + equalsTestCase{kExpected + 1, false, false, ""}, + equalsTestCase{int(kExpected + 1), false, false, ""}, + equalsTestCase{int8(kExpected + 1), false, false, ""}, + equalsTestCase{int16(kExpected + 1), false, false, ""}, + equalsTestCase{int32(kExpected + 1), false, false, ""}, + equalsTestCase{int64(kExpected + 1), false, false, ""}, + equalsTestCase{uint(kExpected + 1), false, false, ""}, + equalsTestCase{uint8(kExpected + 1), false, false, ""}, + equalsTestCase{uint16(kExpected + 1), false, false, ""}, + equalsTestCase{uint32(kExpected + 1), false, false, ""}, + equalsTestCase{uint64(kExpected + 1), false, false, ""}, + equalsTestCase{uintptr(kExpected + 1), false, false, ""}, + equalsTestCase{float32(kExpected + 1), false, false, ""}, + equalsTestCase{float64(kExpected + 1), false, false, ""}, + equalsTestCase{complex64(kExpected + 2i), false, false, ""}, + equalsTestCase{complex64(kExpected + 1), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + equalsTestCase{complex128(kExpected + 1), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) LargeUint64() { + const kExpected = (1 << 32) + 17 + matcher := Equals(uint64(kExpected)) + ExpectEq("4294967313", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of the expected value. + equalsTestCase{4294967313.0, true, false, ""}, + equalsTestCase{4294967313 + 0i, true, false, ""}, + equalsTestCase{int64(kExpected), true, false, ""}, + equalsTestCase{uint64(kExpected), true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric types. + equalsTestCase{int(17), false, false, ""}, + equalsTestCase{int32(17), false, false, ""}, + equalsTestCase{int64(kExpected + 1), false, false, ""}, + equalsTestCase{uint(17), false, false, ""}, + equalsTestCase{uint32(17), false, false, ""}, + equalsTestCase{uint64(kExpected + 1), false, false, ""}, + equalsTestCase{float64(kExpected + 1), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + equalsTestCase{complex128(kExpected + 1), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) Uint64NotExactlyRepresentableBySinglePrecision() { + // Single-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo25 = 1 << 25 + matcher := Equals(uint64(kTwoTo25 + 1)) + ExpectEq("33554433", matcher.Description()) + + cases := []equalsTestCase{ + // Integers. + equalsTestCase{int64(kTwoTo25 + 0), false, false, ""}, + equalsTestCase{int64(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{int64(kTwoTo25 + 2), false, false, ""}, + + equalsTestCase{uint64(kTwoTo25 + 0), false, false, ""}, + equalsTestCase{uint64(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{uint64(kTwoTo25 + 2), false, false, ""}, + + // Single-precision floating point. + equalsTestCase{float32(kTwoTo25 - 2), false, false, ""}, + equalsTestCase{float32(kTwoTo25 - 1), true, false, ""}, + equalsTestCase{float32(kTwoTo25 + 0), true, false, ""}, + equalsTestCase{float32(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{float32(kTwoTo25 + 2), true, false, ""}, + equalsTestCase{float32(kTwoTo25 + 3), false, false, ""}, + + equalsTestCase{complex64(kTwoTo25 - 2), false, false, ""}, + equalsTestCase{complex64(kTwoTo25 - 1), true, false, ""}, + equalsTestCase{complex64(kTwoTo25 + 0), true, false, ""}, + equalsTestCase{complex64(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{complex64(kTwoTo25 + 2), true, false, ""}, + equalsTestCase{complex64(kTwoTo25 + 3), false, false, ""}, + + // Double-precision floating point. + equalsTestCase{float64(kTwoTo25 + 0), false, false, ""}, + equalsTestCase{float64(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{float64(kTwoTo25 + 2), false, false, ""}, + + equalsTestCase{complex128(kTwoTo25 + 0), false, false, ""}, + equalsTestCase{complex128(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{complex128(kTwoTo25 + 2), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) Uint64NotExactlyRepresentableByDoublePrecision() { + // Double-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^54-1, 2^54+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo54 = 1 << 54 + matcher := Equals(uint64(kTwoTo54 + 1)) + ExpectEq("18014398509481985", matcher.Description()) + + cases := []equalsTestCase{ + // Integers. + equalsTestCase{int64(kTwoTo54 + 0), false, false, ""}, + equalsTestCase{int64(kTwoTo54 + 1), true, false, ""}, + equalsTestCase{int64(kTwoTo54 + 2), false, false, ""}, + + equalsTestCase{uint64(kTwoTo54 + 0), false, false, ""}, + equalsTestCase{uint64(kTwoTo54 + 1), true, false, ""}, + equalsTestCase{uint64(kTwoTo54 + 2), false, false, ""}, + + // Double-precision floating point. + equalsTestCase{float64(kTwoTo54 - 2), false, false, ""}, + equalsTestCase{float64(kTwoTo54 - 1), true, false, ""}, + equalsTestCase{float64(kTwoTo54 + 0), true, false, ""}, + equalsTestCase{float64(kTwoTo54 + 1), true, false, ""}, + equalsTestCase{float64(kTwoTo54 + 2), true, false, ""}, + equalsTestCase{float64(kTwoTo54 + 3), false, false, ""}, + + equalsTestCase{complex128(kTwoTo54 - 2), false, false, ""}, + equalsTestCase{complex128(kTwoTo54 - 1), true, false, ""}, + equalsTestCase{complex128(kTwoTo54 + 0), true, false, ""}, + equalsTestCase{complex128(kTwoTo54 + 1), true, false, ""}, + equalsTestCase{complex128(kTwoTo54 + 2), true, false, ""}, + equalsTestCase{complex128(kTwoTo54 + 3), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// uintptr +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) SmallUintptr() { + const kExpected = 17 + matcher := Equals(uintptr(kExpected)) + ExpectEq("17", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of the expected value. + equalsTestCase{17, true, false, ""}, + equalsTestCase{17.0, true, false, ""}, + equalsTestCase{17 + 0i, true, false, ""}, + equalsTestCase{int(kExpected), true, false, ""}, + equalsTestCase{int8(kExpected), true, false, ""}, + equalsTestCase{int16(kExpected), true, false, ""}, + equalsTestCase{int32(kExpected), true, false, ""}, + equalsTestCase{int64(kExpected), true, false, ""}, + equalsTestCase{uint(kExpected), true, false, ""}, + equalsTestCase{uint8(kExpected), true, false, ""}, + equalsTestCase{uint16(kExpected), true, false, ""}, + equalsTestCase{uint32(kExpected), true, false, ""}, + equalsTestCase{uint64(kExpected), true, false, ""}, + equalsTestCase{uintptr(kExpected), true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric types. + equalsTestCase{kExpected + 1, false, false, ""}, + equalsTestCase{int(kExpected + 1), false, false, ""}, + equalsTestCase{int8(kExpected + 1), false, false, ""}, + equalsTestCase{int16(kExpected + 1), false, false, ""}, + equalsTestCase{int32(kExpected + 1), false, false, ""}, + equalsTestCase{int64(kExpected + 1), false, false, ""}, + equalsTestCase{uint(kExpected + 1), false, false, ""}, + equalsTestCase{uint8(kExpected + 1), false, false, ""}, + equalsTestCase{uint16(kExpected + 1), false, false, ""}, + equalsTestCase{uint32(kExpected + 1), false, false, ""}, + equalsTestCase{uint64(kExpected + 1), false, false, ""}, + equalsTestCase{uintptr(kExpected + 1), false, false, ""}, + equalsTestCase{float32(kExpected + 1), false, false, ""}, + equalsTestCase{float64(kExpected + 1), false, false, ""}, + equalsTestCase{complex64(kExpected + 2i), false, false, ""}, + equalsTestCase{complex64(kExpected + 1), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + equalsTestCase{complex128(kExpected + 1), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) LargeUintptr() { + const kExpected = (1 << 32) + 17 + matcher := Equals(uintptr(kExpected)) + ExpectEq("4294967313", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of the expected value. + equalsTestCase{4294967313.0, true, false, ""}, + equalsTestCase{4294967313 + 0i, true, false, ""}, + equalsTestCase{int64(kExpected), true, false, ""}, + equalsTestCase{uint64(kExpected), true, false, ""}, + equalsTestCase{uintptr(kExpected), true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric types. + equalsTestCase{int(17), false, false, ""}, + equalsTestCase{int32(17), false, false, ""}, + equalsTestCase{int64(kExpected + 1), false, false, ""}, + equalsTestCase{uint(17), false, false, ""}, + equalsTestCase{uint32(17), false, false, ""}, + equalsTestCase{uint64(kExpected + 1), false, false, ""}, + equalsTestCase{uintptr(kExpected + 1), false, false, ""}, + equalsTestCase{float64(kExpected + 1), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + equalsTestCase{complex128(kExpected + 1), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// float32 +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) NegativeIntegralFloat32() { + matcher := Equals(float32(-32769)) + ExpectEq("-32769", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of -32769. + equalsTestCase{-32769.0, true, false, ""}, + equalsTestCase{-32769 + 0i, true, false, ""}, + equalsTestCase{int32(-32769), true, false, ""}, + equalsTestCase{int64(-32769), true, false, ""}, + equalsTestCase{float32(-32769), true, false, ""}, + equalsTestCase{float64(-32769), true, false, ""}, + equalsTestCase{complex64(-32769), true, false, ""}, + equalsTestCase{complex128(-32769), true, false, ""}, + equalsTestCase{interface{}(float32(-32769)), true, false, ""}, + equalsTestCase{interface{}(int64(-32769)), true, false, ""}, + + // Values that would be -32769 in two's complement. + equalsTestCase{uint64((1 << 64) - 32769), false, false, ""}, + equalsTestCase{uintptr((1 << 64) - 32769), false, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int64(-32770), false, false, ""}, + equalsTestCase{float32(-32769.1), false, false, ""}, + equalsTestCase{float32(-32768.9), false, false, ""}, + equalsTestCase{float64(-32769.1), false, false, ""}, + equalsTestCase{float64(-32768.9), false, false, ""}, + equalsTestCase{complex128(-32768), false, false, ""}, + equalsTestCase{complex128(-32769 + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) NegativeNonIntegralFloat32() { + matcher := Equals(float32(-32769.1)) + ExpectEq("-32769.1", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of -32769.1. + equalsTestCase{-32769.1, true, false, ""}, + equalsTestCase{-32769.1 + 0i, true, false, ""}, + equalsTestCase{float32(-32769.1), true, false, ""}, + equalsTestCase{float64(-32769.1), true, false, ""}, + equalsTestCase{complex64(-32769.1), true, false, ""}, + equalsTestCase{complex128(-32769.1), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int32(-32769), false, false, ""}, + equalsTestCase{int32(-32770), false, false, ""}, + equalsTestCase{int64(-32769), false, false, ""}, + equalsTestCase{int64(-32770), false, false, ""}, + equalsTestCase{float32(-32769.2), false, false, ""}, + equalsTestCase{float32(-32769.0), false, false, ""}, + equalsTestCase{float64(-32769.2), false, false, ""}, + equalsTestCase{complex128(-32769.1 + 2i), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) LargeNegativeFloat32() { + const kExpected = -1 * (1 << 65) + matcher := Equals(float32(kExpected)) + ExpectEq("-3.689349e+19", matcher.Description()) + + floatExpected := float32(kExpected) + castedInt := int64(floatExpected) + + cases := []equalsTestCase{ + // Equal values of numeric type. + equalsTestCase{kExpected + 0i, true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{castedInt, false, false, ""}, + equalsTestCase{int64(0), false, false, ""}, + equalsTestCase{int64(math.MinInt64), false, false, ""}, + equalsTestCase{int64(math.MaxInt64), false, false, ""}, + equalsTestCase{float32(kExpected / 2), false, false, ""}, + equalsTestCase{float64(kExpected / 2), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) ZeroFloat32() { + matcher := Equals(float32(0)) + ExpectEq("0", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of zero. + equalsTestCase{0.0, true, false, ""}, + equalsTestCase{0 + 0i, true, false, ""}, + equalsTestCase{int(0), true, false, ""}, + equalsTestCase{int8(0), true, false, ""}, + equalsTestCase{int16(0), true, false, ""}, + equalsTestCase{int32(0), true, false, ""}, + equalsTestCase{int64(0), true, false, ""}, + equalsTestCase{uint(0), true, false, ""}, + equalsTestCase{uint8(0), true, false, ""}, + equalsTestCase{uint16(0), true, false, ""}, + equalsTestCase{uint32(0), true, false, ""}, + equalsTestCase{uint64(0), true, false, ""}, + equalsTestCase{uintptr(0), true, false, ""}, + equalsTestCase{float32(0), true, false, ""}, + equalsTestCase{float64(0), true, false, ""}, + equalsTestCase{complex64(0), true, false, ""}, + equalsTestCase{complex128(0), true, false, ""}, + equalsTestCase{interface{}(float32(0)), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int64(1), false, false, ""}, + equalsTestCase{int64(-1), false, false, ""}, + equalsTestCase{float32(1), false, false, ""}, + equalsTestCase{float32(-1), false, false, ""}, + equalsTestCase{complex128(0 + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) PositiveIntegralFloat32() { + matcher := Equals(float32(32769)) + ExpectEq("32769", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of 32769. + equalsTestCase{32769.0, true, false, ""}, + equalsTestCase{32769 + 0i, true, false, ""}, + equalsTestCase{int(32769), true, false, ""}, + equalsTestCase{int32(32769), true, false, ""}, + equalsTestCase{int64(32769), true, false, ""}, + equalsTestCase{uint(32769), true, false, ""}, + equalsTestCase{uint32(32769), true, false, ""}, + equalsTestCase{uint64(32769), true, false, ""}, + equalsTestCase{uintptr(32769), true, false, ""}, + equalsTestCase{float32(32769), true, false, ""}, + equalsTestCase{float64(32769), true, false, ""}, + equalsTestCase{complex64(32769), true, false, ""}, + equalsTestCase{complex128(32769), true, false, ""}, + equalsTestCase{interface{}(float32(32769)), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int64(32770), false, false, ""}, + equalsTestCase{uint64(32770), false, false, ""}, + equalsTestCase{float32(32769.1), false, false, ""}, + equalsTestCase{float32(32768.9), false, false, ""}, + equalsTestCase{float64(32769.1), false, false, ""}, + equalsTestCase{float64(32768.9), false, false, ""}, + equalsTestCase{complex128(32768), false, false, ""}, + equalsTestCase{complex128(32769 + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) PositiveNonIntegralFloat32() { + matcher := Equals(float32(32769.1)) + ExpectEq("32769.1", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of 32769.1. + equalsTestCase{32769.1, true, false, ""}, + equalsTestCase{32769.1 + 0i, true, false, ""}, + equalsTestCase{float32(32769.1), true, false, ""}, + equalsTestCase{float64(32769.1), true, false, ""}, + equalsTestCase{complex64(32769.1), true, false, ""}, + equalsTestCase{complex128(32769.1), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int32(32769), false, false, ""}, + equalsTestCase{int32(32770), false, false, ""}, + equalsTestCase{uint64(32769), false, false, ""}, + equalsTestCase{uint64(32770), false, false, ""}, + equalsTestCase{float32(32769.2), false, false, ""}, + equalsTestCase{float32(32769.0), false, false, ""}, + equalsTestCase{float64(32769.2), false, false, ""}, + equalsTestCase{complex128(32769.1 + 2i), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) LargePositiveFloat32() { + const kExpected = 1 << 65 + matcher := Equals(float32(kExpected)) + ExpectEq("3.689349e+19", matcher.Description()) + + floatExpected := float32(kExpected) + castedInt := uint64(floatExpected) + + cases := []equalsTestCase{ + // Equal values of numeric type. + equalsTestCase{kExpected + 0i, true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{castedInt, false, false, ""}, + equalsTestCase{int64(0), false, false, ""}, + equalsTestCase{int64(math.MinInt64), false, false, ""}, + equalsTestCase{int64(math.MaxInt64), false, false, ""}, + equalsTestCase{uint64(0), false, false, ""}, + equalsTestCase{uint64(math.MaxUint64), false, false, ""}, + equalsTestCase{float32(kExpected / 2), false, false, ""}, + equalsTestCase{float64(kExpected / 2), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) Float32AboveExactIntegerRange() { + // Single-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo25 = 1 << 25 + matcher := Equals(float32(kTwoTo25 + 1)) + ExpectEq("3.3554432e+07", matcher.Description()) + + cases := []equalsTestCase{ + // Integers. + equalsTestCase{int64(kTwoTo25 - 2), false, false, ""}, + equalsTestCase{int64(kTwoTo25 - 1), true, false, ""}, + equalsTestCase{int64(kTwoTo25 + 0), true, false, ""}, + equalsTestCase{int64(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{int64(kTwoTo25 + 2), true, false, ""}, + equalsTestCase{int64(kTwoTo25 + 3), false, false, ""}, + + equalsTestCase{uint64(kTwoTo25 - 2), false, false, ""}, + equalsTestCase{uint64(kTwoTo25 - 1), true, false, ""}, + equalsTestCase{uint64(kTwoTo25 + 0), true, false, ""}, + equalsTestCase{uint64(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{uint64(kTwoTo25 + 2), true, false, ""}, + equalsTestCase{uint64(kTwoTo25 + 3), false, false, ""}, + + // Single-precision floating point. + equalsTestCase{float32(kTwoTo25 - 2), false, false, ""}, + equalsTestCase{float32(kTwoTo25 - 1), true, false, ""}, + equalsTestCase{float32(kTwoTo25 + 0), true, false, ""}, + equalsTestCase{float32(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{float32(kTwoTo25 + 2), true, false, ""}, + equalsTestCase{float32(kTwoTo25 + 3), false, false, ""}, + + equalsTestCase{complex64(kTwoTo25 - 2), false, false, ""}, + equalsTestCase{complex64(kTwoTo25 - 1), true, false, ""}, + equalsTestCase{complex64(kTwoTo25 + 0), true, false, ""}, + equalsTestCase{complex64(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{complex64(kTwoTo25 + 2), true, false, ""}, + equalsTestCase{complex64(kTwoTo25 + 3), false, false, ""}, + + // Double-precision floating point. + equalsTestCase{float64(kTwoTo25 - 2), false, false, ""}, + equalsTestCase{float64(kTwoTo25 - 1), true, false, ""}, + equalsTestCase{float64(kTwoTo25 + 0), true, false, ""}, + equalsTestCase{float64(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{float64(kTwoTo25 + 2), true, false, ""}, + equalsTestCase{float64(kTwoTo25 + 3), false, false, ""}, + + equalsTestCase{complex128(kTwoTo25 - 2), false, false, ""}, + equalsTestCase{complex128(kTwoTo25 - 1), true, false, ""}, + equalsTestCase{complex128(kTwoTo25 + 0), true, false, ""}, + equalsTestCase{complex128(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{complex128(kTwoTo25 + 2), true, false, ""}, + equalsTestCase{complex128(kTwoTo25 + 3), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// float64 +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) NegativeIntegralFloat64() { + const kExpected = -(1 << 50) + matcher := Equals(float64(kExpected)) + ExpectEq("-1.125899906842624e+15", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of the expected value. + equalsTestCase{-1125899906842624.0, true, false, ""}, + equalsTestCase{-1125899906842624.0 + 0i, true, false, ""}, + equalsTestCase{int64(kExpected), true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + equalsTestCase{interface{}(float64(kExpected)), true, false, ""}, + + // Values that would be kExpected in two's complement. + equalsTestCase{uint64((1 << 64) + kExpected), false, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int64(kExpected + 1), false, false, ""}, + equalsTestCase{float32(kExpected - (1 << 30)), false, false, ""}, + equalsTestCase{float32(kExpected + (1 << 30)), false, false, ""}, + equalsTestCase{float64(kExpected - 0.5), false, false, ""}, + equalsTestCase{float64(kExpected + 0.5), false, false, ""}, + equalsTestCase{complex128(kExpected - 1), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) NegativeNonIntegralFloat64() { + const kTwoTo50 = 1 << 50 + const kExpected = -kTwoTo50 - 0.25 + + matcher := Equals(float64(kExpected)) + ExpectEq("-1.1258999068426242e+15", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of the expected value. + equalsTestCase{kExpected, true, false, ""}, + equalsTestCase{kExpected + 0i, true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int64(-kTwoTo50), false, false, ""}, + equalsTestCase{int64(-kTwoTo50 - 1), false, false, ""}, + equalsTestCase{float32(kExpected - (1 << 30)), false, false, ""}, + equalsTestCase{float64(kExpected - 0.25), false, false, ""}, + equalsTestCase{float64(kExpected + 0.25), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) LargeNegativeFloat64() { + const kExpected = -1 * (1 << 65) + matcher := Equals(float64(kExpected)) + ExpectEq("-3.6893488147419103e+19", matcher.Description()) + + floatExpected := float64(kExpected) + castedInt := int64(floatExpected) + + cases := []equalsTestCase{ + // Equal values of numeric type. + equalsTestCase{kExpected + 0i, true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{castedInt, false, false, ""}, + equalsTestCase{int64(0), false, false, ""}, + equalsTestCase{int64(math.MinInt64), false, false, ""}, + equalsTestCase{int64(math.MaxInt64), false, false, ""}, + equalsTestCase{float32(kExpected / 2), false, false, ""}, + equalsTestCase{float64(kExpected / 2), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) ZeroFloat64() { + matcher := Equals(float64(0)) + ExpectEq("0", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of zero. + equalsTestCase{0.0, true, false, ""}, + equalsTestCase{0 + 0i, true, false, ""}, + equalsTestCase{int(0), true, false, ""}, + equalsTestCase{int8(0), true, false, ""}, + equalsTestCase{int16(0), true, false, ""}, + equalsTestCase{int32(0), true, false, ""}, + equalsTestCase{int64(0), true, false, ""}, + equalsTestCase{uint(0), true, false, ""}, + equalsTestCase{uint8(0), true, false, ""}, + equalsTestCase{uint16(0), true, false, ""}, + equalsTestCase{uint32(0), true, false, ""}, + equalsTestCase{uint64(0), true, false, ""}, + equalsTestCase{uintptr(0), true, false, ""}, + equalsTestCase{float32(0), true, false, ""}, + equalsTestCase{float64(0), true, false, ""}, + equalsTestCase{complex64(0), true, false, ""}, + equalsTestCase{complex128(0), true, false, ""}, + equalsTestCase{interface{}(float32(0)), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int64(1), false, false, ""}, + equalsTestCase{int64(-1), false, false, ""}, + equalsTestCase{float32(1), false, false, ""}, + equalsTestCase{float32(-1), false, false, ""}, + equalsTestCase{complex128(0 + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) PositiveIntegralFloat64() { + const kExpected = 1 << 50 + matcher := Equals(float64(kExpected)) + ExpectEq("1.125899906842624e+15", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of 32769. + equalsTestCase{1125899906842624.0, true, false, ""}, + equalsTestCase{1125899906842624.0 + 0i, true, false, ""}, + equalsTestCase{int64(kExpected), true, false, ""}, + equalsTestCase{uint64(kExpected), true, false, ""}, + equalsTestCase{uintptr(kExpected), true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + equalsTestCase{interface{}(float64(kExpected)), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int64(kExpected + 1), false, false, ""}, + equalsTestCase{uint64(kExpected + 1), false, false, ""}, + equalsTestCase{uintptr(kExpected + 1), false, false, ""}, + equalsTestCase{float32(kExpected - (1 << 30)), false, false, ""}, + equalsTestCase{float32(kExpected + (1 << 30)), false, false, ""}, + equalsTestCase{float64(kExpected - 0.5), false, false, ""}, + equalsTestCase{float64(kExpected + 0.5), false, false, ""}, + equalsTestCase{complex128(kExpected - 1), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) PositiveNonIntegralFloat64() { + const kTwoTo50 = 1 << 50 + const kExpected = kTwoTo50 + 0.25 + matcher := Equals(float64(kExpected)) + ExpectEq("1.1258999068426242e+15", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of the expected value. + equalsTestCase{kExpected, true, false, ""}, + equalsTestCase{kExpected + 0i, true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int64(kTwoTo50), false, false, ""}, + equalsTestCase{int64(kTwoTo50 - 1), false, false, ""}, + equalsTestCase{float64(kExpected - 0.25), false, false, ""}, + equalsTestCase{float64(kExpected + 0.25), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) LargePositiveFloat64() { + const kExpected = 1 << 65 + matcher := Equals(float64(kExpected)) + ExpectEq("3.6893488147419103e+19", matcher.Description()) + + floatExpected := float64(kExpected) + castedInt := uint64(floatExpected) + + cases := []equalsTestCase{ + // Equal values of numeric type. + equalsTestCase{kExpected + 0i, true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{castedInt, false, false, ""}, + equalsTestCase{int64(0), false, false, ""}, + equalsTestCase{int64(math.MinInt64), false, false, ""}, + equalsTestCase{int64(math.MaxInt64), false, false, ""}, + equalsTestCase{uint64(0), false, false, ""}, + equalsTestCase{uint64(math.MaxUint64), false, false, ""}, + equalsTestCase{float32(kExpected / 2), false, false, ""}, + equalsTestCase{float64(kExpected / 2), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) Float64AboveExactIntegerRange() { + // Double-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^54-1, 2^54+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo54 = 1 << 54 + matcher := Equals(float64(kTwoTo54 + 1)) + ExpectEq("1.8014398509481984e+16", matcher.Description()) + + cases := []equalsTestCase{ + // Integers. + equalsTestCase{int64(kTwoTo54 - 2), false, false, ""}, + equalsTestCase{int64(kTwoTo54 - 1), true, false, ""}, + equalsTestCase{int64(kTwoTo54 + 0), true, false, ""}, + equalsTestCase{int64(kTwoTo54 + 1), true, false, ""}, + equalsTestCase{int64(kTwoTo54 + 2), true, false, ""}, + equalsTestCase{int64(kTwoTo54 + 3), false, false, ""}, + + equalsTestCase{uint64(kTwoTo54 - 2), false, false, ""}, + equalsTestCase{uint64(kTwoTo54 - 1), true, false, ""}, + equalsTestCase{uint64(kTwoTo54 + 0), true, false, ""}, + equalsTestCase{uint64(kTwoTo54 + 1), true, false, ""}, + equalsTestCase{uint64(kTwoTo54 + 2), true, false, ""}, + equalsTestCase{uint64(kTwoTo54 + 3), false, false, ""}, + + // Double-precision floating point. + equalsTestCase{float64(kTwoTo54 - 2), false, false, ""}, + equalsTestCase{float64(kTwoTo54 - 1), true, false, ""}, + equalsTestCase{float64(kTwoTo54 + 0), true, false, ""}, + equalsTestCase{float64(kTwoTo54 + 1), true, false, ""}, + equalsTestCase{float64(kTwoTo54 + 2), true, false, ""}, + equalsTestCase{float64(kTwoTo54 + 3), false, false, ""}, + + equalsTestCase{complex128(kTwoTo54 - 2), false, false, ""}, + equalsTestCase{complex128(kTwoTo54 - 1), true, false, ""}, + equalsTestCase{complex128(kTwoTo54 + 0), true, false, ""}, + equalsTestCase{complex128(kTwoTo54 + 1), true, false, ""}, + equalsTestCase{complex128(kTwoTo54 + 2), true, false, ""}, + equalsTestCase{complex128(kTwoTo54 + 3), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// complex64 +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) NegativeIntegralComplex64() { + const kExpected = -32769 + matcher := Equals(complex64(kExpected)) + ExpectEq("(-32769+0i)", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of the expected value. + equalsTestCase{-32769.0, true, false, ""}, + equalsTestCase{-32769.0 + 0i, true, false, ""}, + equalsTestCase{int(kExpected), true, false, ""}, + equalsTestCase{int32(kExpected), true, false, ""}, + equalsTestCase{int64(kExpected), true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + equalsTestCase{interface{}(float64(kExpected)), true, false, ""}, + + // Values that would be kExpected in two's complement. + equalsTestCase{uint32((1 << 32) + kExpected), false, false, ""}, + equalsTestCase{uint64((1 << 64) + kExpected), false, false, ""}, + equalsTestCase{uintptr((1 << 64) + kExpected), false, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int64(kExpected + 1), false, false, ""}, + equalsTestCase{float32(kExpected - (1 << 30)), false, false, ""}, + equalsTestCase{float32(kExpected + (1 << 30)), false, false, ""}, + equalsTestCase{float64(kExpected - 0.5), false, false, ""}, + equalsTestCase{float64(kExpected + 0.5), false, false, ""}, + equalsTestCase{complex64(kExpected - 1), false, false, ""}, + equalsTestCase{complex64(kExpected + 2i), false, false, ""}, + equalsTestCase{complex128(kExpected - 1), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) NegativeNonIntegralComplex64() { + const kTwoTo20 = 1 << 20 + const kExpected = -kTwoTo20 - 0.25 + + matcher := Equals(complex64(kExpected)) + ExpectEq("(-1.0485762e+06+0i)", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of the expected value. + equalsTestCase{kExpected, true, false, ""}, + equalsTestCase{kExpected + 0i, true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int(-kTwoTo20), false, false, ""}, + equalsTestCase{int(-kTwoTo20 - 1), false, false, ""}, + equalsTestCase{int32(-kTwoTo20), false, false, ""}, + equalsTestCase{int32(-kTwoTo20 - 1), false, false, ""}, + equalsTestCase{int64(-kTwoTo20), false, false, ""}, + equalsTestCase{int64(-kTwoTo20 - 1), false, false, ""}, + equalsTestCase{float32(kExpected - (1 << 30)), false, false, ""}, + equalsTestCase{float64(kExpected - 0.25), false, false, ""}, + equalsTestCase{float64(kExpected + 0.25), false, false, ""}, + equalsTestCase{complex64(kExpected - 0.75), false, false, ""}, + equalsTestCase{complex64(kExpected + 2i), false, false, ""}, + equalsTestCase{complex128(kExpected - 0.75), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) LargeNegativeComplex64() { + const kExpected = -1 * (1 << 65) + matcher := Equals(complex64(kExpected)) + ExpectEq("(-3.689349e+19+0i)", matcher.Description()) + + floatExpected := float64(kExpected) + castedInt := int64(floatExpected) + + cases := []equalsTestCase{ + // Equal values of numeric type. + equalsTestCase{kExpected + 0i, true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{castedInt, false, false, ""}, + equalsTestCase{int64(0), false, false, ""}, + equalsTestCase{int64(math.MinInt64), false, false, ""}, + equalsTestCase{int64(math.MaxInt64), false, false, ""}, + equalsTestCase{float32(kExpected / 2), false, false, ""}, + equalsTestCase{float64(kExpected / 2), false, false, ""}, + equalsTestCase{complex64(kExpected + 2i), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) ZeroComplex64() { + matcher := Equals(complex64(0)) + ExpectEq("(0+0i)", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of zero. + equalsTestCase{0.0, true, false, ""}, + equalsTestCase{0 + 0i, true, false, ""}, + equalsTestCase{int(0), true, false, ""}, + equalsTestCase{int8(0), true, false, ""}, + equalsTestCase{int16(0), true, false, ""}, + equalsTestCase{int32(0), true, false, ""}, + equalsTestCase{int64(0), true, false, ""}, + equalsTestCase{uint(0), true, false, ""}, + equalsTestCase{uint8(0), true, false, ""}, + equalsTestCase{uint16(0), true, false, ""}, + equalsTestCase{uint32(0), true, false, ""}, + equalsTestCase{uint64(0), true, false, ""}, + equalsTestCase{uintptr(0), true, false, ""}, + equalsTestCase{float32(0), true, false, ""}, + equalsTestCase{float64(0), true, false, ""}, + equalsTestCase{complex64(0), true, false, ""}, + equalsTestCase{complex128(0), true, false, ""}, + equalsTestCase{interface{}(float32(0)), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int64(1), false, false, ""}, + equalsTestCase{int64(-1), false, false, ""}, + equalsTestCase{float32(1), false, false, ""}, + equalsTestCase{float32(-1), false, false, ""}, + equalsTestCase{float64(1), false, false, ""}, + equalsTestCase{float64(-1), false, false, ""}, + equalsTestCase{complex64(0 + 2i), false, false, ""}, + equalsTestCase{complex128(0 + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) PositiveIntegralComplex64() { + const kExpected = 1 << 20 + matcher := Equals(complex64(kExpected)) + ExpectEq("(1.048576e+06+0i)", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of 32769. + equalsTestCase{1048576.0, true, false, ""}, + equalsTestCase{1048576.0 + 0i, true, false, ""}, + equalsTestCase{int(kExpected), true, false, ""}, + equalsTestCase{int32(kExpected), true, false, ""}, + equalsTestCase{int64(kExpected), true, false, ""}, + equalsTestCase{uint(kExpected), true, false, ""}, + equalsTestCase{uint32(kExpected), true, false, ""}, + equalsTestCase{uint64(kExpected), true, false, ""}, + equalsTestCase{uintptr(kExpected), true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + equalsTestCase{interface{}(float64(kExpected)), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int(kExpected + 1), false, false, ""}, + equalsTestCase{int32(kExpected + 1), false, false, ""}, + equalsTestCase{int64(kExpected + 1), false, false, ""}, + equalsTestCase{uint(kExpected + 1), false, false, ""}, + equalsTestCase{uint32(kExpected + 1), false, false, ""}, + equalsTestCase{uint64(kExpected + 1), false, false, ""}, + equalsTestCase{uintptr(kExpected + 1), false, false, ""}, + equalsTestCase{float32(kExpected - (1 << 30)), false, false, ""}, + equalsTestCase{float32(kExpected + (1 << 30)), false, false, ""}, + equalsTestCase{float64(kExpected - 0.5), false, false, ""}, + equalsTestCase{float64(kExpected + 0.5), false, false, ""}, + equalsTestCase{complex128(kExpected - 1), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) PositiveNonIntegralComplex64() { + const kTwoTo20 = 1 << 20 + const kExpected = kTwoTo20 + 0.25 + matcher := Equals(complex64(kExpected)) + ExpectEq("(1.0485762e+06+0i)", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of the expected value. + equalsTestCase{kExpected, true, false, ""}, + equalsTestCase{kExpected + 0i, true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int64(kTwoTo20), false, false, ""}, + equalsTestCase{int64(kTwoTo20 - 1), false, false, ""}, + equalsTestCase{uint64(kTwoTo20), false, false, ""}, + equalsTestCase{uint64(kTwoTo20 - 1), false, false, ""}, + equalsTestCase{float32(kExpected - 1), false, false, ""}, + equalsTestCase{float32(kExpected + 1), false, false, ""}, + equalsTestCase{float64(kExpected - 0.25), false, false, ""}, + equalsTestCase{float64(kExpected + 0.25), false, false, ""}, + equalsTestCase{complex64(kExpected - 1), false, false, ""}, + equalsTestCase{complex64(kExpected - 1i), false, false, ""}, + equalsTestCase{complex128(kExpected - 1), false, false, ""}, + equalsTestCase{complex128(kExpected - 1i), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) LargePositiveComplex64() { + const kExpected = 1 << 65 + matcher := Equals(complex64(kExpected)) + ExpectEq("(3.689349e+19+0i)", matcher.Description()) + + floatExpected := float64(kExpected) + castedInt := uint64(floatExpected) + + cases := []equalsTestCase{ + // Equal values of numeric type. + equalsTestCase{kExpected + 0i, true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{castedInt, false, false, ""}, + equalsTestCase{int64(0), false, false, ""}, + equalsTestCase{int64(math.MinInt64), false, false, ""}, + equalsTestCase{int64(math.MaxInt64), false, false, ""}, + equalsTestCase{uint64(0), false, false, ""}, + equalsTestCase{uint64(math.MaxUint64), false, false, ""}, + equalsTestCase{float32(kExpected / 2), false, false, ""}, + equalsTestCase{float64(kExpected / 2), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) Complex64AboveExactIntegerRange() { + // Single-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo25 = 1 << 25 + matcher := Equals(complex64(kTwoTo25 + 1)) + ExpectEq("(3.3554432e+07+0i)", matcher.Description()) + + cases := []equalsTestCase{ + // Integers. + equalsTestCase{int64(kTwoTo25 - 2), false, false, ""}, + equalsTestCase{int64(kTwoTo25 - 1), true, false, ""}, + equalsTestCase{int64(kTwoTo25 + 0), true, false, ""}, + equalsTestCase{int64(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{int64(kTwoTo25 + 2), true, false, ""}, + equalsTestCase{int64(kTwoTo25 + 3), false, false, ""}, + + equalsTestCase{uint64(kTwoTo25 - 2), false, false, ""}, + equalsTestCase{uint64(kTwoTo25 - 1), true, false, ""}, + equalsTestCase{uint64(kTwoTo25 + 0), true, false, ""}, + equalsTestCase{uint64(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{uint64(kTwoTo25 + 2), true, false, ""}, + equalsTestCase{uint64(kTwoTo25 + 3), false, false, ""}, + + // Single-precision floating point. + equalsTestCase{float32(kTwoTo25 - 2), false, false, ""}, + equalsTestCase{float32(kTwoTo25 - 1), true, false, ""}, + equalsTestCase{float32(kTwoTo25 + 0), true, false, ""}, + equalsTestCase{float32(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{float32(kTwoTo25 + 2), true, false, ""}, + equalsTestCase{float32(kTwoTo25 + 3), false, false, ""}, + + equalsTestCase{complex64(kTwoTo25 - 2), false, false, ""}, + equalsTestCase{complex64(kTwoTo25 - 1), true, false, ""}, + equalsTestCase{complex64(kTwoTo25 + 0), true, false, ""}, + equalsTestCase{complex64(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{complex64(kTwoTo25 + 2), true, false, ""}, + equalsTestCase{complex64(kTwoTo25 + 3), false, false, ""}, + + // Double-precision floating point. + equalsTestCase{float64(kTwoTo25 - 2), false, false, ""}, + equalsTestCase{float64(kTwoTo25 - 1), true, false, ""}, + equalsTestCase{float64(kTwoTo25 + 0), true, false, ""}, + equalsTestCase{float64(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{float64(kTwoTo25 + 2), true, false, ""}, + equalsTestCase{float64(kTwoTo25 + 3), false, false, ""}, + + equalsTestCase{complex128(kTwoTo25 - 2), false, false, ""}, + equalsTestCase{complex128(kTwoTo25 - 1), true, false, ""}, + equalsTestCase{complex128(kTwoTo25 + 0), true, false, ""}, + equalsTestCase{complex128(kTwoTo25 + 1), true, false, ""}, + equalsTestCase{complex128(kTwoTo25 + 2), true, false, ""}, + equalsTestCase{complex128(kTwoTo25 + 3), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) Complex64WithNonZeroImaginaryPart() { + const kRealPart = 17 + const kImagPart = 0.25i + const kExpected = kRealPart + kImagPart + matcher := Equals(complex64(kExpected)) + ExpectEq("(17+0.25i)", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of the expected value. + equalsTestCase{kExpected, true, false, ""}, + equalsTestCase{kRealPart + kImagPart, true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int(kRealPart), false, false, ""}, + equalsTestCase{int8(kRealPart), false, false, ""}, + equalsTestCase{int16(kRealPart), false, false, ""}, + equalsTestCase{int32(kRealPart), false, false, ""}, + equalsTestCase{int64(kRealPart), false, false, ""}, + equalsTestCase{uint(kRealPart), false, false, ""}, + equalsTestCase{uint8(kRealPart), false, false, ""}, + equalsTestCase{uint16(kRealPart), false, false, ""}, + equalsTestCase{uint32(kRealPart), false, false, ""}, + equalsTestCase{uint64(kRealPart), false, false, ""}, + equalsTestCase{float32(kRealPart), false, false, ""}, + equalsTestCase{float64(kRealPart), false, false, ""}, + equalsTestCase{complex64(kRealPart), false, false, ""}, + equalsTestCase{complex64(kRealPart + kImagPart + 0.5), false, false, ""}, + equalsTestCase{complex64(kRealPart + kImagPart + 0.5i), false, false, ""}, + equalsTestCase{complex128(kRealPart), false, false, ""}, + equalsTestCase{complex128(kRealPart + kImagPart + 0.5), false, false, ""}, + equalsTestCase{complex128(kRealPart + kImagPart + 0.5i), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// complex128 +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) NegativeIntegralComplex128() { + const kExpected = -32769 + matcher := Equals(complex128(kExpected)) + ExpectEq("(-32769+0i)", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of the expected value. + equalsTestCase{-32769.0, true, false, ""}, + equalsTestCase{-32769.0 + 0i, true, false, ""}, + equalsTestCase{int(kExpected), true, false, ""}, + equalsTestCase{int32(kExpected), true, false, ""}, + equalsTestCase{int64(kExpected), true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + equalsTestCase{interface{}(float64(kExpected)), true, false, ""}, + + // Values that would be kExpected in two's complement. + equalsTestCase{uint32((1 << 32) + kExpected), false, false, ""}, + equalsTestCase{uint64((1 << 64) + kExpected), false, false, ""}, + equalsTestCase{uintptr((1 << 64) + kExpected), false, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int64(kExpected + 1), false, false, ""}, + equalsTestCase{float32(kExpected - (1 << 30)), false, false, ""}, + equalsTestCase{float32(kExpected + (1 << 30)), false, false, ""}, + equalsTestCase{float64(kExpected - 0.5), false, false, ""}, + equalsTestCase{float64(kExpected + 0.5), false, false, ""}, + equalsTestCase{complex64(kExpected - 1), false, false, ""}, + equalsTestCase{complex64(kExpected + 2i), false, false, ""}, + equalsTestCase{complex128(kExpected - 1), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) NegativeNonIntegralComplex128() { + const kTwoTo20 = 1 << 20 + const kExpected = -kTwoTo20 - 0.25 + + matcher := Equals(complex128(kExpected)) + ExpectEq("(-1.04857625e+06+0i)", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of the expected value. + equalsTestCase{kExpected, true, false, ""}, + equalsTestCase{kExpected + 0i, true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int(-kTwoTo20), false, false, ""}, + equalsTestCase{int(-kTwoTo20 - 1), false, false, ""}, + equalsTestCase{int32(-kTwoTo20), false, false, ""}, + equalsTestCase{int32(-kTwoTo20 - 1), false, false, ""}, + equalsTestCase{int64(-kTwoTo20), false, false, ""}, + equalsTestCase{int64(-kTwoTo20 - 1), false, false, ""}, + equalsTestCase{float32(kExpected - (1 << 30)), false, false, ""}, + equalsTestCase{float64(kExpected - 0.25), false, false, ""}, + equalsTestCase{float64(kExpected + 0.25), false, false, ""}, + equalsTestCase{complex64(kExpected - 0.75), false, false, ""}, + equalsTestCase{complex64(kExpected + 2i), false, false, ""}, + equalsTestCase{complex128(kExpected - 0.75), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) LargeNegativeComplex128() { + const kExpected = -1 * (1 << 65) + matcher := Equals(complex128(kExpected)) + ExpectEq("(-3.6893488147419103e+19+0i)", matcher.Description()) + + floatExpected := float64(kExpected) + castedInt := int64(floatExpected) + + cases := []equalsTestCase{ + // Equal values of numeric type. + equalsTestCase{kExpected + 0i, true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{castedInt, false, false, ""}, + equalsTestCase{int64(0), false, false, ""}, + equalsTestCase{int64(math.MinInt64), false, false, ""}, + equalsTestCase{int64(math.MaxInt64), false, false, ""}, + equalsTestCase{float32(kExpected / 2), false, false, ""}, + equalsTestCase{float64(kExpected / 2), false, false, ""}, + equalsTestCase{complex64(kExpected + 2i), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) ZeroComplex128() { + matcher := Equals(complex128(0)) + ExpectEq("(0+0i)", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of zero. + equalsTestCase{0.0, true, false, ""}, + equalsTestCase{0 + 0i, true, false, ""}, + equalsTestCase{int(0), true, false, ""}, + equalsTestCase{int8(0), true, false, ""}, + equalsTestCase{int16(0), true, false, ""}, + equalsTestCase{int32(0), true, false, ""}, + equalsTestCase{int64(0), true, false, ""}, + equalsTestCase{uint(0), true, false, ""}, + equalsTestCase{uint8(0), true, false, ""}, + equalsTestCase{uint16(0), true, false, ""}, + equalsTestCase{uint32(0), true, false, ""}, + equalsTestCase{uint64(0), true, false, ""}, + equalsTestCase{uintptr(0), true, false, ""}, + equalsTestCase{float32(0), true, false, ""}, + equalsTestCase{float64(0), true, false, ""}, + equalsTestCase{complex64(0), true, false, ""}, + equalsTestCase{complex128(0), true, false, ""}, + equalsTestCase{interface{}(float32(0)), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int64(1), false, false, ""}, + equalsTestCase{int64(-1), false, false, ""}, + equalsTestCase{float32(1), false, false, ""}, + equalsTestCase{float32(-1), false, false, ""}, + equalsTestCase{float64(1), false, false, ""}, + equalsTestCase{float64(-1), false, false, ""}, + equalsTestCase{complex64(0 + 2i), false, false, ""}, + equalsTestCase{complex128(0 + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) PositiveIntegralComplex128() { + const kExpected = 1 << 20 + matcher := Equals(complex128(kExpected)) + ExpectEq("(1.048576e+06+0i)", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of 32769. + equalsTestCase{1048576.0, true, false, ""}, + equalsTestCase{1048576.0 + 0i, true, false, ""}, + equalsTestCase{int(kExpected), true, false, ""}, + equalsTestCase{int32(kExpected), true, false, ""}, + equalsTestCase{int64(kExpected), true, false, ""}, + equalsTestCase{uint(kExpected), true, false, ""}, + equalsTestCase{uint32(kExpected), true, false, ""}, + equalsTestCase{uint64(kExpected), true, false, ""}, + equalsTestCase{uintptr(kExpected), true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + equalsTestCase{interface{}(float64(kExpected)), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int(kExpected + 1), false, false, ""}, + equalsTestCase{int32(kExpected + 1), false, false, ""}, + equalsTestCase{int64(kExpected + 1), false, false, ""}, + equalsTestCase{uint(kExpected + 1), false, false, ""}, + equalsTestCase{uint32(kExpected + 1), false, false, ""}, + equalsTestCase{uint64(kExpected + 1), false, false, ""}, + equalsTestCase{uintptr(kExpected + 1), false, false, ""}, + equalsTestCase{float32(kExpected - (1 << 30)), false, false, ""}, + equalsTestCase{float32(kExpected + (1 << 30)), false, false, ""}, + equalsTestCase{float64(kExpected - 0.5), false, false, ""}, + equalsTestCase{float64(kExpected + 0.5), false, false, ""}, + equalsTestCase{complex128(kExpected - 1), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + + // Non-numeric types. + equalsTestCase{true, false, true, "which is not numeric"}, + equalsTestCase{[...]int{}, false, true, "which is not numeric"}, + equalsTestCase{make(chan int), false, true, "which is not numeric"}, + equalsTestCase{func() {}, false, true, "which is not numeric"}, + equalsTestCase{map[int]int{}, false, true, "which is not numeric"}, + equalsTestCase{&someInt, false, true, "which is not numeric"}, + equalsTestCase{[]int{}, false, true, "which is not numeric"}, + equalsTestCase{"taco", false, true, "which is not numeric"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not numeric"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) PositiveNonIntegralComplex128() { + const kTwoTo20 = 1 << 20 + const kExpected = kTwoTo20 + 0.25 + matcher := Equals(complex128(kExpected)) + ExpectEq("(1.04857625e+06+0i)", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of the expected value. + equalsTestCase{kExpected, true, false, ""}, + equalsTestCase{kExpected + 0i, true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int64(kTwoTo20), false, false, ""}, + equalsTestCase{int64(kTwoTo20 - 1), false, false, ""}, + equalsTestCase{uint64(kTwoTo20), false, false, ""}, + equalsTestCase{uint64(kTwoTo20 - 1), false, false, ""}, + equalsTestCase{float32(kExpected - 1), false, false, ""}, + equalsTestCase{float32(kExpected + 1), false, false, ""}, + equalsTestCase{float64(kExpected - 0.25), false, false, ""}, + equalsTestCase{float64(kExpected + 0.25), false, false, ""}, + equalsTestCase{complex64(kExpected - 1), false, false, ""}, + equalsTestCase{complex64(kExpected - 1i), false, false, ""}, + equalsTestCase{complex128(kExpected - 1), false, false, ""}, + equalsTestCase{complex128(kExpected - 1i), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) LargePositiveComplex128() { + const kExpected = 1 << 65 + matcher := Equals(complex128(kExpected)) + ExpectEq("(3.6893488147419103e+19+0i)", matcher.Description()) + + floatExpected := float64(kExpected) + castedInt := uint64(floatExpected) + + cases := []equalsTestCase{ + // Equal values of numeric type. + equalsTestCase{kExpected + 0i, true, false, ""}, + equalsTestCase{float32(kExpected), true, false, ""}, + equalsTestCase{float64(kExpected), true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{castedInt, false, false, ""}, + equalsTestCase{int64(0), false, false, ""}, + equalsTestCase{int64(math.MinInt64), false, false, ""}, + equalsTestCase{int64(math.MaxInt64), false, false, ""}, + equalsTestCase{uint64(0), false, false, ""}, + equalsTestCase{uint64(math.MaxUint64), false, false, ""}, + equalsTestCase{float32(kExpected / 2), false, false, ""}, + equalsTestCase{float64(kExpected / 2), false, false, ""}, + equalsTestCase{complex128(kExpected + 2i), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) Complex128AboveExactIntegerRange() { + // Double-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^54-1, 2^54+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo54 = 1 << 54 + matcher := Equals(complex128(kTwoTo54 + 1)) + ExpectEq("(1.8014398509481984e+16+0i)", matcher.Description()) + + cases := []equalsTestCase{ + // Integers. + equalsTestCase{int64(kTwoTo54 - 2), false, false, ""}, + equalsTestCase{int64(kTwoTo54 - 1), true, false, ""}, + equalsTestCase{int64(kTwoTo54 + 0), true, false, ""}, + equalsTestCase{int64(kTwoTo54 + 1), true, false, ""}, + equalsTestCase{int64(kTwoTo54 + 2), true, false, ""}, + equalsTestCase{int64(kTwoTo54 + 3), false, false, ""}, + + equalsTestCase{uint64(kTwoTo54 - 2), false, false, ""}, + equalsTestCase{uint64(kTwoTo54 - 1), true, false, ""}, + equalsTestCase{uint64(kTwoTo54 + 0), true, false, ""}, + equalsTestCase{uint64(kTwoTo54 + 1), true, false, ""}, + equalsTestCase{uint64(kTwoTo54 + 2), true, false, ""}, + equalsTestCase{uint64(kTwoTo54 + 3), false, false, ""}, + + // Double-precision floating point. + equalsTestCase{float64(kTwoTo54 - 2), false, false, ""}, + equalsTestCase{float64(kTwoTo54 - 1), true, false, ""}, + equalsTestCase{float64(kTwoTo54 + 0), true, false, ""}, + equalsTestCase{float64(kTwoTo54 + 1), true, false, ""}, + equalsTestCase{float64(kTwoTo54 + 2), true, false, ""}, + equalsTestCase{float64(kTwoTo54 + 3), false, false, ""}, + + equalsTestCase{complex128(kTwoTo54 - 2), false, false, ""}, + equalsTestCase{complex128(kTwoTo54 - 1), true, false, ""}, + equalsTestCase{complex128(kTwoTo54 + 0), true, false, ""}, + equalsTestCase{complex128(kTwoTo54 + 1), true, false, ""}, + equalsTestCase{complex128(kTwoTo54 + 2), true, false, ""}, + equalsTestCase{complex128(kTwoTo54 + 3), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) Complex128WithNonZeroImaginaryPart() { + const kRealPart = 17 + const kImagPart = 0.25i + const kExpected = kRealPart + kImagPart + matcher := Equals(complex128(kExpected)) + ExpectEq("(17+0.25i)", matcher.Description()) + + cases := []equalsTestCase{ + // Various types of the expected value. + equalsTestCase{kExpected, true, false, ""}, + equalsTestCase{kRealPart + kImagPart, true, false, ""}, + equalsTestCase{complex64(kExpected), true, false, ""}, + equalsTestCase{complex128(kExpected), true, false, ""}, + + // Non-equal values of numeric type. + equalsTestCase{int(kRealPart), false, false, ""}, + equalsTestCase{int8(kRealPart), false, false, ""}, + equalsTestCase{int16(kRealPart), false, false, ""}, + equalsTestCase{int32(kRealPart), false, false, ""}, + equalsTestCase{int64(kRealPart), false, false, ""}, + equalsTestCase{uint(kRealPart), false, false, ""}, + equalsTestCase{uint8(kRealPart), false, false, ""}, + equalsTestCase{uint16(kRealPart), false, false, ""}, + equalsTestCase{uint32(kRealPart), false, false, ""}, + equalsTestCase{uint64(kRealPart), false, false, ""}, + equalsTestCase{float32(kRealPart), false, false, ""}, + equalsTestCase{float64(kRealPart), false, false, ""}, + equalsTestCase{complex64(kRealPart), false, false, ""}, + equalsTestCase{complex64(kRealPart + kImagPart + 0.5), false, false, ""}, + equalsTestCase{complex64(kRealPart + kImagPart + 0.5i), false, false, ""}, + equalsTestCase{complex128(kRealPart), false, false, ""}, + equalsTestCase{complex128(kRealPart + kImagPart + 0.5), false, false, ""}, + equalsTestCase{complex128(kRealPart + kImagPart + 0.5i), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// Arrays +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) ArrayOfComparableType() { + expected := [3]uint{17, 19, 23} + + matcher := Equals(expected) + ExpectEq("[17 19 23]", matcher.Description()) + + // To defeat constant de-duping by the compiler. + makeArray := func(i, j, k uint) [3]uint { return [3]uint{i, j, k} } + + type arrayAlias [3]uint + type uintAlias uint + + cases := []equalsTestCase{ + // Correct types, equal. + equalsTestCase{expected, true, false, ""}, + equalsTestCase{[3]uint{17, 19, 23}, true, false, ""}, + equalsTestCase{makeArray(17, 19, 23), true, false, ""}, + + // Correct types, not equal. + equalsTestCase{[3]uint{0, 0, 0}, false, false, ""}, + equalsTestCase{[3]uint{18, 19, 23}, false, false, ""}, + equalsTestCase{[3]uint{17, 20, 23}, false, false, ""}, + equalsTestCase{[3]uint{17, 19, 22}, false, false, ""}, + + // Other types. + equalsTestCase{0, false, true, "which is not [3]uint"}, + equalsTestCase{bool(false), false, true, "which is not [3]uint"}, + equalsTestCase{int(0), false, true, "which is not [3]uint"}, + equalsTestCase{int8(0), false, true, "which is not [3]uint"}, + equalsTestCase{int16(0), false, true, "which is not [3]uint"}, + equalsTestCase{int32(0), false, true, "which is not [3]uint"}, + equalsTestCase{int64(0), false, true, "which is not [3]uint"}, + equalsTestCase{uint(0), false, true, "which is not [3]uint"}, + equalsTestCase{uint8(0), false, true, "which is not [3]uint"}, + equalsTestCase{uint16(0), false, true, "which is not [3]uint"}, + equalsTestCase{uint32(0), false, true, "which is not [3]uint"}, + equalsTestCase{uint64(0), false, true, "which is not [3]uint"}, + equalsTestCase{true, false, true, "which is not [3]uint"}, + equalsTestCase{[...]int{}, false, true, "which is not [3]uint"}, + equalsTestCase{func() {}, false, true, "which is not [3]uint"}, + equalsTestCase{map[int]int{}, false, true, "which is not [3]uint"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not [3]uint"}, + equalsTestCase{[2]uint{17, 19}, false, true, "which is not [3]uint"}, + equalsTestCase{[4]uint{17, 19, 23, 0}, false, true, "which is not [3]uint"}, + equalsTestCase{arrayAlias{17, 19, 23}, false, true, "which is not [3]uint"}, + equalsTestCase{[3]uintAlias{17, 19, 23}, false, true, "which is not [3]uint"}, + equalsTestCase{[3]int32{17, 19, 23}, false, true, "which is not [3]uint"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) ArrayOfNonComparableType() { + type nonComparableArray [2]map[string]string + f := func() { + ExpectEq(nonComparableArray{}, nonComparableArray{}) + } + + ExpectThat(f, Panics(MatchesRegexp("uncomparable.*nonComparableArray"))) +} + +//////////////////////////////////////////////////////////////////////// +// chan +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) NilChan() { + var nilChan1 chan int + var nilChan2 chan int + var nilChan3 chan uint + var nonNilChan1 chan int = make(chan int) + var nonNilChan2 chan uint = make(chan uint) + + matcher := Equals(nilChan1) + ExpectEq("<nil>", matcher.Description()) + + cases := []equalsTestCase{ + // int channels + equalsTestCase{nilChan1, true, false, ""}, + equalsTestCase{nilChan2, true, false, ""}, + equalsTestCase{nonNilChan1, false, false, ""}, + + // uint channels + equalsTestCase{nilChan3, false, true, "which is not a chan int"}, + equalsTestCase{nonNilChan2, false, true, "which is not a chan int"}, + + // Other types. + equalsTestCase{0, false, true, "which is not a chan int"}, + equalsTestCase{bool(false), false, true, "which is not a chan int"}, + equalsTestCase{int(0), false, true, "which is not a chan int"}, + equalsTestCase{int8(0), false, true, "which is not a chan int"}, + equalsTestCase{int16(0), false, true, "which is not a chan int"}, + equalsTestCase{int32(0), false, true, "which is not a chan int"}, + equalsTestCase{int64(0), false, true, "which is not a chan int"}, + equalsTestCase{uint(0), false, true, "which is not a chan int"}, + equalsTestCase{uint8(0), false, true, "which is not a chan int"}, + equalsTestCase{uint16(0), false, true, "which is not a chan int"}, + equalsTestCase{uint32(0), false, true, "which is not a chan int"}, + equalsTestCase{uint64(0), false, true, "which is not a chan int"}, + equalsTestCase{true, false, true, "which is not a chan int"}, + equalsTestCase{[...]int{}, false, true, "which is not a chan int"}, + equalsTestCase{func() {}, false, true, "which is not a chan int"}, + equalsTestCase{map[int]int{}, false, true, "which is not a chan int"}, + equalsTestCase{&someInt, false, true, "which is not a chan int"}, + equalsTestCase{[]int{}, false, true, "which is not a chan int"}, + equalsTestCase{"taco", false, true, "which is not a chan int"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not a chan int"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) NonNilChan() { + var nilChan1 chan int + var nilChan2 chan uint + var nonNilChan1 chan int = make(chan int) + var nonNilChan2 chan int = make(chan int) + var nonNilChan3 chan uint = make(chan uint) + + matcher := Equals(nonNilChan1) + ExpectEq(fmt.Sprintf("%v", nonNilChan1), matcher.Description()) + + cases := []equalsTestCase{ + // int channels + equalsTestCase{nonNilChan1, true, false, ""}, + equalsTestCase{nonNilChan2, false, false, ""}, + equalsTestCase{nilChan1, false, false, ""}, + + // uint channels + equalsTestCase{nilChan2, false, true, "which is not a chan int"}, + equalsTestCase{nonNilChan3, false, true, "which is not a chan int"}, + + // Other types. + equalsTestCase{0, false, true, "which is not a chan int"}, + equalsTestCase{bool(false), false, true, "which is not a chan int"}, + equalsTestCase{int(0), false, true, "which is not a chan int"}, + equalsTestCase{int8(0), false, true, "which is not a chan int"}, + equalsTestCase{int16(0), false, true, "which is not a chan int"}, + equalsTestCase{int32(0), false, true, "which is not a chan int"}, + equalsTestCase{int64(0), false, true, "which is not a chan int"}, + equalsTestCase{uint(0), false, true, "which is not a chan int"}, + equalsTestCase{uint8(0), false, true, "which is not a chan int"}, + equalsTestCase{uint16(0), false, true, "which is not a chan int"}, + equalsTestCase{uint32(0), false, true, "which is not a chan int"}, + equalsTestCase{uint64(0), false, true, "which is not a chan int"}, + equalsTestCase{true, false, true, "which is not a chan int"}, + equalsTestCase{[...]int{}, false, true, "which is not a chan int"}, + equalsTestCase{func() {}, false, true, "which is not a chan int"}, + equalsTestCase{map[int]int{}, false, true, "which is not a chan int"}, + equalsTestCase{&someInt, false, true, "which is not a chan int"}, + equalsTestCase{[]int{}, false, true, "which is not a chan int"}, + equalsTestCase{"taco", false, true, "which is not a chan int"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not a chan int"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) ChanDirection() { + var chan1 chan<- int + var chan2 <-chan int + var chan3 chan int + + matcher := Equals(chan1) + ExpectEq(fmt.Sprintf("%v", chan1), matcher.Description()) + + cases := []equalsTestCase{ + equalsTestCase{chan1, true, false, ""}, + equalsTestCase{chan2, false, true, "which is not a chan<- int"}, + equalsTestCase{chan3, false, true, "which is not a chan<- int"}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// func +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) Functions() { + func1 := func() {} + func2 := func() {} + func3 := func(x int) {} + + matcher := Equals(func1) + ExpectEq(fmt.Sprintf("%v", func1), matcher.Description()) + + cases := []equalsTestCase{ + // Functions. + equalsTestCase{func1, true, false, ""}, + equalsTestCase{func2, false, false, ""}, + equalsTestCase{func3, false, false, ""}, + + // Other types. + equalsTestCase{0, false, true, "which is not a function"}, + equalsTestCase{bool(false), false, true, "which is not a function"}, + equalsTestCase{int(0), false, true, "which is not a function"}, + equalsTestCase{int8(0), false, true, "which is not a function"}, + equalsTestCase{int16(0), false, true, "which is not a function"}, + equalsTestCase{int32(0), false, true, "which is not a function"}, + equalsTestCase{int64(0), false, true, "which is not a function"}, + equalsTestCase{uint(0), false, true, "which is not a function"}, + equalsTestCase{uint8(0), false, true, "which is not a function"}, + equalsTestCase{uint16(0), false, true, "which is not a function"}, + equalsTestCase{uint32(0), false, true, "which is not a function"}, + equalsTestCase{uint64(0), false, true, "which is not a function"}, + equalsTestCase{true, false, true, "which is not a function"}, + equalsTestCase{[...]int{}, false, true, "which is not a function"}, + equalsTestCase{map[int]int{}, false, true, "which is not a function"}, + equalsTestCase{&someInt, false, true, "which is not a function"}, + equalsTestCase{[]int{}, false, true, "which is not a function"}, + equalsTestCase{"taco", false, true, "which is not a function"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not a function"}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// map +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) NilMap() { + var nilMap1 map[int]int + var nilMap2 map[int]int + var nilMap3 map[int]uint + var nonNilMap1 map[int]int = make(map[int]int) + var nonNilMap2 map[int]uint = make(map[int]uint) + + matcher := Equals(nilMap1) + ExpectEq("map[]", matcher.Description()) + + cases := []equalsTestCase{ + // Correct type. + equalsTestCase{nilMap1, true, false, ""}, + equalsTestCase{nilMap2, true, false, ""}, + equalsTestCase{nilMap3, true, false, ""}, + equalsTestCase{nonNilMap1, false, false, ""}, + equalsTestCase{nonNilMap2, false, false, ""}, + + // Other types. + equalsTestCase{0, false, true, "which is not a map"}, + equalsTestCase{bool(false), false, true, "which is not a map"}, + equalsTestCase{int(0), false, true, "which is not a map"}, + equalsTestCase{int8(0), false, true, "which is not a map"}, + equalsTestCase{int16(0), false, true, "which is not a map"}, + equalsTestCase{int32(0), false, true, "which is not a map"}, + equalsTestCase{int64(0), false, true, "which is not a map"}, + equalsTestCase{uint(0), false, true, "which is not a map"}, + equalsTestCase{uint8(0), false, true, "which is not a map"}, + equalsTestCase{uint16(0), false, true, "which is not a map"}, + equalsTestCase{uint32(0), false, true, "which is not a map"}, + equalsTestCase{uint64(0), false, true, "which is not a map"}, + equalsTestCase{true, false, true, "which is not a map"}, + equalsTestCase{[...]int{}, false, true, "which is not a map"}, + equalsTestCase{func() {}, false, true, "which is not a map"}, + equalsTestCase{&someInt, false, true, "which is not a map"}, + equalsTestCase{[]int{}, false, true, "which is not a map"}, + equalsTestCase{"taco", false, true, "which is not a map"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not a map"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) NonNilMap() { + var nilMap1 map[int]int + var nilMap2 map[int]uint + var nonNilMap1 map[int]int = make(map[int]int) + var nonNilMap2 map[int]int = make(map[int]int) + var nonNilMap3 map[int]uint = make(map[int]uint) + + matcher := Equals(nonNilMap1) + ExpectEq("map[]", matcher.Description()) + + cases := []equalsTestCase{ + // Correct type. + equalsTestCase{nonNilMap1, true, false, ""}, + equalsTestCase{nonNilMap2, false, false, ""}, + equalsTestCase{nonNilMap3, false, false, ""}, + equalsTestCase{nilMap1, false, false, ""}, + equalsTestCase{nilMap2, false, false, ""}, + + // Other types. + equalsTestCase{0, false, true, "which is not a map"}, + equalsTestCase{bool(false), false, true, "which is not a map"}, + equalsTestCase{int(0), false, true, "which is not a map"}, + equalsTestCase{int8(0), false, true, "which is not a map"}, + equalsTestCase{int16(0), false, true, "which is not a map"}, + equalsTestCase{int32(0), false, true, "which is not a map"}, + equalsTestCase{int64(0), false, true, "which is not a map"}, + equalsTestCase{uint(0), false, true, "which is not a map"}, + equalsTestCase{uint8(0), false, true, "which is not a map"}, + equalsTestCase{uint16(0), false, true, "which is not a map"}, + equalsTestCase{uint32(0), false, true, "which is not a map"}, + equalsTestCase{uint64(0), false, true, "which is not a map"}, + equalsTestCase{true, false, true, "which is not a map"}, + equalsTestCase{[...]int{}, false, true, "which is not a map"}, + equalsTestCase{func() {}, false, true, "which is not a map"}, + equalsTestCase{&someInt, false, true, "which is not a map"}, + equalsTestCase{[]int{}, false, true, "which is not a map"}, + equalsTestCase{"taco", false, true, "which is not a map"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not a map"}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// Pointers +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) NilPointer() { + var someInt int = 17 + var someUint uint = 17 + + var nilInt1 *int + var nilInt2 *int + var nilUint *uint + var nonNilInt *int = &someInt + var nonNilUint *uint = &someUint + + matcher := Equals(nilInt1) + ExpectEq("<nil>", matcher.Description()) + + cases := []equalsTestCase{ + // Correct type. + equalsTestCase{nilInt1, true, false, ""}, + equalsTestCase{nilInt2, true, false, ""}, + equalsTestCase{nonNilInt, false, false, ""}, + + // Incorrect type. + equalsTestCase{nilUint, false, true, "which is not a *int"}, + equalsTestCase{nonNilUint, false, true, "which is not a *int"}, + + // Other types. + equalsTestCase{0, false, true, "which is not a *int"}, + equalsTestCase{bool(false), false, true, "which is not a *int"}, + equalsTestCase{int(0), false, true, "which is not a *int"}, + equalsTestCase{int8(0), false, true, "which is not a *int"}, + equalsTestCase{int16(0), false, true, "which is not a *int"}, + equalsTestCase{int32(0), false, true, "which is not a *int"}, + equalsTestCase{int64(0), false, true, "which is not a *int"}, + equalsTestCase{uint(0), false, true, "which is not a *int"}, + equalsTestCase{uint8(0), false, true, "which is not a *int"}, + equalsTestCase{uint16(0), false, true, "which is not a *int"}, + equalsTestCase{uint32(0), false, true, "which is not a *int"}, + equalsTestCase{uint64(0), false, true, "which is not a *int"}, + equalsTestCase{true, false, true, "which is not a *int"}, + equalsTestCase{[...]int{}, false, true, "which is not a *int"}, + equalsTestCase{func() {}, false, true, "which is not a *int"}, + equalsTestCase{map[int]int{}, false, true, "which is not a *int"}, + equalsTestCase{[]int{}, false, true, "which is not a *int"}, + equalsTestCase{"taco", false, true, "which is not a *int"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not a *int"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) NonNilPointer() { + var someInt int = 17 + var someOtherInt int = 17 + var someUint uint = 17 + + var nilInt *int + var nilUint *uint + var nonNilInt1 *int = &someInt + var nonNilInt2 *int = &someOtherInt + var nonNilUint *uint = &someUint + + matcher := Equals(nonNilInt1) + ExpectEq(fmt.Sprintf("%v", nonNilInt1), matcher.Description()) + + cases := []equalsTestCase{ + // Correct type. + equalsTestCase{nonNilInt1, true, false, ""}, + equalsTestCase{nonNilInt2, false, false, ""}, + equalsTestCase{nilInt, false, false, ""}, + + // Incorrect type. + equalsTestCase{nilUint, false, true, "which is not a *int"}, + equalsTestCase{nonNilUint, false, true, "which is not a *int"}, + + // Other types. + equalsTestCase{0, false, true, "which is not a *int"}, + equalsTestCase{bool(false), false, true, "which is not a *int"}, + equalsTestCase{int(0), false, true, "which is not a *int"}, + equalsTestCase{int8(0), false, true, "which is not a *int"}, + equalsTestCase{int16(0), false, true, "which is not a *int"}, + equalsTestCase{int32(0), false, true, "which is not a *int"}, + equalsTestCase{int64(0), false, true, "which is not a *int"}, + equalsTestCase{uint(0), false, true, "which is not a *int"}, + equalsTestCase{uint8(0), false, true, "which is not a *int"}, + equalsTestCase{uint16(0), false, true, "which is not a *int"}, + equalsTestCase{uint32(0), false, true, "which is not a *int"}, + equalsTestCase{uint64(0), false, true, "which is not a *int"}, + equalsTestCase{true, false, true, "which is not a *int"}, + equalsTestCase{[...]int{}, false, true, "which is not a *int"}, + equalsTestCase{func() {}, false, true, "which is not a *int"}, + equalsTestCase{map[int]int{}, false, true, "which is not a *int"}, + equalsTestCase{[]int{}, false, true, "which is not a *int"}, + equalsTestCase{"taco", false, true, "which is not a *int"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not a *int"}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// Slices +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) NilSlice() { + var nilInt1 []int + var nilInt2 []int + var nilUint []uint + + var nonNilInt []int = make([]int, 0) + var nonNilUint []uint = make([]uint, 0) + + matcher := Equals(nilInt1) + ExpectEq("[]", matcher.Description()) + + cases := []equalsTestCase{ + // Correct type. + equalsTestCase{nilInt1, true, false, ""}, + equalsTestCase{nilInt2, true, false, ""}, + equalsTestCase{nonNilInt, false, false, ""}, + + // Incorrect type. + equalsTestCase{nilUint, false, true, "which is not a []int"}, + equalsTestCase{nonNilUint, false, true, "which is not a []int"}, + + // Other types. + equalsTestCase{0, false, true, "which is not a []int"}, + equalsTestCase{bool(false), false, true, "which is not a []int"}, + equalsTestCase{int(0), false, true, "which is not a []int"}, + equalsTestCase{int8(0), false, true, "which is not a []int"}, + equalsTestCase{int16(0), false, true, "which is not a []int"}, + equalsTestCase{int32(0), false, true, "which is not a []int"}, + equalsTestCase{int64(0), false, true, "which is not a []int"}, + equalsTestCase{uint(0), false, true, "which is not a []int"}, + equalsTestCase{uint8(0), false, true, "which is not a []int"}, + equalsTestCase{uint16(0), false, true, "which is not a []int"}, + equalsTestCase{uint32(0), false, true, "which is not a []int"}, + equalsTestCase{uint64(0), false, true, "which is not a []int"}, + equalsTestCase{true, false, true, "which is not a []int"}, + equalsTestCase{[...]int{}, false, true, "which is not a []int"}, + equalsTestCase{func() {}, false, true, "which is not a []int"}, + equalsTestCase{map[int]int{}, false, true, "which is not a []int"}, + equalsTestCase{"taco", false, true, "which is not a []int"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not a []int"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) NonNilSlice() { + nonNil := make([]int, 0) + f := func() { Equals(nonNil) } + ExpectThat(f, Panics(HasSubstr("non-nil slice"))) +} + +//////////////////////////////////////////////////////////////////////// +// string +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) String() { + partial := "taco" + expected := fmt.Sprintf("%s%d", partial, 1) + + matcher := Equals(expected) + ExpectEq("taco1", matcher.Description()) + + type stringAlias string + + cases := []equalsTestCase{ + // Correct types. + equalsTestCase{"taco1", true, false, ""}, + equalsTestCase{"taco" + "1", true, false, ""}, + equalsTestCase{expected, true, false, ""}, + equalsTestCase{stringAlias("taco1"), true, false, ""}, + + equalsTestCase{"", false, false, ""}, + equalsTestCase{"taco", false, false, ""}, + equalsTestCase{"taco1\x00", false, false, ""}, + equalsTestCase{"taco2", false, false, ""}, + equalsTestCase{stringAlias("taco2"), false, false, ""}, + + // Other types. + equalsTestCase{0, false, true, "which is not a string"}, + equalsTestCase{bool(false), false, true, "which is not a string"}, + equalsTestCase{int(0), false, true, "which is not a string"}, + equalsTestCase{int8(0), false, true, "which is not a string"}, + equalsTestCase{int16(0), false, true, "which is not a string"}, + equalsTestCase{int32(0), false, true, "which is not a string"}, + equalsTestCase{int64(0), false, true, "which is not a string"}, + equalsTestCase{uint(0), false, true, "which is not a string"}, + equalsTestCase{uint8(0), false, true, "which is not a string"}, + equalsTestCase{uint16(0), false, true, "which is not a string"}, + equalsTestCase{uint32(0), false, true, "which is not a string"}, + equalsTestCase{uint64(0), false, true, "which is not a string"}, + equalsTestCase{true, false, true, "which is not a string"}, + equalsTestCase{[...]int{}, false, true, "which is not a string"}, + equalsTestCase{func() {}, false, true, "which is not a string"}, + equalsTestCase{map[int]int{}, false, true, "which is not a string"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not a string"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) StringAlias() { + type stringAlias string + + matcher := Equals(stringAlias("taco")) + ExpectEq("taco", matcher.Description()) + + cases := []equalsTestCase{ + // Correct types. + equalsTestCase{stringAlias("taco"), true, false, ""}, + equalsTestCase{"taco", true, false, ""}, + + equalsTestCase{"burrito", false, false, ""}, + equalsTestCase{stringAlias("burrito"), false, false, ""}, + + // Other types. + equalsTestCase{0, false, true, "which is not a string"}, + equalsTestCase{bool(false), false, true, "which is not a string"}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// struct +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) Struct() { + type someStruct struct{ foo uint } + f := func() { Equals(someStruct{17}) } + ExpectThat(f, Panics(HasSubstr("unsupported kind struct"))) +} + +//////////////////////////////////////////////////////////////////////// +// unsafe.Pointer +//////////////////////////////////////////////////////////////////////// + +func (t *EqualsTest) NilUnsafePointer() { + someInt := int(17) + + var nilPtr1 unsafe.Pointer + var nilPtr2 unsafe.Pointer + var nonNilPtr unsafe.Pointer = unsafe.Pointer(&someInt) + + matcher := Equals(nilPtr1) + ExpectEq("<nil>", matcher.Description()) + + cases := []equalsTestCase{ + // Correct type. + equalsTestCase{nilPtr1, true, false, ""}, + equalsTestCase{nilPtr2, true, false, ""}, + equalsTestCase{nonNilPtr, false, false, ""}, + + // Other types. + equalsTestCase{0, false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{bool(false), false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{int(0), false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{int8(0), false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{int16(0), false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{int32(0), false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{int64(0), false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{uint(0), false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{uint8(0), false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{uint16(0), false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{uint32(0), false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{uint64(0), false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{true, false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{[...]int{}, false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{make(chan int), false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{func() {}, false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{map[int]int{}, false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{&someInt, false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{[]int{}, false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{"taco", false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not a unsafe.Pointer"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *EqualsTest) NonNilUnsafePointer() { + someInt := int(17) + someOtherInt := int(17) + + var nilPtr unsafe.Pointer + var nonNilPtr1 unsafe.Pointer = unsafe.Pointer(&someInt) + var nonNilPtr2 unsafe.Pointer = unsafe.Pointer(&someOtherInt) + + matcher := Equals(nonNilPtr1) + ExpectEq(fmt.Sprintf("%v", nonNilPtr1), matcher.Description()) + + cases := []equalsTestCase{ + // Correct type. + equalsTestCase{nonNilPtr1, true, false, ""}, + equalsTestCase{nonNilPtr2, false, false, ""}, + equalsTestCase{nilPtr, false, false, ""}, + + // Other types. + equalsTestCase{0, false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{bool(false), false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{int(0), false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{int8(0), false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{int16(0), false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{int32(0), false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{int64(0), false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{uint(0), false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{uint8(0), false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{uint16(0), false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{uint32(0), false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{uint64(0), false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{true, false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{[...]int{}, false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{make(chan int), false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{func() {}, false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{map[int]int{}, false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{&someInt, false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{[]int{}, false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{"taco", false, true, "which is not a unsafe.Pointer"}, + equalsTestCase{equalsTestCase{}, false, true, "which is not a unsafe.Pointer"}, + } + + t.checkTestCases(matcher, cases) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/error.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/error.go new file mode 100644 index 00000000000..8a078e36d86 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/error.go @@ -0,0 +1,51 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package oglematchers + +// Error returns a matcher that matches non-nil values implementing the +// built-in error interface for whom the return value of Error() matches the +// supplied matcher. +// +// For example: +// +// err := errors.New("taco burrito") +// +// Error(Equals("taco burrito")) // matches err +// Error(HasSubstr("taco")) // matches err +// Error(HasSubstr("enchilada")) // doesn't match err +// +func Error(m Matcher) Matcher { + return &errorMatcher{m} +} + +type errorMatcher struct { + wrappedMatcher Matcher +} + +func (m *errorMatcher) Description() string { + return "error " + m.wrappedMatcher.Description() +} + +func (m *errorMatcher) Matches(c interface{}) error { + // Make sure that c is an error. + e, ok := c.(error) + if !ok { + return NewFatalError("which is not an error") + } + + // Pass on the error text to the wrapped matcher. + return m.wrappedMatcher.Matches(e.Error()) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/error_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/error_test.go new file mode 100644 index 00000000000..f92167cad1d --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/error_test.go @@ -0,0 +1,92 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package oglematchers_test + +import ( + "errors" + . "github.com/smartystreets/assertions/internal/oglematchers" + . "github.com/smartystreets/assertions/internal/ogletest" +) + +//////////////////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////////////////// + +type ErrorTest struct { + matcherCalled bool + suppliedCandidate interface{} + wrappedError error + + matcher Matcher +} + +func init() { RegisterTestSuite(&ErrorTest{}) } + +func (t *ErrorTest) SetUp(i *TestInfo) { + wrapped := &fakeMatcher{ + func(c interface{}) error { + t.matcherCalled = true + t.suppliedCandidate = c + return t.wrappedError + }, + "is foo", + } + + t.matcher = Error(wrapped) +} + +func isFatal(err error) bool { + _, isFatal := err.(*FatalError) + return isFatal +} + +//////////////////////////////////////////////////////////////////////// +// Tests +//////////////////////////////////////////////////////////////////////// + +func (t *ErrorTest) Description() { + ExpectThat(t.matcher.Description(), Equals("error is foo")) +} + +func (t *ErrorTest) CandidateIsNil() { + err := t.matcher.Matches(nil) + + ExpectThat(t.matcherCalled, Equals(false)) + ExpectThat(err.Error(), Equals("which is not an error")) + ExpectTrue(isFatal(err)) +} + +func (t *ErrorTest) CandidateIsString() { + err := t.matcher.Matches("taco") + + ExpectThat(t.matcherCalled, Equals(false)) + ExpectThat(err.Error(), Equals("which is not an error")) + ExpectTrue(isFatal(err)) +} + +func (t *ErrorTest) CallsWrappedMatcher() { + candidate := errors.New("taco") + t.matcher.Matches(candidate) + + ExpectThat(t.matcherCalled, Equals(true)) + ExpectThat(t.suppliedCandidate, Equals("taco")) +} + +func (t *ErrorTest) ReturnsWrappedMatcherResult() { + t.wrappedError = errors.New("burrito") + err := t.matcher.Matches(errors.New("")) + ExpectThat(err, Equals(t.wrappedError)) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/greater_or_equal.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/greater_or_equal.go new file mode 100644 index 00000000000..4b9d103a381 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/greater_or_equal.go @@ -0,0 +1,39 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package oglematchers + +import ( + "fmt" + "reflect" +) + +// GreaterOrEqual returns a matcher that matches integer, floating point, or +// strings values v such that v >= x. Comparison is not defined between numeric +// and string types, but is defined between all integer and floating point +// types. +// +// x must itself be an integer, floating point, or string type; otherwise, +// GreaterOrEqual will panic. +func GreaterOrEqual(x interface{}) Matcher { + desc := fmt.Sprintf("greater than or equal to %v", x) + + // Special case: make it clear that strings are strings. + if reflect.TypeOf(x).Kind() == reflect.String { + desc = fmt.Sprintf("greater than or equal to \"%s\"", x) + } + + return transformDescription(Not(LessThan(x)), desc) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/greater_or_equal_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/greater_or_equal_test.go new file mode 100644 index 00000000000..f5e29d1ce59 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/greater_or_equal_test.go @@ -0,0 +1,1101 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package oglematchers_test + +import ( + "math" + + . "github.com/smartystreets/assertions/internal/oglematchers" + . "github.com/smartystreets/assertions/internal/ogletest" +) + +//////////////////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////////////////// + +type GreaterOrEqualTest struct { +} + +func init() { RegisterTestSuite(&GreaterOrEqualTest{}) } + +type geTestCase struct { + candidate interface{} + expectedResult bool + shouldBeFatal bool + expectedError string +} + +func (t *GreaterOrEqualTest) checkTestCases(matcher Matcher, cases []geTestCase) { + for i, c := range cases { + err := matcher.Matches(c.candidate) + + ExpectThat( + (err == nil), + Equals(c.expectedResult), + "Case %d (candidate %v)", + i, + c.candidate) + + if err == nil { + continue + } + + _, isFatal := err.(*FatalError) + ExpectEq( + c.shouldBeFatal, + isFatal, + "Case %d (candidate %v)", + i, + c.candidate) + + ExpectThat( + err, + Error(Equals(c.expectedError)), + "Case %d (candidate %v)", + i, + c.candidate) + } +} + +//////////////////////////////////////////////////////////////////////// +// Integer literals +//////////////////////////////////////////////////////////////////////// + +func (t *GreaterOrEqualTest) IntegerCandidateBadTypes() { + matcher := GreaterOrEqual(int(-150)) + + cases := []geTestCase{ + geTestCase{true, false, true, "which is not comparable"}, + geTestCase{complex64(-151), false, true, "which is not comparable"}, + geTestCase{complex128(-151), false, true, "which is not comparable"}, + geTestCase{[...]int{-151}, false, true, "which is not comparable"}, + geTestCase{make(chan int), false, true, "which is not comparable"}, + geTestCase{func() {}, false, true, "which is not comparable"}, + geTestCase{map[int]int{}, false, true, "which is not comparable"}, + geTestCase{&geTestCase{}, false, true, "which is not comparable"}, + geTestCase{make([]int, 0), false, true, "which is not comparable"}, + geTestCase{"-151", false, true, "which is not comparable"}, + geTestCase{geTestCase{}, false, true, "which is not comparable"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterOrEqualTest) FloatCandidateBadTypes() { + matcher := GreaterOrEqual(float32(-150)) + + cases := []geTestCase{ + geTestCase{true, false, true, "which is not comparable"}, + geTestCase{complex64(-151), false, true, "which is not comparable"}, + geTestCase{complex128(-151), false, true, "which is not comparable"}, + geTestCase{[...]int{-151}, false, true, "which is not comparable"}, + geTestCase{make(chan int), false, true, "which is not comparable"}, + geTestCase{func() {}, false, true, "which is not comparable"}, + geTestCase{map[int]int{}, false, true, "which is not comparable"}, + geTestCase{&geTestCase{}, false, true, "which is not comparable"}, + geTestCase{make([]int, 0), false, true, "which is not comparable"}, + geTestCase{"-151", false, true, "which is not comparable"}, + geTestCase{geTestCase{}, false, true, "which is not comparable"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterOrEqualTest) StringCandidateBadTypes() { + matcher := GreaterOrEqual("17") + + cases := []geTestCase{ + geTestCase{true, false, true, "which is not comparable"}, + geTestCase{int(0), false, true, "which is not comparable"}, + geTestCase{int8(0), false, true, "which is not comparable"}, + geTestCase{int16(0), false, true, "which is not comparable"}, + geTestCase{int32(0), false, true, "which is not comparable"}, + geTestCase{int64(0), false, true, "which is not comparable"}, + geTestCase{uint(0), false, true, "which is not comparable"}, + geTestCase{uint8(0), false, true, "which is not comparable"}, + geTestCase{uint16(0), false, true, "which is not comparable"}, + geTestCase{uint32(0), false, true, "which is not comparable"}, + geTestCase{uint64(0), false, true, "which is not comparable"}, + geTestCase{float32(0), false, true, "which is not comparable"}, + geTestCase{float64(0), false, true, "which is not comparable"}, + geTestCase{complex64(-151), false, true, "which is not comparable"}, + geTestCase{complex128(-151), false, true, "which is not comparable"}, + geTestCase{[...]int{-151}, false, true, "which is not comparable"}, + geTestCase{make(chan int), false, true, "which is not comparable"}, + geTestCase{func() {}, false, true, "which is not comparable"}, + geTestCase{map[int]int{}, false, true, "which is not comparable"}, + geTestCase{&geTestCase{}, false, true, "which is not comparable"}, + geTestCase{make([]int, 0), false, true, "which is not comparable"}, + geTestCase{geTestCase{}, false, true, "which is not comparable"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterOrEqualTest) BadArgument() { + panicked := false + + defer func() { + ExpectThat(panicked, Equals(true)) + }() + + defer func() { + if r := recover(); r != nil { + panicked = true + } + }() + + GreaterOrEqual(complex128(0)) +} + +//////////////////////////////////////////////////////////////////////// +// Integer literals +//////////////////////////////////////////////////////////////////////// + +func (t *GreaterOrEqualTest) NegativeIntegerLiteral() { + matcher := GreaterOrEqual(-150) + desc := matcher.Description() + expectedDesc := "greater than or equal to -150" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []geTestCase{ + // Signed integers. + geTestCase{-(1 << 30), false, false, ""}, + geTestCase{-151, false, false, ""}, + geTestCase{-150, true, false, ""}, + geTestCase{0, true, false, ""}, + geTestCase{17, true, false, ""}, + + geTestCase{int(-(1 << 30)), false, false, ""}, + geTestCase{int(-151), false, false, ""}, + geTestCase{int(-150), true, false, ""}, + geTestCase{int(0), true, false, ""}, + geTestCase{int(17), true, false, ""}, + + geTestCase{int8(-127), true, false, ""}, + geTestCase{int8(0), true, false, ""}, + geTestCase{int8(17), true, false, ""}, + + geTestCase{int16(-(1 << 14)), false, false, ""}, + geTestCase{int16(-151), false, false, ""}, + geTestCase{int16(-150), true, false, ""}, + geTestCase{int16(0), true, false, ""}, + geTestCase{int16(17), true, false, ""}, + + geTestCase{int32(-(1 << 30)), false, false, ""}, + geTestCase{int32(-151), false, false, ""}, + geTestCase{int32(-150), true, false, ""}, + geTestCase{int32(0), true, false, ""}, + geTestCase{int32(17), true, false, ""}, + + geTestCase{int64(-(1 << 30)), false, false, ""}, + geTestCase{int64(-151), false, false, ""}, + geTestCase{int64(-150), true, false, ""}, + geTestCase{int64(0), true, false, ""}, + geTestCase{int64(17), true, false, ""}, + + // Unsigned integers. + geTestCase{uint((1 << 32) - 151), true, false, ""}, + geTestCase{uint(0), true, false, ""}, + geTestCase{uint(17), true, false, ""}, + + geTestCase{uint8(0), true, false, ""}, + geTestCase{uint8(17), true, false, ""}, + geTestCase{uint8(253), true, false, ""}, + + geTestCase{uint16((1 << 16) - 151), true, false, ""}, + geTestCase{uint16(0), true, false, ""}, + geTestCase{uint16(17), true, false, ""}, + + geTestCase{uint32((1 << 32) - 151), true, false, ""}, + geTestCase{uint32(0), true, false, ""}, + geTestCase{uint32(17), true, false, ""}, + + geTestCase{uint64((1 << 64) - 151), true, false, ""}, + geTestCase{uint64(0), true, false, ""}, + geTestCase{uint64(17), true, false, ""}, + + geTestCase{uintptr((1 << 64) - 151), true, false, ""}, + geTestCase{uintptr(0), true, false, ""}, + geTestCase{uintptr(17), true, false, ""}, + + // Floating point. + geTestCase{float32(-(1 << 30)), false, false, ""}, + geTestCase{float32(-151), false, false, ""}, + geTestCase{float32(-150.1), false, false, ""}, + geTestCase{float32(-150), true, false, ""}, + geTestCase{float32(-149.9), true, false, ""}, + geTestCase{float32(0), true, false, ""}, + geTestCase{float32(17), true, false, ""}, + geTestCase{float32(160), true, false, ""}, + + geTestCase{float64(-(1 << 30)), false, false, ""}, + geTestCase{float64(-151), false, false, ""}, + geTestCase{float64(-150.1), false, false, ""}, + geTestCase{float64(-150), true, false, ""}, + geTestCase{float64(-149.9), true, false, ""}, + geTestCase{float64(0), true, false, ""}, + geTestCase{float64(17), true, false, ""}, + geTestCase{float64(160), true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterOrEqualTest) ZeroIntegerLiteral() { + matcher := GreaterOrEqual(0) + desc := matcher.Description() + expectedDesc := "greater than or equal to 0" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []geTestCase{ + // Signed integers. + geTestCase{-(1 << 30), false, false, ""}, + geTestCase{-1, false, false, ""}, + geTestCase{0, true, false, ""}, + geTestCase{1, true, false, ""}, + geTestCase{17, true, false, ""}, + geTestCase{(1 << 30), true, false, ""}, + + geTestCase{int(-(1 << 30)), false, false, ""}, + geTestCase{int(-1), false, false, ""}, + geTestCase{int(0), true, false, ""}, + geTestCase{int(1), true, false, ""}, + geTestCase{int(17), true, false, ""}, + + geTestCase{int8(-1), false, false, ""}, + geTestCase{int8(0), true, false, ""}, + geTestCase{int8(1), true, false, ""}, + + geTestCase{int16(-(1 << 14)), false, false, ""}, + geTestCase{int16(-1), false, false, ""}, + geTestCase{int16(0), true, false, ""}, + geTestCase{int16(1), true, false, ""}, + geTestCase{int16(17), true, false, ""}, + + geTestCase{int32(-(1 << 30)), false, false, ""}, + geTestCase{int32(-1), false, false, ""}, + geTestCase{int32(0), true, false, ""}, + geTestCase{int32(1), true, false, ""}, + geTestCase{int32(17), true, false, ""}, + + geTestCase{int64(-(1 << 30)), false, false, ""}, + geTestCase{int64(-1), false, false, ""}, + geTestCase{int64(0), true, false, ""}, + geTestCase{int64(1), true, false, ""}, + geTestCase{int64(17), true, false, ""}, + + // Unsigned integers. + geTestCase{uint((1 << 32) - 1), true, false, ""}, + geTestCase{uint(0), true, false, ""}, + geTestCase{uint(17), true, false, ""}, + + geTestCase{uint8(0), true, false, ""}, + geTestCase{uint8(17), true, false, ""}, + geTestCase{uint8(253), true, false, ""}, + + geTestCase{uint16((1 << 16) - 1), true, false, ""}, + geTestCase{uint16(0), true, false, ""}, + geTestCase{uint16(17), true, false, ""}, + + geTestCase{uint32((1 << 32) - 1), true, false, ""}, + geTestCase{uint32(0), true, false, ""}, + geTestCase{uint32(17), true, false, ""}, + + geTestCase{uint64((1 << 64) - 1), true, false, ""}, + geTestCase{uint64(0), true, false, ""}, + geTestCase{uint64(17), true, false, ""}, + + geTestCase{uintptr((1 << 64) - 1), true, false, ""}, + geTestCase{uintptr(0), true, false, ""}, + geTestCase{uintptr(17), true, false, ""}, + + // Floating point. + geTestCase{float32(-(1 << 30)), false, false, ""}, + geTestCase{float32(-1), false, false, ""}, + geTestCase{float32(-0.1), false, false, ""}, + geTestCase{float32(-0.0), true, false, ""}, + geTestCase{float32(0), true, false, ""}, + geTestCase{float32(0.1), true, false, ""}, + geTestCase{float32(17), true, false, ""}, + geTestCase{float32(160), true, false, ""}, + + geTestCase{float64(-(1 << 30)), false, false, ""}, + geTestCase{float64(-1), false, false, ""}, + geTestCase{float64(-0.1), false, false, ""}, + geTestCase{float64(-0), true, false, ""}, + geTestCase{float64(0), true, false, ""}, + geTestCase{float64(17), true, false, ""}, + geTestCase{float64(160), true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterOrEqualTest) PositiveIntegerLiteral() { + matcher := GreaterOrEqual(150) + desc := matcher.Description() + expectedDesc := "greater than or equal to 150" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []geTestCase{ + // Signed integers. + geTestCase{-1, false, false, ""}, + geTestCase{149, false, false, ""}, + geTestCase{150, true, false, ""}, + geTestCase{151, true, false, ""}, + + geTestCase{int(-1), false, false, ""}, + geTestCase{int(149), false, false, ""}, + geTestCase{int(150), true, false, ""}, + geTestCase{int(151), true, false, ""}, + + geTestCase{int8(-1), false, false, ""}, + geTestCase{int8(0), false, false, ""}, + geTestCase{int8(17), false, false, ""}, + geTestCase{int8(127), false, false, ""}, + + geTestCase{int16(-1), false, false, ""}, + geTestCase{int16(149), false, false, ""}, + geTestCase{int16(150), true, false, ""}, + geTestCase{int16(151), true, false, ""}, + + geTestCase{int32(-1), false, false, ""}, + geTestCase{int32(149), false, false, ""}, + geTestCase{int32(150), true, false, ""}, + geTestCase{int32(151), true, false, ""}, + + geTestCase{int64(-1), false, false, ""}, + geTestCase{int64(149), false, false, ""}, + geTestCase{int64(150), true, false, ""}, + geTestCase{int64(151), true, false, ""}, + + // Unsigned integers. + geTestCase{uint(0), false, false, ""}, + geTestCase{uint(149), false, false, ""}, + geTestCase{uint(150), true, false, ""}, + geTestCase{uint(151), true, false, ""}, + + geTestCase{uint8(0), false, false, ""}, + geTestCase{uint8(127), false, false, ""}, + + geTestCase{uint16(0), false, false, ""}, + geTestCase{uint16(149), false, false, ""}, + geTestCase{uint16(150), true, false, ""}, + geTestCase{uint16(151), true, false, ""}, + + geTestCase{uint32(0), false, false, ""}, + geTestCase{uint32(149), false, false, ""}, + geTestCase{uint32(150), true, false, ""}, + geTestCase{uint32(151), true, false, ""}, + + geTestCase{uint64(0), false, false, ""}, + geTestCase{uint64(149), false, false, ""}, + geTestCase{uint64(150), true, false, ""}, + geTestCase{uint64(151), true, false, ""}, + + geTestCase{uintptr(0), false, false, ""}, + geTestCase{uintptr(149), false, false, ""}, + geTestCase{uintptr(150), true, false, ""}, + geTestCase{uintptr(151), true, false, ""}, + + // Floating point. + geTestCase{float32(-1), false, false, ""}, + geTestCase{float32(149), false, false, ""}, + geTestCase{float32(149.9), false, false, ""}, + geTestCase{float32(150), true, false, ""}, + geTestCase{float32(150.1), true, false, ""}, + geTestCase{float32(151), true, false, ""}, + + geTestCase{float64(-1), false, false, ""}, + geTestCase{float64(149), false, false, ""}, + geTestCase{float64(149.9), false, false, ""}, + geTestCase{float64(150), true, false, ""}, + geTestCase{float64(150.1), true, false, ""}, + geTestCase{float64(151), true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// Float literals +//////////////////////////////////////////////////////////////////////// + +func (t *GreaterOrEqualTest) NegativeFloatLiteral() { + matcher := GreaterOrEqual(-150.1) + desc := matcher.Description() + expectedDesc := "greater than or equal to -150.1" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []geTestCase{ + // Signed integers. + geTestCase{-(1 << 30), false, false, ""}, + geTestCase{-151, false, false, ""}, + geTestCase{-150, true, false, ""}, + geTestCase{0, true, false, ""}, + geTestCase{17, true, false, ""}, + + geTestCase{int(-(1 << 30)), false, false, ""}, + geTestCase{int(-151), false, false, ""}, + geTestCase{int(-150), true, false, ""}, + geTestCase{int(0), true, false, ""}, + geTestCase{int(17), true, false, ""}, + + geTestCase{int8(-127), true, false, ""}, + geTestCase{int8(0), true, false, ""}, + geTestCase{int8(17), true, false, ""}, + + geTestCase{int16(-(1 << 14)), false, false, ""}, + geTestCase{int16(-151), false, false, ""}, + geTestCase{int16(-150), true, false, ""}, + geTestCase{int16(0), true, false, ""}, + geTestCase{int16(17), true, false, ""}, + + geTestCase{int32(-(1 << 30)), false, false, ""}, + geTestCase{int32(-151), false, false, ""}, + geTestCase{int32(-150), true, false, ""}, + geTestCase{int32(0), true, false, ""}, + geTestCase{int32(17), true, false, ""}, + + geTestCase{int64(-(1 << 30)), false, false, ""}, + geTestCase{int64(-151), false, false, ""}, + geTestCase{int64(-150), true, false, ""}, + geTestCase{int64(0), true, false, ""}, + geTestCase{int64(17), true, false, ""}, + + // Unsigned integers. + geTestCase{uint((1 << 32) - 151), true, false, ""}, + geTestCase{uint(0), true, false, ""}, + geTestCase{uint(17), true, false, ""}, + + geTestCase{uint8(0), true, false, ""}, + geTestCase{uint8(17), true, false, ""}, + geTestCase{uint8(253), true, false, ""}, + + geTestCase{uint16((1 << 16) - 151), true, false, ""}, + geTestCase{uint16(0), true, false, ""}, + geTestCase{uint16(17), true, false, ""}, + + geTestCase{uint32((1 << 32) - 151), true, false, ""}, + geTestCase{uint32(0), true, false, ""}, + geTestCase{uint32(17), true, false, ""}, + + geTestCase{uint64((1 << 64) - 151), true, false, ""}, + geTestCase{uint64(0), true, false, ""}, + geTestCase{uint64(17), true, false, ""}, + + geTestCase{uintptr((1 << 64) - 151), true, false, ""}, + geTestCase{uintptr(0), true, false, ""}, + geTestCase{uintptr(17), true, false, ""}, + + // Floating point. + geTestCase{float32(-(1 << 30)), false, false, ""}, + geTestCase{float32(-151), false, false, ""}, + geTestCase{float32(-150.2), false, false, ""}, + geTestCase{float32(-150.1), true, false, ""}, + geTestCase{float32(-150), true, false, ""}, + geTestCase{float32(0), true, false, ""}, + geTestCase{float32(17), true, false, ""}, + geTestCase{float32(160), true, false, ""}, + + geTestCase{float64(-(1 << 30)), false, false, ""}, + geTestCase{float64(-151), false, false, ""}, + geTestCase{float64(-150.2), false, false, ""}, + geTestCase{float64(-150.1), true, false, ""}, + geTestCase{float64(-150), true, false, ""}, + geTestCase{float64(0), true, false, ""}, + geTestCase{float64(17), true, false, ""}, + geTestCase{float64(160), true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterOrEqualTest) PositiveFloatLiteral() { + matcher := GreaterOrEqual(149.9) + desc := matcher.Description() + expectedDesc := "greater than or equal to 149.9" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []geTestCase{ + // Signed integers. + geTestCase{-1, false, false, ""}, + geTestCase{149, false, false, ""}, + geTestCase{150, true, false, ""}, + geTestCase{151, true, false, ""}, + + geTestCase{int(-1), false, false, ""}, + geTestCase{int(149), false, false, ""}, + geTestCase{int(150), true, false, ""}, + geTestCase{int(151), true, false, ""}, + + geTestCase{int8(-1), false, false, ""}, + geTestCase{int8(0), false, false, ""}, + geTestCase{int8(17), false, false, ""}, + geTestCase{int8(127), false, false, ""}, + + geTestCase{int16(-1), false, false, ""}, + geTestCase{int16(149), false, false, ""}, + geTestCase{int16(150), true, false, ""}, + geTestCase{int16(151), true, false, ""}, + + geTestCase{int32(-1), false, false, ""}, + geTestCase{int32(149), false, false, ""}, + geTestCase{int32(150), true, false, ""}, + geTestCase{int32(151), true, false, ""}, + + geTestCase{int64(-1), false, false, ""}, + geTestCase{int64(149), false, false, ""}, + geTestCase{int64(150), true, false, ""}, + geTestCase{int64(151), true, false, ""}, + + // Unsigned integers. + geTestCase{uint(0), false, false, ""}, + geTestCase{uint(149), false, false, ""}, + geTestCase{uint(150), true, false, ""}, + geTestCase{uint(151), true, false, ""}, + + geTestCase{uint8(0), false, false, ""}, + geTestCase{uint8(127), false, false, ""}, + + geTestCase{uint16(0), false, false, ""}, + geTestCase{uint16(149), false, false, ""}, + geTestCase{uint16(150), true, false, ""}, + geTestCase{uint16(151), true, false, ""}, + + geTestCase{uint32(0), false, false, ""}, + geTestCase{uint32(149), false, false, ""}, + geTestCase{uint32(150), true, false, ""}, + geTestCase{uint32(151), true, false, ""}, + + geTestCase{uint64(0), false, false, ""}, + geTestCase{uint64(149), false, false, ""}, + geTestCase{uint64(150), true, false, ""}, + geTestCase{uint64(151), true, false, ""}, + + geTestCase{uintptr(0), false, false, ""}, + geTestCase{uintptr(149), false, false, ""}, + geTestCase{uintptr(150), true, false, ""}, + geTestCase{uintptr(151), true, false, ""}, + + // Floating point. + geTestCase{float32(-1), false, false, ""}, + geTestCase{float32(149), false, false, ""}, + geTestCase{float32(149.8), false, false, ""}, + geTestCase{float32(149.9), true, false, ""}, + geTestCase{float32(150), true, false, ""}, + geTestCase{float32(151), true, false, ""}, + + geTestCase{float64(-1), false, false, ""}, + geTestCase{float64(149), false, false, ""}, + geTestCase{float64(149.8), false, false, ""}, + geTestCase{float64(149.9), true, false, ""}, + geTestCase{float64(150), true, false, ""}, + geTestCase{float64(151), true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// Subtle cases +//////////////////////////////////////////////////////////////////////// + +func (t *GreaterOrEqualTest) Int64NotExactlyRepresentableBySinglePrecision() { + // Single-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo25 = 1 << 25 + matcher := GreaterOrEqual(int64(kTwoTo25 + 1)) + + desc := matcher.Description() + expectedDesc := "greater than or equal to 33554433" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []geTestCase{ + // Signed integers. + geTestCase{-1, false, false, ""}, + geTestCase{kTwoTo25 + 0, false, false, ""}, + geTestCase{kTwoTo25 + 1, true, false, ""}, + geTestCase{kTwoTo25 + 2, true, false, ""}, + + geTestCase{int(-1), false, false, ""}, + geTestCase{int(kTwoTo25 + 0), false, false, ""}, + geTestCase{int(kTwoTo25 + 1), true, false, ""}, + geTestCase{int(kTwoTo25 + 2), true, false, ""}, + + geTestCase{int8(-1), false, false, ""}, + geTestCase{int8(127), false, false, ""}, + + geTestCase{int16(-1), false, false, ""}, + geTestCase{int16(0), false, false, ""}, + geTestCase{int16(32767), false, false, ""}, + + geTestCase{int32(-1), false, false, ""}, + geTestCase{int32(kTwoTo25 + 0), false, false, ""}, + geTestCase{int32(kTwoTo25 + 1), true, false, ""}, + geTestCase{int32(kTwoTo25 + 2), true, false, ""}, + + geTestCase{int64(-1), false, false, ""}, + geTestCase{int64(kTwoTo25 + 0), false, false, ""}, + geTestCase{int64(kTwoTo25 + 1), true, false, ""}, + geTestCase{int64(kTwoTo25 + 2), true, false, ""}, + + // Unsigned integers. + geTestCase{uint(0), false, false, ""}, + geTestCase{uint(kTwoTo25 + 0), false, false, ""}, + geTestCase{uint(kTwoTo25 + 1), true, false, ""}, + geTestCase{uint(kTwoTo25 + 2), true, false, ""}, + + geTestCase{uint8(0), false, false, ""}, + geTestCase{uint8(255), false, false, ""}, + + geTestCase{uint16(0), false, false, ""}, + geTestCase{uint16(65535), false, false, ""}, + + geTestCase{uint32(0), false, false, ""}, + geTestCase{uint32(kTwoTo25 + 0), false, false, ""}, + geTestCase{uint32(kTwoTo25 + 1), true, false, ""}, + geTestCase{uint32(kTwoTo25 + 2), true, false, ""}, + + geTestCase{uint64(0), false, false, ""}, + geTestCase{uint64(kTwoTo25 + 0), false, false, ""}, + geTestCase{uint64(kTwoTo25 + 1), true, false, ""}, + geTestCase{uint64(kTwoTo25 + 2), true, false, ""}, + + geTestCase{uintptr(0), false, false, ""}, + geTestCase{uintptr(kTwoTo25 + 0), false, false, ""}, + geTestCase{uintptr(kTwoTo25 + 1), true, false, ""}, + geTestCase{uintptr(kTwoTo25 + 2), true, false, ""}, + + // Floating point. + geTestCase{float32(-1), false, false, ""}, + geTestCase{float32(kTwoTo25 - 2), false, false, ""}, + geTestCase{float32(kTwoTo25 - 1), true, false, ""}, + geTestCase{float32(kTwoTo25 + 0), true, false, ""}, + geTestCase{float32(kTwoTo25 + 1), true, false, ""}, + geTestCase{float32(kTwoTo25 + 2), true, false, ""}, + geTestCase{float32(kTwoTo25 + 3), true, false, ""}, + + geTestCase{float64(-1), false, false, ""}, + geTestCase{float64(kTwoTo25 - 2), false, false, ""}, + geTestCase{float64(kTwoTo25 - 1), false, false, ""}, + geTestCase{float64(kTwoTo25 + 0), false, false, ""}, + geTestCase{float64(kTwoTo25 + 1), true, false, ""}, + geTestCase{float64(kTwoTo25 + 2), true, false, ""}, + geTestCase{float64(kTwoTo25 + 3), true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterOrEqualTest) Int64NotExactlyRepresentableByDoublePrecision() { + // Double-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^54-1, 2^54+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo54 = 1 << 54 + matcher := GreaterOrEqual(int64(kTwoTo54 + 1)) + + desc := matcher.Description() + expectedDesc := "greater than or equal to 18014398509481985" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []geTestCase{ + // Signed integers. + geTestCase{-1, false, false, ""}, + geTestCase{1 << 30, false, false, ""}, + + geTestCase{int(-1), false, false, ""}, + geTestCase{int(math.MaxInt32), false, false, ""}, + + geTestCase{int8(-1), false, false, ""}, + geTestCase{int8(127), false, false, ""}, + + geTestCase{int16(-1), false, false, ""}, + geTestCase{int16(0), false, false, ""}, + geTestCase{int16(32767), false, false, ""}, + + geTestCase{int32(-1), false, false, ""}, + geTestCase{int32(math.MaxInt32), false, false, ""}, + + geTestCase{int64(-1), false, false, ""}, + geTestCase{int64(kTwoTo54 - 1), false, false, ""}, + geTestCase{int64(kTwoTo54 + 0), false, false, ""}, + geTestCase{int64(kTwoTo54 + 1), true, false, ""}, + geTestCase{int64(kTwoTo54 + 2), true, false, ""}, + + // Unsigned integers. + geTestCase{uint(0), false, false, ""}, + geTestCase{uint(math.MaxUint32), false, false, ""}, + + geTestCase{uint8(0), false, false, ""}, + geTestCase{uint8(255), false, false, ""}, + + geTestCase{uint16(0), false, false, ""}, + geTestCase{uint16(65535), false, false, ""}, + + geTestCase{uint32(0), false, false, ""}, + geTestCase{uint32(math.MaxUint32), false, false, ""}, + + geTestCase{uint64(0), false, false, ""}, + geTestCase{uint64(kTwoTo54 - 1), false, false, ""}, + geTestCase{uint64(kTwoTo54 + 0), false, false, ""}, + geTestCase{uint64(kTwoTo54 + 1), true, false, ""}, + geTestCase{uint64(kTwoTo54 + 2), true, false, ""}, + + geTestCase{uintptr(0), false, false, ""}, + geTestCase{uintptr(kTwoTo54 - 1), false, false, ""}, + geTestCase{uintptr(kTwoTo54 + 0), false, false, ""}, + geTestCase{uintptr(kTwoTo54 + 1), true, false, ""}, + geTestCase{uintptr(kTwoTo54 + 2), true, false, ""}, + + // Floating point. + geTestCase{float64(-1), false, false, ""}, + geTestCase{float64(kTwoTo54 - 2), false, false, ""}, + geTestCase{float64(kTwoTo54 - 1), true, false, ""}, + geTestCase{float64(kTwoTo54 + 0), true, false, ""}, + geTestCase{float64(kTwoTo54 + 1), true, false, ""}, + geTestCase{float64(kTwoTo54 + 2), true, false, ""}, + geTestCase{float64(kTwoTo54 + 3), true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterOrEqualTest) Uint64NotExactlyRepresentableBySinglePrecision() { + // Single-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo25 = 1 << 25 + matcher := GreaterOrEqual(uint64(kTwoTo25 + 1)) + + desc := matcher.Description() + expectedDesc := "greater than or equal to 33554433" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []geTestCase{ + // Signed integers. + geTestCase{-1, false, false, ""}, + geTestCase{kTwoTo25 + 0, false, false, ""}, + geTestCase{kTwoTo25 + 1, true, false, ""}, + geTestCase{kTwoTo25 + 2, true, false, ""}, + + geTestCase{int(-1), false, false, ""}, + geTestCase{int(kTwoTo25 + 0), false, false, ""}, + geTestCase{int(kTwoTo25 + 1), true, false, ""}, + geTestCase{int(kTwoTo25 + 2), true, false, ""}, + + geTestCase{int8(-1), false, false, ""}, + geTestCase{int8(127), false, false, ""}, + + geTestCase{int16(-1), false, false, ""}, + geTestCase{int16(0), false, false, ""}, + geTestCase{int16(32767), false, false, ""}, + + geTestCase{int32(-1), false, false, ""}, + geTestCase{int32(kTwoTo25 + 0), false, false, ""}, + geTestCase{int32(kTwoTo25 + 1), true, false, ""}, + geTestCase{int32(kTwoTo25 + 2), true, false, ""}, + + geTestCase{int64(-1), false, false, ""}, + geTestCase{int64(kTwoTo25 + 0), false, false, ""}, + geTestCase{int64(kTwoTo25 + 1), true, false, ""}, + geTestCase{int64(kTwoTo25 + 2), true, false, ""}, + + // Unsigned integers. + geTestCase{uint(0), false, false, ""}, + geTestCase{uint(kTwoTo25 + 0), false, false, ""}, + geTestCase{uint(kTwoTo25 + 1), true, false, ""}, + geTestCase{uint(kTwoTo25 + 2), true, false, ""}, + + geTestCase{uint8(0), false, false, ""}, + geTestCase{uint8(255), false, false, ""}, + + geTestCase{uint16(0), false, false, ""}, + geTestCase{uint16(65535), false, false, ""}, + + geTestCase{uint32(0), false, false, ""}, + geTestCase{uint32(kTwoTo25 + 0), false, false, ""}, + geTestCase{uint32(kTwoTo25 + 1), true, false, ""}, + geTestCase{uint32(kTwoTo25 + 2), true, false, ""}, + + geTestCase{uint64(0), false, false, ""}, + geTestCase{uint64(kTwoTo25 + 0), false, false, ""}, + geTestCase{uint64(kTwoTo25 + 1), true, false, ""}, + geTestCase{uint64(kTwoTo25 + 2), true, false, ""}, + + geTestCase{uintptr(0), false, false, ""}, + geTestCase{uintptr(kTwoTo25 + 0), false, false, ""}, + geTestCase{uintptr(kTwoTo25 + 1), true, false, ""}, + geTestCase{uintptr(kTwoTo25 + 2), true, false, ""}, + + // Floating point. + geTestCase{float32(-1), false, false, ""}, + geTestCase{float32(kTwoTo25 - 2), false, false, ""}, + geTestCase{float32(kTwoTo25 - 1), true, false, ""}, + geTestCase{float32(kTwoTo25 + 0), true, false, ""}, + geTestCase{float32(kTwoTo25 + 1), true, false, ""}, + geTestCase{float32(kTwoTo25 + 2), true, false, ""}, + geTestCase{float32(kTwoTo25 + 3), true, false, ""}, + + geTestCase{float64(-1), false, false, ""}, + geTestCase{float64(kTwoTo25 - 2), false, false, ""}, + geTestCase{float64(kTwoTo25 - 1), false, false, ""}, + geTestCase{float64(kTwoTo25 + 0), false, false, ""}, + geTestCase{float64(kTwoTo25 + 1), true, false, ""}, + geTestCase{float64(kTwoTo25 + 2), true, false, ""}, + geTestCase{float64(kTwoTo25 + 3), true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterOrEqualTest) Uint64NotExactlyRepresentableByDoublePrecision() { + // Double-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^54-1, 2^54+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo54 = 1 << 54 + matcher := GreaterOrEqual(uint64(kTwoTo54 + 1)) + + desc := matcher.Description() + expectedDesc := "greater than or equal to 18014398509481985" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []geTestCase{ + // Signed integers. + geTestCase{-1, false, false, ""}, + geTestCase{1 << 30, false, false, ""}, + + geTestCase{int(-1), false, false, ""}, + geTestCase{int(math.MaxInt32), false, false, ""}, + + geTestCase{int8(-1), false, false, ""}, + geTestCase{int8(127), false, false, ""}, + + geTestCase{int16(-1), false, false, ""}, + geTestCase{int16(0), false, false, ""}, + geTestCase{int16(32767), false, false, ""}, + + geTestCase{int32(-1), false, false, ""}, + geTestCase{int32(math.MaxInt32), false, false, ""}, + + geTestCase{int64(-1), false, false, ""}, + geTestCase{int64(kTwoTo54 - 1), false, false, ""}, + geTestCase{int64(kTwoTo54 + 0), false, false, ""}, + geTestCase{int64(kTwoTo54 + 1), true, false, ""}, + geTestCase{int64(kTwoTo54 + 2), true, false, ""}, + + // Unsigned integers. + geTestCase{uint(0), false, false, ""}, + geTestCase{uint(math.MaxUint32), false, false, ""}, + + geTestCase{uint8(0), false, false, ""}, + geTestCase{uint8(255), false, false, ""}, + + geTestCase{uint16(0), false, false, ""}, + geTestCase{uint16(65535), false, false, ""}, + + geTestCase{uint32(0), false, false, ""}, + geTestCase{uint32(math.MaxUint32), false, false, ""}, + + geTestCase{uint64(0), false, false, ""}, + geTestCase{uint64(kTwoTo54 - 1), false, false, ""}, + geTestCase{uint64(kTwoTo54 + 0), false, false, ""}, + geTestCase{uint64(kTwoTo54 + 1), true, false, ""}, + geTestCase{uint64(kTwoTo54 + 2), true, false, ""}, + + geTestCase{uintptr(0), false, false, ""}, + geTestCase{uintptr(kTwoTo54 - 1), false, false, ""}, + geTestCase{uintptr(kTwoTo54 + 0), false, false, ""}, + geTestCase{uintptr(kTwoTo54 + 1), true, false, ""}, + geTestCase{uintptr(kTwoTo54 + 2), true, false, ""}, + + // Floating point. + geTestCase{float64(-1), false, false, ""}, + geTestCase{float64(kTwoTo54 - 2), false, false, ""}, + geTestCase{float64(kTwoTo54 - 1), true, false, ""}, + geTestCase{float64(kTwoTo54 + 0), true, false, ""}, + geTestCase{float64(kTwoTo54 + 1), true, false, ""}, + geTestCase{float64(kTwoTo54 + 2), true, false, ""}, + geTestCase{float64(kTwoTo54 + 3), true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterOrEqualTest) Float32AboveExactIntegerRange() { + // Single-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo25 = 1 << 25 + matcher := GreaterOrEqual(float32(kTwoTo25 + 1)) + + desc := matcher.Description() + expectedDesc := "greater than or equal to 3.3554432e+07" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []geTestCase{ + // Signed integers. + geTestCase{int64(-1), false, false, ""}, + geTestCase{int64(kTwoTo25 - 2), false, false, ""}, + geTestCase{int64(kTwoTo25 - 1), true, false, ""}, + geTestCase{int64(kTwoTo25 + 0), true, false, ""}, + geTestCase{int64(kTwoTo25 + 1), true, false, ""}, + geTestCase{int64(kTwoTo25 + 2), true, false, ""}, + geTestCase{int64(kTwoTo25 + 3), true, false, ""}, + + // Unsigned integers. + geTestCase{uint64(0), false, false, ""}, + geTestCase{uint64(kTwoTo25 - 2), false, false, ""}, + geTestCase{uint64(kTwoTo25 - 1), true, false, ""}, + geTestCase{uint64(kTwoTo25 + 0), true, false, ""}, + geTestCase{uint64(kTwoTo25 + 1), true, false, ""}, + geTestCase{uint64(kTwoTo25 + 2), true, false, ""}, + geTestCase{uint64(kTwoTo25 + 3), true, false, ""}, + + // Floating point. + geTestCase{float32(-1), false, false, ""}, + geTestCase{float32(kTwoTo25 - 2), false, false, ""}, + geTestCase{float32(kTwoTo25 - 1), true, false, ""}, + geTestCase{float32(kTwoTo25 + 0), true, false, ""}, + geTestCase{float32(kTwoTo25 + 1), true, false, ""}, + geTestCase{float32(kTwoTo25 + 2), true, false, ""}, + geTestCase{float32(kTwoTo25 + 3), true, false, ""}, + + geTestCase{float64(-1), false, false, ""}, + geTestCase{float64(kTwoTo25 - 2), false, false, ""}, + geTestCase{float64(kTwoTo25 - 1), true, false, ""}, + geTestCase{float64(kTwoTo25 + 0), true, false, ""}, + geTestCase{float64(kTwoTo25 + 1), true, false, ""}, + geTestCase{float64(kTwoTo25 + 2), true, false, ""}, + geTestCase{float64(kTwoTo25 + 3), true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterOrEqualTest) Float64AboveExactIntegerRange() { + // Double-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^54-1, 2^54+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo54 = 1 << 54 + matcher := GreaterOrEqual(float64(kTwoTo54 + 1)) + + desc := matcher.Description() + expectedDesc := "greater than or equal to 1.8014398509481984e+16" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []geTestCase{ + // Signed integers. + geTestCase{int64(-1), false, false, ""}, + geTestCase{int64(kTwoTo54 - 2), false, false, ""}, + geTestCase{int64(kTwoTo54 - 1), true, false, ""}, + geTestCase{int64(kTwoTo54 + 0), true, false, ""}, + geTestCase{int64(kTwoTo54 + 1), true, false, ""}, + geTestCase{int64(kTwoTo54 + 2), true, false, ""}, + geTestCase{int64(kTwoTo54 + 3), true, false, ""}, + + // Unsigned integers. + geTestCase{uint64(0), false, false, ""}, + geTestCase{uint64(kTwoTo54 - 2), false, false, ""}, + geTestCase{uint64(kTwoTo54 - 1), true, false, ""}, + geTestCase{uint64(kTwoTo54 + 0), true, false, ""}, + geTestCase{uint64(kTwoTo54 + 1), true, false, ""}, + geTestCase{uint64(kTwoTo54 + 2), true, false, ""}, + geTestCase{uint64(kTwoTo54 + 3), true, false, ""}, + + // Floating point. + geTestCase{float64(-1), false, false, ""}, + geTestCase{float64(kTwoTo54 - 2), false, false, ""}, + geTestCase{float64(kTwoTo54 - 1), true, false, ""}, + geTestCase{float64(kTwoTo54 + 0), true, false, ""}, + geTestCase{float64(kTwoTo54 + 1), true, false, ""}, + geTestCase{float64(kTwoTo54 + 2), true, false, ""}, + geTestCase{float64(kTwoTo54 + 3), true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// String literals +//////////////////////////////////////////////////////////////////////// + +func (t *GreaterOrEqualTest) EmptyString() { + matcher := GreaterOrEqual("") + desc := matcher.Description() + expectedDesc := "greater than or equal to \"\"" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []geTestCase{ + geTestCase{"", true, false, ""}, + geTestCase{"\x00", true, false, ""}, + geTestCase{"a", true, false, ""}, + geTestCase{"foo", true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterOrEqualTest) SingleNullByte() { + matcher := GreaterOrEqual("\x00") + desc := matcher.Description() + expectedDesc := "greater than or equal to \"\x00\"" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []geTestCase{ + geTestCase{"", false, false, ""}, + geTestCase{"\x00", true, false, ""}, + geTestCase{"a", true, false, ""}, + geTestCase{"foo", true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterOrEqualTest) LongerString() { + matcher := GreaterOrEqual("foo\x00") + desc := matcher.Description() + expectedDesc := "greater than or equal to \"foo\x00\"" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []geTestCase{ + geTestCase{"", false, false, ""}, + geTestCase{"\x00", false, false, ""}, + geTestCase{"bar", false, false, ""}, + geTestCase{"foo", false, false, ""}, + geTestCase{"foo\x00", true, false, ""}, + geTestCase{"fooa", true, false, ""}, + geTestCase{"qux", true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/greater_than.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/greater_than.go new file mode 100644 index 00000000000..3eef32178f8 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/greater_than.go @@ -0,0 +1,39 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package oglematchers + +import ( + "fmt" + "reflect" +) + +// GreaterThan returns a matcher that matches integer, floating point, or +// strings values v such that v > x. Comparison is not defined between numeric +// and string types, but is defined between all integer and floating point +// types. +// +// x must itself be an integer, floating point, or string type; otherwise, +// GreaterThan will panic. +func GreaterThan(x interface{}) Matcher { + desc := fmt.Sprintf("greater than %v", x) + + // Special case: make it clear that strings are strings. + if reflect.TypeOf(x).Kind() == reflect.String { + desc = fmt.Sprintf("greater than \"%s\"", x) + } + + return transformDescription(Not(LessOrEqual(x)), desc) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/greater_than_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/greater_than_test.go new file mode 100644 index 00000000000..bf70fe56633 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/greater_than_test.go @@ -0,0 +1,1077 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package oglematchers_test + +import ( + "math" + + . "github.com/smartystreets/assertions/internal/oglematchers" + . "github.com/smartystreets/assertions/internal/ogletest" +) + +//////////////////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////////////////// + +type GreaterThanTest struct { +} + +func init() { RegisterTestSuite(&GreaterThanTest{}) } + +type gtTestCase struct { + candidate interface{} + expectedResult bool + shouldBeFatal bool + expectedError string +} + +func (t *GreaterThanTest) checkTestCases(matcher Matcher, cases []gtTestCase) { + for i, c := range cases { + err := matcher.Matches(c.candidate) + + ExpectThat( + (err == nil), + Equals(c.expectedResult), + "Case %d (candidate %v)", + i, + c.candidate) + + if err == nil { + continue + } + + _, isFatal := err.(*FatalError) + ExpectEq( + c.shouldBeFatal, + isFatal, + "Case %d (candidate %v)", + i, + c.candidate) + + ExpectThat( + err, + Error(Equals(c.expectedError)), + "Case %d (candidate %v)", + i, + c.candidate) + } +} + +//////////////////////////////////////////////////////////////////////// +// Integer literals +//////////////////////////////////////////////////////////////////////// + +func (t *GreaterThanTest) IntegerCandidateBadTypes() { + matcher := GreaterThan(int(-150)) + + cases := []gtTestCase{ + gtTestCase{true, false, true, "which is not comparable"}, + gtTestCase{complex64(-151), false, true, "which is not comparable"}, + gtTestCase{complex128(-151), false, true, "which is not comparable"}, + gtTestCase{[...]int{-151}, false, true, "which is not comparable"}, + gtTestCase{make(chan int), false, true, "which is not comparable"}, + gtTestCase{func() {}, false, true, "which is not comparable"}, + gtTestCase{map[int]int{}, false, true, "which is not comparable"}, + gtTestCase{>TestCase{}, false, true, "which is not comparable"}, + gtTestCase{make([]int, 0), false, true, "which is not comparable"}, + gtTestCase{"-151", false, true, "which is not comparable"}, + gtTestCase{gtTestCase{}, false, true, "which is not comparable"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterThanTest) FloatCandidateBadTypes() { + matcher := GreaterThan(float32(-150)) + + cases := []gtTestCase{ + gtTestCase{true, false, true, "which is not comparable"}, + gtTestCase{complex64(-151), false, true, "which is not comparable"}, + gtTestCase{complex128(-151), false, true, "which is not comparable"}, + gtTestCase{[...]int{-151}, false, true, "which is not comparable"}, + gtTestCase{make(chan int), false, true, "which is not comparable"}, + gtTestCase{func() {}, false, true, "which is not comparable"}, + gtTestCase{map[int]int{}, false, true, "which is not comparable"}, + gtTestCase{>TestCase{}, false, true, "which is not comparable"}, + gtTestCase{make([]int, 0), false, true, "which is not comparable"}, + gtTestCase{"-151", false, true, "which is not comparable"}, + gtTestCase{gtTestCase{}, false, true, "which is not comparable"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterThanTest) StringCandidateBadTypes() { + matcher := GreaterThan("17") + + cases := []gtTestCase{ + gtTestCase{true, false, true, "which is not comparable"}, + gtTestCase{int(0), false, true, "which is not comparable"}, + gtTestCase{int8(0), false, true, "which is not comparable"}, + gtTestCase{int16(0), false, true, "which is not comparable"}, + gtTestCase{int32(0), false, true, "which is not comparable"}, + gtTestCase{int64(0), false, true, "which is not comparable"}, + gtTestCase{uint(0), false, true, "which is not comparable"}, + gtTestCase{uint8(0), false, true, "which is not comparable"}, + gtTestCase{uint16(0), false, true, "which is not comparable"}, + gtTestCase{uint32(0), false, true, "which is not comparable"}, + gtTestCase{uint64(0), false, true, "which is not comparable"}, + gtTestCase{float32(0), false, true, "which is not comparable"}, + gtTestCase{float64(0), false, true, "which is not comparable"}, + gtTestCase{complex64(-151), false, true, "which is not comparable"}, + gtTestCase{complex128(-151), false, true, "which is not comparable"}, + gtTestCase{[...]int{-151}, false, true, "which is not comparable"}, + gtTestCase{make(chan int), false, true, "which is not comparable"}, + gtTestCase{func() {}, false, true, "which is not comparable"}, + gtTestCase{map[int]int{}, false, true, "which is not comparable"}, + gtTestCase{>TestCase{}, false, true, "which is not comparable"}, + gtTestCase{make([]int, 0), false, true, "which is not comparable"}, + gtTestCase{gtTestCase{}, false, true, "which is not comparable"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterThanTest) BadArgument() { + panicked := false + + defer func() { + ExpectThat(panicked, Equals(true)) + }() + + defer func() { + if r := recover(); r != nil { + panicked = true + } + }() + + GreaterThan(complex128(0)) +} + +//////////////////////////////////////////////////////////////////////// +// Integer literals +//////////////////////////////////////////////////////////////////////// + +func (t *GreaterThanTest) NegativeIntegerLiteral() { + matcher := GreaterThan(-150) + desc := matcher.Description() + expectedDesc := "greater than -150" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []gtTestCase{ + // Signed integers. + gtTestCase{-(1 << 30), false, false, ""}, + gtTestCase{-151, false, false, ""}, + gtTestCase{-150, false, false, ""}, + gtTestCase{-149, true, false, ""}, + gtTestCase{0, true, false, ""}, + gtTestCase{17, true, false, ""}, + + gtTestCase{int(-(1 << 30)), false, false, ""}, + gtTestCase{int(-151), false, false, ""}, + gtTestCase{int(-150), false, false, ""}, + gtTestCase{int(-149), true, false, ""}, + gtTestCase{int(0), true, false, ""}, + gtTestCase{int(17), true, false, ""}, + + gtTestCase{int8(-127), true, false, ""}, + gtTestCase{int8(0), true, false, ""}, + gtTestCase{int8(17), true, false, ""}, + + gtTestCase{int16(-(1 << 14)), false, false, ""}, + gtTestCase{int16(-151), false, false, ""}, + gtTestCase{int16(-150), false, false, ""}, + gtTestCase{int16(-149), true, false, ""}, + gtTestCase{int16(0), true, false, ""}, + gtTestCase{int16(17), true, false, ""}, + + gtTestCase{int32(-(1 << 30)), false, false, ""}, + gtTestCase{int32(-151), false, false, ""}, + gtTestCase{int32(-150), false, false, ""}, + gtTestCase{int32(-149), true, false, ""}, + gtTestCase{int32(0), true, false, ""}, + gtTestCase{int32(17), true, false, ""}, + + gtTestCase{int64(-(1 << 30)), false, false, ""}, + gtTestCase{int64(-151), false, false, ""}, + gtTestCase{int64(-150), false, false, ""}, + gtTestCase{int64(-149), true, false, ""}, + gtTestCase{int64(0), true, false, ""}, + gtTestCase{int64(17), true, false, ""}, + + // Unsigned integers. + gtTestCase{uint((1 << 32) - 151), true, false, ""}, + gtTestCase{uint(0), true, false, ""}, + gtTestCase{uint(17), true, false, ""}, + + gtTestCase{uint8(0), true, false, ""}, + gtTestCase{uint8(17), true, false, ""}, + gtTestCase{uint8(253), true, false, ""}, + + gtTestCase{uint16((1 << 16) - 151), true, false, ""}, + gtTestCase{uint16(0), true, false, ""}, + gtTestCase{uint16(17), true, false, ""}, + + gtTestCase{uint32((1 << 32) - 151), true, false, ""}, + gtTestCase{uint32(0), true, false, ""}, + gtTestCase{uint32(17), true, false, ""}, + + gtTestCase{uint64((1 << 64) - 151), true, false, ""}, + gtTestCase{uint64(0), true, false, ""}, + gtTestCase{uint64(17), true, false, ""}, + + // Floating point. + gtTestCase{float32(-(1 << 30)), false, false, ""}, + gtTestCase{float32(-151), false, false, ""}, + gtTestCase{float32(-150.1), false, false, ""}, + gtTestCase{float32(-150), false, false, ""}, + gtTestCase{float32(-149.9), true, false, ""}, + gtTestCase{float32(0), true, false, ""}, + gtTestCase{float32(17), true, false, ""}, + gtTestCase{float32(160), true, false, ""}, + + gtTestCase{float64(-(1 << 30)), false, false, ""}, + gtTestCase{float64(-151), false, false, ""}, + gtTestCase{float64(-150.1), false, false, ""}, + gtTestCase{float64(-150), false, false, ""}, + gtTestCase{float64(-149.9), true, false, ""}, + gtTestCase{float64(0), true, false, ""}, + gtTestCase{float64(17), true, false, ""}, + gtTestCase{float64(160), true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterThanTest) ZeroIntegerLiteral() { + matcher := GreaterThan(0) + desc := matcher.Description() + expectedDesc := "greater than 0" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []gtTestCase{ + // Signed integers. + gtTestCase{-(1 << 30), false, false, ""}, + gtTestCase{-1, false, false, ""}, + gtTestCase{0, false, false, ""}, + gtTestCase{1, true, false, ""}, + gtTestCase{17, true, false, ""}, + gtTestCase{(1 << 30), true, false, ""}, + + gtTestCase{int(-(1 << 30)), false, false, ""}, + gtTestCase{int(-1), false, false, ""}, + gtTestCase{int(0), false, false, ""}, + gtTestCase{int(1), true, false, ""}, + gtTestCase{int(17), true, false, ""}, + + gtTestCase{int8(-1), false, false, ""}, + gtTestCase{int8(0), false, false, ""}, + gtTestCase{int8(1), true, false, ""}, + + gtTestCase{int16(-(1 << 14)), false, false, ""}, + gtTestCase{int16(-1), false, false, ""}, + gtTestCase{int16(0), false, false, ""}, + gtTestCase{int16(1), true, false, ""}, + gtTestCase{int16(17), true, false, ""}, + + gtTestCase{int32(-(1 << 30)), false, false, ""}, + gtTestCase{int32(-1), false, false, ""}, + gtTestCase{int32(0), false, false, ""}, + gtTestCase{int32(1), true, false, ""}, + gtTestCase{int32(17), true, false, ""}, + + gtTestCase{int64(-(1 << 30)), false, false, ""}, + gtTestCase{int64(-1), false, false, ""}, + gtTestCase{int64(0), false, false, ""}, + gtTestCase{int64(1), true, false, ""}, + gtTestCase{int64(17), true, false, ""}, + + // Unsigned integers. + gtTestCase{uint((1 << 32) - 1), true, false, ""}, + gtTestCase{uint(0), false, false, ""}, + gtTestCase{uint(1), true, false, ""}, + gtTestCase{uint(17), true, false, ""}, + + gtTestCase{uint8(0), false, false, ""}, + gtTestCase{uint8(1), true, false, ""}, + gtTestCase{uint8(17), true, false, ""}, + gtTestCase{uint8(253), true, false, ""}, + + gtTestCase{uint16((1 << 16) - 1), true, false, ""}, + gtTestCase{uint16(0), false, false, ""}, + gtTestCase{uint16(1), true, false, ""}, + gtTestCase{uint16(17), true, false, ""}, + + gtTestCase{uint32((1 << 32) - 1), true, false, ""}, + gtTestCase{uint32(0), false, false, ""}, + gtTestCase{uint32(1), true, false, ""}, + gtTestCase{uint32(17), true, false, ""}, + + gtTestCase{uint64((1 << 64) - 1), true, false, ""}, + gtTestCase{uint64(0), false, false, ""}, + gtTestCase{uint64(1), true, false, ""}, + gtTestCase{uint64(17), true, false, ""}, + + // Floating point. + gtTestCase{float32(-(1 << 30)), false, false, ""}, + gtTestCase{float32(-1), false, false, ""}, + gtTestCase{float32(-0.1), false, false, ""}, + gtTestCase{float32(-0.0), false, false, ""}, + gtTestCase{float32(0), false, false, ""}, + gtTestCase{float32(0.1), true, false, ""}, + gtTestCase{float32(17), true, false, ""}, + gtTestCase{float32(160), true, false, ""}, + + gtTestCase{float64(-(1 << 30)), false, false, ""}, + gtTestCase{float64(-1), false, false, ""}, + gtTestCase{float64(-0.1), false, false, ""}, + gtTestCase{float64(-0), false, false, ""}, + gtTestCase{float64(0), false, false, ""}, + gtTestCase{float64(0.1), true, false, ""}, + gtTestCase{float64(17), true, false, ""}, + gtTestCase{float64(160), true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterThanTest) PositiveIntegerLiteral() { + matcher := GreaterThan(150) + desc := matcher.Description() + expectedDesc := "greater than 150" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []gtTestCase{ + // Signed integers. + gtTestCase{-1, false, false, ""}, + gtTestCase{149, false, false, ""}, + gtTestCase{150, false, false, ""}, + gtTestCase{151, true, false, ""}, + + gtTestCase{int(-1), false, false, ""}, + gtTestCase{int(149), false, false, ""}, + gtTestCase{int(150), false, false, ""}, + gtTestCase{int(151), true, false, ""}, + + gtTestCase{int8(-1), false, false, ""}, + gtTestCase{int8(0), false, false, ""}, + gtTestCase{int8(17), false, false, ""}, + gtTestCase{int8(127), false, false, ""}, + + gtTestCase{int16(-1), false, false, ""}, + gtTestCase{int16(149), false, false, ""}, + gtTestCase{int16(150), false, false, ""}, + gtTestCase{int16(151), true, false, ""}, + + gtTestCase{int32(-1), false, false, ""}, + gtTestCase{int32(149), false, false, ""}, + gtTestCase{int32(150), false, false, ""}, + gtTestCase{int32(151), true, false, ""}, + + gtTestCase{int64(-1), false, false, ""}, + gtTestCase{int64(149), false, false, ""}, + gtTestCase{int64(150), false, false, ""}, + gtTestCase{int64(151), true, false, ""}, + + // Unsigned integers. + gtTestCase{uint(0), false, false, ""}, + gtTestCase{uint(149), false, false, ""}, + gtTestCase{uint(150), false, false, ""}, + gtTestCase{uint(151), true, false, ""}, + + gtTestCase{uint8(0), false, false, ""}, + gtTestCase{uint8(127), false, false, ""}, + + gtTestCase{uint16(0), false, false, ""}, + gtTestCase{uint16(149), false, false, ""}, + gtTestCase{uint16(150), false, false, ""}, + gtTestCase{uint16(151), true, false, ""}, + + gtTestCase{uint32(0), false, false, ""}, + gtTestCase{uint32(149), false, false, ""}, + gtTestCase{uint32(150), false, false, ""}, + gtTestCase{uint32(151), true, false, ""}, + + gtTestCase{uint64(0), false, false, ""}, + gtTestCase{uint64(149), false, false, ""}, + gtTestCase{uint64(150), false, false, ""}, + gtTestCase{uint64(151), true, false, ""}, + + // Floating point. + gtTestCase{float32(-1), false, false, ""}, + gtTestCase{float32(149), false, false, ""}, + gtTestCase{float32(149.9), false, false, ""}, + gtTestCase{float32(150), false, false, ""}, + gtTestCase{float32(150.1), true, false, ""}, + gtTestCase{float32(151), true, false, ""}, + + gtTestCase{float64(-1), false, false, ""}, + gtTestCase{float64(149), false, false, ""}, + gtTestCase{float64(149.9), false, false, ""}, + gtTestCase{float64(150), false, false, ""}, + gtTestCase{float64(150.1), true, false, ""}, + gtTestCase{float64(151), true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// Float literals +//////////////////////////////////////////////////////////////////////// + +func (t *GreaterThanTest) NegativeFloatLiteral() { + matcher := GreaterThan(-150.1) + desc := matcher.Description() + expectedDesc := "greater than -150.1" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []gtTestCase{ + // Signed integers. + gtTestCase{-(1 << 30), false, false, ""}, + gtTestCase{-151, false, false, ""}, + gtTestCase{-150.1, false, false, ""}, + gtTestCase{-150, true, false, ""}, + gtTestCase{-149, true, false, ""}, + gtTestCase{0, true, false, ""}, + gtTestCase{17, true, false, ""}, + + gtTestCase{int(-(1 << 30)), false, false, ""}, + gtTestCase{int(-151), false, false, ""}, + gtTestCase{int(-150), true, false, ""}, + gtTestCase{int(-149), true, false, ""}, + gtTestCase{int(0), true, false, ""}, + gtTestCase{int(17), true, false, ""}, + + gtTestCase{int8(-127), true, false, ""}, + gtTestCase{int8(0), true, false, ""}, + gtTestCase{int8(17), true, false, ""}, + + gtTestCase{int16(-(1 << 14)), false, false, ""}, + gtTestCase{int16(-151), false, false, ""}, + gtTestCase{int16(-150), true, false, ""}, + gtTestCase{int16(-149), true, false, ""}, + gtTestCase{int16(0), true, false, ""}, + gtTestCase{int16(17), true, false, ""}, + + gtTestCase{int32(-(1 << 30)), false, false, ""}, + gtTestCase{int32(-151), false, false, ""}, + gtTestCase{int32(-150), true, false, ""}, + gtTestCase{int32(-149), true, false, ""}, + gtTestCase{int32(0), true, false, ""}, + gtTestCase{int32(17), true, false, ""}, + + gtTestCase{int64(-(1 << 30)), false, false, ""}, + gtTestCase{int64(-151), false, false, ""}, + gtTestCase{int64(-150), true, false, ""}, + gtTestCase{int64(-149), true, false, ""}, + gtTestCase{int64(0), true, false, ""}, + gtTestCase{int64(17), true, false, ""}, + + // Unsigned integers. + gtTestCase{uint((1 << 32) - 151), true, false, ""}, + gtTestCase{uint(0), true, false, ""}, + gtTestCase{uint(17), true, false, ""}, + + gtTestCase{uint8(0), true, false, ""}, + gtTestCase{uint8(17), true, false, ""}, + gtTestCase{uint8(253), true, false, ""}, + + gtTestCase{uint16((1 << 16) - 151), true, false, ""}, + gtTestCase{uint16(0), true, false, ""}, + gtTestCase{uint16(17), true, false, ""}, + + gtTestCase{uint32((1 << 32) - 151), true, false, ""}, + gtTestCase{uint32(0), true, false, ""}, + gtTestCase{uint32(17), true, false, ""}, + + gtTestCase{uint64((1 << 64) - 151), true, false, ""}, + gtTestCase{uint64(0), true, false, ""}, + gtTestCase{uint64(17), true, false, ""}, + + // Floating point. + gtTestCase{float32(-(1 << 30)), false, false, ""}, + gtTestCase{float32(-151), false, false, ""}, + gtTestCase{float32(-150.2), false, false, ""}, + gtTestCase{float32(-150.1), false, false, ""}, + gtTestCase{float32(-150), true, false, ""}, + gtTestCase{float32(0), true, false, ""}, + gtTestCase{float32(17), true, false, ""}, + gtTestCase{float32(160), true, false, ""}, + + gtTestCase{float64(-(1 << 30)), false, false, ""}, + gtTestCase{float64(-151), false, false, ""}, + gtTestCase{float64(-150.2), false, false, ""}, + gtTestCase{float64(-150.1), false, false, ""}, + gtTestCase{float64(-150), true, false, ""}, + gtTestCase{float64(0), true, false, ""}, + gtTestCase{float64(17), true, false, ""}, + gtTestCase{float64(160), true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterThanTest) PositiveFloatLiteral() { + matcher := GreaterThan(149.9) + desc := matcher.Description() + expectedDesc := "greater than 149.9" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []gtTestCase{ + // Signed integers. + gtTestCase{-1, false, false, ""}, + gtTestCase{149, false, false, ""}, + gtTestCase{149.9, false, false, ""}, + gtTestCase{150, true, false, ""}, + gtTestCase{151, true, false, ""}, + + gtTestCase{int(-1), false, false, ""}, + gtTestCase{int(149), false, false, ""}, + gtTestCase{int(150), true, false, ""}, + gtTestCase{int(151), true, false, ""}, + + gtTestCase{int8(-1), false, false, ""}, + gtTestCase{int8(0), false, false, ""}, + gtTestCase{int8(17), false, false, ""}, + gtTestCase{int8(127), false, false, ""}, + + gtTestCase{int16(-1), false, false, ""}, + gtTestCase{int16(149), false, false, ""}, + gtTestCase{int16(150), true, false, ""}, + gtTestCase{int16(151), true, false, ""}, + + gtTestCase{int32(-1), false, false, ""}, + gtTestCase{int32(149), false, false, ""}, + gtTestCase{int32(150), true, false, ""}, + gtTestCase{int32(151), true, false, ""}, + + gtTestCase{int64(-1), false, false, ""}, + gtTestCase{int64(149), false, false, ""}, + gtTestCase{int64(150), true, false, ""}, + gtTestCase{int64(151), true, false, ""}, + + // Unsigned integers. + gtTestCase{uint(0), false, false, ""}, + gtTestCase{uint(149), false, false, ""}, + gtTestCase{uint(150), true, false, ""}, + gtTestCase{uint(151), true, false, ""}, + + gtTestCase{uint8(0), false, false, ""}, + gtTestCase{uint8(127), false, false, ""}, + + gtTestCase{uint16(0), false, false, ""}, + gtTestCase{uint16(149), false, false, ""}, + gtTestCase{uint16(150), true, false, ""}, + gtTestCase{uint16(151), true, false, ""}, + + gtTestCase{uint32(0), false, false, ""}, + gtTestCase{uint32(149), false, false, ""}, + gtTestCase{uint32(150), true, false, ""}, + gtTestCase{uint32(151), true, false, ""}, + + gtTestCase{uint64(0), false, false, ""}, + gtTestCase{uint64(149), false, false, ""}, + gtTestCase{uint64(150), true, false, ""}, + gtTestCase{uint64(151), true, false, ""}, + + // Floating point. + gtTestCase{float32(-1), false, false, ""}, + gtTestCase{float32(149), false, false, ""}, + gtTestCase{float32(149.8), false, false, ""}, + gtTestCase{float32(149.9), false, false, ""}, + gtTestCase{float32(150), true, false, ""}, + gtTestCase{float32(151), true, false, ""}, + + gtTestCase{float64(-1), false, false, ""}, + gtTestCase{float64(149), false, false, ""}, + gtTestCase{float64(149.8), false, false, ""}, + gtTestCase{float64(149.9), false, false, ""}, + gtTestCase{float64(150), true, false, ""}, + gtTestCase{float64(151), true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// Subtle cases +//////////////////////////////////////////////////////////////////////// + +func (t *GreaterThanTest) Int64NotExactlyRepresentableBySinglePrecision() { + // Single-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo25 = 1 << 25 + matcher := GreaterThan(int64(kTwoTo25 + 1)) + + desc := matcher.Description() + expectedDesc := "greater than 33554433" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []gtTestCase{ + // Signed integers. + gtTestCase{-1, false, false, ""}, + gtTestCase{kTwoTo25 + 0, false, false, ""}, + gtTestCase{kTwoTo25 + 1, false, false, ""}, + gtTestCase{kTwoTo25 + 2, true, false, ""}, + + gtTestCase{int(-1), false, false, ""}, + gtTestCase{int(kTwoTo25 + 0), false, false, ""}, + gtTestCase{int(kTwoTo25 + 1), false, false, ""}, + gtTestCase{int(kTwoTo25 + 2), true, false, ""}, + + gtTestCase{int8(-1), false, false, ""}, + gtTestCase{int8(127), false, false, ""}, + + gtTestCase{int16(-1), false, false, ""}, + gtTestCase{int16(0), false, false, ""}, + gtTestCase{int16(32767), false, false, ""}, + + gtTestCase{int32(-1), false, false, ""}, + gtTestCase{int32(kTwoTo25 + 0), false, false, ""}, + gtTestCase{int32(kTwoTo25 + 1), false, false, ""}, + gtTestCase{int32(kTwoTo25 + 2), true, false, ""}, + + gtTestCase{int64(-1), false, false, ""}, + gtTestCase{int64(kTwoTo25 + 0), false, false, ""}, + gtTestCase{int64(kTwoTo25 + 1), false, false, ""}, + gtTestCase{int64(kTwoTo25 + 2), true, false, ""}, + + // Unsigned integers. + gtTestCase{uint(0), false, false, ""}, + gtTestCase{uint(kTwoTo25 + 0), false, false, ""}, + gtTestCase{uint(kTwoTo25 + 1), false, false, ""}, + gtTestCase{uint(kTwoTo25 + 2), true, false, ""}, + + gtTestCase{uint8(0), false, false, ""}, + gtTestCase{uint8(255), false, false, ""}, + + gtTestCase{uint16(0), false, false, ""}, + gtTestCase{uint16(65535), false, false, ""}, + + gtTestCase{uint32(0), false, false, ""}, + gtTestCase{uint32(kTwoTo25 + 0), false, false, ""}, + gtTestCase{uint32(kTwoTo25 + 1), false, false, ""}, + gtTestCase{uint32(kTwoTo25 + 2), true, false, ""}, + + gtTestCase{uint64(0), false, false, ""}, + gtTestCase{uint64(kTwoTo25 + 0), false, false, ""}, + gtTestCase{uint64(kTwoTo25 + 1), false, false, ""}, + gtTestCase{uint64(kTwoTo25 + 2), true, false, ""}, + + // Floating point. + gtTestCase{float32(-1), false, false, ""}, + gtTestCase{float32(kTwoTo25 - 2), false, false, ""}, + gtTestCase{float32(kTwoTo25 - 1), false, false, ""}, + gtTestCase{float32(kTwoTo25 + 0), false, false, ""}, + gtTestCase{float32(kTwoTo25 + 1), false, false, ""}, + gtTestCase{float32(kTwoTo25 + 2), false, false, ""}, + gtTestCase{float32(kTwoTo25 + 3), true, false, ""}, + + gtTestCase{float64(-1), false, false, ""}, + gtTestCase{float64(kTwoTo25 - 2), false, false, ""}, + gtTestCase{float64(kTwoTo25 - 1), false, false, ""}, + gtTestCase{float64(kTwoTo25 + 0), false, false, ""}, + gtTestCase{float64(kTwoTo25 + 1), false, false, ""}, + gtTestCase{float64(kTwoTo25 + 2), true, false, ""}, + gtTestCase{float64(kTwoTo25 + 3), true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterThanTest) Int64NotExactlyRepresentableByDoublePrecision() { + // Double-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^54-1, 2^54+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo54 = 1 << 54 + matcher := GreaterThan(int64(kTwoTo54 + 1)) + + desc := matcher.Description() + expectedDesc := "greater than 18014398509481985" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []gtTestCase{ + // Signed integers. + gtTestCase{-1, false, false, ""}, + gtTestCase{1 << 30, false, false, ""}, + + gtTestCase{int(-1), false, false, ""}, + gtTestCase{int(math.MaxInt32), false, false, ""}, + + gtTestCase{int8(-1), false, false, ""}, + gtTestCase{int8(127), false, false, ""}, + + gtTestCase{int16(-1), false, false, ""}, + gtTestCase{int16(0), false, false, ""}, + gtTestCase{int16(32767), false, false, ""}, + + gtTestCase{int32(-1), false, false, ""}, + gtTestCase{int32(math.MaxInt32), false, false, ""}, + + gtTestCase{int64(-1), false, false, ""}, + gtTestCase{int64(kTwoTo54 - 1), false, false, ""}, + gtTestCase{int64(kTwoTo54 + 0), false, false, ""}, + gtTestCase{int64(kTwoTo54 + 1), false, false, ""}, + gtTestCase{int64(kTwoTo54 + 2), true, false, ""}, + + // Unsigned integers. + gtTestCase{uint(0), false, false, ""}, + gtTestCase{uint(math.MaxUint32), false, false, ""}, + + gtTestCase{uint8(0), false, false, ""}, + gtTestCase{uint8(255), false, false, ""}, + + gtTestCase{uint16(0), false, false, ""}, + gtTestCase{uint16(65535), false, false, ""}, + + gtTestCase{uint32(0), false, false, ""}, + gtTestCase{uint32(math.MaxUint32), false, false, ""}, + + gtTestCase{uint64(0), false, false, ""}, + gtTestCase{uint64(kTwoTo54 - 1), false, false, ""}, + gtTestCase{uint64(kTwoTo54 + 0), false, false, ""}, + gtTestCase{uint64(kTwoTo54 + 1), false, false, ""}, + gtTestCase{uint64(kTwoTo54 + 2), true, false, ""}, + + // Floating point. + gtTestCase{float64(-1), false, false, ""}, + gtTestCase{float64(kTwoTo54 - 2), false, false, ""}, + gtTestCase{float64(kTwoTo54 - 1), false, false, ""}, + gtTestCase{float64(kTwoTo54 + 0), false, false, ""}, + gtTestCase{float64(kTwoTo54 + 1), false, false, ""}, + gtTestCase{float64(kTwoTo54 + 2), false, false, ""}, + gtTestCase{float64(kTwoTo54 + 3), true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterThanTest) Uint64NotExactlyRepresentableBySinglePrecision() { + // Single-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo25 = 1 << 25 + matcher := GreaterThan(uint64(kTwoTo25 + 1)) + + desc := matcher.Description() + expectedDesc := "greater than 33554433" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []gtTestCase{ + // Signed integers. + gtTestCase{-1, false, false, ""}, + gtTestCase{kTwoTo25 + 0, false, false, ""}, + gtTestCase{kTwoTo25 + 1, false, false, ""}, + gtTestCase{kTwoTo25 + 2, true, false, ""}, + + gtTestCase{int(-1), false, false, ""}, + gtTestCase{int(kTwoTo25 + 0), false, false, ""}, + gtTestCase{int(kTwoTo25 + 1), false, false, ""}, + gtTestCase{int(kTwoTo25 + 2), true, false, ""}, + + gtTestCase{int8(-1), false, false, ""}, + gtTestCase{int8(127), false, false, ""}, + + gtTestCase{int16(-1), false, false, ""}, + gtTestCase{int16(0), false, false, ""}, + gtTestCase{int16(32767), false, false, ""}, + + gtTestCase{int32(-1), false, false, ""}, + gtTestCase{int32(kTwoTo25 + 0), false, false, ""}, + gtTestCase{int32(kTwoTo25 + 1), false, false, ""}, + gtTestCase{int32(kTwoTo25 + 2), true, false, ""}, + + gtTestCase{int64(-1), false, false, ""}, + gtTestCase{int64(kTwoTo25 + 0), false, false, ""}, + gtTestCase{int64(kTwoTo25 + 1), false, false, ""}, + gtTestCase{int64(kTwoTo25 + 2), true, false, ""}, + + // Unsigned integers. + gtTestCase{uint(0), false, false, ""}, + gtTestCase{uint(kTwoTo25 + 0), false, false, ""}, + gtTestCase{uint(kTwoTo25 + 1), false, false, ""}, + gtTestCase{uint(kTwoTo25 + 2), true, false, ""}, + + gtTestCase{uint8(0), false, false, ""}, + gtTestCase{uint8(255), false, false, ""}, + + gtTestCase{uint16(0), false, false, ""}, + gtTestCase{uint16(65535), false, false, ""}, + + gtTestCase{uint32(0), false, false, ""}, + gtTestCase{uint32(kTwoTo25 + 0), false, false, ""}, + gtTestCase{uint32(kTwoTo25 + 1), false, false, ""}, + gtTestCase{uint32(kTwoTo25 + 2), true, false, ""}, + + gtTestCase{uint64(0), false, false, ""}, + gtTestCase{uint64(kTwoTo25 + 0), false, false, ""}, + gtTestCase{uint64(kTwoTo25 + 1), false, false, ""}, + gtTestCase{uint64(kTwoTo25 + 2), true, false, ""}, + + // Floating point. + gtTestCase{float32(-1), false, false, ""}, + gtTestCase{float32(kTwoTo25 - 2), false, false, ""}, + gtTestCase{float32(kTwoTo25 - 1), false, false, ""}, + gtTestCase{float32(kTwoTo25 + 0), false, false, ""}, + gtTestCase{float32(kTwoTo25 + 1), false, false, ""}, + gtTestCase{float32(kTwoTo25 + 2), false, false, ""}, + gtTestCase{float32(kTwoTo25 + 3), true, false, ""}, + + gtTestCase{float64(-1), false, false, ""}, + gtTestCase{float64(kTwoTo25 - 2), false, false, ""}, + gtTestCase{float64(kTwoTo25 - 1), false, false, ""}, + gtTestCase{float64(kTwoTo25 + 0), false, false, ""}, + gtTestCase{float64(kTwoTo25 + 1), false, false, ""}, + gtTestCase{float64(kTwoTo25 + 2), true, false, ""}, + gtTestCase{float64(kTwoTo25 + 3), true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterThanTest) Uint64NotExactlyRepresentableByDoublePrecision() { + // Double-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^54-1, 2^54+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo54 = 1 << 54 + matcher := GreaterThan(uint64(kTwoTo54 + 1)) + + desc := matcher.Description() + expectedDesc := "greater than 18014398509481985" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []gtTestCase{ + // Signed integers. + gtTestCase{-1, false, false, ""}, + gtTestCase{1 << 30, false, false, ""}, + + gtTestCase{int(-1), false, false, ""}, + gtTestCase{int(math.MaxInt32), false, false, ""}, + + gtTestCase{int8(-1), false, false, ""}, + gtTestCase{int8(127), false, false, ""}, + + gtTestCase{int16(-1), false, false, ""}, + gtTestCase{int16(0), false, false, ""}, + gtTestCase{int16(32767), false, false, ""}, + + gtTestCase{int32(-1), false, false, ""}, + gtTestCase{int32(math.MaxInt32), false, false, ""}, + + gtTestCase{int64(-1), false, false, ""}, + gtTestCase{int64(kTwoTo54 - 1), false, false, ""}, + gtTestCase{int64(kTwoTo54 + 0), false, false, ""}, + gtTestCase{int64(kTwoTo54 + 1), false, false, ""}, + gtTestCase{int64(kTwoTo54 + 2), true, false, ""}, + + // Unsigned integers. + gtTestCase{uint(0), false, false, ""}, + gtTestCase{uint(math.MaxUint32), false, false, ""}, + + gtTestCase{uint8(0), false, false, ""}, + gtTestCase{uint8(255), false, false, ""}, + + gtTestCase{uint16(0), false, false, ""}, + gtTestCase{uint16(65535), false, false, ""}, + + gtTestCase{uint32(0), false, false, ""}, + gtTestCase{uint32(math.MaxUint32), false, false, ""}, + + gtTestCase{uint64(0), false, false, ""}, + gtTestCase{uint64(kTwoTo54 - 1), false, false, ""}, + gtTestCase{uint64(kTwoTo54 + 0), false, false, ""}, + gtTestCase{uint64(kTwoTo54 + 1), false, false, ""}, + gtTestCase{uint64(kTwoTo54 + 2), true, false, ""}, + + // Floating point. + gtTestCase{float64(-1), false, false, ""}, + gtTestCase{float64(kTwoTo54 - 2), false, false, ""}, + gtTestCase{float64(kTwoTo54 - 1), false, false, ""}, + gtTestCase{float64(kTwoTo54 + 0), false, false, ""}, + gtTestCase{float64(kTwoTo54 + 1), false, false, ""}, + gtTestCase{float64(kTwoTo54 + 2), false, false, ""}, + gtTestCase{float64(kTwoTo54 + 3), true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterThanTest) Float32AboveExactIntegerRange() { + // Single-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo25 = 1 << 25 + matcher := GreaterThan(float32(kTwoTo25 + 1)) + + desc := matcher.Description() + expectedDesc := "greater than 3.3554432e+07" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []gtTestCase{ + // Signed integers. + gtTestCase{int64(-1), false, false, ""}, + gtTestCase{int64(kTwoTo25 - 2), false, false, ""}, + gtTestCase{int64(kTwoTo25 - 1), false, false, ""}, + gtTestCase{int64(kTwoTo25 + 0), false, false, ""}, + gtTestCase{int64(kTwoTo25 + 1), false, false, ""}, + gtTestCase{int64(kTwoTo25 + 2), false, false, ""}, + gtTestCase{int64(kTwoTo25 + 3), true, false, ""}, + + // Unsigned integers. + gtTestCase{uint64(0), false, false, ""}, + gtTestCase{uint64(kTwoTo25 - 2), false, false, ""}, + gtTestCase{uint64(kTwoTo25 - 1), false, false, ""}, + gtTestCase{uint64(kTwoTo25 + 0), false, false, ""}, + gtTestCase{uint64(kTwoTo25 + 1), false, false, ""}, + gtTestCase{uint64(kTwoTo25 + 2), false, false, ""}, + gtTestCase{uint64(kTwoTo25 + 3), true, false, ""}, + + // Floating point. + gtTestCase{float32(-1), false, false, ""}, + gtTestCase{float32(kTwoTo25 - 2), false, false, ""}, + gtTestCase{float32(kTwoTo25 - 1), false, false, ""}, + gtTestCase{float32(kTwoTo25 + 0), false, false, ""}, + gtTestCase{float32(kTwoTo25 + 1), false, false, ""}, + gtTestCase{float32(kTwoTo25 + 2), false, false, ""}, + gtTestCase{float32(kTwoTo25 + 3), true, false, ""}, + + gtTestCase{float64(-1), false, false, ""}, + gtTestCase{float64(kTwoTo25 - 2), false, false, ""}, + gtTestCase{float64(kTwoTo25 - 1), false, false, ""}, + gtTestCase{float64(kTwoTo25 + 0), false, false, ""}, + gtTestCase{float64(kTwoTo25 + 1), false, false, ""}, + gtTestCase{float64(kTwoTo25 + 2), false, false, ""}, + gtTestCase{float64(kTwoTo25 + 3), true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterThanTest) Float64AboveExactIntegerRange() { + // Double-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^54-1, 2^54+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo54 = 1 << 54 + matcher := GreaterThan(float64(kTwoTo54 + 1)) + + desc := matcher.Description() + expectedDesc := "greater than 1.8014398509481984e+16" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []gtTestCase{ + // Signed integers. + gtTestCase{int64(-1), false, false, ""}, + gtTestCase{int64(kTwoTo54 - 2), false, false, ""}, + gtTestCase{int64(kTwoTo54 - 1), false, false, ""}, + gtTestCase{int64(kTwoTo54 + 0), false, false, ""}, + gtTestCase{int64(kTwoTo54 + 1), false, false, ""}, + gtTestCase{int64(kTwoTo54 + 2), false, false, ""}, + gtTestCase{int64(kTwoTo54 + 3), true, false, ""}, + + // Unsigned integers. + gtTestCase{uint64(0), false, false, ""}, + gtTestCase{uint64(kTwoTo54 - 2), false, false, ""}, + gtTestCase{uint64(kTwoTo54 - 1), false, false, ""}, + gtTestCase{uint64(kTwoTo54 + 0), false, false, ""}, + gtTestCase{uint64(kTwoTo54 + 1), false, false, ""}, + gtTestCase{uint64(kTwoTo54 + 2), false, false, ""}, + gtTestCase{uint64(kTwoTo54 + 3), true, false, ""}, + + // Floating point. + gtTestCase{float64(-1), false, false, ""}, + gtTestCase{float64(kTwoTo54 - 2), false, false, ""}, + gtTestCase{float64(kTwoTo54 - 1), false, false, ""}, + gtTestCase{float64(kTwoTo54 + 0), false, false, ""}, + gtTestCase{float64(kTwoTo54 + 1), false, false, ""}, + gtTestCase{float64(kTwoTo54 + 2), false, false, ""}, + gtTestCase{float64(kTwoTo54 + 3), true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// String literals +//////////////////////////////////////////////////////////////////////// + +func (t *GreaterThanTest) EmptyString() { + matcher := GreaterThan("") + desc := matcher.Description() + expectedDesc := "greater than \"\"" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []gtTestCase{ + gtTestCase{"", false, false, ""}, + gtTestCase{"\x00", true, false, ""}, + gtTestCase{"a", true, false, ""}, + gtTestCase{"foo", true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterThanTest) SingleNullByte() { + matcher := GreaterThan("\x00") + desc := matcher.Description() + expectedDesc := "greater than \"\x00\"" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []gtTestCase{ + gtTestCase{"", false, false, ""}, + gtTestCase{"\x00", false, false, ""}, + gtTestCase{"\x00\x00", true, false, ""}, + gtTestCase{"a", true, false, ""}, + gtTestCase{"foo", true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *GreaterThanTest) LongerString() { + matcher := GreaterThan("foo\x00") + desc := matcher.Description() + expectedDesc := "greater than \"foo\x00\"" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []gtTestCase{ + gtTestCase{"", false, false, ""}, + gtTestCase{"\x00", false, false, ""}, + gtTestCase{"bar", false, false, ""}, + gtTestCase{"foo", false, false, ""}, + gtTestCase{"foo\x00", false, false, ""}, + gtTestCase{"foo\x00\x00", true, false, ""}, + gtTestCase{"fooa", true, false, ""}, + gtTestCase{"qux", true, false, ""}, + } + + t.checkTestCases(matcher, cases) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/has_same_type_as.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/has_same_type_as.go new file mode 100644 index 00000000000..3b286f73218 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/has_same_type_as.go @@ -0,0 +1,37 @@ +// Copyright 2015 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package oglematchers + +import ( + "fmt" + "reflect" +) + +// HasSameTypeAs returns a matcher that matches values with exactly the same +// type as the supplied prototype. +func HasSameTypeAs(p interface{}) Matcher { + expected := reflect.TypeOf(p) + pred := func(c interface{}) error { + actual := reflect.TypeOf(c) + if actual != expected { + return fmt.Errorf("which has type %v", actual) + } + + return nil + } + + return NewMatcher(pred, fmt.Sprintf("has type %v", expected)) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/has_same_type_as_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/has_same_type_as_test.go new file mode 100644 index 00000000000..a4a3e308aa3 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/has_same_type_as_test.go @@ -0,0 +1,181 @@ +// Copyright 2015 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package oglematchers_test + +import ( + "io" + "testing" + + . "github.com/smartystreets/assertions/internal/oglematchers" + . "github.com/smartystreets/assertions/internal/ogletest" +) + +func TestHasSameTypeAs(t *testing.T) { RunTests(t) } + +//////////////////////////////////////////////////////////////////////// +// Boilerplate +//////////////////////////////////////////////////////////////////////// + +type HasSameTypeAsTest struct { +} + +func init() { RegisterTestSuite(&HasSameTypeAsTest{}) } + +//////////////////////////////////////////////////////////////////////// +// Tests +//////////////////////////////////////////////////////////////////////// + +func (t *HasSameTypeAsTest) CandidateIsLiteralNil() { + matcher := HasSameTypeAs(nil) + var err error + + // Description + ExpectEq("has type <nil>", matcher.Description()) + + // Literal nil + err = matcher.Matches(nil) + ExpectEq(nil, err) + + // nil in interface variable + var r io.Reader + err = matcher.Matches(r) + ExpectEq(nil, err) + + // int + err = matcher.Matches(17) + AssertNe(nil, err) + ExpectThat(err, Error(Equals("which has type int"))) + + // string + err = matcher.Matches("") + AssertNe(nil, err) + ExpectThat(err, Error(Equals("which has type string"))) + + // nil map + var m map[string]string + err = matcher.Matches(m) + + AssertNe(nil, err) + ExpectThat(err, Error(Equals("which has type map[string]string"))) + + // Non-nil map + m = make(map[string]string) + err = matcher.Matches(m) + + AssertNe(nil, err) + ExpectThat(err, Error(Equals("which has type map[string]string"))) +} + +func (t *HasSameTypeAsTest) CandidateIsNilMap() { + var m map[string]string + matcher := HasSameTypeAs(m) + var err error + + // Description + ExpectEq("has type map[string]string", matcher.Description()) + + // nil map + m = nil + err = matcher.Matches(m) + ExpectEq(nil, err) + + // Non-nil map + m = make(map[string]string) + err = matcher.Matches(m) + ExpectEq(nil, err) + + // Literal nil + err = matcher.Matches(nil) + AssertNe(nil, err) + ExpectThat(err, Error(Equals("which has type <nil>"))) + + // int + err = matcher.Matches(17) + AssertNe(nil, err) + ExpectThat(err, Error(Equals("which has type int"))) + + // string + err = matcher.Matches("") + AssertNe(nil, err) + ExpectThat(err, Error(Equals("which has type string"))) +} + +func (t *HasSameTypeAsTest) CandidateIsNilInInterfaceVariable() { + var r io.Reader + matcher := HasSameTypeAs(r) + var err error + + // Description + ExpectEq("has type <nil>", matcher.Description()) + + // nil in interface variable + r = nil + err = matcher.Matches(r) + ExpectEq(nil, err) + + // Literal nil + err = matcher.Matches(nil) + ExpectEq(nil, err) + + // int + err = matcher.Matches(17) + AssertNe(nil, err) + ExpectThat(err, Error(Equals("which has type int"))) +} + +func (t *HasSameTypeAsTest) CandidateIsString() { + matcher := HasSameTypeAs("") + var err error + + // Description + ExpectEq("has type string", matcher.Description()) + + // string + err = matcher.Matches("taco") + ExpectEq(nil, err) + + // string alias + type Foo string + err = matcher.Matches(Foo("taco")) + ExpectThat(err, Error(MatchesRegexp("which has type .*Foo"))) + + // Literal nil + err = matcher.Matches(nil) + AssertNe(nil, err) + ExpectThat(err, Error(Equals("which has type <nil>"))) + + // int + err = matcher.Matches(17) + AssertNe(nil, err) + ExpectThat(err, Error(Equals("which has type int"))) +} + +func (t *HasSameTypeAsTest) CandidateIsStringAlias() { + type Foo string + matcher := HasSameTypeAs(Foo("")) + var err error + + // Description + ExpectThat(matcher.Description(), MatchesRegexp("has type .*Foo")) + + // string alias + err = matcher.Matches(Foo("taco")) + ExpectEq(nil, err) + + // string + err = matcher.Matches("taco") + ExpectThat(err, Error(Equals("which has type string"))) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/has_substr.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/has_substr.go new file mode 100644 index 00000000000..bf5bd6ae6d3 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/has_substr.go @@ -0,0 +1,46 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package oglematchers + +import ( + "errors" + "fmt" + "reflect" + "strings" +) + +// HasSubstr returns a matcher that matches strings containing s as a +// substring. +func HasSubstr(s string) Matcher { + return NewMatcher( + func(c interface{}) error { return hasSubstr(s, c) }, + fmt.Sprintf("has substring \"%s\"", s)) +} + +func hasSubstr(needle string, c interface{}) error { + v := reflect.ValueOf(c) + if v.Kind() != reflect.String { + return NewFatalError("which is not a string") + } + + // Perform the substring search. + haystack := v.String() + if strings.Contains(haystack, needle) { + return nil + } + + return errors.New("") +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/has_substr_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/has_substr_test.go new file mode 100644 index 00000000000..6fc913a2490 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/has_substr_test.go @@ -0,0 +1,93 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package oglematchers_test + +import ( + . "github.com/smartystreets/assertions/internal/oglematchers" + . "github.com/smartystreets/assertions/internal/ogletest" +) + +//////////////////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////////////////// + +type HasSubstrTest struct { + +} + +func init() { RegisterTestSuite(&HasSubstrTest{}) } + +//////////////////////////////////////////////////////////////////////// +// Tests +//////////////////////////////////////////////////////////////////////// + +func (t *HasSubstrTest) Description() { + matcher := HasSubstr("taco") + ExpectThat(matcher.Description(), Equals("has substring \"taco\"")) +} + +func (t *HasSubstrTest) CandidateIsNil() { + matcher := HasSubstr("") + err := matcher.Matches(nil) + + ExpectThat(err, Error(Equals("which is not a string"))) + ExpectTrue(isFatal(err)) +} + +func (t *HasSubstrTest) CandidateIsInteger() { + matcher := HasSubstr("") + err := matcher.Matches(17) + + ExpectThat(err, Error(Equals("which is not a string"))) + ExpectTrue(isFatal(err)) +} + +func (t *HasSubstrTest) CandidateIsByteSlice() { + matcher := HasSubstr("") + err := matcher.Matches([]byte{17}) + + ExpectThat(err, Error(Equals("which is not a string"))) + ExpectTrue(isFatal(err)) +} + +func (t *HasSubstrTest) CandidateDoesntHaveSubstring() { + matcher := HasSubstr("taco") + err := matcher.Matches("tac") + + ExpectThat(err, Error(Equals(""))) + ExpectFalse(isFatal(err)) +} + +func (t *HasSubstrTest) CandidateEqualsArg() { + matcher := HasSubstr("taco") + err := matcher.Matches("taco") + + ExpectThat(err, Equals(nil)) +} + +func (t *HasSubstrTest) CandidateHasProperSubstring() { + matcher := HasSubstr("taco") + err := matcher.Matches("burritos and tacos") + + ExpectThat(err, Equals(nil)) +} + +func (t *HasSubstrTest) EmptyStringIsAlwaysSubString() { + matcher := HasSubstr("") + err := matcher.Matches("asdf") + + ExpectThat(err, Equals(nil)) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/identical_to.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/identical_to.go new file mode 100644 index 00000000000..ae6460ed966 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/identical_to.go @@ -0,0 +1,134 @@ +// Copyright 2012 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package oglematchers + +import ( + "errors" + "fmt" + "reflect" +) + +// Is the type comparable according to the definition here? +// +// http://weekly.golang.org/doc/go_spec.html#Comparison_operators +// +func isComparable(t reflect.Type) bool { + switch t.Kind() { + case reflect.Array: + return isComparable(t.Elem()) + + case reflect.Struct: + for i := 0; i < t.NumField(); i++ { + if !isComparable(t.Field(i).Type) { + return false + } + } + + return true + + case reflect.Slice, reflect.Map, reflect.Func: + return false + } + + return true +} + +// Should the supplied type be allowed as an argument to IdenticalTo? +func isLegalForIdenticalTo(t reflect.Type) (bool, error) { + // Allow the zero type. + if t == nil { + return true, nil + } + + // Reference types are always okay; we compare pointers. + switch t.Kind() { + case reflect.Slice, reflect.Map, reflect.Func, reflect.Chan: + return true, nil + } + + // Reject other non-comparable types. + if !isComparable(t) { + return false, errors.New(fmt.Sprintf("%v is not comparable", t)) + } + + return true, nil +} + +// IdenticalTo(x) returns a matcher that matches values v with type identical +// to x such that: +// +// 1. If v and x are of a reference type (slice, map, function, channel), then +// they are either both nil or are references to the same object. +// +// 2. Otherwise, if v and x are not of a reference type but have a valid type, +// then v == x. +// +// If v and x are both the invalid type (which results from the predeclared nil +// value, or from nil interface variables), then the matcher is satisfied. +// +// This function will panic if x is of a value type that is not comparable. For +// example, x cannot be an array of functions. +func IdenticalTo(x interface{}) Matcher { + t := reflect.TypeOf(x) + + // Reject illegal arguments. + if ok, err := isLegalForIdenticalTo(t); !ok { + panic("IdenticalTo: " + err.Error()) + } + + return &identicalToMatcher{x} +} + +type identicalToMatcher struct { + x interface{} +} + +func (m *identicalToMatcher) Description() string { + t := reflect.TypeOf(m.x) + return fmt.Sprintf("identical to <%v> %v", t, m.x) +} + +func (m *identicalToMatcher) Matches(c interface{}) error { + // Make sure the candidate's type is correct. + t := reflect.TypeOf(m.x) + if ct := reflect.TypeOf(c); t != ct { + return NewFatalError(fmt.Sprintf("which is of type %v", ct)) + } + + // Special case: two values of the invalid type are always identical. + if t == nil { + return nil + } + + // Handle reference types. + switch t.Kind() { + case reflect.Slice, reflect.Map, reflect.Func, reflect.Chan: + xv := reflect.ValueOf(m.x) + cv := reflect.ValueOf(c) + if xv.Pointer() == cv.Pointer() { + return nil + } + + return errors.New("which is not an identical reference") + } + + // Are the values equal? + if m.x == c { + return nil + } + + return errors.New("") +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/identical_to_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/identical_to_test.go new file mode 100644 index 00000000000..cc03b214ad6 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/identical_to_test.go @@ -0,0 +1,849 @@ +// Copyright 2012 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package oglematchers_test + +import ( + . "github.com/smartystreets/assertions/internal/oglematchers" + . "github.com/smartystreets/assertions/internal/ogletest" + "fmt" + "io" + "unsafe" +) + +//////////////////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////////////////// + +type IdenticalToTest struct { +} + +func init() { RegisterTestSuite(&IdenticalToTest{}) } + +//////////////////////////////////////////////////////////////////////// +// Tests +//////////////////////////////////////////////////////////////////////// + +func (t *IdenticalToTest) TypesNotIdentical() { + var m Matcher + var err error + + type intAlias int + + // Type alias expected value + m = IdenticalTo(intAlias(17)) + err = m.Matches(int(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type int"))) + + // Type alias candidate + m = IdenticalTo(int(17)) + err = m.Matches(intAlias(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type oglematchers_test.intAlias"))) + + // int and uint + m = IdenticalTo(int(17)) + err = m.Matches(uint(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type uint"))) +} + +func (t *IdenticalToTest) PredeclaredNilIdentifier() { + var m Matcher + var err error + + // Nil literal + m = IdenticalTo(nil) + err = m.Matches(nil) + ExpectEq(nil, err) + + // Zero interface var (which is the same as above since IdenticalTo takes an + // interface{} as an arg) + var nilReader io.Reader + var nilWriter io.Writer + + m = IdenticalTo(nilReader) + err = m.Matches(nilWriter) + ExpectEq(nil, err) + + // Typed nil value. + m = IdenticalTo(nil) + err = m.Matches((chan int)(nil)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type chan int"))) + + // Non-nil value. + m = IdenticalTo(nil) + err = m.Matches("taco") + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type string"))) +} + +func (t *IdenticalToTest) Slices() { + var m Matcher + var err error + + // Nil expected value + m = IdenticalTo(([]int)(nil)) + ExpectEq("identical to <[]int> []", m.Description()) + + err = m.Matches(([]int)(nil)) + ExpectEq(nil, err) + + err = m.Matches([]int{}) + ExpectThat(err, Error(Equals("which is not an identical reference"))) + + // Non-nil expected value + o1 := make([]int, 1) + o2 := make([]int, 1) + m = IdenticalTo(o1) + ExpectEq(fmt.Sprintf("identical to <[]int> %v", o1), m.Description()) + + err = m.Matches(o1) + ExpectEq(nil, err) + + err = m.Matches(o2) + ExpectThat(err, Error(Equals("which is not an identical reference"))) +} + +func (t *IdenticalToTest) Maps() { + var m Matcher + var err error + + // Nil expected value + m = IdenticalTo((map[int]int)(nil)) + ExpectEq("identical to <map[int]int> map[]", m.Description()) + + err = m.Matches((map[int]int)(nil)) + ExpectEq(nil, err) + + err = m.Matches(map[int]int{}) + ExpectThat(err, Error(Equals("which is not an identical reference"))) + + // Non-nil expected value + o1 := map[int]int{} + o2 := map[int]int{} + m = IdenticalTo(o1) + ExpectEq(fmt.Sprintf("identical to <map[int]int> %v", o1), m.Description()) + + err = m.Matches(o1) + ExpectEq(nil, err) + + err = m.Matches(o2) + ExpectThat(err, Error(Equals("which is not an identical reference"))) +} + +func (t *IdenticalToTest) Functions() { + var m Matcher + var err error + + // Nil expected value + m = IdenticalTo((func())(nil)) + ExpectEq("identical to <func()> <nil>", m.Description()) + + err = m.Matches((func())(nil)) + ExpectEq(nil, err) + + err = m.Matches(func(){}) + ExpectThat(err, Error(Equals("which is not an identical reference"))) + + // Non-nil expected value + o1 := func() {} + o2 := func() {} + m = IdenticalTo(o1) + ExpectEq(fmt.Sprintf("identical to <func()> %v", o1), m.Description()) + + err = m.Matches(o1) + ExpectEq(nil, err) + + err = m.Matches(o2) + ExpectThat(err, Error(Equals("which is not an identical reference"))) +} + +func (t *IdenticalToTest) Channels() { + var m Matcher + var err error + + // Nil expected value + m = IdenticalTo((chan int)(nil)) + ExpectEq("identical to <chan int> <nil>", m.Description()) + + err = m.Matches((chan int)(nil)) + ExpectEq(nil, err) + + err = m.Matches(make(chan int)) + ExpectThat(err, Error(Equals("which is not an identical reference"))) + + // Non-nil expected value + o1 := make(chan int) + o2 := make(chan int) + m = IdenticalTo(o1) + ExpectEq(fmt.Sprintf("identical to <chan int> %v", o1), m.Description()) + + err = m.Matches(o1) + ExpectEq(nil, err) + + err = m.Matches(o2) + ExpectThat(err, Error(Equals("which is not an identical reference"))) +} + +func (t *IdenticalToTest) Bools() { + var m Matcher + var err error + + // false + m = IdenticalTo(false) + ExpectEq("identical to <bool> false", m.Description()) + + err = m.Matches(false) + ExpectEq(nil, err) + + err = m.Matches(true) + ExpectThat(err, Error(Equals(""))) + + // true + m = IdenticalTo(true) + ExpectEq("identical to <bool> true", m.Description()) + + err = m.Matches(false) + ExpectThat(err, Error(Equals(""))) + + err = m.Matches(true) + ExpectEq(nil, err) +} + +func (t *IdenticalToTest) Ints() { + var m Matcher + var err error + + m = IdenticalTo(int(17)) + ExpectEq("identical to <int> 17", m.Description()) + + // Identical value + err = m.Matches(int(17)) + ExpectEq(nil, err) + + // Type alias + type myType int + err = m.Matches(myType(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) + + // Completely wrong type + err = m.Matches(int32(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type int32"))) +} + +func (t *IdenticalToTest) Int8s() { + var m Matcher + var err error + + m = IdenticalTo(int8(17)) + ExpectEq("identical to <int8> 17", m.Description()) + + // Identical value + err = m.Matches(int8(17)) + ExpectEq(nil, err) + + // Type alias + type myType int8 + err = m.Matches(myType(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) + + // Completely wrong type + err = m.Matches(int32(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type int32"))) +} + +func (t *IdenticalToTest) Int16s() { + var m Matcher + var err error + + m = IdenticalTo(int16(17)) + ExpectEq("identical to <int16> 17", m.Description()) + + // Identical value + err = m.Matches(int16(17)) + ExpectEq(nil, err) + + // Type alias + type myType int16 + err = m.Matches(myType(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) + + // Completely wrong type + err = m.Matches(int32(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type int32"))) +} + +func (t *IdenticalToTest) Int32s() { + var m Matcher + var err error + + m = IdenticalTo(int32(17)) + ExpectEq("identical to <int32> 17", m.Description()) + + // Identical value + err = m.Matches(int32(17)) + ExpectEq(nil, err) + + // Type alias + type myType int32 + err = m.Matches(myType(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) + + // Completely wrong type + err = m.Matches(int16(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type int16"))) +} + +func (t *IdenticalToTest) Int64s() { + var m Matcher + var err error + + m = IdenticalTo(int64(17)) + ExpectEq("identical to <int64> 17", m.Description()) + + // Identical value + err = m.Matches(int64(17)) + ExpectEq(nil, err) + + // Type alias + type myType int64 + err = m.Matches(myType(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) + + // Completely wrong type + err = m.Matches(int32(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type int32"))) +} + +func (t *IdenticalToTest) Uints() { + var m Matcher + var err error + + m = IdenticalTo(uint(17)) + ExpectEq("identical to <uint> 17", m.Description()) + + // Identical value + err = m.Matches(uint(17)) + ExpectEq(nil, err) + + // Type alias + type myType uint + err = m.Matches(myType(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) + + // Completely wrong type + err = m.Matches(int32(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type int32"))) +} + +func (t *IdenticalToTest) Uint8s() { + var m Matcher + var err error + + m = IdenticalTo(uint8(17)) + ExpectEq("identical to <uint8> 17", m.Description()) + + // Identical value + err = m.Matches(uint8(17)) + ExpectEq(nil, err) + + // Type alias + type myType uint8 + err = m.Matches(myType(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) + + // Completely wrong type + err = m.Matches(int32(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type int32"))) +} + +func (t *IdenticalToTest) Uint16s() { + var m Matcher + var err error + + m = IdenticalTo(uint16(17)) + ExpectEq("identical to <uint16> 17", m.Description()) + + // Identical value + err = m.Matches(uint16(17)) + ExpectEq(nil, err) + + // Type alias + type myType uint16 + err = m.Matches(myType(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) + + // Completely wrong type + err = m.Matches(int32(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type int32"))) +} + +func (t *IdenticalToTest) Uint32s() { + var m Matcher + var err error + + m = IdenticalTo(uint32(17)) + ExpectEq("identical to <uint32> 17", m.Description()) + + // Identical value + err = m.Matches(uint32(17)) + ExpectEq(nil, err) + + // Type alias + type myType uint32 + err = m.Matches(myType(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) + + // Completely wrong type + err = m.Matches(int32(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type int32"))) +} + +func (t *IdenticalToTest) Uint64s() { + var m Matcher + var err error + + m = IdenticalTo(uint64(17)) + ExpectEq("identical to <uint64> 17", m.Description()) + + // Identical value + err = m.Matches(uint64(17)) + ExpectEq(nil, err) + + // Type alias + type myType uint64 + err = m.Matches(myType(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) + + // Completely wrong type + err = m.Matches(int32(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type int32"))) +} + +func (t *IdenticalToTest) Uintptrs() { + var m Matcher + var err error + + m = IdenticalTo(uintptr(17)) + ExpectEq("identical to <uintptr> 17", m.Description()) + + // Identical value + err = m.Matches(uintptr(17)) + ExpectEq(nil, err) + + // Type alias + type myType uintptr + err = m.Matches(myType(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) + + // Completely wrong type + err = m.Matches(int32(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type int32"))) +} + +func (t *IdenticalToTest) Float32s() { + var m Matcher + var err error + + m = IdenticalTo(float32(17)) + ExpectEq("identical to <float32> 17", m.Description()) + + // Identical value + err = m.Matches(float32(17)) + ExpectEq(nil, err) + + // Type alias + type myType float32 + err = m.Matches(myType(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) + + // Completely wrong type + err = m.Matches(int32(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type int32"))) +} + +func (t *IdenticalToTest) Float64s() { + var m Matcher + var err error + + m = IdenticalTo(float64(17)) + ExpectEq("identical to <float64> 17", m.Description()) + + // Identical value + err = m.Matches(float64(17)) + ExpectEq(nil, err) + + // Type alias + type myType float64 + err = m.Matches(myType(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) + + // Completely wrong type + err = m.Matches(int32(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type int32"))) +} + +func (t *IdenticalToTest) Complex64s() { + var m Matcher + var err error + + m = IdenticalTo(complex64(17)) + ExpectEq("identical to <complex64> (17+0i)", m.Description()) + + // Identical value + err = m.Matches(complex64(17)) + ExpectEq(nil, err) + + // Type alias + type myType complex64 + err = m.Matches(myType(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) + + // Completely wrong type + err = m.Matches(int32(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type int32"))) +} + +func (t *IdenticalToTest) Complex128s() { + var m Matcher + var err error + + m = IdenticalTo(complex128(17)) + ExpectEq("identical to <complex128> (17+0i)", m.Description()) + + // Identical value + err = m.Matches(complex128(17)) + ExpectEq(nil, err) + + // Type alias + type myType complex128 + err = m.Matches(myType(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) + + // Completely wrong type + err = m.Matches(int32(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type int32"))) +} + +func (t *IdenticalToTest) EmptyComparableArrays() { + var m Matcher + var err error + + m = IdenticalTo([0]int{}) + ExpectEq("identical to <[0]int> []", m.Description()) + + // Identical value + err = m.Matches([0]int{}) + ExpectEq(nil, err) + + // Length too long + err = m.Matches([1]int{17}) + ExpectThat(err, Error(Equals("which is of type [1]int"))) + + // Element type alias + type myType int + err = m.Matches([0]myType{}) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type [0]oglematchers_test.myType"))) + + // Completely wrong element type + err = m.Matches([0]int32{}) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type [0]int32"))) +} + +func (t *IdenticalToTest) NonEmptyComparableArrays() { + var m Matcher + var err error + + m = IdenticalTo([2]int{17, 19}) + ExpectEq("identical to <[2]int> [17 19]", m.Description()) + + // Identical value + err = m.Matches([2]int{17, 19}) + ExpectEq(nil, err) + + // Length too short + err = m.Matches([1]int{17}) + ExpectThat(err, Error(Equals("which is of type [1]int"))) + + // Length too long + err = m.Matches([3]int{17, 19, 23}) + ExpectThat(err, Error(Equals("which is of type [3]int"))) + + // First element different + err = m.Matches([2]int{13, 19}) + ExpectThat(err, Error(Equals(""))) + + // Second element different + err = m.Matches([2]int{17, 23}) + ExpectThat(err, Error(Equals(""))) + + // Element type alias + type myType int + err = m.Matches([2]myType{17, 19}) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type [2]oglematchers_test.myType"))) + + // Completely wrong element type + err = m.Matches([2]int32{17, 19}) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type [2]int32"))) +} + +func (t *IdenticalToTest) NonEmptyArraysOfComparableArrays() { + var m Matcher + var err error + + x := [2][2]int{ + [2]int{17, 19}, + [2]int{23, 29}, + } + m = IdenticalTo(x) + ExpectEq("identical to <[2][2]int> [[17 19] [23 29]]", m.Description()) + + // Identical value + err = m.Matches([2][2]int{[2]int{17, 19}, [2]int{23, 29}}) + ExpectEq(nil, err) + + // Outer length too short + err = m.Matches([1][2]int{[2]int{17, 19}}) + ExpectThat(err, Error(Equals("which is of type [1][2]int"))) + + // Inner length too short + err = m.Matches([2][1]int{[1]int{17}, [1]int{23}}) + ExpectThat(err, Error(Equals("which is of type [2][1]int"))) + + // First element different + err = m.Matches([2][2]int{[2]int{13, 19}, [2]int{23, 29}}) + ExpectThat(err, Error(Equals(""))) + + // Element type alias + type myType int + err = m.Matches([2][2]myType{[2]myType{17, 19}, [2]myType{23, 29}}) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type [2][2]oglematchers_test.myType"))) +} + +func (t *IdenticalToTest) NonComparableArrays() { + x := [0]func(){} + f := func() { IdenticalTo(x) } + ExpectThat(f, Panics(HasSubstr("is not comparable"))) +} + +func (t *IdenticalToTest) ArraysOfNonComparableArrays() { + x := [0][0]func(){} + f := func() { IdenticalTo(x) } + ExpectThat(f, Panics(HasSubstr("is not comparable"))) +} + +func (t *IdenticalToTest) Strings() { + var m Matcher + var err error + + m = IdenticalTo("taco") + ExpectEq("identical to <string> taco", m.Description()) + + // Identical value + err = m.Matches("ta" + "co") + ExpectEq(nil, err) + + // Type alias + type myType string + err = m.Matches(myType("taco")) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) + + // Completely wrong type + err = m.Matches(int32(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type int32"))) +} + +func (t *IdenticalToTest) ComparableStructs() { + var m Matcher + var err error + + type subStruct struct { + i int + } + + type myStruct struct { + u uint + s subStruct + } + + x := myStruct{17, subStruct{19}} + m = IdenticalTo(x) + ExpectEq("identical to <oglematchers_test.myStruct> {17 {19}}", m.Description()) + + // Identical value + err = m.Matches(myStruct{17, subStruct{19}}) + ExpectEq(nil, err) + + // Wrong outer field + err = m.Matches(myStruct{13, subStruct{19}}) + ExpectThat(err, Error(Equals(""))) + + // Wrong inner field + err = m.Matches(myStruct{17, subStruct{23}}) + ExpectThat(err, Error(Equals(""))) + + // Type alias + type myType myStruct + err = m.Matches(myType{17, subStruct{19}}) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) + + // Completely wrong type + err = m.Matches(int32(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type int32"))) +} + +func (t *IdenticalToTest) NonComparableStructs() { + type subStruct struct { + s []int + } + + type myStruct struct { + u uint + s subStruct + } + + x := myStruct{17, subStruct{[]int{19}}} + f := func() { IdenticalTo(x) } + ExpectThat(f, Panics(AllOf(HasSubstr("IdenticalTo"), HasSubstr("comparable")))) +} + +func (t *IdenticalToTest) NilUnsafePointer() { + var m Matcher + var err error + + x := unsafe.Pointer(nil) + m = IdenticalTo(x) + ExpectEq(fmt.Sprintf("identical to <unsafe.Pointer> %v", x), m.Description()) + + // Identical value + err = m.Matches(unsafe.Pointer(nil)) + ExpectEq(nil, err) + + // Wrong value + j := 17 + err = m.Matches(unsafe.Pointer(&j)) + ExpectThat(err, Error(Equals(""))) + + // Type alias + type myType unsafe.Pointer + err = m.Matches(myType(unsafe.Pointer(nil))) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) + + // Completely wrong type + err = m.Matches(int32(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type int32"))) +} + +func (t *IdenticalToTest) NonNilUnsafePointer() { + var m Matcher + var err error + + i := 17 + x := unsafe.Pointer(&i) + m = IdenticalTo(x) + ExpectEq(fmt.Sprintf("identical to <unsafe.Pointer> %v", x), m.Description()) + + // Identical value + err = m.Matches(unsafe.Pointer(&i)) + ExpectEq(nil, err) + + // Nil value + err = m.Matches(unsafe.Pointer(nil)) + ExpectThat(err, Error(Equals(""))) + + // Wrong value + j := 17 + err = m.Matches(unsafe.Pointer(&j)) + ExpectThat(err, Error(Equals(""))) + + // Type alias + type myType unsafe.Pointer + err = m.Matches(myType(unsafe.Pointer(&i))) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type oglematchers_test.myType"))) + + // Completely wrong type + err = m.Matches(int32(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type int32"))) +} + +func (t *IdenticalToTest) IntAlias() { + var m Matcher + var err error + + type intAlias int + + m = IdenticalTo(intAlias(17)) + ExpectEq("identical to <oglematchers_test.intAlias> 17", m.Description()) + + // Identical value + err = m.Matches(intAlias(17)) + ExpectEq(nil, err) + + // Int + err = m.Matches(int(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type int"))) + + // Completely wrong type + err = m.Matches(int32(17)) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("which is of type int32"))) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/less_or_equal.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/less_or_equal.go new file mode 100644 index 00000000000..8402cdeaf09 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/less_or_equal.go @@ -0,0 +1,41 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package oglematchers + +import ( + "fmt" + "reflect" +) + +// LessOrEqual returns a matcher that matches integer, floating point, or +// strings values v such that v <= x. Comparison is not defined between numeric +// and string types, but is defined between all integer and floating point +// types. +// +// x must itself be an integer, floating point, or string type; otherwise, +// LessOrEqual will panic. +func LessOrEqual(x interface{}) Matcher { + desc := fmt.Sprintf("less than or equal to %v", x) + + // Special case: make it clear that strings are strings. + if reflect.TypeOf(x).Kind() == reflect.String { + desc = fmt.Sprintf("less than or equal to \"%s\"", x) + } + + // Put LessThan last so that its error messages will be used in the event of + // failure. + return transformDescription(AnyOf(Equals(x), LessThan(x)), desc) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/less_or_equal_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/less_or_equal_test.go new file mode 100644 index 00000000000..a1a2ae7d60e --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/less_or_equal_test.go @@ -0,0 +1,1077 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package oglematchers_test + +import ( + "math" + + . "github.com/smartystreets/assertions/internal/oglematchers" + . "github.com/smartystreets/assertions/internal/ogletest" +) + +//////////////////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////////////////// + +type LessOrEqualTest struct { +} + +func init() { RegisterTestSuite(&LessOrEqualTest{}) } + +type leTestCase struct { + candidate interface{} + expectedResult bool + shouldBeFatal bool + expectedError string +} + +func (t *LessOrEqualTest) checkTestCases(matcher Matcher, cases []leTestCase) { + for i, c := range cases { + err := matcher.Matches(c.candidate) + + ExpectThat( + (err == nil), + Equals(c.expectedResult), + "Case %d (candidate %v)", + i, + c.candidate) + + if err == nil { + continue + } + + _, isFatal := err.(*FatalError) + ExpectEq( + c.shouldBeFatal, + isFatal, + "Case %d (candidate %v)", + i, + c.candidate) + + ExpectThat( + err, + Error(Equals(c.expectedError)), + "Case %d (candidate %v)", + i, + c.candidate) + } +} + +//////////////////////////////////////////////////////////////////////// +// Integer literals +//////////////////////////////////////////////////////////////////////// + +func (t *LessOrEqualTest) IntegerCandidateBadTypes() { + matcher := LessOrEqual(int(-150)) + + cases := []leTestCase{ + leTestCase{true, false, true, "which is not comparable"}, + leTestCase{complex64(-151), false, true, "which is not comparable"}, + leTestCase{complex128(-151), false, true, "which is not comparable"}, + leTestCase{[...]int{-151}, false, true, "which is not comparable"}, + leTestCase{make(chan int), false, true, "which is not comparable"}, + leTestCase{func() {}, false, true, "which is not comparable"}, + leTestCase{map[int]int{}, false, true, "which is not comparable"}, + leTestCase{&leTestCase{}, false, true, "which is not comparable"}, + leTestCase{make([]int, 0), false, true, "which is not comparable"}, + leTestCase{"-151", false, true, "which is not comparable"}, + leTestCase{leTestCase{}, false, true, "which is not comparable"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessOrEqualTest) FloatCandidateBadTypes() { + matcher := LessOrEqual(float32(-150)) + + cases := []leTestCase{ + leTestCase{true, false, true, "which is not comparable"}, + leTestCase{complex64(-151), false, true, "which is not comparable"}, + leTestCase{complex128(-151), false, true, "which is not comparable"}, + leTestCase{[...]int{-151}, false, true, "which is not comparable"}, + leTestCase{make(chan int), false, true, "which is not comparable"}, + leTestCase{func() {}, false, true, "which is not comparable"}, + leTestCase{map[int]int{}, false, true, "which is not comparable"}, + leTestCase{&leTestCase{}, false, true, "which is not comparable"}, + leTestCase{make([]int, 0), false, true, "which is not comparable"}, + leTestCase{"-151", false, true, "which is not comparable"}, + leTestCase{leTestCase{}, false, true, "which is not comparable"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessOrEqualTest) StringCandidateBadTypes() { + matcher := LessOrEqual("17") + + cases := []leTestCase{ + leTestCase{true, false, true, "which is not comparable"}, + leTestCase{int(0), false, true, "which is not comparable"}, + leTestCase{int8(0), false, true, "which is not comparable"}, + leTestCase{int16(0), false, true, "which is not comparable"}, + leTestCase{int32(0), false, true, "which is not comparable"}, + leTestCase{int64(0), false, true, "which is not comparable"}, + leTestCase{uint(0), false, true, "which is not comparable"}, + leTestCase{uint8(0), false, true, "which is not comparable"}, + leTestCase{uint16(0), false, true, "which is not comparable"}, + leTestCase{uint32(0), false, true, "which is not comparable"}, + leTestCase{uint64(0), false, true, "which is not comparable"}, + leTestCase{float32(0), false, true, "which is not comparable"}, + leTestCase{float64(0), false, true, "which is not comparable"}, + leTestCase{complex64(-151), false, true, "which is not comparable"}, + leTestCase{complex128(-151), false, true, "which is not comparable"}, + leTestCase{[...]int{-151}, false, true, "which is not comparable"}, + leTestCase{make(chan int), false, true, "which is not comparable"}, + leTestCase{func() {}, false, true, "which is not comparable"}, + leTestCase{map[int]int{}, false, true, "which is not comparable"}, + leTestCase{&leTestCase{}, false, true, "which is not comparable"}, + leTestCase{make([]int, 0), false, true, "which is not comparable"}, + leTestCase{leTestCase{}, false, true, "which is not comparable"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessOrEqualTest) BadArgument() { + panicked := false + + defer func() { + ExpectThat(panicked, Equals(true)) + }() + + defer func() { + if r := recover(); r != nil { + panicked = true + } + }() + + LessOrEqual(complex128(0)) +} + +//////////////////////////////////////////////////////////////////////// +// Integer literals +//////////////////////////////////////////////////////////////////////// + +func (t *LessOrEqualTest) NegativeIntegerLiteral() { + matcher := LessOrEqual(-150) + desc := matcher.Description() + expectedDesc := "less than or equal to -150" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []leTestCase{ + // Signed integers. + leTestCase{-(1 << 30), true, false, ""}, + leTestCase{-151, true, false, ""}, + leTestCase{-150, true, false, ""}, + leTestCase{-149, false, false, ""}, + leTestCase{0, false, false, ""}, + leTestCase{17, false, false, ""}, + + leTestCase{int(-(1 << 30)), true, false, ""}, + leTestCase{int(-151), true, false, ""}, + leTestCase{int(-150), true, false, ""}, + leTestCase{int(-149), false, false, ""}, + leTestCase{int(0), false, false, ""}, + leTestCase{int(17), false, false, ""}, + + leTestCase{int8(-127), false, false, ""}, + leTestCase{int8(0), false, false, ""}, + leTestCase{int8(17), false, false, ""}, + + leTestCase{int16(-(1 << 14)), true, false, ""}, + leTestCase{int16(-151), true, false, ""}, + leTestCase{int16(-150), true, false, ""}, + leTestCase{int16(-149), false, false, ""}, + leTestCase{int16(0), false, false, ""}, + leTestCase{int16(17), false, false, ""}, + + leTestCase{int32(-(1 << 30)), true, false, ""}, + leTestCase{int32(-151), true, false, ""}, + leTestCase{int32(-150), true, false, ""}, + leTestCase{int32(-149), false, false, ""}, + leTestCase{int32(0), false, false, ""}, + leTestCase{int32(17), false, false, ""}, + + leTestCase{int64(-(1 << 30)), true, false, ""}, + leTestCase{int64(-151), true, false, ""}, + leTestCase{int64(-150), true, false, ""}, + leTestCase{int64(-149), false, false, ""}, + leTestCase{int64(0), false, false, ""}, + leTestCase{int64(17), false, false, ""}, + + // Unsigned integers. + leTestCase{uint((1 << 32) - 151), false, false, ""}, + leTestCase{uint(0), false, false, ""}, + leTestCase{uint(17), false, false, ""}, + + leTestCase{uint8(0), false, false, ""}, + leTestCase{uint8(17), false, false, ""}, + leTestCase{uint8(253), false, false, ""}, + + leTestCase{uint16((1 << 16) - 151), false, false, ""}, + leTestCase{uint16(0), false, false, ""}, + leTestCase{uint16(17), false, false, ""}, + + leTestCase{uint32((1 << 32) - 151), false, false, ""}, + leTestCase{uint32(0), false, false, ""}, + leTestCase{uint32(17), false, false, ""}, + + leTestCase{uint64((1 << 64) - 151), false, false, ""}, + leTestCase{uint64(0), false, false, ""}, + leTestCase{uint64(17), false, false, ""}, + + // Floating point. + leTestCase{float32(-(1 << 30)), true, false, ""}, + leTestCase{float32(-151), true, false, ""}, + leTestCase{float32(-150.1), true, false, ""}, + leTestCase{float32(-150), true, false, ""}, + leTestCase{float32(-149.9), false, false, ""}, + leTestCase{float32(0), false, false, ""}, + leTestCase{float32(17), false, false, ""}, + leTestCase{float32(160), false, false, ""}, + + leTestCase{float64(-(1 << 30)), true, false, ""}, + leTestCase{float64(-151), true, false, ""}, + leTestCase{float64(-150.1), true, false, ""}, + leTestCase{float64(-150), true, false, ""}, + leTestCase{float64(-149.9), false, false, ""}, + leTestCase{float64(0), false, false, ""}, + leTestCase{float64(17), false, false, ""}, + leTestCase{float64(160), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessOrEqualTest) ZeroIntegerLiteral() { + matcher := LessOrEqual(0) + desc := matcher.Description() + expectedDesc := "less than or equal to 0" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []leTestCase{ + // Signed integers. + leTestCase{-(1 << 30), true, false, ""}, + leTestCase{-1, true, false, ""}, + leTestCase{0, true, false, ""}, + leTestCase{1, false, false, ""}, + leTestCase{17, false, false, ""}, + leTestCase{(1 << 30), false, false, ""}, + + leTestCase{int(-(1 << 30)), true, false, ""}, + leTestCase{int(-1), true, false, ""}, + leTestCase{int(0), true, false, ""}, + leTestCase{int(1), false, false, ""}, + leTestCase{int(17), false, false, ""}, + + leTestCase{int8(-1), true, false, ""}, + leTestCase{int8(0), true, false, ""}, + leTestCase{int8(1), false, false, ""}, + + leTestCase{int16(-(1 << 14)), true, false, ""}, + leTestCase{int16(-1), true, false, ""}, + leTestCase{int16(0), true, false, ""}, + leTestCase{int16(1), false, false, ""}, + leTestCase{int16(17), false, false, ""}, + + leTestCase{int32(-(1 << 30)), true, false, ""}, + leTestCase{int32(-1), true, false, ""}, + leTestCase{int32(0), true, false, ""}, + leTestCase{int32(1), false, false, ""}, + leTestCase{int32(17), false, false, ""}, + + leTestCase{int64(-(1 << 30)), true, false, ""}, + leTestCase{int64(-1), true, false, ""}, + leTestCase{int64(0), true, false, ""}, + leTestCase{int64(1), false, false, ""}, + leTestCase{int64(17), false, false, ""}, + + // Unsigned integers. + leTestCase{uint((1 << 32) - 1), false, false, ""}, + leTestCase{uint(0), true, false, ""}, + leTestCase{uint(1), false, false, ""}, + leTestCase{uint(17), false, false, ""}, + + leTestCase{uint8(0), true, false, ""}, + leTestCase{uint8(1), false, false, ""}, + leTestCase{uint8(17), false, false, ""}, + leTestCase{uint8(253), false, false, ""}, + + leTestCase{uint16((1 << 16) - 1), false, false, ""}, + leTestCase{uint16(0), true, false, ""}, + leTestCase{uint16(1), false, false, ""}, + leTestCase{uint16(17), false, false, ""}, + + leTestCase{uint32((1 << 32) - 1), false, false, ""}, + leTestCase{uint32(0), true, false, ""}, + leTestCase{uint32(1), false, false, ""}, + leTestCase{uint32(17), false, false, ""}, + + leTestCase{uint64((1 << 64) - 1), false, false, ""}, + leTestCase{uint64(0), true, false, ""}, + leTestCase{uint64(1), false, false, ""}, + leTestCase{uint64(17), false, false, ""}, + + // Floating point. + leTestCase{float32(-(1 << 30)), true, false, ""}, + leTestCase{float32(-1), true, false, ""}, + leTestCase{float32(-0.1), true, false, ""}, + leTestCase{float32(-0.0), true, false, ""}, + leTestCase{float32(0), true, false, ""}, + leTestCase{float32(0.1), false, false, ""}, + leTestCase{float32(17), false, false, ""}, + leTestCase{float32(160), false, false, ""}, + + leTestCase{float64(-(1 << 30)), true, false, ""}, + leTestCase{float64(-1), true, false, ""}, + leTestCase{float64(-0.1), true, false, ""}, + leTestCase{float64(-0), true, false, ""}, + leTestCase{float64(0), true, false, ""}, + leTestCase{float64(0.1), false, false, ""}, + leTestCase{float64(17), false, false, ""}, + leTestCase{float64(160), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessOrEqualTest) PositiveIntegerLiteral() { + matcher := LessOrEqual(150) + desc := matcher.Description() + expectedDesc := "less than or equal to 150" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []leTestCase{ + // Signed integers. + leTestCase{-1, true, false, ""}, + leTestCase{149, true, false, ""}, + leTestCase{150, true, false, ""}, + leTestCase{151, false, false, ""}, + + leTestCase{int(-1), true, false, ""}, + leTestCase{int(149), true, false, ""}, + leTestCase{int(150), true, false, ""}, + leTestCase{int(151), false, false, ""}, + + leTestCase{int8(-1), true, false, ""}, + leTestCase{int8(0), true, false, ""}, + leTestCase{int8(17), true, false, ""}, + leTestCase{int8(127), true, false, ""}, + + leTestCase{int16(-1), true, false, ""}, + leTestCase{int16(149), true, false, ""}, + leTestCase{int16(150), true, false, ""}, + leTestCase{int16(151), false, false, ""}, + + leTestCase{int32(-1), true, false, ""}, + leTestCase{int32(149), true, false, ""}, + leTestCase{int32(150), true, false, ""}, + leTestCase{int32(151), false, false, ""}, + + leTestCase{int64(-1), true, false, ""}, + leTestCase{int64(149), true, false, ""}, + leTestCase{int64(150), true, false, ""}, + leTestCase{int64(151), false, false, ""}, + + // Unsigned integers. + leTestCase{uint(0), true, false, ""}, + leTestCase{uint(149), true, false, ""}, + leTestCase{uint(150), true, false, ""}, + leTestCase{uint(151), false, false, ""}, + + leTestCase{uint8(0), true, false, ""}, + leTestCase{uint8(127), true, false, ""}, + + leTestCase{uint16(0), true, false, ""}, + leTestCase{uint16(149), true, false, ""}, + leTestCase{uint16(150), true, false, ""}, + leTestCase{uint16(151), false, false, ""}, + + leTestCase{uint32(0), true, false, ""}, + leTestCase{uint32(149), true, false, ""}, + leTestCase{uint32(150), true, false, ""}, + leTestCase{uint32(151), false, false, ""}, + + leTestCase{uint64(0), true, false, ""}, + leTestCase{uint64(149), true, false, ""}, + leTestCase{uint64(150), true, false, ""}, + leTestCase{uint64(151), false, false, ""}, + + // Floating point. + leTestCase{float32(-1), true, false, ""}, + leTestCase{float32(149), true, false, ""}, + leTestCase{float32(149.9), true, false, ""}, + leTestCase{float32(150), true, false, ""}, + leTestCase{float32(150.1), false, false, ""}, + leTestCase{float32(151), false, false, ""}, + + leTestCase{float64(-1), true, false, ""}, + leTestCase{float64(149), true, false, ""}, + leTestCase{float64(149.9), true, false, ""}, + leTestCase{float64(150), true, false, ""}, + leTestCase{float64(150.1), false, false, ""}, + leTestCase{float64(151), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// Float literals +//////////////////////////////////////////////////////////////////////// + +func (t *LessOrEqualTest) NegativeFloatLiteral() { + matcher := LessOrEqual(-150.1) + desc := matcher.Description() + expectedDesc := "less than or equal to -150.1" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []leTestCase{ + // Signed integers. + leTestCase{-(1 << 30), true, false, ""}, + leTestCase{-151, true, false, ""}, + leTestCase{-150.1, true, false, ""}, + leTestCase{-150, false, false, ""}, + leTestCase{-149, false, false, ""}, + leTestCase{0, false, false, ""}, + leTestCase{17, false, false, ""}, + + leTestCase{int(-(1 << 30)), true, false, ""}, + leTestCase{int(-151), true, false, ""}, + leTestCase{int(-150), false, false, ""}, + leTestCase{int(-149), false, false, ""}, + leTestCase{int(0), false, false, ""}, + leTestCase{int(17), false, false, ""}, + + leTestCase{int8(-127), false, false, ""}, + leTestCase{int8(0), false, false, ""}, + leTestCase{int8(17), false, false, ""}, + + leTestCase{int16(-(1 << 14)), true, false, ""}, + leTestCase{int16(-151), true, false, ""}, + leTestCase{int16(-150), false, false, ""}, + leTestCase{int16(-149), false, false, ""}, + leTestCase{int16(0), false, false, ""}, + leTestCase{int16(17), false, false, ""}, + + leTestCase{int32(-(1 << 30)), true, false, ""}, + leTestCase{int32(-151), true, false, ""}, + leTestCase{int32(-150), false, false, ""}, + leTestCase{int32(-149), false, false, ""}, + leTestCase{int32(0), false, false, ""}, + leTestCase{int32(17), false, false, ""}, + + leTestCase{int64(-(1 << 30)), true, false, ""}, + leTestCase{int64(-151), true, false, ""}, + leTestCase{int64(-150), false, false, ""}, + leTestCase{int64(-149), false, false, ""}, + leTestCase{int64(0), false, false, ""}, + leTestCase{int64(17), false, false, ""}, + + // Unsigned integers. + leTestCase{uint((1 << 32) - 151), false, false, ""}, + leTestCase{uint(0), false, false, ""}, + leTestCase{uint(17), false, false, ""}, + + leTestCase{uint8(0), false, false, ""}, + leTestCase{uint8(17), false, false, ""}, + leTestCase{uint8(253), false, false, ""}, + + leTestCase{uint16((1 << 16) - 151), false, false, ""}, + leTestCase{uint16(0), false, false, ""}, + leTestCase{uint16(17), false, false, ""}, + + leTestCase{uint32((1 << 32) - 151), false, false, ""}, + leTestCase{uint32(0), false, false, ""}, + leTestCase{uint32(17), false, false, ""}, + + leTestCase{uint64((1 << 64) - 151), false, false, ""}, + leTestCase{uint64(0), false, false, ""}, + leTestCase{uint64(17), false, false, ""}, + + // Floating point. + leTestCase{float32(-(1 << 30)), true, false, ""}, + leTestCase{float32(-151), true, false, ""}, + leTestCase{float32(-150.2), true, false, ""}, + leTestCase{float32(-150.1), true, false, ""}, + leTestCase{float32(-150), false, false, ""}, + leTestCase{float32(0), false, false, ""}, + leTestCase{float32(17), false, false, ""}, + leTestCase{float32(160), false, false, ""}, + + leTestCase{float64(-(1 << 30)), true, false, ""}, + leTestCase{float64(-151), true, false, ""}, + leTestCase{float64(-150.2), true, false, ""}, + leTestCase{float64(-150.1), true, false, ""}, + leTestCase{float64(-150), false, false, ""}, + leTestCase{float64(0), false, false, ""}, + leTestCase{float64(17), false, false, ""}, + leTestCase{float64(160), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessOrEqualTest) PositiveFloatLiteral() { + matcher := LessOrEqual(149.9) + desc := matcher.Description() + expectedDesc := "less than or equal to 149.9" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []leTestCase{ + // Signed integers. + leTestCase{-1, true, false, ""}, + leTestCase{149, true, false, ""}, + leTestCase{149.9, true, false, ""}, + leTestCase{150, false, false, ""}, + leTestCase{151, false, false, ""}, + + leTestCase{int(-1), true, false, ""}, + leTestCase{int(149), true, false, ""}, + leTestCase{int(150), false, false, ""}, + leTestCase{int(151), false, false, ""}, + + leTestCase{int8(-1), true, false, ""}, + leTestCase{int8(0), true, false, ""}, + leTestCase{int8(17), true, false, ""}, + leTestCase{int8(127), true, false, ""}, + + leTestCase{int16(-1), true, false, ""}, + leTestCase{int16(149), true, false, ""}, + leTestCase{int16(150), false, false, ""}, + leTestCase{int16(151), false, false, ""}, + + leTestCase{int32(-1), true, false, ""}, + leTestCase{int32(149), true, false, ""}, + leTestCase{int32(150), false, false, ""}, + leTestCase{int32(151), false, false, ""}, + + leTestCase{int64(-1), true, false, ""}, + leTestCase{int64(149), true, false, ""}, + leTestCase{int64(150), false, false, ""}, + leTestCase{int64(151), false, false, ""}, + + // Unsigned integers. + leTestCase{uint(0), true, false, ""}, + leTestCase{uint(149), true, false, ""}, + leTestCase{uint(150), false, false, ""}, + leTestCase{uint(151), false, false, ""}, + + leTestCase{uint8(0), true, false, ""}, + leTestCase{uint8(127), true, false, ""}, + + leTestCase{uint16(0), true, false, ""}, + leTestCase{uint16(149), true, false, ""}, + leTestCase{uint16(150), false, false, ""}, + leTestCase{uint16(151), false, false, ""}, + + leTestCase{uint32(0), true, false, ""}, + leTestCase{uint32(149), true, false, ""}, + leTestCase{uint32(150), false, false, ""}, + leTestCase{uint32(151), false, false, ""}, + + leTestCase{uint64(0), true, false, ""}, + leTestCase{uint64(149), true, false, ""}, + leTestCase{uint64(150), false, false, ""}, + leTestCase{uint64(151), false, false, ""}, + + // Floating point. + leTestCase{float32(-1), true, false, ""}, + leTestCase{float32(149), true, false, ""}, + leTestCase{float32(149.8), true, false, ""}, + leTestCase{float32(149.9), true, false, ""}, + leTestCase{float32(150), false, false, ""}, + leTestCase{float32(151), false, false, ""}, + + leTestCase{float64(-1), true, false, ""}, + leTestCase{float64(149), true, false, ""}, + leTestCase{float64(149.8), true, false, ""}, + leTestCase{float64(149.9), true, false, ""}, + leTestCase{float64(150), false, false, ""}, + leTestCase{float64(151), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// Subtle cases +//////////////////////////////////////////////////////////////////////// + +func (t *LessOrEqualTest) Int64NotExactlyRepresentableBySinglePrecision() { + // Single-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo25 = 1 << 25 + matcher := LessOrEqual(int64(kTwoTo25 + 1)) + + desc := matcher.Description() + expectedDesc := "less than or equal to 33554433" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []leTestCase{ + // Signed integers. + leTestCase{-1, true, false, ""}, + leTestCase{kTwoTo25 + 0, true, false, ""}, + leTestCase{kTwoTo25 + 1, true, false, ""}, + leTestCase{kTwoTo25 + 2, false, false, ""}, + + leTestCase{int(-1), true, false, ""}, + leTestCase{int(kTwoTo25 + 0), true, false, ""}, + leTestCase{int(kTwoTo25 + 1), true, false, ""}, + leTestCase{int(kTwoTo25 + 2), false, false, ""}, + + leTestCase{int8(-1), true, false, ""}, + leTestCase{int8(127), true, false, ""}, + + leTestCase{int16(-1), true, false, ""}, + leTestCase{int16(0), true, false, ""}, + leTestCase{int16(32767), true, false, ""}, + + leTestCase{int32(-1), true, false, ""}, + leTestCase{int32(kTwoTo25 + 0), true, false, ""}, + leTestCase{int32(kTwoTo25 + 1), true, false, ""}, + leTestCase{int32(kTwoTo25 + 2), false, false, ""}, + + leTestCase{int64(-1), true, false, ""}, + leTestCase{int64(kTwoTo25 + 0), true, false, ""}, + leTestCase{int64(kTwoTo25 + 1), true, false, ""}, + leTestCase{int64(kTwoTo25 + 2), false, false, ""}, + + // Unsigned integers. + leTestCase{uint(0), true, false, ""}, + leTestCase{uint(kTwoTo25 + 0), true, false, ""}, + leTestCase{uint(kTwoTo25 + 1), true, false, ""}, + leTestCase{uint(kTwoTo25 + 2), false, false, ""}, + + leTestCase{uint8(0), true, false, ""}, + leTestCase{uint8(255), true, false, ""}, + + leTestCase{uint16(0), true, false, ""}, + leTestCase{uint16(65535), true, false, ""}, + + leTestCase{uint32(0), true, false, ""}, + leTestCase{uint32(kTwoTo25 + 0), true, false, ""}, + leTestCase{uint32(kTwoTo25 + 1), true, false, ""}, + leTestCase{uint32(kTwoTo25 + 2), false, false, ""}, + + leTestCase{uint64(0), true, false, ""}, + leTestCase{uint64(kTwoTo25 + 0), true, false, ""}, + leTestCase{uint64(kTwoTo25 + 1), true, false, ""}, + leTestCase{uint64(kTwoTo25 + 2), false, false, ""}, + + // Floating point. + leTestCase{float32(-1), true, false, ""}, + leTestCase{float32(kTwoTo25 - 2), true, false, ""}, + leTestCase{float32(kTwoTo25 - 1), true, false, ""}, + leTestCase{float32(kTwoTo25 + 0), true, false, ""}, + leTestCase{float32(kTwoTo25 + 1), true, false, ""}, + leTestCase{float32(kTwoTo25 + 2), true, false, ""}, + leTestCase{float32(kTwoTo25 + 3), false, false, ""}, + + leTestCase{float64(-1), true, false, ""}, + leTestCase{float64(kTwoTo25 - 2), true, false, ""}, + leTestCase{float64(kTwoTo25 - 1), true, false, ""}, + leTestCase{float64(kTwoTo25 + 0), true, false, ""}, + leTestCase{float64(kTwoTo25 + 1), true, false, ""}, + leTestCase{float64(kTwoTo25 + 2), false, false, ""}, + leTestCase{float64(kTwoTo25 + 3), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessOrEqualTest) Int64NotExactlyRepresentableByDoublePrecision() { + // Double-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^54-1, 2^54+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo54 = 1 << 54 + matcher := LessOrEqual(int64(kTwoTo54 + 1)) + + desc := matcher.Description() + expectedDesc := "less than or equal to 18014398509481985" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []leTestCase{ + // Signed integers. + leTestCase{-1, true, false, ""}, + leTestCase{1 << 30, true, false, ""}, + + leTestCase{int(-1), true, false, ""}, + leTestCase{int(math.MaxInt32), true, false, ""}, + + leTestCase{int8(-1), true, false, ""}, + leTestCase{int8(127), true, false, ""}, + + leTestCase{int16(-1), true, false, ""}, + leTestCase{int16(0), true, false, ""}, + leTestCase{int16(32767), true, false, ""}, + + leTestCase{int32(-1), true, false, ""}, + leTestCase{int32(math.MaxInt32), true, false, ""}, + + leTestCase{int64(-1), true, false, ""}, + leTestCase{int64(kTwoTo54 - 1), true, false, ""}, + leTestCase{int64(kTwoTo54 + 0), true, false, ""}, + leTestCase{int64(kTwoTo54 + 1), true, false, ""}, + leTestCase{int64(kTwoTo54 + 2), false, false, ""}, + + // Unsigned integers. + leTestCase{uint(0), true, false, ""}, + leTestCase{uint(math.MaxUint32), true, false, ""}, + + leTestCase{uint8(0), true, false, ""}, + leTestCase{uint8(255), true, false, ""}, + + leTestCase{uint16(0), true, false, ""}, + leTestCase{uint16(65535), true, false, ""}, + + leTestCase{uint32(0), true, false, ""}, + leTestCase{uint32(math.MaxUint32), true, false, ""}, + + leTestCase{uint64(0), true, false, ""}, + leTestCase{uint64(kTwoTo54 - 1), true, false, ""}, + leTestCase{uint64(kTwoTo54 + 0), true, false, ""}, + leTestCase{uint64(kTwoTo54 + 1), true, false, ""}, + leTestCase{uint64(kTwoTo54 + 2), false, false, ""}, + + // Floating point. + leTestCase{float64(-1), true, false, ""}, + leTestCase{float64(kTwoTo54 - 2), true, false, ""}, + leTestCase{float64(kTwoTo54 - 1), true, false, ""}, + leTestCase{float64(kTwoTo54 + 0), true, false, ""}, + leTestCase{float64(kTwoTo54 + 1), true, false, ""}, + leTestCase{float64(kTwoTo54 + 2), true, false, ""}, + leTestCase{float64(kTwoTo54 + 3), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessOrEqualTest) Uint64NotExactlyRepresentableBySinglePrecision() { + // Single-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo25 = 1 << 25 + matcher := LessOrEqual(uint64(kTwoTo25 + 1)) + + desc := matcher.Description() + expectedDesc := "less than or equal to 33554433" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []leTestCase{ + // Signed integers. + leTestCase{-1, true, false, ""}, + leTestCase{kTwoTo25 + 0, true, false, ""}, + leTestCase{kTwoTo25 + 1, true, false, ""}, + leTestCase{kTwoTo25 + 2, false, false, ""}, + + leTestCase{int(-1), true, false, ""}, + leTestCase{int(kTwoTo25 + 0), true, false, ""}, + leTestCase{int(kTwoTo25 + 1), true, false, ""}, + leTestCase{int(kTwoTo25 + 2), false, false, ""}, + + leTestCase{int8(-1), true, false, ""}, + leTestCase{int8(127), true, false, ""}, + + leTestCase{int16(-1), true, false, ""}, + leTestCase{int16(0), true, false, ""}, + leTestCase{int16(32767), true, false, ""}, + + leTestCase{int32(-1), true, false, ""}, + leTestCase{int32(kTwoTo25 + 0), true, false, ""}, + leTestCase{int32(kTwoTo25 + 1), true, false, ""}, + leTestCase{int32(kTwoTo25 + 2), false, false, ""}, + + leTestCase{int64(-1), true, false, ""}, + leTestCase{int64(kTwoTo25 + 0), true, false, ""}, + leTestCase{int64(kTwoTo25 + 1), true, false, ""}, + leTestCase{int64(kTwoTo25 + 2), false, false, ""}, + + // Unsigned integers. + leTestCase{uint(0), true, false, ""}, + leTestCase{uint(kTwoTo25 + 0), true, false, ""}, + leTestCase{uint(kTwoTo25 + 1), true, false, ""}, + leTestCase{uint(kTwoTo25 + 2), false, false, ""}, + + leTestCase{uint8(0), true, false, ""}, + leTestCase{uint8(255), true, false, ""}, + + leTestCase{uint16(0), true, false, ""}, + leTestCase{uint16(65535), true, false, ""}, + + leTestCase{uint32(0), true, false, ""}, + leTestCase{uint32(kTwoTo25 + 0), true, false, ""}, + leTestCase{uint32(kTwoTo25 + 1), true, false, ""}, + leTestCase{uint32(kTwoTo25 + 2), false, false, ""}, + + leTestCase{uint64(0), true, false, ""}, + leTestCase{uint64(kTwoTo25 + 0), true, false, ""}, + leTestCase{uint64(kTwoTo25 + 1), true, false, ""}, + leTestCase{uint64(kTwoTo25 + 2), false, false, ""}, + + // Floating point. + leTestCase{float32(-1), true, false, ""}, + leTestCase{float32(kTwoTo25 - 2), true, false, ""}, + leTestCase{float32(kTwoTo25 - 1), true, false, ""}, + leTestCase{float32(kTwoTo25 + 0), true, false, ""}, + leTestCase{float32(kTwoTo25 + 1), true, false, ""}, + leTestCase{float32(kTwoTo25 + 2), true, false, ""}, + leTestCase{float32(kTwoTo25 + 3), false, false, ""}, + + leTestCase{float64(-1), true, false, ""}, + leTestCase{float64(kTwoTo25 - 2), true, false, ""}, + leTestCase{float64(kTwoTo25 - 1), true, false, ""}, + leTestCase{float64(kTwoTo25 + 0), true, false, ""}, + leTestCase{float64(kTwoTo25 + 1), true, false, ""}, + leTestCase{float64(kTwoTo25 + 2), false, false, ""}, + leTestCase{float64(kTwoTo25 + 3), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessOrEqualTest) Uint64NotExactlyRepresentableByDoublePrecision() { + // Double-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^54-1, 2^54+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo54 = 1 << 54 + matcher := LessOrEqual(uint64(kTwoTo54 + 1)) + + desc := matcher.Description() + expectedDesc := "less than or equal to 18014398509481985" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []leTestCase{ + // Signed integers. + leTestCase{-1, true, false, ""}, + leTestCase{1 << 30, true, false, ""}, + + leTestCase{int(-1), true, false, ""}, + leTestCase{int(math.MaxInt32), true, false, ""}, + + leTestCase{int8(-1), true, false, ""}, + leTestCase{int8(127), true, false, ""}, + + leTestCase{int16(-1), true, false, ""}, + leTestCase{int16(0), true, false, ""}, + leTestCase{int16(32767), true, false, ""}, + + leTestCase{int32(-1), true, false, ""}, + leTestCase{int32(math.MaxInt32), true, false, ""}, + + leTestCase{int64(-1), true, false, ""}, + leTestCase{int64(kTwoTo54 - 1), true, false, ""}, + leTestCase{int64(kTwoTo54 + 0), true, false, ""}, + leTestCase{int64(kTwoTo54 + 1), true, false, ""}, + leTestCase{int64(kTwoTo54 + 2), false, false, ""}, + + // Unsigned integers. + leTestCase{uint(0), true, false, ""}, + leTestCase{uint(math.MaxUint32), true, false, ""}, + + leTestCase{uint8(0), true, false, ""}, + leTestCase{uint8(255), true, false, ""}, + + leTestCase{uint16(0), true, false, ""}, + leTestCase{uint16(65535), true, false, ""}, + + leTestCase{uint32(0), true, false, ""}, + leTestCase{uint32(math.MaxUint32), true, false, ""}, + + leTestCase{uint64(0), true, false, ""}, + leTestCase{uint64(kTwoTo54 - 1), true, false, ""}, + leTestCase{uint64(kTwoTo54 + 0), true, false, ""}, + leTestCase{uint64(kTwoTo54 + 1), true, false, ""}, + leTestCase{uint64(kTwoTo54 + 2), false, false, ""}, + + // Floating point. + leTestCase{float64(-1), true, false, ""}, + leTestCase{float64(kTwoTo54 - 2), true, false, ""}, + leTestCase{float64(kTwoTo54 - 1), true, false, ""}, + leTestCase{float64(kTwoTo54 + 0), true, false, ""}, + leTestCase{float64(kTwoTo54 + 1), true, false, ""}, + leTestCase{float64(kTwoTo54 + 2), true, false, ""}, + leTestCase{float64(kTwoTo54 + 3), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessOrEqualTest) Float32AboveExactIntegerRange() { + // Single-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo25 = 1 << 25 + matcher := LessOrEqual(float32(kTwoTo25 + 1)) + + desc := matcher.Description() + expectedDesc := "less than or equal to 3.3554432e+07" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []leTestCase{ + // Signed integers. + leTestCase{int64(-1), true, false, ""}, + leTestCase{int64(kTwoTo25 - 2), true, false, ""}, + leTestCase{int64(kTwoTo25 - 1), true, false, ""}, + leTestCase{int64(kTwoTo25 + 0), true, false, ""}, + leTestCase{int64(kTwoTo25 + 1), true, false, ""}, + leTestCase{int64(kTwoTo25 + 2), true, false, ""}, + leTestCase{int64(kTwoTo25 + 3), false, false, ""}, + + // Unsigned integers. + leTestCase{uint64(0), true, false, ""}, + leTestCase{uint64(kTwoTo25 - 2), true, false, ""}, + leTestCase{uint64(kTwoTo25 - 1), true, false, ""}, + leTestCase{uint64(kTwoTo25 + 0), true, false, ""}, + leTestCase{uint64(kTwoTo25 + 1), true, false, ""}, + leTestCase{uint64(kTwoTo25 + 2), true, false, ""}, + leTestCase{uint64(kTwoTo25 + 3), false, false, ""}, + + // Floating point. + leTestCase{float32(-1), true, false, ""}, + leTestCase{float32(kTwoTo25 - 2), true, false, ""}, + leTestCase{float32(kTwoTo25 - 1), true, false, ""}, + leTestCase{float32(kTwoTo25 + 0), true, false, ""}, + leTestCase{float32(kTwoTo25 + 1), true, false, ""}, + leTestCase{float32(kTwoTo25 + 2), true, false, ""}, + leTestCase{float32(kTwoTo25 + 3), false, false, ""}, + + leTestCase{float64(-1), true, false, ""}, + leTestCase{float64(kTwoTo25 - 2), true, false, ""}, + leTestCase{float64(kTwoTo25 - 1), true, false, ""}, + leTestCase{float64(kTwoTo25 + 0), true, false, ""}, + leTestCase{float64(kTwoTo25 + 1), true, false, ""}, + leTestCase{float64(kTwoTo25 + 2), true, false, ""}, + leTestCase{float64(kTwoTo25 + 3), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessOrEqualTest) Float64AboveExactIntegerRange() { + // Double-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^54-1, 2^54+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo54 = 1 << 54 + matcher := LessOrEqual(float64(kTwoTo54 + 1)) + + desc := matcher.Description() + expectedDesc := "less than or equal to 1.8014398509481984e+16" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []leTestCase{ + // Signed integers. + leTestCase{int64(-1), true, false, ""}, + leTestCase{int64(kTwoTo54 - 2), true, false, ""}, + leTestCase{int64(kTwoTo54 - 1), true, false, ""}, + leTestCase{int64(kTwoTo54 + 0), true, false, ""}, + leTestCase{int64(kTwoTo54 + 1), true, false, ""}, + leTestCase{int64(kTwoTo54 + 2), true, false, ""}, + leTestCase{int64(kTwoTo54 + 3), false, false, ""}, + + // Unsigned integers. + leTestCase{uint64(0), true, false, ""}, + leTestCase{uint64(kTwoTo54 - 2), true, false, ""}, + leTestCase{uint64(kTwoTo54 - 1), true, false, ""}, + leTestCase{uint64(kTwoTo54 + 0), true, false, ""}, + leTestCase{uint64(kTwoTo54 + 1), true, false, ""}, + leTestCase{uint64(kTwoTo54 + 2), true, false, ""}, + leTestCase{uint64(kTwoTo54 + 3), false, false, ""}, + + // Floating point. + leTestCase{float64(-1), true, false, ""}, + leTestCase{float64(kTwoTo54 - 2), true, false, ""}, + leTestCase{float64(kTwoTo54 - 1), true, false, ""}, + leTestCase{float64(kTwoTo54 + 0), true, false, ""}, + leTestCase{float64(kTwoTo54 + 1), true, false, ""}, + leTestCase{float64(kTwoTo54 + 2), true, false, ""}, + leTestCase{float64(kTwoTo54 + 3), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// String literals +//////////////////////////////////////////////////////////////////////// + +func (t *LessOrEqualTest) EmptyString() { + matcher := LessOrEqual("") + desc := matcher.Description() + expectedDesc := "less than or equal to \"\"" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []leTestCase{ + leTestCase{"", true, false, ""}, + leTestCase{"\x00", false, false, ""}, + leTestCase{"a", false, false, ""}, + leTestCase{"foo", false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessOrEqualTest) SingleNullByte() { + matcher := LessOrEqual("\x00") + desc := matcher.Description() + expectedDesc := "less than or equal to \"\x00\"" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []leTestCase{ + leTestCase{"", true, false, ""}, + leTestCase{"\x00", true, false, ""}, + leTestCase{"\x00\x00", false, false, ""}, + leTestCase{"a", false, false, ""}, + leTestCase{"foo", false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessOrEqualTest) LongerString() { + matcher := LessOrEqual("foo\x00") + desc := matcher.Description() + expectedDesc := "less than or equal to \"foo\x00\"" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []leTestCase{ + leTestCase{"", true, false, ""}, + leTestCase{"\x00", true, false, ""}, + leTestCase{"bar", true, false, ""}, + leTestCase{"foo", true, false, ""}, + leTestCase{"foo\x00", true, false, ""}, + leTestCase{"foo\x00\x00", false, false, ""}, + leTestCase{"fooa", false, false, ""}, + leTestCase{"qux", false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/less_than.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/less_than.go new file mode 100644 index 00000000000..8258e45d99d --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/less_than.go @@ -0,0 +1,152 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package oglematchers + +import ( + "errors" + "fmt" + "math" + "reflect" +) + +// LessThan returns a matcher that matches integer, floating point, or strings +// values v such that v < x. Comparison is not defined between numeric and +// string types, but is defined between all integer and floating point types. +// +// x must itself be an integer, floating point, or string type; otherwise, +// LessThan will panic. +func LessThan(x interface{}) Matcher { + v := reflect.ValueOf(x) + kind := v.Kind() + + switch { + case isInteger(v): + case isFloat(v): + case kind == reflect.String: + + default: + panic(fmt.Sprintf("LessThan: unexpected kind %v", kind)) + } + + return &lessThanMatcher{v} +} + +type lessThanMatcher struct { + limit reflect.Value +} + +func (m *lessThanMatcher) Description() string { + // Special case: make it clear that strings are strings. + if m.limit.Kind() == reflect.String { + return fmt.Sprintf("less than \"%s\"", m.limit.String()) + } + + return fmt.Sprintf("less than %v", m.limit.Interface()) +} + +func compareIntegers(v1, v2 reflect.Value) (err error) { + err = errors.New("") + + switch { + case isSignedInteger(v1) && isSignedInteger(v2): + if v1.Int() < v2.Int() { + err = nil + } + return + + case isSignedInteger(v1) && isUnsignedInteger(v2): + if v1.Int() < 0 || uint64(v1.Int()) < v2.Uint() { + err = nil + } + return + + case isUnsignedInteger(v1) && isSignedInteger(v2): + if v1.Uint() <= math.MaxInt64 && int64(v1.Uint()) < v2.Int() { + err = nil + } + return + + case isUnsignedInteger(v1) && isUnsignedInteger(v2): + if v1.Uint() < v2.Uint() { + err = nil + } + return + } + + panic(fmt.Sprintf("compareIntegers: %v %v", v1, v2)) +} + +func getFloat(v reflect.Value) float64 { + switch { + case isSignedInteger(v): + return float64(v.Int()) + + case isUnsignedInteger(v): + return float64(v.Uint()) + + case isFloat(v): + return v.Float() + } + + panic(fmt.Sprintf("getFloat: %v", v)) +} + +func (m *lessThanMatcher) Matches(c interface{}) (err error) { + v1 := reflect.ValueOf(c) + v2 := m.limit + + err = errors.New("") + + // Handle strings as a special case. + if v1.Kind() == reflect.String && v2.Kind() == reflect.String { + if v1.String() < v2.String() { + err = nil + } + return + } + + // If we get here, we require that we are dealing with integers or floats. + v1Legal := isInteger(v1) || isFloat(v1) + v2Legal := isInteger(v2) || isFloat(v2) + if !v1Legal || !v2Legal { + err = NewFatalError("which is not comparable") + return + } + + // Handle the various comparison cases. + switch { + // Both integers + case isInteger(v1) && isInteger(v2): + return compareIntegers(v1, v2) + + // At least one float32 + case v1.Kind() == reflect.Float32 || v2.Kind() == reflect.Float32: + if float32(getFloat(v1)) < float32(getFloat(v2)) { + err = nil + } + return + + // At least one float64 + case v1.Kind() == reflect.Float64 || v2.Kind() == reflect.Float64: + if getFloat(v1) < getFloat(v2) { + err = nil + } + return + } + + // We shouldn't get here. + panic(fmt.Sprintf("lessThanMatcher.Matches: Shouldn't get here: %v %v", v1, v2)) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/less_than_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/less_than_test.go new file mode 100644 index 00000000000..59f5b7f56bd --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/less_than_test.go @@ -0,0 +1,1057 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package oglematchers_test + +import ( + "math" + + . "github.com/smartystreets/assertions/internal/oglematchers" + . "github.com/smartystreets/assertions/internal/ogletest" +) + +//////////////////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////////////////// + +type LessThanTest struct { +} + +func init() { RegisterTestSuite(&LessThanTest{}) } + +type ltTestCase struct { + candidate interface{} + expectedResult bool + shouldBeFatal bool + expectedError string +} + +func (t *LessThanTest) checkTestCases(matcher Matcher, cases []ltTestCase) { + for i, c := range cases { + err := matcher.Matches(c.candidate) + + ExpectThat( + (err == nil), + Equals(c.expectedResult), + "Case %d (candidate %v)", + i, + c.candidate) + + if err == nil { + continue + } + + _, isFatal := err.(*FatalError) + ExpectEq( + c.shouldBeFatal, + isFatal, + "Case %d (candidate %v)", + i, + c.candidate) + + ExpectThat( + err, + Error(Equals(c.expectedError)), + "Case %d (candidate %v)", + i, + c.candidate) + } +} + +//////////////////////////////////////////////////////////////////////// +// Integer literals +//////////////////////////////////////////////////////////////////////// + +func (t *LessThanTest) IntegerCandidateBadTypes() { + matcher := LessThan(int(-150)) + + cases := []ltTestCase{ + ltTestCase{true, false, true, "which is not comparable"}, + ltTestCase{complex64(-151), false, true, "which is not comparable"}, + ltTestCase{complex128(-151), false, true, "which is not comparable"}, + ltTestCase{[...]int{-151}, false, true, "which is not comparable"}, + ltTestCase{make(chan int), false, true, "which is not comparable"}, + ltTestCase{func() {}, false, true, "which is not comparable"}, + ltTestCase{map[int]int{}, false, true, "which is not comparable"}, + ltTestCase{<TestCase{}, false, true, "which is not comparable"}, + ltTestCase{make([]int, 0), false, true, "which is not comparable"}, + ltTestCase{"-151", false, true, "which is not comparable"}, + ltTestCase{ltTestCase{}, false, true, "which is not comparable"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessThanTest) FloatCandidateBadTypes() { + matcher := LessThan(float32(-150)) + + cases := []ltTestCase{ + ltTestCase{true, false, true, "which is not comparable"}, + ltTestCase{complex64(-151), false, true, "which is not comparable"}, + ltTestCase{complex128(-151), false, true, "which is not comparable"}, + ltTestCase{[...]int{-151}, false, true, "which is not comparable"}, + ltTestCase{make(chan int), false, true, "which is not comparable"}, + ltTestCase{func() {}, false, true, "which is not comparable"}, + ltTestCase{map[int]int{}, false, true, "which is not comparable"}, + ltTestCase{<TestCase{}, false, true, "which is not comparable"}, + ltTestCase{make([]int, 0), false, true, "which is not comparable"}, + ltTestCase{"-151", false, true, "which is not comparable"}, + ltTestCase{ltTestCase{}, false, true, "which is not comparable"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessThanTest) StringCandidateBadTypes() { + matcher := LessThan("17") + + cases := []ltTestCase{ + ltTestCase{true, false, true, "which is not comparable"}, + ltTestCase{int(0), false, true, "which is not comparable"}, + ltTestCase{int8(0), false, true, "which is not comparable"}, + ltTestCase{int16(0), false, true, "which is not comparable"}, + ltTestCase{int32(0), false, true, "which is not comparable"}, + ltTestCase{int64(0), false, true, "which is not comparable"}, + ltTestCase{uint(0), false, true, "which is not comparable"}, + ltTestCase{uint8(0), false, true, "which is not comparable"}, + ltTestCase{uint16(0), false, true, "which is not comparable"}, + ltTestCase{uint32(0), false, true, "which is not comparable"}, + ltTestCase{uint64(0), false, true, "which is not comparable"}, + ltTestCase{float32(0), false, true, "which is not comparable"}, + ltTestCase{float64(0), false, true, "which is not comparable"}, + ltTestCase{complex64(-151), false, true, "which is not comparable"}, + ltTestCase{complex128(-151), false, true, "which is not comparable"}, + ltTestCase{[...]int{-151}, false, true, "which is not comparable"}, + ltTestCase{make(chan int), false, true, "which is not comparable"}, + ltTestCase{func() {}, false, true, "which is not comparable"}, + ltTestCase{map[int]int{}, false, true, "which is not comparable"}, + ltTestCase{<TestCase{}, false, true, "which is not comparable"}, + ltTestCase{make([]int, 0), false, true, "which is not comparable"}, + ltTestCase{ltTestCase{}, false, true, "which is not comparable"}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessThanTest) BadArgument() { + panicked := false + + defer func() { + ExpectThat(panicked, Equals(true)) + }() + + defer func() { + if r := recover(); r != nil { + panicked = true + } + }() + + LessThan(complex128(0)) +} + +//////////////////////////////////////////////////////////////////////// +// Integer literals +//////////////////////////////////////////////////////////////////////// + +func (t *LessThanTest) NegativeIntegerLiteral() { + matcher := LessThan(-150) + desc := matcher.Description() + expectedDesc := "less than -150" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []ltTestCase{ + // Signed integers. + ltTestCase{-(1 << 30), true, false, ""}, + ltTestCase{-151, true, false, ""}, + ltTestCase{-150, false, false, ""}, + ltTestCase{0, false, false, ""}, + ltTestCase{17, false, false, ""}, + + ltTestCase{int(-(1 << 30)), true, false, ""}, + ltTestCase{int(-151), true, false, ""}, + ltTestCase{int(-150), false, false, ""}, + ltTestCase{int(0), false, false, ""}, + ltTestCase{int(17), false, false, ""}, + + ltTestCase{int8(-127), false, false, ""}, + ltTestCase{int8(0), false, false, ""}, + ltTestCase{int8(17), false, false, ""}, + + ltTestCase{int16(-(1 << 14)), true, false, ""}, + ltTestCase{int16(-151), true, false, ""}, + ltTestCase{int16(-150), false, false, ""}, + ltTestCase{int16(0), false, false, ""}, + ltTestCase{int16(17), false, false, ""}, + + ltTestCase{int32(-(1 << 30)), true, false, ""}, + ltTestCase{int32(-151), true, false, ""}, + ltTestCase{int32(-150), false, false, ""}, + ltTestCase{int32(0), false, false, ""}, + ltTestCase{int32(17), false, false, ""}, + + ltTestCase{int64(-(1 << 30)), true, false, ""}, + ltTestCase{int64(-151), true, false, ""}, + ltTestCase{int64(-150), false, false, ""}, + ltTestCase{int64(0), false, false, ""}, + ltTestCase{int64(17), false, false, ""}, + + // Unsigned integers. + ltTestCase{uint((1 << 32) - 151), false, false, ""}, + ltTestCase{uint(0), false, false, ""}, + ltTestCase{uint(17), false, false, ""}, + + ltTestCase{uint8(0), false, false, ""}, + ltTestCase{uint8(17), false, false, ""}, + ltTestCase{uint8(253), false, false, ""}, + + ltTestCase{uint16((1 << 16) - 151), false, false, ""}, + ltTestCase{uint16(0), false, false, ""}, + ltTestCase{uint16(17), false, false, ""}, + + ltTestCase{uint32((1 << 32) - 151), false, false, ""}, + ltTestCase{uint32(0), false, false, ""}, + ltTestCase{uint32(17), false, false, ""}, + + ltTestCase{uint64((1 << 64) - 151), false, false, ""}, + ltTestCase{uint64(0), false, false, ""}, + ltTestCase{uint64(17), false, false, ""}, + + // Floating point. + ltTestCase{float32(-(1 << 30)), true, false, ""}, + ltTestCase{float32(-151), true, false, ""}, + ltTestCase{float32(-150.1), true, false, ""}, + ltTestCase{float32(-150), false, false, ""}, + ltTestCase{float32(-149.9), false, false, ""}, + ltTestCase{float32(0), false, false, ""}, + ltTestCase{float32(17), false, false, ""}, + ltTestCase{float32(160), false, false, ""}, + + ltTestCase{float64(-(1 << 30)), true, false, ""}, + ltTestCase{float64(-151), true, false, ""}, + ltTestCase{float64(-150.1), true, false, ""}, + ltTestCase{float64(-150), false, false, ""}, + ltTestCase{float64(-149.9), false, false, ""}, + ltTestCase{float64(0), false, false, ""}, + ltTestCase{float64(17), false, false, ""}, + ltTestCase{float64(160), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessThanTest) ZeroIntegerLiteral() { + matcher := LessThan(0) + desc := matcher.Description() + expectedDesc := "less than 0" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []ltTestCase{ + // Signed integers. + ltTestCase{-(1 << 30), true, false, ""}, + ltTestCase{-1, true, false, ""}, + ltTestCase{0, false, false, ""}, + ltTestCase{1, false, false, ""}, + ltTestCase{17, false, false, ""}, + ltTestCase{(1 << 30), false, false, ""}, + + ltTestCase{int(-(1 << 30)), true, false, ""}, + ltTestCase{int(-1), true, false, ""}, + ltTestCase{int(0), false, false, ""}, + ltTestCase{int(1), false, false, ""}, + ltTestCase{int(17), false, false, ""}, + + ltTestCase{int8(-1), true, false, ""}, + ltTestCase{int8(0), false, false, ""}, + ltTestCase{int8(1), false, false, ""}, + + ltTestCase{int16(-(1 << 14)), true, false, ""}, + ltTestCase{int16(-1), true, false, ""}, + ltTestCase{int16(0), false, false, ""}, + ltTestCase{int16(1), false, false, ""}, + ltTestCase{int16(17), false, false, ""}, + + ltTestCase{int32(-(1 << 30)), true, false, ""}, + ltTestCase{int32(-1), true, false, ""}, + ltTestCase{int32(0), false, false, ""}, + ltTestCase{int32(1), false, false, ""}, + ltTestCase{int32(17), false, false, ""}, + + ltTestCase{int64(-(1 << 30)), true, false, ""}, + ltTestCase{int64(-1), true, false, ""}, + ltTestCase{int64(0), false, false, ""}, + ltTestCase{int64(1), false, false, ""}, + ltTestCase{int64(17), false, false, ""}, + + // Unsigned integers. + ltTestCase{uint((1 << 32) - 1), false, false, ""}, + ltTestCase{uint(0), false, false, ""}, + ltTestCase{uint(17), false, false, ""}, + + ltTestCase{uint8(0), false, false, ""}, + ltTestCase{uint8(17), false, false, ""}, + ltTestCase{uint8(253), false, false, ""}, + + ltTestCase{uint16((1 << 16) - 1), false, false, ""}, + ltTestCase{uint16(0), false, false, ""}, + ltTestCase{uint16(17), false, false, ""}, + + ltTestCase{uint32((1 << 32) - 1), false, false, ""}, + ltTestCase{uint32(0), false, false, ""}, + ltTestCase{uint32(17), false, false, ""}, + + ltTestCase{uint64((1 << 64) - 1), false, false, ""}, + ltTestCase{uint64(0), false, false, ""}, + ltTestCase{uint64(17), false, false, ""}, + + // Floating point. + ltTestCase{float32(-(1 << 30)), true, false, ""}, + ltTestCase{float32(-1), true, false, ""}, + ltTestCase{float32(-0.1), true, false, ""}, + ltTestCase{float32(-0.0), false, false, ""}, + ltTestCase{float32(0), false, false, ""}, + ltTestCase{float32(0.1), false, false, ""}, + ltTestCase{float32(17), false, false, ""}, + ltTestCase{float32(160), false, false, ""}, + + ltTestCase{float64(-(1 << 30)), true, false, ""}, + ltTestCase{float64(-1), true, false, ""}, + ltTestCase{float64(-0.1), true, false, ""}, + ltTestCase{float64(-0), false, false, ""}, + ltTestCase{float64(0), false, false, ""}, + ltTestCase{float64(17), false, false, ""}, + ltTestCase{float64(160), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessThanTest) PositiveIntegerLiteral() { + matcher := LessThan(150) + desc := matcher.Description() + expectedDesc := "less than 150" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []ltTestCase{ + // Signed integers. + ltTestCase{-1, true, false, ""}, + ltTestCase{149, true, false, ""}, + ltTestCase{150, false, false, ""}, + ltTestCase{151, false, false, ""}, + + ltTestCase{int(-1), true, false, ""}, + ltTestCase{int(149), true, false, ""}, + ltTestCase{int(150), false, false, ""}, + ltTestCase{int(151), false, false, ""}, + + ltTestCase{int8(-1), true, false, ""}, + ltTestCase{int8(0), true, false, ""}, + ltTestCase{int8(17), true, false, ""}, + ltTestCase{int8(127), true, false, ""}, + + ltTestCase{int16(-1), true, false, ""}, + ltTestCase{int16(149), true, false, ""}, + ltTestCase{int16(150), false, false, ""}, + ltTestCase{int16(151), false, false, ""}, + + ltTestCase{int32(-1), true, false, ""}, + ltTestCase{int32(149), true, false, ""}, + ltTestCase{int32(150), false, false, ""}, + ltTestCase{int32(151), false, false, ""}, + + ltTestCase{int64(-1), true, false, ""}, + ltTestCase{int64(149), true, false, ""}, + ltTestCase{int64(150), false, false, ""}, + ltTestCase{int64(151), false, false, ""}, + + // Unsigned integers. + ltTestCase{uint(0), true, false, ""}, + ltTestCase{uint(149), true, false, ""}, + ltTestCase{uint(150), false, false, ""}, + ltTestCase{uint(151), false, false, ""}, + + ltTestCase{uint8(0), true, false, ""}, + ltTestCase{uint8(127), true, false, ""}, + + ltTestCase{uint16(0), true, false, ""}, + ltTestCase{uint16(149), true, false, ""}, + ltTestCase{uint16(150), false, false, ""}, + ltTestCase{uint16(151), false, false, ""}, + + ltTestCase{uint32(0), true, false, ""}, + ltTestCase{uint32(149), true, false, ""}, + ltTestCase{uint32(150), false, false, ""}, + ltTestCase{uint32(151), false, false, ""}, + + ltTestCase{uint64(0), true, false, ""}, + ltTestCase{uint64(149), true, false, ""}, + ltTestCase{uint64(150), false, false, ""}, + ltTestCase{uint64(151), false, false, ""}, + + // Floating point. + ltTestCase{float32(-1), true, false, ""}, + ltTestCase{float32(149), true, false, ""}, + ltTestCase{float32(149.9), true, false, ""}, + ltTestCase{float32(150), false, false, ""}, + ltTestCase{float32(150.1), false, false, ""}, + ltTestCase{float32(151), false, false, ""}, + + ltTestCase{float64(-1), true, false, ""}, + ltTestCase{float64(149), true, false, ""}, + ltTestCase{float64(149.9), true, false, ""}, + ltTestCase{float64(150), false, false, ""}, + ltTestCase{float64(150.1), false, false, ""}, + ltTestCase{float64(151), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// Float literals +//////////////////////////////////////////////////////////////////////// + +func (t *LessThanTest) NegativeFloatLiteral() { + matcher := LessThan(-150.1) + desc := matcher.Description() + expectedDesc := "less than -150.1" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []ltTestCase{ + // Signed integers. + ltTestCase{-(1 << 30), true, false, ""}, + ltTestCase{-151, true, false, ""}, + ltTestCase{-150, false, false, ""}, + ltTestCase{0, false, false, ""}, + ltTestCase{17, false, false, ""}, + + ltTestCase{int(-(1 << 30)), true, false, ""}, + ltTestCase{int(-151), true, false, ""}, + ltTestCase{int(-150), false, false, ""}, + ltTestCase{int(0), false, false, ""}, + ltTestCase{int(17), false, false, ""}, + + ltTestCase{int8(-127), false, false, ""}, + ltTestCase{int8(0), false, false, ""}, + ltTestCase{int8(17), false, false, ""}, + + ltTestCase{int16(-(1 << 14)), true, false, ""}, + ltTestCase{int16(-151), true, false, ""}, + ltTestCase{int16(-150), false, false, ""}, + ltTestCase{int16(0), false, false, ""}, + ltTestCase{int16(17), false, false, ""}, + + ltTestCase{int32(-(1 << 30)), true, false, ""}, + ltTestCase{int32(-151), true, false, ""}, + ltTestCase{int32(-150), false, false, ""}, + ltTestCase{int32(0), false, false, ""}, + ltTestCase{int32(17), false, false, ""}, + + ltTestCase{int64(-(1 << 30)), true, false, ""}, + ltTestCase{int64(-151), true, false, ""}, + ltTestCase{int64(-150), false, false, ""}, + ltTestCase{int64(0), false, false, ""}, + ltTestCase{int64(17), false, false, ""}, + + // Unsigned integers. + ltTestCase{uint((1 << 32) - 151), false, false, ""}, + ltTestCase{uint(0), false, false, ""}, + ltTestCase{uint(17), false, false, ""}, + + ltTestCase{uint8(0), false, false, ""}, + ltTestCase{uint8(17), false, false, ""}, + ltTestCase{uint8(253), false, false, ""}, + + ltTestCase{uint16((1 << 16) - 151), false, false, ""}, + ltTestCase{uint16(0), false, false, ""}, + ltTestCase{uint16(17), false, false, ""}, + + ltTestCase{uint32((1 << 32) - 151), false, false, ""}, + ltTestCase{uint32(0), false, false, ""}, + ltTestCase{uint32(17), false, false, ""}, + + ltTestCase{uint64((1 << 64) - 151), false, false, ""}, + ltTestCase{uint64(0), false, false, ""}, + ltTestCase{uint64(17), false, false, ""}, + + // Floating point. + ltTestCase{float32(-(1 << 30)), true, false, ""}, + ltTestCase{float32(-151), true, false, ""}, + ltTestCase{float32(-150.2), true, false, ""}, + ltTestCase{float32(-150.1), false, false, ""}, + ltTestCase{float32(-150), false, false, ""}, + ltTestCase{float32(0), false, false, ""}, + ltTestCase{float32(17), false, false, ""}, + ltTestCase{float32(160), false, false, ""}, + + ltTestCase{float64(-(1 << 30)), true, false, ""}, + ltTestCase{float64(-151), true, false, ""}, + ltTestCase{float64(-150.2), true, false, ""}, + ltTestCase{float64(-150.1), false, false, ""}, + ltTestCase{float64(-150), false, false, ""}, + ltTestCase{float64(0), false, false, ""}, + ltTestCase{float64(17), false, false, ""}, + ltTestCase{float64(160), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessThanTest) PositiveFloatLiteral() { + matcher := LessThan(149.9) + desc := matcher.Description() + expectedDesc := "less than 149.9" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []ltTestCase{ + // Signed integers. + ltTestCase{-1, true, false, ""}, + ltTestCase{149, true, false, ""}, + ltTestCase{150, false, false, ""}, + ltTestCase{151, false, false, ""}, + + ltTestCase{int(-1), true, false, ""}, + ltTestCase{int(149), true, false, ""}, + ltTestCase{int(150), false, false, ""}, + ltTestCase{int(151), false, false, ""}, + + ltTestCase{int8(-1), true, false, ""}, + ltTestCase{int8(0), true, false, ""}, + ltTestCase{int8(17), true, false, ""}, + ltTestCase{int8(127), true, false, ""}, + + ltTestCase{int16(-1), true, false, ""}, + ltTestCase{int16(149), true, false, ""}, + ltTestCase{int16(150), false, false, ""}, + ltTestCase{int16(151), false, false, ""}, + + ltTestCase{int32(-1), true, false, ""}, + ltTestCase{int32(149), true, false, ""}, + ltTestCase{int32(150), false, false, ""}, + ltTestCase{int32(151), false, false, ""}, + + ltTestCase{int64(-1), true, false, ""}, + ltTestCase{int64(149), true, false, ""}, + ltTestCase{int64(150), false, false, ""}, + ltTestCase{int64(151), false, false, ""}, + + // Unsigned integers. + ltTestCase{uint(0), true, false, ""}, + ltTestCase{uint(149), true, false, ""}, + ltTestCase{uint(150), false, false, ""}, + ltTestCase{uint(151), false, false, ""}, + + ltTestCase{uint8(0), true, false, ""}, + ltTestCase{uint8(127), true, false, ""}, + + ltTestCase{uint16(0), true, false, ""}, + ltTestCase{uint16(149), true, false, ""}, + ltTestCase{uint16(150), false, false, ""}, + ltTestCase{uint16(151), false, false, ""}, + + ltTestCase{uint32(0), true, false, ""}, + ltTestCase{uint32(149), true, false, ""}, + ltTestCase{uint32(150), false, false, ""}, + ltTestCase{uint32(151), false, false, ""}, + + ltTestCase{uint64(0), true, false, ""}, + ltTestCase{uint64(149), true, false, ""}, + ltTestCase{uint64(150), false, false, ""}, + ltTestCase{uint64(151), false, false, ""}, + + // Floating point. + ltTestCase{float32(-1), true, false, ""}, + ltTestCase{float32(149), true, false, ""}, + ltTestCase{float32(149.8), true, false, ""}, + ltTestCase{float32(149.9), false, false, ""}, + ltTestCase{float32(150), false, false, ""}, + ltTestCase{float32(151), false, false, ""}, + + ltTestCase{float64(-1), true, false, ""}, + ltTestCase{float64(149), true, false, ""}, + ltTestCase{float64(149.8), true, false, ""}, + ltTestCase{float64(149.9), false, false, ""}, + ltTestCase{float64(150), false, false, ""}, + ltTestCase{float64(151), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// Subtle cases +//////////////////////////////////////////////////////////////////////// + +func (t *LessThanTest) Int64NotExactlyRepresentableBySinglePrecision() { + // Single-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo25 = 1 << 25 + matcher := LessThan(int64(kTwoTo25 + 1)) + + desc := matcher.Description() + expectedDesc := "less than 33554433" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []ltTestCase{ + // Signed integers. + ltTestCase{-1, true, false, ""}, + ltTestCase{kTwoTo25 + 0, true, false, ""}, + ltTestCase{kTwoTo25 + 1, false, false, ""}, + ltTestCase{kTwoTo25 + 2, false, false, ""}, + + ltTestCase{int(-1), true, false, ""}, + ltTestCase{int(kTwoTo25 + 0), true, false, ""}, + ltTestCase{int(kTwoTo25 + 1), false, false, ""}, + ltTestCase{int(kTwoTo25 + 2), false, false, ""}, + + ltTestCase{int8(-1), true, false, ""}, + ltTestCase{int8(127), true, false, ""}, + + ltTestCase{int16(-1), true, false, ""}, + ltTestCase{int16(0), true, false, ""}, + ltTestCase{int16(32767), true, false, ""}, + + ltTestCase{int32(-1), true, false, ""}, + ltTestCase{int32(kTwoTo25 + 0), true, false, ""}, + ltTestCase{int32(kTwoTo25 + 1), false, false, ""}, + ltTestCase{int32(kTwoTo25 + 2), false, false, ""}, + + ltTestCase{int64(-1), true, false, ""}, + ltTestCase{int64(kTwoTo25 + 0), true, false, ""}, + ltTestCase{int64(kTwoTo25 + 1), false, false, ""}, + ltTestCase{int64(kTwoTo25 + 2), false, false, ""}, + + // Unsigned integers. + ltTestCase{uint(0), true, false, ""}, + ltTestCase{uint(kTwoTo25 + 0), true, false, ""}, + ltTestCase{uint(kTwoTo25 + 1), false, false, ""}, + ltTestCase{uint(kTwoTo25 + 2), false, false, ""}, + + ltTestCase{uint8(0), true, false, ""}, + ltTestCase{uint8(255), true, false, ""}, + + ltTestCase{uint16(0), true, false, ""}, + ltTestCase{uint16(65535), true, false, ""}, + + ltTestCase{uint32(0), true, false, ""}, + ltTestCase{uint32(kTwoTo25 + 0), true, false, ""}, + ltTestCase{uint32(kTwoTo25 + 1), false, false, ""}, + ltTestCase{uint32(kTwoTo25 + 2), false, false, ""}, + + ltTestCase{uint64(0), true, false, ""}, + ltTestCase{uint64(kTwoTo25 + 0), true, false, ""}, + ltTestCase{uint64(kTwoTo25 + 1), false, false, ""}, + ltTestCase{uint64(kTwoTo25 + 2), false, false, ""}, + + // Floating point. + ltTestCase{float32(-1), true, false, ""}, + ltTestCase{float32(kTwoTo25 - 2), true, false, ""}, + ltTestCase{float32(kTwoTo25 - 1), false, false, ""}, + ltTestCase{float32(kTwoTo25 + 0), false, false, ""}, + ltTestCase{float32(kTwoTo25 + 1), false, false, ""}, + ltTestCase{float32(kTwoTo25 + 2), false, false, ""}, + ltTestCase{float32(kTwoTo25 + 3), false, false, ""}, + + ltTestCase{float64(-1), true, false, ""}, + ltTestCase{float64(kTwoTo25 - 2), true, false, ""}, + ltTestCase{float64(kTwoTo25 - 1), true, false, ""}, + ltTestCase{float64(kTwoTo25 + 0), true, false, ""}, + ltTestCase{float64(kTwoTo25 + 1), false, false, ""}, + ltTestCase{float64(kTwoTo25 + 2), false, false, ""}, + ltTestCase{float64(kTwoTo25 + 3), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessThanTest) Int64NotExactlyRepresentableByDoublePrecision() { + // Double-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^54-1, 2^54+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo54 = 1 << 54 + matcher := LessThan(int64(kTwoTo54 + 1)) + + desc := matcher.Description() + expectedDesc := "less than 18014398509481985" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []ltTestCase{ + // Signed integers. + ltTestCase{-1, true, false, ""}, + ltTestCase{1 << 30, true, false, ""}, + + ltTestCase{int(-1), true, false, ""}, + ltTestCase{int(math.MaxInt32), true, false, ""}, + + ltTestCase{int8(-1), true, false, ""}, + ltTestCase{int8(127), true, false, ""}, + + ltTestCase{int16(-1), true, false, ""}, + ltTestCase{int16(0), true, false, ""}, + ltTestCase{int16(32767), true, false, ""}, + + ltTestCase{int32(-1), true, false, ""}, + ltTestCase{int32(math.MaxInt32), true, false, ""}, + + ltTestCase{int64(-1), true, false, ""}, + ltTestCase{int64(kTwoTo54 - 1), true, false, ""}, + ltTestCase{int64(kTwoTo54 + 0), true, false, ""}, + ltTestCase{int64(kTwoTo54 + 1), false, false, ""}, + ltTestCase{int64(kTwoTo54 + 2), false, false, ""}, + + // Unsigned integers. + ltTestCase{uint(0), true, false, ""}, + ltTestCase{uint(math.MaxUint32), true, false, ""}, + + ltTestCase{uint8(0), true, false, ""}, + ltTestCase{uint8(255), true, false, ""}, + + ltTestCase{uint16(0), true, false, ""}, + ltTestCase{uint16(65535), true, false, ""}, + + ltTestCase{uint32(0), true, false, ""}, + ltTestCase{uint32(math.MaxUint32), true, false, ""}, + + ltTestCase{uint64(0), true, false, ""}, + ltTestCase{uint64(kTwoTo54 - 1), true, false, ""}, + ltTestCase{uint64(kTwoTo54 + 0), true, false, ""}, + ltTestCase{uint64(kTwoTo54 + 1), false, false, ""}, + ltTestCase{uint64(kTwoTo54 + 2), false, false, ""}, + + // Floating point. + ltTestCase{float64(-1), true, false, ""}, + ltTestCase{float64(kTwoTo54 - 2), true, false, ""}, + ltTestCase{float64(kTwoTo54 - 1), false, false, ""}, + ltTestCase{float64(kTwoTo54 + 0), false, false, ""}, + ltTestCase{float64(kTwoTo54 + 1), false, false, ""}, + ltTestCase{float64(kTwoTo54 + 2), false, false, ""}, + ltTestCase{float64(kTwoTo54 + 3), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessThanTest) Uint64NotExactlyRepresentableBySinglePrecision() { + // Single-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo25 = 1 << 25 + matcher := LessThan(uint64(kTwoTo25 + 1)) + + desc := matcher.Description() + expectedDesc := "less than 33554433" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []ltTestCase{ + // Signed integers. + ltTestCase{-1, true, false, ""}, + ltTestCase{kTwoTo25 + 0, true, false, ""}, + ltTestCase{kTwoTo25 + 1, false, false, ""}, + ltTestCase{kTwoTo25 + 2, false, false, ""}, + + ltTestCase{int(-1), true, false, ""}, + ltTestCase{int(kTwoTo25 + 0), true, false, ""}, + ltTestCase{int(kTwoTo25 + 1), false, false, ""}, + ltTestCase{int(kTwoTo25 + 2), false, false, ""}, + + ltTestCase{int8(-1), true, false, ""}, + ltTestCase{int8(127), true, false, ""}, + + ltTestCase{int16(-1), true, false, ""}, + ltTestCase{int16(0), true, false, ""}, + ltTestCase{int16(32767), true, false, ""}, + + ltTestCase{int32(-1), true, false, ""}, + ltTestCase{int32(kTwoTo25 + 0), true, false, ""}, + ltTestCase{int32(kTwoTo25 + 1), false, false, ""}, + ltTestCase{int32(kTwoTo25 + 2), false, false, ""}, + + ltTestCase{int64(-1), true, false, ""}, + ltTestCase{int64(kTwoTo25 + 0), true, false, ""}, + ltTestCase{int64(kTwoTo25 + 1), false, false, ""}, + ltTestCase{int64(kTwoTo25 + 2), false, false, ""}, + + // Unsigned integers. + ltTestCase{uint(0), true, false, ""}, + ltTestCase{uint(kTwoTo25 + 0), true, false, ""}, + ltTestCase{uint(kTwoTo25 + 1), false, false, ""}, + ltTestCase{uint(kTwoTo25 + 2), false, false, ""}, + + ltTestCase{uint8(0), true, false, ""}, + ltTestCase{uint8(255), true, false, ""}, + + ltTestCase{uint16(0), true, false, ""}, + ltTestCase{uint16(65535), true, false, ""}, + + ltTestCase{uint32(0), true, false, ""}, + ltTestCase{uint32(kTwoTo25 + 0), true, false, ""}, + ltTestCase{uint32(kTwoTo25 + 1), false, false, ""}, + ltTestCase{uint32(kTwoTo25 + 2), false, false, ""}, + + ltTestCase{uint64(0), true, false, ""}, + ltTestCase{uint64(kTwoTo25 + 0), true, false, ""}, + ltTestCase{uint64(kTwoTo25 + 1), false, false, ""}, + ltTestCase{uint64(kTwoTo25 + 2), false, false, ""}, + + // Floating point. + ltTestCase{float32(-1), true, false, ""}, + ltTestCase{float32(kTwoTo25 - 2), true, false, ""}, + ltTestCase{float32(kTwoTo25 - 1), false, false, ""}, + ltTestCase{float32(kTwoTo25 + 0), false, false, ""}, + ltTestCase{float32(kTwoTo25 + 1), false, false, ""}, + ltTestCase{float32(kTwoTo25 + 2), false, false, ""}, + ltTestCase{float32(kTwoTo25 + 3), false, false, ""}, + + ltTestCase{float64(-1), true, false, ""}, + ltTestCase{float64(kTwoTo25 - 2), true, false, ""}, + ltTestCase{float64(kTwoTo25 - 1), true, false, ""}, + ltTestCase{float64(kTwoTo25 + 0), true, false, ""}, + ltTestCase{float64(kTwoTo25 + 1), false, false, ""}, + ltTestCase{float64(kTwoTo25 + 2), false, false, ""}, + ltTestCase{float64(kTwoTo25 + 3), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessThanTest) Uint64NotExactlyRepresentableByDoublePrecision() { + // Double-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^54-1, 2^54+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo54 = 1 << 54 + matcher := LessThan(uint64(kTwoTo54 + 1)) + + desc := matcher.Description() + expectedDesc := "less than 18014398509481985" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []ltTestCase{ + // Signed integers. + ltTestCase{-1, true, false, ""}, + ltTestCase{1 << 30, true, false, ""}, + + ltTestCase{int(-1), true, false, ""}, + ltTestCase{int(math.MaxInt32), true, false, ""}, + + ltTestCase{int8(-1), true, false, ""}, + ltTestCase{int8(127), true, false, ""}, + + ltTestCase{int16(-1), true, false, ""}, + ltTestCase{int16(0), true, false, ""}, + ltTestCase{int16(32767), true, false, ""}, + + ltTestCase{int32(-1), true, false, ""}, + ltTestCase{int32(math.MaxInt32), true, false, ""}, + + ltTestCase{int64(-1), true, false, ""}, + ltTestCase{int64(kTwoTo54 - 1), true, false, ""}, + ltTestCase{int64(kTwoTo54 + 0), true, false, ""}, + ltTestCase{int64(kTwoTo54 + 1), false, false, ""}, + ltTestCase{int64(kTwoTo54 + 2), false, false, ""}, + + // Unsigned integers. + ltTestCase{uint(0), true, false, ""}, + ltTestCase{uint(math.MaxUint32), true, false, ""}, + + ltTestCase{uint8(0), true, false, ""}, + ltTestCase{uint8(255), true, false, ""}, + + ltTestCase{uint16(0), true, false, ""}, + ltTestCase{uint16(65535), true, false, ""}, + + ltTestCase{uint32(0), true, false, ""}, + ltTestCase{uint32(math.MaxUint32), true, false, ""}, + + ltTestCase{uint64(0), true, false, ""}, + ltTestCase{uint64(kTwoTo54 - 1), true, false, ""}, + ltTestCase{uint64(kTwoTo54 + 0), true, false, ""}, + ltTestCase{uint64(kTwoTo54 + 1), false, false, ""}, + ltTestCase{uint64(kTwoTo54 + 2), false, false, ""}, + + // Floating point. + ltTestCase{float64(-1), true, false, ""}, + ltTestCase{float64(kTwoTo54 - 2), true, false, ""}, + ltTestCase{float64(kTwoTo54 - 1), false, false, ""}, + ltTestCase{float64(kTwoTo54 + 0), false, false, ""}, + ltTestCase{float64(kTwoTo54 + 1), false, false, ""}, + ltTestCase{float64(kTwoTo54 + 2), false, false, ""}, + ltTestCase{float64(kTwoTo54 + 3), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessThanTest) Float32AboveExactIntegerRange() { + // Single-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^25-1, 2^25+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo25 = 1 << 25 + matcher := LessThan(float32(kTwoTo25 + 1)) + + desc := matcher.Description() + expectedDesc := "less than 3.3554432e+07" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []ltTestCase{ + // Signed integers. + ltTestCase{int64(-1), true, false, ""}, + ltTestCase{int64(kTwoTo25 - 2), true, false, ""}, + ltTestCase{int64(kTwoTo25 - 1), false, false, ""}, + ltTestCase{int64(kTwoTo25 + 0), false, false, ""}, + ltTestCase{int64(kTwoTo25 + 1), false, false, ""}, + ltTestCase{int64(kTwoTo25 + 2), false, false, ""}, + ltTestCase{int64(kTwoTo25 + 3), false, false, ""}, + + // Unsigned integers. + ltTestCase{uint64(0), true, false, ""}, + ltTestCase{uint64(kTwoTo25 - 2), true, false, ""}, + ltTestCase{uint64(kTwoTo25 - 1), false, false, ""}, + ltTestCase{uint64(kTwoTo25 + 0), false, false, ""}, + ltTestCase{uint64(kTwoTo25 + 1), false, false, ""}, + ltTestCase{uint64(kTwoTo25 + 2), false, false, ""}, + ltTestCase{uint64(kTwoTo25 + 3), false, false, ""}, + + // Floating point. + ltTestCase{float32(-1), true, false, ""}, + ltTestCase{float32(kTwoTo25 - 2), true, false, ""}, + ltTestCase{float32(kTwoTo25 - 1), false, false, ""}, + ltTestCase{float32(kTwoTo25 + 0), false, false, ""}, + ltTestCase{float32(kTwoTo25 + 1), false, false, ""}, + ltTestCase{float32(kTwoTo25 + 2), false, false, ""}, + ltTestCase{float32(kTwoTo25 + 3), false, false, ""}, + + ltTestCase{float64(-1), true, false, ""}, + ltTestCase{float64(kTwoTo25 - 2), true, false, ""}, + ltTestCase{float64(kTwoTo25 - 1), false, false, ""}, + ltTestCase{float64(kTwoTo25 + 0), false, false, ""}, + ltTestCase{float64(kTwoTo25 + 1), false, false, ""}, + ltTestCase{float64(kTwoTo25 + 2), false, false, ""}, + ltTestCase{float64(kTwoTo25 + 3), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessThanTest) Float64AboveExactIntegerRange() { + // Double-precision floats don't have enough bits to represent the integers + // near this one distinctly, so [2^54-1, 2^54+2] all receive the same value + // and should be treated as equivalent when floats are in the mix. + const kTwoTo54 = 1 << 54 + matcher := LessThan(float64(kTwoTo54 + 1)) + + desc := matcher.Description() + expectedDesc := "less than 1.8014398509481984e+16" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []ltTestCase{ + // Signed integers. + ltTestCase{int64(-1), true, false, ""}, + ltTestCase{int64(kTwoTo54 - 2), true, false, ""}, + ltTestCase{int64(kTwoTo54 - 1), false, false, ""}, + ltTestCase{int64(kTwoTo54 + 0), false, false, ""}, + ltTestCase{int64(kTwoTo54 + 1), false, false, ""}, + ltTestCase{int64(kTwoTo54 + 2), false, false, ""}, + ltTestCase{int64(kTwoTo54 + 3), false, false, ""}, + + // Unsigned integers. + ltTestCase{uint64(0), true, false, ""}, + ltTestCase{uint64(kTwoTo54 - 2), true, false, ""}, + ltTestCase{uint64(kTwoTo54 - 1), false, false, ""}, + ltTestCase{uint64(kTwoTo54 + 0), false, false, ""}, + ltTestCase{uint64(kTwoTo54 + 1), false, false, ""}, + ltTestCase{uint64(kTwoTo54 + 2), false, false, ""}, + ltTestCase{uint64(kTwoTo54 + 3), false, false, ""}, + + // Floating point. + ltTestCase{float64(-1), true, false, ""}, + ltTestCase{float64(kTwoTo54 - 2), true, false, ""}, + ltTestCase{float64(kTwoTo54 - 1), false, false, ""}, + ltTestCase{float64(kTwoTo54 + 0), false, false, ""}, + ltTestCase{float64(kTwoTo54 + 1), false, false, ""}, + ltTestCase{float64(kTwoTo54 + 2), false, false, ""}, + ltTestCase{float64(kTwoTo54 + 3), false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +//////////////////////////////////////////////////////////////////////// +// String literals +//////////////////////////////////////////////////////////////////////// + +func (t *LessThanTest) EmptyString() { + matcher := LessThan("") + desc := matcher.Description() + expectedDesc := "less than \"\"" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []ltTestCase{ + ltTestCase{"", false, false, ""}, + ltTestCase{"\x00", false, false, ""}, + ltTestCase{"a", false, false, ""}, + ltTestCase{"foo", false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessThanTest) SingleNullByte() { + matcher := LessThan("\x00") + desc := matcher.Description() + expectedDesc := "less than \"\x00\"" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []ltTestCase{ + ltTestCase{"", true, false, ""}, + ltTestCase{"\x00", false, false, ""}, + ltTestCase{"a", false, false, ""}, + ltTestCase{"foo", false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} + +func (t *LessThanTest) LongerString() { + matcher := LessThan("foo\x00") + desc := matcher.Description() + expectedDesc := "less than \"foo\x00\"" + + ExpectThat(desc, Equals(expectedDesc)) + + cases := []ltTestCase{ + ltTestCase{"", true, false, ""}, + ltTestCase{"\x00", true, false, ""}, + ltTestCase{"bar", true, false, ""}, + ltTestCase{"foo", true, false, ""}, + ltTestCase{"foo\x00", false, false, ""}, + ltTestCase{"fooa", false, false, ""}, + ltTestCase{"qux", false, false, ""}, + } + + t.checkTestCases(matcher, cases) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/matcher.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/matcher.go new file mode 100644 index 00000000000..78159a0727c --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/matcher.go @@ -0,0 +1,86 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package oglematchers provides a set of matchers useful in a testing or +// mocking framework. These matchers are inspired by and mostly compatible with +// Google Test for C++ and Google JS Test. +// +// This package is used by github.com/smartystreets/assertions/internal/ogletest and +// github.com/smartystreets/assertions/internal/oglemock, which may be more directly useful if you're not +// writing your own testing package or defining your own matchers. +package oglematchers + +// A Matcher is some predicate implicitly defining a set of values that it +// matches. For example, GreaterThan(17) matches all numeric values greater +// than 17, and HasSubstr("taco") matches all strings with the substring +// "taco". +// +// Matchers are typically exposed to tests via constructor functions like +// HasSubstr. In order to implement such a function you can either define your +// own matcher type or use NewMatcher. +type Matcher interface { + // Check whether the supplied value belongs to the the set defined by the + // matcher. Return a non-nil error if and only if it does not. + // + // The error describes why the value doesn't match. The error text is a + // relative clause that is suitable for being placed after the value. For + // example, a predicate that matches strings with a particular substring may, + // when presented with a numerical value, return the following error text: + // + // "which is not a string" + // + // Then the failure message may look like: + // + // Expected: has substring "taco" + // Actual: 17, which is not a string + // + // If the error is self-apparent based on the description of the matcher, the + // error text may be empty (but the error still non-nil). For example: + // + // Expected: 17 + // Actual: 19 + // + // If you are implementing a new matcher, see also the documentation on + // FatalError. + Matches(candidate interface{}) error + + // Description returns a string describing the property that values matching + // this matcher have, as a verb phrase where the subject is the value. For + // example, "is greather than 17" or "has substring "taco"". + Description() string +} + +// FatalError is an implementation of the error interface that may be returned +// from matchers, indicating the error should be propagated. Returning a +// *FatalError indicates that the matcher doesn't process values of the +// supplied type, or otherwise doesn't know how to handle the value. +// +// For example, if GreaterThan(17) returned false for the value "taco" without +// a fatal error, then Not(GreaterThan(17)) would return true. This is +// technically correct, but is surprising and may mask failures where the wrong +// sort of matcher is accidentally used. Instead, GreaterThan(17) can return a +// fatal error, which will be propagated by Not(). +type FatalError struct { + errorText string +} + +// NewFatalError creates a FatalError struct with the supplied error text. +func NewFatalError(s string) *FatalError { + return &FatalError{s} +} + +func (e *FatalError) Error() string { + return e.errorText +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/matches_regexp.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/matches_regexp.go new file mode 100644 index 00000000000..1ed63f30c4e --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/matches_regexp.go @@ -0,0 +1,69 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package oglematchers + +import ( + "errors" + "fmt" + "reflect" + "regexp" +) + +// MatchesRegexp returns a matcher that matches strings and byte slices whose +// contents match the supplied regular expression. The semantics are those of +// regexp.Match. In particular, that means the match is not implicitly anchored +// to the ends of the string: MatchesRegexp("bar") will match "foo bar baz". +func MatchesRegexp(pattern string) Matcher { + re, err := regexp.Compile(pattern) + if err != nil { + panic("MatchesRegexp: " + err.Error()) + } + + return &matchesRegexpMatcher{re} +} + +type matchesRegexpMatcher struct { + re *regexp.Regexp +} + +func (m *matchesRegexpMatcher) Description() string { + return fmt.Sprintf("matches regexp \"%s\"", m.re.String()) +} + +func (m *matchesRegexpMatcher) Matches(c interface{}) (err error) { + v := reflect.ValueOf(c) + isString := v.Kind() == reflect.String + isByteSlice := v.Kind() == reflect.Slice && v.Elem().Kind() == reflect.Uint8 + + err = errors.New("") + + switch { + case isString: + if m.re.MatchString(v.String()) { + err = nil + } + + case isByteSlice: + if m.re.Match(v.Bytes()) { + err = nil + } + + default: + err = NewFatalError("which is not a string or []byte") + } + + return +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/matches_regexp_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/matches_regexp_test.go new file mode 100644 index 00000000000..031c6cb3eff --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/matches_regexp_test.go @@ -0,0 +1,92 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package oglematchers_test + +import ( + . "github.com/smartystreets/assertions/internal/oglematchers" + . "github.com/smartystreets/assertions/internal/ogletest" +) + +//////////////////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////////////////// + +type MatchesRegexpTest struct { +} + +func init() { RegisterTestSuite(&MatchesRegexpTest{}) } + +//////////////////////////////////////////////////////////////////////// +// Tests +//////////////////////////////////////////////////////////////////////// + +func (t *MatchesRegexpTest) Description() { + m := MatchesRegexp("foo.*bar") + ExpectEq("matches regexp \"foo.*bar\"", m.Description()) +} + +func (t *MatchesRegexpTest) InvalidRegexp() { + ExpectThat( + func() { MatchesRegexp("(foo") }, + Panics(HasSubstr("missing closing )"))) +} + +func (t *MatchesRegexpTest) CandidateIsNil() { + m := MatchesRegexp("") + err := m.Matches(nil) + + ExpectThat(err, Error(Equals("which is not a string or []byte"))) + ExpectTrue(isFatal(err)) +} + +func (t *MatchesRegexpTest) CandidateIsInteger() { + m := MatchesRegexp("") + err := m.Matches(17) + + ExpectThat(err, Error(Equals("which is not a string or []byte"))) + ExpectTrue(isFatal(err)) +} + +func (t *MatchesRegexpTest) NonMatchingCandidates() { + m := MatchesRegexp("fo[op]\\s+x") + var err error + + err = m.Matches("fon x") + ExpectThat(err, Error(Equals(""))) + ExpectFalse(isFatal(err)) + + err = m.Matches("fopx") + ExpectThat(err, Error(Equals(""))) + ExpectFalse(isFatal(err)) + + err = m.Matches("fop ") + ExpectThat(err, Error(Equals(""))) + ExpectFalse(isFatal(err)) +} + +func (t *MatchesRegexpTest) MatchingCandidates() { + m := MatchesRegexp("fo[op]\\s+x") + var err error + + err = m.Matches("foo x") + ExpectEq(nil, err) + + err = m.Matches("fop x") + ExpectEq(nil, err) + + err = m.Matches("blah blah foo x blah blah") + ExpectEq(nil, err) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/new_matcher.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/new_matcher.go new file mode 100644 index 00000000000..c9d8398ee63 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/new_matcher.go @@ -0,0 +1,43 @@ +// Copyright 2015 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package oglematchers + +// Create a matcher with the given description and predicate function, which +// will be invoked to handle calls to Matchers. +// +// Using this constructor may be a convenience over defining your own type that +// implements Matcher if you do not need any logic in your Description method. +func NewMatcher( + predicate func(interface{}) error, + description string) Matcher { + return &predicateMatcher{ + predicate: predicate, + description: description, + } +} + +type predicateMatcher struct { + predicate func(interface{}) error + description string +} + +func (pm *predicateMatcher) Matches(c interface{}) error { + return pm.predicate(c) +} + +func (pm *predicateMatcher) Description() string { + return pm.description +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/not.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/not.go new file mode 100644 index 00000000000..623789fe28a --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/not.go @@ -0,0 +1,53 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package oglematchers + +import ( + "errors" + "fmt" +) + +// Not returns a matcher that inverts the set of values matched by the wrapped +// matcher. It does not transform the result for values for which the wrapped +// matcher returns a fatal error. +func Not(m Matcher) Matcher { + return ¬Matcher{m} +} + +type notMatcher struct { + wrapped Matcher +} + +func (m *notMatcher) Matches(c interface{}) (err error) { + err = m.wrapped.Matches(c) + + // Did the wrapped matcher say yes? + if err == nil { + return errors.New("") + } + + // Did the wrapped matcher return a fatal error? + if _, isFatal := err.(*FatalError); isFatal { + return err + } + + // The wrapped matcher returned a non-fatal error. + return nil +} + +func (m *notMatcher) Description() string { + return fmt.Sprintf("not(%s)", m.wrapped.Description()) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/not_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/not_test.go new file mode 100644 index 00000000000..9c65b85ef87 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/not_test.go @@ -0,0 +1,108 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package oglematchers_test + +import ( + "errors" + . "github.com/smartystreets/assertions/internal/oglematchers" + . "github.com/smartystreets/assertions/internal/ogletest" + "testing" +) + +//////////////////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////////////////// + +type fakeMatcher struct { + matchFunc func(interface{}) error + description string +} + +func (m *fakeMatcher) Matches(c interface{}) error { + return m.matchFunc(c) +} + +func (m *fakeMatcher) Description() string { + return m.description +} + +type NotTest struct { + +} + +func init() { RegisterTestSuite(&NotTest{}) } +func TestOgletest(t *testing.T) { RunTests(t) } + +//////////////////////////////////////////////////////////////////////// +// Tests +//////////////////////////////////////////////////////////////////////// + +func (t *NotTest) CallsWrapped() { + var suppliedCandidate interface{} + matchFunc := func(c interface{}) error { + suppliedCandidate = c + return nil + } + + wrapped := &fakeMatcher{matchFunc, ""} + matcher := Not(wrapped) + + matcher.Matches(17) + ExpectThat(suppliedCandidate, Equals(17)) +} + +func (t *NotTest) WrappedReturnsTrue() { + matchFunc := func(c interface{}) error { + return nil + } + + wrapped := &fakeMatcher{matchFunc, ""} + matcher := Not(wrapped) + + err := matcher.Matches(0) + ExpectThat(err, Error(Equals(""))) +} + +func (t *NotTest) WrappedReturnsNonFatalError() { + matchFunc := func(c interface{}) error { + return errors.New("taco") + } + + wrapped := &fakeMatcher{matchFunc, ""} + matcher := Not(wrapped) + + err := matcher.Matches(0) + ExpectEq(nil, err) +} + +func (t *NotTest) WrappedReturnsFatalError() { + matchFunc := func(c interface{}) error { + return NewFatalError("taco") + } + + wrapped := &fakeMatcher{matchFunc, ""} + matcher := Not(wrapped) + + err := matcher.Matches(0) + ExpectThat(err, Error(Equals("taco"))) +} + +func (t *NotTest) Description() { + wrapped := &fakeMatcher{nil, "taco"} + matcher := Not(wrapped) + + ExpectEq("not(taco)", matcher.Description()) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/panics.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/panics.go new file mode 100644 index 00000000000..d2cfc97869b --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/panics.go @@ -0,0 +1,74 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package oglematchers + +import ( + "errors" + "fmt" + "reflect" +) + +// Panics matches zero-arg functions which, when invoked, panic with an error +// that matches the supplied matcher. +// +// NOTE(jacobsa): This matcher cannot detect the case where the function panics +// using panic(nil), by design of the language. See here for more info: +// +// http://goo.gl/9aIQL +// +func Panics(m Matcher) Matcher { + return &panicsMatcher{m} +} + +type panicsMatcher struct { + wrappedMatcher Matcher +} + +func (m *panicsMatcher) Description() string { + return "panics with: " + m.wrappedMatcher.Description() +} + +func (m *panicsMatcher) Matches(c interface{}) (err error) { + // Make sure c is a zero-arg function. + v := reflect.ValueOf(c) + if v.Kind() != reflect.Func || v.Type().NumIn() != 0 { + err = NewFatalError("which is not a zero-arg function") + return + } + + // Call the function and check its panic error. + defer func() { + if e := recover(); e != nil { + err = m.wrappedMatcher.Matches(e) + + // Set a clearer error message if the matcher said no. + if err != nil { + wrappedClause := "" + if err.Error() != "" { + wrappedClause = ", " + err.Error() + } + + err = errors.New(fmt.Sprintf("which panicked with: %v%s", e, wrappedClause)) + } + } + }() + + v.Call([]reflect.Value{}) + + // If we get here, the function didn't panic. + err = errors.New("which didn't panic") + return +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/panics_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/panics_test.go new file mode 100644 index 00000000000..fbb66bf31e2 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/panics_test.go @@ -0,0 +1,141 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package oglematchers_test + +import ( + "errors" + . "github.com/smartystreets/assertions/internal/oglematchers" + . "github.com/smartystreets/assertions/internal/ogletest" +) + +//////////////////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////////////////// + +type PanicsTest struct { + matcherCalled bool + suppliedCandidate interface{} + wrappedError error + + matcher Matcher +} + +func init() { RegisterTestSuite(&PanicsTest{}) } + +func (t *PanicsTest) SetUp(i *TestInfo) { + wrapped := &fakeMatcher{ + func(c interface{}) error { + t.matcherCalled = true + t.suppliedCandidate = c + return t.wrappedError + }, + "foo", + } + + t.matcher = Panics(wrapped) +} + +//////////////////////////////////////////////////////////////////////// +// Tests +//////////////////////////////////////////////////////////////////////// + +func (t *PanicsTest) Description() { + ExpectThat(t.matcher.Description(), Equals("panics with: foo")) +} + +func (t *PanicsTest) CandidateIsNil() { + err := t.matcher.Matches(nil) + + ExpectThat(err, Error(Equals("which is not a zero-arg function"))) + ExpectTrue(isFatal(err)) +} + +func (t *PanicsTest) CandidateIsString() { + err := t.matcher.Matches("taco") + + ExpectThat(err, Error(Equals("which is not a zero-arg function"))) + ExpectTrue(isFatal(err)) +} + +func (t *PanicsTest) CandidateTakesArgs() { + err := t.matcher.Matches(func(i int) string { return "" }) + + ExpectThat(err, Error(Equals("which is not a zero-arg function"))) + ExpectTrue(isFatal(err)) +} + +func (t *PanicsTest) CallsFunction() { + callCount := 0 + t.matcher.Matches(func() string { + callCount++ + return "" + }) + + ExpectThat(callCount, Equals(1)) +} + +func (t *PanicsTest) FunctionDoesntPanic() { + err := t.matcher.Matches(func() {}) + + ExpectThat(err, Error(Equals("which didn't panic"))) + ExpectFalse(isFatal(err)) +} + +func (t *PanicsTest) CallsWrappedMatcher() { + expectedErr := 17 + t.wrappedError = errors.New("") + t.matcher.Matches(func() { panic(expectedErr) }) + + ExpectThat(t.suppliedCandidate, Equals(expectedErr)) +} + +func (t *PanicsTest) WrappedReturnsTrue() { + err := t.matcher.Matches(func() { panic("") }) + + ExpectEq(nil, err) +} + +func (t *PanicsTest) WrappedReturnsFatalErrorWithoutText() { + t.wrappedError = NewFatalError("") + err := t.matcher.Matches(func() { panic(17) }) + + ExpectThat(err, Error(Equals("which panicked with: 17"))) + ExpectFalse(isFatal(err)) +} + +func (t *PanicsTest) WrappedReturnsFatalErrorWithText() { + t.wrappedError = NewFatalError("which blah") + err := t.matcher.Matches(func() { panic(17) }) + + ExpectThat(err, Error(Equals("which panicked with: 17, which blah"))) + ExpectFalse(isFatal(err)) +} + +func (t *PanicsTest) WrappedReturnsNonFatalErrorWithoutText() { + t.wrappedError = errors.New("") + err := t.matcher.Matches(func() { panic(17) }) + + ExpectThat(err, Error(Equals("which panicked with: 17"))) + ExpectFalse(isFatal(err)) +} + +func (t *PanicsTest) WrappedReturnsNonFatalErrorWithText() { + t.wrappedError = errors.New("which blah") + err := t.matcher.Matches(func() { panic(17) }) + + ExpectThat(err, Error(Equals("which panicked with: 17, which blah"))) + ExpectFalse(isFatal(err)) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/pointee.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/pointee.go new file mode 100644 index 00000000000..c5383f2402f --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/pointee.go @@ -0,0 +1,65 @@ +// Copyright 2012 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package oglematchers + +import ( + "errors" + "fmt" + "reflect" +) + +// Return a matcher that matches non-nil pointers whose pointee matches the +// wrapped matcher. +func Pointee(m Matcher) Matcher { + return &pointeeMatcher{m} +} + +type pointeeMatcher struct { + wrapped Matcher +} + +func (m *pointeeMatcher) Matches(c interface{}) (err error) { + // Make sure the candidate is of the appropriate type. + cv := reflect.ValueOf(c) + if !cv.IsValid() || cv.Kind() != reflect.Ptr { + return NewFatalError("which is not a pointer") + } + + // Make sure the candidate is non-nil. + if cv.IsNil() { + return NewFatalError("") + } + + // Defer to the wrapped matcher. Fix up empty errors so that failure messages + // are more helpful than just printing a pointer for "Actual". + pointee := cv.Elem().Interface() + err = m.wrapped.Matches(pointee) + if err != nil && err.Error() == "" { + s := fmt.Sprintf("whose pointee is %v", pointee) + + if _, ok := err.(*FatalError); ok { + err = NewFatalError(s) + } else { + err = errors.New(s) + } + } + + return err +} + +func (m *pointeeMatcher) Description() string { + return fmt.Sprintf("pointee(%s)", m.wrapped.Description()) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/pointee_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/pointee_test.go new file mode 100644 index 00000000000..3bb72a702be --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/pointee_test.go @@ -0,0 +1,152 @@ +// Copyright 2012 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package oglematchers_test + +import ( + "errors" + . "github.com/smartystreets/assertions/internal/oglematchers" + . "github.com/smartystreets/assertions/internal/ogletest" + "testing" +) + +//////////////////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////////////////// + +type PointeeTest struct {} +func init() { RegisterTestSuite(&PointeeTest{}) } + +func TestPointee(t *testing.T) { RunTests(t) } + +//////////////////////////////////////////////////////////////////////// +// Tests +//////////////////////////////////////////////////////////////////////// + +func (t *PointeeTest) Description() { + wrapped := &fakeMatcher{nil, "taco"} + matcher := Pointee(wrapped) + + ExpectEq("pointee(taco)", matcher.Description()) +} + +func (t *PointeeTest) CandidateIsNotAPointer() { + matcher := Pointee(HasSubstr("")) + err := matcher.Matches([]byte{}) + + ExpectThat(err, Error(Equals("which is not a pointer"))) + ExpectTrue(isFatal(err)) +} + +func (t *PointeeTest) CandidateIsANilLiteral() { + matcher := Pointee(HasSubstr("")) + err := matcher.Matches(nil) + + ExpectThat(err, Error(Equals("which is not a pointer"))) + ExpectTrue(isFatal(err)) +} + +func (t *PointeeTest) CandidateIsANilPointer() { + matcher := Pointee(HasSubstr("")) + err := matcher.Matches((*int)(nil)) + + ExpectThat(err, Error(Equals(""))) + ExpectTrue(isFatal(err)) +} + +func (t *PointeeTest) CallsWrapped() { + var suppliedCandidate interface{} + matchFunc := func(c interface{}) error { + suppliedCandidate = c + return nil + } + + wrapped := &fakeMatcher{matchFunc, ""} + matcher := Pointee(wrapped) + + someSlice := []byte{} + matcher.Matches(&someSlice) + ExpectThat(suppliedCandidate, IdenticalTo(someSlice)) +} + +func (t *PointeeTest) WrappedReturnsOkay() { + matchFunc := func(c interface{}) error { + return nil + } + + wrapped := &fakeMatcher{matchFunc, ""} + matcher := Pointee(wrapped) + + err := matcher.Matches(new(int)) + ExpectEq(nil, err) +} + +func (t *PointeeTest) WrappedReturnsNonFatalNonEmptyError() { + matchFunc := func(c interface{}) error { + return errors.New("taco") + } + + wrapped := &fakeMatcher{matchFunc, ""} + matcher := Pointee(wrapped) + + i := 17 + err := matcher.Matches(&i) + ExpectFalse(isFatal(err)) + ExpectThat(err, Error(Equals("taco"))) +} + +func (t *PointeeTest) WrappedReturnsNonFatalEmptyError() { + matchFunc := func(c interface{}) error { + return errors.New("") + } + + wrapped := &fakeMatcher{matchFunc, ""} + matcher := Pointee(wrapped) + + i := 17 + err := matcher.Matches(&i) + ExpectFalse(isFatal(err)) + ExpectThat(err, Error(HasSubstr("whose pointee"))) + ExpectThat(err, Error(HasSubstr("17"))) +} + +func (t *PointeeTest) WrappedReturnsFatalNonEmptyError() { + matchFunc := func(c interface{}) error { + return NewFatalError("taco") + } + + wrapped := &fakeMatcher{matchFunc, ""} + matcher := Pointee(wrapped) + + i := 17 + err := matcher.Matches(&i) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(Equals("taco"))) +} + +func (t *PointeeTest) WrappedReturnsFatalEmptyError() { + matchFunc := func(c interface{}) error { + return NewFatalError("") + } + + wrapped := &fakeMatcher{matchFunc, ""} + matcher := Pointee(wrapped) + + i := 17 + err := matcher.Matches(&i) + ExpectTrue(isFatal(err)) + ExpectThat(err, Error(HasSubstr("whose pointee"))) + ExpectThat(err, Error(HasSubstr("17"))) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/transform_description.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/transform_description.go new file mode 100644 index 00000000000..f79d0c03db1 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/oglematchers/transform_description.go @@ -0,0 +1,36 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package oglematchers + +// transformDescription returns a matcher that is equivalent to the supplied +// one, except that it has the supplied description instead of the one attached +// to the existing matcher. +func transformDescription(m Matcher, newDesc string) Matcher { + return &transformDescriptionMatcher{newDesc, m} +} + +type transformDescriptionMatcher struct { + desc string + wrappedMatcher Matcher +} + +func (m *transformDescriptionMatcher) Description() string { + return m.desc +} + +func (m *transformDescriptionMatcher) Matches(c interface{}) error { + return m.wrappedMatcher.Matches(c) +} 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) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/.gitignore b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/.gitignore new file mode 100644 index 00000000000..dd8fc7468f4 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/.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/ogletest/.travis.yml b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/.travis.yml new file mode 100644 index 00000000000..b97211926e8 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/.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/ogletest/LICENSE b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/LICENSE new file mode 100644 index 00000000000..d6456956733 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/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/ogletest/README.md b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/README.md new file mode 100644 index 00000000000..8e54862082b --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/README.md @@ -0,0 +1,151 @@ +[![GoDoc](https://godoc.org/github.com/smartystreets/assertions/internal/ogletest?status.svg)](https://godoc.org/github.com/smartystreets/assertions/internal/ogletest) + +`ogletest` is a unit testing framework for Go with the following features: + + * An extensive and extensible set of matchers for expressing expectations. + * Automatic failure messages; no need to say `t.Errorf("Expected %v, got + %v"...)`. + * Clean, readable output that tells you exactly what you need to know. + * Built-in support for mocking through the [oglemock][] package. + * Style and semantics similar to [Google Test][googletest] and + [Google JS Test][google-js-test]. + +It integrates with Go's built-in `testing` package, so it works with the +`go test` command, and even with other types of test within your package. Unlike +the `testing` package which offers only basic capabilities for signalling +failures, it offers ways to express expectations and get nice failure messages +automatically. + + +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 `ogletest` and its dependencies, and to +keep them up to date: + + go get -u github.com/smartystreets/assertions/internal/ogletest + + +Documentation +------------- + +See [here][reference] for package documentation containing an exhaustive list of +exported symbols. Alternatively, you can install the package and then use +`godoc`: + + godoc github.com/smartystreets/assertions/internal/ogletest + +An important part of `ogletest` is its use of matchers provided by the +[oglematchers][matcher-reference] package. See that package's documentation +for information on the built-in matchers available, and check out the +`oglematchers.Matcher` interface if you want to define your own. + + +Example +------- + +Let's say you have a function in your package `people` with the following +signature: + +```go +// GetRandomPerson returns the name and phone number of Tony, Dennis, or Scott. +func GetRandomPerson() (name, phone string) { + [...] +} +``` + +A silly function, but it will do for an example. You can write a couple of tests +for it as follows: + +```go +package people + +import ( + "github.com/smartystreets/assertions/internal/oglematchers" + "github.com/smartystreets/assertions/internal/ogletest" + "testing" +) + +// Give ogletest a chance to run your tests when invoked by 'go test'. +func TestOgletest(t *testing.T) { ogletest.RunTests(t) } + +// Create a test suite, which groups together logically related test methods +// (defined below). You can share common setup and teardown code here; see the +// package docs for more info. +type PeopleTest struct {} +func init() { ogletest.RegisterTestSuite(&PeopleTest{}) } + +func (t *PeopleTest) ReturnsCorrectNames() { + // Call the function a few times, and make sure it never strays from the set + // of expected names. + for i := 0; i < 25; i++ { + name, _ := GetRandomPerson() + ogletest.ExpectThat(name, oglematchers.AnyOf("Tony", "Dennis", "Scott")) + } +} + +func (t *PeopleTest) FormatsPhoneNumbersCorrectly() { + // Call the function a few times, and make sure it returns phone numbers in a + // standard US format. + for i := 0; i < 25; i++ { + _, phone := GetRandomPerson() + ogletest.ExpectThat(phone, oglematchers.MatchesRegexp(`^\(\d{3}\) \d{3}-\d{4}$`)) +} +``` + +Note that test control functions (`RunTests`, `ExpectThat`, and so on) are part +of the `ogletest` package, whereas built-in matchers (`AnyOf`, `MatchesRegexp`, +and more) are part of the [oglematchers][matcher-reference] library. You can of +course use dot imports so that you don't need to prefix each function with its +package name: + +```go +import ( + . "github.com/smartystreets/assertions/internal/oglematchers" + . "github.com/smartystreets/assertions/internal/ogletest" +) +``` + +If you save the test in a file whose name ends in `_test.go`, you can run your +tests by simply invoking the following in your package directory: + + go test + +Here's what the failure output of ogletest looks like, if your function's +implementation is bad. + + [----------] Running tests from PeopleTest + [ RUN ] PeopleTest.FormatsPhoneNumbersCorrectly + people_test.go:32: + Expected: matches regexp "^\(\d{3}\) \d{3}-\d{4}$" + Actual: +1 800 555 5555 + + [ FAILED ] PeopleTest.FormatsPhoneNumbersCorrectly + [ RUN ] PeopleTest.ReturnsCorrectNames + people_test.go:23: + Expected: or(Tony, Dennis, Scott) + Actual: Bart + + [ FAILED ] PeopleTest.ReturnsCorrectNames + [----------] Finished with tests from PeopleTest + +And if the test passes: + + [----------] Running tests from PeopleTest + [ RUN ] PeopleTest.FormatsPhoneNumbersCorrectly + [ OK ] PeopleTest.FormatsPhoneNumbersCorrectly + [ RUN ] PeopleTest.ReturnsCorrectNames + [ OK ] PeopleTest.ReturnsCorrectNames + [----------] Finished with tests from PeopleTest + + +[reference]: http://godoc.org/github.com/smartystreets/assertions/internal/ogletest +[matcher-reference]: http://godoc.org/github.com/smartystreets/assertions/internal/oglematchers +[golang-install]: http://golang.org/doc/install.html +[googletest]: http://code.google.com/p/googletest/ +[google-js-test]: http://code.google.com/p/google-js-test/ +[howtowrite]: http://golang.org/doc/code.html +[oglemock]: https://github.com/smartystreets/assertions/internal/oglemock diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/assert_aliases.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/assert_aliases.go new file mode 100644 index 00000000000..70fa25c327a --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/assert_aliases.go @@ -0,0 +1,70 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ogletest + +import ( + "github.com/smartystreets/assertions/internal/oglematchers" +) + +// AssertEq(e, a) is equivalent to AssertThat(a, oglematchers.Equals(e)). +func AssertEq(expected, actual interface{}, errorParts ...interface{}) { + assertThat( + actual, + oglematchers.Equals(expected), + 1, + errorParts) +} + +// AssertNe(e, a) is equivalent to +// AssertThat(a, oglematchers.Not(oglematchers.Equals(e))). +func AssertNe(expected, actual interface{}, errorParts ...interface{}) { + assertThat( + actual, + oglematchers.Not(oglematchers.Equals(expected)), + 1, + errorParts) +} + +// AssertLt(x, y) is equivalent to AssertThat(x, oglematchers.LessThan(y)). +func AssertLt(x, y interface{}, errorParts ...interface{}) { + assertThat(x, oglematchers.LessThan(y), 1, errorParts) +} + +// AssertLe(x, y) is equivalent to AssertThat(x, oglematchers.LessOrEqual(y)). +func AssertLe(x, y interface{}, errorParts ...interface{}) { + assertThat(x, oglematchers.LessOrEqual(y), 1, errorParts) +} + +// AssertGt(x, y) is equivalent to AssertThat(x, oglematchers.GreaterThan(y)). +func AssertGt(x, y interface{}, errorParts ...interface{}) { + assertThat(x, oglematchers.GreaterThan(y), 1, errorParts) +} + +// AssertGe(x, y) is equivalent to +// AssertThat(x, oglematchers.GreaterOrEqual(y)). +func AssertGe(x, y interface{}, errorParts ...interface{}) { + assertThat(x, oglematchers.GreaterOrEqual(y), 1, errorParts) +} + +// AssertTrue(b) is equivalent to AssertThat(b, oglematchers.Equals(true)). +func AssertTrue(b interface{}, errorParts ...interface{}) { + assertThat(b, oglematchers.Equals(true), 1, errorParts) +} + +// AssertFalse(b) is equivalent to AssertThat(b, oglematchers.Equals(false)). +func AssertFalse(b interface{}, errorParts ...interface{}) { + assertThat(b, oglematchers.Equals(false), 1, errorParts) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/assert_that.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/assert_that.go new file mode 100644 index 00000000000..65c8fbce052 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/assert_that.go @@ -0,0 +1,46 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ogletest + +import ( + "github.com/smartystreets/assertions/internal/oglematchers" +) + +func assertThat( + x interface{}, + m oglematchers.Matcher, + depth int, + errorParts []interface{}) { + passed := expectThat(x, m, depth+1, errorParts) + if !passed { + AbortTest() + } +} + +// AssertThat is identical to ExpectThat, except that in the event of failure +// it halts the currently running test immediately. It is thus useful for +// things like bounds checking: +// +// someSlice := [...] +// AssertEq(1, len(someSlice)) // Protects next line from panicking. +// ExpectEq("taco", someSlice[0]) +// +func AssertThat( + x interface{}, + m oglematchers.Matcher, + errorParts ...interface{}) { + assertThat(x, m, 1, errorParts) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/doc.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/doc.go new file mode 100644 index 00000000000..bf6507fae4d --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/doc.go @@ -0,0 +1,51 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package ogletest provides a framework for writing expressive unit tests. It +// integrates with the builtin testing package, so it works with the gotest +// command. Unlike the testing package which offers only basic capabilities for +// signalling failures, it offers ways to express expectations and get nice +// failure messages automatically. +// +// For example: +// +// //////////////////////////////////////////////////////////////////////// +// // testing package test +// //////////////////////////////////////////////////////////////////////// +// +// someStr, err := ComputeSomeString() +// if err != nil { +// t.Errorf("ComputeSomeString: expected nil error, got %v", err) +// } +// +// !strings.Contains(someStr, "foo") { +// t.Errorf("ComputeSomeString: expected substring foo, got %v", someStr) +// } +// +// //////////////////////////////////////////////////////////////////////// +// // ogletest test +// //////////////////////////////////////////////////////////////////////// +// +// someStr, err := ComputeSomeString() +// ExpectEq(nil, err) +// ExpectThat(someStr, HasSubstr("foo") +// +// Failure messages require no work from the user, and look like the following: +// +// foo_test.go:103: +// Expected: has substring "foo" +// Actual: "bar baz" +// +package ogletest diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/expect_aliases.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/expect_aliases.go new file mode 100644 index 00000000000..5bc1dc120a7 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/expect_aliases.go @@ -0,0 +1,64 @@ +// 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 ogletest + +import "github.com/smartystreets/assertions/internal/oglematchers" + +// ExpectEq(e, a) is equivalent to ExpectThat(a, oglematchers.Equals(e)). +func ExpectEq(expected, actual interface{}, errorParts ...interface{}) { + expectThat(actual, oglematchers.Equals(expected), 1, errorParts) +} + +// ExpectNe(e, a) is equivalent to +// ExpectThat(a, oglematchers.Not(oglematchers.Equals(e))). +func ExpectNe(expected, actual interface{}, errorParts ...interface{}) { + expectThat( + actual, + oglematchers.Not(oglematchers.Equals(expected)), + 1, + errorParts) +} + +// ExpectLt(x, y) is equivalent to ExpectThat(x, oglematchers.LessThan(y)). +func ExpectLt(x, y interface{}, errorParts ...interface{}) { + expectThat(x, oglematchers.LessThan(y), 1, errorParts) +} + +// ExpectLe(x, y) is equivalent to ExpectThat(x, oglematchers.LessOrEqual(y)). +func ExpectLe(x, y interface{}, errorParts ...interface{}) { + expectThat(x, oglematchers.LessOrEqual(y), 1, errorParts) +} + +// ExpectGt(x, y) is equivalent to ExpectThat(x, oglematchers.GreaterThan(y)). +func ExpectGt(x, y interface{}, errorParts ...interface{}) { + expectThat(x, oglematchers.GreaterThan(y), 1, errorParts) +} + +// ExpectGe(x, y) is equivalent to +// ExpectThat(x, oglematchers.GreaterOrEqual(y)). +func ExpectGe(x, y interface{}, errorParts ...interface{}) { + expectThat(x, oglematchers.GreaterOrEqual(y), 1, errorParts) +} + +// ExpectTrue(b) is equivalent to ExpectThat(b, oglematchers.Equals(true)). +func ExpectTrue(b interface{}, errorParts ...interface{}) { + expectThat(b, oglematchers.Equals(true), 1, errorParts) +} + +// ExpectFalse(b) is equivalent to ExpectThat(b, oglematchers.Equals(false)). +func ExpectFalse(b interface{}, errorParts ...interface{}) { + expectThat(b, oglematchers.Equals(false), 1, errorParts) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/expect_call.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/expect_call.go new file mode 100644 index 00000000000..b8bf542a8bc --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/expect_call.go @@ -0,0 +1,59 @@ +// 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 ogletest + +import ( + "github.com/smartystreets/assertions/internal/oglemock" + "runtime" +) + +// 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. +// +// For example: +// +// mockWriter := [...] +// ogletest.ExpectCall(mockWriter, "Write")(oglematchers.ElementsAre(0x1)) +// .WillOnce(oglemock.Return(1, nil)) +// +// This is a shortcut for calling i.MockController.ExpectCall, where i is the +// TestInfo struct for the currently-running test. Unlike that direct approach, +// this function automatically sets the correct file name and line number for +// the expectation. +func ExpectCall(o oglemock.MockObject, method string) oglemock.PartialExpecation { + // Get information about the call site. + _, file, lineNumber, ok := runtime.Caller(1) + if !ok { + panic("ExpectCall: runtime.Caller") + } + + // Grab the current test info. + info := currentlyRunningTest + if info == nil { + panic("ExpectCall: no test info.") + } + + // Grab the mock controller. + controller := currentlyRunningTest.MockController + if controller == nil { + panic("ExpectCall: no mock controller.") + } + + // Report the expectation. + return controller.ExpectCall(o, method, file, lineNumber) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/expect_that.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/expect_that.go new file mode 100644 index 00000000000..69fc669785d --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/expect_that.go @@ -0,0 +1,100 @@ +// 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 ogletest + +import ( + "fmt" + "path" + "reflect" + "runtime" + + "github.com/smartystreets/assertions/internal/oglematchers" +) + +// ExpectThat confirms that the supplied matcher matches the value x, adding a +// failure record to the currently running test if it does not. If additional +// parameters are supplied, the first will be used as a format string for the +// later ones, and the user-supplied error message will be added to the test +// output in the event of a failure. +// +// For example: +// +// ExpectThat(userName, Equals("jacobsa")) +// ExpectThat(users[i], Equals("jacobsa"), "while processing user %d", i) +// +func ExpectThat( + x interface{}, + m oglematchers.Matcher, + errorParts ...interface{}) { + expectThat(x, m, 1, errorParts) +} + +// The generalized form of ExpectThat. depth is the distance on the stack +// between the caller's frame and the user's frame. Returns passed iff the +// match succeeded. +func expectThat( + x interface{}, + m oglematchers.Matcher, + depth int, + errorParts []interface{}) (passed bool) { + // Check whether the value matches. If it does, we are finished. + matcherErr := m.Matches(x) + if matcherErr == nil { + passed = true + return + } + + var r FailureRecord + + // Get information about the call site. + var ok bool + if _, r.FileName, r.LineNumber, ok = runtime.Caller(depth + 1); !ok { + panic("expectThat: runtime.Caller") + } + + r.FileName = path.Base(r.FileName) + + // Create an appropriate failure message. Make sure that the expected and + // actual values align properly. + relativeClause := "" + if matcherErr.Error() != "" { + relativeClause = fmt.Sprintf(", %s", matcherErr.Error()) + } + + r.Error = fmt.Sprintf( + "Expected: %s\nActual: %v%s", + m.Description(), + x, + relativeClause) + + // Add the user error, if any. + if len(errorParts) != 0 { + v := reflect.ValueOf(errorParts[0]) + if v.Kind() != reflect.String { + panic(fmt.Sprintf("ExpectThat: invalid format string type %v", v.Kind())) + } + + r.Error = fmt.Sprintf( + "%s\n%s", + r.Error, + fmt.Sprintf(v.String(), errorParts[1:]...)) + } + + // Report the failure. + AddFailureRecord(r) + + return +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/expect_that_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/expect_that_test.go new file mode 100644 index 00000000000..e3e37236700 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/expect_that_test.go @@ -0,0 +1,168 @@ +// 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 ogletest + +import ( + "errors" + "testing" + + . "github.com/smartystreets/assertions/internal/oglematchers" +) + +//////////////////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////////////////// + +// Set up a new test state with empty fields. +func setUpCurrentTest() { + currentlyRunningTest = newTestInfo() +} + +type fakeExpectThatMatcher struct { + desc string + err error +} + +func (m *fakeExpectThatMatcher) Matches(c interface{}) error { + return m.err +} + +func (m *fakeExpectThatMatcher) Description() string { + return m.desc +} + +func assertEqInt(t *testing.T, e, c int) { + if e != c { + t.Fatalf("Expected %d, got %d", e, c) + } +} + +func expectEqInt(t *testing.T, e, c int) { + if e != c { + t.Errorf("Expected %v, got %v", e, c) + } +} + +func expectEqStr(t *testing.T, e, c string) { + if e != c { + t.Errorf("Expected %s, got %s", e, c) + } +} + +//////////////////////////////////////////////////////////////////////// +// Tests +//////////////////////////////////////////////////////////////////////// + +func TestNoCurrentTest(t *testing.T) { + panicked := false + + defer func() { + if !panicked { + t.Errorf("Expected panic; got none.") + } + }() + + defer func() { + if r := recover(); r != nil { + panicked = true + } + }() + + currentlyRunningTest = nil + ExpectThat(17, Equals(19)) +} + +func TestNoFailure(t *testing.T) { + setUpCurrentTest() + matcher := &fakeExpectThatMatcher{"", nil} + ExpectThat(17, matcher) + + assertEqInt(t, 0, len(currentlyRunningTest.failureRecords)) +} + +func TestInvalidFormatString(t *testing.T) { + panicked := false + + defer func() { + if !panicked { + t.Errorf("Expected panic; got none.") + } + }() + + defer func() { + if r := recover(); r != nil { + panicked = true + } + }() + + setUpCurrentTest() + matcher := &fakeExpectThatMatcher{"", errors.New("")} + ExpectThat(17, matcher, 19, "blah") +} + +func TestNoMatchWithoutErrorText(t *testing.T) { + setUpCurrentTest() + matcher := &fakeExpectThatMatcher{"taco", errors.New("")} + ExpectThat(17, matcher) + + assertEqInt(t, 1, len(currentlyRunningTest.failureRecords)) + + record := currentlyRunningTest.failureRecords[0] + expectEqStr(t, "expect_that_test.go", record.FileName) + expectEqInt(t, 119, record.LineNumber) + expectEqStr(t, "Expected: taco\nActual: 17", record.Error) +} + +func TestNoMatchWithErrorTExt(t *testing.T) { + setUpCurrentTest() + matcher := &fakeExpectThatMatcher{"taco", errors.New("which is foo")} + ExpectThat(17, matcher) + + assertEqInt(t, 1, len(currentlyRunningTest.failureRecords)) + record := currentlyRunningTest.failureRecords[0] + + expectEqStr( + t, + "Expected: taco\nActual: 17, which is foo", + record.Error) +} + +func TestFailureWithUserMessage(t *testing.T) { + setUpCurrentTest() + matcher := &fakeExpectThatMatcher{"taco", errors.New("")} + ExpectThat(17, matcher, "Asd: %d %s", 19, "taco") + + assertEqInt(t, 1, len(currentlyRunningTest.failureRecords)) + record := currentlyRunningTest.failureRecords[0] + + expectEqStr(t, "Expected: taco\nActual: 17\nAsd: 19 taco", record.Error) +} + +func TestAdditionalFailure(t *testing.T) { + setUpCurrentTest() + matcher := &fakeExpectThatMatcher{"", errors.New("")} + + // Fail twice. + ExpectThat(17, matcher, "taco") + ExpectThat(19, matcher, "burrito") + + assertEqInt(t, 2, len(currentlyRunningTest.failureRecords)) + record1 := currentlyRunningTest.failureRecords[0] + record2 := currentlyRunningTest.failureRecords[1] + + expectEqStr(t, "Expected: \nActual: 17\ntaco", record1.Error) + expectEqStr(t, "Expected: \nActual: 19\nburrito", record2.Error) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/failure.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/failure.go new file mode 100644 index 00000000000..95be2cf4502 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/failure.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 ogletest + +import ( + "fmt" + "path" + "runtime" +) + +// FailureRecord represents a single failed expectation or assertion for a +// test. Most users don't want to interact with these directly; they are +// generated implicitly using ExpectThat, AssertThat, ExpectLt, etc. +type FailureRecord struct { + // The file name within which the expectation failed, e.g. "foo_test.go". + FileName string + + // The line number at which the expectation failed. + LineNumber int + + // The error associated with the file:line pair above. For example, the + // following expectation: + // + // ExpectEq(17, "taco")" + // + // May cause this error: + // + // Expected: 17 + // Actual: "taco", which is not numeric + // + Error string +} + +// Record a failure for the currently running test (and continue running it). +// Most users will want to use ExpectThat, ExpectEq, etc. instead of this +// function. Those that do want to report arbitrary errors will probably be +// satisfied with AddFailure, which is easier to use. +func AddFailureRecord(r FailureRecord) { + currentlyRunningTest.mu.Lock() + defer currentlyRunningTest.mu.Unlock() + + currentlyRunningTest.failureRecords = append( + currentlyRunningTest.failureRecords, + r) +} + +// Call AddFailureRecord with a record whose file name and line number come +// from the caller of this function, and whose error string is created by +// calling fmt.Sprintf using the arguments to this function. +func AddFailure(format string, a ...interface{}) { + r := FailureRecord{ + Error: fmt.Sprintf(format, a...), + } + + // Get information about the call site. + var ok bool + if _, r.FileName, r.LineNumber, ok = runtime.Caller(1); !ok { + panic("Can't find caller") + } + + r.FileName = path.Base(r.FileName) + + AddFailureRecord(r) +} + +// A sentinel type that is used in a conspiracy between AbortTest and runTests. +// If runTests sees an abortError as the value given to a panic() call, it will +// avoid printing the panic error. +type abortError struct { +} + +// Immediately stop executing the running test, causing it to fail with the +// failures previously recorded. Behavior is undefined if no failures have been +// recorded. +func AbortTest() { + panic(abortError{}) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/integration_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/integration_test.go new file mode 100644 index 00000000000..ec45184e326 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/integration_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 ogletest_test + +import ( + "errors" + "flag" + "fmt" + "go/build" + "io/ioutil" + "os" + "os/exec" + "path" + "regexp" + "strings" + "syscall" + "testing" +) + +const ogletestPkg = "github.com/smartystreets/assertions/internal/ogletest" + +var dumpNew = flag.Bool("dump_new", false, "Dump new golden files.") +var objDir string + +//////////////////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////////////////// + +// Install the possibly locally-modified copy of ogletest, so that these +// integration tests run using the package currently being worked on by the +// programmer. Also install other dependencies needed by the test cases, so +// that `go test` complaining about non-up-to-date packages doesn't make it +// into the golden files. +func installLocalPackages() error { + cmd := exec.Command( + "go", + "install", + ogletestPkg, + "github.com/smartystreets/assertions/internal/oglemock", + "github.com/smartystreets/assertions/internal/ogletest/test_cases/mock_image") + + output, err := cmd.CombinedOutput() + + if err != nil { + return errors.New(fmt.Sprintf("%v:\n%s", err, output)) + } + + return nil +} + +// getCaseNames looks for integration test cases as files in the test_cases +// directory. +func getCaseNames() ([]string, error) { + // Open the test cases directory. + dir, err := os.Open("test_cases") + if err != nil { + return nil, errors.New(fmt.Sprintf("Opening dir: %v", err)) + } + + // Get a list of the names in the directory. + names, err := dir.Readdirnames(0) + if err != nil { + return nil, errors.New(fmt.Sprintf("Readdirnames: %v", err)) + } + + // Filter the names. + result := make([]string, len(names)) + resultLen := 0 + for _, name := range names { + // Skip golden files and hidden files. + if strings.HasPrefix(name, "golden.") || strings.HasPrefix(name, ".") { + continue + } + + // Check for the right format. + if !strings.HasSuffix(name, ".test.go") { + continue + } + + // Store the name minus the extension. + result[resultLen] = name[:len(name)-8] + resultLen++ + } + + return result[:resultLen], nil +} + +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 +} + +// cleanOutput transforms the supplied output so that it no longer contains +// information that changes from run to run, making the golden tests less +// flaky. +func cleanOutput(o []byte, testPkg string) []byte { + // Replace references to the last component of the test package name, which + // contains a unique number. + o = []byte(strings.Replace(string(o), path.Base(testPkg), "somepkg", -1)) + + // Replace things that look like line numbers and process counters in stack + // traces. + stackFrameRe := regexp.MustCompile(`\t\S+\.(c|go):\d+`) + o = stackFrameRe.ReplaceAll(o, []byte("\tsome_file.txt:0")) + + // Replace full paths in failure messages with fake paths. + pathRe := regexp.MustCompile(`/\S+/(\w+\.(?:go|s):\d+)`) + o = pathRe.ReplaceAll(o, []byte("/some/path/$1")) + + // Replace unstable timings in gotest fail messages. + timingRe1 := regexp.MustCompile(`--- FAIL: .* \(\d\.\d{2}s\)`) + o = timingRe1.ReplaceAll(o, []byte("--- FAIL: TestSomething (1.23s)")) + + timingRe2 := regexp.MustCompile(`FAIL.*somepkg\s*\d\.\d{2,}s`) + o = timingRe2.ReplaceAll(o, []byte("FAIL somepkg 1.234s")) + + timingRe3 := regexp.MustCompile(`ok.*somepkg\s*\d\.\d{2,}s`) + o = timingRe3.ReplaceAll(o, []byte("ok somepkg 1.234s")) + + timingRe4 := regexp.MustCompile(`SlowTest \([0-9.]+ms\)`) + o = timingRe4.ReplaceAll(o, []byte("SlowTest (1234ms)")) + + return o +} + +// Create a temporary package directory somewhere that 'go test' can find, and +// return the directory and package name. +func createTempPackageDir(caseName string) (dir, pkg string) { + // Figure out where the local source code for ogletest is. + buildPkg, err := build.Import(ogletestPkg, "", build.FindOnly) + if err != nil { + panic("Finding ogletest tree: " + err.Error()) + } + + // Create a temporary directory underneath this. + ogletestPkgDir := buildPkg.Dir + prefix := fmt.Sprintf("tmp-%s-", caseName) + + dir, err = ioutil.TempDir(ogletestPkgDir, prefix) + if err != nil { + panic("ioutil.TempDir: " + err.Error()) + } + + pkg = path.Join("github.com/smartystreets/assertions/internal/ogletest", dir[len(ogletestPkgDir):]) + return +} + +// runTestCase runs the case with the supplied name (e.g. "passing"), and +// returns its output and exit code. +func runTestCase(name string) ([]byte, int, error) { + // Create a temporary directory for the test files. + testDir, testPkg := createTempPackageDir(name) + defer os.RemoveAll(testDir) + + // Create the test source file. + sourceFile := name + ".test.go" + testContents := readFileOrDie(path.Join("test_cases", sourceFile)) + writeContentsToFileOrDie(testContents, path.Join(testDir, name+"_test.go")) + + // Invoke 'go test'. Use the package directory as working dir instead of + // giving the package name as an argument so that 'go test' prints passing + // test output. Special case: pass a test filter to the filtered case. + cmd := exec.Command("go", "test") + if name == "filtered" { + cmd.Args = append(cmd.Args, "--ogletest.run=Test(Bar|Baz)") + } + + cmd.Dir = testDir + output, err := cmd.CombinedOutput() + + // Clean up the process's output. + output = cleanOutput(output, testPkg) + + // Did the process exist with zero code? + if err == nil { + return output, 0, nil + } + + // Make sure the process actually exited. + exitError, ok := err.(*exec.ExitError) + if !ok || !exitError.Exited() { + return nil, 0, errors.New("exec.Command.Output: " + err.Error()) + } + + return output, exitError.Sys().(syscall.WaitStatus).ExitStatus(), nil +} + +// checkGolden file checks the supplied actual output for the named test case +// against the golden file for that case. If requested by the user, it rewrites +// the golden file on failure. +func checkAgainstGoldenFile(caseName string, output []byte) bool { + goldenFile := path.Join("test_cases", "golden."+caseName+"_test") + goldenContents := readFileOrDie(goldenFile) + + result := string(output) == string(goldenContents) + if !result && *dumpNew { + writeContentsToFileOrDie(output, goldenFile) + } + + return result +} + +//////////////////////////////////////////////////////////////////////// +// Tests +//////////////////////////////////////////////////////////////////////// + +func TestGoldenFiles(t *testing.T) { + // Ensure the local package is installed. This will prevent the test cases + // from using the installed version, which may be out of date. + err := installLocalPackages() + if err != nil { + t.Fatalf("Error installing local ogletest: %v", err) + } + + // We expect there to be at least one case. + caseNames, err := getCaseNames() + if err != nil || len(caseNames) == 0 { + t.Fatalf("Error getting cases: %v", err) + } + + // Run each test case. + for _, caseName := range caseNames { + // Run the test case. + output, exitCode, err := runTestCase(caseName) + if err != nil { + t.Fatalf("Running test case %s: %v", caseName, err) + } + + // Check the status code. We assume all test cases fail except for the + // passing one. + shouldPass := (caseName == "passing" || caseName == "no_cases") + didPass := exitCode == 0 + if shouldPass != didPass { + t.Errorf("Bad exit code for test case %s: %d", caseName, exitCode) + } + + // Check the output against the golden file. + if !checkAgainstGoldenFile(caseName, output) { + t.Errorf("Output for test case %s doesn't match golden file.", caseName) + } + } +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/register.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/register.go new file mode 100644 index 00000000000..756f2aa9ad9 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/register.go @@ -0,0 +1,86 @@ +// 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 ogletest + +// The input to ogletest.Register. Most users will want to use +// ogletest.RegisterTestSuite. +// +// A test suite is the basic unit of registration in ogletest. It consists of +// zero or more named test functions which will be run in sequence, along with +// optional setup and tear-down functions. +type TestSuite struct { + // The name of the overall suite, e.g. "MyPackageTest". + Name string + + // If non-nil, a function that will be run exactly once, before any of the + // test functions are run. + SetUp func() + + // The test functions comprising this suite. + TestFunctions []TestFunction + + // If non-nil, a function that will be run exactly once, after all of the + // test functions have run. + TearDown func() +} + +type TestFunction struct { + // The name of this test function, relative to the suite in which it resides. + // If the name is "TweaksFrobnicator", then the function might be presented + // in the ogletest UI as "FooTest.TweaksFrobnicator". + Name string + + // If non-nil, a function that is run before Run, passed a pointer to a + // struct containing information about the test run. + SetUp func(*TestInfo) + + // The function to invoke for the test body. Must be non-nil. Will not be run + // if SetUp panics. + Run func() + + // If non-nil, a function that is run after Run. + TearDown func() +} + +// Register a test suite for execution by RunTests. +// +// This is the most general registration mechanism. Most users will want +// RegisterTestSuite, which is a wrapper around this function that requires +// less boilerplate. +// +// Panics on invalid input. +func Register(suite TestSuite) { + // Make sure the suite is legal. + if suite.Name == "" { + panic("Test suites must have names.") + } + + for _, tf := range suite.TestFunctions { + if tf.Name == "" { + panic("Test functions must have names.") + } + + if tf.Run == nil { + panic("Test functions must have non-nil run fields.") + } + } + + // Save the suite for later. + registeredSuites = append(registeredSuites, suite) +} + +// The list of test suites previously registered. +var registeredSuites []TestSuite diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/register_test_suite.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/register_test_suite.go new file mode 100644 index 00000000000..7303dfa8a6e --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/register_test_suite.go @@ -0,0 +1,193 @@ +// 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 ogletest + +import ( + "fmt" + "reflect" + + "github.com/smartystreets/assertions/internal/ogletest/srcutil" +) + +// Test suites that implement this interface have special meaning to +// RegisterTestSuite. +type SetUpTestSuiteInterface interface { + // This method will be called exactly once, before the first test method is + // run. The receiver of this method will be a zero value of the test suite + // type, and is not shared with any other methods. Use this method to set up + // any necessary global state shared by all of the test methods. + SetUpTestSuite() +} + +// Test suites that implement this interface have special meaning to +// RegisterTestSuite. +type TearDownTestSuiteInterface interface { + // This method will be called exactly once, after the last test method is + // run. The receiver of this method will be a zero value of the test suite + // type, and is not shared with any other methods. Use this method to clean + // up after any necessary global state shared by all of the test methods. + TearDownTestSuite() +} + +// Test suites that implement this interface have special meaning to +// Register. +type SetUpInterface interface { + // This method is called before each test method is invoked, with the same + // receiver as that test method. At the time this method is invoked, the + // receiver is a zero value for the test suite type. Use this method for + // common setup code that works on data not shared across tests. + SetUp(*TestInfo) +} + +// Test suites that implement this interface have special meaning to +// Register. +type TearDownInterface interface { + // This method is called after each test method is invoked, with the same + // receiver as that test method. Use this method for common cleanup code that + // works on data not shared across tests. + TearDown() +} + +// RegisterTestSuite tells ogletest about a test suite containing tests that it +// should run. Any exported method on the type pointed to by the supplied +// prototype value will be treated as test methods, with the exception of the +// methods defined by the following interfaces, which when present are treated +// as described in the documentation for those interfaces: +// +// * SetUpTestSuiteInterface +// * SetUpInterface +// * TearDownInterface +// * TearDownTestSuiteInterface +// +// Each test method is invoked on a different receiver, which is initially a +// zero value of the test suite type. +// +// Example: +// +// // Some value that is needed by the tests but is expensive to compute. +// var someExpensiveThing uint +// +// type FooTest struct { +// // Path to a temporary file used by the tests. Each test gets a +// // different temporary file. +// tempFile string +// } +// func init() { ogletest.RegisterTestSuite(&FooTest{}) } +// +// func (t *FooTest) SetUpTestSuite() { +// someExpensiveThing = ComputeSomeExpensiveThing() +// } +// +// func (t *FooTest) SetUp(ti *ogletest.TestInfo) { +// t.tempFile = CreateTempFile() +// } +// +// func (t *FooTest) TearDown() { +// DeleteTempFile(t.tempFile) +// } +// +// func (t *FooTest) FrobinicatorIsSuccessfullyTweaked() { +// res := DoSomethingWithExpensiveThing(someExpensiveThing, t.tempFile) +// ExpectThat(res, Equals(true)) +// } +// +func RegisterTestSuite(p interface{}) { + if p == nil { + panic("RegisterTestSuite called with nil suite.") + } + + val := reflect.ValueOf(p) + typ := val.Type() + var zeroInstance reflect.Value + + // We will transform to a TestSuite struct. + suite := TestSuite{} + suite.Name = typ.Elem().Name() + + zeroInstance = reflect.New(typ.Elem()) + if i, ok := zeroInstance.Interface().(SetUpTestSuiteInterface); ok { + suite.SetUp = func() { i.SetUpTestSuite() } + } + + zeroInstance = reflect.New(typ.Elem()) + if i, ok := zeroInstance.Interface().(TearDownTestSuiteInterface); ok { + suite.TearDown = func() { i.TearDownTestSuite() } + } + + // Transform a list of test methods for the suite, filtering them to just the + // ones that we don't need to skip. + for _, method := range filterMethods(suite.Name, srcutil.GetMethodsInSourceOrder(typ)) { + var tf TestFunction + tf.Name = method.Name + + // Create an instance to be operated on by all of the TestFunction's + // internal functions. + instance := reflect.New(typ.Elem()) + + // Bind the functions to the instance. + if i, ok := instance.Interface().(SetUpInterface); ok { + tf.SetUp = func(ti *TestInfo) { i.SetUp(ti) } + } + + methodCopy := method + tf.Run = func() { runTestMethod(instance, methodCopy) } + + if i, ok := instance.Interface().(TearDownInterface); ok { + tf.TearDown = func() { i.TearDown() } + } + + // Save the TestFunction. + suite.TestFunctions = append(suite.TestFunctions, tf) + } + + // Register the suite. + Register(suite) +} + +func runTestMethod(suite reflect.Value, method reflect.Method) { + if method.Func.Type().NumIn() != 1 { + panic(fmt.Sprintf( + "%s: expected 1 args, actually %d.", + method.Name, + method.Func.Type().NumIn())) + } + + method.Func.Call([]reflect.Value{suite}) +} + +func filterMethods(suiteName string, in []reflect.Method) (out []reflect.Method) { + for _, m := range in { + // Skip set up, tear down, and unexported methods. + if isSpecialMethod(m.Name) || !isExportedMethod(m.Name) { + continue + } + + out = append(out, m) + } + + return +} + +func isSpecialMethod(name string) bool { + return (name == "SetUpTestSuite") || + (name == "TearDownTestSuite") || + (name == "SetUp") || + (name == "TearDown") +} + +func isExportedMethod(name string) bool { + return len(name) > 0 && name[0] >= 'A' && name[0] <= 'Z' +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/run_tests.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/run_tests.go new file mode 100644 index 00000000000..003aeb019de --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/run_tests.go @@ -0,0 +1,354 @@ +// 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 ogletest + +import ( + "bytes" + "flag" + "fmt" + "os" + "path" + "regexp" + "runtime" + "sync" + "sync/atomic" + "testing" + "time" + + "github.com/smartystreets/assertions/internal/reqtrace" +) + +var fTestFilter = flag.String( + "ogletest.run", + "", + "Regexp for matching tests to run.") + +var fStopEarly = flag.Bool( + "ogletest.stop_early", + false, + "If true, stop after the first failure.") + +// runTestsOnce protects RunTests from executing multiple times. +var runTestsOnce sync.Once + +func isAbortError(x interface{}) bool { + _, ok := x.(abortError) + return ok +} + +// Run a single test function, returning a slice of failure records. +func runTestFunction(tf TestFunction) (failures []FailureRecord) { + // Set up a clean slate for this test. Make sure to reset it after everything + // below is finished, so we don't accidentally use it elsewhere. + currentlyRunningTest = newTestInfo() + defer func() { + currentlyRunningTest = nil + }() + + ti := currentlyRunningTest + + // Start a trace. + var reportOutcome reqtrace.ReportFunc + ti.Ctx, reportOutcome = reqtrace.Trace(ti.Ctx, tf.Name) + + // Run the SetUp function, if any, paying attention to whether it panics. + setUpPanicked := false + if tf.SetUp != nil { + setUpPanicked = runWithProtection(func() { tf.SetUp(ti) }) + } + + // Run the test function itself, but only if the SetUp function didn't panic. + // (This includes AssertThat errors.) + if !setUpPanicked { + runWithProtection(tf.Run) + } + + // Run the TearDown function, if any. + if tf.TearDown != nil { + runWithProtection(tf.TearDown) + } + + // Tell the mock controller for the tests to report any errors it's sitting + // on. + ti.MockController.Finish() + + // Report the outcome to reqtrace. + if len(ti.failureRecords) == 0 { + reportOutcome(nil) + } else { + reportOutcome(fmt.Errorf("%v failure records", len(ti.failureRecords))) + } + + return ti.failureRecords +} + +// Run everything registered with Register (including via the wrapper +// RegisterTestSuite). +// +// Failures are communicated to the supplied testing.T object. This is the +// bridge between ogletest and the testing package (and `go test`); you should +// ensure that it's called at least once by creating a test function compatible +// with `go test` and calling it there. +// +// For example: +// +// import ( +// "github.com/smartystreets/assertions/internal/ogletest" +// "testing" +// ) +// +// func TestOgletest(t *testing.T) { +// ogletest.RunTests(t) +// } +// +func RunTests(t *testing.T) { + runTestsOnce.Do(func() { runTestsInternal(t) }) +} + +// Signalling between RunTests and StopRunningTests. +var gStopRunning uint64 + +// Request that RunTests stop what it's doing. After the currently running test +// is finished, including tear-down, the program will exit with an error code. +func StopRunningTests() { + atomic.StoreUint64(&gStopRunning, 1) +} + +// runTestsInternal does the real work of RunTests, which simply wraps it in a +// sync.Once. +func runTestsInternal(t *testing.T) { + // Process each registered suite. + for _, suite := range registeredSuites { + // Stop now if we've already seen a failure and we've been told to stop + // early. + if t.Failed() && *fStopEarly { + break + } + + // Print a banner. + fmt.Printf("[----------] Running tests from %s\n", suite.Name) + + // Run the SetUp function, if any. + if suite.SetUp != nil { + suite.SetUp() + } + + // Run each test function that the user has not told us to skip. + stoppedEarly := false + for _, tf := range filterTestFunctions(suite) { + // Did the user request that we stop running tests? If so, skip the rest + // of this suite (and exit after tearing it down). + if atomic.LoadUint64(&gStopRunning) != 0 { + stoppedEarly = true + break + } + + // Print a banner for the start of this test function. + fmt.Printf("[ RUN ] %s.%s\n", suite.Name, tf.Name) + + // Run the test function. + startTime := time.Now() + failures := runTestFunction(tf) + runDuration := time.Since(startTime) + + // Print any failures, and mark the test as having failed if there are any. + for _, record := range failures { + t.Fail() + fmt.Printf( + "%s:%d:\n%s\n\n", + record.FileName, + record.LineNumber, + record.Error) + } + + // Print a banner for the end of the test. + bannerMessage := "[ OK ]" + if len(failures) != 0 { + bannerMessage = "[ FAILED ]" + } + + // Print a summary of the time taken, if long enough. + var timeMessage string + if runDuration >= 25*time.Millisecond { + timeMessage = fmt.Sprintf(" (%s)", runDuration.String()) + } + + fmt.Printf( + "%s %s.%s%s\n", + bannerMessage, + suite.Name, + tf.Name, + timeMessage) + + // Stop running tests from this suite if we've been told to stop early + // and this test failed. + if t.Failed() && *fStopEarly { + break + } + } + + // Run the suite's TearDown function, if any. + if suite.TearDown != nil { + suite.TearDown() + } + + // Were we told to exit early? + if stoppedEarly { + fmt.Println("Exiting early due to user request.") + os.Exit(1) + } + + fmt.Printf("[----------] Finished with tests from %s\n", suite.Name) + } +} + +// Return true iff the supplied program counter appears to lie within panic(). +func isPanic(pc uintptr) bool { + f := runtime.FuncForPC(pc) + if f == nil { + return false + } + + return f.Name() == "runtime.gopanic" || f.Name() == "runtime.sigpanic" +} + +// Find the deepest stack frame containing something that appears to be a +// panic. Return the 'skip' value that a caller to this function would need +// to supply to runtime.Caller for that frame, or a negative number if not found. +func findPanic() int { + localSkip := -1 + for i := 0; ; i++ { + // Stop if we've passed the base of the stack. + pc, _, _, ok := runtime.Caller(i) + if !ok { + break + } + + // Is this a panic? + if isPanic(pc) { + localSkip = i + } + } + + return localSkip - 1 +} + +// Attempt to find the file base name and line number for the ultimate source +// of a panic, on the panicking stack. Return a human-readable sentinel if +// unsuccessful. +func findPanicFileLine() (string, int) { + panicSkip := findPanic() + if panicSkip < 0 { + return "(unknown)", 0 + } + + // Find the trigger of the panic. + _, file, line, ok := runtime.Caller(panicSkip + 1) + if !ok { + return "(unknown)", 0 + } + + return path.Base(file), line +} + +// Run the supplied function, catching panics (including AssertThat errors) and +// reporting them to the currently-running test as appropriate. Return true iff +// the function panicked. +func runWithProtection(f func()) (panicked bool) { + defer func() { + // If the test didn't panic, we're done. + r := recover() + if r == nil { + return + } + + panicked = true + + // We modify the currently running test below. + currentlyRunningTest.mu.Lock() + defer currentlyRunningTest.mu.Unlock() + + // If the function panicked (and the panic was not due to an AssertThat + // failure), add a failure for the panic. + if !isAbortError(r) { + var panicRecord FailureRecord + panicRecord.FileName, panicRecord.LineNumber = findPanicFileLine() + panicRecord.Error = fmt.Sprintf( + "panic: %v\n\n%s", r, formatPanicStack()) + + currentlyRunningTest.failureRecords = append( + currentlyRunningTest.failureRecords, + panicRecord) + } + }() + + f() + return +} + +func formatPanicStack() string { + buf := new(bytes.Buffer) + + // Find the panic. If successful, we'll skip to below it. Otherwise, we'll + // format everything. + var initialSkip int + if panicSkip := findPanic(); panicSkip >= 0 { + initialSkip = panicSkip + 1 + } + + for i := initialSkip; ; i++ { + pc, file, line, ok := runtime.Caller(i) + if !ok { + break + } + + // Choose a function name to display. + funcName := "(unknown)" + if f := runtime.FuncForPC(pc); f != nil { + funcName = f.Name() + } + + // Stop if we've gotten as far as the test runner code. + if funcName == "github.com/smartystreets/assertions/internal/ogletest.runTestMethod" || + funcName == "github.com/smartystreets/assertions/internal/ogletest.runWithProtection" { + break + } + + // Add an entry for this frame. + fmt.Fprintf(buf, "%s\n\t%s:%d\n", funcName, file, line) + } + + return buf.String() +} + +// Filter test functions according to the user-supplied filter flag. +func filterTestFunctions(suite TestSuite) (out []TestFunction) { + re, err := regexp.Compile(*fTestFilter) + if err != nil { + panic("Invalid value for --ogletest.run: " + err.Error()) + } + + for _, tf := range suite.TestFunctions { + fullName := fmt.Sprintf("%s.%s", suite.Name, tf.Name) + if !re.MatchString(fullName) { + continue + } + + out = append(out, tf) + } + + return +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/srcutil/docs.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/srcutil/docs.go new file mode 100644 index 00000000000..d9b9bc8e5fe --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/srcutil/docs.go @@ -0,0 +1,5 @@ +// Copyright 2015 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) + +// Functions for working with source code. +package srcutil diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/srcutil/methods.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/srcutil/methods.go new file mode 100644 index 00000000000..a8c5828ea3a --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/srcutil/methods.go @@ -0,0 +1,65 @@ +// Copyright 2012 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package srcutil + +import ( + "fmt" + "reflect" + "runtime" + "sort" +) + +func getLine(m reflect.Method) int { + pc := m.Func.Pointer() + + f := runtime.FuncForPC(pc) + if f == nil { + panic(fmt.Sprintf("Couldn't get runtime func for method (pc=%d): %v", pc, m)) + } + + _, line := f.FileLine(pc) + return line +} + +type sortableMethodSet []reflect.Method + +func (s sortableMethodSet) Len() int { + return len(s) +} + +func (s sortableMethodSet) Less(i, j int) bool { + return getLine(s[i]) < getLine(s[j]) +} + +func (s sortableMethodSet) Swap(i, j int) { + s[i], s[j] = s[j], s[i] +} + +// Given a type t, return all of the methods of t sorted such that source file +// order is preserved. Order across files is undefined. Order within lines is +// undefined. +func GetMethodsInSourceOrder(t reflect.Type) []reflect.Method { + // Build the list of methods. + methods := sortableMethodSet{} + for i := 0; i < t.NumMethod(); i++ { + methods = append(methods, t.Method(i)) + } + + // Sort it. + sort.Sort(methods) + + return methods +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/srcutil/methods_test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/srcutil/methods_test.go new file mode 100644 index 00000000000..95c07fd4697 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/srcutil/methods_test.go @@ -0,0 +1,107 @@ +// 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 srcutil_test + +import ( + "fmt" + "reflect" + "testing" + + . "github.com/smartystreets/assertions/internal/oglematchers" + . "github.com/smartystreets/assertions/internal/ogletest" + "github.com/smartystreets/assertions/internal/ogletest/srcutil" +) + +func TestRegisterMethodsTest(t *testing.T) { RunTests(t) } + +//////////////////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////////////////// + +type MethodsTest struct { +} + +func init() { RegisterTestSuite(&MethodsTest{}) } + +type OneMethodType int + +func (x OneMethodType) Foo() {} + +type MultipleMethodsType int + +func (x MultipleMethodsType) Foo() {} +func (x MultipleMethodsType) Bar() {} +func (x MultipleMethodsType) Baz() {} + +type methodNameMatcher struct { + expected string +} + +func (m *methodNameMatcher) Description() string { + return fmt.Sprintf("method named %s", m.expected) +} + +func (m *methodNameMatcher) Matches(x interface{}) error { + method, ok := x.(reflect.Method) + if !ok { + panic("Invalid argument.") + } + + if method.Name != m.expected { + return fmt.Errorf("whose name is %s", method.Name) + } + + return nil +} + +func NameIs(name string) Matcher { + return &methodNameMatcher{name} +} + +//////////////////////////////////////////////////////////////////////// +// Tests +//////////////////////////////////////////////////////////////////////// + +func (t *MethodsTest) NoMethods() { + type foo int + + methods := srcutil.GetMethodsInSourceOrder(reflect.TypeOf(foo(17))) + ExpectThat(methods, ElementsAre()) +} + +func (t *MethodsTest) OneMethod() { + methods := srcutil.GetMethodsInSourceOrder(reflect.TypeOf(OneMethodType(17))) + ExpectThat( + methods, + ElementsAre( + NameIs("Foo"), + )) +} + +func (t *MethodsTest) MultipleMethods() { + methods := srcutil.GetMethodsInSourceOrder(reflect.TypeOf(MultipleMethodsType(17))) + ExpectThat( + methods, + ElementsAre( + NameIs("Foo"), + NameIs("Bar"), + NameIs("Baz"), + )) + + ExpectEq("Foo", methods[0].Name) + ExpectEq("Bar", methods[1].Name) + ExpectEq("Baz", methods[2].Name) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/failing.test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/failing.test.go new file mode 100644 index 00000000000..17c50e19487 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/failing.test.go @@ -0,0 +1,252 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package oglematchers_test + +import ( + "fmt" + "testing" + + . "github.com/smartystreets/assertions/internal/oglematchers" + . "github.com/smartystreets/assertions/internal/ogletest" +) + +func TestFailingTest(t *testing.T) { RunTests(t) } + +//////////////////////////////////////////////////////////////////////// +// Usual failures +//////////////////////////////////////////////////////////////////////// + +type FailingTest struct { +} + +var _ TearDownInterface = &FailingTest{} +var _ TearDownTestSuiteInterface = &FailingTest{} + +func init() { RegisterTestSuite(&FailingTest{}) } + +func (t *FailingTest) TearDown() { + fmt.Println("TearDown running.") +} + +func (t *FailingTest) TearDownTestSuite() { + fmt.Println("TearDownTestSuite running.") +} + +func (t *FailingTest) PassingMethod() { +} + +func (t *FailingTest) Equals() { + ExpectThat(17, Equals(17.5)) + ExpectThat(17, Equals("taco")) +} + +func (t *FailingTest) LessThan() { + ExpectThat(18, LessThan(17)) + ExpectThat(18, LessThan("taco")) +} + +func (t *FailingTest) HasSubstr() { + ExpectThat("taco", HasSubstr("ac")) + ExpectThat(17, HasSubstr("ac")) +} + +func (t *FailingTest) ExpectWithUserErrorMessages() { + ExpectThat(17, Equals(19), "foo bar: %d", 112) + ExpectEq(17, 17.5, "foo bar: %d", 112) + ExpectLe(17, 16.9, "foo bar: %d", 112) + ExpectLt(17, 16.9, "foo bar: %d", 112) + ExpectGe(17, 17.1, "foo bar: %d", 112) + ExpectGt(17, "taco", "foo bar: %d", 112) + ExpectNe(17, 17.0, "foo bar: %d", 112) + ExpectFalse(true, "foo bar: %d", 112) + ExpectTrue(false, "foo bar: %d", 112) +} + +func (t *FailingTest) AssertWithUserErrorMessages() { + AssertThat(17, Equals(19), "foo bar: %d", 112) +} + +func (t *FailingTest) ExpectationAliases() { + ExpectEq(17, 17.5) + ExpectEq("taco", 17.5) + + ExpectLe(17, 16.9) + ExpectLt(17, 16.9) + ExpectLt(17, "taco") + + ExpectGe(17, 17.1) + ExpectGt(17, 17.1) + ExpectGt(17, "taco") + + ExpectNe(17, 17.0) + ExpectNe(17, "taco") + + ExpectFalse(true) + ExpectFalse("taco") + + ExpectTrue(false) + ExpectTrue("taco") +} + +func (t *FailingTest) AssertThatFailure() { + AssertThat(17, Equals(19)) + panic("Shouldn't get here.") +} + +func (t *FailingTest) AssertEqFailure() { + AssertEq(19, 17) + panic("Shouldn't get here.") +} + +func (t *FailingTest) AssertNeFailure() { + AssertNe(19, 19) + panic("Shouldn't get here.") +} + +func (t *FailingTest) AssertLeFailure() { + AssertLe(19, 17) + panic("Shouldn't get here.") +} + +func (t *FailingTest) AssertLtFailure() { + AssertLt(19, 17) + panic("Shouldn't get here.") +} + +func (t *FailingTest) AssertGeFailure() { + AssertGe(17, 19) + panic("Shouldn't get here.") +} + +func (t *FailingTest) AssertGtFailure() { + AssertGt(17, 19) + panic("Shouldn't get here.") +} + +func (t *FailingTest) AssertTrueFailure() { + AssertTrue("taco") + panic("Shouldn't get here.") +} + +func (t *FailingTest) AssertFalseFailure() { + AssertFalse("taco") + panic("Shouldn't get here.") +} + +func (t *FailingTest) AddFailureRecord() { + r := FailureRecord{ + FileName: "foo.go", + LineNumber: 17, + Error: "taco\nburrito", + } + + AddFailureRecord(r) +} + +func (t *FailingTest) AddFailure() { + AddFailure("taco") + AddFailure("burrito: %d", 17) +} + +func (t *FailingTest) AddFailureThenAbortTest() { + AddFailure("enchilada") + AbortTest() + fmt.Println("Shouldn't get here.") +} + +//////////////////////////////////////////////////////////////////////// +// Expectation failure during SetUp +//////////////////////////////////////////////////////////////////////// + +type ExpectFailDuringSetUpTest struct { +} + +func init() { RegisterTestSuite(&ExpectFailDuringSetUpTest{}) } + +func (t *ExpectFailDuringSetUpTest) SetUp(i *TestInfo) { + ExpectFalse(true) +} + +func (t *ExpectFailDuringSetUpTest) TearDown() { + fmt.Println("TearDown running.") +} + +func (t *ExpectFailDuringSetUpTest) PassingMethod() { + fmt.Println("Method running.") +} + +//////////////////////////////////////////////////////////////////////// +// Assertion failure during SetUp +//////////////////////////////////////////////////////////////////////// + +type AssertFailDuringSetUpTest struct { +} + +func init() { RegisterTestSuite(&AssertFailDuringSetUpTest{}) } + +func (t *AssertFailDuringSetUpTest) SetUp(i *TestInfo) { + AssertFalse(true) +} + +func (t *AssertFailDuringSetUpTest) TearDown() { + fmt.Println("TearDown running.") +} + +func (t *AssertFailDuringSetUpTest) PassingMethod() { + fmt.Println("Method running.") +} + +//////////////////////////////////////////////////////////////////////// +// Expectation failure during TearDown +//////////////////////////////////////////////////////////////////////// + +type ExpectFailDuringTearDownTest struct { +} + +func init() { RegisterTestSuite(&ExpectFailDuringTearDownTest{}) } + +func (t *ExpectFailDuringTearDownTest) SetUp(i *TestInfo) { + fmt.Println("SetUp running.") +} + +func (t *ExpectFailDuringTearDownTest) TearDown() { + ExpectFalse(true) +} + +func (t *ExpectFailDuringTearDownTest) PassingMethod() { + fmt.Println("Method running.") +} + +//////////////////////////////////////////////////////////////////////// +// Assertion failure during TearDown +//////////////////////////////////////////////////////////////////////// + +type AssertFailDuringTearDownTest struct { +} + +func init() { RegisterTestSuite(&AssertFailDuringTearDownTest{}) } + +func (t *AssertFailDuringTearDownTest) SetUp(i *TestInfo) { + fmt.Println("SetUp running.") +} + +func (t *AssertFailDuringTearDownTest) TearDown() { + AssertFalse(true) +} + +func (t *AssertFailDuringTearDownTest) PassingMethod() { + fmt.Println("Method running.") +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/filtered.test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/filtered.test.go new file mode 100644 index 00000000000..e559c5f926c --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/filtered.test.go @@ -0,0 +1,79 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package oglematchers_test + +import ( + "fmt" + . "github.com/smartystreets/assertions/internal/oglematchers" + . "github.com/smartystreets/assertions/internal/ogletest" + "testing" +) + +func TestFiltered(t *testing.T) { RunTests(t) } + +//////////////////////////////////////////////////////////////////////// +// Partially filtered out +//////////////////////////////////////////////////////////////////////// + +type PartiallyFilteredTest struct { +} + +func init() { RegisterTestSuite(&PartiallyFilteredTest{}) } + +func (t *PartiallyFilteredTest) PassingTestFoo() { + ExpectThat(19, Equals(19)) +} + +func (t *PartiallyFilteredTest) PassingTestBar() { + ExpectThat(17, Equals(17)) +} + +func (t *PartiallyFilteredTest) PartiallyFilteredTestFoo() { + ExpectThat(18, LessThan(17)) +} + +func (t *PartiallyFilteredTest) PartiallyFilteredTestBar() { + ExpectThat("taco", HasSubstr("blah")) +} + +func (t *PartiallyFilteredTest) PartiallyFilteredTestBaz() { + ExpectThat(18, LessThan(17)) +} + +//////////////////////////////////////////////////////////////////////// +// Completely filtered out +//////////////////////////////////////////////////////////////////////// + +type CompletelyFilteredTest struct { +} + +func init() { RegisterTestSuite(&CompletelyFilteredTest{}) } + +func (t *CompletelyFilteredTest) SetUpTestSuite() { + fmt.Println("SetUpTestSuite run!") +} + +func (t *CompletelyFilteredTest) TearDownTestSuite() { + fmt.Println("TearDownTestSuite run!") +} + +func (t *PartiallyFilteredTest) SomePassingTest() { + ExpectThat(19, Equals(19)) +} + +func (t *PartiallyFilteredTest) SomeFailingTest() { + ExpectThat(19, Equals(17)) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/golden.failing_test b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/golden.failing_test new file mode 100644 index 00000000000..f0cd76af500 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/golden.failing_test @@ -0,0 +1,278 @@ +[----------] Running tests from FailingTest +[ RUN ] FailingTest.PassingMethod +TearDown running. +[ OK ] FailingTest.PassingMethod +[ RUN ] FailingTest.Equals +TearDown running. +failing_test.go:52: +Expected: 17.5 +Actual: 17 + +failing_test.go:53: +Expected: taco +Actual: 17, which is not a string + +[ FAILED ] FailingTest.Equals +[ RUN ] FailingTest.LessThan +TearDown running. +failing_test.go:57: +Expected: less than 17 +Actual: 18 + +failing_test.go:58: +Expected: less than "taco" +Actual: 18, which is not comparable + +[ FAILED ] FailingTest.LessThan +[ RUN ] FailingTest.HasSubstr +TearDown running. +failing_test.go:63: +Expected: has substring "ac" +Actual: 17, which is not a string + +[ FAILED ] FailingTest.HasSubstr +[ RUN ] FailingTest.ExpectWithUserErrorMessages +TearDown running. +failing_test.go:67: +Expected: 19 +Actual: 17 +foo bar: 112 + +failing_test.go:68: +Expected: 17 +Actual: 17.5 +foo bar: 112 + +failing_test.go:69: +Expected: less than or equal to 16.9 +Actual: 17 +foo bar: 112 + +failing_test.go:70: +Expected: less than 16.9 +Actual: 17 +foo bar: 112 + +failing_test.go:71: +Expected: greater than or equal to 17.1 +Actual: 17 +foo bar: 112 + +failing_test.go:72: +Expected: greater than "taco" +Actual: 17, which is not comparable +foo bar: 112 + +failing_test.go:73: +Expected: not(17) +Actual: 17 +foo bar: 112 + +failing_test.go:74: +Expected: false +Actual: true +foo bar: 112 + +failing_test.go:75: +Expected: true +Actual: false +foo bar: 112 + +[ FAILED ] FailingTest.ExpectWithUserErrorMessages +[ RUN ] FailingTest.AssertWithUserErrorMessages +TearDown running. +failing_test.go:79: +Expected: 19 +Actual: 17 +foo bar: 112 + +[ FAILED ] FailingTest.AssertWithUserErrorMessages +[ RUN ] FailingTest.ExpectationAliases +TearDown running. +failing_test.go:83: +Expected: 17 +Actual: 17.5 + +failing_test.go:84: +Expected: taco +Actual: 17.5, which is not a string + +failing_test.go:86: +Expected: less than or equal to 16.9 +Actual: 17 + +failing_test.go:87: +Expected: less than 16.9 +Actual: 17 + +failing_test.go:88: +Expected: less than "taco" +Actual: 17, which is not comparable + +failing_test.go:90: +Expected: greater than or equal to 17.1 +Actual: 17 + +failing_test.go:91: +Expected: greater than 17.1 +Actual: 17 + +failing_test.go:92: +Expected: greater than "taco" +Actual: 17, which is not comparable + +failing_test.go:94: +Expected: not(17) +Actual: 17 + +failing_test.go:95: +Expected: not(17) +Actual: taco, which is not numeric + +failing_test.go:97: +Expected: false +Actual: true + +failing_test.go:98: +Expected: false +Actual: taco, which is not a bool + +failing_test.go:100: +Expected: true +Actual: false + +failing_test.go:101: +Expected: true +Actual: taco, which is not a bool + +[ FAILED ] FailingTest.ExpectationAliases +[ RUN ] FailingTest.AssertThatFailure +TearDown running. +failing_test.go:105: +Expected: 19 +Actual: 17 + +[ FAILED ] FailingTest.AssertThatFailure +[ RUN ] FailingTest.AssertEqFailure +TearDown running. +failing_test.go:110: +Expected: 19 +Actual: 17 + +[ FAILED ] FailingTest.AssertEqFailure +[ RUN ] FailingTest.AssertNeFailure +TearDown running. +failing_test.go:115: +Expected: not(19) +Actual: 19 + +[ FAILED ] FailingTest.AssertNeFailure +[ RUN ] FailingTest.AssertLeFailure +TearDown running. +failing_test.go:120: +Expected: less than or equal to 17 +Actual: 19 + +[ FAILED ] FailingTest.AssertLeFailure +[ RUN ] FailingTest.AssertLtFailure +TearDown running. +failing_test.go:125: +Expected: less than 17 +Actual: 19 + +[ FAILED ] FailingTest.AssertLtFailure +[ RUN ] FailingTest.AssertGeFailure +TearDown running. +failing_test.go:130: +Expected: greater than or equal to 19 +Actual: 17 + +[ FAILED ] FailingTest.AssertGeFailure +[ RUN ] FailingTest.AssertGtFailure +TearDown running. +failing_test.go:135: +Expected: greater than 19 +Actual: 17 + +[ FAILED ] FailingTest.AssertGtFailure +[ RUN ] FailingTest.AssertTrueFailure +TearDown running. +failing_test.go:140: +Expected: true +Actual: taco, which is not a bool + +[ FAILED ] FailingTest.AssertTrueFailure +[ RUN ] FailingTest.AssertFalseFailure +TearDown running. +failing_test.go:145: +Expected: false +Actual: taco, which is not a bool + +[ FAILED ] FailingTest.AssertFalseFailure +[ RUN ] FailingTest.AddFailureRecord +TearDown running. +foo.go:17: +taco +burrito + +[ FAILED ] FailingTest.AddFailureRecord +[ RUN ] FailingTest.AddFailure +TearDown running. +failing_test.go:160: +taco + +failing_test.go:161: +burrito: 17 + +[ FAILED ] FailingTest.AddFailure +[ RUN ] FailingTest.AddFailureThenAbortTest +TearDown running. +failing_test.go:165: +enchilada + +[ FAILED ] FailingTest.AddFailureThenAbortTest +TearDownTestSuite running. +[----------] Finished with tests from FailingTest +[----------] Running tests from ExpectFailDuringSetUpTest +[ RUN ] ExpectFailDuringSetUpTest.PassingMethod +Method running. +TearDown running. +failing_test.go:180: +Expected: false +Actual: true + +[ FAILED ] ExpectFailDuringSetUpTest.PassingMethod +[----------] Finished with tests from ExpectFailDuringSetUpTest +[----------] Running tests from AssertFailDuringSetUpTest +[ RUN ] AssertFailDuringSetUpTest.PassingMethod +TearDown running. +failing_test.go:201: +Expected: false +Actual: true + +[ FAILED ] AssertFailDuringSetUpTest.PassingMethod +[----------] Finished with tests from AssertFailDuringSetUpTest +[----------] Running tests from ExpectFailDuringTearDownTest +[ RUN ] ExpectFailDuringTearDownTest.PassingMethod +SetUp running. +Method running. +failing_test.go:226: +Expected: false +Actual: true + +[ FAILED ] ExpectFailDuringTearDownTest.PassingMethod +[----------] Finished with tests from ExpectFailDuringTearDownTest +[----------] Running tests from AssertFailDuringTearDownTest +[ RUN ] AssertFailDuringTearDownTest.PassingMethod +SetUp running. +Method running. +failing_test.go:247: +Expected: false +Actual: true + +[ FAILED ] AssertFailDuringTearDownTest.PassingMethod +[----------] Finished with tests from AssertFailDuringTearDownTest +--- FAIL: TestSomething (1.23s) +FAIL +exit status 1 +FAIL somepkg 1.234s diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/golden.filtered_test b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/golden.filtered_test new file mode 100644 index 00000000000..39fa697140c --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/golden.filtered_test @@ -0,0 +1,24 @@ +[----------] Running tests from PartiallyFilteredTest +[ RUN ] PartiallyFilteredTest.PassingTestBar +[ OK ] PartiallyFilteredTest.PassingTestBar +[ RUN ] PartiallyFilteredTest.PartiallyFilteredTestBar +filtered_test.go:49: +Expected: has substring "blah" +Actual: taco + +[ FAILED ] PartiallyFilteredTest.PartiallyFilteredTestBar +[ RUN ] PartiallyFilteredTest.PartiallyFilteredTestBaz +filtered_test.go:53: +Expected: less than 17 +Actual: 18 + +[ FAILED ] PartiallyFilteredTest.PartiallyFilteredTestBaz +[----------] Finished with tests from PartiallyFilteredTest +[----------] Running tests from CompletelyFilteredTest +SetUpTestSuite run! +TearDownTestSuite run! +[----------] Finished with tests from CompletelyFilteredTest +--- FAIL: TestSomething (1.23s) +FAIL +exit status 1 +FAIL somepkg 1.234s diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/golden.mock_test b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/golden.mock_test new file mode 100644 index 00000000000..4ca29791de7 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/golden.mock_test @@ -0,0 +1,25 @@ +[----------] Running tests from MockTest +[ RUN ] MockTest.ExpectationSatisfied +[ OK ] MockTest.ExpectationSatisfied +[ RUN ] MockTest.MockExpectationNotSatisfied +/some/path/mock_test.go:56: +Unsatisfied expectation; expected At to be called at least 1 times; called 0 times. + +[ FAILED ] MockTest.MockExpectationNotSatisfied +[ RUN ] MockTest.ExpectCallForUnknownMethod +/some/path/mock_test.go:61: +Unknown method: FooBar + +[ FAILED ] MockTest.ExpectCallForUnknownMethod +[ RUN ] MockTest.UnexpectedCall +/some/path/mock_test.go:65: +Unexpected call to At with args: [11 23] + +[ FAILED ] MockTest.UnexpectedCall +[ RUN ] MockTest.InvokeFunction +[ OK ] MockTest.InvokeFunction +[----------] Finished with tests from MockTest +--- FAIL: TestSomething (1.23s) +FAIL +exit status 1 +FAIL somepkg 1.234s diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/golden.no_cases_test b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/golden.no_cases_test new file mode 100644 index 00000000000..8631385581d --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/golden.no_cases_test @@ -0,0 +1,6 @@ +[----------] Running tests from NoCasesTest +SetUpTestSuite run! +TearDownTestSuite run! +[----------] Finished with tests from NoCasesTest +PASS +ok somepkg 1.234s diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/golden.panicking_test b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/golden.panicking_test new file mode 100644 index 00000000000..32eac65f7ba --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/golden.panicking_test @@ -0,0 +1,90 @@ +[----------] Running tests from PanickingTest +[ RUN ] PanickingTest.ExplicitPanic +TearDown running. +panicking_test.go:47: +panic: Panic in ExplicitPanic + +github.com/smartystreets/assertions/internal/ogletest/somepkg_test.(*PanickingTest).ExplicitPanic + some_file.txt:0 +runtime.call16 + /some/path/asm_amd64.s:401 +reflect.Value.call + some_file.txt:0 +reflect.Value.Call + some_file.txt:0 + + +[ FAILED ] PanickingTest.ExplicitPanic +[ RUN ] PanickingTest.ExplicitPanicInHelperFunction +TearDown running. +panicking_test.go:34: +panic: Panic in someFuncThatPanics + +github.com/smartystreets/assertions/internal/ogletest/somepkg_test.someFuncThatPanics + some_file.txt:0 +github.com/smartystreets/assertions/internal/ogletest/somepkg_test.(*PanickingTest).ExplicitPanicInHelperFunction + some_file.txt:0 +runtime.call16 + /some/path/asm_amd64.s:401 +reflect.Value.call + some_file.txt:0 +reflect.Value.Call + some_file.txt:0 + + +[ FAILED ] PanickingTest.ExplicitPanicInHelperFunction +[ RUN ] PanickingTest.NilPointerDerefence +TearDown running. +panicking_test.go:56: +panic: runtime error: invalid memory address or nil pointer dereference + +github.com/smartystreets/assertions/internal/ogletest/somepkg_test.(*PanickingTest).NilPointerDerefence + some_file.txt:0 +runtime.call16 + /some/path/asm_amd64.s:401 +reflect.Value.call + some_file.txt:0 +reflect.Value.Call + some_file.txt:0 + + +[ FAILED ] PanickingTest.NilPointerDerefence +[ RUN ] PanickingTest.ZzzSomeOtherTest +TearDown running. +[ OK ] PanickingTest.ZzzSomeOtherTest +[----------] Finished with tests from PanickingTest +[----------] Running tests from SetUpPanicTest +[ RUN ] SetUpPanicTest.SomeTestCase +SetUp about to panic. +TearDown running. +panicking_test.go:74: +panic: Panic in SetUp + +github.com/smartystreets/assertions/internal/ogletest/somepkg_test.(*SetUpPanicTest).SetUp + some_file.txt:0 +github.com/smartystreets/assertions/internal/ogletest.func·003 + some_file.txt:0 +github.com/smartystreets/assertions/internal/ogletest.func·007 + some_file.txt:0 + + +[ FAILED ] SetUpPanicTest.SomeTestCase +[----------] Finished with tests from SetUpPanicTest +[----------] Running tests from TearDownPanicTest +[ RUN ] TearDownPanicTest.SomeTestCase +TearDown about to panic. +panicking_test.go:95: +panic: Panic in TearDown + +github.com/smartystreets/assertions/internal/ogletest/somepkg_test.(*TearDownPanicTest).TearDown + some_file.txt:0 +github.com/smartystreets/assertions/internal/ogletest.func·005 + some_file.txt:0 + + +[ FAILED ] TearDownPanicTest.SomeTestCase +[----------] Finished with tests from TearDownPanicTest +--- FAIL: TestSomething (1.23s) +FAIL +exit status 1 +FAIL somepkg 1.234s diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/golden.passing_test b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/golden.passing_test new file mode 100644 index 00000000000..031128842ac --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/golden.passing_test @@ -0,0 +1,22 @@ +[----------] Running tests from PassingTest +[ RUN ] PassingTest.EmptyTestMethod +[ OK ] PassingTest.EmptyTestMethod +[ RUN ] PassingTest.SuccessfullMatches +[ OK ] PassingTest.SuccessfullMatches +[ RUN ] PassingTest.ExpectAliases +[ OK ] PassingTest.ExpectAliases +[ RUN ] PassingTest.AssertAliases +[ OK ] PassingTest.AssertAliases +[ RUN ] PassingTest.SlowTest +[ OK ] PassingTest.SlowTest (1234ms) +[----------] Finished with tests from PassingTest +[----------] Running tests from PassingTestWithHelpers +SetUpTestSuite ran. +[ RUN ] PassingTestWithHelpers.EmptyTestMethod +SetUp ran. +TearDown ran. +[ OK ] PassingTestWithHelpers.EmptyTestMethod +TearDownTestSuite ran. +[----------] Finished with tests from PassingTestWithHelpers +PASS +ok somepkg 1.234s diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/golden.run_twice_test b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/golden.run_twice_test new file mode 100644 index 00000000000..0749f916454 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/golden.run_twice_test @@ -0,0 +1,14 @@ +[----------] Running tests from RunTwiceTest +[ RUN ] RunTwiceTest.PassingMethod +[ OK ] RunTwiceTest.PassingMethod +[ RUN ] RunTwiceTest.FailingMethod +run_twice_test.go:46: +Expected: 17.5 +Actual: 17 + +[ FAILED ] RunTwiceTest.FailingMethod +[----------] Finished with tests from RunTwiceTest +--- FAIL: TestSomething (1.23s) +FAIL +exit status 1 +FAIL somepkg 1.234s diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/golden.stop_test b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/golden.stop_test new file mode 100644 index 00000000000..e7d42c79337 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/golden.stop_test @@ -0,0 +1,13 @@ +[----------] Running tests from StopTest +[ RUN ] StopTest.First +TearDown running. +[ OK ] StopTest.First +[ RUN ] StopTest.Second +About to call StopRunningTests. +Called StopRunningTests. +TearDown running. +[ OK ] StopTest.Second +TearDownTestSuite running. +Exiting early due to user request. +exit status 1 +FAIL somepkg 1.234s diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/golden.unexported_test b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/golden.unexported_test new file mode 100644 index 00000000000..6221e65ea9a --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/golden.unexported_test @@ -0,0 +1,12 @@ +[----------] Running tests from UnexportedTest +[ RUN ] UnexportedTest.SomeTest +unexported_test.go:42: +Expected: 4 +Actual: 3 + +[ FAILED ] UnexportedTest.SomeTest +[----------] Finished with tests from UnexportedTest +--- FAIL: TestSomething (1.23s) +FAIL +exit status 1 +FAIL somepkg 1.234s diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/mock.test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/mock.test.go new file mode 100644 index 00000000000..8e0fca9cc01 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/mock.test.go @@ -0,0 +1,82 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package oglematchers_test + +import ( + . "github.com/smartystreets/assertions/internal/oglematchers" + "github.com/smartystreets/assertions/internal/oglemock" + . "github.com/smartystreets/assertions/internal/ogletest" + "github.com/smartystreets/assertions/internal/ogletest/test_cases/mock_image" + "image/color" + "testing" +) + +//////////////////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////////////////// + +type MockTest struct { + controller oglemock.Controller + image mock_image.MockImage +} + +func init() { RegisterTestSuite(&MockTest{}) } +func TestMockTest(t *testing.T) { RunTests(t) } + +func (t *MockTest) SetUp(i *TestInfo) { + t.controller = i.MockController + t.image = mock_image.NewMockImage(t.controller, "some mock image") +} + +//////////////////////////////////////////////////////////////////////// +// Tests +//////////////////////////////////////////////////////////////////////// + +func (t *MockTest) ExpectationSatisfied() { + ExpectCall(t.image, "At")(11, GreaterThan(19)). + WillOnce(oglemock.Return(color.Gray{0})) + + ExpectThat(t.image.At(11, 23), IdenticalTo(color.Gray{0})) +} + +func (t *MockTest) MockExpectationNotSatisfied() { + ExpectCall(t.image, "At")(11, GreaterThan(19)). + WillOnce(oglemock.Return(color.Gray{0})) +} + +func (t *MockTest) ExpectCallForUnknownMethod() { + ExpectCall(t.image, "FooBar")(11) +} + +func (t *MockTest) UnexpectedCall() { + t.image.At(11, 23) +} + +func (t *MockTest) InvokeFunction() { + var suppliedX, suppliedY int + f := func(x, y int) color.Color { + suppliedX = x + suppliedY = y + return color.Gray{17} + } + + ExpectCall(t.image, "At")(Any(), Any()). + WillOnce(oglemock.Invoke(f)) + + ExpectThat(t.image.At(-1, 12), IdenticalTo(color.Gray{17})) + ExpectEq(-1, suppliedX) + ExpectEq(12, suppliedY) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/mock_image/mock_image.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/mock_image/mock_image.go new file mode 100644 index 00000000000..a8d55bc4808 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/mock_image/mock_image.go @@ -0,0 +1,115 @@ +// This file was auto-generated using createmock. See the following page for +// more information: +// +// https://github.com/smartystreets/assertions/internal/oglemock +// + +package mock_image + +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 +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/no_cases.test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/no_cases.test.go new file mode 100644 index 00000000000..ad204e053e5 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/no_cases.test.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 oglematchers_test + +import ( + "fmt" + . "github.com/smartystreets/assertions/internal/ogletest" + "testing" +) + +func TestNoCases(t *testing.T) { RunTests(t) } + +//////////////////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////////////////// + +type NoCasesTest struct { +} + +func init() { RegisterTestSuite(&NoCasesTest{}) } + +func (t *NoCasesTest) SetUpTestSuite() { + fmt.Println("SetUpTestSuite run!") +} + +func (t *NoCasesTest) TearDownTestSuite() { + fmt.Println("TearDownTestSuite run!") +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/panicking.test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/panicking.test.go new file mode 100644 index 00000000000..59d1fe3bae0 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/panicking.test.go @@ -0,0 +1,99 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package oglematchers_test + +import ( + "fmt" + "log" + "testing" + + . "github.com/smartystreets/assertions/internal/oglematchers" + . "github.com/smartystreets/assertions/internal/ogletest" +) + +func TestPanickingTest(t *testing.T) { RunTests(t) } + +//////////////////////////////////////////////////////////////////////// +// PanickingTest +//////////////////////////////////////////////////////////////////////// + +func someFuncThatPanics() { + panic("Panic in someFuncThatPanics") +} + +type PanickingTest struct { +} + +func init() { RegisterTestSuite(&PanickingTest{}) } + +func (t *PanickingTest) TearDown() { + fmt.Println("TearDown running.") +} + +func (t *PanickingTest) ExplicitPanic() { + panic("Panic in ExplicitPanic") +} + +func (t *PanickingTest) ExplicitPanicInHelperFunction() { + someFuncThatPanics() +} + +func (t *PanickingTest) NilPointerDerefence() { + var p *int + log.Println(*p) +} + +func (t *PanickingTest) ZzzSomeOtherTest() { + ExpectThat(17, Equals(17.0)) +} + +//////////////////////////////////////////////////////////////////////// +// SetUpPanicTest +//////////////////////////////////////////////////////////////////////// + +type SetUpPanicTest struct { +} + +func init() { RegisterTestSuite(&SetUpPanicTest{}) } + +func (t *SetUpPanicTest) SetUp(ti *TestInfo) { + fmt.Println("SetUp about to panic.") + panic("Panic in SetUp") +} + +func (t *SetUpPanicTest) TearDown() { + fmt.Println("TearDown running.") +} + +func (t *SetUpPanicTest) SomeTestCase() { +} + +//////////////////////////////////////////////////////////////////////// +// TearDownPanicTest +//////////////////////////////////////////////////////////////////////// + +type TearDownPanicTest struct { +} + +func init() { RegisterTestSuite(&TearDownPanicTest{}) } + +func (t *TearDownPanicTest) TearDown() { + fmt.Println("TearDown about to panic.") + panic("Panic in TearDown") +} + +func (t *TearDownPanicTest) SomeTestCase() { +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/passing.test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/passing.test.go new file mode 100644 index 00000000000..01d8e63446e --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/passing.test.go @@ -0,0 +1,120 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package oglematchers_test + +import ( + "fmt" + "testing" + "time" + + . "github.com/smartystreets/assertions/internal/oglematchers" + . "github.com/smartystreets/assertions/internal/ogletest" +) + +func TestPassingTest(t *testing.T) { RunTests(t) } + +//////////////////////////////////////////////////////////////////////// +// PassingTest +//////////////////////////////////////////////////////////////////////// + +type PassingTest struct { +} + +func init() { RegisterTestSuite(&PassingTest{}) } + +func (t *PassingTest) EmptyTestMethod() { +} + +func (t *PassingTest) SuccessfullMatches() { + ExpectThat(17, Equals(17.0)) + ExpectThat(16.9, LessThan(17)) + ExpectThat("taco", HasSubstr("ac")) + + AssertThat(17, Equals(17.0)) + AssertThat(16.9, LessThan(17)) + AssertThat("taco", HasSubstr("ac")) +} + +func (t *PassingTest) ExpectAliases() { + ExpectEq(17, 17.0) + + ExpectLe(17, 17.0) + ExpectLe(17, 18.0) + ExpectLt(17, 18.0) + + ExpectGe(17, 17.0) + ExpectGe(17, 16.0) + ExpectGt(17, 16.0) + + ExpectNe(17, 18.0) + + ExpectTrue(true) + ExpectFalse(false) +} + +func (t *PassingTest) AssertAliases() { + AssertEq(17, 17.0) + + AssertLe(17, 17.0) + AssertLe(17, 18.0) + AssertLt(17, 18.0) + + AssertGe(17, 17.0) + AssertGe(17, 16.0) + AssertGt(17, 16.0) + + AssertNe(17, 18.0) + + AssertTrue(true) + AssertFalse(false) +} + +func (t *PassingTest) SlowTest() { + time.Sleep(37 * time.Millisecond) +} + +//////////////////////////////////////////////////////////////////////// +// PassingTestWithHelpers +//////////////////////////////////////////////////////////////////////// + +type PassingTestWithHelpers struct { +} + +var _ SetUpTestSuiteInterface = &PassingTestWithHelpers{} +var _ SetUpInterface = &PassingTestWithHelpers{} +var _ TearDownInterface = &PassingTestWithHelpers{} +var _ TearDownTestSuiteInterface = &PassingTestWithHelpers{} + +func init() { RegisterTestSuite(&PassingTestWithHelpers{}) } + +func (t *PassingTestWithHelpers) SetUpTestSuite() { + fmt.Println("SetUpTestSuite ran.") +} + +func (t *PassingTestWithHelpers) SetUp(ti *TestInfo) { + fmt.Println("SetUp ran.") +} + +func (t *PassingTestWithHelpers) TearDown() { + fmt.Println("TearDown ran.") +} + +func (t *PassingTestWithHelpers) TearDownTestSuite() { + fmt.Println("TearDownTestSuite ran.") +} + +func (t *PassingTestWithHelpers) EmptyTestMethod() { +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/run_twice.test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/run_twice.test.go new file mode 100644 index 00000000000..a3a36c17525 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/run_twice.test.go @@ -0,0 +1,47 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package oglematchers_test + +import ( + . "github.com/smartystreets/assertions/internal/oglematchers" + . "github.com/smartystreets/assertions/internal/ogletest" + "testing" +) + +//////////////////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////////////////// + +type RunTwiceTest struct { +} + +func init() { RegisterTestSuite(&RunTwiceTest{}) } + +// Set up two helpers that call RunTests. The test should still only be run +// once. +func TestOgletest(t *testing.T) { RunTests(t) } +func TestOgletest2(t *testing.T) { RunTests(t) } + +//////////////////////////////////////////////////////////////////////// +// Tests +//////////////////////////////////////////////////////////////////////// + +func (t *RunTwiceTest) PassingMethod() { +} + +func (t *RunTwiceTest) FailingMethod() { + ExpectThat(17, Equals(17.5)) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/stop.test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/stop.test.go new file mode 100644 index 00000000000..a008c081e91 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/stop.test.go @@ -0,0 +1,61 @@ +// Copyright 2015 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package oglematchers_test + +import ( + "fmt" + "testing" + + . "github.com/smartystreets/assertions/internal/ogletest" +) + +func TestStop(t *testing.T) { RunTests(t) } + +//////////////////////////////////////////////////////////////////////// +// Boilerplate +//////////////////////////////////////////////////////////////////////// + +type StopTest struct { +} + +var _ TearDownInterface = &StopTest{} +var _ TearDownTestSuiteInterface = &StopTest{} + +func init() { RegisterTestSuite(&StopTest{}) } + +func (t *StopTest) TearDown() { + fmt.Println("TearDown running.") +} + +func (t *StopTest) TearDownTestSuite() { + fmt.Println("TearDownTestSuite running.") +} + +//////////////////////////////////////////////////////////////////////// +// Tests +//////////////////////////////////////////////////////////////////////// + +func (t *StopTest) First() { +} + +func (t *StopTest) Second() { + fmt.Println("About to call StopRunningTests.") + StopRunningTests() + fmt.Println("Called StopRunningTests.") +} + +func (t *StopTest) Third() { +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/unexported.test.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/unexported.test.go new file mode 100644 index 00000000000..a425e78d404 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/unexported.test.go @@ -0,0 +1,43 @@ +// Copyright 2011 Aaron Jacobs. All Rights Reserved. +// Author: aaronjjacobs@gmail.com (Aaron Jacobs) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package oglematchers_test + +import ( + . "github.com/smartystreets/assertions/internal/oglematchers" + . "github.com/smartystreets/assertions/internal/ogletest" + "testing" +) + +//////////////////////////////////////////////////////////////////////// +// Helpers +//////////////////////////////////////////////////////////////////////// + +type UnexportedTest struct { +} + +func init() { RegisterTestSuite(&UnexportedTest{}) } +func TestUnexportedTest(t *testing.T) { RunTests(t) } + +func (t *UnexportedTest) someUnexportedMethod() { +} + +//////////////////////////////////////////////////////////////////////// +// Tests +//////////////////////////////////////////////////////////////////////// + +func (t *UnexportedTest) SomeTest() { + ExpectThat(3, Equals(4)) +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_info.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_info.go new file mode 100644 index 00000000000..3ae12526bc2 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/ogletest/test_info.go @@ -0,0 +1,91 @@ +// 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 ogletest + +import ( + "sync" + + "golang.org/x/net/context" + + "github.com/smartystreets/assertions/internal/oglemock" +) + +// TestInfo represents information about a currently running or previously-run +// test. +type TestInfo struct { + // A mock controller that is set up to report errors to the ogletest test + // runner. This can be used for setting up mock expectations and handling + // mock calls. The Finish method should not be run by the user; ogletest will + // do that automatically after the test's TearDown method is run. + // + // Note that this feature is still experimental, and is subject to change. + MockController oglemock.Controller + + // A context that can be used by tests for long-running operations. In + // particular, this enables conveniently tracing the execution of a test + // function with reqtrace. + Ctx context.Context + + // A mutex protecting shared state. + mu sync.RWMutex + + // A set of failure records that the test has produced. + // + // GUARDED_BY(mu) + failureRecords []FailureRecord +} + +// currentlyRunningTest is the state for the currently running test, if any. +var currentlyRunningTest *TestInfo + +// newTestInfo creates a valid but empty TestInfo struct. +func newTestInfo() (info *TestInfo) { + info = &TestInfo{} + info.MockController = oglemock.NewController(&testInfoErrorReporter{info}) + info.Ctx = context.Background() + + return +} + +// testInfoErrorReporter is an oglemock.ErrorReporter that writes failure +// records into a test info struct. +type testInfoErrorReporter struct { + testInfo *TestInfo +} + +func (r *testInfoErrorReporter) ReportError( + fileName string, + lineNumber int, + err error) { + r.testInfo.mu.Lock() + defer r.testInfo.mu.Unlock() + + record := FailureRecord{ + FileName: fileName, + LineNumber: lineNumber, + Error: err.Error(), + } + + r.testInfo.failureRecords = append(r.testInfo.failureRecords, record) +} + +func (r *testInfoErrorReporter) ReportFatalError( + fileName string, + lineNumber int, + err error) { + r.ReportError(fileName, lineNumber, err) + AbortTest() +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/reqtrace/.gitignore b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/reqtrace/.gitignore new file mode 100644 index 00000000000..daf913b1b34 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/reqtrace/.gitignore @@ -0,0 +1,24 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe +*.test +*.prof diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/reqtrace/LICENSE b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/reqtrace/LICENSE new file mode 100644 index 00000000000..8f71f43fee3 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/reqtrace/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/reqtrace/README.md b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/reqtrace/README.md new file mode 100644 index 00000000000..4392452b5b1 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/reqtrace/README.md @@ -0,0 +1,53 @@ +[![GoDoc](https://godoc.org/github.com/smartystreets/assertions/internal/reqtrace?status.svg)](https://godoc.org/github.com/smartystreets/assertions/internal/reqtrace) + +reqtrace is a package for simple request tracing. It requires nothing of its +user except: + + * They must use [golang.org/x/net/context][context]. + * They must add a single line to each function they want to be visible in + traces. + +[context]: http://godoc.org/golang.org/x/net/context + +In particular, reqtrace is console-based and doesn't require an HTTP server. + +**Warning**: This package is still barebones and in its early days. I reserve +the right to make backwards-incompatible changes to its API. But if it's useful +to you in your current form, have at it. + +## Use + +Call reqtrace.Trace anywhere you want to start a new root trace. (This is +probably where you create your root context.) This returns a new context that +you should pass to child operations, and a reporting function that you must use +to inform reqtrace when the trace is complete. + +For example: + +```Go +func HandleRequest(r *someRequest) (err error) { + ctx, report := reqtrace.Trace(context.Background(), "HandleRequest") + defer func() { report(err) }() + + // Do two things for this request. + DoSomething(ctx, r) + DoSomethingElse(ctx, r) +} +``` + +Within other functions that you want to show up in the trace, you +reqtrace.StartSpan (or its more convenient sibling reqtrace.StartSpanWithError): + +```Go +func DoSomething(ctx context.Context, r *someRequest) (err error) { + defer reqtrace.StartSpanWithError(&ctx, &err, "DoSomething")() + + // Process the request somehow using ctx. If downstream code also annotes + // using reqtrace, reqtrace will know that its spans are descendants of + // this one. + CallAnotherLibrary(ctx, r.Param) +} +``` + +When `--reqtrace.enable` is set, the completion of a trace will cause helpful +ASCII art to be spit out. diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/reqtrace/reqtrace.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/reqtrace/reqtrace.go new file mode 100644 index 00000000000..853c024244f --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/reqtrace/reqtrace.go @@ -0,0 +1,132 @@ +// Copyright 2015 Google Inc. All Rights Reserved. +// +// 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 reqtrace contains a very simple request tracing framework. +package reqtrace + +import ( + "flag" + + "golang.org/x/net/context" +) + +type contextKey int + +var fEnabled = flag.Bool("reqtrace.enable", false, "Collect and print traces.") + +// The key used to associate a *traceState with a context. +const traceStateKey contextKey = 0 + +// A function that must be called exactly once to report the outcome of an +// operation represented by a span. +type ReportFunc func(error) + +// Return false only if traces are disabled, i.e. Trace will never cause a +// trace to be initiated. +// +// REQUIRES: flag.Parsed() +func Enabled() (enabled bool) { + enabled = *fEnabled + return +} + +// Begin a span within the current trace. Return a new context that should be +// used for operations that logically occur within the span, and a report +// function that must be called with the outcome of the logical operation +// represented by the span. +// +// If no trace is active, no span will be created but ctx and report will still +// be valid. +func StartSpan( + parent context.Context, + desc string) (ctx context.Context, report ReportFunc) { + // Look for the trace state. + val := parent.Value(traceStateKey) + if val == nil { + // Nothing to do. + ctx = parent + report = func(err error) {} + return + } + + ts := val.(*traceState) + + // Set up the report function. + report = ts.CreateSpan(desc) + + // For now we don't do anything interesting with the context. In the future, + // we may use it to record span hierarchy. + ctx = parent + + return +} + +// A wrapper around StartSpan that can be more convenient to use when the +// lifetime of a span matches the lifetime of a function. Intended to be used +// in a defer statement within a function using a named error return parameter. +// +// Equivalent to calling StartSpan with *ctx, replacing *ctx with the resulting +// new context, then setting f to a function that will invoke the report +// function with the contents of *error at the time that it is called. +// +// Example: +// +// func DoSomething(ctx context.Context) (err error) { +// defer reqtrace.StartSpanWithError(&ctx, &err, "DoSomething")() +// [...] +// } +// +func StartSpanWithError( + ctx *context.Context, + err *error, + desc string) (f func()) { + var report ReportFunc + *ctx, report = StartSpan(*ctx, desc) + f = func() { report(*err) } + return +} + +// Like StartSpan, but begins a root span for a new trace if no trace is active +// in the supplied context and tracing is enabled for the process. +func Trace( + parent context.Context, + desc string) (ctx context.Context, report ReportFunc) { + // If tracing is disabled, this is a no-op. + if !*fEnabled { + ctx = parent + report = func(err error) {} + return + } + + // Is this context already being traced? If so, simply add a span. + if parent.Value(traceStateKey) != nil { + ctx, report = StartSpan(parent, desc) + return + } + + // Set up a new trace state. + ts := new(traceState) + baseReport := ts.CreateSpan(desc) + + // Log when finished. + report = func(err error) { + baseReport(err) + ts.Log() + } + + // Set up the context. + ctx = context.WithValue(parent, traceStateKey, ts) + + return +} diff --git a/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/reqtrace/trace_state.go b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/reqtrace/trace_state.go new file mode 100644 index 00000000000..614ef90d892 --- /dev/null +++ b/src/mongo/gotools/vendor/src/github.com/smartystreets/assertions/internal/reqtrace/trace_state.go @@ -0,0 +1,175 @@ +// Copyright 2015 Google Inc. All Rights Reserved. +// +// 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 reqtrace + +import ( + "log" + "math" + "os" + "strings" + "sync" + "time" +) + +const logFlags = 0 + +var gLogger = log.New(os.Stderr, "reqtrace: ", logFlags) + +type span struct { + // Fixed at creation. + desc string + start time.Time + + // Updated by report functions. + finished bool + end time.Time + err error +} + +// All of the state for a particular trace root. The zero value is usable. +type traceState struct { + mu sync.Mutex + + // The list of spans associated with this state. Append-only. + // + // GUARDED_BY(mu) + spans []*span +} + +func (ts *traceState) report(spanIndex int, err error) { + ts.mu.Lock() + defer ts.mu.Unlock() + + s := ts.spans[spanIndex] + s.finished = true + s.end = time.Now() + s.err = err +} + +// Associate a new span with the trace. Return a function that will report its +// completion. +func (ts *traceState) CreateSpan(desc string) (report ReportFunc) { + ts.mu.Lock() + defer ts.mu.Unlock() + + index := len(ts.spans) + ts.spans = append(ts.spans, &span{desc: desc, start: time.Now()}) + + report = func(err error) { ts.report(index, err) } + return +} + +func round(x float64) float64 { + if x < 0 { + return math.Ceil(x - 0.5) + } + + return math.Floor(x + 0.5) +} + +// Log information about the spans in this trace. +func (ts *traceState) Log() { + ts.mu.Lock() + defer ts.mu.Unlock() + gLogger.Println() + + // Special case: we require at least one span. + if len(ts.spans) == 0 { + return + } + + // Print a banner for this trace. + const bannerHalfLength = 45 + + gLogger.Println() + gLogger.Printf( + "%s %s %s", + strings.Repeat("=", bannerHalfLength), + ts.spans[0].desc, + strings.Repeat("=", bannerHalfLength)) + gLogger.Printf("Start time: %v", ts.spans[0].start.Format(time.RFC3339Nano)) + gLogger.Println() + + // Find the minimum start time and maximum end time of all durations. + var minStart time.Time + var maxEnd time.Time + for _, s := range ts.spans { + if !s.finished { + continue + } + + if minStart.IsZero() || s.start.Before(minStart) { + minStart = s.start + } + + if maxEnd.Before(s.end) { + maxEnd = s.end + } + } + + // Bail out if something weird happened. + // + // TODO(jacobsa): Be more graceful. + totalDuration := maxEnd.Sub(minStart) + if minStart.IsZero() || maxEnd.IsZero() || totalDuration <= 0 { + gLogger.Println("(Weird trace)") + return + } + + // Calculate the number of nanoseconds elapsed, as a floating point number. + totalNs := float64(totalDuration / time.Nanosecond) + + // Log each span with some ASCII art showing its length relative to the + // total. + const totalNumCols float64 = 120 + for _, s := range ts.spans { + if !s.finished { + gLogger.Printf("(Unfinished: %s)", s.desc) + gLogger.Println() + continue + } + + // Calculate the duration of the span, and its width relative to the + // longest span. + d := s.end.Sub(s.start) + if d <= 0 { + gLogger.Println("(Weird duration)") + gLogger.Println() + continue + } + + durationRatio := float64(d/time.Nanosecond) / totalNs + + // We will offset the label and banner proportional to the time since the + // start of the earliest span. + offsetRatio := float64(s.start.Sub(minStart)/time.Nanosecond) / totalNs + offsetChars := int(round(offsetRatio * totalNumCols)) + offsetStr := strings.Repeat(" ", offsetChars) + + // Print the description and duration. + gLogger.Printf("%s%v", offsetStr, s.desc) + gLogger.Printf("%s%v", offsetStr, d) + + // Print a banner showing the duration graphically. + bannerChars := int(round(durationRatio * totalNumCols)) + var dashes string + if bannerChars > 2 { + dashes = strings.Repeat("-", bannerChars-2) + } + + gLogger.Printf("%s|%s|", offsetStr, dashes) + gLogger.Println() + } +} |