/* * 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 #include #include #include #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 struct MethodStubbingProgress { virtual ~MethodStubbingProgress() THROWS { } template typename std::enable_if::value, MethodStubbingProgress &>::type Return(const R &r) { return Do([r](const arglist &...) -> R { return r; }); } template typename std::enable_if::value, MethodStubbingProgress &>::type Return(const R &r) { return Do([&r](const arglist &...) -> R { return r; }); } MethodStubbingProgress & Return(const Quantifier &q) { const R &value = q.value; auto method = [value](const arglist &...) -> R { return value; }; return DoImpl(new Repeat(method, q.quantity)); } template MethodStubbingProgress & Return(const first &f, const second &s, const tail &... t) { Return(f); return Return(s, t...); } template typename std::enable_if::value, void>::type AlwaysReturn(const R &r) { return AlwaysDo([r](const arglist &...) -> R { return r; }); } template typename std::enable_if::value, void>::type AlwaysReturn(const R &r) { return AlwaysDo([&r](const arglist &...) -> R { return r; }); } MethodStubbingProgress & Return() { return Do([](const arglist &...) -> R { return DefaultValue::value(); }); } void AlwaysReturn() { return AlwaysDo([](const arglist &...) -> R { return DefaultValue::value(); }); } template MethodStubbingProgress &Throw(const E &e) { return Do([e](const arglist &...) -> R { throw e; }); } template MethodStubbingProgress & Throw(const Quantifier &q) { const E &value = q.value; auto method = [value](const arglist &...) -> R { throw value; }; return DoImpl(new Repeat(method, q.quantity)); } template MethodStubbingProgress & Throw(const first &f, const second &s, const tail &... t) { Throw(f); return Throw(s, t...); } template void AlwaysThrow(const E &e) { return AlwaysDo([e](const arglist &...) -> R { throw e; }); } virtual MethodStubbingProgress & Do(std::function method) { return DoImpl(new Repeat(method)); } template MethodStubbingProgress & Do(const Quantifier &q) { return DoImpl(new Repeat(q.value, q.quantity)); } template MethodStubbingProgress & Do(const first &f, const second &s, const tail &... t) { Do(f); return Do(s, t...); } virtual void AlwaysDo(std::function method) { DoImpl(new RepeatForever(method)); } protected: virtual MethodStubbingProgress &DoImpl(Action *action) = 0; private: MethodStubbingProgress &operator=(const MethodStubbingProgress &other) = delete; }; template struct MethodStubbingProgress { virtual ~MethodStubbingProgress() THROWS { } MethodStubbingProgress &Return() { return Do([](const arglist &...) -> void { return DefaultValue::value(); }); } void AlwaysReturn() { return AlwaysDo([](const arglist &...) -> void { return DefaultValue::value(); }); } MethodStubbingProgress & Return(const Quantifier &q) { auto method = [](const arglist &...) -> void { return DefaultValue::value(); }; return DoImpl(new Repeat(method, q.quantity)); } template MethodStubbingProgress &Throw(const E &e) { return Do([e](const arglist &...) -> void { throw e; }); } template MethodStubbingProgress & Throw(const Quantifier &q) { const E &value = q.value; auto method = [value](const arglist &...) -> void { throw value; }; return DoImpl(new Repeat(method, q.quantity)); } template MethodStubbingProgress & Throw(const first &f, const second &s, const tail &... t) { Throw(f); return Throw(s, t...); } template void AlwaysThrow(const E e) { return AlwaysDo([e](const arglist &...) -> void { throw e; }); } virtual MethodStubbingProgress &Do(std::function method) { return DoImpl(new Repeat(method)); } template MethodStubbingProgress & Do(const Quantifier &q) { return DoImpl(new Repeat(q.value, q.quantity)); } template MethodStubbingProgress & Do(const first &f, const second &s, const tail &... t) { Do(f); return Do(s, t...); } virtual void AlwaysDo(std::function method) { DoImpl(new RepeatForever(method)); } protected: virtual MethodStubbingProgress &DoImpl(Action *action) = 0; private: MethodStubbingProgress &operator=(const MethodStubbingProgress &other) = delete; }; }