unofficial mirror of notmuch@notmuchmail.org
 help / color / mirror / code / Atom feed
* [PATCH] Modularize test suite
@ 2010-04-30 18:36 Jesse Rosenthal
  2010-04-30 18:52 ` Jesse Rosenthal
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Jesse Rosenthal @ 2010-04-30 18:36 UTC (permalink / raw)
  To: Notmuch developer list

Responding to this email is a patch to modularize the test suite. It
follows a relatively simple model, but it does seem like it will offer
some degree of flexibility. Plus, no relicensing is necessary.

In short, tests are put in subdirs of test/tests, e.g.:

     test/tests/notmuch-new/
     test/tests/notmuch-search/
     test/tests/json/
     ...

"notmuch-test" (which is the same as "notmuch-test all") should work as
usual. But if you call "notmuch-test json", it will only the json tests.

It will do this by running all of the files in the json subdir that have
an extension "*.test" or "*.setup" (all other files will be ignored). It
runs them in numerical order, which you can set by a numerical
prefix. So, for example, in test/tests/notmuch-reply:

         00001-notmuch-reply.setup
         00100-basic-reply.test          
         00200-multiple-recipients.test  
         00300-reply-with-cc.test        
         00400-reply-from-alternate-address.test
         00500-support-for-reply-to.test
         00600-unmunging-reply-to.test
         99999-notmuch-reply.setup

The basic numbering system is 00100, 00200, etc. to both allow a lot of
space to fit things in between, and to let the collection of tests
grow. 

00001-$(basename $(pwd)).setup and 99999-$(basename $(pwd)).setup are
reserved for setting up and cleaning up. This allows us to call
individual sets of tests without calling the entire suite in order to
get the environment that the tests expect.

Note that if you add a new subdir collection of tests, you have to add
it to the $TEST_COLLECTIONS variable in notmuch-test. It doesn't run all
subdirs automatically, in case you want to test something out, or have a
subdir that only works in certain cases (imagine future tests of remote
setups).

Sorry the patch is so large: there was a lot of back-and-forth, and it
was hard to break the patches down into coherent steps. Carl, if you'd
prefer, I could send you a more granular, but confusing, series of
patches.

Best,
Jesse

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] Modularize test suite
  2010-04-30 18:36 [PATCH] Modularize test suite Jesse Rosenthal
@ 2010-04-30 18:52 ` Jesse Rosenthal
  2010-04-30 19:07 ` [PATCH 1/2] test: add modular test collections Jesse Rosenthal
  2010-05-05  7:23 ` [PATCH] Modularize test suite Michal Sojka
  2 siblings, 0 replies; 8+ messages in thread
From: Jesse Rosenthal @ 2010-04-30 18:52 UTC (permalink / raw)
  To: Notmuch developer list

On Fri, 30 Apr 2010 14:36:56 -0400, Jesse Rosenthal <jrosenthal@jhu.edu> wrote:
> Sorry the patch is so large: there was a lot of back-and-forth, and it
> was hard to break the patches down into coherent steps. Carl, if you'd
> prefer, I could send you a more granular, but confusing, series of
> patches.

Actually, due the listing of new files in the patch, the patch was so
large that it got bounced pending moderation (13K, with a 12K
limit). It's not actually as complicated as this size would make seem --
mainly just a lot of moving lines to individual files. Since I'm not
sure who the mod is, I'll take this as a sign that I should try to break
it down into smaller patches.

Sorry for the delay.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/2] test: add modular test collections
  2010-04-30 18:36 [PATCH] Modularize test suite Jesse Rosenthal
  2010-04-30 18:52 ` Jesse Rosenthal
@ 2010-04-30 19:07 ` Jesse Rosenthal
  2010-04-30 19:09   ` [PATCH 2/2] test: Have notmuch-test use the " Jesse Rosenthal
  2010-05-05  7:23 ` [PATCH] Modularize test suite Michal Sojka
  2 siblings, 1 reply; 8+ messages in thread
From: Jesse Rosenthal @ 2010-04-30 19:07 UTC (permalink / raw)
  To: Notmuch developer list

For the sake of modularization, add modular test collections. Each
collection is a subdir of test/tests. With each dir is a series of files
with the prefix "*.test" or "*.setup". The command "notmuch-test X" will
run all of the files test and setup files in X, in numerical order (as
determined by their numerical prefix).

*.test files are the actual tests, while *.setup files are used to change
to the state that the tests expect.

00001-$(basename $(pwd)).setup and 99999-$(basename $(pwd)).setup are
reserved for setting up for the collection and cleaning up after it. In
the original monolithic test suite, certain tests required a certain state
at their startup. By setting up and cleaning up for each test, we can
guarantee that they do not need to be run in a specific order.

The numbering system for all other tests is 00100, 00200, etc. This is
designed to allow for numerous tests to be added, or added between other
tests, while remaining consistent.
---
 .../00001-author-reordering.setup                  |    2 +
 .../author-reordering/00100-adding-parent-msg.test |    4 +
 .../00200-adding-initial-child-message.test        |    4 +
 .../00300-adding-second-child-msg.test             |    4 +
 .../00400-search-all-msgs-match.test               |    3 +
 .../00500-search-two-msgs-match.test               |    3 +
 .../00600-search-one-msg-matches.test              |    3 +
 .../00700-search-first-msg-matches.test            |    3 +
 .../99999-author-reordering.setup                  |    4 +
 .../00001-from-guessing-multiple.setup             |    2 +
 .../00100-nothing-to-go-on.test                    |   17 +++
 .../from-guessing-multiple/00200-envelope-to.test  |   18 +++
 .../00300-x-original-to.test                       |   18 +++
 .../from-guessing-multiple/00400-received-for.test |   20 +++
 .../00500-received-doman.test                      |   20 +++
 .../99999-from-guessing-multiple.setup             |    4 +
 .../00001-from-guessing-single.setup               |    4 +
 .../00100-nothing-to-go-on.test                    |   17 +++
 .../from-guessing-single/00200-envelope-to.test    |   18 +++
 .../from-guessing-single/00300-x-original-to.test  |   18 +++
 .../from-guessing-single/00400-received-for.test   |   20 +++
 .../from-guessing-single/00500-received-doman.test |   20 +++
 .../99999-from-guessing-single.setup               |   14 ++
 test/tests/json/00001-json.setup                   |    2 +
 test/tests/json/00100-show-message-json.test       |    4 +
 test/tests/json/00200-search-message-json.test     |   10 ++
 test/tests/json/00300-search-by-subject-utf8.test  |    4 +
 test/tests/json/00400-show-message-json-utf8.test  |    4 +
 .../tests/json/00500-search-message-json-utf8.test |   10 ++
 test/tests/json/99999-json.setup                   |    4 +
 .../00001-notmuch-dump-restore.setup               |    2 +
 .../00100-dumping-all-tags.test                    |    3 +
 .../00200-clearing-all-tags.test                   |    5 +
 .../00300-restoring-original-tags.test             |    4 +
 .../00400-restore-with-nothing.test                |    3 +
 .../99999-notmuch-dump-restore.setup               |    4 +
 test/tests/notmuch-new/00001-notmuch-new.setup     |    2 +
 test/tests/notmuch-new/00100-no-new-mail.test      |    3 +
 test/tests/notmuch-new/00200-one-new-message.test  |    4 +
 .../notmuch-new/00300-multiple-new-messages.test   |    5 +
 test/tests/notmuch-new/00400-non-empty-db.test     |    3 +
 test/tests/notmuch-new/00500-new-directories.test  |    8 +
 .../notmuch-new/00550-alternate-inode-order.test   |    9 ++
 test/tests/notmuch-new/00600-message-moved.test    |   12 ++
 test/tests/notmuch-new/00700-renamed-message.test  |    8 +
 test/tests/notmuch-new/00800-deleted-message.test  |    6 +
 .../tests/notmuch-new/00900-renamed-directory.test |   13 ++
 .../tests/notmuch-new/01000-deleted-directory.test |    7 +
 .../notmuch-new/01100-new-directory-end-list.test  |    8 +
 .../01200-deleted-directory-end-list.test          |    7 +
 .../notmuch-new/01300-new-symlink-to-dir.test      |   10 ++
 .../notmuch-new/01400-new-symlink-to-file.test     |    9 ++
 .../tests/notmuch-new/01500-new-two-level-dir.test |    8 +
 .../notmuch-new/01600-deleted-two-level-dir.test   |    7 +
 test/tests/notmuch-new/99999-notmuch-new.setup     |    4 +
 test/tests/notmuch-reply/00001-notmuch-reply.setup |    2 +
 test/tests/notmuch-reply/00100-basic-reply.test    |   17 +++
 .../notmuch-reply/00200-multiple-recipients.test   |   17 +++
 test/tests/notmuch-reply/00300-reply-with-cc.test  |   19 +++
 .../00400-reply-from-alternate-address.test        |   17 +++
 .../notmuch-reply/00500-support-for-reply-to.test  |   18 +++
 .../notmuch-reply/00600-unmunging-reply-to.test    |   18 +++
 test/tests/notmuch-reply/99999-notmuch-reply.setup |    4 +
 .../notmuch-search/00001-notmuch-search.setup      |  152 ++++++++++++++++++++
 test/tests/notmuch-search/00100-search-body.test   |    4 +
 .../tests/notmuch-search/00200-search-by-from.test |    4 +
 test/tests/notmuch-search/00300-search-by-to.test  |    4 +
 .../notmuch-search/00400-search-by-subject.test    |    4 +
 test/tests/notmuch-search/00500-search-by-id.test  |    4 +
 test/tests/notmuch-search/00600-search-by-tag.test |    5 +
 .../notmuch-search/00700-search-by-thread.test     |    5 +
 .../notmuch-search/00800-search-body-phrase.test   |    5 +
 .../00900-search-by-from-address.test              |    4 +
 .../notmuch-search/01000-search-by-from-name.test  |    4 +
 .../notmuch-search/01100-search-by-to-address.test |    4 +
 .../notmuch-search/01200-search-by-to-name.test    |    4 +
 .../01300-search-by-subject-phrase.test            |    5 +
 .../01400-search-for-all-messages.test             |   19 +++
 .../notmuch-search/01500-search-body-utf-8.test    |    4 +
 .../notmuch-search/99999-notmuch-search.setup      |    4 +
 .../00001-out-of-order-threading.setup             |    2 +
 .../00100-addinitial-child-message.test            |    4 +
 .../00200-searching-returns-message.test           |    3 +
 .../00300-adding-second-child-message.test         |    4 +
 .../00400-searching-returns-both-msgs.test         |    3 +
 .../00500-adding-parent-msg.test                   |    4 +
 .../00600-return-all-msgs-in-one-thread.test       |    3 +
 .../99999-out-of-order-threading.setup             |    4 +
 test/tests/thread-naming/00001-thread-naming.setup |   17 +++
 ...00-initial-thread-name-oldest-first-search.test |    3 +
 ...00-initial-thread-name-newest-first-search.test |    3 +
 ...00-changed-thread-name-oldest-first-search.test |    6 +
 ...00-changed-thread-name-newest-first-search.test |    3 +
 .../00500-ignore-added-reply-prefix-re.test        |    6 +
 .../00600-ignore-added-reply-prefix-aw.test        |    6 +
 .../00700-ignore-added-reply-prefix-vs.test        |    6 +
 .../00800-ignore-added-reply-prefix-sv.test        |    6 +
 .../00900-test-order-of-messages-in-nm-show.test   |  114 +++++++++++++++
 test/tests/thread-naming/99999-thread-naming.setup |    4 +
 test/tests/uuencoded/00001-uuencoded.setup         |   19 +++
 .../uuencoded/00100-index-content-before-uu.test   |    3 +
 test/tests/uuencoded/00200-dont-index-uu-data.test |    3 +
 .../tests/uuencoded/00300-index-data-after-uu.test |    3 +
 test/tests/uuencoded/99999-uuencoded.setup         |    4 +
 104 files changed, 1012 insertions(+), 0 deletions(-)
 create mode 100644 test/tests/author-reordering/00001-author-reordering.setup
 create mode 100644 test/tests/author-reordering/00100-adding-parent-msg.test
 create mode 100644 test/tests/author-reordering/00200-adding-initial-child-message.test
 create mode 100644 test/tests/author-reordering/00300-adding-second-child-msg.test
 create mode 100644 test/tests/author-reordering/00400-search-all-msgs-match.test
 create mode 100644 test/tests/author-reordering/00500-search-two-msgs-match.test
 create mode 100644 test/tests/author-reordering/00600-search-one-msg-matches.test
 create mode 100644 test/tests/author-reordering/00700-search-first-msg-matches.test
 create mode 100644 test/tests/author-reordering/99999-author-reordering.setup
 create mode 100644 test/tests/from-guessing-multiple/00001-from-guessing-multiple.setup
 create mode 100644 test/tests/from-guessing-multiple/00100-nothing-to-go-on.test
 create mode 100644 test/tests/from-guessing-multiple/00200-envelope-to.test
 create mode 100644 test/tests/from-guessing-multiple/00300-x-original-to.test
 create mode 100644 test/tests/from-guessing-multiple/00400-received-for.test
 create mode 100644 test/tests/from-guessing-multiple/00500-received-doman.test
 create mode 100644 test/tests/from-guessing-multiple/99999-from-guessing-multiple.setup
 create mode 100644 test/tests/from-guessing-single/00001-from-guessing-single.setup
 create mode 100644 test/tests/from-guessing-single/00100-nothing-to-go-on.test
 create mode 100644 test/tests/from-guessing-single/00200-envelope-to.test
 create mode 100644 test/tests/from-guessing-single/00300-x-original-to.test
 create mode 100644 test/tests/from-guessing-single/00400-received-for.test
 create mode 100644 test/tests/from-guessing-single/00500-received-doman.test
 create mode 100644 test/tests/from-guessing-single/99999-from-guessing-single.setup
 create mode 100644 test/tests/json/00001-json.setup
 create mode 100644 test/tests/json/00100-show-message-json.test
 create mode 100644 test/tests/json/00200-search-message-json.test
 create mode 100644 test/tests/json/00300-search-by-subject-utf8.test
 create mode 100644 test/tests/json/00400-show-message-json-utf8.test
 create mode 100644 test/tests/json/00500-search-message-json-utf8.test
 create mode 100644 test/tests/json/99999-json.setup
 create mode 100644 test/tests/notmuch-dump-restore/00001-notmuch-dump-restore.setup
 create mode 100644 test/tests/notmuch-dump-restore/00100-dumping-all-tags.test
 create mode 100644 test/tests/notmuch-dump-restore/00200-clearing-all-tags.test
 create mode 100644 test/tests/notmuch-dump-restore/00300-restoring-original-tags.test
 create mode 100644 test/tests/notmuch-dump-restore/00400-restore-with-nothing.test
 create mode 100644 test/tests/notmuch-dump-restore/99999-notmuch-dump-restore.setup
 create mode 100644 test/tests/notmuch-new/00001-notmuch-new.setup
 create mode 100644 test/tests/notmuch-new/00100-no-new-mail.test
 create mode 100644 test/tests/notmuch-new/00200-one-new-message.test
 create mode 100644 test/tests/notmuch-new/00300-multiple-new-messages.test
 create mode 100644 test/tests/notmuch-new/00400-non-empty-db.test
 create mode 100644 test/tests/notmuch-new/00500-new-directories.test
 create mode 100644 test/tests/notmuch-new/00550-alternate-inode-order.test
 create mode 100644 test/tests/notmuch-new/00600-message-moved.test
 create mode 100644 test/tests/notmuch-new/00700-renamed-message.test
 create mode 100644 test/tests/notmuch-new/00800-deleted-message.test
 create mode 100644 test/tests/notmuch-new/00900-renamed-directory.test
 create mode 100644 test/tests/notmuch-new/01000-deleted-directory.test
 create mode 100644 test/tests/notmuch-new/01100-new-directory-end-list.test
 create mode 100644 test/tests/notmuch-new/01200-deleted-directory-end-list.test
 create mode 100644 test/tests/notmuch-new/01300-new-symlink-to-dir.test
 create mode 100644 test/tests/notmuch-new/01400-new-symlink-to-file.test
 create mode 100644 test/tests/notmuch-new/01500-new-two-level-dir.test
 create mode 100644 test/tests/notmuch-new/01600-deleted-two-level-dir.test
 create mode 100644 test/tests/notmuch-new/99999-notmuch-new.setup
 create mode 100644 test/tests/notmuch-reply/00001-notmuch-reply.setup
 create mode 100644 test/tests/notmuch-reply/00100-basic-reply.test
 create mode 100644 test/tests/notmuch-reply/00200-multiple-recipients.test
 create mode 100644 test/tests/notmuch-reply/00300-reply-with-cc.test
 create mode 100644 test/tests/notmuch-reply/00400-reply-from-alternate-address.test
 create mode 100644 test/tests/notmuch-reply/00500-support-for-reply-to.test
 create mode 100644 test/tests/notmuch-reply/00600-unmunging-reply-to.test
 create mode 100644 test/tests/notmuch-reply/99999-notmuch-reply.setup
 create mode 100644 test/tests/notmuch-search/00001-notmuch-search.setup
 create mode 100644 test/tests/notmuch-search/00100-search-body.test
 create mode 100644 test/tests/notmuch-search/00200-search-by-from.test
 create mode 100644 test/tests/notmuch-search/00300-search-by-to.test
 create mode 100644 test/tests/notmuch-search/00400-search-by-subject.test
 create mode 100644 test/tests/notmuch-search/00500-search-by-id.test
 create mode 100644 test/tests/notmuch-search/00600-search-by-tag.test
 create mode 100644 test/tests/notmuch-search/00700-search-by-thread.test
 create mode 100644 test/tests/notmuch-search/00800-search-body-phrase.test
 create mode 100644 test/tests/notmuch-search/00900-search-by-from-address.test
 create mode 100644 test/tests/notmuch-search/01000-search-by-from-name.test
 create mode 100644 test/tests/notmuch-search/01100-search-by-to-address.test
 create mode 100644 test/tests/notmuch-search/01200-search-by-to-name.test
 create mode 100644 test/tests/notmuch-search/01300-search-by-subject-phrase.test
 create mode 100644 test/tests/notmuch-search/01400-search-for-all-messages.test
 create mode 100644 test/tests/notmuch-search/01500-search-body-utf-8.test
 create mode 100644 test/tests/notmuch-search/99999-notmuch-search.setup
 create mode 100644 test/tests/out-of-order-threading/00001-out-of-order-threading.setup
 create mode 100644 test/tests/out-of-order-threading/00100-addinitial-child-message.test
 create mode 100644 test/tests/out-of-order-threading/00200-searching-returns-message.test
 create mode 100644 test/tests/out-of-order-threading/00300-adding-second-child-message.test
 create mode 100644 test/tests/out-of-order-threading/00400-searching-returns-both-msgs.test
 create mode 100644 test/tests/out-of-order-threading/00500-adding-parent-msg.test
 create mode 100644 test/tests/out-of-order-threading/00600-return-all-msgs-in-one-thread.test
 create mode 100644 test/tests/out-of-order-threading/99999-out-of-order-threading.setup
 create mode 100644 test/tests/thread-naming/00001-thread-naming.setup
 create mode 100644 test/tests/thread-naming/00100-initial-thread-name-oldest-first-search.test
 create mode 100644 test/tests/thread-naming/00200-initial-thread-name-newest-first-search.test
 create mode 100644 test/tests/thread-naming/00300-changed-thread-name-oldest-first-search.test
 create mode 100644 test/tests/thread-naming/00400-changed-thread-name-newest-first-search.test
 create mode 100644 test/tests/thread-naming/00500-ignore-added-reply-prefix-re.test
 create mode 100644 test/tests/thread-naming/00600-ignore-added-reply-prefix-aw.test
 create mode 100644 test/tests/thread-naming/00700-ignore-added-reply-prefix-vs.test
 create mode 100644 test/tests/thread-naming/00800-ignore-added-reply-prefix-sv.test
 create mode 100644 test/tests/thread-naming/00900-test-order-of-messages-in-nm-show.test
 create mode 100644 test/tests/thread-naming/99999-thread-naming.setup
 create mode 100644 test/tests/uuencoded/00001-uuencoded.setup
 create mode 100644 test/tests/uuencoded/00100-index-content-before-uu.test
 create mode 100644 test/tests/uuencoded/00200-dont-index-uu-data.test
 create mode 100644 test/tests/uuencoded/00300-index-data-after-uu.test
 create mode 100644 test/tests/uuencoded/99999-uuencoded.setup

diff --git a/test/tests/author-reordering/00001-author-reordering.setup b/test/tests/author-reordering/00001-author-reordering.setup
new file mode 100644
index 0000000..46046bb
--- /dev/null
+++ b/test/tests/author-reordering/00001-author-reordering.setup
@@ -0,0 +1,2 @@
+printf "\nTesting author reordering;\n"
+printf " Setting up...\n"
diff --git a/test/tests/author-reordering/00100-adding-parent-msg.test b/test/tests/author-reordering/00100-adding-parent-msg.test
new file mode 100644
index 0000000..1cb6819
--- /dev/null
+++ b/test/tests/author-reordering/00100-adding-parent-msg.test
@@ -0,0 +1,4 @@
+printf " Adding parent message...\t\t\t"
+generate_message [body]=findme [id]=new-parent-id [subject]=author-reorder-threadtest '[from]="User <user@example.com>"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"'
+output=$(NOTMUCH_NEW)
+pass_if_equal "$output" "Added 1 new message to the database."
diff --git a/test/tests/author-reordering/00200-adding-initial-child-message.test b/test/tests/author-reordering/00200-adding-initial-child-message.test
new file mode 100644
index 0000000..193187b
--- /dev/null
+++ b/test/tests/author-reordering/00200-adding-initial-child-message.test
@@ -0,0 +1,4 @@
+printf " Adding initial child message...\t\t"
+generate_message [body]=findme '[in-reply-to]=\<new-parent-id\>' [subject]=author-reorder-threadtest '[from]="User1 <user1@example.com>"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"'
+output=$(NOTMUCH_NEW)
+pass_if_equal "$output" "Added 1 new message to the database."
diff --git a/test/tests/author-reordering/00300-adding-second-child-msg.test b/test/tests/author-reordering/00300-adding-second-child-msg.test
new file mode 100644
index 0000000..e470776
--- /dev/null
+++ b/test/tests/author-reordering/00300-adding-second-child-msg.test
@@ -0,0 +1,4 @@
+printf " Adding second child message...\t\t\t"
+generate_message [body]=findme '[in-reply-to]=\<new-parent-id\>' [subject]=author-reorder-threadtest '[from]="User2 <user2@example.com>"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"'
+output=$(NOTMUCH_NEW)
+pass_if_equal "$output" "Added 1 new message to the database."
diff --git a/test/tests/author-reordering/00400-search-all-msgs-match.test b/test/tests/author-reordering/00400-search-all-msgs-match.test
new file mode 100644
index 0000000..b21af06
--- /dev/null
+++ b/test/tests/author-reordering/00400-search-all-msgs-match.test
@@ -0,0 +1,3 @@
+printf " Searching when all three messages match...\t"
+output=$($NOTMUCH search findme | notmuch_search_sanitize)
+pass_if_equal "$output" "thread:XXX   2000-01-01 [3/3] User, User1, User2; author-reorder-threadtest (inbox unread)"
diff --git a/test/tests/author-reordering/00500-search-two-msgs-match.test b/test/tests/author-reordering/00500-search-two-msgs-match.test
new file mode 100644
index 0000000..b879411
--- /dev/null
+++ b/test/tests/author-reordering/00500-search-two-msgs-match.test
@@ -0,0 +1,3 @@
+printf " Searching when two messages match...\t\t"
+output=$($NOTMUCH search User1 or User2 | notmuch_search_sanitize)
+pass_if_equal "$output" "thread:XXX   2000-01-01 [2/3] User1, User2| User; author-reorder-threadtest (inbox unread)"
diff --git a/test/tests/author-reordering/00600-search-one-msg-matches.test b/test/tests/author-reordering/00600-search-one-msg-matches.test
new file mode 100644
index 0000000..998cb87
--- /dev/null
+++ b/test/tests/author-reordering/00600-search-one-msg-matches.test
@@ -0,0 +1,3 @@
+printf " Searching when only one message matches...\t"
+output=$($NOTMUCH search User2 | notmuch_search_sanitize)
+pass_if_equal "$output" "thread:XXX   2000-01-01 [1/3] User2| User, User1; author-reorder-threadtest (inbox unread)"
diff --git a/test/tests/author-reordering/00700-search-first-msg-matches.test b/test/tests/author-reordering/00700-search-first-msg-matches.test
new file mode 100644
index 0000000..cbabdce
--- /dev/null
+++ b/test/tests/author-reordering/00700-search-first-msg-matches.test
@@ -0,0 +1,3 @@
+printf " Searching when only first message matches...\t"
+output=$($NOTMUCH search User | notmuch_search_sanitize)
+pass_if_equal "$output" "thread:XXX   2000-01-01 [1/3] User| User1, User2; author-reorder-threadtest (inbox unread)"
diff --git a/test/tests/author-reordering/99999-author-reordering.setup b/test/tests/author-reordering/99999-author-reordering.setup
new file mode 100644
index 0000000..ce00cfc
--- /dev/null
+++ b/test/tests/author-reordering/99999-author-reordering.setup
@@ -0,0 +1,4 @@
+printf " Cleaning up...\n"
+
+rm -rf ${MAIL_DIR}/* ${MAIL_DIR}/.notmuch
+$NOTMUCH new > /dev/null
diff --git a/test/tests/from-guessing-multiple/00001-from-guessing-multiple.setup b/test/tests/from-guessing-multiple/00001-from-guessing-multiple.setup
new file mode 100644
index 0000000..f7fb7b2
--- /dev/null
+++ b/test/tests/from-guessing-multiple/00001-from-guessing-multiple.setup
@@ -0,0 +1,2 @@
+printf "\nTesting From line heuristics (with multiple configured addresses):\n"
+printf " Setting up...\n"
diff --git a/test/tests/from-guessing-multiple/00100-nothing-to-go-on.test b/test/tests/from-guessing-multiple/00100-nothing-to-go-on.test
new file mode 100644
index 0000000..e266127
--- /dev/null
+++ b/test/tests/from-guessing-multiple/00100-nothing-to-go-on.test
@@ -0,0 +1,17 @@
+printf " Magic from guessing (nothing to go on)...\t"
+add_message '[from]="Sender <sender@example.com>"' \
+             [to]=mailinglist@notmuchmail.org \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0800"' \
+            '[body]="from guessing test"'
+
+output=$($NOTMUCH reply id:${gen_msg_id})
+pass_if_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <sender@example.com>, mailinglist@notmuchmail.org
+Bcc: test_suite@notmuchmail.org
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0800, Sender <sender@example.com> wrote:
+> from guessing test"
diff --git a/test/tests/from-guessing-multiple/00200-envelope-to.test b/test/tests/from-guessing-multiple/00200-envelope-to.test
new file mode 100644
index 0000000..745eef1
--- /dev/null
+++ b/test/tests/from-guessing-multiple/00200-envelope-to.test
@@ -0,0 +1,18 @@
+printf " Magic from guessing (Envelope-to:)...\t\t"
+add_message '[from]="Sender <sender@example.com>"' \
+             [to]=mailinglist@notmuchmail.org \
+             [subject]=notmuch-reply-test \
+            '[header]="Envelope-To: test_suite_other@notmuchmail.org"' \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0800"' \
+            '[body]="from guessing test"'
+
+output=$($NOTMUCH reply id:${gen_msg_id})
+pass_if_equal "$output" "From: Notmuch Test Suite <test_suite_other@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <sender@example.com>, mailinglist@notmuchmail.org
+Bcc: test_suite@notmuchmail.org
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0800, Sender <sender@example.com> wrote:
+> from guessing test"
diff --git a/test/tests/from-guessing-multiple/00300-x-original-to.test b/test/tests/from-guessing-multiple/00300-x-original-to.test
new file mode 100644
index 0000000..af1baa8
--- /dev/null
+++ b/test/tests/from-guessing-multiple/00300-x-original-to.test
@@ -0,0 +1,18 @@
+printf " Magic from guessing (X-Original-To:)...\t"
+add_message '[from]="Sender <sender@example.com>"' \
+             [to]=mailinglist@notmuchmail.org \
+             [subject]=notmuch-reply-test \
+            '[header]="X-Original-To: test_suite_other@notmuchmail.org"' \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0800"' \
+            '[body]="from guessing test"'
+
+output=$($NOTMUCH reply id:${gen_msg_id})
+pass_if_equal "$output" "From: Notmuch Test Suite <test_suite_other@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <sender@example.com>, mailinglist@notmuchmail.org
+Bcc: test_suite@notmuchmail.org
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0800, Sender <sender@example.com> wrote:
+> from guessing test"
diff --git a/test/tests/from-guessing-multiple/00400-received-for.test b/test/tests/from-guessing-multiple/00400-received-for.test
new file mode 100644
index 0000000..c02f8fa
--- /dev/null
+++ b/test/tests/from-guessing-multiple/00400-received-for.test
@@ -0,0 +1,20 @@
+printf " Magic from guessing (Received: .. for ..)...\t"
+add_message '[from]="Sender <sender@example.com>"' \
+             [to]=mailinglist@notmuchmail.org \
+             [subject]=notmuch-reply-test \
+            '[header]="Received: from mail.example.com (mail.example.com [1.1.1.1])\
+        by mail.notmuchmail.org (some MTA) with ESMTP id 12345678\
+        for <test_suite_other@notmuchmail.org>; Sat, 10 Apr 2010 07:54:51 -0400 (EDT)"' \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0800"' \
+            '[body]="from guessing test"'
+
+output=$($NOTMUCH reply id:${gen_msg_id})
+pass_if_equal "$output" "From: Notmuch Test Suite <test_suite_other@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <sender@example.com>, mailinglist@notmuchmail.org
+Bcc: test_suite@notmuchmail.org
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0800, Sender <sender@example.com> wrote:
+> from guessing test"
diff --git a/test/tests/from-guessing-multiple/00500-received-doman.test b/test/tests/from-guessing-multiple/00500-received-doman.test
new file mode 100644
index 0000000..f0c0abd
--- /dev/null
+++ b/test/tests/from-guessing-multiple/00500-received-doman.test
@@ -0,0 +1,20 @@
+printf " Magic from guessing (Received: domain)...\t"
+add_message '[from]="Sender <sender@example.com>"' \
+             [to]=mailinglist@notmuchmail.org \
+             [subject]=notmuch-reply-test \
+            '[header]="Received: from mail.example.com (mail.example.com [1.1.1.1])\
+        by mail.otherdomain.org (some MTA) with ESMTP id 12345678\
+        Sat, 10 Apr 2010 07:54:51 -0400 (EDT)"' \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0800"' \
+            '[body]="from guessing test"'
+
+output=$($NOTMUCH reply id:${gen_msg_id})
+pass_if_equal "$output" "From: Notmuch Test Suite <test_suite@otherdomain.org>
+Subject: Re: notmuch-reply-test
+To: Sender <sender@example.com>, mailinglist@notmuchmail.org
+Bcc: test_suite@notmuchmail.org
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0800, Sender <sender@example.com> wrote:
+> from guessing test"
diff --git a/test/tests/from-guessing-multiple/99999-from-guessing-multiple.setup b/test/tests/from-guessing-multiple/99999-from-guessing-multiple.setup
new file mode 100644
index 0000000..ce00cfc
--- /dev/null
+++ b/test/tests/from-guessing-multiple/99999-from-guessing-multiple.setup
@@ -0,0 +1,4 @@
+printf " Cleaning up...\n"
+
+rm -rf ${MAIL_DIR}/* ${MAIL_DIR}/.notmuch
+$NOTMUCH new > /dev/null
diff --git a/test/tests/from-guessing-single/00001-from-guessing-single.setup b/test/tests/from-guessing-single/00001-from-guessing-single.setup
new file mode 100644
index 0000000..a8ac5b5
--- /dev/null
+++ b/test/tests/from-guessing-single/00001-from-guessing-single.setup
@@ -0,0 +1,4 @@
+printf "\nTesting From line heuristics (with single configured address):\n"
+printf " Setting up...\n"
+
+sed -i -e 's/^other_email.*//' ${NOTMUCH_CONFIG}
diff --git a/test/tests/from-guessing-single/00100-nothing-to-go-on.test b/test/tests/from-guessing-single/00100-nothing-to-go-on.test
new file mode 100644
index 0000000..e266127
--- /dev/null
+++ b/test/tests/from-guessing-single/00100-nothing-to-go-on.test
@@ -0,0 +1,17 @@
+printf " Magic from guessing (nothing to go on)...\t"
+add_message '[from]="Sender <sender@example.com>"' \
+             [to]=mailinglist@notmuchmail.org \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0800"' \
+            '[body]="from guessing test"'
+
+output=$($NOTMUCH reply id:${gen_msg_id})
+pass_if_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <sender@example.com>, mailinglist@notmuchmail.org
+Bcc: test_suite@notmuchmail.org
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0800, Sender <sender@example.com> wrote:
+> from guessing test"
diff --git a/test/tests/from-guessing-single/00200-envelope-to.test b/test/tests/from-guessing-single/00200-envelope-to.test
new file mode 100644
index 0000000..2c3f375
--- /dev/null
+++ b/test/tests/from-guessing-single/00200-envelope-to.test
@@ -0,0 +1,18 @@
+printf " Magic from guessing (Envelope-to:)...\t\t"
+add_message '[from]="Sender <sender@example.com>"' \
+             [to]=mailinglist@notmuchmail.org \
+             [subject]=notmuch-reply-test \
+            '[header]="Envelope-To: test_suite_other@notmuchmail.org"' \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0800"' \
+            '[body]="from guessing test"'
+
+output=$($NOTMUCH reply id:${gen_msg_id})
+pass_if_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <sender@example.com>, mailinglist@notmuchmail.org
+Bcc: test_suite@notmuchmail.org
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0800, Sender <sender@example.com> wrote:
+> from guessing test"
diff --git a/test/tests/from-guessing-single/00300-x-original-to.test b/test/tests/from-guessing-single/00300-x-original-to.test
new file mode 100644
index 0000000..29906ac
--- /dev/null
+++ b/test/tests/from-guessing-single/00300-x-original-to.test
@@ -0,0 +1,18 @@
+printf " Magic from guessing (X-Original-To:)...\t"
+add_message '[from]="Sender <sender@example.com>"' \
+             [to]=mailinglist@notmuchmail.org \
+             [subject]=notmuch-reply-test \
+            '[header]="X-Original-To: test_suite_other@notmuchmail.org"' \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0800"' \
+            '[body]="from guessing test"'
+
+output=$($NOTMUCH reply id:${gen_msg_id})
+pass_if_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <sender@example.com>, mailinglist@notmuchmail.org
+Bcc: test_suite@notmuchmail.org
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0800, Sender <sender@example.com> wrote:
+> from guessing test"
diff --git a/test/tests/from-guessing-single/00400-received-for.test b/test/tests/from-guessing-single/00400-received-for.test
new file mode 100644
index 0000000..7fc4748
--- /dev/null
+++ b/test/tests/from-guessing-single/00400-received-for.test
@@ -0,0 +1,20 @@
+printf " Magic from guessing (Received: .. for ..)...\t"
+add_message '[from]="Sender <sender@example.com>"' \
+             [to]=mailinglist@notmuchmail.org \
+             [subject]=notmuch-reply-test \
+            '[header]="Received: from mail.example.com (mail.example.com [1.1.1.1])\
+        by mail.notmuchmail.org (some MTA) with ESMTP id 12345678\
+        for <test_suite_other@notmuchmail.org>; Sat, 10 Apr 2010 07:54:51 -0400 (EDT)"' \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0800"' \
+            '[body]="from guessing test"'
+
+output=$($NOTMUCH reply id:${gen_msg_id})
+pass_if_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <sender@example.com>, mailinglist@notmuchmail.org
+Bcc: test_suite@notmuchmail.org
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0800, Sender <sender@example.com> wrote:
+> from guessing test"
diff --git a/test/tests/from-guessing-single/00500-received-doman.test b/test/tests/from-guessing-single/00500-received-doman.test
new file mode 100644
index 0000000..bcd70f6
--- /dev/null
+++ b/test/tests/from-guessing-single/00500-received-doman.test
@@ -0,0 +1,20 @@
+printf " Magic from guessing (Received: domain)...\t"
+add_message '[from]="Sender <sender@example.com>"' \
+             [to]=mailinglist@notmuchmail.org \
+             [subject]=notmuch-reply-test \
+            '[header]="Received: from mail.example.com (mail.example.com [1.1.1.1])\
+        by mail.otherdomain.org (some MTA) with ESMTP id 12345678\
+        Sat, 10 Apr 2010 07:54:51 -0400 (EDT)"' \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0800"' \
+            '[body]="from guessing test"'
+
+output=$($NOTMUCH reply id:${gen_msg_id})
+pass_if_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <sender@example.com>, mailinglist@notmuchmail.org
+Bcc: test_suite@notmuchmail.org
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0800, Sender <sender@example.com> wrote:
+> from guessing test"
diff --git a/test/tests/from-guessing-single/99999-from-guessing-single.setup b/test/tests/from-guessing-single/99999-from-guessing-single.setup
new file mode 100644
index 0000000..1401d0a
--- /dev/null
+++ b/test/tests/from-guessing-single/99999-from-guessing-single.setup
@@ -0,0 +1,14 @@
+printf " Cleaning up...\n"
+
+cat <<EOF > ${NOTMUCH_CONFIG}
+[database]
+path=${MAIL_DIR}
+
+[user]
+name=Notmuch Test Suite
+primary_email=test_suite@notmuchmail.org
+other_email=test_suite_other@notmuchmail.org;test_suite@otherdomain.org
+EOF
+
+rm -rf ${MAIL_DIR}/* ${MAIL_DIR}/.notmuch
+$NOTMUCH new > /dev/null
diff --git a/test/tests/json/00001-json.setup b/test/tests/json/00001-json.setup
new file mode 100644
index 0000000..936fb03
--- /dev/null
+++ b/test/tests/json/00001-json.setup
@@ -0,0 +1,2 @@
+printf "\nTesting --format=json output:\n"
+printf " Setting up...\n"
diff --git a/test/tests/json/00100-show-message-json.test b/test/tests/json/00100-show-message-json.test
new file mode 100644
index 0000000..cc6f98c
--- /dev/null
+++ b/test/tests/json/00100-show-message-json.test
@@ -0,0 +1,4 @@
+printf " Show message: json...\t\t\t\t"
+add_message '[subject]="json-show-subject"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' '[body]="json-show-message"'
+output=$($NOTMUCH show --format=json 'json-show-message')
+pass_if_equal "$output" '[[[{"id": "'${gen_msg_id}'", "match": true, "filename": "'${gen_msg_filename}'", "timestamp": 946728000, "date_relative": "2000-01-01", "tags": ["inbox","unread"], "headers": {"Subject": "json-show-subject", "From": "Notmuch Test Suite <test_suite@notmuchmail.org>", "To": "Notmuch Test Suite <test_suite@notmuchmail.org>", "Cc": "", "Bcc": "", "Date": "Sat, 01 Jan 2000 12:00:00 -0000"}, "body": [{"id": 1, "content-type": "text/plain", "content": "json-show-message\n"}]}, []]]]'
diff --git a/test/tests/json/00200-search-message-json.test b/test/tests/json/00200-search-message-json.test
new file mode 100644
index 0000000..5a30415
--- /dev/null
+++ b/test/tests/json/00200-search-message-json.test
@@ -0,0 +1,10 @@
+printf " Search message: json...\t\t\t"
+add_message '[subject]="json-search-subject"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' '[body]="json-search-message"'
+output=$($NOTMUCH search --format=json 'json-search-message' | notmuch_search_sanitize)
+pass_if_equal "$output" '[{"thread": "XXX",
+"timestamp": 946728000,
+"matched": 1,
+"total": 1,
+"authors": "Notmuch Test Suite",
+"subject": "json-search-subject",
+"tags": ["inbox", "unread"]}]'
diff --git a/test/tests/json/00300-search-by-subject-utf8.test b/test/tests/json/00300-search-by-subject-utf8.test
new file mode 100644
index 0000000..27fbb7d
--- /dev/null
+++ b/test/tests/json/00300-search-by-subject-utf8.test
@@ -0,0 +1,4 @@
+printf " Search by subject (utf-8):...\t\t\t"
+add_message [subject]=utf8-sübjéct '[date]="Sat, 01 Jan 2000 12:00:00 -0000"'
+output=$($NOTMUCH search subject:utf8-sübjéct | notmuch_search_sanitize)
+pass_if_equal "$output" "thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; utf8-sübjéct (inbox unread)"
diff --git a/test/tests/json/00400-show-message-json-utf8.test b/test/tests/json/00400-show-message-json-utf8.test
new file mode 100644
index 0000000..d90f24c
--- /dev/null
+++ b/test/tests/json/00400-show-message-json-utf8.test
@@ -0,0 +1,4 @@
+printf " Show message: json, utf-8...\t\t\t"
+add_message '[subject]="json-show-utf8-body-sübjéct"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' '[body]="jsön-show-méssage"'
+output=$($NOTMUCH show --format=json 'jsön-show-méssage')
+pass_if_equal "$output" '[[[{"id": "'${gen_msg_id}'", "match": true, "filename": "'${gen_msg_filename}'", "timestamp": 946728000, "date_relative": "2000-01-01", "tags": ["inbox","unread"], "headers": {"Subject": "json-show-utf8-body-sübjéct", "From": "Notmuch Test Suite <test_suite@notmuchmail.org>", "To": "Notmuch Test Suite <test_suite@notmuchmail.org>", "Cc": "", "Bcc": "", "Date": "Sat, 01 Jan 2000 12:00:00 -0000"}, "body": [{"id": 1, "content-type": "text/plain", "content": "jsön-show-méssage\n"}]}, []]]]'
diff --git a/test/tests/json/00500-search-message-json-utf8.test b/test/tests/json/00500-search-message-json-utf8.test
new file mode 100644
index 0000000..50a9de7
--- /dev/null
+++ b/test/tests/json/00500-search-message-json-utf8.test
@@ -0,0 +1,10 @@
+printf " Search message: json, utf-8...\t\t\t"
+add_message '[subject]="json-search-utf8-body-sübjéct"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' '[body]="jsön-search-méssage"'
+output=$($NOTMUCH search --format=json 'jsön-search-méssage' | notmuch_search_sanitize)
+pass_if_equal "$output" '[{"thread": "XXX",
+"timestamp": 946728000,
+"matched": 1,
+"total": 1,
+"authors": "Notmuch Test Suite",
+"subject": "json-search-utf8-body-sübjéct",
+"tags": ["inbox", "unread"]}]'
diff --git a/test/tests/json/99999-json.setup b/test/tests/json/99999-json.setup
new file mode 100644
index 0000000..ce00cfc
--- /dev/null
+++ b/test/tests/json/99999-json.setup
@@ -0,0 +1,4 @@
+printf " Cleaning up...\n"
+
+rm -rf ${MAIL_DIR}/* ${MAIL_DIR}/.notmuch
+$NOTMUCH new > /dev/null
diff --git a/test/tests/notmuch-dump-restore/00001-notmuch-dump-restore.setup b/test/tests/notmuch-dump-restore/00001-notmuch-dump-restore.setup
new file mode 100644
index 0000000..be0e7fc
--- /dev/null
+++ b/test/tests/notmuch-dump-restore/00001-notmuch-dump-restore.setup
@@ -0,0 +1,2 @@
+printf "\nTesting \"notmuch dump\" and \"notmuch restore\":\n"
+printf " Setting up...\n"
diff --git a/test/tests/notmuch-dump-restore/00100-dumping-all-tags.test b/test/tests/notmuch-dump-restore/00100-dumping-all-tags.test
new file mode 100644
index 0000000..2869aee
--- /dev/null
+++ b/test/tests/notmuch-dump-restore/00100-dumping-all-tags.test
@@ -0,0 +1,3 @@
+printf " Dumping all tags...\t\t\t\t"
+$NOTMUCH dump dump.expected
+pass_if_equal "$?" "0"
diff --git a/test/tests/notmuch-dump-restore/00200-clearing-all-tags.test b/test/tests/notmuch-dump-restore/00200-clearing-all-tags.test
new file mode 100644
index 0000000..bb6b4f3
--- /dev/null
+++ b/test/tests/notmuch-dump-restore/00200-clearing-all-tags.test
@@ -0,0 +1,5 @@
+printf " Clearing all tags...\t\t\t\t"
+sed -e 's/(\([^(]*\))$/()/' < dump.expected > clear.expected
+$NOTMUCH restore clear.expected
+$NOTMUCH dump clear.actual
+pass_if_equal "$(< clear.actual)" "$(< clear.expected)"
diff --git a/test/tests/notmuch-dump-restore/00300-restoring-original-tags.test b/test/tests/notmuch-dump-restore/00300-restoring-original-tags.test
new file mode 100644
index 0000000..79702ad
--- /dev/null
+++ b/test/tests/notmuch-dump-restore/00300-restoring-original-tags.test
@@ -0,0 +1,4 @@
+printf " Restoring original tags...\t\t\t"
+$NOTMUCH restore dump.expected
+$NOTMUCH dump dump.actual
+pass_if_equal "$(< dump.actual)" "$(< dump.expected)"
diff --git a/test/tests/notmuch-dump-restore/00400-restore-with-nothing.test b/test/tests/notmuch-dump-restore/00400-restore-with-nothing.test
new file mode 100644
index 0000000..536a0eb
--- /dev/null
+++ b/test/tests/notmuch-dump-restore/00400-restore-with-nothing.test
@@ -0,0 +1,3 @@
+printf " Restore with nothing to do...\t\t\t"
+$NOTMUCH restore dump.expected
+pass_if_equal "$?" "0"
diff --git a/test/tests/notmuch-dump-restore/99999-notmuch-dump-restore.setup b/test/tests/notmuch-dump-restore/99999-notmuch-dump-restore.setup
new file mode 100644
index 0000000..ce00cfc
--- /dev/null
+++ b/test/tests/notmuch-dump-restore/99999-notmuch-dump-restore.setup
@@ -0,0 +1,4 @@
+printf " Cleaning up...\n"
+
+rm -rf ${MAIL_DIR}/* ${MAIL_DIR}/.notmuch
+$NOTMUCH new > /dev/null
diff --git a/test/tests/notmuch-new/00001-notmuch-new.setup b/test/tests/notmuch-new/00001-notmuch-new.setup
new file mode 100644
index 0000000..9415160
--- /dev/null
+++ b/test/tests/notmuch-new/00001-notmuch-new.setup
@@ -0,0 +1,2 @@
+printf "Testing \"notmuch new\" in several variations:\n"
+printf " Setting up...\n"
diff --git a/test/tests/notmuch-new/00100-no-new-mail.test b/test/tests/notmuch-new/00100-no-new-mail.test
new file mode 100644
index 0000000..e7c646d
--- /dev/null
+++ b/test/tests/notmuch-new/00100-no-new-mail.test
@@ -0,0 +1,3 @@
+printf " No new messages...\t\t\t\t"
+output=$(NOTMUCH_NEW)
+pass_if_equal "$output" "No new mail."
diff --git a/test/tests/notmuch-new/00200-one-new-message.test b/test/tests/notmuch-new/00200-one-new-message.test
new file mode 100644
index 0000000..6a0af76
--- /dev/null
+++ b/test/tests/notmuch-new/00200-one-new-message.test
@@ -0,0 +1,4 @@
+printf " Single new message...\t\t\t\t"
+generate_message
+output=$(NOTMUCH_NEW)
+pass_if_equal "$output" "Added 1 new message to the database."
diff --git a/test/tests/notmuch-new/00300-multiple-new-messages.test b/test/tests/notmuch-new/00300-multiple-new-messages.test
new file mode 100644
index 0000000..f13bf19
--- /dev/null
+++ b/test/tests/notmuch-new/00300-multiple-new-messages.test
@@ -0,0 +1,5 @@
+printf " Multiple new messages...\t\t\t"
+generate_message
+generate_message
+output=$(NOTMUCH_NEW)
+pass_if_equal "$output" "Added 2 new messages to the database."
diff --git a/test/tests/notmuch-new/00400-non-empty-db.test b/test/tests/notmuch-new/00400-non-empty-db.test
new file mode 100644
index 0000000..92b2fb8
--- /dev/null
+++ b/test/tests/notmuch-new/00400-non-empty-db.test
@@ -0,0 +1,3 @@
+printf " No new messages (non-empty DB)...\t\t"
+output=$(NOTMUCH_NEW)
+pass_if_equal "$output" "No new mail."
diff --git a/test/tests/notmuch-new/00500-new-directories.test b/test/tests/notmuch-new/00500-new-directories.test
new file mode 100644
index 0000000..c123c8f
--- /dev/null
+++ b/test/tests/notmuch-new/00500-new-directories.test
@@ -0,0 +1,8 @@
+printf " New directories...\t\t\t\t"
+rm -rf ${MAIL_DIR}/* ${MAIL_DIR}/.notmuch
+mkdir ${MAIL_DIR}/def
+mkdir ${MAIL_DIR}/ghi
+generate_message [dir]=def
+
+output=$(NOTMUCH_NEW)
+pass_if_equal "$output" "Added 1 new message to the database."
diff --git a/test/tests/notmuch-new/00550-alternate-inode-order.test b/test/tests/notmuch-new/00550-alternate-inode-order.test
new file mode 100644
index 0000000..448fcdf
--- /dev/null
+++ b/test/tests/notmuch-new/00550-alternate-inode-order.test
@@ -0,0 +1,9 @@
+printf " Alternate inode order...\t\t\t"
+
+rm -rf ${MAIL_DIR}/.notmuch
+mv ${MAIL_DIR}/ghi ${MAIL_DIR}/abc
+rm ${MAIL_DIR}/def/*
+generate_message [dir]=abc
+
+output=$(NOTMUCH_NEW)
+pass_if_equal "$output" "Added 1 new message to the database."
diff --git a/test/tests/notmuch-new/00600-message-moved.test b/test/tests/notmuch-new/00600-message-moved.test
new file mode 100644
index 0000000..5bae2af
--- /dev/null
+++ b/test/tests/notmuch-new/00600-message-moved.test
@@ -0,0 +1,12 @@
+printf " Message moved in...\t\t\t\t"
+rm -rf ${MAIL_DIR}/* ${MAIL_DIR}/.notmuch
+generate_message
+tmp_msg_filename=tmp/$gen_msg_filename
+mkdir -p $(dirname $tmp_msg_filename)
+mv $gen_msg_filename $tmp_msg_filename
+increment_mtime ${MAIL_DIR}
+$NOTMUCH new > /dev/null
+mv $tmp_msg_filename $gen_msg_filename
+increment_mtime ${MAIL_DIR}
+output=$(NOTMUCH_NEW)
+pass_if_equal "$output" "Added 1 new message to the database."
diff --git a/test/tests/notmuch-new/00700-renamed-message.test b/test/tests/notmuch-new/00700-renamed-message.test
new file mode 100644
index 0000000..a774d79
--- /dev/null
+++ b/test/tests/notmuch-new/00700-renamed-message.test
@@ -0,0 +1,8 @@
+printf " Renamed message...\t\t\t\t"
+
+generate_message
+$NOTMUCH new > /dev/null
+mv $gen_msg_filename ${gen_msg_filename}-renamed
+increment_mtime ${MAIL_DIR}
+output=$(NOTMUCH_NEW)
+pass_if_equal "$output" "No new mail. Detected 1 file rename."
diff --git a/test/tests/notmuch-new/00800-deleted-message.test b/test/tests/notmuch-new/00800-deleted-message.test
new file mode 100644
index 0000000..7f1a280
--- /dev/null
+++ b/test/tests/notmuch-new/00800-deleted-message.test
@@ -0,0 +1,6 @@
+printf " Deleted message...\t\t\t\t"
+
+rm ${gen_msg_filename}-renamed
+increment_mtime ${MAIL_DIR}
+output=$(NOTMUCH_NEW)
+pass_if_equal "$output" "No new mail. Removed 1 message."
diff --git a/test/tests/notmuch-new/00900-renamed-directory.test b/test/tests/notmuch-new/00900-renamed-directory.test
new file mode 100644
index 0000000..64e587a
--- /dev/null
+++ b/test/tests/notmuch-new/00900-renamed-directory.test
@@ -0,0 +1,13 @@
+printf " Renamed directory...\t\t\t\t"
+
+generate_message [dir]=dir
+generate_message [dir]=dir
+generate_message [dir]=dir
+
+$NOTMUCH new > /dev/null
+
+mv ${MAIL_DIR}/dir ${MAIL_DIR}/dir-renamed
+increment_mtime ${MAIL_DIR}
+
+output=$(NOTMUCH_NEW)
+pass_if_equal "$output" "No new mail. Detected 3 file renames."
diff --git a/test/tests/notmuch-new/01000-deleted-directory.test b/test/tests/notmuch-new/01000-deleted-directory.test
new file mode 100644
index 0000000..1808840
--- /dev/null
+++ b/test/tests/notmuch-new/01000-deleted-directory.test
@@ -0,0 +1,7 @@
+printf " Deleted directory...\t\t\t\t"
+
+rm -rf ${MAIL_DIR}/dir-renamed
+increment_mtime ${MAIL_DIR}
+
+output=$(NOTMUCH_NEW)
+pass_if_equal "$output" "No new mail. Removed 3 messages."
diff --git a/test/tests/notmuch-new/01100-new-directory-end-list.test b/test/tests/notmuch-new/01100-new-directory-end-list.test
new file mode 100644
index 0000000..741fb83
--- /dev/null
+++ b/test/tests/notmuch-new/01100-new-directory-end-list.test
@@ -0,0 +1,8 @@
+printf " New directory (at end of list)...\t\t"
+
+generate_message [dir]=zzz
+generate_message [dir]=zzz
+generate_message [dir]=zzz
+
+output=$(NOTMUCH_NEW)
+pass_if_equal "$output" "Added 3 new messages to the database."
diff --git a/test/tests/notmuch-new/01200-deleted-directory-end-list.test b/test/tests/notmuch-new/01200-deleted-directory-end-list.test
new file mode 100644
index 0000000..ee59bfd
--- /dev/null
+++ b/test/tests/notmuch-new/01200-deleted-directory-end-list.test
@@ -0,0 +1,7 @@
+printf " Deleted directory (end of list)...\t\t"
+
+rm -rf ${MAIL_DIR}/zzz
+increment_mtime ${MAIL_DIR}
+
+output=$(NOTMUCH_NEW)
+pass_if_equal "$output" "No new mail. Removed 3 messages."
diff --git a/test/tests/notmuch-new/01300-new-symlink-to-dir.test b/test/tests/notmuch-new/01300-new-symlink-to-dir.test
new file mode 100644
index 0000000..ffcdfa4
--- /dev/null
+++ b/test/tests/notmuch-new/01300-new-symlink-to-dir.test
@@ -0,0 +1,10 @@
+printf " New symlink to directory...\t\t\t"
+
+rm -rf ${MAIL_DIR}/.notmuch
+mv ${MAIL_DIR} ${TEST_DIR}/actual_maildir
+
+mkdir ${MAIL_DIR}
+ln -s ${TEST_DIR}/actual_maildir ${MAIL_DIR}/symlink
+
+output=$(NOTMUCH_NEW)
+pass_if_equal "$output" "Added 1 new message to the database."
diff --git a/test/tests/notmuch-new/01400-new-symlink-to-file.test b/test/tests/notmuch-new/01400-new-symlink-to-file.test
new file mode 100644
index 0000000..e2ac273
--- /dev/null
+++ b/test/tests/notmuch-new/01400-new-symlink-to-file.test
@@ -0,0 +1,9 @@
+printf " New symlink to a file...\t\t\t"
+generate_message
+external_msg_filename=${TEST_DIR}/external/$(basename $gen_msg_filename)
+mkdir -p $(dirname $external_msg_filename)
+mv $gen_msg_filename $external_msg_filename
+ln -s $external_msg_filename $gen_msg_filename
+increment_mtime ${MAIL_DIR}
+output=$(NOTMUCH_NEW)
+pass_if_equal "$output" "Added 1 new message to the database."
diff --git a/test/tests/notmuch-new/01500-new-two-level-dir.test b/test/tests/notmuch-new/01500-new-two-level-dir.test
new file mode 100644
index 0000000..30c0bbb
--- /dev/null
+++ b/test/tests/notmuch-new/01500-new-two-level-dir.test
@@ -0,0 +1,8 @@
+printf " New two-level directory...\t\t\t"
+
+generate_message [dir]=two/levels
+generate_message [dir]=two/levels
+generate_message [dir]=two/levels
+
+output=$(NOTMUCH_NEW)
+pass_if_equal "$output" "Added 3 new messages to the database."
diff --git a/test/tests/notmuch-new/01600-deleted-two-level-dir.test b/test/tests/notmuch-new/01600-deleted-two-level-dir.test
new file mode 100644
index 0000000..8958b8a
--- /dev/null
+++ b/test/tests/notmuch-new/01600-deleted-two-level-dir.test
@@ -0,0 +1,7 @@
+printf " Deleted two-level directory...\t\t\t"
+
+rm -rf ${MAIL_DIR}/two
+increment_mtime ${MAIL_DIR}
+
+output=$(NOTMUCH_NEW)
+pass_if_equal "$output" "No new mail. Removed 3 messages."
diff --git a/test/tests/notmuch-new/99999-notmuch-new.setup b/test/tests/notmuch-new/99999-notmuch-new.setup
new file mode 100644
index 0000000..ce00cfc
--- /dev/null
+++ b/test/tests/notmuch-new/99999-notmuch-new.setup
@@ -0,0 +1,4 @@
+printf " Cleaning up...\n"
+
+rm -rf ${MAIL_DIR}/* ${MAIL_DIR}/.notmuch
+$NOTMUCH new > /dev/null
diff --git a/test/tests/notmuch-reply/00001-notmuch-reply.setup b/test/tests/notmuch-reply/00001-notmuch-reply.setup
new file mode 100644
index 0000000..48ab355
--- /dev/null
+++ b/test/tests/notmuch-reply/00001-notmuch-reply.setup
@@ -0,0 +1,2 @@
+printf "\nTesting \"notmuch reply\" in several variations:\n"
+printf " Setting up...\n"
diff --git a/test/tests/notmuch-reply/00100-basic-reply.test b/test/tests/notmuch-reply/00100-basic-reply.test
new file mode 100644
index 0000000..12f8d76
--- /dev/null
+++ b/test/tests/notmuch-reply/00100-basic-reply.test
@@ -0,0 +1,17 @@
+printf " Basic reply...\t\t\t\t\t"
+add_message '[from]="Sender <sender@example.com>"' \
+             [to]=test_suite@notmuchmail.org \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0800"' \
+            '[body]="basic reply test"'
+
+output=$($NOTMUCH reply id:${gen_msg_id})
+pass_if_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <sender@example.com>
+Bcc: test_suite@notmuchmail.org
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0800, Sender <sender@example.com> wrote:
+> basic reply test"
diff --git a/test/tests/notmuch-reply/00200-multiple-recipients.test b/test/tests/notmuch-reply/00200-multiple-recipients.test
new file mode 100644
index 0000000..f0846dc
--- /dev/null
+++ b/test/tests/notmuch-reply/00200-multiple-recipients.test
@@ -0,0 +1,17 @@
+printf " Multiple recipients...\t\t\t\t"
+add_message '[from]="Sender <sender@example.com>"' \
+            '[to]="test_suite@notmuchmail.org, Someone Else <someone@example.com>"' \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0800"' \
+            '[body]="Multiple recipients"'
+
+output=$($NOTMUCH reply id:${gen_msg_id})
+pass_if_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <sender@example.com>, Someone Else <someone@example.com>
+Bcc: test_suite@notmuchmail.org
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0800, Sender <sender@example.com> wrote:
+> Multiple recipients"
diff --git a/test/tests/notmuch-reply/00300-reply-with-cc.test b/test/tests/notmuch-reply/00300-reply-with-cc.test
new file mode 100644
index 0000000..904958f
--- /dev/null
+++ b/test/tests/notmuch-reply/00300-reply-with-cc.test
@@ -0,0 +1,19 @@
+printf " Reply with CC...\t\t\t\t"
+add_message '[from]="Sender <sender@example.com>"' \
+             [to]=test_suite@notmuchmail.org \
+            '[cc]="Other Parties <cc@example.com>"' \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0800"' \
+            '[body]="reply with CC"'
+
+output=$($NOTMUCH reply id:${gen_msg_id})
+pass_if_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <sender@example.com>
+Cc: Other Parties <cc@example.com>
+Bcc: test_suite@notmuchmail.org
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0800, Sender <sender@example.com> wrote:
+> reply with CC"
diff --git a/test/tests/notmuch-reply/00400-reply-from-alternate-address.test b/test/tests/notmuch-reply/00400-reply-from-alternate-address.test
new file mode 100644
index 0000000..77848f3
--- /dev/null
+++ b/test/tests/notmuch-reply/00400-reply-from-alternate-address.test
@@ -0,0 +1,17 @@
+printf " Reply from alternate address...\t\t"
+add_message '[from]="Sender <sender@example.com>"' \
+             [to]=test_suite_other@notmuchmail.org \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0800"' \
+            '[body]="reply from alternate address"'
+
+output=$($NOTMUCH reply id:${gen_msg_id})
+pass_if_equal "$output" "From: Notmuch Test Suite <test_suite_other@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <sender@example.com>
+Bcc: test_suite@notmuchmail.org
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0800, Sender <sender@example.com> wrote:
+> reply from alternate address"
diff --git a/test/tests/notmuch-reply/00500-support-for-reply-to.test b/test/tests/notmuch-reply/00500-support-for-reply-to.test
new file mode 100644
index 0000000..9194c7a
--- /dev/null
+++ b/test/tests/notmuch-reply/00500-support-for-reply-to.test
@@ -0,0 +1,18 @@
+printf " Support for Reply-To...\t\t\t"
+add_message '[from]="Sender <sender@example.com>"' \
+             [to]=test_suite@notmuchmail.org \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0800"' \
+            '[body]="support for reply-to"' \
+            '[reply-to]="Sender <elsewhere@example.com>"'
+
+output=$($NOTMUCH reply id:${gen_msg_id})
+pass_if_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <elsewhere@example.com>
+Bcc: test_suite@notmuchmail.org
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0800, Sender <sender@example.com> wrote:
+> support for reply-to"
diff --git a/test/tests/notmuch-reply/00600-unmunging-reply-to.test b/test/tests/notmuch-reply/00600-unmunging-reply-to.test
new file mode 100644
index 0000000..b470f65
--- /dev/null
+++ b/test/tests/notmuch-reply/00600-unmunging-reply-to.test
@@ -0,0 +1,18 @@
+printf " Un-munging Reply-To...\t\t\t\t"
+add_message '[from]="Sender <sender@example.com>"' \
+            '[to]="Some List <list@example.com>"' \
+             [subject]=notmuch-reply-test \
+            '[date]="Tue, 05 Jan 2010 15:43:56 -0800"' \
+            '[body]="Un-munging Reply-To"' \
+            '[reply-to]="Evil Munging List <list@example.com>"'
+
+output=$($NOTMUCH reply id:${gen_msg_id})
+pass_if_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: notmuch-reply-test
+To: Sender <sender@example.com>, Some List <list@example.com>
+Bcc: test_suite@notmuchmail.org
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0800, Sender <sender@example.com> wrote:
+> Un-munging Reply-To"
diff --git a/test/tests/notmuch-reply/99999-notmuch-reply.setup b/test/tests/notmuch-reply/99999-notmuch-reply.setup
new file mode 100644
index 0000000..ce00cfc
--- /dev/null
+++ b/test/tests/notmuch-reply/99999-notmuch-reply.setup
@@ -0,0 +1,4 @@
+printf " Cleaning up...\n"
+
+rm -rf ${MAIL_DIR}/* ${MAIL_DIR}/.notmuch
+$NOTMUCH new > /dev/null
diff --git a/test/tests/notmuch-search/00001-notmuch-search.setup b/test/tests/notmuch-search/00001-notmuch-search.setup
new file mode 100644
index 0000000..5afd7ec
--- /dev/null
+++ b/test/tests/notmuch-search/00001-notmuch-search.setup
@@ -0,0 +1,152 @@
+printf "\nTesting \"notmuch search\" in several variations:\n"
+
+# printf "Testing \"notmuch new\" in several variations:\n"
+# printf " No new messages...\t\t\t\t"
+# output=$(NOTMUCH_NEW)
+# pass_if_equal "$output" "No new mail."
+
+printf " Setting up...\n"
+
+gen_msg_cnt=0
+gen_msg_filename=""
+gen_msg_id=""
+
+# printf " Single new message...\t\t\t\t"
+generate_message
+# output=$(NOTMUCH_NEW)
+# pass_if_equal "$output" "Added 1 new message to the database."
+
+# printf " Multiple new messages...\t\t\t"
+generate_message
+generate_message
+# output=$(NOTMUCH_NEW)
+# pass_if_equal "$output" "Added 2 new messages to the database."
+
+# printf " No new messages (non-empty DB)...\t\t"
+# output=$(NOTMUCH_NEW)
+# pass_if_equal "$output" "No new mail."
+
+# printf " New directories...\t\t\t\t"
+rm -rf ${MAIL_DIR}/* ${MAIL_DIR}/.notmuch
+mkdir ${MAIL_DIR}/def
+mkdir ${MAIL_DIR}/ghi
+generate_message [dir]=def
+
+# output=$(NOTMUCH_NEW)
+# pass_if_equal "$output" "Added 1 new message to the database."
+
+# printf " Alternate inode order...\t\t\t"
+
+rm -rf ${MAIL_DIR}/.notmuch
+mv ${MAIL_DIR}/ghi ${MAIL_DIR}/abc
+rm ${MAIL_DIR}/def/*
+generate_message [dir]=abc
+
+# output=$(NOTMUCH_NEW)
+# pass_if_equal "$output" "Added 1 new message to the database."
+
+# printf " Message moved in...\t\t\t\t"
+rm -rf ${MAIL_DIR}/* ${MAIL_DIR}/.notmuch
+generate_message
+tmp_msg_filename=tmp/$gen_msg_filename
+mkdir -p $(dirname $tmp_msg_filename)
+mv $gen_msg_filename $tmp_msg_filename
+increment_mtime ${MAIL_DIR}
+$NOTMUCH new > /dev/null
+mv $tmp_msg_filename $gen_msg_filename
+increment_mtime ${MAIL_DIR}
+# output=$(NOTMUCH_NEW)
+# pass_if_equal "$output" "Added 1 new message to the database."
+
+# printf " Renamed message...\t\t\t\t"
+
+generate_message
+$NOTMUCH new > /dev/null
+mv $gen_msg_filename ${gen_msg_filename}-renamed
+increment_mtime ${MAIL_DIR}
+# output=$(NOTMUCH_NEW)
+# pass_if_equal "$output" "No new mail. Detected 1 file rename."
+
+# printf " Deleted message...\t\t\t\t"
+
+rm ${gen_msg_filename}-renamed
+increment_mtime ${MAIL_DIR}
+# output=$(NOTMUCH_NEW)
+# pass_if_equal "$output" "No new mail. Removed 1 message."
+
+# printf " Renamed directory...\t\t\t\t"
+
+generate_message [dir]=dir
+generate_message [dir]=dir
+generate_message [dir]=dir
+
+$NOTMUCH new > /dev/null
+
+mv ${MAIL_DIR}/dir ${MAIL_DIR}/dir-renamed
+increment_mtime ${MAIL_DIR}
+
+# output=$(NOTMUCH_NEW)
+# pass_if_equal "$output" "No new mail. Detected 3 file renames."
+
+# printf " Deleted directory...\t\t\t\t"
+
+rm -rf ${MAIL_DIR}/dir-renamed
+increment_mtime ${MAIL_DIR}
+
+# output=$(NOTMUCH_NEW)
+# pass_if_equal "$output" "No new mail. Removed 3 messages."
+
+# printf " New directory (at end of list)...\t\t"
+
+generate_message [dir]=zzz
+generate_message [dir]=zzz
+generate_message [dir]=zzz
+
+# output=$(NOTMUCH_NEW)
+# pass_if_equal "$output" "Added 3 new messages to the database."
+
+# printf " Deleted directory (end of list)...\t\t"
+
+rm -rf ${MAIL_DIR}/zzz
+increment_mtime ${MAIL_DIR}
+
+# output=$(NOTMUCH_NEW)
+# pass_if_equal "$output" "No new mail. Removed 3 messages."
+
+# printf " New symlink to directory...\t\t\t"
+
+rm -rf ${MAIL_DIR}/.notmuch
+mv ${MAIL_DIR} ${TEST_DIR}/actual_maildir
+
+mkdir ${MAIL_DIR}
+ln -s ${TEST_DIR}/actual_maildir ${MAIL_DIR}/symlink
+
+# output=$(NOTMUCH_NEW)
+# pass_if_equal "$output" "Added 1 new message to the database."
+
+# printf " New symlink to a file...\t\t\t"
+generate_message
+external_msg_filename=${TEST_DIR}/external/$(basename $gen_msg_filename)
+mkdir -p $(dirname $external_msg_filename)
+mv $gen_msg_filename $external_msg_filename
+ln -s $external_msg_filename $gen_msg_filename
+increment_mtime ${MAIL_DIR}
+# output=$(NOTMUCH_NEW)
+# pass_if_equal "$output" "Added 1 new message to the database."
+
+# printf " New two-level directory...\t\t\t"
+
+generate_message [dir]=two/levels
+generate_message [dir]=two/levels
+generate_message [dir]=two/levels
+
+# output=$(NOTMUCH_NEW)
+# pass_if_equal "$output" "Added 3 new messages to the database."
+
+# printf " Deleted two-level directory...\t\t\t"
+
+rm -rf ${MAIL_DIR}/two
+increment_mtime ${MAIL_DIR}
+
+# output=$(NOTMUCH_NEW)
+# pass_if_equal "$output" "No new mail. Removed 3 messages."
diff --git a/test/tests/notmuch-search/00100-search-body.test b/test/tests/notmuch-search/00100-search-body.test
new file mode 100644
index 0000000..a50d2e4
--- /dev/null
+++ b/test/tests/notmuch-search/00100-search-body.test
@@ -0,0 +1,4 @@
+printf " Search body...\t\t\t\t\t"
+add_message '[subject]="body search"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' [body]=bodysearchtest
+output=$($NOTMUCH search bodysearchtest | notmuch_search_sanitize)
+pass_if_equal "$output" "thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; body search (inbox unread)"
diff --git a/test/tests/notmuch-search/00200-search-by-from.test b/test/tests/notmuch-search/00200-search-by-from.test
new file mode 100644
index 0000000..f4944d2
--- /dev/null
+++ b/test/tests/notmuch-search/00200-search-by-from.test
@@ -0,0 +1,4 @@
+printf " Search by from:...\t\t\t\t"
+add_message '[subject]="search by from"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' [from]=searchbyfrom
+output=$($NOTMUCH search from:searchbyfrom | notmuch_search_sanitize)
+pass_if_equal "$output" "thread:XXX   2000-01-01 [1/1] searchbyfrom; search by from (inbox unread)"
diff --git a/test/tests/notmuch-search/00300-search-by-to.test b/test/tests/notmuch-search/00300-search-by-to.test
new file mode 100644
index 0000000..fa9c9af
--- /dev/null
+++ b/test/tests/notmuch-search/00300-search-by-to.test
@@ -0,0 +1,4 @@
+printf " Search by to:...\t\t\t\t"
+add_message '[subject]="search by to"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' [to]=searchbyto
+output=$($NOTMUCH search to:searchbyto | notmuch_search_sanitize)
+pass_if_equal "$output" "thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; search by to (inbox unread)"
diff --git a/test/tests/notmuch-search/00400-search-by-subject.test b/test/tests/notmuch-search/00400-search-by-subject.test
new file mode 100644
index 0000000..ea8d98a
--- /dev/null
+++ b/test/tests/notmuch-search/00400-search-by-subject.test
@@ -0,0 +1,4 @@
+printf " Search by subject:...\t\t\t\t"
+add_message [subject]=subjectsearchtest '[date]="Sat, 01 Jan 2000 12:00:00 -0000"'
+output=$($NOTMUCH search subject:subjectsearchtest | notmuch_search_sanitize)
+pass_if_equal "$output" "thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; subjectsearchtest (inbox unread)"
diff --git a/test/tests/notmuch-search/00500-search-by-id.test b/test/tests/notmuch-search/00500-search-by-id.test
new file mode 100644
index 0000000..4e3a06e
--- /dev/null
+++ b/test/tests/notmuch-search/00500-search-by-id.test
@@ -0,0 +1,4 @@
+printf " Search by id:...\t\t\t\t"
+add_message '[subject]="search by id"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"'
+output=$($NOTMUCH search id:${gen_msg_id} | notmuch_search_sanitize)
+pass_if_equal "$output" "thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; search by id (inbox unread)"
diff --git a/test/tests/notmuch-search/00600-search-by-tag.test b/test/tests/notmuch-search/00600-search-by-tag.test
new file mode 100644
index 0000000..2af2d69
--- /dev/null
+++ b/test/tests/notmuch-search/00600-search-by-tag.test
@@ -0,0 +1,5 @@
+printf " Search by tag:...\t\t\t\t"
+add_message '[subject]="search by tag"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"'
+$NOTMUCH tag +searchbytag id:${gen_msg_id}
+output=$($NOTMUCH search tag:searchbytag | notmuch_search_sanitize)
+pass_if_equal "$output" "thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; search by tag (inbox searchbytag unread)"
diff --git a/test/tests/notmuch-search/00700-search-by-thread.test b/test/tests/notmuch-search/00700-search-by-thread.test
new file mode 100644
index 0000000..9196cbd
--- /dev/null
+++ b/test/tests/notmuch-search/00700-search-by-thread.test
@@ -0,0 +1,5 @@
+printf " Search by thread:...\t\t\t\t"
+add_message '[subject]="search by thread"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"'
+thread_id=$($NOTMUCH search id:${gen_msg_id} | sed -e 's/thread:\([a-f0-9]*\).*/\1/')
+output=$($NOTMUCH search thread:${thread_id} | notmuch_search_sanitize)
+pass_if_equal "$output" "thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; search by thread (inbox unread)"
diff --git a/test/tests/notmuch-search/00800-search-body-phrase.test b/test/tests/notmuch-search/00800-search-body-phrase.test
new file mode 100644
index 0000000..687bf1d
--- /dev/null
+++ b/test/tests/notmuch-search/00800-search-body-phrase.test
@@ -0,0 +1,5 @@
+printf " Search body (phrase)...\t\t\t"
+add_message '[subject]="body search (phrase)"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' '[body]="body search (phrase)"'
+add_message '[subject]="negative result"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' '[body]="This phrase should not match the body search"'
+output=$($NOTMUCH search '\"body search (phrase)\"' | notmuch_search_sanitize)
+pass_if_equal "$output" "thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; body search (phrase) (inbox unread)"
diff --git a/test/tests/notmuch-search/00900-search-by-from-address.test b/test/tests/notmuch-search/00900-search-by-from-address.test
new file mode 100644
index 0000000..a21c336
--- /dev/null
+++ b/test/tests/notmuch-search/00900-search-by-from-address.test
@@ -0,0 +1,4 @@
+printf " Search by from: (address)...\t\t\t"
+add_message '[subject]="search by from (address)"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' [from]=searchbyfrom@example.com
+output=$($NOTMUCH search from:searchbyfrom@example.com | notmuch_search_sanitize)
+pass_if_equal "$output" "thread:XXX   2000-01-01 [1/1] searchbyfrom@example.com; search by from (address) (inbox unread)"
diff --git a/test/tests/notmuch-search/01000-search-by-from-name.test b/test/tests/notmuch-search/01000-search-by-from-name.test
new file mode 100644
index 0000000..2db7078
--- /dev/null
+++ b/test/tests/notmuch-search/01000-search-by-from-name.test
@@ -0,0 +1,4 @@
+printf " Search by from: (name)...\t\t\t"
+add_message '[subject]="search by from (name)"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' '[from]="Search By From Name <test@example.com>"'
+output=$($NOTMUCH search from:'Search By From Name' | notmuch_search_sanitize)
+pass_if_equal "$output" "thread:XXX   2000-01-01 [1/1] Search By From Name; search by from (name) (inbox unread)"
diff --git a/test/tests/notmuch-search/01100-search-by-to-address.test b/test/tests/notmuch-search/01100-search-by-to-address.test
new file mode 100644
index 0000000..514ecaf
--- /dev/null
+++ b/test/tests/notmuch-search/01100-search-by-to-address.test
@@ -0,0 +1,4 @@
+printf " Search by to: (address)...\t\t\t"
+add_message '[subject]="search by to (address)"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' [to]=searchbyto@example.com
+output=$($NOTMUCH search to:searchbyto@example.com | notmuch_search_sanitize)
+pass_if_equal "$output" "thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; search by to (address) (inbox unread)"
diff --git a/test/tests/notmuch-search/01200-search-by-to-name.test b/test/tests/notmuch-search/01200-search-by-to-name.test
new file mode 100644
index 0000000..3069a79
--- /dev/null
+++ b/test/tests/notmuch-search/01200-search-by-to-name.test
@@ -0,0 +1,4 @@
+printf " Search by to: (name)...\t\t\t"
+add_message '[subject]="search by to (name)"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' '[to]="Search By To Name <test@example.com>"'
+output=$($NOTMUCH search to:'Search By To Name' | notmuch_search_sanitize)
+pass_if_equal "$output" "thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; search by to (name) (inbox unread)"
diff --git a/test/tests/notmuch-search/01300-search-by-subject-phrase.test b/test/tests/notmuch-search/01300-search-by-subject-phrase.test
new file mode 100644
index 0000000..c9e1dc6
--- /dev/null
+++ b/test/tests/notmuch-search/01300-search-by-subject-phrase.test
@@ -0,0 +1,5 @@
+printf " Search by subject: (phrase)...\t\t\t"
+add_message '[subject]="subject search test (phrase)"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"'
+add_message '[subject]="this phrase should not match the subject search test"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"'
+output=$($NOTMUCH search 'subject:\"subject search test (phrase)\"' | notmuch_search_sanitize)
+pass_if_equal "$output" "thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; subject search test (phrase) (inbox unread)"
diff --git a/test/tests/notmuch-search/01400-search-for-all-messages.test b/test/tests/notmuch-search/01400-search-for-all-messages.test
new file mode 100644
index 0000000..4120442
--- /dev/null
+++ b/test/tests/notmuch-search/01400-search-for-all-messages.test
@@ -0,0 +1,19 @@
+printf " Search for all messages (\"*\"):...\t\t"
+output=$($NOTMUCH search '*' | notmuch_search_sanitize)
+pass_if_equal "$output" "thread:XXX   2001-01-05 [1/1] Notmuch Test Suite; Test message #6 (inbox unread)
+thread:XXX   2001-01-05 [1/1] Notmuch Test Suite; Test message #14 (inbox unread)
+thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; body search (inbox unread)
+thread:XXX   2000-01-01 [1/1] searchbyfrom; search by from (inbox unread)
+thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; search by to (inbox unread)
+thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; subjectsearchtest (inbox unread)
+thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; search by id (inbox unread)
+thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; search by tag (inbox searchbytag unread)
+thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; search by thread (inbox unread)
+thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; body search (phrase) (inbox unread)
+thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; negative result (inbox unread)
+thread:XXX   2000-01-01 [1/1] searchbyfrom@example.com; search by from (address) (inbox unread)
+thread:XXX   2000-01-01 [1/1] Search By From Name; search by from (name) (inbox unread)
+thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; search by to (address) (inbox unread)
+thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; search by to (name) (inbox unread)
+thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; subject search test (phrase) (inbox unread)
+thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; this phrase should not match the subject search test (inbox unread)"
diff --git a/test/tests/notmuch-search/01500-search-body-utf-8.test b/test/tests/notmuch-search/01500-search-body-utf-8.test
new file mode 100644
index 0000000..413d29d
--- /dev/null
+++ b/test/tests/notmuch-search/01500-search-body-utf-8.test
@@ -0,0 +1,4 @@
+printf " Search body (utf-8):...\t\t\t"
+add_message '[subject]="utf8-message-body-subject"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' '[body]="message body utf8: bödý"'
+output=$($NOTMUCH search 'bödý' | notmuch_search_sanitize)
+pass_if_equal "$output" "thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; utf8-message-body-subject (inbox unread)"
diff --git a/test/tests/notmuch-search/99999-notmuch-search.setup b/test/tests/notmuch-search/99999-notmuch-search.setup
new file mode 100644
index 0000000..ce00cfc
--- /dev/null
+++ b/test/tests/notmuch-search/99999-notmuch-search.setup
@@ -0,0 +1,4 @@
+printf " Cleaning up...\n"
+
+rm -rf ${MAIL_DIR}/* ${MAIL_DIR}/.notmuch
+$NOTMUCH new > /dev/null
diff --git a/test/tests/out-of-order-threading/00001-out-of-order-threading.setup b/test/tests/out-of-order-threading/00001-out-of-order-threading.setup
new file mode 100644
index 0000000..3edc3cb
--- /dev/null
+++ b/test/tests/out-of-order-threading/00001-out-of-order-threading.setup
@@ -0,0 +1,2 @@
+printf "\nTesting threading when messages received out of order:\n"
+printf " Setting up...\n"
diff --git a/test/tests/out-of-order-threading/00100-addinitial-child-message.test b/test/tests/out-of-order-threading/00100-addinitial-child-message.test
new file mode 100644
index 0000000..c2a6588
--- /dev/null
+++ b/test/tests/out-of-order-threading/00100-addinitial-child-message.test
@@ -0,0 +1,4 @@
+printf " Adding initial child message...\t\t"
+generate_message [body]=foo '[in-reply-to]=\<parent-id\>' [subject]=brokenthreadtest '[date]="Sat, 01 Jan 2000 12:00:00 -0000"'
+output=$(NOTMUCH_NEW)
+pass_if_equal "$output" "Added 1 new message to the database."
diff --git a/test/tests/out-of-order-threading/00200-searching-returns-message.test b/test/tests/out-of-order-threading/00200-searching-returns-message.test
new file mode 100644
index 0000000..fbda06d
--- /dev/null
+++ b/test/tests/out-of-order-threading/00200-searching-returns-message.test
@@ -0,0 +1,3 @@
+printf " Searching returns the message...\t\t"
+output=$($NOTMUCH search foo | notmuch_search_sanitize)
+pass_if_equal "$output" "thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; brokenthreadtest (inbox unread)"
diff --git a/test/tests/out-of-order-threading/00300-adding-second-child-message.test b/test/tests/out-of-order-threading/00300-adding-second-child-message.test
new file mode 100644
index 0000000..1d3ac41
--- /dev/null
+++ b/test/tests/out-of-order-threading/00300-adding-second-child-message.test
@@ -0,0 +1,4 @@
+printf " Adding second child message...\t\t\t"
+generate_message [body]=foo '[in-reply-to]=\<parent-id\>' [subject]=brokenthreadtest '[date]="Sat, 01 Jan 2000 12:00:00 -0000"'
+output=$(NOTMUCH_NEW)
+pass_if_equal "$output" "Added 1 new message to the database."
diff --git a/test/tests/out-of-order-threading/00400-searching-returns-both-msgs.test b/test/tests/out-of-order-threading/00400-searching-returns-both-msgs.test
new file mode 100644
index 0000000..9b1483e
--- /dev/null
+++ b/test/tests/out-of-order-threading/00400-searching-returns-both-msgs.test
@@ -0,0 +1,3 @@
+printf " Searching returns both messages in one thread..."
+output=$($NOTMUCH search foo | notmuch_search_sanitize)
+pass_if_equal "$output" "thread:XXX   2000-01-01 [2/2] Notmuch Test Suite; brokenthreadtest (inbox unread)"
diff --git a/test/tests/out-of-order-threading/00500-adding-parent-msg.test b/test/tests/out-of-order-threading/00500-adding-parent-msg.test
new file mode 100644
index 0000000..c77c0ae
--- /dev/null
+++ b/test/tests/out-of-order-threading/00500-adding-parent-msg.test
@@ -0,0 +1,4 @@
+printf " Adding parent message...\t\t\t"
+generate_message [body]=foo [id]=parent-id [subject]=brokenthreadtest '[date]="Sat, 01 Jan 2000 12:00:00 -0000"'
+output=$(NOTMUCH_NEW)
+pass_if_equal "$output" "Added 1 new message to the database."
diff --git a/test/tests/out-of-order-threading/00600-return-all-msgs-in-one-thread.test b/test/tests/out-of-order-threading/00600-return-all-msgs-in-one-thread.test
new file mode 100644
index 0000000..91ea3c2
--- /dev/null
+++ b/test/tests/out-of-order-threading/00600-return-all-msgs-in-one-thread.test
@@ -0,0 +1,3 @@
+printf " Searching returns all three messages in one thread..."
+output=$($NOTMUCH search foo | notmuch_search_sanitize)
+pass_if_equal "$output" "thread:XXX   2000-01-01 [3/3] Notmuch Test Suite; brokenthreadtest (inbox unread)"
diff --git a/test/tests/out-of-order-threading/99999-out-of-order-threading.setup b/test/tests/out-of-order-threading/99999-out-of-order-threading.setup
new file mode 100644
index 0000000..ce00cfc
--- /dev/null
+++ b/test/tests/out-of-order-threading/99999-out-of-order-threading.setup
@@ -0,0 +1,4 @@
+printf " Cleaning up...\n"
+
+rm -rf ${MAIL_DIR}/* ${MAIL_DIR}/.notmuch
+$NOTMUCH new > /dev/null
diff --git a/test/tests/thread-naming/00001-thread-naming.setup b/test/tests/thread-naming/00001-thread-naming.setup
new file mode 100644
index 0000000..cc0d764
--- /dev/null
+++ b/test/tests/thread-naming/00001-thread-naming.setup
@@ -0,0 +1,17 @@
+printf "\nTesting naming of threads with changing subject:\n"
+printf " Setting up...\n"
+
+add_message '[subject]="thread-naming: Initial thread subject"' \
+            '[date]="Fri, 05 Jan 2001 15:43:56 -0800"'
+first=${gen_msg_cnt}
+parent=${gen_msg_id}
+add_message '[subject]="thread-naming: Older changed subject"' \
+            '[date]="Sat, 06 Jan 2001 15:43:56 -0800"' \
+            "[in-reply-to]=\<$parent\>"
+add_message '[subject]="thread-naming: Newer changed subject"' \
+            '[date]="Sun, 07 Jan 2001 15:43:56 -0800"' \
+            "[in-reply-to]=\<$parent\>"
+add_message '[subject]="thread-naming: Final thread subject"' \
+            '[date]="Mon, 08 Jan 2001 15:43:56 -0800"' \
+            "[in-reply-to]=\<$parent\>"
+final=${gen_msg_id}
diff --git a/test/tests/thread-naming/00100-initial-thread-name-oldest-first-search.test b/test/tests/thread-naming/00100-initial-thread-name-oldest-first-search.test
new file mode 100644
index 0000000..482a7f4
--- /dev/null
+++ b/test/tests/thread-naming/00100-initial-thread-name-oldest-first-search.test
@@ -0,0 +1,3 @@
+printf " Initial thread name (oldest-first search)...\t"
+output=$($NOTMUCH search --sort=oldest-first thread-naming and tag:inbox | notmuch_search_sanitize)
+pass_if_equal "$output" "thread:XXX   2001-01-05 [4/4] Notmuch Test Suite; thread-naming: Initial thread subject (inbox unread)"
diff --git a/test/tests/thread-naming/00200-initial-thread-name-newest-first-search.test b/test/tests/thread-naming/00200-initial-thread-name-newest-first-search.test
new file mode 100644
index 0000000..799ed66
--- /dev/null
+++ b/test/tests/thread-naming/00200-initial-thread-name-newest-first-search.test
@@ -0,0 +1,3 @@
+printf " Initial thread name (newest-first search)...\t"
+output=$($NOTMUCH search --sort=newest-first thread-naming and tag:inbox | notmuch_search_sanitize)
+pass_if_equal "$output" "thread:XXX   2001-01-08 [4/4] Notmuch Test Suite; thread-naming: Final thread subject (inbox unread)"
diff --git a/test/tests/thread-naming/00300-changed-thread-name-oldest-first-search.test b/test/tests/thread-naming/00300-changed-thread-name-oldest-first-search.test
new file mode 100644
index 0000000..5d300d6
--- /dev/null
+++ b/test/tests/thread-naming/00300-changed-thread-name-oldest-first-search.test
@@ -0,0 +1,6 @@
+# Remove oldest and newest messages from search results
+$NOTMUCH tag -inbox id:$parent or id:$final
+
+printf " Changed thread name (oldest-first search)...\t"
+output=$($NOTMUCH search --sort=oldest-first thread-naming and tag:inbox | notmuch_search_sanitize)
+pass_if_equal "$output" "thread:XXX   2001-01-06 [2/4] Notmuch Test Suite; thread-naming: Older changed subject (inbox unread)"
diff --git a/test/tests/thread-naming/00400-changed-thread-name-newest-first-search.test b/test/tests/thread-naming/00400-changed-thread-name-newest-first-search.test
new file mode 100644
index 0000000..f412770
--- /dev/null
+++ b/test/tests/thread-naming/00400-changed-thread-name-newest-first-search.test
@@ -0,0 +1,3 @@
+printf " Changed thread name (newest-first search)...\t"
+output=$($NOTMUCH search --sort=newest-first thread-naming and tag:inbox | notmuch_search_sanitize)
+pass_if_equal "$output" "thread:XXX   2001-01-07 [2/4] Notmuch Test Suite; thread-naming: Newer changed subject (inbox unread)"
diff --git a/test/tests/thread-naming/00500-ignore-added-reply-prefix-re.test b/test/tests/thread-naming/00500-ignore-added-reply-prefix-re.test
new file mode 100644
index 0000000..7c1544a
--- /dev/null
+++ b/test/tests/thread-naming/00500-ignore-added-reply-prefix-re.test
@@ -0,0 +1,6 @@
+printf " Ignore added reply prefix (Re:)...\t\t"
+add_message '[subject]="Re: thread-naming: Initial thread subject"' \
+            '[date]="Tue, 09 Jan 2001 15:43:45 -0800"' \
+            "[in-reply-to]=\<$parent\>"
+output=$($NOTMUCH search --sort=newest-first thread-naming and tag:inbox | notmuch_search_sanitize)
+pass_if_equal "$output" "thread:XXX   2001-01-09 [3/5] Notmuch Test Suite; thread-naming: Initial thread subject (inbox unread)"
diff --git a/test/tests/thread-naming/00600-ignore-added-reply-prefix-aw.test b/test/tests/thread-naming/00600-ignore-added-reply-prefix-aw.test
new file mode 100644
index 0000000..d279fd1
--- /dev/null
+++ b/test/tests/thread-naming/00600-ignore-added-reply-prefix-aw.test
@@ -0,0 +1,6 @@
+printf " Ignore added reply prefix (Aw:)...\t\t"
+add_message '[subject]="Aw: thread-naming: Initial thread subject"' \
+            '[date]="Wed, 10 Jan 2001 15:43:45 -0800"' \
+            "[in-reply-to]=\<$parent\>"
+output=$($NOTMUCH search --sort=newest-first thread-naming and tag:inbox | notmuch_search_sanitize)
+pass_if_equal "$output" "thread:XXX   2001-01-10 [4/6] Notmuch Test Suite; thread-naming: Initial thread subject (inbox unread)"
diff --git a/test/tests/thread-naming/00700-ignore-added-reply-prefix-vs.test b/test/tests/thread-naming/00700-ignore-added-reply-prefix-vs.test
new file mode 100644
index 0000000..02b6b0e
--- /dev/null
+++ b/test/tests/thread-naming/00700-ignore-added-reply-prefix-vs.test
@@ -0,0 +1,6 @@
+printf " Ignore added reply prefix (Vs:)...\t\t"
+add_message '[subject]="Vs: thread-naming: Initial thread subject"' \
+            '[date]="Thu, 11 Jan 2001 15:43:45 -0800"' \
+            "[in-reply-to]=\<$parent\>"
+output=$($NOTMUCH search --sort=newest-first thread-naming and tag:inbox | notmuch_search_sanitize)
+pass_if_equal "$output" "thread:XXX   2001-01-11 [5/7] Notmuch Test Suite; thread-naming: Initial thread subject (inbox unread)"
diff --git a/test/tests/thread-naming/00800-ignore-added-reply-prefix-sv.test b/test/tests/thread-naming/00800-ignore-added-reply-prefix-sv.test
new file mode 100644
index 0000000..1014ece
--- /dev/null
+++ b/test/tests/thread-naming/00800-ignore-added-reply-prefix-sv.test
@@ -0,0 +1,6 @@
+printf " Ignore added reply prefix (Sv:)...\t\t"
+add_message '[subject]="Sv: thread-naming: Initial thread subject"' \
+            '[date]="Fri, 12 Jan 2001 15:43:45 -0800"' \
+            "[in-reply-to]=\<$parent\>"
+output=$($NOTMUCH search --sort=newest-first thread-naming and tag:inbox | notmuch_search_sanitize)
+pass_if_equal "$output" "thread:XXX   2001-01-12 [6/8] Notmuch Test Suite; thread-naming: Initial thread subject (inbox unread)"
diff --git a/test/tests/thread-naming/00900-test-order-of-messages-in-nm-show.test b/test/tests/thread-naming/00900-test-order-of-messages-in-nm-show.test
new file mode 100644
index 0000000..61af4c1
--- /dev/null
+++ b/test/tests/thread-naming/00900-test-order-of-messages-in-nm-show.test
@@ -0,0 +1,114 @@
+printf " Test order of messages in \"notmuch show\"\t"
+output=$($NOTMUCH show thread-naming | notmuch_show_sanitize)
+pass_if_equal "$output" "\fmessage{ id:msg-$(printf "%03d" $first)@notmuch-test-suite depth:0 match:1 filename:/XXX/mail/msg-$(printf "%03d" $first)
+\fheader{
+Notmuch Test Suite <test_suite@notmuchmail.org> (2001-01-05) (unread)
+Subject: thread-naming: Initial thread subject
+From: Notmuch Test Suite <test_suite@notmuchmail.org>
+To: Notmuch Test Suite <test_suite@notmuchmail.org>
+Date: Fri, 05 Jan 2001 15:43:56 -0800
+\fheader}
+\fbody{
+\fpart{ ID: 1, Content-type: text/plain
+This is just a test message (#$first)
+\fpart}
+\fbody}
+\fmessage}
+\fmessage{ id:msg-$(printf "%03d" $((first + 1)))@notmuch-test-suite depth:1 match:1 filename:/XXX/mail/msg-$(printf "%03d" $((first + 1)))
+\fheader{
+Notmuch Test Suite <test_suite@notmuchmail.org> (2001-01-06) (inbox unread)
+Subject: thread-naming: Older changed subject
+From: Notmuch Test Suite <test_suite@notmuchmail.org>
+To: Notmuch Test Suite <test_suite@notmuchmail.org>
+Date: Sat, 06 Jan 2001 15:43:56 -0800
+\fheader}
+\fbody{
+\fpart{ ID: 1, Content-type: text/plain
+This is just a test message (#$((first + 1)))
+\fpart}
+\fbody}
+\fmessage}
+\fmessage{ id:msg-$(printf "%03d" $((first + 2)))@notmuch-test-suite depth:1 match:1 filename:/XXX/mail/msg-$(printf "%03d" $((first + 2)))
+\fheader{
+Notmuch Test Suite <test_suite@notmuchmail.org> (2001-01-07) (inbox unread)
+Subject: thread-naming: Newer changed subject
+From: Notmuch Test Suite <test_suite@notmuchmail.org>
+To: Notmuch Test Suite <test_suite@notmuchmail.org>
+Date: Sun, 07 Jan 2001 15:43:56 -0800
+\fheader}
+\fbody{
+\fpart{ ID: 1, Content-type: text/plain
+This is just a test message (#$((first + 2)))
+\fpart}
+\fbody}
+\fmessage}
+\fmessage{ id:msg-$(printf "%03d" $((first + 3)))@notmuch-test-suite depth:1 match:1 filename:/XXX/mail/msg-$(printf "%03d" $((first + 3)))
+\fheader{
+Notmuch Test Suite <test_suite@notmuchmail.org> (2001-01-08) (unread)
+Subject: thread-naming: Final thread subject
+From: Notmuch Test Suite <test_suite@notmuchmail.org>
+To: Notmuch Test Suite <test_suite@notmuchmail.org>
+Date: Mon, 08 Jan 2001 15:43:56 -0800
+\fheader}
+\fbody{
+\fpart{ ID: 1, Content-type: text/plain
+This is just a test message (#$((first + 3)))
+\fpart}
+\fbody}
+\fmessage}
+\fmessage{ id:msg-$(printf "%03d" $((first + 4)))@notmuch-test-suite depth:1 match:1 filename:/XXX/mail/msg-$(printf "%03d" $((first + 4)))
+\fheader{
+Notmuch Test Suite <test_suite@notmuchmail.org> (2001-01-09) (inbox unread)
+Subject: Re: thread-naming: Initial thread subject
+From: Notmuch Test Suite <test_suite@notmuchmail.org>
+To: Notmuch Test Suite <test_suite@notmuchmail.org>
+Date: Tue, 09 Jan 2001 15:43:45 -0800
+\fheader}
+\fbody{
+\fpart{ ID: 1, Content-type: text/plain
+This is just a test message (#$((first + 4)))
+\fpart}
+\fbody}
+\fmessage}
+\fmessage{ id:msg-$(printf "%03d" $((first + 5)))@notmuch-test-suite depth:1 match:1 filename:/XXX/mail/msg-$(printf "%03d" $((first + 5)))
+\fheader{
+Notmuch Test Suite <test_suite@notmuchmail.org> (2001-01-10) (inbox unread)
+Subject: Aw: thread-naming: Initial thread subject
+From: Notmuch Test Suite <test_suite@notmuchmail.org>
+To: Notmuch Test Suite <test_suite@notmuchmail.org>
+Date: Wed, 10 Jan 2001 15:43:45 -0800
+\fheader}
+\fbody{
+\fpart{ ID: 1, Content-type: text/plain
+This is just a test message (#$((first + 5)))
+\fpart}
+\fbody}
+\fmessage}
+\fmessage{ id:msg-$(printf "%03d" $((first + 6)))@notmuch-test-suite depth:1 match:1 filename:/XXX/mail/msg-$(printf "%03d" $((first + 6)))
+\fheader{
+Notmuch Test Suite <test_suite@notmuchmail.org> (2001-01-11) (inbox unread)
+Subject: Vs: thread-naming: Initial thread subject
+From: Notmuch Test Suite <test_suite@notmuchmail.org>
+To: Notmuch Test Suite <test_suite@notmuchmail.org>
+Date: Thu, 11 Jan 2001 15:43:45 -0800
+\fheader}
+\fbody{
+\fpart{ ID: 1, Content-type: text/plain
+This is just a test message (#$((first + 6)))
+\fpart}
+\fbody}
+\fmessage}
+\fmessage{ id:msg-$(printf "%03d" $((first + 7)))@notmuch-test-suite depth:1 match:1 filename:/XXX/mail/msg-$(printf "%03d" $((first + 7)))
+\fheader{
+Notmuch Test Suite <test_suite@notmuchmail.org> (2001-01-12) (inbox unread)
+Subject: Sv: thread-naming: Initial thread subject
+From: Notmuch Test Suite <test_suite@notmuchmail.org>
+To: Notmuch Test Suite <test_suite@notmuchmail.org>
+Date: Fri, 12 Jan 2001 15:43:45 -0800
+\fheader}
+\fbody{
+\fpart{ ID: 1, Content-type: text/plain
+This is just a test message (#$((first + 7)))
+\fpart}
+\fbody}
+\fmessage}"
diff --git a/test/tests/thread-naming/99999-thread-naming.setup b/test/tests/thread-naming/99999-thread-naming.setup
new file mode 100644
index 0000000..ce00cfc
--- /dev/null
+++ b/test/tests/thread-naming/99999-thread-naming.setup
@@ -0,0 +1,4 @@
+printf " Cleaning up...\n"
+
+rm -rf ${MAIL_DIR}/* ${MAIL_DIR}/.notmuch
+$NOTMUCH new > /dev/null
diff --git a/test/tests/uuencoded/00001-uuencoded.setup b/test/tests/uuencoded/00001-uuencoded.setup
new file mode 100644
index 0000000..11e6694
--- /dev/null
+++ b/test/tests/uuencoded/00001-uuencoded.setup
@@ -0,0 +1,19 @@
+printf "\nTesting handling of uuencoded data:\n"
+printf " Setting up...\n"
+
+add_message [subject]=uuencodetest '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' \
+'[body]="This message is used to ensure that notmuch correctly handles a
+message containing a block of uuencoded data. First, we have a marker
+this content beforeuudata . Then we beging the uunencoded data itself:
+
+begin 644 bogus-uuencoded-data
+M0123456789012345678901234567890123456789012345678901234567890
+MOBVIOUSLY, THIS IS NOT ANY SORT OF USEFUL UUNECODED DATA.
+MINSTEAD THIS IS JUST A WAY TO ENSURE THAT THIS BLOCK OF DATA
+MIS CORRECTLY IGNORED WHEN NOTMUCH CREATES ITS INDEX. SO WE
+MINCLUDE A DURINGUUDATA MARKER THAT SHOULD NOT RESULT IN ANY
+MSEARCH RESULT.
+\`
+end
+
+Finally, we have our afteruudata marker as well."'
diff --git a/test/tests/uuencoded/00100-index-content-before-uu.test b/test/tests/uuencoded/00100-index-content-before-uu.test
new file mode 100644
index 0000000..97d04a8
--- /dev/null
+++ b/test/tests/uuencoded/00100-index-content-before-uu.test
@@ -0,0 +1,3 @@
+printf " Ensure content before uu data is indexed...\t"
+output=$($NOTMUCH search beforeuudata | notmuch_search_sanitize)
+pass_if_equal "$output" "thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; uuencodetest (inbox unread)"
diff --git a/test/tests/uuencoded/00200-dont-index-uu-data.test b/test/tests/uuencoded/00200-dont-index-uu-data.test
new file mode 100644
index 0000000..dcfe41e
--- /dev/null
+++ b/test/tests/uuencoded/00200-dont-index-uu-data.test
@@ -0,0 +1,3 @@
+printf " Ensure uu data is not indexed...\t\t"
+output=$($NOTMUCH search DURINGUUDATA | notmuch_search_sanitize)
+pass_if_equal "$output" ""
diff --git a/test/tests/uuencoded/00300-index-data-after-uu.test b/test/tests/uuencoded/00300-index-data-after-uu.test
new file mode 100644
index 0000000..1cd7221
--- /dev/null
+++ b/test/tests/uuencoded/00300-index-data-after-uu.test
@@ -0,0 +1,3 @@
+printf " Ensure content after uu data is indexed...\t"
+output=$($NOTMUCH search afteruudata | notmuch_search_sanitize)
+pass_if_equal "$output" "thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; uuencodetest (inbox unread)"
diff --git a/test/tests/uuencoded/99999-uuencoded.setup b/test/tests/uuencoded/99999-uuencoded.setup
new file mode 100644
index 0000000..ce00cfc
--- /dev/null
+++ b/test/tests/uuencoded/99999-uuencoded.setup
@@ -0,0 +1,4 @@
+printf " Cleaning up...\n"
+
+rm -rf ${MAIL_DIR}/* ${MAIL_DIR}/.notmuch
+$NOTMUCH new > /dev/null
-- 
1.6.3.3

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/2] test: Have notmuch-test use the modular test collections
  2010-04-30 19:07 ` [PATCH 1/2] test: add modular test collections Jesse Rosenthal
@ 2010-04-30 19:09   ` Jesse Rosenthal
  2010-05-05  4:46     ` Jesse Rosenthal
  0 siblings, 1 reply; 8+ messages in thread
From: Jesse Rosenthal @ 2010-04-30 19:09 UTC (permalink / raw)
  To: Notmuch developer list

Introduce two new functions (run_collection_setup_and_tests and
run_test_suite) to notmuch-test. The first takes as an argument a subdir
of test/tests and runs all .setup and .test files in there in order of
their numerical prefix. The latter either runs all tests (if given "all"
or no argument) or a given dir (if given it as an argument).

Also introduce the variable TEST_COLLECTIONS. These are all the folders
that "notmuch-test all" should look for. It won't automatically run all
folders, in case there is something that is only relevant in certain
circumstances (such as, perhaps, future tests for remote usage).
---
 test/notmuch-test |  921 +++--------------------------------------------------
 1 files changed, 47 insertions(+), 874 deletions(-)

diff --git a/test/notmuch-test b/test/notmuch-test
index a861df1..29d5c91 100755
--- a/test/notmuch-test
+++ b/test/notmuch-test
@@ -7,6 +7,20 @@ set -e
 # without regard to the time zone of where the test suite is run.
 export TZ=UTC+8
 
+TEST_COLLECTION_DIR="$(dirname $(readlink -f $0))/tests"
+
+TEST_COLLECTIONS="notmuch-new
+notmuch-search
+json
+thread-naming
+notmuch-reply
+uuencoded
+notmuch-dump-restore
+out-of-order-threading
+author-reordering
+from-guessing-multiple
+from-guessing-single"
+
 find_notmuch_binary ()
 {
     dir=$1
@@ -210,13 +224,15 @@ notmuch_show_sanitize ()
     sed -e "$NOTMUCH_SHOW_FILENAME_SQUELCH"
 }
 
-rm -rf ${TEST_DIR}
-mkdir ${TEST_DIR}
-cd ${TEST_DIR}
+initialize_notmuch_test ()
+{
+    rm -rf ${TEST_DIR}
+    mkdir ${TEST_DIR}
+    cd ${TEST_DIR}
 
-mkdir ${MAIL_DIR}
+    mkdir ${MAIL_DIR}
 
-cat <<EOF > ${NOTMUCH_CONFIG}
+    cat <<EOF > ${NOTMUCH_CONFIG}
 [database]
 path=${MAIL_DIR}
 
@@ -225,878 +241,35 @@ name=Notmuch Test Suite
 primary_email=test_suite@notmuchmail.org
 other_email=test_suite_other@notmuchmail.org;test_suite@otherdomain.org
 EOF
+}
 
-printf "Testing \"notmuch new\" in several variations:\n"
-printf " No new messages...\t\t\t\t"
-output=$(NOTMUCH_NEW)
-pass_if_equal "$output" "No new mail."
-
-printf " Single new message...\t\t\t\t"
-generate_message
-output=$(NOTMUCH_NEW)
-pass_if_equal "$output" "Added 1 new message to the database."
-
-printf " Multiple new messages...\t\t\t"
-generate_message
-generate_message
-output=$(NOTMUCH_NEW)
-pass_if_equal "$output" "Added 2 new messages to the database."
-
-printf " No new messages (non-empty DB)...\t\t"
-output=$(NOTMUCH_NEW)
-pass_if_equal "$output" "No new mail."
-
-printf " New directories...\t\t\t\t"
-rm -rf ${MAIL_DIR}/* ${MAIL_DIR}/.notmuch
-mkdir ${MAIL_DIR}/def
-mkdir ${MAIL_DIR}/ghi
-generate_message [dir]=def
-
-output=$(NOTMUCH_NEW)
-pass_if_equal "$output" "Added 1 new message to the database."
-
-printf " Alternate inode order...\t\t\t"
-
-rm -rf ${MAIL_DIR}/.notmuch
-mv ${MAIL_DIR}/ghi ${MAIL_DIR}/abc
-rm ${MAIL_DIR}/def/*
-generate_message [dir]=abc
-
-output=$(NOTMUCH_NEW)
-pass_if_equal "$output" "Added 1 new message to the database."
-
-printf " Message moved in...\t\t\t\t"
-rm -rf ${MAIL_DIR}/* ${MAIL_DIR}/.notmuch
-generate_message
-tmp_msg_filename=tmp/$gen_msg_filename
-mkdir -p $(dirname $tmp_msg_filename)
-mv $gen_msg_filename $tmp_msg_filename
-increment_mtime ${MAIL_DIR}
-$NOTMUCH new > /dev/null
-mv $tmp_msg_filename $gen_msg_filename
-increment_mtime ${MAIL_DIR}
-output=$(NOTMUCH_NEW)
-pass_if_equal "$output" "Added 1 new message to the database."
-
-printf " Renamed message...\t\t\t\t"
-
-generate_message
-$NOTMUCH new > /dev/null
-mv $gen_msg_filename ${gen_msg_filename}-renamed
-increment_mtime ${MAIL_DIR}
-output=$(NOTMUCH_NEW)
-pass_if_equal "$output" "No new mail. Detected 1 file rename."
-
-printf " Deleted message...\t\t\t\t"
-
-rm ${gen_msg_filename}-renamed
-increment_mtime ${MAIL_DIR}
-output=$(NOTMUCH_NEW)
-pass_if_equal "$output" "No new mail. Removed 1 message."
-
-printf " Renamed directory...\t\t\t\t"
-
-generate_message [dir]=dir
-generate_message [dir]=dir
-generate_message [dir]=dir
-
-$NOTMUCH new > /dev/null
-
-mv ${MAIL_DIR}/dir ${MAIL_DIR}/dir-renamed
-increment_mtime ${MAIL_DIR}
-
-output=$(NOTMUCH_NEW)
-pass_if_equal "$output" "No new mail. Detected 3 file renames."
-
-printf " Deleted directory...\t\t\t\t"
-
-rm -rf ${MAIL_DIR}/dir-renamed
-increment_mtime ${MAIL_DIR}
-
-output=$(NOTMUCH_NEW)
-pass_if_equal "$output" "No new mail. Removed 3 messages."
-
-printf " New directory (at end of list)...\t\t"
-
-generate_message [dir]=zzz
-generate_message [dir]=zzz
-generate_message [dir]=zzz
-
-output=$(NOTMUCH_NEW)
-pass_if_equal "$output" "Added 3 new messages to the database."
-
-printf " Deleted directory (end of list)...\t\t"
-
-rm -rf ${MAIL_DIR}/zzz
-increment_mtime ${MAIL_DIR}
-
-output=$(NOTMUCH_NEW)
-pass_if_equal "$output" "No new mail. Removed 3 messages."
-
-printf " New symlink to directory...\t\t\t"
-
-rm -rf ${MAIL_DIR}/.notmuch
-mv ${MAIL_DIR} ${TEST_DIR}/actual_maildir
-
-mkdir ${MAIL_DIR}
-ln -s ${TEST_DIR}/actual_maildir ${MAIL_DIR}/symlink
-
-output=$(NOTMUCH_NEW)
-pass_if_equal "$output" "Added 1 new message to the database."
-
-printf " New symlink to a file...\t\t\t"
-generate_message
-external_msg_filename=${TEST_DIR}/external/$(basename $gen_msg_filename)
-mkdir -p $(dirname $external_msg_filename)
-mv $gen_msg_filename $external_msg_filename
-ln -s $external_msg_filename $gen_msg_filename
-increment_mtime ${MAIL_DIR}
-output=$(NOTMUCH_NEW)
-pass_if_equal "$output" "Added 1 new message to the database."
-
-printf " New two-level directory...\t\t\t"
-
-generate_message [dir]=two/levels
-generate_message [dir]=two/levels
-generate_message [dir]=two/levels
-
-output=$(NOTMUCH_NEW)
-pass_if_equal "$output" "Added 3 new messages to the database."
-
-printf " Deleted two-level directory...\t\t\t"
-
-rm -rf ${MAIL_DIR}/two
-increment_mtime ${MAIL_DIR}
-
-output=$(NOTMUCH_NEW)
-pass_if_equal "$output" "No new mail. Removed 3 messages."
-
-printf "\nTesting \"notmuch search\" in several variations:\n"
-
-printf " Search body...\t\t\t\t\t"
-add_message '[subject]="body search"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' [body]=bodysearchtest
-output=$($NOTMUCH search bodysearchtest | notmuch_search_sanitize)
-pass_if_equal "$output" "thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; body search (inbox unread)"
-
-printf " Search by from:...\t\t\t\t"
-add_message '[subject]="search by from"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' [from]=searchbyfrom
-output=$($NOTMUCH search from:searchbyfrom | notmuch_search_sanitize)
-pass_if_equal "$output" "thread:XXX   2000-01-01 [1/1] searchbyfrom; search by from (inbox unread)"
-
-printf " Search by to:...\t\t\t\t"
-add_message '[subject]="search by to"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' [to]=searchbyto
-output=$($NOTMUCH search to:searchbyto | notmuch_search_sanitize)
-pass_if_equal "$output" "thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; search by to (inbox unread)"
-
-printf " Search by subject:...\t\t\t\t"
-add_message [subject]=subjectsearchtest '[date]="Sat, 01 Jan 2000 12:00:00 -0000"'
-output=$($NOTMUCH search subject:subjectsearchtest | notmuch_search_sanitize)
-pass_if_equal "$output" "thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; subjectsearchtest (inbox unread)"
-
-printf " Search by id:...\t\t\t\t"
-add_message '[subject]="search by id"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"'
-output=$($NOTMUCH search id:${gen_msg_id} | notmuch_search_sanitize)
-pass_if_equal "$output" "thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; search by id (inbox unread)"
-
-printf " Search by tag:...\t\t\t\t"
-add_message '[subject]="search by tag"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"'
-$NOTMUCH tag +searchbytag id:${gen_msg_id}
-output=$($NOTMUCH search tag:searchbytag | notmuch_search_sanitize)
-pass_if_equal "$output" "thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; search by tag (inbox searchbytag unread)"
-
-printf " Search by thread:...\t\t\t\t"
-add_message '[subject]="search by thread"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"'
-thread_id=$($NOTMUCH search id:${gen_msg_id} | sed -e 's/thread:\([a-f0-9]*\).*/\1/')
-output=$($NOTMUCH search thread:${thread_id} | notmuch_search_sanitize)
-pass_if_equal "$output" "thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; search by thread (inbox unread)"
-
-printf " Search body (phrase)...\t\t\t"
-add_message '[subject]="body search (phrase)"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' '[body]="body search (phrase)"'
-add_message '[subject]="negative result"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' '[body]="This phrase should not match the body search"'
-output=$($NOTMUCH search '\"body search (phrase)\"' | notmuch_search_sanitize)
-pass_if_equal "$output" "thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; body search (phrase) (inbox unread)"
-
-printf " Search by from: (address)...\t\t\t"
-add_message '[subject]="search by from (address)"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' [from]=searchbyfrom@example.com
-output=$($NOTMUCH search from:searchbyfrom@example.com | notmuch_search_sanitize)
-pass_if_equal "$output" "thread:XXX   2000-01-01 [1/1] searchbyfrom@example.com; search by from (address) (inbox unread)"
-
-printf " Search by from: (name)...\t\t\t"
-add_message '[subject]="search by from (name)"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' '[from]="Search By From Name <test@example.com>"'
-output=$($NOTMUCH search from:'Search By From Name' | notmuch_search_sanitize)
-pass_if_equal "$output" "thread:XXX   2000-01-01 [1/1] Search By From Name; search by from (name) (inbox unread)"
-
-printf " Search by to: (address)...\t\t\t"
-add_message '[subject]="search by to (address)"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' [to]=searchbyto@example.com
-output=$($NOTMUCH search to:searchbyto@example.com | notmuch_search_sanitize)
-pass_if_equal "$output" "thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; search by to (address) (inbox unread)"
-
-printf " Search by to: (name)...\t\t\t"
-add_message '[subject]="search by to (name)"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' '[to]="Search By To Name <test@example.com>"'
-output=$($NOTMUCH search to:'Search By To Name' | notmuch_search_sanitize)
-pass_if_equal "$output" "thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; search by to (name) (inbox unread)"
-
-printf " Search by subject: (phrase)...\t\t\t"
-add_message '[subject]="subject search test (phrase)"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"'
-add_message '[subject]="this phrase should not match the subject search test"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"'
-output=$($NOTMUCH search 'subject:\"subject search test (phrase)\"' | notmuch_search_sanitize)
-pass_if_equal "$output" "thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; subject search test (phrase) (inbox unread)"
-
-printf " Search for all messages (\"*\"):...\t\t"
-output=$($NOTMUCH search '*' | notmuch_search_sanitize)
-pass_if_equal "$output" "thread:XXX   2001-01-05 [1/1] Notmuch Test Suite; Test message #6 (inbox unread)
-thread:XXX   2001-01-05 [1/1] Notmuch Test Suite; Test message #14 (inbox unread)
-thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; body search (inbox unread)
-thread:XXX   2000-01-01 [1/1] searchbyfrom; search by from (inbox unread)
-thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; search by to (inbox unread)
-thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; subjectsearchtest (inbox unread)
-thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; search by id (inbox unread)
-thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; search by tag (inbox searchbytag unread)
-thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; search by thread (inbox unread)
-thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; body search (phrase) (inbox unread)
-thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; negative result (inbox unread)
-thread:XXX   2000-01-01 [1/1] searchbyfrom@example.com; search by from (address) (inbox unread)
-thread:XXX   2000-01-01 [1/1] Search By From Name; search by from (name) (inbox unread)
-thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; search by to (address) (inbox unread)
-thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; search by to (name) (inbox unread)
-thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; subject search test (phrase) (inbox unread)
-thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; this phrase should not match the subject search test (inbox unread)"
-
-printf " Search body (utf-8):...\t\t\t"
-add_message '[subject]="utf8-message-body-subject"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' '[body]="message body utf8: bödý"'
-output=$($NOTMUCH search 'bödý' | notmuch_search_sanitize)
-pass_if_equal "$output" "thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; utf8-message-body-subject (inbox unread)"
-
-printf "\nTesting --format=json output:\n"
-
-printf " Show message: json...\t\t\t\t"
-add_message '[subject]="json-show-subject"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' '[body]="json-show-message"'
-output=$($NOTMUCH show --format=json 'json-show-message')
-pass_if_equal "$output" '[[[{"id": "'${gen_msg_id}'", "match": true, "filename": "'${gen_msg_filename}'", "timestamp": 946728000, "date_relative": "2000-01-01", "tags": ["inbox","unread"], "headers": {"Subject": "json-show-subject", "From": "Notmuch Test Suite <test_suite@notmuchmail.org>", "To": "Notmuch Test Suite <test_suite@notmuchmail.org>", "Cc": "", "Bcc": "", "Date": "Sat, 01 Jan 2000 12:00:00 -0000"}, "body": [{"id": 1, "content-type": "text/plain", "content": "json-show-message\n"}]}, []]]]'
-
-printf " Search message: json...\t\t\t"
-add_message '[subject]="json-search-subject"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' '[body]="json-search-message"'
-output=$($NOTMUCH search --format=json 'json-search-message' | notmuch_search_sanitize)
-pass_if_equal "$output" '[{"thread": "XXX",
-"timestamp": 946728000,
-"matched": 1,
-"total": 1,
-"authors": "Notmuch Test Suite",
-"subject": "json-search-subject",
-"tags": ["inbox", "unread"]}]'
-
-printf " Search by subject (utf-8):...\t\t\t"
-add_message [subject]=utf8-sübjéct '[date]="Sat, 01 Jan 2000 12:00:00 -0000"'
-output=$($NOTMUCH search subject:utf8-sübjéct | notmuch_search_sanitize)
-pass_if_equal "$output" "thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; utf8-sübjéct (inbox unread)"
-
-printf " Show message: json, utf-8...\t\t\t"
-add_message '[subject]="json-show-utf8-body-sübjéct"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' '[body]="jsön-show-méssage"'
-output=$($NOTMUCH show --format=json 'jsön-show-méssage')
-pass_if_equal "$output" '[[[{"id": "'${gen_msg_id}'", "match": true, "filename": "'${gen_msg_filename}'", "timestamp": 946728000, "date_relative": "2000-01-01", "tags": ["inbox","unread"], "headers": {"Subject": "json-show-utf8-body-sübjéct", "From": "Notmuch Test Suite <test_suite@notmuchmail.org>", "To": "Notmuch Test Suite <test_suite@notmuchmail.org>", "Cc": "", "Bcc": "", "Date": "Sat, 01 Jan 2000 12:00:00 -0000"}, "body": [{"id": 1, "content-type": "text/plain", "content": "jsön-show-méssage\n"}]}, []]]]'
-
-printf " Search message: json, utf-8...\t\t\t"
-add_message '[subject]="json-search-utf8-body-sübjéct"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' '[body]="jsön-search-méssage"'
-output=$($NOTMUCH search --format=json 'jsön-search-méssage' | notmuch_search_sanitize)
-pass_if_equal "$output" '[{"thread": "XXX",
-"timestamp": 946728000,
-"matched": 1,
-"total": 1,
-"authors": "Notmuch Test Suite",
-"subject": "json-search-utf8-body-sübjéct",
-"tags": ["inbox", "unread"]}]'
-
-printf "\nTesting naming of threads with changing subject:\n"
-add_message '[subject]="thread-naming: Initial thread subject"' \
-            '[date]="Fri, 05 Jan 2001 15:43:56 -0800"'
-first=${gen_msg_cnt}
-parent=${gen_msg_id}
-add_message '[subject]="thread-naming: Older changed subject"' \
-            '[date]="Sat, 06 Jan 2001 15:43:56 -0800"' \
-            "[in-reply-to]=\<$parent\>"
-add_message '[subject]="thread-naming: Newer changed subject"' \
-            '[date]="Sun, 07 Jan 2001 15:43:56 -0800"' \
-            "[in-reply-to]=\<$parent\>"
-add_message '[subject]="thread-naming: Final thread subject"' \
-            '[date]="Mon, 08 Jan 2001 15:43:56 -0800"' \
-            "[in-reply-to]=\<$parent\>"
-final=${gen_msg_id}
-
-printf " Initial thread name (oldest-first search)...\t"
-output=$($NOTMUCH search --sort=oldest-first thread-naming and tag:inbox | notmuch_search_sanitize)
-pass_if_equal "$output" "thread:XXX   2001-01-05 [4/4] Notmuch Test Suite; thread-naming: Initial thread subject (inbox unread)"
-
-printf " Initial thread name (newest-first search)...\t"
-output=$($NOTMUCH search --sort=newest-first thread-naming and tag:inbox | notmuch_search_sanitize)
-pass_if_equal "$output" "thread:XXX   2001-01-08 [4/4] Notmuch Test Suite; thread-naming: Final thread subject (inbox unread)"
-
-# Remove oldest and newest messages from search results
-$NOTMUCH tag -inbox id:$parent or id:$final
-
-printf " Changed thread name (oldest-first search)...\t"
-output=$($NOTMUCH search --sort=oldest-first thread-naming and tag:inbox | notmuch_search_sanitize)
-pass_if_equal "$output" "thread:XXX   2001-01-06 [2/4] Notmuch Test Suite; thread-naming: Older changed subject (inbox unread)"
-
-printf " Changed thread name (newest-first search)...\t"
-output=$($NOTMUCH search --sort=newest-first thread-naming and tag:inbox | notmuch_search_sanitize)
-pass_if_equal "$output" "thread:XXX   2001-01-07 [2/4] Notmuch Test Suite; thread-naming: Newer changed subject (inbox unread)"
-
-printf " Ignore added reply prefix (Re:)...\t\t"
-add_message '[subject]="Re: thread-naming: Initial thread subject"' \
-            '[date]="Tue, 09 Jan 2001 15:43:45 -0800"' \
-            "[in-reply-to]=\<$parent\>"
-output=$($NOTMUCH search --sort=newest-first thread-naming and tag:inbox | notmuch_search_sanitize)
-pass_if_equal "$output" "thread:XXX   2001-01-09 [3/5] Notmuch Test Suite; thread-naming: Initial thread subject (inbox unread)"
-
-printf " Ignore added reply prefix (Aw:)...\t\t"
-add_message '[subject]="Aw: thread-naming: Initial thread subject"' \
-            '[date]="Wed, 10 Jan 2001 15:43:45 -0800"' \
-            "[in-reply-to]=\<$parent\>"
-output=$($NOTMUCH search --sort=newest-first thread-naming and tag:inbox | notmuch_search_sanitize)
-pass_if_equal "$output" "thread:XXX   2001-01-10 [4/6] Notmuch Test Suite; thread-naming: Initial thread subject (inbox unread)"
-
-printf " Ignore added reply prefix (Vs:)...\t\t"
-add_message '[subject]="Vs: thread-naming: Initial thread subject"' \
-            '[date]="Thu, 11 Jan 2001 15:43:45 -0800"' \
-            "[in-reply-to]=\<$parent\>"
-output=$($NOTMUCH search --sort=newest-first thread-naming and tag:inbox | notmuch_search_sanitize)
-pass_if_equal "$output" "thread:XXX   2001-01-11 [5/7] Notmuch Test Suite; thread-naming: Initial thread subject (inbox unread)"
-
-printf " Ignore added reply prefix (Sv:)...\t\t"
-add_message '[subject]="Sv: thread-naming: Initial thread subject"' \
-            '[date]="Fri, 12 Jan 2001 15:43:45 -0800"' \
-            "[in-reply-to]=\<$parent\>"
-output=$($NOTMUCH search --sort=newest-first thread-naming and tag:inbox | notmuch_search_sanitize)
-pass_if_equal "$output" "thread:XXX   2001-01-12 [6/8] Notmuch Test Suite; thread-naming: Initial thread subject (inbox unread)"
-
-printf " Test order of messages in \"notmuch show\"\t"
-output=$($NOTMUCH show thread-naming | notmuch_show_sanitize)
-pass_if_equal "$output" "\fmessage{ id:msg-$(printf "%03d" $first)@notmuch-test-suite depth:0 match:1 filename:/XXX/mail/msg-$(printf "%03d" $first)
-\fheader{
-Notmuch Test Suite <test_suite@notmuchmail.org> (2001-01-05) (unread)
-Subject: thread-naming: Initial thread subject
-From: Notmuch Test Suite <test_suite@notmuchmail.org>
-To: Notmuch Test Suite <test_suite@notmuchmail.org>
-Date: Fri, 05 Jan 2001 15:43:56 -0800
-\fheader}
-\fbody{
-\fpart{ ID: 1, Content-type: text/plain
-This is just a test message (#$first)
-\fpart}
-\fbody}
-\fmessage}
-\fmessage{ id:msg-$(printf "%03d" $((first + 1)))@notmuch-test-suite depth:1 match:1 filename:/XXX/mail/msg-$(printf "%03d" $((first + 1)))
-\fheader{
-Notmuch Test Suite <test_suite@notmuchmail.org> (2001-01-06) (inbox unread)
-Subject: thread-naming: Older changed subject
-From: Notmuch Test Suite <test_suite@notmuchmail.org>
-To: Notmuch Test Suite <test_suite@notmuchmail.org>
-Date: Sat, 06 Jan 2001 15:43:56 -0800
-\fheader}
-\fbody{
-\fpart{ ID: 1, Content-type: text/plain
-This is just a test message (#$((first + 1)))
-\fpart}
-\fbody}
-\fmessage}
-\fmessage{ id:msg-$(printf "%03d" $((first + 2)))@notmuch-test-suite depth:1 match:1 filename:/XXX/mail/msg-$(printf "%03d" $((first + 2)))
-\fheader{
-Notmuch Test Suite <test_suite@notmuchmail.org> (2001-01-07) (inbox unread)
-Subject: thread-naming: Newer changed subject
-From: Notmuch Test Suite <test_suite@notmuchmail.org>
-To: Notmuch Test Suite <test_suite@notmuchmail.org>
-Date: Sun, 07 Jan 2001 15:43:56 -0800
-\fheader}
-\fbody{
-\fpart{ ID: 1, Content-type: text/plain
-This is just a test message (#$((first + 2)))
-\fpart}
-\fbody}
-\fmessage}
-\fmessage{ id:msg-$(printf "%03d" $((first + 3)))@notmuch-test-suite depth:1 match:1 filename:/XXX/mail/msg-$(printf "%03d" $((first + 3)))
-\fheader{
-Notmuch Test Suite <test_suite@notmuchmail.org> (2001-01-08) (unread)
-Subject: thread-naming: Final thread subject
-From: Notmuch Test Suite <test_suite@notmuchmail.org>
-To: Notmuch Test Suite <test_suite@notmuchmail.org>
-Date: Mon, 08 Jan 2001 15:43:56 -0800
-\fheader}
-\fbody{
-\fpart{ ID: 1, Content-type: text/plain
-This is just a test message (#$((first + 3)))
-\fpart}
-\fbody}
-\fmessage}
-\fmessage{ id:msg-$(printf "%03d" $((first + 4)))@notmuch-test-suite depth:1 match:1 filename:/XXX/mail/msg-$(printf "%03d" $((first + 4)))
-\fheader{
-Notmuch Test Suite <test_suite@notmuchmail.org> (2001-01-09) (inbox unread)
-Subject: Re: thread-naming: Initial thread subject
-From: Notmuch Test Suite <test_suite@notmuchmail.org>
-To: Notmuch Test Suite <test_suite@notmuchmail.org>
-Date: Tue, 09 Jan 2001 15:43:45 -0800
-\fheader}
-\fbody{
-\fpart{ ID: 1, Content-type: text/plain
-This is just a test message (#$((first + 4)))
-\fpart}
-\fbody}
-\fmessage}
-\fmessage{ id:msg-$(printf "%03d" $((first + 5)))@notmuch-test-suite depth:1 match:1 filename:/XXX/mail/msg-$(printf "%03d" $((first + 5)))
-\fheader{
-Notmuch Test Suite <test_suite@notmuchmail.org> (2001-01-10) (inbox unread)
-Subject: Aw: thread-naming: Initial thread subject
-From: Notmuch Test Suite <test_suite@notmuchmail.org>
-To: Notmuch Test Suite <test_suite@notmuchmail.org>
-Date: Wed, 10 Jan 2001 15:43:45 -0800
-\fheader}
-\fbody{
-\fpart{ ID: 1, Content-type: text/plain
-This is just a test message (#$((first + 5)))
-\fpart}
-\fbody}
-\fmessage}
-\fmessage{ id:msg-$(printf "%03d" $((first + 6)))@notmuch-test-suite depth:1 match:1 filename:/XXX/mail/msg-$(printf "%03d" $((first + 6)))
-\fheader{
-Notmuch Test Suite <test_suite@notmuchmail.org> (2001-01-11) (inbox unread)
-Subject: Vs: thread-naming: Initial thread subject
-From: Notmuch Test Suite <test_suite@notmuchmail.org>
-To: Notmuch Test Suite <test_suite@notmuchmail.org>
-Date: Thu, 11 Jan 2001 15:43:45 -0800
-\fheader}
-\fbody{
-\fpart{ ID: 1, Content-type: text/plain
-This is just a test message (#$((first + 6)))
-\fpart}
-\fbody}
-\fmessage}
-\fmessage{ id:msg-$(printf "%03d" $((first + 7)))@notmuch-test-suite depth:1 match:1 filename:/XXX/mail/msg-$(printf "%03d" $((first + 7)))
-\fheader{
-Notmuch Test Suite <test_suite@notmuchmail.org> (2001-01-12) (inbox unread)
-Subject: Sv: thread-naming: Initial thread subject
-From: Notmuch Test Suite <test_suite@notmuchmail.org>
-To: Notmuch Test Suite <test_suite@notmuchmail.org>
-Date: Fri, 12 Jan 2001 15:43:45 -0800
-\fheader}
-\fbody{
-\fpart{ ID: 1, Content-type: text/plain
-This is just a test message (#$((first + 7)))
-\fpart}
-\fbody}
-\fmessage}"
-
-printf "\nTesting \"notmuch reply\" in several variations:\n"
-
-printf " Basic reply...\t\t\t\t\t"
-add_message '[from]="Sender <sender@example.com>"' \
-             [to]=test_suite@notmuchmail.org \
-             [subject]=notmuch-reply-test \
-            '[date]="Tue, 05 Jan 2010 15:43:56 -0800"' \
-            '[body]="basic reply test"'
-
-output=$($NOTMUCH reply id:${gen_msg_id})
-pass_if_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
-Subject: Re: notmuch-reply-test
-To: Sender <sender@example.com>
-Bcc: test_suite@notmuchmail.org
-In-Reply-To: <${gen_msg_id}>
-References: <${gen_msg_id}>
-
-On Tue, 05 Jan 2010 15:43:56 -0800, Sender <sender@example.com> wrote:
-> basic reply test"
-
-printf " Multiple recipients...\t\t\t\t"
-add_message '[from]="Sender <sender@example.com>"' \
-            '[to]="test_suite@notmuchmail.org, Someone Else <someone@example.com>"' \
-             [subject]=notmuch-reply-test \
-            '[date]="Tue, 05 Jan 2010 15:43:56 -0800"' \
-            '[body]="Multiple recipients"'
-
-output=$($NOTMUCH reply id:${gen_msg_id})
-pass_if_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
-Subject: Re: notmuch-reply-test
-To: Sender <sender@example.com>, Someone Else <someone@example.com>
-Bcc: test_suite@notmuchmail.org
-In-Reply-To: <${gen_msg_id}>
-References: <${gen_msg_id}>
-
-On Tue, 05 Jan 2010 15:43:56 -0800, Sender <sender@example.com> wrote:
-> Multiple recipients"
-
-printf " Reply with CC...\t\t\t\t"
-add_message '[from]="Sender <sender@example.com>"' \
-             [to]=test_suite@notmuchmail.org \
-            '[cc]="Other Parties <cc@example.com>"' \
-             [subject]=notmuch-reply-test \
-            '[date]="Tue, 05 Jan 2010 15:43:56 -0800"' \
-            '[body]="reply with CC"'
-
-output=$($NOTMUCH reply id:${gen_msg_id})
-pass_if_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
-Subject: Re: notmuch-reply-test
-To: Sender <sender@example.com>
-Cc: Other Parties <cc@example.com>
-Bcc: test_suite@notmuchmail.org
-In-Reply-To: <${gen_msg_id}>
-References: <${gen_msg_id}>
-
-On Tue, 05 Jan 2010 15:43:56 -0800, Sender <sender@example.com> wrote:
-> reply with CC"
-
-printf " Reply from alternate address...\t\t"
-add_message '[from]="Sender <sender@example.com>"' \
-             [to]=test_suite_other@notmuchmail.org \
-             [subject]=notmuch-reply-test \
-            '[date]="Tue, 05 Jan 2010 15:43:56 -0800"' \
-            '[body]="reply from alternate address"'
-
-output=$($NOTMUCH reply id:${gen_msg_id})
-pass_if_equal "$output" "From: Notmuch Test Suite <test_suite_other@notmuchmail.org>
-Subject: Re: notmuch-reply-test
-To: Sender <sender@example.com>
-Bcc: test_suite@notmuchmail.org
-In-Reply-To: <${gen_msg_id}>
-References: <${gen_msg_id}>
-
-On Tue, 05 Jan 2010 15:43:56 -0800, Sender <sender@example.com> wrote:
-> reply from alternate address"
-
-printf " Support for Reply-To...\t\t\t"
-add_message '[from]="Sender <sender@example.com>"' \
-             [to]=test_suite@notmuchmail.org \
-             [subject]=notmuch-reply-test \
-            '[date]="Tue, 05 Jan 2010 15:43:56 -0800"' \
-            '[body]="support for reply-to"' \
-            '[reply-to]="Sender <elsewhere@example.com>"'
-
-output=$($NOTMUCH reply id:${gen_msg_id})
-pass_if_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
-Subject: Re: notmuch-reply-test
-To: Sender <elsewhere@example.com>
-Bcc: test_suite@notmuchmail.org
-In-Reply-To: <${gen_msg_id}>
-References: <${gen_msg_id}>
-
-On Tue, 05 Jan 2010 15:43:56 -0800, Sender <sender@example.com> wrote:
-> support for reply-to"
-
-printf " Un-munging Reply-To...\t\t\t\t"
-add_message '[from]="Sender <sender@example.com>"' \
-            '[to]="Some List <list@example.com>"' \
-             [subject]=notmuch-reply-test \
-            '[date]="Tue, 05 Jan 2010 15:43:56 -0800"' \
-            '[body]="Un-munging Reply-To"' \
-            '[reply-to]="Evil Munging List <list@example.com>"'
-
-output=$($NOTMUCH reply id:${gen_msg_id})
-pass_if_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
-Subject: Re: notmuch-reply-test
-To: Sender <sender@example.com>, Some List <list@example.com>
-Bcc: test_suite@notmuchmail.org
-In-Reply-To: <${gen_msg_id}>
-References: <${gen_msg_id}>
-
-On Tue, 05 Jan 2010 15:43:56 -0800, Sender <sender@example.com> wrote:
-> Un-munging Reply-To"
-
-printf "\nTesting handling of uuencoded data:\n"
-
-add_message [subject]=uuencodetest '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' \
-'[body]="This message is used to ensure that notmuch correctly handles a
-message containing a block of uuencoded data. First, we have a marker
-this content beforeuudata . Then we beging the uunencoded data itself:
-
-begin 644 bogus-uuencoded-data
-M0123456789012345678901234567890123456789012345678901234567890
-MOBVIOUSLY, THIS IS NOT ANY SORT OF USEFUL UUNECODED DATA.    
-MINSTEAD THIS IS JUST A WAY TO ENSURE THAT THIS BLOCK OF DATA 
-MIS CORRECTLY IGNORED WHEN NOTMUCH CREATES ITS INDEX. SO WE   
-MINCLUDE A DURINGUUDATA MARKER THAT SHOULD NOT RESULT IN ANY  
-MSEARCH RESULT.                                               
-\`
-end
-
-Finally, we have our afteruudata marker as well."'
-
-printf " Ensure content before uu data is indexed...\t"
-output=$($NOTMUCH search beforeuudata | notmuch_search_sanitize)
-pass_if_equal "$output" "thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; uuencodetest (inbox unread)"
-printf " Ensure uu data is not indexed...\t\t"
-output=$($NOTMUCH search DURINGUUDATA | notmuch_search_sanitize)
-pass_if_equal "$output" ""
-printf " Ensure content after uu data is indexed...\t"
-output=$($NOTMUCH search afteruudata | notmuch_search_sanitize)
-pass_if_equal "$output" "thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; uuencodetest (inbox unread)"
-
-printf "\nTesting \"notmuch dump\" and \"notmuch restore\":\n"
-
-printf " Dumping all tags...\t\t\t\t"
-$NOTMUCH dump dump.expected
-pass_if_equal "$?" "0"
-
-printf " Clearing all tags...\t\t\t\t"
-sed -e 's/(\([^(]*\))$/()/' < dump.expected > clear.expected
-$NOTMUCH restore clear.expected
-$NOTMUCH dump clear.actual
-pass_if_equal "$(< clear.actual)" "$(< clear.expected)"
-
-printf " Restoring original tags...\t\t\t"
-$NOTMUCH restore dump.expected
-$NOTMUCH dump dump.actual
-pass_if_equal "$(< dump.actual)" "$(< dump.expected)"
-
-printf " Restore with nothing to do...\t\t\t"
-$NOTMUCH restore dump.expected
-pass_if_equal "$?" "0"
-
-printf "\nTesting threading when messages received out of order:\n"
-printf " Adding initial child message...\t\t"
-generate_message [body]=foo '[in-reply-to]=\<parent-id\>' [subject]=brokenthreadtest '[date]="Sat, 01 Jan 2000 12:00:00 -0000"'
-output=$(NOTMUCH_NEW)
-pass_if_equal "$output" "Added 1 new message to the database."
-printf " Searching returns the message...\t\t"
-output=$($NOTMUCH search foo | notmuch_search_sanitize)
-pass_if_equal "$output" "thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; brokenthreadtest (inbox unread)"
-printf " Adding second child message...\t\t\t"
-generate_message [body]=foo '[in-reply-to]=\<parent-id\>' [subject]=brokenthreadtest '[date]="Sat, 01 Jan 2000 12:00:00 -0000"'
-output=$(NOTMUCH_NEW)
-pass_if_equal "$output" "Added 1 new message to the database."
-printf " Searching returns both messages in one thread..."
-output=$($NOTMUCH search foo | notmuch_search_sanitize)
-pass_if_equal "$output" "thread:XXX   2000-01-01 [2/2] Notmuch Test Suite; brokenthreadtest (inbox unread)"
-printf " Adding parent message...\t\t\t"
-generate_message [body]=foo [id]=parent-id [subject]=brokenthreadtest '[date]="Sat, 01 Jan 2000 12:00:00 -0000"'
-output=$(NOTMUCH_NEW)
-pass_if_equal "$output" "Added 1 new message to the database."
-printf " Searching returns all three messages in one thread..."
-output=$($NOTMUCH search foo | notmuch_search_sanitize)
-pass_if_equal "$output" "thread:XXX   2000-01-01 [3/3] Notmuch Test Suite; brokenthreadtest (inbox unread)"
-
-printf "\nTesting author reordering;\n"
-printf " Adding parent message...\t\t\t"
-generate_message [body]=findme [id]=new-parent-id [subject]=author-reorder-threadtest '[from]="User <user@example.com>"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"'
-output=$(NOTMUCH_NEW)
-pass_if_equal "$output" "Added 1 new message to the database."
-printf " Adding initial child message...\t\t"
-generate_message [body]=findme '[in-reply-to]=\<new-parent-id\>' [subject]=author-reorder-threadtest '[from]="User1 <user1@example.com>"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"'
-output=$(NOTMUCH_NEW)
-pass_if_equal "$output" "Added 1 new message to the database."
-printf " Adding second child message...\t\t\t"
-generate_message [body]=findme '[in-reply-to]=\<new-parent-id\>' [subject]=author-reorder-threadtest '[from]="User2 <user2@example.com>"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"'
-output=$(NOTMUCH_NEW)
-pass_if_equal "$output" "Added 1 new message to the database."
-printf " Searching when all three messages match...\t"
-output=$($NOTMUCH search findme | notmuch_search_sanitize)
-pass_if_equal "$output" "thread:XXX   2000-01-01 [3/3] User, User1, User2; author-reorder-threadtest (inbox unread)"
-printf " Searching when two messages match...\t\t"
-output=$($NOTMUCH search User1 or User2 | notmuch_search_sanitize)
-pass_if_equal "$output" "thread:XXX   2000-01-01 [2/3] User1, User2| User; author-reorder-threadtest (inbox unread)"
-printf " Searching when only one message matches...\t"
-output=$($NOTMUCH search User2 | notmuch_search_sanitize)
-pass_if_equal "$output" "thread:XXX   2000-01-01 [1/3] User2| User, User1; author-reorder-threadtest (inbox unread)"
-printf " Searching when only first message matches...\t"
-output=$($NOTMUCH search User | notmuch_search_sanitize)
-pass_if_equal "$output" "thread:XXX   2000-01-01 [1/3] User| User1, User2; author-reorder-threadtest (inbox unread)"
-
-printf "\nTesting From line heuristics (with multiple configured addresses):\n"
-printf " Magic from guessing (nothing to go on)...\t"
-add_message '[from]="Sender <sender@example.com>"' \
-             [to]=mailinglist@notmuchmail.org \
-             [subject]=notmuch-reply-test \
-            '[date]="Tue, 05 Jan 2010 15:43:56 -0800"' \
-            '[body]="from guessing test"'
-
-output=$($NOTMUCH reply id:${gen_msg_id})
-pass_if_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
-Subject: Re: notmuch-reply-test
-To: Sender <sender@example.com>, mailinglist@notmuchmail.org
-Bcc: test_suite@notmuchmail.org
-In-Reply-To: <${gen_msg_id}>
-References: <${gen_msg_id}>
-
-On Tue, 05 Jan 2010 15:43:56 -0800, Sender <sender@example.com> wrote:
-> from guessing test"
-
-printf " Magic from guessing (Envelope-to:)...\t\t"
-add_message '[from]="Sender <sender@example.com>"' \
-             [to]=mailinglist@notmuchmail.org \
-             [subject]=notmuch-reply-test \
-            '[header]="Envelope-To: test_suite_other@notmuchmail.org"' \
-            '[date]="Tue, 05 Jan 2010 15:43:56 -0800"' \
-            '[body]="from guessing test"'
-
-output=$($NOTMUCH reply id:${gen_msg_id})
-pass_if_equal "$output" "From: Notmuch Test Suite <test_suite_other@notmuchmail.org>
-Subject: Re: notmuch-reply-test
-To: Sender <sender@example.com>, mailinglist@notmuchmail.org
-Bcc: test_suite@notmuchmail.org
-In-Reply-To: <${gen_msg_id}>
-References: <${gen_msg_id}>
-
-On Tue, 05 Jan 2010 15:43:56 -0800, Sender <sender@example.com> wrote:
-> from guessing test"
-
-printf " Magic from guessing (X-Original-To:)...\t"
-add_message '[from]="Sender <sender@example.com>"' \
-             [to]=mailinglist@notmuchmail.org \
-             [subject]=notmuch-reply-test \
-            '[header]="X-Original-To: test_suite_other@notmuchmail.org"' \
-            '[date]="Tue, 05 Jan 2010 15:43:56 -0800"' \
-            '[body]="from guessing test"'
-
-output=$($NOTMUCH reply id:${gen_msg_id})
-pass_if_equal "$output" "From: Notmuch Test Suite <test_suite_other@notmuchmail.org>
-Subject: Re: notmuch-reply-test
-To: Sender <sender@example.com>, mailinglist@notmuchmail.org
-Bcc: test_suite@notmuchmail.org
-In-Reply-To: <${gen_msg_id}>
-References: <${gen_msg_id}>
-
-On Tue, 05 Jan 2010 15:43:56 -0800, Sender <sender@example.com> wrote:
-> from guessing test"
-
-printf " Magic from guessing (Received: .. for ..)...\t"
-add_message '[from]="Sender <sender@example.com>"' \
-             [to]=mailinglist@notmuchmail.org \
-             [subject]=notmuch-reply-test \
-            '[header]="Received: from mail.example.com (mail.example.com [1.1.1.1])\
-        by mail.notmuchmail.org (some MTA) with ESMTP id 12345678\
-        for <test_suite_other@notmuchmail.org>; Sat, 10 Apr 2010 07:54:51 -0400 (EDT)"' \
-            '[date]="Tue, 05 Jan 2010 15:43:56 -0800"' \
-            '[body]="from guessing test"'
-
-output=$($NOTMUCH reply id:${gen_msg_id})
-pass_if_equal "$output" "From: Notmuch Test Suite <test_suite_other@notmuchmail.org>
-Subject: Re: notmuch-reply-test
-To: Sender <sender@example.com>, mailinglist@notmuchmail.org
-Bcc: test_suite@notmuchmail.org
-In-Reply-To: <${gen_msg_id}>
-References: <${gen_msg_id}>
-
-On Tue, 05 Jan 2010 15:43:56 -0800, Sender <sender@example.com> wrote:
-> from guessing test"
-
-printf " Magic from guessing (Received: domain)...\t"
-add_message '[from]="Sender <sender@example.com>"' \
-             [to]=mailinglist@notmuchmail.org \
-             [subject]=notmuch-reply-test \
-            '[header]="Received: from mail.example.com (mail.example.com [1.1.1.1])\
-        by mail.otherdomain.org (some MTA) with ESMTP id 12345678\
-        Sat, 10 Apr 2010 07:54:51 -0400 (EDT)"' \
-            '[date]="Tue, 05 Jan 2010 15:43:56 -0800"' \
-            '[body]="from guessing test"'
-
-output=$($NOTMUCH reply id:${gen_msg_id})
-pass_if_equal "$output" "From: Notmuch Test Suite <test_suite@otherdomain.org>
-Subject: Re: notmuch-reply-test
-To: Sender <sender@example.com>, mailinglist@notmuchmail.org
-Bcc: test_suite@notmuchmail.org
-In-Reply-To: <${gen_msg_id}>
-References: <${gen_msg_id}>
-
-On Tue, 05 Jan 2010 15:43:56 -0800, Sender <sender@example.com> wrote:
-> from guessing test"
-
-
-printf "\nTesting From line heuristics (with single configured address):\n"
-sed -i -e 's/^other_email.*//' ${NOTMUCH_CONFIG}
-
-printf " Magic from guessing (nothing to go on)...\t"
-add_message '[from]="Sender <sender@example.com>"' \
-             [to]=mailinglist@notmuchmail.org \
-             [subject]=notmuch-reply-test \
-            '[date]="Tue, 05 Jan 2010 15:43:56 -0800"' \
-            '[body]="from guessing test"'
-
-output=$($NOTMUCH reply id:${gen_msg_id})
-pass_if_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
-Subject: Re: notmuch-reply-test
-To: Sender <sender@example.com>, mailinglist@notmuchmail.org
-Bcc: test_suite@notmuchmail.org
-In-Reply-To: <${gen_msg_id}>
-References: <${gen_msg_id}>
-
-On Tue, 05 Jan 2010 15:43:56 -0800, Sender <sender@example.com> wrote:
-> from guessing test"
-
-printf " Magic from guessing (Envelope-to:)...\t\t"
-add_message '[from]="Sender <sender@example.com>"' \
-             [to]=mailinglist@notmuchmail.org \
-             [subject]=notmuch-reply-test \
-            '[header]="Envelope-To: test_suite_other@notmuchmail.org"' \
-            '[date]="Tue, 05 Jan 2010 15:43:56 -0800"' \
-            '[body]="from guessing test"'
-
-output=$($NOTMUCH reply id:${gen_msg_id})
-pass_if_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
-Subject: Re: notmuch-reply-test
-To: Sender <sender@example.com>, mailinglist@notmuchmail.org
-Bcc: test_suite@notmuchmail.org
-In-Reply-To: <${gen_msg_id}>
-References: <${gen_msg_id}>
-
-On Tue, 05 Jan 2010 15:43:56 -0800, Sender <sender@example.com> wrote:
-> from guessing test"
-
-printf " Magic from guessing (X-Original-To:)...\t"
-add_message '[from]="Sender <sender@example.com>"' \
-             [to]=mailinglist@notmuchmail.org \
-             [subject]=notmuch-reply-test \
-            '[header]="X-Original-To: test_suite_other@notmuchmail.org"' \
-            '[date]="Tue, 05 Jan 2010 15:43:56 -0800"' \
-            '[body]="from guessing test"'
-
-output=$($NOTMUCH reply id:${gen_msg_id})
-pass_if_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
-Subject: Re: notmuch-reply-test
-To: Sender <sender@example.com>, mailinglist@notmuchmail.org
-Bcc: test_suite@notmuchmail.org
-In-Reply-To: <${gen_msg_id}>
-References: <${gen_msg_id}>
-
-On Tue, 05 Jan 2010 15:43:56 -0800, Sender <sender@example.com> wrote:
-> from guessing test"
-
-printf " Magic from guessing (Received: .. for ..)...\t"
-add_message '[from]="Sender <sender@example.com>"' \
-             [to]=mailinglist@notmuchmail.org \
-             [subject]=notmuch-reply-test \
-            '[header]="Received: from mail.example.com (mail.example.com [1.1.1.1])\
-        by mail.notmuchmail.org (some MTA) with ESMTP id 12345678\
-        for <test_suite_other@notmuchmail.org>; Sat, 10 Apr 2010 07:54:51 -0400 (EDT)"' \
-            '[date]="Tue, 05 Jan 2010 15:43:56 -0800"' \
-            '[body]="from guessing test"'
-
-output=$($NOTMUCH reply id:${gen_msg_id})
-pass_if_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
-Subject: Re: notmuch-reply-test
-To: Sender <sender@example.com>, mailinglist@notmuchmail.org
-Bcc: test_suite@notmuchmail.org
-In-Reply-To: <${gen_msg_id}>
-References: <${gen_msg_id}>
-
-On Tue, 05 Jan 2010 15:43:56 -0800, Sender <sender@example.com> wrote:
-> from guessing test"
-
-printf " Magic from guessing (Received: domain)...\t"
-add_message '[from]="Sender <sender@example.com>"' \
-             [to]=mailinglist@notmuchmail.org \
-             [subject]=notmuch-reply-test \
-            '[header]="Received: from mail.example.com (mail.example.com [1.1.1.1])\
-        by mail.otherdomain.org (some MTA) with ESMTP id 12345678\
-        Sat, 10 Apr 2010 07:54:51 -0400 (EDT)"' \
-            '[date]="Tue, 05 Jan 2010 15:43:56 -0800"' \
-            '[body]="from guessing test"'
+run_collection_setup_and_tests ()
+{
+    for testfile in $(find ${TEST_COLLECTION_DIR}/$1 \
+	-name "*.test" -o -name "*.setup" |
+	sort -n);
+    do
+	source $testfile
+    done
+}
 
-output=$($NOTMUCH reply id:${gen_msg_id})
-pass_if_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
-Subject: Re: notmuch-reply-test
-To: Sender <sender@example.com>, mailinglist@notmuchmail.org
-Bcc: test_suite@notmuchmail.org
-In-Reply-To: <${gen_msg_id}>
-References: <${gen_msg_id}>
+run_test_suite ()
+{
+    initialize_notmuch_test;
+
+    if [ "$#" = "0" -o "$1" = "all" ]; then
+	for dir in $(echo ${TEST_COLLECTIONS}); do
+	    run_collection_setup_and_tests "$(basename ${dir})";
+	done;
+    elif [ ! -d "${TEST_COLLECTION_DIR}/$1" ]; then
+	echo "${TEST_COLLECTION_DIR}/$1 is not a directory"
+	exit
+    else
+	run_collection_setup_and_tests "$1";
+    fi
+}
 
-On Tue, 05 Jan 2010 15:43:56 -0800, Sender <sender@example.com> wrote:
-> from guessing test"
+run_test_suite $1
 
 echo ""
 echo "Notmuch test suite complete."
-- 
1.6.3.3

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 2/2] test: Have notmuch-test use the modular test collections
  2010-04-30 19:09   ` [PATCH 2/2] test: Have notmuch-test use the " Jesse Rosenthal
@ 2010-05-05  4:46     ` Jesse Rosenthal
  0 siblings, 0 replies; 8+ messages in thread
From: Jesse Rosenthal @ 2010-05-05  4:46 UTC (permalink / raw)
  To: Notmuch developer list

These two patches, it turns out, do not quite go all the way -- they do
not set up the environment to be exactly as it was in the full test
suite. (I discovered this because my modular test suite did not fail on
the recent xapian error -- failure being success in this case.)

Further patches, which will be sent tomorrow, will take care of this in
a very naive way: essentially repeating all the steps from the original
suite up to each set of tests -- this means, of course, that the full
test suite will take longer to run, since it will have to recreate the
nm database for each collection. It's still quick enough though, and
this can be improved if we change the expected results for each tests to
conform to more uniquely tailored setups, instead of the leftovers from
previous tests.

Best,
Jesse

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] Modularize test suite
  2010-04-30 18:36 [PATCH] Modularize test suite Jesse Rosenthal
  2010-04-30 18:52 ` Jesse Rosenthal
  2010-04-30 19:07 ` [PATCH 1/2] test: add modular test collections Jesse Rosenthal
@ 2010-05-05  7:23 ` Michal Sojka
  2010-05-05  8:04   ` Jesse Rosenthal
  2010-05-05 17:33   ` Carl Worth
  2 siblings, 2 replies; 8+ messages in thread
From: Michal Sojka @ 2010-05-05  7:23 UTC (permalink / raw)
  To: Jesse Rosenthal, Notmuch developer list

On Fri, 30 Apr 2010, Jesse Rosenthal wrote:
> Responding to this email is a patch to modularize the test suite. It
> follows a relatively simple model, but it does seem like it will offer
> some degree of flexibility. Plus, no relicensing is necessary.

Hi Jesse,

Junio has just applied relicensing patch for the Git test suite
(http://git.kernel.org/?p=git/git.git;a=commit;h=64b90323f65d2a3ac8d1ff4ed73be881f76aac8a)
so we can use it for notmuch.

I have quickly looked at your modularization and I do not like that each
test resided in a separate file. I've done similar test suite for one of
my projects and it is a pain to modify the tests. If one test depends on
the previous ones, you always have to switch between multiple files in
your editor.

If you agree, I can refresh my git based modularization and send
the patches. What do you (and others) think?

Michal

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] Modularize test suite
  2010-05-05  7:23 ` [PATCH] Modularize test suite Michal Sojka
@ 2010-05-05  8:04   ` Jesse Rosenthal
  2010-05-05 17:33   ` Carl Worth
  1 sibling, 0 replies; 8+ messages in thread
From: Jesse Rosenthal @ 2010-05-05  8:04 UTC (permalink / raw)
  To: Michal Sojka, Notmuch developer list

Hi Michal,

On Wed, 05 May 2010 09:23:57 +0200, Michal Sojka <sojkam1@fel.cvut.cz> wrote:
> Junio has just applied relicensing patch for the Git test suite
> (http://git.kernel.org/?p=git/git.git;a=commit;h=64b90323f65d2a3ac8d1ff4ed73be881f76aac8a)
> so we can use it for notmuch.

Oh, excellent -- in that case, we should definitely go with the
battle-tested approach.

> If you agree, I can refresh my git based modularization and send
> the patches. What do you (and others) think?

I certainly agree. I elected against looking at it, just to get out a
solution without any licensing problems. But it was more out of
necessity (and challenge). If we have the re-licensing, I'd quite
happily rescind these patches, unless others for some reason feel
strongly.

All best,
Jesse

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] Modularize test suite
  2010-05-05  7:23 ` [PATCH] Modularize test suite Michal Sojka
  2010-05-05  8:04   ` Jesse Rosenthal
@ 2010-05-05 17:33   ` Carl Worth
  1 sibling, 0 replies; 8+ messages in thread
From: Carl Worth @ 2010-05-05 17:33 UTC (permalink / raw)
  To: Michal Sojka, Jesse Rosenthal, Notmuch developer list

[-- Attachment #1: Type: text/plain, Size: 459 bytes --]

On Wed, 05 May 2010 09:23:57 +0200, Michal Sojka <sojkam1@fel.cvut.cz> wrote:
> Junio has just applied relicensing patch for the Git test suite
> (http://git.kernel.org/?p=git/git.git;a=commit;h=64b90323f65d2a3ac8d1ff4ed73be881f76aac8a)
> so we can use it for notmuch.

Good news!

> If you agree, I can refresh my git based modularization and send
> the patches. What do you (and others) think?

Go for it!

-Carl

-- 
carl.d.worth@intel.com

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2010-05-05 17:33 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-04-30 18:36 [PATCH] Modularize test suite Jesse Rosenthal
2010-04-30 18:52 ` Jesse Rosenthal
2010-04-30 19:07 ` [PATCH 1/2] test: add modular test collections Jesse Rosenthal
2010-04-30 19:09   ` [PATCH 2/2] test: Have notmuch-test use the " Jesse Rosenthal
2010-05-05  4:46     ` Jesse Rosenthal
2010-05-05  7:23 ` [PATCH] Modularize test suite Michal Sojka
2010-05-05  8:04   ` Jesse Rosenthal
2010-05-05 17:33   ` Carl Worth

Code repositories for project(s) associated with this public inbox

	https://yhetil.org/notmuch.git/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).