github.com/aavshr/aws-sdk-go@v1.41.3/awstesting/assert.go (about) 1 package awstesting 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "net/url" 7 "reflect" 8 "regexp" 9 "sort" 10 "strings" 11 "testing" 12 13 "github.com/aavshr/aws-sdk-go/internal/smithytesting" 14 ) 15 16 // Match is a testing helper to test for testing error by comparing expected 17 // with a regular expression. 18 func Match(t *testing.T, regex, expected string) { 19 if !regexp.MustCompile(regex).Match([]byte(expected)) { 20 t.Errorf("%q\n\tdoes not match /%s/", expected, regex) 21 } 22 } 23 24 // AssertURL verifies the expected URL is matches the actual. 25 func AssertURL(t *testing.T, expect, actual string, msgAndArgs ...interface{}) bool { 26 expectURL, err := url.Parse(expect) 27 if err != nil { 28 t.Errorf(errMsg("unable to parse expected URL", err, msgAndArgs)) 29 return false 30 } 31 actualURL, err := url.Parse(actual) 32 if err != nil { 33 t.Errorf(errMsg("unable to parse actual URL", err, msgAndArgs)) 34 return false 35 } 36 37 equal(t, expectURL.Host, actualURL.Host, msgAndArgs...) 38 equal(t, expectURL.Scheme, actualURL.Scheme, msgAndArgs...) 39 equal(t, expectURL.Path, actualURL.Path, msgAndArgs...) 40 41 return AssertQuery(t, expectURL.Query().Encode(), actualURL.Query().Encode(), msgAndArgs...) 42 } 43 44 var queryMapKey = regexp.MustCompile("(.*?)\\.[0-9]+\\.key") 45 46 // AssertQuery verifies the expect HTTP query string matches the actual. 47 func AssertQuery(t *testing.T, expect, actual string, msgAndArgs ...interface{}) bool { 48 expectQ, err := url.ParseQuery(expect) 49 if err != nil { 50 t.Errorf(errMsg("unable to parse expected Query", err, msgAndArgs)) 51 return false 52 } 53 actualQ, err := url.ParseQuery(actual) 54 if err != nil { 55 t.Errorf(errMsg("unable to parse actual Query", err, msgAndArgs)) 56 return false 57 } 58 59 // Make sure the keys are the same 60 if !equal(t, queryValueKeys(expectQ), queryValueKeys(actualQ), msgAndArgs...) { 61 return false 62 } 63 64 keys := map[string][]string{} 65 for key, v := range expectQ { 66 if queryMapKey.Match([]byte(key)) { 67 submatch := queryMapKey.FindStringSubmatch(key) 68 keys[submatch[1]] = append(keys[submatch[1]], v...) 69 } 70 } 71 72 for k, v := range keys { 73 // clear all keys that have prefix 74 for key := range expectQ { 75 if strings.HasPrefix(key, k) { 76 delete(expectQ, key) 77 } 78 } 79 80 sort.Strings(v) 81 for i, value := range v { 82 expectQ[fmt.Sprintf("%s.%d.key", k, i+1)] = []string{value} 83 } 84 } 85 86 for k, expectQVals := range expectQ { 87 sort.Strings(expectQVals) 88 actualQVals := actualQ[k] 89 sort.Strings(actualQVals) 90 if !equal(t, expectQVals, actualQVals, msgAndArgs...) { 91 return false 92 } 93 } 94 95 return true 96 } 97 98 // AssertJSON verifies that the expect json string matches the actual. 99 func AssertJSON(t *testing.T, expect, actual string, msgAndArgs ...interface{}) bool { 100 expectVal := map[string]interface{}{} 101 if err := json.Unmarshal([]byte(expect), &expectVal); err != nil { 102 t.Errorf(errMsg("unable to parse expected JSON", err, msgAndArgs...)) 103 return false 104 } 105 106 actualVal := map[string]interface{}{} 107 if err := json.Unmarshal([]byte(actual), &actualVal); err != nil { 108 t.Errorf(errMsg("unable to parse actual JSON", err, msgAndArgs...)) 109 return false 110 } 111 112 return equal(t, expectVal, actualVal, msgAndArgs...) 113 } 114 115 // AssertXML verifies that the expect XML string matches the actual. 116 func AssertXML(t *testing.T, expect, actual string, msgAndArgs ...interface{}) bool { 117 if err := smithytesting.XMLEqual([]byte(expect), []byte(actual)); err != nil { 118 t.Error("expect XML match", err, messageFromMsgAndArgs(msgAndArgs)) 119 return false 120 } 121 122 return true 123 } 124 125 // DidPanic returns if the function paniced and returns true if the function paniced. 126 func DidPanic(fn func()) (bool, interface{}) { 127 var paniced bool 128 var msg interface{} 129 func() { 130 defer func() { 131 if msg = recover(); msg != nil { 132 paniced = true 133 } 134 }() 135 fn() 136 }() 137 138 return paniced, msg 139 } 140 141 // objectsAreEqual determines if two objects are considered equal. 142 // 143 // This function does no assertion of any kind. 144 // 145 // Based on github.com/stretchr/testify/assert.ObjectsAreEqual 146 // Copied locally to prevent non-test build dependencies on testify 147 func objectsAreEqual(expected, actual interface{}) bool { 148 if expected == nil || actual == nil { 149 return expected == actual 150 } 151 152 return reflect.DeepEqual(expected, actual) 153 } 154 155 // Equal asserts that two objects are equal. 156 // 157 // assert.Equal(t, 123, 123, "123 and 123 should be equal") 158 // 159 // Returns whether the assertion was successful (true) or not (false). 160 // 161 // Based on github.com/stretchr/testify/assert.Equal 162 // Copied locally to prevent non-test build dependencies on testify 163 func equal(t *testing.T, expected, actual interface{}, msgAndArgs ...interface{}) bool { 164 if !objectsAreEqual(expected, actual) { 165 t.Errorf("%s\n%s", messageFromMsgAndArgs(msgAndArgs), 166 SprintExpectActual(expected, actual)) 167 return false 168 } 169 170 return true 171 } 172 173 func errMsg(baseMsg string, err error, msgAndArgs ...interface{}) string { 174 message := messageFromMsgAndArgs(msgAndArgs) 175 if message != "" { 176 message += ", " 177 } 178 return fmt.Sprintf("%s%s, %v", message, baseMsg, err) 179 } 180 181 // Based on github.com/stretchr/testify/assert.messageFromMsgAndArgs 182 // Copied locally to prevent non-test build dependencies on testify 183 func messageFromMsgAndArgs(msgAndArgs []interface{}) string { 184 if len(msgAndArgs) == 0 || msgAndArgs == nil { 185 return "" 186 } 187 if len(msgAndArgs) == 1 { 188 return msgAndArgs[0].(string) 189 } 190 if len(msgAndArgs) > 1 { 191 return fmt.Sprintf(msgAndArgs[0].(string), msgAndArgs[1:]...) 192 } 193 return "" 194 } 195 196 func queryValueKeys(v url.Values) []string { 197 keys := make([]string, 0, len(v)) 198 for k := range v { 199 keys = append(keys, k) 200 } 201 sort.Strings(keys) 202 return keys 203 } 204 205 // SprintExpectActual returns a string for test failure cases when the actual 206 // value is not the same as the expected. 207 func SprintExpectActual(expect, actual interface{}) string { 208 return fmt.Sprintf("expect: %+v\nactual: %+v\n", expect, actual) 209 }