hardly | b1e7e14 | 2014-08-06 00:43:51 +0300 | [diff] [blame^] | 1 | //#define DOCTEST_CONFIG_DISABLE
|
| 2 |
|
| 3 | #define DOCTEST_CONFIG_IMPLEMENT
|
| 4 | #include "doctest.h"
|
| 5 |
|
| 6 | #include <cstdio>
|
| 7 | #include <exception>
|
| 8 |
|
| 9 | #define DECOMPOSE(expr) (expression_decomposer() << expr)
|
| 10 |
|
| 11 | #define EXPECT(expr) \
|
| 12 | do { \
|
| 13 | if(result failed = DECOMPOSE(expr)) \
|
| 14 | printf("failed!\n"); \
|
| 15 | } while(false)
|
| 16 |
|
| 17 | struct result
|
| 18 | {
|
| 19 | const bool passed;
|
| 20 | const doctest::String decomposition;
|
| 21 |
|
| 22 | result(bool passed, const doctest::String& decomposition)
|
| 23 | : passed(passed), decomposition(decomposition) {}
|
| 24 | operator bool() { return !passed; }
|
| 25 | };
|
| 26 |
|
| 27 | //inline std::string to_string(std::string const & text) { return "\"" + text + "\""; }
|
| 28 | inline doctest::String to_string(const char * text) { return doctest::String("\"") + text + "\""; }
|
| 29 | //inline doctest::String to_string(char text) { return doctest::String("\'") + text + "\'"; }
|
| 30 |
|
| 31 | inline std::ostream & operator<<(std::ostream & os, approx const & appr)
|
| 32 | {
|
| 33 | return os << appr.magnitude();
|
| 34 | }
|
| 35 |
|
| 36 | template <typename T>
|
| 37 | std::string to_string(T const & value, int = 0 /* VC6 */)
|
| 38 | {
|
| 39 | std::ostringstream os; os << std::boolalpha << value; return os.str();
|
| 40 | }
|
| 41 |
|
| 42 | template<typename T1, typename T2>
|
| 43 | std::string to_string(std::pair<T1, T2> const & pair)
|
| 44 | {
|
| 45 | std::ostringstream oss;
|
| 46 | oss << "{ " << to_string(pair.first) << ", " << to_string(pair.second) << " }";
|
| 47 | return oss.str();
|
| 48 | }
|
| 49 |
|
| 50 | template <typename L, typename R>
|
| 51 | std::string to_string(L const & lhs, std::string op, R const & rhs)
|
| 52 | {
|
| 53 | std::ostringstream os; os << to_string(lhs) << " " << op << " " << to_string(rhs); return os.str();
|
| 54 | }
|
| 55 |
|
| 56 |
|
| 57 | template <typename L>
|
| 58 | struct expression_lhs
|
| 59 | {
|
| 60 | const L lhs;
|
| 61 |
|
| 62 | expression_lhs(L lhs)
|
| 63 | : lhs(lhs) {}
|
| 64 |
|
| 65 | operator result() { return result(!!lhs, to_string(lhs)); }
|
| 66 |
|
| 67 | // clang-format off
|
| 68 | template <typename R> result operator==(R const & rhs) { return result(lhs == rhs, to_string(lhs, "==", rhs)); }
|
| 69 | template <typename R> result operator!=(R const & rhs) { return result(lhs != rhs, to_string(lhs, "!=", rhs)); }
|
| 70 | template <typename R> result operator< (R const & rhs) { return result(lhs < rhs, to_string(lhs, "<", rhs)); }
|
| 71 | template <typename R> result operator<=(R const & rhs) { return result(lhs <= rhs, to_string(lhs, "<=", rhs)); }
|
| 72 | template <typename R> result operator> (R const & rhs) { return result(lhs > rhs, to_string(lhs, ">", rhs)); }
|
| 73 | template <typename R> result operator>=(R const & rhs) { return result(lhs >= rhs, to_string(lhs, ">=", rhs)); }
|
| 74 | // clang-format on
|
| 75 | };
|
| 76 |
|
| 77 | struct expression_decomposer
|
| 78 | {
|
| 79 | template <typename L>
|
| 80 | expression_lhs<L const&> operator<<(L const& operand) {
|
| 81 | return expression_lhs<L const &>(operand);
|
| 82 | }
|
| 83 | };
|
| 84 |
|
| 85 |
|
| 86 | testsuite(MAIN);
|
| 87 | test(zzz) {
|
| 88 | printf("main\n");
|
| 89 | subtest("") {
|
| 90 | printf("1\n");
|
| 91 | subtest("") { printf("1-1\n"); }
|
| 92 | subtest("") { printf("1-2\n"); }
|
| 93 | }
|
| 94 | subtest("") { printf("2\n"); }
|
| 95 | }
|
| 96 | testsuite_end;
|
| 97 |
|
| 98 | struct Empty
|
| 99 | {
|
| 100 | virtual ~Empty() {}
|
| 101 | };
|
| 102 |
|
| 103 | doctest_fixture(Empty, trololo) { printf("Help?\n"); }
|
| 104 |
|
| 105 | // test(thrower)
|
| 106 | //{
|
| 107 | // if(rand() > 4) {
|
| 108 | // throw std::exception();
|
| 109 | // } else {
|
| 110 | // cout << "trololo" << endl;
|
| 111 | // }
|
| 112 | //}
|
| 113 |
|
| 114 | static int testWrapper(void (*f)(void)) {
|
| 115 | try {
|
| 116 | f();
|
| 117 | } catch(std::exception& e) {
|
| 118 | printf("caught the bugger! %s\n", e.what());
|
| 119 | return 1;
|
| 120 | }
|
| 121 | return 0;
|
| 122 | }
|
| 123 |
|
| 124 | int main(int argc, char** argv) {
|
| 125 | // initialize
|
| 126 | doctest::Context context(argc, argv);
|
| 127 | context.setTestExecutionWrapper(testWrapper);
|
| 128 |
|
| 129 | // overrides
|
| 130 | context.setOption("dt-case-sensitive", true);
|
| 131 | context.addFilter("dt-name", "zzz");
|
| 132 |
|
| 133 | // run
|
| 134 | int res = context.runTests();
|
| 135 |
|
| 136 | #if defined(WITH_PAUSE)
|
| 137 | system("pause");
|
| 138 | #endif // _MSC_VER
|
| 139 |
|
| 140 | return res;
|
| 141 | }
|
| 142 |
|
| 143 | // test("") { printf("TEST %d\n", __LINE__); }
|
| 144 | // test("") { printf("TEST %d\n", __LINE__); }
|
| 145 | // test("") { printf("TEST %d\n", __LINE__); }
|
| 146 | // test("") { printf("TEST %d\n", __LINE__); }
|
| 147 | // test("") { printf("TEST %d\n", __LINE__); }
|
| 148 | // test("") { printf("TEST %d\n", __LINE__); }
|
| 149 | // test("") { printf("TEST %d\n", __LINE__); }
|
| 150 | // test("") { printf("TEST %d\n", __LINE__); }
|
| 151 | // test("") { printf("TEST %d\n", __LINE__); }
|
| 152 | // test("") { printf("TEST %d\n", __LINE__); }
|
| 153 | // test("") { printf("TEST %d\n", __LINE__); }
|