Re: [PATCH v7 01/10] test: Add broken test for the new JSON reply format.
authorAustin Clements <amdragon@MIT.EDU>
Tue, 13 Mar 2012 16:49:02 +0000 (12:49 +2000)
committerW. Trevor King <wking@tremily.us>
Fri, 7 Nov 2014 17:45:26 +0000 (09:45 -0800)
12/73625eb762981f4e4da70f128c2ea920e00768 [new file with mode: 0644]

diff --git a/12/73625eb762981f4e4da70f128c2ea920e00768 b/12/73625eb762981f4e4da70f128c2ea920e00768
new file mode 100644 (file)
index 0000000..45b90e9
--- /dev/null
@@ -0,0 +1,1401 @@
+Return-Path: <amdragon@mit.edu>\r
+X-Original-To: notmuch@notmuchmail.org\r
+Delivered-To: notmuch@notmuchmail.org\r
+Received: from localhost (localhost [127.0.0.1])\r
+       by olra.theworths.org (Postfix) with ESMTP id 3E434431FAF\r
+       for <notmuch@notmuchmail.org>; Tue, 13 Mar 2012 09:49:09 -0700 (PDT)\r
+X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
+X-Spam-Flag: NO\r
+X-Spam-Score: -0.7\r
+X-Spam-Level: \r
+X-Spam-Status: No, score=-0.7 tagged_above=-999 required=5\r
+       tests=[RCVD_IN_DNSWL_LOW=-0.7] autolearn=disabled\r
+Received: from olra.theworths.org ([127.0.0.1])\r
+       by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
+       with ESMTP id duc7cK61wKaQ for <notmuch@notmuchmail.org>;\r
+       Tue, 13 Mar 2012 09:49:05 -0700 (PDT)\r
+Received: from dmz-mailsec-scanner-4.mit.edu (DMZ-MAILSEC-SCANNER-4.MIT.EDU\r
+       [18.9.25.15])\r
+       by olra.theworths.org (Postfix) with ESMTP id 4012C431FAE\r
+       for <notmuch@notmuchmail.org>; Tue, 13 Mar 2012 09:49:05 -0700 (PDT)\r
+X-AuditID: 1209190f-b7f8a6d000000914-60-4f5f7a80452b\r
+Received: from mailhub-auth-4.mit.edu ( [18.7.62.39])\r
+       by dmz-mailsec-scanner-4.mit.edu (Symantec Messaging Gateway) with SMTP\r
+       id 6F.4A.02324.08A7F5F4; Tue, 13 Mar 2012 12:49:04 -0400 (EDT)\r
+Received: from outgoing.mit.edu (OUTGOING-AUTH.MIT.EDU [18.7.22.103])\r
+       by mailhub-auth-4.mit.edu (8.13.8/8.9.2) with ESMTP id q2DGn3lk007299; \r
+       Tue, 13 Mar 2012 12:49:04 -0400\r
+Received: from awakening.csail.mit.edu (awakening.csail.mit.edu [18.26.4.91])\r
+       (authenticated bits=0)\r
+       (User authenticated as amdragon@ATHENA.MIT.EDU)\r
+       by outgoing.mit.edu (8.13.6/8.12.4) with ESMTP id q2DGn2gJ011704\r
+       (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NOT);\r
+       Tue, 13 Mar 2012 12:49:03 -0400 (EDT)\r
+Received: from amthrax by awakening.csail.mit.edu with local (Exim 4.77)\r
+       (envelope-from <amdragon@mit.edu>)\r
+       id 1S7UuE-0004GO-1R; Tue, 13 Mar 2012 12:49:02 -0400\r
+Date: Tue, 13 Mar 2012 12:49:02 -0400\r
+From: Austin Clements <amdragon@MIT.EDU>\r
+To: Adam Wolfe Gordon <awg+notmuch@xvx.ca>\r
+Subject: Re: [PATCH v7 01/10] test: Add broken test for the new JSON reply\r
+       format.\r
+Message-ID: <20120313164901.GD2787@mit.edu>\r
+References: <1331525142-30539-1-git-send-email-awg+notmuch@xvx.ca>\r
+       <1331525142-30539-2-git-send-email-awg+notmuch@xvx.ca>\r
+MIME-Version: 1.0\r
+Content-Type: text/plain; charset=us-ascii\r
+Content-Disposition: inline\r
+In-Reply-To: <1331525142-30539-2-git-send-email-awg+notmuch@xvx.ca>\r
+User-Agent: Mutt/1.5.21 (2010-09-15)\r
+X-Brightmail-Tracker:\r
+ H4sIAAAAAAAAA+NgFprGKsWRmVeSWpSXmKPExsUixG6nrttQFe9vsHWdqsWRPbPYLa7fnMns\r
+       wOTxbNUtZo+mH4tZA5iiuGxSUnMyy1KL9O0SuDIOXVrIWPBjPVPFqn3LGBsYT71h7GLk5JAQ\r
+       MJFYPPMnO4QtJnHh3no2EFtIYB+jROsZyS5GLiB7A6PE8fmfmSGck0wS8+cfZIVwljBK/LwA\r
+       4nBysAioSkxvXsYEYrMJaEhs278cbIWIgJbEj/VfwWqYBaQlvv1uBqsRFgiRmD7lIVicV0Bb\r
+       YvvSZ+wQq6slHq+byAIRF5Q4OfMJC0SvlsSNfy+BejnA5iz/xwFicgo4SzRPFwGpEBVQkZhy\r
+       chvbBEahWUiaZyFpnoXQvICReRWjbEpulW5uYmZOcWqybnFyYl5eapGuiV5uZoleakrpJkZQ\r
+       YHNK8u9g/HZQ6RCjAAejEg+vokicvxBrYllxZe4hRkkOJiVRXo+KeH8hvqT8lMqMxOKM+KLS\r
+       nNTiQ4wSHMxKIrw2pUA53pTEyqrUonyYlDQHi5I4r5rWOz8hgfTEktTs1NSC1CKYrAwHh5IE\r
+       77ZKoEbBotT01Iq0zJwShDQTByfIcB6g4RNBaniLCxJzizPTIfKnGI057p5fdYmR4+KftZcY\r
+       hVjy8vNSpcR5u0BKBUBKM0rz4KbBktMrRnGg54R514NU8QATG9y8V0CrmIBWlXyLA1lVkoiQ\r
+       kmpgjKz17ctIkDbiZY1Ol967sXSHbvS9oP8iql6T7JnUl+zsOPT5aIKJw7wi67ftjcI7hS9s\r
+       erPyzb07Cw55adYx28+KDizZqa2/by7PrZvlzFqLF2XnqRhX/pEr+7M1+kvL3KrcJ4GTPx89\r
+       yJZguVv46Zocb22/+9lJ1/7fez7HdZKp2WJTF7dUJZbijERDLeai4kQAT4pmFSkDAAA=\r
+Cc: notmuch@notmuchmail.org\r
+X-BeenThere: notmuch@notmuchmail.org\r
+X-Mailman-Version: 2.1.13\r
+Precedence: list\r
+List-Id: "Use and development of the notmuch mail system."\r
+       <notmuch.notmuchmail.org>\r
+List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
+       <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
+List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
+List-Post: <mailto:notmuch@notmuchmail.org>\r
+List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
+List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
+       <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
+X-List-Received-Date: Tue, 13 Mar 2012 16:49:09 -0000\r
+\r
+Quoth Adam Wolfe Gordon on Mar 11 at 10:05 pm:\r
+> ---\r
+>  test/multipart |   53 +++\r
+>  test/test-lib  | 1242 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r
+>  2 files changed, 1295 insertions(+), 0 deletions(-)\r
+>  create mode 100755 test/test-lib\r
+> \r
+> diff --git a/test/multipart b/test/multipart\r
+> index 53782c6..80d6e88 100755\r
+> --- a/test/multipart\r
+> +++ b/test/multipart\r
+> @@ -589,6 +589,59 @@ Non-text part: text/html\r
+>  EOF\r
+>  test_expect_equal_file OUTPUT EXPECTED\r
+>  \r
+> +test_begin_subtest "'notmuch reply' to a multipart message with json format"\r
+> +test_subtest_known_broken\r
+> +notmuch reply --format=json 'id:87liy5ap00.fsf@yoom.home.cworth.org' | notmuch_json_show_sanitize >OUTPUT\r
+> +cat <<EOF >EXPECTED\r
+> +{"reply-headers": {"Subject": "Re: Multipart message",\r
+> + "From": "Notmuch Test Suite <test_suite@notmuchmail.org>",\r
+> + "To": "Carl Worth <cworth@cworth.org>,\r
+> + cworth@cworth.org",\r
+> + "In-reply-to": "<87liy5ap00.fsf@yoom.home.cworth.org>",\r
+> + "References": " <87liy5ap00.fsf@yoom.home.cworth.org>"},\r
+> + "original": {"id": "XXXXX",\r
+> + "match": false,\r
+> + "excluded": false,\r
+> + "filename": "YYYYY",\r
+> + "timestamp": 978709437,\r
+> + "date_relative": "2001-01-05",\r
+> + "tags": ["attachment","inbox","signed","unread"],\r
+> + "headers": {"Subject": "Multipart message",\r
+> + "From": "Carl Worth <cworth@cworth.org>",\r
+> + "To": "cworth@cworth.org",\r
+> + "Date": "Fri,\r
+> + 05 Jan 2001 15:43:57 +0000"},\r
+> + "body": [{"id": 1,\r
+> + "content-type": "multipart/signed",\r
+> + "content": [{"id": 2,\r
+> + "content-type": "multipart/mixed",\r
+> + "content": [{"id": 3,\r
+> + "content-type": "message/rfc822",\r
+> + "content": [{"headers": {"Subject": "html message",\r
+> + "From": "Carl Worth <cworth@cworth.org>",\r
+> + "To": "cworth@cworth.org",\r
+> + "Date": "Fri,\r
+> + 05 Jan 2001 15:42:57 +0000"},\r
+> + "body": [{"id": 4,\r
+> + "content-type": "multipart/alternative",\r
+> + "content": [{"id": 5,\r
+> + "content-type": "text/html"},\r
+> + {"id": 6,\r
+> + "content-type": "text/plain",\r
+> + "content": "This is an embedded message,\r
+> + with a multipart/alternative part.\n"}]}]}]},\r
+> + {"id": 7,\r
+> + "content-type": "text/plain",\r
+> + "filename": "YYYYY",\r
+> + "content": "This is a text attachment.\n"},\r
+> + {"id": 8,\r
+> + "content-type": "text/plain",\r
+> + "content": "And this message is signed.\n\n-Carl\n"}]},\r
+> + {"id": 9,\r
+> + "content-type": "application/pgp-signature"}]}]}}\r
+> +EOF\r
+> +test_expect_equal_file OUTPUT EXPECTED\r
+> +\r
+>  test_begin_subtest "'notmuch show --part' does not corrupt a part with CRLF pair"\r
+>  notmuch show --format=raw --part=3 id:base64-part-with-crlf > crlf.out\r
+>  echo -n -e "\xEF\x0D\x0A" > crlf.expected\r
+> diff --git a/test/test-lib b/test/test-lib\r
+> new file mode 100755\r
+> index 0000000..8158328\r
+> --- /dev/null\r
+> +++ b/test/test-lib\r
+\r
+Spurious git add?  (IIRC, this is what test-lib.sh used to be called,\r
+so I'd guess you have an old copy of this file laying around.)\r
+\r
+> @@ -0,0 +1,1242 @@\r
+> +#\r
+> +# Copyright (c) 2005 Junio C Hamano\r
+> +#\r
+> +# This program is free software: you can redistribute it and/or modify\r
+> +# it under the terms of the GNU General Public License as published by\r
+> +# the Free Software Foundation, either version 2 of the License, or\r
+> +# (at your option) any later version.\r
+> +#\r
+> +# This program is distributed in the hope that it will be useful,\r
+> +# but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+> +# GNU General Public License for more details.\r
+> +#\r
+> +# You should have received a copy of the GNU General Public License\r
+> +# along with this program.  If not, see http://www.gnu.org/licenses/ .\r
+> +\r
+> +if [ ${BASH_VERSINFO[0]} -lt 4 ]; then\r
+> +    echo "Error: The notmuch test suite requires a bash version >= 4.0"\r
+> +    echo "due to use of associative arrays within the test suite."\r
+> +    echo "Please try again with a newer bash (or help us fix the"\r
+> +    echo "test suite to be more portable). Thanks."\r
+> +    exit 1\r
+> +fi\r
+> +\r
+> +# if --tee was passed, write the output not only to the terminal, but\r
+> +# additionally to the file test-results/$BASENAME.out, too.\r
+> +case "$GIT_TEST_TEE_STARTED, $* " in\r
+> +done,*)\r
+> +    # do not redirect again\r
+> +    ;;\r
+> +*' --tee '*|*' --va'*)\r
+> +    mkdir -p test-results\r
+> +    BASE=test-results/$(basename "$0" .sh)\r
+> +    (GIT_TEST_TEE_STARTED=done ${SHELL-sh} "$0" "$@" 2>&1;\r
+> +     echo $? > $BASE.exit) | tee $BASE.out\r
+> +    test "$(cat $BASE.exit)" = 0\r
+> +    exit\r
+> +    ;;\r
+> +esac\r
+> +\r
+> +# Keep the original TERM for say_color and test_emacs\r
+> +ORIGINAL_TERM=$TERM\r
+> +\r
+> +# For repeatability, reset the environment to known value.\r
+> +LANG=C\r
+> +LC_ALL=C\r
+> +PAGER=cat\r
+> +TZ=UTC\r
+> +TERM=dumb\r
+> +export LANG LC_ALL PAGER TERM TZ\r
+> +GIT_TEST_CMP=${GIT_TEST_CMP:-diff -u}\r
+> +TEST_EMACS=${TEST_EMACS:-${EMACS:-emacs}}\r
+> +\r
+> +# Protect ourselves from common misconfiguration to export\r
+> +# CDPATH into the environment\r
+> +unset CDPATH\r
+> +\r
+> +unset GREP_OPTIONS\r
+> +\r
+> +# Convenience\r
+> +#\r
+> +# A regexp to match 5 and 40 hexdigits\r
+> +_x05='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'\r
+> +_x40="$_x05$_x05$_x05$_x05$_x05$_x05$_x05$_x05"\r
+> +\r
+> +_x04='[0-9a-f][0-9a-f][0-9a-f][0-9a-f]'\r
+> +_x32="$_x04$_x04$_x04$_x04$_x04$_x04$_x04$_x04"\r
+> +\r
+> +# Each test should start with something like this, after copyright notices:\r
+> +#\r
+> +# test_description='Description of this test...\r
+> +# This test checks if command xyzzy does the right thing...\r
+> +# '\r
+> +# . ./test-lib.sh\r
+> +[ "x$ORIGINAL_TERM" != "xdumb" ] && (\r
+> +            TERM=$ORIGINAL_TERM &&\r
+> +            export TERM &&\r
+> +            [ -t 1 ] &&\r
+> +            tput bold >/dev/null 2>&1 &&\r
+> +            tput setaf 1 >/dev/null 2>&1 &&\r
+> +            tput sgr0 >/dev/null 2>&1\r
+> +    ) &&\r
+> +    color=t\r
+> +\r
+> +while test "$#" -ne 0\r
+> +do\r
+> +    case "$1" in\r
+> +    -d|--d|--de|--deb|--debu|--debug)\r
+> +            debug=t; shift ;;\r
+> +    -i|--i|--im|--imm|--imme|--immed|--immedi|--immedia|--immediat|--immediate)\r
+> +            immediate=t; shift ;;\r
+> +    -l|--l|--lo|--lon|--long|--long-|--long-t|--long-te|--long-tes|--long-test|--long-tests)\r
+> +            GIT_TEST_LONG=t; export GIT_TEST_LONG; shift ;;\r
+> +    -h|--h|--he|--hel|--help)\r
+> +            help=t; shift ;;\r
+> +    -v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose)\r
+> +            verbose=t; shift ;;\r
+> +    -q|--q|--qu|--qui|--quie|--quiet)\r
+> +            quiet=t; shift ;;\r
+> +    --with-dashes)\r
+> +            with_dashes=t; shift ;;\r
+> +    --no-color)\r
+> +            color=; shift ;;\r
+> +    --no-python)\r
+> +            # noop now...\r
+> +            shift ;;\r
+> +    --va|--val|--valg|--valgr|--valgri|--valgrin|--valgrind)\r
+> +            valgrind=t; verbose=t; shift ;;\r
+> +    --tee)\r
+> +            shift ;; # was handled already\r
+> +    --root=*)\r
+> +            root=$(expr "z$1" : 'z[^=]*=\(.*\)')\r
+> +            shift ;;\r
+> +    *)\r
+> +            echo "error: unknown test option '$1'" >&2; exit 1 ;;\r
+> +    esac\r
+> +done\r
+> +\r
+> +if test -n "$debug"; then\r
+> +    print_subtest () {\r
+> +    printf " %-4s" "[$((test_count - 1))]"\r
+> +    }\r
+> +else\r
+> +    print_subtest () {\r
+> +    true\r
+> +    }\r
+> +fi\r
+> +\r
+> +if test -n "$color"; then\r
+> +    say_color () {\r
+> +            (\r
+> +            TERM=$ORIGINAL_TERM\r
+> +            export TERM\r
+> +            case "$1" in\r
+> +                    error) tput bold; tput setaf 1;; # bold red\r
+> +                    skip)  tput bold; tput setaf 2;; # bold green\r
+> +                    pass)  tput setaf 2;;            # green\r
+> +                    info)  tput setaf 3;;            # brown\r
+> +                    *) test -n "$quiet" && return;;\r
+> +            esac\r
+> +            shift\r
+> +            printf " "\r
+> +            printf "$@"\r
+> +            tput sgr0\r
+> +            print_subtest\r
+> +            )\r
+> +    }\r
+> +else\r
+> +    say_color() {\r
+> +            test -z "$1" && test -n "$quiet" && return\r
+> +            shift\r
+> +            printf " "\r
+> +            printf "$@"\r
+> +            print_subtest\r
+> +    }\r
+> +fi\r
+> +\r
+> +error () {\r
+> +    say_color error "error: $*\n"\r
+> +    GIT_EXIT_OK=t\r
+> +    exit 1\r
+> +}\r
+> +\r
+> +say () {\r
+> +    say_color info "$*"\r
+> +}\r
+> +\r
+> +test "${test_description}" != "" ||\r
+> +error "Test script did not set test_description."\r
+> +\r
+> +if test "$help" = "t"\r
+> +then\r
+> +    echo "Tests ${test_description}"\r
+> +    exit 0\r
+> +fi\r
+> +\r
+> +echo $(basename "$0"): "Testing ${test_description}"\r
+> +\r
+> +exec 5>&1\r
+> +\r
+> +test_failure=0\r
+> +test_count=0\r
+> +test_fixed=0\r
+> +test_broken=0\r
+> +test_success=0\r
+> +\r
+> +die () {\r
+> +    code=$?\r
+> +    rm -rf "$TEST_TMPDIR"\r
+> +    if test -n "$GIT_EXIT_OK"\r
+> +    then\r
+> +            exit $code\r
+> +    else\r
+> +            echo >&5 "FATAL: Unexpected exit with code $code"\r
+> +            exit 1\r
+> +    fi\r
+> +}\r
+> +\r
+> +GIT_EXIT_OK=\r
+> +# Note: TEST_TMPDIR *NOT* exported!\r
+> +TEST_TMPDIR=$(mktemp -d "${TMPDIR:-/tmp}/notmuch-test-$$.XXXXXX")\r
+> +trap 'die' EXIT\r
+> +\r
+> +test_decode_color () {\r
+> +    sed     -e 's/.\[1m/<WHITE>/g' \\r
+> +            -e 's/.\[31m/<RED>/g' \\r
+> +            -e 's/.\[32m/<GREEN>/g' \\r
+> +            -e 's/.\[33m/<YELLOW>/g' \\r
+> +            -e 's/.\[34m/<BLUE>/g' \\r
+> +            -e 's/.\[35m/<MAGENTA>/g' \\r
+> +            -e 's/.\[36m/<CYAN>/g' \\r
+> +            -e 's/.\[m/<RESET>/g'\r
+> +}\r
+> +\r
+> +q_to_nul () {\r
+> +    perl -pe 'y/Q/\000/'\r
+> +}\r
+> +\r
+> +q_to_cr () {\r
+> +    tr Q '\015'\r
+> +}\r
+> +\r
+> +append_cr () {\r
+> +    sed -e 's/$/Q/' | tr Q '\015'\r
+> +}\r
+> +\r
+> +remove_cr () {\r
+> +    tr '\015' Q | sed -e 's/Q$//'\r
+> +}\r
+> +\r
+> +# Generate a new message in the mail directory, with a unique message\r
+> +# ID and subject. The message is not added to the index.\r
+> +#\r
+> +# After this function returns, the filename of the generated message\r
+> +# is available as $gen_msg_filename and the message ID is available as\r
+> +# $gen_msg_id .\r
+> +#\r
+> +# This function supports named parameters with the bash syntax for\r
+> +# assigning a value to an associative array ([name]=value). The\r
+> +# supported parameters are:\r
+> +#\r
+> +#  [dir]=directory/of/choice\r
+> +#\r
+> +#   Generate the message in directory 'directory/of/choice' within\r
+> +#   the mail store. The directory will be created if necessary.\r
+> +#\r
+> +#  [filename]=name\r
+> +#\r
+> +#   Store the message in file 'name'. The default is to store it\r
+> +#   in 'msg-<count>', where <count> is three-digit number of the\r
+> +#   message.\r
+> +#\r
+> +#  [body]=text\r
+> +#\r
+> +#   Text to use as the body of the email message\r
+> +#\r
+> +#  '[from]="Some User <user@example.com>"'\r
+> +#  '[to]="Some User <user@example.com>"'\r
+> +#  '[subject]="Subject of email message"'\r
+> +#  '[date]="RFC 822 Date"'\r
+> +#\r
+> +#   Values for email headers. If not provided, default values will\r
+> +#   be generated instead.\r
+> +#\r
+> +#  '[cc]="Some User <user@example.com>"'\r
+> +#  [reply-to]=some-address\r
+> +#  [in-reply-to]=<message-id>\r
+> +#  [references]=<message-id>\r
+> +#  [content-type]=content-type-specification\r
+> +#  '[header]=full header line, including keyword'\r
+> +#\r
+> +#   Additional values for email headers. If these are not provided\r
+> +#   then the relevant headers will simply not appear in the\r
+> +#   message.\r
+> +#\r
+> +#  '[id]=message-id'\r
+> +#\r
+> +#   Controls the message-id of the created message.\r
+> +gen_msg_cnt=0\r
+> +gen_msg_filename=""\r
+> +gen_msg_id=""\r
+> +generate_message ()\r
+> +{\r
+> +    # This is our (bash-specific) magic for doing named parameters\r
+> +    local -A template="($@)"\r
+> +    local additional_headers\r
+> +\r
+> +    gen_msg_cnt=$((gen_msg_cnt + 1))\r
+> +    if [ -z "${template[filename]}" ]; then\r
+> +    gen_msg_name="msg-$(printf "%03d" $gen_msg_cnt)"\r
+> +    else\r
+> +    gen_msg_name=${template[filename]}\r
+> +    fi\r
+> +\r
+> +    if [ -z "${template[id]}" ]; then\r
+> +    gen_msg_id="${gen_msg_name%:2,*}@notmuch-test-suite"\r
+> +    else\r
+> +    gen_msg_id="${template[id]}"\r
+> +    fi\r
+> +\r
+> +    if [ -z "${template[dir]}" ]; then\r
+> +    gen_msg_filename="${MAIL_DIR}/$gen_msg_name"\r
+> +    else\r
+> +    gen_msg_filename="${MAIL_DIR}/${template[dir]}/$gen_msg_name"\r
+> +    mkdir -p "$(dirname "$gen_msg_filename")"\r
+> +    fi\r
+> +\r
+> +    if [ -z "${template[body]}" ]; then\r
+> +    template[body]="This is just a test message (#${gen_msg_cnt})"\r
+> +    fi\r
+> +\r
+> +    if [ -z "${template[from]}" ]; then\r
+> +    template[from]="Notmuch Test Suite <test_suite@notmuchmail.org>"\r
+> +    fi\r
+> +\r
+> +    if [ -z "${template[to]}" ]; then\r
+> +    template[to]="Notmuch Test Suite <test_suite@notmuchmail.org>"\r
+> +    fi\r
+> +\r
+> +    if [ -z "${template[subject]}" ]; then\r
+> +    template[subject]="Test message #${gen_msg_cnt}"\r
+> +    fi\r
+> +\r
+> +    if [ -z "${template[date]}" ]; then\r
+> +    template[date]="Fri, 05 Jan 2001 15:43:57 +0000"\r
+> +    fi\r
+> +\r
+> +    additional_headers=""\r
+> +    if [ ! -z "${template[header]}" ]; then\r
+> +    additional_headers="${template[header]}\r
+> +${additional_headers}"\r
+> +    fi\r
+> +\r
+> +    if [ ! -z "${template[reply-to]}" ]; then\r
+> +    additional_headers="Reply-To: ${template[reply-to]}\r
+> +${additional_headers}"\r
+> +    fi\r
+> +\r
+> +    if [ ! -z "${template[in-reply-to]}" ]; then\r
+> +    additional_headers="In-Reply-To: ${template[in-reply-to]}\r
+> +${additional_headers}"\r
+> +    fi\r
+> +\r
+> +    if [ ! -z "${template[cc]}" ]; then\r
+> +    additional_headers="Cc: ${template[cc]}\r
+> +${additional_headers}"\r
+> +    fi\r
+> +\r
+> +    if [ ! -z "${template[references]}" ]; then\r
+> +    additional_headers="References: ${template[references]}\r
+> +${additional_headers}"\r
+> +    fi\r
+> +\r
+> +    if [ ! -z "${template[content-type]}" ]; then\r
+> +    additional_headers="Content-Type: ${template[content-type]}\r
+> +${additional_headers}"\r
+> +    fi\r
+> +\r
+> +    # Note that in the way we're setting it above and using it below,\r
+> +    # `additional_headers' will also serve as the header / body separator\r
+> +    # (empty line in between).\r
+> +\r
+> +    cat <<EOF >"$gen_msg_filename"\r
+> +From: ${template[from]}\r
+> +To: ${template[to]}\r
+> +Message-Id: <${gen_msg_id}>\r
+> +Subject: ${template[subject]}\r
+> +Date: ${template[date]}\r
+> +${additional_headers}\r
+> +${template[body]}\r
+> +EOF\r
+> +}\r
+> +\r
+> +# Generate a new message and add it to the database.\r
+> +#\r
+> +# All of the arguments and return values supported by generate_message\r
+> +# are also supported here, so see that function for details.\r
+> +add_message ()\r
+> +{\r
+> +    generate_message "$@" &&\r
+> +    notmuch new > /dev/null\r
+> +}\r
+> +\r
+> +# Deliver a message with emacs and add it to the database\r
+> +#\r
+> +# Uses emacs to generate and deliver a message to the mail store.\r
+> +# Accepts arbitrary extra emacs/elisp functions to modify the message\r
+> +# before sending, which is useful to doing things like attaching files\r
+> +# to the message and encrypting/signing.\r
+> +emacs_deliver_message ()\r
+> +{\r
+> +    local subject="$1"\r
+> +    local body="$2"\r
+> +    shift 2\r
+> +    # before we can send a message, we have to prepare the FCC maildir\r
+> +    mkdir -p "$MAIL_DIR"/sent/{cur,new,tmp}\r
+> +    $TEST_DIRECTORY/smtp-dummy sent_message &\r
+> +    smtp_dummy_pid=$!\r
+> +    test_emacs \\r
+> +    "(let ((message-send-mail-function 'message-smtpmail-send-it)\r
+> +           (smtpmail-smtp-server \"localhost\")\r
+> +           (smtpmail-smtp-service \"25025\"))\r
+> +       (notmuch-hello)\r
+> +       (notmuch-mua-mail)\r
+> +       (message-goto-to)\r
+> +       (insert \"test_suite@notmuchmail.org\nDate: 01 Jan 2000 12:00:00 -0000\")\r
+> +       (message-goto-subject)\r
+> +       (insert \"${subject}\")\r
+> +       (message-goto-body)\r
+> +       (insert \"${body}\")\r
+> +       $@\r
+> +       (message-send-and-exit))"\r
+> +    # opportunistically quit smtp-dummy in case above fails.\r
+> +    { echo QUIT > /dev/tcp/localhost/25025; } 2>/dev/null\r
+> +    wait ${smtp_dummy_pid}\r
+> +    notmuch new >/dev/null\r
+> +}\r
+> +\r
+> +# Generate a corpus of email and add it to the database.\r
+> +#\r
+> +# This corpus is fixed, (it happens to be 50 messages from early in\r
+> +# the history of the notmuch mailing list), which allows for reliably\r
+> +# testing commands that need to operate on a not-totally-trivial\r
+> +# number of messages.\r
+> +add_email_corpus ()\r
+> +{\r
+> +    rm -rf ${MAIL_DIR}\r
+> +    if [ -d $TEST_DIRECTORY/corpus.mail ]; then\r
+> +    cp -a $TEST_DIRECTORY/corpus.mail ${MAIL_DIR}\r
+> +    else\r
+> +    cp -a $TEST_DIRECTORY/corpus ${MAIL_DIR}\r
+> +    notmuch new >/dev/null\r
+> +    cp -a ${MAIL_DIR} $TEST_DIRECTORY/corpus.mail\r
+> +    fi\r
+> +}\r
+> +\r
+> +test_begin_subtest ()\r
+> +{\r
+> +    if [ -n "$inside_subtest" ]; then\r
+> +    exec 1>&6 2>&7          # Restore stdout and stderr\r
+> +    error "bug in test script: Missing test_expect_equal in ${BASH_SOURCE[1]}:${BASH_LINENO[0]}"\r
+> +    fi\r
+> +    test_subtest_name="$1"\r
+> +    test_reset_state_\r
+> +    # Remember stdout and stderr file descriptors and redirect test\r
+> +    # output to the previously prepared file descriptors 3 and 4 (see\r
+> +    # below)\r
+> +    if test "$verbose" != "t"; then exec 4>test.output 3>&4; fi\r
+> +    exec 6>&1 7>&2 >&3 2>&4\r
+> +    inside_subtest=t\r
+> +}\r
+> +\r
+> +# Pass test if two arguments match\r
+> +#\r
+> +# Note: Unlike all other test_expect_* functions, this function does\r
+> +# not accept a test name. Instead, the caller should call\r
+> +# test_begin_subtest before calling this function in order to set the\r
+> +# name.\r
+> +test_expect_equal ()\r
+> +{\r
+> +    exec 1>&6 2>&7          # Restore stdout and stderr\r
+> +    inside_subtest=\r
+> +    test "$#" = 3 && { prereq=$1; shift; } || prereq=\r
+> +    test "$#" = 2 ||\r
+> +    error "bug in the test script: not 2 or 3 parameters to test_expect_equal"\r
+> +\r
+> +    output="$1"\r
+> +    expected="$2"\r
+> +    if ! test_skip "$test_subtest_name"\r
+> +    then\r
+> +            if [ "$output" = "$expected" ]; then\r
+> +                    test_ok_ "$test_subtest_name"\r
+> +            else\r
+> +                    testname=$this_test.$test_count\r
+> +                    echo "$expected" > $testname.expected\r
+> +                    echo "$output" > $testname.output\r
+> +                    test_failure_ "$test_subtest_name" "$(diff -u $testname.expected $testname.output)"\r
+> +            fi\r
+> +    fi\r
+> +}\r
+> +\r
+> +# Like test_expect_equal, but takes two filenames.\r
+> +test_expect_equal_file ()\r
+> +{\r
+> +    exec 1>&6 2>&7          # Restore stdout and stderr\r
+> +    inside_subtest=\r
+> +    test "$#" = 3 && { prereq=$1; shift; } || prereq=\r
+> +    test "$#" = 2 ||\r
+> +    error "bug in the test script: not 2 or 3 parameters to test_expect_equal"\r
+> +\r
+> +    output="$1"\r
+> +    expected="$2"\r
+> +    if ! test_skip "$test_subtest_name"\r
+> +    then\r
+> +            if diff -q "$expected" "$output" >/dev/null ; then\r
+> +                    test_ok_ "$test_subtest_name"\r
+> +            else\r
+> +                    testname=$this_test.$test_count\r
+> +                    cp "$output" $testname.output\r
+> +                    cp "$expected" $testname.expected\r
+> +                    test_failure_ "$test_subtest_name" "$(diff -u $testname.expected $testname.output)"\r
+> +            fi\r
+> +    fi\r
+> +}\r
+> +\r
+> +test_emacs_expect_t () {\r
+> +    test "$#" = 2 && { prereq=$1; shift; } || prereq=\r
+> +    test "$#" = 1 ||\r
+> +    error "bug in the test script: not 1 or 2 parameters to test_emacs_expect_t"\r
+> +\r
+> +    # Run the test.\r
+> +    if ! test_skip "$test_subtest_name"\r
+> +    then\r
+> +            test_emacs "(notmuch-test-run $1)" >/dev/null\r
+> +\r
+> +            # Restore state after the test.\r
+> +            exec 1>&6 2>&7          # Restore stdout and stderr\r
+> +            inside_subtest=\r
+> +\r
+> +            # Report success/failure.\r
+> +            result=$(cat OUTPUT)\r
+> +            if [ "$result" = t ]\r
+> +            then\r
+> +                    test_ok_ "$test_subtest_name"\r
+> +            else\r
+> +                    test_failure_ "$test_subtest_name" "${result}"\r
+> +            fi\r
+> +    else\r
+> +            # Restore state after the (non) test.\r
+> +            exec 1>&6 2>&7          # Restore stdout and stderr\r
+> +            inside_subtest=\r
+> +    fi\r
+> +}\r
+> +\r
+> +NOTMUCH_NEW ()\r
+> +{\r
+> +    notmuch new | grep -v -E -e '^Processed [0-9]*( total)? file|Found [0-9]* total file'\r
+> +}\r
+> +\r
+> +notmuch_search_sanitize ()\r
+> +{\r
+> +    sed -r -e 's/("?thread"?: ?)("?)................("?)/\1\2XXX\3/'\r
+> +}\r
+> +\r
+> +NOTMUCH_SHOW_FILENAME_SQUELCH='s,filename:.*/mail,filename:/XXX/mail,'\r
+> +notmuch_show_sanitize ()\r
+> +{\r
+> +    sed -e "$NOTMUCH_SHOW_FILENAME_SQUELCH"\r
+> +}\r
+> +notmuch_show_sanitize_all ()\r
+> +{\r
+> +    sed \\r
+> +    -e 's| filename:.*| filename:XXXXX|' \\r
+> +    -e 's| id:[^ ]* | id:XXXXX |'\r
+> +}\r
+> +\r
+> +notmuch_json_show_sanitize ()\r
+> +{\r
+> +    sed -e 's|, |,\n |g' | \\r
+> +    sed \\r
+> +    -e 's|"id": "[^"]*",|"id": "XXXXX",|' \\r
+> +    -e 's|"filename": "[^"]*",|"filename": "YYYYY",|'\r
+> +}\r
+> +\r
+> +# End of notmuch helper functions\r
+> +\r
+> +# Use test_set_prereq to tell that a particular prerequisite is available.\r
+> +# The prerequisite can later be checked for in two ways:\r
+> +#\r
+> +# - Explicitly using test_have_prereq.\r
+> +#\r
+> +# - Implicitly by specifying the prerequisite tag in the calls to\r
+> +#   test_expect_{success,failure,code}.\r
+> +#\r
+> +# The single parameter is the prerequisite tag (a simple word, in all\r
+> +# capital letters by convention).\r
+> +\r
+> +test_set_prereq () {\r
+> +    satisfied="$satisfied$1 "\r
+> +}\r
+> +satisfied=" "\r
+> +\r
+> +test_have_prereq () {\r
+> +    case $satisfied in\r
+> +    *" $1 "*)\r
+> +            : yes, have it ;;\r
+> +    *)\r
+> +            ! : nope ;;\r
+> +    esac\r
+> +}\r
+> +\r
+> +# declare prerequisite for the given external binary\r
+> +test_declare_external_prereq () {\r
+> +    binary="$1"\r
+> +    test "$#" = 2 && name=$2 || name="$binary(1)"\r
+> +\r
+> +    hash $binary 2>/dev/null || eval "\r
+> +    test_missing_external_prereq_${binary}_=t\r
+> +$binary () {\r
+> +    echo -n \"\$test_subtest_missing_external_prereqs_ \" | grep -qe \" $name \" ||\r
+> +    test_subtest_missing_external_prereqs_=\"\$test_subtest_missing_external_prereqs_ $name\"\r
+> +    false\r
+> +}"\r
+> +}\r
+> +\r
+> +# Explicitly require external prerequisite.  Useful when binary is\r
+> +# called indirectly (e.g. from emacs).\r
+> +# Returns success if dependency is available, failure otherwise.\r
+> +test_require_external_prereq () {\r
+> +    binary="$1"\r
+> +    if [ "$(eval echo -n \$test_missing_external_prereq_${binary}_)" = t ]; then\r
+> +            # dependency is missing, call the replacement function to note it\r
+> +            eval "$binary"\r
+> +    else\r
+> +            true\r
+> +    fi\r
+> +}\r
+> +\r
+> +# You are not expected to call test_ok_ and test_failure_ directly, use\r
+> +# the text_expect_* functions instead.\r
+> +\r
+> +test_ok_ () {\r
+> +    if test "$test_subtest_known_broken_" = "t"; then\r
+> +            test_known_broken_ok_ "$@"\r
+> +            return\r
+> +    fi\r
+> +    test_success=$(($test_success + 1))\r
+> +    say_color pass "%-6s" "PASS"\r
+> +    echo " $@"\r
+> +}\r
+> +\r
+> +test_failure_ () {\r
+> +    if test "$test_subtest_known_broken_" = "t"; then\r
+> +            test_known_broken_failure_ "$@"\r
+> +            return\r
+> +    fi\r
+> +    test_failure=$(($test_failure + 1))\r
+> +    test_failure_message_ "FAIL" "$@"\r
+> +    test "$immediate" = "" || { GIT_EXIT_OK=t; exit 1; }\r
+> +    return 1\r
+> +}\r
+> +\r
+> +test_failure_message_ () {\r
+> +    say_color error "%-6s" "$1"\r
+> +    echo " $2"\r
+> +    shift 2\r
+> +    echo "$@" | sed -e 's/^/        /'\r
+> +    if test "$verbose" != "t"; then cat test.output; fi\r
+> +}\r
+> +\r
+> +test_known_broken_ok_ () {\r
+> +    test_reset_state_\r
+> +    test_fixed=$(($test_fixed+1))\r
+> +    say_color pass "%-6s" "FIXED"\r
+> +    echo " $@"\r
+> +}\r
+> +\r
+> +test_known_broken_failure_ () {\r
+> +    test_reset_state_\r
+> +    test_broken=$(($test_broken+1))\r
+> +    test_failure_message_ "BROKEN" "$@"\r
+> +    return 1\r
+> +}\r
+> +\r
+> +test_debug () {\r
+> +    test "$debug" = "" || eval "$1"\r
+> +}\r
+> +\r
+> +test_run_ () {\r
+> +    test_cleanup=:\r
+> +    if test "$verbose" != "t"; then exec 4>test.output 3>&4; fi\r
+> +    eval >&3 2>&4 "$1"\r
+> +    eval_ret=$?\r
+> +    eval >&3 2>&4 "$test_cleanup"\r
+> +    return 0\r
+> +}\r
+> +\r
+> +test_skip () {\r
+> +    test_count=$(($test_count+1))\r
+> +    to_skip=\r
+> +    for skp in $NOTMUCH_SKIP_TESTS\r
+> +    do\r
+> +            case $this_test.$test_count in\r
+> +            $skp)\r
+> +                    to_skip=t\r
+> +            esac\r
+> +    done\r
+> +    if test -z "$to_skip" && test -n "$prereq" &&\r
+> +       ! test_have_prereq "$prereq"\r
+> +    then\r
+> +            to_skip=t\r
+> +    fi\r
+> +    case "$to_skip" in\r
+> +    t)\r
+> +            test_report_skip_ "$@"\r
+> +            ;;\r
+> +    *)\r
+> +            test_check_missing_external_prereqs_ "$@"\r
+> +            ;;\r
+> +    esac\r
+> +}\r
+> +\r
+> +test_check_missing_external_prereqs_ () {\r
+> +    if test -n "$test_subtest_missing_external_prereqs_"; then\r
+> +            say_color skip >&3 "missing prerequisites:"\r
+> +            echo "$test_subtest_missing_external_prereqs_" >&3\r
+> +            test_report_skip_ "$@"\r
+> +    else\r
+> +            false\r
+> +    fi\r
+> +}\r
+> +\r
+> +test_report_skip_ () {\r
+> +    test_reset_state_\r
+> +    say_color skip >&3 "skipping test:"\r
+> +    echo " $@" >&3\r
+> +    say_color skip "%-6s" "SKIP"\r
+> +    echo " $1"\r
+> +}\r
+> +\r
+> +test_subtest_known_broken () {\r
+> +    test_subtest_known_broken_=t\r
+> +}\r
+> +\r
+> +test_expect_success () {\r
+> +    test "$#" = 3 && { prereq=$1; shift; } || prereq=\r
+> +    test "$#" = 2 ||\r
+> +    error "bug in the test script: not 2 or 3 parameters to test-expect-success"\r
+> +    test_reset_state_\r
+> +    if ! test_skip "$@"\r
+> +    then\r
+> +            test_run_ "$2"\r
+> +            run_ret="$?"\r
+> +            # test_run_ may update missing external prerequisites\r
+> +            test_check_missing_external_prereqs_ "$@" ||\r
+> +            if [ "$run_ret" = 0 -a "$eval_ret" = 0 ]\r
+> +            then\r
+> +                    test_ok_ "$1"\r
+> +            else\r
+> +                    test_failure_ "$@"\r
+> +            fi\r
+> +    fi\r
+> +}\r
+> +\r
+> +test_expect_code () {\r
+> +    test "$#" = 4 && { prereq=$1; shift; } || prereq=\r
+> +    test "$#" = 3 ||\r
+> +    error "bug in the test script: not 3 or 4 parameters to test-expect-code"\r
+> +    test_reset_state_\r
+> +    if ! test_skip "$@"\r
+> +    then\r
+> +            test_run_ "$3"\r
+> +            run_ret="$?"\r
+> +            # test_run_ may update missing external prerequisites,\r
+> +            test_check_missing_external_prereqs_ "$@" ||\r
+> +            if [ "$run_ret" = 0 -a "$eval_ret" = "$1" ]\r
+> +            then\r
+> +                    test_ok_ "$2"\r
+> +            else\r
+> +                    test_failure_ "$@"\r
+> +            fi\r
+> +    fi\r
+> +}\r
+> +\r
+> +# test_external runs external test scripts that provide continuous\r
+> +# test output about their progress, and succeeds/fails on\r
+> +# zero/non-zero exit code.  It outputs the test output on stdout even\r
+> +# in non-verbose mode, and announces the external script with "* run\r
+> +# <n>: ..." before running it.  When providing relative paths, keep in\r
+> +# mind that all scripts run in "trash directory".\r
+> +# Usage: test_external description command arguments...\r
+> +# Example: test_external 'Perl API' perl ../path/to/test.pl\r
+> +test_external () {\r
+> +    test "$#" = 4 && { prereq=$1; shift; } || prereq=\r
+> +    test "$#" = 3 ||\r
+> +    error >&5 "bug in the test script: not 3 or 4 parameters to test_external"\r
+> +    descr="$1"\r
+> +    shift\r
+> +    test_reset_state_\r
+> +    if ! test_skip "$descr" "$@"\r
+> +    then\r
+> +            # Announce the script to reduce confusion about the\r
+> +            # test output that follows.\r
+> +            say_color "" " run $test_count: $descr ($*)"\r
+> +            # Run command; redirect its stderr to &4 as in\r
+> +            # test_run_, but keep its stdout on our stdout even in\r
+> +            # non-verbose mode.\r
+> +            "$@" 2>&4\r
+> +            if [ "$?" = 0 ]\r
+> +            then\r
+> +                    test_ok_ "$descr"\r
+> +            else\r
+> +                    test_failure_ "$descr" "$@"\r
+> +            fi\r
+> +    fi\r
+> +}\r
+> +\r
+> +# Like test_external, but in addition tests that the command generated\r
+> +# no output on stderr.\r
+> +test_external_without_stderr () {\r
+> +    # The temporary file has no (and must have no) security\r
+> +    # implications.\r
+> +    tmp="$TMPDIR"; if [ -z "$tmp" ]; then tmp=/tmp; fi\r
+> +    stderr="$tmp/git-external-stderr.$$.tmp"\r
+> +    test_external "$@" 4> "$stderr"\r
+> +    [ -f "$stderr" ] || error "Internal error: $stderr disappeared."\r
+> +    descr="no stderr: $1"\r
+> +    shift\r
+> +    if [ ! -s "$stderr" ]; then\r
+> +            rm "$stderr"\r
+> +            test_ok_ "$descr"\r
+> +    else\r
+> +            if [ "$verbose" = t ]; then\r
+> +                    output=`echo; echo Stderr is:; cat "$stderr"`\r
+> +            else\r
+> +                    output=\r
+> +            fi\r
+> +            # rm first in case test_failure exits.\r
+> +            rm "$stderr"\r
+> +            test_failure_ "$descr" "$@" "$output"\r
+> +    fi\r
+> +}\r
+> +\r
+> +# This is not among top-level (test_expect_success)\r
+> +# but is a prefix that can be used in the test script, like:\r
+> +#\r
+> +#   test_expect_success 'complain and die' '\r
+> +#           do something &&\r
+> +#           do something else &&\r
+> +#       test_must_fail git checkout ../outerspace\r
+> +#   '\r
+> +#\r
+> +# Writing this as "! git checkout ../outerspace" is wrong, because\r
+> +# the failure could be due to a segv.  We want a controlled failure.\r
+> +\r
+> +test_must_fail () {\r
+> +    "$@"\r
+> +    test $? -gt 0 -a $? -le 129 -o $? -gt 192\r
+> +}\r
+> +\r
+> +# test_cmp is a helper function to compare actual and expected output.\r
+> +# You can use it like:\r
+> +#\r
+> +#   test_expect_success 'foo works' '\r
+> +#           echo expected >expected &&\r
+> +#           foo >actual &&\r
+> +#           test_cmp expected actual\r
+> +#   '\r
+> +#\r
+> +# This could be written as either "cmp" or "diff -u", but:\r
+> +# - cmp's output is not nearly as easy to read as diff -u\r
+> +# - not all diff versions understand "-u"\r
+> +\r
+> +test_cmp() {\r
+> +    $GIT_TEST_CMP "$@"\r
+> +}\r
+> +\r
+> +# This function can be used to schedule some commands to be run\r
+> +# unconditionally at the end of the test to restore sanity:\r
+> +#\r
+> +#   test_expect_success 'test core.capslock' '\r
+> +#           git config core.capslock true &&\r
+> +#           test_when_finished "git config --unset core.capslock" &&\r
+> +#           hello world\r
+> +#   '\r
+> +#\r
+> +# That would be roughly equivalent to\r
+> +#\r
+> +#   test_expect_success 'test core.capslock' '\r
+> +#           git config core.capslock true &&\r
+> +#           hello world\r
+> +#           git config --unset core.capslock\r
+> +#   '\r
+> +#\r
+> +# except that the greeting and config --unset must both succeed for\r
+> +# the test to pass.\r
+> +\r
+> +test_when_finished () {\r
+> +    test_cleanup="{ $*\r
+> +            } && (exit \"\$eval_ret\"); eval_ret=\$?; $test_cleanup"\r
+> +}\r
+> +\r
+> +test_done () {\r
+> +    GIT_EXIT_OK=t\r
+> +    test_results_dir="$TEST_DIRECTORY/test-results"\r
+> +    mkdir -p "$test_results_dir"\r
+> +    test_results_path="$test_results_dir/${0%.sh}-$$"\r
+> +\r
+> +    echo "total $test_count" >> $test_results_path\r
+> +    echo "success $test_success" >> $test_results_path\r
+> +    echo "fixed $test_fixed" >> $test_results_path\r
+> +    echo "broken $test_broken" >> $test_results_path\r
+> +    echo "failed $test_failure" >> $test_results_path\r
+> +    echo "" >> $test_results_path\r
+> +\r
+> +    echo\r
+> +\r
+> +    [ -n "$EMACS_SERVER" ] && test_emacs '(kill-emacs)'\r
+> +\r
+> +    if [ "$test_failure" = "0" ]; then\r
+> +        if [ "$test_broken" = "0" ]; then\r
+> +            rm -rf "$remove_tmp"\r
+> +        fi\r
+> +        exit 0\r
+> +    else\r
+> +        exit 1\r
+> +    fi\r
+> +}\r
+> +\r
+> +emacs_generate_script () {\r
+> +    # Construct a little test script here for the benefit of the user,\r
+> +    # (who can easily run "run_emacs" to get the same emacs environment\r
+> +    # for investigating any failures).\r
+> +    cat <<EOF >"$TMP_DIRECTORY/run_emacs"\r
+> +#!/bin/sh\r
+> +export PATH=$PATH\r
+> +export NOTMUCH_CONFIG=$NOTMUCH_CONFIG\r
+> +\r
+> +# Here's what we are using here:\r
+> +#\r
+> +# --no-init-file    Don't load users ~/.emacs\r
+> +#\r
+> +# --no-site-file    Don't load the site-wide startup stuff\r
+> +#\r
+> +# --directory               Ensure that the local elisp sources are found\r
+> +#\r
+> +# --load            Force loading of notmuch.el and test-lib.el\r
+> +\r
+> +exec ${TEST_EMACS} --no-init-file --no-site-file \\r
+> +    --directory "$TEST_DIRECTORY/../emacs" --load notmuch.el \\r
+> +    --directory "$TEST_DIRECTORY" --load test-lib.el \\r
+> +    "\$@"\r
+> +EOF\r
+> +    chmod a+x "$TMP_DIRECTORY/run_emacs"\r
+> +}\r
+> +\r
+> +test_emacs () {\r
+> +    # test dependencies beforehand to avoid the waiting loop below\r
+> +    missing_dependencies=\r
+> +    test_require_external_prereq dtach || missing_dependencies=1\r
+> +    test_require_external_prereq emacs || missing_dependencies=1\r
+> +    test_require_external_prereq emacsclient || missing_dependencies=1\r
+> +    test -z "$missing_dependencies" || return\r
+> +\r
+> +    if [ -z "$EMACS_SERVER" ]; then\r
+> +            server_name="notmuch-test-suite-$$"\r
+> +            # start a detached session with an emacs server\r
+> +            # user's TERM is given to dtach which assumes a minimally\r
+> +            # VT100-compatible terminal -- and emacs inherits that\r
+> +            TERM=$ORIGINAL_TERM dtach -n "$TEST_TMPDIR/emacs-dtach-socket.$$" \\r
+> +                    sh -c "stty rows 24 cols 80; exec '$TMP_DIRECTORY/run_emacs' \\r
+> +                            --no-window-system \\r
+> +                            --eval '(setq server-name \"$server_name\")' \\r
+> +                            --eval '(server-start)' \\r
+> +                            --eval '(orphan-watchdog $$)'" || return\r
+> +            EMACS_SERVER="$server_name"\r
+> +            # wait until the emacs server is up\r
+> +            until test_emacs '()' >/dev/null 2>/dev/null; do\r
+> +                    sleep 1\r
+> +            done\r
+> +    fi\r
+> +\r
+> +    emacsclient --socket-name="$EMACS_SERVER" --eval "(progn $@)"\r
+> +}\r
+> +\r
+> +test_python() {\r
+> +    export LD_LIBRARY_PATH=$TEST_DIRECTORY/../lib\r
+> +    export PYTHONPATH=$TEST_DIRECTORY/../bindings/python\r
+> +\r
+> +    # Some distros (e.g. Arch Linux) ship Python 2.* as /usr/bin/python2,\r
+> +    # most others as /usr/bin/python. So first try python2, and fallback to\r
+> +    # python if python2 doesn't exist.\r
+> +    cmd=python2\r
+> +    [[ "$test_missing_external_prereq_python2_" = t ]] && cmd=python\r
+> +\r
+> +    (echo "import sys; _orig_stdout=sys.stdout; sys.stdout=open('OUTPUT', 'w')"; cat) \\r
+> +            | $cmd -\r
+> +}\r
+> +\r
+> +# Creates a script that counts how much time it is executed and calls\r
+> +# notmuch.  $notmuch_counter_command is set to the path to the\r
+> +# generated script.  Use notmuch_counter_value() function to get the\r
+> +# current counter value.\r
+> +notmuch_counter_reset () {\r
+> +    notmuch_counter_command="$TMP_DIRECTORY/notmuch_counter"\r
+> +    if [ ! -x "$notmuch_counter_command" ]; then\r
+> +            notmuch_counter_state_path="$TMP_DIRECTORY/notmuch_counter.state"\r
+> +            cat >"$notmuch_counter_command" <<EOF || return\r
+> +#!/bin/sh\r
+> +\r
+> +read count < "$notmuch_counter_state_path"\r
+> +echo \$((count + 1)) > "$notmuch_counter_state_path"\r
+> +\r
+> +exec notmuch "\$@"\r
+> +EOF\r
+> +            chmod +x "$notmuch_counter_command" || return\r
+> +    fi\r
+> +\r
+> +    echo 0 > "$notmuch_counter_state_path"\r
+> +}\r
+> +\r
+> +# Returns the current notmuch counter value.\r
+> +notmuch_counter_value () {\r
+> +    if [ -r "$notmuch_counter_state_path" ]; then\r
+> +            read count < "$notmuch_counter_state_path"\r
+> +    else\r
+> +            count=0\r
+> +    fi\r
+> +    echo $count\r
+> +}\r
+> +\r
+> +test_reset_state_ () {\r
+> +    test -z "$test_init_done_" && test_init_\r
+> +\r
+> +    test_subtest_known_broken_=\r
+> +    test_subtest_missing_external_prereqs_=\r
+> +}\r
+> +\r
+> +# called once before the first subtest\r
+> +test_init_ () {\r
+> +    test_init_done_=t\r
+> +\r
+> +    # skip all tests if there were external prerequisites missing during init\r
+> +    test_check_missing_external_prereqs_ "all tests in $this_test" && test_done\r
+> +}\r
+> +\r
+> +\r
+> +find_notmuch_path ()\r
+> +{\r
+> +    dir="$1"\r
+> +\r
+> +    while [ -n "$dir" ]; do\r
+> +    bin="$dir/notmuch"\r
+> +    if [ -x "$bin" ]; then\r
+> +        echo "$dir"\r
+> +        return\r
+> +    fi\r
+> +    dir="$(dirname "$dir")"\r
+> +    if [ "$dir" = "/" ]; then\r
+> +        break\r
+> +    fi\r
+> +    done\r
+> +}\r
+> +\r
+> +# Test the binaries we have just built.  The tests are kept in\r
+> +# test/ subdirectory and are run in 'trash directory' subdirectory.\r
+> +TEST_DIRECTORY=$(pwd)\r
+> +if test -n "$valgrind"\r
+> +then\r
+> +    make_symlink () {\r
+> +            test -h "$2" &&\r
+> +            test "$1" = "$(readlink "$2")" || {\r
+> +                    # be super paranoid\r
+> +                    if mkdir "$2".lock\r
+> +                    then\r
+> +                            rm -f "$2" &&\r
+> +                            ln -s "$1" "$2" &&\r
+> +                            rm -r "$2".lock\r
+> +                    else\r
+> +                            while test -d "$2".lock\r
+> +                            do\r
+> +                                    say "Waiting for lock on $2."\r
+> +                                    sleep 1\r
+> +                            done\r
+> +                    fi\r
+> +            }\r
+> +    }\r
+> +\r
+> +    make_valgrind_symlink () {\r
+> +            # handle only executables\r
+> +            test -x "$1" || return\r
+> +\r
+> +            base=$(basename "$1")\r
+> +            symlink_target=$TEST_DIRECTORY/../$base\r
+> +            # do not override scripts\r
+> +            if test -x "$symlink_target" &&\r
+> +                test ! -d "$symlink_target" &&\r
+> +                test "#!" != "$(head -c 2 < "$symlink_target")"\r
+> +            then\r
+> +                    symlink_target=$TEST_DIRECTORY/valgrind.sh\r
+> +            fi\r
+> +            case "$base" in\r
+> +            *.sh|*.perl)\r
+> +                    symlink_target=$TEST_DIRECTORY/unprocessed-script\r
+> +            esac\r
+> +            # create the link, or replace it if it is out of date\r
+> +            make_symlink "$symlink_target" "$GIT_VALGRIND/bin/$base" || exit\r
+> +    }\r
+> +\r
+> +    # override notmuch executable in TEST_DIRECTORY/..\r
+> +    GIT_VALGRIND=$TEST_DIRECTORY/valgrind\r
+> +    mkdir -p "$GIT_VALGRIND"/bin\r
+> +    make_valgrind_symlink $TEST_DIRECTORY/../notmuch\r
+> +    OLDIFS=$IFS\r
+> +    IFS=:\r
+> +    for path in $PATH\r
+> +    do\r
+> +            ls "$path"/notmuch 2> /dev/null |\r
+> +            while read file\r
+> +            do\r
+> +                    make_valgrind_symlink "$file"\r
+> +            done\r
+> +    done\r
+> +    IFS=$OLDIFS\r
+> +    PATH=$GIT_VALGRIND/bin:$PATH\r
+> +    GIT_EXEC_PATH=$GIT_VALGRIND/bin\r
+> +    export GIT_VALGRIND\r
+> +else # normal case\r
+> +    notmuch_path=`find_notmuch_path "$TEST_DIRECTORY"`\r
+> +    test -n "$notmuch_path" && PATH="$notmuch_path:$PATH"\r
+> +fi\r
+> +export PATH\r
+> +\r
+> +# Test repository\r
+> +test="tmp.$(basename "$0" .sh)"\r
+> +test -n "$root" && test="$root/$test"\r
+> +case "$test" in\r
+> +/*) TMP_DIRECTORY="$test" ;;\r
+> + *) TMP_DIRECTORY="$TEST_DIRECTORY/$test" ;;\r
+> +esac\r
+> +test ! -z "$debug" || remove_tmp=$TMP_DIRECTORY\r
+> +rm -fr "$test" || {\r
+> +    GIT_EXIT_OK=t\r
+> +    echo >&5 "FATAL: Cannot prepare test area"\r
+> +    exit 1\r
+> +}\r
+> +\r
+> +# A temporary home directory is needed by at least:\r
+> +# - emacs/"Sending a message via (fake) SMTP"\r
+> +# - emacs/"Reply within emacs"\r
+> +# - crypto/emacs_deliver_message\r
+> +export HOME="${TMP_DIRECTORY}/home"\r
+> +mkdir -p "${HOME}"\r
+> +\r
+> +MAIL_DIR="${TMP_DIRECTORY}/mail"\r
+> +export GNUPGHOME="${TMP_DIRECTORY}/gnupg"\r
+> +export NOTMUCH_CONFIG="${TMP_DIRECTORY}/notmuch-config"\r
+> +\r
+> +mkdir -p "${test}"\r
+> +mkdir -p "${MAIL_DIR}"\r
+> +\r
+> +cat <<EOF >"${NOTMUCH_CONFIG}"\r
+> +[database]\r
+> +path=${MAIL_DIR}\r
+> +\r
+> +[user]\r
+> +name=Notmuch Test Suite\r
+> +primary_email=test_suite@notmuchmail.org\r
+> +other_email=test_suite_other@notmuchmail.org;test_suite@otherdomain.org\r
+> +EOF\r
+> +\r
+> +emacs_generate_script\r
+> +\r
+> +\r
+> +# Use -P to resolve symlinks in our working directory so that the cwd\r
+> +# in subprocesses like git equals our $PWD (for pathname comparisons).\r
+> +cd -P "$test" || error "Cannot setup test environment"\r
+> +\r
+> +if test "$verbose" = "t"\r
+> +then\r
+> +    exec 4>&2 3>&1\r
+> +else\r
+> +    exec 4>test.output 3>&4\r
+> +fi\r
+> +\r
+> +this_test=${0##*/}\r
+> +for skp in $NOTMUCH_SKIP_TESTS\r
+> +do\r
+> +    to_skip=\r
+> +    for skp in $NOTMUCH_SKIP_TESTS\r
+> +    do\r
+> +            case "$this_test" in\r
+> +            $skp)\r
+> +                    to_skip=t\r
+> +            esac\r
+> +    done\r
+> +    case "$to_skip" in\r
+> +    t)\r
+> +            say_color skip >&3 "skipping test $this_test altogether"\r
+> +            say_color skip "skip all tests in $this_test"\r
+> +            test_done\r
+> +    esac\r
+> +done\r
+> +\r
+> +# Provide an implementation of the 'yes' utility\r
+> +yes () {\r
+> +    if test $# = 0\r
+> +    then\r
+> +            y=y\r
+> +    else\r
+> +            y="$*"\r
+> +    fi\r
+> +\r
+> +    while echo "$y"\r
+> +    do\r
+> +            :\r
+> +    done\r
+> +}\r
+> +\r
+> +# Fix some commands on Windows\r
+> +case $(uname -s) in\r
+> +*MINGW*)\r
+> +    # Windows has its own (incompatible) sort and find\r
+> +    sort () {\r
+> +            /usr/bin/sort "$@"\r
+> +    }\r
+> +    find () {\r
+> +            /usr/bin/find "$@"\r
+> +    }\r
+> +    sum () {\r
+> +            md5sum "$@"\r
+> +    }\r
+> +    # git sees Windows-style pwd\r
+> +    pwd () {\r
+> +            builtin pwd -W\r
+> +    }\r
+> +    # no POSIX permissions\r
+> +    # backslashes in pathspec are converted to '/'\r
+> +    # exec does not inherit the PID\r
+> +    ;;\r
+> +*)\r
+> +    test_set_prereq POSIXPERM\r
+> +    test_set_prereq BSLASHPSPEC\r
+> +    test_set_prereq EXECKEEPSPID\r
+> +    ;;\r
+> +esac\r
+> +\r
+> +test -z "$NO_PERL" && test_set_prereq PERL\r
+> +test -z "$NO_PYTHON" && test_set_prereq PYTHON\r
+> +\r
+> +# test whether the filesystem supports symbolic links\r
+> +ln -s x y 2>/dev/null && test -h y 2>/dev/null && test_set_prereq SYMLINKS\r
+> +rm -f y\r
+> +\r
+> +# declare prerequisites for external binaries used in tests\r
+> +test_declare_external_prereq dtach\r
+> +test_declare_external_prereq emacs\r
+> +test_declare_external_prereq emacsclient\r
+> +test_declare_external_prereq gdb\r
+> +test_declare_external_prereq gpg\r
+> +test_declare_external_prereq python\r
+> +test_declare_external_prereq python2\r