2007-06-12 Murray Cumming <murrayc@murrayc.com>
[modest] / tests / check_text-utils.c
1 /* Copyright (c) 2006, Nokia Corporation
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  *   notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  *   notice, this list of conditions and the following disclaimer in the
12  *   documentation and/or other materials provided with the distribution.
13  * * Neither the name of the Nokia Corporation nor the names of its
14  *   contributors may be used to endorse or promote products derived from
15  *   this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #include <check.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <stdlib.h>
34 #include <modest-text-utils.h>
35
36 typedef struct {
37         const gchar *original;
38         const gchar *expected;
39 } StringPair;
40
41 /* ----------------- display address tests -------------- */
42
43 /**
44  * Test regular usage of modest_text_utils_get_display_address
45  *  - Test 1: Check "<...>" deletion
46  *  - Test 2: Check "(...)" deletion
47  *  - Test 3: Check address left and right trim, also non ASCII chars
48  *  - Test 4: Check issues in tests 1, 2 and 3 together
49  *  - Test 5: Check with an empty address
50  */
51 START_TEST (test_get_display_address_regular)
52 {
53         gint i;
54         const StringPair tests[] = {
55                 { "John Doe <foo@bar>", "John Doe" },
56                 { "Rupert Griffin (test)", "Rupert Griffin"},
57                 { "    Hyvää päivää    ", "Hyvää päivää"},
58                 { "  John Doe  <foo@bar>  (test)  ", "John Doe" },
59                 { "", "" },
60         };
61
62         /* Tests 1, 2, 3, 4 */
63         for (i = 0; i !=  sizeof(tests)/sizeof(StringPair); ++i) {
64                 gchar *str = g_strdup (tests[i].original);
65                 str = modest_text_utils_get_display_address (str);
66                 fail_unless (str && strcmp(str, tests[i].expected) == 0,
67                         "modest_text_utils_get_display_address failed for '%s': "
68                              "expected '%s' but got '%s'",
69                              tests[i].original, tests[i].expected, str);
70                 g_free (str);
71         }
72 }
73 END_TEST
74
75
76 /**
77  * Test invalid usage of modest_text_utils_get_display_address
78  *  - Test 1: Check with NULL address (should return NULL)
79  */
80 START_TEST (test_get_display_address_invalid)
81 {
82         /* Test 1 */
83         fail_unless (modest_text_utils_get_display_address (NULL) == NULL,
84                      "modest_text_utils_get_display_address(NULL) should be NULL");
85 }
86 END_TEST
87
88 /* ----------------- derived address tests -------------- */
89
90 /**
91  * Test regular usage of modest_text_utils_derived_subject
92  *  - Test 1: Check with a normal subject
93  *  - Test 2: Test with NULL subject
94  *  - Test 3: Test with non ASCII chars
95  *  - Test 4: Test with an empty subject
96  */
97 START_TEST (test_derived_subject_regular)
98 {
99         gint i;
100         const gchar *prefix="Re:";
101         const StringPair tests[] = {
102                 { "subject", "Re: subject" },
103                 { NULL,      "Re:"},
104                 { "Hyvää päivää", "Re: Hyvää päivää"},
105                 { "", "Re: "},
106         };
107
108         /* Tests 1, 2, 3, 4 */
109         for (i = 0; i !=  sizeof(tests)/sizeof(StringPair); ++i) {
110                 gchar *orig = g_strdup (tests[i].original);
111                 gchar *str = modest_text_utils_derived_subject (orig, prefix);
112                 fail_unless (str && strcmp(str, tests[i].expected) == 0,
113                         "modest_text_utils_derived_subject failed for '%s': "
114                              "expected '%s' but got '%s'",
115                              tests[i].original, tests[i].expected, str);
116                 g_free (orig);
117                 g_free (str);
118         }
119 }
120 END_TEST
121
122 /**
123  * Test invalid usage of modest_text_utils_derived_subject
124  *  - Test 1: Check with NULL prefix (should return NULL)
125  */
126 START_TEST (test_derived_subject_invalid)
127 {
128         /* Test 1 */
129         fail_unless (modest_text_utils_derived_subject (NULL, NULL) == NULL,
130                      "modest_text_utils_derived_subject (*,NULL) should be NULL");
131 }
132 END_TEST
133
134 /* --------------------- quote tests -------------------- */
135
136 /**
137  * Test regular usage of modest_text_utils_quote
138  *  - Test 1: Quote empty text
139  *  - Test 2: Quote 1 line of plain text 
140  *  - Test 3: Quote several lines of plain text 
141  *  - Test 4: Quote non ASCII chars
142  *  - Test 5: Quote with a limit lower than the any word in the text
143  *  - TODO: Test HTML quotation once its implementation if finished
144  */
145 START_TEST (test_quote_regular)
146 {
147         gint i;
148         gchar *text = NULL;
149         gchar *expected_quoted_text = NULL;
150         gchar *quoted_text = NULL;
151
152         /* Tests 1, 2, 3 */
153         const StringPair tests[] = {
154                 { "", 
155                   "On Thu Jan  1 01:00:00 1970, foo@bar wrote:\n> \n" },
156                 { "This text should be quoted", 
157                   "On Thu Jan  1 01:00:00 1970, foo@bar wrote:\n> This text\n> should be quoted\n> \n" },
158                 { "These are several\nlines\nof plain text", 
159                   "On Thu Jan  1 01:00:00 1970, foo@bar wrote:\n> These are\n> several lines\n> of plain text\n" },
160                 { "áéíÍÓÚäëïÏÖÜñÑçÇŽÊîš", 
161                   "On Thu Jan  1 01:00:00 1970, foo@bar wrote:\n> áéíÍÓÚäëïÏÖÜñÑçÇŽÊîš\n" },
162         };
163
164         for (i = 0; i !=  sizeof(tests)/sizeof(StringPair); ++i) {
165                 text = g_strdup (tests[i].original);
166                 expected_quoted_text = g_strdup (tests[i].expected);
167                 quoted_text = modest_text_utils_quote (text, "text/plain", "foo@bar",  0, 15);
168                 fail_unless (quoted_text && strcmp(expected_quoted_text, quoted_text)==0,
169                              "modest_text_utils_quote failed:\nOriginal text:\n\"%s\"\n" \
170                              "Expected quotation:\n\"%s\"\nQuoted text:\n\"%s\"",
171                              text, expected_quoted_text, quoted_text);
172                 g_free (text);
173                 g_free (expected_quoted_text);
174                 g_free (quoted_text);
175         }
176
177         /* Test 5 */
178         text = g_strdup ("Quotation test example");
179         expected_quoted_text = 
180                 g_strdup ("On Thu Jan  1 01:00:00 1970, foo@bar wrote:\n> Quotation\n> test\n> example\n> \n");
181         quoted_text = modest_text_utils_quote (text, "text/plain", "foo@bar",  0, 1);
182         fail_unless (quoted_text && !strcmp (expected_quoted_text, quoted_text),
183                      "modest_text_utils_quote failed:\nOriginal text:\n\"%s\"\n" \
184                      "Expected quotation:\n\"%s\"\nQuoted text:\n\"%s\"",
185                      text, expected_quoted_text, quoted_text);
186         g_free (text);
187         g_free (expected_quoted_text);
188         g_free (quoted_text);
189 }
190 END_TEST
191
192 /**
193  * Test invalid usage of modest_text_utils_quote
194  *  - Test 1: Check NULL text (should return NULL)
195  *  - Test 2: Check NULL content_type (should quote as text/plain)
196  *  - Test 3: Check NULL address (should cite address as "(null)")
197  *  - Test 4: Check negative limit (should write each word in its own line)
198  *  - TODO: Repeat tests for HTML quotation when its implementation is finished
199  */
200 START_TEST (test_quote_invalid)
201 {
202         gchar *text = NULL;
203         gchar *expected_quoted_text = NULL;
204         gchar *quoted_text = NULL;
205
206         /* Test 1 (Fault) */
207         text = NULL;
208         quoted_text = modest_text_utils_quote (NULL, "text/plain", "foo@bar",  0, 15);
209         fail_unless (quoted_text == NULL,
210                      "modest_text_utils_quote failed:\nOriginal text: NULL\n" \
211                      "Expected quotation: NULL\nQuoted text: \"%s\"",
212                      quoted_text);
213         g_free (quoted_text);
214         
215         
216         /* Test 2 (Fault) */
217         text = g_strdup ("Text");
218         expected_quoted_text = g_strdup ("On Thu Jan  1 01:00:00 1970, foo@bar wrote:\n> Text\n");
219         quoted_text = modest_text_utils_quote (text, NULL, "foo@bar",  0, 15);
220         fail_unless (quoted_text == NULL,
221                      "modest_text_utils_quote failed:\nOriginal text: NULL\n" \
222                      "Expected quotation: NULL\nQuoted text: \"%s\"",
223                      quoted_text);
224         g_free (text);
225         g_free (expected_quoted_text);
226         g_free (quoted_text);
227
228         /* Test 3 */
229         text = g_strdup ("Text");
230         expected_quoted_text = g_strdup ("On Thu Jan  1 01:00:00 1970, (null) wrote:\n> Text\n");
231         quoted_text = modest_text_utils_quote (text, "text/plain", NULL,  0, 15);
232         fail_unless (quoted_text == NULL,
233                      "modest_text_utils_quote failed:\nOriginal text: NULL\n" \
234                      "Expected quotation: NULL\nQuoted text: \"%s\"",
235                      quoted_text);
236         g_free (text);
237         g_free (expected_quoted_text);
238         g_free (quoted_text);
239
240         /* Test 4 */
241         text = g_strdup ("This is a text");
242         expected_quoted_text = g_strdup ("On Thu Jan  1 01:00:00 1970, foo@bar wrote:\n> This\n> is\n> a\n> text\n> \n");
243         quoted_text = modest_text_utils_quote (text, "text/plain", "foo@bar",  0, 0);
244         fail_unless (quoted_text && !strcmp (expected_quoted_text, quoted_text),
245                      "modest_text_utils_quote failed:\nOriginal text:\n\"%s\"\n" \
246                      "Expected quotation:\n\"%s\"\nQuoted text:\n\"%s\"",
247                      text, expected_quoted_text, quoted_text);
248         g_free (text);
249         g_free (expected_quoted_text);
250         g_free (quoted_text);
251 }
252 END_TEST
253
254 /* ---------------------- cite tests -------------------- */
255
256 /**
257  * Test regular usage of modest_text_utils_cite
258  *  - Test 1: Check cite of an empty text
259  *  - Test 2: Check cite of a line of text
260  *  - Test 3: Check cite of several lines of text
261  *  - Test 4: Check with non ASCII chars
262  */
263 START_TEST (test_cite_regular)
264 {
265         gint i;
266         gchar *cited_text = NULL;
267         const StringPair tests[] = {
268                 { "", 
269                   "On Thu Jan  1 01:00:00 1970, foo@bar wrote:\n\n" },
270                 { "This is some text", 
271                   "On Thu Jan  1 01:00:00 1970, foo@bar wrote:\nThis is some text\n" },
272                 { "This\nis some\ntext", 
273                   "On Thu Jan  1 01:00:00 1970, foo@bar wrote:\nThis\nis some\ntext\n" },
274                 { "áéíÍÓÚäëïÏÖÜñÑçÇŽÊîš",
275                   "On Thu Jan  1 01:00:00 1970, foo@bar wrote:\náéíÍÓÚäëïÏÖÜñÑçÇŽÊîš\n" },
276         };
277
278         /* Tests 1, 2, 3, 4 */
279         for (i = 0; i !=  sizeof(tests)/sizeof(StringPair); ++i) {
280                 cited_text = modest_text_utils_cite (tests[i].original, "text/plain", "foo@bar", 0);
281                 fail_unless (cited_text && !strcmp (tests[i].expected, cited_text),
282                              "modest_text_utils_cite failed:\nOriginal text:\n\"%s\"\n" \
283                              "Expected cite:\n\"%s\"\nCite obtained:\n\"%s\"",
284                              tests[i].original, tests[i].expected, cited_text);
285                 g_free (cited_text);
286         }
287 }
288 END_TEST
289
290 /**
291  * Test invalid usage of modest_text_utils_cite
292  *  - Test 1: Check NULL text (should cite text as (null))
293  *  - Test 2: Check NULL address (should cite address as (null)
294  *  TODO: add tests for content_type once it is used in the implementation
295  */
296 START_TEST (test_cite_invalid)
297 {
298         gchar *text = NULL;
299         gchar *cited_text = NULL;
300         gchar *expected_cite = NULL;
301
302         /* Test 1 */
303         text = NULL;
304         expected_cite = g_strdup ("On Thu Jan  1 01:00:00 1970, foo@bar wrote:\n(null)\n");
305         cited_text = modest_text_utils_cite (text, "text/plain", "foo@bar", 0);
306         fail_unless (cited_text && !strcmp (expected_cite, cited_text),
307                      "modest_text_utils_cite failed:\nOriginal text:\nNULL\n" \
308                      "Expected cite:\n\"%s\"\nCite obtained:\n\"%s\"",
309                      expected_cite, cited_text);
310         g_free (expected_cite);
311         g_free (cited_text);
312
313         /* Test 2 */
314         text = g_strdup ("This is some text");
315         expected_cite = g_strdup ("On Thu Jan  1 01:00:00 1970, (null) wrote:\nThis is some text\n");
316         cited_text = modest_text_utils_cite (text, "text/plain", NULL, 0);
317         fail_unless (cited_text && !strcmp (expected_cite, cited_text),
318                      "modest_text_utils_cite failed:\nOriginal text:\n\"%s\"\n" \
319                      "Expected cite:\n\"%s\"\nCite obtained:\n\"%s\"",
320                      text, expected_cite, cited_text);
321         g_free (text);
322         g_free (expected_cite);
323         g_free (cited_text);
324 }
325 END_TEST
326
327 /* -------------------- inline tests -------------------- */
328
329 /**
330  * Test regular usage of modest_text_utils_inline
331  *  - Test 1: Check inline of an empty text
332  *  - Test 2: Check inline of a regular text
333  *  - Test 3: Check with non ASCII chars
334  *  TODO: add tests for HTML when implementation is finished
335  */
336 START_TEST (test_inline_regular)
337 {
338         gint i;
339         gchar *inlined_text = NULL;
340         const StringPair tests[] = {
341                 { "", 
342                   "-----Forwarded Message-----\n" \
343                   "From: foo@bar\n" \
344                   "Sent: Thu Jan  1 01:00:00 1970\n" \
345                   "To: bar@foo\n" \
346                   "Subject: Any subject\n\n" },
347                 { "Some text\nto inline", 
348                   "-----Forwarded Message-----\n" \
349                   "From: foo@bar\n" \
350                   "Sent: Thu Jan  1 01:00:00 1970\n" \
351                   "To: bar@foo\n" \
352                   "Subject: Any subject\n\n" \
353                   "Some text\nto inline" },
354                 { "áéíÍÓÚäëïÏÖÜñÑçÇŽÊîš", 
355                   "-----Forwarded Message-----\n" \
356                   "From: foo@bar\n" \
357                   "Sent: Thu Jan  1 01:00:00 1970\n" \
358                   "To: bar@foo\n" \
359                   "Subject: Any subject\n\n" \
360                   "áéíÍÓÚäëïÏÖÜñÑçÇŽÊîš" },
361         };
362
363         /* Tests 1, 2, 3 */
364         for (i = 0; i !=  sizeof(tests)/sizeof(StringPair); ++i) {
365                 inlined_text =  modest_text_utils_inline (tests[i].original, 
366                                                           "text/plain", 
367                                                           "foo@bar", 
368                                                           0, 
369                                                           "bar@foo", 
370                                                           "Any subject");
371                 fail_unless (inlined_text && !strcmp (tests[i].expected, inlined_text),
372                              "modest_text_utils_inline failed:\nOriginal text:\n\"%s\"\n" \
373                              "Expected inline:\n\"%s\"\nInline obtained:\n\"%s\"",
374                              tests[i].original, tests[i].expected, inlined_text);               
375                 g_free (inlined_text);
376         }
377 }
378 END_TEST
379
380 /**
381  * Test invalid usage of modest_text_utils_inline
382  *  - Test 1: Check NULL text (should inline text as (null))
383  *  - Test 2: Check NULL content_type (should assume text/plain)
384  *  - Test 3: Check NULL from (should write "(null)")
385  *  - Test 4: Check NULL to (should write ("null"))
386  *  - Test 5: Check NULL subject (should write ("null"))
387  * TODO: repeat tests from HTML when implemented
388  */
389 START_TEST (test_inline_invalid)
390 {
391         gchar *text = NULL;
392         gchar *expected_inline = NULL;
393         gchar *inlined_text = NULL;
394
395         /* Test 1 */
396         expected_inline = g_strdup("-----Forwarded Message-----\n" \
397                                    "From: foo@bar\n" \
398                                    "Sent: Thu Jan  1 01:00:00 1970\n" \
399                                    "To: bar@foo\n" \
400                                    "Subject: Any subject\n\n" \
401                                    "(null)");
402         inlined_text =  modest_text_utils_inline (NULL, 
403                                                   "text/plain", 
404                                                   "foo@bar", 
405                                                   0, 
406                                                   "bar@foo", 
407                                                   "Any subject");
408         fail_unless (inlined_text == NULL, 
409                      "modest_text_utils_inline failed: it should return NULL");
410         g_free (inlined_text);
411
412         /* Test 2 (Fault) */
413         text = g_strdup ("Some text");
414         expected_inline = g_strdup("-----Forwarded Message-----\n" \
415                                    "From: foo@bar\n" \
416                                    "Sent: Thu Jan  1 01:00:00 1970\n" \
417                                    "To: bar@foo\n" \
418                                    "Subject: Any subject\n\n" \
419                                    "Some text");
420         inlined_text =  modest_text_utils_inline (text,
421                                                   NULL,
422                                                   "foo@bar",
423                                                   0,
424                                                   "bar@foo",
425                                                   "Any subject");
426         fail_unless (inlined_text == NULL, 
427                      "modest_text_utils_inline failed: it should return NULL");
428         g_free (inlined_text);
429
430         /* Test 3 */
431         text = g_strdup ("Some text");
432         expected_inline = g_strdup("-----Forwarded Message-----\n" \
433                                    "From: (null)\n" \
434                                    "Sent: Thu Jan  1 01:00:00 1970\n" \
435                                    "To: bar@foo\n" \
436                                    "Subject: Any subject\n\n" \
437                                    "Some text");
438         inlined_text =  modest_text_utils_inline (text, 
439                                                   "text/plain", 
440                                                   NULL, 
441                                                   0, 
442                                                   "bar@foo", 
443                                                   "Any subject");
444         fail_unless (inlined_text == NULL, 
445                      "modest_text_utils_inline failed: it should return NULL");
446
447         g_free (inlined_text);
448
449         /* Test 4 */
450         text = g_strdup ("Some text");
451         expected_inline = g_strdup("-----Forwarded Message-----\n" \
452                                    "From: foo@bar\n" \
453                                    "Sent: Thu Jan  1 01:00:00 1970\n" \
454                                    "To: (null)\n" \
455                                    "Subject: Any subject\n\n" \
456                                    "Some text");
457         inlined_text =  modest_text_utils_inline (text, 
458                                                   "text/plain", 
459                                                   "foo@bar", 
460                                                   0, 
461                                                   NULL, 
462                                                   "Any subject");
463         fail_unless (inlined_text == NULL, 
464                      "modest_text_utils_inline failed: it should return NULL");
465         g_free (inlined_text);
466         
467         /* Test 5 */
468         text = g_strdup ("Some text");
469         expected_inline = g_strdup("-----Forwarded Message-----\n" \
470                                    "From: foo@bar\n" \
471                                    "Sent: Thu Jan  1 01:00:00 1970\n" \
472                                    "To: bar@foo\n" \
473                                    "Subject: (null)\n\n" \
474                                    "Some text");
475         inlined_text =  modest_text_utils_inline (text, 
476                                                   "text/plain", 
477                                                   "foo@bar", 
478                                                   0, 
479                                                   "bar@foo", 
480                                                   NULL);
481         fail_unless (inlined_text == NULL, 
482                      "modest_text_utils_inline failed: it should return NULL");
483
484         g_free (inlined_text);
485 }
486 END_TEST
487
488 /* ---------------- remove address tests ---------------- */
489
490 /**
491  * Test regular usage of modest_text_utils_remove_address
492  *  - Test 1: Remove a single address in the middle of a list
493  *  - Test 2: Remove an extended address in the middle of a list
494  *  - Test 3: Remove an address that appears more than once in the list
495  *  - Test 4: Remove address from an empty list
496  *  - Test 5: Check with non ASCII characters
497  */
498 START_TEST (test_remove_address_regular)
499 {
500         gchar *list = NULL;
501         gchar *new_list = NULL;
502         gchar *address = NULL;
503
504         /* Test 1 */
505         list = g_strdup ("foo@bar <foo>, myname@mycompany.com (myname), " \
506                          "xxx@yyy.zzz (xxx yyy zzz), bar@foo");
507         address = g_strdup ("xxx@yyy.zzz");
508         new_list = modest_text_utils_remove_address (list, address);
509
510         fail_unless (new_list && strstr (new_list, "foo@bar <foo>") != NULL,
511                      "modest_text_utils_remove_address failed: "\
512                      "Removing \"%s\" from address list \"%s\" returns \"%s\"",
513                      address, list, new_list);
514         fail_unless (new_list && strstr (new_list, "myname@mycompany.com (myname)") != NULL,
515                      "modest_text_utils_remove_address failed: " \
516                      "Removing \"%s\" from address list \"%s\" returns \"%s\"",
517                      address, list, new_list);
518         fail_unless (new_list && strstr (new_list, "bar@foo") != NULL,
519                      "modest_text_utils_remove_address failed: " \
520                      "Removing \"%s\" from address list \"%s\" returns \"%s\"",
521                      address, list, new_list);
522         fail_unless (new_list && strstr (new_list, "xxx@yyy.zzz") == NULL,
523                      "modest_text_utils_remove_address failed: " \
524                      "Removing \"%s\" from address list \"%s\" returns \"%s\"",
525                      address, list, new_list);
526         fail_unless (new_list && strstr (new_list, "(xxx yyy zzz)") == NULL,
527                      "modest_text_utils_remove_address failed: " \
528                      "Removing \"%s\" from address list \"%s\" returns \"%s\"",
529                      address, list, new_list);
530
531         g_free (list);
532         g_free (new_list);
533         g_free (address);
534
535         /* Test 2 */
536         list = g_strdup ("foo@bar <foo>, xxx@yyy.zzz (xxx yyy zzz), bar@foo");
537         address = g_strdup ("xxx@yyy.zzz (xxx yyy zzz)");
538         new_list = modest_text_utils_remove_address (list, address);
539
540         fail_unless (new_list && strstr (new_list, "foo@bar <foo>") != NULL,
541                      "modest_text_utils_remove_address failed: " \
542                      "Removing \"%s\" from address list \"%s\" returns \"%s\"",
543                      address, list, new_list);
544         fail_unless (new_list && strstr (new_list, "bar@foo") != NULL,
545                      "modest_text_utils_remove_address failed: " \
546                      "Removing \"%s\" from address list \"%s\" returns \"%s\"",
547                      address, list, new_list);
548         fail_unless (new_list && strstr (new_list, "xxx@yyy.zzz") == NULL,
549                      "modest_text_utils_remove_address failed: " \
550                      "Removing \"%s\" from address list \"%s\" returns \"%s\"",
551                      address, list, new_list);
552         fail_unless (new_list && strstr (new_list, "(xxx yyy zzz)") == NULL,
553                      "modest_text_utils_remove_address failed: " \
554                      "Removing \"%s\" from address list \"%s\" returns \"%s\"",
555                      address, list, new_list);
556
557         g_free (list);
558         g_free (new_list);
559         g_free (address);
560
561         /* Test 3 */
562         list = g_strdup ("foo@bar <foo>, bar@foo (BAR), xxx@yyy.zzz (xxx yyy zzz), bar@foo");
563         address = g_strdup ("bar@foo");
564         new_list = modest_text_utils_remove_address (list, address);
565
566         fail_unless (new_list && strstr (new_list, "foo@bar <foo>") != NULL,
567                      "modest_text_utils_remove_address failed: " \
568                      "Removing \"%s\" from address list \"%s\" returns \"%s\"",
569                      address, list, new_list);
570         fail_unless (new_list && strstr (new_list, "xxx@yyy.zzz (xxx yyy zzz)") != NULL,
571                      "modest_text_utils_remove_address failed: " \
572                      "Removing \"%s\" from address list \"%s\" returns \"%s\"",
573                      address, list, new_list);
574         fail_unless (new_list && strstr (new_list, "bar@foo") == NULL,
575                      "modest_text_utils_remove_address failed: " \
576                      "Removing \"%s\" from address list \"%s\" returns \"%s\"",
577                      address, list, new_list);
578         fail_unless (new_list && strstr (new_list, "(BAR)") == NULL,
579                      "modest_text_utils_remove_address failed: " \
580                      "Removing \"%s\" from address list \"%s\" returns \"%s\"",
581                      address, list, new_list);
582
583         g_free (list);
584         g_free (new_list);
585         g_free (address);
586
587         /* Test 4 */
588         list = g_strdup ("");
589         address = g_strdup ("bar@foo");
590         new_list = modest_text_utils_remove_address (list, address);
591
592         fail_unless (new_list && !strcmp (new_list, list),
593                      "modest_text_utils_remove_address failed: " \
594                      "Removing \"%s\" from address list \"%s\" returns \"%s\"",
595                      address, list, new_list);
596
597         g_free (list);
598         g_free (new_list);
599         g_free (address);
600
601         /* Test 5 */
602         list = g_strdup ("foo@bar, áñï@Èž.com (Àç ÑŸž), bar@foo");
603         address = g_strdup ("áñï@Èž.com");
604         new_list = modest_text_utils_remove_address (list, address);
605
606         fail_unless (new_list && strstr (new_list, "foo@bar") != NULL,
607                      "modest_text_utils_remove_address failed: " \
608                      "Removing \"%s\" from address list \"%s\" returns \"%s\"",
609                      address, list, new_list);
610         fail_unless (new_list && strstr (new_list, "bar@foo") != NULL,
611                      "modest_text_utils_remove_address failed: " \
612                      "Removing \"%s\" from address list \"%s\" returns \"%s\"",
613                      address, list, new_list);
614         fail_unless (new_list && strstr (new_list, "áñï@Èž.com") == NULL,
615                      "modest_text_utils_remove_address failed: " \
616                      "Removing \"%s\" from address list \"%s\" returns \"%s\"",
617                      address, list, new_list);
618         fail_unless (new_list && strstr (new_list, "(Àç ÑŸž)") == NULL,
619                      "modest_text_utils_remove_address failed: " \
620                      "Removing \"%s\" from address list \"%s\" returns \"%s\"",
621                      address, list, new_list);
622
623         g_free (list);
624         g_free (new_list);
625         g_free (address);
626 }
627 END_TEST
628
629 /**
630  * Test limits usage of modest_text_utils_remove_address
631  *  - Test 1: Remove address at the beginning of the list
632  *  - Test 2: Remove address at the end  of the list
633  *  - Test 3: Remove the address of a one-element-size list
634  */
635 START_TEST (test_remove_address_limits)
636 {
637         gchar *list = NULL;
638         gchar *new_list = NULL;
639         gchar *expected_list = NULL;
640         //gchar *address = NULL;
641         gint i;
642
643         const StringPair tests[] = {
644                 { "foo@bar <FOO BAR>, bar@foo (BAR FOO)", "bar@foo (BAR FOO)" },
645                 { "foo@bar <FOO BAR>, bar@foo (BAR FOO)", "foo@bar <FOO BAR>" },
646                 { "foo@bar <FOO BAR>", "" },
647         };
648         const gchar *remove[] = { "foo@bar", "bar@foo", "foo@bar" };
649
650         /* Tests 1, 2, 3 */
651         for (i = 0; i !=  sizeof(tests)/sizeof(StringPair); ++i) {
652                 list = g_strdup (tests[i].original);
653                 expected_list = g_strdup (tests[i].expected);
654                 new_list = modest_text_utils_remove_address (list, remove[i]);
655                 fail_unless (new_list && !strcmp (expected_list, new_list),
656                              "modest_text_utils_remove_address failed: " \
657                              "Removing \"%s\" from address list \"%s\" returns \"%s\" instead of \"%s\"",
658                              remove[i], list, new_list, expected_list);
659                 g_free (list);
660                 g_free (expected_list);
661                 g_free (new_list);
662         }
663 }
664 END_TEST
665
666 /**
667  * Test invalid usage of modest_text_utils_remove_address
668  *  - Test 1: Remove a NULL address (should return the same list)
669  *  - Test 2: Remove an address form a NULL list (should return NULL)
670  */
671 START_TEST (test_remove_address_invalid)
672 {
673         gchar *list = NULL;
674         gchar *new_list = NULL;
675
676         /* Test 1 (Fault) */
677         list = g_strdup ("foo@bar, bar@foo");
678         new_list = modest_text_utils_remove_address (list, NULL);
679         fail_unless (new_list && !strcmp (list, new_list),
680                      "modest_text_utils_remove_address failed: " \
681                      "Removing a NULL address from \"%s\" returns \"%s\"",
682                      list, new_list);
683         g_free (list);
684         g_free (new_list);
685
686         /* Test 2 */
687         new_list = modest_text_utils_remove_address (NULL, "foo@bar");
688         fail_unless (new_list == NULL,
689                      "modest_text_utils_remove_address failed: " \
690                      "Removing an address from a NULL list does not return NULL");
691         g_free (new_list);
692 }
693 END_TEST
694
695 /* --------------- convert to html tests ---------------- */
696
697 /**
698  * Test regular usage of modest_text_utils_convert_to_html
699  *  - Test 1: Check conversion of a regular text
700  *  - Test 2: Check conversion of a regular text with links
701  *  - Test 3: Check conversion of a regular text with special html chars
702  */
703 START_TEST (test_convert_to_html_regular)
704 {
705         gchar *text_in_html;
706         gchar *html_start = NULL;
707         gchar *html_end = NULL;
708         gchar *html = NULL;
709         gint bytes;
710         int i;
711
712         const StringPair tests[] = {
713                 { "This is some text.", 
714                   "<tt>This is some text.</tt>" },
715                 { "http://xxx.yyy.zzz/myfile", 
716                   "<tt><a href=\"http://xxx.yyy.zzz/myfile\">http://xxx.yyy.zzz/myfile</a></tt>" },
717                 { "<a  &  b>\n\tx", 
718                   "<tt>&lt;a &nbsp;&quot;&nbsp;&nbsp;b&gt;<br>\n&nbsp; &nbsp;&nbsp;x</tt>" },
719         };
720
721         /* Tests 1, 2, 3 */
722         for (i = 0; i !=  sizeof(tests)/sizeof(StringPair); ++i) {
723                 html = modest_text_utils_convert_to_html (tests[i].original);
724                 fail_unless (html != NULL,
725                              "modest_text_utils_convert_to_html failed:" \
726                              "Original text:\n\"%s\"\nExpected html:\n\"%s\"\nObtained html:\nNULL",
727                              tests[i].original, tests[i].expected);
728                 html_start = strstr (html, "<tt>");
729                 html_end = strstr (html, "</body>");
730                 bytes = html_end - html_start;
731                 text_in_html = g_strndup (html_start, bytes);
732                 
733                 fail_unless (strstr (html, tests[i].expected) != NULL,
734                              "modest_text_utils_convert_to_html failed:" \
735                              "Original text:\n\"%s\"\nExpected html:\n\"%s\"\nObtained html:\n\"%s\"",
736                              tests[i].original, tests[i].expected, text_in_html);
737 //              g_free (html_start);
738 //              g_free (text_in_html);
739 //              g_free (html);
740         }
741 }
742 END_TEST
743
744 /**
745  * Test invalid usage of modest_text_utils_convert_to_html
746  *  - Test 1: Check with NULL data
747  */
748 START_TEST (test_convert_to_html_invalid)
749 {
750         gchar *html = NULL;
751
752         /* Test 1 */
753         html = modest_text_utils_convert_to_html (NULL);
754         fail_unless (html == NULL,
755                      "modest_text_utils_convert_to_html failed:" \
756                      "Does not return NULL when passed NULL data");
757 }
758 END_TEST
759
760
761 /* ------------------- Suite creation ------------------- */
762
763 static Suite*
764 text_utils_suite (void)
765 {
766         Suite *suite = suite_create ("ModestTextUtils");
767         TCase *tc = NULL;
768
769         /* Tests case for "display adress" */
770         tc = tcase_create ("display_adress");
771         tcase_add_test (tc, test_get_display_address_regular);
772         tcase_add_test (tc, test_get_display_address_invalid);
773         suite_add_tcase (suite, tc);
774
775         /* Test case for "derived subject" */
776         tc = tcase_create ("derived_subject");
777         tcase_add_test (tc, test_derived_subject_regular);
778         tcase_add_test (tc, test_derived_subject_invalid);
779         suite_add_tcase (suite, tc);
780
781         /* Test case for "quote" */
782         tc = tcase_create ("quote");
783         tcase_add_test (tc, test_quote_regular);
784         tcase_add_test (tc, test_quote_invalid);
785         suite_add_tcase (suite, tc);
786
787         /* Test case for "cite" */
788         tc = tcase_create ("cite");
789         tcase_add_test (tc, test_cite_regular);
790         tcase_add_test (tc, test_cite_invalid);
791         suite_add_tcase (suite, tc);
792
793         /* Test case for "inline" */
794         tc = tcase_create ("inline");
795         tcase_add_test (tc, test_inline_regular);
796         tcase_add_test (tc, test_inline_invalid);
797         suite_add_tcase (suite, tc);
798
799         /* Test case for "remove address" */
800         tc = tcase_create ("remove_address");
801         tcase_add_test (tc, test_remove_address_regular);
802         tcase_add_test (tc, test_remove_address_limits);
803         tcase_add_test (tc, test_remove_address_invalid);
804         suite_add_tcase (suite, tc);
805
806         /* Test case for "convert to html" */
807         tc = tcase_create ("convert_to_html");
808         tcase_add_test (tc, test_convert_to_html_regular);
809         tcase_add_test (tc, test_convert_to_html_invalid);
810         suite_add_tcase (suite, tc);
811
812         return suite;
813 }
814
815 /* --------------------- Main program ------------------- */
816
817 gint
818 main ()
819 {
820         SRunner *srunner;
821         Suite   *suite;
822         int     failures;
823
824         setenv ("TZ", "Europe/Paris", 1);
825         
826         suite   = text_utils_suite ();
827         srunner = srunner_create (suite);
828                 
829         srunner_run_all (srunner, CK_ENV);
830         failures = srunner_ntests_failed (srunner);
831         srunner_free (srunner);
832         
833         return failures;
834 }