+# Uses emacs to generate and deliver a message to the mail store.
+# Accepts arbitrary extra emacs/elisp functions to modify the message
+# before sending, which is useful to doing things like attaching files
+# to the message and encrypting/signing.
+emacs_deliver_message ()
+{
+ local subject="$1"
+ local body="$2"
+ shift 2
+ # before we can send a message, we have to prepare the FCC maildir
+ mkdir -p "$MAIL_DIR"/sent/{cur,new,tmp}
+ # eval'ing smtp-dummy --background will set smtp_dummy_pid
+ smtp_dummy_pid=
+ eval `$TEST_DIRECTORY/smtp-dummy --background sent_message`
+ test -n "$smtp_dummy_pid" || return 1
+
+ test_emacs \
+ "(let ((message-send-mail-function 'message-smtpmail-send-it)
+ (mail-host-address \"example.com\")
+ (smtpmail-smtp-server \"localhost\")
+ (smtpmail-smtp-service \"25025\"))
+ (notmuch-mua-mail)
+ (message-goto-to)
+ (insert \"test_suite@notmuchmail.org\nDate: 01 Jan 2000 12:00:00 -0000\")
+ (message-goto-subject)
+ (insert \"${subject}\")
+ (message-goto-body)
+ (insert \"${body}\")
+ $@
+ (message-send-and-exit))"
+
+ # In case message was sent properly, client waits for confirmation
+ # before exiting and resuming control here; therefore making sure
+ # that server exits by sending (KILL) signal to it is safe.
+ kill -9 $smtp_dummy_pid
+ notmuch new >/dev/null
+}
+
+# Pretend to deliver a message with emacs. Really save it to a file
+# and add it to the database
+#
+# Uses emacs to generate and deliver a message to the mail store.
+# Accepts arbitrary extra emacs/elisp functions to modify the message
+# before sending, which is useful to doing things like attaching files
+# to the message and encrypting/signing.
+emacs_fcc_message ()
+{
+ local subject="$1"
+ local body="$2"
+ shift 2
+ # before we can send a message, we have to prepare the FCC maildir
+ mkdir -p "$MAIL_DIR"/sent/{cur,new,tmp}
+
+ test_emacs \
+ "(let ((message-send-mail-function (lambda () t))
+ (mail-host-address \"example.com\"))
+ (notmuch-mua-mail)
+ (message-goto-to)
+ (insert \"test_suite@notmuchmail.org\nDate: 01 Jan 2000 12:00:00 -0000\")
+ (message-goto-subject)
+ (insert \"${subject}\")
+ (message-goto-body)
+ (insert \"${body}\")
+ $@
+ (message-send-and-exit))" || return 1
+ notmuch new >/dev/null
+}
+
+# Generate a corpus of email and add it to the database.
+#
+# This corpus is fixed, (it happens to be 50 messages from early in
+# the history of the notmuch mailing list), which allows for reliably
+# testing commands that need to operate on a not-totally-trivial
+# number of messages.
+add_email_corpus ()
+{
+ rm -rf ${MAIL_DIR}
+ if [ -d $TEST_DIRECTORY/corpus.mail ]; then
+ cp -a $TEST_DIRECTORY/corpus.mail ${MAIL_DIR}
+ else
+ cp -a $TEST_DIRECTORY/corpus ${MAIL_DIR}
+ notmuch new >/dev/null
+ cp -a ${MAIL_DIR} $TEST_DIRECTORY/corpus.mail
+ fi
+}
+
+test_begin_subtest ()
+{
+ if [ -n "$inside_subtest" ]; then
+ exec 1>&6 2>&7 # Restore stdout and stderr
+ error "bug in test script: Missing test_expect_equal in ${BASH_SOURCE[1]}:${BASH_LINENO[0]}"
+ fi
+ test_subtest_name="$1"
+ test_reset_state_
+ # Remember stdout and stderr file descriptors and redirect test
+ # output to the previously prepared file descriptors 3 and 4 (see
+ # below)
+ if test "$verbose" != "t"; then exec 4>test.output 3>&4; fi
+ exec 6>&1 7>&2 >&3 2>&4
+ inside_subtest=t
+}
+
+# Pass test if two arguments match
+#
+# Note: Unlike all other test_expect_* functions, this function does
+# not accept a test name. Instead, the caller should call
+# test_begin_subtest before calling this function in order to set the
+# name.
+test_expect_equal ()
+{
+ exec 1>&6 2>&7 # Restore stdout and stderr
+ inside_subtest=
+ test "$#" = 3 && { prereq=$1; shift; } || prereq=
+ test "$#" = 2 ||
+ error "bug in the test script: not 2 or 3 parameters to test_expect_equal"
+
+ output="$1"
+ expected="$2"
+ if ! test_skip "$test_subtest_name"
+ then
+ if [ "$output" = "$expected" ]; then
+ test_ok_
+ else
+ testname=$this_test.$test_count
+ echo "$expected" > $testname.expected
+ echo "$output" > $testname.output
+ test_failure_ "$(diff -u $testname.expected $testname.output)"
+ fi
+ fi
+}
+
+# Like test_expect_equal, but takes two filenames.
+test_expect_equal_file ()
+{
+ exec 1>&6 2>&7 # Restore stdout and stderr
+ inside_subtest=
+ test "$#" = 3 && { prereq=$1; shift; } || prereq=
+ test "$#" = 2 ||
+ error "bug in the test script: not 2 or 3 parameters to test_expect_equal"
+
+ file1="$1"
+ basename1=`basename "$file1"`
+ file2="$2"
+ basename2=`basename "$file2"`
+ if ! test_skip "$test_subtest_name"
+ then
+ if diff -q "$file1" "$file2" >/dev/null ; then
+ test_ok_
+ else
+ testname=$this_test.$test_count
+ cp "$file1" "$testname.$basename1"
+ cp "$file2" "$testname.$basename2"
+ test_failure_ "$(diff -u "$testname.$basename1" "$testname.$basename2")"
+ fi
+ fi
+}
+
+# Like test_expect_equal, but arguments are JSON expressions to be
+# canonicalized before diff'ing. If an argument cannot be parsed, it
+# is used unchanged so that there's something to diff against.
+test_expect_equal_json () {
+ # The test suite forces LC_ALL=C, but this causes Python 3 to
+ # decode stdin as ASCII. We need to read JSON in UTF-8, so
+ # override Python's stdio encoding defaults.
+ output=$(echo "$1" | PYTHONIOENCODING=utf-8 python -mjson.tool \
+ || echo "$1")
+ expected=$(echo "$2" | PYTHONIOENCODING=utf-8 python -mjson.tool \
+ || echo "$2")
+ shift 2
+ test_expect_equal "$output" "$expected" "$@"
+}