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