]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Split test-mail binary to test-mail-* binaries.
authorTimo Sirainen <tss@iki.fi>
Tue, 26 May 2009 18:55:40 +0000 (14:55 -0400)
committerTimo Sirainen <tss@iki.fi>
Tue, 26 May 2009 18:55:40 +0000 (14:55 -0400)
--HG--
branch : HEAD

src/lib-mail/Makefile.am
src/lib-mail/test-istream-header-filter.c [new file with mode: 0644]
src/lib-mail/test-mail.c [deleted file]
src/lib-mail/test-message-address.c [new file with mode: 0644]
src/lib-mail/test-message-date.c [new file with mode: 0644]
src/lib-mail/test-message-parser.c [new file with mode: 0644]
src/lib-mail/test-rfc2231-parser.c [new file with mode: 0644]

index 81458b36d75b2e85cd574e60aafdf6b754e139e6..c1777ea70441bbf7266a134f7d2e24fb948c7bcf 100644 (file)
@@ -49,20 +49,38 @@ else
   noinst_HEADERS = $(headers)
 endif
 
-test_programs = test-mail
+test_programs = \
+       test-istream-header-filter \
+       test-message-address \
+       test-message-date \
+       test-message-parser \
+       test-rfc2231-parser
+
 noinst_PROGRAMS = $(test_programs)
 
 test_libs = \
-       libmail.la \
-       ../lib-charset/libcharset.la \
        ../lib-test/libtest.la \
        ../lib/liblib.la
 
-test_mail_SOURCES = \
-       test-mail.c
+test_istream_header_filter_SOURCES = test-istream-header-filter.c
+test_istream_header_filter_LDADD = istream-header-filter.lo message-header-parser.lo $(test_libs)
+test_istream_header_filter_DEPENDENCIES = istream-header-filter.lo message-header-parser.lo $(test_libs)
+
+test_message_address_SOURCES = test-message-address.c
+test_message_address_LDADD = message-address.lo rfc822-parser.lo $(test_libs)
+test_message_address_DEPENDENCIES = message-address.lo rfc822-parser.lo $(test_libs)
+
+test_message_date_SOURCES = test-message-date.c
+test_message_date_LDADD = message-date.lo rfc822-parser.lo $(test_libs)
+test_message_date_DEPENDENCIES = message-date.lo rfc822-parser.lo $(test_libs)
+
+test_message_parser_SOURCES = test-message-parser.c
+test_message_parser_LDADD = message-parser.lo message-header-parser.lo message-size.lo rfc822-parser.lo rfc2231-parser.lo $(test_libs)
+test_message_parser_DEPENDENCIES = message-parser.lo message-header-parser.lo message-size.lo rfc822-parser.lo rfc2231-parser.lo $(test_libs)
 
-test_mail_LDADD = $(test_libs) $(LIBICONV)
-test_mail_DEPENDENCIES = $(test_libs)
+test_rfc2231_parser_SOURCES = test-rfc2231-parser.c
+test_rfc2231_parser_LDADD = rfc2231-parser.lo rfc822-parser.lo $(test_libs)
+test_rfc2231_parser_DEPENDENCIES = rfc2231-parser.lo rfc822-parser.lo $(test_libs)
 
 check: check-am check-test
 check-test: $(test_programs)
diff --git a/src/lib-mail/test-istream-header-filter.c b/src/lib-mail/test-istream-header-filter.c
new file mode 100644 (file)
index 0000000..f909b6c
--- /dev/null
@@ -0,0 +1,69 @@
+/* Copyright (c) 2007-2009 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "istream.h"
+#include "message-header-parser.h"
+#include "istream-header-filter.h"
+#include "test-common.h"
+
+static void filter_callback(struct message_header_line *hdr,
+                           bool *matched, void *context ATTR_UNUSED)
+{
+       if (hdr != NULL && hdr->name_offset == 0) {
+               /* drop first header */
+               *matched = TRUE;
+       }
+}
+
+static void test_istream_filter(void)
+{
+       static const char *exclude_headers[] = { "To", NULL };
+       const char *input = "From: foo\nFrom: abc\nTo: bar\n\nhello world\n";
+       const char *output = "From: abc\n\nhello world\n";
+       struct istream *istream, *filter;
+       unsigned int i, input_len = strlen(input);
+       unsigned int output_len = strlen(output);
+       const unsigned char *data;
+       size_t size;
+       ssize_t ret;
+       bool success = TRUE;
+
+       istream = test_istream_create(input);
+       filter = i_stream_create_header_filter(istream,
+                                              HEADER_FILTER_EXCLUDE |
+                                              HEADER_FILTER_NO_CR,
+                                              exclude_headers, 1,
+                                              filter_callback, NULL);
+       for (i = 1; i <= input_len; i++) {
+               test_istream_set_size(istream, i);
+               ret = i_stream_read(filter);
+               if (ret < 0) {
+                       success = FALSE;
+                       break;
+               }
+       }
+       data = i_stream_get_data(filter, &size);
+       if (size != output_len || memcmp(data, output, size) != 0)
+               success = FALSE;
+
+       i_stream_skip(filter, size);
+       i_stream_seek(filter, 0);
+       while ((ret = i_stream_read(filter)) > 0) ;
+       data = i_stream_get_data(filter, &size);
+       if (size != output_len || memcmp(data, output, size) != 0)
+               success = FALSE;
+
+       i_stream_unref(&filter);
+       i_stream_unref(&istream);
+
+       test_out("i_stream_create_header_filter()", success);
+}
+
+int main(void)
+{
+       static void (*test_functions[])(void) = {
+               test_istream_filter,
+               NULL
+       };
+       return test_run(test_functions);
+}
diff --git a/src/lib-mail/test-mail.c b/src/lib-mail/test-mail.c
deleted file mode 100644 (file)
index 339052a..0000000
+++ /dev/null
@@ -1,369 +0,0 @@
-/* Copyright (c) 2007-2009 Dovecot authors, see the included COPYING file */
-
-#include "lib.h"
-#include "str.h"
-#include "istream.h"
-#include "rfc822-parser.h"
-#include "rfc2231-parser.h"
-#include "message-address.h"
-#include "message-date.h"
-#include "message-parser.h"
-#include "istream-header-filter.h"
-#include "test-common.h"
-
-static const char test_msg[] =
-"Return-Path: <test@example.org>\n"
-"Subject: Hello world\n"
-"From: Test User <test@example.org>\n"
-"To: Another User <test2@example.org>\n"
-"Message-Id: <1.2.3.4@example>\n"
-"Mime-Version: 1.0\n"
-"Date: Sun, 23 May 2007 04:58:08 +0300\n"
-"Content-Type: multipart/signed; micalg=pgp-sha1;\n"
-"      protocol=\"application/pgp-signature\";\n"
-"      boundary=\"=-GNQXLhuj24Pl1aCkk4/d\"\n"
-"\n"
-"--=-GNQXLhuj24Pl1aCkk4/d\n"
-"Content-Type: text/plain\n"
-"Content-Transfer-Encoding: quoted-printable\n"
-"\n"
-"There was a day=20\n"
-"a happy=20day\n"
-"\n"
-"--=-GNQXLhuj24Pl1aCkk4/d\n"
-"Content-Type: application/pgp-signature; name=signature.asc\n"
-"\n"
-"-----BEGIN PGP SIGNATURE-----\n"
-"Version: GnuPG v1.2.4 (GNU/Linux)\n"
-"\n"
-"invalid\n"
-"-----END PGP SIGNATURE-----\n"
-"\n"
-"--=-GNQXLhuj24Pl1aCkk4/d--\n"
-"\n"
-"\n";
-#define TEST_MSG_LEN (sizeof(test_msg)-1)
-
-static bool cmp_addr(const struct message_address *a1,
-                    const struct message_address *a2)
-{
-       return null_strcmp(a1->name, a2->name) == 0 &&
-               null_strcmp(a1->route, a2->route) == 0 &&
-               null_strcmp(a1->mailbox, a2->mailbox) == 0 &&
-               null_strcmp(a1->domain, a2->domain) == 0 &&
-               a1->invalid_syntax == a2->invalid_syntax;
-}
-
-static void test_message_address(void)
-{
-       static const char *input[] = {
-               "user@domain",
-               "<user@domain>",
-               "foo bar <user@domain>",
-               "\"foo bar\" <user@domain>",
-               "<@route:user@domain>",
-               "<@route@route2:user@domain>",
-               "hello <@route ,@route2:user@domain>",
-               "user (hello)",
-               "hello <user>",
-               "@domain"
-       };
-       static struct message_address group_prefix = {
-               NULL, NULL, NULL, "group", NULL, FALSE
-       };
-       static struct message_address group_suffix = {
-               NULL, NULL, NULL, NULL, NULL, FALSE
-       };
-       static struct message_address output[] = {
-               { NULL, NULL, NULL, "user", "domain", FALSE },
-               { NULL, NULL, NULL, "user", "domain", FALSE },
-               { NULL, "foo bar", NULL, "user", "domain", FALSE },
-               { NULL, "foo bar", NULL, "user", "domain", FALSE },
-               { NULL, NULL, "@route", "user", "domain", FALSE },
-               { NULL, NULL, "@route,@route2", "user", "domain", FALSE },
-               { NULL, "hello", "@route,@route2", "user", "domain", FALSE },
-               { NULL, "hello", NULL, "user", "", TRUE },
-               { NULL, "hello", NULL, "user", "", TRUE },
-               { NULL, NULL, NULL, "", "domain", TRUE }
-       };
-       struct message_address *addr;
-       string_t *group;
-       unsigned int i;
-       bool success;
-
-       group = t_str_new(256);
-       str_append(group, "group: ");
-
-       for (i = 0; i < N_ELEMENTS(input); i++) {
-               addr = message_address_parse(pool_datastack_create(),
-                                            (const unsigned char *)input[i],
-                                            strlen(input[i]), -1U, FALSE);
-               success = addr != NULL && addr->next == NULL &&
-                       cmp_addr(addr, &output[i]);
-               test_out(t_strdup_printf("message_address_parse(%d)", i),
-                        success);
-
-               if (!output[i].invalid_syntax) {
-                       if (i != 0) {
-                               if ((i % 2) == 0)
-                                       str_append(group, ",");
-                               else
-                                       str_append(group, " , \n ");
-                       }
-                       str_append(group, input[i]);
-               }
-       }
-       str_append_c(group, ';');
-
-       addr = message_address_parse(pool_datastack_create(), str_data(group),
-                                    str_len(group), -1U, FALSE);
-       success = addr != NULL && cmp_addr(addr, &group_prefix);
-       addr = addr->next;
-       for (i = 0; i < N_ELEMENTS(input) && addr != NULL; i++) {
-               if (output[i].invalid_syntax)
-                       continue;
-               if (!cmp_addr(addr, &output[i])) {
-                       success = FALSE;
-                       break;
-               }
-               addr = addr->next;
-       }
-       if (addr == NULL || addr->next != NULL ||
-           !cmp_addr(addr, &group_suffix))
-               success = FALSE;
-       test_out("message_address_parse(group)", success);
-}
-
-struct test_message_date_output {
-       time_t time;
-       int tz_offset;
-       bool ret;
-};
-
-static void test_message_date_parse(void)
-{
-       static const char *input[] = {
-#ifdef TIME_T_SIGNED
-               "Thu, 01 Jan 1970 01:59:59 +0200",
-               "Fri, 13 Dec 1901 20:45:53 +0000",
-#endif
-#if (TIME_T_MAX_BITS > 32 || !defined(TIME_T_SIGNED))
-               "Sun, 07 Feb 2106 06:28:15 +0000",
-#endif
-               "Wed, 07 Nov 2007 01:07:20 +0200",
-               "Wed, 07 Nov 2007 01:07:20",
-               "Thu, 01 Jan 1970 02:00:00 +0200",
-               "Tue, 19 Jan 2038 03:14:07 +0000",
-               "Tue, 19 Jan 2038"
-       };
-       static struct test_message_date_output output[] = {
-#ifdef TIME_T_SIGNED
-               { -1, 2*60, TRUE },
-               { -2147483647, 0, TRUE },
-#endif
-#if (TIME_T_MAX_BITS > 32 || !defined(TIME_T_SIGNED))
-               { 4294967295, 0, TRUE },
-#endif
-               { 1194390440, 2*60, TRUE },
-               { 1194397640, 0, TRUE },
-               { 0, 2*60, TRUE },
-               { 2147483647, 0, TRUE },
-               { 0, 0, FALSE }
-       };
-       unsigned int i;
-       bool success;
-       time_t t;
-       int tz;
-       bool ret;
-
-       for (i = 0; i < N_ELEMENTS(input); i++) {
-               ret = message_date_parse((const unsigned char *)input[i],
-                                        strlen(input[i]), &t, &tz);
-               success = (!ret && !output[i].ret) ||
-                       (ret == output[i].ret && t == output[i].time &&
-                        tz == output[i].tz_offset);
-               test_out(t_strdup_printf("message_date_parse(%d)", i), success);
-       }
-}
-
-static bool msg_parts_cmp(struct message_part *p1, struct message_part *p2)
-{
-       while (p1 != NULL || p2 != NULL) {
-               if ((p1 != NULL) != (p2 != NULL))
-                       return FALSE;
-               if ((p1->children != NULL) != (p2->children != NULL))
-                       return FALSE;
-
-               if (p1->children) {
-                       if (!msg_parts_cmp(p1->children, p2->children))
-                               return FALSE;
-               }
-
-               if (p1->physical_pos != p2->physical_pos ||
-                   p1->header_size.physical_size != p2->header_size.physical_size ||
-                   p1->header_size.virtual_size != p2->header_size.virtual_size ||
-                   p1->header_size.lines != p2->header_size.lines ||
-                   p1->body_size.physical_size != p2->body_size.physical_size ||
-                   p1->body_size.virtual_size != p2->body_size.virtual_size ||
-                   p1->body_size.lines != p2->body_size.lines ||
-                   p1->flags != p2->flags)
-                       return FALSE;
-
-               p1 = p1->next;
-               p2 = p2->next;
-       }
-       return TRUE;
-}
-
-static void test_message_parser(void)
-{
-       struct message_parser_ctx *parser;
-       struct istream *input;
-       struct message_part *parts, *parts2;
-       struct message_block block;
-       unsigned int i;
-       bool success = TRUE;
-       pool_t pool;
-       int ret;
-
-       pool = pool_alloconly_create("message parser", 10240);
-       input = i_stream_create_from_data(test_msg, TEST_MSG_LEN);
-
-       parser = message_parser_init(pool, input, 0, 0);
-       while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ;
-       i_assert(ret < 0);
-       ret = message_parser_deinit(&parser, &parts);
-       i_assert(ret == 0);
-       i_stream_unref(&input);
-
-       input = test_istream_create(test_msg);
-       test_istream_set_allow_eof(input, FALSE);
-
-       parser = message_parser_init(pool, input, 0, 0);
-       for (i = 1; i <= TEST_MSG_LEN*2+1; i++) {
-               test_istream_set_size(input, i/2);
-               if (i > TEST_MSG_LEN*2)
-                       test_istream_set_allow_eof(input, TRUE);
-               while ((ret = message_parser_parse_next_block(parser,
-                                                             &block)) > 0) ;
-               if (ret < 0 && i < TEST_MSG_LEN*2) {
-                       success = FALSE;
-                       break;
-               }
-       }
-       ret = message_parser_deinit(&parser, &parts2);
-       i_assert(ret == 0);
-       i_stream_unref(&input);
-
-       if (!msg_parts_cmp(parts, parts2))
-               success = FALSE;
-
-       pool_unref(&pool);
-       test_out("message_parser()", success);
-}
-
-static void test_rfc2231_parser(void)
-{
-       const char *input =
-               "; key*2=ba%"
-               "; key2*0=a"
-               "; key3*0*=us-ascii'en'xyz"
-               "; key*0=\"foo\""
-               "; key2*1*=b%25"
-               "; key3*1=plop%"
-               "; key*1=baz";
-       const char *output[] = {
-               "key",
-               "foobazba%",
-               "key2*",
-               "''ab%25",
-               "key3*",
-               "us-ascii'en'xyzplop%25",
-               NULL
-       };
-       struct rfc822_parser_context parser;
-       const char *const *result;
-       unsigned int i;
-       bool success;
-
-       rfc822_parser_init(&parser, (const void *)input, strlen(input), NULL);
-       if (rfc2231_parse(&parser, &result) < 0)
-               success = FALSE;
-       else {
-               success = TRUE;
-               for (i = 0; output[i] != NULL && result[i] != NULL; i++) {
-                       if (strcmp(output[i], result[i]) != 0)
-                               break;
-               }
-               if (output[i] != NULL || result[i] != NULL)
-                       success = FALSE;
-       }
-       test_out("rfc2231_parse()", success);
-}
-
-static void filter_callback(struct message_header_line *hdr,
-                           bool *matched, void *context ATTR_UNUSED)
-{
-       if (hdr != NULL && hdr->name_offset == 0) {
-               /* drop first header */
-               *matched = TRUE;
-       }
-}
-
-static void test_istream_filter(void)
-{
-       static const char *exclude_headers[] = { "To", NULL };
-       const char *input = "From: foo\nFrom: abc\nTo: bar\n\nhello world\n";
-       const char *output = "From: abc\n\nhello world\n";
-       struct istream *istream, *filter;
-       unsigned int i, input_len = strlen(input);
-       unsigned int output_len = strlen(output);
-       const unsigned char *data;
-       size_t size;
-       ssize_t ret;
-       bool success = TRUE;
-
-       istream = test_istream_create(input);
-       filter = i_stream_create_header_filter(istream,
-                                              HEADER_FILTER_EXCLUDE |
-                                              HEADER_FILTER_NO_CR,
-                                              exclude_headers, 1,
-                                              filter_callback, NULL);
-       for (i = 1; i <= input_len; i++) {
-               test_istream_set_size(istream, i);
-               ret = i_stream_read(filter);
-               if (ret < 0) {
-                       success = FALSE;
-                       break;
-               }
-       }
-       data = i_stream_get_data(filter, &size);
-       if (size != output_len || memcmp(data, output, size) != 0)
-               success = FALSE;
-
-       i_stream_skip(filter, size);
-       i_stream_seek(filter, 0);
-       while ((ret = i_stream_read(filter)) > 0) ;
-       data = i_stream_get_data(filter, &size);
-       if (size != output_len || memcmp(data, output, size) != 0)
-               success = FALSE;
-
-       i_stream_unref(&filter);
-       i_stream_unref(&istream);
-
-       test_out("i_stream_create_header_filter()", success);
-}
-
-int main(void)
-{
-       static void (*test_functions[])(void) = {
-               test_message_address,
-               test_message_date_parse,
-               test_message_parser,
-               test_rfc2231_parser,
-               test_istream_filter,
-
-               NULL
-       };
-       return test_run(test_functions);
-}
diff --git a/src/lib-mail/test-message-address.c b/src/lib-mail/test-message-address.c
new file mode 100644 (file)
index 0000000..cd7b0a2
--- /dev/null
@@ -0,0 +1,105 @@
+/* Copyright (c) 2007-2009 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "str.h"
+#include "message-address.h"
+#include "test-common.h"
+
+static bool cmp_addr(const struct message_address *a1,
+                    const struct message_address *a2)
+{
+       return null_strcmp(a1->name, a2->name) == 0 &&
+               null_strcmp(a1->route, a2->route) == 0 &&
+               null_strcmp(a1->mailbox, a2->mailbox) == 0 &&
+               null_strcmp(a1->domain, a2->domain) == 0 &&
+               a1->invalid_syntax == a2->invalid_syntax;
+}
+
+static void test_message_address(void)
+{
+       static const char *input[] = {
+               "user@domain",
+               "<user@domain>",
+               "foo bar <user@domain>",
+               "\"foo bar\" <user@domain>",
+               "<@route:user@domain>",
+               "<@route@route2:user@domain>",
+               "hello <@route ,@route2:user@domain>",
+               "user (hello)",
+               "hello <user>",
+               "@domain"
+       };
+       static struct message_address group_prefix = {
+               NULL, NULL, NULL, "group", NULL, FALSE
+       };
+       static struct message_address group_suffix = {
+               NULL, NULL, NULL, NULL, NULL, FALSE
+       };
+       static struct message_address output[] = {
+               { NULL, NULL, NULL, "user", "domain", FALSE },
+               { NULL, NULL, NULL, "user", "domain", FALSE },
+               { NULL, "foo bar", NULL, "user", "domain", FALSE },
+               { NULL, "foo bar", NULL, "user", "domain", FALSE },
+               { NULL, NULL, "@route", "user", "domain", FALSE },
+               { NULL, NULL, "@route,@route2", "user", "domain", FALSE },
+               { NULL, "hello", "@route,@route2", "user", "domain", FALSE },
+               { NULL, "hello", NULL, "user", "", TRUE },
+               { NULL, "hello", NULL, "user", "", TRUE },
+               { NULL, NULL, NULL, "", "domain", TRUE }
+       };
+       struct message_address *addr;
+       string_t *group;
+       unsigned int i;
+       bool success;
+
+       group = t_str_new(256);
+       str_append(group, "group: ");
+
+       for (i = 0; i < N_ELEMENTS(input); i++) {
+               addr = message_address_parse(pool_datastack_create(),
+                                            (const unsigned char *)input[i],
+                                            strlen(input[i]), -1U, FALSE);
+               success = addr != NULL && addr->next == NULL &&
+                       cmp_addr(addr, &output[i]);
+               test_out(t_strdup_printf("message_address_parse(%d)", i),
+                        success);
+
+               if (!output[i].invalid_syntax) {
+                       if (i != 0) {
+                               if ((i % 2) == 0)
+                                       str_append(group, ",");
+                               else
+                                       str_append(group, " , \n ");
+                       }
+                       str_append(group, input[i]);
+               }
+       }
+       str_append_c(group, ';');
+
+       addr = message_address_parse(pool_datastack_create(), str_data(group),
+                                    str_len(group), -1U, FALSE);
+       success = addr != NULL && cmp_addr(addr, &group_prefix);
+       addr = addr->next;
+       for (i = 0; i < N_ELEMENTS(input) && addr != NULL; i++) {
+               if (output[i].invalid_syntax)
+                       continue;
+               if (!cmp_addr(addr, &output[i])) {
+                       success = FALSE;
+                       break;
+               }
+               addr = addr->next;
+       }
+       if (addr == NULL || addr->next != NULL ||
+           !cmp_addr(addr, &group_suffix))
+               success = FALSE;
+       test_out("message_address_parse(group)", success);
+}
+
+int main(void)
+{
+       static void (*test_functions[])(void) = {
+               test_message_address,
+               NULL
+       };
+       return test_run(test_functions);
+}
diff --git a/src/lib-mail/test-message-date.c b/src/lib-mail/test-message-date.c
new file mode 100644 (file)
index 0000000..169d5c5
--- /dev/null
@@ -0,0 +1,66 @@
+/* Copyright (c) 2007-2009 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "message-date.h"
+#include "test-common.h"
+
+struct test_message_date_output {
+       time_t time;
+       int tz_offset;
+       bool ret;
+};
+
+static void test_message_date_parse(void)
+{
+       static const char *input[] = {
+#ifdef TIME_T_SIGNED
+               "Thu, 01 Jan 1970 01:59:59 +0200",
+               "Fri, 13 Dec 1901 20:45:53 +0000",
+#endif
+#if (TIME_T_MAX_BITS > 32 || !defined(TIME_T_SIGNED))
+               "Sun, 07 Feb 2106 06:28:15 +0000",
+#endif
+               "Wed, 07 Nov 2007 01:07:20 +0200",
+               "Wed, 07 Nov 2007 01:07:20",
+               "Thu, 01 Jan 1970 02:00:00 +0200",
+               "Tue, 19 Jan 2038 03:14:07 +0000",
+               "Tue, 19 Jan 2038"
+       };
+       static struct test_message_date_output output[] = {
+#ifdef TIME_T_SIGNED
+               { -1, 2*60, TRUE },
+               { -2147483647, 0, TRUE },
+#endif
+#if (TIME_T_MAX_BITS > 32 || !defined(TIME_T_SIGNED))
+               { 4294967295, 0, TRUE },
+#endif
+               { 1194390440, 2*60, TRUE },
+               { 1194397640, 0, TRUE },
+               { 0, 2*60, TRUE },
+               { 2147483647, 0, TRUE },
+               { 0, 0, FALSE }
+       };
+       unsigned int i;
+       bool success;
+       time_t t;
+       int tz;
+       bool ret;
+
+       for (i = 0; i < N_ELEMENTS(input); i++) {
+               ret = message_date_parse((const unsigned char *)input[i],
+                                        strlen(input[i]), &t, &tz);
+               success = (!ret && !output[i].ret) ||
+                       (ret == output[i].ret && t == output[i].time &&
+                        tz == output[i].tz_offset);
+               test_out(t_strdup_printf("message_date_parse(%d)", i), success);
+       }
+}
+
+int main(void)
+{
+       static void (*test_functions[])(void) = {
+               test_message_date_parse,
+               NULL
+       };
+       return test_run(test_functions);
+}
diff --git a/src/lib-mail/test-message-parser.c b/src/lib-mail/test-message-parser.c
new file mode 100644 (file)
index 0000000..59f31d0
--- /dev/null
@@ -0,0 +1,124 @@
+/* Copyright (c) 2007-2009 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "istream.h"
+#include "message-parser.h"
+#include "test-common.h"
+
+static const char test_msg[] =
+"Return-Path: <test@example.org>\n"
+"Subject: Hello world\n"
+"From: Test User <test@example.org>\n"
+"To: Another User <test2@example.org>\n"
+"Message-Id: <1.2.3.4@example>\n"
+"Mime-Version: 1.0\n"
+"Date: Sun, 23 May 2007 04:58:08 +0300\n"
+"Content-Type: multipart/signed; micalg=pgp-sha1;\n"
+"      protocol=\"application/pgp-signature\";\n"
+"      boundary=\"=-GNQXLhuj24Pl1aCkk4/d\"\n"
+"\n"
+"--=-GNQXLhuj24Pl1aCkk4/d\n"
+"Content-Type: text/plain\n"
+"Content-Transfer-Encoding: quoted-printable\n"
+"\n"
+"There was a day=20\n"
+"a happy=20day\n"
+"\n"
+"--=-GNQXLhuj24Pl1aCkk4/d\n"
+"Content-Type: application/pgp-signature; name=signature.asc\n"
+"\n"
+"-----BEGIN PGP SIGNATURE-----\n"
+"Version: GnuPG v1.2.4 (GNU/Linux)\n"
+"\n"
+"invalid\n"
+"-----END PGP SIGNATURE-----\n"
+"\n"
+"--=-GNQXLhuj24Pl1aCkk4/d--\n"
+"\n"
+"\n";
+#define TEST_MSG_LEN (sizeof(test_msg)-1)
+
+static bool msg_parts_cmp(struct message_part *p1, struct message_part *p2)
+{
+       while (p1 != NULL || p2 != NULL) {
+               if ((p1 != NULL) != (p2 != NULL))
+                       return FALSE;
+               if ((p1->children != NULL) != (p2->children != NULL))
+                       return FALSE;
+
+               if (p1->children) {
+                       if (!msg_parts_cmp(p1->children, p2->children))
+                               return FALSE;
+               }
+
+               if (p1->physical_pos != p2->physical_pos ||
+                   p1->header_size.physical_size != p2->header_size.physical_size ||
+                   p1->header_size.virtual_size != p2->header_size.virtual_size ||
+                   p1->header_size.lines != p2->header_size.lines ||
+                   p1->body_size.physical_size != p2->body_size.physical_size ||
+                   p1->body_size.virtual_size != p2->body_size.virtual_size ||
+                   p1->body_size.lines != p2->body_size.lines ||
+                   p1->flags != p2->flags)
+                       return FALSE;
+
+               p1 = p1->next;
+               p2 = p2->next;
+       }
+       return TRUE;
+}
+
+static void test_message_parser(void)
+{
+       struct message_parser_ctx *parser;
+       struct istream *input;
+       struct message_part *parts, *parts2;
+       struct message_block block;
+       unsigned int i;
+       bool success = TRUE;
+       pool_t pool;
+       int ret;
+
+       pool = pool_alloconly_create("message parser", 10240);
+       input = i_stream_create_from_data(test_msg, TEST_MSG_LEN);
+
+       parser = message_parser_init(pool, input, 0, 0);
+       while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ;
+       i_assert(ret < 0);
+       ret = message_parser_deinit(&parser, &parts);
+       i_assert(ret == 0);
+       i_stream_unref(&input);
+
+       input = test_istream_create(test_msg);
+       test_istream_set_allow_eof(input, FALSE);
+
+       parser = message_parser_init(pool, input, 0, 0);
+       for (i = 1; i <= TEST_MSG_LEN*2+1; i++) {
+               test_istream_set_size(input, i/2);
+               if (i > TEST_MSG_LEN*2)
+                       test_istream_set_allow_eof(input, TRUE);
+               while ((ret = message_parser_parse_next_block(parser,
+                                                             &block)) > 0) ;
+               if (ret < 0 && i < TEST_MSG_LEN*2) {
+                       success = FALSE;
+                       break;
+               }
+       }
+       ret = message_parser_deinit(&parser, &parts2);
+       i_assert(ret == 0);
+       i_stream_unref(&input);
+
+       if (!msg_parts_cmp(parts, parts2))
+               success = FALSE;
+
+       pool_unref(&pool);
+       test_out("message_parser()", success);
+}
+
+int main(void)
+{
+       static void (*test_functions[])(void) = {
+               test_message_parser,
+               NULL
+       };
+       return test_run(test_functions);
+}
diff --git a/src/lib-mail/test-rfc2231-parser.c b/src/lib-mail/test-rfc2231-parser.c
new file mode 100644 (file)
index 0000000..c8164d2
--- /dev/null
@@ -0,0 +1,54 @@
+/* Copyright (c) 2007-2009 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "rfc822-parser.h"
+#include "rfc2231-parser.h"
+#include "test-common.h"
+
+static void test_rfc2231_parser(void)
+{
+       const char *input =
+               "; key*2=ba%"
+               "; key2*0=a"
+               "; key3*0*=us-ascii'en'xyz"
+               "; key*0=\"foo\""
+               "; key2*1*=b%25"
+               "; key3*1=plop%"
+               "; key*1=baz";
+       const char *output[] = {
+               "key",
+               "foobazba%",
+               "key2*",
+               "''ab%25",
+               "key3*",
+               "us-ascii'en'xyzplop%25",
+               NULL
+       };
+       struct rfc822_parser_context parser;
+       const char *const *result;
+       unsigned int i;
+       bool success;
+
+       rfc822_parser_init(&parser, (const void *)input, strlen(input), NULL);
+       if (rfc2231_parse(&parser, &result) < 0)
+               success = FALSE;
+       else {
+               success = TRUE;
+               for (i = 0; output[i] != NULL && result[i] != NULL; i++) {
+                       if (strcmp(output[i], result[i]) != 0)
+                               break;
+               }
+               if (output[i] != NULL || result[i] != NULL)
+                       success = FALSE;
+       }
+       test_out("rfc2231_parse()", success);
+}
+
+int main(void)
+{
+       static void (*test_functions[])(void) = {
+               test_rfc2231_parser,
+               NULL
+       };
+       return test_run(test_functions);
+}