unofficial mirror of notmuch@notmuchmail.org
 help / color / mirror / code / Atom feed
* [PATCH v3 0/5] Git-based modularization of test suite
@ 2010-06-10  6:47 Michal Sojka
  2010-06-10  6:48 ` [PATCH v3 1/5] Copy test framework from Git Michal Sojka
                   ` (5 more replies)
  0 siblings, 6 replies; 11+ messages in thread
From: Michal Sojka @ 2010-06-10  6:47 UTC (permalink / raw)
  To: notmuch

Hi,

this is an updated version of v2
(id:1273510084-19896-1-git-send-email-sojkam1@fel.cvut.cz). It includes
all test suite changes which were done in master since v2. Also a few
minor bugs was fixed since v2, namely:
- Messages are generated with UTC time zone by default
- Unnecessary \n was remvoved from the title in t0005-reply.sh

Michal Sojka (5):
  Copy test framework from Git
  Update test framework for use with notmuch
  test: Update helper functions
  Convert the actual tests to the new framework
  test: Set all times to UTC

 test/Makefile                        |   49 ++
 test/README                          |  299 +++++++++
 test/aggregate-results.sh            |   34 +
 test/notmuch-test                    | 1190 +---------------------------------
 test/t0000-basic.sh                  |   88 +++
 test/t0001-new.sh                    |  164 +++++
 test/t0002-search.sh                 |  111 ++++
 test/t0003-json.sh                   |   46 ++
 test/t0004-thread-naming.sh          |  191 ++++++
 test/t0005-reply.sh                  |  137 ++++
 test/t0006-dump-restore.sh           |   30 +
 test/t0007-uuencode.sh               |   36 +
 test/t0008-threading-out-of-order.sh |   31 +
 test/t0009-author-reordering.sh      |   35 +
 test/t0010-from-line-heuristics.sh   |  215 ++++++
 test/t0011-long-msgid.sh             |   29 +
 test/t0012-encoding-issues.sh        |   25 +
 test/test-lib.sh                     |  913 ++++++++++++++++++++++++++
 18 files changed, 2435 insertions(+), 1188 deletions(-)
 create mode 100644 test/Makefile
 create mode 100644 test/README
 create mode 100755 test/aggregate-results.sh
 create mode 100755 test/t0000-basic.sh
 create mode 100755 test/t0001-new.sh
 create mode 100755 test/t0002-search.sh
 create mode 100755 test/t0003-json.sh
 create mode 100755 test/t0004-thread-naming.sh
 create mode 100755 test/t0005-reply.sh
 create mode 100755 test/t0006-dump-restore.sh
 create mode 100755 test/t0007-uuencode.sh
 create mode 100755 test/t0008-threading-out-of-order.sh
 create mode 100755 test/t0009-author-reordering.sh
 create mode 100755 test/t0010-from-line-heuristics.sh
 create mode 100755 test/t0011-long-msgid.sh
 create mode 100755 test/t0012-encoding-issues.sh
 create mode 100644 test/test-lib.sh

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

* [PATCH v3 1/5] Copy test framework from Git
  2010-06-10  6:47 [PATCH v3 0/5] Git-based modularization of test suite Michal Sojka
@ 2010-06-10  6:48 ` Michal Sojka
  2010-06-10  6:48 ` [PATCH v3 2/5] Update test framework for use with notmuch Michal Sojka
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 11+ messages in thread
From: Michal Sojka @ 2010-06-10  6:48 UTC (permalink / raw)
  To: notmuch

Git uses a simple and yet powerful test framework, written in shell.
The framework is easy to use for both users and developers so I think
it would help if it is used in notmuch as well.

This is a copy of Git's test framework from commit
b6b0afdc30e066788592ca07c9a6c6936c68cc11 in git repository.

Signed-off-by: Michal Sojka <sojkam1@fel.cvut.cz>
---
 test/Makefile             |   48 +++
 test/README               |  297 ++++++++++++++++
 test/aggregate-results.sh |   34 ++
 test/t0000-basic.sh       |  389 +++++++++++++++++++++
 test/test-lib.sh          |  832 +++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 1600 insertions(+), 0 deletions(-)
 create mode 100644 test/Makefile
 create mode 100644 test/README
 create mode 100755 test/aggregate-results.sh
 create mode 100755 test/t0000-basic.sh
 create mode 100644 test/test-lib.sh

diff --git a/test/Makefile b/test/Makefile
new file mode 100644
index 0000000..25c559b
--- /dev/null
+++ b/test/Makefile
@@ -0,0 +1,48 @@
+# Run tests
+#
+# Copyright (c) 2005 Junio C Hamano
+#
+
+-include ../config.mak
+
+#GIT_TEST_OPTS=--verbose --debug
+SHELL_PATH ?= $(SHELL)
+TAR ?= $(TAR)
+RM ?= rm -f
+
+# Shell quote;
+SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
+
+T = $(wildcard t[0-9][0-9][0-9][0-9]-*.sh)
+TSVN = $(wildcard t91[0-9][0-9]-*.sh)
+
+all: pre-clean
+	$(MAKE) aggregate-results-and-cleanup
+
+$(T):
+	@echo "*** $@ ***"; GIT_CONFIG=.git/config '$(SHELL_PATH_SQ)' $@ $(GIT_TEST_OPTS)
+
+pre-clean:
+	$(RM) -r test-results
+
+clean:
+	$(RM) -r 'trash directory'.* test-results
+	$(RM) t????/cvsroot/CVSROOT/?*
+	$(RM) -r valgrind/bin
+
+aggregate-results-and-cleanup: $(T)
+	$(MAKE) aggregate-results
+	$(MAKE) clean
+
+aggregate-results:
+	'$(SHELL_PATH_SQ)' ./aggregate-results.sh test-results/t*-*
+
+# we can test NO_OPTIMIZE_COMMITS independently of LC_ALL
+full-svn-test:
+	$(MAKE) $(TSVN) GIT_SVN_NO_OPTIMIZE_COMMITS=1 LC_ALL=C
+	$(MAKE) $(TSVN) GIT_SVN_NO_OPTIMIZE_COMMITS=0 LC_ALL=en_US.UTF-8
+
+valgrind:
+	GIT_TEST_OPTS=--valgrind $(MAKE)
+
+.PHONY: pre-clean $(T) aggregate-results clean valgrind
diff --git a/test/README b/test/README
new file mode 100644
index 0000000..dcd3ebb
--- /dev/null
+++ b/test/README
@@ -0,0 +1,297 @@
+Core GIT Tests
+==============
+
+This directory holds many test scripts for core GIT tools.  The
+first part of this short document describes how to run the tests
+and read their output.
+
+When fixing the tools or adding enhancements, you are strongly
+encouraged to add tests in this directory to cover what you are
+trying to fix or enhance.  The later part of this short document
+describes how your test scripts should be organized.
+
+
+Running Tests
+-------------
+
+The easiest way to run tests is to say "make".  This runs all
+the tests.
+
+    *** t0000-basic.sh ***
+    *   ok 1: .git/objects should be empty after git-init in an empty repo.
+    *   ok 2: .git/objects should have 256 subdirectories.
+    *   ok 3: git-update-index without --add should fail adding.
+    ...
+    *   ok 23: no diff after checkout and git-update-index --refresh.
+    * passed all 23 test(s)
+    *** t0100-environment-names.sh ***
+    *   ok 1: using old names should issue warnings.
+    *   ok 2: using old names but having new names should not issue warnings.
+    ...
+
+Or you can run each test individually from command line, like
+this:
+
+    $ sh ./t3001-ls-files-killed.sh
+    *   ok 1: git-update-index --add to add various paths.
+    *   ok 2: git-ls-files -k to show killed files.
+    *   ok 3: validate git-ls-files -k output.
+    * passed all 3 test(s)
+
+You can pass --verbose (or -v), --debug (or -d), and --immediate
+(or -i) command line argument to the test, or by setting GIT_TEST_OPTS
+appropriately before running "make".
+
+--verbose::
+	This makes the test more verbose.  Specifically, the
+	command being run and their output if any are also
+	output.
+
+--debug::
+	This may help the person who is developing a new test.
+	It causes the command defined with test_debug to run.
+
+--immediate::
+	This causes the test to immediately exit upon the first
+	failed test.
+
+--long-tests::
+	This causes additional long-running tests to be run (where
+	available), for more exhaustive testing.
+
+--valgrind::
+	Execute all Git binaries with valgrind and exit with status
+	126 on errors (just like regular tests, this will only stop
+	the test script when running under -i).  Valgrind errors
+	go to stderr, so you might want to pass the -v option, too.
+
+	Since it makes no sense to run the tests with --valgrind and
+	not see any output, this option implies --verbose.  For
+	convenience, it also implies --tee.
+
+--tee::
+	In addition to printing the test output to the terminal,
+	write it to files named 't/test-results/$TEST_NAME.out'.
+	As the names depend on the tests' file names, it is safe to
+	run the tests with this option in parallel.
+
+--with-dashes::
+	By default tests are run without dashed forms of
+	commands (like git-commit) in the PATH (it only uses
+	wrappers from ../bin-wrappers).  Use this option to include
+	the build directory (..) in the PATH, which contains all
+	the dashed forms of commands.  This option is currently
+	implied by other options like --valgrind and
+	GIT_TEST_INSTALLED.
+
+You can also set the GIT_TEST_INSTALLED environment variable to
+the bindir of an existing git installation to test that installation.
+You still need to have built this git sandbox, from which various
+test-* support programs, templates, and perl libraries are used.
+If your installed git is incomplete, it will silently test parts of
+your built version instead.
+
+When using GIT_TEST_INSTALLED, you can also set GIT_TEST_EXEC_PATH to
+override the location of the dashed-form subcommands (what
+GIT_EXEC_PATH would be used for during normal operation).
+GIT_TEST_EXEC_PATH defaults to `$GIT_TEST_INSTALLED/git --exec-path`.
+
+
+Skipping Tests
+--------------
+
+In some environments, certain tests have no way of succeeding
+due to platform limitation, such as lack of 'unzip' program, or
+filesystem that do not allow arbitrary sequence of non-NUL bytes
+as pathnames.
+
+You should be able to say something like
+
+    $ GIT_SKIP_TESTS=t9200.8 sh ./t9200-git-cvsexport-commit.sh
+
+and even:
+
+    $ GIT_SKIP_TESTS='t[0-4]??? t91?? t9200.8' make
+
+to omit such tests.  The value of the environment variable is a
+SP separated list of patterns that tells which tests to skip,
+and either can match the "t[0-9]{4}" part to skip the whole
+test, or t[0-9]{4} followed by ".$number" to say which
+particular test to skip.
+
+Note that some tests in the existing test suite rely on previous
+test item, so you cannot arbitrarily disable one and expect the
+remainder of test to check what the test originally was intended
+to check.
+
+
+Naming Tests
+------------
+
+The test files are named as:
+
+	tNNNN-commandname-details.sh
+
+where N is a decimal digit.
+
+First digit tells the family:
+
+	0 - the absolute basics and global stuff
+	1 - the basic commands concerning database
+	2 - the basic commands concerning the working tree
+	3 - the other basic commands (e.g. ls-files)
+	4 - the diff commands
+	5 - the pull and exporting commands
+	6 - the revision tree commands (even e.g. merge-base)
+	7 - the porcelainish commands concerning the working tree
+	8 - the porcelainish commands concerning forensics
+	9 - the git tools
+
+Second digit tells the particular command we are testing.
+
+Third digit (optionally) tells the particular switch or group of switches
+we are testing.
+
+If you create files under t/ directory (i.e. here) that is not
+the top-level test script, never name the file to match the above
+pattern.  The Makefile here considers all such files as the
+top-level test script and tries to run all of them.  A care is
+especially needed if you are creating a common test library
+file, similar to test-lib.sh, because such a library file may
+not be suitable for standalone execution.
+
+
+Writing Tests
+-------------
+
+The test script is written as a shell script.  It should start
+with the standard "#!/bin/sh" with copyright notices, and an
+assignment to variable 'test_description', like this:
+
+	#!/bin/sh
+	#
+	# Copyright (c) 2005 Junio C Hamano
+	#
+
+	test_description='xxx test (option --frotz)
+
+	This test registers the following structure in the cache
+	and tries to run git-ls-files with option --frotz.'
+
+
+Source 'test-lib.sh'
+--------------------
+
+After assigning test_description, the test script should source
+test-lib.sh like this:
+
+	. ./test-lib.sh
+
+This test harness library does the following things:
+
+ - If the script is invoked with command line argument --help
+   (or -h), it shows the test_description and exits.
+
+ - Creates an empty test directory with an empty .git/objects
+   database and chdir(2) into it.  This directory is 't/trash directory'
+   if you must know, but I do not think you care.
+
+ - Defines standard test helper functions for your scripts to
+   use.  These functions are designed to make all scripts behave
+   consistently when command line arguments --verbose (or -v),
+   --debug (or -d), and --immediate (or -i) is given.
+
+
+End with test_done
+------------------
+
+Your script will be a sequence of tests, using helper functions
+from the test harness library.  At the end of the script, call
+'test_done'.
+
+
+Test harness library
+--------------------
+
+There are a handful helper functions defined in the test harness
+library for your script to use.
+
+ - test_expect_success <message> <script>
+
+   This takes two strings as parameter, and evaluates the
+   <script>.  If it yields success, test is considered
+   successful.  <message> should state what it is testing.
+
+   Example:
+
+	test_expect_success \
+	    'git-write-tree should be able to write an empty tree.' \
+	    'tree=$(git-write-tree)'
+
+ - test_expect_failure <message> <script>
+
+   This is NOT the opposite of test_expect_success, but is used
+   to mark a test that demonstrates a known breakage.  Unlike
+   the usual test_expect_success tests, which say "ok" on
+   success and "FAIL" on failure, this will say "FIXED" on
+   success and "still broken" on failure.  Failures from these
+   tests won't cause -i (immediate) to stop.
+
+ - test_debug <script>
+
+   This takes a single argument, <script>, and evaluates it only
+   when the test script is started with --debug command line
+   argument.  This is primarily meant for use during the
+   development of a new test script.
+
+ - test_done
+
+   Your test script must have test_done at the end.  Its purpose
+   is to summarize successes and failures in the test script and
+   exit with an appropriate error code.
+
+ - test_tick
+
+   Make commit and tag names consistent by setting the author and
+   committer times to defined stated.  Subsequent calls will
+   advance the times by a fixed amount.
+
+ - test_commit <message> [<filename> [<contents>]]
+
+   Creates a commit with the given message, committing the given
+   file with the given contents (default for both is to reuse the
+   message string), and adds a tag (again reusing the message
+   string as name).  Calls test_tick to make the SHA-1s
+   reproducible.
+
+ - test_merge <message> <commit-or-tag>
+
+   Merges the given rev using the given message.  Like test_commit,
+   creates a tag and calls test_tick before committing.
+
+Tips for Writing Tests
+----------------------
+
+As with any programming projects, existing programs are the best
+source of the information.  However, do _not_ emulate
+t0000-basic.sh when writing your tests.  The test is special in
+that it tries to validate the very core of GIT.  For example, it
+knows that there will be 256 subdirectories under .git/objects/,
+and it knows that the object ID of an empty tree is a certain
+40-byte string.  This is deliberately done so in t0000-basic.sh
+because the things the very basic core test tries to achieve is
+to serve as a basis for people who are changing the GIT internal
+drastically.  For these people, after making certain changes,
+not seeing failures from the basic test _is_ a failure.  And
+such drastic changes to the core GIT that even changes these
+otherwise supposedly stable object IDs should be accompanied by
+an update to t0000-basic.sh.
+
+However, other tests that simply rely on basic parts of the core
+GIT working properly should not have that level of intimate
+knowledge of the core GIT internals.  If all the test scripts
+hardcoded the object IDs like t0000-basic.sh does, that defeats
+the purpose of t0000-basic.sh, which is to isolate that level of
+validation in one place.  Your test also ends up needing
+updating when such a change to the internal happens, so do _not_
+do it and leave the low level of validation to t0000-basic.sh.
diff --git a/test/aggregate-results.sh b/test/aggregate-results.sh
new file mode 100755
index 0000000..d5bab75
--- /dev/null
+++ b/test/aggregate-results.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+fixed=0
+success=0
+failed=0
+broken=0
+total=0
+
+for file
+do
+	while read type value
+	do
+		case $type in
+		'')
+			continue ;;
+		fixed)
+			fixed=$(($fixed + $value)) ;;
+		success)
+			success=$(($success + $value)) ;;
+		failed)
+			failed=$(($failed + $value)) ;;
+		broken)
+			broken=$(($broken + $value)) ;;
+		total)
+			total=$(($total + $value)) ;;
+		esac
+	done <"$file"
+done
+
+printf "%-8s%d\n" fixed $fixed
+printf "%-8s%d\n" success $success
+printf "%-8s%d\n" failed $failed
+printf "%-8s%d\n" broken $broken
+printf "%-8s%d\n" total $total
diff --git a/test/t0000-basic.sh b/test/t0000-basic.sh
new file mode 100755
index 0000000..3ec9cbe
--- /dev/null
+++ b/test/t0000-basic.sh
@@ -0,0 +1,389 @@
+#!/bin/sh
+#
+# Copyright (c) 2005 Junio C Hamano
+#
+
+test_description='Test the very basics part #1.
+
+The rest of the test suite does not check the basic operation of git
+plumbing commands to work very carefully.  Their job is to concentrate
+on tricky features that caused bugs in the past to detect regression.
+
+This test runs very basic features, like registering things in cache,
+writing tree, etc.
+
+Note that this test *deliberately* hard-codes many expected object
+IDs.  When object ID computation changes, like in the previous case of
+swapping compression and hashing order, the person who is making the
+modification *should* take notice and update the test vectors here.
+'
+
+################################################################
+# It appears that people try to run tests without building...
+
+../git >/dev/null
+if test $? != 1
+then
+	echo >&2 'You do not seem to have built git yet.'
+	exit 1
+fi
+
+. ./test-lib.sh
+
+################################################################
+# git init has been done in an empty repository.
+# make sure it is empty.
+
+find .git/objects -type f -print >should-be-empty
+test_expect_success \
+    '.git/objects should be empty after git init in an empty repo.' \
+    'cmp -s /dev/null should-be-empty'
+
+# also it should have 2 subdirectories; no fan-out anymore, pack, and info.
+# 3 is counting "objects" itself
+find .git/objects -type d -print >full-of-directories
+test_expect_success \
+    '.git/objects should have 3 subdirectories.' \
+    'test $(wc -l < full-of-directories) = 3'
+
+################################################################
+# Test harness
+test_expect_success 'success is reported like this' '
+    :
+'
+test_expect_failure 'pretend we have a known breakage' '
+    false
+'
+test_expect_failure 'pretend we have fixed a known breakage' '
+    :
+'
+test_set_prereq HAVEIT
+haveit=no
+test_expect_success HAVEIT 'test runs if prerequisite is satisfied' '
+    test_have_prereq HAVEIT &&
+    haveit=yes
+'
+donthaveit=yes
+test_expect_success DONTHAVEIT 'unmet prerequisite causes test to be skipped' '
+    donthaveit=no
+'
+if test $haveit$donthaveit != yesyes
+then
+	say "bug in test framework: prerequisite tags do not work reliably"
+	exit 1
+fi
+
+clean=no
+test_expect_success 'tests clean up after themselves' '
+    test_when_finished clean=yes
+'
+
+cleaner=no
+test_expect_code 1 'tests clean up even after a failure' '
+    test_when_finished cleaner=yes &&
+    (exit 1)
+'
+
+if test $clean$cleaner != yesyes
+then
+	say "bug in test framework: cleanup commands do not work reliably"
+	exit 1
+fi
+
+test_expect_code 2 'failure to clean up causes the test to fail' '
+    test_when_finished "(exit 2)"
+'
+
+################################################################
+# Basics of the basics
+
+# updating a new file without --add should fail.
+test_expect_success 'git update-index without --add should fail adding.' '
+    test_must_fail git update-index should-be-empty
+'
+
+# and with --add it should succeed, even if it is empty (it used to fail).
+test_expect_success \
+    'git update-index with --add should succeed.' \
+    'git update-index --add should-be-empty'
+
+test_expect_success \
+    'writing tree out with git write-tree' \
+    'tree=$(git write-tree)'
+
+# we know the shape and contents of the tree and know the object ID for it.
+test_expect_success \
+    'validate object ID of a known tree.' \
+    'test "$tree" = 7bb943559a305bdd6bdee2cef6e5df2413c3d30a'
+
+# Removing paths.
+rm -f should-be-empty full-of-directories
+test_expect_success 'git update-index without --remove should fail removing.' '
+    test_must_fail git update-index should-be-empty
+'
+
+test_expect_success \
+    'git update-index with --remove should be able to remove.' \
+    'git update-index --remove should-be-empty'
+
+# Empty tree can be written with recent write-tree.
+test_expect_success \
+    'git write-tree should be able to write an empty tree.' \
+    'tree=$(git write-tree)'
+
+test_expect_success \
+    'validate object ID of a known tree.' \
+    'test "$tree" = 4b825dc642cb6eb9a060e54bf8d69288fbee4904'
+
+# Various types of objects
+# Some filesystems do not support symblic links; on such systems
+# some expected values are different
+mkdir path2 path3 path3/subp3
+paths='path0 path2/file2 path3/file3 path3/subp3/file3'
+for p in $paths
+do
+    echo "hello $p" >$p
+done
+if test_have_prereq SYMLINKS
+then
+	for p in $paths
+	do
+		ln -s "hello $p" ${p}sym
+	done
+	expectfilter=cat
+	expectedtree=087704a96baf1c2d1c869a8b084481e121c88b5b
+	expectedptree1=21ae8269cacbe57ae09138dcc3a2887f904d02b3
+	expectedptree2=3c5e5399f3a333eddecce7a9b9465b63f65f51e2
+else
+	expectfilter='grep -v sym'
+	expectedtree=8e18edf7d7edcf4371a3ac6ae5f07c2641db7c46
+	expectedptree1=cfb8591b2f65de8b8cc1020cd7d9e67e7793b325
+	expectedptree2=ce580448f0148b985a513b693fdf7d802cacb44f
+fi
+
+test_expect_success \
+    'adding various types of objects with git update-index --add.' \
+    'find path* ! -type d -print | xargs git update-index --add'
+
+# Show them and see that matches what we expect.
+test_expect_success \
+    'showing stage with git ls-files --stage' \
+    'git ls-files --stage >current'
+
+$expectfilter >expected <<\EOF
+100644 f87290f8eb2cbbea7857214459a0739927eab154 0	path0
+120000 15a98433ae33114b085f3eb3bb03b832b3180a01 0	path0sym
+100644 3feff949ed00a62d9f7af97c15cd8a30595e7ac7 0	path2/file2
+120000 d8ce161addc5173867a3c3c730924388daedbc38 0	path2/file2sym
+100644 0aa34cae68d0878578ad119c86ca2b5ed5b28376 0	path3/file3
+120000 8599103969b43aff7e430efea79ca4636466794f 0	path3/file3sym
+100644 00fb5908cb97c2564a9783c0c64087333b3b464f 0	path3/subp3/file3
+120000 6649a1ebe9e9f1c553b66f5a6e74136a07ccc57c 0	path3/subp3/file3sym
+EOF
+test_expect_success \
+    'validate git ls-files output for a known tree.' \
+    'test_cmp expected current'
+
+test_expect_success \
+    'writing tree out with git write-tree.' \
+    'tree=$(git write-tree)'
+test_expect_success \
+    'validate object ID for a known tree.' \
+    'test "$tree" = "$expectedtree"'
+
+test_expect_success \
+    'showing tree with git ls-tree' \
+    'git ls-tree $tree >current'
+cat >expected <<\EOF
+100644 blob f87290f8eb2cbbea7857214459a0739927eab154	path0
+120000 blob 15a98433ae33114b085f3eb3bb03b832b3180a01	path0sym
+040000 tree 58a09c23e2ca152193f2786e06986b7b6712bdbe	path2
+040000 tree 21ae8269cacbe57ae09138dcc3a2887f904d02b3	path3
+EOF
+test_expect_success SYMLINKS \
+    'git ls-tree output for a known tree.' \
+    'test_cmp expected current'
+
+# This changed in ls-tree pathspec change -- recursive does
+# not show tree nodes anymore.
+test_expect_success \
+    'showing tree with git ls-tree -r' \
+    'git ls-tree -r $tree >current'
+$expectfilter >expected <<\EOF
+100644 blob f87290f8eb2cbbea7857214459a0739927eab154	path0
+120000 blob 15a98433ae33114b085f3eb3bb03b832b3180a01	path0sym
+100644 blob 3feff949ed00a62d9f7af97c15cd8a30595e7ac7	path2/file2
+120000 blob d8ce161addc5173867a3c3c730924388daedbc38	path2/file2sym
+100644 blob 0aa34cae68d0878578ad119c86ca2b5ed5b28376	path3/file3
+120000 blob 8599103969b43aff7e430efea79ca4636466794f	path3/file3sym
+100644 blob 00fb5908cb97c2564a9783c0c64087333b3b464f	path3/subp3/file3
+120000 blob 6649a1ebe9e9f1c553b66f5a6e74136a07ccc57c	path3/subp3/file3sym
+EOF
+test_expect_success \
+    'git ls-tree -r output for a known tree.' \
+    'test_cmp expected current'
+
+# But with -r -t we can have both.
+test_expect_success \
+    'showing tree with git ls-tree -r -t' \
+    'git ls-tree -r -t $tree >current'
+cat >expected <<\EOF
+100644 blob f87290f8eb2cbbea7857214459a0739927eab154	path0
+120000 blob 15a98433ae33114b085f3eb3bb03b832b3180a01	path0sym
+040000 tree 58a09c23e2ca152193f2786e06986b7b6712bdbe	path2
+100644 blob 3feff949ed00a62d9f7af97c15cd8a30595e7ac7	path2/file2
+120000 blob d8ce161addc5173867a3c3c730924388daedbc38	path2/file2sym
+040000 tree 21ae8269cacbe57ae09138dcc3a2887f904d02b3	path3
+100644 blob 0aa34cae68d0878578ad119c86ca2b5ed5b28376	path3/file3
+120000 blob 8599103969b43aff7e430efea79ca4636466794f	path3/file3sym
+040000 tree 3c5e5399f3a333eddecce7a9b9465b63f65f51e2	path3/subp3
+100644 blob 00fb5908cb97c2564a9783c0c64087333b3b464f	path3/subp3/file3
+120000 blob 6649a1ebe9e9f1c553b66f5a6e74136a07ccc57c	path3/subp3/file3sym
+EOF
+test_expect_success SYMLINKS \
+    'git ls-tree -r output for a known tree.' \
+    'test_cmp expected current'
+
+test_expect_success \
+    'writing partial tree out with git write-tree --prefix.' \
+    'ptree=$(git write-tree --prefix=path3)'
+test_expect_success \
+    'validate object ID for a known tree.' \
+    'test "$ptree" = "$expectedptree1"'
+
+test_expect_success \
+    'writing partial tree out with git write-tree --prefix.' \
+    'ptree=$(git write-tree --prefix=path3/subp3)'
+test_expect_success \
+    'validate object ID for a known tree.' \
+    'test "$ptree" = "$expectedptree2"'
+
+cat >badobjects <<EOF
+100644 blob 1000000000000000000000000000000000000000	dir/file1
+100644 blob 2000000000000000000000000000000000000000	dir/file2
+100644 blob 3000000000000000000000000000000000000000	dir/file3
+100644 blob 4000000000000000000000000000000000000000	dir/file4
+100644 blob 5000000000000000000000000000000000000000	dir/file5
+EOF
+
+rm .git/index
+test_expect_success \
+    'put invalid objects into the index.' \
+    'git update-index --index-info < badobjects'
+
+test_expect_success 'writing this tree without --missing-ok.' '
+    test_must_fail git write-tree
+'
+
+test_expect_success \
+    'writing this tree with --missing-ok.' \
+    'git write-tree --missing-ok'
+
+
+################################################################
+rm .git/index
+test_expect_success \
+    'git read-tree followed by write-tree should be idempotent.' \
+    'git read-tree $tree &&
+     test -f .git/index &&
+     newtree=$(git write-tree) &&
+     test "$newtree" = "$tree"'
+
+$expectfilter >expected <<\EOF
+:100644 100644 f87290f8eb2cbbea7857214459a0739927eab154 0000000000000000000000000000000000000000 M	path0
+:120000 120000 15a98433ae33114b085f3eb3bb03b832b3180a01 0000000000000000000000000000000000000000 M	path0sym
+:100644 100644 3feff949ed00a62d9f7af97c15cd8a30595e7ac7 0000000000000000000000000000000000000000 M	path2/file2
+:120000 120000 d8ce161addc5173867a3c3c730924388daedbc38 0000000000000000000000000000000000000000 M	path2/file2sym
+:100644 100644 0aa34cae68d0878578ad119c86ca2b5ed5b28376 0000000000000000000000000000000000000000 M	path3/file3
+:120000 120000 8599103969b43aff7e430efea79ca4636466794f 0000000000000000000000000000000000000000 M	path3/file3sym
+:100644 100644 00fb5908cb97c2564a9783c0c64087333b3b464f 0000000000000000000000000000000000000000 M	path3/subp3/file3
+:120000 120000 6649a1ebe9e9f1c553b66f5a6e74136a07ccc57c 0000000000000000000000000000000000000000 M	path3/subp3/file3sym
+EOF
+test_expect_success \
+    'validate git diff-files output for a know cache/work tree state.' \
+    'git diff-files >current && diff >/dev/null -b current expected'
+
+test_expect_success \
+    'git update-index --refresh should succeed.' \
+    'git update-index --refresh'
+
+test_expect_success \
+    'no diff after checkout and git update-index --refresh.' \
+    'git diff-files >current && cmp -s current /dev/null'
+
+################################################################
+P=$expectedtree
+test_expect_success \
+    'git commit-tree records the correct tree in a commit.' \
+    'commit0=$(echo NO | git commit-tree $P) &&
+     tree=$(git show --pretty=raw $commit0 |
+	 sed -n -e "s/^tree //p" -e "/^author /q") &&
+     test "z$tree" = "z$P"'
+
+test_expect_success \
+    'git commit-tree records the correct parent in a commit.' \
+    'commit1=$(echo NO | git commit-tree $P -p $commit0) &&
+     parent=$(git show --pretty=raw $commit1 |
+	 sed -n -e "s/^parent //p" -e "/^author /q") &&
+     test "z$commit0" = "z$parent"'
+
+test_expect_success \
+    'git commit-tree omits duplicated parent in a commit.' \
+    'commit2=$(echo NO | git commit-tree $P -p $commit0 -p $commit0) &&
+     parent=$(git show --pretty=raw $commit2 |
+	 sed -n -e "s/^parent //p" -e "/^author /q" |
+	 sort -u) &&
+     test "z$commit0" = "z$parent" &&
+     numparent=$(git show --pretty=raw $commit2 |
+	 sed -n -e "s/^parent //p" -e "/^author /q" |
+	 wc -l) &&
+     test $numparent = 1'
+
+test_expect_success 'update-index D/F conflict' '
+	mv path0 tmp &&
+	mv path2 path0 &&
+	mv tmp path2 &&
+	git update-index --add --replace path2 path0/file2 &&
+	numpath0=$(git ls-files path0 | wc -l) &&
+	test $numpath0 = 1
+'
+
+test_expect_success SYMLINKS 'absolute path works as expected' '
+	mkdir first &&
+	ln -s ../.git first/.git &&
+	mkdir second &&
+	ln -s ../first second/other &&
+	mkdir third &&
+	dir="$(cd .git; pwd -P)" &&
+	dir2=third/../second/other/.git &&
+	test "$dir" = "$(test-path-utils make_absolute_path $dir2)" &&
+	file="$dir"/index &&
+	test "$file" = "$(test-path-utils make_absolute_path $dir2/index)" &&
+	basename=blub &&
+	test "$dir/$basename" = "$(cd .git && test-path-utils make_absolute_path "$basename")" &&
+	ln -s ../first/file .git/syml &&
+	sym="$(cd first; pwd -P)"/file &&
+	test "$sym" = "$(test-path-utils make_absolute_path "$dir2/syml")"
+'
+
+test_expect_success 'very long name in the index handled sanely' '
+
+	a=a && # 1
+	a=$a$a$a$a$a$a$a$a$a$a$a$a$a$a$a$a && # 16
+	a=$a$a$a$a$a$a$a$a$a$a$a$a$a$a$a$a && # 256
+	a=$a$a$a$a$a$a$a$a$a$a$a$a$a$a$a$a && # 4096
+	a=${a}q &&
+
+	>path4 &&
+	git update-index --add path4 &&
+	(
+		git ls-files -s path4 |
+		sed -e "s/	.*/	/" |
+		tr -d "\012"
+		echo "$a"
+	) | git update-index --index-info &&
+	len=$(git ls-files "a*" | wc -c) &&
+	test $len = 4098
+'
+
+test_done
diff --git a/test/test-lib.sh b/test/test-lib.sh
new file mode 100644
index 0000000..7422bba
--- /dev/null
+++ b/test/test-lib.sh
@@ -0,0 +1,832 @@
+#!/bin/sh
+#
+# Copyright (c) 2005 Junio C Hamano
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see http://www.gnu.org/licenses/ .
+
+# if --tee was passed, write the output not only to the terminal, but
+# additionally to the file test-results/$BASENAME.out, too.
+case "$GIT_TEST_TEE_STARTED, $* " in
+done,*)
+	# do not redirect again
+	;;
+*' --tee '*|*' --va'*)
+	mkdir -p test-results
+	BASE=test-results/$(basename "$0" .sh)
+	(GIT_TEST_TEE_STARTED=done ${SHELL-sh} "$0" "$@" 2>&1;
+	 echo $? > $BASE.exit) | tee $BASE.out
+	test "$(cat $BASE.exit)" = 0
+	exit
+	;;
+esac
+
+# Keep the original TERM for say_color
+ORIGINAL_TERM=$TERM
+
+# For repeatability, reset the environment to known value.
+LANG=C
+LC_ALL=C
+PAGER=cat
+TZ=UTC
+TERM=dumb
+export LANG LC_ALL PAGER TERM TZ
+EDITOR=:
+unset VISUAL
+unset GIT_EDITOR
+unset AUTHOR_DATE
+unset AUTHOR_EMAIL
+unset AUTHOR_NAME
+unset COMMIT_AUTHOR_EMAIL
+unset COMMIT_AUTHOR_NAME
+unset EMAIL
+unset GIT_ALTERNATE_OBJECT_DIRECTORIES
+unset GIT_AUTHOR_DATE
+GIT_AUTHOR_EMAIL=author@example.com
+GIT_AUTHOR_NAME='A U Thor'
+unset GIT_COMMITTER_DATE
+GIT_COMMITTER_EMAIL=committer@example.com
+GIT_COMMITTER_NAME='C O Mitter'
+unset GIT_DIFF_OPTS
+unset GIT_DIR
+unset GIT_WORK_TREE
+unset GIT_EXTERNAL_DIFF
+unset GIT_INDEX_FILE
+unset GIT_OBJECT_DIRECTORY
+unset GIT_CEILING_DIRECTORIES
+unset SHA1_FILE_DIRECTORIES
+unset SHA1_FILE_DIRECTORY
+unset GIT_NOTES_REF
+unset GIT_NOTES_DISPLAY_REF
+unset GIT_NOTES_REWRITE_REF
+unset GIT_NOTES_REWRITE_MODE
+GIT_MERGE_VERBOSITY=5
+export GIT_MERGE_VERBOSITY
+export GIT_AUTHOR_EMAIL GIT_AUTHOR_NAME
+export GIT_COMMITTER_EMAIL GIT_COMMITTER_NAME
+export EDITOR
+GIT_TEST_CMP=${GIT_TEST_CMP:-diff -u}
+
+# Protect ourselves from common misconfiguration to export
+# CDPATH into the environment
+unset CDPATH
+
+unset GREP_OPTIONS
+
+case $(echo $GIT_TRACE |tr "[A-Z]" "[a-z]") in
+	1|2|true)
+		echo "* warning: Some tests will not work if GIT_TRACE" \
+			"is set as to trace on STDERR ! *"
+		echo "* warning: Please set GIT_TRACE to something" \
+			"other than 1, 2 or true ! *"
+		;;
+esac
+
+# Convenience
+#
+# A regexp to match 5 and 40 hexdigits
+_x05='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
+_x40="$_x05$_x05$_x05$_x05$_x05$_x05$_x05$_x05"
+
+# Each test should start with something like this, after copyright notices:
+#
+# test_description='Description of this test...
+# This test checks if command xyzzy does the right thing...
+# '
+# . ./test-lib.sh
+[ "x$ORIGINAL_TERM" != "xdumb" ] && (
+		TERM=$ORIGINAL_TERM &&
+		export TERM &&
+		[ -t 1 ] &&
+		tput bold >/dev/null 2>&1 &&
+		tput setaf 1 >/dev/null 2>&1 &&
+		tput sgr0 >/dev/null 2>&1
+	) &&
+	color=t
+
+while test "$#" -ne 0
+do
+	case "$1" in
+	-d|--d|--de|--deb|--debu|--debug)
+		debug=t; shift ;;
+	-i|--i|--im|--imm|--imme|--immed|--immedi|--immedia|--immediat|--immediate)
+		immediate=t; shift ;;
+	-l|--l|--lo|--lon|--long|--long-|--long-t|--long-te|--long-tes|--long-test|--long-tests)
+		GIT_TEST_LONG=t; export GIT_TEST_LONG; shift ;;
+	-h|--h|--he|--hel|--help)
+		help=t; shift ;;
+	-v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose)
+		verbose=t; shift ;;
+	-q|--q|--qu|--qui|--quie|--quiet)
+		quiet=t; shift ;;
+	--with-dashes)
+		with_dashes=t; shift ;;
+	--no-color)
+		color=; shift ;;
+	--no-python)
+		# noop now...
+		shift ;;
+	--va|--val|--valg|--valgr|--valgri|--valgrin|--valgrind)
+		valgrind=t; verbose=t; shift ;;
+	--tee)
+		shift ;; # was handled already
+	--root=*)
+		root=$(expr "z$1" : 'z[^=]*=\(.*\)')
+		shift ;;
+	*)
+		echo "error: unknown test option '$1'" >&2; exit 1 ;;
+	esac
+done
+
+if test -n "$color"; then
+	say_color () {
+		(
+		TERM=$ORIGINAL_TERM
+		export TERM
+		case "$1" in
+			error) tput bold; tput setaf 1;; # bold red
+			skip)  tput bold; tput setaf 2;; # bold green
+			pass)  tput setaf 2;;            # green
+			info)  tput setaf 3;;            # brown
+			*) test -n "$quiet" && return;;
+		esac
+		shift
+		printf "* %s" "$*"
+		tput sgr0
+		echo
+		)
+	}
+else
+	say_color() {
+		test -z "$1" && test -n "$quiet" && return
+		shift
+		echo "* $*"
+	}
+fi
+
+error () {
+	say_color error "error: $*"
+	GIT_EXIT_OK=t
+	exit 1
+}
+
+say () {
+	say_color info "$*"
+}
+
+test "${test_description}" != "" ||
+error "Test script did not set test_description."
+
+if test "$help" = "t"
+then
+	echo "$test_description"
+	exit 0
+fi
+
+exec 5>&1
+if test "$verbose" = "t"
+then
+	exec 4>&2 3>&1
+else
+	exec 4>/dev/null 3>/dev/null
+fi
+
+test_failure=0
+test_count=0
+test_fixed=0
+test_broken=0
+test_success=0
+
+die () {
+	code=$?
+	if test -n "$GIT_EXIT_OK"
+	then
+		exit $code
+	else
+		echo >&5 "FATAL: Unexpected exit with code $code"
+		exit 1
+	fi
+}
+
+GIT_EXIT_OK=
+trap 'die' EXIT
+
+# The semantics of the editor variables are that of invoking
+# sh -c "$EDITOR \"$@\"" files ...
+#
+# If our trash directory contains shell metacharacters, they will be
+# interpreted if we just set $EDITOR directly, so do a little dance with
+# environment variables to work around this.
+#
+# In particular, quoting isn't enough, as the path may contain the same quote
+# that we're using.
+test_set_editor () {
+	FAKE_EDITOR="$1"
+	export FAKE_EDITOR
+	EDITOR='"$FAKE_EDITOR"'
+	export EDITOR
+}
+
+test_decode_color () {
+	sed	-e 's/.\[1m/<WHITE>/g' \
+		-e 's/.\[31m/<RED>/g' \
+		-e 's/.\[32m/<GREEN>/g' \
+		-e 's/.\[33m/<YELLOW>/g' \
+		-e 's/.\[34m/<BLUE>/g' \
+		-e 's/.\[35m/<MAGENTA>/g' \
+		-e 's/.\[36m/<CYAN>/g' \
+		-e 's/.\[m/<RESET>/g'
+}
+
+q_to_nul () {
+	perl -pe 'y/Q/\000/'
+}
+
+q_to_cr () {
+	tr Q '\015'
+}
+
+append_cr () {
+	sed -e 's/$/Q/' | tr Q '\015'
+}
+
+remove_cr () {
+	tr '\015' Q | sed -e 's/Q$//'
+}
+
+test_tick () {
+	if test -z "${test_tick+set}"
+	then
+		test_tick=1112911993
+	else
+		test_tick=$(($test_tick + 60))
+	fi
+	GIT_COMMITTER_DATE="$test_tick -0700"
+	GIT_AUTHOR_DATE="$test_tick -0700"
+	export GIT_COMMITTER_DATE GIT_AUTHOR_DATE
+}
+
+# Call test_commit with the arguments "<message> [<file> [<contents>]]"
+#
+# This will commit a file with the given contents and the given commit
+# message.  It will also add a tag with <message> as name.
+#
+# Both <file> and <contents> default to <message>.
+
+test_commit () {
+	file=${2:-"$1.t"}
+	echo "${3-$1}" > "$file" &&
+	git add "$file" &&
+	test_tick &&
+	git commit -m "$1" &&
+	git tag "$1"
+}
+
+# Call test_merge with the arguments "<message> <commit>", where <commit>
+# can be a tag pointing to the commit-to-merge.
+
+test_merge () {
+	test_tick &&
+	git merge -m "$1" "$2" &&
+	git tag "$1"
+}
+
+# This function helps systems where core.filemode=false is set.
+# Use it instead of plain 'chmod +x' to set or unset the executable bit
+# of a file in the working directory and add it to the index.
+
+test_chmod () {
+	chmod "$@" &&
+	git update-index --add "--chmod=$@"
+}
+
+# Use test_set_prereq to tell that a particular prerequisite is available.
+# The prerequisite can later be checked for in two ways:
+#
+# - Explicitly using test_have_prereq.
+#
+# - Implicitly by specifying the prerequisite tag in the calls to
+#   test_expect_{success,failure,code}.
+#
+# The single parameter is the prerequisite tag (a simple word, in all
+# capital letters by convention).
+
+test_set_prereq () {
+	satisfied="$satisfied$1 "
+}
+satisfied=" "
+
+test_have_prereq () {
+	case $satisfied in
+	*" $1 "*)
+		: yes, have it ;;
+	*)
+		! : nope ;;
+	esac
+}
+
+# You are not expected to call test_ok_ and test_failure_ directly, use
+# the text_expect_* functions instead.
+
+test_ok_ () {
+	test_success=$(($test_success + 1))
+	say_color "" "  ok $test_count: $@"
+}
+
+test_failure_ () {
+	test_failure=$(($test_failure + 1))
+	say_color error "FAIL $test_count: $1"
+	shift
+	echo "$@" | sed -e 's/^/	/'
+	test "$immediate" = "" || { GIT_EXIT_OK=t; exit 1; }
+}
+
+test_known_broken_ok_ () {
+	test_fixed=$(($test_fixed+1))
+	say_color "" "  FIXED $test_count: $@"
+}
+
+test_known_broken_failure_ () {
+	test_broken=$(($test_broken+1))
+	say_color skip "  still broken $test_count: $@"
+}
+
+test_debug () {
+	test "$debug" = "" || eval "$1"
+}
+
+test_run_ () {
+	test_cleanup=:
+	eval >&3 2>&4 "$1"
+	eval_ret=$?
+	eval >&3 2>&4 "$test_cleanup"
+	return 0
+}
+
+test_skip () {
+	test_count=$(($test_count+1))
+	to_skip=
+	for skp in $GIT_SKIP_TESTS
+	do
+		case $this_test.$test_count in
+		$skp)
+			to_skip=t
+		esac
+	done
+	if test -z "$to_skip" && test -n "$prereq" &&
+	   ! test_have_prereq "$prereq"
+	then
+		to_skip=t
+	fi
+	case "$to_skip" in
+	t)
+		say_color skip >&3 "skipping test: $@"
+		say_color skip "skip $test_count: $1"
+		: true
+		;;
+	*)
+		false
+		;;
+	esac
+}
+
+test_expect_failure () {
+	test "$#" = 3 && { prereq=$1; shift; } || prereq=
+	test "$#" = 2 ||
+	error "bug in the test script: not 2 or 3 parameters to test-expect-failure"
+	if ! test_skip "$@"
+	then
+		say >&3 "checking known breakage: $2"
+		test_run_ "$2"
+		if [ "$?" = 0 -a "$eval_ret" = 0 ]
+		then
+			test_known_broken_ok_ "$1"
+		else
+			test_known_broken_failure_ "$1"
+		fi
+	fi
+	echo >&3 ""
+}
+
+test_expect_success () {
+	test "$#" = 3 && { prereq=$1; shift; } || prereq=
+	test "$#" = 2 ||
+	error "bug in the test script: not 2 or 3 parameters to test-expect-success"
+	if ! test_skip "$@"
+	then
+		say >&3 "expecting success: $2"
+		test_run_ "$2"
+		if [ "$?" = 0 -a "$eval_ret" = 0 ]
+		then
+			test_ok_ "$1"
+		else
+			test_failure_ "$@"
+		fi
+	fi
+	echo >&3 ""
+}
+
+test_expect_code () {
+	test "$#" = 4 && { prereq=$1; shift; } || prereq=
+	test "$#" = 3 ||
+	error "bug in the test script: not 3 or 4 parameters to test-expect-code"
+	if ! test_skip "$@"
+	then
+		say >&3 "expecting exit code $1: $3"
+		test_run_ "$3"
+		if [ "$?" = 0 -a "$eval_ret" = "$1" ]
+		then
+			test_ok_ "$2"
+		else
+			test_failure_ "$@"
+		fi
+	fi
+	echo >&3 ""
+}
+
+# test_external runs external test scripts that provide continuous
+# test output about their progress, and succeeds/fails on
+# zero/non-zero exit code.  It outputs the test output on stdout even
+# in non-verbose mode, and announces the external script with "* run
+# <n>: ..." before running it.  When providing relative paths, keep in
+# mind that all scripts run in "trash directory".
+# Usage: test_external description command arguments...
+# Example: test_external 'Perl API' perl ../path/to/test.pl
+test_external () {
+	test "$#" = 4 && { prereq=$1; shift; } || prereq=
+	test "$#" = 3 ||
+	error >&5 "bug in the test script: not 3 or 4 parameters to test_external"
+	descr="$1"
+	shift
+	if ! test_skip "$descr" "$@"
+	then
+		# Announce the script to reduce confusion about the
+		# test output that follows.
+		say_color "" " run $test_count: $descr ($*)"
+		# Run command; redirect its stderr to &4 as in
+		# test_run_, but keep its stdout on our stdout even in
+		# non-verbose mode.
+		"$@" 2>&4
+		if [ "$?" = 0 ]
+		then
+			test_ok_ "$descr"
+		else
+			test_failure_ "$descr" "$@"
+		fi
+	fi
+}
+
+# Like test_external, but in addition tests that the command generated
+# no output on stderr.
+test_external_without_stderr () {
+	# The temporary file has no (and must have no) security
+	# implications.
+	tmp="$TMPDIR"; if [ -z "$tmp" ]; then tmp=/tmp; fi
+	stderr="$tmp/git-external-stderr.$$.tmp"
+	test_external "$@" 4> "$stderr"
+	[ -f "$stderr" ] || error "Internal error: $stderr disappeared."
+	descr="no stderr: $1"
+	shift
+	say >&3 "expecting no stderr from previous command"
+	if [ ! -s "$stderr" ]; then
+		rm "$stderr"
+		test_ok_ "$descr"
+	else
+		if [ "$verbose" = t ]; then
+			output=`echo; echo Stderr is:; cat "$stderr"`
+		else
+			output=
+		fi
+		# rm first in case test_failure exits.
+		rm "$stderr"
+		test_failure_ "$descr" "$@" "$output"
+	fi
+}
+
+# This is not among top-level (test_expect_success | test_expect_failure)
+# but is a prefix that can be used in the test script, like:
+#
+#	test_expect_success 'complain and die' '
+#           do something &&
+#           do something else &&
+#	    test_must_fail git checkout ../outerspace
+#	'
+#
+# Writing this as "! git checkout ../outerspace" is wrong, because
+# the failure could be due to a segv.  We want a controlled failure.
+
+test_must_fail () {
+	"$@"
+	test $? -gt 0 -a $? -le 129 -o $? -gt 192
+}
+
+# test_cmp is a helper function to compare actual and expected output.
+# You can use it like:
+#
+#	test_expect_success 'foo works' '
+#		echo expected >expected &&
+#		foo >actual &&
+#		test_cmp expected actual
+#	'
+#
+# This could be written as either "cmp" or "diff -u", but:
+# - cmp's output is not nearly as easy to read as diff -u
+# - not all diff versions understand "-u"
+
+test_cmp() {
+	$GIT_TEST_CMP "$@"
+}
+
+# This function can be used to schedule some commands to be run
+# unconditionally at the end of the test to restore sanity:
+#
+#	test_expect_success 'test core.capslock' '
+#		git config core.capslock true &&
+#		test_when_finished "git config --unset core.capslock" &&
+#		hello world
+#	'
+#
+# That would be roughly equivalent to
+#
+#	test_expect_success 'test core.capslock' '
+#		git config core.capslock true &&
+#		hello world
+#		git config --unset core.capslock
+#	'
+#
+# except that the greeting and config --unset must both succeed for
+# the test to pass.
+
+test_when_finished () {
+	test_cleanup="{ $*
+		} && (exit \"\$eval_ret\"); eval_ret=\$?; $test_cleanup"
+}
+
+# Most tests can use the created repository, but some may need to create more.
+# Usage: test_create_repo <directory>
+test_create_repo () {
+	test "$#" = 1 ||
+	error "bug in the test script: not 1 parameter to test-create-repo"
+	owd=`pwd`
+	repo="$1"
+	mkdir -p "$repo"
+	cd "$repo" || error "Cannot setup test environment"
+	"$GIT_EXEC_PATH/git-init" "--template=$TEST_DIRECTORY/../templates/blt/" >&3 2>&4 ||
+	error "cannot run git init -- have you built things yet?"
+	mv .git/hooks .git/hooks-disabled
+	cd "$owd"
+}
+
+test_done () {
+	GIT_EXIT_OK=t
+	test_results_dir="$TEST_DIRECTORY/test-results"
+	mkdir -p "$test_results_dir"
+	test_results_path="$test_results_dir/${0%.sh}-$$"
+
+	echo "total $test_count" >> $test_results_path
+	echo "success $test_success" >> $test_results_path
+	echo "fixed $test_fixed" >> $test_results_path
+	echo "broken $test_broken" >> $test_results_path
+	echo "failed $test_failure" >> $test_results_path
+	echo "" >> $test_results_path
+
+	if test "$test_fixed" != 0
+	then
+		say_color pass "fixed $test_fixed known breakage(s)"
+	fi
+	if test "$test_broken" != 0
+	then
+		say_color error "still have $test_broken known breakage(s)"
+		msg="remaining $(($test_count-$test_broken)) test(s)"
+	else
+		msg="$test_count test(s)"
+	fi
+	case "$test_failure" in
+	0)
+		say_color pass "passed all $msg"
+
+		test -d "$remove_trash" &&
+		cd "$(dirname "$remove_trash")" &&
+		rm -rf "$(basename "$remove_trash")"
+
+		exit 0 ;;
+
+	*)
+		say_color error "failed $test_failure among $msg"
+		exit 1 ;;
+
+	esac
+}
+
+# Test the binaries we have just built.  The tests are kept in
+# t/ subdirectory and are run in 'trash directory' subdirectory.
+TEST_DIRECTORY=$(pwd)
+if test -n "$valgrind"
+then
+	make_symlink () {
+		test -h "$2" &&
+		test "$1" = "$(readlink "$2")" || {
+			# be super paranoid
+			if mkdir "$2".lock
+			then
+				rm -f "$2" &&
+				ln -s "$1" "$2" &&
+				rm -r "$2".lock
+			else
+				while test -d "$2".lock
+				do
+					say "Waiting for lock on $2."
+					sleep 1
+				done
+			fi
+		}
+	}
+
+	make_valgrind_symlink () {
+		# handle only executables
+		test -x "$1" || return
+
+		base=$(basename "$1")
+		symlink_target=$TEST_DIRECTORY/../$base
+		# do not override scripts
+		if test -x "$symlink_target" &&
+		    test ! -d "$symlink_target" &&
+		    test "#!" != "$(head -c 2 < "$symlink_target")"
+		then
+			symlink_target=../valgrind.sh
+		fi
+		case "$base" in
+		*.sh|*.perl)
+			symlink_target=../unprocessed-script
+		esac
+		# create the link, or replace it if it is out of date
+		make_symlink "$symlink_target" "$GIT_VALGRIND/bin/$base" || exit
+	}
+
+	# override all git executables in TEST_DIRECTORY/..
+	GIT_VALGRIND=$TEST_DIRECTORY/valgrind
+	mkdir -p "$GIT_VALGRIND"/bin
+	for file in $TEST_DIRECTORY/../git* $TEST_DIRECTORY/../test-*
+	do
+		make_valgrind_symlink $file
+	done
+	OLDIFS=$IFS
+	IFS=:
+	for path in $PATH
+	do
+		ls "$path"/git-* 2> /dev/null |
+		while read file
+		do
+			make_valgrind_symlink "$file"
+		done
+	done
+	IFS=$OLDIFS
+	PATH=$GIT_VALGRIND/bin:$PATH
+	GIT_EXEC_PATH=$GIT_VALGRIND/bin
+	export GIT_VALGRIND
+elif test -n "$GIT_TEST_INSTALLED" ; then
+	GIT_EXEC_PATH=$($GIT_TEST_INSTALLED/git --exec-path)  ||
+	error "Cannot run git from $GIT_TEST_INSTALLED."
+	PATH=$GIT_TEST_INSTALLED:$TEST_DIRECTORY/..:$PATH
+	GIT_EXEC_PATH=${GIT_TEST_EXEC_PATH:-$GIT_EXEC_PATH}
+else # normal case, use ../bin-wrappers only unless $with_dashes:
+	git_bin_dir="$TEST_DIRECTORY/../bin-wrappers"
+	if ! test -x "$git_bin_dir/git" ; then
+		if test -z "$with_dashes" ; then
+			say "$git_bin_dir/git is not executable; using GIT_EXEC_PATH"
+		fi
+		with_dashes=t
+	fi
+	PATH="$git_bin_dir:$PATH"
+	GIT_EXEC_PATH=$TEST_DIRECTORY/..
+	if test -n "$with_dashes" ; then
+		PATH="$TEST_DIRECTORY/..:$PATH"
+	fi
+fi
+GIT_TEMPLATE_DIR=$(pwd)/../templates/blt
+unset GIT_CONFIG
+GIT_CONFIG_NOSYSTEM=1
+GIT_CONFIG_NOGLOBAL=1
+export PATH GIT_EXEC_PATH GIT_TEMPLATE_DIR GIT_CONFIG_NOSYSTEM GIT_CONFIG_NOGLOBAL
+
+. ../GIT-BUILD-OPTIONS
+
+GITPERLLIB=$(pwd)/../perl/blib/lib:$(pwd)/../perl/blib/arch/auto/Git
+export GITPERLLIB
+test -d ../templates/blt || {
+	error "You haven't built things yet, have you?"
+}
+
+if test -z "$GIT_TEST_INSTALLED" && test -z "$NO_PYTHON"
+then
+	GITPYTHONLIB="$(pwd)/../git_remote_helpers/build/lib"
+	export GITPYTHONLIB
+	test -d ../git_remote_helpers/build || {
+		error "You haven't built git_remote_helpers yet, have you?"
+	}
+fi
+
+if ! test -x ../test-chmtime; then
+	echo >&2 'You need to build test-chmtime:'
+	echo >&2 'Run "make test-chmtime" in the source (toplevel) directory'
+	exit 1
+fi
+
+# Test repository
+test="trash directory.$(basename "$0" .sh)"
+test -n "$root" && test="$root/$test"
+case "$test" in
+/*) TRASH_DIRECTORY="$test" ;;
+ *) TRASH_DIRECTORY="$TEST_DIRECTORY/$test" ;;
+esac
+test ! -z "$debug" || remove_trash=$TRASH_DIRECTORY
+rm -fr "$test" || {
+	GIT_EXIT_OK=t
+	echo >&5 "FATAL: Cannot prepare test area"
+	exit 1
+}
+
+test_create_repo "$test"
+# Use -P to resolve symlinks in our working directory so that the cwd
+# in subprocesses like git equals our $PWD (for pathname comparisons).
+cd -P "$test" || exit 1
+
+this_test=${0##*/}
+this_test=${this_test%%-*}
+for skp in $GIT_SKIP_TESTS
+do
+	to_skip=
+	for skp in $GIT_SKIP_TESTS
+	do
+		case "$this_test" in
+		$skp)
+			to_skip=t
+		esac
+	done
+	case "$to_skip" in
+	t)
+		say_color skip >&3 "skipping test $this_test altogether"
+		say_color skip "skip all tests in $this_test"
+		test_done
+	esac
+done
+
+# Provide an implementation of the 'yes' utility
+yes () {
+	if test $# = 0
+	then
+		y=y
+	else
+		y="$*"
+	fi
+
+	while echo "$y"
+	do
+		:
+	done
+}
+
+# Fix some commands on Windows
+case $(uname -s) in
+*MINGW*)
+	# Windows has its own (incompatible) sort and find
+	sort () {
+		/usr/bin/sort "$@"
+	}
+	find () {
+		/usr/bin/find "$@"
+	}
+	sum () {
+		md5sum "$@"
+	}
+	# git sees Windows-style pwd
+	pwd () {
+		builtin pwd -W
+	}
+	# no POSIX permissions
+	# backslashes in pathspec are converted to '/'
+	# exec does not inherit the PID
+	;;
+*)
+	test_set_prereq POSIXPERM
+	test_set_prereq BSLASHPSPEC
+	test_set_prereq EXECKEEPSPID
+	;;
+esac
+
+test -z "$NO_PERL" && test_set_prereq PERL
+test -z "$NO_PYTHON" && test_set_prereq PYTHON
+
+# test whether the filesystem supports symbolic links
+ln -s x y 2>/dev/null && test -h y 2>/dev/null && test_set_prereq SYMLINKS
+rm -f y
-- 
1.7.1.3.g75e44

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

* [PATCH v3 2/5] Update test framework for use with notmuch
  2010-06-10  6:47 [PATCH v3 0/5] Git-based modularization of test suite Michal Sojka
  2010-06-10  6:48 ` [PATCH v3 1/5] Copy test framework from Git Michal Sojka
@ 2010-06-10  6:48 ` Michal Sojka
  2010-06-10  6:48 ` [PATCH v3 3/5] test: Update helper functions Michal Sojka
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 11+ messages in thread
From: Michal Sojka @ 2010-06-10  6:48 UTC (permalink / raw)
  To: notmuch

This removes Git specific things from the test-lib.sh and adds helper
functions for notmuch taken from Carl's notmuch-test script. README is
also slightly modified to reflect the current state.

Signed-off-by: Michal Sojka <sojkam1@fel.cvut.cz>
---
 test/Makefile       |    1 +
 test/README         |   12 +-
 test/t0000-basic.sh |  335 +++-------------------------------------------
 test/test-lib.sh    |  374 +++++++++++++++++++++++++++++++--------------------
 4 files changed, 256 insertions(+), 466 deletions(-)

diff --git a/test/Makefile b/test/Makefile
index 25c559b..7a29eaa 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -6,6 +6,7 @@
 -include ../config.mak
 
 #GIT_TEST_OPTS=--verbose --debug
+SHELL=/bin/bash
 SHELL_PATH ?= $(SHELL)
 TAR ?= $(TAR)
 RM ?= rm -f
diff --git a/test/README b/test/README
index dcd3ebb..af27d60 100644
--- a/test/README
+++ b/test/README
@@ -165,10 +165,10 @@ Writing Tests
 -------------
 
 The test script is written as a shell script.  It should start
-with the standard "#!/bin/sh" with copyright notices, and an
+with the standard "#!/bin/bash" with copyright notices, and an
 assignment to variable 'test_description', like this:
 
-	#!/bin/sh
+	#!/bin/bash
 	#
 	# Copyright (c) 2005 Junio C Hamano
 	#
@@ -192,9 +192,11 @@ This test harness library does the following things:
  - If the script is invoked with command line argument --help
    (or -h), it shows the test_description and exits.
 
- - Creates an empty test directory with an empty .git/objects
-   database and chdir(2) into it.  This directory is 't/trash directory'
-   if you must know, but I do not think you care.
+ - Creates a test directory with default notmuch-config and empty mail
+   store. This directory is 't/trash directory.<test-basename>' (note
+   the space) if you must know, but I do not think you care. The path
+   to notmuch-config is exported in NOTMUCH_CONFIG environment
+   variable and mail store path is stored in MAIL_DIR variable.
 
  - Defines standard test helper functions for your scripts to
    use.  These functions are designed to make all scripts behave
diff --git a/test/t0000-basic.sh b/test/t0000-basic.sh
index 3ec9cbe..caade68 100755
--- a/test/t0000-basic.sh
+++ b/test/t0000-basic.sh
@@ -3,48 +3,39 @@
 # Copyright (c) 2005 Junio C Hamano
 #
 
-test_description='Test the very basics part #1.
-
-The rest of the test suite does not check the basic operation of git
-plumbing commands to work very carefully.  Their job is to concentrate
-on tricky features that caused bugs in the past to detect regression.
-
-This test runs very basic features, like registering things in cache,
-writing tree, etc.
-
-Note that this test *deliberately* hard-codes many expected object
-IDs.  When object ID computation changes, like in the previous case of
-swapping compression and hashing order, the person who is making the
-modification *should* take notice and update the test vectors here.
-'
+test_description='Tests the test framework itself.'
 
 ################################################################
 # It appears that people try to run tests without building...
 
-../git >/dev/null
-if test $? != 1
+if ! test -x ../notmuch
 then
-	echo >&2 'You do not seem to have built git yet.'
+	echo >&2 'You do not seem to have built notmuch yet.'
 	exit 1
 fi
 
 . ./test-lib.sh
 
 ################################################################
-# git init has been done in an empty repository.
-# make sure it is empty.
+# Test mail store prepared in test-lib.sh
 
-find .git/objects -type f -print >should-be-empty
 test_expect_success \
-    '.git/objects should be empty after git init in an empty repo.' \
+    'test that mail store was created' \
+    'test -d "${MAIL_DIR}"'
+
+
+find "${MAIL_DIR}" -type f -print >should-be-empty
+test_expect_success \
+    'mail store should be empty' \
     'cmp -s /dev/null should-be-empty'
 
-# also it should have 2 subdirectories; no fan-out anymore, pack, and info.
-# 3 is counting "objects" itself
-find .git/objects -type d -print >full-of-directories
 test_expect_success \
-    '.git/objects should have 3 subdirectories.' \
-    'test $(wc -l < full-of-directories) = 3'
+    'NOTMUCH_CONFIG is set and points to an existing file' \
+    'test -f "${NOTMUCH_CONFIG}"'
+
+test_expect_success \
+    'PATH is set to this repository' \
+    'test "`echo $PATH|cut -f1 -d:`" = "`dirname ${TEST_DIRECTORY}`"'
 
 ################################################################
 # Test harness
@@ -94,296 +85,4 @@ test_expect_code 2 'failure to clean up causes the test to fail' '
     test_when_finished "(exit 2)"
 '
 
-################################################################
-# Basics of the basics
-
-# updating a new file without --add should fail.
-test_expect_success 'git update-index without --add should fail adding.' '
-    test_must_fail git update-index should-be-empty
-'
-
-# and with --add it should succeed, even if it is empty (it used to fail).
-test_expect_success \
-    'git update-index with --add should succeed.' \
-    'git update-index --add should-be-empty'
-
-test_expect_success \
-    'writing tree out with git write-tree' \
-    'tree=$(git write-tree)'
-
-# we know the shape and contents of the tree and know the object ID for it.
-test_expect_success \
-    'validate object ID of a known tree.' \
-    'test "$tree" = 7bb943559a305bdd6bdee2cef6e5df2413c3d30a'
-
-# Removing paths.
-rm -f should-be-empty full-of-directories
-test_expect_success 'git update-index without --remove should fail removing.' '
-    test_must_fail git update-index should-be-empty
-'
-
-test_expect_success \
-    'git update-index with --remove should be able to remove.' \
-    'git update-index --remove should-be-empty'
-
-# Empty tree can be written with recent write-tree.
-test_expect_success \
-    'git write-tree should be able to write an empty tree.' \
-    'tree=$(git write-tree)'
-
-test_expect_success \
-    'validate object ID of a known tree.' \
-    'test "$tree" = 4b825dc642cb6eb9a060e54bf8d69288fbee4904'
-
-# Various types of objects
-# Some filesystems do not support symblic links; on such systems
-# some expected values are different
-mkdir path2 path3 path3/subp3
-paths='path0 path2/file2 path3/file3 path3/subp3/file3'
-for p in $paths
-do
-    echo "hello $p" >$p
-done
-if test_have_prereq SYMLINKS
-then
-	for p in $paths
-	do
-		ln -s "hello $p" ${p}sym
-	done
-	expectfilter=cat
-	expectedtree=087704a96baf1c2d1c869a8b084481e121c88b5b
-	expectedptree1=21ae8269cacbe57ae09138dcc3a2887f904d02b3
-	expectedptree2=3c5e5399f3a333eddecce7a9b9465b63f65f51e2
-else
-	expectfilter='grep -v sym'
-	expectedtree=8e18edf7d7edcf4371a3ac6ae5f07c2641db7c46
-	expectedptree1=cfb8591b2f65de8b8cc1020cd7d9e67e7793b325
-	expectedptree2=ce580448f0148b985a513b693fdf7d802cacb44f
-fi
-
-test_expect_success \
-    'adding various types of objects with git update-index --add.' \
-    'find path* ! -type d -print | xargs git update-index --add'
-
-# Show them and see that matches what we expect.
-test_expect_success \
-    'showing stage with git ls-files --stage' \
-    'git ls-files --stage >current'
-
-$expectfilter >expected <<\EOF
-100644 f87290f8eb2cbbea7857214459a0739927eab154 0	path0
-120000 15a98433ae33114b085f3eb3bb03b832b3180a01 0	path0sym
-100644 3feff949ed00a62d9f7af97c15cd8a30595e7ac7 0	path2/file2
-120000 d8ce161addc5173867a3c3c730924388daedbc38 0	path2/file2sym
-100644 0aa34cae68d0878578ad119c86ca2b5ed5b28376 0	path3/file3
-120000 8599103969b43aff7e430efea79ca4636466794f 0	path3/file3sym
-100644 00fb5908cb97c2564a9783c0c64087333b3b464f 0	path3/subp3/file3
-120000 6649a1ebe9e9f1c553b66f5a6e74136a07ccc57c 0	path3/subp3/file3sym
-EOF
-test_expect_success \
-    'validate git ls-files output for a known tree.' \
-    'test_cmp expected current'
-
-test_expect_success \
-    'writing tree out with git write-tree.' \
-    'tree=$(git write-tree)'
-test_expect_success \
-    'validate object ID for a known tree.' \
-    'test "$tree" = "$expectedtree"'
-
-test_expect_success \
-    'showing tree with git ls-tree' \
-    'git ls-tree $tree >current'
-cat >expected <<\EOF
-100644 blob f87290f8eb2cbbea7857214459a0739927eab154	path0
-120000 blob 15a98433ae33114b085f3eb3bb03b832b3180a01	path0sym
-040000 tree 58a09c23e2ca152193f2786e06986b7b6712bdbe	path2
-040000 tree 21ae8269cacbe57ae09138dcc3a2887f904d02b3	path3
-EOF
-test_expect_success SYMLINKS \
-    'git ls-tree output for a known tree.' \
-    'test_cmp expected current'
-
-# This changed in ls-tree pathspec change -- recursive does
-# not show tree nodes anymore.
-test_expect_success \
-    'showing tree with git ls-tree -r' \
-    'git ls-tree -r $tree >current'
-$expectfilter >expected <<\EOF
-100644 blob f87290f8eb2cbbea7857214459a0739927eab154	path0
-120000 blob 15a98433ae33114b085f3eb3bb03b832b3180a01	path0sym
-100644 blob 3feff949ed00a62d9f7af97c15cd8a30595e7ac7	path2/file2
-120000 blob d8ce161addc5173867a3c3c730924388daedbc38	path2/file2sym
-100644 blob 0aa34cae68d0878578ad119c86ca2b5ed5b28376	path3/file3
-120000 blob 8599103969b43aff7e430efea79ca4636466794f	path3/file3sym
-100644 blob 00fb5908cb97c2564a9783c0c64087333b3b464f	path3/subp3/file3
-120000 blob 6649a1ebe9e9f1c553b66f5a6e74136a07ccc57c	path3/subp3/file3sym
-EOF
-test_expect_success \
-    'git ls-tree -r output for a known tree.' \
-    'test_cmp expected current'
-
-# But with -r -t we can have both.
-test_expect_success \
-    'showing tree with git ls-tree -r -t' \
-    'git ls-tree -r -t $tree >current'
-cat >expected <<\EOF
-100644 blob f87290f8eb2cbbea7857214459a0739927eab154	path0
-120000 blob 15a98433ae33114b085f3eb3bb03b832b3180a01	path0sym
-040000 tree 58a09c23e2ca152193f2786e06986b7b6712bdbe	path2
-100644 blob 3feff949ed00a62d9f7af97c15cd8a30595e7ac7	path2/file2
-120000 blob d8ce161addc5173867a3c3c730924388daedbc38	path2/file2sym
-040000 tree 21ae8269cacbe57ae09138dcc3a2887f904d02b3	path3
-100644 blob 0aa34cae68d0878578ad119c86ca2b5ed5b28376	path3/file3
-120000 blob 8599103969b43aff7e430efea79ca4636466794f	path3/file3sym
-040000 tree 3c5e5399f3a333eddecce7a9b9465b63f65f51e2	path3/subp3
-100644 blob 00fb5908cb97c2564a9783c0c64087333b3b464f	path3/subp3/file3
-120000 blob 6649a1ebe9e9f1c553b66f5a6e74136a07ccc57c	path3/subp3/file3sym
-EOF
-test_expect_success SYMLINKS \
-    'git ls-tree -r output for a known tree.' \
-    'test_cmp expected current'
-
-test_expect_success \
-    'writing partial tree out with git write-tree --prefix.' \
-    'ptree=$(git write-tree --prefix=path3)'
-test_expect_success \
-    'validate object ID for a known tree.' \
-    'test "$ptree" = "$expectedptree1"'
-
-test_expect_success \
-    'writing partial tree out with git write-tree --prefix.' \
-    'ptree=$(git write-tree --prefix=path3/subp3)'
-test_expect_success \
-    'validate object ID for a known tree.' \
-    'test "$ptree" = "$expectedptree2"'
-
-cat >badobjects <<EOF
-100644 blob 1000000000000000000000000000000000000000	dir/file1
-100644 blob 2000000000000000000000000000000000000000	dir/file2
-100644 blob 3000000000000000000000000000000000000000	dir/file3
-100644 blob 4000000000000000000000000000000000000000	dir/file4
-100644 blob 5000000000000000000000000000000000000000	dir/file5
-EOF
-
-rm .git/index
-test_expect_success \
-    'put invalid objects into the index.' \
-    'git update-index --index-info < badobjects'
-
-test_expect_success 'writing this tree without --missing-ok.' '
-    test_must_fail git write-tree
-'
-
-test_expect_success \
-    'writing this tree with --missing-ok.' \
-    'git write-tree --missing-ok'
-
-
-################################################################
-rm .git/index
-test_expect_success \
-    'git read-tree followed by write-tree should be idempotent.' \
-    'git read-tree $tree &&
-     test -f .git/index &&
-     newtree=$(git write-tree) &&
-     test "$newtree" = "$tree"'
-
-$expectfilter >expected <<\EOF
-:100644 100644 f87290f8eb2cbbea7857214459a0739927eab154 0000000000000000000000000000000000000000 M	path0
-:120000 120000 15a98433ae33114b085f3eb3bb03b832b3180a01 0000000000000000000000000000000000000000 M	path0sym
-:100644 100644 3feff949ed00a62d9f7af97c15cd8a30595e7ac7 0000000000000000000000000000000000000000 M	path2/file2
-:120000 120000 d8ce161addc5173867a3c3c730924388daedbc38 0000000000000000000000000000000000000000 M	path2/file2sym
-:100644 100644 0aa34cae68d0878578ad119c86ca2b5ed5b28376 0000000000000000000000000000000000000000 M	path3/file3
-:120000 120000 8599103969b43aff7e430efea79ca4636466794f 0000000000000000000000000000000000000000 M	path3/file3sym
-:100644 100644 00fb5908cb97c2564a9783c0c64087333b3b464f 0000000000000000000000000000000000000000 M	path3/subp3/file3
-:120000 120000 6649a1ebe9e9f1c553b66f5a6e74136a07ccc57c 0000000000000000000000000000000000000000 M	path3/subp3/file3sym
-EOF
-test_expect_success \
-    'validate git diff-files output for a know cache/work tree state.' \
-    'git diff-files >current && diff >/dev/null -b current expected'
-
-test_expect_success \
-    'git update-index --refresh should succeed.' \
-    'git update-index --refresh'
-
-test_expect_success \
-    'no diff after checkout and git update-index --refresh.' \
-    'git diff-files >current && cmp -s current /dev/null'
-
-################################################################
-P=$expectedtree
-test_expect_success \
-    'git commit-tree records the correct tree in a commit.' \
-    'commit0=$(echo NO | git commit-tree $P) &&
-     tree=$(git show --pretty=raw $commit0 |
-	 sed -n -e "s/^tree //p" -e "/^author /q") &&
-     test "z$tree" = "z$P"'
-
-test_expect_success \
-    'git commit-tree records the correct parent in a commit.' \
-    'commit1=$(echo NO | git commit-tree $P -p $commit0) &&
-     parent=$(git show --pretty=raw $commit1 |
-	 sed -n -e "s/^parent //p" -e "/^author /q") &&
-     test "z$commit0" = "z$parent"'
-
-test_expect_success \
-    'git commit-tree omits duplicated parent in a commit.' \
-    'commit2=$(echo NO | git commit-tree $P -p $commit0 -p $commit0) &&
-     parent=$(git show --pretty=raw $commit2 |
-	 sed -n -e "s/^parent //p" -e "/^author /q" |
-	 sort -u) &&
-     test "z$commit0" = "z$parent" &&
-     numparent=$(git show --pretty=raw $commit2 |
-	 sed -n -e "s/^parent //p" -e "/^author /q" |
-	 wc -l) &&
-     test $numparent = 1'
-
-test_expect_success 'update-index D/F conflict' '
-	mv path0 tmp &&
-	mv path2 path0 &&
-	mv tmp path2 &&
-	git update-index --add --replace path2 path0/file2 &&
-	numpath0=$(git ls-files path0 | wc -l) &&
-	test $numpath0 = 1
-'
-
-test_expect_success SYMLINKS 'absolute path works as expected' '
-	mkdir first &&
-	ln -s ../.git first/.git &&
-	mkdir second &&
-	ln -s ../first second/other &&
-	mkdir third &&
-	dir="$(cd .git; pwd -P)" &&
-	dir2=third/../second/other/.git &&
-	test "$dir" = "$(test-path-utils make_absolute_path $dir2)" &&
-	file="$dir"/index &&
-	test "$file" = "$(test-path-utils make_absolute_path $dir2/index)" &&
-	basename=blub &&
-	test "$dir/$basename" = "$(cd .git && test-path-utils make_absolute_path "$basename")" &&
-	ln -s ../first/file .git/syml &&
-	sym="$(cd first; pwd -P)"/file &&
-	test "$sym" = "$(test-path-utils make_absolute_path "$dir2/syml")"
-'
-
-test_expect_success 'very long name in the index handled sanely' '
-
-	a=a && # 1
-	a=$a$a$a$a$a$a$a$a$a$a$a$a$a$a$a$a && # 16
-	a=$a$a$a$a$a$a$a$a$a$a$a$a$a$a$a$a && # 256
-	a=$a$a$a$a$a$a$a$a$a$a$a$a$a$a$a$a && # 4096
-	a=${a}q &&
-
-	>path4 &&
-	git update-index --add path4 &&
-	(
-		git ls-files -s path4 |
-		sed -e "s/	.*/	/" |
-		tr -d "\012"
-		echo "$a"
-	) | git update-index --index-info &&
-	len=$(git ls-files "a*" | wc -c) &&
-	test $len = 4098
-'
-
 test_done
diff --git a/test/test-lib.sh b/test/test-lib.sh
index 7422bba..7684c2e 100644
--- a/test/test-lib.sh
+++ b/test/test-lib.sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
 #
 # Copyright (c) 2005 Junio C Hamano
 #
@@ -41,40 +41,6 @@ PAGER=cat
 TZ=UTC
 TERM=dumb
 export LANG LC_ALL PAGER TERM TZ
-EDITOR=:
-unset VISUAL
-unset GIT_EDITOR
-unset AUTHOR_DATE
-unset AUTHOR_EMAIL
-unset AUTHOR_NAME
-unset COMMIT_AUTHOR_EMAIL
-unset COMMIT_AUTHOR_NAME
-unset EMAIL
-unset GIT_ALTERNATE_OBJECT_DIRECTORIES
-unset GIT_AUTHOR_DATE
-GIT_AUTHOR_EMAIL=author@example.com
-GIT_AUTHOR_NAME='A U Thor'
-unset GIT_COMMITTER_DATE
-GIT_COMMITTER_EMAIL=committer@example.com
-GIT_COMMITTER_NAME='C O Mitter'
-unset GIT_DIFF_OPTS
-unset GIT_DIR
-unset GIT_WORK_TREE
-unset GIT_EXTERNAL_DIFF
-unset GIT_INDEX_FILE
-unset GIT_OBJECT_DIRECTORY
-unset GIT_CEILING_DIRECTORIES
-unset SHA1_FILE_DIRECTORIES
-unset SHA1_FILE_DIRECTORY
-unset GIT_NOTES_REF
-unset GIT_NOTES_DISPLAY_REF
-unset GIT_NOTES_REWRITE_REF
-unset GIT_NOTES_REWRITE_MODE
-GIT_MERGE_VERBOSITY=5
-export GIT_MERGE_VERBOSITY
-export GIT_AUTHOR_EMAIL GIT_AUTHOR_NAME
-export GIT_COMMITTER_EMAIL GIT_COMMITTER_NAME
-export EDITOR
 GIT_TEST_CMP=${GIT_TEST_CMP:-diff -u}
 
 # Protect ourselves from common misconfiguration to export
@@ -98,6 +64,9 @@ esac
 _x05='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
 _x40="$_x05$_x05$_x05$_x05$_x05$_x05$_x05$_x05"
 
+_x04='[0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
+_x32="$_x04$_x04$_x04$_x04$_x04$_x04$_x04$_x04"
+
 # Each test should start with something like this, after copyright notices:
 #
 # test_description='Description of this test...
@@ -221,22 +190,6 @@ die () {
 GIT_EXIT_OK=
 trap 'die' EXIT
 
-# The semantics of the editor variables are that of invoking
-# sh -c "$EDITOR \"$@\"" files ...
-#
-# If our trash directory contains shell metacharacters, they will be
-# interpreted if we just set $EDITOR directly, so do a little dance with
-# environment variables to work around this.
-#
-# In particular, quoting isn't enough, as the path may contain the same quote
-# that we're using.
-test_set_editor () {
-	FAKE_EDITOR="$1"
-	export FAKE_EDITOR
-	EDITOR='"$FAKE_EDITOR"'
-	export EDITOR
-}
-
 test_decode_color () {
 	sed	-e 's/.\[1m/<WHITE>/g' \
 		-e 's/.\[31m/<RED>/g' \
@@ -264,52 +217,205 @@ remove_cr () {
 	tr '\015' Q | sed -e 's/Q$//'
 }
 
-test_tick () {
-	if test -z "${test_tick+set}"
-	then
-		test_tick=1112911993
-	else
-		test_tick=$(($test_tick + 60))
-	fi
-	GIT_COMMITTER_DATE="$test_tick -0700"
-	GIT_AUTHOR_DATE="$test_tick -0700"
-	export GIT_COMMITTER_DATE GIT_AUTHOR_DATE
+# Notmuch helper functions
+increment_mtime_amount=0
+increment_mtime ()
+{
+    dir=$1
+
+    increment_mtime_amount=$((increment_mtime_amount + 1))
+    touch -d "+${increment_mtime_amount} seconds" $dir
 }
 
-# Call test_commit with the arguments "<message> [<file> [<contents>]]"
+# Generate a new message in the mail directory, with a unique message
+# ID and subject. The message is not added to the index.
+#
+# After this function returns, the filename of the generated message
+# is available as $gen_msg_filename and the message ID is available as
+# $gen_msg_id .
+#
+# This function supports named parameters with the bash syntax for
+# assigning a value to an associative array ([name]=value). The
+# supported parameters are:
+#
+#  [dir]=directory/of/choice
+#
+#	Generate the message in directory 'directory/of/choice' within
+#	the mail store. The directory will be created if necessary.
 #
-# This will commit a file with the given contents and the given commit
-# message.  It will also add a tag with <message> as name.
+#  [body]=text
 #
-# Both <file> and <contents> default to <message>.
+#	Text to use as the body of the email message
+#
+#  '[from]="Some User <user@example.com>"'
+#  '[to]="Some User <user@example.com>"'
+#  '[subject]="Subject of email message"'
+#  '[date]="RFC 822 Date"'
+#
+#	Values for email headers. If not provided, default values will
+#	be generated instead.
+#
+#  '[cc]="Some User <user@example.com>"'
+#  [reply-to]=some-address
+#  [in-reply-to]=<message-id>
+#  [references]=<message-id>
+#  [content-type]=content-type-specification
+#  '[header]=full header line, including keyword'
+#
+#	Additional values for email headers. If these are not provided
+#	then the relevant headers will simply not appear in the
+#	message.
+#
+#  '[id]=message-id'
+#
+#	Controls the message-id of the created message.
+gen_msg_cnt=0
+gen_msg_filename=""
+gen_msg_id=""
+generate_message ()
+{
+    # This is our (bash-specific) magic for doing named parameters
+    local -A template="($@)"
+    local additional_headers
+
+    gen_msg_cnt=$((gen_msg_cnt + 1))
+    gen_msg_name=msg-$(printf "%03d" $gen_msg_cnt)
+
+    if [ -z "${template[id]}" ]; then
+	gen_msg_id="${gen_msg_name}@notmuch-test-suite"
+    else
+	gen_msg_id="${template[id]}"
+    fi
+
+    if [ -z "${template[dir]}" ]; then
+	gen_msg_filename="${MAIL_DIR}/$gen_msg_name"
+    else
+	gen_msg_filename="${MAIL_DIR}/${template[dir]}/$gen_msg_name"
+	mkdir -p $(dirname $gen_msg_filename)
+    fi
+
+    if [ -z "${template[body]}" ]; then
+	template[body]="This is just a test message (#${gen_msg_cnt})"
+    fi
+
+    if [ -z "${template[from]}" ]; then
+	template[from]="Notmuch Test Suite <test_suite@notmuchmail.org>"
+    fi
+
+    if [ -z "${template[to]}" ]; then
+	template[to]="Notmuch Test Suite <test_suite@notmuchmail.org>"
+    fi
+
+    if [ -z "${template[subject]}" ]; then
+	template[subject]="Test message #${gen_msg_cnt}"
+    fi
+
+    if [ -z "${template[date]}" ]; then
+	template[date]="Tue, 05 Jan 2001 15:43:57 -0800"
+    fi
+
+    additional_headers=""
+    if [ ! -z "${template[header]}" ]; then
+	additional_headers="${template[header]}
+${additional_headers}"
+    fi
+
+    if [ ! -z "${template[reply-to]}" ]; then
+	additional_headers="Reply-To: ${template[reply-to]}
+${additional_headers}"
+    fi
+
+    if [ ! -z "${template[in-reply-to]}" ]; then
+	additional_headers="In-Reply-To: ${template[in-reply-to]}
+${additional_headers}"
+    fi
+
+    if [ ! -z "${template[cc]}" ]; then
+	additional_headers="Cc: ${template[cc]}
+${additional_headers}"
+    fi
+
+    if [ ! -z "${template[references]}" ]; then
+	additional_headers="References: ${template[references]}
+${additional_headers}"
+    fi
+
+    if [ ! -z "${template[content-type]}" ]; then
+	additional_headers="Content-Type: ${template[content-type]}
+${additional_headers}"
+    fi
+
+
+cat <<EOF >$gen_msg_filename
+From: ${template[from]}
+To: ${template[to]}
+Message-Id: <${gen_msg_id}>
+Subject: ${template[subject]}
+Date: ${template[date]}
+${additional_headers}
+${template[body]}
+EOF
+
+    # Ensure that the mtime of the containing directory is updated
+    increment_mtime $(dirname ${gen_msg_filename})
+}
+
+# Generate a new message and add it to the index.
+#
+# All of the arguments and return values supported by generate_message
+# are also supported here, so see that function for details.
+add_message ()
+{
+    generate_message "$@"
 
-test_commit () {
-	file=${2:-"$1.t"}
-	echo "${3-$1}" > "$file" &&
-	git add "$file" &&
-	test_tick &&
-	git commit -m "$1" &&
-	git tag "$1"
+    $NOTMUCH new > /dev/null
 }
 
-# Call test_merge with the arguments "<message> <commit>", where <commit>
-# can be a tag pointing to the commit-to-merge.
+tests=0
+test_failures=0
 
-test_merge () {
-	test_tick &&
-	git merge -m "$1" "$2" &&
-	git tag "$1"
+pass_if_equal ()
+{
+    output=$1
+    expected=$2
+
+    tests=$((tests + 1))
+
+    if [ "$output" = "$expected" ]; then
+	echo "	PASS"
+    else
+	echo "	FAIL"
+	testname=test-$(printf "%03d" $tests)
+	echo "$expected" > $testname.expected
+	echo "$output" > $testname.output
+	diff -u $testname.expected $testname.output || true
+	test_failures=$((test_failures + 1))
+    fi
+}
+
+TEST_DIR=$(pwd)/test.$$
+MAIL_DIR=${TEST_DIR}/mail
+export NOTMUCH_CONFIG=${TEST_DIR}/notmuch-config
+NOTMUCH=$(find_notmuch_binary $(pwd))
+
+NOTMUCH_NEW ()
+{
+    $NOTMUCH new | grep -v -E -e '^Processed [0-9]*( total)? file|Found [0-9]* total file'
 }
 
-# This function helps systems where core.filemode=false is set.
-# Use it instead of plain 'chmod +x' to set or unset the executable bit
-# of a file in the working directory and add it to the index.
+notmuch_search_sanitize ()
+{
+    sed -r -e 's/("?thread"?: ?)("?)................("?)/\1\2XXX\3/'
+}
 
-test_chmod () {
-	chmod "$@" &&
-	git update-index --add "--chmod=$@"
+NOTMUCH_SHOW_FILENAME_SQUELCH='s,filename:.*/mail,filename:/XXX/mail,'
+notmuch_show_sanitize ()
+{
+    sed -e "$NOTMUCH_SHOW_FILENAME_SQUELCH"
 }
 
+# End of notmuch helper functions
+
 # Use test_set_prereq to tell that a particular prerequisite is available.
 # The prerequisite can later be checked for in two ways:
 #
@@ -572,21 +678,6 @@ test_when_finished () {
 		} && (exit \"\$eval_ret\"); eval_ret=\$?; $test_cleanup"
 }
 
-# Most tests can use the created repository, but some may need to create more.
-# Usage: test_create_repo <directory>
-test_create_repo () {
-	test "$#" = 1 ||
-	error "bug in the test script: not 1 parameter to test-create-repo"
-	owd=`pwd`
-	repo="$1"
-	mkdir -p "$repo"
-	cd "$repo" || error "Cannot setup test environment"
-	"$GIT_EXEC_PATH/git-init" "--template=$TEST_DIRECTORY/../templates/blt/" >&3 2>&4 ||
-	error "cannot run git init -- have you built things yet?"
-	mv .git/hooks .git/hooks-disabled
-	cd "$owd"
-}
-
 test_done () {
 	GIT_EXIT_OK=t
 	test_results_dir="$TEST_DIRECTORY/test-results"
@@ -628,9 +719,27 @@ test_done () {
 	esac
 }
 
+find_notmuch_path ()
+{
+    dir="$1"
+
+    while [ -n "$dir" ]; do
+	bin="$dir/notmuch"
+	if [ -x "$bin" ]; then
+	    echo "$dir"
+	    return
+	fi
+	dir="$(dirname "$dir")"
+	if [ "$dir" = "/" ]; then
+	    break
+	fi
+    done
+}
+
 # Test the binaries we have just built.  The tests are kept in
-# t/ subdirectory and are run in 'trash directory' subdirectory.
+# test/ subdirectory and are run in 'trash directory' subdirectory.
 TEST_DIRECTORY=$(pwd)
+# FIXME: Only the normal case bellow is updated to notmuch
 if test -n "$valgrind"
 then
 	make_symlink () {
@@ -699,48 +808,11 @@ elif test -n "$GIT_TEST_INSTALLED" ; then
 	error "Cannot run git from $GIT_TEST_INSTALLED."
 	PATH=$GIT_TEST_INSTALLED:$TEST_DIRECTORY/..:$PATH
 	GIT_EXEC_PATH=${GIT_TEST_EXEC_PATH:-$GIT_EXEC_PATH}
-else # normal case, use ../bin-wrappers only unless $with_dashes:
-	git_bin_dir="$TEST_DIRECTORY/../bin-wrappers"
-	if ! test -x "$git_bin_dir/git" ; then
-		if test -z "$with_dashes" ; then
-			say "$git_bin_dir/git is not executable; using GIT_EXEC_PATH"
-		fi
-		with_dashes=t
-	fi
-	PATH="$git_bin_dir:$PATH"
-	GIT_EXEC_PATH=$TEST_DIRECTORY/..
-	if test -n "$with_dashes" ; then
-		PATH="$TEST_DIRECTORY/..:$PATH"
-	fi
-fi
-GIT_TEMPLATE_DIR=$(pwd)/../templates/blt
-unset GIT_CONFIG
-GIT_CONFIG_NOSYSTEM=1
-GIT_CONFIG_NOGLOBAL=1
-export PATH GIT_EXEC_PATH GIT_TEMPLATE_DIR GIT_CONFIG_NOSYSTEM GIT_CONFIG_NOGLOBAL
-
-. ../GIT-BUILD-OPTIONS
-
-GITPERLLIB=$(pwd)/../perl/blib/lib:$(pwd)/../perl/blib/arch/auto/Git
-export GITPERLLIB
-test -d ../templates/blt || {
-	error "You haven't built things yet, have you?"
-}
-
-if test -z "$GIT_TEST_INSTALLED" && test -z "$NO_PYTHON"
-then
-	GITPYTHONLIB="$(pwd)/../git_remote_helpers/build/lib"
-	export GITPYTHONLIB
-	test -d ../git_remote_helpers/build || {
-		error "You haven't built git_remote_helpers yet, have you?"
-	}
-fi
-
-if ! test -x ../test-chmtime; then
-	echo >&2 'You need to build test-chmtime:'
-	echo >&2 'Run "make test-chmtime" in the source (toplevel) directory'
-	exit 1
+else # normal case
+	notmuch_path=`find_notmuch_path "$TEST_DIRECTORY"`
+	test -n "$notmuch_path" && PATH="$notmuch_path:$PATH"
 fi
+export PATH
 
 # Test repository
 test="trash directory.$(basename "$0" .sh)"
@@ -756,10 +828,26 @@ rm -fr "$test" || {
 	exit 1
 }
 
-test_create_repo "$test"
+MAIL_DIR="${TRASH_DIRECTORY}/mail"
+export NOTMUCH_CONFIG="${TRASH_DIRECTORY}/notmuch-config"
+
+mkdir -p "${test}"
+mkdir "$MAIL_DIR"
+
+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
+
+
 # Use -P to resolve symlinks in our working directory so that the cwd
 # in subprocesses like git equals our $PWD (for pathname comparisons).
-cd -P "$test" || exit 1
+cd -P "$test" || error "Cannot setup test environment"
 
 this_test=${0##*/}
 this_test=${this_test%%-*}
-- 
1.7.1.3.g75e44

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

* [PATCH v3 3/5] test: Update helper functions
  2010-06-10  6:47 [PATCH v3 0/5] Git-based modularization of test suite Michal Sojka
  2010-06-10  6:48 ` [PATCH v3 1/5] Copy test framework from Git Michal Sojka
  2010-06-10  6:48 ` [PATCH v3 2/5] Update test framework for use with notmuch Michal Sojka
@ 2010-06-10  6:48 ` Michal Sojka
  2010-06-10  6:48 ` [PATCH v3 4/5] Convert the actual tests to the new framework Michal Sojka
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 11+ messages in thread
From: Michal Sojka @ 2010-06-10  6:48 UTC (permalink / raw)
  To: notmuch

Modify the helper functions to work with git-based test suite i.e.
1) Quote arguments where it is necessary.
2) Do not use $NOTMUCH. It is equal to "notmuch" since $PATH is set to
   the build tree.
3) Modify pass_if_equal to fit into the git-based test suite.

Signed-off-by: Michal Sojka <sojkam1@fel.cvut.cz>
---
 test/test-lib.sh |   33 +++++++++++++--------------------
 1 files changed, 13 insertions(+), 20 deletions(-)

diff --git a/test/test-lib.sh b/test/test-lib.sh
index 7684c2e..d045820 100644
--- a/test/test-lib.sh
+++ b/test/test-lib.sh
@@ -221,10 +221,10 @@ remove_cr () {
 increment_mtime_amount=0
 increment_mtime ()
 {
-    dir=$1
+    dir="$1"
 
     increment_mtime_amount=$((increment_mtime_amount + 1))
-    touch -d "+${increment_mtime_amount} seconds" $dir
+    touch -d "+${increment_mtime_amount} seconds" "$dir"
 }
 
 # Generate a new message in the mail directory, with a unique message
@@ -291,7 +291,7 @@ generate_message ()
 	gen_msg_filename="${MAIL_DIR}/$gen_msg_name"
     else
 	gen_msg_filename="${MAIL_DIR}/${template[dir]}/$gen_msg_name"
-	mkdir -p $(dirname $gen_msg_filename)
+	mkdir -p "$(dirname "$gen_msg_filename")"
     fi
 
     if [ -z "${template[body]}" ]; then
@@ -346,7 +346,7 @@ ${additional_headers}"
     fi
 
 
-cat <<EOF >$gen_msg_filename
+cat <<EOF >"$gen_msg_filename"
 From: ${template[from]}
 To: ${template[to]}
 Message-Id: <${gen_msg_id}>
@@ -357,7 +357,7 @@ ${template[body]}
 EOF
 
     # Ensure that the mtime of the containing directory is updated
-    increment_mtime $(dirname ${gen_msg_filename})
+    increment_mtime "$(dirname "${gen_msg_filename}")"
 }
 
 # Generate a new message and add it to the index.
@@ -366,41 +366,34 @@ EOF
 # are also supported here, so see that function for details.
 add_message ()
 {
-    generate_message "$@"
-
-    $NOTMUCH new > /dev/null
+    generate_message "$@" &&
+    notmuch new > /dev/null
 }
 
-tests=0
-test_failures=0
-
 pass_if_equal ()
 {
     output=$1
     expected=$2
 
-    tests=$((tests + 1))
-
     if [ "$output" = "$expected" ]; then
-	echo "	PASS"
+	true
     else
-	echo "	FAIL"
-	testname=test-$(printf "%03d" $tests)
+	testname=$this_test.$test_count
 	echo "$expected" > $testname.expected
 	echo "$output" > $testname.output
-	diff -u $testname.expected $testname.output || true
-	test_failures=$((test_failures + 1))
+	diff -u $testname.expected $testname.output
+	false
     fi
 }
 
 TEST_DIR=$(pwd)/test.$$
 MAIL_DIR=${TEST_DIR}/mail
 export NOTMUCH_CONFIG=${TEST_DIR}/notmuch-config
-NOTMUCH=$(find_notmuch_binary $(pwd))
+NOTMUCH=notmuch
 
 NOTMUCH_NEW ()
 {
-    $NOTMUCH new | grep -v -E -e '^Processed [0-9]*( total)? file|Found [0-9]* total file'
+    notmuch new | grep -v -E -e '^Processed [0-9]*( total)? file|Found [0-9]* total file'
 }
 
 notmuch_search_sanitize ()
-- 
1.7.1.3.g75e44

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

* [PATCH v3 4/5] Convert the actual tests to the new framework
  2010-06-10  6:47 [PATCH v3 0/5] Git-based modularization of test suite Michal Sojka
                   ` (2 preceding siblings ...)
  2010-06-10  6:48 ` [PATCH v3 3/5] test: Update helper functions Michal Sojka
@ 2010-06-10  6:48 ` Michal Sojka
  2010-06-10  6:48 ` [PATCH v3 5/5] test: Set all times to UTC Michal Sojka
  2010-09-20 22:33 ` [PATCH v3 0/5] Git-based modularization of test suite Carl Worth
  5 siblings, 0 replies; 11+ messages in thread
From: Michal Sojka @ 2010-06-10  6:48 UTC (permalink / raw)
  To: notmuch

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 103020 bytes --]

The changes are:
- The notmuch-test was split into several files (t000?-*.sh).
- Removed helper functions which were moved to test-lib.sh
- Replaced every printf with test_expect_success.
- Test commands chained with && (test-lib.sh doesn't use "set -e" in
  order to complete the test suite even if something fails)
- Many variables such as ${MAIL_DIR} were properly quoted as they
  contain spaces.
- Changed quoting patterns in add_message and generate_message (single
  quotes are already used by the test framework).
- ${TEST_DIR} replaced by ${PWD}

QUICK HOWTO:

To run the whole test suite
    make

To run only a single test
   ./t0001-new.sh

To stop on the first error
   ./t0001-new.sh -i
then mail store and database can be inspected in
"trash directory.t0001-new"

To see the output of tests
   ./t0001-new.sh -v

To not remove trash directory at the end:
   ./t0001-new.sh -d

To run all tests verbosely:
   make GIT_TEST_OPTS="-v"

Signed-off-by: Michal Sojka <sojkam1@fel.cvut.cz>
---
 test/notmuch-test                    | 1190 +---------------------------------
 test/t0000-basic.sh                  |    2 +-
 test/t0001-new.sh                    |  164 +++++
 test/t0002-search.sh                 |  111 ++++
 test/t0003-json.sh                   |   46 ++
 test/t0004-thread-naming.sh          |  191 ++++++
 test/t0005-reply.sh                  |  137 ++++
 test/t0006-dump-restore.sh           |   30 +
 test/t0007-uuencode.sh               |   36 +
 test/t0008-threading-out-of-order.sh |   31 +
 test/t0009-author-reordering.sh      |   35 +
 test/t0010-from-line-heuristics.sh   |  215 ++++++
 test/t0011-long-msgid.sh             |   29 +
 test/t0012-encoding-issues.sh        |   25 +
 14 files changed, 1053 insertions(+), 1189 deletions(-)
 create mode 100755 test/t0001-new.sh
 create mode 100755 test/t0002-search.sh
 create mode 100755 test/t0003-json.sh
 create mode 100755 test/t0004-thread-naming.sh
 create mode 100755 test/t0005-reply.sh
 create mode 100755 test/t0006-dump-restore.sh
 create mode 100755 test/t0007-uuencode.sh
 create mode 100755 test/t0008-threading-out-of-order.sh
 create mode 100755 test/t0009-author-reordering.sh
 create mode 100755 test/t0010-from-line-heuristics.sh
 create mode 100755 test/t0011-long-msgid.sh
 create mode 100755 test/t0012-encoding-issues.sh

diff --git a/test/notmuch-test b/test/notmuch-test
index 00ac6b0..5c066ed 100755
--- a/test/notmuch-test
+++ b/test/notmuch-test
@@ -1,1190 +1,4 @@
 #!/bin/bash
-set -e
 
-# Messages contain time/date values with time zone and notmuch
-# displays them converted to the local time zone. We need to set fixed
-# timezone here so that the output of the tests is always the same
-# without regard to the time zone of where the test suite is run.
-export TZ=UTC+8
-
-find_notmuch_binary ()
-{
-    dir=$1
-
-    while [ -n "$dir" ]; do
-	bin=$dir/notmuch
-	if [ -x $bin ]; then
-	    echo $bin
-	    return
-	fi
-	dir=$(dirname $dir)
-	if [ "$dir" = "/" ]; then
-	    break
-	fi
-    done
-
-    echo notmuch
-}
-
-increment_mtime_amount=0
-increment_mtime ()
-{
-    dir=$1
-
-    increment_mtime_amount=$((increment_mtime_amount + 1))
-    touch -d "+${increment_mtime_amount} seconds" $dir
-}
-
-# Generate a new message in the mail directory, with a unique message
-# ID and subject. The message is not added to the index.
-#
-# After this function returns, the filename of the generated message
-# is available as $gen_msg_filename and the message ID is available as
-# $gen_msg_id .
-#
-# This function supports named parameters with the bash syntax for
-# assigning a value to an associative array ([name]=value). The
-# supported parameters are:
-#
-#  [dir]=directory/of/choice
-#
-#	Generate the message in directory 'directory/of/choice' within
-#	the mail store. The directory will be created if necessary.
-#
-#  [body]=text
-#
-#	Text to use as the body of the email message
-#
-#  '[from]="Some User <user@example.com>"'
-#  '[to]="Some User <user@example.com>"'
-#  '[subject]="Subject of email message"'
-#  '[date]="RFC 822 Date"'
-#
-#	Values for email headers. If not provided, default values will
-#	be generated instead.
-#
-#  '[cc]="Some User <user@example.com>"'
-#  [reply-to]=some-address
-#  [in-reply-to]=<message-id>
-#  [references]=<message-id>
-#  [content-type]=content-type-specification
-#  '[header]=full header line, including keyword'
-#
-#	Additional values for email headers. If these are not provided
-#	then the relevant headers will simply not appear in the
-#	message.
-#
-#  '[id]=message-id'
-#
-#	Controls the message-id of the created message.
-gen_msg_cnt=0
-gen_msg_filename=""
-gen_msg_id=""
-generate_message ()
-{
-    # This is our (bash-specific) magic for doing named parameters
-    local -A template="($@)"
-    local additional_headers
-
-    gen_msg_cnt=$((gen_msg_cnt + 1))
-    gen_msg_name=msg-$(printf "%03d" $gen_msg_cnt)
-
-    if [ -z "${template[id]}" ]; then
-	gen_msg_id="${gen_msg_name}@notmuch-test-suite"
-    else
-	gen_msg_id="${template[id]}"
-    fi
-
-    if [ -z "${template[dir]}" ]; then
-	gen_msg_filename="${MAIL_DIR}/$gen_msg_name"
-    else
-	gen_msg_filename="${MAIL_DIR}/${template[dir]}/$gen_msg_name"
-	mkdir -p $(dirname $gen_msg_filename)
-    fi
-
-    if [ -z "${template[body]}" ]; then
-	template[body]="This is just a test message (#${gen_msg_cnt})"
-    fi
-
-    if [ -z "${template[from]}" ]; then
-	template[from]="Notmuch Test Suite <test_suite@notmuchmail.org>"
-    fi
-
-    if [ -z "${template[to]}" ]; then
-	template[to]="Notmuch Test Suite <test_suite@notmuchmail.org>"
-    fi
-
-    if [ -z "${template[subject]}" ]; then
-	template[subject]="Test message #${gen_msg_cnt}"
-    fi
-
-    if [ -z "${template[date]}" ]; then
-	template[date]="Tue, 05 Jan 2001 15:43:57 -0800"
-    fi
-
-    additional_headers=""
-    if [ ! -z "${template[header]}" ]; then
-	additional_headers="${template[header]}
-${additional_headers}"
-    fi
-
-    if [ ! -z "${template[reply-to]}" ]; then
-	additional_headers="Reply-To: ${template[reply-to]}
-${additional_headers}"
-    fi
-
-    if [ ! -z "${template[in-reply-to]}" ]; then
-	additional_headers="In-Reply-To: ${template[in-reply-to]}
-${additional_headers}"
-    fi
-
-    if [ ! -z "${template[cc]}" ]; then
-	additional_headers="Cc: ${template[cc]}
-${additional_headers}"
-    fi
-
-    if [ ! -z "${template[references]}" ]; then
-	additional_headers="References: ${template[references]}
-${additional_headers}"
-    fi
-
-    if [ ! -z "${template[content-type]}" ]; then
-	additional_headers="Content-Type: ${template[content-type]}
-${additional_headers}"
-    fi
-
-
-cat <<EOF >$gen_msg_filename
-From: ${template[from]}
-To: ${template[to]}
-Message-Id: <${gen_msg_id}>
-Subject: ${template[subject]}
-Date: ${template[date]}
-${additional_headers}
-${template[body]}
-EOF
-
-    # Ensure that the mtime of the containing directory is updated
-    increment_mtime $(dirname ${gen_msg_filename})
-}
-
-# Generate a new message and add it to the index.
-#
-# All of the arguments and return values supported by generate_message
-# are also supported here, so see that function for details.
-add_message ()
-{
-    generate_message "$@"
-
-    $NOTMUCH new > /dev/null
-}
-
-tests=0
-test_failures=0
-
-pass_if_equal ()
-{
-    output=$1
-    expected=$2
-
-    tests=$((tests + 1))
-
-    if [ "$output" = "$expected" ]; then
-	echo "	PASS"
-    else
-	echo "	FAIL"
-	testname=test-$(printf "%03d" $tests)
-	echo "$expected" > $testname.expected
-	echo "$output" > $testname.output
-	diff -u $testname.expected $testname.output || true
-	test_failures=$((test_failures + 1))
-    fi
-}
-
-TEST_DIR=$(pwd)/test.$$
-MAIL_DIR=${TEST_DIR}/mail
-export NOTMUCH_CONFIG=${TEST_DIR}/notmuch-config
-NOTMUCH=$(find_notmuch_binary $(pwd))
-
-NOTMUCH_NEW ()
-{
-    $NOTMUCH new | grep -v -E -e '^Processed [0-9]*( total)? file|Found [0-9]* total file'
-}
-
-notmuch_search_sanitize ()
-{
-    sed -r -e 's/("?thread"?: ?)("?)................("?)/\1\2XXX\3/'
-}
-
-NOTMUCH_SHOW_FILENAME_SQUELCH='s,filename:.*/mail,filename:/XXX/mail,'
-notmuch_show_sanitize ()
-{
-    sed -e "$NOTMUCH_SHOW_FILENAME_SQUELCH"
-}
-
-rm -rf ${TEST_DIR}
-mkdir ${TEST_DIR}
-cd ${TEST_DIR}
-
-mkdir ${MAIL_DIR}
-
-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
-
-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 " Message with header of exactly 200 bytes...\t"
-
-add_message '[subject]="This subject is exactly 200 bytes in length. Other than its length there is not much of note here. Note that the length of 200 bytes includes the Subject: and Re: prefixes with two spaces"' \
-            '[date]="Tue, 05 Jan 2010 15:43:56 -0800"' \
-            '[body]="200-byte header"'
-
-output=$($NOTMUCH reply id:${gen_msg_id})
-pass_if_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
-Subject: Re: This subject is exactly 200 bytes in length. Other than its length there is not much of note here. Note that the length of 200 bytes includes the Subject: and Re: prefixes with two spaces
-Bcc: test_suite@notmuchmail.org
-In-Reply-To: <${gen_msg_id}>
-References: <${gen_msg_id}>
-
-On Tue, 05 Jan 2010 15:43:56 -0800, Notmuch Test Suite <test_suite@notmuchmail.org> wrote:
-> 200-byte header"
-
-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"'
-
-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 "\nTesting messages with ridiculously-long message IDs...\n"
-printf " Referencing long ID before adding...\t\t"
-generate_message '[subject]="Reference of ridiculously-long message ID"' \
-		 '[references]=\<abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-\>'
-
-output=$(NOTMUCH_NEW)
-pass_if_equal "$output" "Added 1 new message to the database."
-
-printf " Adding message with long ID...\t\t\t"
-generate_message '[subject]="A ridiculously-long message ID"' \
-		 '[id]=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-'
-
-output=$(NOTMUCH_NEW)
-pass_if_equal "$output" "Added 1 new message to the database."
-
-printf " Referencing long ID after adding...\t\t"
-generate_message '[subject]="Reply to ridiculously-long message ID"' \
-		 '[in-reply-to]=\<abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-\>'
-
-output=$(NOTMUCH_NEW)
-pass_if_equal "$output" "Added 1 new message to the database."
-
-printf " Ensure all messages were threaded together...\t"
-
-output=$($NOTMUCH search 'subject:"a ridiculously-long message ID"' | notmuch_search_sanitize)
-pass_if_equal "$output" "thread:XXX   2001-01-05 [1/3] Notmuch Test Suite; A ridiculously-long message ID (inbox unread)"
-
-printf "\nTesting encoding issues...\n"
-printf " Message with text of unknown charset...\t"
-add_message '[content-type]="text/plain; charset=unknown-8bit"' \
-            '[body]=irrelevant'
-
-output=$($NOTMUCH show id:${gen_msg_id} 2>&1 | notmuch_show_sanitize)
-pass_if_equal "$output" "\fmessage{ id:msg-074@notmuch-test-suite depth:0 match:1 filename:/XXX/mail/msg-074
-\fheader{
-Notmuch Test Suite <test_suite@notmuchmail.org> (2001-01-05) (inbox unread)
-Subject: Test message #74
-From: Notmuch Test Suite <test_suite@notmuchmail.org>
-To: Notmuch Test Suite <test_suite@notmuchmail.org>
-Date: Tue, 05 Jan 2001 15:43:57 -0800
-\fheader}
-\fbody{
-\fpart{ ID: 1, Content-type: text/plain
-irrelevant
-\fpart}
-\fbody}
-\fmessage}"
-
-echo ""
-echo "Notmuch test suite complete."
-
-if [ "$test_failures" = "0" ]; then
-    echo "All $tests tests passed."
-    rm -rf ${TEST_DIR}
-else
-    echo "$test_failures/$tests tests failed. The failures can be investigated in:"
-    echo "${TEST_DIR}"
-fi
-
-echo ""
-
-exit $test_failures
+cd $(dirname $0)
+make
diff --git a/test/t0000-basic.sh b/test/t0000-basic.sh
index caade68..511e200 100755
--- a/test/t0000-basic.sh
+++ b/test/t0000-basic.sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
 #
 # Copyright (c) 2005 Junio C Hamano
 #
diff --git a/test/t0001-new.sh b/test/t0001-new.sh
new file mode 100755
index 0000000..97726e7
--- /dev/null
+++ b/test/t0001-new.sh
@@ -0,0 +1,164 @@
+#!/bin/bash
+test_description="\"notmuch new\" in several variations"
+. ./test-lib.sh
+test_expect_success "No new messages" '
+output=$(NOTMUCH_NEW) &&
+pass_if_equal "$output" "No new mail."
+
+'
+test_expect_success "Single new message" '
+generate_message &&
+output=$(NOTMUCH_NEW) &&
+pass_if_equal "$output" "Added 1 new message to the database."
+
+'
+test_expect_success "Multiple new messages" '
+generate_message &&
+generate_message &&
+output=$(NOTMUCH_NEW) &&
+pass_if_equal "$output" "Added 2 new messages to the database."
+
+'
+test_expect_success "No new messages (non-empty DB)" '
+output=$(NOTMUCH_NEW) &&
+pass_if_equal "$output" "No new mail."
+
+'
+test_expect_success "New directories" '
+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."
+
+'
+test_expect_success "Alternate inode order" '
+
+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."
+
+'
+test_expect_success "Message moved in" '
+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."
+
+'
+test_expect_success "Renamed message" '
+
+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."
+
+'
+test_expect_success "Deleted message" '
+
+rm "${gen_msg_filename}"-renamed &&
+increment_mtime "${MAIL_DIR}" &&
+output=$(NOTMUCH_NEW) &&
+pass_if_equal "$output" "No new mail. Removed 1 message."
+
+'
+test_expect_success "Renamed directory" '
+
+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."
+
+'
+test_expect_success "Deleted directory" '
+
+rm -rf "${MAIL_DIR}"/dir-renamed &&
+increment_mtime "${MAIL_DIR}" &&
+
+output=$(NOTMUCH_NEW) &&
+pass_if_equal "$output" "No new mail. Removed 3 messages."
+
+'
+test_expect_success "New directory (at end of list)" '
+
+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."
+
+'
+test_expect_success "Deleted directory (end of list)" '
+
+rm -rf "${MAIL_DIR}"/zzz &&
+increment_mtime "${MAIL_DIR}" &&
+
+output=$(NOTMUCH_NEW) &&
+pass_if_equal "$output" "No new mail. Removed 3 messages."
+
+'
+test_expect_success "New symlink to directory" '
+
+rm -rf "${MAIL_DIR}"/.notmuch &&
+mv "${MAIL_DIR}" "$PWD"/actual_maildir &&
+
+mkdir "${MAIL_DIR}" &&
+ln -s "$PWD"/actual_maildir "${MAIL_DIR}"/symlink &&
+
+output=$(NOTMUCH_NEW) &&
+pass_if_equal "$output" "Added 1 new message to the database."
+
+'
+test_expect_success "New symlink to a file" '
+generate_message &&
+external_msg_filename="$PWD"/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."
+
+'
+test_expect_success "New two-level directory" '
+
+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."
+
+'
+test_expect_success "Deleted two-level directory" '
+
+rm -rf "${MAIL_DIR}"/two &&
+increment_mtime "${MAIL_DIR}" &&
+
+output=$(NOTMUCH_NEW) &&
+pass_if_equal "$output" "No new mail. Removed 3 messages."
+'
+test_done
diff --git a/test/t0002-search.sh b/test/t0002-search.sh
new file mode 100755
index 0000000..7de4d47
--- /dev/null
+++ b/test/t0002-search.sh
@@ -0,0 +1,111 @@
+#!/bin/bash
+test_description="\"notmuch search\" in several variations"
+. ./test-lib.sh
+
+test_expect_success "Search body" '
+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)"
+
+'
+test_expect_success "Search by from:" '
+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)"
+
+'
+test_expect_success "Search by to:" '
+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)"
+
+'
+test_expect_success "Search by subject:" '
+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)"
+
+'
+test_expect_success "Search by id:" '
+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)"
+
+'
+test_expect_success "Search by tag:" '
+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)"
+
+'
+test_expect_success "Search by thread:" '
+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)"
+
+'
+test_expect_success "Search body (phrase)" '
+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)"
+
+'
+test_expect_success "Search by from: (address)" '
+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)"
+
+'
+test_expect_success "Search by from: (name)" '
+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)"
+
+'
+test_expect_success "Search by to: (address)" '
+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)"
+
+'
+test_expect_success "Search by to: (name)" '
+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)"
+
+'
+test_expect_success "Search by subject: (phrase)" '
+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)"
+
+'
+test_expect_success "Search for all messages (\"*\"):" '
+output=$($NOTMUCH search "*" | notmuch_search_sanitize) &&
+pass_if_equal "$output" "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)"
+
+'
+test_expect_success "Search body (utf-8):" '
+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)"
+'
+test_done
diff --git a/test/t0003-json.sh b/test/t0003-json.sh
new file mode 100755
index 0000000..810262c
--- /dev/null
+++ b/test/t0003-json.sh
@@ -0,0 +1,46 @@
+#!/bin/bash
+test_description="--format=json output"
+. ./test-lib.sh
+
+test_expect_success "Show message: json" '
+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\"}]}, []]]]"
+
+'
+test_expect_success "Search message: json" '
+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\"]}]"
+
+'
+test_expect_success "Search by subject (utf-8):" '
+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)"
+
+'
+test_expect_success "Show message: json, utf-8" '
+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\"}]}, []]]]"
+
+'
+test_expect_success "Search message: json, utf-8" '
+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\"]}]"
+'
+test_done
diff --git a/test/t0004-thread-naming.sh b/test/t0004-thread-naming.sh
new file mode 100755
index 0000000..88216f2
--- /dev/null
+++ b/test/t0004-thread-naming.sh
@@ -0,0 +1,191 @@
+#!/bin/bash
+test_description="naming of threads with changing subject"
+. ./test-lib.sh
+test_expect_success 'Generate some messages' '
+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}
+
+'
+test_expect_success "Initial thread name (oldest-first search)" '
+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)"
+
+'
+test_expect_success "Initial thread name (newest-first search)" '
+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
+
+'
+test_expect_success "Changed thread name (oldest-first search)" '
+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)"
+
+'
+test_expect_success "Changed thread name (newest-first search)" '
+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)"
+
+'
+test_expect_success "Ignore added reply prefix (Re:)" '
+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)"
+
+'
+test_expect_success "Ignore added reply prefix (Aw:)" '
+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)"
+
+'
+test_expect_success "Ignore added reply prefix (Vs:)" '
+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)"
+
+'
+test_expect_success "Ignore added reply prefix (Sv:)" '
+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)"
+
+'
+test_expect_success "Test order of messages in \"notmuch show\"" '
+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}"
+'
+test_done
diff --git a/test/t0005-reply.sh b/test/t0005-reply.sh
new file mode 100755
index 0000000..650d5bd
--- /dev/null
+++ b/test/t0005-reply.sh
@@ -0,0 +1,137 @@
+#!/bin/bash
+test_description="\"notmuch reply\" in several variations"
+. ./test-lib.sh
+
+test_expect_success "Basic reply" '
+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"
+
+'
+test_expect_success "Multiple recipients" '
+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"
+
+'
+test_expect_success "Reply with CC" '
+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"
+
+'
+test_expect_success "Reply from alternate address" '
+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"
+
+'
+test_expect_success "Support for Reply-To" '
+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"
+
+'
+test_expect_success "Un-munging Reply-To" '
+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"
+'
+
+test_expect_success "Message with header of exactly 200 bytes" '
+add_message "[subject]=\"This subject is exactly 200 bytes in length. Other than its length there is not much of note here. Note that the length of 200 bytes includes the Subject: and Re: prefixes with two spaces\"" \
+            "[date]=\"Tue, 05 Jan 2010 15:43:56 -0800\"" \
+            "[body]=\"200-byte header\"" &&
+output=$($NOTMUCH reply id:${gen_msg_id}) &&
+pass_if_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
+Subject: Re: This subject is exactly 200 bytes in length. Other than its length there is not much of note here. Note that the length of 200 bytes includes the Subject: and Re: prefixes with two spaces
+Bcc: test_suite@notmuchmail.org
+In-Reply-To: <${gen_msg_id}>
+References: <${gen_msg_id}>
+
+On Tue, 05 Jan 2010 15:43:56 -0800, Notmuch Test Suite <test_suite@notmuchmail.org> wrote:
+> 200-byte header"
+'
+test_done
diff --git a/test/t0006-dump-restore.sh b/test/t0006-dump-restore.sh
new file mode 100755
index 0000000..f971181
--- /dev/null
+++ b/test/t0006-dump-restore.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+test_description="\"notmuch dump\" and \"notmuch restore\""
+. ./test-lib.sh
+test_expect_success 'Generate some message' '
+generate_message &&
+notmuch new
+'
+test_expect_success "Dumping all tags" '
+$NOTMUCH dump dump.expected &&
+pass_if_equal "$?" "0"
+
+'
+test_expect_success "Clearing all tags" '
+sed -e "s/(\([^(]*\))$/()/" < dump.expected > clear.expected
+$NOTMUCH restore clear.expected &&
+$NOTMUCH dump clear.actual &&
+pass_if_equal "$(< clear.actual)" "$(< clear.expected)"
+
+'
+test_expect_success "Restoring original tags" '
+$NOTMUCH restore dump.expected &&
+$NOTMUCH dump dump.actual &&
+pass_if_equal "$(< dump.actual)" "$(< dump.expected)"
+
+'
+test_expect_success "Restore with nothing to do" '
+$NOTMUCH restore dump.expected &&
+pass_if_equal "$?" "0"
+'
+test_done
diff --git a/test/t0007-uuencode.sh b/test/t0007-uuencode.sh
new file mode 100755
index 0000000..e290610
--- /dev/null
+++ b/test/t0007-uuencode.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+test_description="handling of uuencoded data"
+. ./test-lib.sh
+test_expect_success 'Generate message' '
+
+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.\""
+
+'
+test_expect_success "Ensure content before uu data is indexed" '
+output=$($NOTMUCH search beforeuudata | notmuch_search_sanitize) &&
+pass_if_equal "$output" "thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; uuencodetest (inbox unread)"
+'
+test_expect_success "Ensure uu data is not indexed" '
+output=$($NOTMUCH search DURINGUUDATA | notmuch_search_sanitize) &&
+pass_if_equal "$output" ""
+'
+test_expect_success "Ensure content after uu data is indexed" '
+output=$($NOTMUCH search afteruudata | notmuch_search_sanitize) &&
+pass_if_equal "$output" "thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; uuencodetest (inbox unread)"
+'
+test_done
diff --git a/test/t0008-threading-out-of-order.sh b/test/t0008-threading-out-of-order.sh
new file mode 100755
index 0000000..9f360b7
--- /dev/null
+++ b/test/t0008-threading-out-of-order.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+test_description="threading when messages received out of order"
+. ./test-lib.sh
+test_expect_success "Adding initial child message" '
+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."
+'
+test_expect_success "Searching returns the message" '
+output=$($NOTMUCH search foo | notmuch_search_sanitize) &&
+pass_if_equal "$output" "thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; brokenthreadtest (inbox unread)"
+'
+test_expect_success "Adding second child message" '
+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."
+'
+test_expect_success "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)"
+'
+test_expect_success "Adding parent message" '
+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."
+'
+test_expect_success "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)"
+'
+test_done
diff --git a/test/t0009-author-reordering.sh b/test/t0009-author-reordering.sh
new file mode 100755
index 0000000..b993341
--- /dev/null
+++ b/test/t0009-author-reordering.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+test_description="author reordering;"
+. ./test-lib.sh
+test_expect_success "Adding parent message" '
+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."
+'
+test_expect_success "Adding initial child message" '
+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."
+'
+test_expect_success "Adding second child message" '
+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."
+'
+test_expect_success "Searching when all three messages match" '
+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)"
+'
+test_expect_success "Searching when two messages match" '
+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)"
+'
+test_expect_success "Searching when only one message matches" '
+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)"
+'
+test_expect_success "Searching when only first message matches" '
+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)"
+'
+test_done
diff --git a/test/t0010-from-line-heuristics.sh b/test/t0010-from-line-heuristics.sh
new file mode 100755
index 0000000..bd0e887
--- /dev/null
+++ b/test/t0010-from-line-heuristics.sh
@@ -0,0 +1,215 @@
+#!/bin/bash
+test_description="From line heuristics (with multiple configured addresses)"
+. ./test-lib.sh
+
+test_expect_success "Magic from guessing (nothing to go on)" '
+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"
+
+'
+test_expect_success "Magic from guessing (Envelope-to:)" '
+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"
+
+'
+test_expect_success "Magic from guessing (X-Original-To:)" '
+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"
+
+'
+test_expect_success "Magic from guessing (Received: .. for ..)" '
+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"
+
+'
+test_expect_success "Magic from guessing (Received: domain)" '
+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"
+
+
+'
+test_expect_success "Testing From line heuristics (with single configured address)" '
+sed -i -e "s/^other_email.*//" "${NOTMUCH_CONFIG}"
+
+'
+test_expect_success "Magic from guessing (nothing to go on)" '
+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"
+
+'
+test_expect_success "Magic from guessing (Envelope-to:)" '
+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"
+
+'
+test_expect_success "Magic from guessing (X-Original-To:)" '
+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"
+
+'
+test_expect_success "Magic from guessing (Received: .. for ..)" '
+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"
+
+'
+test_expect_success "Magic from guessing (Received: domain)" '
+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"
+'
+test_done
diff --git a/test/t0011-long-msgid.sh b/test/t0011-long-msgid.sh
new file mode 100755
index 0000000..c1cbd9f
--- /dev/null
+++ b/test/t0011-long-msgid.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+test_description="Testing messages with ridiculously-long message IDs"
+. ./test-lib.sh
+
+test_expect_success "Referencing long ID before adding" '
+generate_message "[subject]=\"Reference of ridiculously-long message ID\"" \
+		 "[references]=\<abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-\>" &&
+output=$(NOTMUCH_NEW) &&
+pass_if_equal "$output" "Added 1 new message to the database."
+'
+test_expect_success "Adding message with long ID" '
+generate_message "[subject]=\"A ridiculously-long message ID\"" \
+		 "[id]=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-" &&
+output=$(NOTMUCH_NEW) &&
+pass_if_equal "$output" "Added 1 new message to the database."
+
+'
+test_expect_success "Referencing long ID after adding" '
+generate_message "[subject]=\"Reply to ridiculously-long message ID\"" \
+		 "[in-reply-to]=\<abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-\>" &&
+output=$(NOTMUCH_NEW) &&
+pass_if_equal "$output" "Added 1 new message to the database."
+
+'
+test_expect_success "Ensure all messages were threaded together" '
+output=$($NOTMUCH search "subject:\"a ridiculously-long message ID\"" | notmuch_search_sanitize) &&
+pass_if_equal "$output" "thread:XXX   2001-01-05 [1/3] Notmuch Test Suite; A ridiculously-long message ID (inbox unread)"
+'
+test_done
diff --git a/test/t0012-encoding-issues.sh b/test/t0012-encoding-issues.sh
new file mode 100755
index 0000000..643ba1b
--- /dev/null
+++ b/test/t0012-encoding-issues.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+test_description="Testing encoding issues"
+. ./test-lib.sh
+
+test_expect_success "Message with text of unknown charset" '
+add_message "[content-type]=\"text/plain; charset=unknown-8bit\"" \
+            "[body]=irrelevant" &&
+output=$($NOTMUCH show id:${gen_msg_id} 2>&1 | notmuch_show_sanitize) &&
+pass_if_equal "$output" "\fmessage{ id:msg-001@notmuch-test-suite depth:0 match:1 filename:/XXX/mail/msg-001
+\fheader{
+Notmuch Test Suite <test_suite@notmuchmail.org> (2001-01-05) (inbox unread)
+Subject: Test message #1
+From: Notmuch Test Suite <test_suite@notmuchmail.org>
+To: Notmuch Test Suite <test_suite@notmuchmail.org>
+Date: Tue, 05 Jan 2001 15:43:57 -0800
+\fheader}
+\fbody{
+\fpart{ ID: 1, Content-type: text/plain
+irrelevant
+\fpart}
+\fbody}
+\fmessage}"
+'
+
+test_done
-- 
1.7.1.3.g75e44

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

* [PATCH v3 5/5] test: Set all times to UTC
  2010-06-10  6:47 [PATCH v3 0/5] Git-based modularization of test suite Michal Sojka
                   ` (3 preceding siblings ...)
  2010-06-10  6:48 ` [PATCH v3 4/5] Convert the actual tests to the new framework Michal Sojka
@ 2010-06-10  6:48 ` Michal Sojka
  2010-09-20 22:33 ` [PATCH v3 0/5] Git-based modularization of test suite Carl Worth
  5 siblings, 0 replies; 11+ messages in thread
From: Michal Sojka @ 2010-06-10  6:48 UTC (permalink / raw)
  To: notmuch

In order to have repeatable test suite, all times in messages are set
to UTC time zone to match the time zone (TZ variable) set in
test-lib.sh.

Signed-off-by: Michal Sojka <sojkam1@fel.cvut.cz>
---
 test/t0004-thread-naming.sh        |   32 ++++++++++++++--------------
 test/t0005-reply.sh                |   28 ++++++++++++------------
 test/t0010-from-line-heuristics.sh |   40 ++++++++++++++++++------------------
 test/t0012-encoding-issues.sh      |    2 +-
 test/test-lib.sh                   |    2 +-
 5 files changed, 52 insertions(+), 52 deletions(-)

diff --git a/test/t0004-thread-naming.sh b/test/t0004-thread-naming.sh
index 88216f2..c77f726 100755
--- a/test/t0004-thread-naming.sh
+++ b/test/t0004-thread-naming.sh
@@ -3,17 +3,17 @@ test_description="naming of threads with changing subject"
 . ./test-lib.sh
 test_expect_success 'Generate some messages' '
 add_message "[subject]=\"thread-naming: Initial thread subject\"" \
-            "[date]=\"Fri, 05 Jan 2001 15:43:56 -0800\"" &&
+            "[date]=\"Fri, 05 Jan 2001 15:43:56 -0000\"" &&
 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\"" \
+            "[date]=\"Sat, 06 Jan 2001 15:43:56 -0000\"" \
             "[in-reply-to]=\<$parent\>" &&
 add_message "[subject]=\"thread-naming: Newer changed subject\"" \
-            "[date]=\"Sun, 07 Jan 2001 15:43:56 -0800\"" \
+            "[date]=\"Sun, 07 Jan 2001 15:43:56 -0000\"" \
             "[in-reply-to]=\<$parent\>" &&
 add_message "[subject]=\"thread-naming: Final thread subject\"" \
-            "[date]=\"Mon, 08 Jan 2001 15:43:56 -0800\"" \
+            "[date]=\"Mon, 08 Jan 2001 15:43:56 -0000\"" \
             "[in-reply-to]=\<$parent\>" &&
 final=${gen_msg_id}
 
@@ -43,7 +43,7 @@ pass_if_equal "$output" "thread:XXX   2001-01-07 [2/4] Notmuch Test Suite; threa
 '
 test_expect_success "Ignore added reply prefix (Re:)" '
 add_message "[subject]=\"Re: thread-naming: Initial thread subject\"" \
-            "[date]=\"Tue, 09 Jan 2001 15:43:45 -0800\"" \
+            "[date]=\"Tue, 09 Jan 2001 15:43:45 -0000\"" \
             "[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)"
@@ -51,7 +51,7 @@ pass_if_equal "$output" "thread:XXX   2001-01-09 [3/5] Notmuch Test Suite; threa
 '
 test_expect_success "Ignore added reply prefix (Aw:)" '
 add_message "[subject]=\"Aw: thread-naming: Initial thread subject\"" \
-            "[date]=\"Wed, 10 Jan 2001 15:43:45 -0800\"" \
+            "[date]=\"Wed, 10 Jan 2001 15:43:45 -0000\"" \
             "[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)"
@@ -59,7 +59,7 @@ pass_if_equal "$output" "thread:XXX   2001-01-10 [4/6] Notmuch Test Suite; threa
 '
 test_expect_success "Ignore added reply prefix (Vs:)" '
 add_message "[subject]=\"Vs: thread-naming: Initial thread subject\"" \
-            "[date]=\"Thu, 11 Jan 2001 15:43:45 -0800\"" \
+            "[date]=\"Thu, 11 Jan 2001 15:43:45 -0000\"" \
             "[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)"
@@ -67,7 +67,7 @@ pass_if_equal "$output" "thread:XXX   2001-01-11 [5/7] Notmuch Test Suite; threa
 '
 test_expect_success "Ignore added reply prefix (Sv:)" '
 add_message "[subject]=\"Sv: thread-naming: Initial thread subject\"" \
-            "[date]=\"Fri, 12 Jan 2001 15:43:45 -0800\"" \
+            "[date]=\"Fri, 12 Jan 2001 15:43:45 -0000\"" \
             "[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)"
@@ -81,7 +81,7 @@ 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
+Date: Fri, 05 Jan 2001 15:43:56 -0000
 \fheader}
 \fbody{
 \fpart{ ID: 1, Content-type: text/plain
@@ -95,7 +95,7 @@ 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
+Date: Sat, 06 Jan 2001 15:43:56 -0000
 \fheader}
 \fbody{
 \fpart{ ID: 1, Content-type: text/plain
@@ -109,7 +109,7 @@ 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
+Date: Sun, 07 Jan 2001 15:43:56 -0000
 \fheader}
 \fbody{
 \fpart{ ID: 1, Content-type: text/plain
@@ -123,7 +123,7 @@ 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
+Date: Mon, 08 Jan 2001 15:43:56 -0000
 \fheader}
 \fbody{
 \fpart{ ID: 1, Content-type: text/plain
@@ -137,7 +137,7 @@ 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
+Date: Tue, 09 Jan 2001 15:43:45 -0000
 \fheader}
 \fbody{
 \fpart{ ID: 1, Content-type: text/plain
@@ -151,7 +151,7 @@ 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
+Date: Wed, 10 Jan 2001 15:43:45 -0000
 \fheader}
 \fbody{
 \fpart{ ID: 1, Content-type: text/plain
@@ -165,7 +165,7 @@ 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
+Date: Thu, 11 Jan 2001 15:43:45 -0000
 \fheader}
 \fbody{
 \fpart{ ID: 1, Content-type: text/plain
@@ -179,7 +179,7 @@ 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
+Date: Fri, 12 Jan 2001 15:43:45 -0000
 \fheader}
 \fbody{
 \fpart{ ID: 1, Content-type: text/plain
diff --git a/test/t0005-reply.sh b/test/t0005-reply.sh
index 650d5bd..97e1006 100755
--- a/test/t0005-reply.sh
+++ b/test/t0005-reply.sh
@@ -6,7 +6,7 @@ test_expect_success "Basic reply" '
 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\"" \
+            "[date]=\"Tue, 05 Jan 2010 15:43:56 -0000\"" \
             "[body]=\"basic reply test\"" &&
 
 output=$($NOTMUCH reply id:${gen_msg_id}) &&
@@ -17,7 +17,7 @@ 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:
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
 > basic reply test"
 
 '
@@ -25,7 +25,7 @@ test_expect_success "Multiple recipients" '
 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\"" \
+            "[date]=\"Tue, 05 Jan 2010 15:43:56 -0000\"" \
             "[body]=\"Multiple recipients\"" &&
 
 output=$($NOTMUCH reply id:${gen_msg_id}) &&
@@ -36,7 +36,7 @@ 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:
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
 > Multiple recipients"
 
 '
@@ -45,7 +45,7 @@ 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\"" \
+            "[date]=\"Tue, 05 Jan 2010 15:43:56 -0000\"" \
             "[body]=\"reply with CC\"" &&
 
 output=$($NOTMUCH reply id:${gen_msg_id}) &&
@@ -57,7 +57,7 @@ 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:
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
 > reply with CC"
 
 '
@@ -65,7 +65,7 @@ test_expect_success "Reply from alternate address" '
 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\"" \
+            "[date]=\"Tue, 05 Jan 2010 15:43:56 -0000\"" \
             "[body]=\"reply from alternate address\"" &&
 
 output=$($NOTMUCH reply id:${gen_msg_id}) &&
@@ -76,7 +76,7 @@ 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:
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
 > reply from alternate address"
 
 '
@@ -84,7 +84,7 @@ test_expect_success "Support for Reply-To" '
 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\"" \
+            "[date]=\"Tue, 05 Jan 2010 15:43:56 -0000\"" \
             "[body]=\"support for reply-to\"" \
             "[reply-to]=\"Sender <elsewhere@example.com>\"" &&
 
@@ -96,7 +96,7 @@ 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:
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
 > support for reply-to"
 
 '
@@ -104,7 +104,7 @@ test_expect_success "Un-munging Reply-To" '
 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\"" \
+            "[date]=\"Tue, 05 Jan 2010 15:43:56 -0000\"" \
             "[body]=\"Un-munging Reply-To\"" \
             "[reply-to]=\"Evil Munging List <list@example.com>\"" &&
 
@@ -116,13 +116,13 @@ 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:
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
 > Un-munging Reply-To"
 '
 
 test_expect_success "Message with header of exactly 200 bytes" '
 add_message "[subject]=\"This subject is exactly 200 bytes in length. Other than its length there is not much of note here. Note that the length of 200 bytes includes the Subject: and Re: prefixes with two spaces\"" \
-            "[date]=\"Tue, 05 Jan 2010 15:43:56 -0800\"" \
+            "[date]=\"Tue, 05 Jan 2010 15:43:56 -0000\"" \
             "[body]=\"200-byte header\"" &&
 output=$($NOTMUCH reply id:${gen_msg_id}) &&
 pass_if_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
@@ -131,7 +131,7 @@ Bcc: test_suite@notmuchmail.org
 In-Reply-To: <${gen_msg_id}>
 References: <${gen_msg_id}>
 
-On Tue, 05 Jan 2010 15:43:56 -0800, Notmuch Test Suite <test_suite@notmuchmail.org> wrote:
+On Tue, 05 Jan 2010 15:43:56 -0000, Notmuch Test Suite <test_suite@notmuchmail.org> wrote:
 > 200-byte header"
 '
 test_done
diff --git a/test/t0010-from-line-heuristics.sh b/test/t0010-from-line-heuristics.sh
index bd0e887..89702b5 100755
--- a/test/t0010-from-line-heuristics.sh
+++ b/test/t0010-from-line-heuristics.sh
@@ -6,7 +6,7 @@ test_expect_success "Magic from guessing (nothing to go on)" '
 add_message "[from]=\"Sender <sender@example.com>\"" \
              [to]=mailinglist@notmuchmail.org \
              [subject]=notmuch-reply-test \
-            "[date]=\"Tue, 05 Jan 2010 15:43:56 -0800\"" \
+            "[date]=\"Tue, 05 Jan 2010 15:43:56 -0000\"" \
             "[body]=\"from guessing test\"" &&
 
 output=$($NOTMUCH reply id:${gen_msg_id}) &&
@@ -17,7 +17,7 @@ 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:
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
 > from guessing test"
 
 '
@@ -26,7 +26,7 @@ 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\"" \
+            "[date]=\"Tue, 05 Jan 2010 15:43:56 -0000\"" \
             "[body]=\"from guessing test\"" &&
 
 output=$($NOTMUCH reply id:${gen_msg_id}) &&
@@ -37,7 +37,7 @@ 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:
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
 > from guessing test"
 
 '
@@ -46,7 +46,7 @@ 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\"" \
+            "[date]=\"Tue, 05 Jan 2010 15:43:56 -0000\"" \
             "[body]=\"from guessing test\"" &&
 
 output=$($NOTMUCH reply id:${gen_msg_id}) &&
@@ -57,7 +57,7 @@ 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:
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
 > from guessing test"
 
 '
@@ -68,7 +68,7 @@ add_message "[from]=\"Sender <sender@example.com>\"" \
             "[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\"" \
+            "[date]=\"Tue, 05 Jan 2010 15:43:56 -0000\"" \
             "[body]=\"from guessing test\"" &&
 
 output=$($NOTMUCH reply id:${gen_msg_id}) &&
@@ -79,7 +79,7 @@ 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:
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
 > from guessing test"
 
 '
@@ -90,7 +90,7 @@ add_message "[from]=\"Sender <sender@example.com>\"" \
             "[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\"" \
+            "[date]=\"Tue, 05 Jan 2010 15:43:56 -0000\"" \
             "[body]=\"from guessing test\"" &&
 
 output=$($NOTMUCH reply id:${gen_msg_id}) &&
@@ -101,7 +101,7 @@ 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:
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
 > from guessing test"
 
 
@@ -114,7 +114,7 @@ test_expect_success "Magic from guessing (nothing to go on)" '
 add_message "[from]=\"Sender <sender@example.com>\"" \
              [to]=mailinglist@notmuchmail.org \
              [subject]=notmuch-reply-test \
-            "[date]=\"Tue, 05 Jan 2010 15:43:56 -0800\"" \
+            "[date]=\"Tue, 05 Jan 2010 15:43:56 -0000\"" \
             "[body]=\"from guessing test\"" &&
 
 output=$($NOTMUCH reply id:${gen_msg_id}) &&
@@ -125,7 +125,7 @@ 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:
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
 > from guessing test"
 
 '
@@ -134,7 +134,7 @@ 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\"" \
+            "[date]=\"Tue, 05 Jan 2010 15:43:56 -0000\"" \
             "[body]=\"from guessing test\"" &&
 
 output=$($NOTMUCH reply id:${gen_msg_id}) &&
@@ -145,7 +145,7 @@ 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:
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
 > from guessing test"
 
 '
@@ -154,7 +154,7 @@ 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\"" \
+            "[date]=\"Tue, 05 Jan 2010 15:43:56 -0000\"" \
             "[body]=\"from guessing test\"" &&
 
 output=$($NOTMUCH reply id:${gen_msg_id}) &&
@@ -165,7 +165,7 @@ 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:
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
 > from guessing test"
 
 '
@@ -176,7 +176,7 @@ add_message "[from]=\"Sender <sender@example.com>\"" \
             "[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\"" \
+            "[date]=\"Tue, 05 Jan 2010 15:43:56 -0000\"" \
             "[body]=\"from guessing test\"" &&
 
 output=$($NOTMUCH reply id:${gen_msg_id}) &&
@@ -187,7 +187,7 @@ 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:
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
 > from guessing test"
 
 '
@@ -198,7 +198,7 @@ add_message "[from]=\"Sender <sender@example.com>\"" \
             "[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\"" \
+            "[date]=\"Tue, 05 Jan 2010 15:43:56 -0000\"" \
             "[body]=\"from guessing test\"" &&
 
 output=$($NOTMUCH reply id:${gen_msg_id}) &&
@@ -209,7 +209,7 @@ 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:
+On Tue, 05 Jan 2010 15:43:56 -0000, Sender <sender@example.com> wrote:
 > from guessing test"
 '
 test_done
diff --git a/test/t0012-encoding-issues.sh b/test/t0012-encoding-issues.sh
index 643ba1b..6a6ceda 100755
--- a/test/t0012-encoding-issues.sh
+++ b/test/t0012-encoding-issues.sh
@@ -12,7 +12,7 @@ Notmuch Test Suite <test_suite@notmuchmail.org> (2001-01-05) (inbox unread)
 Subject: Test message #1
 From: Notmuch Test Suite <test_suite@notmuchmail.org>
 To: Notmuch Test Suite <test_suite@notmuchmail.org>
-Date: Tue, 05 Jan 2001 15:43:57 -0800
+Date: Tue, 05 Jan 2001 15:43:57 -0000
 \fheader}
 \fbody{
 \fpart{ ID: 1, Content-type: text/plain
diff --git a/test/test-lib.sh b/test/test-lib.sh
index d045820..5ae916c 100644
--- a/test/test-lib.sh
+++ b/test/test-lib.sh
@@ -311,7 +311,7 @@ generate_message ()
     fi
 
     if [ -z "${template[date]}" ]; then
-	template[date]="Tue, 05 Jan 2001 15:43:57 -0800"
+	template[date]="Tue, 05 Jan 2001 15:43:57 -0000"
     fi
 
     additional_headers=""
-- 
1.7.1.3.g75e44

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

* Re: [PATCH v3 0/5] Git-based modularization of test suite
  2010-06-10  6:47 [PATCH v3 0/5] Git-based modularization of test suite Michal Sojka
                   ` (4 preceding siblings ...)
  2010-06-10  6:48 ` [PATCH v3 5/5] test: Set all times to UTC Michal Sojka
@ 2010-09-20 22:33 ` Carl Worth
  2010-09-20 23:46   ` Carl Worth
  2010-09-22  9:48   ` Michal Sojka
  5 siblings, 2 replies; 11+ messages in thread
From: Carl Worth @ 2010-09-20 22:33 UTC (permalink / raw)
  To: Michal Sojka, notmuch

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

> Michal Sojka (5):
>   Copy test framework from Git
>   Update test framework for use with notmuch
>   test: Update helper functions
>   Convert the actual tests to the new framework
>   test: Set all times to UTC

Hi Michal,

Thanks for sending this, (and patiently sending in three versions of
it).

I've now pushed this out, along with some changes of my own on top of
it. My changes make things in the test suite look more like they did
before the git-based modularization, (both output from the test suite
and how the tests themselves are written). I couldn't stand the approach
of doing long chains of shell commands within strings for the tests, and
I also didn't like the numeric filenames.

Take a look at what I've done, and let me know if I defeated any
intended benefits of the git-based modularization of the test suite.

One problem with the current arrangement is that all tests now start
with an empty database of messages. This means that the search tests
aren't giving as much test coverage. And the dump/restore tests are
actually testing nothing at all!

I think what I'd prefer to have is for test-lib.sh to populate a
non-empty database (it could even provide a function to reset the
database to empty for any tests that actually want that).

For efficiency, the non-empty database could be created just once at the
first invocation and then could simply be copied into place for future
invocations.

If anyone wants to help fix that, that would be great.

-Carl

PS. The valgrind support[*] in the newly modularized test suite helped
me find a use-after-free bug in the current code base, so that's already
a useful result here. Thanks again!

[*] The valgrind support isn't ideal yet since it's not actually
flagging failures since the test suite isn't currently looking at return
values of valgrind/notmuch. This is arguably my fault since I got rid of
the ugly 'command && another_command && yet_another_command' syntax. I'd
like to see a way to fix the valgrind support without introducing that
awful syntax. I'm open to ideas.

-- 
carl.d.worth@intel.com

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

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

* Re: [PATCH v3 0/5] Git-based modularization of test suite
  2010-09-20 22:33 ` [PATCH v3 0/5] Git-based modularization of test suite Carl Worth
@ 2010-09-20 23:46   ` Carl Worth
  2010-09-22  9:48   ` Michal Sojka
  1 sibling, 0 replies; 11+ messages in thread
From: Carl Worth @ 2010-09-20 23:46 UTC (permalink / raw)
  To: Michal Sojka, notmuch

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

On Mon, 20 Sep 2010 15:33:09 -0700, Carl Worth <cworth@cworth.org> wrote:
> I think what I'd prefer to have is for test-lib.sh to populate a
> non-empty database (it could even provide a function to reset the
> database to empty for any tests that actually want that).

I've now implemented this. I did it slightly differently, making
test-lib.sh provide an empty database by default and allowing tests to
call a new add_email_corpus function if they need a bunch of email to
work with.

That's because it turns out that many of the existing tests really do
want to focus only on a few, carefully-controlled messages (think about
the tests for "notmuch reply" for example).

> For efficiency, the non-empty database could be created just once at the
> first invocation and then could simply be copied into place for future
> invocations.

I did do it this efficient way. It's only being used currently by the
search and dump-restore tests, so that efficiency doesn't matter too
much yet. But I do expect many more tests to start using this
functionality soon.

-Carl

-- 
carl.d.worth@intel.com

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

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

* Re: [PATCH v3 0/5] Git-based modularization of test suite
  2010-09-20 22:33 ` [PATCH v3 0/5] Git-based modularization of test suite Carl Worth
  2010-09-20 23:46   ` Carl Worth
@ 2010-09-22  9:48   ` Michal Sojka
  2010-10-13 12:44     ` Michal Sojka
  1 sibling, 1 reply; 11+ messages in thread
From: Michal Sojka @ 2010-09-22  9:48 UTC (permalink / raw)
  To: Carl Worth, notmuch

Hi Carl,

good to here from you again :-)

On Mon, 20 Sep 2010, Carl Worth wrote:
> I've now pushed this out, along with some changes of my own on top of
> it. My changes make things in the test suite look more like they did
> before the git-based modularization, (both output from the test suite
> and how the tests themselves are written). I couldn't stand the approach
> of doing long chains of shell commands within strings for the tests, and
> I also didn't like the numeric filenames.
> 
> Take a look at what I've done, and let me know if I defeated any
> intended benefits of the git-based modularization of the test suite.

I went through your changes and they seems reasonable to me. I'll try to
update my tests for maildir synchronization and let you know (or send a
patch) if I find some problems.

> One problem with the current arrangement is that all tests now start
> with an empty database of messages. This means that the search tests
> aren't giving as much test coverage. And the dump/restore tests are
> actually testing nothing at all!
> 
> I think what I'd prefer to have is for test-lib.sh to populate a
> non-empty database (it could even provide a function to reset the
> database to empty for any tests that actually want that).
> 
> For efficiency, the non-empty database could be created just once at the
> first invocation and then could simply be copied into place for future
> invocations.
> 
> If anyone wants to help fix that, that would be great.

Looks like you have already fix that.

Thanks,
Michal

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

* Re: [PATCH v3 0/5] Git-based modularization of test suite
  2010-09-22  9:48   ` Michal Sojka
@ 2010-10-13 12:44     ` Michal Sojka
  2010-10-13 15:41       ` Carl Worth
  0 siblings, 1 reply; 11+ messages in thread
From: Michal Sojka @ 2010-10-13 12:44 UTC (permalink / raw)
  To: Carl Worth, notmuch

On Wed, 22 Sep 2010, Michal Sojka wrote:
> On Mon, 20 Sep 2010, Carl Worth wrote:
> > I've now pushed this out, along with some changes of my own on top of
> > it. My changes make things in the test suite look more like they did
> > before the git-based modularization, (both output from the test suite
> > and how the tests themselves are written). I couldn't stand the approach
> > of doing long chains of shell commands within strings for the tests, and
> > I also didn't like the numeric filenames.
> > 
> > Take a look at what I've done, and let me know if I defeated any
> > intended benefits of the git-based modularization of the test suite.
> 
> I went through your changes and they seems reasonable to me. I'll try to
> update my tests for maildir synchronization and let you know (or send a
> patch) if I find some problems.

Hi Carl,

here is my experience with test_begin_subtest and test_expect_equal
functions in test-lib.sh. I see there two significant differences from
the git's test_expect_success and similar functions.

First, when the test fails, you only see the differences in the real
output and the expected output. If you use test_expect_success you also
see the actual commands that were executed.

Second, when some command between test_begin_subtest and
test_expect_success fails (e.g. because of segfault) you may not detect
it. You can add "set -e" the test-lib.sh (see the patch bellow), but in
this case when a test fails you would see

  FATAL: Unexpected exit with code 1

without any additional information.

-Michal


diff --git a/test/test-lib.sh b/test/test-lib.sh
index 2036669..c98ea2f 100644
--- a/test/test-lib.sh
+++ b/test/test-lib.sh
@@ -395,6 +395,7 @@ add_email_corpus ()
 test_begin_subtest ()
 {
     test_subtest_name="$1"
+    set -e
 }
 
 # Pass test if two arguments match

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

* Re: [PATCH v3 0/5] Git-based modularization of test suite
  2010-10-13 12:44     ` Michal Sojka
@ 2010-10-13 15:41       ` Carl Worth
  0 siblings, 0 replies; 11+ messages in thread
From: Carl Worth @ 2010-10-13 15:41 UTC (permalink / raw)
  To: Michal Sojka, notmuch

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

On Wed, 13 Oct 2010 14:44:23 +0200, Michal Sojka <sojkam1@fel.cvut.cz> wrote:
> here is my experience with test_begin_subtest and test_expect_equal
> functions in test-lib.sh. I see there two significant differences from
> the git's test_expect_success and similar functions.
> 
> First, when the test fails, you only see the differences in the real
> output and the expected output. If you use test_expect_success you also
> see the actual commands that were executed.

Yes. For me, I never found the printing of the exact commands as
something useful. We probably should fix our test suite to behave
consistently regardless of which interface is used.

> Second, when some command between test_begin_subtest and
> test_expect_success fails (e.g. because of segfault) you may not detect
> it. You can add "set -e" the test-lib.sh (see the patch bellow), but in
> this case when a test fails you would see
> 
>   FATAL: Unexpected exit with code 1
> 
> without any additional information.

What do you recommend here?

Frankly, I'm fine if the test cases are easy to read, (and I think they
are easier without having many commands chained by "&&" and concatenated
into a single string). Then if any test fails, (whether a segfault or
simply incorrect output), it shouldn't be hard to just open the test
case and manually inspect the commands.

But if you've got some idea for anything more useful, (some magic action
with trap for example?), I'd be glad to hear it.

-Carl

-- 
carl.d.worth@intel.com

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

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

end of thread, other threads:[~2010-10-13 15:42 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-06-10  6:47 [PATCH v3 0/5] Git-based modularization of test suite Michal Sojka
2010-06-10  6:48 ` [PATCH v3 1/5] Copy test framework from Git Michal Sojka
2010-06-10  6:48 ` [PATCH v3 2/5] Update test framework for use with notmuch Michal Sojka
2010-06-10  6:48 ` [PATCH v3 3/5] test: Update helper functions Michal Sojka
2010-06-10  6:48 ` [PATCH v3 4/5] Convert the actual tests to the new framework Michal Sojka
2010-06-10  6:48 ` [PATCH v3 5/5] test: Set all times to UTC Michal Sojka
2010-09-20 22:33 ` [PATCH v3 0/5] Git-based modularization of test suite Carl Worth
2010-09-20 23:46   ` Carl Worth
2010-09-22  9:48   ` Michal Sojka
2010-10-13 12:44     ` Michal Sojka
2010-10-13 15:41       ` 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).