func()

in gomock/call.go [326:422]


func (c *Call) matches(args []interface{}) error {
	if !c.methodType.IsVariadic() {
		if len(args) != len(c.args) {
			return fmt.Errorf("expected call at %s has the wrong number of arguments. Got: %d, want: %d",
				c.origin, len(args), len(c.args))
		}

		for i, m := range c.args {
			if !m.Matches(args[i]) {
				return fmt.Errorf(
					"expected call at %s doesn't match the argument at index %d.\nGot: %v\nWant: %v",
					c.origin, i, formatGottenArg(m, args[i]), m,
				)
			}
		}
	} else {
		if len(c.args) < c.methodType.NumIn()-1 {
			return fmt.Errorf("expected call at %s has the wrong number of matchers. Got: %d, want: %d",
				c.origin, len(c.args), c.methodType.NumIn()-1)
		}
		if len(c.args) != c.methodType.NumIn() && len(args) != len(c.args) {
			return fmt.Errorf("expected call at %s has the wrong number of arguments. Got: %d, want: %d",
				c.origin, len(args), len(c.args))
		}
		if len(args) < len(c.args)-1 {
			return fmt.Errorf("expected call at %s has the wrong number of arguments. Got: %d, want: greater than or equal to %d",
				c.origin, len(args), len(c.args)-1)
		}

		for i, m := range c.args {
			if i < c.methodType.NumIn()-1 {
				// Non-variadic args
				if !m.Matches(args[i]) {
					return fmt.Errorf("expected call at %s doesn't match the argument at index %s.\nGot: %v\nWant: %v",
						c.origin, strconv.Itoa(i), formatGottenArg(m, args[i]), m)
				}
				continue
			}
			// The last arg has a possibility of a variadic argument, so let it branch

			// sample: Foo(a int, b int, c ...int)
			if i < len(c.args) && i < len(args) {
				if m.Matches(args[i]) {
					// Got Foo(a, b, c) want Foo(matcherA, matcherB, gomock.Any())
					// Got Foo(a, b, c) want Foo(matcherA, matcherB, someSliceMatcher)
					// Got Foo(a, b, c) want Foo(matcherA, matcherB, matcherC)
					// Got Foo(a, b) want Foo(matcherA, matcherB)
					// Got Foo(a, b, c, d) want Foo(matcherA, matcherB, matcherC, matcherD)
					continue
				}
			}

			// The number of actual args don't match the number of matchers,
			// or the last matcher is a slice and the last arg is not.
			// If this function still matches it is because the last matcher
			// matches all the remaining arguments or the lack of any.
			// Convert the remaining arguments, if any, into a slice of the
			// expected type.
			vArgsType := c.methodType.In(c.methodType.NumIn() - 1)
			vArgs := reflect.MakeSlice(vArgsType, 0, len(args)-i)
			for _, arg := range args[i:] {
				vArgs = reflect.Append(vArgs, reflect.ValueOf(arg))
			}
			if m.Matches(vArgs.Interface()) {
				// Got Foo(a, b, c, d, e) want Foo(matcherA, matcherB, gomock.Any())
				// Got Foo(a, b, c, d, e) want Foo(matcherA, matcherB, someSliceMatcher)
				// Got Foo(a, b) want Foo(matcherA, matcherB, gomock.Any())
				// Got Foo(a, b) want Foo(matcherA, matcherB, someEmptySliceMatcher)
				break
			}
			// Wrong number of matchers or not match. Fail.
			// Got Foo(a, b) want Foo(matcherA, matcherB, matcherC, matcherD)
			// Got Foo(a, b, c) want Foo(matcherA, matcherB, matcherC, matcherD)
			// Got Foo(a, b, c, d) want Foo(matcherA, matcherB, matcherC, matcherD, matcherE)
			// Got Foo(a, b, c, d, e) want Foo(matcherA, matcherB, matcherC, matcherD)
			// Got Foo(a, b, c) want Foo(matcherA, matcherB)

			return fmt.Errorf("expected call at %s doesn't match the argument at index %s.\nGot: %v\nWant: %v",
				c.origin, strconv.Itoa(i), formatGottenArg(m, args[i:]), c.args[i])
		}
	}

	// Check that all prerequisite calls have been satisfied.
	for _, preReqCall := range c.preReqs {
		if !preReqCall.satisfied() {
			return fmt.Errorf("expected call at %s doesn't have a prerequisite call satisfied:\n%v\nshould be called before:\n%v",
				c.origin, preReqCall, c)
		}
	}

	// Check that the call is not exhausted.
	if c.exhausted() {
		return fmt.Errorf("expected call at %s has already been called the max number of times", c.origin)
	}

	return nil
}