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 *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 *MatchErrorMatcher) Match(actual interface{}) (success bool, message string, err error) { if isNil(actual) { return false, "", fmt.Errorf("Expected an error, got nil") } if !isError(actual) { return false, "", fmt.Errorf("Expected an error. Got:\n%s", format.Object(actual, 1)) } actualErr := actual.(error) if isString(matcher.Expected) { if reflect.DeepEqual(actualErr.Error(), matcher.Expected) { return true, format.Message(actual, "not to match error", matcher.Expected), nil } else { return false, format.Message(actual, "to match error", matcher.Expected), nil } } if isError(matcher.Expected) { if reflect.DeepEqual(actualErr, matcher.Expected) { return true, format.Message(actual, "not to match error", matcher.Expected), nil } else { return false, format.Message(actual, "to match error", matcher.Expected), nil } } return false, "", fmt.Errorf("MatchError must be passed an error or string. Got:\n%s", format.Object(matcher.Expected, 1)) }
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 *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 *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 *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 *HaveKeyMatcher) NegatedFailureMessage(actual interface{}) (message string) { switch matcher.Key.(type) { case omegaMatcher: return format.Message(actual, "not to have key matching", matcher.Key) default: return format.Message(actual, "not to have key", matcher.Key) } }
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 *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 *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 (m *exitMatcher) FailureMessage(actual interface{}) (message string) { if m.actualExitCode == -1 { return "Expected process to exit. It did not." } else { return format.Message(m.actualExitCode, "to match exit code:", m.exitCode) } }
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 *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 *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 (m *FieldsMatcher) FailureMessage(actual interface{}) (message string) { failures := make([]string, len(m.failures)) for i := range m.failures { failures[i] = m.failures[i].Error() } return format.Message(reflect.TypeOf(actual).Name(), fmt.Sprintf("to match fields: {\n%v\n}\n", strings.Join(failures, "\n"))) }
func (matcher *ReceiveMatcher) NegatedFailureMessage(actual interface{}) (message string) { subMatcher, hasSubMatcher := (matcher.Arg).(omegaMatcher) if hasSubMatcher { return subMatcher.NegatedFailureMessage(matcher.receivedValue) } else { return format.Message(actual, "not to receive anything") } }
func (m *exitMatcher) NegatedFailureMessage(actual interface{}) (message string) { if m.actualExitCode == -1 { return "you really shouldn't be able to see this!" } else { if m.exitCode == -1 { return "Expected process not to exit. It did." } else { return format.Message(m.actualExitCode, "not to match exit code:", m.exitCode) } } }
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 *HaveKeyWithValueMatcher) FailureMessage(actual interface{}) (message string) { str := "to have {key: value}" if _, ok := matcher.Key.(omegaMatcher); ok { str += " matching" } else if _, ok := matcher.Value.(omegaMatcher); ok { str += " matching" } expect := make(map[interface{}]interface{}, 1) expect[matcher.Key] = matcher.Value return format.Message(actual, str, expect) }
func (p *panics) FailureMessage(actual interface{}) (message string) { if p.actPanicValue == nil { return format.Message(actual, "to panic with:", p.err) } return fmt.Sprintf( "Expected\n%s\nto panic with:\n%s\nbut got:\n%s", format.Object(actual, 1), format.Object(p.err, 1), format.Object(p.actPanicValue, 1), ) }
func (p *panicsWithSubstring) FailureMessage(actual interface{}) string { if p.panics.actPanicValue == nil { return format.Message(actual, "to panic contains:", p.substr) } return fmt.Sprintf( "Expected\n%s\nto panic contains:\n%s\nbut got:\n%s", format.Object(actual, 1), format.Object(p.substr, 1), format.Object(p.actPanicValue, 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)) } }
func (matcher *ReceiveMatcher) NegatedFailureMessage(actual interface{}) (message string) { subMatcher, hasSubMatcher := (matcher.Arg).(omegaMatcher) if hasSubMatcher { if matcher.receivedValue.IsValid() { return subMatcher.NegatedFailureMessage(matcher.receivedValue.Interface()) } return "When passed a matcher, ReceiveMatcher's channel *must* receive something." } else { return format.Message(actual, "not to receive anything") } }
func (matcher *HaveKeyWithValueMatcher) NegatedFailureMessage(actual interface{}) (message string) { kStr := "not to have key" if _, ok := matcher.Key.(omegaMatcher); ok { kStr = "not to have key matching" } vStr := "or that key's value not be" if _, ok := matcher.Value.(omegaMatcher); ok { vStr = "or to have that key's value not matching" } return format.Message(actual, kStr, matcher.Key, vStr, matcher.Value) }
func (matcher *ReceiveMatcher) FailureMessage(actual interface{}) (message string) { subMatcher, hasSubMatcher := (matcher.Arg).(omegaMatcher) closedAddendum := "" if matcher.channelClosed { closedAddendum = " The channel is closed." } if hasSubMatcher { if matcher.receivedValue.IsValid() { return subMatcher.FailureMessage(matcher.receivedValue.Interface()) } return "When passed a matcher, ReceiveMatcher's channel *must* receive something." } else { return format.Message(actual, "to receive something."+closedAddendum) } }
func (m *PointerMatcher) Match(actual interface{}) (bool, error) { val := reflect.ValueOf(actual) // return error if actual type is not a pointer if val.Kind() != reflect.Ptr { return false, fmt.Errorf("PointerMatcher expects a pointer but we have '%s'", val.Kind()) } if !val.IsValid() || val.IsNil() { m.failure = format.Message(actual, "not to be <nil>") return false, nil } // Forward the value. elem := val.Elem().Interface() match, err := m.Matcher.Match(elem) if !match { m.failure = m.Matcher.FailureMessage(elem) } return match, err }