Skip to content

Commit

Permalink
Rewrote matcher code.
Browse files Browse the repository at this point in the history
Now expected type doesn't need to be the same (or convertible) to the actual type. And the expected value is moved if possible, instead of always copied.
  • Loading branch information
FranckRJ committed May 7, 2022
1 parent 2441116 commit 3d0684a
Show file tree
Hide file tree
Showing 7 changed files with 487 additions and 388 deletions.
49 changes: 12 additions & 37 deletions include/fakeit/MatchersCollector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,6 @@ namespace fakeit {
template<std::size_t N>
using NakedArgType = typename naked_type<ArgType<index>>::type;

template<std::size_t N>
using ArgMatcherCreatorType = decltype(std::declval<TypedMatcherCreator<NakedArgType<N>>>());

MatchersCollector(std::vector<Destructible *> &matchers)
: _matchers(matchers) {
}
Expand All @@ -46,56 +43,34 @@ namespace fakeit {

template<typename Head>
typename std::enable_if< //
std::is_constructible<NakedArgType<index>, Head>::value, void> //
::type CollectMatchers(const Head &value) {
std::is_constructible<NakedArgType<index>, Head&&>::value, void> //
::type CollectMatchers(Head &&value) {

TypedMatcher<NakedArgType<index>> *d = Eq<NakedArgType<index>>(value).createMatcher();
TypedMatcher<NakedArgType<index>> *d = Eq(std::forward<Head>(value)).template createMatcher<NakedArgType<index>>();
_matchers.push_back(d);
}

template<typename Head, typename ...Tail>
typename std::enable_if< //
std::is_constructible<NakedArgType<index>, Head>::value //
, void> //
::type CollectMatchers(const Head &head, const Tail &... tail) {
CollectMatchers(head);
MatchersCollector<index + 1, arglist...> c(_matchers);
c.CollectMatchers(tail...);
}

template<typename Head>
typename std::enable_if< //
std::is_base_of<TypedMatcherCreator<NakedArgType<index>>, Head>::value, void> //
::type CollectMatchers(const Head &creator) {
TypedMatcher<NakedArgType<index>> *d = creator.createMatcher();
naked_type<Head>::type::template IsTypeCompatible<NakedArgType<index>>::value, void> //
::type CollectMatchers(Head &&creator) {
TypedMatcher<NakedArgType<index>> *d = creator.template createMatcher<NakedArgType<index>>();
_matchers.push_back(d);
}

template<typename Head, typename ...Tail>
//
typename std::enable_if< //
std::is_base_of<TypedMatcherCreator<NakedArgType<index>>, Head>::value, void> //
::type CollectMatchers(const Head &head, const Tail &... tail) {
CollectMatchers(head);
MatchersCollector<index + 1, arglist...> c(_matchers);
c.CollectMatchers(tail...);
}

template<typename Head>
typename std::enable_if<//
std::is_same<AnyMatcher, Head>::value, void> //
::type CollectMatchers(const Head &) {
TypedMatcher<NakedArgType<index>> *d = Any<NakedArgType<index>>().createMatcher();
std::is_same<AnyMatcher, typename naked_type<Head>::type>::value, void> //
::type CollectMatchers(Head &&) {
TypedMatcher<NakedArgType<index>> *d = Any().template createMatcher<NakedArgType<index>>();
_matchers.push_back(d);
}

template<typename Head, typename ...Tail>
typename std::enable_if< //
std::is_same<AnyMatcher, Head>::value, void> //
::type CollectMatchers(const Head &head, const Tail &... tail) {
CollectMatchers(head);
void CollectMatchers(Head &&head, Tail &&... tail) {
CollectMatchers(std::forward<Head>(head));
MatchersCollector<index + 1, arglist...> c(_matchers);
c.CollectMatchers(tail...);
c.CollectMatchers(std::forward<Tail>(tail)...);
}

};
Expand Down
39 changes: 15 additions & 24 deletions include/fakeit/MethodMockingContext.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,13 +222,13 @@ namespace fakeit {
_impl->setMethodDetails(mockName, methodName);
}

void setMatchingCriteria(std::function<bool(arglist &...)> predicate) {
void setMatchingCriteria(const std::function<bool(arglist &...)>& predicate) {
typename ActualInvocation<arglist...>::Matcher *matcher{
new UserDefinedInvocationMatcher<arglist...>(predicate)};
_impl->setInvocationMatcher(matcher);
}

void setMatchingCriteria(const std::vector<Destructible *> &matchers) {
void setMatchingCriteria(std::vector<Destructible *> &matchers) {
typename ActualInvocation<arglist...>::Matcher *matcher{
new ArgumentsMatcherInvocationMatcher<arglist...>(matchers)};
_impl->setInvocationMatcher(matcher);
Expand All @@ -245,13 +245,14 @@ namespace fakeit {
_impl->setMethodBodyByAssignment(method);
}

template<class ...matcherCreators, class = typename std::enable_if<
sizeof...(matcherCreators) == sizeof...(arglist)>::type>
void setMatchingCriteria(const matcherCreators &... matcherCreator) {
template<class ...matcherCreators>
typename std::enable_if< //
sizeof...(matcherCreators) == sizeof...(arglist), void> //
::type setMatchingCriteria(matcherCreators &&... matcherCreator) {
std::vector<Destructible *> matchers;

MatchersCollector<0, arglist...> c(matchers);
c.CollectMatchers(matcherCreator...);
c.CollectMatchers(std::forward<matcherCreators>(matcherCreator)...);

MethodMockingContext<R, arglist...>::setMatchingCriteria(matchers);
}
Expand Down Expand Up @@ -287,18 +288,13 @@ namespace fakeit {
return *this;
}

MockingContext<R, arglist...> &Using(const arglist &... args) {
MethodMockingContext<R, arglist...>::setMatchingCriteria(args...);
return *this;
}

template<class ...arg_matcher>
MockingContext<R, arglist...> &Using(const arg_matcher &... arg_matchers) {
MethodMockingContext<R, arglist...>::setMatchingCriteria(arg_matchers...);
MockingContext<R, arglist...> &Using(arg_matcher &&... arg_matchers) {
MethodMockingContext<R, arglist...>::setMatchingCriteria(std::forward<arg_matcher>(arg_matchers)...);
return *this;
}

MockingContext<R, arglist...> &Matching(std::function<bool(arglist &...)> matcher) {
MockingContext<R, arglist...> &Matching(const std::function<bool(arglist &...)>& matcher) {
MethodMockingContext<R, arglist...>::setMatchingCriteria(matcher);
return *this;
}
Expand All @@ -308,7 +304,7 @@ namespace fakeit {
return *this;
}

MockingContext<R, arglist...> &operator()(std::function<bool(arglist &...)> matcher) {
MockingContext<R, arglist...> &operator()(const std::function<bool(arglist &...)>& matcher) {
MethodMockingContext<R, arglist...>::setMatchingCriteria(matcher);
return *this;
}
Expand Down Expand Up @@ -352,18 +348,13 @@ namespace fakeit {
return *this;
}

MockingContext<void, arglist...> &Using(const arglist &... args) {
MethodMockingContext<void, arglist...>::setMatchingCriteria(args...);
return *this;
}

template<class ...arg_matcher>
MockingContext<void, arglist...> &Using(const arg_matcher &... arg_matchers) {
MethodMockingContext<void, arglist...>::setMatchingCriteria(arg_matchers...);
MockingContext<void, arglist...> &Using(arg_matcher &&... arg_matchers) {
MethodMockingContext<void, arglist...>::setMatchingCriteria(std::forward<arg_matcher>(arg_matchers)...);
return *this;
}

MockingContext<void, arglist...> &Matching(std::function<bool(arglist &...)> matcher) {
MockingContext<void, arglist...> &Matching(const std::function<bool(arglist &...)>& matcher) {
MethodMockingContext<void, arglist...>::setMatchingCriteria(matcher);
return *this;
}
Expand All @@ -373,7 +364,7 @@ namespace fakeit {
return *this;
}

MockingContext<void, arglist...> &operator()(std::function<bool(arglist &...)> matcher) {
MockingContext<void, arglist...> &operator()(const std::function<bool(arglist &...)>& matcher) {
MethodMockingContext<void, arglist...>::setMatchingCriteria(matcher);
return *this;
}
Expand Down
Loading

0 comments on commit 3d0684a

Please sign in to comment.