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  }