Slides
Slides
Slides
Andrew Paxie
Introduction
Motivation
Trompeloeil
Backporting Goals
Backporting to C++11
Library
Language
Issues
Summary
Introduction
Motivation
Trompeloeil
Backporting Goals
Backporting to C++11
Library
Language
Issues
Summary
I Google Mock
I Turtle
I HippoMocks
I FakeIt
I Mockator
I Trompeloeil
I Upgrade compiler to C++14
I Avoid mocking frameworks in unit tests
Introduction
Motivation
Trompeloeil
Backporting Goals
Backporting to C++11
Library
Language
Issues
Summary
https://github.com/rollbear/trompeloeil
https://github.com/rollbear https://github.com/AndrewPaxie
https://playfulprogramming.blogspot.com https://blog.andrew.paxie.org
Main features:
I Mock functions
I Expectations
I Matchers
I Modifiers
Main features:
I Mock functions
I Expectations
I Matchers
I Modifiers
Other features:
I Sequencing expectations
I Object-lifetime monitoring
I Integration into test framework reporting
I Tracing
Interface
struct Interface
{
virtual void setValue(int v) = 0;
virtual int getValue() const = 0;
};
Interface
struct Interface
{
virtual void setValue(int v) = 0;
virtual int getValue() const = 0;
};
Mock class
struct Mock: Interface
{
MAKE_MOCK1(setValue, void(int), override);
MAKE_CONST_MOCK0(getValue, int(), override);
};
Interface
struct Interface
{
virtual void setValue(int v) = 0;
virtual int getValue() const = 0;
};
Mock class
struct Mock: Interface mock functions ----+
{ |
MAKE_MOCK1(setValue, void(int), override); <-+
MAKE_CONST_MOCK0(getValue, int(), override); <-+
};
Mock obj;
REQUIRE_CALL(obj, setValue(lt(7))
.WITH(obj.getValue() == 3)
.RETURN(_1 + 2);
// :::
}
Paxie Backporting to the Future Pacific++ 2018 12 / 87
Trompeloeil
Example
struct Interface struct Mock: Interface
{ {
virtual void setValue(int v) = 0; MAKE_MOCK1(setValue, void(int), override);
virtual int getValue() const = 0; MAKE_CONST_MOCK0(getValue, int(), override);
}; };
Mock obj;
I REQUIRE_CALL(obj, func(params))
I ALLOW_CALL(obj, func(params))
I FORBID_CALL(obj, func(params))
REQUIRE_CALL(obj, setValue(ANY(int));
FORBID_CALL(obj, getValue());
// :::
}
Also: Named variants of the above
Paxie Backporting to the Future Pacific++ 2018 19 / 87
Trompeloeil
Matchers
Matchers Notes
_ ANY(type) wildcards
eq(mark) ne(mark) equal, not equal
ge(mark) le(mark) [greater or less] than or equal
gt(mark) lt(mark) greater than, less than
re(mark, ...) regular expression
! negating matcher
* pointer dereference
I WITH(condition)
I SIDE_EFFECT(statement)
I RETURN(expression)
I THROW(expression)
Introduction
Motivation
Trompeloeil
Backporting Goals
Backporting to C++11
Library
Language
Issues
Summary
Introduction
Motivation
Trompeloeil
Backporting Goals
Backporting to C++11
Library
Language
Issues
Summary
Introduction
Motivation
Trompeloeil
Backporting Goals
Backporting to C++11
Library
Language
Issues
Summary
decltype(auto) [N3638]
Return type deduction for normal functions [N3638]
Generalized lambda captures [N3648]
Generic lambda expressions [N3649]
Introduction
Motivation
Trompeloeil
Backporting Goals
Backporting to C++11
Library
Language
Issues
Summary
Introduction
Motivation
Trompeloeil
Backporting Goals
Backporting to C++11
Library
Language
Issues
Summary
C++14
[](auto x)
{
return x + x;
}
C++14 C++14
[](auto x) [](auto&&... xs)
{ {
return x + x; return sum(
} std::forward<
decltype(xs)
>(xs)...);
}
C++14
[](auto x)
{
return x + x;
}
C++14 C++11/14
[](auto x) class ClosureType
{ {
return x + x; public:
} template <typename T>
auto
operator()(T x) const
{
return x + x;
}
};
C++14
[](
std::ostream& os,
auto const& value)
{
os << " == ";
print(os, value);
}
C++14 C++11/14
[]( struct equal_printer
std::ostream& os, {
auto const& value) template <typename T>
{ void
os << " == "; operator()(
print(os, value); std::ostream& os,
} T const& value)
const
{
os << " == ";
print(os, value);
}
};
C++14
auto p = std::make_unique<std::vector<int>>();
[ptr = std::move(p)]
{
return ptr->empty();
}
C++14
auto p =
std::make_unique<
std::vector<int>>();
[ptr = std::move(p)]
{
return ptr->empty();
}
C++14 C++11/14
auto p = struct ClosureType
std::make_unique< {
std::vector<int>>(); using T = std::unique_ptr<
std::vector<int>>;
[ptr = std::move(p)]
{ explicit ClosureType(T&& p)
return ptr->empty(); : ptr(std::move(p))
} {}
private:
T ptr;
};
C++14
inline auto
regex_check(std::regex&& re)
{
return [re = std::move(re)](
/* args */ )
-> decltype(std::regex_search(
/* args */ ,
re))
{
return std::regex_search(
/* args */ ,
re);
}
}
C++14 C++11/14
inline auto struct regex_check
regex_check(std::regex&& re) {
{ regex_check(std::regex&& re_)
return [re = std::move(re)]( : re(std::move(re_))
/* args */ ) {}
-> decltype(std::regex_search(
/* args */ , template <typename T>
re)) bool
{ operator()(/* args */ ) const
return std::regex_search( {
/* args */ , return std::regex_search(
re); /* args */ ,
} re);
} }
std::regex_check re;
};
C++14
auto foo(int var)
{
if (var)
{
return 0;
}
else
{
return var + 1;
}
}
Paxie Backporting to the Future Pacific++ 2018 46 / 87
Replace Return Type Deduction
Approach
C++14
auto
foo(int var)
{
if (var)
{
return 0;
}
else
{
return var + 1;
}
}
C++14 C++11/14
auto auto
foo(int var) foo(int var)
-> int
{ {
if (var) if (var)
{ {
return 0; return 0;
} }
else else
{ {
return var + 1; return var + 1;
} }
} }
C++14
template <
typename Kind = wildcard
>
auto
re(
std::string s,
match_flag_type match_type)
{
return make_matcher<Kind>(
lambdas::regex_check(
std::regex(s), match_type),
lambdas::regex_printer(),
std::move(s));
}
C++14 C++11/14
template < template <
typename Kind = wildcard typename Kind = wildcard,
typename R = /* omitted */
> >
auto auto
re( re(
std::string s, std::string s,
match_flag_type match_type) match_flag_type match_type)
-> decltype(R)
{ {
return make_matcher<Kind>( return make_matcher<Kind>(
lambdas::regex_check( lambdas::regex_check(
std::regex(s), match_type), std::regex(s), match_type),
lambdas::regex_printer(), lambdas::regex_printer(),
std::move(s)); std::move(s));
} }
C++14
handle_return(
[&](auto& x)
-> decltype(auto)
{
// Define placeholders
// _1 ... _15 from x
return __VA_ARGS__;
})
C++14 C++11/14
handle_return( handle_return(
[&](auto& x) [&](/* ::: */ & x)
-> decltype(auto) -> return_of_t
{ {
// Define placeholders // Define placeholders
// _1 ... _15 from x // _1 ... _15 from x
C++14
template <
int N,
typename T
>
constexpr
decltype(auto)
arg(
T* t,
std::true_type)
{
return std::get<N-1>(*t);
}
C++14 C++11/14
template < template <
int N, int N,
typename T typename T
> >
constexpr constexpr
decltype(auto) auto
arg( arg(
T* t, T* t,
std::true_type) std::true_type)
-> decltype(
{ std::get<N-1>(*t))
return std::get<N-1>(*t); {
} return std::get<N-1>(*t);
}
Paxie Backporting to the Future Pacific++ 2018 53 / 87
Outline
Introduction
Motivation
Trompeloeil
Backporting Goals
Backporting to C++11
Library
Language
Issues
Summary
REQUIRE_CALL(...)
RETURN(...)
RETURN(...)
RETURN(...)
_V is for ’variadic’
_V is for ’variadic’
https://github.com/rollbear/trompeloeil
https://github.com/rollbear https://github.com/AndrewPaxie
https://playfulprogramming.blogspot.com https://blog.andrew.paxie.org
Catch,
Available: https://github.com/catchorg/catch2
Accessed: 13 October 2018
Google Mock
Available: https://github.com/google/googletest
Accessed: 10 October 2018
Turtle
Available: https://github.com/mat007/turtle
Accessed: 10 October 2018
HippoMocks
Available: http://hippomocks.com/Main_Page
Available: https://github.com/dascandy/hippomocks
Accessed: 10 October 2018
FakeIt
Available: https://github.com/eranpeer/FakeIt
Accessed: 10 October 2018
Mockator
Available: https://www.cevelop.com/
Accessed: 10 October 2018
Trompeloeil
Available: https://github.com/rollbear/trompeloeil
Accessed: 15 October 2018
Jonathan Wakely,
“Compile-time integer sequences,” N3658, 18 April 2013.
Available: http://wg21.link/n3658
Accessed: 22 September 2018
Stephan T. Lavavej,
“make unique (Revision 1),” N3656, 18 April 2013.
Available: http://wg21.link/n3656
Accessed: 22 September 2018
Jeffrey Yasskin,
“exchange() utility function, revision 3,” N3668, 19 April
2013.
Available: http://wg21.link/n3668
Accessed: 22 September 2018
Mike Spertus and Attila Pall,
“Making non-modifying sequence operations more robust:
Revision 2,” N3671, 19 April 2013.
Available: http://wg21.link/n3671
Accessed: 22 September 2018
Walter E. Brown,
“A Proposal to Tweak Certain C++ Contextual Conversions,
v3,” N3323, 8 December 2012.
Available: http://wg21.link/n3323
Accessed: 22 September 2018
Jason Merrill,
“Return type deduction for normal functions,” N3638, 17 April
2013.
Available: http://wg21.link/n3638
Accessed: 22 September 2018
GCC Bugzilla,
“Bug 61582 - C++11 regex memory corruption,” 23 June
2014.
Available:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61582
Accessed: 9 November 2017
GCC Bugzilla,
“Bug 61947 - [4.8/4.9 Regression] Ambiguous calls when
constructing std::tuple,” 29 July 2014.
Available:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61947
Accessed: 8 November 2017
Alan Talbot,
“Null forward iterators,” N3644, 18 April 2013.
Available: http://wg21.link/n3644
Accessed: 22 September 2018
Berman Dawes,
“Quoted Strings Library Proposal (Revision 2),” N3654, 19
April 2013.
Available: http://wg21.link/n3654
Accessed: 22 September 2018
Jonathan Wakely, Stephan T. Lavavej, and Joaquı́n Mª López
Muñoz,
“Adding heterogeneous comparison lookup to associative
containers (rev 4),” N3657, 19 March 2013.
Available: http://wg21.link/n3657
Accessed: 22 September 2018
Paxie Backporting to the Future Pacific++ 2018 80 / 87
References
Unused Features from C++14: Library (2)(b)
James Dennett,
“Binary Literals in the C++ Core Language,” N3472, 19
October 2012.
Available: http://wg21.link/n3472
Accessed: 22 September 2018
Gabriel Dos Reis,
“Variable Templates (Revision 1),” N3651, 19 April 2013.
Available: http://wg21.link/n3651
Accessed: 22 September 2018
Richard Smith,
“Relaxing constraints on constexpr functions, constexpr
member functions and implicit const,” N3652, 18 April 2013.
Available: http://wg21.link/n3652
Accessed: 22 September 2018
Gerard Meszaros,
“xUnit Test Patterns: Refactoring Test Code,”
Addison-Wesley, Upper Saddle River, NJ, 2007.
Scott Meyers,
“Effective Modern C++,” O’Reilly Media, Inc., Sebastopol,
CA, 2015.
Scott Meyers,
“Modification History and Errata List for ’Effective Modern
C++’,” last updated 18 May 2018.
Available: https:
//www.aristeia.com/BookErrata/emc++-errata.html
Accessed: 23 September 2018