mirror of
https://github.com/mat007/turtle.git
synced 2026-06-22 12:13:43 +00:00
257 lines
7.2 KiB
Text
257 lines
7.2 KiB
Text
[/
|
|
/ 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 Limitations]
|
|
[import example/limitations_literal_zero.cpp]
|
|
[import example/limitations_throw_specifier.cpp]
|
|
[import example/limitations_non_virtual_method.cpp]
|
|
[import example/limitations_template_method.cpp]
|
|
[import example/limitations_private_method.cpp]
|
|
[import example/limitations_comma_in_macro.cpp]
|
|
[import example/limitations_const_parameter_warning.cpp]
|
|
|
|
This section lists the library known limitations.
|
|
|
|
[section No support for unicode logging]
|
|
|
|
There is no support for unicode logging mainly because Boost.Test does not support it either.
|
|
|
|
[endsect]
|
|
|
|
[section Literal 0 cannot be used as null pointer in constraints]
|
|
|
|
Given :
|
|
|
|
[limitations_literal_zero_problem]
|
|
|
|
The following code does not compile :
|
|
|
|
BOOST_AUTO_TEST_CASE( literal_zero )
|
|
{
|
|
mock_base m;
|
|
MOCK_EXPECT( m.method ).with( mock::equal( 0 ) ); // this fails
|
|
MOCK_EXPECT( m.method ).with( 0 ); // this fails too !
|
|
}
|
|
|
|
This is due to the fact that the library uses templates pretty heavily, and literal 0 is considered as an int when instantiating a template function.
|
|
|
|
A workaround is :
|
|
|
|
[limitations_literal_zero_solution_1]
|
|
|
|
However a somewhat better solution would be :
|
|
|
|
[limitations_literal_zero_solution_2]
|
|
|
|
or with C++11 nullptr support :
|
|
|
|
[limitations_literal_zero_solution_3]
|
|
|
|
[endsect]
|
|
|
|
[section Non-virtual methods cannot be mocked]
|
|
|
|
Given :
|
|
|
|
[limitations_non_virtual_method_problem]
|
|
|
|
the following code compiles but will not work as expected :
|
|
|
|
[limitations_non_virtual_method_problem_2]
|
|
|
|
The mock object will never be exercised because the library relies on polymorphism to hook the calls.
|
|
|
|
There is no other solution than to refactor the production code, the most simple being to change the method to virtual.
|
|
|
|
[endsect]
|
|
|
|
[section Template methods cannot be mocked]
|
|
|
|
Given :
|
|
|
|
[limitations_template_method_problem]
|
|
|
|
writing a mock object modeling 'concept' requires to list all the possible versions of 'method' :
|
|
|
|
[limitations_template_method_solution]
|
|
|
|
However if one or more template parameters must be explicitly specified as in :
|
|
|
|
[limitations_template_method_problem_2]
|
|
|
|
delegate methods must be manually added :
|
|
|
|
[limitations_template_method_solution_2]
|
|
|
|
While still somewhat possible, mocking a template method can indeed prove a bit cumbersome.
|
|
|
|
[endsect]
|
|
|
|
[section Template base class methods cannot be mocked without specifying the signature]
|
|
|
|
Given :
|
|
|
|
[limitations_template_base_class_method_problem]
|
|
|
|
the following code does not compile :
|
|
|
|
template< typename T >
|
|
MOCK_BASE_CLASS( mock_base, base< T > )
|
|
{
|
|
MOCK_METHOD( method, 0 ) // this fails
|
|
};
|
|
|
|
A workaround would be to add the signature to MOCK_METHOD :
|
|
|
|
[limitations_template_base_class_method_solution]
|
|
|
|
[endsect]
|
|
|
|
[section Private virtual methods cannot be mocked without specifying the signature]
|
|
|
|
Given :
|
|
|
|
[limitations_private_method_problem]
|
|
|
|
the following code does not compile :
|
|
|
|
MOCK_BASE_CLASS( mock_base, base )
|
|
{
|
|
MOCK_METHOD( method, 0 ) // this fails because 'method' is not visible
|
|
};
|
|
|
|
A workaround would be to add the signature to MOCK_METHOD :
|
|
|
|
[limitations_private_method_solution]
|
|
|
|
[endsect]
|
|
|
|
[section Methods with a throw specifier cannot be mocked]
|
|
|
|
Given :
|
|
|
|
[limitations_throw_specifier_problem]
|
|
|
|
the following code does not compile :
|
|
|
|
MOCK_BASE_CLASS( mock_class, base_class )
|
|
{
|
|
MOCK_METHOD( method, 0 ) // this fails because of the throw specifier
|
|
};
|
|
|
|
A workaround would be to write a proxy member function :
|
|
|
|
[limitations_throw_specifier_solution]
|
|
|
|
[endsect]
|
|
|
|
[section Compilers without support for variadic macros fail on commas in MOCK_BASE_CLASS]
|
|
|
|
For compilers without support for variadic macros given :
|
|
|
|
[limitations_comma_in_macro_problem]
|
|
|
|
the following code does not compile :
|
|
|
|
MOCK_BASE_CLASS( my_mock, my_base_class< int, int > ) // this fails because the pre-processor believes the macro to be called with 3 arguments
|
|
{};
|
|
|
|
One workaround is :
|
|
|
|
[limitations_comma_in_macro_solution_1]
|
|
|
|
Of course this is not always possible, as in :
|
|
|
|
template< typename T1, typename T2 >
|
|
MOCK_BASE_CLASS( my_mock, my_base_type< T1, T2 > )
|
|
{};
|
|
|
|
Another workaround would make use of [@http://www.boost.org/libs/preprocessor Boost.Preprocessor] :
|
|
|
|
[limitations_comma_in_macro_solution_2]
|
|
|
|
Actually BOOST_PP_COMMA implementation is quite trivial, being only :
|
|
|
|
#define BOOST_PP_COMMA() ,
|
|
|
|
Finally another workaround would be to not use the macro at all :
|
|
|
|
[limitations_comma_in_macro_solution_3]
|
|
|
|
Note that [@http://www.boost.org/libs/utility/identity_type/doc/html/index.html Boost.IdentityType] is of little help here because the type is by essence very often abstract, which doesn't work well for some compilers (e.g. gcc).
|
|
|
|
[endsect]
|
|
|
|
[section Warning C4505: '...' : unreferenced local function has been removed]
|
|
|
|
Example :
|
|
|
|
[teletype]
|
|
|
|
warning C4505: 'base::[thunk]: __thiscall base::`vcall'{0,{flat}}' }'' : unreferenced local function has been removed
|
|
|
|
[c++]
|
|
|
|
This seems to be [@https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=324427 a random bug] with some versions of the Microsoft Visual Studio compiler.
|
|
|
|
The only known workaround is to disable the warning with a pragma :
|
|
|
|
#pragma warning( disable: 4505 )
|
|
|
|
[endsect]
|
|
|
|
[section Warning C4301: '...': overriding virtual function only differs from '...' by const/volatile qualifier]
|
|
|
|
Example :
|
|
|
|
[teletype]
|
|
|
|
warning C4301: '`anonymous-namespace'::base::method': overriding virtual function only differs from '`anonymous-namespace'::base::method' by const/volatile qualifier
|
|
|
|
[c++]
|
|
|
|
Given :
|
|
|
|
[limitations_const_parameter_warning_problem]
|
|
|
|
the following code produces this warning with some versions of the Microsoft Visual Studio compiler :
|
|
|
|
MOCK_BASE_CLASS( mock_base, base )
|
|
{
|
|
MOCK_METHOD( method, 1 ) // this produces the warning
|
|
MOCK_METHOD( method, 1, void( const int ) ) // forcing the signature will not help, this produces the warning too !
|
|
};
|
|
|
|
The problem is that the 'const' is actually not part of the function signature and therefore cannot be introspected.
|
|
|
|
The first workaround would be to remove the 'const' all together.
|
|
|
|
This is more sensible than it first sounds, after all the 'const' is useless in this situation, indeed the following compiles, links and is valid C++ :
|
|
|
|
[limitations_const_parameter_warning_explanation]
|
|
|
|
Otherwise another workaround would be to provide a proxy method :
|
|
|
|
[limitations_const_parameter_warning_solution]
|
|
|
|
[endsect]
|
|
|
|
[section Warning C4267: 'argument' : conversion from 'size_t' to 'unsigned int', possible loss of data]
|
|
|
|
Compiling under Microsoft Visual Studio with the /Wp64 flag produces this warning at various locations in the library code.
|
|
|
|
This is actually a bug in the compiler, for more information see [@http://connect.microsoft.com/VisualStudio/feedback/details/253172/incorrect-warning-c4267 incorrect-warning-c4267].
|
|
|
|
[endsect]
|
|
|
|
[section Using C++11 lambda as constraints requires decltype compiler support]
|
|
|
|
The technique used in order to detect whether a constraint is a C++11 lambda or not is based on decltype, which means the library can fail to detect a lambda in case the compiler does not support it.
|
|
|
|
[endsect]
|
|
|
|
[endsect]
|