template<class T>
const auto Equality_comparable =
$requires(T)(auto a, auto b) (
bool(a == b),
bool(a != b)
);
template<class T>
const auto Iterator() {
return CopyConstructible<T> &&
CopyAssignable<T> &&
Destructible<T> &&
$requires(T)(auto&& t) (
*t,
typename decltype(t)::type
);
}
}
template<class T, class F, class R, class... Ts>
const auto Callable(F f) {
return $requires(T)(auto&& t, Ts... args) (
R((t.*f)(args...));
)
}
template<class T, class R, class... Ts>
const auto Creatable = Callable<T, R(Ts...)>($(create));
struct Readable {
template<class T>
auto operator()() {
return CopyConstructible() &&
$requires(T)(auto&& t, std::ostream& os) (
os = (os << t)
) &&
Callable<T, void(int)>($(read));
}
};
struct FileReader {
void read(int) const {
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
};
std::ostream& operator<<(std::ostream& os, FileReader&) {
return os;
}
int main() {
// constraint checking
static_assert(Equality_comparable<int>, "");
static_assert(Readable{}.operator()<FileReader>(), "");
// template mocking
testing::GMock<Readable> mockReadable;
EXPECT_CALL(mockReadable, read, 42);
mockReadable.read(42);
// type erasure - dynamic dispatch
type_erasure::any<Readable> readable = FileReader{};
readable.read(42);
// type erasure mocking
readable = GMock<Readable>{};
EXPECT_CALL(mock, read, 42);
readable.read(42);
}
template<class TReader = Readable> // = 'Concept'
class App {
TReader reader; // static dispatch
type_erasure::any<Printable> printer; // dynamic dispatch
public:
App(TReader reader, type_erasure::any<Printable> printer)
: reader(reader), printer(printer)
{ }
void run() {
printer.print(reader.read());
}
};
int main() {
const auto injector = di::make_injector(
di::bind<Readable>.to<FileReader>()
di::bind<Printable>.to<ConsolePrinter>()
);
injector.create<App>().run();
}
"should print read text"_test = [] {
constexpr auto value = 42;
auto [sut, mocks] = testing::make<App>(); // creates System Under Test
// and Mocks
InSequence sequence;
EXPECT_CALL(mocks<Readable>(), read).WillOnce(Return(value));
EXPECT_CALL(mocks<Printable>(), print, value);
sut.run();
};
- Concepts
- Type Erasure (any)
- Mocking (GMock)
- Dependency Injection