From 64bf89ebdd0584a6951b68d815a3bb5abd4cdc1d Mon Sep 17 00:00:00 2001 From: "Hoa V. DINH" Date: Tue, 25 Nov 2014 14:23:25 -0800 Subject: Implemented unit tests for C++ platforms --- unittest/unittest.cpp | 323 ++++++++++++++++++++++++++++++++++++++++++++++++++ unittest/unittest.mm | 1 + 2 files changed, 324 insertions(+) create mode 100644 unittest/unittest.cpp (limited to 'unittest') diff --git a/unittest/unittest.cpp b/unittest/unittest.cpp new file mode 100644 index 00000000..a96a82e2 --- /dev/null +++ b/unittest/unittest.cpp @@ -0,0 +1,323 @@ +#include +#include + +using namespace mailcore; + +static int global_failure = 0; +static int global_success = 0; + +static time_t referenceDate(void) +{ + struct tm aTm; + memset(&aTm, 0, sizeof(aTm)); + aTm.tm_sec = 0; + aTm.tm_min = 0; + aTm.tm_hour = 16; + aTm.tm_mday = 31; + aTm.tm_mon = 11; + aTm.tm_year = 2000 - 1900; + time_t date = mktime(&aTm); + return date; +} + +static void testMessageBuilder1(String * path) +{ + printf("testMessageBuilder1\n"); + MessageBuilder * builder = new MessageBuilder(); + builder->header()->setFrom(Address::addressWithRFC822String(MCSTR("Hoà "))); + builder->header()->setTo(Array::arrayWithObject(Address::addressWithRFC822String(MCSTR("Foo Bar ")))); + builder->header()->setSubject(MCSTR("testMessageBuilder1")); + builder->header()->setDate(referenceDate()); + builder->header()->setMessageID(MCSTR("MyMessageID123@mail.gmail.com")); + builder->setHTMLBody(MCSTR("This is a HTML content")); + Array * boundaries = Array::array(); + boundaries->addObject(MCSTR("1")); + boundaries->addObject(MCSTR("2")); + boundaries->addObject(MCSTR("3")); + boundaries->addObject(MCSTR("4")); + boundaries->addObject(MCSTR("5")); + builder->setBoundaries(boundaries); + String * outputPath = path->stringByAppendingPathComponent(MCSTR("output/builder1.eml")); + Data * expectedData = Data::dataWithContentsOfFile(outputPath); + if (!builder->data()->isEqual(expectedData)) { + printf("testMessageBuilder1 failed\n"); + fprintf(stderr, "current:\n%s\n", MCUTF8(builder->data()->stringWithCharset("utf-8"))); + fprintf(stderr, "expected:\n%s\n", MCUTF8(expectedData->stringWithCharset("utf-8"))); + global_failure ++; + return; + } + printf("testMessageBuilder1 ok\n"); + global_success ++; +} + +static void testMessageBuilder2(String * path) +{ + printf("testMessageBuilder2\n"); + MessageBuilder * builder = new MessageBuilder(); + builder->header()->setFrom(Address::addressWithRFC822String(MCSTR("Hoà "))); + Array * to = Array::array(); + to->addObject(Address::addressWithRFC822String(MCSTR("Foo Bar "))); + to->addObject(Address::addressWithRFC822String(MCSTR("Other Recipient "))); + builder->header()->setTo(to); + Array * cc = Array::array(); + cc->addObject(Address::addressWithRFC822String(MCSTR("Carbon Copy "))); + cc->addObject(Address::addressWithRFC822String(MCSTR("Other Recipient "))); + builder->header()->setCc(cc); + builder->header()->setSubject(MCSTR("testMessageBuilder2")); + builder->header()->setDate(referenceDate()); + builder->header()->setMessageID(MCSTR("MyMessageID123@mail.gmail.com")); + builder->setHTMLBody(MCSTR("This is a HTML content")); + String * attachmentPath = path->stringByAppendingPathComponent(MCSTR("input/photo.jpg")); + builder->addAttachment(Attachment::attachmentWithContentsOfFile(attachmentPath)); + attachmentPath = path->stringByAppendingPathComponent(MCSTR("input/photo2.jpg")); + builder->addAttachment(Attachment::attachmentWithContentsOfFile(attachmentPath)); + Array * boundaries = Array::array(); + boundaries->addObject(MCSTR("1")); + boundaries->addObject(MCSTR("2")); + boundaries->addObject(MCSTR("3")); + boundaries->addObject(MCSTR("4")); + boundaries->addObject(MCSTR("5")); + builder->setBoundaries(boundaries); + String * outputPath = path->stringByAppendingPathComponent(MCSTR("output/builder2.eml")); + Data * expectedData = Data::dataWithContentsOfFile(outputPath); + if (!builder->data()->isEqual(expectedData)) { + printf("testMessageBuilder2 failed\n"); + fprintf(stderr, "current:\n%s\n", MCUTF8(builder->data()->stringWithCharset("utf-8"))); + fprintf(stderr, "expected:\n%s\n", MCUTF8(expectedData->stringWithCharset("utf-8"))); + global_failure ++; + return; + } + printf("testMessageBuilder2 ok\n"); + global_success ++; +} + +static void testMessageBuilder3(String * path) +{ + printf("testMessageBuilder3\n"); + MessageBuilder * builder = new MessageBuilder(); + builder->header()->setFrom(Address::addressWithRFC822String(MCSTR("Hoà "))); + Array * to = Array::array(); + to->addObject(Address::addressWithRFC822String(MCSTR("Foo Bar "))); + to->addObject(Address::addressWithRFC822String(MCSTR("Other Recipient "))); + builder->header()->setTo(to); + Array * cc = Array::array(); + cc->addObject(Address::addressWithRFC822String(MCSTR("Carbon Copy "))); + cc->addObject(Address::addressWithRFC822String(MCSTR("Other Recipient "))); + builder->header()->setCc(cc); + builder->header()->setSubject(MCSTR("testMessageBuilder3")); + builder->header()->setDate(referenceDate()); + builder->header()->setMessageID(MCSTR("MyMessageID123@mail.gmail.com")); + builder->setHTMLBody(MCSTR("
This is a HTML content
")); + String * attachmentPath = path->stringByAppendingPathComponent(MCSTR("input/photo.jpg")); + builder->addAttachment(Attachment::attachmentWithContentsOfFile(attachmentPath)); + attachmentPath = path->stringByAppendingPathComponent(MCSTR("input/photo2.jpg")); + Attachment * attachment = Attachment::attachmentWithContentsOfFile(attachmentPath); + attachment->setContentID(MCSTR("123")); + builder->addRelatedAttachment(attachment); + Array * boundaries = Array::array(); + boundaries->addObject(MCSTR("1")); + boundaries->addObject(MCSTR("2")); + boundaries->addObject(MCSTR("3")); + boundaries->addObject(MCSTR("4")); + boundaries->addObject(MCSTR("5")); + builder->setBoundaries(boundaries); + String * outputPath = path->stringByAppendingPathComponent(MCSTR("output/builder3.eml")); + Data * expectedData = Data::dataWithContentsOfFile(outputPath); + if (!builder->data()->isEqual(expectedData)) { + printf("testMessageBuilder3 failed\n"); + fprintf(stderr, "current:\n%s\n", MCUTF8(builder->data()->stringWithCharset("utf-8"))); + fprintf(stderr, "expected:\n%s\n", MCUTF8(expectedData->stringWithCharset("utf-8"))); + global_failure ++; + return; + } + printf("testMessageBuilder3 ok\n"); + global_success ++; +} + +static Array * pathsInDirectory(String * directory) +{ + Array * result = Array::array(); + + DIR * dir = opendir(directory->fileSystemRepresentation()); + if (dir == NULL) { + return result; + } + + struct dirent * ent; + while ((ent = readdir(dir)) != NULL) { + if (ent->d_name[0] == '.') { + continue; + } + + String * subpath = directory->stringByAppendingPathComponent(String::stringWithFileSystemRepresentation(ent->d_name)); + if (ent->d_type == DT_DIR) { + result->addObjectsFromArray(pathsInDirectory(subpath)); + } + else { + result->addObject(subpath); + } + } + closedir(dir); + + return result; +} + +static void prepareHeaderForUnitTest(MessageHeader * header) +{ + time_t now = time(NULL); + if (fabs(now - header->date()) <= 2) { + // Date might be generated, set to known date. + header->setDate(referenceDate()); + } + if (fabs(header->receivedDate() - now) <= 2) { + // Date might be generated, set to known date. + header->setReceivedDate(referenceDate()); + } + if (header->isMessageIDAutoGenerated()) { + header->setMessageID(MCSTR("MyMessageID123@mail.gmail.com")); + } +} + +static void preparePartForUnitTest(AbstractPart * part) +{ + if (part->className()->isEqual(MCSTR("mailcore::Multipart"))) { + Multipart * multipart = (Multipart *) part; + for(unsigned int i = 0 ; i < multipart->parts()->count() ; i ++) { + preparePartForUnitTest((AbstractPart *) multipart->parts()->objectAtIndex(i)); + } + } + else if (part->className()->isEqual(MCSTR("mailcore::MessagePart"))) { + prepareHeaderForUnitTest(((MessagePart *) part)->header()); + preparePartForUnitTest(((MessagePart *) part)->mainPart()); + } +} + +static void testMessageParser(String * path) +{ + printf("testMessageParser\n"); + String * inputPath = path->stringByAppendingPathComponent(MCSTR("input")); + String * outputPath = path->stringByAppendingPathComponent(MCSTR("output")); + Array * list = pathsInDirectory(inputPath); + int failure = 0; + int success = 0; + mc_foreacharray(String, filename, list) { + MessageParser * parser = MessageParser::messageParserWithContentsOfFile(filename); + prepareHeaderForUnitTest(parser->header()); + preparePartForUnitTest(parser->mainPart()); + HashMap * result = parser->serializable(); + String * expectedPath = outputPath->stringByAppendingPathComponent(filename->substringFromIndex(inputPath->length())); + //fprintf(stderr, "expected: %s\n", MCUTF8(expectedPath)); + HashMap * expectedResult = (HashMap *) JSON::objectFromJSONData(Data::dataWithContentsOfFile(expectedPath)); + if (result->isEqual(expectedResult)) { + success ++; + } + else { + fprintf(stderr, "testMessageParser: failed for %s\n", MCUTF8(filename)); + fprintf(stderr, "expected: %s\n", MCUTF8(expectedResult)); + fprintf(stderr, "got: %s\n", MCUTF8(result)); + failure ++; + } + } + if (failure > 0) { + printf("testMessageParser ok: %i succeeded, %i failed\n", success, failure); + global_failure ++; + return; + } + printf("testMessageParser ok: %i succeeded\n", success); + global_success ++; +} + +static void testCharsetDetection(String * path) +{ + printf("testCharsetDetection\n"); + String * inputPath = path->stringByAppendingPathComponent(MCSTR("input")); + Array * list = pathsInDirectory(inputPath); + int failure = 0; + int success = 0; + mc_foreacharray(String, filename, list) { + Data * data = Data::dataWithContentsOfFile(filename); + String * charset = data->charsetWithFilteredHTML(false); + charset = charset->lowercaseString(); + if (!filename->lastPathComponent()->stringByDeletingPathExtension()->isEqual(charset)) { + failure ++; + fprintf(stderr, "testCharsetDetection: failed for %s\n", MCUTF8(filename)); + fprintf(stderr, "got: %s\n", MCUTF8(charset)); + } + else { + success ++; + } + } + if (failure > 0) { + printf("testCharsetDetection ok: %i succeeded, %i failed\n", success, failure); + global_failure ++; + return; + } + printf("testCharsetDetection ok: %i succeeded\n", success); + global_success ++; +} + +static void testSummary(String * path) +{ + printf("testSummary\n"); + String * inputPath = path->stringByAppendingPathComponent(MCSTR("input")); + String * outputPath = path->stringByAppendingPathComponent(MCSTR("output")); + Array * list = pathsInDirectory(inputPath); + int failure = 0; + int success = 0; + mc_foreacharray(String, filename, list) { + MessageParser * parser = MessageParser::messageParserWithContentsOfFile(filename); + prepareHeaderForUnitTest(parser->header()); + preparePartForUnitTest(parser->mainPart()); + String * str = parser->plainTextRendering(); + String * resultPath = outputPath->stringByAppendingPathComponent(filename->substringFromIndex(inputPath->length())); + resultPath = resultPath->stringByDeletingPathExtension()->stringByAppendingString(MCSTR(".txt")); + Data * resultData = Data::dataWithContentsOfFile(resultPath); + if (resultData == nil) { + fprintf(stderr, "test %s is a well-known failing test", MCUTF8(filename)); + continue; + } + + if (!resultData->stringWithCharset("utf-8")->isEqual(str)) { + failure ++; + fprintf(stderr, "testSummary: failed for %s\n", MCUTF8(filename)); + fprintf(stderr, "got: %s\n", MCUTF8(str)); + fprintf(stderr, "expected: %s\n", MCUTF8(resultData->stringWithCharset("utf-8"))); + } + else { + success ++; + } + } + if (failure > 0) { + printf("testSummary ok: %i succeeded, %i failed\n", success, failure); + global_failure ++; + return; + } + printf("testSummary ok: %i succeeded\n", success); + global_success ++; +} + +int main(int argc, char ** argv) +{ + if (argc < 2) { + fprintf(stderr, "syntax: unittestcpp [unittestdatadir]\n"); + exit(EXIT_FAILURE); + } + + AutoreleasePool * pool = new AutoreleasePool(); + + String * path = String::stringWithUTF8Characters(argv[1]); + printf("data path: %s\n", MCUTF8(path)); + + testMessageBuilder1(path->stringByAppendingPathComponent(MCSTR("builder"))); + testMessageBuilder2(path->stringByAppendingPathComponent(MCSTR("builder"))); + testMessageBuilder3(path->stringByAppendingPathComponent(MCSTR("builder"))); + testMessageParser(path->stringByAppendingPathComponent(MCSTR("parser"))); + testCharsetDetection(path->stringByAppendingPathComponent(MCSTR("charset-detection"))); + testSummary(path->stringByAppendingPathComponent(MCSTR("summary"))); + + printf("%i tests succeeded, %i tests failed\n", global_success, global_failure); + + pool->release(); + + exit(EXIT_SUCCESS); +} \ No newline at end of file diff --git a/unittest/unittest.mm b/unittest/unittest.mm index ed5f94d5..2563e9aa 100644 --- a/unittest/unittest.mm +++ b/unittest/unittest.mm @@ -225,6 +225,7 @@ NSData * data = [NSData dataWithContentsOfFile:path]; MCOMessageParser * parser = [MCOMessageParser messageParserWithData:data]; [[parser header] prepareForUnitTest]; + [[parser mainPart] prepareForUnitTest]; NSString * str = [parser plainTextRendering]; // NSString * outputPath = [@"/Users/hoa/mc2-results/summary" stringByAppendingPathComponent:name]; -- cgit v1.2.3