mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Updated packages
This commit is contained in:
parent
c4a48b35c0
commit
b2f70c12b9
5
Godeps/Godeps.json
generated
5
Godeps/Godeps.json
generated
@ -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"
|
||||
|
1
Godeps/_workspace/src/github.com/go-xorm/core/mapper.go
generated
vendored
1
Godeps/_workspace/src/github.com/go-xorm/core/mapper.go
generated
vendored
@ -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
Godeps/_workspace/src/github.com/jacobsa/oglematchers/.gitignore
generated
vendored
Normal file
5
Godeps/_workspace/src/github.com/jacobsa/oglematchers/.gitignore
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
*.6
|
||||
6.out
|
||||
_obj/
|
||||
_test/
|
||||
_testmain.go
|
202
Godeps/_workspace/src/github.com/jacobsa/oglematchers/LICENSE
generated
vendored
Normal file
202
Godeps/_workspace/src/github.com/jacobsa/oglematchers/LICENSE
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/jacobsa/oglematchers/README.markdown
generated
vendored
Normal file
56
Godeps/_workspace/src/github.com/jacobsa/oglematchers/README.markdown
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/jacobsa/oglematchers/all_of.go
generated
vendored
Normal file
70
Godeps/_workspace/src/github.com/jacobsa/oglematchers/all_of.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/jacobsa/oglematchers/all_of_test.go
generated
vendored
Normal file
110
Godeps/_workspace/src/github.com/jacobsa/oglematchers/all_of_test.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/jacobsa/oglematchers/any.go
generated
vendored
Normal file
32
Godeps/_workspace/src/github.com/jacobsa/oglematchers/any.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/jacobsa/oglematchers/any_of.go
generated
vendored
Normal file
93
Godeps/_workspace/src/github.com/jacobsa/oglematchers/any_of.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/jacobsa/oglematchers/any_of_test.go
generated
vendored
Normal file
121
Godeps/_workspace/src/github.com/jacobsa/oglematchers/any_of_test.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/jacobsa/oglematchers/any_test.go
generated
vendored
Normal file
53
Godeps/_workspace/src/github.com/jacobsa/oglematchers/any_test.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/jacobsa/oglematchers/contains.go
generated
vendored
Normal file
61
Godeps/_workspace/src/github.com/jacobsa/oglematchers/contains.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/jacobsa/oglematchers/contains_test.go
generated
vendored
Normal file
233
Godeps/_workspace/src/github.com/jacobsa/oglematchers/contains_test.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/jacobsa/oglematchers/deep_equals.go
generated
vendored
Normal file
88
Godeps/_workspace/src/github.com/jacobsa/oglematchers/deep_equals.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/jacobsa/oglematchers/deep_equals_test.go
generated
vendored
Normal file
343
Godeps/_workspace/src/github.com/jacobsa/oglematchers/deep_equals_test.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/jacobsa/oglematchers/elements_are.go
generated
vendored
Normal file
91
Godeps/_workspace/src/github.com/jacobsa/oglematchers/elements_are.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/jacobsa/oglematchers/elements_are_test.go
generated
vendored
Normal file
208
Godeps/_workspace/src/github.com/jacobsa/oglematchers/elements_are_test.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/jacobsa/oglematchers/equals.go
generated
vendored
Normal file
557
Godeps/_workspace/src/github.com/jacobsa/oglematchers/equals.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/jacobsa/oglematchers/equals_test.go
generated
vendored
Normal file
3843
Godeps/_workspace/src/github.com/jacobsa/oglematchers/equals_test.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
51
Godeps/_workspace/src/github.com/jacobsa/oglematchers/error.go
generated
vendored
Normal file
51
Godeps/_workspace/src/github.com/jacobsa/oglematchers/error.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/jacobsa/oglematchers/error_test.go
generated
vendored
Normal file
92
Godeps/_workspace/src/github.com/jacobsa/oglematchers/error_test.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/jacobsa/oglematchers/greater_or_equal.go
generated
vendored
Normal file
39
Godeps/_workspace/src/github.com/jacobsa/oglematchers/greater_or_equal.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/jacobsa/oglematchers/greater_or_equal_test.go
generated
vendored
Normal file
1059
Godeps/_workspace/src/github.com/jacobsa/oglematchers/greater_or_equal_test.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
39
Godeps/_workspace/src/github.com/jacobsa/oglematchers/greater_than.go
generated
vendored
Normal file
39
Godeps/_workspace/src/github.com/jacobsa/oglematchers/greater_than.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/jacobsa/oglematchers/greater_than_test.go
generated
vendored
Normal file
1079
Godeps/_workspace/src/github.com/jacobsa/oglematchers/greater_than_test.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
52
Godeps/_workspace/src/github.com/jacobsa/oglematchers/has_substr.go
generated
vendored
Normal file
52
Godeps/_workspace/src/github.com/jacobsa/oglematchers/has_substr.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/jacobsa/oglematchers/has_substr_test.go
generated
vendored
Normal file
93
Godeps/_workspace/src/github.com/jacobsa/oglematchers/has_substr_test.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/jacobsa/oglematchers/identical_to.go
generated
vendored
Normal file
134
Godeps/_workspace/src/github.com/jacobsa/oglematchers/identical_to.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/jacobsa/oglematchers/identical_to_test.go
generated
vendored
Normal file
849
Godeps/_workspace/src/github.com/jacobsa/oglematchers/identical_to_test.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/jacobsa/oglematchers/less_or_equal.go
generated
vendored
Normal file
41
Godeps/_workspace/src/github.com/jacobsa/oglematchers/less_or_equal.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/jacobsa/oglematchers/less_or_equal_test.go
generated
vendored
Normal file
1079
Godeps/_workspace/src/github.com/jacobsa/oglematchers/less_or_equal_test.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
152
Godeps/_workspace/src/github.com/jacobsa/oglematchers/less_than.go
generated
vendored
Normal file
152
Godeps/_workspace/src/github.com/jacobsa/oglematchers/less_than.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/jacobsa/oglematchers/less_than_test.go
generated
vendored
Normal file
1059
Godeps/_workspace/src/github.com/jacobsa/oglematchers/less_than_test.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
82
Godeps/_workspace/src/github.com/jacobsa/oglematchers/matcher.go
generated
vendored
Normal file
82
Godeps/_workspace/src/github.com/jacobsa/oglematchers/matcher.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/jacobsa/oglematchers/matches_regexp.go
generated
vendored
Normal file
69
Godeps/_workspace/src/github.com/jacobsa/oglematchers/matches_regexp.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/jacobsa/oglematchers/matches_regexp_test.go
generated
vendored
Normal file
92
Godeps/_workspace/src/github.com/jacobsa/oglematchers/matches_regexp_test.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/jacobsa/oglematchers/not.go
generated
vendored
Normal file
53
Godeps/_workspace/src/github.com/jacobsa/oglematchers/not.go
generated
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
// Copyright 2011 Aaron Jacobs. All Rights Reserved.
|
||||
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package oglematchers
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Not returns a matcher that inverts the set of values matched by the wrapped
|
||||
// matcher. It does not transform the result for values for which the wrapped
|
||||
// matcher returns a fatal error.
|
||||
func Not(m Matcher) Matcher {
|
||||
return ¬Matcher{m}
|
||||
}
|
||||
|
||||
type notMatcher struct {
|
||||
wrapped Matcher
|
||||
}
|
||||
|
||||
func (m *notMatcher) Matches(c interface{}) (err error) {
|
||||
err = m.wrapped.Matches(c)
|
||||
|
||||
// Did the wrapped matcher say yes?
|
||||
if err == nil {
|
||||
return errors.New("")
|
||||
}
|
||||
|
||||
// Did the wrapped matcher return a fatal error?
|
||||
if _, isFatal := err.(*FatalError); isFatal {
|
||||
return err
|
||||
}
|
||||
|
||||
// The wrapped matcher returned a non-fatal error.
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *notMatcher) Description() string {
|
||||
return fmt.Sprintf("not(%s)", m.wrapped.Description())
|
||||
}
|
108
Godeps/_workspace/src/github.com/jacobsa/oglematchers/not_test.go
generated
vendored
Normal file
108
Godeps/_workspace/src/github.com/jacobsa/oglematchers/not_test.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/jacobsa/oglematchers/panics.go
generated
vendored
Normal file
74
Godeps/_workspace/src/github.com/jacobsa/oglematchers/panics.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/jacobsa/oglematchers/panics_test.go
generated
vendored
Normal file
141
Godeps/_workspace/src/github.com/jacobsa/oglematchers/panics_test.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/jacobsa/oglematchers/pointee.go
generated
vendored
Normal file
65
Godeps/_workspace/src/github.com/jacobsa/oglematchers/pointee.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/jacobsa/oglematchers/pointee_test.go
generated
vendored
Normal file
152
Godeps/_workspace/src/github.com/jacobsa/oglematchers/pointee_test.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/jacobsa/oglematchers/transform_description.go
generated
vendored
Normal file
36
Godeps/_workspace/src/github.com/jacobsa/oglematchers/transform_description.go
generated
vendored
Normal file
@ -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)
|
||||
}
|
6
Godeps/_workspace/src/github.com/mattn/go-sqlite3/doc.go
generated
vendored
6
Godeps/_workspace/src/github.com/mattn/go-sqlite3/doc.go
generated
vendored
@ -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
|
||||
|
6
Godeps/_workspace/src/github.com/mattn/go-sqlite3/sqlite3_test/sqltest.go
generated
vendored
6
Godeps/_workspace/src/github.com/mattn/go-sqlite3/sqlite3_test/sqltest.go
generated
vendored
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions.go
generated
vendored
Normal file
63
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/collections.go
generated
vendored
Normal file
140
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/collections.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/collections_test.go
generated
vendored
Normal file
103
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/collections_test.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/doc.go
generated
vendored
Normal file
3
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/doc.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/equality.go
generated
vendored
Normal file
281
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/equality.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/equality_test.go
generated
vendored
Normal file
256
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/equality_test.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/filter.go
generated
vendored
Normal file
22
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/filter.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/init.go
generated
vendored
Normal file
7
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/init.go
generated
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
package assertions
|
||||
|
||||
var serializer Serializer
|
||||
|
||||
func init() {
|
||||
serializer = newSerializer()
|
||||
}
|
86
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/messages.go
generated
vendored
Normal file
86
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/messages.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/panic.go
generated
vendored
Normal file
115
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/panic.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/panic_test.go
generated
vendored
Normal file
53
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/panic_test.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/quantity.go
generated
vendored
Normal file
141
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/quantity.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/quantity_test.go
generated
vendored
Normal file
145
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/quantity_test.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/serializer.go
generated
vendored
Normal file
31
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/serializer.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/serializer_test.go
generated
vendored
Normal file
28
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/serializer_test.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/strings.go
generated
vendored
Normal file
183
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/strings.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/strings_test.go
generated
vendored
Normal file
102
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/strings_test.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/time.go
generated
vendored
Normal file
202
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/time.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/time_test.go
generated
vendored
Normal file
159
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/time_test.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/type.go
generated
vendored
Normal file
112
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/type.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/type_test.go
generated
vendored
Normal file
76
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/type_test.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/utilities_for_test.go
generated
vendored
Normal file
75
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/assertions/utilities_for_test.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/context.go
generated
vendored
Normal file
179
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/context.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/discovery.go
generated
vendored
Normal file
57
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/discovery.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/doc.go
generated
vendored
Normal file
178
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/doc.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/focused_execution_test.go
generated
vendored
Normal file
72
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/focused_execution_test.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/gotest/utils.go
generated
vendored
Normal file
37
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/gotest/utils.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/init.go
generated
vendored
Normal file
72
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/init.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/isolated_execution_test.go
generated
vendored
Normal file
742
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/isolated_execution_test.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/registration.go
generated
vendored
Normal file
74
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/registration.go
generated
vendored
Normal file
@ -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 ®istration{
|
||||
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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/console.go
generated
vendored
Normal file
16
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/console.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/doc.go
generated
vendored
Normal file
5
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/doc.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/dot.go
generated
vendored
Normal file
40
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/dot.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/dot_test.go
generated
vendored
Normal file
40
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/dot_test.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/gotest.go
generated
vendored
Normal file
33
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/gotest.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/gotest_test.go
generated
vendored
Normal file
66
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/gotest_test.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/init.go
generated
vendored
Normal file
94
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/init.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/json.go
generated
vendored
Normal file
88
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/json.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/printer.go
generated
vendored
Normal file
57
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/printer.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/printer_test.go
generated
vendored
Normal file
181
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/printer_test.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/problems.go
generated
vendored
Normal file
68
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/problems.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/problems_test.go
generated
vendored
Normal file
46
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/problems_test.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/reporter.go
generated
vendored
Normal file
39
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/reporter.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/reporter_test.go
generated
vendored
Normal file
94
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/reporter_test.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/reports.go
generated
vendored
Normal file
179
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/reports.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/statistics.go
generated
vendored
Normal file
79
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/statistics.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/story.go
generated
vendored
Normal file
65
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/story.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting_hooks_test.go
generated
vendored
Normal file
270
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting_hooks_test.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/runner.go
generated
vendored
Normal file
92
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/runner.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/scope.go
generated
vendored
Normal file
116
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/scope.go
generated
vendored
Normal file
@ -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
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/story_conventions_test.go
generated
vendored
Normal file
185
Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/story_conventions_test.go
generated
vendored
Normal file
@ -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)
|
||||
}
|
Loading…
Reference in New Issue
Block a user