test-mail-search-args-simplify.c revision e5834cb5a1d79a886fe81648a1b8cc57f973dd1f
5f5870385cff47efd2f58e7892f251cf13761528Timo Sirainen/* Copyright (c) 2015-2017 Dovecot authors, see the included COPYING file */
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen#include "lib.h"
6157a322f2ac1ea1332d9003ecb0b11466aa8fe7Timo Sirainen#include "str.h"
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen#include "test-common.h"
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen#include "mail-storage-private.h"
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen#include "mail-search-build.h"
8b681dae1e8fa564649e703ab17398dcfaf896e4Timo Sirainen#include "mail-search-parser.h"
4bbee99b3aef449a9a2a11a5b5cf1ca486915c49Timo Sirainen#include "mail-search.h"
c4cfee078c4a185b5ba8f0c55f51275b7e885b2cTimo Sirainen
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainenstatic const struct {
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen const char *input;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen const char *output;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen} tests[] = {
8c02331f9f569d8b30e74b6bc8550734d65f9daeTimo Sirainen { "ALL", "ALL" },
8c02331f9f569d8b30e74b6bc8550734d65f9daeTimo Sirainen { "NOT ALL", "NOT ALL" },
8c02331f9f569d8b30e74b6bc8550734d65f9daeTimo Sirainen { "ALL NOT ALL", "NOT ALL" },
8c02331f9f569d8b30e74b6bc8550734d65f9daeTimo Sirainen { "ALL NOT ALL TEXT foo", "NOT ALL" },
9bf2dc275ec21bff3d468ab1bc4fddc8874f7d1bTimo Sirainen { "OR ALL NOT ALL", "ALL" },
9bf2dc275ec21bff3d468ab1bc4fddc8874f7d1bTimo Sirainen { "OR ALL OR NOT ALL TEXT foo", "ALL" },
9bf2dc275ec21bff3d468ab1bc4fddc8874f7d1bTimo Sirainen { "OR ALL OR TEXT foo TEXT bar", "ALL" },
9bf2dc275ec21bff3d468ab1bc4fddc8874f7d1bTimo Sirainen { "OR TEXT FOO ( ALL NOT ALL )", "TEXT FOO" },
9bf2dc275ec21bff3d468ab1bc4fddc8874f7d1bTimo Sirainen { "TEXT FOO OR ALL NOT ALL", "TEXT FOO" },
9bf2dc275ec21bff3d468ab1bc4fddc8874f7d1bTimo Sirainen
9bf2dc275ec21bff3d468ab1bc4fddc8874f7d1bTimo Sirainen { "TEXT foo", "TEXT foo" },
9bf2dc275ec21bff3d468ab1bc4fddc8874f7d1bTimo Sirainen { "( TEXT foo )", "TEXT foo" },
9bf2dc275ec21bff3d468ab1bc4fddc8874f7d1bTimo Sirainen { "( ( TEXT foo ) )", "TEXT foo" },
9bf2dc275ec21bff3d468ab1bc4fddc8874f7d1bTimo Sirainen { "( ( TEXT foo ) ( TEXT bar ) )", "TEXT foo TEXT bar" },
5c0034beb9933bca2a8b7d83d11dface1ea3b7faTimo Sirainen
5c0034beb9933bca2a8b7d83d11dface1ea3b7faTimo Sirainen { "OR ( TEXT foo ) ( TEXT bar )", "OR TEXT foo TEXT bar" },
5c0034beb9933bca2a8b7d83d11dface1ea3b7faTimo Sirainen { "OR ( TEXT foo ) OR ( TEXT bar ) ( TEXT baz )",
9bf2dc275ec21bff3d468ab1bc4fddc8874f7d1bTimo Sirainen "OR TEXT foo OR TEXT bar TEXT baz" },
9bf2dc275ec21bff3d468ab1bc4fddc8874f7d1bTimo Sirainen { "OR ( ( TEXT foo TEXT foo2 ) ) ( ( TEXT bar ( TEXT baz ) ) )",
9bf2dc275ec21bff3d468ab1bc4fddc8874f7d1bTimo Sirainen "OR (TEXT foo TEXT foo2) (TEXT bar TEXT baz)" },
9bf2dc275ec21bff3d468ab1bc4fddc8874f7d1bTimo Sirainen
9bf2dc275ec21bff3d468ab1bc4fddc8874f7d1bTimo Sirainen { "NOT ( TEXT foo )", "NOT TEXT foo" },
9bf2dc275ec21bff3d468ab1bc4fddc8874f7d1bTimo Sirainen { "NOT ( NOT ( TEXT foo ) )", "TEXT foo" },
5c0034beb9933bca2a8b7d83d11dface1ea3b7faTimo Sirainen { "NOT OR ( TEXT foo ) ( TEXT bar )", "NOT TEXT foo NOT TEXT bar" },
5c0034beb9933bca2a8b7d83d11dface1ea3b7faTimo Sirainen { "NOT ( OR ( TEXT foo ) ( TEXT bar ) )", "NOT TEXT foo NOT TEXT bar" },
5c0034beb9933bca2a8b7d83d11dface1ea3b7faTimo Sirainen { "NOT ( TEXT foo TEXT bar )", "OR NOT TEXT foo NOT TEXT bar" },
5c0034beb9933bca2a8b7d83d11dface1ea3b7faTimo Sirainen
5c0034beb9933bca2a8b7d83d11dface1ea3b7faTimo Sirainen { "ANSWERED FLAGGED SEEN", "(ANSWERED FLAGGED SEEN)" },
5c0034beb9933bca2a8b7d83d11dface1ea3b7faTimo Sirainen { "OR ( ANSWERED FLAGGED SEEN ) DRAFT", "OR (ANSWERED FLAGGED SEEN) DRAFT" },
5c0034beb9933bca2a8b7d83d11dface1ea3b7faTimo Sirainen { "ANSWERED TEXT foo FLAGGED SEEN", "(ANSWERED FLAGGED SEEN) TEXT foo" },
5c0034beb9933bca2a8b7d83d11dface1ea3b7faTimo Sirainen { "NOT ( ANSWERED FLAGGED SEEN )", "NOT (ANSWERED FLAGGED SEEN)" },
5c0034beb9933bca2a8b7d83d11dface1ea3b7faTimo Sirainen { "OR NOT ANSWERED OR NOT FLAGGED NOT SEEN", "NOT (ANSWERED FLAGGED SEEN)" },
5c0034beb9933bca2a8b7d83d11dface1ea3b7faTimo Sirainen { "OR NOT ANSWERED OR NOT FLAGGED SEEN", "OR NOT (ANSWERED FLAGGED) SEEN" },
5c0034beb9933bca2a8b7d83d11dface1ea3b7faTimo Sirainen { "OR NOT ANSWERED OR FLAGGED NOT SEEN", "OR NOT (ANSWERED SEEN) FLAGGED" },
5c0034beb9933bca2a8b7d83d11dface1ea3b7faTimo Sirainen { "NOT ANSWERED OR FLAGGED NOT SEEN", "NOT ANSWERED OR FLAGGED NOT SEEN" },
9bf2dc275ec21bff3d468ab1bc4fddc8874f7d1bTimo Sirainen { "NOT ANSWERED OR NOT FLAGGED NOT SEEN", "NOT ANSWERED NOT (FLAGGED SEEN)" },
9bf2dc275ec21bff3d468ab1bc4fddc8874f7d1bTimo Sirainen { "ANSWERED NOT FLAGGED SEEN NOT DRAFT", "(ANSWERED SEEN) NOT FLAGGED NOT DRAFT" },
9bf2dc275ec21bff3d468ab1bc4fddc8874f7d1bTimo Sirainen { "OR NOT ANSWERED NOT SEEN", "NOT (ANSWERED SEEN)" },
9bf2dc275ec21bff3d468ab1bc4fddc8874f7d1bTimo Sirainen { "OR NOT ANSWERED OR NOT SEEN TEXT foo", "OR NOT (ANSWERED SEEN) TEXT foo" },
9bf2dc275ec21bff3d468ab1bc4fddc8874f7d1bTimo Sirainen
9bf2dc275ec21bff3d468ab1bc4fddc8874f7d1bTimo Sirainen { "ANSWERED ANSWERED", "ANSWERED" },
9bf2dc275ec21bff3d468ab1bc4fddc8874f7d1bTimo Sirainen { "ANSWERED NOT ANSWERED", "NOT ALL" },
9bf2dc275ec21bff3d468ab1bc4fddc8874f7d1bTimo Sirainen { "ANSWERED ANSWERED NOT ANSWERED", "NOT ALL" },
9bf2dc275ec21bff3d468ab1bc4fddc8874f7d1bTimo Sirainen { "ANSWERED NOT ANSWERED ANSWERED NOT ANSWERED", "NOT ALL" },
9bf2dc275ec21bff3d468ab1bc4fddc8874f7d1bTimo Sirainen { "NOT ANSWERED NOT ANSWERED", "NOT ANSWERED" },
9bf2dc275ec21bff3d468ab1bc4fddc8874f7d1bTimo Sirainen { "NOT SEEN NOT ANSWERED NOT ANSWERED", "NOT SEEN NOT ANSWERED" },
9bf2dc275ec21bff3d468ab1bc4fddc8874f7d1bTimo Sirainen { "OR NOT SEEN OR NOT ANSWERED NOT ANSWERED", "NOT (ANSWERED SEEN)" },
9bf2dc275ec21bff3d468ab1bc4fddc8874f7d1bTimo Sirainen
9bf2dc275ec21bff3d468ab1bc4fddc8874f7d1bTimo Sirainen { "KEYWORD foo", "KEYWORD foo" },
9bf2dc275ec21bff3d468ab1bc4fddc8874f7d1bTimo Sirainen { "KEYWORD foo KEYWORD bar", "KEYWORD foo KEYWORD bar" },
9bf2dc275ec21bff3d468ab1bc4fddc8874f7d1bTimo Sirainen { "NOT KEYWORD foo", "NOT KEYWORD foo" },
9bf2dc275ec21bff3d468ab1bc4fddc8874f7d1bTimo Sirainen { "NOT KEYWORD foo NOT KEYWORD bar", "NOT KEYWORD foo NOT KEYWORD bar" },
9bf2dc275ec21bff3d468ab1bc4fddc8874f7d1bTimo Sirainen { "OR KEYWORD foo KEYWORD bar", "OR KEYWORD foo KEYWORD bar" },
008a83e9f680f04f69789fb702232416eab2a86cTimo Sirainen { "OR NOT KEYWORD foo NOT KEYWORD bar", "OR NOT KEYWORD foo NOT KEYWORD bar" },
008a83e9f680f04f69789fb702232416eab2a86cTimo Sirainen
008a83e9f680f04f69789fb702232416eab2a86cTimo Sirainen { "KEYWORD foo KEYWORD foo", "KEYWORD foo" },
008a83e9f680f04f69789fb702232416eab2a86cTimo Sirainen { "KEYWORD foo NOT KEYWORD foo", "NOT ALL" },
008a83e9f680f04f69789fb702232416eab2a86cTimo Sirainen { "OR KEYWORD foo NOT KEYWORD foo", "ALL" },
008a83e9f680f04f69789fb702232416eab2a86cTimo Sirainen { "OR KEYWORD foo KEYWORD foo", "KEYWORD foo" },
008a83e9f680f04f69789fb702232416eab2a86cTimo Sirainen { "NOT KEYWORD foo NOT KEYWORD foo", "NOT KEYWORD foo" },
008a83e9f680f04f69789fb702232416eab2a86cTimo Sirainen
008a83e9f680f04f69789fb702232416eab2a86cTimo Sirainen { "1:* 1:*", "ALL" },
008a83e9f680f04f69789fb702232416eab2a86cTimo Sirainen { "OR 1:5 6:*", "ALL" },
008a83e9f680f04f69789fb702232416eab2a86cTimo Sirainen
008a83e9f680f04f69789fb702232416eab2a86cTimo Sirainen { "UID 1:* UID 1:*", "ALL" },
008a83e9f680f04f69789fb702232416eab2a86cTimo Sirainen { "OR UID 1:5 UID 6:*", "ALL" },
008a83e9f680f04f69789fb702232416eab2a86cTimo Sirainen
008a83e9f680f04f69789fb702232416eab2a86cTimo Sirainen { "2:* 2:*", "2:4294967295" },
008a83e9f680f04f69789fb702232416eab2a86cTimo Sirainen { "OR 2:* 2:*", "2:4294967295" },
008a83e9f680f04f69789fb702232416eab2a86cTimo Sirainen
008a83e9f680f04f69789fb702232416eab2a86cTimo Sirainen { "UID 2:* UID 2:*", "UID 2:4294967295" },
008a83e9f680f04f69789fb702232416eab2a86cTimo Sirainen { "OR UID 2:* UID 2:*", "UID 2:4294967295" },
008a83e9f680f04f69789fb702232416eab2a86cTimo Sirainen
008a83e9f680f04f69789fb702232416eab2a86cTimo Sirainen { "1:5 6:7", "NOT ALL" },
008a83e9f680f04f69789fb702232416eab2a86cTimo Sirainen { "1:5 3:7", "3:5" },
008a83e9f680f04f69789fb702232416eab2a86cTimo Sirainen { "1:5 3:7 4:9", "4:5" },
008a83e9f680f04f69789fb702232416eab2a86cTimo Sirainen { "1:5 OR 3:4 4:6", "3:5" },
008a83e9f680f04f69789fb702232416eab2a86cTimo Sirainen { "OR 1 2", "1:2" },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "NOT 1,3:5", "2,6:4294967294" },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "NOT 1:100 NOT 50:200", "201:4294967294" },
9d3ccd79130199ffdb19a688027d49bf20a4aaaaTimo Sirainen { "OR NOT 1:100 NOT 50:200", "1:49,101:4294967294" },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "UID 1:5 UID 6:7", "NOT ALL" },
8d6cb44a0161d88743756733f83c4fb278485987Timo Sirainen { "UID 1:5 UID 3:7", "UID 3:5" },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "OR UID 1 UID 2", "UID 1:2" },
be889d9b142fbb5604a922c6955bd7f6ea32f163Timo Sirainen { "NOT UID 1,3:5", "UID 2,6:4294967294" },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "1:5 UID 10:20", "1:5 UID 10:20" },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "1:5 NOT UID 10:20", "1:5 UID 1:9,21:4294967294" },
3ccab0bac68040f179a7de45c516cec258e28fdbTimo Sirainen
3ccab0bac68040f179a7de45c516cec258e28fdbTimo Sirainen { "ALL NOT UID 3:*", "NOT UID 3:4294967295" },
3ccab0bac68040f179a7de45c516cec258e28fdbTimo Sirainen { "NOT 1:10 NOT *", "11:4294967294 NOT 4294967295" },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "BEFORE 03-Aug-2014 BEFORE 01-Aug-2014 BEFORE 02-Aug-2014", "BEFORE \"01-Aug-2014\"" },
008a83e9f680f04f69789fb702232416eab2a86cTimo Sirainen { "OR BEFORE 01-Aug-2014 BEFORE 02-Aug-2014", "BEFORE \"02-Aug-2014\"" },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "OR BEFORE 01-Aug-2014 OR BEFORE 03-Aug-2014 BEFORE 02-Aug-2014", "BEFORE \"03-Aug-2014\"" },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "BEFORE 03-Aug-2014 NOT BEFORE 01-Aug-2014 BEFORE 02-Aug-2014", "BEFORE \"02-Aug-2014\" NOT BEFORE \"01-Aug-2014\"" },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "SENTBEFORE 03-Aug-2014 SENTBEFORE 01-Aug-2014 SENTBEFORE 02-Aug-2014", "SENTBEFORE \"01-Aug-2014\"" },
be889d9b142fbb5604a922c6955bd7f6ea32f163Timo Sirainen { "SENTBEFORE 03-Aug-2014 BEFORE 01-Aug-2014 SENTBEFORE 02-Aug-2014", "SENTBEFORE \"02-Aug-2014\" BEFORE \"01-Aug-2014\"" },
be889d9b142fbb5604a922c6955bd7f6ea32f163Timo Sirainen
be889d9b142fbb5604a922c6955bd7f6ea32f163Timo Sirainen { "ON 03-Aug-2014 ON 03-Aug-2014", "ON \"03-Aug-2014\"" },
be889d9b142fbb5604a922c6955bd7f6ea32f163Timo Sirainen { "ON 03-Aug-2014 ON 04-Aug-2014", "ON \"03-Aug-2014\" ON \"04-Aug-2014\"" }, /* this could be replaced with e.g. NOT ALL */
be889d9b142fbb5604a922c6955bd7f6ea32f163Timo Sirainen { "OR ON 03-Aug-2014 ON 04-Aug-2014", "OR ON \"03-Aug-2014\" ON \"04-Aug-2014\"" },
be889d9b142fbb5604a922c6955bd7f6ea32f163Timo Sirainen
be889d9b142fbb5604a922c6955bd7f6ea32f163Timo Sirainen { "SINCE 03-Aug-2014 SINCE 01-Aug-2014 SINCE 02-Aug-2014", "SINCE \"03-Aug-2014\"" },
be889d9b142fbb5604a922c6955bd7f6ea32f163Timo Sirainen { "OR SINCE 01-Aug-2014 SINCE 02-Aug-2014", "SINCE \"01-Aug-2014\"" },
be889d9b142fbb5604a922c6955bd7f6ea32f163Timo Sirainen { "OR SINCE 01-Aug-2014 OR SINCE 03-Aug-2014 SINCE 02-Aug-2014", "SINCE \"01-Aug-2014\"" },
be889d9b142fbb5604a922c6955bd7f6ea32f163Timo Sirainen { "SINCE 03-Aug-2014 NOT SINCE 01-Aug-2014 SINCE 02-Aug-2014", "SINCE \"03-Aug-2014\" NOT SINCE \"01-Aug-2014\"" },
be889d9b142fbb5604a922c6955bd7f6ea32f163Timo Sirainen { "SENTSINCE 03-Aug-2014 SENTSINCE 01-Aug-2014 SENTSINCE 02-Aug-2014", "SENTSINCE \"03-Aug-2014\"" },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "SENTSINCE 03-Aug-2014 SINCE 01-Aug-2014 SENTSINCE 02-Aug-2014", "SENTSINCE \"03-Aug-2014\" SINCE \"01-Aug-2014\"" },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "SMALLER 1 SMALLER 2", "SMALLER 1" },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "OR SMALLER 1 SMALLER 2", "SMALLER 2" },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "OR SMALLER 1 OR SMALLER 3 SMALLER 2", "SMALLER 3" },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "SMALLER 3 NOT SMALLER 1 SMALLER 2", "SMALLER 2 NOT SMALLER 1" },
0cea9b1f4fa0495a48f5f097e40492517d67e1baTimo Sirainen { "SMALLER 3 LARGER 5", "SMALLER 3 LARGER 5" }, /* this could be replaced with e.g. NOT ALL */
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "OR SMALLER 3 LARGER 5", "OR SMALLER 3 LARGER 5" },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "LARGER 3 LARGER 1 LARGER 2", "LARGER 3" },
0cea9b1f4fa0495a48f5f097e40492517d67e1baTimo Sirainen { "OR LARGER 1 LARGER 2", "LARGER 1" },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "OR LARGER 1 OR LARGER 3 LARGER 2", "LARGER 1" },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "LARGER 3 NOT LARGER 1 LARGER 2", "LARGER 3 NOT LARGER 1" },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "SUBJECT foo SUBJECT foo", "SUBJECT foo" },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "SUBJECT foo NOT SUBJECT foo", "NOT ALL" },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "OR SUBJECT foo NOT SUBJECT foo", "ALL" },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "SUBJECT foo SUBJECT foob", "SUBJECT foo SUBJECT foob" },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "OR SUBJECT foo SUBJECT foo", "SUBJECT foo" },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "FROM foo FROM foo", "FROM foo" },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "FROM foo NOT FROM foo", "NOT ALL" },
8d6cb44a0161d88743756733f83c4fb278485987Timo Sirainen { "OR FROM foo NOT FROM foo", "ALL" },
4bbee99b3aef449a9a2a11a5b5cf1ca486915c49Timo Sirainen { "FROM foo FROM bar", "FROM foo FROM bar" },
8d6cb44a0161d88743756733f83c4fb278485987Timo Sirainen { "FROM foo TO foo", "FROM foo TO foo" },
008a83e9f680f04f69789fb702232416eab2a86cTimo Sirainen
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "TEXT foo TEXT foo", "TEXT foo" },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "TEXT foo TEXT foob", "TEXT foo TEXT foob" },
9bf2dc275ec21bff3d468ab1bc4fddc8874f7d1bTimo Sirainen { "OR TEXT foo TEXT foo", "TEXT foo" },
4bbee99b3aef449a9a2a11a5b5cf1ca486915c49Timo Sirainen { "OR NOT TEXT foo TEXT foo", "ALL" },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "OR TEXT foo NOT TEXT foo", "ALL" },
3ccab0bac68040f179a7de45c516cec258e28fdbTimo Sirainen { "TEXT foo NOT TEXT foo", "NOT ALL" },
3ccab0bac68040f179a7de45c516cec258e28fdbTimo Sirainen { "NOT TEXT foo TEXT foo", "NOT ALL" },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "BODY foo BODY foo", "BODY foo" },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "BODY foo NOT BODY foo", "NOT ALL" },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "OR BODY foo NOT BODY foo", "ALL" },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "OR BODY foo BODY foo", "BODY foo" },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "TEXT foo BODY foo", "TEXT foo BODY foo" },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "OR ( TEXT foo OR TEXT foo TEXT foo ) ( TEXT foo ( TEXT foo ) )", "TEXT foo" },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen /* value="" tests */
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "HEADER foo ", "HEADER FOO \"\"" },
3ccab0bac68040f179a7de45c516cec258e28fdbTimo Sirainen { "SUBJECT ", "SUBJECT \"\"" },
3ccab0bac68040f179a7de45c516cec258e28fdbTimo Sirainen { "BODY ", "ALL" },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "TEXT ", "ALL" },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "HEADER foo .", "HEADER FOO ." },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "SUBJECT .", "SUBJECT ." },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "BODY .", "BODY ." },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "TEXT .", "TEXT ." },
e2e105f6182f550efa82f77d2a46b3e8a2d4da10Timo Sirainen
e2e105f6182f550efa82f77d2a46b3e8a2d4da10Timo Sirainen /* OR: drop redundant args */
e2e105f6182f550efa82f77d2a46b3e8a2d4da10Timo Sirainen { "OR ( TEXT common1 TEXT unique1 ) TEXT common1", "TEXT common1" },
e2e105f6182f550efa82f77d2a46b3e8a2d4da10Timo Sirainen { "OR ( TEXT unique1 TEXT common1 ) TEXT common1", "TEXT common1" },
e2e105f6182f550efa82f77d2a46b3e8a2d4da10Timo Sirainen { "OR TEXT common1 ( TEXT common1 TEXT unique1 )", "TEXT common1" },
e2e105f6182f550efa82f77d2a46b3e8a2d4da10Timo Sirainen { "OR TEXT common1 ( TEXT unique1 TEXT common1 )", "TEXT common1" },
e2e105f6182f550efa82f77d2a46b3e8a2d4da10Timo Sirainen { "OR ( TEXT common1 TEXT common2 ) ( TEXT common1 TEXT common2 TEXT unique1 )", "TEXT common1 TEXT common2" },
e2e105f6182f550efa82f77d2a46b3e8a2d4da10Timo Sirainen { "OR TEXT common1 OR ( TEXT unique1 TEXT common1 ) ( TEXT unique3 TEXT common1 )", "TEXT common1" },
16598a1fb870ae40d6177755a4306216e4d6a4cdTimo Sirainen
16598a1fb870ae40d6177755a4306216e4d6a4cdTimo Sirainen /* OR: extract common AND */
16598a1fb870ae40d6177755a4306216e4d6a4cdTimo Sirainen { "OR ( TEXT common1 TEXT unique1 ) ( TEXT common1 TEXT unique2 )", "OR TEXT unique1 TEXT unique2 TEXT common1" },
16598a1fb870ae40d6177755a4306216e4d6a4cdTimo Sirainen { "OR ( TEXT unique1 TEXT common1 ) ( TEXT unique2 TEXT common1 )", "OR TEXT unique1 TEXT unique2 TEXT common1" },
16598a1fb870ae40d6177755a4306216e4d6a4cdTimo Sirainen { "OR ( TEXT common1 TEXT unique1 ) ( TEXT unique2 TEXT common1 )", "OR TEXT unique1 TEXT unique2 TEXT common1" },
16598a1fb870ae40d6177755a4306216e4d6a4cdTimo Sirainen { "OR ( TEXT unique1 TEXT common1 ) ( TEXT common1 TEXT unique2 )", "OR TEXT unique1 TEXT unique2 TEXT common1" },
16598a1fb870ae40d6177755a4306216e4d6a4cdTimo Sirainen
bc793bfcee945ce8871edfa298fe7235744425b6Timo Sirainen { "OR ( TEXT unique1 TEXT common1 ) ( TEXT common1 TEXT unique2 TEXT unique3 )", "OR TEXT unique1 (TEXT unique2 TEXT unique3) TEXT common1" },
bc793bfcee945ce8871edfa298fe7235744425b6Timo Sirainen { "OR ( TEXT common1 TEXT common2 TEXT unique1 ) ( TEXT common1 TEXT common2 TEXT unique2 )", "OR TEXT unique1 TEXT unique2 TEXT common2 TEXT common1" },
bc793bfcee945ce8871edfa298fe7235744425b6Timo Sirainen { "OR ( TEXT common1 TEXT common2 TEXT unique1 TEXT unique2 ) ( TEXT common1 TEXT common2 TEXT unique3 TEXT unique4 )", "OR (TEXT unique1 TEXT unique2) (TEXT unique3 TEXT unique4) TEXT common2 TEXT common1" },
32c24eab7111799d880139634144ba8aea5a666eTimo Sirainen
32c24eab7111799d880139634144ba8aea5a666eTimo Sirainen /* non-matching cases */
ea4ca37ec14913354f3a0deebc0df96097eb9468Timo Sirainen { "OR ( TEXT unique1 TEXT unique2 ) TEXT unique3", "OR (TEXT unique1 TEXT unique2) TEXT unique3" },
16598a1fb870ae40d6177755a4306216e4d6a4cdTimo Sirainen { "OR ( TEXT unique1 TEXT unique2 ) ( TEXT unique3 TEXT unique4 )", "OR (TEXT unique1 TEXT unique2) (TEXT unique3 TEXT unique4)" },
ea4ca37ec14913354f3a0deebc0df96097eb9468Timo Sirainen { "OR ( TEXT common1 TEXT unique1 ) OR ( TEXT common1 TEXT unique2 ) TEXT unique3", "OR (TEXT common1 TEXT unique1) OR (TEXT common1 TEXT unique2) TEXT unique3" },
ea4ca37ec14913354f3a0deebc0df96097eb9468Timo Sirainen { "OR ( TEXT common1 TEXT unique1 ) OR ( TEXT common1 TEXT common2 ) ( TEXT common2 TEXT unique2 )", "OR (TEXT common1 TEXT unique1) OR (TEXT common1 TEXT common2) (TEXT common2 TEXT unique2)" },
16598a1fb870ae40d6177755a4306216e4d6a4cdTimo Sirainen
16598a1fb870ae40d6177755a4306216e4d6a4cdTimo Sirainen /* SUB: drop redundant args */
16598a1fb870ae40d6177755a4306216e4d6a4cdTimo Sirainen { "( OR TEXT common1 TEXT unique1 ) TEXT common1", "TEXT common1" },
16598a1fb870ae40d6177755a4306216e4d6a4cdTimo Sirainen { "( OR TEXT unique1 TEXT common1 ) TEXT common1", "TEXT common1" },
16598a1fb870ae40d6177755a4306216e4d6a4cdTimo Sirainen { "TEXT common1 ( OR TEXT common1 TEXT unique1 )", "TEXT common1" },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "TEXT common1 ( OR TEXT unique1 TEXT common1 )", "TEXT common1" },
8b681dae1e8fa564649e703ab17398dcfaf896e4Timo Sirainen { "( OR TEXT common1 TEXT common2 ) ( OR TEXT common1 OR TEXT common2 TEXT unique1 )", "OR TEXT common1 TEXT common2" },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "TEXT common1 ( OR TEXT unique1 TEXT common1 ) ( OR TEXT unique3 TEXT common1 )", "TEXT common1" },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "OR ( TEXT common1 ( OR TEXT unique1 TEXT common1 ) ) TEXT unique1", "OR TEXT common1 TEXT unique1" },
8b681dae1e8fa564649e703ab17398dcfaf896e4Timo Sirainen
6e235046e1d8e9d89fc948f5c623676c20421a28Timo Sirainen /* SUB: extract common OR */
abb83d133dd082527d500916fca66a72fbbbaa8dTimo Sirainen { "( OR TEXT common1 TEXT unique1 ) ( OR TEXT common1 TEXT unique2 )", "OR (TEXT unique1 TEXT unique2) TEXT common1" },
e4423c16a4f798ecf75ca2b0c3ef834000faed4bTimo Sirainen { "( OR TEXT unique1 TEXT common1 ) ( OR TEXT unique2 TEXT common1 )", "OR (TEXT unique1 TEXT unique2) TEXT common1" },
8b681dae1e8fa564649e703ab17398dcfaf896e4Timo Sirainen { "( OR TEXT common1 TEXT unique1 ) ( OR TEXT unique2 TEXT common1 )", "OR (TEXT unique1 TEXT unique2) TEXT common1" },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "( OR TEXT unique1 TEXT common1 ) ( OR TEXT common1 TEXT unique2 )", "OR (TEXT unique1 TEXT unique2) TEXT common1" },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "( OR TEXT unique1 TEXT common1 ) ( OR TEXT common1 OR TEXT unique2 TEXT unique3 )", "OR (TEXT unique1 OR TEXT unique2 TEXT unique3) TEXT common1" },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "( OR TEXT common1 OR TEXT common2 TEXT unique1 ) ( OR TEXT common1 OR TEXT common2 TEXT unique2 )", "OR (TEXT unique1 TEXT unique2) OR TEXT common2 TEXT common1" },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "( OR TEXT common1 OR TEXT common2 OR TEXT unique1 TEXT unique2 ) ( OR TEXT common1 OR TEXT common2 OR TEXT unique3 TEXT unique4 )", "OR (OR TEXT unique1 TEXT unique2 OR TEXT unique3 TEXT unique4) OR TEXT common2 TEXT common1" },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen /* non-matching cases */
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen { "( OR TEXT unique1 TEXT unique2 ) TEXT unique3", "OR TEXT unique1 TEXT unique2 TEXT unique3" },
6e235046e1d8e9d89fc948f5c623676c20421a28Timo Sirainen { "( OR TEXT unique1 TEXT unique2 ) ( OR TEXT unique3 TEXT unique4 )", "OR TEXT unique1 TEXT unique2 OR TEXT unique3 TEXT unique4" },
6e235046e1d8e9d89fc948f5c623676c20421a28Timo Sirainen { "( OR TEXT common1 TEXT unique1 ) ( OR TEXT common1 TEXT unique2 ) TEXT unique3", "OR TEXT common1 TEXT unique1 OR TEXT common1 TEXT unique2 TEXT unique3" },
44ff75ca53188056ff5a3e50428e3f2078800b3cTimo Sirainen { "( OR TEXT common1 TEXT unique1 ) ( OR TEXT common1 TEXT common2 ) ( OR TEXT common2 TEXT unique2 )", "OR TEXT common1 TEXT unique1 OR TEXT common1 TEXT common2 OR TEXT common2 TEXT unique2" },
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen};
4bbee99b3aef449a9a2a11a5b5cf1ca486915c49Timo Sirainen
4bbee99b3aef449a9a2a11a5b5cf1ca486915c49Timo Sirainenstatic struct mail_search_args *
4bbee99b3aef449a9a2a11a5b5cf1ca486915c49Timo Sirainentest_build_search_args(const char *args)
4bbee99b3aef449a9a2a11a5b5cf1ca486915c49Timo Sirainen{
4bbee99b3aef449a9a2a11a5b5cf1ca486915c49Timo Sirainen struct mail_search_parser *parser;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen struct mail_search_args *sargs;
e4423c16a4f798ecf75ca2b0c3ef834000faed4bTimo Sirainen const char *error, *charset = "UTF-8";
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen
8b681dae1e8fa564649e703ab17398dcfaf896e4Timo Sirainen parser = mail_search_parser_init_cmdline(t_strsplit(args, " "));
8b681dae1e8fa564649e703ab17398dcfaf896e4Timo Sirainen if (mail_search_build(mail_search_register_get_imap(),
8b681dae1e8fa564649e703ab17398dcfaf896e4Timo Sirainen parser, &charset, &sargs, &error) < 0)
8b681dae1e8fa564649e703ab17398dcfaf896e4Timo Sirainen i_panic("%s", error);
73b251f13abfbd8e06c8c78784eb570d28fe7e40Timo Sirainen mail_search_parser_deinit(&parser);
73b251f13abfbd8e06c8c78784eb570d28fe7e40Timo Sirainen return sargs;
73b251f13abfbd8e06c8c78784eb570d28fe7e40Timo Sirainen}
73b251f13abfbd8e06c8c78784eb570d28fe7e40Timo Sirainen
73b251f13abfbd8e06c8c78784eb570d28fe7e40Timo Sirainenstatic bool test_search_args_are_initialized(struct mail_search_arg *arg)
c4cfee078c4a185b5ba8f0c55f51275b7e885b2cTimo Sirainen{
8b681dae1e8fa564649e703ab17398dcfaf896e4Timo Sirainen for (; arg != NULL; arg = arg->next) {
8b681dae1e8fa564649e703ab17398dcfaf896e4Timo Sirainen switch (arg->type) {
8b681dae1e8fa564649e703ab17398dcfaf896e4Timo Sirainen case SEARCH_MODSEQ:
8b681dae1e8fa564649e703ab17398dcfaf896e4Timo Sirainen if (arg->value.str != NULL &&
8b681dae1e8fa564649e703ab17398dcfaf896e4Timo Sirainen arg->initialized.keywords == NULL)
8b681dae1e8fa564649e703ab17398dcfaf896e4Timo Sirainen return FALSE;
8b681dae1e8fa564649e703ab17398dcfaf896e4Timo Sirainen break;
8b681dae1e8fa564649e703ab17398dcfaf896e4Timo Sirainen case SEARCH_KEYWORDS:
8b681dae1e8fa564649e703ab17398dcfaf896e4Timo Sirainen if (arg->initialized.keywords == NULL)
8b681dae1e8fa564649e703ab17398dcfaf896e4Timo Sirainen return FALSE;
8b681dae1e8fa564649e703ab17398dcfaf896e4Timo Sirainen break;
8b681dae1e8fa564649e703ab17398dcfaf896e4Timo Sirainen case SEARCH_MAILBOX_GLOB:
8b681dae1e8fa564649e703ab17398dcfaf896e4Timo Sirainen if (arg->initialized.mailbox_glob == NULL)
73b251f13abfbd8e06c8c78784eb570d28fe7e40Timo Sirainen return FALSE;
8b681dae1e8fa564649e703ab17398dcfaf896e4Timo Sirainen break;
8b681dae1e8fa564649e703ab17398dcfaf896e4Timo Sirainen case SEARCH_INTHREAD:
8b681dae1e8fa564649e703ab17398dcfaf896e4Timo Sirainen case SEARCH_SUB:
114a0f74e0f825c6bd8aeadfafb248a030762a1fTimo Sirainen case SEARCH_OR:
c4cfee078c4a185b5ba8f0c55f51275b7e885b2cTimo Sirainen if (!test_search_args_are_initialized(arg->value.subargs))
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen return FALSE;
44ff75ca53188056ff5a3e50428e3f2078800b3cTimo Sirainen break;
abb83d133dd082527d500916fca66a72fbbbaa8dTimo Sirainen default:
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen break;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen }
6e235046e1d8e9d89fc948f5c623676c20421a28Timo Sirainen }
6e235046e1d8e9d89fc948f5c623676c20421a28Timo Sirainen return TRUE;
6e235046e1d8e9d89fc948f5c623676c20421a28Timo Sirainen}
6e235046e1d8e9d89fc948f5c623676c20421a28Timo Sirainen
6e235046e1d8e9d89fc948f5c623676c20421a28Timo Sirainenstatic void test_mail_search_args_simplify(void)
6e235046e1d8e9d89fc948f5c623676c20421a28Timo Sirainen{
abb83d133dd082527d500916fca66a72fbbbaa8dTimo Sirainen struct mail_search_args *args;
abb83d133dd082527d500916fca66a72fbbbaa8dTimo Sirainen struct mail_storage_settings set = { .mail_max_keyword_length = 100 };
abb83d133dd082527d500916fca66a72fbbbaa8dTimo Sirainen struct mail_storage storage = { .set = &set };
8b681dae1e8fa564649e703ab17398dcfaf896e4Timo Sirainen struct mailbox box = { .opened = TRUE, .storage = &storage };
e4423c16a4f798ecf75ca2b0c3ef834000faed4bTimo Sirainen string_t *str = t_str_new(256);
e4423c16a4f798ecf75ca2b0c3ef834000faed4bTimo Sirainen const char *error;
e4423c16a4f798ecf75ca2b0c3ef834000faed4bTimo Sirainen unsigned int i;
e4423c16a4f798ecf75ca2b0c3ef834000faed4bTimo Sirainen
8b681dae1e8fa564649e703ab17398dcfaf896e4Timo Sirainen test_begin("mail search args simplify");
8b681dae1e8fa564649e703ab17398dcfaf896e4Timo Sirainen box.index = mail_index_alloc(NULL, "dovecot.index.");
8b681dae1e8fa564649e703ab17398dcfaf896e4Timo Sirainen for (i = 0; i < N_ELEMENTS(tests); i++) {
8b681dae1e8fa564649e703ab17398dcfaf896e4Timo Sirainen args = test_build_search_args(tests[i].input);
8b681dae1e8fa564649e703ab17398dcfaf896e4Timo Sirainen /* delay simplification until after init. that way we can test
8b681dae1e8fa564649e703ab17398dcfaf896e4Timo Sirainen that the simplification works correctly when working on
8b681dae1e8fa564649e703ab17398dcfaf896e4Timo Sirainen already-initialized args. */
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen args->simplified = TRUE;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen mail_search_args_init(args, &box, FALSE, NULL);
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen mail_search_args_simplify(args);
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen str_truncate(str, 0);
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen test_assert(mail_search_args_to_imap(str, args->args, &error));
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen test_assert_idx(strcmp(str_c(str), tests[i].output) == 0, i);
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen test_assert_idx(test_search_args_are_initialized(args->args), i);
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen mail_search_args_unref(&args);
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen }
4bbee99b3aef449a9a2a11a5b5cf1ca486915c49Timo Sirainen mail_index_free(&box.index);
a04b6515c20b431294626400e173d81f3d25889bTimo Sirainen test_end();
2bfc60a0c890585f1c9d75d721dc78d86d65f6caTimo Sirainen}
9a583c7a827f7a4d89ee43774f2d51ea6a214543Timo Sirainen
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainenstatic void test_mail_search_args_simplify_empty_lists(void)
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen{
8b681dae1e8fa564649e703ab17398dcfaf896e4Timo Sirainen struct mail_search_args *args;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen test_begin("mail search args simplify empty args");
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen args = mail_search_build_init();
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen mail_search_args_simplify(args);
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen mail_search_args_unref(&args);
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen test_end();
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen}
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainenint main(void)
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen{
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen static void (*const test_functions[])(void) = {
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen mail_storage_init,
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen test_mail_search_args_simplify,
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen test_mail_search_args_simplify_empty_lists,
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen mail_storage_deinit,
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen NULL
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen };
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen return test_run(test_functions);
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen}
1098fc409a45e7603701dc94635927a673bee0c1Timo Sirainen