github.com/richardwilkes/toolbox@v1.121.0/check/check.go (about) 1 // Copyright (c) 2016-2024 by Richard A. Wilkes. All rights reserved. 2 // 3 // This Source Code Form is subject to the terms of the Mozilla Public 4 // License, version 2.0. If a copy of the MPL was not distributed with 5 // this file, You can obtain one at http://mozilla.org/MPL/2.0/. 6 // 7 // This Source Code Form is "Incompatible With Secondary Licenses", as 8 // defined by the Mozilla Public License, version 2.0. 9 10 package check 11 12 import ( 13 "bytes" 14 "fmt" 15 "reflect" 16 "strings" 17 "testing" 18 19 "github.com/richardwilkes/toolbox" 20 "github.com/richardwilkes/toolbox/errs" 21 ) 22 23 // Equal compares two values for equality. 24 func Equal(t *testing.T, expected, actual any, msgAndArgs ...any) { 25 t.Helper() 26 if !equal(expected, actual) { 27 errMsg(t, fmt.Sprintf("Expected %v, got %v", expected, actual), msgAndArgs...) 28 } 29 } 30 31 // NotEqual compares two values for inequality. 32 func NotEqual(t *testing.T, expected, actual any, msgAndArgs ...any) { 33 t.Helper() 34 if equal(expected, actual) { 35 errMsg(t, fmt.Sprintf("Expected %v to not be %v", expected, actual), msgAndArgs...) 36 } 37 } 38 39 func equal(expected, actual any) bool { 40 if expected == nil || actual == nil { 41 return expected == actual 42 } 43 exp, ok := expected.([]byte) 44 if !ok { 45 return reflect.DeepEqual(expected, actual) 46 } 47 act, ok2 := actual.([]byte) 48 if !ok2 { 49 return false 50 } 51 if exp == nil || act == nil { 52 return exp == nil && act == nil 53 } 54 return bytes.Equal(exp, act) 55 } 56 57 // Nil expects value to be nil. 58 func Nil(t *testing.T, value any, msgAndArgs ...any) { 59 t.Helper() 60 if !toolbox.IsNil(value) { 61 errMsg(t, fmt.Sprintf("Expected nil, instead got %v", value), msgAndArgs...) 62 } 63 } 64 65 // NotNil expects value to not be nil. 66 func NotNil(t *testing.T, value any, msgAndArgs ...any) { 67 t.Helper() 68 if toolbox.IsNil(value) { 69 errMsg(t, "Expected a non-nil value", msgAndArgs...) 70 } 71 } 72 73 // True expects value to be true. 74 func True(t *testing.T, value bool, msgAndArgs ...any) { 75 t.Helper() 76 if !value { 77 errMsg(t, "Expected true", msgAndArgs...) 78 } 79 } 80 81 // False expects value to be false. 82 func False(t *testing.T, value bool, msgAndArgs ...any) { 83 t.Helper() 84 if value { 85 errMsg(t, "Expected false", msgAndArgs...) 86 } 87 } 88 89 // Contains expects s to contain substr. 90 func Contains(t *testing.T, s, substr string, msgAndArgs ...any) { 91 t.Helper() 92 if !strings.Contains(s, substr) { 93 errMsg(t, fmt.Sprintf("Expected string %q to contain %q", s, substr), msgAndArgs...) 94 } 95 } 96 97 // NotContains expects s not to contain substr. 98 func NotContains(t *testing.T, s, substr string, msgAndArgs ...any) { 99 t.Helper() 100 if strings.Contains(s, substr) { 101 errMsg(t, fmt.Sprintf("Expected string %q not to contain %q", s, substr), msgAndArgs...) 102 } 103 } 104 105 // NoError expects err to be nil. 106 func NoError(t *testing.T, err error, msgAndArgs ...any) { 107 t.Helper() 108 if err != nil { 109 errMsg(t, fmt.Sprintf("Expected no error, got %v", err), msgAndArgs...) 110 } 111 } 112 113 // Error expects err to not be nil. 114 func Error(t *testing.T, err error, msgAndArgs ...any) { 115 t.Helper() 116 if err == nil { 117 errMsg(t, "Expected an error", msgAndArgs...) 118 } 119 } 120 121 // Panics expects f to panic when called. 122 func Panics(t *testing.T, f func(), msgAndArgs ...any) { 123 t.Helper() 124 if err := doesPanic(f); err == nil { 125 errMsg(t, "Expected panic, but got none", msgAndArgs...) 126 } 127 } 128 129 // NotPanics expects no panic when f is called. 130 func NotPanics(t *testing.T, f func(), msgAndArgs ...any) { 131 t.Helper() 132 if err := doesPanic(f); err != nil { 133 errMsg(t, fmt.Sprintf("Expected no panic, but does: %v", err), msgAndArgs...) 134 } 135 } 136 137 func doesPanic(f func()) (panicErr error) { 138 defer errs.Recovery(func(err error) { panicErr = err }) 139 f() 140 return 141 } 142 143 func errMsg(t *testing.T, prefix string, msgAndArgs ...any) { 144 t.Helper() 145 var buffer strings.Builder 146 buffer.WriteString(prefix) 147 switch len(msgAndArgs) { 148 case 0: 149 case 1: 150 _, _ = fmt.Fprintf(&buffer, "; %v", msgAndArgs[0]) 151 default: 152 if s, ok := msgAndArgs[0].(string); ok { 153 _, _ = fmt.Fprintf(&buffer, "; "+s, msgAndArgs[1:]...) 154 } else { 155 buffer.WriteByte(';') 156 for _, one := range msgAndArgs { 157 _, _ = fmt.Fprintf(&buffer, " %v", one) 158 } 159 } 160 } 161 t.Error(buffer.String()) 162 }