func (matcher *ContainElementMatcher) Match(actual interface{}) (success bool, message string, err error) { if !isArrayOrSlice(actual) && !isMap(actual) { return false, "", fmt.Errorf("ContainElement matcher expects an array/slice/map. Got:\n%s", format.Object(actual, 1)) } elemMatcher, elementIsMatcher := matcher.Element.(omegaMatcher) matchingString := " matching" if !elementIsMatcher { elemMatcher = &EqualMatcher{Expected: matcher.Element} matchingString = "" } value := reflect.ValueOf(actual) var keys []reflect.Value if isMap(actual) { keys = value.MapKeys() } for i := 0; i < value.Len(); i++ { var success bool var err error if isMap(actual) { success, _, err = elemMatcher.Match(value.MapIndex(keys[i]).Interface()) } else { success, _, err = elemMatcher.Match(value.Index(i).Interface()) } if err != nil { return false, "", fmt.Errorf("ContainElement's element matcher failed with:\n\t%s", err.Error()) } if success { return true, format.Message(actual, "not to contain element"+matchingString, matcher.Element), nil } } return false, format.Message(actual, "to contain element"+matchingString, matcher.Element), nil }
func (matcher *BeNilMatcher) Match(actual interface{}) (success bool, message string, err error) { if isNil(actual) { return true, format.Message(actual, "not to be nil"), nil } else { return false, format.Message(actual, "to be nil"), nil } }
func (matcher *HaveKeyMatcher) Match(actual interface{}) (success bool, message string, err error) { if !isMap(actual) { return false, "", fmt.Errorf("HaveKey matcher expects a map. Got:%s", format.Object(actual, 1)) } keyMatcher, keyIsMatcher := matcher.Key.(omegaMatcher) matchingString := " matching" if !keyIsMatcher { keyMatcher = &EqualMatcher{Expected: matcher.Key} matchingString = "" } keys := reflect.ValueOf(actual).MapKeys() for i := 0; i < len(keys); i++ { success, _, err := keyMatcher.Match(keys[i].Interface()) if err != nil { return false, "", fmt.Errorf("HaveKey's key matcher failed with:\n%s%s", format.Indent, err.Error()) } if success { return true, format.Message(actual, "not to have key"+matchingString, matcher.Key), nil } } return false, format.Message(actual, "to have key"+matchingString, matcher.Key), nil }
func (matcher *BeClosedMatcher) Match(actual interface{}) (success bool, message string, err error) { if !isChan(actual) { return false, "", fmt.Errorf("BeClosed matcher expects a channel. Got:\n%s", format.Object(actual, 1)) } channelType := reflect.TypeOf(actual) channelValue := reflect.ValueOf(actual) var closed bool if channelType.ChanDir() == reflect.SendDir { return false, "", fmt.Errorf("BeClosed matcher cannot determine if a send-only channel is closed or open. Got:\n%s", format.Object(actual, 1)) } else { winnerIndex, _, open := reflect.Select([]reflect.SelectCase{ reflect.SelectCase{Dir: reflect.SelectRecv, Chan: channelValue}, reflect.SelectCase{Dir: reflect.SelectDefault}, }) if winnerIndex == 0 { closed = !open } else if winnerIndex == 1 { closed = false } } if closed { return true, format.Message(actual, "to be open"), nil } else { return false, format.Message(actual, "to be closed"), nil } }
func (matcher *PanicMatcher) Match(actual interface{}) (success bool, message string, err error) { if actual == nil { return false, "", fmt.Errorf("PanicMatcher expects a non-nil actual.") } actualType := reflect.TypeOf(actual) if actualType.Kind() != reflect.Func { return false, "", fmt.Errorf("PanicMatcher expects a function. Got:\n%s", format.Object(actual, 1)) } if !(actualType.NumIn() == 0 && actualType.NumOut() == 0) { return false, "", fmt.Errorf("PanicMatcher expects a function with no arguments and no return value. Got:\n%s", format.Object(actual, 1)) } success = false message = format.Message(actual, "to panic") err = nil defer func() { if e := recover(); e != nil { success = true message = format.Message(actual, "not to panic") err = nil } }() reflect.ValueOf(actual).Call([]reflect.Value{}) return }
func (matcher *MatchJSONMatcher) Match(actual interface{}) (success bool, message string, err error) { actualString, aok := toString(actual) expectedString, eok := toString(matcher.JSONToMatch) if aok && eok { abuf := new(bytes.Buffer) ebuf := new(bytes.Buffer) if err := json.Indent(abuf, []byte(actualString), "", " "); err != nil { return false, "", err } if err := json.Indent(ebuf, []byte(expectedString), "", " "); err != nil { return false, "", err } var aval interface{} var eval interface{} json.Unmarshal([]byte(actualString), &aval) json.Unmarshal([]byte(expectedString), &eval) if reflect.DeepEqual(aval, eval) { return true, format.Message(abuf.String(), "not to match JSON of", ebuf.String()), nil } else { return false, format.Message(abuf.String(), "to match JSON of", ebuf.String()), nil } } else { return false, "", fmt.Errorf("MatchJSONMatcher matcher requires a string or stringer. Got:\n%s", format.Object(actual, 1)) } return false, "", nil }
func (matcher *EqualMatcher) Match(actual interface{}) (success bool, message string, err error) { if actual == nil && matcher.Expected == nil { return false, "", fmt.Errorf("Refusing to compare <nil> to <nil>.") } if reflect.DeepEqual(actual, matcher.Expected) { return true, format.Message(actual, "not to equal", matcher.Expected), nil } else { return false, format.Message(actual, "to equal", matcher.Expected), nil } }
func (matcher *BeTrueMatcher) Match(actual interface{}) (success bool, message string, err error) { if !isBool(actual) { return false, "", fmt.Errorf("Expected a boolean. Got:\n%s", format.Object(actual, 1)) } if actual == true { return true, format.Message(actual, "not to be true"), nil } else { return false, format.Message(actual, "to be true"), nil } }
func (matcher *ReceiveMatcher) Match(actual interface{}) (success bool, message string, err error) { if !isChan(actual) { return false, "", fmt.Errorf("ReceiveMatcher expects a channel. Got:\n%s", format.Object(actual, 1)) } channelType := reflect.TypeOf(actual) channelValue := reflect.ValueOf(actual) if channelType.ChanDir() == reflect.SendDir { return false, "", fmt.Errorf("ReceiveMatcher matcher cannot be passed a send-only channel. Got:\n%s", format.Object(actual, 1)) } if matcher.Arg != nil { argType := reflect.TypeOf(matcher.Arg) if argType.Kind() != reflect.Ptr { return false, "", fmt.Errorf("Cannot assign a value from the channel:\n%s\nTo:\n%s\nYou need to pass a pointer!", format.Object(actual, 1), format.Object(matcher.Arg, 1)) } assignable := channelType.Elem().AssignableTo(argType.Elem()) if !assignable { return false, "", fmt.Errorf("Cannot assign a value from the channel:\n%s\nTo:\n%s", format.Object(actual, 1), format.Object(matcher.Arg, 1)) } } var closed bool var didReceive bool winnerIndex, value, open := reflect.Select([]reflect.SelectCase{ reflect.SelectCase{Dir: reflect.SelectRecv, Chan: channelValue}, reflect.SelectCase{Dir: reflect.SelectDefault}, }) if winnerIndex == 0 { closed = !open didReceive = open } else if winnerIndex == 1 { closed = false didReceive = false } if closed { return false, "", fmt.Errorf("ReceiveMatcher was given a closed channel:\n%s", format.Object(actual, 1)) } if didReceive { if matcher.Arg != nil { outValue := reflect.ValueOf(matcher.Arg) reflect.Indirect(outValue).Set(value) } return true, format.Message(actual, "not to receive anything"), nil } else { return false, format.Message(actual, "to receive something"), nil } }
func (matcher *BeZeroMatcher) Match(actual interface{}) (success bool, message string, err error) { if actual == nil { return true, format.Message(actual, "not to be zero-valued"), nil } zeroValue := reflect.Zero(reflect.TypeOf(actual)).Interface() if reflect.DeepEqual(zeroValue, actual) { return true, format.Message(actual, "not to be zero-valued"), nil } else { return false, format.Message(actual, "to be zero-valued"), nil } }
func (matcher *BeEmptyMatcher) Match(actual interface{}) (success bool, message string, err error) { length, ok := lengthOf(actual) if ok { if length == 0 { return true, format.Message(actual, "not to be empty"), nil } else { return false, format.Message(actual, "to be empty"), nil } } else { return false, "", fmt.Errorf("BeEmpty matcher expects a string/array/map/channel/slice. Got:\n%s", format.Object(actual, 1)) } }
func (matcher *AssignableToTypeOfMatcher) Match(actual interface{}) (success bool, message string, err error) { if actual == nil || matcher.Expected == nil { return false, "", fmt.Errorf("Refusing to compare <nil> to <nil>.") } actualType := reflect.TypeOf(actual) expectedType := reflect.TypeOf(matcher.Expected) if actualType.AssignableTo(expectedType) { return true, format.Message(actual, fmt.Sprintf("not to be assignable to the type: %T", matcher.Expected)), nil } else { return false, format.Message(actual, fmt.Sprintf("to be assignable to the type: %T", matcher.Expected)), nil } }
func (matcher *BeNumericallyMatcher) Match(actual interface{}) (success bool, message string, err error) { if len(matcher.CompareTo) == 0 || len(matcher.CompareTo) > 2 { return false, "", fmt.Errorf("BeNumerically requires 1 or 2 CompareTo arguments. Got:\n%s", format.Object(matcher.CompareTo, 1)) } if !isNumber(actual) { return false, "", fmt.Errorf("Expected a number. Got:\n%s", format.Object(actual, 1)) } if !isNumber(matcher.CompareTo[0]) { return false, "", fmt.Errorf("Expected a number. Got:\n%s", format.Object(matcher.CompareTo[0], 1)) } if len(matcher.CompareTo) == 2 && !isNumber(matcher.CompareTo[1]) { return false, "", fmt.Errorf("Expected a number. Got:\n%s", format.Object(matcher.CompareTo[0], 1)) } switch matcher.Comparator { case "==", "~", ">", ">=", "<", "<=": default: return false, "", fmt.Errorf("Unknown comparator: %s", matcher.Comparator) } if isFloat(actual) || isFloat(matcher.CompareTo[0]) { var secondOperand float64 = 1e-8 if len(matcher.CompareTo) == 2 { secondOperand = toFloat(matcher.CompareTo[1]) } success = matcher.matchFloats(toFloat(actual), toFloat(matcher.CompareTo[0]), secondOperand) } else if isInteger(actual) { var secondOperand int64 = 0 if len(matcher.CompareTo) == 2 { secondOperand = toInteger(matcher.CompareTo[1]) } success = matcher.matchIntegers(toInteger(actual), toInteger(matcher.CompareTo[0]), secondOperand) } else if isUnsignedInteger(actual) { var secondOperand uint64 = 0 if len(matcher.CompareTo) == 2 { secondOperand = toUnsignedInteger(matcher.CompareTo[1]) } success = matcher.matchUnsignedIntegers(toUnsignedInteger(actual), toUnsignedInteger(matcher.CompareTo[0]), secondOperand) } else { return false, "", fmt.Errorf("Failed to compare:\n%s\n%s:\n%s", format.Object(actual, 1), matcher.Comparator, format.Object(matcher.CompareTo[0], 1)) } if success { return true, format.Message(actual, fmt.Sprintf("not to be %s", matcher.Comparator), matcher.CompareTo[0]), nil } else { return false, format.Message(actual, fmt.Sprintf("to be %s", matcher.Comparator), matcher.CompareTo[0]), nil } }
func (matcher *ContainSubstringMatcher) Match(actual interface{}) (success bool, message string, err error) { actualString, ok := toString(actual) if ok { stringToMatch := matcher.Substr if len(matcher.Args) > 0 { stringToMatch = fmt.Sprintf(matcher.Substr, matcher.Args...) } match := strings.Contains(actualString, stringToMatch) if match { return true, format.Message(actual, "not to contain substring", stringToMatch), nil } else { return false, format.Message(actual, "to contain substring", stringToMatch), nil } } else { return false, "", fmt.Errorf("ContainSubstring matcher requires a string or stringer. Got:\n%s", format.Object(actual, 1)) } }
func (matcher *BeEquivalentToMatcher) Match(actual interface{}) (success bool, message string, err error) { if actual == nil && matcher.Expected == nil { return false, "", fmt.Errorf("Both actual and expected must not be nil.") } convertedActual := actual if actual != nil && matcher.Expected != nil && reflect.TypeOf(actual).ConvertibleTo(reflect.TypeOf(matcher.Expected)) { convertedActual = reflect.ValueOf(actual).Convert(reflect.TypeOf(matcher.Expected)).Interface() } if reflect.DeepEqual(convertedActual, matcher.Expected) { return true, format.Message(actual, "not to be equivalent to", matcher.Expected), nil } else { return false, format.Message(actual, "to be equivalent to", matcher.Expected), nil } }
func (matcher *HaveOccurredMatcher) Match(actual interface{}) (success bool, message string, err error) { if actual == nil { return false, format.Message(actual, "to have occurred"), nil } else { if isError(actual) { return true, fmt.Sprintf("Expected error:\n%s\n%s\n%s", format.Object(actual, 1), format.IndentString(actual.(error).Error(), 1), "not to have occurred"), nil } else { return false, "", fmt.Errorf("Expected an error. Got:\n%s", format.Object(actual, 1)) } } }
func (matcher *MatchRegexpMatcher) Match(actual interface{}) (success bool, message string, err error) { actualString, ok := toString(actual) if ok { re := matcher.Regexp if len(matcher.Args) > 0 { re = fmt.Sprintf(matcher.Regexp, matcher.Args...) } match, err := regexp.Match(re, []byte(actualString)) if err != nil { return false, "", fmt.Errorf("RegExp match failed to compile with error:\n\t%s", err.Error()) } if match { return true, format.Message(actual, "not to match regular expression", re), nil } else { return false, format.Message(actual, "to match regular expression", re), nil } } else { return false, "", fmt.Errorf("RegExp matcher requires a string or stringer.\nGot:%s", format.Object(actual, 1)) } }