mirror of
https://github.com/stretchr/testify.git
synced 2025-07-13 07:39:48 +00:00
Compare commits
No commits in common. "master" and "v1.7.4" have entirely different histories.
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
#!/bin/bash
|
||||
|
||||
if [ -n "$(gofmt -l .)" ]; then
|
||||
echo "Go code is not formatted:"
|
||||
|
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
#!/bin/bash
|
||||
|
||||
# If GOMOD is defined we are running with Go Modules enabled, either
|
||||
# automatically or via the GO111MODULE=on environment variable. Codegen only
|
||||
|
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
|
@ -1,12 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Verify that the code snippets in README.md are formatted.
|
||||
# The tool https://github.com/hougesen/mdsf is used.
|
||||
|
||||
if [ -n "$(mdsf verify --config .mdsf.json --log-level error README.md 2>&1)" ]; then
|
||||
echo "Go code in the README.md is not formatted."
|
||||
echo "Did you forget to run 'mdsf format --config .mdsf.json README.md'?"
|
||||
mdsf format --config .mdsf.json README.md
|
||||
git diff
|
||||
exit 1
|
||||
fi
|
23
.github/ISSUE_TEMPLATE/bug_report.md
vendored
23
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -1,23 +0,0 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Format to report a bug
|
||||
title: ''
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!-- If this is a question, consider using the discussion section of this repo -->
|
||||
<!-- Here: https://github.com/stretchr/testify/discussions/new?category=q-a -->
|
||||
|
||||
## Description
|
||||
<!-- A detailed description of the bug -->
|
||||
|
||||
## Step To Reproduce
|
||||
<!-- Steps or code snippet to reproduce the behavior -->
|
||||
|
||||
## Expected behavior
|
||||
<!-- A clear and concise description of what you expected to happen -->
|
||||
|
||||
## Actual behavior
|
||||
<!-- What testify does -->
|
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@ -1,20 +0,0 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Propose a new feature
|
||||
title: ''
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!-- If this is a question, consider using the discussion section of this repo -->
|
||||
<!-- Here: https://github.com/stretchr/testify/discussions/new?category=q-a -->
|
||||
|
||||
## Description
|
||||
<!-- A clear and concise description of what feature you are proposing -->
|
||||
|
||||
## Proposed solution
|
||||
<!-- Optionally a suggested implementation -->
|
||||
|
||||
## Use case
|
||||
<!-- What is the motivation? What workarounds have you used? -->
|
30
.github/workflows/main.yml
vendored
30
.github/workflows/main.yml
vendored
@ -6,36 +6,14 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
go_version:
|
||||
- stable
|
||||
- oldstable
|
||||
go_version: ["1.18.1", "1.17.6", "1.16.5"]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v3
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v5
|
||||
uses: actions/setup-go@v3.2.0
|
||||
with:
|
||||
go-version: ${{ matrix.go_version }}
|
||||
- run: npm install -g mdsf-cli
|
||||
- run: ./.ci.gogenerate.sh
|
||||
- run: ./.ci.gogenerate.sh
|
||||
- run: ./.ci.gofmt.sh
|
||||
- run: ./.ci.readme.fmt.sh
|
||||
- run: ./.ci.govet.sh
|
||||
- run: go test -v -race ./...
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
go_version:
|
||||
- "1.17"
|
||||
- "1.18"
|
||||
- "1.19"
|
||||
- "1.20"
|
||||
- "1.21"
|
||||
- "1.22"
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ${{ matrix.go_version }}
|
||||
- run: go test -v -race ./...
|
||||
|
21
.github/workflows/release.yml
vendored
21
.github/workflows/release.yml
vendored
@ -1,21 +0,0 @@
|
||||
name: Create release from new tag
|
||||
|
||||
# this flow will be run only when new tags are pushed that match our pattern
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "v[0-9]+.[0-9]+.[0-9]+"
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Create GitHub release from tag
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
generate_release_notes: true
|
6
.gitignore
vendored
6
.gitignore
vendored
@ -22,9 +22,3 @@ _testmain.go
|
||||
*.exe
|
||||
|
||||
.DS_Store
|
||||
|
||||
# Output of "go test -c"
|
||||
/assert/assert.test
|
||||
/require/require.test
|
||||
/suite/suite.test
|
||||
/mock/mock.test
|
||||
|
12
.mdsf.json
12
.mdsf.json
@ -1,12 +0,0 @@
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/hougesen/mdsf/main/schemas/v0.8.2/mdsf.schema.json",
|
||||
"format_finished_document": false,
|
||||
"languages": {
|
||||
"go": [
|
||||
[
|
||||
"gofmt",
|
||||
"goimports"
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
12
EMERITUS.md
12
EMERITUS.md
@ -1,12 +0,0 @@
|
||||
# Emeritus
|
||||
|
||||
We would like to acknowledge previous testify maintainers and their huge contributions to our collective success:
|
||||
|
||||
* @matryer
|
||||
* @glesica
|
||||
* @ernesto-jimenez
|
||||
* @mvdkleijn
|
||||
* @georgelesica-wf
|
||||
* @bencampbell-wf
|
||||
|
||||
We thank these members for their service to this community.
|
@ -3,15 +3,7 @@
|
||||
The individuals listed below are active in the project and have the ability to approve and merge
|
||||
pull requests.
|
||||
|
||||
* @glesica
|
||||
* @boyan-soubachov
|
||||
* @dolmen
|
||||
* @MovieStoreGuy
|
||||
* @brackendawson
|
||||
* @mvdkleijn
|
||||
|
||||
## Approvers
|
||||
|
||||
The individuals listed below are active in the project and have the ability to approve pull
|
||||
requests.
|
||||
|
||||
* @arjunmahishi
|
||||
* @ccoVeille
|
||||
|
222
README.md
222
README.md
@ -1,11 +1,9 @@
|
||||
Testify - Thou Shalt Write Tests
|
||||
================================
|
||||
|
||||
> [!NOTE]
|
||||
> Testify is being maintained at v1, no breaking changes will be accepted in this repo.
|
||||
> [See discussion about v2](https://github.com/stretchr/testify/discussions/1560).
|
||||
ℹ️ We are working on testify v2 and would love to hear what you'd like to see in it, have your say here: https://cutt.ly/testify
|
||||
|
||||
[](https://github.com/stretchr/testify/actions/workflows/main.yml) [](https://goreportcard.com/report/github.com/stretchr/testify) [](https://pkg.go.dev/github.com/stretchr/testify)
|
||||
[](https://travis-ci.org/stretchr/testify) [](https://goreportcard.com/report/github.com/stretchr/testify) [](https://pkg.go.dev/github.com/stretchr/testify)
|
||||
|
||||
Go code (golang) set of packages that provide many tools for testifying that your code will behave as you intend.
|
||||
|
||||
@ -18,12 +16,14 @@ Features include:
|
||||
Get started:
|
||||
|
||||
* Install testify with [one line of code](#installation), or [update it with another](#staying-up-to-date)
|
||||
* For an introduction to writing test code in Go, see https://go.dev/doc/code#Testing
|
||||
* Check out the API Documentation https://pkg.go.dev/github.com/stretchr/testify
|
||||
* Use [testifylint](https://github.com/Antonboom/testifylint) (via [golangci-lint](https://golangci-lint.run/)) to avoid common mistakes
|
||||
* A little about [Test-Driven Development (TDD)](https://en.wikipedia.org/wiki/Test-driven_development)
|
||||
* For an introduction to writing test code in Go, see http://golang.org/doc/code.html#Testing
|
||||
* Check out the API Documentation http://godoc.org/github.com/stretchr/testify
|
||||
* To make your testing life easier, check out our other project, [gorc](http://github.com/stretchr/gorc)
|
||||
* A little about [Test-Driven Development (TDD)](http://en.wikipedia.org/wiki/Test-driven_development)
|
||||
|
||||
[`assert`](https://pkg.go.dev/github.com/stretchr/testify/assert "API documentation") package
|
||||
|
||||
|
||||
[`assert`](http://godoc.org/github.com/stretchr/testify/assert "API documentation") package
|
||||
-------------------------------------------------------------------------------------------
|
||||
|
||||
The `assert` package provides some helpful methods that allow you to write better test code in Go.
|
||||
@ -38,27 +38,30 @@ See it in action:
|
||||
package yours
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestSomething(t *testing.T) {
|
||||
// assert equality
|
||||
assert.Equal(t, 123, 123, "they should be equal")
|
||||
|
||||
// assert inequality
|
||||
assert.NotEqual(t, 123, 456, "they should not be equal")
|
||||
// assert equality
|
||||
assert.Equal(t, 123, 123, "they should be equal")
|
||||
|
||||
// assert for nil (good for errors)
|
||||
assert.Nil(t, object)
|
||||
// assert inequality
|
||||
assert.NotEqual(t, 123, 456, "they should not be equal")
|
||||
|
||||
// assert for nil (good for errors)
|
||||
assert.Nil(t, object)
|
||||
|
||||
// assert for not nil (good when you expect something)
|
||||
if assert.NotNil(t, object) {
|
||||
|
||||
// now we know that object isn't nil, we are safe to make
|
||||
// further assertions without causing any errors
|
||||
assert.Equal(t, "Something", object.Value)
|
||||
|
||||
}
|
||||
|
||||
// assert for not nil (good when you expect something)
|
||||
if assert.NotNil(t, object) {
|
||||
// now we know that object isn't nil, we are safe to make
|
||||
// further assertions without causing any errors
|
||||
assert.Equal(t, "Something", object.Value)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@ -71,55 +74,52 @@ if you assert many times, use the below:
|
||||
package yours
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestSomething(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
assert := assert.New(t)
|
||||
|
||||
// assert equality
|
||||
assert.Equal(123, 123, "they should be equal")
|
||||
// assert equality
|
||||
assert.Equal(123, 123, "they should be equal")
|
||||
|
||||
// assert inequality
|
||||
assert.NotEqual(123, 456, "they should not be equal")
|
||||
// assert inequality
|
||||
assert.NotEqual(123, 456, "they should not be equal")
|
||||
|
||||
// assert for nil (good for errors)
|
||||
assert.Nil(object)
|
||||
// assert for nil (good for errors)
|
||||
assert.Nil(object)
|
||||
|
||||
// assert for not nil (good when you expect something)
|
||||
if assert.NotNil(object) {
|
||||
// now we know that object isn't nil, we are safe to make
|
||||
// further assertions without causing any errors
|
||||
assert.Equal("Something", object.Value)
|
||||
}
|
||||
// assert for not nil (good when you expect something)
|
||||
if assert.NotNil(object) {
|
||||
|
||||
// now we know that object isn't nil, we are safe to make
|
||||
// further assertions without causing any errors
|
||||
assert.Equal("Something", object.Value)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
[`require`](https://pkg.go.dev/github.com/stretchr/testify/require "API documentation") package
|
||||
[`require`](http://godoc.org/github.com/stretchr/testify/require "API documentation") package
|
||||
---------------------------------------------------------------------------------------------
|
||||
|
||||
The `require` package provides same global functions as the `assert` package, but instead of returning a boolean result they terminate current test.
|
||||
These functions must be called from the goroutine running the test or benchmark function, not from other goroutines created during the test.
|
||||
Otherwise race conditions may occur.
|
||||
|
||||
See [t.FailNow](https://pkg.go.dev/testing#T.FailNow) for details.
|
||||
See [t.FailNow](http://golang.org/pkg/testing/#T.FailNow) for details.
|
||||
|
||||
[`mock`](https://pkg.go.dev/github.com/stretchr/testify/mock "API documentation") package
|
||||
[`mock`](http://godoc.org/github.com/stretchr/testify/mock "API documentation") package
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
The `mock` package provides a mechanism for easily writing mock objects that can be used in place of real objects when writing test code.
|
||||
|
||||
An example test function that tests a piece of code that relies on an external object `testObj`, can set up expectations (testify) and assert that they indeed happened:
|
||||
An example test function that tests a piece of code that relies on an external object `testObj`, can setup expectations (testify) and assert that they indeed happened:
|
||||
|
||||
```go
|
||||
package yours
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/mock"
|
||||
"testing"
|
||||
"github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
||||
/*
|
||||
@ -128,8 +128,8 @@ import (
|
||||
|
||||
// MyMockedObject is a mocked object that implements an interface
|
||||
// that describes an object that the code I am testing relies on.
|
||||
type MyMockedObject struct {
|
||||
mock.Mock
|
||||
type MyMockedObject struct{
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// DoSomething is a method on MyMockedObject that implements some interface
|
||||
@ -140,8 +140,10 @@ type MyMockedObject struct {
|
||||
//
|
||||
// NOTE: This method is not being tested here, code that uses this object is.
|
||||
func (m *MyMockedObject) DoSomething(number int) (bool, error) {
|
||||
args := m.Called(number)
|
||||
return args.Bool(0), args.Error(1)
|
||||
|
||||
args := m.Called(number)
|
||||
return args.Bool(0), args.Error(1)
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@ -151,17 +153,20 @@ func (m *MyMockedObject) DoSomething(number int) (bool, error) {
|
||||
// TestSomething is an example of how to use our test object to
|
||||
// make assertions about some target code we are testing.
|
||||
func TestSomething(t *testing.T) {
|
||||
// create an instance of our test object
|
||||
testObj := new(MyMockedObject)
|
||||
|
||||
// set up expectations
|
||||
testObj.On("DoSomething", 123).Return(true, nil)
|
||||
// create an instance of our test object
|
||||
testObj := new(MyMockedObject)
|
||||
|
||||
// setup expectations
|
||||
testObj.On("DoSomething", 123).Return(true, nil)
|
||||
|
||||
// call the code we are testing
|
||||
targetFuncThatDoesSomethingWithObj(testObj)
|
||||
|
||||
// assert that the expectations were met
|
||||
testObj.AssertExpectations(t)
|
||||
|
||||
// call the code we are testing
|
||||
targetFuncThatDoesSomethingWithObj(testObj)
|
||||
|
||||
// assert that the expectations were met
|
||||
testObj.AssertExpectations(t)
|
||||
}
|
||||
|
||||
// TestSomethingWithPlaceholder is a second example of how to use our test object to
|
||||
@ -170,131 +175,105 @@ func TestSomething(t *testing.T) {
|
||||
// data being passed in is normally dynamically generated and cannot be
|
||||
// predicted beforehand (eg. containing hashes that are time sensitive)
|
||||
func TestSomethingWithPlaceholder(t *testing.T) {
|
||||
// create an instance of our test object
|
||||
testObj := new(MyMockedObject)
|
||||
|
||||
// set up expectations with a placeholder in the argument list
|
||||
testObj.On("DoSomething", mock.Anything).Return(true, nil)
|
||||
// create an instance of our test object
|
||||
testObj := new(MyMockedObject)
|
||||
|
||||
// call the code we are testing
|
||||
targetFuncThatDoesSomethingWithObj(testObj)
|
||||
// setup expectations with a placeholder in the argument list
|
||||
testObj.On("DoSomething", mock.Anything).Return(true, nil)
|
||||
|
||||
// assert that the expectations were met
|
||||
testObj.AssertExpectations(t)
|
||||
// call the code we are testing
|
||||
targetFuncThatDoesSomethingWithObj(testObj)
|
||||
|
||||
}
|
||||
// assert that the expectations were met
|
||||
testObj.AssertExpectations(t)
|
||||
|
||||
// TestSomethingElse2 is a third example that shows how you can use
|
||||
// the Unset method to cleanup handlers and then add new ones.
|
||||
func TestSomethingElse2(t *testing.T) {
|
||||
// create an instance of our test object
|
||||
testObj := new(MyMockedObject)
|
||||
|
||||
// set up expectations with a placeholder in the argument list
|
||||
mockCall := testObj.On("DoSomething", mock.Anything).Return(true, nil)
|
||||
|
||||
// call the code we are testing
|
||||
targetFuncThatDoesSomethingWithObj(testObj)
|
||||
|
||||
// assert that the expectations were met
|
||||
testObj.AssertExpectations(t)
|
||||
|
||||
// remove the handler now so we can add another one that takes precedence
|
||||
mockCall.Unset()
|
||||
|
||||
// return false now instead of true
|
||||
testObj.On("DoSomething", mock.Anything).Return(false, nil)
|
||||
|
||||
testObj.AssertExpectations(t)
|
||||
}
|
||||
```
|
||||
|
||||
For more information on how to write mock code, check out the [API documentation for the `mock` package](https://pkg.go.dev/github.com/stretchr/testify/mock).
|
||||
For more information on how to write mock code, check out the [API documentation for the `mock` package](http://godoc.org/github.com/stretchr/testify/mock).
|
||||
|
||||
You can use the [mockery tool](https://vektra.github.io/mockery/latest/) to autogenerate the mock code against an interface as well, making using mocks much quicker.
|
||||
You can use the [mockery tool](http://github.com/vektra/mockery) to autogenerate the mock code against an interface as well, making using mocks much quicker.
|
||||
|
||||
[`suite`](https://pkg.go.dev/github.com/stretchr/testify/suite "API documentation") package
|
||||
[`suite`](http://godoc.org/github.com/stretchr/testify/suite "API documentation") package
|
||||
-----------------------------------------------------------------------------------------
|
||||
> [!WARNING]
|
||||
> The suite package does not support parallel tests. See [#934](https://github.com/stretchr/testify/issues/934).
|
||||
|
||||
The `suite` package provides functionality that you might be used to from more common object-oriented languages. With it, you can build a testing suite as a struct, build setup/teardown methods and testing methods on your struct, and run them with 'go test' as per normal.
|
||||
The `suite` package provides functionality that you might be used to from more common object oriented languages. With it, you can build a testing suite as a struct, build setup/teardown methods and testing methods on your struct, and run them with 'go test' as per normal.
|
||||
|
||||
An example suite is shown below:
|
||||
|
||||
```go
|
||||
// Basic imports
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/suite"
|
||||
"testing"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/suite"
|
||||
)
|
||||
|
||||
// Define the suite, and absorb the built-in basic suite
|
||||
// functionality from testify - including a T() method which
|
||||
// returns the current testing context
|
||||
type ExampleTestSuite struct {
|
||||
suite.Suite
|
||||
VariableThatShouldStartAtFive int
|
||||
suite.Suite
|
||||
VariableThatShouldStartAtFive int
|
||||
}
|
||||
|
||||
// Make sure that VariableThatShouldStartAtFive is set to five
|
||||
// before each test
|
||||
func (suite *ExampleTestSuite) SetupTest() {
|
||||
suite.VariableThatShouldStartAtFive = 5
|
||||
suite.VariableThatShouldStartAtFive = 5
|
||||
}
|
||||
|
||||
// All methods that begin with "Test" are run as tests within a
|
||||
// suite.
|
||||
func (suite *ExampleTestSuite) TestExample() {
|
||||
assert.Equal(suite.T(), 5, suite.VariableThatShouldStartAtFive)
|
||||
assert.Equal(suite.T(), 5, suite.VariableThatShouldStartAtFive)
|
||||
}
|
||||
|
||||
// In order for 'go test' to run this suite, we need to create
|
||||
// a normal test function and pass our suite to suite.Run
|
||||
func TestExampleTestSuite(t *testing.T) {
|
||||
suite.Run(t, new(ExampleTestSuite))
|
||||
suite.Run(t, new(ExampleTestSuite))
|
||||
}
|
||||
```
|
||||
|
||||
For a more complete example, using all of the functionality provided by the suite package, look at our [example testing suite](https://github.com/stretchr/testify/blob/master/suite/suite_test.go)
|
||||
|
||||
For more information on writing suites, check out the [API documentation for the `suite` package](https://pkg.go.dev/github.com/stretchr/testify/suite).
|
||||
For more information on writing suites, check out the [API documentation for the `suite` package](http://godoc.org/github.com/stretchr/testify/suite).
|
||||
|
||||
`Suite` object has assertion methods:
|
||||
|
||||
```go
|
||||
// Basic imports
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/suite"
|
||||
"testing"
|
||||
"github.com/stretchr/testify/suite"
|
||||
)
|
||||
|
||||
// Define the suite, and absorb the built-in basic suite
|
||||
// functionality from testify - including assertion methods.
|
||||
type ExampleTestSuite struct {
|
||||
suite.Suite
|
||||
VariableThatShouldStartAtFive int
|
||||
suite.Suite
|
||||
VariableThatShouldStartAtFive int
|
||||
}
|
||||
|
||||
// Make sure that VariableThatShouldStartAtFive is set to five
|
||||
// before each test
|
||||
func (suite *ExampleTestSuite) SetupTest() {
|
||||
suite.VariableThatShouldStartAtFive = 5
|
||||
suite.VariableThatShouldStartAtFive = 5
|
||||
}
|
||||
|
||||
// All methods that begin with "Test" are run as tests within a
|
||||
// suite.
|
||||
func (suite *ExampleTestSuite) TestExample() {
|
||||
suite.Equal(suite.VariableThatShouldStartAtFive, 5)
|
||||
suite.Equal(suite.VariableThatShouldStartAtFive, 5)
|
||||
}
|
||||
|
||||
// In order for 'go test' to run this suite, we need to create
|
||||
// a normal test function and pass our suite to suite.Run
|
||||
func TestExampleTestSuite(t *testing.T) {
|
||||
suite.Run(t, new(ExampleTestSuite))
|
||||
suite.Run(t, new(ExampleTestSuite))
|
||||
}
|
||||
```
|
||||
|
||||
@ -321,13 +300,14 @@ Import the `testify/assert` package into your code using this template:
|
||||
package yours
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestSomething(t *testing.T) {
|
||||
assert.True(t, true, "True is true!")
|
||||
|
||||
assert.True(t, true, "True is true!")
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
@ -343,7 +323,7 @@ To update Testify to the latest version, use `go get -u github.com/stretchr/test
|
||||
Supported go versions
|
||||
==================
|
||||
|
||||
We currently support the most recent major Go versions from 1.19 onward.
|
||||
We currently support the most recent major Go versions from 1.13 onward.
|
||||
|
||||
------
|
||||
|
||||
@ -354,7 +334,7 @@ Please feel free to submit issues, fork the repository and send pull requests!
|
||||
|
||||
When submitting an issue, we ask that you please include a complete test function that demonstrates the issue. Extra credit for those using Testify to write the test code that demonstrates it.
|
||||
|
||||
Code generation is used. [Look for `Code generated with`](https://github.com/search?q=repo%3Astretchr%2Ftestify%20%22Code%20generated%20with%22&type=code) at the top of some files. Run `go generate ./...` to update generated files.
|
||||
Code generation is used. Look for `CODE GENERATED AUTOMATICALLY` at the top of some files. Run `go generate ./...` to update generated files.
|
||||
|
||||
We also chat on the [Gophers Slack](https://gophers.slack.com) group in the `#testify` and `#testify-dev` channels.
|
||||
|
||||
|
@ -16,6 +16,7 @@ import (
|
||||
"go/token"
|
||||
"go/types"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"path"
|
||||
@ -100,15 +101,13 @@ func parseTemplates() (*template.Template, *template.Template, error) {
|
||||
return nil, nil, err
|
||||
}
|
||||
if *tmplFile != "" {
|
||||
f, err := os.ReadFile(*tmplFile)
|
||||
f, err := ioutil.ReadFile(*tmplFile)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
funcTemplate = string(f)
|
||||
}
|
||||
tmpl, err := template.New("function").Funcs(template.FuncMap{
|
||||
"replace": strings.ReplaceAll,
|
||||
}).Parse(funcTemplate)
|
||||
tmpl, err := template.New("function").Parse(funcTemplate)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@ -182,7 +181,7 @@ func parsePackageSource(pkg string) (*types.Scope, *doc.Package, error) {
|
||||
files := make(map[string]*ast.File)
|
||||
fileList := make([]*ast.File, len(pd.GoFiles))
|
||||
for i, fname := range pd.GoFiles {
|
||||
src, err := os.ReadFile(path.Join(pd.Dir, fname))
|
||||
src, err := ioutil.ReadFile(path.Join(pd.Dir, fname))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@ -298,8 +297,10 @@ func (f *testFunc) CommentWithoutT(receiver string) string {
|
||||
return strings.Replace(f.Comment(), search, replace, -1)
|
||||
}
|
||||
|
||||
// Standard header https://go.dev/s/generatedcode.
|
||||
var headerTemplate = `// Code generated with github.com/stretchr/testify/_codegen; DO NOT EDIT.
|
||||
var headerTemplate = `/*
|
||||
* CODE GENERATED AUTOMATICALLY WITH github.com/stretchr/testify/_codegen
|
||||
* THIS FILE MUST NOT BE EDITED BY HAND
|
||||
*/
|
||||
|
||||
package {{.Name}}
|
||||
|
||||
|
@ -1,19 +1,15 @@
|
||||
package assert
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Deprecated: CompareType has only ever been for internal use and has accidentally been published since v1.6.0. Do not use it.
|
||||
type CompareType = compareResult
|
||||
|
||||
type compareResult int
|
||||
type CompareType int
|
||||
|
||||
const (
|
||||
compareLess compareResult = iota - 1
|
||||
compareLess CompareType = iota - 1
|
||||
compareEqual
|
||||
compareGreater
|
||||
)
|
||||
@ -31,18 +27,15 @@ var (
|
||||
uint32Type = reflect.TypeOf(uint32(1))
|
||||
uint64Type = reflect.TypeOf(uint64(1))
|
||||
|
||||
uintptrType = reflect.TypeOf(uintptr(1))
|
||||
|
||||
float32Type = reflect.TypeOf(float32(1))
|
||||
float64Type = reflect.TypeOf(float64(1))
|
||||
|
||||
stringType = reflect.TypeOf("")
|
||||
|
||||
timeType = reflect.TypeOf(time.Time{})
|
||||
bytesType = reflect.TypeOf([]byte{})
|
||||
timeType = reflect.TypeOf(time.Time{})
|
||||
)
|
||||
|
||||
func compare(obj1, obj2 interface{}, kind reflect.Kind) (compareResult, bool) {
|
||||
func compare(obj1, obj2 interface{}, kind reflect.Kind) (CompareType, bool) {
|
||||
obj1Value := reflect.ValueOf(obj1)
|
||||
obj2Value := reflect.ValueOf(obj2)
|
||||
|
||||
@ -313,11 +306,11 @@ func compare(obj1, obj2 interface{}, kind reflect.Kind) (compareResult, bool) {
|
||||
case reflect.Struct:
|
||||
{
|
||||
// All structs enter here. We're not interested in most types.
|
||||
if !obj1Value.CanConvert(timeType) {
|
||||
if !canConvert(obj1Value, timeType) {
|
||||
break
|
||||
}
|
||||
|
||||
// time.Time can be compared!
|
||||
// time.Time can compared!
|
||||
timeObj1, ok := obj1.(time.Time)
|
||||
if !ok {
|
||||
timeObj1 = obj1Value.Convert(timeType).Interface().(time.Time)
|
||||
@ -328,53 +321,7 @@ func compare(obj1, obj2 interface{}, kind reflect.Kind) (compareResult, bool) {
|
||||
timeObj2 = obj2Value.Convert(timeType).Interface().(time.Time)
|
||||
}
|
||||
|
||||
if timeObj1.Before(timeObj2) {
|
||||
return compareLess, true
|
||||
}
|
||||
if timeObj1.Equal(timeObj2) {
|
||||
return compareEqual, true
|
||||
}
|
||||
return compareGreater, true
|
||||
}
|
||||
case reflect.Slice:
|
||||
{
|
||||
// We only care about the []byte type.
|
||||
if !obj1Value.CanConvert(bytesType) {
|
||||
break
|
||||
}
|
||||
|
||||
// []byte can be compared!
|
||||
bytesObj1, ok := obj1.([]byte)
|
||||
if !ok {
|
||||
bytesObj1 = obj1Value.Convert(bytesType).Interface().([]byte)
|
||||
|
||||
}
|
||||
bytesObj2, ok := obj2.([]byte)
|
||||
if !ok {
|
||||
bytesObj2 = obj2Value.Convert(bytesType).Interface().([]byte)
|
||||
}
|
||||
|
||||
return compareResult(bytes.Compare(bytesObj1, bytesObj2)), true
|
||||
}
|
||||
case reflect.Uintptr:
|
||||
{
|
||||
uintptrObj1, ok := obj1.(uintptr)
|
||||
if !ok {
|
||||
uintptrObj1 = obj1Value.Convert(uintptrType).Interface().(uintptr)
|
||||
}
|
||||
uintptrObj2, ok := obj2.(uintptr)
|
||||
if !ok {
|
||||
uintptrObj2 = obj2Value.Convert(uintptrType).Interface().(uintptr)
|
||||
}
|
||||
if uintptrObj1 > uintptrObj2 {
|
||||
return compareGreater, true
|
||||
}
|
||||
if uintptrObj1 == uintptrObj2 {
|
||||
return compareEqual, true
|
||||
}
|
||||
if uintptrObj1 < uintptrObj2 {
|
||||
return compareLess, true
|
||||
}
|
||||
return compare(timeObj1.UnixNano(), timeObj2.UnixNano(), reflect.Int64)
|
||||
}
|
||||
}
|
||||
|
||||
@ -383,85 +330,79 @@ func compare(obj1, obj2 interface{}, kind reflect.Kind) (compareResult, bool) {
|
||||
|
||||
// Greater asserts that the first element is greater than the second
|
||||
//
|
||||
// assert.Greater(t, 2, 1)
|
||||
// assert.Greater(t, float64(2), float64(1))
|
||||
// assert.Greater(t, "b", "a")
|
||||
// assert.Greater(t, 2, 1)
|
||||
// assert.Greater(t, float64(2), float64(1))
|
||||
// assert.Greater(t, "b", "a")
|
||||
func Greater(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
failMessage := fmt.Sprintf("\"%v\" is not greater than \"%v\"", e1, e2)
|
||||
return compareTwoValues(t, e1, e2, []compareResult{compareGreater}, failMessage, msgAndArgs...)
|
||||
return compareTwoValues(t, e1, e2, []CompareType{compareGreater}, "\"%v\" is not greater than \"%v\"", msgAndArgs...)
|
||||
}
|
||||
|
||||
// GreaterOrEqual asserts that the first element is greater than or equal to the second
|
||||
//
|
||||
// assert.GreaterOrEqual(t, 2, 1)
|
||||
// assert.GreaterOrEqual(t, 2, 2)
|
||||
// assert.GreaterOrEqual(t, "b", "a")
|
||||
// assert.GreaterOrEqual(t, "b", "b")
|
||||
// assert.GreaterOrEqual(t, 2, 1)
|
||||
// assert.GreaterOrEqual(t, 2, 2)
|
||||
// assert.GreaterOrEqual(t, "b", "a")
|
||||
// assert.GreaterOrEqual(t, "b", "b")
|
||||
func GreaterOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
failMessage := fmt.Sprintf("\"%v\" is not greater than or equal to \"%v\"", e1, e2)
|
||||
return compareTwoValues(t, e1, e2, []compareResult{compareGreater, compareEqual}, failMessage, msgAndArgs...)
|
||||
return compareTwoValues(t, e1, e2, []CompareType{compareGreater, compareEqual}, "\"%v\" is not greater than or equal to \"%v\"", msgAndArgs...)
|
||||
}
|
||||
|
||||
// Less asserts that the first element is less than the second
|
||||
//
|
||||
// assert.Less(t, 1, 2)
|
||||
// assert.Less(t, float64(1), float64(2))
|
||||
// assert.Less(t, "a", "b")
|
||||
// assert.Less(t, 1, 2)
|
||||
// assert.Less(t, float64(1), float64(2))
|
||||
// assert.Less(t, "a", "b")
|
||||
func Less(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
failMessage := fmt.Sprintf("\"%v\" is not less than \"%v\"", e1, e2)
|
||||
return compareTwoValues(t, e1, e2, []compareResult{compareLess}, failMessage, msgAndArgs...)
|
||||
return compareTwoValues(t, e1, e2, []CompareType{compareLess}, "\"%v\" is not less than \"%v\"", msgAndArgs...)
|
||||
}
|
||||
|
||||
// LessOrEqual asserts that the first element is less than or equal to the second
|
||||
//
|
||||
// assert.LessOrEqual(t, 1, 2)
|
||||
// assert.LessOrEqual(t, 2, 2)
|
||||
// assert.LessOrEqual(t, "a", "b")
|
||||
// assert.LessOrEqual(t, "b", "b")
|
||||
// assert.LessOrEqual(t, 1, 2)
|
||||
// assert.LessOrEqual(t, 2, 2)
|
||||
// assert.LessOrEqual(t, "a", "b")
|
||||
// assert.LessOrEqual(t, "b", "b")
|
||||
func LessOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
failMessage := fmt.Sprintf("\"%v\" is not less than or equal to \"%v\"", e1, e2)
|
||||
return compareTwoValues(t, e1, e2, []compareResult{compareLess, compareEqual}, failMessage, msgAndArgs...)
|
||||
return compareTwoValues(t, e1, e2, []CompareType{compareLess, compareEqual}, "\"%v\" is not less than or equal to \"%v\"", msgAndArgs...)
|
||||
}
|
||||
|
||||
// Positive asserts that the specified element is positive
|
||||
//
|
||||
// assert.Positive(t, 1)
|
||||
// assert.Positive(t, 1.23)
|
||||
// assert.Positive(t, 1)
|
||||
// assert.Positive(t, 1.23)
|
||||
func Positive(t TestingT, e interface{}, msgAndArgs ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
zero := reflect.Zero(reflect.TypeOf(e))
|
||||
failMessage := fmt.Sprintf("\"%v\" is not positive", e)
|
||||
return compareTwoValues(t, e, zero.Interface(), []compareResult{compareGreater}, failMessage, msgAndArgs...)
|
||||
return compareTwoValues(t, e, zero.Interface(), []CompareType{compareGreater}, "\"%v\" is not positive", msgAndArgs...)
|
||||
}
|
||||
|
||||
// Negative asserts that the specified element is negative
|
||||
//
|
||||
// assert.Negative(t, -1)
|
||||
// assert.Negative(t, -1.23)
|
||||
// assert.Negative(t, -1)
|
||||
// assert.Negative(t, -1.23)
|
||||
func Negative(t TestingT, e interface{}, msgAndArgs ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
zero := reflect.Zero(reflect.TypeOf(e))
|
||||
failMessage := fmt.Sprintf("\"%v\" is not negative", e)
|
||||
return compareTwoValues(t, e, zero.Interface(), []compareResult{compareLess}, failMessage, msgAndArgs...)
|
||||
return compareTwoValues(t, e, zero.Interface(), []CompareType{compareLess}, "\"%v\" is not negative", msgAndArgs...)
|
||||
}
|
||||
|
||||
func compareTwoValues(t TestingT, e1 interface{}, e2 interface{}, allowedComparesResults []compareResult, failMessage string, msgAndArgs ...interface{}) bool {
|
||||
func compareTwoValues(t TestingT, e1 interface{}, e2 interface{}, allowedComparesResults []CompareType, failMessage string, msgAndArgs ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
@ -474,17 +415,17 @@ func compareTwoValues(t TestingT, e1 interface{}, e2 interface{}, allowedCompare
|
||||
|
||||
compareResult, isComparable := compare(e1, e2, e1Kind)
|
||||
if !isComparable {
|
||||
return Fail(t, fmt.Sprintf(`Can not compare type "%T"`, e1), msgAndArgs...)
|
||||
return Fail(t, fmt.Sprintf("Can not compare type \"%s\"", reflect.TypeOf(e1)), msgAndArgs...)
|
||||
}
|
||||
|
||||
if !containsValue(allowedComparesResults, compareResult) {
|
||||
return Fail(t, failMessage, msgAndArgs...)
|
||||
return Fail(t, fmt.Sprintf(failMessage, e1, e2), msgAndArgs...)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func containsValue(values []compareResult, value compareResult) bool {
|
||||
func containsValue(values []CompareType, value CompareType) bool {
|
||||
for _, v := range values {
|
||||
if v == value {
|
||||
return true
|
||||
|
16
assert/assertion_compare_can_convert.go
Normal file
16
assert/assertion_compare_can_convert.go
Normal file
@ -0,0 +1,16 @@
|
||||
//go:build go1.17
|
||||
// +build go1.17
|
||||
|
||||
// TODO: once support for Go 1.16 is dropped, this file can be
|
||||
// merged/removed with assertion_compare_go1.17_test.go and
|
||||
// assertion_compare_legacy.go
|
||||
|
||||
package assert
|
||||
|
||||
import "reflect"
|
||||
|
||||
// Wrapper around reflect.Value.CanConvert, for compatibility
|
||||
// reasons.
|
||||
func canConvert(value reflect.Value, to reflect.Type) bool {
|
||||
return value.CanConvert(to)
|
||||
}
|
54
assert/assertion_compare_go1.17_test.go
Normal file
54
assert/assertion_compare_go1.17_test.go
Normal file
@ -0,0 +1,54 @@
|
||||
//go:build go1.17
|
||||
// +build go1.17
|
||||
|
||||
// TODO: once support for Go 1.16 is dropped, this file can be
|
||||
// merged/removed with assertion_compare_can_convert.go and
|
||||
// assertion_compare_legacy.go
|
||||
|
||||
package assert
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestCompare17(t *testing.T) {
|
||||
type customTime time.Time
|
||||
for _, currCase := range []struct {
|
||||
less interface{}
|
||||
greater interface{}
|
||||
cType string
|
||||
}{
|
||||
{less: time.Now(), greater: time.Now().Add(time.Hour), cType: "time.Time"},
|
||||
{less: customTime(time.Now()), greater: customTime(time.Now().Add(time.Hour)), cType: "time.Time"},
|
||||
} {
|
||||
resLess, isComparable := compare(currCase.less, currCase.greater, reflect.ValueOf(currCase.less).Kind())
|
||||
if !isComparable {
|
||||
t.Error("object should be comparable for type " + currCase.cType)
|
||||
}
|
||||
|
||||
if resLess != compareLess {
|
||||
t.Errorf("object less (%v) should be less than greater (%v) for type "+currCase.cType,
|
||||
currCase.less, currCase.greater)
|
||||
}
|
||||
|
||||
resGreater, isComparable := compare(currCase.greater, currCase.less, reflect.ValueOf(currCase.less).Kind())
|
||||
if !isComparable {
|
||||
t.Error("object are comparable for type " + currCase.cType)
|
||||
}
|
||||
|
||||
if resGreater != compareGreater {
|
||||
t.Errorf("object greater should be greater than less for type " + currCase.cType)
|
||||
}
|
||||
|
||||
resEqual, isComparable := compare(currCase.less, currCase.less, reflect.ValueOf(currCase.less).Kind())
|
||||
if !isComparable {
|
||||
t.Error("object are comparable for type " + currCase.cType)
|
||||
}
|
||||
|
||||
if resEqual != 0 {
|
||||
t.Errorf("objects should be equal for type " + currCase.cType)
|
||||
}
|
||||
}
|
||||
}
|
16
assert/assertion_compare_legacy.go
Normal file
16
assert/assertion_compare_legacy.go
Normal file
@ -0,0 +1,16 @@
|
||||
//go:build !go1.17
|
||||
// +build !go1.17
|
||||
|
||||
// TODO: once support for Go 1.16 is dropped, this file can be
|
||||
// merged/removed with assertion_compare_go1.17_test.go and
|
||||
// assertion_compare_can_convert.go
|
||||
|
||||
package assert
|
||||
|
||||
import "reflect"
|
||||
|
||||
// Older versions of Go does not have the reflect.Value.CanConvert
|
||||
// method.
|
||||
func canConvert(value reflect.Value, to reflect.Type) bool {
|
||||
return false
|
||||
}
|
@ -6,13 +6,9 @@ import (
|
||||
"reflect"
|
||||
"runtime"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestCompare(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
type customString string
|
||||
type customInt int
|
||||
type customInt8 int8
|
||||
type customInt16 int16
|
||||
@ -25,9 +21,7 @@ func TestCompare(t *testing.T) {
|
||||
type customUInt64 uint64
|
||||
type customFloat32 float32
|
||||
type customFloat64 float64
|
||||
type customUintptr uintptr
|
||||
type customTime time.Time
|
||||
type customBytes []byte
|
||||
type customString string
|
||||
for _, currCase := range []struct {
|
||||
less interface{}
|
||||
greater interface{}
|
||||
@ -58,13 +52,6 @@ func TestCompare(t *testing.T) {
|
||||
{less: customFloat32(1.23), greater: customFloat32(2.23), cType: "float32"},
|
||||
{less: float64(1.23), greater: float64(2.34), cType: "float64"},
|
||||
{less: customFloat64(1.23), greater: customFloat64(2.34), cType: "float64"},
|
||||
{less: uintptr(1), greater: uintptr(2), cType: "uintptr"},
|
||||
{less: customUintptr(1), greater: customUintptr(2), cType: "uint64"},
|
||||
{less: time.Now(), greater: time.Now().Add(time.Hour), cType: "time.Time"},
|
||||
{less: time.Date(2024, 0, 0, 0, 0, 0, 0, time.Local), greater: time.Date(2263, 0, 0, 0, 0, 0, 0, time.Local), cType: "time.Time"},
|
||||
{less: customTime(time.Now()), greater: customTime(time.Now().Add(time.Hour)), cType: "time.Time"},
|
||||
{less: []byte{1, 1}, greater: []byte{1, 2}, cType: "[]byte"},
|
||||
{less: customBytes([]byte{1, 1}), greater: customBytes([]byte{1, 2}), cType: "[]byte"},
|
||||
} {
|
||||
resLess, isComparable := compare(currCase.less, currCase.greater, reflect.ValueOf(currCase.less).Kind())
|
||||
if !isComparable {
|
||||
@ -129,8 +116,6 @@ func callerName(skip int) string {
|
||||
}
|
||||
|
||||
func TestGreater(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(testing.T)
|
||||
|
||||
if !Greater(mockT, 2, 1) {
|
||||
@ -163,9 +148,6 @@ func TestGreater(t *testing.T) {
|
||||
{less: uint64(1), greater: uint64(2), msg: `"1" is not greater than "2"`},
|
||||
{less: float32(1.23), greater: float32(2.34), msg: `"1.23" is not greater than "2.34"`},
|
||||
{less: float64(1.23), greater: float64(2.34), msg: `"1.23" is not greater than "2.34"`},
|
||||
{less: uintptr(1), greater: uintptr(2), msg: `"1" is not greater than "2"`},
|
||||
{less: time.Time{}, greater: time.Time{}.Add(time.Hour), msg: `"0001-01-01 00:00:00 +0000 UTC" is not greater than "0001-01-01 01:00:00 +0000 UTC"`},
|
||||
{less: []byte{1, 1}, greater: []byte{1, 2}, msg: `"[1 1]" is not greater than "[1 2]"`},
|
||||
} {
|
||||
out := &outputT{buf: bytes.NewBuffer(nil)}
|
||||
False(t, Greater(out, currCase.less, currCase.greater))
|
||||
@ -175,8 +157,6 @@ func TestGreater(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGreaterOrEqual(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(testing.T)
|
||||
|
||||
if !GreaterOrEqual(mockT, 2, 1) {
|
||||
@ -209,9 +189,6 @@ func TestGreaterOrEqual(t *testing.T) {
|
||||
{less: uint64(1), greater: uint64(2), msg: `"1" is not greater than or equal to "2"`},
|
||||
{less: float32(1.23), greater: float32(2.34), msg: `"1.23" is not greater than or equal to "2.34"`},
|
||||
{less: float64(1.23), greater: float64(2.34), msg: `"1.23" is not greater than or equal to "2.34"`},
|
||||
{less: uintptr(1), greater: uintptr(2), msg: `"1" is not greater than or equal to "2"`},
|
||||
{less: time.Time{}, greater: time.Time{}.Add(time.Hour), msg: `"0001-01-01 00:00:00 +0000 UTC" is not greater than or equal to "0001-01-01 01:00:00 +0000 UTC"`},
|
||||
{less: []byte{1, 1}, greater: []byte{1, 2}, msg: `"[1 1]" is not greater than or equal to "[1 2]"`},
|
||||
} {
|
||||
out := &outputT{buf: bytes.NewBuffer(nil)}
|
||||
False(t, GreaterOrEqual(out, currCase.less, currCase.greater))
|
||||
@ -221,8 +198,6 @@ func TestGreaterOrEqual(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestLess(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(testing.T)
|
||||
|
||||
if !Less(mockT, 1, 2) {
|
||||
@ -255,9 +230,6 @@ func TestLess(t *testing.T) {
|
||||
{less: uint64(1), greater: uint64(2), msg: `"2" is not less than "1"`},
|
||||
{less: float32(1.23), greater: float32(2.34), msg: `"2.34" is not less than "1.23"`},
|
||||
{less: float64(1.23), greater: float64(2.34), msg: `"2.34" is not less than "1.23"`},
|
||||
{less: uintptr(1), greater: uintptr(2), msg: `"2" is not less than "1"`},
|
||||
{less: time.Time{}, greater: time.Time{}.Add(time.Hour), msg: `"0001-01-01 01:00:00 +0000 UTC" is not less than "0001-01-01 00:00:00 +0000 UTC"`},
|
||||
{less: []byte{1, 1}, greater: []byte{1, 2}, msg: `"[1 2]" is not less than "[1 1]"`},
|
||||
} {
|
||||
out := &outputT{buf: bytes.NewBuffer(nil)}
|
||||
False(t, Less(out, currCase.greater, currCase.less))
|
||||
@ -267,8 +239,6 @@ func TestLess(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestLessOrEqual(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(testing.T)
|
||||
|
||||
if !LessOrEqual(mockT, 1, 2) {
|
||||
@ -301,9 +271,6 @@ func TestLessOrEqual(t *testing.T) {
|
||||
{less: uint64(1), greater: uint64(2), msg: `"2" is not less than or equal to "1"`},
|
||||
{less: float32(1.23), greater: float32(2.34), msg: `"2.34" is not less than or equal to "1.23"`},
|
||||
{less: float64(1.23), greater: float64(2.34), msg: `"2.34" is not less than or equal to "1.23"`},
|
||||
{less: uintptr(1), greater: uintptr(2), msg: `"2" is not less than or equal to "1"`},
|
||||
{less: time.Time{}, greater: time.Time{}.Add(time.Hour), msg: `"0001-01-01 01:00:00 +0000 UTC" is not less than or equal to "0001-01-01 00:00:00 +0000 UTC"`},
|
||||
{less: []byte{1, 1}, greater: []byte{1, 2}, msg: `"[1 2]" is not less than or equal to "[1 1]"`},
|
||||
} {
|
||||
out := &outputT{buf: bytes.NewBuffer(nil)}
|
||||
False(t, LessOrEqual(out, currCase.greater, currCase.less))
|
||||
@ -313,8 +280,6 @@ func TestLessOrEqual(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestPositive(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(testing.T)
|
||||
|
||||
if !Positive(mockT, 1) {
|
||||
@ -354,8 +319,6 @@ func TestPositive(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNegative(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(testing.T)
|
||||
|
||||
if !Negative(mockT, -1) {
|
||||
@ -395,8 +358,6 @@ func TestNegative(t *testing.T) {
|
||||
}
|
||||
|
||||
func Test_compareTwoValuesDifferentValuesTypes(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(testing.T)
|
||||
|
||||
for _, currCase := range []struct {
|
||||
@ -409,14 +370,12 @@ func Test_compareTwoValuesDifferentValuesTypes(t *testing.T) {
|
||||
{v1: float64(12), v2: "123"},
|
||||
{v1: "float(12)", v2: float64(1)},
|
||||
} {
|
||||
result := compareTwoValues(mockT, currCase.v1, currCase.v2, []compareResult{compareLess, compareEqual, compareGreater}, "testFailMessage")
|
||||
False(t, result)
|
||||
compareResult := compareTwoValues(mockT, currCase.v1, currCase.v2, []CompareType{compareLess, compareEqual, compareGreater}, "testFailMessage")
|
||||
False(t, compareResult)
|
||||
}
|
||||
}
|
||||
|
||||
func Test_compareTwoValuesNotComparableValues(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(testing.T)
|
||||
|
||||
type CompareStruct struct {
|
||||
@ -430,48 +389,44 @@ func Test_compareTwoValuesNotComparableValues(t *testing.T) {
|
||||
{v1: map[string]int{}, v2: map[string]int{}},
|
||||
{v1: make([]int, 5), v2: make([]int, 5)},
|
||||
} {
|
||||
result := compareTwoValues(mockT, currCase.v1, currCase.v2, []compareResult{compareLess, compareEqual, compareGreater}, "testFailMessage")
|
||||
False(t, result)
|
||||
compareResult := compareTwoValues(mockT, currCase.v1, currCase.v2, []CompareType{compareLess, compareEqual, compareGreater}, "testFailMessage")
|
||||
False(t, compareResult)
|
||||
}
|
||||
}
|
||||
|
||||
func Test_compareTwoValuesCorrectCompareResult(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(testing.T)
|
||||
|
||||
for _, currCase := range []struct {
|
||||
v1 interface{}
|
||||
v2 interface{}
|
||||
allowedResults []compareResult
|
||||
v1 interface{}
|
||||
v2 interface{}
|
||||
compareTypes []CompareType
|
||||
}{
|
||||
{v1: 1, v2: 2, allowedResults: []compareResult{compareLess}},
|
||||
{v1: 1, v2: 2, allowedResults: []compareResult{compareLess, compareEqual}},
|
||||
{v1: 2, v2: 2, allowedResults: []compareResult{compareGreater, compareEqual}},
|
||||
{v1: 2, v2: 2, allowedResults: []compareResult{compareEqual}},
|
||||
{v1: 2, v2: 1, allowedResults: []compareResult{compareEqual, compareGreater}},
|
||||
{v1: 2, v2: 1, allowedResults: []compareResult{compareGreater}},
|
||||
{v1: 1, v2: 2, compareTypes: []CompareType{compareLess}},
|
||||
{v1: 1, v2: 2, compareTypes: []CompareType{compareLess, compareEqual}},
|
||||
{v1: 2, v2: 2, compareTypes: []CompareType{compareGreater, compareEqual}},
|
||||
{v1: 2, v2: 2, compareTypes: []CompareType{compareEqual}},
|
||||
{v1: 2, v2: 1, compareTypes: []CompareType{compareEqual, compareGreater}},
|
||||
{v1: 2, v2: 1, compareTypes: []CompareType{compareGreater}},
|
||||
} {
|
||||
result := compareTwoValues(mockT, currCase.v1, currCase.v2, currCase.allowedResults, "testFailMessage")
|
||||
True(t, result)
|
||||
compareResult := compareTwoValues(mockT, currCase.v1, currCase.v2, currCase.compareTypes, "testFailMessage")
|
||||
True(t, compareResult)
|
||||
}
|
||||
}
|
||||
|
||||
func Test_containsValue(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
for _, currCase := range []struct {
|
||||
values []compareResult
|
||||
value compareResult
|
||||
values []CompareType
|
||||
value CompareType
|
||||
result bool
|
||||
}{
|
||||
{values: []compareResult{compareGreater}, value: compareGreater, result: true},
|
||||
{values: []compareResult{compareGreater, compareLess}, value: compareGreater, result: true},
|
||||
{values: []compareResult{compareGreater, compareLess}, value: compareLess, result: true},
|
||||
{values: []compareResult{compareGreater, compareLess}, value: compareEqual, result: false},
|
||||
{values: []CompareType{compareGreater}, value: compareGreater, result: true},
|
||||
{values: []CompareType{compareGreater, compareLess}, value: compareGreater, result: true},
|
||||
{values: []CompareType{compareGreater, compareLess}, value: compareLess, result: true},
|
||||
{values: []CompareType{compareGreater, compareLess}, value: compareEqual, result: false},
|
||||
} {
|
||||
result := containsValue(currCase.values, currCase.value)
|
||||
Equal(t, currCase.result, result)
|
||||
compareResult := containsValue(currCase.values, currCase.value)
|
||||
Equal(t, currCase.result, compareResult)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,7 @@
|
||||
// Code generated with github.com/stretchr/testify/_codegen; DO NOT EDIT.
|
||||
/*
|
||||
* CODE GENERATED AUTOMATICALLY WITH github.com/stretchr/testify/_codegen
|
||||
* THIS FILE MUST NOT BE EDITED BY HAND
|
||||
*/
|
||||
|
||||
package assert
|
||||
|
||||
@ -19,9 +22,9 @@ func Conditionf(t TestingT, comp Comparison, msg string, args ...interface{}) bo
|
||||
// Containsf asserts that the specified string, list(array, slice...) or map contains the
|
||||
// specified substring or element.
|
||||
//
|
||||
// assert.Containsf(t, "Hello World", "World", "error message %s", "formatted")
|
||||
// assert.Containsf(t, ["Hello", "World"], "World", "error message %s", "formatted")
|
||||
// assert.Containsf(t, {"Hello": "World"}, "Hello", "error message %s", "formatted")
|
||||
// assert.Containsf(t, "Hello World", "World", "error message %s", "formatted")
|
||||
// assert.Containsf(t, ["Hello", "World"], "World", "error message %s", "formatted")
|
||||
// assert.Containsf(t, {"Hello": "World"}, "Hello", "error message %s", "formatted")
|
||||
func Containsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -50,19 +53,10 @@ func ElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string
|
||||
return ElementsMatch(t, listA, listB, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// Emptyf asserts that the given value is "empty".
|
||||
// Emptyf asserts that the specified object is empty. I.e. nil, "", false, 0 or either
|
||||
// a slice or a channel with len == 0.
|
||||
//
|
||||
// [Zero values] are "empty".
|
||||
//
|
||||
// Arrays are "empty" if every element is the zero value of the type (stricter than "empty").
|
||||
//
|
||||
// Slices, maps and channels with zero length are "empty".
|
||||
//
|
||||
// Pointer values are "empty" if the pointer is nil or if the pointed value is "empty".
|
||||
//
|
||||
// assert.Emptyf(t, obj, "error message %s", "formatted")
|
||||
//
|
||||
// [Zero values]: https://go.dev/ref/spec#The_zero_value
|
||||
// assert.Emptyf(t, obj, "error message %s", "formatted")
|
||||
func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -72,7 +66,7 @@ func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) boo
|
||||
|
||||
// Equalf asserts that two objects are equal.
|
||||
//
|
||||
// assert.Equalf(t, 123, 123, "error message %s", "formatted")
|
||||
// assert.Equalf(t, 123, 123, "error message %s", "formatted")
|
||||
//
|
||||
// Pointer variable equality is determined based on the equality of the
|
||||
// referenced values (as opposed to the memory addresses). Function equality
|
||||
@ -87,8 +81,8 @@ func Equalf(t TestingT, expected interface{}, actual interface{}, msg string, ar
|
||||
// EqualErrorf asserts that a function returned an error (i.e. not `nil`)
|
||||
// and that it is equal to the provided error.
|
||||
//
|
||||
// actualObj, err := SomeFunction()
|
||||
// assert.EqualErrorf(t, err, expectedErrorString, "error message %s", "formatted")
|
||||
// actualObj, err := SomeFunction()
|
||||
// assert.EqualErrorf(t, err, expectedErrorString, "error message %s", "formatted")
|
||||
func EqualErrorf(t TestingT, theError error, errString string, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -96,27 +90,10 @@ func EqualErrorf(t TestingT, theError error, errString string, msg string, args
|
||||
return EqualError(t, theError, errString, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// EqualExportedValuesf asserts that the types of two objects are equal and their public
|
||||
// fields are also equal. This is useful for comparing structs that have private fields
|
||||
// that could potentially differ.
|
||||
// EqualValuesf asserts that two objects are equal or convertable to the same types
|
||||
// and equal.
|
||||
//
|
||||
// type S struct {
|
||||
// Exported int
|
||||
// notExported int
|
||||
// }
|
||||
// assert.EqualExportedValuesf(t, S{1, 2}, S{1, 3}, "error message %s", "formatted") => true
|
||||
// assert.EqualExportedValuesf(t, S{1, 2}, S{2, 3}, "error message %s", "formatted") => false
|
||||
func EqualExportedValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
return EqualExportedValues(t, expected, actual, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// EqualValuesf asserts that two objects are equal or convertible to the larger
|
||||
// type and equal.
|
||||
//
|
||||
// assert.EqualValuesf(t, uint32(123), int32(123), "error message %s", "formatted")
|
||||
// assert.EqualValuesf(t, uint32(123), int32(123), "error message %s", "formatted")
|
||||
func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -126,8 +103,10 @@ func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg stri
|
||||
|
||||
// Errorf asserts that a function returned an error (i.e. not `nil`).
|
||||
//
|
||||
// actualObj, err := SomeFunction()
|
||||
// assert.Errorf(t, err, "error message %s", "formatted")
|
||||
// actualObj, err := SomeFunction()
|
||||
// if assert.Errorf(t, err, "error message %s", "formatted") {
|
||||
// assert.Equal(t, expectedErrorf, err)
|
||||
// }
|
||||
func Errorf(t TestingT, err error, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -147,8 +126,8 @@ func ErrorAsf(t TestingT, err error, target interface{}, msg string, args ...int
|
||||
// ErrorContainsf asserts that a function returned an error (i.e. not `nil`)
|
||||
// and that the error contains the specified substring.
|
||||
//
|
||||
// actualObj, err := SomeFunction()
|
||||
// assert.ErrorContainsf(t, err, expectedErrorSubString, "error message %s", "formatted")
|
||||
// actualObj, err := SomeFunction()
|
||||
// assert.ErrorContainsf(t, err, expectedErrorSubString, "error message %s", "formatted")
|
||||
func ErrorContainsf(t TestingT, theError error, contains string, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -168,7 +147,7 @@ func ErrorIsf(t TestingT, err error, target error, msg string, args ...interface
|
||||
// Eventuallyf asserts that given condition will be met in waitFor time,
|
||||
// periodically checking target function each tick.
|
||||
//
|
||||
// assert.Eventuallyf(t, func() bool { return true; }, time.Second, 10*time.Millisecond, "error message %s", "formatted")
|
||||
// assert.Eventuallyf(t, func() bool { return true; }, time.Second, 10*time.Millisecond, "error message %s", "formatted")
|
||||
func Eventuallyf(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -176,34 +155,9 @@ func Eventuallyf(t TestingT, condition func() bool, waitFor time.Duration, tick
|
||||
return Eventually(t, condition, waitFor, tick, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// EventuallyWithTf asserts that given condition will be met in waitFor time,
|
||||
// periodically checking target function each tick. In contrast to Eventually,
|
||||
// it supplies a CollectT to the condition function, so that the condition
|
||||
// function can use the CollectT to call other assertions.
|
||||
// The condition is considered "met" if no errors are raised in a tick.
|
||||
// The supplied CollectT collects all errors from one tick (if there are any).
|
||||
// If the condition is not met before waitFor, the collected errors of
|
||||
// the last tick are copied to t.
|
||||
//
|
||||
// externalValue := false
|
||||
// go func() {
|
||||
// time.Sleep(8*time.Second)
|
||||
// externalValue = true
|
||||
// }()
|
||||
// assert.EventuallyWithTf(t, func(c *assert.CollectT, "error message %s", "formatted") {
|
||||
// // add assertions as needed; any assertion failure will fail the current tick
|
||||
// assert.True(c, externalValue, "expected 'externalValue' to be true")
|
||||
// }, 10*time.Second, 1*time.Second, "external state has not changed to 'true'; still false")
|
||||
func EventuallyWithTf(t TestingT, condition func(collect *CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
return EventuallyWithT(t, condition, waitFor, tick, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// Exactlyf asserts that two objects are equal in value and type.
|
||||
//
|
||||
// assert.Exactlyf(t, int32(123), int64(123), "error message %s", "formatted")
|
||||
// assert.Exactlyf(t, int32(123), int64(123), "error message %s", "formatted")
|
||||
func Exactlyf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -229,7 +183,7 @@ func FailNowf(t TestingT, failureMessage string, msg string, args ...interface{}
|
||||
|
||||
// Falsef asserts that the specified value is false.
|
||||
//
|
||||
// assert.Falsef(t, myBool, "error message %s", "formatted")
|
||||
// assert.Falsef(t, myBool, "error message %s", "formatted")
|
||||
func Falsef(t TestingT, value bool, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -248,9 +202,9 @@ func FileExistsf(t TestingT, path string, msg string, args ...interface{}) bool
|
||||
|
||||
// Greaterf asserts that the first element is greater than the second
|
||||
//
|
||||
// assert.Greaterf(t, 2, 1, "error message %s", "formatted")
|
||||
// assert.Greaterf(t, float64(2), float64(1), "error message %s", "formatted")
|
||||
// assert.Greaterf(t, "b", "a", "error message %s", "formatted")
|
||||
// assert.Greaterf(t, 2, 1, "error message %s", "formatted")
|
||||
// assert.Greaterf(t, float64(2), float64(1), "error message %s", "formatted")
|
||||
// assert.Greaterf(t, "b", "a", "error message %s", "formatted")
|
||||
func Greaterf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -260,10 +214,10 @@ func Greaterf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...in
|
||||
|
||||
// GreaterOrEqualf asserts that the first element is greater than or equal to the second
|
||||
//
|
||||
// assert.GreaterOrEqualf(t, 2, 1, "error message %s", "formatted")
|
||||
// assert.GreaterOrEqualf(t, 2, 2, "error message %s", "formatted")
|
||||
// assert.GreaterOrEqualf(t, "b", "a", "error message %s", "formatted")
|
||||
// assert.GreaterOrEqualf(t, "b", "b", "error message %s", "formatted")
|
||||
// assert.GreaterOrEqualf(t, 2, 1, "error message %s", "formatted")
|
||||
// assert.GreaterOrEqualf(t, 2, 2, "error message %s", "formatted")
|
||||
// assert.GreaterOrEqualf(t, "b", "a", "error message %s", "formatted")
|
||||
// assert.GreaterOrEqualf(t, "b", "b", "error message %s", "formatted")
|
||||
func GreaterOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -274,7 +228,7 @@ func GreaterOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, arg
|
||||
// HTTPBodyContainsf asserts that a specified handler returns a
|
||||
// body that contains a string.
|
||||
//
|
||||
// assert.HTTPBodyContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
|
||||
// assert.HTTPBodyContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func HTTPBodyContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool {
|
||||
@ -287,7 +241,7 @@ func HTTPBodyContainsf(t TestingT, handler http.HandlerFunc, method string, url
|
||||
// HTTPBodyNotContainsf asserts that a specified handler returns a
|
||||
// body that does not contain a string.
|
||||
//
|
||||
// assert.HTTPBodyNotContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
|
||||
// assert.HTTPBodyNotContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool {
|
||||
@ -299,7 +253,7 @@ func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, u
|
||||
|
||||
// HTTPErrorf asserts that a specified handler returns an error status code.
|
||||
//
|
||||
// assert.HTTPErrorf(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}}
|
||||
// assert.HTTPErrorf(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}}
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {
|
||||
@ -311,7 +265,7 @@ func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string,
|
||||
|
||||
// HTTPRedirectf asserts that a specified handler returns a redirect status code.
|
||||
//
|
||||
// assert.HTTPRedirectf(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}}
|
||||
// assert.HTTPRedirectf(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}}
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {
|
||||
@ -323,7 +277,7 @@ func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url stri
|
||||
|
||||
// HTTPStatusCodef asserts that a specified handler returns a specified status code.
|
||||
//
|
||||
// assert.HTTPStatusCodef(t, myHandler, "GET", "/notImplemented", nil, 501, "error message %s", "formatted")
|
||||
// assert.HTTPStatusCodef(t, myHandler, "GET", "/notImplemented", nil, 501, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func HTTPStatusCodef(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msg string, args ...interface{}) bool {
|
||||
@ -335,7 +289,7 @@ func HTTPStatusCodef(t TestingT, handler http.HandlerFunc, method string, url st
|
||||
|
||||
// HTTPSuccessf asserts that a specified handler returns a success status code.
|
||||
//
|
||||
// assert.HTTPSuccessf(t, myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted")
|
||||
// assert.HTTPSuccessf(t, myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {
|
||||
@ -347,7 +301,7 @@ func HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url strin
|
||||
|
||||
// Implementsf asserts that an object is implemented by the specified interface.
|
||||
//
|
||||
// assert.Implementsf(t, (*MyInterface)(nil), new(MyObject), "error message %s", "formatted")
|
||||
// assert.Implementsf(t, (*MyInterface)(nil), new(MyObject), "error message %s", "formatted")
|
||||
func Implementsf(t TestingT, interfaceObject interface{}, object interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -357,7 +311,7 @@ func Implementsf(t TestingT, interfaceObject interface{}, object interface{}, ms
|
||||
|
||||
// InDeltaf asserts that the two numerals are within delta of each other.
|
||||
//
|
||||
// assert.InDeltaf(t, math.Pi, 22/7.0, 0.01, "error message %s", "formatted")
|
||||
// assert.InDeltaf(t, math.Pi, 22/7.0, 0.01, "error message %s", "formatted")
|
||||
func InDeltaf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -399,9 +353,9 @@ func InEpsilonSlicef(t TestingT, expected interface{}, actual interface{}, epsil
|
||||
|
||||
// IsDecreasingf asserts that the collection is decreasing
|
||||
//
|
||||
// assert.IsDecreasingf(t, []int{2, 1, 0}, "error message %s", "formatted")
|
||||
// assert.IsDecreasingf(t, []float{2, 1}, "error message %s", "formatted")
|
||||
// assert.IsDecreasingf(t, []string{"b", "a"}, "error message %s", "formatted")
|
||||
// assert.IsDecreasingf(t, []int{2, 1, 0}, "error message %s", "formatted")
|
||||
// assert.IsDecreasingf(t, []float{2, 1}, "error message %s", "formatted")
|
||||
// assert.IsDecreasingf(t, []string{"b", "a"}, "error message %s", "formatted")
|
||||
func IsDecreasingf(t TestingT, object interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -411,9 +365,9 @@ func IsDecreasingf(t TestingT, object interface{}, msg string, args ...interface
|
||||
|
||||
// IsIncreasingf asserts that the collection is increasing
|
||||
//
|
||||
// assert.IsIncreasingf(t, []int{1, 2, 3}, "error message %s", "formatted")
|
||||
// assert.IsIncreasingf(t, []float{1, 2}, "error message %s", "formatted")
|
||||
// assert.IsIncreasingf(t, []string{"a", "b"}, "error message %s", "formatted")
|
||||
// assert.IsIncreasingf(t, []int{1, 2, 3}, "error message %s", "formatted")
|
||||
// assert.IsIncreasingf(t, []float{1, 2}, "error message %s", "formatted")
|
||||
// assert.IsIncreasingf(t, []string{"a", "b"}, "error message %s", "formatted")
|
||||
func IsIncreasingf(t TestingT, object interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -423,9 +377,9 @@ func IsIncreasingf(t TestingT, object interface{}, msg string, args ...interface
|
||||
|
||||
// IsNonDecreasingf asserts that the collection is not decreasing
|
||||
//
|
||||
// assert.IsNonDecreasingf(t, []int{1, 1, 2}, "error message %s", "formatted")
|
||||
// assert.IsNonDecreasingf(t, []float{1, 2}, "error message %s", "formatted")
|
||||
// assert.IsNonDecreasingf(t, []string{"a", "b"}, "error message %s", "formatted")
|
||||
// assert.IsNonDecreasingf(t, []int{1, 1, 2}, "error message %s", "formatted")
|
||||
// assert.IsNonDecreasingf(t, []float{1, 2}, "error message %s", "formatted")
|
||||
// assert.IsNonDecreasingf(t, []string{"a", "b"}, "error message %s", "formatted")
|
||||
func IsNonDecreasingf(t TestingT, object interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -435,9 +389,9 @@ func IsNonDecreasingf(t TestingT, object interface{}, msg string, args ...interf
|
||||
|
||||
// IsNonIncreasingf asserts that the collection is not increasing
|
||||
//
|
||||
// assert.IsNonIncreasingf(t, []int{2, 1, 1}, "error message %s", "formatted")
|
||||
// assert.IsNonIncreasingf(t, []float{2, 1}, "error message %s", "formatted")
|
||||
// assert.IsNonIncreasingf(t, []string{"b", "a"}, "error message %s", "formatted")
|
||||
// assert.IsNonIncreasingf(t, []int{2, 1, 1}, "error message %s", "formatted")
|
||||
// assert.IsNonIncreasingf(t, []float{2, 1}, "error message %s", "formatted")
|
||||
// assert.IsNonIncreasingf(t, []string{"b", "a"}, "error message %s", "formatted")
|
||||
func IsNonIncreasingf(t TestingT, object interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -445,19 +399,7 @@ func IsNonIncreasingf(t TestingT, object interface{}, msg string, args ...interf
|
||||
return IsNonIncreasing(t, object, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// IsNotTypef asserts that the specified objects are not of the same type.
|
||||
//
|
||||
// assert.IsNotTypef(t, &NotMyStruct{}, &MyStruct{}, "error message %s", "formatted")
|
||||
func IsNotTypef(t TestingT, theType interface{}, object interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
return IsNotType(t, theType, object, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// IsTypef asserts that the specified objects are of the same type.
|
||||
//
|
||||
// assert.IsTypef(t, &MyStruct{}, &MyStruct{}, "error message %s", "formatted")
|
||||
func IsTypef(t TestingT, expectedType interface{}, object interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -467,7 +409,7 @@ func IsTypef(t TestingT, expectedType interface{}, object interface{}, msg strin
|
||||
|
||||
// JSONEqf asserts that two JSON strings are equivalent.
|
||||
//
|
||||
// assert.JSONEqf(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted")
|
||||
// assert.JSONEqf(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted")
|
||||
func JSONEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -478,7 +420,7 @@ func JSONEqf(t TestingT, expected string, actual string, msg string, args ...int
|
||||
// Lenf asserts that the specified object has specific length.
|
||||
// Lenf also fails if the object has a type that len() not accept.
|
||||
//
|
||||
// assert.Lenf(t, mySlice, 3, "error message %s", "formatted")
|
||||
// assert.Lenf(t, mySlice, 3, "error message %s", "formatted")
|
||||
func Lenf(t TestingT, object interface{}, length int, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -488,9 +430,9 @@ func Lenf(t TestingT, object interface{}, length int, msg string, args ...interf
|
||||
|
||||
// Lessf asserts that the first element is less than the second
|
||||
//
|
||||
// assert.Lessf(t, 1, 2, "error message %s", "formatted")
|
||||
// assert.Lessf(t, float64(1), float64(2), "error message %s", "formatted")
|
||||
// assert.Lessf(t, "a", "b", "error message %s", "formatted")
|
||||
// assert.Lessf(t, 1, 2, "error message %s", "formatted")
|
||||
// assert.Lessf(t, float64(1), float64(2), "error message %s", "formatted")
|
||||
// assert.Lessf(t, "a", "b", "error message %s", "formatted")
|
||||
func Lessf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -500,10 +442,10 @@ func Lessf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...inter
|
||||
|
||||
// LessOrEqualf asserts that the first element is less than or equal to the second
|
||||
//
|
||||
// assert.LessOrEqualf(t, 1, 2, "error message %s", "formatted")
|
||||
// assert.LessOrEqualf(t, 2, 2, "error message %s", "formatted")
|
||||
// assert.LessOrEqualf(t, "a", "b", "error message %s", "formatted")
|
||||
// assert.LessOrEqualf(t, "b", "b", "error message %s", "formatted")
|
||||
// assert.LessOrEqualf(t, 1, 2, "error message %s", "formatted")
|
||||
// assert.LessOrEqualf(t, 2, 2, "error message %s", "formatted")
|
||||
// assert.LessOrEqualf(t, "a", "b", "error message %s", "formatted")
|
||||
// assert.LessOrEqualf(t, "b", "b", "error message %s", "formatted")
|
||||
func LessOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -513,8 +455,8 @@ func LessOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args .
|
||||
|
||||
// Negativef asserts that the specified element is negative
|
||||
//
|
||||
// assert.Negativef(t, -1, "error message %s", "formatted")
|
||||
// assert.Negativef(t, -1.23, "error message %s", "formatted")
|
||||
// assert.Negativef(t, -1, "error message %s", "formatted")
|
||||
// assert.Negativef(t, -1.23, "error message %s", "formatted")
|
||||
func Negativef(t TestingT, e interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -525,7 +467,7 @@ func Negativef(t TestingT, e interface{}, msg string, args ...interface{}) bool
|
||||
// Neverf asserts that the given condition doesn't satisfy in waitFor time,
|
||||
// periodically checking the target function each tick.
|
||||
//
|
||||
// assert.Neverf(t, func() bool { return false; }, time.Second, 10*time.Millisecond, "error message %s", "formatted")
|
||||
// assert.Neverf(t, func() bool { return false; }, time.Second, 10*time.Millisecond, "error message %s", "formatted")
|
||||
func Neverf(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -535,7 +477,7 @@ func Neverf(t TestingT, condition func() bool, waitFor time.Duration, tick time.
|
||||
|
||||
// Nilf asserts that the specified object is nil.
|
||||
//
|
||||
// assert.Nilf(t, err, "error message %s", "formatted")
|
||||
// assert.Nilf(t, err, "error message %s", "formatted")
|
||||
func Nilf(t TestingT, object interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -554,10 +496,10 @@ func NoDirExistsf(t TestingT, path string, msg string, args ...interface{}) bool
|
||||
|
||||
// NoErrorf asserts that a function returned no error (i.e. `nil`).
|
||||
//
|
||||
// actualObj, err := SomeFunction()
|
||||
// if assert.NoErrorf(t, err, "error message %s", "formatted") {
|
||||
// assert.Equal(t, expectedObj, actualObj)
|
||||
// }
|
||||
// actualObj, err := SomeFunction()
|
||||
// if assert.NoErrorf(t, err, "error message %s", "formatted") {
|
||||
// assert.Equal(t, expectedObj, actualObj)
|
||||
// }
|
||||
func NoErrorf(t TestingT, err error, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -577,9 +519,9 @@ func NoFileExistsf(t TestingT, path string, msg string, args ...interface{}) boo
|
||||
// NotContainsf asserts that the specified string, list(array, slice...) or map does NOT contain the
|
||||
// specified substring or element.
|
||||
//
|
||||
// assert.NotContainsf(t, "Hello World", "Earth", "error message %s", "formatted")
|
||||
// assert.NotContainsf(t, ["Hello", "World"], "Earth", "error message %s", "formatted")
|
||||
// assert.NotContainsf(t, {"Hello": "World"}, "Earth", "error message %s", "formatted")
|
||||
// assert.NotContainsf(t, "Hello World", "Earth", "error message %s", "formatted")
|
||||
// assert.NotContainsf(t, ["Hello", "World"], "Earth", "error message %s", "formatted")
|
||||
// assert.NotContainsf(t, {"Hello": "World"}, "Earth", "error message %s", "formatted")
|
||||
func NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -587,28 +529,12 @@ func NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, a
|
||||
return NotContains(t, s, contains, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// NotElementsMatchf asserts that the specified listA(array, slice...) is NOT equal to specified
|
||||
// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements,
|
||||
// the number of appearances of each of them in both lists should not match.
|
||||
// This is an inverse of ElementsMatch.
|
||||
// NotEmptyf asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either
|
||||
// a slice or a channel with len == 0.
|
||||
//
|
||||
// assert.NotElementsMatchf(t, [1, 1, 2, 3], [1, 1, 2, 3], "error message %s", "formatted") -> false
|
||||
//
|
||||
// assert.NotElementsMatchf(t, [1, 1, 2, 3], [1, 2, 3], "error message %s", "formatted") -> true
|
||||
//
|
||||
// assert.NotElementsMatchf(t, [1, 2, 3], [1, 2, 4], "error message %s", "formatted") -> true
|
||||
func NotElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
return NotElementsMatch(t, listA, listB, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// NotEmptyf asserts that the specified object is NOT [Empty].
|
||||
//
|
||||
// if assert.NotEmptyf(t, obj, "error message %s", "formatted") {
|
||||
// assert.Equal(t, "two", obj[1])
|
||||
// }
|
||||
// if assert.NotEmptyf(t, obj, "error message %s", "formatted") {
|
||||
// assert.Equal(t, "two", obj[1])
|
||||
// }
|
||||
func NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -618,7 +544,7 @@ func NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{})
|
||||
|
||||
// NotEqualf asserts that the specified values are NOT equal.
|
||||
//
|
||||
// assert.NotEqualf(t, obj1, obj2, "error message %s", "formatted")
|
||||
// assert.NotEqualf(t, obj1, obj2, "error message %s", "formatted")
|
||||
//
|
||||
// Pointer variable equality is determined based on the equality of the
|
||||
// referenced values (as opposed to the memory addresses).
|
||||
@ -631,7 +557,7 @@ func NotEqualf(t TestingT, expected interface{}, actual interface{}, msg string,
|
||||
|
||||
// NotEqualValuesf asserts that two objects are not equal even when converted to the same type
|
||||
//
|
||||
// assert.NotEqualValuesf(t, obj1, obj2, "error message %s", "formatted")
|
||||
// assert.NotEqualValuesf(t, obj1, obj2, "error message %s", "formatted")
|
||||
func NotEqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -639,16 +565,7 @@ func NotEqualValuesf(t TestingT, expected interface{}, actual interface{}, msg s
|
||||
return NotEqualValues(t, expected, actual, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// NotErrorAsf asserts that none of the errors in err's chain matches target,
|
||||
// but if so, sets target to that error value.
|
||||
func NotErrorAsf(t TestingT, err error, target interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
return NotErrorAs(t, err, target, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// NotErrorIsf asserts that none of the errors in err's chain matches target.
|
||||
// NotErrorIsf asserts that at none of the errors in err's chain matches target.
|
||||
// This is a wrapper for errors.Is.
|
||||
func NotErrorIsf(t TestingT, err error, target error, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
@ -657,19 +574,9 @@ func NotErrorIsf(t TestingT, err error, target error, msg string, args ...interf
|
||||
return NotErrorIs(t, err, target, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// NotImplementsf asserts that an object does not implement the specified interface.
|
||||
//
|
||||
// assert.NotImplementsf(t, (*MyInterface)(nil), new(MyObject), "error message %s", "formatted")
|
||||
func NotImplementsf(t TestingT, interfaceObject interface{}, object interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
return NotImplements(t, interfaceObject, object, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// NotNilf asserts that the specified object is not nil.
|
||||
//
|
||||
// assert.NotNilf(t, err, "error message %s", "formatted")
|
||||
// assert.NotNilf(t, err, "error message %s", "formatted")
|
||||
func NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -679,7 +586,7 @@ func NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) bo
|
||||
|
||||
// NotPanicsf asserts that the code inside the specified PanicTestFunc does NOT panic.
|
||||
//
|
||||
// assert.NotPanicsf(t, func(){ RemainCalm() }, "error message %s", "formatted")
|
||||
// assert.NotPanicsf(t, func(){ RemainCalm() }, "error message %s", "formatted")
|
||||
func NotPanicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -689,8 +596,8 @@ func NotPanicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bo
|
||||
|
||||
// NotRegexpf asserts that a specified regexp does not match a string.
|
||||
//
|
||||
// assert.NotRegexpf(t, regexp.MustCompile("starts"), "it's starting", "error message %s", "formatted")
|
||||
// assert.NotRegexpf(t, "^start", "it's not starting", "error message %s", "formatted")
|
||||
// assert.NotRegexpf(t, regexp.MustCompile("starts"), "it's starting", "error message %s", "formatted")
|
||||
// assert.NotRegexpf(t, "^start", "it's not starting", "error message %s", "formatted")
|
||||
func NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -700,7 +607,7 @@ func NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args ..
|
||||
|
||||
// NotSamef asserts that two pointers do not reference the same object.
|
||||
//
|
||||
// assert.NotSamef(t, ptr1, ptr2, "error message %s", "formatted")
|
||||
// assert.NotSamef(t, ptr1, ptr2, "error message %s", "formatted")
|
||||
//
|
||||
// Both arguments must be pointer variables. Pointer variable sameness is
|
||||
// determined based on the equality of both type and value.
|
||||
@ -711,15 +618,10 @@ func NotSamef(t TestingT, expected interface{}, actual interface{}, msg string,
|
||||
return NotSame(t, expected, actual, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// NotSubsetf asserts that the list (array, slice, or map) does NOT contain all
|
||||
// elements given in the subset (array, slice, or map).
|
||||
// Map elements are key-value pairs unless compared with an array or slice where
|
||||
// only the map key is evaluated.
|
||||
// NotSubsetf asserts that the specified list(array, slice...) contains not all
|
||||
// elements given in the specified subset(array, slice...).
|
||||
//
|
||||
// assert.NotSubsetf(t, [1, 3, 4], [1, 2], "error message %s", "formatted")
|
||||
// assert.NotSubsetf(t, {"x": 1, "y": 2}, {"z": 3}, "error message %s", "formatted")
|
||||
// assert.NotSubsetf(t, [1, 3, 4], {1: "one", 2: "two"}, "error message %s", "formatted")
|
||||
// assert.NotSubsetf(t, {"x": 1, "y": 2}, ["z"], "error message %s", "formatted")
|
||||
// assert.NotSubsetf(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted")
|
||||
func NotSubsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -737,7 +639,7 @@ func NotZerof(t TestingT, i interface{}, msg string, args ...interface{}) bool {
|
||||
|
||||
// Panicsf asserts that the code inside the specified PanicTestFunc panics.
|
||||
//
|
||||
// assert.Panicsf(t, func(){ GoCrazy() }, "error message %s", "formatted")
|
||||
// assert.Panicsf(t, func(){ GoCrazy() }, "error message %s", "formatted")
|
||||
func Panicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -749,7 +651,7 @@ func Panicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bool
|
||||
// panics, and that the recovered panic value is an error that satisfies the
|
||||
// EqualError comparison.
|
||||
//
|
||||
// assert.PanicsWithErrorf(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted")
|
||||
// assert.PanicsWithErrorf(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted")
|
||||
func PanicsWithErrorf(t TestingT, errString string, f PanicTestFunc, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -760,7 +662,7 @@ func PanicsWithErrorf(t TestingT, errString string, f PanicTestFunc, msg string,
|
||||
// PanicsWithValuef asserts that the code inside the specified PanicTestFunc panics, and that
|
||||
// the recovered panic value equals the expected panic value.
|
||||
//
|
||||
// assert.PanicsWithValuef(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted")
|
||||
// assert.PanicsWithValuef(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted")
|
||||
func PanicsWithValuef(t TestingT, expected interface{}, f PanicTestFunc, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -770,8 +672,8 @@ func PanicsWithValuef(t TestingT, expected interface{}, f PanicTestFunc, msg str
|
||||
|
||||
// Positivef asserts that the specified element is positive
|
||||
//
|
||||
// assert.Positivef(t, 1, "error message %s", "formatted")
|
||||
// assert.Positivef(t, 1.23, "error message %s", "formatted")
|
||||
// assert.Positivef(t, 1, "error message %s", "formatted")
|
||||
// assert.Positivef(t, 1.23, "error message %s", "formatted")
|
||||
func Positivef(t TestingT, e interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -781,8 +683,8 @@ func Positivef(t TestingT, e interface{}, msg string, args ...interface{}) bool
|
||||
|
||||
// Regexpf asserts that a specified regexp matches a string.
|
||||
//
|
||||
// assert.Regexpf(t, regexp.MustCompile("start"), "it's starting", "error message %s", "formatted")
|
||||
// assert.Regexpf(t, "start...$", "it's not starting", "error message %s", "formatted")
|
||||
// assert.Regexpf(t, regexp.MustCompile("start"), "it's starting", "error message %s", "formatted")
|
||||
// assert.Regexpf(t, "start...$", "it's not starting", "error message %s", "formatted")
|
||||
func Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -792,7 +694,7 @@ func Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...in
|
||||
|
||||
// Samef asserts that two pointers reference the same object.
|
||||
//
|
||||
// assert.Samef(t, ptr1, ptr2, "error message %s", "formatted")
|
||||
// assert.Samef(t, ptr1, ptr2, "error message %s", "formatted")
|
||||
//
|
||||
// Both arguments must be pointer variables. Pointer variable sameness is
|
||||
// determined based on the equality of both type and value.
|
||||
@ -803,15 +705,10 @@ func Samef(t TestingT, expected interface{}, actual interface{}, msg string, arg
|
||||
return Same(t, expected, actual, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// Subsetf asserts that the list (array, slice, or map) contains all elements
|
||||
// given in the subset (array, slice, or map).
|
||||
// Map elements are key-value pairs unless compared with an array or slice where
|
||||
// only the map key is evaluated.
|
||||
// Subsetf asserts that the specified list(array, slice...) contains all
|
||||
// elements given in the specified subset(array, slice...).
|
||||
//
|
||||
// assert.Subsetf(t, [1, 2, 3], [1, 2], "error message %s", "formatted")
|
||||
// assert.Subsetf(t, {"x": 1, "y": 2}, {"x": 1}, "error message %s", "formatted")
|
||||
// assert.Subsetf(t, [1, 2, 3], {1: "one", 2: "two"}, "error message %s", "formatted")
|
||||
// assert.Subsetf(t, {"x": 1, "y": 2}, ["x"], "error message %s", "formatted")
|
||||
// assert.Subsetf(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted")
|
||||
func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -821,7 +718,7 @@ func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args
|
||||
|
||||
// Truef asserts that the specified value is true.
|
||||
//
|
||||
// assert.Truef(t, myBool, "error message %s", "formatted")
|
||||
// assert.Truef(t, myBool, "error message %s", "formatted")
|
||||
func Truef(t TestingT, value bool, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -831,7 +728,7 @@ func Truef(t TestingT, value bool, msg string, args ...interface{}) bool {
|
||||
|
||||
// WithinDurationf asserts that the two times are within duration delta of each other.
|
||||
//
|
||||
// assert.WithinDurationf(t, time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted")
|
||||
// assert.WithinDurationf(t, time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted")
|
||||
func WithinDurationf(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -839,16 +736,6 @@ func WithinDurationf(t TestingT, expected time.Time, actual time.Time, delta tim
|
||||
return WithinDuration(t, expected, actual, delta, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// WithinRangef asserts that a time is within a time range (inclusive).
|
||||
//
|
||||
// assert.WithinRangef(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second), "error message %s", "formatted")
|
||||
func WithinRangef(t TestingT, actual time.Time, start time.Time, end time.Time, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
return WithinRange(t, actual, start, end, append([]interface{}{msg}, args...)...)
|
||||
}
|
||||
|
||||
// YAMLEqf asserts that two YAML strings are equivalent.
|
||||
func YAMLEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -6,7 +6,7 @@ import (
|
||||
)
|
||||
|
||||
// isOrdered checks that collection contains orderable elements.
|
||||
func isOrdered(t TestingT, object interface{}, allowedComparesResults []compareResult, failMessage string, msgAndArgs ...interface{}) bool {
|
||||
func isOrdered(t TestingT, object interface{}, allowedComparesResults []CompareType, failMessage string, msgAndArgs ...interface{}) bool {
|
||||
objKind := reflect.TypeOf(object).Kind()
|
||||
if objKind != reflect.Slice && objKind != reflect.Array {
|
||||
return false
|
||||
@ -33,7 +33,7 @@ func isOrdered(t TestingT, object interface{}, allowedComparesResults []compareR
|
||||
compareResult, isComparable := compare(prevValueInterface, valueInterface, firstValueKind)
|
||||
|
||||
if !isComparable {
|
||||
return Fail(t, fmt.Sprintf(`Can not compare type "%T" and "%T"`, value, prevValue), msgAndArgs...)
|
||||
return Fail(t, fmt.Sprintf("Can not compare type \"%s\" and \"%s\"", reflect.TypeOf(value), reflect.TypeOf(prevValue)), msgAndArgs...)
|
||||
}
|
||||
|
||||
if !containsValue(allowedComparesResults, compareResult) {
|
||||
@ -46,36 +46,36 @@ func isOrdered(t TestingT, object interface{}, allowedComparesResults []compareR
|
||||
|
||||
// IsIncreasing asserts that the collection is increasing
|
||||
//
|
||||
// assert.IsIncreasing(t, []int{1, 2, 3})
|
||||
// assert.IsIncreasing(t, []float{1, 2})
|
||||
// assert.IsIncreasing(t, []string{"a", "b"})
|
||||
// assert.IsIncreasing(t, []int{1, 2, 3})
|
||||
// assert.IsIncreasing(t, []float{1, 2})
|
||||
// assert.IsIncreasing(t, []string{"a", "b"})
|
||||
func IsIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
|
||||
return isOrdered(t, object, []compareResult{compareLess}, "\"%v\" is not less than \"%v\"", msgAndArgs...)
|
||||
return isOrdered(t, object, []CompareType{compareLess}, "\"%v\" is not less than \"%v\"", msgAndArgs...)
|
||||
}
|
||||
|
||||
// IsNonIncreasing asserts that the collection is not increasing
|
||||
//
|
||||
// assert.IsNonIncreasing(t, []int{2, 1, 1})
|
||||
// assert.IsNonIncreasing(t, []float{2, 1})
|
||||
// assert.IsNonIncreasing(t, []string{"b", "a"})
|
||||
// assert.IsNonIncreasing(t, []int{2, 1, 1})
|
||||
// assert.IsNonIncreasing(t, []float{2, 1})
|
||||
// assert.IsNonIncreasing(t, []string{"b", "a"})
|
||||
func IsNonIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
|
||||
return isOrdered(t, object, []compareResult{compareEqual, compareGreater}, "\"%v\" is not greater than or equal to \"%v\"", msgAndArgs...)
|
||||
return isOrdered(t, object, []CompareType{compareEqual, compareGreater}, "\"%v\" is not greater than or equal to \"%v\"", msgAndArgs...)
|
||||
}
|
||||
|
||||
// IsDecreasing asserts that the collection is decreasing
|
||||
//
|
||||
// assert.IsDecreasing(t, []int{2, 1, 0})
|
||||
// assert.IsDecreasing(t, []float{2, 1})
|
||||
// assert.IsDecreasing(t, []string{"b", "a"})
|
||||
// assert.IsDecreasing(t, []int{2, 1, 0})
|
||||
// assert.IsDecreasing(t, []float{2, 1})
|
||||
// assert.IsDecreasing(t, []string{"b", "a"})
|
||||
func IsDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
|
||||
return isOrdered(t, object, []compareResult{compareGreater}, "\"%v\" is not greater than \"%v\"", msgAndArgs...)
|
||||
return isOrdered(t, object, []CompareType{compareGreater}, "\"%v\" is not greater than \"%v\"", msgAndArgs...)
|
||||
}
|
||||
|
||||
// IsNonDecreasing asserts that the collection is not decreasing
|
||||
//
|
||||
// assert.IsNonDecreasing(t, []int{1, 1, 2})
|
||||
// assert.IsNonDecreasing(t, []float{1, 2})
|
||||
// assert.IsNonDecreasing(t, []string{"a", "b"})
|
||||
// assert.IsNonDecreasing(t, []int{1, 1, 2})
|
||||
// assert.IsNonDecreasing(t, []float{1, 2})
|
||||
// assert.IsNonDecreasing(t, []string{"a", "b"})
|
||||
func IsNonDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
|
||||
return isOrdered(t, object, []compareResult{compareLess, compareEqual}, "\"%v\" is not less than or equal to \"%v\"", msgAndArgs...)
|
||||
return isOrdered(t, object, []CompareType{compareLess, compareEqual}, "\"%v\" is not less than or equal to \"%v\"", msgAndArgs...)
|
||||
}
|
||||
|
@ -6,8 +6,6 @@ import (
|
||||
)
|
||||
|
||||
func TestIsIncreasing(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(testing.T)
|
||||
|
||||
if !IsIncreasing(mockT, []int{1, 2}) {
|
||||
@ -53,8 +51,6 @@ func TestIsIncreasing(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestIsNonIncreasing(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(testing.T)
|
||||
|
||||
if !IsNonIncreasing(mockT, []int{2, 1}) {
|
||||
@ -100,8 +96,6 @@ func TestIsNonIncreasing(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestIsDecreasing(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(testing.T)
|
||||
|
||||
if !IsDecreasing(mockT, []int{2, 1}) {
|
||||
@ -147,8 +141,6 @@ func TestIsDecreasing(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestIsNonDecreasing(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(testing.T)
|
||||
|
||||
if !IsNonDecreasing(mockT, []int{1, 2}) {
|
||||
@ -194,8 +186,6 @@ func TestIsNonDecreasing(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestOrderingMsgAndArgsForwarding(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
msgAndArgs := []interface{}{"format %s %x", "this", 0xc001}
|
||||
expectedOutput := "format this c001\n"
|
||||
collection := []int{1, 2, 1}
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,44 +1,39 @@
|
||||
// Package assert provides a set of comprehensive testing tools for use with the normal Go testing system.
|
||||
//
|
||||
// # Note
|
||||
//
|
||||
// All functions in this package return a bool value indicating whether the assertion has passed.
|
||||
//
|
||||
// # Example Usage
|
||||
// Example Usage
|
||||
//
|
||||
// The following is a complete example using assert in a standard test function:
|
||||
// import (
|
||||
// "testing"
|
||||
// "github.com/stretchr/testify/assert"
|
||||
// )
|
||||
//
|
||||
// import (
|
||||
// "testing"
|
||||
// "github.com/stretchr/testify/assert"
|
||||
// )
|
||||
// func TestSomething(t *testing.T) {
|
||||
//
|
||||
// func TestSomething(t *testing.T) {
|
||||
// var a string = "Hello"
|
||||
// var b string = "Hello"
|
||||
//
|
||||
// var a string = "Hello"
|
||||
// var b string = "Hello"
|
||||
// assert.Equal(t, a, b, "The two words should be the same.")
|
||||
//
|
||||
// assert.Equal(t, a, b, "The two words should be the same.")
|
||||
//
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if you assert many times, use the format below:
|
||||
//
|
||||
// import (
|
||||
// "testing"
|
||||
// "github.com/stretchr/testify/assert"
|
||||
// )
|
||||
// import (
|
||||
// "testing"
|
||||
// "github.com/stretchr/testify/assert"
|
||||
// )
|
||||
//
|
||||
// func TestSomething(t *testing.T) {
|
||||
// assert := assert.New(t)
|
||||
// func TestSomething(t *testing.T) {
|
||||
// assert := assert.New(t)
|
||||
//
|
||||
// var a string = "Hello"
|
||||
// var b string = "Hello"
|
||||
// var a string = "Hello"
|
||||
// var b string = "Hello"
|
||||
//
|
||||
// assert.Equal(a, b, "The two words should be the same.")
|
||||
// }
|
||||
// assert.Equal(a, b, "The two words should be the same.")
|
||||
// }
|
||||
//
|
||||
// # Assertions
|
||||
// Assertions
|
||||
//
|
||||
// Assertions allow you to easily write test code, and are global funcs in the `assert` package.
|
||||
// All assertion functions take, as the first argument, the `*testing.T` object provided by the
|
||||
|
@ -8,8 +8,6 @@ import (
|
||||
)
|
||||
|
||||
func TestImplementsWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(new(testing.T))
|
||||
|
||||
if !assert.Implements((*AssertionTesterInterface)(nil), new(AssertionTesterConformingObject)) {
|
||||
@ -21,8 +19,6 @@ func TestImplementsWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestIsTypeWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(new(testing.T))
|
||||
|
||||
if !assert.IsType(new(AssertionTesterConformingObject), new(AssertionTesterConformingObject)) {
|
||||
@ -35,8 +31,6 @@ func TestIsTypeWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestEqualWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(new(testing.T))
|
||||
|
||||
if !assert.Equal("Hello World", "Hello World") {
|
||||
@ -57,8 +51,6 @@ func TestEqualWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestEqualValuesWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(new(testing.T))
|
||||
|
||||
if !assert.EqualValues(uint32(10), int32(10)) {
|
||||
@ -67,8 +59,6 @@ func TestEqualValuesWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNotNilWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(new(testing.T))
|
||||
|
||||
if !assert.NotNil(new(AssertionTesterConformingObject)) {
|
||||
@ -81,8 +71,6 @@ func TestNotNilWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNilWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(new(testing.T))
|
||||
|
||||
if !assert.Nil(nil) {
|
||||
@ -95,8 +83,6 @@ func TestNilWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestTrueWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(new(testing.T))
|
||||
|
||||
if !assert.True(true) {
|
||||
@ -109,8 +95,6 @@ func TestTrueWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestFalseWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(new(testing.T))
|
||||
|
||||
if !assert.False(false) {
|
||||
@ -123,8 +107,6 @@ func TestFalseWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestExactlyWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(new(testing.T))
|
||||
|
||||
a := float32(1)
|
||||
@ -152,7 +134,6 @@ func TestExactlyWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNotEqualWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(new(testing.T))
|
||||
|
||||
@ -174,7 +155,6 @@ func TestNotEqualWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNotEqualValuesWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(new(testing.T))
|
||||
|
||||
@ -199,7 +179,6 @@ func TestNotEqualValuesWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestContainsWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(new(testing.T))
|
||||
list := []string{"Foo", "Bar"}
|
||||
@ -221,7 +200,6 @@ func TestContainsWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNotContainsWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(new(testing.T))
|
||||
list := []string{"Foo", "Bar"}
|
||||
@ -243,7 +221,6 @@ func TestNotContainsWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestConditionWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(new(testing.T))
|
||||
|
||||
@ -258,7 +235,6 @@ func TestConditionWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDidPanicWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
if funcDidPanic, _, _ := didPanic(func() {
|
||||
panic("Panic!")
|
||||
@ -274,7 +250,6 @@ func TestDidPanicWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestPanicsWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(new(testing.T))
|
||||
|
||||
@ -292,7 +267,6 @@ func TestPanicsWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNotPanicsWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(new(testing.T))
|
||||
|
||||
@ -310,8 +284,6 @@ func TestNotPanicsWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNoErrorWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(t)
|
||||
mockAssert := New(new(testing.T))
|
||||
|
||||
@ -328,8 +300,6 @@ func TestNoErrorWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestErrorWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(t)
|
||||
mockAssert := New(new(testing.T))
|
||||
|
||||
@ -346,8 +316,6 @@ func TestErrorWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestErrorContainsWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(t)
|
||||
mockAssert := New(new(testing.T))
|
||||
|
||||
@ -367,8 +335,6 @@ func TestErrorContainsWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestEqualErrorWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(t)
|
||||
mockAssert := New(new(testing.T))
|
||||
|
||||
@ -386,8 +352,6 @@ func TestEqualErrorWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestEmptyWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(t)
|
||||
mockAssert := New(new(testing.T))
|
||||
|
||||
@ -406,8 +370,6 @@ func TestEmptyWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNotEmptyWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(t)
|
||||
mockAssert := New(new(testing.T))
|
||||
|
||||
@ -426,8 +388,6 @@ func TestNotEmptyWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestLenWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(t)
|
||||
mockAssert := New(new(testing.T))
|
||||
|
||||
@ -468,8 +428,6 @@ func TestLenWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestWithinDurationWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(t)
|
||||
mockAssert := New(new(testing.T))
|
||||
a := time.Now()
|
||||
@ -489,8 +447,6 @@ func TestWithinDurationWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestInDeltaWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(new(testing.T))
|
||||
|
||||
True(t, assert.InDelta(1.001, 1, 0.01), "|1.001 - 1| <= 0.01")
|
||||
@ -525,8 +481,6 @@ func TestInDeltaWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestInEpsilonWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(new(testing.T))
|
||||
|
||||
cases := []struct {
|
||||
@ -565,7 +519,6 @@ func TestInEpsilonWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestRegexpWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(new(testing.T))
|
||||
|
||||
@ -593,7 +546,7 @@ func TestRegexpWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
False(t, assert.Regexp(tc.rx, tc.str), "Expected %q to not match %q", tc.rx, tc.str)
|
||||
False(t, assert.Regexp(tc.rx, tc.str), "Expected \"%s\" to not match \"%s\"", tc.rx, tc.str)
|
||||
False(t, assert.Regexp(regexp.MustCompile(tc.rx), tc.str))
|
||||
True(t, assert.NotRegexp(tc.rx, tc.str))
|
||||
True(t, assert.NotRegexp(regexp.MustCompile(tc.rx), tc.str))
|
||||
@ -601,8 +554,6 @@ func TestRegexpWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestZeroWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(t)
|
||||
mockAssert := New(new(testing.T))
|
||||
|
||||
@ -616,8 +567,6 @@ func TestZeroWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNotZeroWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(t)
|
||||
mockAssert := New(new(testing.T))
|
||||
|
||||
@ -631,8 +580,6 @@ func TestNotZeroWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestJSONEqWrapper_EqualSONString(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(new(testing.T))
|
||||
if !assert.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"hello": "world", "foo": "bar"}`) {
|
||||
t.Error("JSONEq should return true")
|
||||
@ -641,8 +588,6 @@ func TestJSONEqWrapper_EqualSONString(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestJSONEqWrapper_EquivalentButNotEqual(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(new(testing.T))
|
||||
if !assert.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) {
|
||||
t.Error("JSONEq should return true")
|
||||
@ -651,8 +596,6 @@ func TestJSONEqWrapper_EquivalentButNotEqual(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestJSONEqWrapper_HashOfArraysAndHashes(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(new(testing.T))
|
||||
if !assert.JSONEq("{\r\n\t\"numeric\": 1.5,\r\n\t\"array\": [{\"foo\": \"bar\"}, 1, \"string\", [\"nested\", \"array\", 5.5]],\r\n\t\"hash\": {\"nested\": \"hash\", \"nested_slice\": [\"this\", \"is\", \"nested\"]},\r\n\t\"string\": \"foo\"\r\n}",
|
||||
"{\r\n\t\"numeric\": 1.5,\r\n\t\"hash\": {\"nested\": \"hash\", \"nested_slice\": [\"this\", \"is\", \"nested\"]},\r\n\t\"string\": \"foo\",\r\n\t\"array\": [{\"foo\": \"bar\"}, 1, \"string\", [\"nested\", \"array\", 5.5]]\r\n}") {
|
||||
@ -661,8 +604,6 @@ func TestJSONEqWrapper_HashOfArraysAndHashes(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestJSONEqWrapper_Array(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(new(testing.T))
|
||||
if !assert.JSONEq(`["foo", {"hello": "world", "nested": "hash"}]`, `["foo", {"nested": "hash", "hello": "world"}]`) {
|
||||
t.Error("JSONEq should return true")
|
||||
@ -671,8 +612,6 @@ func TestJSONEqWrapper_Array(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestJSONEqWrapper_HashAndArrayNotEquivalent(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(new(testing.T))
|
||||
if assert.JSONEq(`["foo", {"hello": "world", "nested": "hash"}]`, `{"foo": "bar", {"nested": "hash", "hello": "world"}}`) {
|
||||
t.Error("JSONEq should return false")
|
||||
@ -680,8 +619,6 @@ func TestJSONEqWrapper_HashAndArrayNotEquivalent(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestJSONEqWrapper_HashesNotEquivalent(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(new(testing.T))
|
||||
if assert.JSONEq(`{"foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) {
|
||||
t.Error("JSONEq should return false")
|
||||
@ -689,8 +626,6 @@ func TestJSONEqWrapper_HashesNotEquivalent(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestJSONEqWrapper_ActualIsNotJSON(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(new(testing.T))
|
||||
if assert.JSONEq(`{"foo": "bar"}`, "Not JSON") {
|
||||
t.Error("JSONEq should return false")
|
||||
@ -698,8 +633,6 @@ func TestJSONEqWrapper_ActualIsNotJSON(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestJSONEqWrapper_ExpectedIsNotJSON(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(new(testing.T))
|
||||
if assert.JSONEq("Not JSON", `{"foo": "bar", "hello": "world"}`) {
|
||||
t.Error("JSONEq should return false")
|
||||
@ -707,8 +640,6 @@ func TestJSONEqWrapper_ExpectedIsNotJSON(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestJSONEqWrapper_ExpectedAndActualNotJSON(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(new(testing.T))
|
||||
if assert.JSONEq("Not JSON", "Not JSON") {
|
||||
t.Error("JSONEq should return false")
|
||||
@ -716,8 +647,6 @@ func TestJSONEqWrapper_ExpectedAndActualNotJSON(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestJSONEqWrapper_ArraysOfDifferentOrder(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(new(testing.T))
|
||||
if assert.JSONEq(`["foo", {"hello": "world", "nested": "hash"}]`, `[{ "hello": "world", "nested": "hash"}, "foo"]`) {
|
||||
t.Error("JSONEq should return false")
|
||||
@ -725,8 +654,6 @@ func TestJSONEqWrapper_ArraysOfDifferentOrder(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestYAMLEqWrapper_EqualYAMLString(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(new(testing.T))
|
||||
if !assert.YAMLEq(`{"hello": "world", "foo": "bar"}`, `{"hello": "world", "foo": "bar"}`) {
|
||||
t.Error("YAMLEq should return true")
|
||||
@ -735,8 +662,6 @@ func TestYAMLEqWrapper_EqualYAMLString(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestYAMLEqWrapper_EquivalentButNotEqual(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(new(testing.T))
|
||||
if !assert.YAMLEq(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) {
|
||||
t.Error("YAMLEq should return true")
|
||||
@ -745,8 +670,6 @@ func TestYAMLEqWrapper_EquivalentButNotEqual(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestYAMLEqWrapper_HashOfArraysAndHashes(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(new(testing.T))
|
||||
expected := `
|
||||
numeric: 1.5
|
||||
@ -779,8 +702,6 @@ array:
|
||||
}
|
||||
|
||||
func TestYAMLEqWrapper_Array(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(new(testing.T))
|
||||
if !assert.YAMLEq(`["foo", {"hello": "world", "nested": "hash"}]`, `["foo", {"nested": "hash", "hello": "world"}]`) {
|
||||
t.Error("YAMLEq should return true")
|
||||
@ -789,8 +710,6 @@ func TestYAMLEqWrapper_Array(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestYAMLEqWrapper_HashAndArrayNotEquivalent(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(new(testing.T))
|
||||
if assert.YAMLEq(`["foo", {"hello": "world", "nested": "hash"}]`, `{"foo": "bar", {"nested": "hash", "hello": "world"}}`) {
|
||||
t.Error("YAMLEq should return false")
|
||||
@ -798,8 +717,6 @@ func TestYAMLEqWrapper_HashAndArrayNotEquivalent(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestYAMLEqWrapper_HashesNotEquivalent(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(new(testing.T))
|
||||
if assert.YAMLEq(`{"foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) {
|
||||
t.Error("YAMLEq should return false")
|
||||
@ -807,8 +724,6 @@ func TestYAMLEqWrapper_HashesNotEquivalent(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestYAMLEqWrapper_ActualIsSimpleString(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(new(testing.T))
|
||||
if assert.YAMLEq(`{"foo": "bar"}`, "Simple String") {
|
||||
t.Error("YAMLEq should return false")
|
||||
@ -816,8 +731,6 @@ func TestYAMLEqWrapper_ActualIsSimpleString(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestYAMLEqWrapper_ExpectedIsSimpleString(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(new(testing.T))
|
||||
if assert.YAMLEq("Simple String", `{"foo": "bar", "hello": "world"}`) {
|
||||
t.Error("YAMLEq should return false")
|
||||
@ -825,8 +738,6 @@ func TestYAMLEqWrapper_ExpectedIsSimpleString(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestYAMLEqWrapper_ExpectedAndActualSimpleString(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(new(testing.T))
|
||||
if !assert.YAMLEq("Simple String", "Simple String") {
|
||||
t.Error("YAMLEq should return true")
|
||||
@ -834,8 +745,6 @@ func TestYAMLEqWrapper_ExpectedAndActualSimpleString(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestYAMLEqWrapper_ArraysOfDifferentOrder(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(new(testing.T))
|
||||
if assert.YAMLEq(`["foo", {"hello": "world", "nested": "hash"}]`, `[{ "hello": "world", "nested": "hash"}, "foo"]`) {
|
||||
t.Error("YAMLEq should return false")
|
||||
|
@ -12,7 +12,7 @@ import (
|
||||
// an error if building a new request fails.
|
||||
func httpCode(handler http.HandlerFunc, method, url string, values url.Values) (int, error) {
|
||||
w := httptest.NewRecorder()
|
||||
req, err := http.NewRequest(method, url, http.NoBody)
|
||||
req, err := http.NewRequest(method, url, nil)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
@ -23,7 +23,7 @@ func httpCode(handler http.HandlerFunc, method, url string, values url.Values) (
|
||||
|
||||
// HTTPSuccess asserts that a specified handler returns a success status code.
|
||||
//
|
||||
// assert.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil)
|
||||
// assert.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func HTTPSuccess(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool {
|
||||
@ -32,12 +32,12 @@ func HTTPSuccess(t TestingT, handler http.HandlerFunc, method, url string, value
|
||||
}
|
||||
code, err := httpCode(handler, method, url, values)
|
||||
if err != nil {
|
||||
Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err), msgAndArgs...)
|
||||
Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err))
|
||||
}
|
||||
|
||||
isSuccessCode := code >= http.StatusOK && code <= http.StatusPartialContent
|
||||
if !isSuccessCode {
|
||||
Fail(t, fmt.Sprintf("Expected HTTP success status code for %q but received %d", url+"?"+values.Encode(), code), msgAndArgs...)
|
||||
Fail(t, fmt.Sprintf("Expected HTTP success status code for %q but received %d", url+"?"+values.Encode(), code))
|
||||
}
|
||||
|
||||
return isSuccessCode
|
||||
@ -45,7 +45,7 @@ func HTTPSuccess(t TestingT, handler http.HandlerFunc, method, url string, value
|
||||
|
||||
// HTTPRedirect asserts that a specified handler returns a redirect status code.
|
||||
//
|
||||
// assert.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}}
|
||||
// assert.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}}
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func HTTPRedirect(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool {
|
||||
@ -54,12 +54,12 @@ func HTTPRedirect(t TestingT, handler http.HandlerFunc, method, url string, valu
|
||||
}
|
||||
code, err := httpCode(handler, method, url, values)
|
||||
if err != nil {
|
||||
Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err), msgAndArgs...)
|
||||
Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err))
|
||||
}
|
||||
|
||||
isRedirectCode := code >= http.StatusMultipleChoices && code <= http.StatusTemporaryRedirect
|
||||
if !isRedirectCode {
|
||||
Fail(t, fmt.Sprintf("Expected HTTP redirect status code for %q but received %d", url+"?"+values.Encode(), code), msgAndArgs...)
|
||||
Fail(t, fmt.Sprintf("Expected HTTP redirect status code for %q but received %d", url+"?"+values.Encode(), code))
|
||||
}
|
||||
|
||||
return isRedirectCode
|
||||
@ -67,7 +67,7 @@ func HTTPRedirect(t TestingT, handler http.HandlerFunc, method, url string, valu
|
||||
|
||||
// HTTPError asserts that a specified handler returns an error status code.
|
||||
//
|
||||
// assert.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}}
|
||||
// assert.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}}
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func HTTPError(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool {
|
||||
@ -76,12 +76,12 @@ func HTTPError(t TestingT, handler http.HandlerFunc, method, url string, values
|
||||
}
|
||||
code, err := httpCode(handler, method, url, values)
|
||||
if err != nil {
|
||||
Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err), msgAndArgs...)
|
||||
Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err))
|
||||
}
|
||||
|
||||
isErrorCode := code >= http.StatusBadRequest
|
||||
if !isErrorCode {
|
||||
Fail(t, fmt.Sprintf("Expected HTTP error status code for %q but received %d", url+"?"+values.Encode(), code), msgAndArgs...)
|
||||
Fail(t, fmt.Sprintf("Expected HTTP error status code for %q but received %d", url+"?"+values.Encode(), code))
|
||||
}
|
||||
|
||||
return isErrorCode
|
||||
@ -89,7 +89,7 @@ func HTTPError(t TestingT, handler http.HandlerFunc, method, url string, values
|
||||
|
||||
// HTTPStatusCode asserts that a specified handler returns a specified status code.
|
||||
//
|
||||
// assert.HTTPStatusCode(t, myHandler, "GET", "/notImplemented", nil, 501)
|
||||
// assert.HTTPStatusCode(t, myHandler, "GET", "/notImplemented", nil, 501)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func HTTPStatusCode(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, statuscode int, msgAndArgs ...interface{}) bool {
|
||||
@ -98,12 +98,12 @@ func HTTPStatusCode(t TestingT, handler http.HandlerFunc, method, url string, va
|
||||
}
|
||||
code, err := httpCode(handler, method, url, values)
|
||||
if err != nil {
|
||||
Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err), msgAndArgs...)
|
||||
Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err))
|
||||
}
|
||||
|
||||
successful := code == statuscode
|
||||
if !successful {
|
||||
Fail(t, fmt.Sprintf("Expected HTTP status code %d for %q but received %d", statuscode, url+"?"+values.Encode(), code), msgAndArgs...)
|
||||
Fail(t, fmt.Sprintf("Expected HTTP status code %d for %q but received %d", statuscode, url+"?"+values.Encode(), code))
|
||||
}
|
||||
|
||||
return successful
|
||||
@ -113,10 +113,7 @@ func HTTPStatusCode(t TestingT, handler http.HandlerFunc, method, url string, va
|
||||
// empty string if building a new request fails.
|
||||
func HTTPBody(handler http.HandlerFunc, method, url string, values url.Values) string {
|
||||
w := httptest.NewRecorder()
|
||||
if len(values) > 0 {
|
||||
url += "?" + values.Encode()
|
||||
}
|
||||
req, err := http.NewRequest(method, url, http.NoBody)
|
||||
req, err := http.NewRequest(method, url+"?"+values.Encode(), nil)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
@ -127,7 +124,7 @@ func HTTPBody(handler http.HandlerFunc, method, url string, values url.Values) s
|
||||
// HTTPBodyContains asserts that a specified handler returns a
|
||||
// body that contains a string.
|
||||
//
|
||||
// assert.HTTPBodyContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky")
|
||||
// assert.HTTPBodyContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool {
|
||||
@ -138,7 +135,7 @@ func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method, url string,
|
||||
|
||||
contains := strings.Contains(body, fmt.Sprint(str))
|
||||
if !contains {
|
||||
Fail(t, fmt.Sprintf("Expected response body for %q to contain %q but found %q", url+"?"+values.Encode(), str, body), msgAndArgs...)
|
||||
Fail(t, fmt.Sprintf("Expected response body for \"%s\" to contain \"%s\" but found \"%s\"", url+"?"+values.Encode(), str, body))
|
||||
}
|
||||
|
||||
return contains
|
||||
@ -147,7 +144,7 @@ func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method, url string,
|
||||
// HTTPBodyNotContains asserts that a specified handler returns a
|
||||
// body that does not contain a string.
|
||||
//
|
||||
// assert.HTTPBodyNotContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky")
|
||||
// assert.HTTPBodyNotContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool {
|
||||
@ -158,7 +155,7 @@ func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method, url strin
|
||||
|
||||
contains := strings.Contains(body, fmt.Sprint(str))
|
||||
if contains {
|
||||
Fail(t, fmt.Sprintf("Expected response body for %q to NOT contain %q but found %q", url+"?"+values.Encode(), str, body), msgAndArgs...)
|
||||
Fail(t, fmt.Sprintf("Expected response body for \"%s\" to NOT contain \"%s\" but found \"%s\"", url+"?"+values.Encode(), str, body))
|
||||
}
|
||||
|
||||
return !contains
|
||||
|
@ -2,7 +2,6 @@ package assert
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"testing"
|
||||
@ -12,12 +11,6 @@ func httpOK(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func httpReadBody(w http.ResponseWriter, r *http.Request) {
|
||||
_, _ = io.Copy(io.Discard, r.Body)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
_, _ = w.Write([]byte("hello"))
|
||||
}
|
||||
|
||||
func httpRedirect(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusTemporaryRedirect)
|
||||
}
|
||||
@ -31,8 +24,6 @@ func httpStatusCode(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func TestHTTPSuccess(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(t)
|
||||
|
||||
mockT1 := new(testing.T)
|
||||
@ -43,35 +34,21 @@ func TestHTTPSuccess(t *testing.T) {
|
||||
assert.Equal(HTTPSuccess(mockT2, httpRedirect, "GET", "/", nil), false)
|
||||
assert.True(mockT2.Failed())
|
||||
|
||||
mockT3 := new(mockTestingT)
|
||||
assert.Equal(HTTPSuccess(
|
||||
mockT3, httpError, "GET", "/", nil,
|
||||
"was not expecting a failure here",
|
||||
), false)
|
||||
mockT3 := new(testing.T)
|
||||
assert.Equal(HTTPSuccess(mockT3, httpError, "GET", "/", nil), false)
|
||||
assert.True(mockT3.Failed())
|
||||
assert.Contains(mockT3.errorString(), "was not expecting a failure here")
|
||||
|
||||
mockT4 := new(testing.T)
|
||||
assert.Equal(HTTPSuccess(mockT4, httpStatusCode, "GET", "/", nil), false)
|
||||
assert.True(mockT4.Failed())
|
||||
|
||||
mockT5 := new(testing.T)
|
||||
assert.Equal(HTTPSuccess(mockT5, httpReadBody, "POST", "/", nil), true)
|
||||
assert.False(mockT5.Failed())
|
||||
}
|
||||
|
||||
func TestHTTPRedirect(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(t)
|
||||
|
||||
mockT1 := new(mockTestingT)
|
||||
assert.Equal(HTTPRedirect(
|
||||
mockT1, httpOK, "GET", "/", nil,
|
||||
"was expecting a 3xx status code. Got 200.",
|
||||
), false)
|
||||
mockT1 := new(testing.T)
|
||||
assert.Equal(HTTPRedirect(mockT1, httpOK, "GET", "/", nil), false)
|
||||
assert.True(mockT1.Failed())
|
||||
assert.Contains(mockT1.errorString(), "was expecting a 3xx status code. Got 200.")
|
||||
|
||||
mockT2 := new(testing.T)
|
||||
assert.Equal(HTTPRedirect(mockT2, httpRedirect, "GET", "/", nil), true)
|
||||
@ -87,21 +64,15 @@ func TestHTTPRedirect(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestHTTPError(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(t)
|
||||
|
||||
mockT1 := new(testing.T)
|
||||
assert.Equal(HTTPError(mockT1, httpOK, "GET", "/", nil), false)
|
||||
assert.True(mockT1.Failed())
|
||||
|
||||
mockT2 := new(mockTestingT)
|
||||
assert.Equal(HTTPError(
|
||||
mockT2, httpRedirect, "GET", "/", nil,
|
||||
"Expected this request to error out. But it didn't",
|
||||
), false)
|
||||
mockT2 := new(testing.T)
|
||||
assert.Equal(HTTPError(mockT2, httpRedirect, "GET", "/", nil), false)
|
||||
assert.True(mockT2.Failed())
|
||||
assert.Contains(mockT2.errorString(), "Expected this request to error out. But it didn't")
|
||||
|
||||
mockT3 := new(testing.T)
|
||||
assert.Equal(HTTPError(mockT3, httpError, "GET", "/", nil), true)
|
||||
@ -113,8 +84,6 @@ func TestHTTPError(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestHTTPStatusCode(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(t)
|
||||
|
||||
mockT1 := new(testing.T)
|
||||
@ -125,13 +94,9 @@ func TestHTTPStatusCode(t *testing.T) {
|
||||
assert.Equal(HTTPStatusCode(mockT2, httpRedirect, "GET", "/", nil, http.StatusSwitchingProtocols), false)
|
||||
assert.True(mockT2.Failed())
|
||||
|
||||
mockT3 := new(mockTestingT)
|
||||
assert.Equal(HTTPStatusCode(
|
||||
mockT3, httpError, "GET", "/", nil, http.StatusSwitchingProtocols,
|
||||
"Expected the status code to be %d", http.StatusSwitchingProtocols,
|
||||
), false)
|
||||
mockT3 := new(testing.T)
|
||||
assert.Equal(HTTPStatusCode(mockT3, httpError, "GET", "/", nil, http.StatusSwitchingProtocols), false)
|
||||
assert.True(mockT3.Failed())
|
||||
assert.Contains(mockT3.errorString(), "Expected the status code to be 101")
|
||||
|
||||
mockT4 := new(testing.T)
|
||||
assert.Equal(HTTPStatusCode(mockT4, httpStatusCode, "GET", "/", nil, http.StatusSwitchingProtocols), true)
|
||||
@ -139,8 +104,6 @@ func TestHTTPStatusCode(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestHTTPStatusesWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(t)
|
||||
mockAssert := New(new(testing.T))
|
||||
|
||||
@ -159,12 +122,10 @@ func TestHTTPStatusesWrapper(t *testing.T) {
|
||||
|
||||
func httpHelloName(w http.ResponseWriter, r *http.Request) {
|
||||
name := r.FormValue("name")
|
||||
_, _ = fmt.Fprintf(w, "Hello, %s!", name)
|
||||
_, _ = w.Write([]byte(fmt.Sprintf("Hello, %s!", name)))
|
||||
}
|
||||
|
||||
func TestHTTPRequestWithNoParams(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var got *http.Request
|
||||
handler := func(w http.ResponseWriter, r *http.Request) {
|
||||
got = r
|
||||
@ -178,8 +139,6 @@ func TestHTTPRequestWithNoParams(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestHTTPRequestWithParams(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var got *http.Request
|
||||
handler := func(w http.ResponseWriter, r *http.Request) {
|
||||
got = r
|
||||
@ -196,29 +155,19 @@ func TestHTTPRequestWithParams(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestHttpBody(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(t)
|
||||
mockT := new(mockTestingT)
|
||||
mockT := new(testing.T)
|
||||
|
||||
assert.True(HTTPBodyContains(mockT, httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "Hello, World!"))
|
||||
assert.True(HTTPBodyContains(mockT, httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "World"))
|
||||
assert.False(HTTPBodyContains(mockT, httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "world"))
|
||||
|
||||
assert.False(HTTPBodyNotContains(mockT, httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "Hello, World!"))
|
||||
assert.False(HTTPBodyNotContains(
|
||||
mockT, httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "World",
|
||||
"Expected the request body to not contain 'World'. But it did.",
|
||||
))
|
||||
assert.False(HTTPBodyNotContains(mockT, httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "World"))
|
||||
assert.True(HTTPBodyNotContains(mockT, httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "world"))
|
||||
assert.Contains(mockT.errorString(), "Expected the request body to not contain 'World'. But it did.")
|
||||
|
||||
assert.True(HTTPBodyContains(mockT, httpReadBody, "GET", "/", nil, "hello"))
|
||||
}
|
||||
|
||||
func TestHttpBodyWrappers(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := New(t)
|
||||
mockAssert := New(new(testing.T))
|
||||
|
||||
@ -229,4 +178,5 @@ func TestHttpBodyWrappers(t *testing.T) {
|
||||
assert.False(mockAssert.HTTPBodyNotContains(httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "Hello, World!"))
|
||||
assert.False(mockAssert.HTTPBodyNotContains(httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "World"))
|
||||
assert.True(mockAssert.HTTPBodyNotContains(httpHelloName, "GET", "/", url.Values{"name": []string{"World"}}, "world"))
|
||||
|
||||
}
|
||||
|
@ -1,4 +0,0 @@
|
||||
// This package exists just to isolate tests that reference the [unsafe] package.
|
||||
//
|
||||
// The tests in this package are totally safe.
|
||||
package unsafetests
|
@ -1,34 +0,0 @@
|
||||
package unsafetests_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
"unsafe"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
type ignoreTestingT struct{}
|
||||
|
||||
var _ assert.TestingT = ignoreTestingT{}
|
||||
|
||||
func (ignoreTestingT) Helper() {}
|
||||
|
||||
func (ignoreTestingT) Errorf(format string, args ...interface{}) {
|
||||
// Run the formatting, but ignore the result
|
||||
msg := fmt.Sprintf(format, args...)
|
||||
_ = msg
|
||||
}
|
||||
|
||||
func TestUnsafePointers(t *testing.T) {
|
||||
var ignore ignoreTestingT
|
||||
|
||||
assert.True(t, assert.Nil(t, unsafe.Pointer(nil), "unsafe.Pointer(nil) is nil"))
|
||||
assert.False(t, assert.NotNil(ignore, unsafe.Pointer(nil), "unsafe.Pointer(nil) is nil"))
|
||||
|
||||
assert.True(t, assert.Nil(t, unsafe.Pointer((*int)(nil)), "unsafe.Pointer((*int)(nil)) is nil"))
|
||||
assert.False(t, assert.NotNil(ignore, unsafe.Pointer((*int)(nil)), "unsafe.Pointer((*int)(nil)) is nil"))
|
||||
|
||||
assert.False(t, assert.Nil(ignore, unsafe.Pointer(new(int)), "unsafe.Pointer(new(int)) is NOT nil"))
|
||||
assert.True(t, assert.NotNil(t, unsafe.Pointer(new(int)), "unsafe.Pointer(new(int)) is NOT nil"))
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
//go:build testify_yaml_custom && !testify_yaml_fail && !testify_yaml_default
|
||||
|
||||
// Package yaml is an implementation of YAML functions that calls a pluggable implementation.
|
||||
//
|
||||
// This implementation is selected with the testify_yaml_custom build tag.
|
||||
//
|
||||
// go test -tags testify_yaml_custom
|
||||
//
|
||||
// This implementation can be used at build time to replace the default implementation
|
||||
// to avoid linking with [gopkg.in/yaml.v3].
|
||||
//
|
||||
// In your test package:
|
||||
//
|
||||
// import assertYaml "github.com/stretchr/testify/assert/yaml"
|
||||
//
|
||||
// func init() {
|
||||
// assertYaml.Unmarshal = func (in []byte, out interface{}) error {
|
||||
// // ...
|
||||
// return nil
|
||||
// }
|
||||
// }
|
||||
package yaml
|
||||
|
||||
var Unmarshal func(in []byte, out interface{}) error
|
@ -1,36 +0,0 @@
|
||||
//go:build !testify_yaml_fail && !testify_yaml_custom
|
||||
|
||||
// Package yaml is just an indirection to handle YAML deserialization.
|
||||
//
|
||||
// This package is just an indirection that allows the builder to override the
|
||||
// indirection with an alternative implementation of this package that uses
|
||||
// another implementation of YAML deserialization. This allows to not either not
|
||||
// use YAML deserialization at all, or to use another implementation than
|
||||
// [gopkg.in/yaml.v3] (for example for license compatibility reasons, see [PR #1120]).
|
||||
//
|
||||
// Alternative implementations are selected using build tags:
|
||||
//
|
||||
// - testify_yaml_fail: [Unmarshal] always fails with an error
|
||||
// - testify_yaml_custom: [Unmarshal] is a variable. Caller must initialize it
|
||||
// before calling any of [github.com/stretchr/testify/assert.YAMLEq] or
|
||||
// [github.com/stretchr/testify/assert.YAMLEqf].
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// go test -tags testify_yaml_fail
|
||||
//
|
||||
// You can check with "go list" which implementation is linked:
|
||||
//
|
||||
// go list -f '{{.Imports}}' github.com/stretchr/testify/assert/yaml
|
||||
// go list -tags testify_yaml_fail -f '{{.Imports}}' github.com/stretchr/testify/assert/yaml
|
||||
// go list -tags testify_yaml_custom -f '{{.Imports}}' github.com/stretchr/testify/assert/yaml
|
||||
//
|
||||
// [PR #1120]: https://github.com/stretchr/testify/pull/1120
|
||||
package yaml
|
||||
|
||||
import goyaml "gopkg.in/yaml.v3"
|
||||
|
||||
// Unmarshal is just a wrapper of [gopkg.in/yaml.v3.Unmarshal].
|
||||
func Unmarshal(in []byte, out interface{}) error {
|
||||
return goyaml.Unmarshal(in, out)
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
//go:build testify_yaml_fail && !testify_yaml_custom && !testify_yaml_default
|
||||
|
||||
// Package yaml is an implementation of YAML functions that always fail.
|
||||
//
|
||||
// This implementation can be used at build time to replace the default implementation
|
||||
// to avoid linking with [gopkg.in/yaml.v3]:
|
||||
//
|
||||
// go test -tags testify_yaml_fail
|
||||
package yaml
|
||||
|
||||
import "errors"
|
||||
|
||||
var errNotImplemented = errors.New("YAML functions are not available (see https://pkg.go.dev/github.com/stretchr/testify/assert/yaml)")
|
||||
|
||||
func Unmarshal([]byte, interface{}) error {
|
||||
return errNotImplemented
|
||||
}
|
28
doc.go
28
doc.go
@ -1,17 +1,23 @@
|
||||
// Module testify is a set of packages that provide many tools for testifying that your code will behave as you intend.
|
||||
// ** We are working on testify v2 and would love to hear what you'd like to see in it, have your say here: https://cutt.ly/testify **
|
||||
// Package testify is a set of packages that provide many tools for testifying that your code will behave as you intend.
|
||||
//
|
||||
// Testify contains the following packages:
|
||||
// testify contains the following packages:
|
||||
//
|
||||
// The [github.com/stretchr/testify/assert] package provides a comprehensive set of assertion functions that tie in to [the Go testing system].
|
||||
// The [github.com/stretchr/testify/require] package provides the same assertions but as fatal checks.
|
||||
// The assert package provides a comprehensive set of assertion functions that tie in to the Go testing system.
|
||||
//
|
||||
// The [github.com/stretchr/testify/mock] package provides a system by which it is possible to mock your objects and verify calls are happening as expected.
|
||||
// The http package contains tools to make it easier to test http activity using the Go testing system.
|
||||
//
|
||||
// The [github.com/stretchr/testify/suite] package provides a basic structure for using structs as testing suites, and methods on those structs as tests. It includes setup/teardown functionality in the way of interfaces.
|
||||
// The mock package provides a system by which it is possible to mock your objects and verify calls are happening as expected.
|
||||
//
|
||||
// A [golangci-lint] compatible linter for testify is available called [testifylint].
|
||||
//
|
||||
// [the Go testing system]: https://go.dev/doc/code#Testing
|
||||
// [golangci-lint]: https://golangci-lint.run/
|
||||
// [testifylint]: https://github.com/Antonboom/testifylint
|
||||
// The suite package provides a basic structure for using structs as testing suites, and methods on those structs as tests. It includes setup/teardown functionality in the way of interfaces.
|
||||
package testify
|
||||
|
||||
// blank imports help docs.
|
||||
import (
|
||||
// assert package
|
||||
_ "github.com/stretchr/testify/assert"
|
||||
// http package
|
||||
_ "github.com/stretchr/testify/http"
|
||||
// mock package
|
||||
_ "github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
10
go.mod
10
go.mod
@ -1,16 +1,10 @@
|
||||
module github.com/stretchr/testify
|
||||
|
||||
// This should match the minimum supported version that is tested in
|
||||
// .github/workflows/main.yml
|
||||
go 1.17
|
||||
go 1.13
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
github.com/pmezard/go-difflib v1.0.0
|
||||
github.com/stretchr/objx v0.5.2 // To avoid a cycle the version of testify used by objx should be excluded below
|
||||
github.com/stretchr/objx v0.4.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
|
||||
// Break dependency cycle with objx.
|
||||
// See https://github.com/stretchr/objx/pull/140
|
||||
exclude github.com/stretchr/testify v1.8.4
|
||||
|
8
go.sum
8
go.sum
@ -1,10 +1,14 @@
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
@ -1,2 +1,2 @@
|
||||
// Deprecated: Use [net/http/httptest] instead.
|
||||
// Package http DEPRECATED USE net/http/httptest
|
||||
package http
|
||||
|
@ -4,7 +4,7 @@ import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// Deprecated: Use [net/http/httptest] instead.
|
||||
// TestResponseWriter DEPRECATED: We recommend you use http://golang.org/pkg/net/http/httptest instead.
|
||||
type TestResponseWriter struct {
|
||||
|
||||
// StatusCode is the last int written by the call to WriteHeader(int)
|
||||
@ -17,7 +17,7 @@ type TestResponseWriter struct {
|
||||
header http.Header
|
||||
}
|
||||
|
||||
// Deprecated: Use [net/http/httptest] instead.
|
||||
// Header DEPRECATED: We recommend you use http://golang.org/pkg/net/http/httptest instead.
|
||||
func (rw *TestResponseWriter) Header() http.Header {
|
||||
|
||||
if rw.header == nil {
|
||||
@ -27,7 +27,7 @@ func (rw *TestResponseWriter) Header() http.Header {
|
||||
return rw.header
|
||||
}
|
||||
|
||||
// Deprecated: Use [net/http/httptest] instead.
|
||||
// Write DEPRECATED: We recommend you use http://golang.org/pkg/net/http/httptest instead.
|
||||
func (rw *TestResponseWriter) Write(bytes []byte) (int, error) {
|
||||
|
||||
// assume 200 success if no header has been set
|
||||
@ -43,7 +43,7 @@ func (rw *TestResponseWriter) Write(bytes []byte) (int, error) {
|
||||
|
||||
}
|
||||
|
||||
// Deprecated: Use [net/http/httptest] instead.
|
||||
// WriteHeader DEPRECATED: We recommend you use http://golang.org/pkg/net/http/httptest instead.
|
||||
func (rw *TestResponseWriter) WriteHeader(i int) {
|
||||
rw.StatusCode = i
|
||||
}
|
||||
|
@ -6,12 +6,12 @@ import (
|
||||
"github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
||||
// Deprecated: Use [net/http/httptest] instead.
|
||||
// TestRoundTripper DEPRECATED USE net/http/httptest
|
||||
type TestRoundTripper struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// Deprecated: Use [net/http/httptest] instead.
|
||||
// RoundTrip DEPRECATED USE net/http/httptest
|
||||
func (t *TestRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
args := t.Called(req)
|
||||
return args.Get(0).(*http.Response), args.Error(1)
|
||||
|
30
mock/doc.go
30
mock/doc.go
@ -1,17 +1,17 @@
|
||||
// Package mock provides a system by which it is possible to mock your objects
|
||||
// and verify calls are happening as expected.
|
||||
//
|
||||
// # Example Usage
|
||||
// Example Usage
|
||||
//
|
||||
// The mock package provides an object, Mock, that tracks activity on another object. It is usually
|
||||
// embedded into a test object as shown below:
|
||||
//
|
||||
// type MyTestObject struct {
|
||||
// // add a Mock object instance
|
||||
// mock.Mock
|
||||
// type MyTestObject struct {
|
||||
// // add a Mock object instance
|
||||
// mock.Mock
|
||||
//
|
||||
// // other fields go here as normal
|
||||
// }
|
||||
// // other fields go here as normal
|
||||
// }
|
||||
//
|
||||
// When implementing the methods of an interface, you wire your functions up
|
||||
// to call the Mock.Called(args...) method, and return the appropriate values.
|
||||
@ -19,25 +19,25 @@
|
||||
// For example, to mock a method that saves the name and age of a person and returns
|
||||
// the year of their birth or an error, you might write this:
|
||||
//
|
||||
// func (o *MyTestObject) SavePersonDetails(firstname, lastname string, age int) (int, error) {
|
||||
// args := o.Called(firstname, lastname, age)
|
||||
// return args.Int(0), args.Error(1)
|
||||
// }
|
||||
// func (o *MyTestObject) SavePersonDetails(firstname, lastname string, age int) (int, error) {
|
||||
// args := o.Called(firstname, lastname, age)
|
||||
// return args.Int(0), args.Error(1)
|
||||
// }
|
||||
//
|
||||
// The Int, Error and Bool methods are examples of strongly typed getters that take the argument
|
||||
// index position. Given this argument list:
|
||||
//
|
||||
// (12, true, "Something")
|
||||
// (12, true, "Something")
|
||||
//
|
||||
// You could read them out strongly typed like this:
|
||||
//
|
||||
// args.Int(0)
|
||||
// args.Bool(1)
|
||||
// args.String(2)
|
||||
// args.Int(0)
|
||||
// args.Bool(1)
|
||||
// args.String(2)
|
||||
//
|
||||
// For objects of your own type, use the generic Arguments.Get(index) method and make a type assertion:
|
||||
//
|
||||
// return args.Get(0).(*MyObject), args.Get(1).(*AnotherObjectOfMine)
|
||||
// return args.Get(0).(*MyObject), args.Get(1).(*AnotherObjectOfMine)
|
||||
//
|
||||
// This may cause a panic if the object you are getting is nil (the type assertion will fail), in those
|
||||
// cases you should check for nil first.
|
||||
|
534
mock/mock.go
534
mock/mock.go
@ -3,7 +3,6 @@ package mock
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"path"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"runtime"
|
||||
@ -14,13 +13,9 @@ import (
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/pmezard/go-difflib/difflib"
|
||||
"github.com/stretchr/objx"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
// regex for GCCGO functions
|
||||
var gccgoRE = regexp.MustCompile(`\.pN\d+_`)
|
||||
|
||||
// TestingT is an interface wrapper around *testing.T
|
||||
type TestingT interface {
|
||||
Logf(format string, args ...interface{})
|
||||
@ -75,17 +70,14 @@ type Call struct {
|
||||
// if the PanicMsg is set to a non nil string the function call will panic
|
||||
// irrespective of other settings
|
||||
PanicMsg *string
|
||||
|
||||
// Calls which must be satisfied before this call can be
|
||||
requires []*Call
|
||||
}
|
||||
|
||||
func newCall(parent *Mock, methodName string, callerInfo []string, methodArguments Arguments, returnArguments Arguments) *Call {
|
||||
func newCall(parent *Mock, methodName string, callerInfo []string, methodArguments ...interface{}) *Call {
|
||||
return &Call{
|
||||
Parent: parent,
|
||||
Method: methodName,
|
||||
Arguments: methodArguments,
|
||||
ReturnArguments: returnArguments,
|
||||
ReturnArguments: make([]interface{}, 0),
|
||||
callerInfo: callerInfo,
|
||||
Repeatability: 0,
|
||||
WaitFor: nil,
|
||||
@ -104,7 +96,7 @@ func (c *Call) unlock() {
|
||||
|
||||
// Return specifies the return arguments for the expectation.
|
||||
//
|
||||
// Mock.On("DoSomething").Return(errors.New("failed"))
|
||||
// Mock.On("DoSomething").Return(errors.New("failed"))
|
||||
func (c *Call) Return(returnArguments ...interface{}) *Call {
|
||||
c.lock()
|
||||
defer c.unlock()
|
||||
@ -114,9 +106,9 @@ func (c *Call) Return(returnArguments ...interface{}) *Call {
|
||||
return c
|
||||
}
|
||||
|
||||
// Panic specifies if the function call should fail and the panic message
|
||||
// Panic specifies if the functon call should fail and the panic message
|
||||
//
|
||||
// Mock.On("DoSomething").Panic("test panic")
|
||||
// Mock.On("DoSomething").Panic("test panic")
|
||||
func (c *Call) Panic(msg string) *Call {
|
||||
c.lock()
|
||||
defer c.unlock()
|
||||
@ -126,24 +118,24 @@ func (c *Call) Panic(msg string) *Call {
|
||||
return c
|
||||
}
|
||||
|
||||
// Once indicates that the mock should only return the value once.
|
||||
// Once indicates that that the mock should only return the value once.
|
||||
//
|
||||
// Mock.On("MyMethod", arg1, arg2).Return(returnArg1, returnArg2).Once()
|
||||
// Mock.On("MyMethod", arg1, arg2).Return(returnArg1, returnArg2).Once()
|
||||
func (c *Call) Once() *Call {
|
||||
return c.Times(1)
|
||||
}
|
||||
|
||||
// Twice indicates that the mock should only return the value twice.
|
||||
// Twice indicates that that the mock should only return the value twice.
|
||||
//
|
||||
// Mock.On("MyMethod", arg1, arg2).Return(returnArg1, returnArg2).Twice()
|
||||
// Mock.On("MyMethod", arg1, arg2).Return(returnArg1, returnArg2).Twice()
|
||||
func (c *Call) Twice() *Call {
|
||||
return c.Times(2)
|
||||
}
|
||||
|
||||
// Times indicates that the mock should only return the indicated number
|
||||
// Times indicates that that the mock should only return the indicated number
|
||||
// of times.
|
||||
//
|
||||
// Mock.On("MyMethod", arg1, arg2).Return(returnArg1, returnArg2).Times(5)
|
||||
// Mock.On("MyMethod", arg1, arg2).Return(returnArg1, returnArg2).Times(5)
|
||||
func (c *Call) Times(i int) *Call {
|
||||
c.lock()
|
||||
defer c.unlock()
|
||||
@ -154,7 +146,7 @@ func (c *Call) Times(i int) *Call {
|
||||
// WaitUntil sets the channel that will block the mock's return until its closed
|
||||
// or a message is received.
|
||||
//
|
||||
// Mock.On("MyMethod", arg1, arg2).WaitUntil(time.After(time.Second))
|
||||
// Mock.On("MyMethod", arg1, arg2).WaitUntil(time.After(time.Second))
|
||||
func (c *Call) WaitUntil(w <-chan time.Time) *Call {
|
||||
c.lock()
|
||||
defer c.unlock()
|
||||
@ -164,7 +156,7 @@ func (c *Call) WaitUntil(w <-chan time.Time) *Call {
|
||||
|
||||
// After sets how long to block until the call returns
|
||||
//
|
||||
// Mock.On("MyMethod", arg1, arg2).After(time.Second)
|
||||
// Mock.On("MyMethod", arg1, arg2).After(time.Second)
|
||||
func (c *Call) After(d time.Duration) *Call {
|
||||
c.lock()
|
||||
defer c.unlock()
|
||||
@ -176,10 +168,10 @@ func (c *Call) After(d time.Duration) *Call {
|
||||
// mocking a method (such as an unmarshaler) that takes a pointer to a struct and
|
||||
// sets properties in such struct
|
||||
//
|
||||
// Mock.On("Unmarshal", AnythingOfType("*map[string]interface{}")).Return().Run(func(args Arguments) {
|
||||
// arg := args.Get(0).(*map[string]interface{})
|
||||
// arg["foo"] = "bar"
|
||||
// })
|
||||
// Mock.On("Unmarshal", AnythingOfType("*map[string]interface{}")).Return().Run(func(args Arguments) {
|
||||
// arg := args.Get(0).(*map[string]interface{})
|
||||
// arg["foo"] = "bar"
|
||||
// })
|
||||
func (c *Call) Run(fn func(args Arguments)) *Call {
|
||||
c.lock()
|
||||
defer c.unlock()
|
||||
@ -199,101 +191,14 @@ func (c *Call) Maybe() *Call {
|
||||
// On chains a new expectation description onto the mocked interface. This
|
||||
// allows syntax like.
|
||||
//
|
||||
// Mock.
|
||||
// On("MyMethod", 1).Return(nil).
|
||||
// On("MyOtherMethod", 'a', 'b', 'c').Return(errors.New("Some Error"))
|
||||
//
|
||||
// Mock.
|
||||
// On("MyMethod", 1).Return(nil).
|
||||
// On("MyOtherMethod", 'a', 'b', 'c').Return(errors.New("Some Error"))
|
||||
//go:noinline
|
||||
func (c *Call) On(methodName string, arguments ...interface{}) *Call {
|
||||
return c.Parent.On(methodName, arguments...)
|
||||
}
|
||||
|
||||
// Unset removes all mock handlers that satisfy the call instance arguments from being
|
||||
// called. Only supported on call instances with static input arguments.
|
||||
//
|
||||
// For example, the only handler remaining after the following would be "MyMethod(2, 2)":
|
||||
//
|
||||
// Mock.
|
||||
// On("MyMethod", 2, 2).Return(0).
|
||||
// On("MyMethod", 3, 3).Return(0).
|
||||
// On("MyMethod", Anything, Anything).Return(0)
|
||||
// Mock.On("MyMethod", 3, 3).Unset()
|
||||
func (c *Call) Unset() *Call {
|
||||
var unlockOnce sync.Once
|
||||
|
||||
for _, arg := range c.Arguments {
|
||||
if v := reflect.ValueOf(arg); v.Kind() == reflect.Func {
|
||||
panic(fmt.Sprintf("cannot use Func in expectations. Use mock.AnythingOfType(\"%T\")", arg))
|
||||
}
|
||||
}
|
||||
|
||||
c.lock()
|
||||
defer unlockOnce.Do(c.unlock)
|
||||
|
||||
foundMatchingCall := false
|
||||
|
||||
// in-place filter slice for calls to be removed - iterate from 0'th to last skipping unnecessary ones
|
||||
var index int // write index
|
||||
for _, call := range c.Parent.ExpectedCalls {
|
||||
if call.Method == c.Method {
|
||||
_, diffCount := call.Arguments.Diff(c.Arguments)
|
||||
if diffCount == 0 {
|
||||
foundMatchingCall = true
|
||||
// Remove from ExpectedCalls - just skip it
|
||||
continue
|
||||
}
|
||||
}
|
||||
c.Parent.ExpectedCalls[index] = call
|
||||
index++
|
||||
}
|
||||
// trim slice up to last copied index
|
||||
c.Parent.ExpectedCalls = c.Parent.ExpectedCalls[:index]
|
||||
|
||||
if !foundMatchingCall {
|
||||
unlockOnce.Do(c.unlock)
|
||||
c.Parent.fail("\n\nmock: Could not find expected call\n-----------------------------\n\n%s\n\n",
|
||||
callString(c.Method, c.Arguments, true),
|
||||
)
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
// NotBefore indicates that the mock should only be called after the referenced
|
||||
// calls have been called as expected. The referenced calls may be from the
|
||||
// same mock instance and/or other mock instances.
|
||||
//
|
||||
// Mock.On("Do").Return(nil).NotBefore(
|
||||
// Mock.On("Init").Return(nil)
|
||||
// )
|
||||
func (c *Call) NotBefore(calls ...*Call) *Call {
|
||||
c.lock()
|
||||
defer c.unlock()
|
||||
|
||||
for _, call := range calls {
|
||||
if call.Parent == nil {
|
||||
panic("not before calls must be created with Mock.On()")
|
||||
}
|
||||
}
|
||||
|
||||
c.requires = append(c.requires, calls...)
|
||||
return c
|
||||
}
|
||||
|
||||
// InOrder defines the order in which the calls should be made
|
||||
//
|
||||
// For example:
|
||||
//
|
||||
// InOrder(
|
||||
// Mock.On("init").Return(nil),
|
||||
// Mock.On("Do").Return(nil),
|
||||
// )
|
||||
func InOrder(calls ...*Call) {
|
||||
for i := 1; i < len(calls); i++ {
|
||||
calls[i].NotBefore(calls[i-1])
|
||||
}
|
||||
}
|
||||
|
||||
// Mock is the workhorse used to track activity on another object.
|
||||
// For an example of its usage, refer to the "Example Usage" section at the top
|
||||
// of this document.
|
||||
@ -313,7 +218,7 @@ type Mock struct {
|
||||
// this data completely allowing you to do whatever you like with it.
|
||||
testData objx.Map
|
||||
|
||||
mutex sync.Mutex
|
||||
mutex *sync.Mutex
|
||||
}
|
||||
|
||||
// String provides a %v format string for Mock.
|
||||
@ -338,11 +243,12 @@ func (m *Mock) TestData() objx.Map {
|
||||
Setting expectations
|
||||
*/
|
||||
|
||||
// Test sets the [TestingT] on which errors will be reported, otherwise errors
|
||||
// will cause a panic.
|
||||
// Test should not be called on an object that is going to be used in a
|
||||
// goroutine other than the one running the test function.
|
||||
// Test sets the test struct variable of the mock object
|
||||
func (m *Mock) Test(t TestingT) {
|
||||
if m.mutex == nil {
|
||||
m.mutex = &sync.Mutex{}
|
||||
}
|
||||
|
||||
m.mutex.Lock()
|
||||
defer m.mutex.Unlock()
|
||||
m.test = t
|
||||
@ -365,7 +271,7 @@ func (m *Mock) fail(format string, args ...interface{}) {
|
||||
// On starts a description of an expectation of the specified method
|
||||
// being called.
|
||||
//
|
||||
// Mock.On("MyMethod", arg1, arg2)
|
||||
// Mock.On("MyMethod", arg1, arg2)
|
||||
func (m *Mock) On(methodName string, arguments ...interface{}) *Call {
|
||||
for _, arg := range arguments {
|
||||
if v := reflect.ValueOf(arg); v.Kind() == reflect.Func {
|
||||
@ -373,10 +279,12 @@ func (m *Mock) On(methodName string, arguments ...interface{}) *Call {
|
||||
}
|
||||
}
|
||||
|
||||
// Since we start mocks with the .On() function, m.mutex should be reset
|
||||
m.mutex = &sync.Mutex{}
|
||||
|
||||
m.mutex.Lock()
|
||||
defer m.mutex.Unlock()
|
||||
|
||||
c := newCall(m, methodName, assert.CallerInfo(), arguments, make([]interface{}, 0))
|
||||
c := newCall(m, methodName, assert.CallerInfo(), arguments...)
|
||||
m.ExpectedCalls = append(m.ExpectedCalls, c)
|
||||
return c
|
||||
}
|
||||
@ -456,10 +364,6 @@ func callString(method string, arguments Arguments, includeArgumentValues bool)
|
||||
if includeArgumentValues {
|
||||
var argVals []string
|
||||
for argIndex, arg := range arguments {
|
||||
if _, ok := arg.(*FunctionalOptionsArgument); ok {
|
||||
argVals = append(argVals, fmt.Sprintf("%d: %s", argIndex, arg))
|
||||
continue
|
||||
}
|
||||
argVals = append(argVals, fmt.Sprintf("%d: %#v", argIndex, arg))
|
||||
}
|
||||
argValsString = fmt.Sprintf("\n\t\t%s", strings.Join(argVals, "\n\t\t"))
|
||||
@ -483,8 +387,9 @@ func (m *Mock) Called(arguments ...interface{}) Arguments {
|
||||
// For Ex: github_com_docker_libkv_store_mock.WatchTree.pN39_github_com_docker_libkv_store_mock.Mock
|
||||
// uses interface information unlike golang github.com/docker/libkv/store/mock.(*Mock).WatchTree
|
||||
// With GCCGO we need to remove interface information starting from pN<dd>.
|
||||
if gccgoRE.MatchString(functionPath) {
|
||||
functionPath = gccgoRE.Split(functionPath, -1)[0]
|
||||
re := regexp.MustCompile("\\.pN\\d+_")
|
||||
if re.MatchString(functionPath) {
|
||||
functionPath = re.Split(functionPath, -1)[0]
|
||||
}
|
||||
parts := strings.Split(functionPath, ".")
|
||||
functionName := parts[len(parts)-1]
|
||||
@ -501,10 +406,10 @@ func (m *Mock) MethodCalled(methodName string, arguments ...interface{}) Argumen
|
||||
found, call := m.findExpectedCall(methodName, arguments...)
|
||||
|
||||
if found < 0 {
|
||||
// expected call found, but it has already been called with repeatable times
|
||||
// expected call found but it has already been called with repeatable times
|
||||
if call != nil {
|
||||
m.mutex.Unlock()
|
||||
m.fail("\nassert: mock: The method has been called over %d times.\n\tEither do one more Mock.On(%#v).Return(...), or remove extra call.\n\tThis call was unexpected:\n\t\t%s\n\tat: %s", call.totalCalls, methodName, callString(methodName, arguments, true), assert.CallerInfo())
|
||||
m.fail("\nassert: mock: The method has been called over %d times.\n\tEither do one more Mock.On(\"%s\").Return(...), or remove extra call.\n\tThis call was unexpected:\n\t\t%s\n\tat: %s", call.totalCalls, methodName, callString(methodName, arguments, true), assert.CallerInfo())
|
||||
}
|
||||
// we have to fail here - because we don't know what to do
|
||||
// as the return arguments. This is because:
|
||||
@ -516,34 +421,14 @@ func (m *Mock) MethodCalled(methodName string, arguments ...interface{}) Argumen
|
||||
m.mutex.Unlock()
|
||||
|
||||
if closestCall != nil {
|
||||
m.fail("\n\nmock: Unexpected Method Call\n-----------------------------\n\n%s\n\nThe closest call I have is: \n\n%s\n\n%s\nDiff: %s\nat: %s\n",
|
||||
m.fail("\n\nmock: Unexpected Method Call\n-----------------------------\n\n%s\n\nThe closest call I have is: \n\n%s\n\n%s\nDiff: %s",
|
||||
callString(methodName, arguments, true),
|
||||
callString(methodName, closestCall.Arguments, true),
|
||||
diffArguments(closestCall.Arguments, arguments),
|
||||
strings.TrimSpace(mismatch),
|
||||
assert.CallerInfo(),
|
||||
)
|
||||
} else {
|
||||
m.fail("\nassert: mock: I don't know what to return because the method call was unexpected.\n\tEither do Mock.On(%#v).Return(...) first, or remove the %s() call.\n\tThis method was unexpected:\n\t\t%s\n\tat: %s", methodName, methodName, callString(methodName, arguments, true), assert.CallerInfo())
|
||||
}
|
||||
}
|
||||
|
||||
for _, requirement := range call.requires {
|
||||
if satisfied, _ := requirement.Parent.checkExpectation(requirement); !satisfied {
|
||||
m.mutex.Unlock()
|
||||
m.fail("mock: Unexpected Method Call\n-----------------------------\n\n%s\n\nMust not be called before%s:\n\n%s",
|
||||
callString(call.Method, call.Arguments, true),
|
||||
func() (s string) {
|
||||
if requirement.totalCalls > 0 {
|
||||
s = " another call of"
|
||||
}
|
||||
if call.Parent != requirement.Parent {
|
||||
s += " method from another mock instance"
|
||||
}
|
||||
return
|
||||
}(),
|
||||
callString(requirement.Method, requirement.Arguments, true),
|
||||
)
|
||||
m.fail("\nassert: mock: I don't know what to return because the method call was unexpected.\n\tEither do Mock.On(\"%s\").Return(...) first, or remove the %s() call.\n\tThis method was unexpected:\n\t\t%s\n\tat: %s", methodName, methodName, callString(methodName, arguments, true), assert.CallerInfo())
|
||||
}
|
||||
}
|
||||
|
||||
@ -555,7 +440,7 @@ func (m *Mock) MethodCalled(methodName string, arguments ...interface{}) Argumen
|
||||
call.totalCalls++
|
||||
|
||||
// add the call
|
||||
m.Calls = append(m.Calls, *newCall(m, methodName, assert.CallerInfo(), arguments, call.ReturnArguments))
|
||||
m.Calls = append(m.Calls, *newCall(m, methodName, assert.CallerInfo(), arguments...))
|
||||
m.mutex.Unlock()
|
||||
|
||||
// block if specified
|
||||
@ -591,7 +476,7 @@ func (m *Mock) MethodCalled(methodName string, arguments ...interface{}) Argumen
|
||||
Assertions
|
||||
*/
|
||||
|
||||
type assertExpectationiser interface {
|
||||
type assertExpectationser interface {
|
||||
AssertExpectations(TestingT) bool
|
||||
}
|
||||
|
||||
@ -604,11 +489,11 @@ func AssertExpectationsForObjects(t TestingT, testObjects ...interface{}) bool {
|
||||
h.Helper()
|
||||
}
|
||||
for _, obj := range testObjects {
|
||||
if m, ok := obj.(*Mock); ok {
|
||||
if m, ok := obj.(Mock); ok {
|
||||
t.Logf("Deprecated mock.AssertExpectationsForObjects(myMock.Mock) use mock.AssertExpectationsForObjects(myMock)")
|
||||
obj = m
|
||||
obj = &m
|
||||
}
|
||||
m := obj.(assertExpectationiser)
|
||||
m := obj.(assertExpectationser)
|
||||
if !m.AssertExpectations(t) {
|
||||
t.Logf("Expectations didn't match for Mock: %+v", reflect.TypeOf(m))
|
||||
return false
|
||||
@ -620,42 +505,41 @@ func AssertExpectationsForObjects(t TestingT, testObjects ...interface{}) bool {
|
||||
// AssertExpectations asserts that everything specified with On and Return was
|
||||
// in fact called as expected. Calls may have occurred in any order.
|
||||
func (m *Mock) AssertExpectations(t TestingT) bool {
|
||||
if s, ok := t.(interface{ Skipped() bool }); ok && s.Skipped() {
|
||||
return true
|
||||
}
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
if m.mutex == nil {
|
||||
m.mutex = &sync.Mutex{}
|
||||
}
|
||||
|
||||
m.mutex.Lock()
|
||||
defer m.mutex.Unlock()
|
||||
var somethingMissing bool
|
||||
var failedExpectations int
|
||||
|
||||
// iterate through each expectation
|
||||
expectedCalls := m.expectedCalls()
|
||||
for _, expectedCall := range expectedCalls {
|
||||
satisfied, reason := m.checkExpectation(expectedCall)
|
||||
if !satisfied {
|
||||
if !expectedCall.optional && !m.methodWasCalled(expectedCall.Method, expectedCall.Arguments) && expectedCall.totalCalls == 0 {
|
||||
somethingMissing = true
|
||||
failedExpectations++
|
||||
t.Logf(reason)
|
||||
t.Logf("FAIL:\t%s(%s)\n\t\tat: %s", expectedCall.Method, expectedCall.Arguments.String(), expectedCall.callerInfo)
|
||||
} else {
|
||||
if expectedCall.Repeatability > 0 {
|
||||
somethingMissing = true
|
||||
failedExpectations++
|
||||
t.Logf("FAIL:\t%s(%s)\n\t\tat: %s", expectedCall.Method, expectedCall.Arguments.String(), expectedCall.callerInfo)
|
||||
} else {
|
||||
t.Logf("PASS:\t%s(%s)", expectedCall.Method, expectedCall.Arguments.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if failedExpectations != 0 {
|
||||
if somethingMissing {
|
||||
t.Errorf("FAIL: %d out of %d expectation(s) were met.\n\tThe code you are testing needs to make %d more call(s).\n\tat: %s", len(expectedCalls)-failedExpectations, len(expectedCalls), failedExpectations, assert.CallerInfo())
|
||||
}
|
||||
|
||||
return failedExpectations == 0
|
||||
}
|
||||
|
||||
func (m *Mock) checkExpectation(call *Call) (bool, string) {
|
||||
if !call.optional && !m.methodWasCalled(call.Method, call.Arguments) && call.totalCalls == 0 {
|
||||
return false, fmt.Sprintf("FAIL:\t%s(%s)\n\t\tat: %s", call.Method, call.Arguments.String(), call.callerInfo)
|
||||
}
|
||||
if call.Repeatability > 0 {
|
||||
return false, fmt.Sprintf("FAIL:\t%s(%s)\n\t\tat: %s", call.Method, call.Arguments.String(), call.callerInfo)
|
||||
}
|
||||
return true, fmt.Sprintf("PASS:\t%s(%s)", call.Method, call.Arguments.String())
|
||||
return !somethingMissing
|
||||
}
|
||||
|
||||
// AssertNumberOfCalls asserts that the method was called expectedCalls times.
|
||||
@ -671,7 +555,7 @@ func (m *Mock) AssertNumberOfCalls(t TestingT, methodName string, expectedCalls
|
||||
actualCalls++
|
||||
}
|
||||
}
|
||||
return assert.Equal(t, expectedCalls, actualCalls, fmt.Sprintf("Expected number of calls (%d) of method %s does not match the actual number of calls (%d).", expectedCalls, methodName, actualCalls))
|
||||
return assert.Equal(t, expectedCalls, actualCalls, fmt.Sprintf("Expected number of calls (%d) does not match the actual number of calls (%d).", expectedCalls, actualCalls))
|
||||
}
|
||||
|
||||
// AssertCalled asserts that the method was called.
|
||||
@ -789,80 +673,34 @@ const (
|
||||
Anything = "mock.Anything"
|
||||
)
|
||||
|
||||
// AnythingOfTypeArgument contains the type of an argument
|
||||
// for use when type checking. Used in [Arguments.Diff] and [Arguments.Assert].
|
||||
//
|
||||
// Deprecated: this is an implementation detail that must not be used. Use the [AnythingOfType] constructor instead, example:
|
||||
//
|
||||
// m.On("Do", mock.AnythingOfType("string"))
|
||||
//
|
||||
// All explicit type declarations can be replaced with interface{} as is expected by [Mock.On], example:
|
||||
//
|
||||
// func anyString interface{} {
|
||||
// return mock.AnythingOfType("string")
|
||||
// }
|
||||
type AnythingOfTypeArgument = anythingOfTypeArgument
|
||||
|
||||
// anythingOfTypeArgument is a string that contains the type of an argument
|
||||
// AnythingOfTypeArgument is a string that contains the type of an argument
|
||||
// for use when type checking. Used in Diff and Assert.
|
||||
type anythingOfTypeArgument string
|
||||
type AnythingOfTypeArgument string
|
||||
|
||||
// AnythingOfType returns a special value containing the
|
||||
// name of the type to check for. The type name will be matched against the type name returned by [reflect.Type.String].
|
||||
//
|
||||
// Used in Diff and Assert.
|
||||
// AnythingOfType returns an AnythingOfTypeArgument object containing the
|
||||
// name of the type to check for. Used in Diff and Assert.
|
||||
//
|
||||
// For example:
|
||||
//
|
||||
// args.Assert(t, AnythingOfType("string"), AnythingOfType("int"))
|
||||
// Assert(t, AnythingOfType("string"), AnythingOfType("int"))
|
||||
func AnythingOfType(t string) AnythingOfTypeArgument {
|
||||
return anythingOfTypeArgument(t)
|
||||
return AnythingOfTypeArgument(t)
|
||||
}
|
||||
|
||||
// IsTypeArgument is a struct that contains the type of an argument
|
||||
// for use when type checking. This is an alternative to [AnythingOfType].
|
||||
// Used in [Arguments.Diff] and [Arguments.Assert].
|
||||
// for use when type checking. This is an alternative to AnythingOfType.
|
||||
// Used in Diff and Assert.
|
||||
type IsTypeArgument struct {
|
||||
t reflect.Type
|
||||
t interface{}
|
||||
}
|
||||
|
||||
// IsType returns an IsTypeArgument object containing the type to check for.
|
||||
// You can provide a zero-value of the type to check. This is an
|
||||
// alternative to [AnythingOfType]. Used in [Arguments.Diff] and [Arguments.Assert].
|
||||
// alternative to AnythingOfType. Used in Diff and Assert.
|
||||
//
|
||||
// For example:
|
||||
//
|
||||
// args.Assert(t, IsType(""), IsType(0))
|
||||
// Assert(t, IsType(""), IsType(0))
|
||||
func IsType(t interface{}) *IsTypeArgument {
|
||||
return &IsTypeArgument{t: reflect.TypeOf(t)}
|
||||
}
|
||||
|
||||
// FunctionalOptionsArgument contains a list of functional options arguments
|
||||
// expected for use when matching a list of arguments.
|
||||
type FunctionalOptionsArgument struct {
|
||||
values []interface{}
|
||||
}
|
||||
|
||||
// String returns the string representation of FunctionalOptionsArgument
|
||||
func (f *FunctionalOptionsArgument) String() string {
|
||||
var name string
|
||||
if len(f.values) > 0 {
|
||||
name = "[]" + reflect.TypeOf(f.values[0]).String()
|
||||
}
|
||||
|
||||
return strings.Replace(fmt.Sprintf("%#v", f.values), "[]interface {}", name, 1)
|
||||
}
|
||||
|
||||
// FunctionalOptions returns an [FunctionalOptionsArgument] object containing
|
||||
// the expected functional-options to check for.
|
||||
//
|
||||
// For example:
|
||||
//
|
||||
// args.Assert(t, FunctionalOptions(foo.Opt1("strValue"), foo.Opt2(613)))
|
||||
func FunctionalOptions(values ...interface{}) *FunctionalOptionsArgument {
|
||||
return &FunctionalOptionsArgument{
|
||||
values: values,
|
||||
}
|
||||
return &IsTypeArgument{t: t}
|
||||
}
|
||||
|
||||
// argumentMatcher performs custom argument matching, returning whether or
|
||||
@ -908,11 +746,10 @@ func (f argumentMatcher) String() string {
|
||||
// and false otherwise.
|
||||
//
|
||||
// Example:
|
||||
// m.On("Do", MatchedBy(func(req *http.Request) bool { return req.Host == "example.com" }))
|
||||
//
|
||||
// m.On("Do", MatchedBy(func(req *http.Request) bool { return req.Host == "example.com" }))
|
||||
//
|
||||
// fn must be a function accepting a single argument (of the expected type)
|
||||
// which returns a bool. If fn doesn't match the required signature,
|
||||
// |fn|, must be a function accepting a single argument (of the expected type)
|
||||
// which returns a bool. If |fn| doesn't match the required signature,
|
||||
// MatchedBy() panics.
|
||||
func MatchedBy(fn interface{}) argumentMatcher {
|
||||
fnType := reflect.TypeOf(fn)
|
||||
@ -948,8 +785,6 @@ func (args Arguments) Is(objects ...interface{}) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
type outputRenderer func() string
|
||||
|
||||
// Diff gets a string describing the differences between the arguments
|
||||
// and the specified objects.
|
||||
//
|
||||
@ -957,7 +792,7 @@ type outputRenderer func() string
|
||||
func (args Arguments) Diff(objects []interface{}) (string, int) {
|
||||
// TODO: could return string as error and nil for No difference
|
||||
|
||||
var outputBuilder strings.Builder
|
||||
output := "\n"
|
||||
var differences int
|
||||
|
||||
maxArgCount := len(args)
|
||||
@ -965,118 +800,56 @@ func (args Arguments) Diff(objects []interface{}) (string, int) {
|
||||
maxArgCount = len(objects)
|
||||
}
|
||||
|
||||
outputRenderers := []outputRenderer{}
|
||||
|
||||
for i := 0; i < maxArgCount; i++ {
|
||||
i := i
|
||||
var actual, expected interface{}
|
||||
var actualFmt, expectedFmt func() string
|
||||
var actualFmt, expectedFmt string
|
||||
|
||||
if len(objects) <= i {
|
||||
actual = "(Missing)"
|
||||
actualFmt = func() string {
|
||||
return "(Missing)"
|
||||
}
|
||||
actualFmt = "(Missing)"
|
||||
} else {
|
||||
actual = objects[i]
|
||||
actualFmt = func() string {
|
||||
return fmt.Sprintf("(%[1]T=%[1]v)", actual)
|
||||
}
|
||||
actualFmt = fmt.Sprintf("(%[1]T=%[1]v)", actual)
|
||||
}
|
||||
|
||||
if len(args) <= i {
|
||||
expected = "(Missing)"
|
||||
expectedFmt = func() string {
|
||||
return "(Missing)"
|
||||
}
|
||||
expectedFmt = "(Missing)"
|
||||
} else {
|
||||
expected = args[i]
|
||||
expectedFmt = func() string {
|
||||
return fmt.Sprintf("(%[1]T=%[1]v)", expected)
|
||||
}
|
||||
expectedFmt = fmt.Sprintf("(%[1]T=%[1]v)", expected)
|
||||
}
|
||||
|
||||
if matcher, ok := expected.(argumentMatcher); ok {
|
||||
var matches bool
|
||||
func() {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
actualFmt = func() string {
|
||||
return fmt.Sprintf("panic in argument matcher: %v", r)
|
||||
}
|
||||
}
|
||||
}()
|
||||
matches = matcher.Matches(actual)
|
||||
}()
|
||||
if matches {
|
||||
outputRenderers = append(outputRenderers, func() string {
|
||||
return fmt.Sprintf("\t%d: PASS: %s matched by %s\n", i, actualFmt(), matcher)
|
||||
})
|
||||
if matcher.Matches(actual) {
|
||||
output = fmt.Sprintf("%s\t%d: PASS: %s matched by %s\n", output, i, actualFmt, matcher)
|
||||
} else {
|
||||
differences++
|
||||
outputRenderers = append(outputRenderers, func() string {
|
||||
return fmt.Sprintf("\t%d: FAIL: %s not matched by %s\n", i, actualFmt(), matcher)
|
||||
})
|
||||
output = fmt.Sprintf("%s\t%d: FAIL: %s not matched by %s\n", output, i, actualFmt, matcher)
|
||||
}
|
||||
} else if reflect.TypeOf(expected) == reflect.TypeOf((*AnythingOfTypeArgument)(nil)).Elem() {
|
||||
// type checking
|
||||
if reflect.TypeOf(actual).Name() != string(expected.(AnythingOfTypeArgument)) && reflect.TypeOf(actual).String() != string(expected.(AnythingOfTypeArgument)) {
|
||||
// not match
|
||||
differences++
|
||||
output = fmt.Sprintf("%s\t%d: FAIL: type %s != type %s - %s\n", output, i, expected, reflect.TypeOf(actual).Name(), actualFmt)
|
||||
}
|
||||
} else if reflect.TypeOf(expected) == reflect.TypeOf((*IsTypeArgument)(nil)) {
|
||||
t := expected.(*IsTypeArgument).t
|
||||
if reflect.TypeOf(t) != reflect.TypeOf(actual) {
|
||||
differences++
|
||||
output = fmt.Sprintf("%s\t%d: FAIL: type %s != type %s - %s\n", output, i, reflect.TypeOf(t).Name(), reflect.TypeOf(actual).Name(), actualFmt)
|
||||
}
|
||||
} else {
|
||||
switch expected := expected.(type) {
|
||||
case anythingOfTypeArgument:
|
||||
// type checking
|
||||
if reflect.TypeOf(actual).Name() != string(expected) && reflect.TypeOf(actual).String() != string(expected) {
|
||||
// not match
|
||||
differences++
|
||||
outputRenderers = append(outputRenderers, func() string {
|
||||
return fmt.Sprintf("\t%d: FAIL: type %s != type %s - %s\n", i, expected, reflect.TypeOf(actual).Name(), actualFmt())
|
||||
})
|
||||
}
|
||||
case *IsTypeArgument:
|
||||
actualT := reflect.TypeOf(actual)
|
||||
if actualT != expected.t {
|
||||
differences++
|
||||
outputRenderers = append(outputRenderers, func() string {
|
||||
return fmt.Sprintf("\t%d: FAIL: type %s != type %s - %s\n", i, expected.t.Name(), actualT.Name(), actualFmt())
|
||||
})
|
||||
}
|
||||
case *FunctionalOptionsArgument:
|
||||
var name string
|
||||
if len(expected.values) > 0 {
|
||||
name = "[]" + reflect.TypeOf(expected.values[0]).String()
|
||||
}
|
||||
// normal checking
|
||||
|
||||
const tName = "[]interface{}"
|
||||
if name != reflect.TypeOf(actual).String() && len(expected.values) != 0 {
|
||||
differences++
|
||||
outputRenderers = append(outputRenderers, func() string {
|
||||
return fmt.Sprintf("\t%d: FAIL: type %s != type %s - %s\n", i, tName, reflect.TypeOf(actual).Name(), actualFmt())
|
||||
})
|
||||
} else {
|
||||
if ef, af := assertOpts(expected.values, actual); ef == "" && af == "" {
|
||||
// match
|
||||
outputRenderers = append(outputRenderers, func() string {
|
||||
return fmt.Sprintf("\t%d: PASS: %s == %s\n", i, tName, tName)
|
||||
})
|
||||
} else {
|
||||
// not match
|
||||
differences++
|
||||
outputRenderers = append(outputRenderers, func() string {
|
||||
return fmt.Sprintf("\t%d: FAIL: %s != %s\n", i, af, ef)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
if assert.ObjectsAreEqual(expected, Anything) || assert.ObjectsAreEqual(actual, Anything) || assert.ObjectsAreEqual(actual, expected) {
|
||||
// match
|
||||
outputRenderers = append(outputRenderers, func() string {
|
||||
return fmt.Sprintf("\t%d: PASS: %s == %s\n", i, actualFmt(), expectedFmt())
|
||||
})
|
||||
} else {
|
||||
// not match
|
||||
differences++
|
||||
outputRenderers = append(outputRenderers, func() string {
|
||||
return fmt.Sprintf("\t%d: FAIL: %s != %s\n", i, actualFmt(), expectedFmt())
|
||||
})
|
||||
}
|
||||
if assert.ObjectsAreEqual(expected, Anything) || assert.ObjectsAreEqual(actual, Anything) || assert.ObjectsAreEqual(actual, expected) {
|
||||
// match
|
||||
output = fmt.Sprintf("%s\t%d: PASS: %s == %s\n", output, i, actualFmt, expectedFmt)
|
||||
} else {
|
||||
// not match
|
||||
differences++
|
||||
output = fmt.Sprintf("%s\t%d: FAIL: %s != %s\n", output, i, actualFmt, expectedFmt)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1086,12 +859,7 @@ func (args Arguments) Diff(objects []interface{}) (string, int) {
|
||||
return "No differences.", differences
|
||||
}
|
||||
|
||||
outputBuilder.WriteString("\n")
|
||||
for _, r := range outputRenderers {
|
||||
outputBuilder.WriteString(r())
|
||||
}
|
||||
|
||||
return outputBuilder.String(), differences
|
||||
return output, differences
|
||||
}
|
||||
|
||||
// Assert compares the arguments with the specified objects and fails if
|
||||
@ -1163,7 +931,7 @@ func (args Arguments) Error(index int) error {
|
||||
return nil
|
||||
}
|
||||
if s, ok = obj.(error); !ok {
|
||||
panic(fmt.Sprintf("assert: arguments: Error(%d) failed because object wasn't correct type: %v", index, obj))
|
||||
panic(fmt.Sprintf("assert: arguments: Error(%d) failed because object wasn't correct type: %v", index, args.Get(index)))
|
||||
}
|
||||
return s
|
||||
}
|
||||
@ -1248,89 +1016,3 @@ var spewConfig = spew.ConfigState{
|
||||
type tHelper interface {
|
||||
Helper()
|
||||
}
|
||||
|
||||
func assertOpts(expected, actual interface{}) (expectedFmt, actualFmt string) {
|
||||
expectedOpts := reflect.ValueOf(expected)
|
||||
actualOpts := reflect.ValueOf(actual)
|
||||
|
||||
var expectedFuncs []*runtime.Func
|
||||
var expectedNames []string
|
||||
for i := 0; i < expectedOpts.Len(); i++ {
|
||||
f := runtimeFunc(expectedOpts.Index(i).Interface())
|
||||
expectedFuncs = append(expectedFuncs, f)
|
||||
expectedNames = append(expectedNames, funcName(f))
|
||||
}
|
||||
var actualFuncs []*runtime.Func
|
||||
var actualNames []string
|
||||
for i := 0; i < actualOpts.Len(); i++ {
|
||||
f := runtimeFunc(actualOpts.Index(i).Interface())
|
||||
actualFuncs = append(actualFuncs, f)
|
||||
actualNames = append(actualNames, funcName(f))
|
||||
}
|
||||
|
||||
if expectedOpts.Len() != actualOpts.Len() {
|
||||
expectedFmt = fmt.Sprintf("%v", expectedNames)
|
||||
actualFmt = fmt.Sprintf("%v", actualNames)
|
||||
return
|
||||
}
|
||||
|
||||
for i := 0; i < expectedOpts.Len(); i++ {
|
||||
if !isFuncSame(expectedFuncs[i], actualFuncs[i]) {
|
||||
expectedFmt = expectedNames[i]
|
||||
actualFmt = actualNames[i]
|
||||
return
|
||||
}
|
||||
|
||||
expectedOpt := expectedOpts.Index(i).Interface()
|
||||
actualOpt := actualOpts.Index(i).Interface()
|
||||
|
||||
ot := reflect.TypeOf(expectedOpt)
|
||||
var expectedValues []reflect.Value
|
||||
var actualValues []reflect.Value
|
||||
if ot.NumIn() == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
for i := 0; i < ot.NumIn(); i++ {
|
||||
vt := ot.In(i).Elem()
|
||||
expectedValues = append(expectedValues, reflect.New(vt))
|
||||
actualValues = append(actualValues, reflect.New(vt))
|
||||
}
|
||||
|
||||
reflect.ValueOf(expectedOpt).Call(expectedValues)
|
||||
reflect.ValueOf(actualOpt).Call(actualValues)
|
||||
|
||||
for i := 0; i < ot.NumIn(); i++ {
|
||||
if expectedArg, actualArg := expectedValues[i].Interface(), actualValues[i].Interface(); !assert.ObjectsAreEqual(expectedArg, actualArg) {
|
||||
expectedFmt = fmt.Sprintf("%s(%T) -> %#v", expectedNames[i], expectedArg, expectedArg)
|
||||
actualFmt = fmt.Sprintf("%s(%T) -> %#v", expectedNames[i], actualArg, actualArg)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return "", ""
|
||||
}
|
||||
|
||||
func runtimeFunc(opt interface{}) *runtime.Func {
|
||||
return runtime.FuncForPC(reflect.ValueOf(opt).Pointer())
|
||||
}
|
||||
|
||||
func funcName(f *runtime.Func) string {
|
||||
name := f.Name()
|
||||
trimmed := strings.TrimSuffix(path.Base(name), path.Ext(name))
|
||||
splitted := strings.Split(trimmed, ".")
|
||||
|
||||
if len(splitted) == 0 {
|
||||
return trimmed
|
||||
}
|
||||
|
||||
return splitted[len(splitted)-1]
|
||||
}
|
||||
|
||||
func isFuncSame(f1, f2 *runtime.Func) bool {
|
||||
f1File, f1Loc := f1.FileLine(f1.Entry())
|
||||
f2File, f2Loc := f2.FileLine(f2.Entry())
|
||||
|
||||
return f1File == f2File && f1Loc == f2Loc
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,30 +1,27 @@
|
||||
// Package require implements the same assertions as the `assert` package but
|
||||
// stops test execution when a test fails.
|
||||
//
|
||||
// # Example Usage
|
||||
// Example Usage
|
||||
//
|
||||
// The following is a complete example using require in a standard test function:
|
||||
// import (
|
||||
// "testing"
|
||||
// "github.com/stretchr/testify/require"
|
||||
// )
|
||||
//
|
||||
// import (
|
||||
// "testing"
|
||||
// "github.com/stretchr/testify/require"
|
||||
// )
|
||||
// func TestSomething(t *testing.T) {
|
||||
//
|
||||
// func TestSomething(t *testing.T) {
|
||||
// var a string = "Hello"
|
||||
// var b string = "Hello"
|
||||
//
|
||||
// var a string = "Hello"
|
||||
// var b string = "Hello"
|
||||
// require.Equal(t, a, b, "The two words should be the same.")
|
||||
//
|
||||
// require.Equal(t, a, b, "The two words should be the same.")
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//
|
||||
// # Assertions
|
||||
// Assertions
|
||||
//
|
||||
// The `require` package have same global functions as in the `assert` package,
|
||||
// but instead of returning a boolean result they call `t.FailNow()`.
|
||||
// A consequence of this is that it must be called from the goroutine running
|
||||
// the test function, not from other goroutines created during the test.
|
||||
//
|
||||
// Every assertion function also takes an optional string message as the final argument,
|
||||
// allowing custom error messages to be appended to the message the assertion method outputs.
|
||||
|
@ -7,8 +7,6 @@ import (
|
||||
)
|
||||
|
||||
func TestImplementsWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require := New(t)
|
||||
|
||||
require.Implements((*AssertionTesterInterface)(nil), new(AssertionTesterConformingObject))
|
||||
@ -21,23 +19,7 @@ func TestImplementsWrapper(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsNotTypeWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require := New(t)
|
||||
require.IsNotType(new(AssertionTesterNonConformingObject), new(AssertionTesterConformingObject))
|
||||
|
||||
mockT := new(MockT)
|
||||
mockRequire := New(mockT)
|
||||
mockRequire.IsNotType(new(AssertionTesterConformingObject), new(AssertionTesterConformingObject))
|
||||
if !mockT.Failed {
|
||||
t.Error("Check should fail")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsTypeWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require := New(t)
|
||||
require.IsType(new(AssertionTesterConformingObject), new(AssertionTesterConformingObject))
|
||||
|
||||
@ -50,8 +32,6 @@ func TestIsTypeWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestEqualWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require := New(t)
|
||||
require.Equal(1, 1)
|
||||
|
||||
@ -64,8 +44,6 @@ func TestEqualWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNotEqualWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require := New(t)
|
||||
require.NotEqual(1, 2)
|
||||
|
||||
@ -78,8 +56,6 @@ func TestNotEqualWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestExactlyWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require := New(t)
|
||||
|
||||
a := float32(1)
|
||||
@ -97,8 +73,6 @@ func TestExactlyWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNotNilWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require := New(t)
|
||||
require.NotNil(t, new(AssertionTesterConformingObject))
|
||||
|
||||
@ -111,8 +85,6 @@ func TestNotNilWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNilWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require := New(t)
|
||||
require.Nil(nil)
|
||||
|
||||
@ -125,8 +97,6 @@ func TestNilWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestTrueWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require := New(t)
|
||||
require.True(true)
|
||||
|
||||
@ -139,8 +109,6 @@ func TestTrueWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestFalseWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require := New(t)
|
||||
require.False(false)
|
||||
|
||||
@ -153,8 +121,6 @@ func TestFalseWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestContainsWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require := New(t)
|
||||
require.Contains("Hello World", "Hello")
|
||||
|
||||
@ -167,8 +133,6 @@ func TestContainsWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNotContainsWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require := New(t)
|
||||
require.NotContains("Hello World", "Hello!")
|
||||
|
||||
@ -181,8 +145,6 @@ func TestNotContainsWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestPanicsWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require := New(t)
|
||||
require.Panics(func() {
|
||||
panic("Panic!")
|
||||
@ -197,8 +159,6 @@ func TestPanicsWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNotPanicsWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require := New(t)
|
||||
require.NotPanics(func() {})
|
||||
|
||||
@ -213,8 +173,6 @@ func TestNotPanicsWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNoErrorWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require := New(t)
|
||||
require.NoError(nil)
|
||||
|
||||
@ -227,8 +185,6 @@ func TestNoErrorWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestErrorWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require := New(t)
|
||||
require.Error(errors.New("some error"))
|
||||
|
||||
@ -241,8 +197,6 @@ func TestErrorWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestErrorContainsWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require := New(t)
|
||||
require.ErrorContains(errors.New("some error: another error"), "some error")
|
||||
|
||||
@ -255,8 +209,6 @@ func TestErrorContainsWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestEqualErrorWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require := New(t)
|
||||
require.EqualError(errors.New("some error"), "some error")
|
||||
|
||||
@ -269,8 +221,6 @@ func TestEqualErrorWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestEmptyWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require := New(t)
|
||||
require.Empty("")
|
||||
|
||||
@ -283,8 +233,6 @@ func TestEmptyWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNotEmptyWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require := New(t)
|
||||
require.NotEmpty("x")
|
||||
|
||||
@ -297,8 +245,6 @@ func TestNotEmptyWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestWithinDurationWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require := New(t)
|
||||
a := time.Now()
|
||||
b := a.Add(10 * time.Second)
|
||||
@ -314,8 +260,6 @@ func TestWithinDurationWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestInDeltaWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require := New(t)
|
||||
require.InDelta(1.001, 1, 0.01)
|
||||
|
||||
@ -328,8 +272,6 @@ func TestInDeltaWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestZeroWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require := New(t)
|
||||
require.Zero(0)
|
||||
|
||||
@ -342,8 +284,6 @@ func TestZeroWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNotZeroWrapper(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require := New(t)
|
||||
require.NotZero(1)
|
||||
|
||||
@ -356,8 +296,6 @@ func TestNotZeroWrapper(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestJSONEqWrapper_EqualSONString(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(MockT)
|
||||
mockRequire := New(mockT)
|
||||
|
||||
@ -368,8 +306,6 @@ func TestJSONEqWrapper_EqualSONString(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestJSONEqWrapper_EquivalentButNotEqual(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(MockT)
|
||||
mockRequire := New(mockT)
|
||||
|
||||
@ -380,8 +316,6 @@ func TestJSONEqWrapper_EquivalentButNotEqual(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestJSONEqWrapper_HashOfArraysAndHashes(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(MockT)
|
||||
mockRequire := New(mockT)
|
||||
|
||||
@ -393,8 +327,6 @@ func TestJSONEqWrapper_HashOfArraysAndHashes(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestJSONEqWrapper_Array(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(MockT)
|
||||
mockRequire := New(mockT)
|
||||
|
||||
@ -405,8 +337,6 @@ func TestJSONEqWrapper_Array(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestJSONEqWrapper_HashAndArrayNotEquivalent(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(MockT)
|
||||
mockRequire := New(mockT)
|
||||
|
||||
@ -417,8 +347,6 @@ func TestJSONEqWrapper_HashAndArrayNotEquivalent(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestJSONEqWrapper_HashesNotEquivalent(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(MockT)
|
||||
mockRequire := New(mockT)
|
||||
|
||||
@ -429,8 +357,6 @@ func TestJSONEqWrapper_HashesNotEquivalent(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestJSONEqWrapper_ActualIsNotJSON(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(MockT)
|
||||
mockRequire := New(mockT)
|
||||
|
||||
@ -441,8 +367,6 @@ func TestJSONEqWrapper_ActualIsNotJSON(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestJSONEqWrapper_ExpectedIsNotJSON(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(MockT)
|
||||
mockRequire := New(mockT)
|
||||
|
||||
@ -453,8 +377,6 @@ func TestJSONEqWrapper_ExpectedIsNotJSON(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestJSONEqWrapper_ExpectedAndActualNotJSON(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(MockT)
|
||||
mockRequire := New(mockT)
|
||||
|
||||
@ -465,8 +387,6 @@ func TestJSONEqWrapper_ExpectedAndActualNotJSON(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestJSONEqWrapper_ArraysOfDifferentOrder(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(MockT)
|
||||
mockRequire := New(mockT)
|
||||
|
||||
@ -477,8 +397,6 @@ func TestJSONEqWrapper_ArraysOfDifferentOrder(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestYAMLEqWrapper_EqualYAMLString(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(MockT)
|
||||
mockRequire := New(mockT)
|
||||
|
||||
@ -489,8 +407,6 @@ func TestYAMLEqWrapper_EqualYAMLString(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestYAMLEqWrapper_EquivalentButNotEqual(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(MockT)
|
||||
mockRequire := New(mockT)
|
||||
|
||||
@ -501,8 +417,6 @@ func TestYAMLEqWrapper_EquivalentButNotEqual(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestYAMLEqWrapper_HashOfArraysAndHashes(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(MockT)
|
||||
mockRequire := New(mockT)
|
||||
|
||||
@ -539,8 +453,6 @@ array:
|
||||
}
|
||||
|
||||
func TestYAMLEqWrapper_Array(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(MockT)
|
||||
mockRequire := New(mockT)
|
||||
|
||||
@ -551,8 +463,6 @@ func TestYAMLEqWrapper_Array(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestYAMLEqWrapper_HashAndArrayNotEquivalent(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(MockT)
|
||||
mockRequire := New(mockT)
|
||||
|
||||
@ -563,8 +473,6 @@ func TestYAMLEqWrapper_HashAndArrayNotEquivalent(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestYAMLEqWrapper_HashesNotEquivalent(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(MockT)
|
||||
mockRequire := New(mockT)
|
||||
|
||||
@ -575,8 +483,6 @@ func TestYAMLEqWrapper_HashesNotEquivalent(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestYAMLEqWrapper_ActualIsSimpleString(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(MockT)
|
||||
mockRequire := New(mockT)
|
||||
|
||||
@ -587,8 +493,6 @@ func TestYAMLEqWrapper_ActualIsSimpleString(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestYAMLEqWrapper_ExpectedIsSimpleString(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(MockT)
|
||||
mockRequire := New(mockT)
|
||||
|
||||
@ -599,8 +503,6 @@ func TestYAMLEqWrapper_ExpectedIsSimpleString(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestYAMLEqWrapper_ExpectedAndActualSimpleString(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(MockT)
|
||||
mockRequire := New(mockT)
|
||||
|
||||
@ -611,8 +513,6 @@ func TestYAMLEqWrapper_ExpectedAndActualSimpleString(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestYAMLEqWrapper_ArraysOfDifferentOrder(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(MockT)
|
||||
mockRequire := New(mockT)
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
{{ replace .Comment "assert." "require."}}
|
||||
{{.Comment}}
|
||||
func {{.DocInfo.Name}}(t TestingT, {{.Params}}) {
|
||||
if h, ok := t.(tHelper); ok { h.Helper() }
|
||||
if assert.{{.DocInfo.Name}}(t, {{.ForwardedParams}}) { return }
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -6,7 +6,7 @@ type TestingT interface {
|
||||
FailNow()
|
||||
}
|
||||
|
||||
type tHelper = interface {
|
||||
type tHelper interface {
|
||||
Helper()
|
||||
}
|
||||
|
||||
|
@ -5,8 +5,6 @@ import (
|
||||
"errors"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
// AssertionTesterInterface defines an interface to be used for testing assertion methods
|
||||
@ -29,9 +27,6 @@ type MockT struct {
|
||||
Failed bool
|
||||
}
|
||||
|
||||
// Helper is like [testing.T.Helper] but does nothing.
|
||||
func (MockT) Helper() {}
|
||||
|
||||
func (t *MockT) FailNow() {
|
||||
t.Failed = true
|
||||
}
|
||||
@ -41,7 +36,6 @@ func (t *MockT) Errorf(format string, args ...interface{}) {
|
||||
}
|
||||
|
||||
func TestImplements(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
Implements(t, (*AssertionTesterInterface)(nil), new(AssertionTesterConformingObject))
|
||||
|
||||
@ -53,7 +47,6 @@ func TestImplements(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestIsType(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
IsType(t, new(AssertionTesterConformingObject), new(AssertionTesterConformingObject))
|
||||
|
||||
@ -65,7 +58,6 @@ func TestIsType(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestEqual(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
Equal(t, 1, 1)
|
||||
|
||||
@ -78,7 +70,6 @@ func TestEqual(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNotEqual(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
NotEqual(t, 1, 2)
|
||||
mockT := new(MockT)
|
||||
@ -89,7 +80,6 @@ func TestNotEqual(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestExactly(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
a := float32(1)
|
||||
b := float32(1)
|
||||
@ -105,7 +95,6 @@ func TestExactly(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNotNil(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
NotNil(t, new(AssertionTesterConformingObject))
|
||||
|
||||
@ -117,7 +106,6 @@ func TestNotNil(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNil(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
Nil(t, nil)
|
||||
|
||||
@ -129,7 +117,6 @@ func TestNil(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestTrue(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
True(t, true)
|
||||
|
||||
@ -141,7 +128,6 @@ func TestTrue(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestFalse(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
False(t, false)
|
||||
|
||||
@ -153,7 +139,6 @@ func TestFalse(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestContains(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
Contains(t, "Hello World", "Hello")
|
||||
|
||||
@ -165,7 +150,6 @@ func TestContains(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNotContains(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
NotContains(t, "Hello World", "Hello!")
|
||||
|
||||
@ -177,7 +161,6 @@ func TestNotContains(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestPanics(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
Panics(t, func() {
|
||||
panic("Panic!")
|
||||
@ -191,7 +174,6 @@ func TestPanics(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNotPanics(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
NotPanics(t, func() {})
|
||||
|
||||
@ -205,7 +187,6 @@ func TestNotPanics(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNoError(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
NoError(t, nil)
|
||||
|
||||
@ -217,7 +198,6 @@ func TestNoError(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestError(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
Error(t, errors.New("some error"))
|
||||
|
||||
@ -229,7 +209,6 @@ func TestError(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestErrorContains(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
ErrorContains(t, errors.New("some error: another error"), "some error")
|
||||
|
||||
@ -241,7 +220,6 @@ func TestErrorContains(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestEqualError(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
EqualError(t, errors.New("some error"), "some error")
|
||||
|
||||
@ -253,7 +231,6 @@ func TestEqualError(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestEmpty(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
Empty(t, "")
|
||||
|
||||
@ -265,7 +242,6 @@ func TestEmpty(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNotEmpty(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
NotEmpty(t, "x")
|
||||
|
||||
@ -277,7 +253,6 @@ func TestNotEmpty(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestWithinDuration(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
a := time.Now()
|
||||
b := a.Add(10 * time.Second)
|
||||
@ -292,7 +267,6 @@ func TestWithinDuration(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestInDelta(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
InDelta(t, 1.001, 1, 0.01)
|
||||
|
||||
@ -304,7 +278,6 @@ func TestInDelta(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestZero(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
Zero(t, "")
|
||||
|
||||
@ -316,7 +289,6 @@ func TestZero(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNotZero(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
NotZero(t, "x")
|
||||
|
||||
@ -328,8 +300,6 @@ func TestNotZero(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestJSONEq_EqualSONString(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(MockT)
|
||||
JSONEq(mockT, `{"hello": "world", "foo": "bar"}`, `{"hello": "world", "foo": "bar"}`)
|
||||
if mockT.Failed {
|
||||
@ -338,8 +308,6 @@ func TestJSONEq_EqualSONString(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestJSONEq_EquivalentButNotEqual(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(MockT)
|
||||
JSONEq(mockT, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
|
||||
if mockT.Failed {
|
||||
@ -348,8 +316,6 @@ func TestJSONEq_EquivalentButNotEqual(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestJSONEq_HashOfArraysAndHashes(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(MockT)
|
||||
JSONEq(mockT, "{\r\n\t\"numeric\": 1.5,\r\n\t\"array\": [{\"foo\": \"bar\"}, 1, \"string\", [\"nested\", \"array\", 5.5]],\r\n\t\"hash\": {\"nested\": \"hash\", \"nested_slice\": [\"this\", \"is\", \"nested\"]},\r\n\t\"string\": \"foo\"\r\n}",
|
||||
"{\r\n\t\"numeric\": 1.5,\r\n\t\"hash\": {\"nested\": \"hash\", \"nested_slice\": [\"this\", \"is\", \"nested\"]},\r\n\t\"string\": \"foo\",\r\n\t\"array\": [{\"foo\": \"bar\"}, 1, \"string\", [\"nested\", \"array\", 5.5]]\r\n}")
|
||||
@ -359,8 +325,6 @@ func TestJSONEq_HashOfArraysAndHashes(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestJSONEq_Array(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(MockT)
|
||||
JSONEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `["foo", {"nested": "hash", "hello": "world"}]`)
|
||||
if mockT.Failed {
|
||||
@ -369,8 +333,6 @@ func TestJSONEq_Array(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestJSONEq_HashAndArrayNotEquivalent(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(MockT)
|
||||
JSONEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `{"foo": "bar", {"nested": "hash", "hello": "world"}}`)
|
||||
if !mockT.Failed {
|
||||
@ -379,8 +341,6 @@ func TestJSONEq_HashAndArrayNotEquivalent(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestJSONEq_HashesNotEquivalent(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(MockT)
|
||||
JSONEq(mockT, `{"foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
|
||||
if !mockT.Failed {
|
||||
@ -389,8 +349,6 @@ func TestJSONEq_HashesNotEquivalent(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestJSONEq_ActualIsNotJSON(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(MockT)
|
||||
JSONEq(mockT, `{"foo": "bar"}`, "Not JSON")
|
||||
if !mockT.Failed {
|
||||
@ -399,8 +357,6 @@ func TestJSONEq_ActualIsNotJSON(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestJSONEq_ExpectedIsNotJSON(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(MockT)
|
||||
JSONEq(mockT, "Not JSON", `{"foo": "bar", "hello": "world"}`)
|
||||
if !mockT.Failed {
|
||||
@ -409,8 +365,6 @@ func TestJSONEq_ExpectedIsNotJSON(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestJSONEq_ExpectedAndActualNotJSON(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(MockT)
|
||||
JSONEq(mockT, "Not JSON", "Not JSON")
|
||||
if !mockT.Failed {
|
||||
@ -419,8 +373,6 @@ func TestJSONEq_ExpectedAndActualNotJSON(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestJSONEq_ArraysOfDifferentOrder(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(MockT)
|
||||
JSONEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `[{ "hello": "world", "nested": "hash"}, "foo"]`)
|
||||
if !mockT.Failed {
|
||||
@ -429,8 +381,6 @@ func TestJSONEq_ArraysOfDifferentOrder(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestYAMLEq_EqualYAMLString(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(MockT)
|
||||
YAMLEq(mockT, `{"hello": "world", "foo": "bar"}`, `{"hello": "world", "foo": "bar"}`)
|
||||
if mockT.Failed {
|
||||
@ -439,8 +389,6 @@ func TestYAMLEq_EqualYAMLString(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestYAMLEq_EquivalentButNotEqual(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(MockT)
|
||||
YAMLEq(mockT, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
|
||||
if mockT.Failed {
|
||||
@ -449,8 +397,6 @@ func TestYAMLEq_EquivalentButNotEqual(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestYAMLEq_HashOfArraysAndHashes(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(MockT)
|
||||
expected := `
|
||||
numeric: 1.5
|
||||
@ -484,8 +430,6 @@ array:
|
||||
}
|
||||
|
||||
func TestYAMLEq_Array(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(MockT)
|
||||
YAMLEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `["foo", {"nested": "hash", "hello": "world"}]`)
|
||||
if mockT.Failed {
|
||||
@ -494,8 +438,6 @@ func TestYAMLEq_Array(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestYAMLEq_HashAndArrayNotEquivalent(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(MockT)
|
||||
YAMLEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `{"foo": "bar", {"nested": "hash", "hello": "world"}}`)
|
||||
if !mockT.Failed {
|
||||
@ -504,8 +446,6 @@ func TestYAMLEq_HashAndArrayNotEquivalent(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestYAMLEq_HashesNotEquivalent(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(MockT)
|
||||
YAMLEq(mockT, `{"foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
|
||||
if !mockT.Failed {
|
||||
@ -514,8 +454,6 @@ func TestYAMLEq_HashesNotEquivalent(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestYAMLEq_ActualIsSimpleString(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(MockT)
|
||||
YAMLEq(mockT, `{"foo": "bar"}`, "Simple String")
|
||||
if !mockT.Failed {
|
||||
@ -524,8 +462,6 @@ func TestYAMLEq_ActualIsSimpleString(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestYAMLEq_ExpectedIsSimpleString(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(MockT)
|
||||
YAMLEq(mockT, "Simple String", `{"foo": "bar", "hello": "world"}`)
|
||||
if !mockT.Failed {
|
||||
@ -534,8 +470,6 @@ func TestYAMLEq_ExpectedIsSimpleString(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestYAMLEq_ExpectedAndActualSimpleString(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(MockT)
|
||||
YAMLEq(mockT, "Simple String", "Simple String")
|
||||
if mockT.Failed {
|
||||
@ -544,8 +478,6 @@ func TestYAMLEq_ExpectedAndActualSimpleString(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestYAMLEq_ArraysOfDifferentOrder(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(MockT)
|
||||
YAMLEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `[{ "hello": "world", "nested": "hash"}, "foo"]`)
|
||||
if !mockT.Failed {
|
||||
@ -584,8 +516,6 @@ func ExampleComparisonAssertionFunc() {
|
||||
}
|
||||
|
||||
func TestComparisonAssertionFunc(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
type iface interface {
|
||||
Name() string
|
||||
}
|
||||
@ -647,8 +577,6 @@ func ExampleValueAssertionFunc() {
|
||||
}
|
||||
|
||||
func TestValueAssertionFunc(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
value interface{}
|
||||
@ -695,8 +623,6 @@ func ExampleBoolAssertionFunc() {
|
||||
}
|
||||
|
||||
func TestBoolAssertionFunc(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
value bool
|
||||
@ -740,8 +666,6 @@ func ExampleErrorAssertionFunc() {
|
||||
}
|
||||
|
||||
func TestErrorAssertionFunc(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
err error
|
||||
@ -757,34 +681,3 @@ func TestErrorAssertionFunc(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestEventuallyWithTFalse(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(MockT)
|
||||
|
||||
condition := func(collect *assert.CollectT) {
|
||||
True(collect, false)
|
||||
}
|
||||
|
||||
EventuallyWithT(mockT, condition, 100*time.Millisecond, 20*time.Millisecond)
|
||||
True(t, mockT.Failed, "Check should fail")
|
||||
}
|
||||
|
||||
func TestEventuallyWithTTrue(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockT := new(MockT)
|
||||
|
||||
counter := 0
|
||||
condition := func(collect *assert.CollectT) {
|
||||
defer func() {
|
||||
counter += 1
|
||||
}()
|
||||
True(collect, counter == 1)
|
||||
}
|
||||
|
||||
EventuallyWithT(mockT, condition, 100*time.Millisecond, 20*time.Millisecond)
|
||||
False(t, mockT.Failed, "Check should pass")
|
||||
Equal(t, 2, counter, "Condition is expected to be called 2 times")
|
||||
}
|
||||
|
63
suite/doc.go
63
suite/doc.go
@ -5,8 +5,6 @@
|
||||
// or individual tests (depending on which interface(s) you
|
||||
// implement).
|
||||
//
|
||||
// The suite package does not support parallel tests. See [issue 934].
|
||||
//
|
||||
// A testing suite is usually built by first extending the built-in
|
||||
// suite functionality from suite.Suite in testify. Alternatively,
|
||||
// you could reproduce that logic on your own if you wanted (you
|
||||
@ -31,40 +29,37 @@
|
||||
// Suite object has assertion methods.
|
||||
//
|
||||
// A crude example:
|
||||
// // Basic imports
|
||||
// import (
|
||||
// "testing"
|
||||
// "github.com/stretchr/testify/assert"
|
||||
// "github.com/stretchr/testify/suite"
|
||||
// )
|
||||
//
|
||||
// // Basic imports
|
||||
// import (
|
||||
// "testing"
|
||||
// "github.com/stretchr/testify/assert"
|
||||
// "github.com/stretchr/testify/suite"
|
||||
// )
|
||||
// // Define the suite, and absorb the built-in basic suite
|
||||
// // functionality from testify - including a T() method which
|
||||
// // returns the current testing context
|
||||
// type ExampleTestSuite struct {
|
||||
// suite.Suite
|
||||
// VariableThatShouldStartAtFive int
|
||||
// }
|
||||
//
|
||||
// // Define the suite, and absorb the built-in basic suite
|
||||
// // functionality from testify - including a T() method which
|
||||
// // returns the current testing context
|
||||
// type ExampleTestSuite struct {
|
||||
// suite.Suite
|
||||
// VariableThatShouldStartAtFive int
|
||||
// }
|
||||
// // Make sure that VariableThatShouldStartAtFive is set to five
|
||||
// // before each test
|
||||
// func (suite *ExampleTestSuite) SetupTest() {
|
||||
// suite.VariableThatShouldStartAtFive = 5
|
||||
// }
|
||||
//
|
||||
// // Make sure that VariableThatShouldStartAtFive is set to five
|
||||
// // before each test
|
||||
// func (suite *ExampleTestSuite) SetupTest() {
|
||||
// suite.VariableThatShouldStartAtFive = 5
|
||||
// }
|
||||
// // All methods that begin with "Test" are run as tests within a
|
||||
// // suite.
|
||||
// func (suite *ExampleTestSuite) TestExample() {
|
||||
// assert.Equal(suite.T(), 5, suite.VariableThatShouldStartAtFive)
|
||||
// suite.Equal(5, suite.VariableThatShouldStartAtFive)
|
||||
// }
|
||||
//
|
||||
// // All methods that begin with "Test" are run as tests within a
|
||||
// // suite.
|
||||
// func (suite *ExampleTestSuite) TestExample() {
|
||||
// assert.Equal(suite.T(), 5, suite.VariableThatShouldStartAtFive)
|
||||
// suite.Equal(5, suite.VariableThatShouldStartAtFive)
|
||||
// }
|
||||
//
|
||||
// // In order for 'go test' to run this suite, we need to create
|
||||
// // a normal test function and pass our suite to suite.Run
|
||||
// func TestExampleTestSuite(t *testing.T) {
|
||||
// suite.Run(t, new(ExampleTestSuite))
|
||||
// }
|
||||
//
|
||||
// [issue 934]: https://github.com/stretchr/testify/issues/934
|
||||
// // In order for 'go test' to run this suite, we need to create
|
||||
// // a normal test function and pass our suite to suite.Run
|
||||
// func TestExampleTestSuite(t *testing.T) {
|
||||
// suite.Run(t, new(ExampleTestSuite))
|
||||
// }
|
||||
package suite
|
||||
|
@ -7,7 +7,6 @@ import "testing"
|
||||
type TestingSuite interface {
|
||||
T() *testing.T
|
||||
SetT(*testing.T)
|
||||
SetS(suite TestingSuite)
|
||||
}
|
||||
|
||||
// SetupAllSuite has a SetupSuite method, which will run before the
|
||||
@ -52,15 +51,3 @@ type AfterTest interface {
|
||||
type WithStats interface {
|
||||
HandleStats(suiteName string, stats *SuiteInformation)
|
||||
}
|
||||
|
||||
// SetupSubTest has a SetupSubTest method, which will run before each
|
||||
// subtest in the suite.
|
||||
type SetupSubTest interface {
|
||||
SetupSubTest()
|
||||
}
|
||||
|
||||
// TearDownSubTest has a TearDownSubTest method, which will run after
|
||||
// each subtest in the suite have been run.
|
||||
type TearDownSubTest interface {
|
||||
TearDownSubTest()
|
||||
}
|
||||
|
@ -16,30 +16,26 @@ type TestInformation struct {
|
||||
}
|
||||
|
||||
func newSuiteInformation() *SuiteInformation {
|
||||
testStats := make(map[string]*TestInformation)
|
||||
|
||||
return &SuiteInformation{
|
||||
TestStats: make(map[string]*TestInformation),
|
||||
TestStats: testStats,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SuiteInformation) start(testName string) {
|
||||
if s == nil {
|
||||
return
|
||||
}
|
||||
func (s SuiteInformation) start(testName string) {
|
||||
s.TestStats[testName] = &TestInformation{
|
||||
TestName: testName,
|
||||
Start: time.Now(),
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SuiteInformation) end(testName string, passed bool) {
|
||||
if s == nil {
|
||||
return
|
||||
}
|
||||
func (s SuiteInformation) end(testName string, passed bool) {
|
||||
s.TestStats[testName].End = time.Now()
|
||||
s.TestStats[testName].Passed = passed
|
||||
}
|
||||
|
||||
func (s *SuiteInformation) Passed() bool {
|
||||
func (s SuiteInformation) Passed() bool {
|
||||
for _, stats := range s.TestStats {
|
||||
if !stats.Passed {
|
||||
return false
|
||||
|
@ -27,14 +27,3 @@ func TestPassedReturnsFalseWhenSomeTestFails(t *testing.T) {
|
||||
|
||||
assert.False(t, sinfo.Passed())
|
||||
}
|
||||
|
||||
func TestPassedReturnsFalseWhenAllTestsFail(t *testing.T) {
|
||||
sinfo := newSuiteInformation()
|
||||
sinfo.TestStats = map[string]*TestInformation{
|
||||
"Test1": {TestName: "Test1", Passed: false},
|
||||
"Test2": {TestName: "Test2", Passed: false},
|
||||
"Test3": {TestName: "Test3", Passed: false},
|
||||
}
|
||||
|
||||
assert.False(t, sinfo.Passed())
|
||||
}
|
||||
|
160
suite/suite.go
160
suite/suite.go
@ -7,7 +7,6 @@ import (
|
||||
"reflect"
|
||||
"regexp"
|
||||
"runtime/debug"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
@ -16,19 +15,16 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var allTestsFilter = func(_, _ string) (bool, error) { return true, nil }
|
||||
var matchMethod = flag.String("testify.m", "", "regular expression to select tests of the testify suite to run")
|
||||
|
||||
// Suite is a basic testing suite with methods for storing and
|
||||
// retrieving the current *testing.T context.
|
||||
type Suite struct {
|
||||
*assert.Assertions
|
||||
|
||||
mu sync.RWMutex
|
||||
require *require.Assertions
|
||||
t *testing.T
|
||||
|
||||
// Parent suite to have access to the implemented methods of parent struct
|
||||
s TestingSuite
|
||||
}
|
||||
|
||||
// T retrieves the current *testing.T context.
|
||||
@ -47,18 +43,12 @@ func (suite *Suite) SetT(t *testing.T) {
|
||||
suite.require = require.New(t)
|
||||
}
|
||||
|
||||
// SetS needs to set the current test suite as parent
|
||||
// to get access to the parent methods
|
||||
func (suite *Suite) SetS(s TestingSuite) {
|
||||
suite.s = s
|
||||
}
|
||||
|
||||
// Require returns a require context for suite.
|
||||
func (suite *Suite) Require() *require.Assertions {
|
||||
suite.mu.Lock()
|
||||
defer suite.mu.Unlock()
|
||||
if suite.require == nil {
|
||||
panic("'Require' must not be called before 'Run' or 'SetT'")
|
||||
suite.require = require.New(suite.T())
|
||||
}
|
||||
return suite.require
|
||||
}
|
||||
@ -72,19 +62,13 @@ func (suite *Suite) Assert() *assert.Assertions {
|
||||
suite.mu.Lock()
|
||||
defer suite.mu.Unlock()
|
||||
if suite.Assertions == nil {
|
||||
panic("'Assert' must not be called before 'Run' or 'SetT'")
|
||||
suite.Assertions = assert.New(suite.T())
|
||||
}
|
||||
return suite.Assertions
|
||||
}
|
||||
|
||||
func recoverAndFailOnPanic(t *testing.T) {
|
||||
t.Helper()
|
||||
func failOnPanic(t *testing.T) {
|
||||
r := recover()
|
||||
failOnPanic(t, r)
|
||||
}
|
||||
|
||||
func failOnPanic(t *testing.T, r interface{}) {
|
||||
t.Helper()
|
||||
if r != nil {
|
||||
t.Errorf("test panicked: %v\n%s", r, debug.Stack())
|
||||
t.FailNow()
|
||||
@ -97,80 +81,67 @@ func failOnPanic(t *testing.T, r interface{}) {
|
||||
// Provides compatibility with go test pkg -run TestSuite/TestName/SubTestName.
|
||||
func (suite *Suite) Run(name string, subtest func()) bool {
|
||||
oldT := suite.T()
|
||||
|
||||
defer suite.SetT(oldT)
|
||||
return oldT.Run(name, func(t *testing.T) {
|
||||
suite.SetT(t)
|
||||
defer suite.SetT(oldT)
|
||||
|
||||
defer recoverAndFailOnPanic(t)
|
||||
|
||||
if setupSubTest, ok := suite.s.(SetupSubTest); ok {
|
||||
setupSubTest.SetupSubTest()
|
||||
}
|
||||
|
||||
if tearDownSubTest, ok := suite.s.(TearDownSubTest); ok {
|
||||
defer tearDownSubTest.TearDownSubTest()
|
||||
}
|
||||
|
||||
subtest()
|
||||
})
|
||||
}
|
||||
|
||||
type test = struct {
|
||||
name string
|
||||
run func(t *testing.T)
|
||||
}
|
||||
|
||||
// Run takes a testing suite and runs all of the tests attached
|
||||
// to it.
|
||||
func Run(t *testing.T, suite TestingSuite) {
|
||||
defer recoverAndFailOnPanic(t)
|
||||
defer failOnPanic(t)
|
||||
|
||||
suite.SetT(t)
|
||||
suite.SetS(suite)
|
||||
|
||||
var suiteSetupDone bool
|
||||
|
||||
var stats *SuiteInformation
|
||||
if _, ok := suite.(WithStats); ok {
|
||||
stats = newSuiteInformation()
|
||||
}
|
||||
|
||||
var tests []test
|
||||
tests := []testing.InternalTest{}
|
||||
methodFinder := reflect.TypeOf(suite)
|
||||
suiteName := methodFinder.Elem().Name()
|
||||
|
||||
var matchMethodRE *regexp.Regexp
|
||||
if *matchMethod != "" {
|
||||
var err error
|
||||
matchMethodRE, err = regexp.Compile(*matchMethod)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "testify: invalid regexp for -m: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
for i := 0; i < methodFinder.NumMethod(); i++ {
|
||||
method := methodFinder.Method(i)
|
||||
|
||||
if !strings.HasPrefix(method.Name, "Test") {
|
||||
continue
|
||||
ok, err := methodFilter(method.Name)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "testify: invalid regexp for -m: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
// Apply -testify.m filter
|
||||
if matchMethodRE != nil && !matchMethodRE.MatchString(method.Name) {
|
||||
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
test := test{
|
||||
name: method.Name,
|
||||
run: func(t *testing.T) {
|
||||
if !suiteSetupDone {
|
||||
if stats != nil {
|
||||
stats.Start = time.Now()
|
||||
}
|
||||
|
||||
if setupAllSuite, ok := suite.(SetupAllSuite); ok {
|
||||
setupAllSuite.SetupSuite()
|
||||
}
|
||||
|
||||
suiteSetupDone = true
|
||||
}
|
||||
|
||||
test := testing.InternalTest{
|
||||
Name: method.Name,
|
||||
F: func(t *testing.T) {
|
||||
parentT := suite.T()
|
||||
suite.SetT(t)
|
||||
defer recoverAndFailOnPanic(t)
|
||||
defer failOnPanic(t)
|
||||
defer func() {
|
||||
t.Helper()
|
||||
|
||||
r := recover()
|
||||
|
||||
stats.end(method.Name, !t.Failed() && r == nil)
|
||||
if stats != nil {
|
||||
passed := !t.Failed()
|
||||
stats.end(method.Name, passed)
|
||||
}
|
||||
|
||||
if afterTestSuite, ok := suite.(AfterTest); ok {
|
||||
afterTestSuite.AfterTest(suiteName, method.Name)
|
||||
@ -181,7 +152,6 @@ func Run(t *testing.T, suite TestingSuite) {
|
||||
}
|
||||
|
||||
suite.SetT(parentT)
|
||||
failOnPanic(t, r)
|
||||
}()
|
||||
|
||||
if setupTestSuite, ok := suite.(SetupTestSuite); ok {
|
||||
@ -191,47 +161,59 @@ func Run(t *testing.T, suite TestingSuite) {
|
||||
beforeTestSuite.BeforeTest(methodFinder.Elem().Name(), method.Name)
|
||||
}
|
||||
|
||||
stats.start(method.Name)
|
||||
if stats != nil {
|
||||
stats.start(method.Name)
|
||||
}
|
||||
|
||||
method.Func.Call([]reflect.Value{reflect.ValueOf(suite)})
|
||||
},
|
||||
}
|
||||
tests = append(tests, test)
|
||||
}
|
||||
if suiteSetupDone {
|
||||
defer func() {
|
||||
if tearDownAllSuite, ok := suite.(TearDownAllSuite); ok {
|
||||
tearDownAllSuite.TearDownSuite()
|
||||
}
|
||||
|
||||
if len(tests) == 0 {
|
||||
return
|
||||
if suiteWithStats, measureStats := suite.(WithStats); measureStats {
|
||||
stats.End = time.Now()
|
||||
suiteWithStats.HandleStats(suiteName, stats)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
if stats != nil {
|
||||
stats.Start = time.Now()
|
||||
}
|
||||
|
||||
if setupAllSuite, ok := suite.(SetupAllSuite); ok {
|
||||
setupAllSuite.SetupSuite()
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if tearDownAllSuite, ok := suite.(TearDownAllSuite); ok {
|
||||
tearDownAllSuite.TearDownSuite()
|
||||
}
|
||||
|
||||
if suiteWithStats, measureStats := suite.(WithStats); measureStats {
|
||||
stats.End = time.Now()
|
||||
suiteWithStats.HandleStats(suiteName, stats)
|
||||
}
|
||||
}()
|
||||
|
||||
runTests(t, tests)
|
||||
}
|
||||
|
||||
func runTests(t *testing.T, tests []test) {
|
||||
// Filtering method according to set regular expression
|
||||
// specified command-line argument -m
|
||||
func methodFilter(name string) (bool, error) {
|
||||
if ok, _ := regexp.MatchString("^Test", name); !ok {
|
||||
return false, nil
|
||||
}
|
||||
return regexp.MatchString(*matchMethod, name)
|
||||
}
|
||||
|
||||
func runTests(t testing.TB, tests []testing.InternalTest) {
|
||||
if len(tests) == 0 {
|
||||
t.Log("warning: no tests to run")
|
||||
return
|
||||
}
|
||||
|
||||
r, ok := t.(runner)
|
||||
if !ok { // backwards compatibility with Go 1.6 and below
|
||||
if !testing.RunTests(allTestsFilter, tests) {
|
||||
t.Fail()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, test.run)
|
||||
r.Run(test.Name, test.F)
|
||||
}
|
||||
}
|
||||
|
||||
type runner interface {
|
||||
Run(name string, f func(t *testing.T)) bool
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"flag"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
"os"
|
||||
"os/exec"
|
||||
@ -16,30 +16,25 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// allTestsFilter is a yes filter for testing.RunTests
|
||||
func allTestsFilter(pat, str string) (bool, error) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// SuiteRequireTwice is intended to test the usage of suite.Require in two
|
||||
// different tests
|
||||
type SuiteRequireTwice struct{ Suite }
|
||||
|
||||
// TestSuiteRequireTwice checks for regressions of issue #149 where
|
||||
// suite.requirements was not initialized in suite.SetT()
|
||||
// suite.requirements was not initialised in suite.SetT()
|
||||
// A regression would result on these tests panicking rather than failing.
|
||||
func TestSuiteRequireTwice(t *testing.T) {
|
||||
ok := testing.RunTests(
|
||||
allTestsFilter,
|
||||
[]testing.InternalTest{{
|
||||
Name: t.Name() + "/SuiteRequireTwice",
|
||||
Name: "TestSuiteRequireTwice",
|
||||
F: func(t *testing.T) {
|
||||
suite := new(SuiteRequireTwice)
|
||||
Run(t, suite)
|
||||
},
|
||||
}},
|
||||
)
|
||||
assert.False(t, ok)
|
||||
assert.Equal(t, false, ok)
|
||||
}
|
||||
|
||||
func (s *SuiteRequireTwice) TestRequireOne() {
|
||||
@ -109,31 +104,31 @@ func TestSuiteRecoverPanic(t *testing.T) {
|
||||
ok := true
|
||||
panickingTests := []testing.InternalTest{
|
||||
{
|
||||
Name: t.Name() + "/InSetupSuite",
|
||||
Name: "TestPanicInSetupSuite",
|
||||
F: func(t *testing.T) { Run(t, &panickingSuite{panicInSetupSuite: true}) },
|
||||
},
|
||||
{
|
||||
Name: t.Name() + "/InSetupTest",
|
||||
Name: "TestPanicInSetupTest",
|
||||
F: func(t *testing.T) { Run(t, &panickingSuite{panicInSetupTest: true}) },
|
||||
},
|
||||
{
|
||||
Name: t.Name() + "InBeforeTest",
|
||||
Name: "TestPanicInBeforeTest",
|
||||
F: func(t *testing.T) { Run(t, &panickingSuite{panicInBeforeTest: true}) },
|
||||
},
|
||||
{
|
||||
Name: t.Name() + "/InTest",
|
||||
Name: "TestPanicInTest",
|
||||
F: func(t *testing.T) { Run(t, &panickingSuite{panicInTest: true}) },
|
||||
},
|
||||
{
|
||||
Name: t.Name() + "/InAfterTest",
|
||||
Name: "TestPanicInAfterTest",
|
||||
F: func(t *testing.T) { Run(t, &panickingSuite{panicInAfterTest: true}) },
|
||||
},
|
||||
{
|
||||
Name: t.Name() + "/InTearDownTest",
|
||||
Name: "TestPanicInTearDownTest",
|
||||
F: func(t *testing.T) { Run(t, &panickingSuite{panicInTearDownTest: true}) },
|
||||
},
|
||||
{
|
||||
Name: t.Name() + "/InTearDownSuite",
|
||||
Name: "TestPanicInTearDownSuite",
|
||||
F: func(t *testing.T) { Run(t, &panickingSuite{panicInTearDownSuite: true}) },
|
||||
},
|
||||
}
|
||||
@ -156,19 +151,14 @@ type SuiteTester struct {
|
||||
Suite
|
||||
|
||||
// Keep counts of how many times each method is run.
|
||||
SetupSuiteRunCount int
|
||||
TearDownSuiteRunCount int
|
||||
SetupTestRunCount int
|
||||
TearDownTestRunCount int
|
||||
TestOneRunCount int
|
||||
TestTwoRunCount int
|
||||
TestSubtestRunCount int
|
||||
NonTestMethodRunCount int
|
||||
SetupSubTestRunCount int
|
||||
TearDownSubTestRunCount int
|
||||
|
||||
SetupSubTestNames []string
|
||||
TearDownSubTestNames []string
|
||||
SetupSuiteRunCount int
|
||||
TearDownSuiteRunCount int
|
||||
SetupTestRunCount int
|
||||
TearDownTestRunCount int
|
||||
TestOneRunCount int
|
||||
TestTwoRunCount int
|
||||
TestSubtestRunCount int
|
||||
NonTestMethodRunCount int
|
||||
|
||||
SuiteNameBefore []string
|
||||
TestNameBefore []string
|
||||
@ -265,16 +255,6 @@ func (suite *SuiteTester) TestSubtest() {
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *SuiteTester) TearDownSubTest() {
|
||||
suite.TearDownSubTestNames = append(suite.TearDownSubTestNames, suite.T().Name())
|
||||
suite.TearDownSubTestRunCount++
|
||||
}
|
||||
|
||||
func (suite *SuiteTester) SetupSubTest() {
|
||||
suite.SetupSubTestNames = append(suite.SetupSubTestNames, suite.T().Name())
|
||||
suite.SetupSubTestRunCount++
|
||||
}
|
||||
|
||||
type SuiteSkipTester struct {
|
||||
// Include our basic suite logic.
|
||||
Suite
|
||||
@ -311,13 +291,13 @@ func TestRunSuite(t *testing.T) {
|
||||
|
||||
// The suite was only run once, so the SetupSuite and TearDownSuite
|
||||
// methods should have each been run only once.
|
||||
assert.Equal(t, 1, suiteTester.SetupSuiteRunCount)
|
||||
assert.Equal(t, 1, suiteTester.TearDownSuiteRunCount)
|
||||
assert.Equal(t, suiteTester.SetupSuiteRunCount, 1)
|
||||
assert.Equal(t, suiteTester.TearDownSuiteRunCount, 1)
|
||||
|
||||
assert.Len(t, suiteTester.SuiteNameAfter, 4)
|
||||
assert.Len(t, suiteTester.SuiteNameBefore, 4)
|
||||
assert.Len(t, suiteTester.TestNameAfter, 4)
|
||||
assert.Len(t, suiteTester.TestNameBefore, 4)
|
||||
assert.Equal(t, len(suiteTester.SuiteNameAfter), 4)
|
||||
assert.Equal(t, len(suiteTester.SuiteNameBefore), 4)
|
||||
assert.Equal(t, len(suiteTester.TestNameAfter), 4)
|
||||
assert.Equal(t, len(suiteTester.TestNameBefore), 4)
|
||||
|
||||
assert.Contains(t, suiteTester.TestNameAfter, "TestOne")
|
||||
assert.Contains(t, suiteTester.TestNameAfter, "TestTwo")
|
||||
@ -329,12 +309,6 @@ func TestRunSuite(t *testing.T) {
|
||||
assert.Contains(t, suiteTester.TestNameBefore, "TestSkip")
|
||||
assert.Contains(t, suiteTester.TestNameBefore, "TestSubtest")
|
||||
|
||||
assert.Contains(t, suiteTester.SetupSubTestNames, "TestRunSuite/TestSubtest/first")
|
||||
assert.Contains(t, suiteTester.SetupSubTestNames, "TestRunSuite/TestSubtest/second")
|
||||
|
||||
assert.Contains(t, suiteTester.TearDownSubTestNames, "TestRunSuite/TestSubtest/first")
|
||||
assert.Contains(t, suiteTester.TearDownSubTestNames, "TestRunSuite/TestSubtest/second")
|
||||
|
||||
for _, suiteName := range suiteTester.SuiteNameAfter {
|
||||
assert.Equal(t, "SuiteTester", suiteName)
|
||||
}
|
||||
@ -354,20 +328,17 @@ func TestRunSuite(t *testing.T) {
|
||||
// There are four test methods (TestOne, TestTwo, TestSkip, and TestSubtest), so
|
||||
// the SetupTest and TearDownTest methods (which should be run once for
|
||||
// each test) should have been run four times.
|
||||
assert.Equal(t, 4, suiteTester.SetupTestRunCount)
|
||||
assert.Equal(t, 4, suiteTester.TearDownTestRunCount)
|
||||
assert.Equal(t, suiteTester.SetupTestRunCount, 4)
|
||||
assert.Equal(t, suiteTester.TearDownTestRunCount, 4)
|
||||
|
||||
// Each test should have been run once.
|
||||
assert.Equal(t, 1, suiteTester.TestOneRunCount)
|
||||
assert.Equal(t, 1, suiteTester.TestTwoRunCount)
|
||||
assert.Equal(t, 1, suiteTester.TestSubtestRunCount)
|
||||
|
||||
assert.Equal(t, 2, suiteTester.TearDownSubTestRunCount)
|
||||
assert.Equal(t, 2, suiteTester.SetupSubTestRunCount)
|
||||
assert.Equal(t, suiteTester.TestOneRunCount, 1)
|
||||
assert.Equal(t, suiteTester.TestTwoRunCount, 1)
|
||||
assert.Equal(t, suiteTester.TestSubtestRunCount, 1)
|
||||
|
||||
// Methods that don't match the test method identifier shouldn't
|
||||
// have been run at all.
|
||||
assert.Equal(t, 0, suiteTester.NonTestMethodRunCount)
|
||||
assert.Equal(t, suiteTester.NonTestMethodRunCount, 0)
|
||||
|
||||
suiteSkipTester := new(SuiteSkipTester)
|
||||
Run(t, suiteSkipTester)
|
||||
@ -375,8 +346,8 @@ func TestRunSuite(t *testing.T) {
|
||||
// The suite was only run once, so the SetupSuite and TearDownSuite
|
||||
// methods should have each been run only once, even though SetupSuite
|
||||
// called Skip()
|
||||
assert.Equal(t, 1, suiteSkipTester.SetupSuiteRunCount)
|
||||
assert.Equal(t, 1, suiteSkipTester.TearDownSuiteRunCount)
|
||||
assert.Equal(t, suiteSkipTester.SetupSuiteRunCount, 1)
|
||||
assert.Equal(t, suiteSkipTester.TearDownSuiteRunCount, 1)
|
||||
|
||||
}
|
||||
|
||||
@ -445,7 +416,7 @@ func (sc *StdoutCapture) StopCapture() (string, error) {
|
||||
}
|
||||
os.Stdout.Close()
|
||||
os.Stdout = sc.oldStdout
|
||||
bytes, err := io.ReadAll(sc.readPipe)
|
||||
bytes, err := ioutil.ReadAll(sc.readPipe)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@ -456,7 +427,7 @@ func TestSuiteLogging(t *testing.T) {
|
||||
suiteLoggingTester := new(SuiteLoggingTester)
|
||||
capture := StdoutCapture{}
|
||||
internalTest := testing.InternalTest{
|
||||
Name: t.Name() + "/SuiteLoggingTester",
|
||||
Name: "SomeTest",
|
||||
F: func(subT *testing.T) {
|
||||
Run(subT, suiteLoggingTester)
|
||||
},
|
||||
@ -497,7 +468,7 @@ func (s *CallOrderSuite) SetupSuite() {
|
||||
|
||||
func (s *CallOrderSuite) TearDownSuite() {
|
||||
s.call("TearDownSuite")
|
||||
assert.Equal(s.T(), "SetupSuite;SetupTest;Test A;SetupSubTest;SubTest A1;TearDownSubTest;SetupSubTest;SubTest A2;TearDownSubTest;TearDownTest;SetupTest;Test B;SetupSubTest;SubTest B1;TearDownSubTest;SetupSubTest;SubTest B2;TearDownSubTest;TearDownTest;TearDownSuite", strings.Join(s.callOrder, ";"))
|
||||
assert.Equal(s.T(), "SetupSuite;SetupTest;Test A;TearDownTest;SetupTest;Test B;TearDownTest;TearDownSuite", strings.Join(s.callOrder, ";"))
|
||||
}
|
||||
func (s *CallOrderSuite) SetupTest() {
|
||||
s.call("SetupTest")
|
||||
@ -507,32 +478,12 @@ func (s *CallOrderSuite) TearDownTest() {
|
||||
s.call("TearDownTest")
|
||||
}
|
||||
|
||||
func (s *CallOrderSuite) SetupSubTest() {
|
||||
s.call("SetupSubTest")
|
||||
}
|
||||
|
||||
func (s *CallOrderSuite) TearDownSubTest() {
|
||||
s.call("TearDownSubTest")
|
||||
}
|
||||
|
||||
func (s *CallOrderSuite) Test_A() {
|
||||
s.call("Test A")
|
||||
s.Run("SubTest A1", func() {
|
||||
s.call("SubTest A1")
|
||||
})
|
||||
s.Run("SubTest A2", func() {
|
||||
s.call("SubTest A2")
|
||||
})
|
||||
}
|
||||
|
||||
func (s *CallOrderSuite) Test_B() {
|
||||
s.call("Test B")
|
||||
s.Run("SubTest B1", func() {
|
||||
s.call("SubTest B1")
|
||||
})
|
||||
s.Run("SubTest B2", func() {
|
||||
s.call("SubTest B2")
|
||||
})
|
||||
}
|
||||
|
||||
type suiteWithStats struct {
|
||||
@ -550,37 +501,19 @@ func (s *suiteWithStats) TestSomething() {
|
||||
s.Equal(1, 1)
|
||||
}
|
||||
|
||||
func (s *suiteWithStats) TestPanic() {
|
||||
panic("oops")
|
||||
}
|
||||
|
||||
func TestSuiteWithStats(t *testing.T) {
|
||||
suiteWithStats := new(suiteWithStats)
|
||||
|
||||
suiteSuccess := testing.RunTests(allTestsFilter, []testing.InternalTest{
|
||||
{
|
||||
Name: t.Name() + "/suiteWithStats",
|
||||
F: func(t *testing.T) {
|
||||
Run(t, suiteWithStats)
|
||||
},
|
||||
},
|
||||
})
|
||||
require.False(t, suiteSuccess, "suiteWithStats should report test failure because of panic in TestPanic")
|
||||
Run(t, suiteWithStats)
|
||||
|
||||
assert.True(t, suiteWithStats.wasCalled)
|
||||
assert.NotZero(t, suiteWithStats.stats.Start)
|
||||
assert.NotZero(t, suiteWithStats.stats.End)
|
||||
assert.False(t, suiteWithStats.stats.Passed())
|
||||
assert.True(t, suiteWithStats.stats.Passed())
|
||||
|
||||
testStats := suiteWithStats.stats.TestStats
|
||||
|
||||
assert.NotZero(t, testStats["TestSomething"].Start)
|
||||
assert.NotZero(t, testStats["TestSomething"].End)
|
||||
assert.True(t, testStats["TestSomething"].Passed)
|
||||
|
||||
assert.NotZero(t, testStats["TestPanic"].Start)
|
||||
assert.NotZero(t, testStats["TestPanic"].End)
|
||||
assert.False(t, testStats["TestPanic"].Passed)
|
||||
testStats := suiteWithStats.stats.TestStats["TestSomething"]
|
||||
assert.NotZero(t, testStats.Start)
|
||||
assert.NotZero(t, testStats.End)
|
||||
assert.True(t, testStats.Passed)
|
||||
}
|
||||
|
||||
// FailfastSuite will test the behavior when running with the failfast flag
|
||||
@ -602,51 +535,21 @@ func TestFailfastSuite(t *testing.T) {
|
||||
ok := testing.RunTests(
|
||||
allTestsFilter,
|
||||
[]testing.InternalTest{{
|
||||
Name: t.Name() + "/FailfastSuite",
|
||||
Name: "TestFailfastSuite",
|
||||
F: func(t *testing.T) {
|
||||
Run(t, s)
|
||||
},
|
||||
}},
|
||||
)
|
||||
assert.False(t, ok)
|
||||
var expect []string
|
||||
assert.Equal(t, false, ok)
|
||||
if failFast {
|
||||
// Test A Fails and because we are running with failfast Test B never runs and we proceed straight to TearDownSuite
|
||||
expect = []string{"SetupSuite", "SetupTest", "Test A Fails", "TearDownTest", "TearDownSuite"}
|
||||
assert.Equal(t, "SetupSuite;SetupTest;Test A Fails;TearDownTest;TearDownSuite", strings.Join(s.callOrder, ";"))
|
||||
} else {
|
||||
// Test A Fails and because we are running without failfast we continue and run Test B and then proceed to TearDownSuite
|
||||
expect = []string{"SetupSuite", "SetupTest", "Test A Fails", "TearDownTest", "SetupTest", "Test B Passes", "TearDownTest", "TearDownSuite"}
|
||||
assert.Equal(t, "SetupSuite;SetupTest;Test A Fails;TearDownTest;SetupTest;Test B Passes;TearDownTest;TearDownSuite", strings.Join(s.callOrder, ";"))
|
||||
}
|
||||
callOrderAssert(t, expect, s.callOrder)
|
||||
}
|
||||
|
||||
type tHelper interface {
|
||||
Helper()
|
||||
}
|
||||
|
||||
// callOrderAssert is a help with confirms that asserts that expect
|
||||
// matches one or more times in callOrder. This makes it compatible
|
||||
// with go test flag -count=X where X > 1.
|
||||
func callOrderAssert(t *testing.T, expect, callOrder []string) {
|
||||
var ti interface{} = t
|
||||
if h, ok := ti.(tHelper); ok {
|
||||
h.Helper()
|
||||
}
|
||||
|
||||
callCount := len(callOrder)
|
||||
expectCount := len(expect)
|
||||
if callCount > expectCount && callCount%expectCount == 0 {
|
||||
// Command line flag -count=X where X > 1.
|
||||
for len(callOrder) >= expectCount {
|
||||
assert.Equal(t, expect, callOrder[:expectCount])
|
||||
callOrder = callOrder[expectCount:]
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
assert.Equal(t, expect, callOrder)
|
||||
}
|
||||
|
||||
func TestFailfastSuiteFailFastOn(t *testing.T) {
|
||||
// To test this with failfast on (and isolated from other intended test failures in our test suite) we launch it in its own process
|
||||
cmd := exec.Command("go", "test", "-v", "-race", "-run", "TestFailfastSuite", "-failfast")
|
||||
@ -684,70 +587,3 @@ func (s *FailfastSuite) Test_B_Passes() {
|
||||
s.call("Test B Passes")
|
||||
s.Require().True(true)
|
||||
}
|
||||
|
||||
type subtestPanicSuite struct {
|
||||
Suite
|
||||
inTearDownSuite bool
|
||||
inTearDownTest bool
|
||||
inTearDownSubTest bool
|
||||
}
|
||||
|
||||
func (s *subtestPanicSuite) TearDownSuite() {
|
||||
s.inTearDownSuite = true
|
||||
}
|
||||
|
||||
func (s *subtestPanicSuite) TearDownTest() {
|
||||
s.inTearDownTest = true
|
||||
}
|
||||
|
||||
func (s *subtestPanicSuite) TearDownSubTest() {
|
||||
s.inTearDownSubTest = true
|
||||
}
|
||||
|
||||
func (s *subtestPanicSuite) TestSubtestPanic() {
|
||||
ok := s.Run("subtest", func() {
|
||||
panic("panic")
|
||||
})
|
||||
s.False(ok, "subtest failure is expected")
|
||||
}
|
||||
|
||||
func TestSubtestPanic(t *testing.T) {
|
||||
suite := new(subtestPanicSuite)
|
||||
ok := testing.RunTests(
|
||||
allTestsFilter,
|
||||
[]testing.InternalTest{{
|
||||
Name: t.Name() + "/subtestPanicSuite",
|
||||
F: func(t *testing.T) {
|
||||
Run(t, suite)
|
||||
},
|
||||
}},
|
||||
)
|
||||
assert.False(t, ok, "TestSubtestPanic/subtest should make the testsuite fail")
|
||||
assert.True(t, suite.inTearDownSubTest)
|
||||
assert.True(t, suite.inTearDownTest)
|
||||
assert.True(t, suite.inTearDownSuite)
|
||||
}
|
||||
|
||||
type unInitializedSuite struct {
|
||||
Suite
|
||||
}
|
||||
|
||||
// TestUnInitializedSuites asserts the behavior of the suite methods when the
|
||||
// suite is not initialized
|
||||
func TestUnInitializedSuites(t *testing.T) {
|
||||
t.Run("should panic on Require", func(t *testing.T) {
|
||||
suite := new(unInitializedSuite)
|
||||
|
||||
assert.Panics(t, func() {
|
||||
suite.Require().True(true)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("should panic on Assert", func(t *testing.T) {
|
||||
suite := new(unInitializedSuite)
|
||||
|
||||
assert.Panics(t, func() {
|
||||
suite.Assert().True(true)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user