[/
 / Copyright (c) 2014 Mathieu Champlon
 /
 / Distributed under the Boost Software License, Version 1.0. (See accompanying
 / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 /]

[section:rationale Rationale]
[import example/rationale.cpp]

This section explains some of the design and implementation choices.

[section General design forces]

The general idea behind the library design is to be able to write tests quickly and easily as well as to get the best possible diagnostic upon error (both compile and runtime errors).

The chainable syntax has been chosen in order to be as intuitive as possible, with the most simple form covering the most general use cases.

Several design choices follow the same motivation :

* expectations are automatically verified upon destruction
* both const and non-const versions of a method are mocked by default
* the short-cuts for adding constraints cover 95% of the use cases
* non-serializable types do not yield compilation errors but are logged as '?' by default

At the same time customizing any aspect of the library should require minimum effort, for instance :

* custom constraints can be any functors, including free functions
* customizing the logging of a type is done by defining a serialization operator
* integrating into a test framework is made possible by writing a simple custom policy

[endsect]

[section Exceptions thrown should not extend std::exception]

By design the exceptions thrown upon error should not inherit from std::exception, for instance consider the following test case based on the example from the [link turtle.motivation motivation] section :

[overflow_throws]

Any call to 'v' will be unexpected and yield an exception, which if it were an std::exception would erroneously make the test succeed whereas it is supposed to pass only if the operation overflows (thus not triggering 'v').

[endsect]

[section The library interface is based on many macros]

Despite being often considered harmful they also provide a number of advantages :

* they pack a lot of code and hide implementation details (MOCK_BASE_CLASS, MOCK_METHOD)
* they make the interface homogeneous (MOCK_FUNCTOR, MOCK_CLASS)
* line number and file name can be added for logging purposes (MOCK_EXPECT)

Variadic macros are available for fairly recent compilers and provide a smoother user interface :

* they help seemlessly support arguments containing commas (MOCK_BASE_CLASS)
* they make some of the parameters optional (MOCK_METHOD)

An alternate more portable set of macros is provided for maximum portability if needed.

[endsect]

[endsect]
