Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 1 | // Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 2 | // Distributed under MIT license, or public domain if desired and |
| 3 | // recognized in your jurisdiction. |
| 4 | // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE |
| 5 | |
| 6 | #ifndef JSONTEST_H_INCLUDED |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 7 | #define JSONTEST_H_INCLUDED |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 8 | |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 9 | #include <cstdio> |
| 10 | #include <deque> |
| 11 | #include <iomanip> |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 12 | #include <json/config.h> |
| 13 | #include <json/value.h> |
| 14 | #include <json/writer.h> |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 15 | #include <sstream> |
| 16 | #include <string> |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 17 | |
| 18 | // ////////////////////////////////////////////////////////////////// |
| 19 | // ////////////////////////////////////////////////////////////////// |
| 20 | // Mini Unit Testing framework |
| 21 | // ////////////////////////////////////////////////////////////////// |
| 22 | // ////////////////////////////////////////////////////////////////// |
| 23 | |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 24 | /** \brief Unit testing framework. |
| 25 | * \warning: all assertions are non-aborting, test case execution will continue |
| 26 | * even if an assertion namespace. |
| 27 | * This constraint is for portability: the framework needs to compile |
| 28 | * on Visual Studio 6 and must not require exception usage. |
| 29 | */ |
| 30 | namespace JsonTest { |
| 31 | |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 32 | class Failure { |
| 33 | public: |
| 34 | const char* file_; |
| 35 | unsigned int line_; |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 36 | Json::String expr_; |
| 37 | Json::String message_; |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 38 | unsigned int nestingLevel_; |
| 39 | }; |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 40 | |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 41 | /// Context used to create the assertion callstack on failure. |
| 42 | /// Must be a POD to allow inline initialisation without stepping |
| 43 | /// into the debugger. |
| 44 | struct PredicateContext { |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 45 | using Id = unsigned int; |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 46 | Id id_; |
| 47 | const char* file_; |
| 48 | unsigned int line_; |
| 49 | const char* expr_; |
| 50 | PredicateContext* next_; |
| 51 | /// Related Failure, set when the PredicateContext is converted |
| 52 | /// into a Failure. |
| 53 | Failure* failure_; |
| 54 | }; |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 55 | |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 56 | class TestResult { |
| 57 | public: |
| 58 | TestResult(); |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 59 | |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 60 | /// \internal Implementation detail for assertion macros |
| 61 | /// Not encapsulated to prevent step into when debugging failed assertions |
| 62 | /// Incremented by one on assertion predicate entry, decreased by one |
| 63 | /// by addPredicateContext(). |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 64 | PredicateContext::Id predicateId_{1}; |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 65 | |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 66 | /// \internal Implementation detail for predicate macros |
| 67 | PredicateContext* predicateStackTail_; |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 68 | |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 69 | void setTestName(const Json::String& name); |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 70 | |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 71 | /// Adds an assertion failure. |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 72 | TestResult& addFailure(const char* file, unsigned int line, |
| 73 | const char* expr = nullptr); |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 74 | |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 75 | /// Removes the last PredicateContext added to the predicate stack |
| 76 | /// chained list. |
| 77 | /// Next messages will be targed at the PredicateContext that was removed. |
| 78 | TestResult& popPredicateContext(); |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 79 | |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 80 | bool failed() const; |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 81 | |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 82 | void printFailure(bool printTestName) const; |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 83 | |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 84 | // Generic operator that will work with anything ostream can deal with. |
| 85 | template <typename T> TestResult& operator<<(const T& value) { |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 86 | Json::OStringStream oss; |
| 87 | oss << std::setprecision(16) << std::hexfloat << value; |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 88 | return addToLastFailure(oss.str()); |
| 89 | } |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 90 | |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 91 | // Specialized versions. |
| 92 | TestResult& operator<<(bool value); |
| 93 | // std:ostream does not support 64bits integers on all STL implementation |
| 94 | TestResult& operator<<(Json::Int64 value); |
| 95 | TestResult& operator<<(Json::UInt64 value); |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 96 | |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 97 | private: |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 98 | TestResult& addToLastFailure(const Json::String& message); |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 99 | /// Adds a failure or a predicate context |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 100 | void addFailureInfo(const char* file, unsigned int line, const char* expr, |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 101 | unsigned int nestingLevel); |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 102 | static Json::String indentText(const Json::String& text, |
| 103 | const Json::String& indent); |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 104 | |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 105 | using Failures = std::deque<Failure>; |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 106 | Failures failures_; |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 107 | Json::String name_; |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 108 | PredicateContext rootPredicateNode_; |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 109 | PredicateContext::Id lastUsedPredicateId_{0}; |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 110 | /// Failure which is the target of the messages added using operator << |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 111 | Failure* messageTarget_{nullptr}; |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 112 | }; |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 113 | |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 114 | class TestCase { |
| 115 | public: |
| 116 | TestCase(); |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 117 | |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 118 | virtual ~TestCase(); |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 119 | |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 120 | void run(TestResult& result); |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 121 | |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 122 | virtual const char* testName() const = 0; |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 123 | |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 124 | protected: |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 125 | TestResult* result_{nullptr}; |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 126 | |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 127 | private: |
| 128 | virtual void runTestCase() = 0; |
| 129 | }; |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 130 | |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 131 | /// Function pointer type for TestCase factory |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 132 | using TestCaseFactory = TestCase* (*)(); |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 133 | |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 134 | class Runner { |
| 135 | public: |
| 136 | Runner(); |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 137 | |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 138 | /// Adds a test to the suite |
| 139 | Runner& add(TestCaseFactory factory); |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 140 | |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 141 | /// Runs test as specified on the command-line |
| 142 | /// If no command-line arguments are provided, run all tests. |
| 143 | /// If --list-tests is provided, then print the list of all test cases |
| 144 | /// If --test <testname> is provided, then run test testname. |
| 145 | int runCommandLine(int argc, const char* argv[]) const; |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 146 | |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 147 | /// Runs all the test cases |
| 148 | bool runAllTest(bool printSummary) const; |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 149 | |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 150 | /// Returns the number of test case in the suite |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 151 | size_t testCount() const; |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 152 | |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 153 | /// Returns the name of the test case at the specified index |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 154 | Json::String testNameAt(size_t index) const; |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 155 | |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 156 | /// Runs the test case at the specified index using the specified TestResult |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 157 | void runTestAt(size_t index, TestResult& result) const; |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 158 | |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 159 | static void printUsage(const char* appName); |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 160 | |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 161 | private: // prevents copy construction and assignment |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 162 | Runner(const Runner& other) = delete; |
| 163 | Runner& operator=(const Runner& other) = delete; |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 164 | |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 165 | private: |
| 166 | void listTests() const; |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 167 | bool testIndex(const Json::String& testName, size_t& indexOut) const; |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 168 | static void preventDialogOnCrash(); |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 169 | |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 170 | private: |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 171 | using Factories = std::deque<TestCaseFactory>; |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 172 | Factories tests_; |
| 173 | }; |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 174 | |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 175 | template <typename T, typename U> |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 176 | TestResult& checkEqual(TestResult& result, T expected, U actual, |
| 177 | const char* file, unsigned int line, const char* expr) { |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 178 | if (static_cast<U>(expected) != actual) { |
| 179 | result.addFailure(file, line, expr); |
| 180 | result << "Expected: " << static_cast<U>(expected) << "\n"; |
| 181 | result << "Actual : " << actual; |
| 182 | } |
| 183 | return result; |
| 184 | } |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 185 | |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 186 | Json::String ToJsonString(const char* toConvert); |
| 187 | Json::String ToJsonString(Json::String in); |
| 188 | #if JSONCPP_USING_SECURE_MEMORY |
| 189 | Json::String ToJsonString(std::string in); |
| 190 | #endif |
| 191 | |
| 192 | TestResult& checkStringEqual(TestResult& result, const Json::String& expected, |
| 193 | const Json::String& actual, const char* file, |
| 194 | unsigned int line, const char* expr); |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 195 | |
| 196 | } // namespace JsonTest |
| 197 | |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 198 | /// \brief Asserts that the given expression is true. |
| 199 | /// JSONTEST_ASSERT( x == y ) << "x=" << x << ", y=" << y; |
| 200 | /// JSONTEST_ASSERT( x == y ); |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 201 | #define JSONTEST_ASSERT(expr) \ |
| 202 | if (expr) { \ |
| 203 | } else \ |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 204 | result_->addFailure(__FILE__, __LINE__, #expr) |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 205 | |
| 206 | /// \brief Asserts that the given predicate is true. |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 207 | /// The predicate may do other assertions and be a member function of the |
| 208 | /// fixture. |
| 209 | #define JSONTEST_ASSERT_PRED(expr) \ |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 210 | do { \ |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 211 | JsonTest::PredicateContext _minitest_Context = { \ |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 212 | result_->predicateId_, __FILE__, __LINE__, #expr, NULL, NULL}; \ |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 213 | result_->predicateStackTail_->next_ = &_minitest_Context; \ |
| 214 | result_->predicateId_ += 1; \ |
| 215 | result_->predicateStackTail_ = &_minitest_Context; \ |
| 216 | (expr); \ |
| 217 | result_->popPredicateContext(); \ |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 218 | } while (0) |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 219 | |
| 220 | /// \brief Asserts that two values are equals. |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 221 | #define JSONTEST_ASSERT_EQUAL(expected, actual) \ |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 222 | JsonTest::checkEqual(*result_, expected, actual, __FILE__, __LINE__, \ |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 223 | #expected " == " #actual) |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 224 | |
| 225 | /// \brief Asserts that two values are equals. |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 226 | #define JSONTEST_ASSERT_STRING_EQUAL(expected, actual) \ |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 227 | JsonTest::checkStringEqual(*result_, JsonTest::ToJsonString(expected), \ |
| 228 | JsonTest::ToJsonString(actual), __FILE__, \ |
| 229 | __LINE__, #expected " == " #actual) |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 230 | |
| 231 | /// \brief Asserts that a given expression throws an exception |
| 232 | #define JSONTEST_ASSERT_THROWS(expr) \ |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 233 | do { \ |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 234 | bool _threw = false; \ |
| 235 | try { \ |
| 236 | expr; \ |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 237 | } catch (...) { \ |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 238 | _threw = true; \ |
| 239 | } \ |
| 240 | if (!_threw) \ |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 241 | result_->addFailure(__FILE__, __LINE__, \ |
| 242 | "expected exception thrown: " #expr); \ |
| 243 | } while (0) |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 244 | |
| 245 | /// \brief Begin a fixture test case. |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 246 | #define JSONTEST_FIXTURE(FixtureType, name) \ |
| 247 | class Test##FixtureType##name : public FixtureType { \ |
| 248 | public: \ |
| 249 | static JsonTest::TestCase* factory() { \ |
| 250 | return new Test##FixtureType##name(); \ |
| 251 | } \ |
| 252 | \ |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 253 | public: /* overridden from TestCase */ \ |
| 254 | const char* testName() const override { return #FixtureType "/" #name; } \ |
| 255 | void runTestCase() override; \ |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 256 | }; \ |
| 257 | \ |
| 258 | void Test##FixtureType##name::runTestCase() |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 259 | |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 260 | #define JSONTEST_FIXTURE_FACTORY(FixtureType, name) \ |
| 261 | &Test##FixtureType##name::factory |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 262 | |
Derek Sollenberger | 2eb3b4d | 2016-01-11 14:41:40 -0500 | [diff] [blame] | 263 | #define JSONTEST_REGISTER_FIXTURE(runner, FixtureType, name) \ |
| 264 | (runner).add(JSONTEST_FIXTURE_FACTORY(FixtureType, name)) |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 265 | |
Haibo Huang | b0bee82 | 2021-02-24 15:40:15 -0800 | [diff] [blame] | 266 | /// \brief Begin a fixture test case. |
| 267 | #define JSONTEST_FIXTURE_V2(FixtureType, name, collections) \ |
| 268 | class Test##FixtureType##name : public FixtureType { \ |
| 269 | public: \ |
| 270 | static JsonTest::TestCase* factory() { \ |
| 271 | return new Test##FixtureType##name(); \ |
| 272 | } \ |
| 273 | static bool collect() { \ |
| 274 | (collections).push_back(JSONTEST_FIXTURE_FACTORY(FixtureType, name)); \ |
| 275 | return true; \ |
| 276 | } \ |
| 277 | \ |
| 278 | public: /* overridden from TestCase */ \ |
| 279 | const char* testName() const override { return #FixtureType "/" #name; } \ |
| 280 | void runTestCase() override; \ |
| 281 | }; \ |
| 282 | \ |
| 283 | static bool test##FixtureType##name##collect = \ |
| 284 | Test##FixtureType##name::collect(); \ |
| 285 | \ |
| 286 | void Test##FixtureType##name::runTestCase() |
| 287 | |
Leon Scroggins III | f59fb0e | 2014-05-28 15:19:42 -0400 | [diff] [blame] | 288 | #endif // ifndef JSONTEST_H_INCLUDED |