210 lines
6.8 KiB
C++
210 lines
6.8 KiB
C++
/*
|
|
* Copyright (c) 2014 Eran Pe'er.
|
|
*
|
|
* This program is made available under the terms of the MIT License.
|
|
*
|
|
* Created on Mar 10, 2014
|
|
*/
|
|
#pragma once
|
|
|
|
#include <functional>
|
|
#include <type_traits>
|
|
#include <stdexcept>
|
|
#include <utility>
|
|
|
|
#include "fakeit/FakeitExceptions.hpp"
|
|
#include "fakeit/ActualInvocation.hpp"
|
|
#include "fakeit/Quantifier.hpp"
|
|
#include "fakeit/Action.hpp"
|
|
#include "mockutils/DefaultValue.hpp"
|
|
#include "mockutils/Macros.hpp"
|
|
|
|
namespace fakeit {
|
|
|
|
template<typename R, typename ... arglist>
|
|
struct MethodStubbingProgress {
|
|
|
|
virtual ~MethodStubbingProgress() THROWS {
|
|
}
|
|
|
|
template<typename U = R>
|
|
typename std::enable_if<!std::is_reference<U>::value, MethodStubbingProgress<R, arglist...> &>::type
|
|
Return(const R &r) {
|
|
return Do([r](const arglist &...) -> R { return r; });
|
|
}
|
|
|
|
template<typename U = R>
|
|
typename std::enable_if<std::is_reference<U>::value, MethodStubbingProgress<R, arglist...> &>::type
|
|
Return(const R &r) {
|
|
return Do([&r](const arglist &...) -> R { return r; });
|
|
}
|
|
|
|
MethodStubbingProgress<R, arglist...> &
|
|
Return(const Quantifier<R> &q) {
|
|
const R &value = q.value;
|
|
auto method = [value](const arglist &...) -> R { return value; };
|
|
return DoImpl(new Repeat<R, arglist...>(method, q.quantity));
|
|
}
|
|
|
|
template<typename first, typename second, typename ... tail>
|
|
MethodStubbingProgress<R, arglist...> &
|
|
Return(const first &f, const second &s, const tail &... t) {
|
|
Return(f);
|
|
return Return(s, t...);
|
|
}
|
|
|
|
|
|
template<typename U = R>
|
|
typename std::enable_if<!std::is_reference<U>::value, void>::type
|
|
AlwaysReturn(const R &r) {
|
|
return AlwaysDo([r](const arglist &...) -> R { return r; });
|
|
}
|
|
|
|
template<typename U = R>
|
|
typename std::enable_if<std::is_reference<U>::value, void>::type
|
|
AlwaysReturn(const R &r) {
|
|
return AlwaysDo([&r](const arglist &...) -> R { return r; });
|
|
}
|
|
|
|
MethodStubbingProgress<R, arglist...> &
|
|
Return() {
|
|
return Do([](const arglist &...) -> R { return DefaultValue<R>::value(); });
|
|
}
|
|
|
|
void AlwaysReturn() {
|
|
return AlwaysDo([](const arglist &...) -> R { return DefaultValue<R>::value(); });
|
|
}
|
|
|
|
template<typename E>
|
|
MethodStubbingProgress<R, arglist...> &Throw(const E &e) {
|
|
return Do([e](const arglist &...) -> R { throw e; });
|
|
}
|
|
|
|
template<typename E>
|
|
MethodStubbingProgress<R, arglist...> &
|
|
Throw(const Quantifier<E> &q) {
|
|
const E &value = q.value;
|
|
auto method = [value](const arglist &...) -> R { throw value; };
|
|
return DoImpl(new Repeat<R, arglist...>(method, q.quantity));
|
|
}
|
|
|
|
template<typename first, typename second, typename ... tail>
|
|
MethodStubbingProgress<R, arglist...> &
|
|
Throw(const first &f, const second &s, const tail &... t) {
|
|
Throw(f);
|
|
return Throw(s, t...);
|
|
}
|
|
|
|
template<typename E>
|
|
void AlwaysThrow(const E &e) {
|
|
return AlwaysDo([e](const arglist &...) -> R { throw e; });
|
|
}
|
|
|
|
virtual MethodStubbingProgress<R, arglist...> &
|
|
Do(std::function<R(arglist &...)> method) {
|
|
return DoImpl(new Repeat<R, arglist...>(method));
|
|
}
|
|
|
|
template<typename F>
|
|
MethodStubbingProgress<R, arglist...> &
|
|
Do(const Quantifier<F> &q) {
|
|
return DoImpl(new Repeat<R, arglist...>(q.value, q.quantity));
|
|
}
|
|
|
|
template<typename first, typename second, typename ... tail>
|
|
MethodStubbingProgress<R, arglist...> &
|
|
Do(const first &f, const second &s, const tail &... t) {
|
|
Do(f);
|
|
return Do(s, t...);
|
|
}
|
|
|
|
virtual void AlwaysDo(std::function<R(arglist &...)> method) {
|
|
DoImpl(new RepeatForever<R, arglist...>(method));
|
|
}
|
|
|
|
protected:
|
|
|
|
virtual MethodStubbingProgress<R, arglist...> &DoImpl(Action<R, arglist...> *action) = 0;
|
|
|
|
private:
|
|
MethodStubbingProgress &operator=(const MethodStubbingProgress &other) = delete;
|
|
};
|
|
|
|
|
|
template<typename ... arglist>
|
|
struct MethodStubbingProgress<void, arglist...> {
|
|
|
|
virtual ~MethodStubbingProgress() THROWS {
|
|
}
|
|
|
|
MethodStubbingProgress<void, arglist...> &Return() {
|
|
return Do([](const arglist &...) -> void { return DefaultValue<void>::value(); });
|
|
}
|
|
|
|
void AlwaysReturn() {
|
|
return AlwaysDo([](const arglist &...) -> void { return DefaultValue<void>::value(); });
|
|
}
|
|
|
|
MethodStubbingProgress<void, arglist...> &
|
|
Return(const Quantifier<void> &q) {
|
|
auto method = [](const arglist &...) -> void { return DefaultValue<void>::value(); };
|
|
return DoImpl(new Repeat<void, arglist...>(method, q.quantity));
|
|
}
|
|
|
|
template<typename E>
|
|
MethodStubbingProgress<void, arglist...> &Throw(const E &e) {
|
|
return Do([e](const arglist &...) -> void { throw e; });
|
|
}
|
|
|
|
template<typename E>
|
|
MethodStubbingProgress<void, arglist...> &
|
|
Throw(const Quantifier<E> &q) {
|
|
const E &value = q.value;
|
|
auto method = [value](const arglist &...) -> void { throw value; };
|
|
return DoImpl(new Repeat<void, arglist...>(method, q.quantity));
|
|
}
|
|
|
|
template<typename first, typename second, typename ... tail>
|
|
MethodStubbingProgress<void, arglist...> &
|
|
Throw(const first &f, const second &s, const tail &... t) {
|
|
Throw(f);
|
|
return Throw(s, t...);
|
|
}
|
|
|
|
template<typename E>
|
|
void AlwaysThrow(const E e) {
|
|
return AlwaysDo([e](const arglist &...) -> void { throw e; });
|
|
}
|
|
|
|
virtual MethodStubbingProgress<void, arglist...> &Do(std::function<void(arglist &...)> method) {
|
|
return DoImpl(new Repeat<void, arglist...>(method));
|
|
}
|
|
|
|
template<typename F>
|
|
MethodStubbingProgress<void, arglist...> &
|
|
Do(const Quantifier<F> &q) {
|
|
return DoImpl(new Repeat<void, arglist...>(q.value, q.quantity));
|
|
}
|
|
|
|
template<typename first, typename second, typename ... tail>
|
|
MethodStubbingProgress<void, arglist...> &
|
|
Do(const first &f, const second &s, const tail &... t) {
|
|
Do(f);
|
|
return Do(s, t...);
|
|
}
|
|
|
|
virtual void AlwaysDo(std::function<void(arglist &...)> method) {
|
|
DoImpl(new RepeatForever<void, arglist...>(method));
|
|
}
|
|
|
|
protected:
|
|
|
|
virtual MethodStubbingProgress<void, arglist...> &DoImpl(Action<void, arglist...> *action) = 0;
|
|
|
|
private:
|
|
MethodStubbingProgress &operator=(const MethodStubbingProgress &other) = delete;
|
|
};
|
|
|
|
|
|
}
|