1/*Package assert provides assertions for comparing expected values to actual
2values. When an assertion fails a helpful error message is printed.
3
4Assert and Check
5
6Assert() and Check() both accept a Comparison, and fail the test when the
7comparison fails. The one difference is that Assert() will end the test execution
8immediately (using t.FailNow()) whereas Check() will fail the test (using t.Fail()),
9return the value of the comparison, then proceed with the rest of the test case.
10
11Example usage
12
13The example below shows assert used with some common types.
14
15
16	import (
17	    "testing"
18
19	    "gotest.tools/assert"
20	    is "gotest.tools/assert/cmp"
21	)
22
23	func TestEverything(t *testing.T) {
24	    // booleans
25	    assert.Assert(t, ok)
26	    assert.Assert(t, !missing)
27
28	    // primitives
29	    assert.Equal(t, count, 1)
30	    assert.Equal(t, msg, "the message")
31	    assert.Assert(t, total != 10) // NotEqual
32
33	    // errors
34	    assert.NilError(t, closer.Close())
35	    assert.Error(t, err, "the exact error message")
36	    assert.ErrorContains(t, err, "includes this")
37	    assert.ErrorType(t, err, os.IsNotExist)
38
39	    // complex types
40	    assert.DeepEqual(t, result, myStruct{Name: "title"})
41	    assert.Assert(t, is.Len(items, 3))
42	    assert.Assert(t, len(sequence) != 0) // NotEmpty
43	    assert.Assert(t, is.Contains(mapping, "key"))
44
45	    // pointers and interface
46	    assert.Assert(t, is.Nil(ref))
47	    assert.Assert(t, ref != nil) // NotNil
48	}
49
50Comparisons
51
52Package http://pkg.go.dev/gotest.tools/v3/assert/cmp provides
53many common comparisons. Additional comparisons can be written to compare
54values in other ways. See the example Assert (CustomComparison).
55
56Automated migration from testify
57
58gty-migrate-from-testify is a command which translates Go source code from
59testify assertions to the assertions provided by this package.
60
61See http://pkg.go.dev/gotest.tools/v3/assert/cmd/gty-migrate-from-testify.
62
63
64*/
65package assert // import "gotest.tools/v3/assert"
66
67import (
68	gocmp "github.com/google/go-cmp/cmp"
69	"gotest.tools/v3/assert/cmp"
70	"gotest.tools/v3/internal/assert"
71)
72
73// BoolOrComparison can be a bool, or cmp.Comparison. See Assert() for usage.
74type BoolOrComparison interface{}
75
76// TestingT is the subset of testing.T used by the assert package.
77type TestingT interface {
78	FailNow()
79	Fail()
80	Log(args ...interface{})
81}
82
83type helperT interface {
84	Helper()
85}
86
87// Assert performs a comparison. If the comparison fails, the test is marked as
88// failed, a failure message is logged, and execution is stopped immediately.
89//
90// The comparison argument may be one of three types:
91//   bool
92// True is success. False is a failure.
93// The failure message will contain the literal source code of the expression.
94//   cmp.Comparison
95// Uses cmp.Result.Success() to check for success of failure.
96// The comparison is responsible for producing a helpful failure message.
97// http://pkg.go.dev/gotest.tools/v3/assert/cmp provides many common comparisons.
98//   error
99// A nil value is considered success.
100// A non-nil error is a failure, err.Error() is used as the failure message.
101func Assert(t TestingT, comparison BoolOrComparison, msgAndArgs ...interface{}) {
102	if ht, ok := t.(helperT); ok {
103		ht.Helper()
104	}
105	if !assert.Eval(t, assert.ArgsFromComparisonCall, comparison, msgAndArgs...) {
106		t.FailNow()
107	}
108}
109
110// Check performs a comparison. If the comparison fails the test is marked as
111// failed, a failure message is logged, and Check returns false. Otherwise returns
112// true.
113//
114// See Assert for details about the comparison arg and failure messages.
115func Check(t TestingT, comparison BoolOrComparison, msgAndArgs ...interface{}) bool {
116	if ht, ok := t.(helperT); ok {
117		ht.Helper()
118	}
119	if !assert.Eval(t, assert.ArgsFromComparisonCall, comparison, msgAndArgs...) {
120		t.Fail()
121		return false
122	}
123	return true
124}
125
126// NilError fails the test immediately if err is not nil.
127// This is equivalent to Assert(t, err)
128func NilError(t TestingT, err error, msgAndArgs ...interface{}) {
129	if ht, ok := t.(helperT); ok {
130		ht.Helper()
131	}
132	if !assert.Eval(t, assert.ArgsAfterT, err, msgAndArgs...) {
133		t.FailNow()
134	}
135}
136
137// Equal uses the == operator to assert two values are equal and fails the test
138// if they are not equal.
139//
140// If the comparison fails Equal will use the variable names for x and y as part
141// of the failure message to identify the actual and expected values.
142//
143// If either x or y are a multi-line string the failure message will include a
144// unified diff of the two values. If the values only differ by whitespace
145// the unified diff will be augmented by replacing whitespace characters with
146// visible characters to identify the whitespace difference.
147//
148// This is equivalent to Assert(t, cmp.Equal(x, y)).
149func Equal(t TestingT, x, y interface{}, msgAndArgs ...interface{}) {
150	if ht, ok := t.(helperT); ok {
151		ht.Helper()
152	}
153	if !assert.Eval(t, assert.ArgsAfterT, cmp.Equal(x, y), msgAndArgs...) {
154		t.FailNow()
155	}
156}
157
158// DeepEqual uses google/go-cmp (https://godoc.org/github.com/google/go-cmp/cmp)
159// to assert two values are equal and fails the test if they are not equal.
160//
161// Package http://pkg.go.dev/gotest.tools/v3/assert/opt provides some additional
162// commonly used Options.
163//
164// This is equivalent to Assert(t, cmp.DeepEqual(x, y)).
165func DeepEqual(t TestingT, x, y interface{}, opts ...gocmp.Option) {
166	if ht, ok := t.(helperT); ok {
167		ht.Helper()
168	}
169	if !assert.Eval(t, assert.ArgsAfterT, cmp.DeepEqual(x, y, opts...)) {
170		t.FailNow()
171	}
172}
173
174// Error fails the test if err is nil, or the error message is not the expected
175// message.
176// Equivalent to Assert(t, cmp.Error(err, message)).
177func Error(t TestingT, err error, message string, msgAndArgs ...interface{}) {
178	if ht, ok := t.(helperT); ok {
179		ht.Helper()
180	}
181	if !assert.Eval(t, assert.ArgsAfterT, cmp.Error(err, message), msgAndArgs...) {
182		t.FailNow()
183	}
184}
185
186// ErrorContains fails the test if err is nil, or the error message does not
187// contain the expected substring.
188// Equivalent to Assert(t, cmp.ErrorContains(err, substring)).
189func ErrorContains(t TestingT, err error, substring string, msgAndArgs ...interface{}) {
190	if ht, ok := t.(helperT); ok {
191		ht.Helper()
192	}
193	if !assert.Eval(t, assert.ArgsAfterT, cmp.ErrorContains(err, substring), msgAndArgs...) {
194		t.FailNow()
195	}
196}
197
198// ErrorType fails the test if err is nil, or err is not the expected type.
199// Equivalent to Assert(t, cmp.ErrorType(err, expected)).
200//
201// Expected can be one of:
202//   func(error) bool
203// Function should return true if the error is the expected type.
204//   type struct{}, type &struct{}
205// A struct or a pointer to a struct.
206// Fails if the error is not of the same type as expected.
207//   type &interface{}
208// A pointer to an interface type.
209// Fails if err does not implement the interface.
210//   reflect.Type
211// Fails if err does not implement the reflect.Type
212func ErrorType(t TestingT, err error, expected interface{}, msgAndArgs ...interface{}) {
213	if ht, ok := t.(helperT); ok {
214		ht.Helper()
215	}
216	if !assert.Eval(t, assert.ArgsAfterT, cmp.ErrorType(err, expected), msgAndArgs...) {
217		t.FailNow()
218	}
219}
220