11f6b57a5SAndrew Lindesay /*
21f6b57a5SAndrew Lindesay * Copyright 2017, Andrew Lindesay <apl@lindesay.co.nz>
31f6b57a5SAndrew Lindesay * Distributed under the terms of the MIT License.
41f6b57a5SAndrew Lindesay */
51f6b57a5SAndrew Lindesay #include "JsonErrorHandlingTest.h"
61f6b57a5SAndrew Lindesay
71f6b57a5SAndrew Lindesay #include <AutoDeleter.h>
81f6b57a5SAndrew Lindesay
91f6b57a5SAndrew Lindesay #include <Json.h>
101f6b57a5SAndrew Lindesay #include <JsonEventListener.h>
111f6b57a5SAndrew Lindesay
121f6b57a5SAndrew Lindesay #include <cppunit/TestCaller.h>
131f6b57a5SAndrew Lindesay #include <cppunit/TestSuite.h>
141f6b57a5SAndrew Lindesay
151f6b57a5SAndrew Lindesay #include "JsonSamples.h"
161f6b57a5SAndrew Lindesay
171f6b57a5SAndrew Lindesay
181f6b57a5SAndrew Lindesay using namespace BPrivate;
191f6b57a5SAndrew Lindesay
201f6b57a5SAndrew Lindesay class ErrorCapturingListener : public BJsonEventListener {
211f6b57a5SAndrew Lindesay public:
221f6b57a5SAndrew Lindesay ErrorCapturingListener();
231f6b57a5SAndrew Lindesay virtual ~ErrorCapturingListener();
241f6b57a5SAndrew Lindesay
251f6b57a5SAndrew Lindesay bool Handle(const BJsonEvent& event);
261f6b57a5SAndrew Lindesay void HandleError(status_t status, int32 line,
271f6b57a5SAndrew Lindesay const char* message);
Complete()281f6b57a5SAndrew Lindesay void Complete() {};
291f6b57a5SAndrew Lindesay
301f6b57a5SAndrew Lindesay status_t ErrorStatus();
311f6b57a5SAndrew Lindesay int32 GetErrorLine();
321f6b57a5SAndrew Lindesay BString GetErrorMessage();
331f6b57a5SAndrew Lindesay bool HasEventsAfterError();
341f6b57a5SAndrew Lindesay json_event_type FirstEventTypeAfterError();
351f6b57a5SAndrew Lindesay private:
361f6b57a5SAndrew Lindesay status_t fErrorStatus;
371f6b57a5SAndrew Lindesay int32 fErrorLine;
381f6b57a5SAndrew Lindesay BString fErrorMessage;
391f6b57a5SAndrew Lindesay json_event_type fFirstEventTypeAfterError;
401f6b57a5SAndrew Lindesay int32 fEventCountAfterError;
411f6b57a5SAndrew Lindesay
421f6b57a5SAndrew Lindesay };
431f6b57a5SAndrew Lindesay
441f6b57a5SAndrew Lindesay
451f6b57a5SAndrew Lindesay /*! This DataIO concrete implementation is designed to open and then to fail
461f6b57a5SAndrew Lindesay in order to simulate what might happen if there were an IO problem when
471f6b57a5SAndrew Lindesay parsing some JSON.
481f6b57a5SAndrew Lindesay */
491f6b57a5SAndrew Lindesay
501f6b57a5SAndrew Lindesay class FailingDataIO : public BDataIO {
511f6b57a5SAndrew Lindesay public:
521f6b57a5SAndrew Lindesay FailingDataIO();
531f6b57a5SAndrew Lindesay virtual ~FailingDataIO();
541f6b57a5SAndrew Lindesay
551f6b57a5SAndrew Lindesay ssize_t Read(void* buffer, size_t size);
561f6b57a5SAndrew Lindesay ssize_t Write(const void* buffer, size_t size);
571f6b57a5SAndrew Lindesay
581f6b57a5SAndrew Lindesay status_t Flush();
591f6b57a5SAndrew Lindesay };
601f6b57a5SAndrew Lindesay
611f6b57a5SAndrew Lindesay
621f6b57a5SAndrew Lindesay // #pragma mark - FailingDataIO
631f6b57a5SAndrew Lindesay
641f6b57a5SAndrew Lindesay
FailingDataIO()651f6b57a5SAndrew Lindesay FailingDataIO::FailingDataIO()
661f6b57a5SAndrew Lindesay {
671f6b57a5SAndrew Lindesay }
681f6b57a5SAndrew Lindesay
691f6b57a5SAndrew Lindesay
~FailingDataIO()701f6b57a5SAndrew Lindesay FailingDataIO::~FailingDataIO()
711f6b57a5SAndrew Lindesay {
721f6b57a5SAndrew Lindesay }
731f6b57a5SAndrew Lindesay
741f6b57a5SAndrew Lindesay
751f6b57a5SAndrew Lindesay ssize_t
Read(void * buffer,size_t size)761f6b57a5SAndrew Lindesay FailingDataIO::Read(void* buffer, size_t size)
771f6b57a5SAndrew Lindesay {
781f6b57a5SAndrew Lindesay return B_IO_ERROR;
791f6b57a5SAndrew Lindesay }
801f6b57a5SAndrew Lindesay
811f6b57a5SAndrew Lindesay
821f6b57a5SAndrew Lindesay ssize_t
Write(const void * buffer,size_t size)831f6b57a5SAndrew Lindesay FailingDataIO::Write(const void* buffer, size_t size)
841f6b57a5SAndrew Lindesay {
851f6b57a5SAndrew Lindesay fprintf(stdout, "attempt to write");
861f6b57a5SAndrew Lindesay return B_IO_ERROR;
871f6b57a5SAndrew Lindesay }
881f6b57a5SAndrew Lindesay
891f6b57a5SAndrew Lindesay
901f6b57a5SAndrew Lindesay status_t
Flush()911f6b57a5SAndrew Lindesay FailingDataIO::Flush()
921f6b57a5SAndrew Lindesay {
931f6b57a5SAndrew Lindesay return B_IO_ERROR;
941f6b57a5SAndrew Lindesay }
951f6b57a5SAndrew Lindesay
961f6b57a5SAndrew Lindesay
971f6b57a5SAndrew Lindesay // #pragma mark - ErrorCapturingListener
981f6b57a5SAndrew Lindesay
991f6b57a5SAndrew Lindesay
ErrorCapturingListener()1001f6b57a5SAndrew Lindesay ErrorCapturingListener::ErrorCapturingListener()
1011f6b57a5SAndrew Lindesay {
1021f6b57a5SAndrew Lindesay fErrorStatus = B_OK;
1031f6b57a5SAndrew Lindesay fFirstEventTypeAfterError = B_JSON_NULL; // least likely
1041f6b57a5SAndrew Lindesay fEventCountAfterError = 0;
1051f6b57a5SAndrew Lindesay }
1061f6b57a5SAndrew Lindesay
1071f6b57a5SAndrew Lindesay
~ErrorCapturingListener()1081f6b57a5SAndrew Lindesay ErrorCapturingListener::~ErrorCapturingListener()
1091f6b57a5SAndrew Lindesay {
1101f6b57a5SAndrew Lindesay }
1111f6b57a5SAndrew Lindesay
1121f6b57a5SAndrew Lindesay
1131f6b57a5SAndrew Lindesay bool
Handle(const BJsonEvent & event)1141f6b57a5SAndrew Lindesay ErrorCapturingListener::Handle(const BJsonEvent& event)
1151f6b57a5SAndrew Lindesay {
1161f6b57a5SAndrew Lindesay if (fErrorStatus != B_OK) {
1171f6b57a5SAndrew Lindesay if (fEventCountAfterError == 0)
1181f6b57a5SAndrew Lindesay fFirstEventTypeAfterError = event.EventType();
1191f6b57a5SAndrew Lindesay
1201f6b57a5SAndrew Lindesay fEventCountAfterError++;
1211f6b57a5SAndrew Lindesay }
1221f6b57a5SAndrew Lindesay return true; // keep going.
1231f6b57a5SAndrew Lindesay }
1241f6b57a5SAndrew Lindesay
1251f6b57a5SAndrew Lindesay
1261f6b57a5SAndrew Lindesay void
HandleError(status_t status,int32 line,const char * message)1271f6b57a5SAndrew Lindesay ErrorCapturingListener::HandleError(status_t status, int32 line,
1281f6b57a5SAndrew Lindesay const char *message)
1291f6b57a5SAndrew Lindesay {
1301f6b57a5SAndrew Lindesay fErrorStatus = status;
1311f6b57a5SAndrew Lindesay fErrorLine = line;
1321f6b57a5SAndrew Lindesay
1331f6b57a5SAndrew Lindesay if (message != NULL)
1341f6b57a5SAndrew Lindesay fErrorMessage = BString(message);
1351f6b57a5SAndrew Lindesay else
1361f6b57a5SAndrew Lindesay fErrorMessage = BString();
1371f6b57a5SAndrew Lindesay }
1381f6b57a5SAndrew Lindesay
1391f6b57a5SAndrew Lindesay
1401f6b57a5SAndrew Lindesay status_t
ErrorStatus()1411f6b57a5SAndrew Lindesay ErrorCapturingListener::ErrorStatus()
1421f6b57a5SAndrew Lindesay {
1431f6b57a5SAndrew Lindesay return fErrorStatus;
1441f6b57a5SAndrew Lindesay }
1451f6b57a5SAndrew Lindesay
1461f6b57a5SAndrew Lindesay
1471f6b57a5SAndrew Lindesay int32
GetErrorLine()1481f6b57a5SAndrew Lindesay ErrorCapturingListener::GetErrorLine()
1491f6b57a5SAndrew Lindesay {
1501f6b57a5SAndrew Lindesay return fErrorLine;
1511f6b57a5SAndrew Lindesay }
1521f6b57a5SAndrew Lindesay
1531f6b57a5SAndrew Lindesay
1541f6b57a5SAndrew Lindesay BString
GetErrorMessage()1551f6b57a5SAndrew Lindesay ErrorCapturingListener::GetErrorMessage()
1561f6b57a5SAndrew Lindesay {
1571f6b57a5SAndrew Lindesay return fErrorMessage;
1581f6b57a5SAndrew Lindesay }
1591f6b57a5SAndrew Lindesay
1601f6b57a5SAndrew Lindesay
1611f6b57a5SAndrew Lindesay json_event_type
FirstEventTypeAfterError()1621f6b57a5SAndrew Lindesay ErrorCapturingListener::FirstEventTypeAfterError()
1631f6b57a5SAndrew Lindesay {
1641f6b57a5SAndrew Lindesay return fFirstEventTypeAfterError;
1651f6b57a5SAndrew Lindesay }
1661f6b57a5SAndrew Lindesay
1671f6b57a5SAndrew Lindesay
1681f6b57a5SAndrew Lindesay bool
HasEventsAfterError()1691f6b57a5SAndrew Lindesay ErrorCapturingListener::HasEventsAfterError()
1701f6b57a5SAndrew Lindesay {
1711f6b57a5SAndrew Lindesay return fEventCountAfterError > 0;
1721f6b57a5SAndrew Lindesay }
1731f6b57a5SAndrew Lindesay
1741f6b57a5SAndrew Lindesay
JsonErrorHandlingTest()1751f6b57a5SAndrew Lindesay JsonErrorHandlingTest::JsonErrorHandlingTest()
1761f6b57a5SAndrew Lindesay {
1771f6b57a5SAndrew Lindesay }
1781f6b57a5SAndrew Lindesay
1791f6b57a5SAndrew Lindesay
~JsonErrorHandlingTest()1801f6b57a5SAndrew Lindesay JsonErrorHandlingTest::~JsonErrorHandlingTest()
1811f6b57a5SAndrew Lindesay {
1821f6b57a5SAndrew Lindesay }
1831f6b57a5SAndrew Lindesay
1841f6b57a5SAndrew Lindesay
1851f6b57a5SAndrew Lindesay void
TestParseWithBadStringEscape(const char * input,int32 line,status_t expectedStatus,char expectedBadEscapeChar)1861f6b57a5SAndrew Lindesay JsonErrorHandlingTest::TestParseWithBadStringEscape(const char* input,
1871f6b57a5SAndrew Lindesay int32 line, status_t expectedStatus, char expectedBadEscapeChar)
1881f6b57a5SAndrew Lindesay {
1891f6b57a5SAndrew Lindesay BString expectedMessage;
1901f6b57a5SAndrew Lindesay expectedMessage.SetToFormat("unexpected escaped character [%c] "
1911f6b57a5SAndrew Lindesay "in string parsing", expectedBadEscapeChar);
1921f6b57a5SAndrew Lindesay
1931f6b57a5SAndrew Lindesay TestParseWithErrorMessage(input, line, expectedStatus,
1941f6b57a5SAndrew Lindesay expectedMessage.String());
1951f6b57a5SAndrew Lindesay }
1961f6b57a5SAndrew Lindesay
1971f6b57a5SAndrew Lindesay
1981f6b57a5SAndrew Lindesay void
TestParseWithUnterminatedElement(const char * input,int32 line,status_t expectedStatus)1991f6b57a5SAndrew Lindesay JsonErrorHandlingTest::TestParseWithUnterminatedElement(const char* input,
2001f6b57a5SAndrew Lindesay int32 line, status_t expectedStatus)
2011f6b57a5SAndrew Lindesay {
2021f6b57a5SAndrew Lindesay BString expectedMessage;
2031f6b57a5SAndrew Lindesay expectedMessage.SetToFormat("unterminated element");
2041f6b57a5SAndrew Lindesay
2051f6b57a5SAndrew Lindesay TestParseWithErrorMessage(input, line, expectedStatus,
2061f6b57a5SAndrew Lindesay expectedMessage.String());
2071f6b57a5SAndrew Lindesay }
2081f6b57a5SAndrew Lindesay
2091f6b57a5SAndrew Lindesay
2101f6b57a5SAndrew Lindesay void
TestParseWithUnexpectedCharacter(const char * input,int32 line,status_t expectedStatus,char expectedChar)2111f6b57a5SAndrew Lindesay JsonErrorHandlingTest::TestParseWithUnexpectedCharacter(const char* input,
2121f6b57a5SAndrew Lindesay int32 line, status_t expectedStatus, char expectedChar)
2131f6b57a5SAndrew Lindesay {
2141f6b57a5SAndrew Lindesay BString expectedMessage;
2151f6b57a5SAndrew Lindesay expectedMessage.SetToFormat("unexpected character [%" B_PRIu8
2161f6b57a5SAndrew Lindesay "] (%c) when parsing element", static_cast<uint8>(expectedChar),
2171f6b57a5SAndrew Lindesay expectedChar);
2181f6b57a5SAndrew Lindesay
2191f6b57a5SAndrew Lindesay TestParseWithErrorMessage(input, line, expectedStatus,
2201f6b57a5SAndrew Lindesay expectedMessage.String());
2211f6b57a5SAndrew Lindesay }
2221f6b57a5SAndrew Lindesay
2231f6b57a5SAndrew Lindesay
2241f6b57a5SAndrew Lindesay void
TestParseWithErrorMessage(const char * input,int32 line,status_t expectedStatus,const char * expectedMessage)2251f6b57a5SAndrew Lindesay JsonErrorHandlingTest::TestParseWithErrorMessage(const char* input, int32 line,
2261f6b57a5SAndrew Lindesay status_t expectedStatus, const char* expectedMessage)
2271f6b57a5SAndrew Lindesay {
2281f6b57a5SAndrew Lindesay fprintf(stderr, "in >%s<\n", input);
2291f6b57a5SAndrew Lindesay BDataIO *inputData = new BMemoryIO(input, strlen(input));
2301f6b57a5SAndrew Lindesay ObjectDeleter<BDataIO> inputDataDeleter(inputData);
2311f6b57a5SAndrew Lindesay TestParseWithErrorMessage(inputData, line, expectedStatus, expectedMessage);
2321f6b57a5SAndrew Lindesay }
2331f6b57a5SAndrew Lindesay
2341f6b57a5SAndrew Lindesay
2351f6b57a5SAndrew Lindesay void
TestParseWithErrorMessage(BDataIO * inputData,int32 line,status_t expectedStatus,const char * expectedMessage)2361f6b57a5SAndrew Lindesay JsonErrorHandlingTest::TestParseWithErrorMessage(BDataIO* inputData, int32 line,
2371f6b57a5SAndrew Lindesay status_t expectedStatus, const char* expectedMessage)
2381f6b57a5SAndrew Lindesay {
2391f6b57a5SAndrew Lindesay ErrorCapturingListener* listener = new ErrorCapturingListener();
2401f6b57a5SAndrew Lindesay ObjectDeleter<ErrorCapturingListener> listenerDeleter(listener);
2411f6b57a5SAndrew Lindesay
2421f6b57a5SAndrew Lindesay // ----------------------
2431f6b57a5SAndrew Lindesay BPrivate::BJson::Parse(inputData, listener);
2441f6b57a5SAndrew Lindesay // ----------------------
2451f6b57a5SAndrew Lindesay
2461f6b57a5SAndrew Lindesay fprintf(stderr, "expected error at line %" B_PRIi32 " - %s : %s\n",
2471f6b57a5SAndrew Lindesay line,
2481f6b57a5SAndrew Lindesay strerror(expectedStatus),
2491f6b57a5SAndrew Lindesay expectedMessage);
2501f6b57a5SAndrew Lindesay
2511f6b57a5SAndrew Lindesay fprintf(stderr, "actual error at line %" B_PRIi32 " - %s : %s\n",
2521f6b57a5SAndrew Lindesay listener->GetErrorLine(),
2531f6b57a5SAndrew Lindesay strerror(listener->ErrorStatus()),
2541f6b57a5SAndrew Lindesay listener->GetErrorMessage().String());
2551f6b57a5SAndrew Lindesay
2561f6b57a5SAndrew Lindesay if (listener->HasEventsAfterError()) {
2571f6b57a5SAndrew Lindesay fprintf(stderr, "first event after error [%d]\n",
2581f6b57a5SAndrew Lindesay listener->FirstEventTypeAfterError());
2591f6b57a5SAndrew Lindesay }
2601f6b57a5SAndrew Lindesay
2611f6b57a5SAndrew Lindesay CPPUNIT_ASSERT(!listener->HasEventsAfterError());
2621f6b57a5SAndrew Lindesay CPPUNIT_ASSERT_EQUAL(expectedStatus, listener->ErrorStatus());
2631f6b57a5SAndrew Lindesay CPPUNIT_ASSERT_EQUAL(line, listener->GetErrorLine());
2641f6b57a5SAndrew Lindesay CPPUNIT_ASSERT(0 == strcmp(expectedMessage,
2651f6b57a5SAndrew Lindesay listener->GetErrorMessage().String()));
2661f6b57a5SAndrew Lindesay }
2671f6b57a5SAndrew Lindesay
2681f6b57a5SAndrew Lindesay
2691f6b57a5SAndrew Lindesay void
TestCompletelyUnknown()2701f6b57a5SAndrew Lindesay JsonErrorHandlingTest::TestCompletelyUnknown()
2711f6b57a5SAndrew Lindesay {
2721f6b57a5SAndrew Lindesay TestParseWithUnexpectedCharacter(
2731f6b57a5SAndrew Lindesay JSON_SAMPLE_BROKEN_COMPLETELY_UNKNOWN, 1, B_BAD_DATA, 'z');
2741f6b57a5SAndrew Lindesay }
2751f6b57a5SAndrew Lindesay
2761f6b57a5SAndrew Lindesay
2771f6b57a5SAndrew Lindesay void
TestObjectWithPrematureSeparator()2781f6b57a5SAndrew Lindesay JsonErrorHandlingTest::TestObjectWithPrematureSeparator()
2791f6b57a5SAndrew Lindesay {
2801f6b57a5SAndrew Lindesay TestParseWithErrorMessage(JSON_SAMPLE_BROKEN_OBJECT_PREMATURE_SEPARATOR, 1,
2811f6b57a5SAndrew Lindesay B_BAD_DATA, "unexpected item separator when parsing start of object");
2821f6b57a5SAndrew Lindesay }
2831f6b57a5SAndrew Lindesay
2841f6b57a5SAndrew Lindesay
2851f6b57a5SAndrew Lindesay void
TestStringUnterminated()2861f6b57a5SAndrew Lindesay JsonErrorHandlingTest::TestStringUnterminated()
2871f6b57a5SAndrew Lindesay {
2881f6b57a5SAndrew Lindesay TestParseWithErrorMessage(JSON_SAMPLE_BROKEN_UNTERMINATED_STRING, 1,
2891f6b57a5SAndrew Lindesay B_BAD_DATA, "unexpected end of input");
2901f6b57a5SAndrew Lindesay }
2911f6b57a5SAndrew Lindesay
2921f6b57a5SAndrew Lindesay
2931f6b57a5SAndrew Lindesay void
TestBadStringEscape()2941f6b57a5SAndrew Lindesay JsonErrorHandlingTest::TestBadStringEscape()
2951f6b57a5SAndrew Lindesay {
2961f6b57a5SAndrew Lindesay TestParseWithBadStringEscape(
2971f6b57a5SAndrew Lindesay JSON_SAMPLE_BROKEN_BAD_STRING_ESCAPE, 1, B_BAD_DATA, 'v');
2981f6b57a5SAndrew Lindesay }
2991f6b57a5SAndrew Lindesay
3001f6b57a5SAndrew Lindesay
3011f6b57a5SAndrew Lindesay void
TestBadNumber()3021f6b57a5SAndrew Lindesay JsonErrorHandlingTest::TestBadNumber()
3031f6b57a5SAndrew Lindesay {
3041f6b57a5SAndrew Lindesay TestParseWithErrorMessage(JSON_SAMPLE_BROKEN_NUMBER, 1, B_BAD_DATA,
305*0c28e8e5SAndrew Lindesay "malformed number");
3061f6b57a5SAndrew Lindesay }
3071f6b57a5SAndrew Lindesay
3081f6b57a5SAndrew Lindesay
3091f6b57a5SAndrew Lindesay void
TestIOIssue()3101f6b57a5SAndrew Lindesay JsonErrorHandlingTest::TestIOIssue()
3111f6b57a5SAndrew Lindesay {
3121f6b57a5SAndrew Lindesay BDataIO *inputData = new FailingDataIO();
3131f6b57a5SAndrew Lindesay ObjectDeleter<BDataIO> inputDataDeleter(inputData);
3141f6b57a5SAndrew Lindesay TestParseWithErrorMessage(inputData, -1, B_IO_ERROR,
3151f6b57a5SAndrew Lindesay "io related read error");
3161f6b57a5SAndrew Lindesay }
3171f6b57a5SAndrew Lindesay
3181f6b57a5SAndrew Lindesay
3191f6b57a5SAndrew Lindesay /*static*/ void
AddTests(BTestSuite & parent)3201f6b57a5SAndrew Lindesay JsonErrorHandlingTest::AddTests(BTestSuite& parent)
3211f6b57a5SAndrew Lindesay {
3221f6b57a5SAndrew Lindesay CppUnit::TestSuite& suite = *new CppUnit::TestSuite(
3231f6b57a5SAndrew Lindesay "JsonErrorHandlingTest");
3241f6b57a5SAndrew Lindesay
3251f6b57a5SAndrew Lindesay suite.addTest(new CppUnit::TestCaller<JsonErrorHandlingTest>(
3261f6b57a5SAndrew Lindesay "JsonErrorHandlingTest::TestCompletelyUnknown",
3271f6b57a5SAndrew Lindesay &JsonErrorHandlingTest::TestCompletelyUnknown));
3281f6b57a5SAndrew Lindesay
3291f6b57a5SAndrew Lindesay suite.addTest(new CppUnit::TestCaller<JsonErrorHandlingTest>(
3301f6b57a5SAndrew Lindesay "JsonErrorHandlingTest::TestObjectWithPrematureSeparator",
3311f6b57a5SAndrew Lindesay &JsonErrorHandlingTest::TestObjectWithPrematureSeparator));
3321f6b57a5SAndrew Lindesay
3331f6b57a5SAndrew Lindesay suite.addTest(new CppUnit::TestCaller<JsonErrorHandlingTest>(
3341f6b57a5SAndrew Lindesay "JsonErrorHandlingTest::TestStringUnterminated",
3351f6b57a5SAndrew Lindesay &JsonErrorHandlingTest::TestStringUnterminated));
3361f6b57a5SAndrew Lindesay
3371f6b57a5SAndrew Lindesay suite.addTest(new CppUnit::TestCaller<JsonErrorHandlingTest>(
3381f6b57a5SAndrew Lindesay "JsonErrorHandlingTest::TestBadStringEscape",
3391f6b57a5SAndrew Lindesay &JsonErrorHandlingTest::TestBadStringEscape));
3401f6b57a5SAndrew Lindesay
3411f6b57a5SAndrew Lindesay suite.addTest(new CppUnit::TestCaller<JsonErrorHandlingTest>(
3421f6b57a5SAndrew Lindesay "JsonErrorHandlingTest::TestBadNumber",
3431f6b57a5SAndrew Lindesay &JsonErrorHandlingTest::TestBadNumber));
3441f6b57a5SAndrew Lindesay
3451f6b57a5SAndrew Lindesay suite.addTest(new CppUnit::TestCaller<JsonErrorHandlingTest>(
3461f6b57a5SAndrew Lindesay "JsonErrorHandlingTest::TestIOIssue",
3471f6b57a5SAndrew Lindesay &JsonErrorHandlingTest::TestIOIssue));
3481f6b57a5SAndrew Lindesay
3491f6b57a5SAndrew Lindesay parent.addTest("JsonErrorHandlingTest", &suite);
3501f6b57a5SAndrew Lindesay }