예제 #1
0
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
}
예제 #2
0
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
	}
}
예제 #3
0
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
}
예제 #4
0
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
	}
}
예제 #5
0
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
}
예제 #6
0
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
}
예제 #7
0
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
	}
}
예제 #8
0
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
	}
}
예제 #9
0
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
	}
}
예제 #10
0
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
	}
}
예제 #11
0
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
	}
}
예제 #13
0
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
	}
}
예제 #14
0
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))
	}
}
예제 #15
0
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
	}
}
예제 #16
0
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))
		}
	}
}
예제 #17
0
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))
	}
}