1 package assert
2
3 import (
4 "bufio"
5 "bytes"
6 "encoding/json"
7 "errors"
8 "fmt"
9 "math"
10 "os"
11 "reflect"
12 "regexp"
13 "runtime"
14 "runtime/debug"
15 "strings"
16 "time"
17 "unicode"
18 "unicode/utf8"
19
20 "github.com/davecgh/go-spew/spew"
21 "github.com/pmezard/go-difflib/difflib"
22 "gopkg.in/yaml.v3"
23 )
24
25
26
27
28 type TestingT interface {
29 Errorf(format string, args ...interface{})
30 }
31
32
33
34 type ComparisonAssertionFunc func(TestingT, interface{}, interface{}, ...interface{}) bool
35
36
37
38 type ValueAssertionFunc func(TestingT, interface{}, ...interface{}) bool
39
40
41
42 type BoolAssertionFunc func(TestingT, bool, ...interface{}) bool
43
44
45
46 type ErrorAssertionFunc func(TestingT, error, ...interface{}) bool
47
48
49 type Comparison func() (success bool)
50
51
54
55
56
57
58 func ObjectsAreEqual(expected, actual interface{}) bool {
59 if expected == nil || actual == nil {
60 return expected == actual
61 }
62
63 exp, ok := expected.([]byte)
64 if !ok {
65 return reflect.DeepEqual(expected, actual)
66 }
67
68 act, ok := actual.([]byte)
69 if !ok {
70 return false
71 }
72 if exp == nil || act == nil {
73 return exp == nil && act == nil
74 }
75 return bytes.Equal(exp, act)
76 }
77
78
79
80 func copyExportedFields(expected interface{}) interface{} {
81 if isNil(expected) {
82 return expected
83 }
84
85 expectedType := reflect.TypeOf(expected)
86 expectedKind := expectedType.Kind()
87 expectedValue := reflect.ValueOf(expected)
88
89 switch expectedKind {
90 case reflect.Struct:
91 result := reflect.New(expectedType).Elem()
92 for i := 0; i < expectedType.NumField(); i++ {
93 field := expectedType.Field(i)
94 isExported := field.IsExported()
95 if isExported {
96 fieldValue := expectedValue.Field(i)
97 if isNil(fieldValue) || isNil(fieldValue.Interface()) {
98 continue
99 }
100 newValue := copyExportedFields(fieldValue.Interface())
101 result.Field(i).Set(reflect.ValueOf(newValue))
102 }
103 }
104 return result.Interface()
105
106 case reflect.Ptr:
107 result := reflect.New(expectedType.Elem())
108 unexportedRemoved := copyExportedFields(expectedValue.Elem().Interface())
109 result.Elem().Set(reflect.ValueOf(unexportedRemoved))
110 return result.Interface()
111
112 case reflect.Array, reflect.Slice:
113 var result reflect.Value
114 if expectedKind == reflect.Array {
115 result = reflect.New(reflect.ArrayOf(expectedValue.Len(), expectedType.Elem())).Elem()
116 } else {
117 result = reflect.MakeSlice(expectedType, expectedValue.Len(), expectedValue.Len())
118 }
119 for i := 0; i < expectedValue.Len(); i++ {
120 index := expectedValue.Index(i)
121 if isNil(index) {
122 continue
123 }
124 unexportedRemoved := copyExportedFields(index.Interface())
125 result.Index(i).Set(reflect.ValueOf(unexportedRemoved))
126 }
127 return result.Interface()
128
129 case reflect.Map:
130 result := reflect.MakeMap(expectedType)
131 for _, k := range expectedValue.MapKeys() {
132 index := expectedValue.MapIndex(k)
133 unexportedRemoved := copyExportedFields(index.Interface())
134 result.SetMapIndex(k, reflect.ValueOf(unexportedRemoved))
135 }
136 return result.Interface()
137
138 default:
139 return expected
140 }
141 }
142
143
144
145
146
147
148
149
150 func ObjectsExportedFieldsAreEqual(expected, actual interface{}) bool {
151 expectedCleaned := copyExportedFields(expected)
152 actualCleaned := copyExportedFields(actual)
153 return ObjectsAreEqualValues(expectedCleaned, actualCleaned)
154 }
155
156
157
158 func ObjectsAreEqualValues(expected, actual interface{}) bool {
159 if ObjectsAreEqual(expected, actual) {
160 return true
161 }
162
163 expectedValue := reflect.ValueOf(expected)
164 actualValue := reflect.ValueOf(actual)
165 if !expectedValue.IsValid() || !actualValue.IsValid() {
166 return false
167 }
168
169 expectedType := expectedValue.Type()
170 actualType := actualValue.Type()
171 if !expectedType.ConvertibleTo(actualType) {
172 return false
173 }
174
175 if !isNumericType(expectedType) || !isNumericType(actualType) {
176
177 return reflect.DeepEqual(
178 expectedValue.Convert(actualType).Interface(), actual,
179 )
180 }
181
182
183
184
185 if expectedType.Size() >= actualType.Size() {
186 return actualValue.Convert(expectedType).Interface() == expected
187 }
188
189 return expectedValue.Convert(actualType).Interface() == actual
190 }
191
192
193
194
195 func isNumericType(t reflect.Type) bool {
196 return t.Kind() >= reflect.Int && t.Kind() <= reflect.Complex128
197 }
198
199
202
203
204
205
206 func CallerInfo() []string {
207
208 var pc uintptr
209 var ok bool
210 var file string
211 var line int
212 var name string
213
214 callers := []string{}
215 for i := 0; ; i++ {
216 pc, file, line, ok = runtime.Caller(i)
217 if !ok {
218
219
220 break
221 }
222
223
224 if file == "<autogenerated>" {
225 break
226 }
227
228 f := runtime.FuncForPC(pc)
229 if f == nil {
230 break
231 }
232 name = f.Name()
233
234
235
236
237
238
239 if name == "testing.tRunner" {
240 break
241 }
242
243 parts := strings.Split(file, "/")
244 if len(parts) > 1 {
245 filename := parts[len(parts)-1]
246 dir := parts[len(parts)-2]
247 if (dir != "assert" && dir != "mock" && dir != "require") || filename == "mock_test.go" {
248 callers = append(callers, fmt.Sprintf("%s:%d", file, line))
249 }
250 }
251
252
253 segments := strings.Split(name, ".")
254 name = segments[len(segments)-1]
255 if isTest(name, "Test") ||
256 isTest(name, "Benchmark") ||
257 isTest(name, "Example") {
258 break
259 }
260 }
261
262 return callers
263 }
264
265
266
267
268
269 func isTest(name, prefix string) bool {
270 if !strings.HasPrefix(name, prefix) {
271 return false
272 }
273 if len(name) == len(prefix) {
274 return true
275 }
276 r, _ := utf8.DecodeRuneInString(name[len(prefix):])
277 return !unicode.IsLower(r)
278 }
279
280 func messageFromMsgAndArgs(msgAndArgs ...interface{}) string {
281 if len(msgAndArgs) == 0 || msgAndArgs == nil {
282 return ""
283 }
284 if len(msgAndArgs) == 1 {
285 msg := msgAndArgs[0]
286 if msgAsStr, ok := msg.(string); ok {
287 return msgAsStr
288 }
289 return fmt.Sprintf("%+v", msg)
290 }
291 if len(msgAndArgs) > 1 {
292 return fmt.Sprintf(msgAndArgs[0].(string), msgAndArgs[1:]...)
293 }
294 return ""
295 }
296
297
298
299
300
301 func indentMessageLines(message string, longestLabelLen int) string {
302 outBuf := new(bytes.Buffer)
303
304 for i, scanner := 0, bufio.NewScanner(strings.NewReader(message)); scanner.Scan(); i++ {
305
306 if i != 0 {
307
308 outBuf.WriteString("\n\t" + strings.Repeat(" ", longestLabelLen+1) + "\t")
309 }
310 outBuf.WriteString(scanner.Text())
311 }
312
313 return outBuf.String()
314 }
315
316 type failNower interface {
317 FailNow()
318 }
319
320
321 func FailNow(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool {
322 if h, ok := t.(tHelper); ok {
323 h.Helper()
324 }
325 Fail(t, failureMessage, msgAndArgs...)
326
327
328
329
330
331
332
333 if t, ok := t.(failNower); ok {
334 t.FailNow()
335 } else {
336 panic("test failed and t is missing `FailNow()`")
337 }
338 return false
339 }
340
341
342 func Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool {
343 if h, ok := t.(tHelper); ok {
344 h.Helper()
345 }
346 content := []labeledContent{
347 {"Error Trace", strings.Join(CallerInfo(), "\n\t\t\t")},
348 {"Error", failureMessage},
349 }
350
351
352 if n, ok := t.(interface {
353 Name() string
354 }); ok {
355 content = append(content, labeledContent{"Test", n.Name()})
356 }
357
358 message := messageFromMsgAndArgs(msgAndArgs...)
359 if len(message) > 0 {
360 content = append(content, labeledContent{"Messages", message})
361 }
362
363 t.Errorf("\n%s", ""+labeledOutput(content...))
364
365 return false
366 }
367
368 type labeledContent struct {
369 label string
370 content string
371 }
372
373
374
375
376
377
378
379
380
381
382 func labeledOutput(content ...labeledContent) string {
383 longestLabel := 0
384 for _, v := range content {
385 if len(v.label) > longestLabel {
386 longestLabel = len(v.label)
387 }
388 }
389 var output string
390 for _, v := range content {
391 output += "\t" + v.label + ":" + strings.Repeat(" ", longestLabel-len(v.label)) + "\t" + indentMessageLines(v.content, longestLabel) + "\n"
392 }
393 return output
394 }
395
396
397
398
399 func Implements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool {
400 if h, ok := t.(tHelper); ok {
401 h.Helper()
402 }
403 interfaceType := reflect.TypeOf(interfaceObject).Elem()
404
405 if object == nil {
406 return Fail(t, fmt.Sprintf("Cannot check if nil implements %v", interfaceType), msgAndArgs...)
407 }
408 if !reflect.TypeOf(object).Implements(interfaceType) {
409 return Fail(t, fmt.Sprintf("%T must implement %v", object, interfaceType), msgAndArgs...)
410 }
411
412 return true
413 }
414
415
416
417
418 func NotImplements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool {
419 if h, ok := t.(tHelper); ok {
420 h.Helper()
421 }
422 interfaceType := reflect.TypeOf(interfaceObject).Elem()
423
424 if object == nil {
425 return Fail(t, fmt.Sprintf("Cannot check if nil does not implement %v", interfaceType), msgAndArgs...)
426 }
427 if reflect.TypeOf(object).Implements(interfaceType) {
428 return Fail(t, fmt.Sprintf("%T implements %v", object, interfaceType), msgAndArgs...)
429 }
430
431 return true
432 }
433
434
435 func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool {
436 if h, ok := t.(tHelper); ok {
437 h.Helper()
438 }
439
440 if !ObjectsAreEqual(reflect.TypeOf(object), reflect.TypeOf(expectedType)) {
441 return Fail(t, fmt.Sprintf("Object expected to be of type %v, but was %v", reflect.TypeOf(expectedType), reflect.TypeOf(object)), msgAndArgs...)
442 }
443
444 return true
445 }
446
447
448
449
450
451
452
453
454 func Equal(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
455 if h, ok := t.(tHelper); ok {
456 h.Helper()
457 }
458 if err := validateEqualArgs(expected, actual); err != nil {
459 return Fail(t, fmt.Sprintf("Invalid operation: %#v == %#v (%s)",
460 expected, actual, err), msgAndArgs...)
461 }
462
463 if !ObjectsAreEqual(expected, actual) {
464 diff := diff(expected, actual)
465 expected, actual = formatUnequalValues(expected, actual)
466 return Fail(t, fmt.Sprintf("Not equal: \n"+
467 "expected: %s\n"+
468 "actual : %s%s", expected, actual, diff), msgAndArgs...)
469 }
470
471 return true
472
473 }
474
475
476
477 func validateEqualArgs(expected, actual interface{}) error {
478 if expected == nil && actual == nil {
479 return nil
480 }
481
482 if isFunction(expected) || isFunction(actual) {
483 return errors.New("cannot take func type as argument")
484 }
485 return nil
486 }
487
488
489
490
491
492
493
494 func Same(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
495 if h, ok := t.(tHelper); ok {
496 h.Helper()
497 }
498
499 if !samePointers(expected, actual) {
500 return Fail(t, fmt.Sprintf("Not same: \n"+
501 "expected: %p %#v\n"+
502 "actual : %p %#v", expected, expected, actual, actual), msgAndArgs...)
503 }
504
505 return true
506 }
507
508
509
510
511
512
513
514 func NotSame(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
515 if h, ok := t.(tHelper); ok {
516 h.Helper()
517 }
518
519 if samePointers(expected, actual) {
520 return Fail(t, fmt.Sprintf(
521 "Expected and actual point to the same object: %p %#v",
522 expected, expected), msgAndArgs...)
523 }
524 return true
525 }
526
527
528
529 func samePointers(first, second interface{}) bool {
530 firstPtr, secondPtr := reflect.ValueOf(first), reflect.ValueOf(second)
531 if firstPtr.Kind() != reflect.Ptr || secondPtr.Kind() != reflect.Ptr {
532 return false
533 }
534
535 firstType, secondType := reflect.TypeOf(first), reflect.TypeOf(second)
536 if firstType != secondType {
537 return false
538 }
539
540
541 return first == second
542 }
543
544
545
546
547
548
549
550 func formatUnequalValues(expected, actual interface{}) (e string, a string) {
551 if reflect.TypeOf(expected) != reflect.TypeOf(actual) {
552 return fmt.Sprintf("%T(%s)", expected, truncatingFormat(expected)),
553 fmt.Sprintf("%T(%s)", actual, truncatingFormat(actual))
554 }
555 switch expected.(type) {
556 case time.Duration:
557 return fmt.Sprintf("%v", expected), fmt.Sprintf("%v", actual)
558 }
559 return truncatingFormat(expected), truncatingFormat(actual)
560 }
561
562
563
564
565
566 func truncatingFormat(data interface{}) string {
567 value := fmt.Sprintf("%#v", data)
568 max := bufio.MaxScanTokenSize - 100
569 if len(value) > max {
570 value = value[0:max] + "<... truncated>"
571 }
572 return value
573 }
574
575
576
577
578
579 func EqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
580 if h, ok := t.(tHelper); ok {
581 h.Helper()
582 }
583
584 if !ObjectsAreEqualValues(expected, actual) {
585 diff := diff(expected, actual)
586 expected, actual = formatUnequalValues(expected, actual)
587 return Fail(t, fmt.Sprintf("Not equal: \n"+
588 "expected: %s\n"+
589 "actual : %s%s", expected, actual, diff), msgAndArgs...)
590 }
591
592 return true
593
594 }
595
596
597
598
599
600
601
602
603
604
605
606 func EqualExportedValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
607 if h, ok := t.(tHelper); ok {
608 h.Helper()
609 }
610
611 aType := reflect.TypeOf(expected)
612 bType := reflect.TypeOf(actual)
613
614 if aType != bType {
615 return Fail(t, fmt.Sprintf("Types expected to match exactly\n\t%v != %v", aType, bType), msgAndArgs...)
616 }
617
618 if aType.Kind() == reflect.Ptr {
619 aType = aType.Elem()
620 }
621 if bType.Kind() == reflect.Ptr {
622 bType = bType.Elem()
623 }
624
625 if aType.Kind() != reflect.Struct {
626 return Fail(t, fmt.Sprintf("Types expected to both be struct or pointer to struct \n\t%v != %v", aType.Kind(), reflect.Struct), msgAndArgs...)
627 }
628
629 if bType.Kind() != reflect.Struct {
630 return Fail(t, fmt.Sprintf("Types expected to both be struct or pointer to struct \n\t%v != %v", bType.Kind(), reflect.Struct), msgAndArgs...)
631 }
632
633 expected = copyExportedFields(expected)
634 actual = copyExportedFields(actual)
635
636 if !ObjectsAreEqualValues(expected, actual) {
637 diff := diff(expected, actual)
638 expected, actual = formatUnequalValues(expected, actual)
639 return Fail(t, fmt.Sprintf("Not equal (comparing only exported fields): \n"+
640 "expected: %s\n"+
641 "actual : %s%s", expected, actual, diff), msgAndArgs...)
642 }
643
644 return true
645 }
646
647
648
649
650 func Exactly(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
651 if h, ok := t.(tHelper); ok {
652 h.Helper()
653 }
654
655 aType := reflect.TypeOf(expected)
656 bType := reflect.TypeOf(actual)
657
658 if aType != bType {
659 return Fail(t, fmt.Sprintf("Types expected to match exactly\n\t%v != %v", aType, bType), msgAndArgs...)
660 }
661
662 return Equal(t, expected, actual, msgAndArgs...)
663
664 }
665
666
667
668
669 func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
670 if !isNil(object) {
671 return true
672 }
673 if h, ok := t.(tHelper); ok {
674 h.Helper()
675 }
676 return Fail(t, "Expected value not to be nil.", msgAndArgs...)
677 }
678
679
680 func isNil(object interface{}) bool {
681 if object == nil {
682 return true
683 }
684
685 value := reflect.ValueOf(object)
686 switch value.Kind() {
687 case
688 reflect.Chan, reflect.Func,
689 reflect.Interface, reflect.Map,
690 reflect.Ptr, reflect.Slice, reflect.UnsafePointer:
691
692 return value.IsNil()
693 }
694
695 return false
696 }
697
698
699
700
701 func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
702 if isNil(object) {
703 return true
704 }
705 if h, ok := t.(tHelper); ok {
706 h.Helper()
707 }
708 return Fail(t, fmt.Sprintf("Expected nil, but got: %#v", object), msgAndArgs...)
709 }
710
711
712 func isEmpty(object interface{}) bool {
713
714
715 if object == nil {
716 return true
717 }
718
719 objValue := reflect.ValueOf(object)
720
721 switch objValue.Kind() {
722
723 case reflect.Chan, reflect.Map, reflect.Slice:
724 return objValue.Len() == 0
725
726 case reflect.Ptr:
727 if objValue.IsNil() {
728 return true
729 }
730 deref := objValue.Elem().Interface()
731 return isEmpty(deref)
732
733
734 default:
735 zero := reflect.Zero(objValue.Type())
736 return reflect.DeepEqual(object, zero.Interface())
737 }
738 }
739
740
741
742
743
744 func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
745 pass := isEmpty(object)
746 if !pass {
747 if h, ok := t.(tHelper); ok {
748 h.Helper()
749 }
750 Fail(t, fmt.Sprintf("Should be empty, but was %v", object), msgAndArgs...)
751 }
752
753 return pass
754
755 }
756
757
758
759
760
761
762
763 func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
764 pass := !isEmpty(object)
765 if !pass {
766 if h, ok := t.(tHelper); ok {
767 h.Helper()
768 }
769 Fail(t, fmt.Sprintf("Should NOT be empty, but was %v", object), msgAndArgs...)
770 }
771
772 return pass
773
774 }
775
776
777
778 func getLen(x interface{}) (length int, ok bool) {
779 v := reflect.ValueOf(x)
780 defer func() {
781 ok = recover() == nil
782 }()
783 return v.Len(), true
784 }
785
786
787
788
789
790 func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) bool {
791 if h, ok := t.(tHelper); ok {
792 h.Helper()
793 }
794 l, ok := getLen(object)
795 if !ok {
796 return Fail(t, fmt.Sprintf("\"%v\" could not be applied builtin len()", object), msgAndArgs...)
797 }
798
799 if l != length {
800 return Fail(t, fmt.Sprintf("\"%v\" should have %d item(s), but has %d", object, length, l), msgAndArgs...)
801 }
802 return true
803 }
804
805
806
807
808 func True(t TestingT, value bool, msgAndArgs ...interface{}) bool {
809 if !value {
810 if h, ok := t.(tHelper); ok {
811 h.Helper()
812 }
813 return Fail(t, "Should be true", msgAndArgs...)
814 }
815
816 return true
817
818 }
819
820
821
822
823 func False(t TestingT, value bool, msgAndArgs ...interface{}) bool {
824 if value {
825 if h, ok := t.(tHelper); ok {
826 h.Helper()
827 }
828 return Fail(t, "Should be false", msgAndArgs...)
829 }
830
831 return true
832
833 }
834
835
836
837
838
839
840
841 func NotEqual(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
842 if h, ok := t.(tHelper); ok {
843 h.Helper()
844 }
845 if err := validateEqualArgs(expected, actual); err != nil {
846 return Fail(t, fmt.Sprintf("Invalid operation: %#v != %#v (%s)",
847 expected, actual, err), msgAndArgs...)
848 }
849
850 if ObjectsAreEqual(expected, actual) {
851 return Fail(t, fmt.Sprintf("Should not be: %#v\n", actual), msgAndArgs...)
852 }
853
854 return true
855
856 }
857
858
859
860
861 func NotEqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
862 if h, ok := t.(tHelper); ok {
863 h.Helper()
864 }
865
866 if ObjectsAreEqualValues(expected, actual) {
867 return Fail(t, fmt.Sprintf("Should not be: %#v\n", actual), msgAndArgs...)
868 }
869
870 return true
871 }
872
873
874
875
876
877 func containsElement(list interface{}, element interface{}) (ok, found bool) {
878
879 listValue := reflect.ValueOf(list)
880 listType := reflect.TypeOf(list)
881 if listType == nil {
882 return false, false
883 }
884 listKind := listType.Kind()
885 defer func() {
886 if e := recover(); e != nil {
887 ok = false
888 found = false
889 }
890 }()
891
892 if listKind == reflect.String {
893 elementValue := reflect.ValueOf(element)
894 return true, strings.Contains(listValue.String(), elementValue.String())
895 }
896
897 if listKind == reflect.Map {
898 mapKeys := listValue.MapKeys()
899 for i := 0; i < len(mapKeys); i++ {
900 if ObjectsAreEqual(mapKeys[i].Interface(), element) {
901 return true, true
902 }
903 }
904 return true, false
905 }
906
907 for i := 0; i < listValue.Len(); i++ {
908 if ObjectsAreEqual(listValue.Index(i).Interface(), element) {
909 return true, true
910 }
911 }
912 return true, false
913
914 }
915
916
917
918
919
920
921
922 func Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool {
923 if h, ok := t.(tHelper); ok {
924 h.Helper()
925 }
926
927 ok, found := containsElement(s, contains)
928 if !ok {
929 return Fail(t, fmt.Sprintf("%#v could not be applied builtin len()", s), msgAndArgs...)
930 }
931 if !found {
932 return Fail(t, fmt.Sprintf("%#v does not contain %#v", s, contains), msgAndArgs...)
933 }
934
935 return true
936
937 }
938
939
940
941
942
943
944
945 func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool {
946 if h, ok := t.(tHelper); ok {
947 h.Helper()
948 }
949
950 ok, found := containsElement(s, contains)
951 if !ok {
952 return Fail(t, fmt.Sprintf("%#v could not be applied builtin len()", s), msgAndArgs...)
953 }
954 if found {
955 return Fail(t, fmt.Sprintf("%#v should not contain %#v", s, contains), msgAndArgs...)
956 }
957
958 return true
959
960 }
961
962
963
964
965
966
967 func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) {
968 if h, ok := t.(tHelper); ok {
969 h.Helper()
970 }
971 if subset == nil {
972 return true
973 }
974
975 listKind := reflect.TypeOf(list).Kind()
976 if listKind != reflect.Array && listKind != reflect.Slice && listKind != reflect.Map {
977 return Fail(t, fmt.Sprintf("%q has an unsupported type %s", list, listKind), msgAndArgs...)
978 }
979
980 subsetKind := reflect.TypeOf(subset).Kind()
981 if subsetKind != reflect.Array && subsetKind != reflect.Slice && listKind != reflect.Map {
982 return Fail(t, fmt.Sprintf("%q has an unsupported type %s", subset, subsetKind), msgAndArgs...)
983 }
984
985 if subsetKind == reflect.Map && listKind == reflect.Map {
986 subsetMap := reflect.ValueOf(subset)
987 actualMap := reflect.ValueOf(list)
988
989 for _, k := range subsetMap.MapKeys() {
990 ev := subsetMap.MapIndex(k)
991 av := actualMap.MapIndex(k)
992
993 if !av.IsValid() {
994 return Fail(t, fmt.Sprintf("%#v does not contain %#v", list, subset), msgAndArgs...)
995 }
996 if !ObjectsAreEqual(ev.Interface(), av.Interface()) {
997 return Fail(t, fmt.Sprintf("%#v does not contain %#v", list, subset), msgAndArgs...)
998 }
999 }
1000
1001 return true
1002 }
1003
1004 subsetList := reflect.ValueOf(subset)
1005 for i := 0; i < subsetList.Len(); i++ {
1006 element := subsetList.Index(i).Interface()
1007 ok, found := containsElement(list, element)
1008 if !ok {
1009 return Fail(t, fmt.Sprintf("%#v could not be applied builtin len()", list), msgAndArgs...)
1010 }
1011 if !found {
1012 return Fail(t, fmt.Sprintf("%#v does not contain %#v", list, element), msgAndArgs...)
1013 }
1014 }
1015
1016 return true
1017 }
1018
1019
1020
1021
1022
1023
1024
1025 func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) {
1026 if h, ok := t.(tHelper); ok {
1027 h.Helper()
1028 }
1029 if subset == nil {
1030 return Fail(t, "nil is the empty set which is a subset of every set", msgAndArgs...)
1031 }
1032
1033 listKind := reflect.TypeOf(list).Kind()
1034 if listKind != reflect.Array && listKind != reflect.Slice && listKind != reflect.Map {
1035 return Fail(t, fmt.Sprintf("%q has an unsupported type %s", list, listKind), msgAndArgs...)
1036 }
1037
1038 subsetKind := reflect.TypeOf(subset).Kind()
1039 if subsetKind != reflect.Array && subsetKind != reflect.Slice && listKind != reflect.Map {
1040 return Fail(t, fmt.Sprintf("%q has an unsupported type %s", subset, subsetKind), msgAndArgs...)
1041 }
1042
1043 if subsetKind == reflect.Map && listKind == reflect.Map {
1044 subsetMap := reflect.ValueOf(subset)
1045 actualMap := reflect.ValueOf(list)
1046
1047 for _, k := range subsetMap.MapKeys() {
1048 ev := subsetMap.MapIndex(k)
1049 av := actualMap.MapIndex(k)
1050
1051 if !av.IsValid() {
1052 return true
1053 }
1054 if !ObjectsAreEqual(ev.Interface(), av.Interface()) {
1055 return true
1056 }
1057 }
1058
1059 return Fail(t, fmt.Sprintf("%q is a subset of %q", subset, list), msgAndArgs...)
1060 }
1061
1062 subsetList := reflect.ValueOf(subset)
1063 for i := 0; i < subsetList.Len(); i++ {
1064 element := subsetList.Index(i).Interface()
1065 ok, found := containsElement(list, element)
1066 if !ok {
1067 return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", list), msgAndArgs...)
1068 }
1069 if !found {
1070 return true
1071 }
1072 }
1073
1074 return Fail(t, fmt.Sprintf("%q is a subset of %q", subset, list), msgAndArgs...)
1075 }
1076
1077
1078
1079
1080
1081
1082 func ElementsMatch(t TestingT, listA, listB interface{}, msgAndArgs ...interface{}) (ok bool) {
1083 if h, ok := t.(tHelper); ok {
1084 h.Helper()
1085 }
1086 if isEmpty(listA) && isEmpty(listB) {
1087 return true
1088 }
1089
1090 if !isList(t, listA, msgAndArgs...) || !isList(t, listB, msgAndArgs...) {
1091 return false
1092 }
1093
1094 extraA, extraB := diffLists(listA, listB)
1095
1096 if len(extraA) == 0 && len(extraB) == 0 {
1097 return true
1098 }
1099
1100 return Fail(t, formatListDiff(listA, listB, extraA, extraB), msgAndArgs...)
1101 }
1102
1103
1104 func isList(t TestingT, list interface{}, msgAndArgs ...interface{}) (ok bool) {
1105 kind := reflect.TypeOf(list).Kind()
1106 if kind != reflect.Array && kind != reflect.Slice {
1107 return Fail(t, fmt.Sprintf("%q has an unsupported type %s, expecting array or slice", list, kind),
1108 msgAndArgs...)
1109 }
1110 return true
1111 }
1112
1113
1114
1115
1116 func diffLists(listA, listB interface{}) (extraA, extraB []interface{}) {
1117 aValue := reflect.ValueOf(listA)
1118 bValue := reflect.ValueOf(listB)
1119
1120 aLen := aValue.Len()
1121 bLen := bValue.Len()
1122
1123
1124 visited := make([]bool, bLen)
1125 for i := 0; i < aLen; i++ {
1126 element := aValue.Index(i).Interface()
1127 found := false
1128 for j := 0; j < bLen; j++ {
1129 if visited[j] {
1130 continue
1131 }
1132 if ObjectsAreEqual(bValue.Index(j).Interface(), element) {
1133 visited[j] = true
1134 found = true
1135 break
1136 }
1137 }
1138 if !found {
1139 extraA = append(extraA, element)
1140 }
1141 }
1142
1143 for j := 0; j < bLen; j++ {
1144 if visited[j] {
1145 continue
1146 }
1147 extraB = append(extraB, bValue.Index(j).Interface())
1148 }
1149
1150 return
1151 }
1152
1153 func formatListDiff(listA, listB interface{}, extraA, extraB []interface{}) string {
1154 var msg bytes.Buffer
1155
1156 msg.WriteString("elements differ")
1157 if len(extraA) > 0 {
1158 msg.WriteString("\n\nextra elements in list A:\n")
1159 msg.WriteString(spewConfig.Sdump(extraA))
1160 }
1161 if len(extraB) > 0 {
1162 msg.WriteString("\n\nextra elements in list B:\n")
1163 msg.WriteString(spewConfig.Sdump(extraB))
1164 }
1165 msg.WriteString("\n\nlistA:\n")
1166 msg.WriteString(spewConfig.Sdump(listA))
1167 msg.WriteString("\n\nlistB:\n")
1168 msg.WriteString(spewConfig.Sdump(listB))
1169
1170 return msg.String()
1171 }
1172
1173
1174 func Condition(t TestingT, comp Comparison, msgAndArgs ...interface{}) bool {
1175 if h, ok := t.(tHelper); ok {
1176 h.Helper()
1177 }
1178 result := comp()
1179 if !result {
1180 Fail(t, "Condition failed!", msgAndArgs...)
1181 }
1182 return result
1183 }
1184
1185
1186
1187 type PanicTestFunc func()
1188
1189
1190 func didPanic(f PanicTestFunc) (didPanic bool, message interface{}, stack string) {
1191 didPanic = true
1192
1193 defer func() {
1194 message = recover()
1195 if didPanic {
1196 stack = string(debug.Stack())
1197 }
1198 }()
1199
1200
1201 f()
1202 didPanic = false
1203
1204 return
1205 }
1206
1207
1208
1209
1210 func Panics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool {
1211 if h, ok := t.(tHelper); ok {
1212 h.Helper()
1213 }
1214
1215 if funcDidPanic, panicValue, _ := didPanic(f); !funcDidPanic {
1216 return Fail(t, fmt.Sprintf("func %#v should panic\n\tPanic value:\t%#v", f, panicValue), msgAndArgs...)
1217 }
1218
1219 return true
1220 }
1221
1222
1223
1224
1225
1226 func PanicsWithValue(t TestingT, expected interface{}, f PanicTestFunc, msgAndArgs ...interface{}) bool {
1227 if h, ok := t.(tHelper); ok {
1228 h.Helper()
1229 }
1230
1231 funcDidPanic, panicValue, panickedStack := didPanic(f)
1232 if !funcDidPanic {
1233 return Fail(t, fmt.Sprintf("func %#v should panic\n\tPanic value:\t%#v", f, panicValue), msgAndArgs...)
1234 }
1235 if panicValue != expected {
1236 return Fail(t, fmt.Sprintf("func %#v should panic with value:\t%#v\n\tPanic value:\t%#v\n\tPanic stack:\t%s", f, expected, panicValue, panickedStack), msgAndArgs...)
1237 }
1238
1239 return true
1240 }
1241
1242
1243
1244
1245
1246
1247 func PanicsWithError(t TestingT, errString string, f PanicTestFunc, msgAndArgs ...interface{}) bool {
1248 if h, ok := t.(tHelper); ok {
1249 h.Helper()
1250 }
1251
1252 funcDidPanic, panicValue, panickedStack := didPanic(f)
1253 if !funcDidPanic {
1254 return Fail(t, fmt.Sprintf("func %#v should panic\n\tPanic value:\t%#v", f, panicValue), msgAndArgs...)
1255 }
1256 panicErr, ok := panicValue.(error)
1257 if !ok || panicErr.Error() != errString {
1258 return Fail(t, fmt.Sprintf("func %#v should panic with error message:\t%#v\n\tPanic value:\t%#v\n\tPanic stack:\t%s", f, errString, panicValue, panickedStack), msgAndArgs...)
1259 }
1260
1261 return true
1262 }
1263
1264
1265
1266
1267 func NotPanics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool {
1268 if h, ok := t.(tHelper); ok {
1269 h.Helper()
1270 }
1271
1272 if funcDidPanic, panicValue, panickedStack := didPanic(f); funcDidPanic {
1273 return Fail(t, fmt.Sprintf("func %#v should not panic\n\tPanic value:\t%v\n\tPanic stack:\t%s", f, panicValue, panickedStack), msgAndArgs...)
1274 }
1275
1276 return true
1277 }
1278
1279
1280
1281
1282 func WithinDuration(t TestingT, expected, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool {
1283 if h, ok := t.(tHelper); ok {
1284 h.Helper()
1285 }
1286
1287 dt := expected.Sub(actual)
1288 if dt < -delta || dt > delta {
1289 return Fail(t, fmt.Sprintf("Max difference between %v and %v allowed is %v, but difference was %v", expected, actual, delta, dt), msgAndArgs...)
1290 }
1291
1292 return true
1293 }
1294
1295
1296
1297
1298 func WithinRange(t TestingT, actual, start, end time.Time, msgAndArgs ...interface{}) bool {
1299 if h, ok := t.(tHelper); ok {
1300 h.Helper()
1301 }
1302
1303 if end.Before(start) {
1304 return Fail(t, "Start should be before end", msgAndArgs...)
1305 }
1306
1307 if actual.Before(start) {
1308 return Fail(t, fmt.Sprintf("Time %v expected to be in time range %v to %v, but is before the range", actual, start, end), msgAndArgs...)
1309 } else if actual.After(end) {
1310 return Fail(t, fmt.Sprintf("Time %v expected to be in time range %v to %v, but is after the range", actual, start, end), msgAndArgs...)
1311 }
1312
1313 return true
1314 }
1315
1316 func toFloat(x interface{}) (float64, bool) {
1317 var xf float64
1318 xok := true
1319
1320 switch xn := x.(type) {
1321 case uint:
1322 xf = float64(xn)
1323 case uint8:
1324 xf = float64(xn)
1325 case uint16:
1326 xf = float64(xn)
1327 case uint32:
1328 xf = float64(xn)
1329 case uint64:
1330 xf = float64(xn)
1331 case int:
1332 xf = float64(xn)
1333 case int8:
1334 xf = float64(xn)
1335 case int16:
1336 xf = float64(xn)
1337 case int32:
1338 xf = float64(xn)
1339 case int64:
1340 xf = float64(xn)
1341 case float32:
1342 xf = float64(xn)
1343 case float64:
1344 xf = xn
1345 case time.Duration:
1346 xf = float64(xn)
1347 default:
1348 xok = false
1349 }
1350
1351 return xf, xok
1352 }
1353
1354
1355
1356
1357 func InDelta(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
1358 if h, ok := t.(tHelper); ok {
1359 h.Helper()
1360 }
1361
1362 af, aok := toFloat(expected)
1363 bf, bok := toFloat(actual)
1364
1365 if !aok || !bok {
1366 return Fail(t, "Parameters must be numerical", msgAndArgs...)
1367 }
1368
1369 if math.IsNaN(af) && math.IsNaN(bf) {
1370 return true
1371 }
1372
1373 if math.IsNaN(af) {
1374 return Fail(t, "Expected must not be NaN", msgAndArgs...)
1375 }
1376
1377 if math.IsNaN(bf) {
1378 return Fail(t, fmt.Sprintf("Expected %v with delta %v, but was NaN", expected, delta), msgAndArgs...)
1379 }
1380
1381 dt := af - bf
1382 if dt < -delta || dt > delta {
1383 return Fail(t, fmt.Sprintf("Max difference between %v and %v allowed is %v, but difference was %v", expected, actual, delta, dt), msgAndArgs...)
1384 }
1385
1386 return true
1387 }
1388
1389
1390 func InDeltaSlice(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
1391 if h, ok := t.(tHelper); ok {
1392 h.Helper()
1393 }
1394 if expected == nil || actual == nil ||
1395 reflect.TypeOf(actual).Kind() != reflect.Slice ||
1396 reflect.TypeOf(expected).Kind() != reflect.Slice {
1397 return Fail(t, "Parameters must be slice", msgAndArgs...)
1398 }
1399
1400 actualSlice := reflect.ValueOf(actual)
1401 expectedSlice := reflect.ValueOf(expected)
1402
1403 for i := 0; i < actualSlice.Len(); i++ {
1404 result := InDelta(t, actualSlice.Index(i).Interface(), expectedSlice.Index(i).Interface(), delta, msgAndArgs...)
1405 if !result {
1406 return result
1407 }
1408 }
1409
1410 return true
1411 }
1412
1413
1414 func InDeltaMapValues(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
1415 if h, ok := t.(tHelper); ok {
1416 h.Helper()
1417 }
1418 if expected == nil || actual == nil ||
1419 reflect.TypeOf(actual).Kind() != reflect.Map ||
1420 reflect.TypeOf(expected).Kind() != reflect.Map {
1421 return Fail(t, "Arguments must be maps", msgAndArgs...)
1422 }
1423
1424 expectedMap := reflect.ValueOf(expected)
1425 actualMap := reflect.ValueOf(actual)
1426
1427 if expectedMap.Len() != actualMap.Len() {
1428 return Fail(t, "Arguments must have the same number of keys", msgAndArgs...)
1429 }
1430
1431 for _, k := range expectedMap.MapKeys() {
1432 ev := expectedMap.MapIndex(k)
1433 av := actualMap.MapIndex(k)
1434
1435 if !ev.IsValid() {
1436 return Fail(t, fmt.Sprintf("missing key %q in expected map", k), msgAndArgs...)
1437 }
1438
1439 if !av.IsValid() {
1440 return Fail(t, fmt.Sprintf("missing key %q in actual map", k), msgAndArgs...)
1441 }
1442
1443 if !InDelta(
1444 t,
1445 ev.Interface(),
1446 av.Interface(),
1447 delta,
1448 msgAndArgs...,
1449 ) {
1450 return false
1451 }
1452 }
1453
1454 return true
1455 }
1456
1457 func calcRelativeError(expected, actual interface{}) (float64, error) {
1458 af, aok := toFloat(expected)
1459 bf, bok := toFloat(actual)
1460 if !aok || !bok {
1461 return 0, fmt.Errorf("Parameters must be numerical")
1462 }
1463 if math.IsNaN(af) && math.IsNaN(bf) {
1464 return 0, nil
1465 }
1466 if math.IsNaN(af) {
1467 return 0, errors.New("expected value must not be NaN")
1468 }
1469 if af == 0 {
1470 return 0, fmt.Errorf("expected value must have a value other than zero to calculate the relative error")
1471 }
1472 if math.IsNaN(bf) {
1473 return 0, errors.New("actual value must not be NaN")
1474 }
1475
1476 return math.Abs(af-bf) / math.Abs(af), nil
1477 }
1478
1479
1480 func InEpsilon(t TestingT, expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool {
1481 if h, ok := t.(tHelper); ok {
1482 h.Helper()
1483 }
1484 if math.IsNaN(epsilon) {
1485 return Fail(t, "epsilon must not be NaN", msgAndArgs...)
1486 }
1487 actualEpsilon, err := calcRelativeError(expected, actual)
1488 if err != nil {
1489 return Fail(t, err.Error(), msgAndArgs...)
1490 }
1491 if actualEpsilon > epsilon {
1492 return Fail(t, fmt.Sprintf("Relative error is too high: %#v (expected)\n"+
1493 " < %#v (actual)", epsilon, actualEpsilon), msgAndArgs...)
1494 }
1495
1496 return true
1497 }
1498
1499
1500 func InEpsilonSlice(t TestingT, expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool {
1501 if h, ok := t.(tHelper); ok {
1502 h.Helper()
1503 }
1504
1505 if expected == nil || actual == nil {
1506 return Fail(t, "Parameters must be slice", msgAndArgs...)
1507 }
1508
1509 expectedSlice := reflect.ValueOf(expected)
1510 actualSlice := reflect.ValueOf(actual)
1511
1512 if expectedSlice.Type().Kind() != reflect.Slice {
1513 return Fail(t, "Expected value must be slice", msgAndArgs...)
1514 }
1515
1516 expectedLen := expectedSlice.Len()
1517 if !IsType(t, expected, actual) || !Len(t, actual, expectedLen) {
1518 return false
1519 }
1520
1521 for i := 0; i < expectedLen; i++ {
1522 if !InEpsilon(t, expectedSlice.Index(i).Interface(), actualSlice.Index(i).Interface(), epsilon, "at index %d", i) {
1523 return false
1524 }
1525 }
1526
1527 return true
1528 }
1529
1530
1533
1534
1535
1536
1537
1538
1539
1540 func NoError(t TestingT, err error, msgAndArgs ...interface{}) bool {
1541 if err != nil {
1542 if h, ok := t.(tHelper); ok {
1543 h.Helper()
1544 }
1545 return Fail(t, fmt.Sprintf("Received unexpected error:\n%+v", err), msgAndArgs...)
1546 }
1547
1548 return true
1549 }
1550
1551
1552
1553
1554
1555
1556
1557 func Error(t TestingT, err error, msgAndArgs ...interface{}) bool {
1558 if err == nil {
1559 if h, ok := t.(tHelper); ok {
1560 h.Helper()
1561 }
1562 return Fail(t, "An error is expected but got nil.", msgAndArgs...)
1563 }
1564
1565 return true
1566 }
1567
1568
1569
1570
1571
1572
1573 func EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) bool {
1574 if h, ok := t.(tHelper); ok {
1575 h.Helper()
1576 }
1577 if !Error(t, theError, msgAndArgs...) {
1578 return false
1579 }
1580 expected := errString
1581 actual := theError.Error()
1582
1583 if expected != actual {
1584 return Fail(t, fmt.Sprintf("Error message not equal:\n"+
1585 "expected: %q\n"+
1586 "actual : %q", expected, actual), msgAndArgs...)
1587 }
1588 return true
1589 }
1590
1591
1592
1593
1594
1595
1596 func ErrorContains(t TestingT, theError error, contains string, msgAndArgs ...interface{}) bool {
1597 if h, ok := t.(tHelper); ok {
1598 h.Helper()
1599 }
1600 if !Error(t, theError, msgAndArgs...) {
1601 return false
1602 }
1603
1604 actual := theError.Error()
1605 if !strings.Contains(actual, contains) {
1606 return Fail(t, fmt.Sprintf("Error %#v does not contain %#v", actual, contains), msgAndArgs...)
1607 }
1608
1609 return true
1610 }
1611
1612
1613 func matchRegexp(rx interface{}, str interface{}) bool {
1614
1615 var r *regexp.Regexp
1616 if rr, ok := rx.(*regexp.Regexp); ok {
1617 r = rr
1618 } else {
1619 r = regexp.MustCompile(fmt.Sprint(rx))
1620 }
1621
1622 return (r.FindStringIndex(fmt.Sprint(str)) != nil)
1623
1624 }
1625
1626
1627
1628
1629
1630 func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool {
1631 if h, ok := t.(tHelper); ok {
1632 h.Helper()
1633 }
1634
1635 match := matchRegexp(rx, str)
1636
1637 if !match {
1638 Fail(t, fmt.Sprintf("Expect \"%v\" to match \"%v\"", str, rx), msgAndArgs...)
1639 }
1640
1641 return match
1642 }
1643
1644
1645
1646
1647
1648 func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool {
1649 if h, ok := t.(tHelper); ok {
1650 h.Helper()
1651 }
1652 match := matchRegexp(rx, str)
1653
1654 if match {
1655 Fail(t, fmt.Sprintf("Expect \"%v\" to NOT match \"%v\"", str, rx), msgAndArgs...)
1656 }
1657
1658 return !match
1659
1660 }
1661
1662
1663 func Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool {
1664 if h, ok := t.(tHelper); ok {
1665 h.Helper()
1666 }
1667 if i != nil && !reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) {
1668 return Fail(t, fmt.Sprintf("Should be zero, but was %v", i), msgAndArgs...)
1669 }
1670 return true
1671 }
1672
1673
1674 func NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool {
1675 if h, ok := t.(tHelper); ok {
1676 h.Helper()
1677 }
1678 if i == nil || reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) {
1679 return Fail(t, fmt.Sprintf("Should not be zero, but was %v", i), msgAndArgs...)
1680 }
1681 return true
1682 }
1683
1684
1685
1686 func FileExists(t TestingT, path string, msgAndArgs ...interface{}) bool {
1687 if h, ok := t.(tHelper); ok {
1688 h.Helper()
1689 }
1690 info, err := os.Lstat(path)
1691 if err != nil {
1692 if os.IsNotExist(err) {
1693 return Fail(t, fmt.Sprintf("unable to find file %q", path), msgAndArgs...)
1694 }
1695 return Fail(t, fmt.Sprintf("error when running os.Lstat(%q): %s", path, err), msgAndArgs...)
1696 }
1697 if info.IsDir() {
1698 return Fail(t, fmt.Sprintf("%q is a directory", path), msgAndArgs...)
1699 }
1700 return true
1701 }
1702
1703
1704
1705 func NoFileExists(t TestingT, path string, msgAndArgs ...interface{}) bool {
1706 if h, ok := t.(tHelper); ok {
1707 h.Helper()
1708 }
1709 info, err := os.Lstat(path)
1710 if err != nil {
1711 return true
1712 }
1713 if info.IsDir() {
1714 return true
1715 }
1716 return Fail(t, fmt.Sprintf("file %q exists", path), msgAndArgs...)
1717 }
1718
1719
1720
1721 func DirExists(t TestingT, path string, msgAndArgs ...interface{}) bool {
1722 if h, ok := t.(tHelper); ok {
1723 h.Helper()
1724 }
1725 info, err := os.Lstat(path)
1726 if err != nil {
1727 if os.IsNotExist(err) {
1728 return Fail(t, fmt.Sprintf("unable to find file %q", path), msgAndArgs...)
1729 }
1730 return Fail(t, fmt.Sprintf("error when running os.Lstat(%q): %s", path, err), msgAndArgs...)
1731 }
1732 if !info.IsDir() {
1733 return Fail(t, fmt.Sprintf("%q is a file", path), msgAndArgs...)
1734 }
1735 return true
1736 }
1737
1738
1739
1740 func NoDirExists(t TestingT, path string, msgAndArgs ...interface{}) bool {
1741 if h, ok := t.(tHelper); ok {
1742 h.Helper()
1743 }
1744 info, err := os.Lstat(path)
1745 if err != nil {
1746 if os.IsNotExist(err) {
1747 return true
1748 }
1749 return true
1750 }
1751 if !info.IsDir() {
1752 return true
1753 }
1754 return Fail(t, fmt.Sprintf("directory %q exists", path), msgAndArgs...)
1755 }
1756
1757
1758
1759
1760 func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) bool {
1761 if h, ok := t.(tHelper); ok {
1762 h.Helper()
1763 }
1764 var expectedJSONAsInterface, actualJSONAsInterface interface{}
1765
1766 if err := json.Unmarshal([]byte(expected), &expectedJSONAsInterface); err != nil {
1767 return Fail(t, fmt.Sprintf("Expected value ('%s') is not valid json.\nJSON parsing error: '%s'", expected, err.Error()), msgAndArgs...)
1768 }
1769
1770 if err := json.Unmarshal([]byte(actual), &actualJSONAsInterface); err != nil {
1771 return Fail(t, fmt.Sprintf("Input ('%s') needs to be valid json.\nJSON parsing error: '%s'", actual, err.Error()), msgAndArgs...)
1772 }
1773
1774 return Equal(t, expectedJSONAsInterface, actualJSONAsInterface, msgAndArgs...)
1775 }
1776
1777
1778 func YAMLEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) bool {
1779 if h, ok := t.(tHelper); ok {
1780 h.Helper()
1781 }
1782 var expectedYAMLAsInterface, actualYAMLAsInterface interface{}
1783
1784 if err := yaml.Unmarshal([]byte(expected), &expectedYAMLAsInterface); err != nil {
1785 return Fail(t, fmt.Sprintf("Expected value ('%s') is not valid yaml.\nYAML parsing error: '%s'", expected, err.Error()), msgAndArgs...)
1786 }
1787
1788 if err := yaml.Unmarshal([]byte(actual), &actualYAMLAsInterface); err != nil {
1789 return Fail(t, fmt.Sprintf("Input ('%s') needs to be valid yaml.\nYAML error: '%s'", actual, err.Error()), msgAndArgs...)
1790 }
1791
1792 return Equal(t, expectedYAMLAsInterface, actualYAMLAsInterface, msgAndArgs...)
1793 }
1794
1795 func typeAndKind(v interface{}) (reflect.Type, reflect.Kind) {
1796 t := reflect.TypeOf(v)
1797 k := t.Kind()
1798
1799 if k == reflect.Ptr {
1800 t = t.Elem()
1801 k = t.Kind()
1802 }
1803 return t, k
1804 }
1805
1806
1807
1808 func diff(expected interface{}, actual interface{}) string {
1809 if expected == nil || actual == nil {
1810 return ""
1811 }
1812
1813 et, ek := typeAndKind(expected)
1814 at, _ := typeAndKind(actual)
1815
1816 if et != at {
1817 return ""
1818 }
1819
1820 if ek != reflect.Struct && ek != reflect.Map && ek != reflect.Slice && ek != reflect.Array && ek != reflect.String {
1821 return ""
1822 }
1823
1824 var e, a string
1825
1826 switch et {
1827 case reflect.TypeOf(""):
1828 e = reflect.ValueOf(expected).String()
1829 a = reflect.ValueOf(actual).String()
1830 case reflect.TypeOf(time.Time{}):
1831 e = spewConfigStringerEnabled.Sdump(expected)
1832 a = spewConfigStringerEnabled.Sdump(actual)
1833 default:
1834 e = spewConfig.Sdump(expected)
1835 a = spewConfig.Sdump(actual)
1836 }
1837
1838 diff, _ := difflib.GetUnifiedDiffString(difflib.UnifiedDiff{
1839 A: difflib.SplitLines(e),
1840 B: difflib.SplitLines(a),
1841 FromFile: "Expected",
1842 FromDate: "",
1843 ToFile: "Actual",
1844 ToDate: "",
1845 Context: 1,
1846 })
1847
1848 return "\n\nDiff:\n" + diff
1849 }
1850
1851 func isFunction(arg interface{}) bool {
1852 if arg == nil {
1853 return false
1854 }
1855 return reflect.TypeOf(arg).Kind() == reflect.Func
1856 }
1857
1858 var spewConfig = spew.ConfigState{
1859 Indent: " ",
1860 DisablePointerAddresses: true,
1861 DisableCapacities: true,
1862 SortKeys: true,
1863 DisableMethods: true,
1864 MaxDepth: 10,
1865 }
1866
1867 var spewConfigStringerEnabled = spew.ConfigState{
1868 Indent: " ",
1869 DisablePointerAddresses: true,
1870 DisableCapacities: true,
1871 SortKeys: true,
1872 MaxDepth: 10,
1873 }
1874
1875 type tHelper interface {
1876 Helper()
1877 }
1878
1879
1880
1881
1882
1883 func Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool {
1884 if h, ok := t.(tHelper); ok {
1885 h.Helper()
1886 }
1887
1888 ch := make(chan bool, 1)
1889
1890 timer := time.NewTimer(waitFor)
1891 defer timer.Stop()
1892
1893 ticker := time.NewTicker(tick)
1894 defer ticker.Stop()
1895
1896 for tick := ticker.C; ; {
1897 select {
1898 case <-timer.C:
1899 return Fail(t, "Condition never satisfied", msgAndArgs...)
1900 case <-tick:
1901 tick = nil
1902 go func() { ch <- condition() }()
1903 case v := <-ch:
1904 if v {
1905 return true
1906 }
1907 tick = ticker.C
1908 }
1909 }
1910 }
1911
1912
1913 type CollectT struct {
1914 errors []error
1915 }
1916
1917
1918 func (c *CollectT) Errorf(format string, args ...interface{}) {
1919 c.errors = append(c.errors, fmt.Errorf(format, args...))
1920 }
1921
1922
1923 func (*CollectT) FailNow() {
1924 panic("Assertion failed")
1925 }
1926
1927
1928 func (*CollectT) Reset() {
1929 panic("Reset() is deprecated")
1930 }
1931
1932
1933 func (*CollectT) Copy(TestingT) {
1934 panic("Copy() is deprecated")
1935 }
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955 func EventuallyWithT(t TestingT, condition func(collect *CollectT), waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool {
1956 if h, ok := t.(tHelper); ok {
1957 h.Helper()
1958 }
1959
1960 var lastFinishedTickErrs []error
1961 ch := make(chan []error, 1)
1962
1963 timer := time.NewTimer(waitFor)
1964 defer timer.Stop()
1965
1966 ticker := time.NewTicker(tick)
1967 defer ticker.Stop()
1968
1969 for tick := ticker.C; ; {
1970 select {
1971 case <-timer.C:
1972 for _, err := range lastFinishedTickErrs {
1973 t.Errorf("%v", err)
1974 }
1975 return Fail(t, "Condition never satisfied", msgAndArgs...)
1976 case <-tick:
1977 tick = nil
1978 go func() {
1979 collect := new(CollectT)
1980 defer func() {
1981 ch <- collect.errors
1982 }()
1983 condition(collect)
1984 }()
1985 case errs := <-ch:
1986 if len(errs) == 0 {
1987 return true
1988 }
1989
1990 lastFinishedTickErrs = errs
1991 tick = ticker.C
1992 }
1993 }
1994 }
1995
1996
1997
1998
1999
2000 func Never(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool {
2001 if h, ok := t.(tHelper); ok {
2002 h.Helper()
2003 }
2004
2005 ch := make(chan bool, 1)
2006
2007 timer := time.NewTimer(waitFor)
2008 defer timer.Stop()
2009
2010 ticker := time.NewTicker(tick)
2011 defer ticker.Stop()
2012
2013 for tick := ticker.C; ; {
2014 select {
2015 case <-timer.C:
2016 return true
2017 case <-tick:
2018 tick = nil
2019 go func() { ch <- condition() }()
2020 case v := <-ch:
2021 if v {
2022 return Fail(t, "Condition satisfied", msgAndArgs...)
2023 }
2024 tick = ticker.C
2025 }
2026 }
2027 }
2028
2029
2030
2031 func ErrorIs(t TestingT, err, target error, msgAndArgs ...interface{}) bool {
2032 if h, ok := t.(tHelper); ok {
2033 h.Helper()
2034 }
2035 if errors.Is(err, target) {
2036 return true
2037 }
2038
2039 var expectedText string
2040 if target != nil {
2041 expectedText = target.Error()
2042 }
2043
2044 chain := buildErrorChainString(err)
2045
2046 return Fail(t, fmt.Sprintf("Target error should be in err chain:\n"+
2047 "expected: %q\n"+
2048 "in chain: %s", expectedText, chain,
2049 ), msgAndArgs...)
2050 }
2051
2052
2053
2054 func NotErrorIs(t TestingT, err, target error, msgAndArgs ...interface{}) bool {
2055 if h, ok := t.(tHelper); ok {
2056 h.Helper()
2057 }
2058 if !errors.Is(err, target) {
2059 return true
2060 }
2061
2062 var expectedText string
2063 if target != nil {
2064 expectedText = target.Error()
2065 }
2066
2067 chain := buildErrorChainString(err)
2068
2069 return Fail(t, fmt.Sprintf("Target error should not be in err chain:\n"+
2070 "found: %q\n"+
2071 "in chain: %s", expectedText, chain,
2072 ), msgAndArgs...)
2073 }
2074
2075
2076
2077 func ErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{}) bool {
2078 if h, ok := t.(tHelper); ok {
2079 h.Helper()
2080 }
2081 if errors.As(err, target) {
2082 return true
2083 }
2084
2085 chain := buildErrorChainString(err)
2086
2087 return Fail(t, fmt.Sprintf("Should be in error chain:\n"+
2088 "expected: %q\n"+
2089 "in chain: %s", target, chain,
2090 ), msgAndArgs...)
2091 }
2092
2093 func buildErrorChainString(err error) string {
2094 if err == nil {
2095 return ""
2096 }
2097
2098 e := errors.Unwrap(err)
2099 chain := fmt.Sprintf("%q", err.Error())
2100 for e != nil {
2101 chain += fmt.Sprintf("\n\t%q", e.Error())
2102 e = errors.Unwrap(e)
2103 }
2104 return chain
2105 }
2106
View as plain text