1package assert
2
3import (
4 "bufio"
5 "bytes"
6 "encoding/json"
7 "errors"
8 "fmt"
9 "math"
10 "os"
11 "reflect"
12 "regexp"
13 "runtime"
14 "strings"
15 "time"
16 "unicode"
17 "unicode/utf8"
18
19 "github.com/davecgh/go-spew/spew"
20 "github.com/pmezard/go-difflib/difflib"
21)
22
23//go:generate go run ../_codegen/main.go -output-package=assert -template=assertion_format.go.tmpl
24
25// TestingT is an interface wrapper around *testing.T
26type TestingT interface {
27 Errorf(format string, args ...interface{})
28}
29
30// ComparisonAssertionFunc is a common function prototype when comparing two values. Can be useful
31// for table driven tests.
32type ComparisonAssertionFunc func(TestingT, interface{}, interface{}, ...interface{}) bool
33
34// ValueAssertionFunc is a common function prototype when validating a single value. Can be useful
35// for table driven tests.
36type ValueAssertionFunc func(TestingT, interface{}, ...interface{}) bool
37
38// BoolAssertionFunc is a common function prototype when validating a bool value. Can be useful
39// for table driven tests.
40type BoolAssertionFunc func(TestingT, bool, ...interface{}) bool
41
42// ValuesAssertionFunc is a common function prototype when validating an error value. Can be useful
43// for table driven tests.
44type ErrorAssertionFunc func(TestingT, error, ...interface{}) bool
45
46// Comparison a custom function that returns true on success and false on failure
47type Comparison func() (success bool)
48
49/*
50 Helper functions
51*/
52
53// ObjectsAreEqual determines if two objects are considered equal.
54//
55// This function does no assertion of any kind.
56func ObjectsAreEqual(expected, actual interface{}) bool {
57 if expected == nil || actual == nil {
58 return expected == actual
59 }
60
61 exp, ok := expected.([]byte)
62 if !ok {
63 return reflect.DeepEqual(expected, actual)
64 }
65
66 act, ok := actual.([]byte)
67 if !ok {
68 return false
69 }
70 if exp == nil || act == nil {
71 return exp == nil && act == nil
72 }
73 return bytes.Equal(exp, act)
74}
75
76// ObjectsAreEqualValues gets whether two objects are equal, or if their
77// values are equal.
78func ObjectsAreEqualValues(expected, actual interface{}) bool {
79 if ObjectsAreEqual(expected, actual) {
80 return true
81 }
82
83 actualType := reflect.TypeOf(actual)
84 if actualType == nil {
85 return false
86 }
87 expectedValue := reflect.ValueOf(expected)
88 if expectedValue.IsValid() && expectedValue.Type().ConvertibleTo(actualType) {
89 // Attempt comparison after type conversion
90 return reflect.DeepEqual(expectedValue.Convert(actualType).Interface(), actual)
91 }
92
93 return false
94}
95
96/* CallerInfo is necessary because the assert functions use the testing object
97internally, causing it to print the file:line of the assert method, rather than where
98the problem actually occurred in calling code.*/
99
100// CallerInfo returns an array of strings containing the file and line number
101// of each stack frame leading from the current test to the assert call that
102// failed.
103func CallerInfo() []string {
104
105 pc := uintptr(0)
106 file := ""
107 line := 0
108 ok := false
109 name := ""
110
111 callers := []string{}
112 for i := 0; ; i++ {
113 pc, file, line, ok = runtime.Caller(i)
114 if !ok {
115 // The breaks below failed to terminate the loop, and we ran off the
116 // end of the call stack.
117 break
118 }
119
120 // This is a huge edge case, but it will panic if this is the case, see #180
121 if file == "<autogenerated>" {
122 break
123 }
124
125 f := runtime.FuncForPC(pc)
126 if f == nil {
127 break
128 }
129 name = f.Name()
130
131 // testing.tRunner is the standard library function that calls
132 // tests. Subtests are called directly by tRunner, without going through
133 // the Test/Benchmark/Example function that contains the t.Run calls, so
134 // with subtests we should break when we hit tRunner, without adding it
135 // to the list of callers.
136 if name == "testing.tRunner" {
137 break
138 }
139
140 parts := strings.Split(file, "/")
141 file = parts[len(parts)-1]
142 if len(parts) > 1 {
143 dir := parts[len(parts)-2]
144 if (dir != "assert" && dir != "mock" && dir != "require") || file == "mock_test.go" {
145 callers = append(callers, fmt.Sprintf("%s:%d", file, line))
146 }
147 }
148
149 // Drop the package
150 segments := strings.Split(name, ".")
151 name = segments[len(segments)-1]
152 if isTest(name, "Test") ||
153 isTest(name, "Benchmark") ||
154 isTest(name, "Example") {
155 break
156 }
157 }
158
159 return callers
160}
161
162// Stolen from the `go test` tool.
163// isTest tells whether name looks like a test (or benchmark, according to prefix).
164// It is a Test (say) if there is a character after Test that is not a lower-case letter.
165// We don't want TesticularCancer.
166func isTest(name, prefix string) bool {
167 if !strings.HasPrefix(name, prefix) {
168 return false
169 }
170 if len(name) == len(prefix) { // "Test" is ok
171 return true
172 }
173 rune, _ := utf8.DecodeRuneInString(name[len(prefix):])
174 return !unicode.IsLower(rune)
175}
176
177func messageFromMsgAndArgs(msgAndArgs ...interface{}) string {
178 if len(msgAndArgs) == 0 || msgAndArgs == nil {
179 return ""
180 }
181 if len(msgAndArgs) == 1 {
182 return msgAndArgs[0].(string)
183 }
184 if len(msgAndArgs) > 1 {
185 return fmt.Sprintf(msgAndArgs[0].(string), msgAndArgs[1:]...)
186 }
187 return ""
188}
189
190// Aligns the provided message so that all lines after the first line start at the same location as the first line.
191// Assumes that the first line starts at the correct location (after carriage return, tab, label, spacer and tab).
192// The longestLabelLen parameter specifies the length of the longest label in the output (required becaues this is the
193// basis on which the alignment occurs).
194func indentMessageLines(message string, longestLabelLen int) string {
195 outBuf := new(bytes.Buffer)
196
197 for i, scanner := 0, bufio.NewScanner(strings.NewReader(message)); scanner.Scan(); i++ {
198 // no need to align first line because it starts at the correct location (after the label)
199 if i != 0 {
200 // append alignLen+1 spaces to align with "{{longestLabel}}:" before adding tab
201 outBuf.WriteString("\n\t" + strings.Repeat(" ", longestLabelLen+1) + "\t")
202 }
203 outBuf.WriteString(scanner.Text())
204 }
205
206 return outBuf.String()
207}
208
209type failNower interface {
210 FailNow()
211}
212
213// FailNow fails test
214func FailNow(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool {
215 if h, ok := t.(tHelper); ok {
216 h.Helper()
217 }
218 Fail(t, failureMessage, msgAndArgs...)
219
220 // We cannot extend TestingT with FailNow() and
221 // maintain backwards compatibility, so we fallback
222 // to panicking when FailNow is not available in
223 // TestingT.
224 // See issue #263
225
226 if t, ok := t.(failNower); ok {
227 t.FailNow()
228 } else {
229 panic("test failed and t is missing `FailNow()`")
230 }
231 return false
232}
233
234// Fail reports a failure through
235func Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool {
236 if h, ok := t.(tHelper); ok {
237 h.Helper()
238 }
239 content := []labeledContent{
240 {"Error Trace", strings.Join(CallerInfo(), "\n\t\t\t")},
241 {"Error", failureMessage},
242 }
243
244 // Add test name if the Go version supports it
245 if n, ok := t.(interface {
246 Name() string
247 }); ok {
248 content = append(content, labeledContent{"Test", n.Name()})
249 }
250
251 message := messageFromMsgAndArgs(msgAndArgs...)
252 if len(message) > 0 {
253 content = append(content, labeledContent{"Messages", message})
254 }
255
256 t.Errorf("\n%s", ""+labeledOutput(content...))
257
258 return false
259}
260
261type labeledContent struct {
262 label string
263 content string
264}
265
266// labeledOutput returns a string consisting of the provided labeledContent. Each labeled output is appended in the following manner:
267//
268// \t{{label}}:{{align_spaces}}\t{{content}}\n
269//
270// The initial carriage return is required to undo/erase any padding added by testing.T.Errorf. The "\t{{label}}:" is for the label.
271// If a label is shorter than the longest label provided, padding spaces are added to make all the labels match in length. Once this
272// alignment is achieved, "\t{{content}}\n" is added for the output.
273//
274// If the content of the labeledOutput contains line breaks, the subsequent lines are aligned so that they start at the same location as the first line.
275func labeledOutput(content ...labeledContent) string {
276 longestLabel := 0
277 for _, v := range content {
278 if len(v.label) > longestLabel {
279 longestLabel = len(v.label)
280 }
281 }
282 var output string
283 for _, v := range content {
284 output += "\t" + v.label + ":" + strings.Repeat(" ", longestLabel-len(v.label)) + "\t" + indentMessageLines(v.content, longestLabel) + "\n"
285 }
286 return output
287}
288
289// Implements asserts that an object is implemented by the specified interface.
290//
291// assert.Implements(t, (*MyInterface)(nil), new(MyObject))
292func Implements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool {
293 if h, ok := t.(tHelper); ok {
294 h.Helper()
295 }
296 interfaceType := reflect.TypeOf(interfaceObject).Elem()
297
298 if object == nil {
299 return Fail(t, fmt.Sprintf("Cannot check if nil implements %v", interfaceType), msgAndArgs...)
300 }
301 if !reflect.TypeOf(object).Implements(interfaceType) {
302 return Fail(t, fmt.Sprintf("%T must implement %v", object, interfaceType), msgAndArgs...)
303 }
304
305 return true
306}
307
308// IsType asserts that the specified objects are of the same type.
309func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool {
310 if h, ok := t.(tHelper); ok {
311 h.Helper()
312 }
313
314 if !ObjectsAreEqual(reflect.TypeOf(object), reflect.TypeOf(expectedType)) {
315 return Fail(t, fmt.Sprintf("Object expected to be of type %v, but was %v", reflect.TypeOf(expectedType), reflect.TypeOf(object)), msgAndArgs...)
316 }
317
318 return true
319}
320
321// Equal asserts that two objects are equal.
322//
323// assert.Equal(t, 123, 123)
324//
325// Pointer variable equality is determined based on the equality of the
326// referenced values (as opposed to the memory addresses). Function equality
327// cannot be determined and will always fail.
328func Equal(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
329 if h, ok := t.(tHelper); ok {
330 h.Helper()
331 }
332 if err := validateEqualArgs(expected, actual); err != nil {
333 return Fail(t, fmt.Sprintf("Invalid operation: %#v == %#v (%s)",
334 expected, actual, err), msgAndArgs...)
335 }
336
337 if !ObjectsAreEqual(expected, actual) {
338 diff := diff(expected, actual)
339 expected, actual = formatUnequalValues(expected, actual)
340 return Fail(t, fmt.Sprintf("Not equal: \n"+
341 "expected: %s\n"+
342 "actual : %s%s", expected, actual, diff), msgAndArgs...)
343 }
344
345 return true
346
347}
348
349// formatUnequalValues takes two values of arbitrary types and returns string
350// representations appropriate to be presented to the user.
351//
352// If the values are not of like type, the returned strings will be prefixed
353// with the type name, and the value will be enclosed in parenthesis similar
354// to a type conversion in the Go grammar.
355func formatUnequalValues(expected, actual interface{}) (e string, a string) {
356 if reflect.TypeOf(expected) != reflect.TypeOf(actual) {
357 return fmt.Sprintf("%T(%#v)", expected, expected),
358 fmt.Sprintf("%T(%#v)", actual, actual)
359 }
360
361 return fmt.Sprintf("%#v", expected),
362 fmt.Sprintf("%#v", actual)
363}
364
365// EqualValues asserts that two objects are equal or convertable to the same types
366// and equal.
367//
368// assert.EqualValues(t, uint32(123), int32(123))
369func EqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
370 if h, ok := t.(tHelper); ok {
371 h.Helper()
372 }
373
374 if !ObjectsAreEqualValues(expected, actual) {
375 diff := diff(expected, actual)
376 expected, actual = formatUnequalValues(expected, actual)
377 return Fail(t, fmt.Sprintf("Not equal: \n"+
378 "expected: %s\n"+
379 "actual : %s%s", expected, actual, diff), msgAndArgs...)
380 }
381
382 return true
383
384}
385
386// Exactly asserts that two objects are equal in value and type.
387//
388// assert.Exactly(t, int32(123), int64(123))
389func Exactly(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
390 if h, ok := t.(tHelper); ok {
391 h.Helper()
392 }
393
394 aType := reflect.TypeOf(expected)
395 bType := reflect.TypeOf(actual)
396
397 if aType != bType {
398 return Fail(t, fmt.Sprintf("Types expected to match exactly\n\t%v != %v", aType, bType), msgAndArgs...)
399 }
400
401 return Equal(t, expected, actual, msgAndArgs...)
402
403}
404
405// NotNil asserts that the specified object is not nil.
406//
407// assert.NotNil(t, err)
408func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
409 if h, ok := t.(tHelper); ok {
410 h.Helper()
411 }
412 if !isNil(object) {
413 return true
414 }
415 return Fail(t, "Expected value not to be nil.", msgAndArgs...)
416}
417
418// isNil checks if a specified object is nil or not, without Failing.
419func isNil(object interface{}) bool {
420 if object == nil {
421 return true
422 }
423
424 value := reflect.ValueOf(object)
425 kind := value.Kind()
426 if kind >= reflect.Chan && kind <= reflect.Slice && value.IsNil() {
427 return true
428 }
429
430 return false
431}
432
433// Nil asserts that the specified object is nil.
434//
435// assert.Nil(t, err)
436func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
437 if h, ok := t.(tHelper); ok {
438 h.Helper()
439 }
440 if isNil(object) {
441 return true
442 }
443 return Fail(t, fmt.Sprintf("Expected nil, but got: %#v", object), msgAndArgs...)
444}
445
446// isEmpty gets whether the specified object is considered empty or not.
447func isEmpty(object interface{}) bool {
448
449 // get nil case out of the way
450 if object == nil {
451 return true
452 }
453
454 objValue := reflect.ValueOf(object)
455
456 switch objValue.Kind() {
457 // collection types are empty when they have no element
458 case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice:
459 return objValue.Len() == 0
460 // pointers are empty if nil or if the value they point to is empty
461 case reflect.Ptr:
462 if objValue.IsNil() {
463 return true
464 }
465 deref := objValue.Elem().Interface()
466 return isEmpty(deref)
467 // for all other types, compare against the zero value
468 default:
469 zero := reflect.Zero(objValue.Type())
470 return reflect.DeepEqual(object, zero.Interface())
471 }
472}
473
474// Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either
475// a slice or a channel with len == 0.
476//
477// assert.Empty(t, obj)
478func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
479 if h, ok := t.(tHelper); ok {
480 h.Helper()
481 }
482
483 pass := isEmpty(object)
484 if !pass {
485 Fail(t, fmt.Sprintf("Should be empty, but was %v", object), msgAndArgs...)
486 }
487
488 return pass
489
490}
491
492// NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either
493// a slice or a channel with len == 0.
494//
495// if assert.NotEmpty(t, obj) {
496// assert.Equal(t, "two", obj[1])
497// }
498func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
499 if h, ok := t.(tHelper); ok {
500 h.Helper()
501 }
502
503 pass := !isEmpty(object)
504 if !pass {
505 Fail(t, fmt.Sprintf("Should NOT be empty, but was %v", object), msgAndArgs...)
506 }
507
508 return pass
509
510}
511
512// getLen try to get length of object.
513// return (false, 0) if impossible.
514func getLen(x interface{}) (ok bool, length int) {
515 v := reflect.ValueOf(x)
516 defer func() {
517 if e := recover(); e != nil {
518 ok = false
519 }
520 }()
521 return true, v.Len()
522}
523
524// Len asserts that the specified object has specific length.
525// Len also fails if the object has a type that len() not accept.
526//
527// assert.Len(t, mySlice, 3)
528func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) bool {
529 if h, ok := t.(tHelper); ok {
530 h.Helper()
531 }
532 ok, l := getLen(object)
533 if !ok {
534 return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", object), msgAndArgs...)
535 }
536
537 if l != length {
538 return Fail(t, fmt.Sprintf("\"%s\" should have %d item(s), but has %d", object, length, l), msgAndArgs...)
539 }
540 return true
541}
542
543// True asserts that the specified value is true.
544//
545// assert.True(t, myBool)
546func True(t TestingT, value bool, msgAndArgs ...interface{}) bool {
547 if h, ok := t.(tHelper); ok {
548 h.Helper()
549 }
550 if h, ok := t.(interface {
551 Helper()
552 }); ok {
553 h.Helper()
554 }
555
556 if value != true {
557 return Fail(t, "Should be true", msgAndArgs...)
558 }
559
560 return true
561
562}
563
564// False asserts that the specified value is false.
565//
566// assert.False(t, myBool)
567func False(t TestingT, value bool, msgAndArgs ...interface{}) bool {
568 if h, ok := t.(tHelper); ok {
569 h.Helper()
570 }
571
572 if value != false {
573 return Fail(t, "Should be false", msgAndArgs...)
574 }
575
576 return true
577
578}
579
580// NotEqual asserts that the specified values are NOT equal.
581//
582// assert.NotEqual(t, obj1, obj2)
583//
584// Pointer variable equality is determined based on the equality of the
585// referenced values (as opposed to the memory addresses).
586func NotEqual(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
587 if h, ok := t.(tHelper); ok {
588 h.Helper()
589 }
590 if err := validateEqualArgs(expected, actual); err != nil {
591 return Fail(t, fmt.Sprintf("Invalid operation: %#v != %#v (%s)",
592 expected, actual, err), msgAndArgs...)
593 }
594
595 if ObjectsAreEqual(expected, actual) {
596 return Fail(t, fmt.Sprintf("Should not be: %#v\n", actual), msgAndArgs...)
597 }
598
599 return true
600
601}
602
603// containsElement try loop over the list check if the list includes the element.
604// return (false, false) if impossible.
605// return (true, false) if element was not found.
606// return (true, true) if element was found.
607func includeElement(list interface{}, element interface{}) (ok, found bool) {
608
609 listValue := reflect.ValueOf(list)
610 elementValue := reflect.ValueOf(element)
611 defer func() {
612 if e := recover(); e != nil {
613 ok = false
614 found = false
615 }
616 }()
617
618 if reflect.TypeOf(list).Kind() == reflect.String {
619 return true, strings.Contains(listValue.String(), elementValue.String())
620 }
621
622 if reflect.TypeOf(list).Kind() == reflect.Map {
623 mapKeys := listValue.MapKeys()
624 for i := 0; i < len(mapKeys); i++ {
625 if ObjectsAreEqual(mapKeys[i].Interface(), element) {
626 return true, true
627 }
628 }
629 return true, false
630 }
631
632 for i := 0; i < listValue.Len(); i++ {
633 if ObjectsAreEqual(listValue.Index(i).Interface(), element) {
634 return true, true
635 }
636 }
637 return true, false
638
639}
640
641// Contains asserts that the specified string, list(array, slice...) or map contains the
642// specified substring or element.
643//
644// assert.Contains(t, "Hello World", "World")
645// assert.Contains(t, ["Hello", "World"], "World")
646// assert.Contains(t, {"Hello": "World"}, "Hello")
647func Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool {
648 if h, ok := t.(tHelper); ok {
649 h.Helper()
650 }
651
652 ok, found := includeElement(s, contains)
653 if !ok {
654 return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", s), msgAndArgs...)
655 }
656 if !found {
657 return Fail(t, fmt.Sprintf("\"%s\" does not contain \"%s\"", s, contains), msgAndArgs...)
658 }
659
660 return true
661
662}
663
664// NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the
665// specified substring or element.
666//
667// assert.NotContains(t, "Hello World", "Earth")
668// assert.NotContains(t, ["Hello", "World"], "Earth")
669// assert.NotContains(t, {"Hello": "World"}, "Earth")
670func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool {
671 if h, ok := t.(tHelper); ok {
672 h.Helper()
673 }
674
675 ok, found := includeElement(s, contains)
676 if !ok {
677 return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", s), msgAndArgs...)
678 }
679 if found {
680 return Fail(t, fmt.Sprintf("\"%s\" should not contain \"%s\"", s, contains), msgAndArgs...)
681 }
682
683 return true
684
685}
686
687// Subset asserts that the specified list(array, slice...) contains all
688// elements given in the specified subset(array, slice...).
689//
690// assert.Subset(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]")
691func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) {
692 if h, ok := t.(tHelper); ok {
693 h.Helper()
694 }
695 if subset == nil {
696 return true // we consider nil to be equal to the nil set
697 }
698
699 subsetValue := reflect.ValueOf(subset)
700 defer func() {
701 if e := recover(); e != nil {
702 ok = false
703 }
704 }()
705
706 listKind := reflect.TypeOf(list).Kind()
707 subsetKind := reflect.TypeOf(subset).Kind()
708
709 if listKind != reflect.Array && listKind != reflect.Slice {
710 return Fail(t, fmt.Sprintf("%q has an unsupported type %s", list, listKind), msgAndArgs...)
711 }
712
713 if subsetKind != reflect.Array && subsetKind != reflect.Slice {
714 return Fail(t, fmt.Sprintf("%q has an unsupported type %s", subset, subsetKind), msgAndArgs...)
715 }
716
717 for i := 0; i < subsetValue.Len(); i++ {
718 element := subsetValue.Index(i).Interface()
719 ok, found := includeElement(list, element)
720 if !ok {
721 return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", list), msgAndArgs...)
722 }
723 if !found {
724 return Fail(t, fmt.Sprintf("\"%s\" does not contain \"%s\"", list, element), msgAndArgs...)
725 }
726 }
727
728 return true
729}
730
731// NotSubset asserts that the specified list(array, slice...) contains not all
732// elements given in the specified subset(array, slice...).
733//
734// assert.NotSubset(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]")
735func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) {
736 if h, ok := t.(tHelper); ok {
737 h.Helper()
738 }
739 if subset == nil {
740 return Fail(t, fmt.Sprintf("nil is the empty set which is a subset of every set"), msgAndArgs...)
741 }
742
743 subsetValue := reflect.ValueOf(subset)
744 defer func() {
745 if e := recover(); e != nil {
746 ok = false
747 }
748 }()
749
750 listKind := reflect.TypeOf(list).Kind()
751 subsetKind := reflect.TypeOf(subset).Kind()
752
753 if listKind != reflect.Array && listKind != reflect.Slice {
754 return Fail(t, fmt.Sprintf("%q has an unsupported type %s", list, listKind), msgAndArgs...)
755 }
756
757 if subsetKind != reflect.Array && subsetKind != reflect.Slice {
758 return Fail(t, fmt.Sprintf("%q has an unsupported type %s", subset, subsetKind), msgAndArgs...)
759 }
760
761 for i := 0; i < subsetValue.Len(); i++ {
762 element := subsetValue.Index(i).Interface()
763 ok, found := includeElement(list, element)
764 if !ok {
765 return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", list), msgAndArgs...)
766 }
767 if !found {
768 return true
769 }
770 }
771
772 return Fail(t, fmt.Sprintf("%q is a subset of %q", subset, list), msgAndArgs...)
773}
774
775// ElementsMatch asserts that the specified listA(array, slice...) is equal to specified
776// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements,
777// the number of appearances of each of them in both lists should match.
778//
779// assert.ElementsMatch(t, [1, 3, 2, 3], [1, 3, 3, 2])
780func ElementsMatch(t TestingT, listA, listB interface{}, msgAndArgs ...interface{}) (ok bool) {
781 if h, ok := t.(tHelper); ok {
782 h.Helper()
783 }
784 if isEmpty(listA) && isEmpty(listB) {
785 return true
786 }
787
788 aKind := reflect.TypeOf(listA).Kind()
789 bKind := reflect.TypeOf(listB).Kind()
790
791 if aKind != reflect.Array && aKind != reflect.Slice {
792 return Fail(t, fmt.Sprintf("%q has an unsupported type %s", listA, aKind), msgAndArgs...)
793 }
794
795 if bKind != reflect.Array && bKind != reflect.Slice {
796 return Fail(t, fmt.Sprintf("%q has an unsupported type %s", listB, bKind), msgAndArgs...)
797 }
798
799 aValue := reflect.ValueOf(listA)
800 bValue := reflect.ValueOf(listB)
801
802 aLen := aValue.Len()
803 bLen := bValue.Len()
804
805 if aLen != bLen {
806 return Fail(t, fmt.Sprintf("lengths don't match: %d != %d", aLen, bLen), msgAndArgs...)
807 }
808
809 // Mark indexes in bValue that we already used
810 visited := make([]bool, bLen)
811 for i := 0; i < aLen; i++ {
812 element := aValue.Index(i).Interface()
813 found := false
814 for j := 0; j < bLen; j++ {
815 if visited[j] {
816 continue
817 }
818 if ObjectsAreEqual(bValue.Index(j).Interface(), element) {
819 visited[j] = true
820 found = true
821 break
822 }
823 }
824 if !found {
825 return Fail(t, fmt.Sprintf("element %s appears more times in %s than in %s", element, aValue, bValue), msgAndArgs...)
826 }
827 }
828
829 return true
830}
831
832// Condition uses a Comparison to assert a complex condition.
833func Condition(t TestingT, comp Comparison, msgAndArgs ...interface{}) bool {
834 if h, ok := t.(tHelper); ok {
835 h.Helper()
836 }
837 result := comp()
838 if !result {
839 Fail(t, "Condition failed!", msgAndArgs...)
840 }
841 return result
842}
843
844// PanicTestFunc defines a func that should be passed to the assert.Panics and assert.NotPanics
845// methods, and represents a simple func that takes no arguments, and returns nothing.
846type PanicTestFunc func()
847
848// didPanic returns true if the function passed to it panics. Otherwise, it returns false.
849func didPanic(f PanicTestFunc) (bool, interface{}) {
850
851 didPanic := false
852 var message interface{}
853 func() {
854
855 defer func() {
856 if message = recover(); message != nil {
857 didPanic = true
858 }
859 }()
860
861 // call the target function
862 f()
863
864 }()
865
866 return didPanic, message
867
868}
869
870// Panics asserts that the code inside the specified PanicTestFunc panics.
871//
872// assert.Panics(t, func(){ GoCrazy() })
873func Panics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool {
874 if h, ok := t.(tHelper); ok {
875 h.Helper()
876 }
877
878 if funcDidPanic, panicValue := didPanic(f); !funcDidPanic {
879 return Fail(t, fmt.Sprintf("func %#v should panic\n\tPanic value:\t%#v", f, panicValue), msgAndArgs...)
880 }
881
882 return true
883}
884
885// PanicsWithValue asserts that the code inside the specified PanicTestFunc panics, and that
886// the recovered panic value equals the expected panic value.
887//
888// assert.PanicsWithValue(t, "crazy error", func(){ GoCrazy() })
889func PanicsWithValue(t TestingT, expected interface{}, f PanicTestFunc, msgAndArgs ...interface{}) bool {
890 if h, ok := t.(tHelper); ok {
891 h.Helper()
892 }
893
894 funcDidPanic, panicValue := didPanic(f)
895 if !funcDidPanic {
896 return Fail(t, fmt.Sprintf("func %#v should panic\n\tPanic value:\t%#v", f, panicValue), msgAndArgs...)
897 }
898 if panicValue != expected {
899 return Fail(t, fmt.Sprintf("func %#v should panic with value:\t%#v\n\tPanic value:\t%#v", f, expected, panicValue), msgAndArgs...)
900 }
901
902 return true
903}
904
905// NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic.
906//
907// assert.NotPanics(t, func(){ RemainCalm() })
908func NotPanics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool {
909 if h, ok := t.(tHelper); ok {
910 h.Helper()
911 }
912
913 if funcDidPanic, panicValue := didPanic(f); funcDidPanic {
914 return Fail(t, fmt.Sprintf("func %#v should not panic\n\tPanic value:\t%v", f, panicValue), msgAndArgs...)
915 }
916
917 return true
918}
919
920// WithinDuration asserts that the two times are within duration delta of each other.
921//
922// assert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second)
923func WithinDuration(t TestingT, expected, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool {
924 if h, ok := t.(tHelper); ok {
925 h.Helper()
926 }
927
928 dt := expected.Sub(actual)
929 if dt < -delta || dt > delta {
930 return Fail(t, fmt.Sprintf("Max difference between %v and %v allowed is %v, but difference was %v", expected, actual, delta, dt), msgAndArgs...)
931 }
932
933 return true
934}
935
936func toFloat(x interface{}) (float64, bool) {
937 var xf float64
938 xok := true
939
940 switch xn := x.(type) {
941 case uint8:
942 xf = float64(xn)
943 case uint16:
944 xf = float64(xn)
945 case uint32:
946 xf = float64(xn)
947 case uint64:
948 xf = float64(xn)
949 case int:
950 xf = float64(xn)
951 case int8:
952 xf = float64(xn)
953 case int16:
954 xf = float64(xn)
955 case int32:
956 xf = float64(xn)
957 case int64:
958 xf = float64(xn)
959 case float32:
960 xf = float64(xn)
961 case float64:
962 xf = float64(xn)
963 case time.Duration:
964 xf = float64(xn)
965 default:
966 xok = false
967 }
968
969 return xf, xok
970}
971
972// InDelta asserts that the two numerals are within delta of each other.
973//
974// assert.InDelta(t, math.Pi, (22 / 7.0), 0.01)
975func InDelta(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
976 if h, ok := t.(tHelper); ok {
977 h.Helper()
978 }
979
980 af, aok := toFloat(expected)
981 bf, bok := toFloat(actual)
982
983 if !aok || !bok {
984 return Fail(t, fmt.Sprintf("Parameters must be numerical"), msgAndArgs...)
985 }
986
987 if math.IsNaN(af) {
988 return Fail(t, fmt.Sprintf("Expected must not be NaN"), msgAndArgs...)
989 }
990
991 if math.IsNaN(bf) {
992 return Fail(t, fmt.Sprintf("Expected %v with delta %v, but was NaN", expected, delta), msgAndArgs...)
993 }
994
995 dt := af - bf
996 if dt < -delta || dt > delta {
997 return Fail(t, fmt.Sprintf("Max difference between %v and %v allowed is %v, but difference was %v", expected, actual, delta, dt), msgAndArgs...)
998 }
999
1000 return true
1001}
1002
1003// InDeltaSlice is the same as InDelta, except it compares two slices.
1004func InDeltaSlice(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
1005 if h, ok := t.(tHelper); ok {
1006 h.Helper()
1007 }
1008 if expected == nil || actual == nil ||
1009 reflect.TypeOf(actual).Kind() != reflect.Slice ||
1010 reflect.TypeOf(expected).Kind() != reflect.Slice {
1011 return Fail(t, fmt.Sprintf("Parameters must be slice"), msgAndArgs...)
1012 }
1013
1014 actualSlice := reflect.ValueOf(actual)
1015 expectedSlice := reflect.ValueOf(expected)
1016
1017 for i := 0; i < actualSlice.Len(); i++ {
1018 result := InDelta(t, actualSlice.Index(i).Interface(), expectedSlice.Index(i).Interface(), delta, msgAndArgs...)
1019 if !result {
1020 return result
1021 }
1022 }
1023
1024 return true
1025}
1026
1027// InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.
1028func InDeltaMapValues(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
1029 if h, ok := t.(tHelper); ok {
1030 h.Helper()
1031 }
1032 if expected == nil || actual == nil ||
1033 reflect.TypeOf(actual).Kind() != reflect.Map ||
1034 reflect.TypeOf(expected).Kind() != reflect.Map {
1035 return Fail(t, "Arguments must be maps", msgAndArgs...)
1036 }
1037
1038 expectedMap := reflect.ValueOf(expected)
1039 actualMap := reflect.ValueOf(actual)
1040
1041 if expectedMap.Len() != actualMap.Len() {
1042 return Fail(t, "Arguments must have the same number of keys", msgAndArgs...)
1043 }
1044
1045 for _, k := range expectedMap.MapKeys() {
1046 ev := expectedMap.MapIndex(k)
1047 av := actualMap.MapIndex(k)
1048
1049 if !ev.IsValid() {
1050 return Fail(t, fmt.Sprintf("missing key %q in expected map", k), msgAndArgs...)
1051 }
1052
1053 if !av.IsValid() {
1054 return Fail(t, fmt.Sprintf("missing key %q in actual map", k), msgAndArgs...)
1055 }
1056
1057 if !InDelta(
1058 t,
1059 ev.Interface(),
1060 av.Interface(),
1061 delta,
1062 msgAndArgs...,
1063 ) {
1064 return false
1065 }
1066 }
1067
1068 return true
1069}
1070
1071func calcRelativeError(expected, actual interface{}) (float64, error) {
1072 af, aok := toFloat(expected)
1073 if !aok {
1074 return 0, fmt.Errorf("expected value %q cannot be converted to float", expected)
1075 }
1076 if af == 0 {
1077 return 0, fmt.Errorf("expected value must have a value other than zero to calculate the relative error")
1078 }
1079 bf, bok := toFloat(actual)
1080 if !bok {
1081 return 0, fmt.Errorf("actual value %q cannot be converted to float", actual)
1082 }
1083
1084 return math.Abs(af-bf) / math.Abs(af), nil
1085}
1086
1087// InEpsilon asserts that expected and actual have a relative error less than epsilon
1088func InEpsilon(t TestingT, expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool {
1089 if h, ok := t.(tHelper); ok {
1090 h.Helper()
1091 }
1092 actualEpsilon, err := calcRelativeError(expected, actual)
1093 if err != nil {
1094 return Fail(t, err.Error(), msgAndArgs...)
1095 }
1096 if actualEpsilon > epsilon {
1097 return Fail(t, fmt.Sprintf("Relative error is too high: %#v (expected)\n"+
1098 " < %#v (actual)", epsilon, actualEpsilon), msgAndArgs...)
1099 }
1100
1101 return true
1102}
1103
1104// InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices.
1105func InEpsilonSlice(t TestingT, expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool {
1106 if h, ok := t.(tHelper); ok {
1107 h.Helper()
1108 }
1109 if expected == nil || actual == nil ||
1110 reflect.TypeOf(actual).Kind() != reflect.Slice ||
1111 reflect.TypeOf(expected).Kind() != reflect.Slice {
1112 return Fail(t, fmt.Sprintf("Parameters must be slice"), msgAndArgs...)
1113 }
1114
1115 actualSlice := reflect.ValueOf(actual)
1116 expectedSlice := reflect.ValueOf(expected)
1117
1118 for i := 0; i < actualSlice.Len(); i++ {
1119 result := InEpsilon(t, actualSlice.Index(i).Interface(), expectedSlice.Index(i).Interface(), epsilon)
1120 if !result {
1121 return result
1122 }
1123 }
1124
1125 return true
1126}
1127
1128/*
1129 Errors
1130*/
1131
1132// NoError asserts that a function returned no error (i.e. `nil`).
1133//
1134// actualObj, err := SomeFunction()
1135// if assert.NoError(t, err) {
1136// assert.Equal(t, expectedObj, actualObj)
1137// }
1138func NoError(t TestingT, err error, msgAndArgs ...interface{}) bool {
1139 if h, ok := t.(tHelper); ok {
1140 h.Helper()
1141 }
1142 if err != nil {
1143 return Fail(t, fmt.Sprintf("Received unexpected error:\n%+v", err), msgAndArgs...)
1144 }
1145
1146 return true
1147}
1148
1149// Error asserts that a function returned an error (i.e. not `nil`).
1150//
1151// actualObj, err := SomeFunction()
1152// if assert.Error(t, err) {
1153// assert.Equal(t, expectedError, err)
1154// }
1155func Error(t TestingT, err error, msgAndArgs ...interface{}) bool {
1156 if h, ok := t.(tHelper); ok {
1157 h.Helper()
1158 }
1159
1160 if err == nil {
1161 return Fail(t, "An error is expected but got nil.", msgAndArgs...)
1162 }
1163
1164 return true
1165}
1166
1167// EqualError asserts that a function returned an error (i.e. not `nil`)
1168// and that it is equal to the provided error.
1169//
1170// actualObj, err := SomeFunction()
1171// assert.EqualError(t, err, expectedErrorString)
1172func EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) bool {
1173 if h, ok := t.(tHelper); ok {
1174 h.Helper()
1175 }
1176 if !Error(t, theError, msgAndArgs...) {
1177 return false
1178 }
1179 expected := errString
1180 actual := theError.Error()
1181 // don't need to use deep equals here, we know they are both strings
1182 if expected != actual {
1183 return Fail(t, fmt.Sprintf("Error message not equal:\n"+
1184 "expected: %q\n"+
1185 "actual : %q", expected, actual), msgAndArgs...)
1186 }
1187 return true
1188}
1189
1190// matchRegexp return true if a specified regexp matches a string.
1191func matchRegexp(rx interface{}, str interface{}) bool {
1192
1193 var r *regexp.Regexp
1194 if rr, ok := rx.(*regexp.Regexp); ok {
1195 r = rr
1196 } else {
1197 r = regexp.MustCompile(fmt.Sprint(rx))
1198 }
1199
1200 return (r.FindStringIndex(fmt.Sprint(str)) != nil)
1201
1202}
1203
1204// Regexp asserts that a specified regexp matches a string.
1205//
1206// assert.Regexp(t, regexp.MustCompile("start"), "it's starting")
1207// assert.Regexp(t, "start...$", "it's not starting")
1208func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool {
1209 if h, ok := t.(tHelper); ok {
1210 h.Helper()
1211 }
1212
1213 match := matchRegexp(rx, str)
1214
1215 if !match {
1216 Fail(t, fmt.Sprintf("Expect \"%v\" to match \"%v\"", str, rx), msgAndArgs...)
1217 }
1218
1219 return match
1220}
1221
1222// NotRegexp asserts that a specified regexp does not match a string.
1223//
1224// assert.NotRegexp(t, regexp.MustCompile("starts"), "it's starting")
1225// assert.NotRegexp(t, "^start", "it's not starting")
1226func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool {
1227 if h, ok := t.(tHelper); ok {
1228 h.Helper()
1229 }
1230 match := matchRegexp(rx, str)
1231
1232 if match {
1233 Fail(t, fmt.Sprintf("Expect \"%v\" to NOT match \"%v\"", str, rx), msgAndArgs...)
1234 }
1235
1236 return !match
1237
1238}
1239
1240// Zero asserts that i is the zero value for its type.
1241func Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool {
1242 if h, ok := t.(tHelper); ok {
1243 h.Helper()
1244 }
1245 if i != nil && !reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) {
1246 return Fail(t, fmt.Sprintf("Should be zero, but was %v", i), msgAndArgs...)
1247 }
1248 return true
1249}
1250
1251// NotZero asserts that i is not the zero value for its type.
1252func NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool {
1253 if h, ok := t.(tHelper); ok {
1254 h.Helper()
1255 }
1256 if i == nil || reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) {
1257 return Fail(t, fmt.Sprintf("Should not be zero, but was %v", i), msgAndArgs...)
1258 }
1259 return true
1260}
1261
1262// FileExists checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file.
1263func FileExists(t TestingT, path string, msgAndArgs ...interface{}) bool {
1264 if h, ok := t.(tHelper); ok {
1265 h.Helper()
1266 }
1267 info, err := os.Lstat(path)
1268 if err != nil {
1269 if os.IsNotExist(err) {
1270 return Fail(t, fmt.Sprintf("unable to find file %q", path), msgAndArgs...)
1271 }
1272 return Fail(t, fmt.Sprintf("error when running os.Lstat(%q): %s", path, err), msgAndArgs...)
1273 }
1274 if info.IsDir() {
1275 return Fail(t, fmt.Sprintf("%q is a directory", path), msgAndArgs...)
1276 }
1277 return true
1278}
1279
1280// DirExists checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists.
1281func DirExists(t TestingT, path string, msgAndArgs ...interface{}) bool {
1282 if h, ok := t.(tHelper); ok {
1283 h.Helper()
1284 }
1285 info, err := os.Lstat(path)
1286 if err != nil {
1287 if os.IsNotExist(err) {
1288 return Fail(t, fmt.Sprintf("unable to find file %q", path), msgAndArgs...)
1289 }
1290 return Fail(t, fmt.Sprintf("error when running os.Lstat(%q): %s", path, err), msgAndArgs...)
1291 }
1292 if !info.IsDir() {
1293 return Fail(t, fmt.Sprintf("%q is a file", path), msgAndArgs...)
1294 }
1295 return true
1296}
1297
1298// JSONEq asserts that two JSON strings are equivalent.
1299//
1300// assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
1301func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) bool {
1302 if h, ok := t.(tHelper); ok {
1303 h.Helper()
1304 }
1305 var expectedJSONAsInterface, actualJSONAsInterface interface{}
1306
1307 if err := json.Unmarshal([]byte(expected), &expectedJSONAsInterface); err != nil {
1308 return Fail(t, fmt.Sprintf("Expected value ('%s') is not valid json.\nJSON parsing error: '%s'", expected, err.Error()), msgAndArgs...)
1309 }
1310
1311 if err := json.Unmarshal([]byte(actual), &actualJSONAsInterface); err != nil {
1312 return Fail(t, fmt.Sprintf("Input ('%s') needs to be valid json.\nJSON parsing error: '%s'", actual, err.Error()), msgAndArgs...)
1313 }
1314
1315 return Equal(t, expectedJSONAsInterface, actualJSONAsInterface, msgAndArgs...)
1316}
1317
1318func typeAndKind(v interface{}) (reflect.Type, reflect.Kind) {
1319 t := reflect.TypeOf(v)
1320 k := t.Kind()
1321
1322 if k == reflect.Ptr {
1323 t = t.Elem()
1324 k = t.Kind()
1325 }
1326 return t, k
1327}
1328
1329// diff returns a diff of both values as long as both are of the same type and
1330// are a struct, map, slice or array. Otherwise it returns an empty string.
1331func diff(expected interface{}, actual interface{}) string {
1332 if expected == nil || actual == nil {
1333 return ""
1334 }
1335
1336 et, ek := typeAndKind(expected)
1337 at, _ := typeAndKind(actual)
1338
1339 if et != at {
1340 return ""
1341 }
1342
1343 if ek != reflect.Struct && ek != reflect.Map && ek != reflect.Slice && ek != reflect.Array && ek != reflect.String {
1344 return ""
1345 }
1346
1347 var e, a string
1348 if ek != reflect.String {
1349 e = spewConfig.Sdump(expected)
1350 a = spewConfig.Sdump(actual)
1351 } else {
1352 e = expected.(string)
1353 a = actual.(string)
1354 }
1355
1356 diff, _ := difflib.GetUnifiedDiffString(difflib.UnifiedDiff{
1357 A: difflib.SplitLines(e),
1358 B: difflib.SplitLines(a),
1359 FromFile: "Expected",
1360 FromDate: "",
1361 ToFile: "Actual",
1362 ToDate: "",
1363 Context: 1,
1364 })
1365
1366 return "\n\nDiff:\n" + diff
1367}
1368
1369// validateEqualArgs checks whether provided arguments can be safely used in the
1370// Equal/NotEqual functions.
1371func validateEqualArgs(expected, actual interface{}) error {
1372 if isFunction(expected) || isFunction(actual) {
1373 return errors.New("cannot take func type as argument")
1374 }
1375 return nil
1376}
1377
1378func isFunction(arg interface{}) bool {
1379 if arg == nil {
1380 return false
1381 }
1382 return reflect.TypeOf(arg).Kind() == reflect.Func
1383}
1384
1385var spewConfig = spew.ConfigState{
1386 Indent: " ",
1387 DisablePointerAddresses: true,
1388 DisableCapacities: true,
1389 SortKeys: true,
1390}
1391
1392type tHelper interface {
1393 Helper()
1394}