浏览代码

Updated packages

Torkel Ödegaard 11 年之前
父节点
当前提交
b2f70c12b9
共有 96 个文件被更改,包括 18514 次插入7 次删除
  1. 5 0
      Godeps/Godeps.json
  2. 0 1
      Godeps/_workspace/src/github.com/go-xorm/core/mapper.go
  3. 5 0
      Godeps/_workspace/src/github.com/jacobsa/oglematchers/.gitignore
  4. 202 0
      Godeps/_workspace/src/github.com/jacobsa/oglematchers/LICENSE
  5. 56 0
      Godeps/_workspace/src/github.com/jacobsa/oglematchers/README.markdown
  6. 70 0
      Godeps/_workspace/src/github.com/jacobsa/oglematchers/all_of.go
  7. 110 0
      Godeps/_workspace/src/github.com/jacobsa/oglematchers/all_of_test.go
  8. 32 0
      Godeps/_workspace/src/github.com/jacobsa/oglematchers/any.go
  9. 93 0
      Godeps/_workspace/src/github.com/jacobsa/oglematchers/any_of.go
  10. 121 0
      Godeps/_workspace/src/github.com/jacobsa/oglematchers/any_of_test.go
  11. 53 0
      Godeps/_workspace/src/github.com/jacobsa/oglematchers/any_test.go
  12. 61 0
      Godeps/_workspace/src/github.com/jacobsa/oglematchers/contains.go
  13. 233 0
      Godeps/_workspace/src/github.com/jacobsa/oglematchers/contains_test.go
  14. 88 0
      Godeps/_workspace/src/github.com/jacobsa/oglematchers/deep_equals.go
  15. 343 0
      Godeps/_workspace/src/github.com/jacobsa/oglematchers/deep_equals_test.go
  16. 91 0
      Godeps/_workspace/src/github.com/jacobsa/oglematchers/elements_are.go
  17. 208 0
      Godeps/_workspace/src/github.com/jacobsa/oglematchers/elements_are_test.go
  18. 557 0
      Godeps/_workspace/src/github.com/jacobsa/oglematchers/equals.go
  19. 3843 0
      Godeps/_workspace/src/github.com/jacobsa/oglematchers/equals_test.go
  20. 51 0
      Godeps/_workspace/src/github.com/jacobsa/oglematchers/error.go
  21. 92 0
      Godeps/_workspace/src/github.com/jacobsa/oglematchers/error_test.go
  22. 39 0
      Godeps/_workspace/src/github.com/jacobsa/oglematchers/greater_or_equal.go
  23. 1059 0
      Godeps/_workspace/src/github.com/jacobsa/oglematchers/greater_or_equal_test.go
  24. 39 0
      Godeps/_workspace/src/github.com/jacobsa/oglematchers/greater_than.go
  25. 1079 0
      Godeps/_workspace/src/github.com/jacobsa/oglematchers/greater_than_test.go
  26. 52 0
      Godeps/_workspace/src/github.com/jacobsa/oglematchers/has_substr.go
  27. 93 0
      Godeps/_workspace/src/github.com/jacobsa/oglematchers/has_substr_test.go
  28. 134 0
      Godeps/_workspace/src/github.com/jacobsa/oglematchers/identical_to.go
  29. 849 0
      Godeps/_workspace/src/github.com/jacobsa/oglematchers/identical_to_test.go
  30. 41 0
      Godeps/_workspace/src/github.com/jacobsa/oglematchers/less_or_equal.go
  31. 1079 0
      Godeps/_workspace/src/github.com/jacobsa/oglematchers/less_or_equal_test.go
  32. 152 0
      Godeps/_workspace/src/github.com/jacobsa/oglematchers/less_than.go
  33. 1059 0
      Godeps/_workspace/src/github.com/jacobsa/oglematchers/less_than_test.go
  34. 82 0
      Godeps/_workspace/src/github.com/jacobsa/oglematchers/matcher.go
  35. 69 0
      Godeps/_workspace/src/github.com/jacobsa/oglematchers/matches_regexp.go
  36. 92 0
      Godeps/_workspace/src/github.com/jacobsa/oglematchers/matches_regexp_test.go
  37. 53 0
      Godeps/_workspace/src/github.com/jacobsa/oglematchers/not.go
  38. 108 0
      Godeps/_workspace/src/github.com/jacobsa/oglematchers/not_test.go
  39. 74 0
      Godeps/_workspace/src/github.com/jacobsa/oglematchers/panics.go
  40. 141 0
      Godeps/_workspace/src/github.com/jacobsa/oglematchers/panics_test.go
  41. 65 0
      Godeps/_workspace/src/github.com/jacobsa/oglematchers/pointee.go
  42. 152 0
      Godeps/_workspace/src/github.com/jacobsa/oglematchers/pointee_test.go
  43. 36 0
      Godeps/_workspace/src/github.com/jacobsa/oglematchers/transform_description.go
  44. 3 3
      Godeps/_workspace/src/github.com/mattn/go-sqlite3/doc.go
  45. 3 3
      Godeps/_workspace/src/github.com/mattn/go-sqlite3/sqlite3_test/sqltest.go
  46. 63 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions.go
  47. 140 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/collections.go
  48. 103 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/collections_test.go
  49. 3 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/doc.go
  50. 281 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/equality.go
  51. 256 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/equality_test.go
  52. 22 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/filter.go
  53. 7 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/init.go
  54. 86 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/messages.go
  55. 115 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/panic.go
  56. 53 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/panic_test.go
  57. 141 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/quantity.go
  58. 145 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/quantity_test.go
  59. 31 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/serializer.go
  60. 28 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/serializer_test.go
  61. 183 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/strings.go
  62. 102 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/strings_test.go
  63. 202 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/time.go
  64. 159 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/time_test.go
  65. 112 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/type.go
  66. 76 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/type_test.go
  67. 75 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/utilities_for_test.go
  68. 179 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/context.go
  69. 57 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/discovery.go
  70. 178 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/doc.go
  71. 72 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/focused_execution_test.go
  72. 37 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/gotest/utils.go
  73. 72 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/init.go
  74. 742 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/isolated_execution_test.go
  75. 74 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/registration.go
  76. 16 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/console.go
  77. 5 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/doc.go
  78. 40 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/dot.go
  79. 40 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/dot_test.go
  80. 33 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/gotest.go
  81. 66 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/gotest_test.go
  82. 94 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/init.go
  83. 88 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/json.go
  84. 57 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/printer.go
  85. 181 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/printer_test.go
  86. 68 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/problems.go
  87. 46 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/problems_test.go
  88. 39 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/reporter.go
  89. 94 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/reporter_test.go
  90. 179 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/reports.go
  91. 79 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/statistics.go
  92. 65 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/story.go
  93. 270 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting_hooks_test.go
  94. 92 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/runner.go
  95. 116 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/scope.go
  96. 185 0
      Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/story_conventions_test.go

+ 5 - 0
Godeps/Godeps.json

@@ -36,6 +36,11 @@
 			"ImportPath": "github.com/mattn/go-sqlite3",
 			"Rev": "d10e2c8f62100097910367dee90a9bd89d426a44"
 		},
+		{
+			"ImportPath": "github.com/smartystreets/goconvey/convey",
+			"Comment": "1.5.0-254-g627707e",
+			"Rev": "627707e8db4a4e52f4e1fbbb4e10d98e79a3c946"
+		},
 		{
 			"ImportPath": "golang.org/x/net/context",
 			"Rev": "3053e46bf4d836639f474dd738a58070463890e9"

+ 0 - 1
Godeps/_workspace/src/github.com/go-xorm/core/mapper.go

@@ -151,7 +151,6 @@ func (mapper SnakeMapper) Table2Obj(name string) string {
 func (mapper SnakeMapper) TableName(t string) string {
 	return t
 }
-
 // provide prefix table name support
 type PrefixMapper struct {
 	Mapper IMapper

+ 5 - 0
Godeps/_workspace/src/github.com/jacobsa/oglematchers/.gitignore

@@ -0,0 +1,5 @@
+*.6
+6.out
+_obj/
+_test/
+_testmain.go

+ 202 - 0
Godeps/_workspace/src/github.com/jacobsa/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.

+ 56 - 0
Godeps/_workspace/src/github.com/jacobsa/oglematchers/README.markdown

@@ -0,0 +1,56 @@
+`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/jacobsa/oglematchers
+
+
+Documentation
+-------------
+
+See [here][reference] for documentation hosted on GoPkgDoc. Alternatively, you
+can install the package and then use `go doc`:
+
+    go doc github.com/jacobsa/oglematchers
+
+
+[reference]: http://gopkgdoc.appspot.com/pkg/github.com/jacobsa/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/jacobsa/ogletest
+[oglemock]: http://github.com/jacobsa/oglemock

+ 70 - 0
Godeps/_workspace/src/github.com/jacobsa/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
+}

+ 110 - 0
Godeps/_workspace/src/github.com/jacobsa/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/jacobsa/oglematchers"
+	. "github.com/jacobsa/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)
+}

+ 32 - 0
Godeps/_workspace/src/github.com/jacobsa/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
+}

+ 93 - 0
Godeps/_workspace/src/github.com/jacobsa/oglematchers/any_of.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
+
+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 {
+		if reflect.TypeOf(v).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
+}

+ 121 - 0
Godeps/_workspace/src/github.com/jacobsa/oglematchers/any_of_test.go

@@ -0,0 +1,121 @@
+// 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/jacobsa/oglematchers"
+	. "github.com/jacobsa/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) 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())
+}

+ 53 - 0
Godeps/_workspace/src/github.com/jacobsa/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/jacobsa/oglematchers"
+	. "github.com/jacobsa/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)
+}

+ 61 - 0
Godeps/_workspace/src/github.com/jacobsa/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("")
+}

+ 233 - 0
Godeps/_workspace/src/github.com/jacobsa/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/jacobsa/oglematchers"
+	. "github.com/jacobsa/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("")))
+}

+ 88 - 0
Godeps/_workspace/src/github.com/jacobsa/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("")
+}

+ 343 - 0
Godeps/_workspace/src/github.com/jacobsa/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/jacobsa/oglematchers"
+	. "github.com/jacobsa/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)
+}

+ 91 - 0
Godeps/_workspace/src/github.com/jacobsa/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
+}

+ 208 - 0
Godeps/_workspace/src/github.com/jacobsa/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/jacobsa/oglematchers"
+	. "github.com/jacobsa/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))
+}

+ 557 - 0
Godeps/_workspace/src/github.com/jacobsa/oglematchers/equals.go

@@ -0,0 +1,557 @@
+// 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.Uint64
+}
+
+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 checkAgainstUintptr(e uintptr, c reflect.Value) (err error) {
+	if c.Kind() != reflect.Uintptr {
+		err = NewFatalError("which is not a uintptr")
+		return
+	}
+
+	err = errors.New("")
+	if uintptr(c.Uint()) == 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.Uintptr:
+		return checkAgainstUintptr(uintptr(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())
+}

+ 3843 - 0
Godeps/_workspace/src/github.com/jacobsa/oglematchers/equals_test.go

@@ -0,0 +1,3843 @@
+// 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/jacobsa/oglematchers"
+	. "github.com/jacobsa/ogletest"
+	"math"
+	"unsafe"
+)
+
+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, ""},
+
+		// 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{uintptr(0), false, true, "which is not numeric"},
+		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{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{uintptr(0), false, true, "which is not numeric"},
+		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, ""},
+
+		// 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{uintptr(0), false, true, "which is not numeric"},
+		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, ""},
+
+		// 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{uintptr(0), false, true, "which is not numeric"},
+		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{complex128(17.1 + 2i), false, false, ""},
+
+		// Non-numeric types.
+		equalsTestCase{uintptr(0), false, true, "which is not numeric"},
+		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, ""},
+
+		// 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{uintptr(0), false, true, "which is not numeric"},
+		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{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{uintptr(0), false, true, "which is not numeric"},
+		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, ""},
+
+		// 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{uintptr((1 << 32) - 17), false, true, "which is not numeric"},
+		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, ""},
+
+		// 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{uintptr(0), false, true, "which is not numeric"},
+		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, ""},
+
+		// 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{uintptr(17), false, true, "which is not numeric"},
+		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, ""},
+
+		// 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{uintptr((1 << 32) - 32766), false, true, "which is not numeric"},
+		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, ""},
+
+		// 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{uintptr(0), false, true, "which is not numeric"},
+		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, ""},
+
+		// 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{uintptr(32765), false, true, "which is not numeric"},
+		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, ""},
+
+		// 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{uintptr(0), false, true, "which is not numeric"},
+		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{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{uintptr(0), false, true, "which is not numeric"},
+		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{uintptr(0), false, true, "which is not numeric"},
+		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{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{uintptr(0), false, true, "which is not numeric"},
+		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{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{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{uintptr(0), false, true, "which is not numeric"},
+		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{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{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{uintptr(0), false, true, "which is not numeric"},
+		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{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{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{uintptr(0), false, true, "which is not numeric"},
+		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{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{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{uintptr(0), false, true, "which is not numeric"},
+		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{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{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{uintptr(0), false, true, "which is not numeric"},
+		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) NilUintptr() {
+	var ptr1 uintptr
+	var ptr2 uintptr
+
+	matcher := Equals(ptr1)
+	ExpectEq("0", matcher.Description())
+
+	cases := []equalsTestCase{
+		// uintptrs
+		equalsTestCase{ptr1, true, false, ""},
+		equalsTestCase{ptr2, true, false, ""},
+		equalsTestCase{uintptr(0), true, false, ""},
+		equalsTestCase{uintptr(17), false, false, ""},
+
+		// Other types.
+		equalsTestCase{0, false, true, "which is not a uintptr"},
+		equalsTestCase{bool(false), false, true, "which is not a uintptr"},
+		equalsTestCase{int(0), false, true, "which is not a uintptr"},
+		equalsTestCase{int8(0), false, true, "which is not a uintptr"},
+		equalsTestCase{int16(0), false, true, "which is not a uintptr"},
+		equalsTestCase{int32(0), false, true, "which is not a uintptr"},
+		equalsTestCase{int64(0), false, true, "which is not a uintptr"},
+		equalsTestCase{uint(0), false, true, "which is not a uintptr"},
+		equalsTestCase{uint8(0), false, true, "which is not a uintptr"},
+		equalsTestCase{uint16(0), false, true, "which is not a uintptr"},
+		equalsTestCase{uint32(0), false, true, "which is not a uintptr"},
+		equalsTestCase{uint64(0), false, true, "which is not a uintptr"},
+		equalsTestCase{true, false, true, "which is not a uintptr"},
+		equalsTestCase{[...]int{}, false, true, "which is not a uintptr"},
+		equalsTestCase{make(chan int), false, true, "which is not a uintptr"},
+		equalsTestCase{func() {}, false, true, "which is not a uintptr"},
+		equalsTestCase{map[int]int{}, false, true, "which is not a uintptr"},
+		equalsTestCase{&someInt, false, true, "which is not a uintptr"},
+		equalsTestCase{[]int{}, false, true, "which is not a uintptr"},
+		equalsTestCase{"taco", false, true, "which is not a uintptr"},
+		equalsTestCase{equalsTestCase{}, false, true, "which is not a uintptr"},
+	}
+
+	t.checkTestCases(matcher, cases)
+}
+
+func (t *EqualsTest) NonNilUintptr() {
+	matcher := Equals(uintptr(17))
+	ExpectEq("17", matcher.Description())
+
+	cases := []equalsTestCase{
+		// uintptrs
+		equalsTestCase{uintptr(17), true, false, ""},
+		equalsTestCase{uintptr(16), false, false, ""},
+		equalsTestCase{uintptr(0), false, false, ""},
+
+		// Other types.
+		equalsTestCase{0, false, true, "which is not a uintptr"},
+		equalsTestCase{bool(false), false, true, "which is not a uintptr"},
+		equalsTestCase{int(0), false, true, "which is not a uintptr"},
+		equalsTestCase{int8(0), false, true, "which is not a uintptr"},
+		equalsTestCase{int16(0), false, true, "which is not a uintptr"},
+		equalsTestCase{int32(0), false, true, "which is not a uintptr"},
+		equalsTestCase{int64(0), false, true, "which is not a uintptr"},
+		equalsTestCase{uint(0), false, true, "which is not a uintptr"},
+		equalsTestCase{uint8(0), false, true, "which is not a uintptr"},
+		equalsTestCase{uint16(0), false, true, "which is not a uintptr"},
+		equalsTestCase{uint32(0), false, true, "which is not a uintptr"},
+		equalsTestCase{uint64(0), false, true, "which is not a uintptr"},
+		equalsTestCase{true, false, true, "which is not a uintptr"},
+		equalsTestCase{[...]int{}, false, true, "which is not a uintptr"},
+		equalsTestCase{make(chan int), false, true, "which is not a uintptr"},
+		equalsTestCase{func() {}, false, true, "which is not a uintptr"},
+		equalsTestCase{map[int]int{}, false, true, "which is not a uintptr"},
+		equalsTestCase{&someInt, false, true, "which is not a uintptr"},
+		equalsTestCase{[]int{}, false, true, "which is not a uintptr"},
+		equalsTestCase{"taco", false, true, "which is not a uintptr"},
+		equalsTestCase{equalsTestCase{}, false, true, "which is not a uintptr"},
+	}
+
+	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, ""},
+
+		// 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{uintptr(0), false, true, "which is not numeric"},
+		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{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{uintptr(0), false, true, "which is not numeric"},
+		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{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{uintptr(0), false, true, "which is not numeric"},
+		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{uintptr(0), false, true, "which is not numeric"},
+		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{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{uintptr(0), false, true, "which is not numeric"},
+		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{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{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{uintptr(0), false, true, "which is not numeric"},
+		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, ""},
+
+		// 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{uintptr(0), false, true, "which is not numeric"},
+		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{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{uintptr(0), false, true, "which is not numeric"},
+		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{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{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{uintptr(0), false, true, "which is not numeric"},
+		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, ""},
+
+		// 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{uintptr(0), false, true, "which is not numeric"},
+		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{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{uintptr(0), false, true, "which is not numeric"},
+		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{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{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{uintptr(0), false, true, "which is not numeric"},
+		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{uintptr(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{uintptr(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)
+}

+ 51 - 0
Godeps/_workspace/src/github.com/jacobsa/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())
+}

+ 92 - 0
Godeps/_workspace/src/github.com/jacobsa/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/jacobsa/oglematchers"
+	. "github.com/jacobsa/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))
+}

+ 39 - 0
Godeps/_workspace/src/github.com/jacobsa/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)
+}

+ 1059 - 0
Godeps/_workspace/src/github.com/jacobsa/oglematchers/greater_or_equal_test.go

@@ -0,0 +1,1059 @@
+// 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/jacobsa/oglematchers"
+	. "github.com/jacobsa/ogletest"
+	"math"
+)
+
+////////////////////////////////////////////////////////////////////////
+// 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{uintptr(17), 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{uintptr(17), 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{uintptr(17), 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, ""},
+
+		// 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, ""},
+
+		// 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, ""},
+
+		// 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, ""},
+
+		// 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, ""},
+
+		// 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, ""},
+
+		// 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, ""},
+
+		// 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, ""},
+
+		// 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, ""},
+
+		// 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)
+}

+ 39 - 0
Godeps/_workspace/src/github.com/jacobsa/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)
+}

+ 1079 - 0
Godeps/_workspace/src/github.com/jacobsa/oglematchers/greater_than_test.go

@@ -0,0 +1,1079 @@
+// 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/jacobsa/oglematchers"
+	. "github.com/jacobsa/ogletest"
+	"math"
+)
+
+////////////////////////////////////////////////////////////////////////
+// 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{uintptr(17), 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{&gtTestCase{}, 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{uintptr(17), 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{&gtTestCase{}, 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{uintptr(17), 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{&gtTestCase{}, 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)
+}

+ 52 - 0
Godeps/_workspace/src/github.com/jacobsa/oglematchers/has_substr.go

@@ -0,0 +1,52 @@
+// 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 &hasSubstrMatcher{s}
+}
+
+type hasSubstrMatcher struct {
+	needle string
+}
+
+func (m *hasSubstrMatcher) Description() string {
+	return fmt.Sprintf("has substring \"%s\"", m.needle)
+}
+
+func (m *hasSubstrMatcher) Matches(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, m.needle) {
+		return nil
+	}
+
+	return errors.New("")
+}

+ 93 - 0
Godeps/_workspace/src/github.com/jacobsa/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/jacobsa/oglematchers"
+	. "github.com/jacobsa/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))
+}

+ 134 - 0
Godeps/_workspace/src/github.com/jacobsa/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("")
+}

+ 849 - 0
Godeps/_workspace/src/github.com/jacobsa/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/jacobsa/oglematchers"
+	. "github.com/jacobsa/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")))
+}

+ 41 - 0
Godeps/_workspace/src/github.com/jacobsa/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)
+}

+ 1079 - 0
Godeps/_workspace/src/github.com/jacobsa/oglematchers/less_or_equal_test.go

@@ -0,0 +1,1079 @@
+// 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/jacobsa/oglematchers"
+	. "github.com/jacobsa/ogletest"
+	"math"
+)
+
+////////////////////////////////////////////////////////////////////////
+// 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{uintptr(17), 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{uintptr(17), 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{uintptr(17), 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)
+}

+ 152 - 0
Godeps/_workspace/src/github.com/jacobsa/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))
+}

+ 1059 - 0
Godeps/_workspace/src/github.com/jacobsa/oglematchers/less_than_test.go

@@ -0,0 +1,1059 @@
+// 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/jacobsa/oglematchers"
+	. "github.com/jacobsa/ogletest"
+	"math"
+)
+
+////////////////////////////////////////////////////////////////////////
+// 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{uintptr(17), 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{&ltTestCase{}, 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{uintptr(17), 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{&ltTestCase{}, 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{uintptr(17), 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{&ltTestCase{}, 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)
+}

+ 82 - 0
Godeps/_workspace/src/github.com/jacobsa/oglematchers/matcher.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 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/jacobsa/ogletest and
+// github.com/jacobsa/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".
+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
+}

+ 69 - 0
Godeps/_workspace/src/github.com/jacobsa/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 supplide 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
+}

+ 92 - 0
Godeps/_workspace/src/github.com/jacobsa/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/jacobsa/oglematchers"
+	. "github.com/jacobsa/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)
+}

+ 53 - 0
Godeps/_workspace/src/github.com/jacobsa/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 &notMatcher{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())
+}

+ 108 - 0
Godeps/_workspace/src/github.com/jacobsa/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/jacobsa/oglematchers"
+	. "github.com/jacobsa/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())
+}

+ 74 - 0
Godeps/_workspace/src/github.com/jacobsa/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
+}

+ 141 - 0
Godeps/_workspace/src/github.com/jacobsa/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/jacobsa/oglematchers"
+	. "github.com/jacobsa/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))
+}

+ 65 - 0
Godeps/_workspace/src/github.com/jacobsa/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())
+}

+ 152 - 0
Godeps/_workspace/src/github.com/jacobsa/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/jacobsa/oglematchers"
+	. "github.com/jacobsa/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")))
+}

+ 36 - 0
Godeps/_workspace/src/github.com/jacobsa/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)
+}

+ 3 - 3
Godeps/_workspace/src/github.com/mattn/go-sqlite3/doc.go

@@ -33,7 +33,7 @@ extension for Regexp matcher operation.
     #include <string.h>
     #include <stdio.h>
     #include <sqlite3ext.h>
-
+    
     SQLITE_EXTENSION_INIT1
     static void regexp_func(sqlite3_context *context, int argc, sqlite3_value **argv) {
       if (argc >= 2) {
@@ -44,7 +44,7 @@ extension for Regexp matcher operation.
         int vec[500];
         int n, rc;
         pcre* re = pcre_compile(pattern, 0, &errstr, &erroff, NULL);
-        rc = pcre_exec(re, NULL, target, strlen(target), 0, 0, vec, 500);
+        rc = pcre_exec(re, NULL, target, strlen(target), 0, 0, vec, 500); 
         if (rc <= 0) {
           sqlite3_result_error(context, errstr, 0);
           return;
@@ -52,7 +52,7 @@ extension for Regexp matcher operation.
         sqlite3_result_int(context, 1);
       }
     }
-
+    
     #ifdef _WIN32
     __declspec(dllexport)
     #endif

+ 3 - 3
Godeps/_workspace/src/github.com/mattn/go-sqlite3/sqlite3_test/sqltest.go

@@ -318,7 +318,7 @@ func BenchmarkQuery(b *testing.B) {
 		var i int
 		var f float64
 		var s string
-		//		var t time.Time
+//		var t time.Time
 		if err := db.QueryRow("select null, 1, 1.1, 'foo'").Scan(&n, &i, &f, &s); err != nil {
 			panic(err)
 		}
@@ -331,7 +331,7 @@ func BenchmarkParams(b *testing.B) {
 		var i int
 		var f float64
 		var s string
-		//		var t time.Time
+//		var t time.Time
 		if err := db.QueryRow("select ?, ?, ?, ?", nil, 1, 1.1, "foo").Scan(&n, &i, &f, &s); err != nil {
 			panic(err)
 		}
@@ -350,7 +350,7 @@ func BenchmarkStmt(b *testing.B) {
 		var i int
 		var f float64
 		var s string
-		//		var t time.Time
+//		var t time.Time
 		if err := st.QueryRow(nil, 1, 1.1, "foo").Scan(&n, &i, &f, &s); err != nil {
 			panic(err)
 		}

+ 63 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions.go

@@ -0,0 +1,63 @@
+package convey
+
+import "github.com/smartystreets/goconvey/convey/assertions"
+
+var (
+	ShouldEqual          = assertions.ShouldEqual
+	ShouldNotEqual       = assertions.ShouldNotEqual
+	ShouldAlmostEqual    = assertions.ShouldAlmostEqual
+	ShouldNotAlmostEqual = assertions.ShouldNotAlmostEqual
+	ShouldResemble       = assertions.ShouldResemble
+	ShouldNotResemble    = assertions.ShouldNotResemble
+	ShouldPointTo        = assertions.ShouldPointTo
+	ShouldNotPointTo     = assertions.ShouldNotPointTo
+	ShouldBeNil          = assertions.ShouldBeNil
+	ShouldNotBeNil       = assertions.ShouldNotBeNil
+	ShouldBeTrue         = assertions.ShouldBeTrue
+	ShouldBeFalse        = assertions.ShouldBeFalse
+	ShouldBeZeroValue    = assertions.ShouldBeZeroValue
+
+	ShouldBeGreaterThan          = assertions.ShouldBeGreaterThan
+	ShouldBeGreaterThanOrEqualTo = assertions.ShouldBeGreaterThanOrEqualTo
+	ShouldBeLessThan             = assertions.ShouldBeLessThan
+	ShouldBeLessThanOrEqualTo    = assertions.ShouldBeLessThanOrEqualTo
+	ShouldBeBetween              = assertions.ShouldBeBetween
+	ShouldNotBeBetween           = assertions.ShouldNotBeBetween
+
+	ShouldContain    = assertions.ShouldContain
+	ShouldNotContain = assertions.ShouldNotContain
+	ShouldBeIn       = assertions.ShouldBeIn
+	ShouldNotBeIn    = assertions.ShouldNotBeIn
+	ShouldBeEmpty    = assertions.ShouldBeEmpty
+	ShouldNotBeEmpty = assertions.ShouldNotBeEmpty
+
+	ShouldStartWith           = assertions.ShouldStartWith
+	ShouldNotStartWith        = assertions.ShouldNotStartWith
+	ShouldEndWith             = assertions.ShouldEndWith
+	ShouldNotEndWith          = assertions.ShouldNotEndWith
+	ShouldBeBlank             = assertions.ShouldBeBlank
+	ShouldNotBeBlank          = assertions.ShouldNotBeBlank
+	ShouldContainSubstring    = assertions.ShouldContainSubstring
+	ShouldNotContainSubstring = assertions.ShouldNotContainSubstring
+
+	ShouldPanic        = assertions.ShouldPanic
+	ShouldNotPanic     = assertions.ShouldNotPanic
+	ShouldPanicWith    = assertions.ShouldPanicWith
+	ShouldNotPanicWith = assertions.ShouldNotPanicWith
+
+	ShouldHaveSameTypeAs    = assertions.ShouldHaveSameTypeAs
+	ShouldNotHaveSameTypeAs = assertions.ShouldNotHaveSameTypeAs
+	ShouldImplement         = assertions.ShouldImplement
+	ShouldNotImplement      = assertions.ShouldNotImplement
+
+	ShouldHappenBefore         = assertions.ShouldHappenBefore
+	ShouldHappenOnOrBefore     = assertions.ShouldHappenOnOrBefore
+	ShouldHappenAfter          = assertions.ShouldHappenAfter
+	ShouldHappenOnOrAfter      = assertions.ShouldHappenOnOrAfter
+	ShouldHappenBetween        = assertions.ShouldHappenBetween
+	ShouldHappenOnOrBetween    = assertions.ShouldHappenOnOrBetween
+	ShouldNotHappenOnOrBetween = assertions.ShouldNotHappenOnOrBetween
+	ShouldHappenWithin         = assertions.ShouldHappenWithin
+	ShouldNotHappenWithin      = assertions.ShouldNotHappenWithin
+	ShouldBeChronological      = assertions.ShouldBeChronological
+)

+ 140 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/collections.go

@@ -0,0 +1,140 @@
+package assertions
+
+import (
+	"fmt"
+	"reflect"
+
+	"github.com/jacobsa/oglematchers"
+)
+
+// ShouldContain receives exactly two parameters. The first is a slice and the
+// second is a proposed member. Membership is determined using ShouldEqual.
+func ShouldContain(actual interface{}, expected ...interface{}) string {
+	if fail := need(1, expected); fail != success {
+		return fail
+	}
+
+	if matchError := oglematchers.Contains(expected[0]).Matches(actual); matchError != nil {
+		typeName := reflect.TypeOf(actual)
+
+		if fmt.Sprintf("%v", matchError) == "which is not a slice or array" {
+			return fmt.Sprintf(shouldHaveBeenAValidCollection, typeName)
+		}
+		return fmt.Sprintf(shouldHaveContained, typeName, expected[0])
+	}
+	return success
+}
+
+// ShouldNotContain receives exactly two parameters. The first is a slice and the
+// second is a proposed member. Membership is determinied using ShouldEqual.
+func ShouldNotContain(actual interface{}, expected ...interface{}) string {
+	if fail := need(1, expected); fail != success {
+		return fail
+	}
+	typeName := reflect.TypeOf(actual)
+
+	if matchError := oglematchers.Contains(expected[0]).Matches(actual); matchError != nil {
+		if fmt.Sprintf("%v", matchError) == "which is not a slice or array" {
+			return fmt.Sprintf(shouldHaveBeenAValidCollection, typeName)
+		}
+		return success
+	}
+	return fmt.Sprintf(shouldNotHaveContained, typeName, expected[0])
+}
+
+// ShouldBeIn receives at least 2 parameters. The first is a proposed member of the collection
+// that is passed in either as the second parameter, or of the collection that is comprised
+// of all the remaining parameters. This assertion ensures that the proposed member is in
+// the collection (using ShouldEqual).
+func ShouldBeIn(actual interface{}, expected ...interface{}) string {
+	if fail := atLeast(1, expected); fail != success {
+		return fail
+	}
+
+	if len(expected) == 1 {
+		return shouldBeIn(actual, expected[0])
+	}
+	return shouldBeIn(actual, expected)
+}
+func shouldBeIn(actual interface{}, expected interface{}) string {
+	if matchError := oglematchers.Contains(actual).Matches(expected); matchError != nil {
+		return fmt.Sprintf(shouldHaveBeenIn, actual, reflect.TypeOf(expected))
+	}
+	return success
+}
+
+// ShouldNotBeIn receives at least 2 parameters. The first is a proposed member of the collection
+// that is passed in either as the second parameter, or of the collection that is comprised
+// of all the remaining parameters. This assertion ensures that the proposed member is NOT in
+// the collection (using ShouldEqual).
+func ShouldNotBeIn(actual interface{}, expected ...interface{}) string {
+	if fail := atLeast(1, expected); fail != success {
+		return fail
+	}
+
+	if len(expected) == 1 {
+		return shouldNotBeIn(actual, expected[0])
+	}
+	return shouldNotBeIn(actual, expected)
+}
+func shouldNotBeIn(actual interface{}, expected interface{}) string {
+	if matchError := oglematchers.Contains(actual).Matches(expected); matchError == nil {
+		return fmt.Sprintf(shouldNotHaveBeenIn, actual, reflect.TypeOf(expected))
+	}
+	return success
+}
+
+// ShouldBeEmpty receives a single parameter (actual) and determines whether or not
+// calling len(actual) would return `0`. It obeys the rules specified by the len
+// function for determining length: http://golang.org/pkg/builtin/#len
+func ShouldBeEmpty(actual interface{}, expected ...interface{}) string {
+	if fail := need(0, expected); fail != success {
+		return fail
+	}
+
+	if actual == nil {
+		return success
+	}
+
+	value := reflect.ValueOf(actual)
+	switch value.Kind() {
+	case reflect.Slice:
+		if value.Len() == 0 {
+			return success
+		}
+	case reflect.Chan:
+		if value.Len() == 0 {
+			return success
+		}
+	case reflect.Map:
+		if value.Len() == 0 {
+			return success
+		}
+	case reflect.String:
+		if value.Len() == 0 {
+			return success
+		}
+	case reflect.Ptr:
+		elem := value.Elem()
+		kind := elem.Kind()
+		if (kind == reflect.Slice || kind == reflect.Array) && elem.Len() == 0 {
+			return success
+		}
+	}
+
+	return fmt.Sprintf(shouldHaveBeenEmpty, actual)
+}
+
+// ShouldNotBeEmpty receives a single parameter (actual) and determines whether or not
+// calling len(actual) would return a value greater than zero. It obeys the rules
+// specified by the `len` function for determining length: http://golang.org/pkg/builtin/#len
+func ShouldNotBeEmpty(actual interface{}, expected ...interface{}) string {
+	if fail := need(0, expected); fail != success {
+		return fail
+	}
+
+	if empty := ShouldBeEmpty(actual, expected...); empty != success {
+		return success
+	}
+	return fmt.Sprintf(shouldNotHaveBeenEmpty, actual)
+}

+ 103 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/collections_test.go

@@ -0,0 +1,103 @@
+package assertions
+
+import (
+	"fmt"
+	"testing"
+	"time"
+)
+
+func TestShouldContain(t *testing.T) {
+	fail(t, so([]int{}, ShouldContain), "This assertion requires exactly 1 comparison values (you provided 0).")
+	fail(t, so([]int{}, ShouldContain, 1, 2, 3), "This assertion requires exactly 1 comparison values (you provided 3).")
+
+	fail(t, so(Thing1{}, ShouldContain, 1), "You must provide a valid container (was assertions.Thing1)!")
+	fail(t, so(nil, ShouldContain, 1), "You must provide a valid container (was <nil>)!")
+	fail(t, so([]int{1}, ShouldContain, 2), "Expected the container ([]int) to contain: '2' (but it didn't)!")
+
+	pass(t, so([]int{1}, ShouldContain, 1))
+	pass(t, so([]int{1, 2, 3}, ShouldContain, 2))
+}
+
+func TestShouldNotContain(t *testing.T) {
+	fail(t, so([]int{}, ShouldNotContain), "This assertion requires exactly 1 comparison values (you provided 0).")
+	fail(t, so([]int{}, ShouldNotContain, 1, 2, 3), "This assertion requires exactly 1 comparison values (you provided 3).")
+
+	fail(t, so(Thing1{}, ShouldNotContain, 1), "You must provide a valid container (was assertions.Thing1)!")
+	fail(t, so(nil, ShouldNotContain, 1), "You must provide a valid container (was <nil>)!")
+
+	fail(t, so([]int{1}, ShouldNotContain, 1), "Expected the container ([]int) NOT to contain: '1' (but it did)!")
+	fail(t, so([]int{1, 2, 3}, ShouldNotContain, 2), "Expected the container ([]int) NOT to contain: '2' (but it did)!")
+
+	pass(t, so([]int{1}, ShouldNotContain, 2))
+}
+
+func TestShouldBeIn(t *testing.T) {
+	fail(t, so(4, ShouldBeIn), shouldHaveProvidedCollectionMembers)
+
+	container := []int{1, 2, 3, 4}
+	pass(t, so(4, ShouldBeIn, container))
+	pass(t, so(4, ShouldBeIn, 1, 2, 3, 4))
+
+	fail(t, so(4, ShouldBeIn, 1, 2, 3), "Expected '4' to be in the container ([]interface {}, but it wasn't)!")
+	fail(t, so(4, ShouldBeIn, []int{1, 2, 3}), "Expected '4' to be in the container ([]int, but it wasn't)!")
+}
+
+func TestShouldNotBeIn(t *testing.T) {
+	fail(t, so(4, ShouldNotBeIn), shouldHaveProvidedCollectionMembers)
+
+	container := []int{1, 2, 3, 4}
+	pass(t, so(42, ShouldNotBeIn, container))
+	pass(t, so(42, ShouldNotBeIn, 1, 2, 3, 4))
+
+	fail(t, so(2, ShouldNotBeIn, 1, 2, 3), "Expected '2' NOT to be in the container ([]interface {}, but it was)!")
+	fail(t, so(2, ShouldNotBeIn, []int{1, 2, 3}), "Expected '2' NOT to be in the container ([]int, but it was)!")
+}
+
+func TestShouldBeEmpty(t *testing.T) {
+	fail(t, so(1, ShouldBeEmpty, 2, 3), "This assertion requires exactly 0 comparison values (you provided 2).")
+
+	pass(t, so([]int{}, ShouldBeEmpty))           // empty slice
+	pass(t, so([]interface{}{}, ShouldBeEmpty))   // empty slice
+	pass(t, so(map[string]int{}, ShouldBeEmpty))  // empty map
+	pass(t, so("", ShouldBeEmpty))                // empty string
+	pass(t, so(&[]int{}, ShouldBeEmpty))          // pointer to empty slice
+	pass(t, so(&[0]int{}, ShouldBeEmpty))         // pointer to empty array
+	pass(t, so(nil, ShouldBeEmpty))               // nil
+	pass(t, so(make(chan string), ShouldBeEmpty)) // empty channel
+
+	fail(t, so([]int{1}, ShouldBeEmpty), "Expected [1] to be empty (but it wasn't)!")                      // non-empty slice
+	fail(t, so([]interface{}{1}, ShouldBeEmpty), "Expected [1] to be empty (but it wasn't)!")              // non-empty slice
+	fail(t, so(map[string]int{"hi": 0}, ShouldBeEmpty), "Expected map[hi:0] to be empty (but it wasn't)!") // non-empty map
+	fail(t, so("hi", ShouldBeEmpty), "Expected hi to be empty (but it wasn't)!")                           // non-empty string
+	fail(t, so(&[]int{1}, ShouldBeEmpty), "Expected &[1] to be empty (but it wasn't)!")                    // pointer to non-empty slice
+	fail(t, so(&[1]int{1}, ShouldBeEmpty), "Expected &[1] to be empty (but it wasn't)!")                   // pointer to non-empty array
+	c := make(chan int, 1)                                                                                 // non-empty channel
+	go func() { c <- 1 }()
+	time.Sleep(time.Millisecond)
+	fail(t, so(c, ShouldBeEmpty), fmt.Sprintf("Expected %+v to be empty (but it wasn't)!", c))
+}
+
+func TestShouldNotBeEmpty(t *testing.T) {
+	fail(t, so(1, ShouldNotBeEmpty, 2, 3), "This assertion requires exactly 0 comparison values (you provided 2).")
+
+	fail(t, so([]int{}, ShouldNotBeEmpty), "Expected [] to NOT be empty (but it was)!")             // empty slice
+	fail(t, so([]interface{}{}, ShouldNotBeEmpty), "Expected [] to NOT be empty (but it was)!")     // empty slice
+	fail(t, so(map[string]int{}, ShouldNotBeEmpty), "Expected map[] to NOT be empty (but it was)!") // empty map
+	fail(t, so("", ShouldNotBeEmpty), "Expected  to NOT be empty (but it was)!")                    // empty string
+	fail(t, so(&[]int{}, ShouldNotBeEmpty), "Expected &[] to NOT be empty (but it was)!")           // pointer to empty slice
+	fail(t, so(&[0]int{}, ShouldNotBeEmpty), "Expected &[] to NOT be empty (but it was)!")          // pointer to empty array
+	fail(t, so(nil, ShouldNotBeEmpty), "Expected <nil> to NOT be empty (but it was)!")              // nil
+	c := make(chan int, 0)                                                                          // non-empty channel
+	fail(t, so(c, ShouldNotBeEmpty), fmt.Sprintf("Expected %+v to NOT be empty (but it was)!", c))  // empty channel
+
+	pass(t, so([]int{1}, ShouldNotBeEmpty))                // non-empty slice
+	pass(t, so([]interface{}{1}, ShouldNotBeEmpty))        // non-empty slice
+	pass(t, so(map[string]int{"hi": 0}, ShouldNotBeEmpty)) // non-empty map
+	pass(t, so("hi", ShouldNotBeEmpty))                    // non-empty string
+	pass(t, so(&[]int{1}, ShouldNotBeEmpty))               // pointer to non-empty slice
+	pass(t, so(&[1]int{1}, ShouldNotBeEmpty))              // pointer to non-empty array
+	c = make(chan int, 1)
+	go func() { c <- 1 }()
+	time.Sleep(time.Millisecond)
+	pass(t, so(c, ShouldNotBeEmpty))
+}

+ 3 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/doc.go

@@ -0,0 +1,3 @@
+// Package assertions contains the implementations for all assertions which
+// are referenced in the convey package for use with the So(...) method.
+package assertions

+ 281 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/equality.go

@@ -0,0 +1,281 @@
+package assertions
+
+import (
+	"errors"
+	"fmt"
+	"math"
+	"reflect"
+	"strings"
+
+	"github.com/jacobsa/oglematchers"
+)
+
+// default acceptable delta for ShouldAlmostEqual
+const defaultDelta = 0.0000000001
+
+// ShouldEqual receives exactly two parameters and does an equality check.
+func ShouldEqual(actual interface{}, expected ...interface{}) string {
+	if message := need(1, expected); message != success {
+		return message
+	}
+	return shouldEqual(actual, expected[0])
+}
+func shouldEqual(actual, expected interface{}) (message string) {
+	defer func() {
+		if r := recover(); r != nil {
+			message = serializer.serialize(expected, actual, fmt.Sprintf(shouldHaveBeenEqual, expected, actual))
+			return
+		}
+	}()
+
+	if matchError := oglematchers.Equals(expected).Matches(actual); matchError != nil {
+		message = serializer.serialize(expected, actual, fmt.Sprintf(shouldHaveBeenEqual, expected, actual))
+		return
+	}
+
+	return success
+}
+
+// ShouldNotEqual receives exactly two parameters and does an inequality check.
+func ShouldNotEqual(actual interface{}, expected ...interface{}) string {
+	if fail := need(1, expected); fail != success {
+		return fail
+	} else if ShouldEqual(actual, expected[0]) == success {
+		return fmt.Sprintf(shouldNotHaveBeenEqual, actual, expected[0])
+	}
+	return success
+}
+
+// ShouldAlmostEqual makes sure that two parameters are close enough to being equal.
+// The acceptable delta may be specified with a third argument,
+// or a very small default delta will be used.
+func ShouldAlmostEqual(actual interface{}, expected ...interface{}) string {
+	actualFloat, expectedFloat, deltaFloat, err := cleanAlmostEqualInput(actual, expected...)
+
+	if err != "" {
+		return err
+	}
+
+	if math.Abs(actualFloat-expectedFloat) <= deltaFloat {
+		return success
+	} else {
+		return fmt.Sprintf(shouldHaveBeenAlmostEqual, actualFloat, expectedFloat)
+	}
+}
+
+// ShouldNotAlmostEqual is the inverse of ShouldAlmostEqual
+func ShouldNotAlmostEqual(actual interface{}, expected ...interface{}) string {
+	actualFloat, expectedFloat, deltaFloat, err := cleanAlmostEqualInput(actual, expected...)
+
+	if err != "" {
+		return err
+	}
+
+	if math.Abs(actualFloat-expectedFloat) > deltaFloat {
+		return success
+	} else {
+		return fmt.Sprintf(shouldHaveNotBeenAlmostEqual, actualFloat, expectedFloat)
+	}
+}
+
+func cleanAlmostEqualInput(actual interface{}, expected ...interface{}) (float64, float64, float64, string) {
+	deltaFloat := 0.0000000001
+
+	if len(expected) == 0 {
+		return 0.0, 0.0, 0.0, "This assertion requires exactly one comparison value and an optional delta (you provided neither)"
+	} else if len(expected) == 2 {
+		delta, err := getFloat(expected[1])
+
+		if err != nil {
+			return 0.0, 0.0, 0.0, "delta must be a numerical type"
+		}
+
+		deltaFloat = delta
+	} else if len(expected) > 2 {
+		return 0.0, 0.0, 0.0, "This assertion requires exactly one comparison value and an optional delta (you provided more values)"
+	}
+
+	actualFloat, err := getFloat(actual)
+
+	if err != nil {
+		return 0.0, 0.0, 0.0, err.Error()
+	}
+
+	expectedFloat, err := getFloat(expected[0])
+
+	if err != nil {
+		return 0.0, 0.0, 0.0, err.Error()
+	}
+
+	return actualFloat, expectedFloat, deltaFloat, ""
+}
+
+// returns the float value of any real number, or error if it is not a numerical type
+func getFloat(num interface{}) (float64, error) {
+	numValue := reflect.ValueOf(num)
+	numKind := numValue.Kind()
+
+	if numKind == reflect.Int ||
+		numKind == reflect.Int8 ||
+		numKind == reflect.Int16 ||
+		numKind == reflect.Int32 ||
+		numKind == reflect.Int64 {
+		return float64(numValue.Int()), nil
+	} else if numKind == reflect.Uint ||
+		numKind == reflect.Uint8 ||
+		numKind == reflect.Uint16 ||
+		numKind == reflect.Uint32 ||
+		numKind == reflect.Uint64 {
+		return float64(numValue.Uint()), nil
+	} else if numKind == reflect.Float32 ||
+		numKind == reflect.Float64 {
+		return numValue.Float(), nil
+	} else {
+		return 0.0, errors.New("must be a numerical type, but was " + numKind.String())
+	}
+}
+
+// ShouldResemble receives exactly two parameters and does a deep equal check (see reflect.DeepEqual)
+func ShouldResemble(actual interface{}, expected ...interface{}) string {
+	if message := need(1, expected); message != success {
+		return message
+	}
+
+	if matchError := oglematchers.DeepEquals(expected[0]).Matches(actual); matchError != nil {
+		message := fmt.Sprintf(
+			shouldHaveResembled,
+			expected[0], expected[0],
+			actual, actual,
+		)
+		return serializer.serialize(
+			expected[0], actual, message)
+	}
+
+	return success
+}
+
+// ShouldNotResemble receives exactly two parameters and does an inverse deep equal check (see reflect.DeepEqual)
+func ShouldNotResemble(actual interface{}, expected ...interface{}) string {
+	if message := need(1, expected); message != success {
+		return message
+	} else if ShouldResemble(actual, expected[0]) == success {
+		return fmt.Sprintf(
+			shouldNotHaveResembled,
+			actual, actual,
+			expected[0], expected[0],
+		)
+	}
+	return success
+}
+
+// ShouldPointTo receives exactly two parameters and checks to see that they point to the same address.
+func ShouldPointTo(actual interface{}, expected ...interface{}) string {
+	if message := need(1, expected); message != success {
+		return message
+	}
+	return shouldPointTo(actual, expected[0])
+
+}
+func shouldPointTo(actual, expected interface{}) string {
+	actualValue := reflect.ValueOf(actual)
+	expectedValue := reflect.ValueOf(expected)
+
+	if ShouldNotBeNil(actual) != success {
+		return fmt.Sprintf(shouldHaveBeenNonNilPointer, "first", "nil")
+	} else if ShouldNotBeNil(expected) != success {
+		return fmt.Sprintf(shouldHaveBeenNonNilPointer, "second", "nil")
+	} else if actualValue.Kind() != reflect.Ptr {
+		return fmt.Sprintf(shouldHaveBeenNonNilPointer, "first", "not")
+	} else if expectedValue.Kind() != reflect.Ptr {
+		return fmt.Sprintf(shouldHaveBeenNonNilPointer, "second", "not")
+	} else if ShouldEqual(actualValue.Pointer(), expectedValue.Pointer()) != success {
+		actualAddress := reflect.ValueOf(actual).Pointer()
+		expectedAddress := reflect.ValueOf(expected).Pointer()
+		return serializer.serialize(expectedAddress, actualAddress, fmt.Sprintf(shouldHavePointedTo,
+			actual, actualAddress,
+			expected, expectedAddress))
+	}
+	return success
+}
+
+// ShouldNotPointTo receives exactly two parameters and checks to see that they point to different addresess.
+func ShouldNotPointTo(actual interface{}, expected ...interface{}) string {
+	if message := need(1, expected); message != success {
+		return message
+	}
+	compare := ShouldPointTo(actual, expected[0])
+	if strings.HasPrefix(compare, shouldBePointers) {
+		return compare
+	} else if compare == success {
+		return fmt.Sprintf(shouldNotHavePointedTo, actual, expected[0], reflect.ValueOf(actual).Pointer())
+	}
+	return success
+}
+
+// ShouldBeNil receives a single parameter and ensures that it is nil.
+func ShouldBeNil(actual interface{}, expected ...interface{}) string {
+	if fail := need(0, expected); fail != success {
+		return fail
+	} else if actual == nil {
+		return success
+	} else if interfaceHasNilValue(actual) {
+		return success
+	}
+	return fmt.Sprintf(shouldHaveBeenNil, actual)
+}
+func interfaceHasNilValue(actual interface{}) bool {
+	value := reflect.ValueOf(actual)
+	kind := value.Kind()
+	nilable := kind == reflect.Slice ||
+		kind == reflect.Chan ||
+		kind == reflect.Func ||
+		kind == reflect.Ptr ||
+		kind == reflect.Map
+
+	// Careful: reflect.Value.IsNil() will panic unless it's an interface, chan, map, func, slice, or ptr
+	// Reference: http://golang.org/pkg/reflect/#Value.IsNil
+	return nilable && value.IsNil()
+}
+
+// ShouldNotBeNil receives a single parameter and ensures that it is not nil.
+func ShouldNotBeNil(actual interface{}, expected ...interface{}) string {
+	if fail := need(0, expected); fail != success {
+		return fail
+	} else if ShouldBeNil(actual) == success {
+		return fmt.Sprintf(shouldNotHaveBeenNil, actual)
+	}
+	return success
+}
+
+// ShouldBeTrue receives a single parameter and ensures that it is true.
+func ShouldBeTrue(actual interface{}, expected ...interface{}) string {
+	if fail := need(0, expected); fail != success {
+		return fail
+	} else if actual != true {
+		return fmt.Sprintf(shouldHaveBeenTrue, actual)
+	}
+	return success
+}
+
+// ShouldBeFalse receives a single parameter and ensures that it is false.
+func ShouldBeFalse(actual interface{}, expected ...interface{}) string {
+	if fail := need(0, expected); fail != success {
+		return fail
+	} else if actual != false {
+		return fmt.Sprintf(shouldHaveBeenFalse, actual)
+	}
+	return success
+}
+
+// ShouldBeZeroValue receives a single parameter and ensures that it is
+// the Go equivalent of the default value, or "zero" value.
+func ShouldBeZeroValue(actual interface{}, expected ...interface{}) string {
+	if fail := need(0, expected); fail != success {
+		return fail
+	}
+	zeroVal := reflect.Zero(reflect.TypeOf(actual)).Interface()
+	if !reflect.DeepEqual(zeroVal, actual) {
+		return serializer.serialize(zeroVal, actual, fmt.Sprintf(shouldHaveBeenZeroValue, actual))
+	}
+	return success
+}

+ 256 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/equality_test.go

@@ -0,0 +1,256 @@
+package assertions
+
+import (
+	"fmt"
+	"reflect"
+	"testing"
+)
+
+func TestShouldEqual(t *testing.T) {
+	serializer = newFakeSerializer()
+
+	fail(t, so(1, ShouldEqual), "This assertion requires exactly 1 comparison values (you provided 0).")
+	fail(t, so(1, ShouldEqual, 1, 2), "This assertion requires exactly 1 comparison values (you provided 2).")
+	fail(t, so(1, ShouldEqual, 1, 2, 3), "This assertion requires exactly 1 comparison values (you provided 3).")
+
+	pass(t, so(1, ShouldEqual, 1))
+	fail(t, so(1, ShouldEqual, 2), "2|1|Expected: '2' Actual: '1' (Should be equal)")
+
+	pass(t, so(true, ShouldEqual, true))
+	fail(t, so(true, ShouldEqual, false), "false|true|Expected: 'false' Actual: 'true' (Should be equal)")
+
+	pass(t, so("hi", ShouldEqual, "hi"))
+	fail(t, so("hi", ShouldEqual, "bye"), "bye|hi|Expected: 'bye' Actual: 'hi' (Should be equal)")
+
+	pass(t, so(42, ShouldEqual, uint(42)))
+
+	fail(t, so(Thing1{"hi"}, ShouldEqual, Thing1{}), "{}|{hi}|Expected: '{}' Actual: '{hi}' (Should be equal)")
+	fail(t, so(Thing1{"hi"}, ShouldEqual, Thing1{"hi"}), "{hi}|{hi}|Expected: '{hi}' Actual: '{hi}' (Should be equal)")
+	fail(t, so(&Thing1{"hi"}, ShouldEqual, &Thing1{"hi"}), "&{hi}|&{hi}|Expected: '&{hi}' Actual: '&{hi}' (Should be equal)")
+
+	fail(t, so(Thing1{}, ShouldEqual, Thing2{}), "{}|{}|Expected: '{}' Actual: '{}' (Should be equal)")
+}
+
+func TestShouldNotEqual(t *testing.T) {
+	fail(t, so(1, ShouldNotEqual), "This assertion requires exactly 1 comparison values (you provided 0).")
+	fail(t, so(1, ShouldNotEqual, 1, 2), "This assertion requires exactly 1 comparison values (you provided 2).")
+	fail(t, so(1, ShouldNotEqual, 1, 2, 3), "This assertion requires exactly 1 comparison values (you provided 3).")
+
+	pass(t, so(1, ShouldNotEqual, 2))
+	fail(t, so(1, ShouldNotEqual, 1), "Expected '1' to NOT equal '1' (but it did)!")
+
+	pass(t, so(true, ShouldNotEqual, false))
+	fail(t, so(true, ShouldNotEqual, true), "Expected 'true' to NOT equal 'true' (but it did)!")
+
+	pass(t, so("hi", ShouldNotEqual, "bye"))
+	fail(t, so("hi", ShouldNotEqual, "hi"), "Expected 'hi' to NOT equal 'hi' (but it did)!")
+
+	pass(t, so(&Thing1{"hi"}, ShouldNotEqual, &Thing1{"hi"}))
+	pass(t, so(Thing1{"hi"}, ShouldNotEqual, Thing1{"hi"}))
+	pass(t, so(Thing1{}, ShouldNotEqual, Thing1{}))
+	pass(t, so(Thing1{}, ShouldNotEqual, Thing2{}))
+}
+
+func TestShouldAlmostEqual(t *testing.T) {
+	fail(t, so(1, ShouldAlmostEqual), "This assertion requires exactly one comparison value and an optional delta (you provided neither)")
+	fail(t, so(1, ShouldAlmostEqual, 1, 2, 3), "This assertion requires exactly one comparison value and an optional delta (you provided more values)")
+
+	// with the default delta
+	pass(t, so(1, ShouldAlmostEqual, .99999999999999))
+	pass(t, so(1.3612499999999996, ShouldAlmostEqual, 1.36125))
+	pass(t, so(0.7285312499999999, ShouldAlmostEqual, 0.72853125))
+	fail(t, so(1, ShouldAlmostEqual, .99), "Expected '1' to almost equal '0.99' (but it didn't)!")
+
+	// with a different delta
+	pass(t, so(100.0, ShouldAlmostEqual, 110.0, 10.0))
+	fail(t, so(100.0, ShouldAlmostEqual, 111.0, 10.5), "Expected '100' to almost equal '111' (but it didn't)!")
+
+	// ints should work
+	pass(t, so(100, ShouldAlmostEqual, 100.0))
+	fail(t, so(100, ShouldAlmostEqual, 99.0), "Expected '100' to almost equal '99' (but it didn't)!")
+
+	// float32 should work
+	pass(t, so(float64(100.0), ShouldAlmostEqual, float32(100.0)))
+	fail(t, so(float32(100.0), ShouldAlmostEqual, 99.0, float32(0.1)), "Expected '100' to almost equal '99' (but it didn't)!")
+}
+
+func TestShouldNotAlmostEqual(t *testing.T) {
+	fail(t, so(1, ShouldNotAlmostEqual), "This assertion requires exactly one comparison value and an optional delta (you provided neither)")
+	fail(t, so(1, ShouldNotAlmostEqual, 1, 2, 3), "This assertion requires exactly one comparison value and an optional delta (you provided more values)")
+
+	// with the default delta
+	fail(t, so(1, ShouldNotAlmostEqual, .99999999999999), "Expected '1' to NOT almost equal '0.99999999999999' (but it did)!")
+	fail(t, so(1.3612499999999996, ShouldNotAlmostEqual, 1.36125), "Expected '1.3612499999999996' to NOT almost equal '1.36125' (but it did)!")
+	pass(t, so(1, ShouldNotAlmostEqual, .99))
+
+	// with a different delta
+	fail(t, so(100.0, ShouldNotAlmostEqual, 110.0, 10.0), "Expected '100' to NOT almost equal '110' (but it did)!")
+	pass(t, so(100.0, ShouldNotAlmostEqual, 111.0, 10.5))
+
+	// ints should work
+	fail(t, so(100, ShouldNotAlmostEqual, 100.0), "Expected '100' to NOT almost equal '100' (but it did)!")
+	pass(t, so(100, ShouldNotAlmostEqual, 99.0))
+
+	// float32 should work
+	fail(t, so(float64(100.0), ShouldNotAlmostEqual, float32(100.0)), "Expected '100' to NOT almost equal '100' (but it did)!")
+	pass(t, so(float32(100.0), ShouldNotAlmostEqual, 99.0, float32(0.1)))
+}
+
+func TestShouldResemble(t *testing.T) {
+	serializer = newFakeSerializer()
+
+	fail(t, so(Thing1{"hi"}, ShouldResemble), "This assertion requires exactly 1 comparison values (you provided 0).")
+	fail(t, so(Thing1{"hi"}, ShouldResemble, Thing1{"hi"}, Thing1{"hi"}), "This assertion requires exactly 1 comparison values (you provided 2).")
+
+	pass(t, so(Thing1{"hi"}, ShouldResemble, Thing1{"hi"}))
+	fail(t, so(Thing1{"hi"}, ShouldResemble, Thing1{"bye"}), "{bye}|{hi}|Expected: 'assertions.Thing1({a:bye})' Actual: 'assertions.Thing1({a:hi})' (Should resemble)!")
+}
+
+func TestShouldNotResemble(t *testing.T) {
+	fail(t, so(Thing1{"hi"}, ShouldNotResemble), "This assertion requires exactly 1 comparison values (you provided 0).")
+	fail(t, so(Thing1{"hi"}, ShouldNotResemble, Thing1{"hi"}, Thing1{"hi"}), "This assertion requires exactly 1 comparison values (you provided 2).")
+
+	pass(t, so(Thing1{"hi"}, ShouldNotResemble, Thing1{"bye"}))
+	fail(t, so(Thing1{"hi"}, ShouldNotResemble, Thing1{"hi"}),
+		"Expected 'assertions.Thing1({a:hi})' to NOT resemble 'assertions.Thing1({a:hi})' (but it did)!")
+
+	pass(t, so(map[string]string{"hi": "bye"}, ShouldResemble, map[string]string{"hi": "bye"}))
+	fail(t, so(StringStringMapAlias{"hi": "bye"}, ShouldResemble, map[string]string{"hi": "bye"}),
+		"map[hi:bye]|map[hi:bye]|Expected: 'map[string]string(map[hi:bye])' Actual: 'assertions.StringStringMapAlias(map[hi:bye])' (Should resemble)!")
+	pass(t, so(IntAlias(42), ShouldNotResemble, 42))
+	fail(t, so(IntAlias(42), ShouldResemble, 42), "42|42|Expected: 'int(42)' Actual: 'assertions.IntAlias(42)' (Should resemble)!")
+	fail(t, so(StringAlias("hi"), ShouldResemble, "hi"), "hi|hi|Expected: 'string(hi)' Actual: 'assertions.StringAlias(hi)' (Should resemble)!")
+
+	pass(t, so(StringSliceAlias{"hi", "bye"}, ShouldNotResemble, []string{"hi", "bye"}))
+	fail(t, so(StringSliceAlias{"hi", "bye"}, ShouldResemble, []string{"hi", "bye"}),
+		"[hi bye]|[hi bye]|Expected: '[]string([hi bye])' Actual: 'assertions.StringSliceAlias([hi bye])' (Should resemble)!")
+}
+
+func TestShouldPointTo(t *testing.T) {
+	serializer = newFakeSerializer()
+
+	t1 := &Thing1{}
+	t2 := t1
+	t3 := &Thing1{}
+
+	pointer1 := reflect.ValueOf(t1).Pointer()
+	pointer3 := reflect.ValueOf(t3).Pointer()
+
+	fail(t, so(t1, ShouldPointTo), "This assertion requires exactly 1 comparison values (you provided 0).")
+	fail(t, so(t1, ShouldPointTo, t2, t3), "This assertion requires exactly 1 comparison values (you provided 2).")
+
+	pass(t, so(t1, ShouldPointTo, t2))
+	fail(t, so(t1, ShouldPointTo, t3), fmt.Sprintf(
+		"%v|%v|Expected '&{a:}' (address: '%v') and '&{a:}' (address: '%v') to be the same address (but their weren't)!",
+		pointer3, pointer1, pointer1, pointer3))
+
+	t4 := Thing1{}
+	t5 := t4
+
+	fail(t, so(t4, ShouldPointTo, t5), "Both arguments should be pointers (the first was not)!")
+	fail(t, so(&t4, ShouldPointTo, t5), "Both arguments should be pointers (the second was not)!")
+	fail(t, so(nil, ShouldPointTo, nil), "Both arguments should be pointers (the first was nil)!")
+	fail(t, so(&t4, ShouldPointTo, nil), "Both arguments should be pointers (the second was nil)!")
+}
+
+func TestShouldNotPointTo(t *testing.T) {
+	t1 := &Thing1{}
+	t2 := t1
+	t3 := &Thing1{}
+
+	pointer1 := reflect.ValueOf(t1).Pointer()
+
+	fail(t, so(t1, ShouldNotPointTo), "This assertion requires exactly 1 comparison values (you provided 0).")
+	fail(t, so(t1, ShouldNotPointTo, t2, t3), "This assertion requires exactly 1 comparison values (you provided 2).")
+
+	pass(t, so(t1, ShouldNotPointTo, t3))
+	fail(t, so(t1, ShouldNotPointTo, t2), fmt.Sprintf("Expected '&{a:}' and '&{a:}' to be different references (but they matched: '%v')!", pointer1))
+
+	t4 := Thing1{}
+	t5 := t4
+
+	fail(t, so(t4, ShouldNotPointTo, t5), "Both arguments should be pointers (the first was not)!")
+	fail(t, so(&t4, ShouldNotPointTo, t5), "Both arguments should be pointers (the second was not)!")
+	fail(t, so(nil, ShouldNotPointTo, nil), "Both arguments should be pointers (the first was nil)!")
+	fail(t, so(&t4, ShouldNotPointTo, nil), "Both arguments should be pointers (the second was nil)!")
+}
+
+func TestShouldBeNil(t *testing.T) {
+	fail(t, so(nil, ShouldBeNil, nil, nil, nil), "This assertion requires exactly 0 comparison values (you provided 3).")
+	fail(t, so(nil, ShouldBeNil, nil), "This assertion requires exactly 0 comparison values (you provided 1).")
+
+	pass(t, so(nil, ShouldBeNil))
+	fail(t, so(1, ShouldBeNil), "Expected: nil Actual: '1'")
+
+	var thing Thinger
+	pass(t, so(thing, ShouldBeNil))
+	thing = &Thing{}
+	fail(t, so(thing, ShouldBeNil), "Expected: nil Actual: '&{}'")
+
+	var thingOne *Thing1
+	pass(t, so(thingOne, ShouldBeNil))
+
+	var nilSlice []int = nil
+	pass(t, so(nilSlice, ShouldBeNil))
+
+	var nilMap map[string]string = nil
+	pass(t, so(nilMap, ShouldBeNil))
+
+	var nilChannel chan int = nil
+	pass(t, so(nilChannel, ShouldBeNil))
+
+	var nilFunc func() = nil
+	pass(t, so(nilFunc, ShouldBeNil))
+
+	var nilInterface interface{} = nil
+	pass(t, so(nilInterface, ShouldBeNil))
+}
+
+func TestShouldNotBeNil(t *testing.T) {
+	fail(t, so(nil, ShouldNotBeNil, nil, nil, nil), "This assertion requires exactly 0 comparison values (you provided 3).")
+	fail(t, so(nil, ShouldNotBeNil, nil), "This assertion requires exactly 0 comparison values (you provided 1).")
+
+	fail(t, so(nil, ShouldNotBeNil), "Expected '<nil>' to NOT be nil (but it was)!")
+	pass(t, so(1, ShouldNotBeNil))
+
+	var thing Thinger
+	fail(t, so(thing, ShouldNotBeNil), "Expected '<nil>' to NOT be nil (but it was)!")
+	thing = &Thing{}
+	pass(t, so(thing, ShouldNotBeNil))
+}
+
+func TestShouldBeTrue(t *testing.T) {
+	fail(t, so(true, ShouldBeTrue, 1, 2, 3), "This assertion requires exactly 0 comparison values (you provided 3).")
+	fail(t, so(true, ShouldBeTrue, 1), "This assertion requires exactly 0 comparison values (you provided 1).")
+
+	fail(t, so(false, ShouldBeTrue), "Expected: true Actual: false")
+	fail(t, so(1, ShouldBeTrue), "Expected: true Actual: 1")
+	pass(t, so(true, ShouldBeTrue))
+}
+
+func TestShouldBeFalse(t *testing.T) {
+	fail(t, so(false, ShouldBeFalse, 1, 2, 3), "This assertion requires exactly 0 comparison values (you provided 3).")
+	fail(t, so(false, ShouldBeFalse, 1), "This assertion requires exactly 0 comparison values (you provided 1).")
+
+	fail(t, so(true, ShouldBeFalse), "Expected: false Actual: true")
+	fail(t, so(1, ShouldBeFalse), "Expected: false Actual: 1")
+	pass(t, so(false, ShouldBeFalse))
+}
+
+func TestShouldBeZeroValue(t *testing.T) {
+	serializer = newFakeSerializer()
+
+	fail(t, so(0, ShouldBeZeroValue, 1, 2, 3), "This assertion requires exactly 0 comparison values (you provided 3).")
+	fail(t, so(false, ShouldBeZeroValue, true), "This assertion requires exactly 0 comparison values (you provided 1).")
+
+	fail(t, so(1, ShouldBeZeroValue), "0|1|'1' should have been the zero value")                                       //"Expected: (zero value) Actual: 1")
+	fail(t, so(true, ShouldBeZeroValue), "false|true|'true' should have been the zero value")                          //"Expected: (zero value) Actual: true")
+	fail(t, so("123", ShouldBeZeroValue), "|123|'123' should have been the zero value")                                //"Expected: (zero value) Actual: 123")
+	fail(t, so(" ", ShouldBeZeroValue), "| |' ' should have been the zero value")                                      //"Expected: (zero value) Actual:  ")
+	fail(t, so([]string{"Nonempty"}, ShouldBeZeroValue), "[]|[Nonempty]|'[Nonempty]' should have been the zero value") //"Expected: (zero value) Actual: [Nonempty]")
+	fail(t, so(struct{ a string }{a: "asdf"}, ShouldBeZeroValue), "{}|{asdf}|'{a:asdf}' should have been the zero value")
+	pass(t, so(0, ShouldBeZeroValue))
+	pass(t, so(false, ShouldBeZeroValue))
+	pass(t, so("", ShouldBeZeroValue))
+	pass(t, so(struct{}{}, ShouldBeZeroValue))
+}

+ 22 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/filter.go

@@ -0,0 +1,22 @@
+package assertions
+
+import "fmt"
+
+const (
+	success         = ""
+	needExactValues = "This assertion requires exactly %d comparison values (you provided %d)."
+)
+
+func need(needed int, expected []interface{}) string {
+	if len(expected) != needed {
+		return fmt.Sprintf(needExactValues, needed, len(expected))
+	}
+	return success
+}
+
+func atLeast(minimum int, expected []interface{}) string {
+	if len(expected) < 1 {
+		return shouldHaveProvidedCollectionMembers
+	}
+	return success
+}

+ 7 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/init.go

@@ -0,0 +1,7 @@
+package assertions
+
+var serializer Serializer
+
+func init() {
+	serializer = newSerializer()
+}

+ 86 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/messages.go

@@ -0,0 +1,86 @@
+package assertions
+
+const ( // equality
+	shouldHaveBeenEqual          = "Expected: '%v'\nActual:   '%v'\n(Should be equal)"
+	shouldNotHaveBeenEqual       = "Expected     '%v'\nto NOT equal '%v'\n(but it did)!"
+	shouldHaveBeenAlmostEqual    = "Expected '%v' to almost equal '%v' (but it didn't)!"
+	shouldHaveNotBeenAlmostEqual = "Expected '%v' to NOT almost equal '%v' (but it did)!"
+	shouldHaveResembled          = "Expected: '%T(%+v)'\nActual:   '%T(%+v)'\n(Should resemble)!"
+	shouldNotHaveResembled       = "Expected        '%T(%+v)'\nto NOT resemble '%T(%+v)'\n(but it did)!"
+	shouldBePointers             = "Both arguments should be pointers "
+	shouldHaveBeenNonNilPointer  = shouldBePointers + "(the %s was %s)!"
+	shouldHavePointedTo          = "Expected '%+v' (address: '%v') and '%+v' (address: '%v') to be the same address (but their weren't)!"
+	shouldNotHavePointedTo       = "Expected '%+v' and '%+v' to be different references (but they matched: '%v')!"
+	shouldHaveBeenNil            = "Expected: nil\nActual:   '%v'"
+	shouldNotHaveBeenNil         = "Expected '%+v' to NOT be nil (but it was)!"
+	shouldHaveBeenTrue           = "Expected: true\nActual:   %v"
+	shouldHaveBeenFalse          = "Expected: false\nActual:   %v"
+	shouldHaveBeenZeroValue      = "'%+v' should have been the zero value" //"Expected: (zero value)\nActual:   %v"
+)
+
+const ( // quantity comparisons
+	shouldHaveBeenGreater            = "Expected '%v' to be greater than '%v' (but it wasn't)!"
+	shouldHaveBeenGreaterOrEqual     = "Expected '%v' to be greater than or equal to '%v' (but it wasn't)!"
+	shouldHaveBeenLess               = "Expected '%v' to be less than '%v' (but it wasn't)!"
+	shouldHaveBeenLessOrEqual        = "Expected '%v' to be less than or equal to '%v' (but it wasn't)!"
+	shouldHaveBeenBetween            = "Expected '%v' to be between '%v' and '%v' (but it wasn't)!"
+	shouldNotHaveBeenBetween         = "Expected '%v' NOT to be between '%v' and '%v' (but it was)!"
+	shouldHaveDifferentUpperAndLower = "The lower and upper bounds must be different values (they were both '%v')."
+	shouldHaveBeenBetweenOrEqual     = "Expected '%v' to be between '%v' and '%v' or equal to one of them (but it wasn't)!"
+	shouldNotHaveBeenBetweenOrEqual  = "Expected '%v' NOT to be between '%v' and '%v' or equal to one of them (but it was)!"
+)
+
+const ( // collections
+	shouldHaveContained                 = "Expected the container (%v) to contain: '%v' (but it didn't)!"
+	shouldNotHaveContained              = "Expected the container (%v) NOT to contain: '%v' (but it did)!"
+	shouldHaveBeenIn                    = "Expected '%v' to be in the container (%v, but it wasn't)!"
+	shouldNotHaveBeenIn                 = "Expected '%v' NOT to be in the container (%v, but it was)!"
+	shouldHaveBeenAValidCollection      = "You must provide a valid container (was %v)!"
+	shouldHaveProvidedCollectionMembers = "This assertion requires at least 1 comparison value (you provided 0)."
+	shouldHaveBeenEmpty                 = "Expected %+v to be empty (but it wasn't)!"
+	shouldNotHaveBeenEmpty              = "Expected %+v to NOT be empty (but it was)!"
+)
+
+const ( // strings
+	shouldHaveStartedWith           = "Expected      '%v'\nto start with '%v'\n(but it didn't)!"
+	shouldNotHaveStartedWith        = "Expected          '%v'\nNOT to start with '%v'\n(but it did)!"
+	shouldHaveEndedWith             = "Expected    '%v'\nto end with '%v'\n(but it didn't)!"
+	shouldNotHaveEndedWith          = "Expected        '%v'\nNOT to end with '%v'\n(but it did)!"
+	shouldBothBeStrings             = "Both arguments to this assertion must be strings (you provided %v and %v)."
+	shouldBeString                  = "The argument to this assertion must be a string (you provided %v)."
+	shouldHaveContainedSubstring    = "Expected '%s' to contain substring '%s' (but it didn't)!"
+	shouldNotHaveContainedSubstring = "Expected '%s' NOT to contain substring '%s' (but it didn't)!"
+	shouldHaveBeenBlank             = "Expected '%s' to be blank (but it wasn't)!"
+	shouldNotHaveBeenBlank          = "Expected value to NOT be blank (but it was)!"
+)
+
+const ( // panics
+	shouldUseVoidNiladicFunction = "You must provide a void, niladic function as the first argument!"
+	shouldHavePanickedWith       = "Expected func() to panic with '%v' (but it panicked with '%v')!"
+	shouldHavePanicked           = "Expected func() to panic (but it didn't)!"
+	shouldNotHavePanicked        = "Expected func() NOT to panic (error: '%+v')!"
+	shouldNotHavePanickedWith    = "Expected func() NOT to panic with '%v' (but it did)!"
+)
+
+const ( // type checking
+	shouldHaveBeenA    = "Expected '%v' to be: '%v' (but was: '%v')!"
+	shouldNotHaveBeenA = "Expected '%v' to NOT be: '%v' (but it was)!"
+
+	shouldHaveImplemented             = "Expected: '%v interface support'\nActual:   '%v' does not implement the interface!"
+	shouldNotHaveImplemented          = "Expected         '%v'\nto NOT implement '%v'\n(but it did)!"
+	shouldCompareWithInterfacePointer = "The expected value must be a pointer to an interface type (eg. *fmt.Stringer)"
+	shouldNotBeNilActual              = "The actual value was 'nil' and should be a value or a pointer to a value!"
+)
+
+const ( // time comparisons
+	shouldUseTimes                   = "You must provide time instances as arguments to this assertion."
+	shouldUseTimeSlice               = "You must provide a slice of time instances as the first argument to this assertion."
+	shouldUseDurationAndTime         = "You must provide a duration and a time as arguments to this assertion."
+	shouldHaveHappenedBefore         = "Expected '%v' to happen before '%v' (it happened '%v' after)!"
+	shouldHaveHappenedAfter          = "Expected '%v' to happen after '%v' (it happened '%v' before)!"
+	shouldHaveHappenedBetween        = "Expected '%v' to happen between '%v' and '%v' (it happened '%v' outside threshold)!"
+	shouldNotHaveHappenedOnOrBetween = "Expected '%v' to NOT happen on or between '%v' and '%v' (but it did)!"
+
+	// format params: incorrect-index, previous-index, previous-time, incorrect-index, incorrect-time
+	shouldHaveBeenChronological = "The 'Time' at index [%d] should have happened after the previous one (but it didn't!):\n  [%d]: %s\n  [%d]: %s (see, it happened before!)"
+)

+ 115 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/panic.go

@@ -0,0 +1,115 @@
+package assertions
+
+import "fmt"
+
+// ShouldPanic receives a void, niladic function and expects to recover a panic.
+func ShouldPanic(actual interface{}, expected ...interface{}) (message string) {
+	if fail := need(0, expected); fail != success {
+		return fail
+	}
+
+	action, _ := actual.(func())
+
+	if action == nil {
+		message = shouldUseVoidNiladicFunction
+		return
+	}
+
+	defer func() {
+		recovered := recover()
+		if recovered == nil {
+			message = shouldHavePanicked
+		} else {
+			message = success
+		}
+	}()
+	action()
+
+	return
+}
+
+// ShouldNotPanic receives a void, niladic function and expects to execute the function without any panic.
+func ShouldNotPanic(actual interface{}, expected ...interface{}) (message string) {
+	if fail := need(0, expected); fail != success {
+		return fail
+	}
+
+	action, _ := actual.(func())
+
+	if action == nil {
+		message = shouldUseVoidNiladicFunction
+		return
+	}
+
+	defer func() {
+		recovered := recover()
+		if recovered != nil {
+			message = fmt.Sprintf(shouldNotHavePanicked, recovered)
+		} else {
+			message = success
+		}
+	}()
+	action()
+
+	return
+}
+
+// ShouldPanicWith receives a void, niladic function and expects to recover a panic with the second argument as the content.
+func ShouldPanicWith(actual interface{}, expected ...interface{}) (message string) {
+	if fail := need(1, expected); fail != success {
+		return fail
+	}
+
+	action, _ := actual.(func())
+
+	if action == nil {
+		message = shouldUseVoidNiladicFunction
+		return
+	}
+
+	defer func() {
+		recovered := recover()
+		if recovered == nil {
+			message = shouldHavePanicked
+		} else {
+			if equal := ShouldEqual(recovered, expected[0]); equal != success {
+				message = serializer.serialize(expected[0], recovered, fmt.Sprintf(shouldHavePanickedWith, expected[0], recovered))
+			} else {
+				message = success
+			}
+		}
+	}()
+	action()
+
+	return
+}
+
+// ShouldNotPanicWith receives a void, niladic function and expects to recover a panic whose content differs from the second argument.
+func ShouldNotPanicWith(actual interface{}, expected ...interface{}) (message string) {
+	if fail := need(1, expected); fail != success {
+		return fail
+	}
+
+	action, _ := actual.(func())
+
+	if action == nil {
+		message = shouldUseVoidNiladicFunction
+		return
+	}
+
+	defer func() {
+		recovered := recover()
+		if recovered == nil {
+			message = success
+		} else {
+			if equal := ShouldEqual(recovered, expected[0]); equal == success {
+				message = fmt.Sprintf(shouldNotHavePanickedWith, expected[0])
+			} else {
+				message = success
+			}
+		}
+	}()
+	action()
+
+	return
+}

+ 53 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/panic_test.go

@@ -0,0 +1,53 @@
+package assertions
+
+import (
+	"fmt"
+	"testing"
+)
+
+func TestShouldPanic(t *testing.T) {
+	fail(t, so(func() {}, ShouldPanic, 1), "This assertion requires exactly 0 comparison values (you provided 1).")
+	fail(t, so(func() {}, ShouldPanic, 1, 2, 3), "This assertion requires exactly 0 comparison values (you provided 3).")
+
+	fail(t, so(1, ShouldPanic), shouldUseVoidNiladicFunction)
+	fail(t, so(func(i int) {}, ShouldPanic), shouldUseVoidNiladicFunction)
+	fail(t, so(func() int { panic("hi") }, ShouldPanic), shouldUseVoidNiladicFunction)
+
+	fail(t, so(func() {}, ShouldPanic), shouldHavePanicked)
+	pass(t, so(func() { panic("hi") }, ShouldPanic))
+}
+
+func TestShouldNotPanic(t *testing.T) {
+	fail(t, so(func() {}, ShouldNotPanic, 1), "This assertion requires exactly 0 comparison values (you provided 1).")
+	fail(t, so(func() {}, ShouldNotPanic, 1, 2, 3), "This assertion requires exactly 0 comparison values (you provided 3).")
+
+	fail(t, so(1, ShouldNotPanic), shouldUseVoidNiladicFunction)
+	fail(t, so(func(i int) {}, ShouldNotPanic), shouldUseVoidNiladicFunction)
+
+	fail(t, so(func() { panic("hi") }, ShouldNotPanic), fmt.Sprintf(shouldNotHavePanicked, "hi"))
+	pass(t, so(func() {}, ShouldNotPanic))
+}
+
+func TestShouldPanicWith(t *testing.T) {
+	fail(t, so(func() {}, ShouldPanicWith), "This assertion requires exactly 1 comparison values (you provided 0).")
+	fail(t, so(func() {}, ShouldPanicWith, 1, 2, 3), "This assertion requires exactly 1 comparison values (you provided 3).")
+
+	fail(t, so(1, ShouldPanicWith, 1), shouldUseVoidNiladicFunction)
+	fail(t, so(func(i int) {}, ShouldPanicWith, "hi"), shouldUseVoidNiladicFunction)
+	fail(t, so(func() {}, ShouldPanicWith, "bye"), shouldHavePanicked)
+	fail(t, so(func() { panic("hi") }, ShouldPanicWith, "bye"), "bye|hi|Expected func() to panic with 'bye' (but it panicked with 'hi')!")
+
+	pass(t, so(func() { panic("hi") }, ShouldPanicWith, "hi"))
+}
+
+func TestShouldNotPanicWith(t *testing.T) {
+	fail(t, so(func() {}, ShouldNotPanicWith), "This assertion requires exactly 1 comparison values (you provided 0).")
+	fail(t, so(func() {}, ShouldNotPanicWith, 1, 2, 3), "This assertion requires exactly 1 comparison values (you provided 3).")
+
+	fail(t, so(1, ShouldNotPanicWith, 1), shouldUseVoidNiladicFunction)
+	fail(t, so(func(i int) {}, ShouldNotPanicWith, "hi"), shouldUseVoidNiladicFunction)
+	fail(t, so(func() { panic("hi") }, ShouldNotPanicWith, "hi"), "Expected func() NOT to panic with 'hi' (but it did)!")
+
+	pass(t, so(func() {}, ShouldNotPanicWith, "bye"))
+	pass(t, so(func() { panic("hi") }, ShouldNotPanicWith, "bye"))
+}

+ 141 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/quantity.go

@@ -0,0 +1,141 @@
+package assertions
+
+import (
+	"fmt"
+
+	"github.com/jacobsa/oglematchers"
+)
+
+// ShouldBeGreaterThan receives exactly two parameters and ensures that the first is greater than the second.
+func ShouldBeGreaterThan(actual interface{}, expected ...interface{}) string {
+	if fail := need(1, expected); fail != success {
+		return fail
+	}
+
+	if matchError := oglematchers.GreaterThan(expected[0]).Matches(actual); matchError != nil {
+		return fmt.Sprintf(shouldHaveBeenGreater, actual, expected[0])
+	}
+	return success
+}
+
+// ShouldBeGreaterThanOrEqualTo receives exactly two parameters and ensures that the first is greater than or equal to the second.
+func ShouldBeGreaterThanOrEqualTo(actual interface{}, expected ...interface{}) string {
+	if fail := need(1, expected); fail != success {
+		return fail
+	} else if matchError := oglematchers.GreaterOrEqual(expected[0]).Matches(actual); matchError != nil {
+		return fmt.Sprintf(shouldHaveBeenGreaterOrEqual, actual, expected[0])
+	}
+	return success
+}
+
+// ShouldBeLessThan receives exactly two parameters and ensures that the first is less than the second.
+func ShouldBeLessThan(actual interface{}, expected ...interface{}) string {
+	if fail := need(1, expected); fail != success {
+		return fail
+	} else if matchError := oglematchers.LessThan(expected[0]).Matches(actual); matchError != nil {
+		return fmt.Sprintf(shouldHaveBeenLess, actual, expected[0])
+	}
+	return success
+}
+
+// ShouldBeLessThan receives exactly two parameters and ensures that the first is less than or equal to the second.
+func ShouldBeLessThanOrEqualTo(actual interface{}, expected ...interface{}) string {
+	if fail := need(1, expected); fail != success {
+		return fail
+	} else if matchError := oglematchers.LessOrEqual(expected[0]).Matches(actual); matchError != nil {
+		return fmt.Sprintf(shouldHaveBeenLess, actual, expected[0])
+	}
+	return success
+}
+
+// ShouldBeBetween receives exactly three parameters: an actual value, a lower bound, and an upper bound.
+// It ensures that the actual value is between both bounds (but not equal to either of them).
+func ShouldBeBetween(actual interface{}, expected ...interface{}) string {
+	if fail := need(2, expected); fail != success {
+		return fail
+	}
+	lower, upper, fail := deriveBounds(expected)
+
+	if fail != success {
+		return fail
+	} else if !isBetween(actual, lower, upper) {
+		return fmt.Sprintf(shouldHaveBeenBetween, actual, lower, upper)
+	}
+	return success
+}
+
+// ShouldNotBeBetween receives exactly three parameters: an actual value, a lower bound, and an upper bound.
+// It ensures that the actual value is NOT between both bounds.
+func ShouldNotBeBetween(actual interface{}, expected ...interface{}) string {
+	if fail := need(2, expected); fail != success {
+		return fail
+	}
+	lower, upper, fail := deriveBounds(expected)
+
+	if fail != success {
+		return fail
+	} else if isBetween(actual, lower, upper) {
+		return fmt.Sprintf(shouldNotHaveBeenBetween, actual, lower, upper)
+	}
+	return success
+}
+func deriveBounds(values []interface{}) (lower interface{}, upper interface{}, fail string) {
+	lower = values[0]
+	upper = values[1]
+
+	if ShouldNotEqual(lower, upper) != success {
+		return nil, nil, fmt.Sprintf(shouldHaveDifferentUpperAndLower, lower)
+	} else if ShouldBeLessThan(lower, upper) != success {
+		lower, upper = upper, lower
+	}
+	return lower, upper, success
+}
+func isBetween(value, lower, upper interface{}) bool {
+	if ShouldBeGreaterThan(value, lower) != success {
+		return false
+	} else if ShouldBeLessThan(value, upper) != success {
+		return false
+	}
+	return true
+}
+
+// ShouldBeBetweenOrEqual receives exactly three parameters: an actual value, a lower bound, and an upper bound.
+// It ensures that the actual value is between both bounds or equal to one of them.
+func ShouldBeBetweenOrEqual(actual interface{}, expected ...interface{}) string {
+	if fail := need(2, expected); fail != success {
+		return fail
+	}
+	lower, upper, fail := deriveBounds(expected)
+
+	if fail != success {
+		return fail
+	} else if !isBetweenOrEqual(actual, lower, upper) {
+		return fmt.Sprintf(shouldHaveBeenBetweenOrEqual, actual, lower, upper)
+	}
+	return success
+}
+
+// ShouldNotBeBetweenOrEqual receives exactly three parameters: an actual value, a lower bound, and an upper bound.
+// It ensures that the actual value is nopt between the bounds nor equal to either of them.
+func ShouldNotBeBetweenOrEqual(actual interface{}, expected ...interface{}) string {
+	if fail := need(2, expected); fail != success {
+		return fail
+	}
+	lower, upper, fail := deriveBounds(expected)
+
+	if fail != success {
+		return fail
+	} else if isBetweenOrEqual(actual, lower, upper) {
+		return fmt.Sprintf(shouldNotHaveBeenBetweenOrEqual, actual, lower, upper)
+	}
+	return success
+}
+
+func isBetweenOrEqual(value, lower, upper interface{}) bool {
+	if ShouldBeGreaterThanOrEqualTo(value, lower) != success {
+		return false
+	} else if ShouldBeLessThanOrEqualTo(value, upper) != success {
+		return false
+	}
+	return true
+}

+ 145 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/quantity_test.go

@@ -0,0 +1,145 @@
+package assertions
+
+import "testing"
+
+func TestShouldBeGreaterThan(t *testing.T) {
+	fail(t, so(1, ShouldBeGreaterThan), "This assertion requires exactly 1 comparison values (you provided 0).")
+	fail(t, so(1, ShouldBeGreaterThan, 0, 0), "This assertion requires exactly 1 comparison values (you provided 2).")
+
+	pass(t, so(1, ShouldBeGreaterThan, 0))
+	pass(t, so(1.1, ShouldBeGreaterThan, 1))
+	pass(t, so(1, ShouldBeGreaterThan, uint(0)))
+	pass(t, so("b", ShouldBeGreaterThan, "a"))
+
+	fail(t, so(0, ShouldBeGreaterThan, 1), "Expected '0' to be greater than '1' (but it wasn't)!")
+	fail(t, so(1, ShouldBeGreaterThan, 1.1), "Expected '1' to be greater than '1.1' (but it wasn't)!")
+	fail(t, so(uint(0), ShouldBeGreaterThan, 1.1), "Expected '0' to be greater than '1.1' (but it wasn't)!")
+	fail(t, so("a", ShouldBeGreaterThan, "b"), "Expected 'a' to be greater than 'b' (but it wasn't)!")
+}
+
+func TestShouldBeGreaterThanOrEqual(t *testing.T) {
+	fail(t, so(1, ShouldBeGreaterThanOrEqualTo), "This assertion requires exactly 1 comparison values (you provided 0).")
+	fail(t, so(1, ShouldBeGreaterThanOrEqualTo, 0, 0), "This assertion requires exactly 1 comparison values (you provided 2).")
+
+	pass(t, so(1, ShouldBeGreaterThanOrEqualTo, 1))
+	pass(t, so(1.1, ShouldBeGreaterThanOrEqualTo, 1.1))
+	pass(t, so(1, ShouldBeGreaterThanOrEqualTo, uint(1)))
+	pass(t, so("b", ShouldBeGreaterThanOrEqualTo, "b"))
+
+	pass(t, so(1, ShouldBeGreaterThanOrEqualTo, 0))
+	pass(t, so(1.1, ShouldBeGreaterThanOrEqualTo, 1))
+	pass(t, so(1, ShouldBeGreaterThanOrEqualTo, uint(0)))
+	pass(t, so("b", ShouldBeGreaterThanOrEqualTo, "a"))
+
+	fail(t, so(0, ShouldBeGreaterThanOrEqualTo, 1), "Expected '0' to be greater than or equal to '1' (but it wasn't)!")
+	fail(t, so(1, ShouldBeGreaterThanOrEqualTo, 1.1), "Expected '1' to be greater than or equal to '1.1' (but it wasn't)!")
+	fail(t, so(uint(0), ShouldBeGreaterThanOrEqualTo, 1.1), "Expected '0' to be greater than or equal to '1.1' (but it wasn't)!")
+	fail(t, so("a", ShouldBeGreaterThanOrEqualTo, "b"), "Expected 'a' to be greater than or equal to 'b' (but it wasn't)!")
+}
+
+func TestShouldBeLessThan(t *testing.T) {
+	fail(t, so(1, ShouldBeLessThan), "This assertion requires exactly 1 comparison values (you provided 0).")
+	fail(t, so(1, ShouldBeLessThan, 0, 0), "This assertion requires exactly 1 comparison values (you provided 2).")
+
+	pass(t, so(0, ShouldBeLessThan, 1))
+	pass(t, so(1, ShouldBeLessThan, 1.1))
+	pass(t, so(uint(0), ShouldBeLessThan, 1))
+	pass(t, so("a", ShouldBeLessThan, "b"))
+
+	fail(t, so(1, ShouldBeLessThan, 0), "Expected '1' to be less than '0' (but it wasn't)!")
+	fail(t, so(1.1, ShouldBeLessThan, 1), "Expected '1.1' to be less than '1' (but it wasn't)!")
+	fail(t, so(1.1, ShouldBeLessThan, uint(0)), "Expected '1.1' to be less than '0' (but it wasn't)!")
+	fail(t, so("b", ShouldBeLessThan, "a"), "Expected 'b' to be less than 'a' (but it wasn't)!")
+}
+
+func TestShouldBeLessThanOrEqualTo(t *testing.T) {
+	fail(t, so(1, ShouldBeLessThanOrEqualTo), "This assertion requires exactly 1 comparison values (you provided 0).")
+	fail(t, so(1, ShouldBeLessThanOrEqualTo, 0, 0), "This assertion requires exactly 1 comparison values (you provided 2).")
+
+	pass(t, so(1, ShouldBeLessThanOrEqualTo, 1))
+	pass(t, so(1.1, ShouldBeLessThanOrEqualTo, 1.1))
+	pass(t, so(uint(1), ShouldBeLessThanOrEqualTo, 1))
+	pass(t, so("b", ShouldBeLessThanOrEqualTo, "b"))
+
+	pass(t, so(0, ShouldBeLessThanOrEqualTo, 1))
+	pass(t, so(1, ShouldBeLessThanOrEqualTo, 1.1))
+	pass(t, so(uint(0), ShouldBeLessThanOrEqualTo, 1))
+	pass(t, so("a", ShouldBeLessThanOrEqualTo, "b"))
+
+	fail(t, so(1, ShouldBeLessThanOrEqualTo, 0), "Expected '1' to be less than '0' (but it wasn't)!")
+	fail(t, so(1.1, ShouldBeLessThanOrEqualTo, 1), "Expected '1.1' to be less than '1' (but it wasn't)!")
+	fail(t, so(1.1, ShouldBeLessThanOrEqualTo, uint(0)), "Expected '1.1' to be less than '0' (but it wasn't)!")
+	fail(t, so("b", ShouldBeLessThanOrEqualTo, "a"), "Expected 'b' to be less than 'a' (but it wasn't)!")
+}
+
+func TestShouldBeBetween(t *testing.T) {
+	fail(t, so(1, ShouldBeBetween), "This assertion requires exactly 2 comparison values (you provided 0).")
+	fail(t, so(1, ShouldBeBetween, 1, 2, 3), "This assertion requires exactly 2 comparison values (you provided 3).")
+
+	fail(t, so(4, ShouldBeBetween, 1, 1), "The lower and upper bounds must be different values (they were both '1').")
+
+	fail(t, so(7, ShouldBeBetween, 8, 12), "Expected '7' to be between '8' and '12' (but it wasn't)!")
+	fail(t, so(8, ShouldBeBetween, 8, 12), "Expected '8' to be between '8' and '12' (but it wasn't)!")
+	pass(t, so(9, ShouldBeBetween, 8, 12))
+	pass(t, so(10, ShouldBeBetween, 8, 12))
+	pass(t, so(11, ShouldBeBetween, 8, 12))
+	fail(t, so(12, ShouldBeBetween, 8, 12), "Expected '12' to be between '8' and '12' (but it wasn't)!")
+	fail(t, so(13, ShouldBeBetween, 8, 12), "Expected '13' to be between '8' and '12' (but it wasn't)!")
+
+	pass(t, so(1, ShouldBeBetween, 2, 0))
+	fail(t, so(-1, ShouldBeBetween, 2, 0), "Expected '-1' to be between '0' and '2' (but it wasn't)!")
+}
+
+func TestShouldNotBeBetween(t *testing.T) {
+	fail(t, so(1, ShouldNotBeBetween), "This assertion requires exactly 2 comparison values (you provided 0).")
+	fail(t, so(1, ShouldNotBeBetween, 1, 2, 3), "This assertion requires exactly 2 comparison values (you provided 3).")
+
+	fail(t, so(4, ShouldNotBeBetween, 1, 1), "The lower and upper bounds must be different values (they were both '1').")
+
+	pass(t, so(7, ShouldNotBeBetween, 8, 12))
+	pass(t, so(8, ShouldNotBeBetween, 8, 12))
+	fail(t, so(9, ShouldNotBeBetween, 8, 12), "Expected '9' NOT to be between '8' and '12' (but it was)!")
+	fail(t, so(10, ShouldNotBeBetween, 8, 12), "Expected '10' NOT to be between '8' and '12' (but it was)!")
+	fail(t, so(11, ShouldNotBeBetween, 8, 12), "Expected '11' NOT to be between '8' and '12' (but it was)!")
+	pass(t, so(12, ShouldNotBeBetween, 8, 12))
+	pass(t, so(13, ShouldNotBeBetween, 8, 12))
+
+	pass(t, so(-1, ShouldNotBeBetween, 2, 0))
+	fail(t, so(1, ShouldNotBeBetween, 2, 0), "Expected '1' NOT to be between '0' and '2' (but it was)!")
+}
+
+func TestShouldBeBetweenOrEqual(t *testing.T) {
+	fail(t, so(1, ShouldBeBetweenOrEqual), "This assertion requires exactly 2 comparison values (you provided 0).")
+	fail(t, so(1, ShouldBeBetweenOrEqual, 1, 2, 3), "This assertion requires exactly 2 comparison values (you provided 3).")
+
+	fail(t, so(4, ShouldBeBetweenOrEqual, 1, 1), "The lower and upper bounds must be different values (they were both '1').")
+
+	fail(t, so(7, ShouldBeBetweenOrEqual, 8, 12), "Expected '7' to be between '8' and '12' or equal to one of them (but it wasn't)!")
+	pass(t, so(8, ShouldBeBetweenOrEqual, 8, 12))
+	pass(t, so(9, ShouldBeBetweenOrEqual, 8, 12))
+	pass(t, so(10, ShouldBeBetweenOrEqual, 8, 12))
+	pass(t, so(11, ShouldBeBetweenOrEqual, 8, 12))
+	pass(t, so(12, ShouldBeBetweenOrEqual, 8, 12))
+	fail(t, so(13, ShouldBeBetweenOrEqual, 8, 12), "Expected '13' to be between '8' and '12' or equal to one of them (but it wasn't)!")
+
+	pass(t, so(1, ShouldBeBetweenOrEqual, 2, 0))
+	fail(t, so(-1, ShouldBeBetweenOrEqual, 2, 0), "Expected '-1' to be between '0' and '2' or equal to one of them (but it wasn't)!")
+}
+
+func TestShouldNotBeBetweenOrEqual(t *testing.T) {
+	fail(t, so(1, ShouldNotBeBetweenOrEqual), "This assertion requires exactly 2 comparison values (you provided 0).")
+	fail(t, so(1, ShouldNotBeBetweenOrEqual, 1, 2, 3), "This assertion requires exactly 2 comparison values (you provided 3).")
+
+	fail(t, so(4, ShouldNotBeBetweenOrEqual, 1, 1), "The lower and upper bounds must be different values (they were both '1').")
+
+	pass(t, so(7, ShouldNotBeBetweenOrEqual, 8, 12))
+	fail(t, so(8, ShouldNotBeBetweenOrEqual, 8, 12), "Expected '8' NOT to be between '8' and '12' or equal to one of them (but it was)!")
+	fail(t, so(9, ShouldNotBeBetweenOrEqual, 8, 12), "Expected '9' NOT to be between '8' and '12' or equal to one of them (but it was)!")
+	fail(t, so(10, ShouldNotBeBetweenOrEqual, 8, 12), "Expected '10' NOT to be between '8' and '12' or equal to one of them (but it was)!")
+	fail(t, so(11, ShouldNotBeBetweenOrEqual, 8, 12), "Expected '11' NOT to be between '8' and '12' or equal to one of them (but it was)!")
+	fail(t, so(12, ShouldNotBeBetweenOrEqual, 8, 12), "Expected '12' NOT to be between '8' and '12' or equal to one of them (but it was)!")
+	pass(t, so(13, ShouldNotBeBetweenOrEqual, 8, 12))
+
+	pass(t, so(-1, ShouldNotBeBetweenOrEqual, 2, 0))
+	fail(t, so(1, ShouldNotBeBetweenOrEqual, 2, 0), "Expected '1' NOT to be between '0' and '2' or equal to one of them (but it was)!")
+}

+ 31 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/serializer.go

@@ -0,0 +1,31 @@
+package assertions
+
+import (
+	"encoding/json"
+	"fmt"
+
+	"github.com/smartystreets/goconvey/convey/reporting"
+)
+
+type Serializer interface {
+	serialize(expected, actual interface{}, message string) string
+}
+
+type failureSerializer struct{}
+
+func (self *failureSerializer) serialize(expected, actual interface{}, message string) string {
+	view := reporting.FailureView{
+		Message:  message,
+		Expected: fmt.Sprintf("%+v", expected),
+		Actual:   fmt.Sprintf("%+v", actual),
+	}
+	serialized, err := json.Marshal(view)
+	if err != nil {
+		return message
+	}
+	return string(serialized)
+}
+
+func newSerializer() *failureSerializer {
+	return &failureSerializer{}
+}

+ 28 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/serializer_test.go

@@ -0,0 +1,28 @@
+package assertions
+
+import (
+	"encoding/json"
+	"fmt"
+	"testing"
+
+	"github.com/smartystreets/goconvey/convey/reporting"
+)
+
+func TestSerializerCreatesSerializedVersionOfAssertionResult(t *testing.T) {
+	thing1 := Thing1{"Hi"}
+	thing2 := Thing2{"Bye"}
+	message := "Super-hip failure message."
+	serializer := newSerializer()
+
+	actualResult := serializer.serialize(thing1, thing2, message)
+
+	expectedResult, _ := json.Marshal(reporting.FailureView{
+		Message:  message,
+		Expected: fmt.Sprintf("%+v", thing1),
+		Actual:   fmt.Sprintf("%+v", thing2),
+	})
+
+	if actualResult != string(expectedResult) {
+		t.Errorf("\nExpected: %s\nActual:   %s", string(expectedResult), actualResult)
+	}
+}

+ 183 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/strings.go

@@ -0,0 +1,183 @@
+package assertions
+
+import (
+	"fmt"
+	"reflect"
+	"strings"
+)
+
+// ShouldStartWith receives exactly 2 string parameters and ensures that the first starts with the second.
+func ShouldStartWith(actual interface{}, expected ...interface{}) string {
+	if fail := need(1, expected); fail != success {
+		return fail
+	}
+
+	value, valueIsString := actual.(string)
+	prefix, prefixIsString := expected[0].(string)
+
+	if !valueIsString || !prefixIsString {
+		return fmt.Sprintf(shouldBothBeStrings, reflect.TypeOf(actual), reflect.TypeOf(expected[0]))
+	}
+
+	return shouldStartWith(value, prefix)
+}
+func shouldStartWith(value, prefix string) string {
+	if !strings.HasPrefix(value, prefix) {
+		shortval := value
+		if len(shortval) > len(prefix) {
+			shortval = shortval[:len(prefix)] + "..."
+		}
+		return serializer.serialize(prefix, shortval, fmt.Sprintf(shouldHaveStartedWith, value, prefix))
+	}
+	return success
+}
+
+// ShouldNotStartWith receives exactly 2 string parameters and ensures that the first does not start with the second.
+func ShouldNotStartWith(actual interface{}, expected ...interface{}) string {
+	if fail := need(1, expected); fail != success {
+		return fail
+	}
+
+	value, valueIsString := actual.(string)
+	prefix, prefixIsString := expected[0].(string)
+
+	if !valueIsString || !prefixIsString {
+		return fmt.Sprintf(shouldBothBeStrings, reflect.TypeOf(actual), reflect.TypeOf(expected[0]))
+	}
+
+	return shouldNotStartWith(value, prefix)
+}
+func shouldNotStartWith(value, prefix string) string {
+	if strings.HasPrefix(value, prefix) {
+		if value == "" {
+			value = "<empty>"
+		}
+		if prefix == "" {
+			prefix = "<empty>"
+		}
+		return fmt.Sprintf(shouldNotHaveStartedWith, value, prefix)
+	}
+	return success
+}
+
+// ShouldEndWith receives exactly 2 string parameters and ensures that the first ends with the second.
+func ShouldEndWith(actual interface{}, expected ...interface{}) string {
+	if fail := need(1, expected); fail != success {
+		return fail
+	}
+
+	value, valueIsString := actual.(string)
+	suffix, suffixIsString := expected[0].(string)
+
+	if !valueIsString || !suffixIsString {
+		return fmt.Sprintf(shouldBothBeStrings, reflect.TypeOf(actual), reflect.TypeOf(expected[0]))
+	}
+
+	return shouldEndWith(value, suffix)
+}
+func shouldEndWith(value, suffix string) string {
+	if !strings.HasSuffix(value, suffix) {
+		shortval := value
+		if len(shortval) > len(suffix) {
+			shortval = "..." + shortval[len(shortval)-len(suffix):]
+		}
+		return serializer.serialize(suffix, shortval, fmt.Sprintf(shouldHaveEndedWith, value, suffix))
+	}
+	return success
+}
+
+// ShouldEndWith receives exactly 2 string parameters and ensures that the first does not end with the second.
+func ShouldNotEndWith(actual interface{}, expected ...interface{}) string {
+	if fail := need(1, expected); fail != success {
+		return fail
+	}
+
+	value, valueIsString := actual.(string)
+	suffix, suffixIsString := expected[0].(string)
+
+	if !valueIsString || !suffixIsString {
+		return fmt.Sprintf(shouldBothBeStrings, reflect.TypeOf(actual), reflect.TypeOf(expected[0]))
+	}
+
+	return shouldNotEndWith(value, suffix)
+}
+func shouldNotEndWith(value, suffix string) string {
+	if strings.HasSuffix(value, suffix) {
+		if value == "" {
+			value = "<empty>"
+		}
+		if suffix == "" {
+			suffix = "<empty>"
+		}
+		return fmt.Sprintf(shouldNotHaveEndedWith, value, suffix)
+	}
+	return success
+}
+
+// ShouldContainSubstring receives exactly 2 string parameters and ensures that the first contains the second as a substring.
+func ShouldContainSubstring(actual interface{}, expected ...interface{}) string {
+	if fail := need(1, expected); fail != success {
+		return fail
+	}
+
+	long, longOk := actual.(string)
+	short, shortOk := expected[0].(string)
+
+	if !longOk || !shortOk {
+		return fmt.Sprintf(shouldBothBeStrings, reflect.TypeOf(actual), reflect.TypeOf(expected[0]))
+	}
+
+	if !strings.Contains(long, short) {
+		return serializer.serialize(expected[0], actual, fmt.Sprintf(shouldHaveContainedSubstring, long, short))
+	}
+	return success
+}
+
+// ShouldNotContainSubstring receives exactly 2 string parameters and ensures that the first does NOT contain the second as a substring.
+func ShouldNotContainSubstring(actual interface{}, expected ...interface{}) string {
+	if fail := need(1, expected); fail != success {
+		return fail
+	}
+
+	long, longOk := actual.(string)
+	short, shortOk := expected[0].(string)
+
+	if !longOk || !shortOk {
+		return fmt.Sprintf(shouldBothBeStrings, reflect.TypeOf(actual), reflect.TypeOf(expected[0]))
+	}
+
+	if strings.Contains(long, short) {
+		return fmt.Sprintf(shouldNotHaveContainedSubstring, long, short)
+	}
+	return success
+}
+
+// ShouldBeBlank receives exactly 1 string parameter and ensures that it is equal to "".
+func ShouldBeBlank(actual interface{}, expected ...interface{}) string {
+	if fail := need(0, expected); fail != success {
+		return fail
+	}
+	value, ok := actual.(string)
+	if !ok {
+		return fmt.Sprintf(shouldBeString, reflect.TypeOf(actual))
+	}
+	if value != "" {
+		return serializer.serialize("", value, fmt.Sprintf(shouldHaveBeenBlank, value))
+	}
+	return success
+}
+
+// ShouldNotBeBlank receives exactly 1 string parameter and ensures that it is equal to "".
+func ShouldNotBeBlank(actual interface{}, expected ...interface{}) string {
+	if fail := need(0, expected); fail != success {
+		return fail
+	}
+	value, ok := actual.(string)
+	if !ok {
+		return fmt.Sprintf(shouldBeString, reflect.TypeOf(actual))
+	}
+	if value == "" {
+		return shouldNotHaveBeenBlank
+	}
+	return success
+}

+ 102 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/strings_test.go

@@ -0,0 +1,102 @@
+package assertions
+
+import "testing"
+
+func TestShouldStartWith(t *testing.T) {
+	serializer = newFakeSerializer()
+
+	fail(t, so("", ShouldStartWith), "This assertion requires exactly 1 comparison values (you provided 0).")
+	fail(t, so("", ShouldStartWith, "asdf", "asdf"), "This assertion requires exactly 1 comparison values (you provided 2).")
+
+	pass(t, so("", ShouldStartWith, ""))
+	fail(t, so("", ShouldStartWith, "x"), "x||Expected '' to start with 'x' (but it didn't)!")
+	pass(t, so("abc", ShouldStartWith, "abc"))
+	fail(t, so("abc", ShouldStartWith, "abcd"), "abcd|abc|Expected 'abc' to start with 'abcd' (but it didn't)!")
+
+	pass(t, so("superman", ShouldStartWith, "super"))
+	fail(t, so("superman", ShouldStartWith, "bat"), "bat|sup...|Expected 'superman' to start with 'bat' (but it didn't)!")
+	fail(t, so("superman", ShouldStartWith, "man"), "man|sup...|Expected 'superman' to start with 'man' (but it didn't)!")
+
+	fail(t, so(1, ShouldStartWith, 2), "Both arguments to this assertion must be strings (you provided int and int).")
+}
+
+func TestShouldNotStartWith(t *testing.T) {
+	fail(t, so("", ShouldNotStartWith), "This assertion requires exactly 1 comparison values (you provided 0).")
+	fail(t, so("", ShouldNotStartWith, "asdf", "asdf"), "This assertion requires exactly 1 comparison values (you provided 2).")
+
+	fail(t, so("", ShouldNotStartWith, ""), "Expected '<empty>' NOT to start with '<empty>' (but it did)!")
+	fail(t, so("superman", ShouldNotStartWith, "super"), "Expected 'superman' NOT to start with 'super' (but it did)!")
+	pass(t, so("superman", ShouldNotStartWith, "bat"))
+	pass(t, so("superman", ShouldNotStartWith, "man"))
+
+	fail(t, so(1, ShouldNotStartWith, 2), "Both arguments to this assertion must be strings (you provided int and int).")
+}
+
+func TestShouldEndWith(t *testing.T) {
+	serializer = newFakeSerializer()
+
+	fail(t, so("", ShouldEndWith), "This assertion requires exactly 1 comparison values (you provided 0).")
+	fail(t, so("", ShouldEndWith, "", ""), "This assertion requires exactly 1 comparison values (you provided 2).")
+
+	pass(t, so("", ShouldEndWith, ""))
+	fail(t, so("", ShouldEndWith, "z"), "z||Expected '' to end with 'z' (but it didn't)!")
+	pass(t, so("xyz", ShouldEndWith, "xyz"))
+	fail(t, so("xyz", ShouldEndWith, "wxyz"), "wxyz|xyz|Expected 'xyz' to end with 'wxyz' (but it didn't)!")
+
+	pass(t, so("superman", ShouldEndWith, "man"))
+	fail(t, so("superman", ShouldEndWith, "super"), "super|...erman|Expected 'superman' to end with 'super' (but it didn't)!")
+	fail(t, so("superman", ShouldEndWith, "blah"), "blah|...rman|Expected 'superman' to end with 'blah' (but it didn't)!")
+
+	fail(t, so(1, ShouldEndWith, 2), "Both arguments to this assertion must be strings (you provided int and int).")
+}
+
+func TestShouldNotEndWith(t *testing.T) {
+	fail(t, so("", ShouldNotEndWith), "This assertion requires exactly 1 comparison values (you provided 0).")
+	fail(t, so("", ShouldNotEndWith, "", ""), "This assertion requires exactly 1 comparison values (you provided 2).")
+
+	fail(t, so("", ShouldNotEndWith, ""), "Expected '<empty>' NOT to end with '<empty>' (but it did)!")
+	fail(t, so("superman", ShouldNotEndWith, "man"), "Expected 'superman' NOT to end with 'man' (but it did)!")
+	pass(t, so("superman", ShouldNotEndWith, "super"))
+
+	fail(t, so(1, ShouldNotEndWith, 2), "Both arguments to this assertion must be strings (you provided int and int).")
+}
+
+func TestShouldContainSubstring(t *testing.T) {
+	serializer = newFakeSerializer()
+
+	fail(t, so("asdf", ShouldContainSubstring), "This assertion requires exactly 1 comparison values (you provided 0).")
+	fail(t, so("asdf", ShouldContainSubstring, 1, 2, 3), "This assertion requires exactly 1 comparison values (you provided 3).")
+
+	fail(t, so(123, ShouldContainSubstring, 23), "Both arguments to this assertion must be strings (you provided int and int).")
+
+	pass(t, so("asdf", ShouldContainSubstring, "sd"))
+	fail(t, so("qwer", ShouldContainSubstring, "sd"), "sd|qwer|Expected 'qwer' to contain substring 'sd' (but it didn't)!")
+}
+
+func TestShouldNotContainSubstring(t *testing.T) {
+	fail(t, so("asdf", ShouldNotContainSubstring), "This assertion requires exactly 1 comparison values (you provided 0).")
+	fail(t, so("asdf", ShouldNotContainSubstring, 1, 2, 3), "This assertion requires exactly 1 comparison values (you provided 3).")
+
+	fail(t, so(123, ShouldNotContainSubstring, 23), "Both arguments to this assertion must be strings (you provided int and int).")
+
+	pass(t, so("qwer", ShouldNotContainSubstring, "sd"))
+	fail(t, so("asdf", ShouldNotContainSubstring, "sd"), "Expected 'asdf' NOT to contain substring 'sd' (but it didn't)!")
+}
+
+func TestShouldBeBlank(t *testing.T) {
+	serializer = newFakeSerializer()
+
+	fail(t, so("", ShouldBeBlank, "adsf"), "This assertion requires exactly 0 comparison values (you provided 1).")
+	fail(t, so(1, ShouldBeBlank), "The argument to this assertion must be a string (you provided int).")
+
+	fail(t, so("asdf", ShouldBeBlank), "|asdf|Expected 'asdf' to be blank (but it wasn't)!")
+	pass(t, so("", ShouldBeBlank))
+}
+
+func TestShouldNotBeBlank(t *testing.T) {
+	fail(t, so("", ShouldNotBeBlank, "adsf"), "This assertion requires exactly 0 comparison values (you provided 1).")
+	fail(t, so(1, ShouldNotBeBlank), "The argument to this assertion must be a string (you provided int).")
+
+	fail(t, so("", ShouldNotBeBlank), "Expected value to NOT be blank (but it was)!")
+	pass(t, so("asdf", ShouldNotBeBlank))
+}

+ 202 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/time.go

@@ -0,0 +1,202 @@
+package assertions
+
+import (
+	"fmt"
+	"time"
+)
+
+// ShouldHappenBefore receives exactly 2 time.Time arguments and asserts that the first happens before the second.
+func ShouldHappenBefore(actual interface{}, expected ...interface{}) string {
+	if fail := need(1, expected); fail != success {
+		return fail
+	}
+	actualTime, firstOk := actual.(time.Time)
+	expectedTime, secondOk := expected[0].(time.Time)
+
+	if !firstOk || !secondOk {
+		return shouldUseTimes
+	}
+
+	if !actualTime.Before(expectedTime) {
+		return fmt.Sprintf(shouldHaveHappenedBefore, actualTime, expectedTime, actualTime.Sub(expectedTime))
+	}
+
+	return success
+}
+
+// ShouldHappenOnOrBefore receives exactly 2 time.Time arguments and asserts that the first happens on or before the second.
+func ShouldHappenOnOrBefore(actual interface{}, expected ...interface{}) string {
+	if fail := need(1, expected); fail != success {
+		return fail
+	}
+	actualTime, firstOk := actual.(time.Time)
+	expectedTime, secondOk := expected[0].(time.Time)
+
+	if !firstOk || !secondOk {
+		return shouldUseTimes
+	}
+
+	if actualTime.Equal(expectedTime) {
+		return success
+	}
+	return ShouldHappenBefore(actualTime, expectedTime)
+}
+
+// ShouldHappenAfter receives exactly 2 time.Time arguments and asserts that the first happens after the second.
+func ShouldHappenAfter(actual interface{}, expected ...interface{}) string {
+	if fail := need(1, expected); fail != success {
+		return fail
+	}
+	actualTime, firstOk := actual.(time.Time)
+	expectedTime, secondOk := expected[0].(time.Time)
+
+	if !firstOk || !secondOk {
+		return shouldUseTimes
+	}
+	if !actualTime.After(expectedTime) {
+		return fmt.Sprintf(shouldHaveHappenedAfter, actualTime, expectedTime, expectedTime.Sub(actualTime))
+	}
+	return success
+}
+
+// ShouldHappenOnOrAfter receives exactly 2 time.Time arguments and asserts that the first happens on or after the second.
+func ShouldHappenOnOrAfter(actual interface{}, expected ...interface{}) string {
+	if fail := need(1, expected); fail != success {
+		return fail
+	}
+	actualTime, firstOk := actual.(time.Time)
+	expectedTime, secondOk := expected[0].(time.Time)
+
+	if !firstOk || !secondOk {
+		return shouldUseTimes
+	}
+	if actualTime.Equal(expectedTime) {
+		return success
+	}
+	return ShouldHappenAfter(actualTime, expectedTime)
+}
+
+// ShouldHappenBetween receives exactly 3 time.Time arguments and asserts that the first happens between (not on) the second and third.
+func ShouldHappenBetween(actual interface{}, expected ...interface{}) string {
+	if fail := need(2, expected); fail != success {
+		return fail
+	}
+	actualTime, firstOk := actual.(time.Time)
+	min, secondOk := expected[0].(time.Time)
+	max, thirdOk := expected[1].(time.Time)
+
+	if !firstOk || !secondOk || !thirdOk {
+		return shouldUseTimes
+	}
+
+	if !actualTime.After(min) {
+		return fmt.Sprintf(shouldHaveHappenedBetween, actualTime, min, max, min.Sub(actualTime))
+	}
+	if !actualTime.Before(max) {
+		return fmt.Sprintf(shouldHaveHappenedBetween, actualTime, min, max, actualTime.Sub(max))
+	}
+	return success
+}
+
+// ShouldHappenOnOrBetween receives exactly 3 time.Time arguments and asserts that the first happens between or on the second and third.
+func ShouldHappenOnOrBetween(actual interface{}, expected ...interface{}) string {
+	if fail := need(2, expected); fail != success {
+		return fail
+	}
+	actualTime, firstOk := actual.(time.Time)
+	min, secondOk := expected[0].(time.Time)
+	max, thirdOk := expected[1].(time.Time)
+
+	if !firstOk || !secondOk || !thirdOk {
+		return shouldUseTimes
+	}
+	if actualTime.Equal(min) || actualTime.Equal(max) {
+		return success
+	}
+	return ShouldHappenBetween(actualTime, min, max)
+}
+
+// ShouldNotHappenOnOrBetween receives exactly 3 time.Time arguments and asserts that the first
+// does NOT happen between or on the second or third.
+func ShouldNotHappenOnOrBetween(actual interface{}, expected ...interface{}) string {
+	if fail := need(2, expected); fail != success {
+		return fail
+	}
+	actualTime, firstOk := actual.(time.Time)
+	min, secondOk := expected[0].(time.Time)
+	max, thirdOk := expected[1].(time.Time)
+
+	if !firstOk || !secondOk || !thirdOk {
+		return shouldUseTimes
+	}
+	if actualTime.Equal(min) || actualTime.Equal(max) {
+		return fmt.Sprintf(shouldNotHaveHappenedOnOrBetween, actualTime, min, max)
+	}
+	if actualTime.After(min) && actualTime.Before(max) {
+		return fmt.Sprintf(shouldNotHaveHappenedOnOrBetween, actualTime, min, max)
+	}
+	return success
+}
+
+// ShouldHappenWithin receives a time.Time, a time.Duration, and a time.Time (3 arguments)
+// and asserts that the first time.Time happens within or on the duration specified relative to
+// the other time.Time.
+func ShouldHappenWithin(actual interface{}, expected ...interface{}) string {
+	if fail := need(2, expected); fail != success {
+		return fail
+	}
+	actualTime, firstOk := actual.(time.Time)
+	tolerance, secondOk := expected[0].(time.Duration)
+	threshold, thirdOk := expected[1].(time.Time)
+
+	if !firstOk || !secondOk || !thirdOk {
+		return shouldUseDurationAndTime
+	}
+
+	min := threshold.Add(-tolerance)
+	max := threshold.Add(tolerance)
+	return ShouldHappenOnOrBetween(actualTime, min, max)
+}
+
+// ShouldNotHappenWithin receives a time.Time, a time.Duration, and a time.Time (3 arguments)
+// and asserts that the first time.Time does NOT happen within or on the duration specified relative to
+// the other time.Time.
+func ShouldNotHappenWithin(actual interface{}, expected ...interface{}) string {
+	if fail := need(2, expected); fail != success {
+		return fail
+	}
+	actualTime, firstOk := actual.(time.Time)
+	tolerance, secondOk := expected[0].(time.Duration)
+	threshold, thirdOk := expected[1].(time.Time)
+
+	if !firstOk || !secondOk || !thirdOk {
+		return shouldUseDurationAndTime
+	}
+
+	min := threshold.Add(-tolerance)
+	max := threshold.Add(tolerance)
+	return ShouldNotHappenOnOrBetween(actualTime, min, max)
+}
+
+// ShouldBeChronological receives a []time.Time slice and asserts that the are
+// in chronological order starting with the first time.Time as the earliest.
+func ShouldBeChronological(actual interface{}, expected ...interface{}) string {
+	if fail := need(0, expected); fail != success {
+		return fail
+	}
+
+	times, ok := actual.([]time.Time)
+	if !ok {
+		return shouldUseTimeSlice
+	}
+
+	var previous time.Time
+	for i, current := range times {
+		if i > 0 && current.Before(previous) {
+			return fmt.Sprintf(shouldHaveBeenChronological,
+				i, i-1, previous.String(), i, current.String())
+		}
+		previous = current
+	}
+	return ""
+}

+ 159 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/time_test.go

@@ -0,0 +1,159 @@
+package assertions
+
+import (
+	"fmt"
+	"testing"
+	"time"
+)
+
+func TestShouldHappenBefore(t *testing.T) {
+	fail(t, so(0, ShouldHappenBefore), "This assertion requires exactly 1 comparison values (you provided 0).")
+	fail(t, so(0, ShouldHappenBefore, 1, 2, 3), "This assertion requires exactly 1 comparison values (you provided 3).")
+
+	fail(t, so(0, ShouldHappenBefore, 1), shouldUseTimes)
+	fail(t, so(0, ShouldHappenBefore, time.Now()), shouldUseTimes)
+	fail(t, so(time.Now(), ShouldHappenBefore, 0), shouldUseTimes)
+
+	fail(t, so(january3, ShouldHappenBefore, january1), fmt.Sprintf("Expected '%s' to happen before '%s' (it happened '48h0m0s' after)!", pretty(january3), pretty(january1)))
+	fail(t, so(january3, ShouldHappenBefore, january3), fmt.Sprintf("Expected '%s' to happen before '%s' (it happened '0' after)!", pretty(january3), pretty(january3)))
+	pass(t, so(january1, ShouldHappenBefore, january3))
+}
+
+func TestShouldHappenOnOrBefore(t *testing.T) {
+	fail(t, so(0, ShouldHappenOnOrBefore), "This assertion requires exactly 1 comparison values (you provided 0).")
+	fail(t, so(0, ShouldHappenOnOrBefore, 1, 2, 3), "This assertion requires exactly 1 comparison values (you provided 3).")
+
+	fail(t, so(0, ShouldHappenOnOrBefore, 1), shouldUseTimes)
+	fail(t, so(0, ShouldHappenOnOrBefore, time.Now()), shouldUseTimes)
+	fail(t, so(time.Now(), ShouldHappenOnOrBefore, 0), shouldUseTimes)
+
+	fail(t, so(january3, ShouldHappenOnOrBefore, january1), fmt.Sprintf("Expected '%s' to happen before '%s' (it happened '48h0m0s' after)!", pretty(january3), pretty(january1)))
+	pass(t, so(january3, ShouldHappenOnOrBefore, january3))
+	pass(t, so(january1, ShouldHappenOnOrBefore, january3))
+}
+
+func TestShouldHappenAfter(t *testing.T) {
+	fail(t, so(0, ShouldHappenAfter), "This assertion requires exactly 1 comparison values (you provided 0).")
+	fail(t, so(0, ShouldHappenAfter, 1, 2, 3), "This assertion requires exactly 1 comparison values (you provided 3).")
+
+	fail(t, so(0, ShouldHappenAfter, 1), shouldUseTimes)
+	fail(t, so(0, ShouldHappenAfter, time.Now()), shouldUseTimes)
+	fail(t, so(time.Now(), ShouldHappenAfter, 0), shouldUseTimes)
+
+	fail(t, so(january1, ShouldHappenAfter, january2), fmt.Sprintf("Expected '%s' to happen after '%s' (it happened '24h0m0s' before)!", pretty(january1), pretty(january2)))
+	fail(t, so(january1, ShouldHappenAfter, january1), fmt.Sprintf("Expected '%s' to happen after '%s' (it happened '0' before)!", pretty(january1), pretty(january1)))
+	pass(t, so(january3, ShouldHappenAfter, january1))
+}
+
+func TestShouldHappenOnOrAfter(t *testing.T) {
+	fail(t, so(0, ShouldHappenOnOrAfter), "This assertion requires exactly 1 comparison values (you provided 0).")
+	fail(t, so(0, ShouldHappenOnOrAfter, 1, 2, 3), "This assertion requires exactly 1 comparison values (you provided 3).")
+
+	fail(t, so(0, ShouldHappenOnOrAfter, 1), shouldUseTimes)
+	fail(t, so(0, ShouldHappenOnOrAfter, time.Now()), shouldUseTimes)
+	fail(t, so(time.Now(), ShouldHappenOnOrAfter, 0), shouldUseTimes)
+
+	fail(t, so(january1, ShouldHappenOnOrAfter, january2), fmt.Sprintf("Expected '%s' to happen after '%s' (it happened '24h0m0s' before)!", pretty(january1), pretty(january2)))
+	pass(t, so(january1, ShouldHappenOnOrAfter, january1))
+	pass(t, so(january3, ShouldHappenOnOrAfter, january1))
+}
+
+func TestShouldHappenBetween(t *testing.T) {
+	fail(t, so(0, ShouldHappenBetween), "This assertion requires exactly 2 comparison values (you provided 0).")
+	fail(t, so(0, ShouldHappenBetween, 1, 2, 3), "This assertion requires exactly 2 comparison values (you provided 3).")
+
+	fail(t, so(0, ShouldHappenBetween, 1, 2), shouldUseTimes)
+	fail(t, so(0, ShouldHappenBetween, time.Now(), time.Now()), shouldUseTimes)
+	fail(t, so(time.Now(), ShouldHappenBetween, 0, time.Now()), shouldUseTimes)
+	fail(t, so(time.Now(), ShouldHappenBetween, time.Now(), 9), shouldUseTimes)
+
+	fail(t, so(january1, ShouldHappenBetween, january2, january4), fmt.Sprintf("Expected '%s' to happen between '%s' and '%s' (it happened '24h0m0s' outside threshold)!", pretty(january1), pretty(january2), pretty(january4)))
+	fail(t, so(january2, ShouldHappenBetween, january2, january4), fmt.Sprintf("Expected '%s' to happen between '%s' and '%s' (it happened '0' outside threshold)!", pretty(january2), pretty(january2), pretty(january4)))
+	pass(t, so(january3, ShouldHappenBetween, january2, january4))
+	fail(t, so(january4, ShouldHappenBetween, january2, january4), fmt.Sprintf("Expected '%s' to happen between '%s' and '%s' (it happened '0' outside threshold)!", pretty(january4), pretty(january2), pretty(january4)))
+	fail(t, so(january5, ShouldHappenBetween, january2, january4), fmt.Sprintf("Expected '%s' to happen between '%s' and '%s' (it happened '24h0m0s' outside threshold)!", pretty(january5), pretty(january2), pretty(january4)))
+}
+
+func TestShouldHappenOnOrBetween(t *testing.T) {
+	fail(t, so(0, ShouldHappenOnOrBetween), "This assertion requires exactly 2 comparison values (you provided 0).")
+	fail(t, so(0, ShouldHappenOnOrBetween, 1, 2, 3), "This assertion requires exactly 2 comparison values (you provided 3).")
+
+	fail(t, so(0, ShouldHappenOnOrBetween, 1, time.Now()), shouldUseTimes)
+	fail(t, so(0, ShouldHappenOnOrBetween, time.Now(), 1), shouldUseTimes)
+	fail(t, so(time.Now(), ShouldHappenOnOrBetween, 0, 1), shouldUseTimes)
+
+	fail(t, so(january1, ShouldHappenOnOrBetween, january2, january4), fmt.Sprintf("Expected '%s' to happen between '%s' and '%s' (it happened '24h0m0s' outside threshold)!", pretty(january1), pretty(january2), pretty(january4)))
+	pass(t, so(january2, ShouldHappenOnOrBetween, january2, january4))
+	pass(t, so(january3, ShouldHappenOnOrBetween, january2, january4))
+	pass(t, so(january4, ShouldHappenOnOrBetween, january2, january4))
+	fail(t, so(january5, ShouldHappenOnOrBetween, january2, january4), fmt.Sprintf("Expected '%s' to happen between '%s' and '%s' (it happened '24h0m0s' outside threshold)!", pretty(january5), pretty(january2), pretty(january4)))
+}
+
+func TestShouldNotHappenOnOrBetween(t *testing.T) {
+	fail(t, so(0, ShouldNotHappenOnOrBetween), "This assertion requires exactly 2 comparison values (you provided 0).")
+	fail(t, so(0, ShouldNotHappenOnOrBetween, 1, 2, 3), "This assertion requires exactly 2 comparison values (you provided 3).")
+
+	fail(t, so(0, ShouldNotHappenOnOrBetween, 1, time.Now()), shouldUseTimes)
+	fail(t, so(0, ShouldNotHappenOnOrBetween, time.Now(), 1), shouldUseTimes)
+	fail(t, so(time.Now(), ShouldNotHappenOnOrBetween, 0, 1), shouldUseTimes)
+
+	pass(t, so(january1, ShouldNotHappenOnOrBetween, january2, january4))
+	fail(t, so(january2, ShouldNotHappenOnOrBetween, january2, january4), fmt.Sprintf("Expected '%s' to NOT happen on or between '%s' and '%s' (but it did)!", pretty(january2), pretty(january2), pretty(january4)))
+	fail(t, so(january3, ShouldNotHappenOnOrBetween, january2, january4), fmt.Sprintf("Expected '%s' to NOT happen on or between '%s' and '%s' (but it did)!", pretty(january3), pretty(january2), pretty(january4)))
+	fail(t, so(january4, ShouldNotHappenOnOrBetween, january2, january4), fmt.Sprintf("Expected '%s' to NOT happen on or between '%s' and '%s' (but it did)!", pretty(january4), pretty(january2), pretty(january4)))
+	pass(t, so(january5, ShouldNotHappenOnOrBetween, january2, january4))
+}
+
+func TestShouldHappenWithin(t *testing.T) {
+	fail(t, so(0, ShouldHappenWithin), "This assertion requires exactly 2 comparison values (you provided 0).")
+	fail(t, so(0, ShouldHappenWithin, 1, 2, 3), "This assertion requires exactly 2 comparison values (you provided 3).")
+
+	fail(t, so(0, ShouldHappenWithin, 1, 2), shouldUseDurationAndTime)
+	fail(t, so(0, ShouldHappenWithin, oneDay, time.Now()), shouldUseDurationAndTime)
+	fail(t, so(time.Now(), ShouldHappenWithin, 0, time.Now()), shouldUseDurationAndTime)
+
+	fail(t, so(january1, ShouldHappenWithin, oneDay, january3), fmt.Sprintf("Expected '%s' to happen between '%s' and '%s' (it happened '24h0m0s' outside threshold)!", pretty(january1), pretty(january2), pretty(january4)))
+	pass(t, so(january2, ShouldHappenWithin, oneDay, january3))
+	pass(t, so(january3, ShouldHappenWithin, oneDay, january3))
+	pass(t, so(january4, ShouldHappenWithin, oneDay, january3))
+	fail(t, so(january5, ShouldHappenWithin, oneDay, january3), fmt.Sprintf("Expected '%s' to happen between '%s' and '%s' (it happened '24h0m0s' outside threshold)!", pretty(january5), pretty(january2), pretty(january4)))
+}
+
+func TestShouldNotHappenWithin(t *testing.T) {
+	fail(t, so(0, ShouldNotHappenWithin), "This assertion requires exactly 2 comparison values (you provided 0).")
+	fail(t, so(0, ShouldNotHappenWithin, 1, 2, 3), "This assertion requires exactly 2 comparison values (you provided 3).")
+
+	fail(t, so(0, ShouldNotHappenWithin, 1, 2), shouldUseDurationAndTime)
+	fail(t, so(0, ShouldNotHappenWithin, oneDay, time.Now()), shouldUseDurationAndTime)
+	fail(t, so(time.Now(), ShouldNotHappenWithin, 0, time.Now()), shouldUseDurationAndTime)
+
+	pass(t, so(january1, ShouldNotHappenWithin, oneDay, january3))
+	fail(t, so(january2, ShouldNotHappenWithin, oneDay, january3), fmt.Sprintf("Expected '%s' to NOT happen on or between '%s' and '%s' (but it did)!", pretty(january2), pretty(january2), pretty(january4)))
+	fail(t, so(january3, ShouldNotHappenWithin, oneDay, january3), fmt.Sprintf("Expected '%s' to NOT happen on or between '%s' and '%s' (but it did)!", pretty(january3), pretty(january2), pretty(january4)))
+	fail(t, so(january4, ShouldNotHappenWithin, oneDay, january3), fmt.Sprintf("Expected '%s' to NOT happen on or between '%s' and '%s' (but it did)!", pretty(january4), pretty(january2), pretty(january4)))
+	pass(t, so(january5, ShouldNotHappenWithin, oneDay, january3))
+}
+
+func TestShouldBeChronological(t *testing.T) {
+	fail(t, so(0, ShouldBeChronological, 1, 2, 3), "This assertion requires exactly 0 comparison values (you provided 3).")
+	fail(t, so(0, ShouldBeChronological), shouldUseTimeSlice)
+	fail(t, so([]time.Time{january5, january1}, ShouldBeChronological),
+		"The 'Time' at index [1] should have happened after the previous one (but it didn't!):\n  [0]: 2013-01-05 00:00:00 +0000 UTC\n  [1]: 2013-01-01 00:00:00 +0000 UTC (see, it happened before!)")
+
+	pass(t, so([]time.Time{january1, january2, january3, january4, january5}, ShouldBeChronological))
+}
+
+const layout = "2006-01-02 15:04"
+
+var january1, _ = time.Parse(layout, "2013-01-01 00:00")
+var january2, _ = time.Parse(layout, "2013-01-02 00:00")
+var january3, _ = time.Parse(layout, "2013-01-03 00:00")
+var january4, _ = time.Parse(layout, "2013-01-04 00:00")
+var january5, _ = time.Parse(layout, "2013-01-05 00:00")
+
+var oneDay, _ = time.ParseDuration("24h0m0s")
+var twoDays, _ = time.ParseDuration("48h0m0s")
+
+func pretty(t time.Time) string {
+	return fmt.Sprintf("%v", t)
+}

+ 112 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/type.go

@@ -0,0 +1,112 @@
+package assertions
+
+import (
+	"fmt"
+	"reflect"
+)
+
+// ShouldHaveSameTypeAs receives exactly two parameters and compares their underlying types for equality.
+func ShouldHaveSameTypeAs(actual interface{}, expected ...interface{}) string {
+	if fail := need(1, expected); fail != success {
+		return fail
+	}
+
+	first := reflect.TypeOf(actual)
+	second := reflect.TypeOf(expected[0])
+
+	if equal := ShouldEqual(first, second); equal != success {
+		return serializer.serialize(second, first, fmt.Sprintf(shouldHaveBeenA, actual, second, first))
+	}
+	return success
+}
+
+// ShouldNotHaveSameTypeAs receives exactly two parameters and compares their underlying types for inequality.
+func ShouldNotHaveSameTypeAs(actual interface{}, expected ...interface{}) string {
+	if fail := need(1, expected); fail != success {
+		return fail
+	}
+
+	first := reflect.TypeOf(actual)
+	second := reflect.TypeOf(expected[0])
+
+	if equal := ShouldEqual(first, second); equal == success {
+		return fmt.Sprintf(shouldNotHaveBeenA, actual, second)
+	}
+	return success
+}
+
+// ShouldImplement receives exactly two parameters and ensures
+// that the first implements the interface type of the second.
+func ShouldImplement(actual interface{}, expectedList ...interface{}) string {
+	if fail := need(1, expectedList); fail != success {
+		return fail
+	}
+
+	expected := expectedList[0]
+	if fail := ShouldBeNil(expected); fail != success {
+		return shouldCompareWithInterfacePointer
+	}
+
+	if fail := ShouldNotBeNil(actual); fail != success {
+		return shouldNotBeNilActual
+	}
+
+	var actualType reflect.Type
+	if reflect.TypeOf(actual).Kind() != reflect.Ptr {
+		actualType = reflect.PtrTo(reflect.TypeOf(actual))
+	} else {
+		actualType = reflect.TypeOf(actual)
+	}
+
+	expectedType := reflect.TypeOf(expected)
+	if fail := ShouldNotBeNil(expectedType); fail != success {
+		return shouldCompareWithInterfacePointer
+	}
+
+	expectedInterface := expectedType.Elem()
+
+	if actualType == nil {
+		return fmt.Sprintf(shouldHaveImplemented, expectedInterface, actual)
+	}
+
+	if !actualType.Implements(expectedInterface) {
+		return fmt.Sprintf(shouldHaveImplemented, expectedInterface, actualType)
+	}
+	return success
+}
+
+// ShouldNotImplement receives exactly two parameters and ensures
+// that the first does NOT implement the interface type of the second.
+func ShouldNotImplement(actual interface{}, expectedList ...interface{}) string {
+	if fail := need(1, expectedList); fail != success {
+		return fail
+	}
+
+	expected := expectedList[0]
+	if fail := ShouldBeNil(expected); fail != success {
+		return shouldCompareWithInterfacePointer
+	}
+
+	if fail := ShouldNotBeNil(actual); fail != success {
+		return shouldNotBeNilActual
+	}
+
+	var actualType reflect.Type
+	if reflect.TypeOf(actual).Kind() != reflect.Ptr {
+		actualType = reflect.PtrTo(reflect.TypeOf(actual))
+	} else {
+		actualType = reflect.TypeOf(actual)
+	}
+
+	expectedType := reflect.TypeOf(expected)
+	if fail := ShouldNotBeNil(expectedType); fail != success {
+		return shouldCompareWithInterfacePointer
+	}
+
+	expectedInterface := expectedType.Elem()
+
+	if actualType.Implements(expectedInterface) {
+		return fmt.Sprintf(shouldNotHaveImplemented, actualType, expectedInterface)
+	}
+	return success
+}

+ 76 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/type_test.go

@@ -0,0 +1,76 @@
+package assertions
+
+import (
+	"bytes"
+	"io"
+	"net/http"
+	"testing"
+)
+
+func TestShouldHaveSameTypeAs(t *testing.T) {
+	serializer = newFakeSerializer()
+
+	fail(t, so(1, ShouldHaveSameTypeAs), "This assertion requires exactly 1 comparison values (you provided 0).")
+	fail(t, so(1, ShouldHaveSameTypeAs, 1, 2, 3), "This assertion requires exactly 1 comparison values (you provided 3).")
+
+	fail(t, so(nil, ShouldHaveSameTypeAs, 0), "int|<nil>|Expected '<nil>' to be: 'int' (but was: '<nil>')!")
+	fail(t, so(1, ShouldHaveSameTypeAs, "asdf"), "string|int|Expected '1' to be: 'string' (but was: 'int')!")
+
+	pass(t, so(1, ShouldHaveSameTypeAs, 0))
+	pass(t, so(nil, ShouldHaveSameTypeAs, nil))
+}
+
+func TestShouldNotHaveSameTypeAs(t *testing.T) {
+	fail(t, so(1, ShouldNotHaveSameTypeAs), "This assertion requires exactly 1 comparison values (you provided 0).")
+	fail(t, so(1, ShouldNotHaveSameTypeAs, 1, 2, 3), "This assertion requires exactly 1 comparison values (you provided 3).")
+
+	fail(t, so(1, ShouldNotHaveSameTypeAs, 0), "Expected '1' to NOT be: 'int' (but it was)!")
+	fail(t, so(nil, ShouldNotHaveSameTypeAs, nil), "Expected '<nil>' to NOT be: '<nil>' (but it was)!")
+
+	pass(t, so(nil, ShouldNotHaveSameTypeAs, 0))
+	pass(t, so(1, ShouldNotHaveSameTypeAs, "asdf"))
+}
+
+func TestShouldImplement(t *testing.T) {
+	var ioReader *io.Reader = nil
+	var response http.Response = http.Response{}
+	var responsePtr *http.Response = new(http.Response)
+	var reader = bytes.NewBufferString("")
+
+	fail(t, so(reader, ShouldImplement), "This assertion requires exactly 1 comparison values (you provided 0).")
+	fail(t, so(reader, ShouldImplement, ioReader, ioReader), "This assertion requires exactly 1 comparison values (you provided 2).")
+	fail(t, so(reader, ShouldImplement, ioReader, ioReader, ioReader), "This assertion requires exactly 1 comparison values (you provided 3).")
+
+	fail(t, so(reader, ShouldImplement, "foo"), shouldCompareWithInterfacePointer)
+	fail(t, so(reader, ShouldImplement, 1), shouldCompareWithInterfacePointer)
+	fail(t, so(reader, ShouldImplement, nil), shouldCompareWithInterfacePointer)
+
+	fail(t, so(nil, ShouldImplement, ioReader), shouldNotBeNilActual)
+	fail(t, so(1, ShouldImplement, ioReader), "Expected: 'io.Reader interface support'\nActual:   '*int' does not implement the interface!")
+
+	fail(t, so(response, ShouldImplement, ioReader), "Expected: 'io.Reader interface support'\nActual:   '*http.Response' does not implement the interface!")
+	fail(t, so(responsePtr, ShouldImplement, ioReader), "Expected: 'io.Reader interface support'\nActual:   '*http.Response' does not implement the interface!")
+	pass(t, so(reader, ShouldImplement, ioReader))
+	pass(t, so(reader, ShouldImplement, (*io.Reader)(nil)))
+}
+
+func TestShouldNotImplement(t *testing.T) {
+	var ioReader *io.Reader = nil
+	var response http.Response = http.Response{}
+	var responsePtr *http.Response = new(http.Response)
+	var reader io.Reader = bytes.NewBufferString("")
+
+	fail(t, so(reader, ShouldNotImplement), "This assertion requires exactly 1 comparison values (you provided 0).")
+	fail(t, so(reader, ShouldNotImplement, ioReader, ioReader), "This assertion requires exactly 1 comparison values (you provided 2).")
+	fail(t, so(reader, ShouldNotImplement, ioReader, ioReader, ioReader), "This assertion requires exactly 1 comparison values (you provided 3).")
+
+	fail(t, so(reader, ShouldNotImplement, "foo"), shouldCompareWithInterfacePointer)
+	fail(t, so(reader, ShouldNotImplement, 1), shouldCompareWithInterfacePointer)
+	fail(t, so(reader, ShouldNotImplement, nil), shouldCompareWithInterfacePointer)
+
+	fail(t, so(reader, ShouldNotImplement, ioReader), "Expected         '*bytes.Buffer'\nto NOT implement   'io.Reader' (but it did)!")
+	fail(t, so(nil, ShouldNotImplement, ioReader), shouldNotBeNilActual)
+	pass(t, so(1, ShouldNotImplement, ioReader))
+	pass(t, so(response, ShouldNotImplement, ioReader))
+	pass(t, so(responsePtr, ShouldNotImplement, ioReader))
+}

+ 75 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/utilities_for_test.go

@@ -0,0 +1,75 @@
+package assertions
+
+import (
+	"fmt"
+	"path"
+	"runtime"
+	"strings"
+	"testing"
+)
+
+func pass(t *testing.T, result string) {
+	if result != success {
+		_, file, line, _ := runtime.Caller(1)
+		base := path.Base(file)
+		t.Errorf("Expectation should have passed but failed (see %s: line %d): '%s'", base, line, result)
+	}
+}
+
+func fail(t *testing.T, actual string, expected string) {
+	actual = format(actual)
+	expected = format(expected)
+
+	if actual != expected {
+		if actual == "" {
+			actual = "(empty)"
+		}
+		_, file, line, _ := runtime.Caller(1)
+		base := path.Base(file)
+		t.Errorf("Expectation should have failed but passed (see %s: line %d). \nExpected: %s\nActual:   %s\n",
+			base, line, expected, actual)
+	}
+}
+func format(message string) string {
+	message = strings.Replace(message, "\n", " ", -1)
+	for strings.Contains(message, "  ") {
+		message = strings.Replace(message, "  ", " ", -1)
+	}
+	return message
+}
+
+func so(actual interface{}, assert func(interface{}, ...interface{}) string, expected ...interface{}) string {
+	return assert(actual, expected...)
+}
+
+type Thing1 struct {
+	a string
+}
+type Thing2 struct {
+	a string
+}
+
+type Thinger interface {
+	Hi()
+}
+
+type Thing struct{}
+
+func (self *Thing) Hi() {}
+
+type IntAlias int
+type StringAlias string
+type StringSliceAlias []string
+type StringStringMapAlias map[string]string
+
+/******** FakeSerialzier ********/
+
+type fakeSerializer struct{}
+
+func (self *fakeSerializer) serialize(expected, actual interface{}, message string) string {
+	return fmt.Sprintf("%v|%v|%s", expected, actual, message)
+}
+
+func newFakeSerializer() *fakeSerializer {
+	return new(fakeSerializer)
+}

+ 179 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/context.go

@@ -0,0 +1,179 @@
+// Oh the stack trace scanning!
+// The density of comments in this file is evidence that
+// the code doesn't exactly explain itself. Tread with care...
+package convey
+
+import (
+	"errors"
+	"fmt"
+	"runtime"
+	"strconv"
+	"strings"
+	"sync"
+)
+
+const (
+	missingGoTest string = `Top-level calls to Convey(...) need a reference to the *testing.T. 
+		Hint: Convey("description here", t, func() { /* notice that the second argument was the *testing.T (t)! */ }) `
+	extraGoTest string = `Only the top-level call to Convey(...) needs a reference to the *testing.T.`
+)
+
+// suiteContext magically handles all coordination of reporter, runners as they handle calls
+// to Convey, So, and the like. It does this via runtime call stack inspection, making sure
+// that each test function has its own runner, and routes all live registrations
+// to the appropriate runner.
+type suiteContext struct {
+	lock    sync.Mutex
+	runners map[string]*runner // key: testName;
+
+	// stores a correlation to the actual runner for outside-of-stack scenaios
+	locations map[string]string // key: file:line; value: testName (key to runners)
+}
+
+func (self *suiteContext) Run(entry *registration) {
+	if self.current() != nil {
+		panic(extraGoTest)
+	}
+
+	runner := newRunner(buildReporter())
+
+	testName, location, _ := suiteAnchor()
+
+	self.setRunner(location, testName, runner)
+
+	runner.Run(entry)
+
+	self.unsetRunner(location, testName)
+}
+
+func (self *suiteContext) Current() *runner {
+	if runner := self.current(); runner != nil {
+		return runner
+	}
+	panic(missingGoTest)
+}
+func (self *suiteContext) current() *runner {
+	self.lock.Lock()
+	defer self.lock.Unlock()
+
+	if testName, _, err := suiteAnchor(); err == nil {
+		return self.runners[testName]
+	}
+
+	return self.runners[correlate(self.locations)]
+}
+func (self *suiteContext) setRunner(location string, testName string, runner *runner) {
+	self.lock.Lock()
+	defer self.lock.Unlock()
+
+	self.locations[location] = testName
+	self.runners[testName] = runner
+}
+func (self *suiteContext) unsetRunner(location string, testName string) {
+	self.lock.Lock()
+	defer self.lock.Unlock()
+
+	delete(self.locations, location)
+	delete(self.runners, testName)
+}
+
+func newSuiteContext() *suiteContext {
+	return &suiteContext{
+		locations: map[string]string{},
+		runners:   map[string]*runner{},
+	}
+}
+
+//////////////////// Helper Functions ///////////////////////
+
+// suiteAnchor returns the enclosing test function name (including package) and the
+// file:line combination of the top-level Convey. It does this by traversing the
+// call stack in reverse, looking for the go testing harnass call ("testing.tRunner")
+// and then grabs the very next entry.
+func suiteAnchor() (testName, location string, err error) {
+	callers := runtime.Callers(0, callStack)
+
+	for y := callers; y > 0; y-- {
+		callerId, file, conveyLine, found := runtime.Caller(y)
+		if !found {
+			continue
+		}
+
+		if name := runtime.FuncForPC(callerId).Name(); name != goTestHarness {
+			continue
+		}
+
+		callerId, file, conveyLine, _ = runtime.Caller(y - 1)
+		testName = runtime.FuncForPC(callerId).Name()
+		location = fmt.Sprintf("%s:%d", file, conveyLine)
+		return
+	}
+	return "", "", errors.New("Can't resolve test method name! Are you calling Convey() from a `*_test.go` file and a `Test*` method (because you should be)?")
+}
+
+// correlate links the current stack with the appropriate
+// top-level Convey by comparing line numbers in its own stack trace
+// with the registered file:line combo. It's come to this.
+func correlate(locations map[string]string) (testName string) {
+	file, line := resolveTestFileAndLine()
+	closest := -1
+
+	for location, registeredTestName := range locations {
+		locationFile, rawLocationLine := splitFileAndLine(location)
+
+		if locationFile != file {
+			continue
+		}
+
+		locationLine, err := strconv.Atoi(rawLocationLine)
+		if err != nil || locationLine < line {
+			continue
+		}
+
+		if closest == -1 || locationLine < closest {
+			closest = locationLine
+			testName = registeredTestName
+		}
+	}
+	return
+}
+
+// splitFileAndLine receives a path and a line number in a single string,
+// separated by a colon and splits them.
+func splitFileAndLine(value string) (file, line string) {
+	parts := strings.Split(value, ":")
+	if len(parts) == 2 {
+		file = parts[0]
+		line = parts[1]
+	} else if len(parts) > 2 {
+		// 'C:/blah.go:123' (windows drive letter has two colons
+		// '-:--------:---'  instead of just one to separate file and line)
+		file = strings.Join(parts[:2], ":")
+		line = parts[2]
+	}
+	return
+}
+
+// resolveTestFileAndLine is used as a last-ditch effort to correlate an
+// assertion with the right executor and runner.
+func resolveTestFileAndLine() (file string, line int) {
+	callers := runtime.Callers(0, callStack)
+	var found bool
+
+	for y := callers; y > 0; y-- {
+		_, file, line, found = runtime.Caller(y)
+		if !found {
+			continue
+		}
+
+		if strings.HasSuffix(file, "_test.go") {
+			return
+		}
+	}
+	return "", 0
+}
+
+const maxStackDepth = 100               // This had better be enough...
+const goTestHarness = "testing.tRunner" // I hope this doesn't change...
+
+var callStack []uintptr = make([]uintptr, maxStackDepth, maxStackDepth)

+ 57 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/discovery.go

@@ -0,0 +1,57 @@
+package convey
+
+func discover(items []interface{}) *registration {
+	name, items := parseName(items)
+	test, items := parseGoTest(items)
+	action, items := parseAction(items)
+
+	if len(items) != 0 {
+		panic(parseError)
+	}
+
+	return newRegistration(name, action, test)
+}
+func item(items []interface{}) interface{} {
+	if len(items) == 0 {
+		panic(parseError)
+	}
+	return items[0]
+}
+func parseName(items []interface{}) (string, []interface{}) {
+	if name, parsed := item(items).(string); parsed {
+		return name, items[1:]
+	}
+	panic(parseError)
+}
+func parseGoTest(items []interface{}) (t, []interface{}) {
+	if test, parsed := item(items).(t); parsed {
+		return test, items[1:]
+	}
+	return nil, items
+}
+func parseFailureMode(items []interface{}) (FailureMode, []interface{}) {
+	if mode, parsed := item(items).(FailureMode); parsed {
+		return mode, items[1:]
+	}
+	return FailureInherits, items
+}
+func parseAction(items []interface{}) (*action, []interface{}) {
+	failure, items := parseFailureMode(items)
+
+	if action, parsed := item(items).(func()); parsed {
+		return newAction(action, failure), items[1:]
+	}
+	if item(items) == nil {
+		return newSkippedAction(skipReport, failure), items[1:]
+	}
+	panic(parseError)
+}
+
+// This interface allows us to pass the *testing.T struct
+// throughout the internals of this tool without ever
+// having to import the "testing" package.
+type t interface {
+	Fail()
+}
+
+const parseError = "You must provide a name (string), then a *testing.T (if in outermost scope), an optional FailureMode, and then an action (func())."

+ 178 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/doc.go

@@ -0,0 +1,178 @@
+// Package convey contains all of the public-facing entry points to this project.
+// This means that it should never be required of the user to import any other
+// packages from this project as they serve internal purposes.
+package convey
+
+import (
+	"fmt"
+
+	"github.com/smartystreets/goconvey/convey/reporting"
+)
+
+////////////////////////////////// Registration //////////////////////////////////
+
+// Convey is the method intended for use when declaring the scopes
+// of a specification. Each scope has a description and a func()
+// which may contain other calls to Convey(), Reset() or Should-style
+// assertions. Convey calls can be nested as far as you see fit.
+//
+// IMPORTANT NOTE: The top-level Convey() within a Test method
+// must conform to the following signature:
+//
+//     Convey(description string, t *testing.T, action func())
+//
+// All other calls should like like this (no need to pass in *testing.T):
+//
+//     Convey(description string, action func())
+//
+// Don't worry, the goconvey will panic if you get it wrong so you can fix it.
+//
+// All Convey()-blocks also take an optional parameter of FailureMode which
+// sets how goconvey should treat failures for So()-assertions in the block and
+// nested blocks. See the constants in this file for the available options.
+//
+// By default it will inherit from its parent block and the top-level blocks
+// start with setting of FailureHalts.
+//
+// This parameter is inserted before the block itself:
+//
+//     Convey(description string, t *testing.T, mode FailureMode, action func())
+//     Convey(description string, mode FailureMode, action func())
+//
+// See the examples package for, well, examples.
+func Convey(items ...interface{}) {
+	register(discover(items))
+}
+
+// SkipConvey is analagous to Convey except that the scope is not executed
+// (which means that child scopes defined within this scope are not run either).
+// The reporter will be notified that this step was skipped.
+func SkipConvey(items ...interface{}) {
+	entry := discover(items)
+	entry.action = newSkippedAction(skipReport, entry.action.failureMode)
+
+	register(entry)
+}
+
+// FocusConvey is has the inverse effect of SkipConvey. If the top-level
+// Convey is changed to `FocusConvey`, only nested scopes that are defined
+// with FocusConvey will be run. The rest will be ignored completely. This
+// is handy when debugging a large suite that runs a misbehaving function
+// repeatedly as you can disable all but one of that function
+// without swaths of `SkipConvey` calls, just a targeted chain of calls
+// to FocusConvey.
+func FocusConvey(items ...interface{}) {
+	entry := discover(items)
+	entry.Focus = true
+
+	register(entry)
+}
+
+func register(entry *registration) {
+	if entry.ShouldBeTopLevel() {
+		suites.Run(entry)
+	} else {
+		suites.Current().Register(entry)
+	}
+}
+
+func skipReport() {
+	suites.Current().Report(reporting.NewSkipReport())
+}
+
+// Reset registers a cleanup function to be run after each Convey()
+// in the same scope. See the examples package for a simple use case.
+func Reset(action func()) {
+	/* TODO: Failure mode configuration */
+	suites.Current().RegisterReset(newAction(action, FailureInherits))
+}
+
+/////////////////////////////////// Assertions ///////////////////////////////////
+
+// assertion is an alias for a function with a signature that the convey.So()
+// method can handle. Any future or custom assertions should conform to this
+// method signature. The return value should be an empty string if the assertion
+// passes and a well-formed failure message if not.
+type assertion func(actual interface{}, expected ...interface{}) string
+
+const assertionSuccess = ""
+
+// So is the means by which assertions are made against the system under test.
+// The majority of exported names in the assertions package begin with the word
+// 'Should' and describe how the first argument (actual) should compare with any
+// of the final (expected) arguments. How many final arguments are accepted
+// depends on the particular assertion that is passed in as the assert argument.
+// See the examples package for use cases and the assertions package for
+// documentation on specific assertion methods.
+func So(actual interface{}, assert assertion, expected ...interface{}) {
+	if result := assert(actual, expected...); result == assertionSuccess {
+		suites.Current().Report(reporting.NewSuccessReport())
+	} else {
+		suites.Current().Report(reporting.NewFailureReport(result))
+	}
+}
+
+// SkipSo is analagous to So except that the assertion that would have been passed
+// to So is not executed and the reporter is notified that the assertion was skipped.
+func SkipSo(stuff ...interface{}) {
+	skipReport()
+}
+
+// FailureMode is a type which determines how the So() blocks should fail
+// if their assertion fails. See constants further down for acceptable values
+type FailureMode string
+
+const (
+
+	// FailureContinues is a failure mode which prevents failing
+	// So()-assertions from halting Convey-block execution, instead
+	// allowing the test to continue past failing So()-assertions.
+	FailureContinues FailureMode = "continue"
+
+	// FailureHalts is the default setting for a top-level Convey()-block
+	// and will cause all failing So()-assertions to halt further execution
+	// in that test-arm and continue on to the next arm.
+	FailureHalts FailureMode = "halt"
+
+	// FailureInherits is the default setting for failure-mode, it will
+	// default to the failure-mode of the parent block. You should never
+	// need to specify this mode in your tests..
+	FailureInherits FailureMode = "inherits"
+)
+
+var defaultFailureMode FailureMode = FailureHalts
+
+// SetDefaultFailureMode allows you to specify the default failure mode
+// for all Convey blocks. It is meant to be used in an init function to
+// allow the default mode to be changd across all tests for an entire packgae
+// but it can be used anywhere.
+func SetDefaultFailureMode(mode FailureMode) {
+	if mode == FailureContinues || mode == FailureHalts {
+		defaultFailureMode = mode
+	} else {
+		panic("You may only use the constants named 'FailureContinues' and 'FailureHalts' as default failure modes.")
+	}
+}
+
+//////////////////////////////////// Print functions ////////////////////////////////////
+
+// Print is analogous to fmt.Print (and it even calls fmt.Print). It ensures that
+// output is aligned with the corresponding scopes in the web UI.
+func Print(items ...interface{}) (written int, err error) {
+	fmt.Fprint(suites.Current(), items...)
+	return fmt.Print(items...)
+}
+
+// Print is analogous to fmt.Println (and it even calls fmt.Println). It ensures that
+// output is aligned with the corresponding scopes in the web UI.
+func Println(items ...interface{}) (written int, err error) {
+	fmt.Fprintln(suites.Current(), items...)
+	return fmt.Println(items...)
+}
+
+// Print is analogous to fmt.Printf (and it even calls fmt.Printf). It ensures that
+// output is aligned with the corresponding scopes in the web UI.
+func Printf(format string, items ...interface{}) (written int, err error) {
+	fmt.Fprintf(suites.Current(), format, items...)
+	return fmt.Printf(format, items...)
+}

+ 72 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/focused_execution_test.go

@@ -0,0 +1,72 @@
+package convey
+
+import "testing"
+
+func TestFocusOnlyAtTopLevel(t *testing.T) {
+	output := prepare()
+
+	FocusConvey("hi", t, func() {
+		output += "done"
+	})
+
+	expectEqual(t, "done", output)
+}
+
+func TestFocus(t *testing.T) {
+	output := prepare()
+
+	FocusConvey("hi", t, func() {
+		output += "1"
+
+		Convey("bye", func() {
+			output += "2"
+		})
+	})
+
+	expectEqual(t, "1", output)
+}
+
+func TestNestedFocus(t *testing.T) {
+	output := prepare()
+
+	FocusConvey("hi", t, func() {
+		output += "1"
+
+		Convey("This shouldn't run", func() {
+			output += "boink!"
+		})
+
+		FocusConvey("This should run", func() {
+			output += "2"
+
+			FocusConvey("The should run too", func() {
+				output += "3"
+
+			})
+
+			Convey("The should NOT run", func() {
+				output += "blah blah blah!"
+			})
+		})
+	})
+
+	expectEqual(t, "123", output)
+}
+
+func TestForgotTopLevelFocus(t *testing.T) {
+	output := prepare()
+
+	Convey("1", t, func() {
+		output += "1"
+
+		FocusConvey("This will be run because the top-level lacks Focus", func() {
+			output += "2"
+		})
+
+		Convey("3", func() {
+			output += "3"
+		})
+	})
+
+	expectEqual(t, "1213", output)
+}

+ 37 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/gotest/utils.go

@@ -0,0 +1,37 @@
+// Package gotest contains internal functionality. Although this package
+// contains one or more exported names it is not intended for public
+// consumption. See the examples package for how to use this project.
+package gotest
+
+import (
+	"fmt"
+	"runtime"
+	"strings"
+)
+
+func FormatExternalFileAndLine() string {
+	file, line, _ := ResolveExternalCaller()
+	if line == -1 {
+		return "<unknown caller!>" // panic?
+	}
+	return fmt.Sprintf("%s:%d", file, line)
+}
+
+func ResolveExternalCaller() (file string, line int, name string) {
+	var caller_id uintptr
+	callers := runtime.Callers(0, callStack)
+
+	for x := 0; x < callers; x++ {
+		caller_id, file, line, _ = runtime.Caller(x)
+		if strings.HasSuffix(file, "_test.go") {
+			name = runtime.FuncForPC(caller_id).Name()
+			return
+		}
+	}
+	file, line, name = "<unkown file>", -1, "<unknown name>"
+	return // panic?
+}
+
+const maxStackDepth = 100 // This had better be enough...
+
+var callStack []uintptr = make([]uintptr, maxStackDepth, maxStackDepth)

+ 72 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/init.go

@@ -0,0 +1,72 @@
+package convey
+
+import (
+	"flag"
+	"os"
+
+	"github.com/smartystreets/goconvey/convey/reporting"
+)
+
+func init() {
+	declareFlags()
+
+	suites = newSuiteContext()
+}
+
+func declareFlags() {
+	flag.BoolVar(&json, "json", false, "When true, emits results in JSON blocks. Default: 'false'")
+	flag.BoolVar(&silent, "silent", false, "When true, all output from GoConvey is suppressed.")
+	flag.BoolVar(&story, "story", false, "When true, emits story output, otherwise emits dot output. When not provided, this flag mirros the value of the '-test.v' flag")
+
+	if noStoryFlagProvided() {
+		story = verboseEnabled
+	}
+
+	// FYI: flag.Parse() is called from the testing package.
+}
+
+func noStoryFlagProvided() bool {
+	return !story && !storyDisabled
+}
+
+func buildReporter() reporting.Reporter {
+	switch {
+	case testReporter != nil:
+		return testReporter
+	case json:
+		return reporting.BuildJsonReporter()
+	case silent:
+		return reporting.BuildSilentReporter()
+	case story:
+		return reporting.BuildStoryReporter()
+	default:
+		return reporting.BuildDotReporter()
+	}
+}
+
+var (
+	suites *suiteContext
+
+	// only set by internal tests
+	testReporter reporting.Reporter
+)
+
+var (
+	json   bool
+	silent bool
+	story  bool
+
+	verboseEnabled = flagFound("-test.v=true")
+	storyDisabled  = flagFound("-story=false")
+)
+
+// flagFound parses the command line args manually for flags defined in other
+// packages. Like the '-v' flag from the "testing" package, for instance.
+func flagFound(flagValue string) bool {
+	for _, arg := range os.Args {
+		if arg == flagValue {
+			return true
+		}
+	}
+	return false
+}

+ 742 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/isolated_execution_test.go

@@ -0,0 +1,742 @@
+package convey
+
+import (
+	"strconv"
+	"testing"
+	"time"
+)
+
+func TestSingleScope(t *testing.T) {
+	output := prepare()
+
+	Convey("hi", t, func() {
+		output += "done"
+	})
+
+	expectEqual(t, "done", output)
+}
+
+func TestSingleScopeWithMultipleConveys(t *testing.T) {
+	output := prepare()
+
+	Convey("1", t, func() {
+		output += "1"
+	})
+
+	Convey("2", t, func() {
+		output += "2"
+	})
+
+	expectEqual(t, "12", output)
+}
+
+func TestNestedScopes(t *testing.T) {
+	output := prepare()
+
+	Convey("a", t, func() {
+		output += "a "
+
+		Convey("bb", func() {
+			output += "bb "
+
+			Convey("ccc", func() {
+				output += "ccc | "
+			})
+		})
+	})
+
+	expectEqual(t, "a bb ccc | ", output)
+}
+
+func TestNestedScopesWithIsolatedExecution(t *testing.T) {
+	output := prepare()
+
+	Convey("a", t, func() {
+		output += "a "
+
+		Convey("aa", func() {
+			output += "aa "
+
+			Convey("aaa", func() {
+				output += "aaa | "
+			})
+
+			Convey("aaa1", func() {
+				output += "aaa1 | "
+			})
+		})
+
+		Convey("ab", func() {
+			output += "ab "
+
+			Convey("abb", func() {
+				output += "abb | "
+			})
+		})
+	})
+
+	expectEqual(t, "a aa aaa | a aa aaa1 | a ab abb | ", output)
+}
+
+func TestSingleScopeWithConveyAndNestedReset(t *testing.T) {
+	output := prepare()
+
+	Convey("1", t, func() {
+		output += "1"
+
+		Reset(func() {
+			output += "a"
+		})
+	})
+
+	expectEqual(t, "1a", output)
+}
+
+func TestSingleScopeWithMultipleRegistrationsAndReset(t *testing.T) {
+	output := prepare()
+
+	Convey("reset after each nested convey", t, func() {
+		Convey("first output", func() {
+			output += "1"
+		})
+
+		Convey("second output", func() {
+			output += "2"
+		})
+
+		Reset(func() {
+			output += "a"
+		})
+	})
+
+	expectEqual(t, "1a2a", output)
+}
+
+func TestSingleScopeWithMultipleRegistrationsAndMultipleResets(t *testing.T) {
+	output := prepare()
+
+	Convey("each reset is run at end of each nested convey", t, func() {
+		Convey("1", func() {
+			output += "1"
+		})
+
+		Convey("2", func() {
+			output += "2"
+		})
+
+		Reset(func() {
+			output += "a"
+		})
+
+		Reset(func() {
+			output += "b"
+		})
+	})
+
+	expectEqual(t, "1ab2ab", output)
+}
+
+func Test_Failure_AtHigherLevelScopePreventsChildScopesFromRunning(t *testing.T) {
+	output := prepare()
+
+	Convey("This step fails", t, func() {
+		So(1, ShouldEqual, 2)
+
+		Convey("this should NOT be executed", func() {
+			output += "a"
+		})
+	})
+
+	expectEqual(t, "", output)
+}
+
+func Test_Panic_AtHigherLevelScopePreventsChildScopesFromRunning(t *testing.T) {
+	output := prepare()
+
+	Convey("This step panics", t, func() {
+		Convey("this should NOT be executed", func() {
+			output += "1"
+		})
+
+		panic("Hi")
+	})
+
+	expectEqual(t, "", output)
+}
+
+func Test_Panic_InChildScopeDoes_NOT_PreventExecutionOfSiblingScopes(t *testing.T) {
+	output := prepare()
+
+	Convey("This is the parent", t, func() {
+		Convey("This step panics", func() {
+			panic("Hi")
+			output += "1"
+		})
+
+		Convey("This sibling should execute", func() {
+			output += "2"
+		})
+	})
+
+	expectEqual(t, "2", output)
+}
+
+func Test_Failure_InChildScopeDoes_NOT_PreventExecutionOfSiblingScopes(t *testing.T) {
+	output := prepare()
+
+	Convey("This is the parent", t, func() {
+		Convey("This step fails", func() {
+			So(1, ShouldEqual, 2)
+			output += "1"
+		})
+
+		Convey("This sibling should execute", func() {
+			output += "2"
+		})
+	})
+
+	expectEqual(t, "2", output)
+}
+
+func TestResetsAreAlwaysExecutedAfterScope_Panics(t *testing.T) {
+	output := prepare()
+
+	Convey("This is the parent", t, func() {
+		Convey("This step panics", func() {
+			panic("Hi")
+			output += "1"
+		})
+
+		Convey("This sibling step does not panic", func() {
+			output += "a"
+
+			Reset(func() {
+				output += "b"
+			})
+		})
+
+		Reset(func() {
+			output += "2"
+		})
+	})
+
+	expectEqual(t, "2ab2", output)
+}
+
+func TestResetsAreAlwaysExecutedAfterScope_Failures(t *testing.T) {
+	output := prepare()
+
+	Convey("This is the parent", t, func() {
+		Convey("This step fails", func() {
+			So(1, ShouldEqual, 2)
+			output += "1"
+		})
+
+		Convey("This sibling step does not fail", func() {
+			output += "a"
+
+			Reset(func() {
+				output += "b"
+			})
+		})
+
+		Reset(func() {
+			output += "2"
+		})
+	})
+
+	expectEqual(t, "2ab2", output)
+}
+
+func TestSkipTopLevel(t *testing.T) {
+	output := prepare()
+
+	SkipConvey("hi", t, func() {
+		output += "This shouldn't be executed!"
+	})
+
+	expectEqual(t, "", output)
+}
+
+func TestSkipNestedLevel(t *testing.T) {
+	output := prepare()
+
+	Convey("hi", t, func() {
+		output += "yes"
+
+		SkipConvey("bye", func() {
+			output += "no"
+		})
+	})
+
+	expectEqual(t, "yes", output)
+}
+
+func TestSkipNestedLevelSkipsAllChildLevels(t *testing.T) {
+	output := prepare()
+
+	Convey("hi", t, func() {
+		output += "yes"
+
+		SkipConvey("bye", func() {
+			output += "no"
+
+			Convey("byebye", func() {
+				output += "no-no"
+			})
+		})
+	})
+
+	expectEqual(t, "yes", output)
+}
+
+func TestIterativeConveys(t *testing.T) {
+	output := prepare()
+
+	Convey("Test", t, func() {
+		for x := 0; x < 10; x++ {
+			y := strconv.Itoa(x)
+
+			Convey(y, func() {
+				output += y
+			})
+		}
+	})
+
+	expectEqual(t, "0123456789", output)
+}
+
+func TestClosureVariables(t *testing.T) {
+	output := prepare()
+
+	i := 0
+
+	Convey("A", t, func() {
+		i = i + 1
+		j := i
+
+		output += "A" + strconv.Itoa(i) + " "
+
+		Convey("B", func() {
+			k := j
+			j = j + 1
+
+			output += "B" + strconv.Itoa(k) + " "
+
+			Convey("C", func() {
+				output += "C" + strconv.Itoa(k) + strconv.Itoa(j) + " "
+			})
+
+			Convey("D", func() {
+				output += "D" + strconv.Itoa(k) + strconv.Itoa(j) + " "
+			})
+		})
+
+		Convey("C", func() {
+			output += "C" + strconv.Itoa(j) + " "
+		})
+	})
+
+	output += "D" + strconv.Itoa(i) + " "
+
+	expectEqual(t, "A1 B1 C12 A2 B2 D23 A3 C3 D3 ", output)
+}
+
+func TestClosureVariablesWithReset(t *testing.T) {
+	output := prepare()
+
+	i := 0
+
+	Convey("A", t, func() {
+		i = i + 1
+		j := i
+
+		output += "A" + strconv.Itoa(i) + " "
+
+		Reset(func() {
+			output += "R" + strconv.Itoa(i) + strconv.Itoa(j) + " "
+		})
+
+		Convey("B", func() {
+			output += "B" + strconv.Itoa(j) + " "
+		})
+
+		Convey("C", func() {
+			output += "C" + strconv.Itoa(j) + " "
+		})
+	})
+
+	output += "D" + strconv.Itoa(i) + " "
+
+	expectEqual(t, "A1 B1 R11 A2 C2 R22 D2 ", output)
+}
+
+func TestWrappedSimple(t *testing.T) {
+	prepare()
+	output := resetTestString{""}
+
+	Convey("A", t, func() {
+		func() {
+			output.output += "A "
+
+			Convey("B", func() {
+				output.output += "B "
+
+				Convey("C", func() {
+					output.output += "C "
+				})
+
+			})
+
+			Convey("D", func() {
+				output.output += "D "
+			})
+		}()
+	})
+
+	expectEqual(t, "A B C A D ", output.output)
+}
+
+type resetTestString struct {
+	output string
+}
+
+func addReset(o *resetTestString, f func()) func() {
+	return func() {
+		Reset(func() {
+			o.output += "R "
+		})
+
+		f()
+	}
+}
+
+func TestWrappedReset(t *testing.T) {
+	prepare()
+	output := resetTestString{""}
+
+	Convey("A", t, addReset(&output, func() {
+		output.output += "A "
+
+		Convey("B", func() {
+			output.output += "B "
+		})
+
+		Convey("C", func() {
+			output.output += "C "
+		})
+	}))
+
+	expectEqual(t, "A B R A C R ", output.output)
+}
+
+func TestWrappedReset2(t *testing.T) {
+	prepare()
+	output := resetTestString{""}
+
+	Convey("A", t, func() {
+		Reset(func() {
+			output.output += "R "
+		})
+
+		func() {
+			output.output += "A "
+
+			Convey("B", func() {
+				output.output += "B "
+
+				Convey("C", func() {
+					output.output += "C "
+				})
+			})
+
+			Convey("D", func() {
+				output.output += "D "
+			})
+		}()
+	})
+
+	expectEqual(t, "A B C R A D R ", output.output)
+}
+
+func TestInfiniteLoopWithTrailingFail(t *testing.T) {
+	done := make(chan int)
+
+	go func() {
+		Convey("This fails", t, func() {
+			Convey("and this is run", func() {
+				So(true, ShouldEqual, true)
+			})
+
+			/* And this prevents the whole block to be marked as run */
+			So(false, ShouldEqual, true)
+		})
+
+		done <- 1
+	}()
+
+	select {
+	case <-done:
+		return
+	case <-time.After(1 * time.Millisecond):
+		t.Fail()
+	}
+}
+
+func TestOutermostResetInvokedForGrandchildren(t *testing.T) {
+	output := prepare()
+
+	Convey("A", t, func() {
+		output += "A "
+
+		Reset(func() {
+			output += "rA "
+		})
+
+		Convey("B", func() {
+			output += "B "
+
+			Reset(func() {
+				output += "rB "
+			})
+
+			Convey("C", func() {
+				output += "C "
+
+				Reset(func() {
+					output += "rC "
+				})
+			})
+
+			Convey("D", func() {
+				output += "D "
+
+				Reset(func() {
+					output += "rD "
+				})
+			})
+		})
+	})
+
+	expectEqual(t, "A B C rC rB rA A B D rD rB rA ", output)
+}
+
+func TestFailureOption(t *testing.T) {
+	output := prepare()
+
+	Convey("A", t, FailureHalts, func() {
+		output += "A "
+		So(true, ShouldEqual, true)
+		output += "B "
+		So(false, ShouldEqual, true)
+		output += "C "
+	})
+
+	expectEqual(t, "A B ", output)
+}
+
+func TestFailureOption2(t *testing.T) {
+	output := prepare()
+
+	Convey("A", t, func() {
+		output += "A "
+		So(true, ShouldEqual, true)
+		output += "B "
+		So(false, ShouldEqual, true)
+		output += "C "
+	})
+
+	expectEqual(t, "A B ", output)
+}
+
+func TestFailureOption3(t *testing.T) {
+	output := prepare()
+
+	Convey("A", t, FailureContinues, func() {
+		output += "A "
+		So(true, ShouldEqual, true)
+		output += "B "
+		So(false, ShouldEqual, true)
+		output += "C "
+	})
+
+	expectEqual(t, "A B C ", output)
+}
+
+func TestFailureOptionInherit(t *testing.T) {
+	output := prepare()
+
+	Convey("A", t, FailureContinues, func() {
+		output += "A1 "
+		So(false, ShouldEqual, true)
+		output += "A2 "
+
+		Convey("B", func() {
+			output += "B1 "
+			So(true, ShouldEqual, true)
+			output += "B2 "
+			So(false, ShouldEqual, true)
+			output += "B3 "
+		})
+	})
+
+	expectEqual(t, "A1 A2 B1 B2 B3 ", output)
+}
+
+func TestFailureOptionInherit2(t *testing.T) {
+	output := prepare()
+
+	Convey("A", t, FailureHalts, func() {
+		output += "A1 "
+		So(false, ShouldEqual, true)
+		output += "A2 "
+
+		Convey("B", func() {
+			output += "A1 "
+			So(true, ShouldEqual, true)
+			output += "A2 "
+			So(false, ShouldEqual, true)
+			output += "A3 "
+		})
+	})
+
+	expectEqual(t, "A1 ", output)
+}
+
+func TestFailureOptionInherit3(t *testing.T) {
+	output := prepare()
+
+	Convey("A", t, FailureHalts, func() {
+		output += "A1 "
+		So(true, ShouldEqual, true)
+		output += "A2 "
+
+		Convey("B", func() {
+			output += "B1 "
+			So(true, ShouldEqual, true)
+			output += "B2 "
+			So(false, ShouldEqual, true)
+			output += "B3 "
+		})
+	})
+
+	expectEqual(t, "A1 A2 B1 B2 ", output)
+}
+
+func TestFailureOptionNestedOverride(t *testing.T) {
+	output := prepare()
+
+	Convey("A", t, FailureContinues, func() {
+		output += "A "
+		So(false, ShouldEqual, true)
+		output += "B "
+
+		Convey("C", FailureHalts, func() {
+			output += "C "
+			So(true, ShouldEqual, true)
+			output += "D "
+			So(false, ShouldEqual, true)
+			output += "E "
+		})
+	})
+
+	expectEqual(t, "A B C D ", output)
+}
+
+func TestFailureOptionNestedOverride2(t *testing.T) {
+	output := prepare()
+
+	Convey("A", t, FailureHalts, func() {
+		output += "A "
+		So(true, ShouldEqual, true)
+		output += "B "
+
+		Convey("C", FailureContinues, func() {
+			output += "C "
+			So(true, ShouldEqual, true)
+			output += "D "
+			So(false, ShouldEqual, true)
+			output += "E "
+		})
+	})
+
+	expectEqual(t, "A B C D E ", output)
+}
+
+func TestMultipleInvocationInheritance(t *testing.T) {
+	output := prepare()
+
+	Convey("A", t, FailureHalts, func() {
+		output += "A1 "
+		So(true, ShouldEqual, true)
+		output += "A2 "
+
+		Convey("B", FailureContinues, func() {
+			output += "B1 "
+			So(true, ShouldEqual, true)
+			output += "B2 "
+			So(false, ShouldEqual, true)
+			output += "B3 "
+		})
+
+		Convey("C", func() {
+			output += "C1 "
+			So(true, ShouldEqual, true)
+			output += "C2 "
+			So(false, ShouldEqual, true)
+			output += "C3 "
+		})
+	})
+
+	expectEqual(t, "A1 A2 B1 B2 B3 A1 A2 C1 C2 ", output)
+}
+
+func TestMultipleInvocationInheritance2(t *testing.T) {
+	output := prepare()
+
+	Convey("A", t, FailureContinues, func() {
+		output += "A1 "
+		So(true, ShouldEqual, true)
+		output += "A2 "
+		So(false, ShouldEqual, true)
+		output += "A3 "
+
+		Convey("B", FailureHalts, func() {
+			output += "B1 "
+			So(true, ShouldEqual, true)
+			output += "B2 "
+			So(false, ShouldEqual, true)
+			output += "B3 "
+		})
+
+		Convey("C", func() {
+			output += "C1 "
+			So(true, ShouldEqual, true)
+			output += "C2 "
+			So(false, ShouldEqual, true)
+			output += "C3 "
+		})
+	})
+
+	expectEqual(t, "A1 A2 A3 B1 B2 A1 A2 A3 C1 C2 C3 ", output)
+}
+
+func TestSetDefaultFailureMode(t *testing.T) {
+	output := prepare()
+
+	SetDefaultFailureMode(FailureContinues) // the default is normally FailureHalts
+	defer SetDefaultFailureMode(FailureHalts)
+
+	Convey("A", t, func() {
+		output += "A1 "
+		So(true, ShouldBeFalse)
+		output += "A2 "
+	})
+
+	expectEqual(t, "A1 A2 ", output)
+}
+
+func prepare() string {
+	testReporter = newNilReporter()
+	return ""
+}

+ 74 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/registration.go

@@ -0,0 +1,74 @@
+package convey
+
+import (
+	"reflect"
+	"runtime"
+
+	"github.com/smartystreets/goconvey/convey/gotest"
+)
+
+type registration struct {
+	Situation string
+	action    *action
+	Test      t
+	File      string
+	Line      int
+	Focus     bool
+}
+
+func (self *registration) ShouldBeTopLevel() bool {
+	return self.Test != nil
+}
+
+func newRegistration(situation string, action *action, test t) *registration {
+	file, line, _ := gotest.ResolveExternalCaller()
+
+	return &registration{
+		Situation: situation,
+		action:    action,
+		Test:      test,
+		File:      file,
+		Line:      line,
+	}
+}
+
+////////////////////////// action ///////////////////////
+
+type action struct {
+	wrapped     func()
+	name        string
+	failureMode FailureMode
+}
+
+func (self *action) Invoke() {
+	self.wrapped()
+}
+
+func newAction(wrapped func(), mode FailureMode) *action {
+	return &action{
+		name:        functionName(wrapped),
+		wrapped:     wrapped,
+		failureMode: mode,
+	}
+}
+
+func newSkippedAction(wrapped func(), mode FailureMode) *action {
+	// The choice to use the filename and line number as the action name
+	// reflects the need for something unique but also that corresponds
+	// in a determinist way to the action itself.
+	return &action{
+		name:        gotest.FormatExternalFileAndLine(),
+		wrapped:     wrapped,
+		failureMode: mode,
+	}
+}
+
+///////////////////////// helpers //////////////////////////////
+
+func functionName(action func()) string {
+	return runtime.FuncForPC(functionId(action)).Name()
+}
+
+func functionId(action func()) uintptr {
+	return reflect.ValueOf(action).Pointer()
+}

+ 16 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/console.go

@@ -0,0 +1,16 @@
+package reporting
+
+import (
+	"fmt"
+	"io"
+)
+
+type console struct{}
+
+func (self *console) Write(p []byte) (n int, err error) {
+	return fmt.Print(string(p))
+}
+
+func NewConsole() io.Writer {
+	return new(console)
+}

+ 5 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/doc.go

@@ -0,0 +1,5 @@
+// Package reporting contains internal functionality related
+// to console reporting and output. Although this package has
+// exported names is not intended for public consumption. See the
+// examples package for how to use this project.
+package reporting

+ 40 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/dot.go

@@ -0,0 +1,40 @@
+package reporting
+
+import "fmt"
+
+type dot struct{ out *Printer }
+
+func (self *dot) BeginStory(story *StoryReport) {}
+
+func (self *dot) Enter(scope *ScopeReport) {}
+
+func (self *dot) Report(report *AssertionResult) {
+	if report.Error != nil {
+		fmt.Print(redColor)
+		self.out.Insert(dotError)
+	} else if report.Failure != "" {
+		fmt.Print(yellowColor)
+		self.out.Insert(dotFailure)
+	} else if report.Skipped {
+		fmt.Print(yellowColor)
+		self.out.Insert(dotSkip)
+	} else {
+		fmt.Print(greenColor)
+		self.out.Insert(dotSuccess)
+	}
+	fmt.Print(resetColor)
+}
+
+func (self *dot) Exit() {}
+
+func (self *dot) EndStory() {}
+
+func (self *dot) Write(content []byte) (written int, err error) {
+	return len(content), nil // no-op
+}
+
+func NewDotReporter(out *Printer) *dot {
+	self := new(dot)
+	self.out = out
+	return self
+}

+ 40 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/dot_test.go

@@ -0,0 +1,40 @@
+package reporting
+
+import (
+	"errors"
+	"testing"
+)
+
+func TestDotReporterAssertionPrinting(t *testing.T) {
+	monochrome()
+	file := newMemoryFile()
+	printer := NewPrinter(file)
+	reporter := NewDotReporter(printer)
+
+	reporter.Report(NewSuccessReport())
+	reporter.Report(NewFailureReport("failed"))
+	reporter.Report(NewErrorReport(errors.New("error")))
+	reporter.Report(NewSkipReport())
+
+	expected := dotSuccess + dotFailure + dotError + dotSkip
+
+	if file.buffer != expected {
+		t.Errorf("\nExpected: '%s'\nActual:  '%s'", expected, file.buffer)
+	}
+}
+
+func TestDotReporterOnlyReportsAssertions(t *testing.T) {
+	monochrome()
+	file := newMemoryFile()
+	printer := NewPrinter(file)
+	reporter := NewDotReporter(printer)
+
+	reporter.BeginStory(nil)
+	reporter.Enter(nil)
+	reporter.Exit()
+	reporter.EndStory()
+
+	if file.buffer != "" {
+		t.Errorf("\nExpected: '(blank)'\nActual:  '%s'", file.buffer)
+	}
+}

+ 33 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/gotest.go

@@ -0,0 +1,33 @@
+package reporting
+
+type gotestReporter struct{ test T }
+
+func (self *gotestReporter) BeginStory(story *StoryReport) {
+	self.test = story.Test
+}
+
+func (self *gotestReporter) Enter(scope *ScopeReport) {}
+
+func (self *gotestReporter) Report(r *AssertionResult) {
+	if !passed(r) {
+		self.test.Fail()
+	}
+}
+
+func (self *gotestReporter) Exit() {}
+
+func (self *gotestReporter) EndStory() {
+	self.test = nil
+}
+
+func (self *gotestReporter) Write(content []byte) (written int, err error) {
+	return len(content), nil // no-op
+}
+
+func NewGoTestReporter() *gotestReporter {
+	return new(gotestReporter)
+}
+
+func passed(r *AssertionResult) bool {
+	return r.Error == nil && r.Failure == ""
+}

+ 66 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/gotest_test.go

@@ -0,0 +1,66 @@
+package reporting
+
+import "testing"
+
+func TestReporterReceivesSuccessfulReport(t *testing.T) {
+	reporter := NewGoTestReporter()
+	test := new(fakeTest)
+	reporter.BeginStory(NewStoryReport(test))
+	reporter.Report(NewSuccessReport())
+
+	if test.failed {
+		t.Errorf("Should have have marked test as failed--the report reflected success.")
+	}
+}
+
+func TestReporterReceivesFailureReport(t *testing.T) {
+	reporter := NewGoTestReporter()
+	test := new(fakeTest)
+	reporter.BeginStory(NewStoryReport(test))
+	reporter.Report(NewFailureReport("This is a failure."))
+
+	if !test.failed {
+		t.Errorf("Test should have been marked as failed (but it wasn't).")
+	}
+}
+
+func TestReporterReceivesErrorReport(t *testing.T) {
+	reporter := NewGoTestReporter()
+	test := new(fakeTest)
+	reporter.BeginStory(NewStoryReport(test))
+	reporter.Report(NewErrorReport("This is an error."))
+
+	if !test.failed {
+		t.Errorf("Test should have been marked as failed (but it wasn't).")
+	}
+}
+
+func TestReporterIsResetAtTheEndOfTheStory(t *testing.T) {
+	defer catch(t)
+	reporter := NewGoTestReporter()
+	test := new(fakeTest)
+	reporter.BeginStory(NewStoryReport(test))
+	reporter.EndStory()
+
+	reporter.Report(NewSuccessReport())
+}
+
+func TestReporterNoopMethods(t *testing.T) {
+	reporter := NewGoTestReporter()
+	reporter.Enter(NewScopeReport("title", "name"))
+	reporter.Exit()
+}
+
+func catch(t *testing.T) {
+	if r := recover(); r != nil {
+		t.Log("Getting to this point means we've passed (because we caught a panic appropriately).")
+	}
+}
+
+type fakeTest struct {
+	failed bool
+}
+
+func (self *fakeTest) Fail() {
+	self.failed = true
+}

+ 94 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/init.go

@@ -0,0 +1,94 @@
+package reporting
+
+import (
+	"fmt"
+	"os"
+	"runtime"
+	"strings"
+)
+
+func init() {
+	if !isXterm() {
+		monochrome()
+	}
+
+	if runtime.GOOS == "windows" {
+		success, failure, error_ = dotSuccess, dotFailure, dotError
+	}
+}
+
+func BuildJsonReporter() Reporter {
+	out := NewPrinter(NewConsole())
+	return NewReporters(
+		NewGoTestReporter(),
+		NewJsonReporter(out))
+}
+func BuildDotReporter() Reporter {
+	out := NewPrinter(NewConsole())
+	return NewReporters(
+		NewGoTestReporter(),
+		NewDotReporter(out),
+		NewProblemReporter(out),
+		consoleStatistics)
+}
+func BuildStoryReporter() Reporter {
+	out := NewPrinter(NewConsole())
+	return NewReporters(
+		NewGoTestReporter(),
+		NewStoryReporter(out),
+		NewProblemReporter(out),
+		consoleStatistics)
+}
+func BuildSilentReporter() Reporter {
+	out := NewPrinter(NewConsole())
+	return NewReporters(
+		NewGoTestReporter(),
+		NewProblemReporter(out))
+}
+
+var (
+	newline         = "\n"
+	success         = "✔"
+	failure         = "✘"
+	error_          = "🔥"
+	skip            = "⚠"
+	dotSuccess      = "."
+	dotFailure      = "x"
+	dotError        = "E"
+	dotSkip         = "S"
+	errorTemplate   = "* %s \nLine %d: - %v \n%s\n"
+	failureTemplate = "* %s \nLine %d:\n%s\n"
+)
+
+var (
+	greenColor  = "\033[32m"
+	yellowColor = "\033[33m"
+	redColor    = "\033[31m"
+	resetColor  = "\033[0m"
+)
+
+var consoleStatistics = NewStatisticsReporter(NewPrinter(NewConsole()))
+
+// QuiteMode disables all console output symbols. This is only meant to be used
+// for tests that are internal to goconvey where the output is distracting or
+// otherwise not needed in the test output.
+func QuietMode() {
+	success, failure, error_, skip, dotSuccess, dotFailure, dotError, dotSkip = "", "", "", "", "", "", "", ""
+}
+
+func monochrome() {
+	greenColor, yellowColor, redColor, resetColor = "", "", "", ""
+}
+
+func isXterm() bool {
+	env := fmt.Sprintf("%v", os.Environ())
+	return strings.Contains(env, " TERM=isXterm") ||
+		strings.Contains(env, " TERM=xterm")
+}
+
+// This interface allows us to pass the *testing.T struct
+// throughout the internals of this tool without ever
+// having to import the "testing" package.
+type T interface {
+	Fail()
+}

+ 88 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/json.go

@@ -0,0 +1,88 @@
+// TODO: under unit test
+
+package reporting
+
+import (
+	"bytes"
+	"encoding/json"
+	"fmt"
+	"strings"
+)
+
+type JsonReporter struct {
+	out     *Printer
+	current *ScopeResult
+	index   map[string]*ScopeResult
+	scopes  []*ScopeResult
+	depth   int
+}
+
+func (self *JsonReporter) BeginStory(story *StoryReport) {}
+
+func (self *JsonReporter) Enter(scope *ScopeReport) {
+	if _, found := self.index[scope.ID]; !found {
+		self.registerScope(scope)
+	}
+	self.depth++
+	self.current = self.index[scope.ID]
+}
+func (self *JsonReporter) registerScope(scope *ScopeReport) {
+	next := newScopeResult(scope.Title, self.depth, scope.File, scope.Line)
+	self.scopes = append(self.scopes, next)
+	self.index[scope.ID] = next
+}
+
+func (self *JsonReporter) Report(report *AssertionResult) {
+	self.current.Assertions = append(self.current.Assertions, report)
+}
+
+func (self *JsonReporter) Exit() {
+	self.depth--
+}
+
+func (self *JsonReporter) EndStory() {
+	self.report()
+	self.reset()
+}
+func (self *JsonReporter) report() {
+	scopes := []string{}
+	for _, scope := range self.scopes {
+		serialized, err := json.Marshal(scope)
+		if err != nil {
+			self.out.Println(jsonMarshalFailure)
+			panic(err)
+		}
+		var buffer bytes.Buffer
+		json.Indent(&buffer, serialized, "", "  ")
+		scopes = append(scopes, buffer.String())
+	}
+	self.out.Print(fmt.Sprintf("%s\n%s,\n%s\n", OpenJson, strings.Join(scopes, ","), CloseJson))
+}
+func (self *JsonReporter) reset() {
+	self.scopes = []*ScopeResult{}
+	self.index = map[string]*ScopeResult{}
+	self.depth = 0
+}
+
+func (self *JsonReporter) Write(content []byte) (written int, err error) {
+	self.current.Output += string(content)
+	return len(content), nil
+}
+
+func NewJsonReporter(out *Printer) *JsonReporter {
+	self := new(JsonReporter)
+	self.out = out
+	self.reset()
+	return self
+}
+
+const OpenJson = ">>>>>"  // "⌦"
+const CloseJson = "<<<<<" // "⌫"
+const jsonMarshalFailure = `
+
+GOCONVEY_JSON_MARSHALL_FAILURE: There was an error when attempting to convert test results to JSON.
+Please file a bug report and reference the code that caused this failure if possible.
+
+Here's the panic:
+
+`

+ 57 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/printer.go

@@ -0,0 +1,57 @@
+package reporting
+
+import (
+	"fmt"
+	"io"
+	"strings"
+)
+
+type Printer struct {
+	out    io.Writer
+	prefix string
+}
+
+func (self *Printer) Println(message string, values ...interface{}) {
+	formatted := self.format(message, values...) + newline
+	self.out.Write([]byte(formatted))
+}
+
+func (self *Printer) Print(message string, values ...interface{}) {
+	formatted := self.format(message, values...)
+	self.out.Write([]byte(formatted))
+}
+
+func (self *Printer) Insert(text string) {
+	self.out.Write([]byte(text))
+}
+
+func (self *Printer) format(message string, values ...interface{}) string {
+	var formatted string
+	if len(values) == 0 {
+		formatted = self.prefix + message
+	} else {
+		formatted = self.prefix + fmt.Sprintf(message, values...)
+	}
+	indented := strings.Replace(formatted, newline, newline+self.prefix, -1)
+	return strings.TrimRight(indented, space)
+}
+
+func (self *Printer) Indent() {
+	self.prefix += pad
+}
+
+func (self *Printer) Dedent() {
+	if len(self.prefix) >= padLength {
+		self.prefix = self.prefix[:len(self.prefix)-padLength]
+	}
+}
+
+func NewPrinter(out io.Writer) *Printer {
+	self := new(Printer)
+	self.out = out
+	return self
+}
+
+const space = " "
+const pad = space + space
+const padLength = len(pad)

+ 181 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/printer_test.go

@@ -0,0 +1,181 @@
+package reporting
+
+import "testing"
+
+func TestPrint(t *testing.T) {
+	file := newMemoryFile()
+	printer := NewPrinter(file)
+	const expected = "Hello, World!"
+
+	printer.Print(expected)
+
+	if file.buffer != expected {
+		t.Errorf("Expected '%s' to equal '%s'.", expected, file.buffer)
+	}
+}
+
+func TestPrintFormat(t *testing.T) {
+	file := newMemoryFile()
+	printer := NewPrinter(file)
+	template := "Hi, %s"
+	name := "Ralph"
+	expected := "Hi, Ralph"
+
+	printer.Print(template, name)
+
+	if file.buffer != expected {
+		t.Errorf("Expected '%s' to equal '%s'.", expected, file.buffer)
+	}
+}
+
+func TestPrintPreservesEncodedStrings(t *testing.T) {
+	file := newMemoryFile()
+	printer := NewPrinter(file)
+	const expected = "= -> %3D"
+	printer.Print(expected)
+
+	if file.buffer != expected {
+		t.Errorf("Expected '%s' to equal '%s'.", expected, file.buffer)
+	}
+}
+
+func TestPrintln(t *testing.T) {
+	file := newMemoryFile()
+	printer := NewPrinter(file)
+	const expected = "Hello, World!"
+
+	printer.Println(expected)
+
+	if file.buffer != expected+"\n" {
+		t.Errorf("Expected '%s' to equal '%s'.", expected, file.buffer)
+	}
+}
+
+func TestPrintlnFormat(t *testing.T) {
+	file := newMemoryFile()
+	printer := NewPrinter(file)
+	template := "Hi, %s"
+	name := "Ralph"
+	expected := "Hi, Ralph\n"
+
+	printer.Println(template, name)
+
+	if file.buffer != expected {
+		t.Errorf("Expected '%s' to equal '%s'.", expected, file.buffer)
+	}
+}
+
+func TestPrintlnPreservesEncodedStrings(t *testing.T) {
+	file := newMemoryFile()
+	printer := NewPrinter(file)
+	const expected = "= -> %3D"
+	printer.Println(expected)
+
+	if file.buffer != expected+"\n" {
+		t.Errorf("Expected '%s' to equal '%s'.", expected, file.buffer)
+	}
+}
+
+func TestPrintIndented(t *testing.T) {
+	file := newMemoryFile()
+	printer := NewPrinter(file)
+	const message = "Hello, World!\nGoodbye, World!"
+	const expected = "  Hello, World!\n  Goodbye, World!"
+
+	printer.Indent()
+	printer.Print(message)
+
+	if file.buffer != expected {
+		t.Errorf("Expected '%s' to equal '%s'.", expected, file.buffer)
+	}
+}
+
+func TestPrintDedented(t *testing.T) {
+	file := newMemoryFile()
+	printer := NewPrinter(file)
+	const expected = "Hello, World!\nGoodbye, World!"
+
+	printer.Indent()
+	printer.Dedent()
+	printer.Print(expected)
+
+	if file.buffer != expected {
+		t.Errorf("Expected '%s' to equal '%s'.", expected, file.buffer)
+	}
+}
+
+func TestPrintlnIndented(t *testing.T) {
+	file := newMemoryFile()
+	printer := NewPrinter(file)
+	const message = "Hello, World!\nGoodbye, World!"
+	const expected = "  Hello, World!\n  Goodbye, World!\n"
+
+	printer.Indent()
+	printer.Println(message)
+
+	if file.buffer != expected {
+		t.Errorf("Expected '%s' to equal '%s'.", expected, file.buffer)
+	}
+}
+
+func TestPrintlnDedented(t *testing.T) {
+	file := newMemoryFile()
+	printer := NewPrinter(file)
+	const expected = "Hello, World!\nGoodbye, World!"
+
+	printer.Indent()
+	printer.Dedent()
+	printer.Println(expected)
+
+	if file.buffer != expected+"\n" {
+		t.Errorf("Expected '%s' to equal '%s'.", expected, file.buffer)
+	}
+}
+
+func TestDedentTooFarShouldNotPanic(t *testing.T) {
+	defer func() {
+		if r := recover(); r != nil {
+			t.Error("Should not have panicked!")
+		}
+	}()
+	file := newMemoryFile()
+	printer := NewPrinter(file)
+
+	printer.Dedent()
+
+	t.Log("Getting to this point without panicking means we passed.")
+}
+
+func TestInsert(t *testing.T) {
+	file := newMemoryFile()
+	printer := NewPrinter(file)
+
+	printer.Indent()
+	printer.Print("Hi")
+	printer.Insert(" there")
+	printer.Dedent()
+
+	expected := "  Hi there"
+	if file.buffer != expected {
+		t.Errorf("Should have written '%s' but instead wrote '%s'.", expected, file.buffer)
+	}
+}
+
+////////////////// memoryFile ////////////////////
+
+type memoryFile struct {
+	buffer string
+}
+
+func (self *memoryFile) Write(p []byte) (n int, err error) {
+	self.buffer += string(p)
+	return len(p), nil
+}
+
+func (self *memoryFile) String() string {
+	return self.buffer
+}
+
+func newMemoryFile() *memoryFile {
+	return new(memoryFile)
+}

+ 68 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/problems.go

@@ -0,0 +1,68 @@
+package reporting
+
+import "fmt"
+
+type problem struct {
+	out      *Printer
+	errors   []*AssertionResult
+	failures []*AssertionResult
+}
+
+func (self *problem) BeginStory(story *StoryReport) {}
+
+func (self *problem) Enter(scope *ScopeReport) {}
+
+func (self *problem) Report(report *AssertionResult) {
+	if report.Error != nil {
+		self.errors = append(self.errors, report)
+	} else if report.Failure != "" {
+		self.failures = append(self.failures, report)
+	}
+}
+
+func (self *problem) Exit() {}
+
+func (self *problem) EndStory() {
+	self.show(self.showErrors, redColor)
+	self.show(self.showFailures, yellowColor)
+	self.prepareForNextStory()
+}
+func (self *problem) show(display func(), color string) {
+	fmt.Print(color)
+	display()
+	fmt.Print(resetColor)
+	self.out.Dedent()
+}
+func (self *problem) showErrors() {
+	for i, e := range self.errors {
+		if i == 0 {
+			self.out.Println("\nErrors:\n")
+			self.out.Indent()
+		}
+		self.out.Println(errorTemplate, e.File, e.Line, e.Error, e.StackTrace)
+	}
+}
+func (self *problem) showFailures() {
+	for i, f := range self.failures {
+		if i == 0 {
+			self.out.Println("\nFailures:\n")
+			self.out.Indent()
+		}
+		self.out.Println(failureTemplate, f.File, f.Line, f.Failure)
+	}
+}
+
+func (self *problem) Write(content []byte) (written int, err error) {
+	return len(content), nil // no-op
+}
+
+func NewProblemReporter(out *Printer) *problem {
+	self := new(problem)
+	self.out = out
+	self.prepareForNextStory()
+	return self
+}
+func (self *problem) prepareForNextStory() {
+	self.errors = []*AssertionResult{}
+	self.failures = []*AssertionResult{}
+}

+ 46 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/problems_test.go

@@ -0,0 +1,46 @@
+package reporting
+
+import (
+	"strings"
+	"testing"
+)
+
+func TestNoopProblemReporterActions(t *testing.T) {
+	file, reporter := setup()
+	reporter.BeginStory(nil)
+	reporter.Enter(nil)
+	reporter.Exit()
+	expected := ""
+	actual := file.String()
+	if expected != actual {
+		t.Errorf("Expected: '(blank)'\nActual:  '%s'", actual)
+	}
+}
+
+func TestReporterPrintsFailuresAndErrorsAtTheEndOfTheStory(t *testing.T) {
+	file, reporter := setup()
+	reporter.Report(NewFailureReport("failed"))
+	reporter.Report(NewErrorReport("error"))
+	reporter.Report(NewSuccessReport())
+	reporter.EndStory()
+
+	result := file.String()
+	if !strings.Contains(result, "Errors:\n") {
+		t.Errorf("Expected errors, found none.")
+	}
+	if !strings.Contains(result, "Failures:\n") {
+		t.Errorf("Expected failures, found none.")
+	}
+	problemCount := strings.Count(result, "*")
+	if problemCount != 2 {
+		t.Errorf("Expected one failure and one error (total of 2 '*' characters). Got %d", problemCount)
+	}
+}
+
+func setup() (file *memoryFile, reporter *problem) {
+	monochrome()
+	file = newMemoryFile()
+	printer := NewPrinter(file)
+	reporter = NewProblemReporter(printer)
+	return
+}

+ 39 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/reporter.go

@@ -0,0 +1,39 @@
+package reporting
+
+import "io"
+
+type Reporter interface {
+	BeginStory(story *StoryReport)
+	Enter(scope *ScopeReport)
+	Report(r *AssertionResult)
+	Exit()
+	EndStory()
+	io.Writer
+}
+
+type reporters struct{ collection []Reporter }
+
+func (self *reporters) BeginStory(s *StoryReport) { self.foreach(func(r Reporter) { r.BeginStory(s) }) }
+func (self *reporters) Enter(s *ScopeReport)      { self.foreach(func(r Reporter) { r.Enter(s) }) }
+func (self *reporters) Report(a *AssertionResult) { self.foreach(func(r Reporter) { r.Report(a) }) }
+func (self *reporters) Exit()                     { self.foreach(func(r Reporter) { r.Exit() }) }
+func (self *reporters) EndStory()                 { self.foreach(func(r Reporter) { r.EndStory() }) }
+
+func (self *reporters) Write(contents []byte) (written int, err error) {
+	self.foreach(func(r Reporter) {
+		written, err = r.Write(contents)
+	})
+	return written, err
+}
+
+func (self *reporters) foreach(action func(Reporter)) {
+	for _, r := range self.collection {
+		action(r)
+	}
+}
+
+func NewReporters(collection ...Reporter) *reporters {
+	self := new(reporters)
+	self.collection = collection
+	return self
+}

+ 94 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/reporter_test.go

@@ -0,0 +1,94 @@
+package reporting
+
+import (
+	"runtime"
+	"testing"
+)
+
+func TestEachNestedReporterReceivesTheCallFromTheContainingReporter(t *testing.T) {
+	fake1 := newFakeReporter()
+	fake2 := newFakeReporter()
+	reporter := NewReporters(fake1, fake2)
+
+	reporter.BeginStory(nil)
+	assertTrue(t, fake1.begun)
+	assertTrue(t, fake2.begun)
+
+	reporter.Enter(NewScopeReport("scope", "hi"))
+	assertTrue(t, fake1.entered)
+	assertTrue(t, fake2.entered)
+
+	reporter.Report(NewSuccessReport())
+	assertTrue(t, fake1.reported)
+	assertTrue(t, fake2.reported)
+
+	reporter.Exit()
+	assertTrue(t, fake1.exited)
+	assertTrue(t, fake2.exited)
+
+	reporter.EndStory()
+	assertTrue(t, fake1.ended)
+	assertTrue(t, fake2.ended)
+
+	content := []byte("hi")
+	written, err := reporter.Write(content)
+	assertTrue(t, fake1.written)
+	assertTrue(t, fake2.written)
+	assertEqual(t, written, len(content))
+	assertNil(t, err)
+
+}
+
+func assertTrue(t *testing.T, value bool) {
+	if !value {
+		_, _, line, _ := runtime.Caller(1)
+		t.Errorf("Value should have been true (but was false). See line %d", line)
+	}
+}
+
+func assertEqual(t *testing.T, expected, actual int) {
+	if actual != expected {
+		_, _, line, _ := runtime.Caller(1)
+		t.Errorf("Value should have been %d (but was %d). See line %d", expected, actual, line)
+	}
+}
+
+func assertNil(t *testing.T, err error) {
+	if err != nil {
+		_, _, line, _ := runtime.Caller(1)
+		t.Errorf("Error should have been <nil> (but wasn't). See line %d", err, line)
+	}
+}
+
+type fakeReporter struct {
+	begun    bool
+	entered  bool
+	reported bool
+	exited   bool
+	ended    bool
+	written  bool
+}
+
+func newFakeReporter() *fakeReporter {
+	return &fakeReporter{}
+}
+
+func (self *fakeReporter) BeginStory(story *StoryReport) {
+	self.begun = true
+}
+func (self *fakeReporter) Enter(scope *ScopeReport) {
+	self.entered = true
+}
+func (self *fakeReporter) Report(report *AssertionResult) {
+	self.reported = true
+}
+func (self *fakeReporter) Exit() {
+	self.exited = true
+}
+func (self *fakeReporter) EndStory() {
+	self.ended = true
+}
+func (self *fakeReporter) Write(content []byte) (int, error) {
+	self.written = true
+	return len(content), nil
+}

+ 179 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/reports.go

@@ -0,0 +1,179 @@
+package reporting
+
+import (
+	"encoding/json"
+	"fmt"
+	"runtime"
+	"strings"
+
+	"github.com/smartystreets/goconvey/convey/gotest"
+)
+
+////////////////// ScopeReport ////////////////////
+
+type ScopeReport struct {
+	Title string
+	ID    string
+	File  string
+	Line  int
+}
+
+func NewScopeReport(title, name string) *ScopeReport {
+	file, line, _ := gotest.ResolveExternalCaller()
+	self := new(ScopeReport)
+	self.Title = title
+	self.ID = fmt.Sprintf("%s|%s", title, name)
+	self.File = file
+	self.Line = line
+	return self
+}
+
+////////////////// ScopeResult ////////////////////
+
+type ScopeResult struct {
+	Title      string
+	File       string
+	Line       int
+	Depth      int
+	Assertions []*AssertionResult
+	Output     string
+}
+
+func newScopeResult(title string, depth int, file string, line int) *ScopeResult {
+	self := new(ScopeResult)
+	self.Title = title
+	self.Depth = depth
+	self.File = file
+	self.Line = line
+	self.Assertions = []*AssertionResult{}
+	return self
+}
+
+/////////////////// StoryReport /////////////////////
+
+type StoryReport struct {
+	Test T
+	Name string
+	File string
+	Line int
+}
+
+func NewStoryReport(test T) *StoryReport {
+	file, line, name := gotest.ResolveExternalCaller()
+	name = removePackagePath(name)
+	self := new(StoryReport)
+	self.Test = test
+	self.Name = name
+	self.File = file
+	self.Line = line
+	return self
+}
+
+// name comes in looking like "github.com/smartystreets/goconvey/examples.TestName".
+// We only want the stuff after the last '.', which is the name of the test function.
+func removePackagePath(name string) string {
+	parts := strings.Split(name, ".")
+	return parts[len(parts)-1]
+}
+
+/////////////////// FailureView ////////////////////////
+
+type FailureView struct {
+	Message  string
+	Expected string
+	Actual   string
+}
+
+////////////////////AssertionResult //////////////////////
+
+type AssertionResult struct {
+	File       string
+	Line       int
+	Expected   string
+	Actual     string
+	Failure    string
+	Error      interface{}
+	StackTrace string
+	Skipped    bool
+}
+
+func NewFailureReport(failure string) *AssertionResult {
+	report := new(AssertionResult)
+	report.File, report.Line = caller()
+	report.StackTrace = stackTrace()
+	parseFailure(failure, report)
+	return report
+}
+func parseFailure(failure string, report *AssertionResult) {
+	view := new(FailureView)
+	err := json.Unmarshal([]byte(failure), view)
+	if err == nil {
+		report.Failure = view.Message
+		report.Expected = view.Expected
+		report.Actual = view.Actual
+	} else {
+		report.Failure = failure
+	}
+}
+func NewErrorReport(err interface{}) *AssertionResult {
+	report := new(AssertionResult)
+	report.File, report.Line = caller()
+	report.StackTrace = fullStackTrace()
+	report.Error = fmt.Sprintf("%v", err)
+	return report
+}
+func NewSuccessReport() *AssertionResult {
+	return new(AssertionResult)
+}
+func NewSkipReport() *AssertionResult {
+	report := new(AssertionResult)
+	report.File, report.Line = caller()
+	report.StackTrace = fullStackTrace()
+	report.Skipped = true
+	return report
+}
+
+func caller() (file string, line int) {
+	file, line, _ = gotest.ResolveExternalCaller()
+	return
+}
+
+func stackTrace() string {
+	buffer := make([]byte, 1024*64)
+	n := runtime.Stack(buffer, false)
+	return removeInternalEntries(string(buffer[:n]))
+}
+func fullStackTrace() string {
+	buffer := make([]byte, 1024*64)
+	n := runtime.Stack(buffer, true)
+	return removeInternalEntries(string(buffer[:n]))
+}
+func removeInternalEntries(stack string) string {
+	lines := strings.Split(stack, newline)
+	filtered := []string{}
+	for _, line := range lines {
+		if !isExternal(line) {
+			filtered = append(filtered, line)
+		}
+	}
+	return strings.Join(filtered, newline)
+}
+func isExternal(line string) bool {
+	for _, p := range internalPackages {
+		if strings.Contains(line, p) {
+			return true
+		}
+	}
+	return false
+}
+
+// NOTE: any new packages that host goconvey packages will need to be added here!
+// An alternative is to scan the goconvey directory and then exclude stuff like
+// the examples package but that's nasty too.
+var internalPackages = []string{
+	"goconvey/assertions",
+	"goconvey/convey",
+	"goconvey/execution",
+	"goconvey/gotest",
+	"goconvey/reporting",
+}

+ 79 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/statistics.go

@@ -0,0 +1,79 @@
+package reporting
+
+import "fmt"
+
+func (self *statistics) BeginStory(story *StoryReport) {}
+
+func (self *statistics) Enter(scope *ScopeReport) {}
+
+func (self *statistics) Report(report *AssertionResult) {
+	if !self.failing && report.Failure != "" {
+		self.failing = true
+	}
+	if !self.erroring && report.Error != nil {
+		self.erroring = true
+	}
+	if report.Skipped {
+		self.skipped += 1
+	} else {
+		self.total++
+	}
+}
+
+func (self *statistics) Exit() {}
+
+func (self *statistics) EndStory() {
+	self.reportAssertions()
+	self.reportSkippedSections()
+	self.completeReport()
+}
+func (self *statistics) reportAssertions() {
+	self.decideColor()
+	self.out.Print("\n%d %s thus far", self.total, plural("assertion", self.total))
+}
+func (self *statistics) decideColor() {
+	if self.failing && !self.erroring {
+		fmt.Print(yellowColor)
+	} else if self.erroring {
+		fmt.Print(redColor)
+	} else {
+		fmt.Print(greenColor)
+	}
+}
+func (self *statistics) reportSkippedSections() {
+	if self.skipped > 0 {
+		fmt.Print(yellowColor)
+		self.out.Print(" (one or more sections skipped)")
+		self.skipped = 0
+	}
+}
+func (self *statistics) completeReport() {
+	fmt.Print(resetColor)
+	self.out.Print("\n")
+	self.out.Print("\n")
+}
+
+func (self *statistics) Write(content []byte) (written int, err error) {
+	return len(content), nil // no-op
+}
+
+func NewStatisticsReporter(out *Printer) *statistics {
+	self := statistics{}
+	self.out = out
+	return &self
+}
+
+type statistics struct {
+	out      *Printer
+	total    int
+	failing  bool
+	erroring bool
+	skipped  int
+}
+
+func plural(word string, count int) string {
+	if count == 1 {
+		return word
+	}
+	return word + "s"
+}

+ 65 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/story.go

@@ -0,0 +1,65 @@
+// TODO: in order for this reporter to be completely honest
+// we need to retrofit to be more like the json reporter such that:
+// 1. it maintains ScopeResult collections, which count assertions
+// 2. it reports only after EndStory(), so that all tick marks
+//    are placed near the appropriate title.
+// 3. Under unit test
+
+package reporting
+
+import "fmt"
+
+type story struct {
+	out        *Printer
+	titlesById map[string]string
+}
+
+func (self *story) BeginStory(story *StoryReport) {}
+
+func (self *story) Enter(scope *ScopeReport) {
+	self.out.Indent()
+
+	if _, found := self.titlesById[scope.ID]; !found {
+		self.out.Println("")
+		self.out.Print(scope.Title)
+		self.out.Insert(" ")
+		self.titlesById[scope.ID] = scope.Title
+	}
+}
+
+func (self *story) Report(report *AssertionResult) {
+	if report.Error != nil {
+		fmt.Print(redColor)
+		self.out.Insert(error_)
+	} else if report.Failure != "" {
+		fmt.Print(yellowColor)
+		self.out.Insert(failure)
+	} else if report.Skipped {
+		fmt.Print(yellowColor)
+		self.out.Insert(skip)
+	} else {
+		fmt.Print(greenColor)
+		self.out.Insert(success)
+	}
+	fmt.Print(resetColor)
+}
+
+func (self *story) Exit() {
+	self.out.Dedent()
+}
+
+func (self *story) EndStory() {
+	self.titlesById = make(map[string]string)
+	self.out.Println("\n")
+}
+
+func (self *story) Write(content []byte) (written int, err error) {
+	return len(content), nil // no-op
+}
+
+func NewStoryReporter(out *Printer) *story {
+	self := new(story)
+	self.out = out
+	self.titlesById = make(map[string]string)
+	return self
+}

+ 270 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting_hooks_test.go

@@ -0,0 +1,270 @@
+package convey
+
+import (
+	"fmt"
+	"net/http"
+	"net/http/httptest"
+	"path"
+	"runtime"
+	"strconv"
+	"strings"
+	"testing"
+
+	"github.com/smartystreets/goconvey/convey/reporting"
+)
+
+func TestSingleScopeReported(t *testing.T) {
+	myReporter, test := setupFakeReporter()
+
+	Convey("A", test, func() {
+		So(1, ShouldEqual, 1)
+	})
+
+	expectEqual(t, "Begin|A|Success|Exit|End", myReporter.wholeStory())
+}
+
+func TestNestedScopeReported(t *testing.T) {
+	myReporter, test := setupFakeReporter()
+
+	Convey("A", test, func() {
+		Convey("B", func() {
+			So(1, ShouldEqual, 1)
+		})
+	})
+
+	expectEqual(t, "Begin|A|B|Success|Exit|Exit|End", myReporter.wholeStory())
+}
+
+func TestFailureReported(t *testing.T) {
+	myReporter, test := setupFakeReporter()
+
+	Convey("A", test, func() {
+		So(1, ShouldBeNil)
+	})
+
+	expectEqual(t, "Begin|A|Failure|Exit|End", myReporter.wholeStory())
+}
+
+func TestFirstFailureEndsScopeExecution(t *testing.T) {
+	myReporter, test := setupFakeReporter()
+
+	Convey("A", test, func() {
+		So(1, ShouldBeNil)
+		So(nil, ShouldBeNil)
+	})
+
+	expectEqual(t, "Begin|A|Failure|Exit|End", myReporter.wholeStory())
+}
+
+func TestComparisonFailureDeserializedAndReported(t *testing.T) {
+	myReporter, test := setupFakeReporter()
+
+	Convey("A", test, func() {
+		So("hi", ShouldEqual, "bye")
+	})
+
+	expectEqual(t, "Begin|A|Failure(bye/hi)|Exit|End", myReporter.wholeStory())
+}
+
+func TestNestedFailureReported(t *testing.T) {
+	myReporter, test := setupFakeReporter()
+
+	Convey("A", test, func() {
+		Convey("B", func() {
+			So(2, ShouldBeNil)
+		})
+	})
+
+	expectEqual(t, "Begin|A|B|Failure|Exit|Exit|End", myReporter.wholeStory())
+}
+
+func TestSuccessAndFailureReported(t *testing.T) {
+	myReporter, test := setupFakeReporter()
+
+	Convey("A", test, func() {
+		So(nil, ShouldBeNil)
+		So(1, ShouldBeNil)
+	})
+
+	expectEqual(t, "Begin|A|Success|Failure|Exit|End", myReporter.wholeStory())
+}
+
+func TestIncompleteActionReportedAsSkipped(t *testing.T) {
+	myReporter, test := setupFakeReporter()
+
+	Convey("A", test, func() {
+		Convey("B", nil)
+	})
+
+	expectEqual(t, "Begin|A|B|Skipped|Exit|Exit|End", myReporter.wholeStory())
+}
+
+func TestSkippedConveyReportedAsSkipped(t *testing.T) {
+	myReporter, test := setupFakeReporter()
+
+	Convey("A", test, func() {
+		SkipConvey("B", func() {
+			So(1, ShouldEqual, 1)
+		})
+	})
+
+	expectEqual(t, "Begin|A|B|Skipped|Exit|Exit|End", myReporter.wholeStory())
+}
+
+func TestMultipleSkipsAreReported(t *testing.T) {
+	myReporter, test := setupFakeReporter()
+
+	Convey("A", test, func() {
+		Convey("0", func() {
+			So(nil, ShouldBeNil)
+		})
+
+		SkipConvey("1", func() {})
+		SkipConvey("2", func() {})
+
+		Convey("3", nil)
+		Convey("4", nil)
+
+		Convey("5", func() {
+			So(nil, ShouldBeNil)
+		})
+	})
+
+	expected := "Begin" +
+		"|A|0|Success|Exit|Exit" +
+		"|A|1|Skipped|Exit|Exit" +
+		"|A|2|Skipped|Exit|Exit" +
+		"|A|3|Skipped|Exit|Exit" +
+		"|A|4|Skipped|Exit|Exit" +
+		"|A|5|Success|Exit|Exit" +
+		"|End"
+
+	expectEqual(t, expected, myReporter.wholeStory())
+}
+
+func TestSkippedAssertionIsNotReported(t *testing.T) {
+	myReporter, test := setupFakeReporter()
+
+	Convey("A", test, func() {
+		SkipSo(1, ShouldEqual, 1)
+	})
+
+	expectEqual(t, "Begin|A|Skipped|Exit|End", myReporter.wholeStory())
+}
+
+func TestMultipleSkippedAssertionsAreNotReported(t *testing.T) {
+	myReporter, test := setupFakeReporter()
+
+	Convey("A", test, func() {
+		SkipSo(1, ShouldEqual, 1)
+		So(1, ShouldEqual, 1)
+		SkipSo(1, ShouldEqual, 1)
+	})
+
+	expectEqual(t, "Begin|A|Skipped|Success|Skipped|Exit|End", myReporter.wholeStory())
+}
+
+func TestErrorByManualPanicReported(t *testing.T) {
+	myReporter, test := setupFakeReporter()
+
+	Convey("A", test, func() {
+		panic("Gopher alert!")
+	})
+
+	expectEqual(t, "Begin|A|Error|Exit|End", myReporter.wholeStory())
+}
+
+func TestIterativeConveysReported(t *testing.T) {
+	myReporter, test := setupFakeReporter()
+
+	Convey("A", test, func() {
+		for x := 0; x < 3; x++ {
+			Convey(strconv.Itoa(x), func() {
+				So(x, ShouldEqual, x)
+			})
+		}
+	})
+
+	expectEqual(t, "Begin|A|0|Success|Exit|Exit|A|1|Success|Exit|Exit|A|2|Success|Exit|Exit|End", myReporter.wholeStory())
+}
+
+func TestEmbeddedAssertionReported(t *testing.T) {
+	myReporter, test := setupFakeReporter()
+
+	Convey("A", test, func() {
+		ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+			So(r.FormValue("msg"), ShouldEqual, "ping")
+		}))
+		http.DefaultClient.Get(ts.URL + "?msg=ping")
+	})
+
+	expectEqual(t, "Begin|A|Success|Exit|End", myReporter.wholeStory())
+}
+
+func expectEqual(t *testing.T, expected interface{}, actual interface{}) {
+	if expected != actual {
+		_, file, line, _ := runtime.Caller(1)
+		t.Errorf("Expected '%v' to be '%v' but it wasn't. See '%s' at line %d.",
+			actual, expected, path.Base(file), line)
+	}
+}
+
+func setupFakeReporter() (*fakeReporter, *fakeGoTest) {
+	myReporter := new(fakeReporter)
+	myReporter.calls = []string{}
+	testReporter = myReporter
+	return myReporter, new(fakeGoTest)
+}
+
+type fakeReporter struct {
+	calls []string
+}
+
+func (self *fakeReporter) BeginStory(story *reporting.StoryReport) {
+	self.calls = append(self.calls, "Begin")
+}
+
+func (self *fakeReporter) Enter(scope *reporting.ScopeReport) {
+	self.calls = append(self.calls, scope.Title)
+}
+
+func (self *fakeReporter) Report(report *reporting.AssertionResult) {
+	if report.Error != nil {
+		self.calls = append(self.calls, "Error")
+	} else if report.Failure != "" {
+		message := "Failure"
+		if report.Expected != "" || report.Actual != "" {
+			message += fmt.Sprintf("(%s/%s)", report.Expected, report.Actual)
+		}
+		self.calls = append(self.calls, message)
+	} else if report.Skipped {
+		self.calls = append(self.calls, "Skipped")
+	} else {
+		self.calls = append(self.calls, "Success")
+	}
+}
+
+func (self *fakeReporter) Exit() {
+	self.calls = append(self.calls, "Exit")
+}
+
+func (self *fakeReporter) EndStory() {
+	self.calls = append(self.calls, "End")
+}
+
+func (self *fakeReporter) Write(content []byte) (int, error) {
+	return len(content), nil // no-op
+}
+
+func (self *fakeReporter) wholeStory() string {
+	return strings.Join(self.calls, "|")
+}
+
+////////////////////////////////
+
+type fakeGoTest struct{}
+
+func (self *fakeGoTest) Fail()                                     {}
+func (self *fakeGoTest) Fatalf(format string, args ...interface{}) {}
+
+var test t = new(fakeGoTest)

+ 92 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/runner.go

@@ -0,0 +1,92 @@
+package convey
+
+import (
+	"github.com/smartystreets/goconvey/convey/reporting"
+)
+
+type runner struct {
+	top         *scope
+	active      *scope
+	reporter    reporting.Reporter
+	failureMode FailureMode
+	focus       bool
+}
+
+func (self *runner) Register(entry *registration) {
+	if self.focus && !entry.Focus {
+		return
+	}
+
+	self.active.adopt(newScope(entry, self.reporter))
+}
+
+func (self *runner) RegisterReset(action *action) {
+	self.active.registerReset(action)
+}
+
+func (self *runner) Run(entry *registration) {
+	self.active = self.top
+	self.focus = entry.Focus
+	self.failureMode = defaultFailureMode
+
+	self.Register(entry)
+	self.reporter.BeginStory(reporting.NewStoryReport(entry.Test))
+
+	for !self.top.visited() {
+		self.top.visit(self)
+	}
+
+	self.reporter.EndStory()
+}
+
+func newRunner(reporter reporting.Reporter) *runner {
+	// Top-level is always using a nilReporter
+	scope := newScope(newRegistration(topLevel, newAction(func() {}, FailureInherits), nil), newNilReporter())
+
+	return &runner{
+		reporter: reporter,
+		top:      scope,
+		active:   scope,
+	}
+}
+
+func (self *runner) Report(result *reporting.AssertionResult) {
+	self.reporter.Report(result)
+
+	if result.Failure != "" && self.failureMode == FailureHalts {
+		panic(failureHalt)
+	}
+}
+
+func (self *runner) Write(content []byte) (written int, err error) {
+	return self.reporter.Write(content)
+}
+
+func (self *runner) setFailureMode(mode FailureMode) FailureMode {
+	old := self.failureMode
+
+	if mode != FailureInherits {
+		self.failureMode = mode
+	}
+
+	return old
+}
+
+func last(group []string) string {
+	return group[len(group)-1]
+}
+
+const topLevel = "TOP"
+const failureHalt = "___FAILURE_HALT___"
+
+//////////////////////// nilReporter /////////////////////////////
+
+type nilReporter struct{}
+
+func (self *nilReporter) BeginStory(story *reporting.StoryReport)  {}
+func (self *nilReporter) Enter(scope *reporting.ScopeReport)       {}
+func (self *nilReporter) Report(report *reporting.AssertionResult) {}
+func (self *nilReporter) Exit()                                    {}
+func (self *nilReporter) EndStory()                                {}
+func (self *nilReporter) Write(p []byte) (int, error)              { return len(p), nil }
+func newNilReporter() *nilReporter                                 { return &nilReporter{} }

+ 116 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/scope.go

@@ -0,0 +1,116 @@
+package convey
+
+import (
+	"fmt"
+	"strings"
+
+	"github.com/smartystreets/goconvey/convey/reporting"
+)
+
+type scope struct {
+	name       string
+	title      string
+	action     *action
+	children   map[string]*scope
+	birthOrder []*scope
+	child      int
+	resetOrder []string
+	resets     map[string]*action
+	panicked   bool
+	reporter   reporting.Reporter
+	report     *reporting.ScopeReport
+}
+
+func (parent *scope) adopt(child *scope) {
+	i := parent.getChildIndex(child)
+
+	if i == -1 {
+		parent.children[child.name] = child
+		parent.birthOrder = append(parent.birthOrder, child)
+	} else {
+		/* We need to replace the action to retain the closed over variables from
+		   the specific invocation of the parent scope, enabling the enclosing
+		   parent scope to serve as a set-up for the child scope */
+		parent.birthOrder[i].action = child.action
+	}
+}
+
+func (parent *scope) getChildIndex(child *scope) int {
+	for i, ordered := range parent.birthOrder {
+		if ordered.name == child.name && ordered.title == child.title {
+			return i
+		}
+	}
+
+	return -1
+}
+
+func (self *scope) registerReset(action *action) {
+	self.resets[action.name] = action
+	for _, name := range self.resetOrder {
+		if name == action.name {
+			return
+		}
+	}
+	self.resetOrder = append(self.resetOrder, action.name)
+}
+
+func (self *scope) visited() bool {
+	return self.panicked || self.child >= len(self.birthOrder)
+}
+
+func (parent *scope) visit(runner *runner) {
+	runner.active = parent
+	defer parent.exit()
+
+	oldMode := runner.setFailureMode(parent.action.failureMode)
+	defer runner.setFailureMode(oldMode)
+
+	parent.reporter.Enter(parent.report)
+	parent.action.Invoke()
+	parent.visitNextChild(runner)
+	parent.cleanup()
+}
+func (parent *scope) visitNextChild(runner *runner) {
+	if len(parent.birthOrder) > parent.child {
+		child := parent.birthOrder[parent.child]
+
+		child.visit(runner)
+
+		if child.visited() {
+			parent.child++
+		}
+	}
+}
+func (parent *scope) cleanup() {
+	for _, name := range parent.resetOrder {
+		reset := parent.resets[name]
+		reset.Invoke()
+	}
+}
+func (parent *scope) exit() {
+	if problem := recover(); problem != nil {
+		if strings.HasPrefix(fmt.Sprintf("%v", problem), extraGoTest) {
+			panic(problem)
+		}
+		if problem != failureHalt {
+			parent.reporter.Report(reporting.NewErrorReport(problem))
+		}
+		parent.panicked = true
+	}
+	parent.reporter.Exit()
+}
+
+func newScope(entry *registration, reporter reporting.Reporter) *scope {
+	return &scope{
+		reporter:   reporter,
+		name:       entry.action.name,
+		title:      entry.Situation,
+		action:     entry.action,
+		children:   make(map[string]*scope),
+		birthOrder: []*scope{},
+		resetOrder: []string{},
+		resets:     make(map[string]*action),
+		report:     reporting.NewScopeReport(entry.Situation, entry.action.name),
+	}
+}

+ 185 - 0
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/story_conventions_test.go

@@ -0,0 +1,185 @@
+package convey
+
+import (
+	"fmt"
+	"strings"
+	"testing"
+)
+
+func TestMissingTopLevelGoTestReferenceCausesPanic(t *testing.T) {
+	output := map[string]bool{}
+
+	defer expectEqual(t, false, output["good"])
+	defer requireGoTestReference(t)
+
+	Convey("Hi", func() {
+		output["bad"] = true // this shouldn't happen
+	})
+}
+
+func requireGoTestReference(t *testing.T) {
+	err := recover()
+	if err == nil {
+		t.Error("We should have recovered a panic here (because of a missing *testing.T reference)!")
+	} else {
+		expectEqual(t, missingGoTest, err)
+	}
+}
+
+func TestMissingTopLevelGoTestReferenceAfterGoodExample(t *testing.T) {
+	output := map[string]bool{}
+
+	defer func() {
+		expectEqual(t, true, output["good"])
+		expectEqual(t, false, output["bad"])
+	}()
+	defer requireGoTestReference(t)
+
+	Convey("Good example", t, func() {
+		output["good"] = true
+	})
+
+	Convey("Bad example", func() {
+		output["bad"] = true // shouldn't happen
+	})
+}
+
+func TestExtraReferencePanics(t *testing.T) {
+	output := map[string]bool{}
+
+	defer func() {
+		err := recover()
+		if err == nil {
+			t.Error("We should have recovered a panic here (because of an extra *testing.T reference)!")
+		} else if !strings.HasPrefix(fmt.Sprintf("%v", err), extraGoTest) {
+			t.Error("Should have panicked with the 'extra go test' error!")
+		}
+		if output["bad"] {
+			t.Error("We should NOT have run the bad example!")
+		}
+	}()
+
+	Convey("Good example", t, func() {
+		Convey("Bad example - passing in *testing.T a second time!", t, func() {
+			output["bad"] = true // shouldn't happen
+		})
+	})
+}
+
+func TestParseRegistrationMissingRequiredElements(t *testing.T) {
+	defer func() {
+		if r := recover(); r != nil {
+			if r != "You must provide a name (string), then a *testing.T (if in outermost scope), an optional FailureMode, and then an action (func())." {
+				t.Errorf("Incorrect panic message.")
+			}
+		}
+	}()
+
+	Convey()
+
+	t.Errorf("goTest should have panicked in Convey(...) and then recovered in the defer func().")
+}
+
+func TestParseRegistration_MissingNameString(t *testing.T) {
+	defer func() {
+		if r := recover(); r != nil {
+			if r != parseError {
+				t.Errorf("Incorrect panic message.")
+			}
+		}
+	}()
+
+	action := func() {}
+
+	Convey(action)
+
+	t.Errorf("goTest should have panicked in Convey(...) and then recovered in the defer func().")
+}
+
+func TestParseRegistration_MissingActionFunc(t *testing.T) {
+	defer func() {
+		if r := recover(); r != nil {
+			if r != parseError {
+				t.Errorf("Incorrect panic message: '%s'", r)
+			}
+		}
+	}()
+
+	Convey("Hi there", 12345)
+
+	t.Errorf("goTest should have panicked in Convey(...) and then recovered in the defer func().")
+}
+
+func TestFailureModeParameterButMissing(t *testing.T) {
+	defer func() {
+		if r := recover(); r != nil {
+			if r != parseError {
+				t.Errorf("Incorrect panic message.")
+			}
+		} else {
+			t.Errorf("Expected panic")
+		}
+	}()
+
+	prepare()
+
+	Convey("Foobar", t, FailureHalts)
+}
+
+func TestFailureModeParameterWithAction(t *testing.T) {
+	prepare()
+
+	defer func() {
+		if r := recover(); r != nil {
+			t.Errorf("Unexpected panic")
+		}
+	}()
+
+	Convey("Foobar", t, FailureHalts, func() {})
+}
+
+func TestExtraConveyParameters(t *testing.T) {
+	defer func() {
+		if r := recover(); r != nil {
+			if r != parseError {
+				t.Errorf("Incorrect panic message.")
+			}
+		} else {
+			t.Errorf("Expected panic")
+		}
+	}()
+
+	prepare()
+
+	Convey("Foobar", t, FailureHalts, func() {}, "This is not supposed to be here")
+}
+
+func TestExtraConveyParameters2(t *testing.T) {
+	defer func() {
+		if r := recover(); r != nil {
+			if r != parseError {
+				t.Errorf("Incorrect panic message.")
+			}
+		} else {
+			t.Errorf("Expected panic")
+		}
+	}()
+
+	prepare()
+
+	Convey("Foobar", t, func() {}, "This is not supposed to be here")
+}
+
+func TestExtraConveyParameters3(t *testing.T) {
+	output := prepare()
+
+	Convey("A", t, func() {
+		output += "A "
+
+		Convey("B", func() {
+			output += "B "
+		}, "This is not supposed to be here")
+	})
+
+	expectEqual(t, "A ", output)
+}