blob: 58691df131be0db2b9ed7e9de07f8fcff49327b7 [file] [log] [blame]
onqtam4a655632016-05-26 14:20:52 +03001#include "doctest.h"
2
onqtam7cc0e962017-04-17 23:30:36 +03003#include "header.h"
4
onqtam4a655632016-05-26 14:20:52 +03005#include <string>
6#include <vector>
7#include <list>
8
9#include <sstream>
10
11// the standard forbids writing in the std namespace but it works on all compilers
12namespace std
13{
14template <typename T>
15ostream& operator<<(ostream& stream, const vector<T>& in) {
16 stream << "[";
17 for(size_t i = 0; i < in.size(); ++i)
18 if(i < in.size() - 1)
19 stream << in[i] << ", ";
20 else
21 stream << in[i];
22 stream << "]";
23 return stream;
24}
25}
26
27// as an alternative you may write a specialization of doctest::StringMaker
28namespace doctest
29{
30template <typename T>
31struct StringMaker<std::list<T> >
32{
33 static String convert(const std::list<T>& in) {
34 std::ostringstream oss;
35
36 oss << "[";
37 for(typename std::list<T>::const_iterator it = in.begin(); it != in.end(); ++it)
38 oss << *it << ", ";
39 oss << "]";
40
41 return oss.str().c_str();
42 }
43};
44}
45
onqtam4a655632016-05-26 14:20:52 +030046template <typename T, typename K>
47struct MyType
48{
49 T one;
50 K two;
51};
52
53template <typename T>
54struct MyTypeInherited : MyType<T, float>
55{};
56
57template <typename T, typename K>
58bool operator==(const MyType<T, K>& lhs, const MyType<T, K>& rhs) {
59 return lhs.one == rhs.one && lhs.two == rhs.two;
60}
61
62template <typename T, typename K>
63std::ostream& operator<<(std::ostream& stream, const MyType<T, K>& in) {
64 stream << "[" << in.one << ", " << in.two << "]";
65 return stream;
66}
67
onqtam12d55982017-04-16 22:35:27 +030068namespace Bar
69{
onqtam4a655632016-05-26 14:20:52 +030070struct Foo
onqtam12d55982017-04-16 22:35:27 +030071{
72 friend bool operator==(const Foo&, const Foo&) { return false; }
73};
onqtam4a655632016-05-26 14:20:52 +030074
onqtamb18680d2016-11-15 14:08:56 +020075// as a third option you may provide an overload of toString()
onqtam7cc0e962017-04-17 23:30:36 +030076inline doctest::String toString(const Foo&) { return "Foo{}"; }
onqtamb18680d2016-11-15 14:08:56 +020077} // namespace Bar
onqtam4a655632016-05-26 14:20:52 +030078
onqtam05bcc372017-03-17 02:10:38 +020079// set an exception translator for MyTypeInherited<int>
80REGISTER_EXCEPTION_TRANSLATOR(MyTypeInherited<int>& ex) {
onqtam12d55982017-04-16 22:35:27 +030081 return doctest::String("MyTypeInherited<int>(") + doctest::toString(ex.one) + ", " +
82 doctest::toString(ex.two) + ")";
onqtam05bcc372017-03-17 02:10:38 +020083}
84
onqtam7cc0e962017-04-17 23:30:36 +030085TEST_CASE("all asserts should fail and show how the objects get stringified") {
onqtam4a655632016-05-26 14:20:52 +030086 MyTypeInherited<int> bla1;
87 bla1.one = 5;
88 bla1.two = 4.0f;
89 MyTypeInherited<int> bla2;
90 bla2.one = 5;
91 bla2.two = 6.0f;
92
onqtamb18680d2016-11-15 14:08:56 +020093 Bar::Foo f1;
94 Bar::Foo f2;
onqtam4a655632016-05-26 14:20:52 +030095 CHECK(f1 == f2);
96
97 // std::string already has an operator<< working with std::ostream
98 std::string dummy1 = "omg";
99 std::string dummy2 = "tralala";
100
101 CHECK(dummy1 == dummy2);
102
103 std::vector<int> vec1;
104 vec1.push_back(1);
105 vec1.push_back(2);
106 vec1.push_back(3);
107
108 std::vector<int> vec2;
109 vec2.push_back(1);
110 vec2.push_back(2);
111 vec2.push_back(4);
112
113 CHECK(vec1 == vec2);
114
115 std::list<int> lst_1;
116 lst_1.push_back(1);
117 lst_1.push_back(42);
118 lst_1.push_back(3);
119
120 std::list<int> lst_2;
121 lst_2.push_back(1);
122 lst_2.push_back(2);
123 lst_2.push_back(666);
124
125 CHECK(lst_1 == lst_2);
onqtam12d55982017-04-16 22:35:27 +0300126
onqtam05bcc372017-03-17 02:10:38 +0200127 // lets see if this exception gets translated
onqtam7cc0e962017-04-17 23:30:36 +0300128 throw_if(true, bla1);
onqtam05bcc372017-03-17 02:10:38 +0200129}
130
onqtam12d55982017-04-16 22:35:27 +0300131static doctest::String intTranslator(int ex) {
132 return doctest::String("int: ") + doctest::toString(ex);
133}
onqtam246e8172017-03-17 02:48:12 +0200134
onqtam05bcc372017-03-17 02:10:38 +0200135TEST_CASE("a test case that registers an exception translator for int and then throws one") {
136 // set an exception translator for int - note that this shouldn't be done in a test case but
onqtam7cc0e962017-04-17 23:30:36 +0300137 // in main() or somewhere before executing the tests - but here I'm just lazy...
onqtam246e8172017-03-17 02:48:12 +0200138 doctest::registerExceptionTranslator(intTranslator);
onqtam12d55982017-04-16 22:35:27 +0300139
onqtam7cc0e962017-04-17 23:30:36 +0300140 throw_if(true, 5);
onqtam4a655632016-05-26 14:20:52 +0300141}