; emacs local configuration settings for notmuch source
; surmised by dkg on 2010-11-23 13:43:18-0500
+; amended by amdragon on 2011-06-06
-((c-mode . ((indent-tabs-mode . t)
- (tab-width . 8)
- (c-basic-offset . 4)
- (c-file-style . "linux"))))
+((c-mode
+ (indent-tabs-mode . t)
+ (tab-width . 8)
+ (c-basic-offset . 4)
+ (c-file-style . "linux"))
+ (c++-mode
+ (indent-tabs-mode . t)
+ (tab-width . 8)
+ (c-basic-offset . 4)
+ (c-file-style . "linux"))
+ (emacs-lisp-mode
+ (indent-tabs-mode . t)
+ (tab-width . 8))
+ (shell-mode
+ (indent-tabs-mode . t)
+ (tab-width . 8)
+ (sh-basic-offset . 4)
+ (sh-indentation . 4))
+ )
*cscope*
.deps
notmuch
+notmuch.sym
notmuch-shared
notmuch.1.gz
libnotmuch.so*
"notmuch search --format=json" results.
Fix '*' to work by simply calling '+' or '-' on a region consisting of
-the entire buffer.
+the entire buffer, (this would avoid one race condition---while still
+leaving other race conditions---but could also potentially make '*' a
+very expensive operation).
Add a global keybinding table for notmuch, and then view-specific
tables that add to it.
Add support for a delete keybinding that adds a "deleted" tag to the
current message/thread and make searches not return deleted messages
-by default, (unless the user asks explicitly for deleted messags in
+by default, (unless the user asks explicitly for deleted messages in
the search query).
Add keybindings for next/previous thread.
indexing.
Replace the "notmuch part --part=id" command with "notmuch show
---part=id", (David Edmonson wants to rewrite some of "notmuch show" to
+--part=id", (David Edmondson wants to rewrite some of "notmuch show" to
provide more MIME-structure information in its output first).
Replace the "notmuch search-tags" command with "notmuch search
search" syntax could be added to allow the user to find these files,
(and perhaps delete them or move them away as appropriate).
+Fix filesystem/notmuch-new race condition by not updating database
+mtime for a directory if it is the same as the current mtime.
+
Test suite
----------
Achieve 100% test coverage with the test suite.
# Raise a NotmuchError if not initialized
self._verify_initialized_db()
- return notmuch_database_needs_upgrade(self._db)
+ return nmlib.notmuch_database_needs_upgrade(self._db)
def upgrade(self):
"""Upgrades the current database
-notmuch/comapt
+notmuch/compat
This directory consists of two things:
-# See Makfefile.local for the list of files to be compiled in this
+# See Makefile.local for the list of files to be compiled in this
# directory.
all:
$(MAKE) -C .. all
fi
# Set several defaults (optionally specified by the user in
-# environemnt variables)
+# environment variables)
CC=${CC:-gcc}
CXX=${CXX:-g++}
CFLAGS=${CFLAGS:--O2}
# The directory to which man pages should be installed
mandir = ${MANDIR:=\$(prefix)/share/man}
-# The directory to which read-only (configuration) filesshould be installed
+# The directory to which read-only (configuration) files should be installed
sysconfdir = ${SYSCONFDIR:=\$(prefix)/etc}
# The directory to which emacs lisp files should be installed
-# See Makfefile.local for the list of files to be compiled in this
+# See Makefile.local for the list of files to be compiled in this
# directory.
all:
$(MAKE) -C .. all
emacs_bytecode = $(emacs_sources:.el=.elc)
-%.elc: %.el
+%.elc: %.el $(global_deps)
$(call quiet,EMACS) --directory emacs -batch -f batch-byte-compile $<
ifeq ($(WITH_EMACS),1)
(let ((found-target-pos nil)
(final-target-pos nil))
(let* ((saved-alist
- ;; Filter out empty saved seaches if required.
+ ;; Filter out empty saved searches if required.
(if notmuch-show-empty-saved-searches
notmuch-saved-searches
(loop for elem in notmuch-saved-searches
(notmuch-config-get "user.primary_email"))
(defun notmuch-user-other-email ()
- "Return the user.primary_email value (as a list) from the notmuch configuration."
+ "Return the user.other_email value (as a list) from the notmuch configuration."
(split-string (notmuch-config-get "user.other_email") "\n"))
(defun notmuch-kill-this-buffer ()
(make-directory (concat path "/new/") t)
(make-directory (concat path "/tmp/") t))
((file-regular-p path)
- (error "%s is a file. Can't creat maildir." path))
+ (error "%s is a file. Can't create maildir." path))
(t
(error "I don't know how to create a maildir here"))))
"Use external viewers to view all attachments from the current message."
(interactive)
(with-current-notmuch-show-message
- ; We ovverride the mm-inline-media-tests to indicate which message
+ ; We override the mm-inline-media-tests to indicate which message
; parts are already sufficiently handled by the original
; presentation of the message in notmuch-show mode. These parts
; will be inserted directly into the temporary buffer of
messages from the thread matching this search term are shown if
non-nil.
-The optional BUFFER-NAME provides the neame of the buffer in
+The optional BUFFER-NAME provides the name of the buffer in
which the message thread is shown. If it is nil (which occurs
when the command is called interactively) the argument to the
function is used. "
without removing any tags, and '\\[notmuch-show-archive-thread]' to archive an entire thread
without scrolling through with \\[notmuch-show-advance-and-archive]).
-You can add or remove arbitary tags from the current message with
+You can add or remove arbitrary tags from the current message with
'\\[notmuch-show-add-tag]' or '\\[notmuch-show-remove-tag]'.
All currently available key bindings:
(format label-format lines-count)))
(defun notmuch-wash-region-to-button (msg beg end type prefix)
- "Auxilary function to do the actual making of overlays and buttons
+ "Auxiliary function to do the actual making of overlays and buttons
BEG and END are buffer locations. TYPE should a string, either
\"citation\" or \"signature\". PREFIX is some arbitrary text to
("authors" . "%-20s ")
("subject" . "%s ")
("tags" . "(%s)"))
- "Search result formating. Supported fields are:
+ "Search result formatting. Supported fields are:
date, count, authors, subject, tags
For example:
(setq notmuch-search-result-format \(\(\"authors\" . \"%-40s\"\)
:group 'notmuch)
(defcustom notmuch-after-tag-hook nil
- "Hooks that are run before tags of a message are modified.
+ "Hooks that are run after tags of a message are modified.
'tags' will contain the tags that were added or removed as
a list of strings of the form \"+TAG\" or \"-TAG\".
(defun notmuch-search-operate-all (action)
"Add/remove tags from all matching messages.
-Tis command adds or removes tags from all messages matching the
+This command adds or removes tags from all messages matching the
current search terms. When called interactively, this command
will prompt for tags to be added or removed. Tags prefixed with
'+' will be added and tags prefixed with '-' will be removed.
* @parent_object: parent #GMimeFilter
* @saw_nl: previous char was a \n
* @line: temporary buffer for line unfolding
- * @line_size: size of currently allocated nemory for @line
+ * @line_size: size of currently allocated memory for @line
* @lineptr: pointer to the first unused character in @line
*
* A filter to decode rfc2047 encoded headers
-# See Makfefile.local for the list of files to be compiled in this
+# See Makefile.local for the list of files to be compiled in this
# directory.
all:
$(MAKE) -C .. all
$(call quiet,AR) rcs $@ $^
$(dir)/$(LIBNAME): $(libnotmuch_modules) notmuch.sym
- echo $(libnotmuch_modules)
$(call quiet,CXX $(CXXFLAGS)) $(libnotmuch_modules) $(FINAL_LIBNOTMUCH_LDFLAGS) $(LIBRARY_LINK_FLAG) -o $@
notmuch.sym: lib/notmuch.h
printf "{\nglobal:\n" > notmuch.sym
- sed -n 's/^\s*\(notmuch_[a-z_]*\)\s*(.*/\t\1;/p' $< >> notmuch.sym
+ sed -n 's/^[[:space:]]*\(notmuch_[a-z_]*\)[[:space:]]*(.*/'"`printf "\t"`"'\1;/p' $< >> notmuch.sym
printf "local: *;\n};\n" >> notmuch.sym
$(dir)/$(SONAME): $(dir)/$(LIBNAME)
install: install-$(dir)
-# The (often-reused) $dir works fine within targets/pre-requisites,
+# The (often-reused) $dir works fine within targets/prerequisites,
# but cannot be used reliably within commands, so copy its value to a
# variable that is not reused.
lib := $(dir)
$(LIBRARY_INSTALL_POST_COMMAND)
SRCS := $(SRCS) $(libnotmuch_c_srcs) $(libnotmuch_cxx_srcs)
-CLEAN := $(CLEAN) $(libnotmuch_modules) $(dir)/$(SONAME) $(dir)/$(LINKER_NAME) $(dir)$(LIBNAME) libnotmuch.a notmuch.sym
+CLEAN += $(libnotmuch_modules) $(dir)/$(SONAME) $(dir)/$(LINKER_NAME)
+CLEAN += $(dir)/$(LIBNAME) $(dir)/libnotmuch.a notmuch.sym
+CLEAN += $(dir)/notmuch.h.gch
*
* Multiple terms of given prefix:
*
- * reference: All message IDs from In-Reply-To and Re ferences
+ * reference: All message IDs from In-Reply-To and References
* headers in the message.
*
* tag: Any tags associated with this message by the user.
* ASCII integer. The initial database version
* was 1, (though a schema existed before that
* were no "version" database value existed at
- * all). Succesive versions are allocated as
+ * all). Successive versions are allocated as
* changes are made to the database (such as by
* indexing new fields).
*
* incremented for each thread ID.
*
* thread_id_* A pre-allocated thread ID for a particular
- * message. This is actually an arbitarily large
+ * message. This is actually an arbitrarily large
* family of metadata name. Any particular name is
* formed by concatenating "thread_id_" with a message
* ID (or the SHA1 sum of a message ID if it is very
}
/* Parse an RFC 822 message-id, discarding whitespace, any RFC 822
- * comments, and the '<' and '>' delimeters.
+ * comments, and the '<' and '>' delimiters.
*
* If not NULL, then *next will be made to point to the first character
* not parsed, (possibly pointing to the final '\0' terminator.
/* Given a legal 'path' for the database, return the relative path.
*
- * The return value will be a pointer to the originl path contents,
+ * The return value will be a pointer to the original path contents,
* and will be either the original string (if 'path' was relative) or
* a portion of the string (if path was absolute and begins with the
* database path).
* In all cases, we assign to the current message the first thread_id
* found (through either parent or child). We will also merge any
* existing, distinct threads where this message belongs to both,
- * (which is not uncommon when mesages are processed out of order).
+ * (which is not uncommon when messages are processed out of order).
*
* Finally, if no thread ID has been found through parent or child, we
* call _notmuch_message_generate_thread_id to generate a new thread
if((ctx->count[0] += len) < len)
++(ctx->count[1]);
- while(len >= space) /* tranfer whole blocks if possible */
+ while(len >= space) /* transfer whole blocks if possible */
{
memcpy(((unsigned char*)ctx->wbuf) + pos, sp, space);
sp += space; len -= space; space = SHA1_BLOCK_SIZE; pos = 0;
{
#endif
#if 0
-} /* Appleasing Emacs */
+} /* Appeasing Emacs */
#endif
#include <stdint.h>
/* Parse 'text' and add a term to 'message' for each parsed word. Each
* term will be added both prefixed (if prefix_name is not NULL) and
- * also unprefixed). */
+ * also non-prefixed). */
notmuch_private_status_t
_notmuch_message_gen_terms (notmuch_message_t *message,
const char *prefix_name,
/* Get a string representation of a notmuch_status_t value.
*
- * The result is readonly.
+ * The result is read-only.
*/
const char *
notmuch_status_to_string (notmuch_status_t status);
*
* It's not strictly necessary to call this function. All memory from
* the notmuch_threads_t object will be reclaimed when the
- * containg query object is destroyed.
+ * containing query object is destroyed.
*/
void
notmuch_threads_destroy (notmuch_threads_t *threads);
"\tsynchronize_flags Valid values are true and false.\n"
"\n"
"\tIf true, then the following maildir flags (in message filenames)\n"
- "\twill be syncrhonized with the corresponding notmuch tags:\n"
+ "\twill be synchronized with the corresponding notmuch tags:\n"
"\n"
"\t\tFlag Tag\n"
"\t\t---- -------\n"
* information is lost from the database).
*
* o Tell the database to update its time of 'path' to 'fs_mtime'
+ * if fs_mtime isn't the current wall-clock time.
*/
static notmuch_status_t
add_files_recursive (notmuch_database_t *notmuch,
notmuch_directory_t *directory;
notmuch_filenames_t *db_files = NULL;
notmuch_filenames_t *db_subdirs = NULL;
+ time_t stat_time;
struct stat st;
notmuch_bool_t is_maildir, new_directory;
const char **tag;
path, strerror (errno));
return NOTMUCH_STATUS_FILE_ERROR;
}
+ stat_time = time (NULL);
/* This is not an error since we may have recursed based on a
* symlink to a regular file, not a directory, and we don't know
new_directory = db_mtime ? FALSE : TRUE;
+ /* XXX This is a temporary workaround. If we don't update the
+ * database mtime until after processing messages in this
+ * directory, then a 0 mtime is *not* sufficient to indicate that
+ * this directory has no messages or subdirs in the database (for
+ * example, if an earlier run skipped the mtime update because
+ * fs_mtime == stat_time, or was interrupted before updating the
+ * mtime at the end). To address this, we record a (bogus)
+ * non-zero value before processing any child messages so that a
+ * later run won't mistake this for a new directory (and, for
+ * example, fail to detect removed files and subdirs).
+ *
+ * A better solution would be for notmuch_database_get_directory
+ * to indicate if it really created a new directory or not, either
+ * by a new out-argument, or by recording this information and
+ * providing an accessor.
+ */
+ if (new_directory)
+ notmuch_directory_set_mtime (directory, -1);
+
/* If the database knows about this directory, then we sort based
* on strcmp to match the database sorting. Otherwise, we can do
* inode-based sorting for faster filesystem operation. */
/* If we're looking at a symlink, we only want to add it if it
* links to a regular file, (and not to a directory, say).
*
- * Similarly, if the file is of unknown type (due to filesytem
+ * Similarly, if the file is of unknown type (due to filesystem
* limitations), then we also need to look closer.
*
* In either case, a stat does the trick.
notmuch_filenames_move_to_next (db_subdirs);
}
- if (! interrupted) {
+ /* If the directory's mtime is the same as the wall-clock time
+ * when we stat'ed the directory, we skip updating the mtime in
+ * the database because a message could be delivered later in this
+ * same second. This may lead to unnecessary re-scans, but it
+ * avoids overlooking messages. */
+ if (! interrupted && fs_mtime != stat_time) {
status = notmuch_directory_set_mtime (directory, fs_mtime);
if (status && ret == NOTMUCH_STATUS_SUCCESS)
ret = status;
* The munging is easy to detect, because it results in a
* redundant reply-to header, (with an address that already exists
* in either To or Cc). So in this case, we ignore the Reply-To
- * field and use the From header. Thie ensures the original sender
+ * field and use the From header. This ensures the original sender
* will get the reply even if not subscribed to the list. Note
* that the address in the Reply-To header will always appear in
* the reply.
* them indications to which email address this message was
* delivered.
* The Received: header is special in our get_header function
- * and is always concated.
+ * and is always concatenated.
*/
received = notmuch_message_get_header (message, "received");
if (received == NULL)
static void
format_part_content_text (GMimeObject *part)
{
- GMimeContentDisposition *disposition = g_mime_object_get_content_disposition (part);
+ const char *cid = g_mime_object_get_content_id (part);
GMimeContentType *content_type = g_mime_object_get_content_type (GMIME_OBJECT (part));
- printf (", Content-type: %s\n", g_mime_content_type_to_string (content_type));
-
- if (disposition &&
- strcmp (disposition->disposition, GMIME_DISPOSITION_ATTACHMENT) == 0)
+ if (GMIME_IS_PART (part))
{
const char *filename = g_mime_part_get_filename (GMIME_PART (part));
- printf ("Attachment: %s (%s)\n", filename,
- g_mime_content_type_to_string (content_type));
+ if (filename)
+ printf (", Filename: %s", filename);
}
+ if (cid)
+ printf (", Content-id: %s", cid);
+
+ printf (", Content-type: %s\n", g_mime_content_type_to_string (content_type));
+
if (g_mime_content_type_is_type (content_type, "text", "*") &&
!g_mime_content_type_is_type (content_type, "text", "html"))
{
GMimeStream *stream_memory = g_mime_stream_mem_new ();
const char *cid = g_mime_object_get_content_id (part);
void *ctx = talloc_new (NULL);
- GMimeContentDisposition *disposition = g_mime_object_get_content_disposition (part);
GByteArray *part_content;
printf (", \"content-type\": %s",
if (cid != NULL)
printf(", \"content-id\": %s", json_quote_str (ctx, cid));
- if (disposition &&
- strcmp (disposition->disposition, GMIME_DISPOSITION_ATTACHMENT) == 0)
+ if (GMIME_IS_PART (part))
{
const char *filename = g_mime_part_get_filename (GMIME_PART (part));
-
- printf (", \"filename\": %s", json_quote_str (ctx, filename));
+ if (filename)
+ printf (", \"filename\": %s", json_quote_str (ctx, filename));
}
if (g_mime_content_type_is_type (content_type, "text", "*") &&
The
.B part
-command can used to output a single part of a multi-part MIME message.
+command can used to output a single part of a multipart MIME message.
.RS 4
.TP 4
Finally, results can be restricted to only messages within a
particular time range, (based on the Date: header) with a syntax of:
- <intial-timestamp>..<final-timestamp>
+ <initial-timestamp>..<final-timestamp>
Each timestamp is a number representing the number of seconds since
1970\-01\-01 00:00:00 UTC. This is not the most convenient means of
expressing date ranges, but until notmuch is fixed to accept a more
convenient form, one can use the date program to construct
-timestamps. For example, with the bash shell the folowing syntax would
+timestamps. For example, with the bash shell the following syntax would
specify a date range to return messages from 2009\-10\-01 until the
current time:
notmuch_help_command (void *ctx, int argc, char *argv[]);
static const char search_terms_help[] =
- "\tSeveral notmuch commands accept a comman syntax for search\n"
+ "\tSeveral notmuch commands accept a common syntax for search\n"
"\tterms.\n"
"\n"
"\tThe search terms can consist of free-form text (and quoted\n"
-The debian packaging exists in the top-level "debian" directory within
-this source-code respository.
+The Debian packaging exists in the top-level "debian" directory within
+this source-code repository.
-# See Makfefile.local for the list of files to be compiled in this
+# See Makefile.local for the list of files to be compiled in this
# directory.
all:
$(MAKE) -C .. all
As the names depend on the tests' file names, it is safe to
run the tests with this option in parallel.
+--root=<dir>::
+ This runs the testsuites specified under a seperate directory.
+ However, caution is advised, as not all tests are maintained
+ with this relocation in mind, so some tests may behave
+ differently.
+
+ Pointing this argument at a tmpfs filesystem can improve the
+ speed of the test suite for some users.
+
When invoking the test suite via "make test" any of the above options
can be specified as follows:
will generate a failure and print the difference of the two
strings.
+ test_expect_equal_file <output> <expected>
+
+ Identical to test_exepect_equal, except that <output> and
+ <expected> are files instead of strings. This is a much more
+ robust method to compare formatted textual information, since it
+ also notices whitespace and closing newline differences.
+
test_expect_equal_failure <output> <expected>
This works similar to test_expect_equal (see above) but is used to
mark a test that demonstrates a known breakage, (that is, the
- author of the test expectes "output" and "expected" to differ until
+ author of the test expects "output" and "expected" to differ until
the breakage is fixed). See test_expect_failure for details.
test_debug <script>
generate_message
Generates a message with an optional template. Most tests will
- actually prefere to call add_message. See below.
+ actually prefer to call add_message. See below.
add_message
This function should be called at the beginning of a test file
when a test needs to operate on a non-empty body of messages. It
- will intialize the mail database to a known state of 50 sample
+ will initialize the mail database to a known state of 50 sample
messages, (culled from the early history of the notmuch mailing
list).
# Ensure that all tests are being run
test_begin_subtest 'Ensure that all available tests will be run by notmuch-test'
-eval $(sed -n -e '/^TESTS="$/,/^"$/p' notmuch-test ../notmuch-test)
+eval $(sed -n -e '/^TESTS="$/,/^"$/p' notmuch-test $TEST_DIRECTORY/notmuch-test)
tests_in_suite=$(for i in $TESTS; do echo $i; done | sort)
-available=$(ls -1 ../ | \
+available=$(ls -1 $TEST_DIRECTORY/ | \
sed -r -e "/^(aggregate-results.sh|Makefile|Makefile.local|notmuch-test)/d" \
-e "/^(README|test-lib.sh|test-lib.el|test-results|tmp.*|valgrind|corpus*)/d" \
-e "/^(emacs.expected-output|smtp-dummy|smtp-dummy.c|test-verbose|symbol-test.cc)/d" \
| sort)
test_expect_equal "$tests_in_suite" "$available"
-EXPECTED=../test.expected-output
+EXPECTED=$TEST_DIRECTORY/test.expected-output
suppress_diff_date() {
sed -e 's/\(.*\-\-\- test-verbose\.4\.\expected\).*/\1/' \
-e 's/\(.*\+\+\+ test-verbose\.4\.\output\).*/\1/'
}
test_begin_subtest "Ensure that test output is suppressed unless the test fails"
-output=$(cd ..; ./test-verbose 2>&1 | suppress_diff_date)
+output=$(cd $TEST_DIRECTORY; ./test-verbose 2>&1 | suppress_diff_date)
expected=$(cat $EXPECTED/test-verbose-no | suppress_diff_date)
test_expect_equal "$output" "$expected"
test_begin_subtest "Ensure that -v does not suppress test output"
-output=$(cd ..; ./test-verbose -v 2>&1 | suppress_diff_date)
+output=$(cd $TEST_DIRECTORY; ./test-verbose -v 2>&1 | suppress_diff_date)
expected=$(cat $EXPECTED/test-verbose-yes | suppress_diff_date)
# Do not include the results of test-verbose in totals
rm $TEST_DIRECTORY/test-results/test-verbose-*
--- /dev/null
+From: "Aron Griffis" <agriffis@n01se.net>
+To: notmuch@notmuchmail.org
+Date: Tue, 17 Nov 2009 18:21:38 -0500
+Subject: [notmuch] archive
+Message-ID: <20091117232137.GA7669@griffis1.net>
+
+Just subscribed, I'd like to catch up on the previous postings,
+but the archive link seems to be bogus?
+
+Thanks,
+Aron
+
local output
[ -d ${GNUPGHOME} ] && return
mkdir -m 0700 "$GNUPGHOME"
- gpg --no-tty --import <../gnupg-secret-key.asc >"$GNUPGHOME"/import.log 2>&1
+ gpg --no-tty --import <$TEST_DIRECTORY/gnupg-secret-key.asc >"$GNUPGHOME"/import.log 2>&1
test_debug "cat $GNUPGHOME/import.log"
if (gpg --quick-random --version >/dev/null 2>&1) ; then
echo quick-random >> "$GNUPGHOME"/gpg.conf
\fpart{ ID: 4, Content-type: text/plain
This is a test encrypted message.
\fpart}
-\fattachment{ ID: 5, Content-type: application/octet-stream
-Attachment: TESTATTACHMENT (application/octet-stream)
+\fattachment{ ID: 5, Filename: TESTATTACHMENT, Content-type: application/octet-stream
Non-text part: application/octet-stream
\fattachment}
\fpart}
"$expected"
test_begin_subtest "signature verification with revoked key"
-# generate revokation certificate and load it to revoke key
+# generate revocation certificate and load it to revoke key
echo "y
1
Notmuch Test Suite key revocation (automated) $(date '+%F_%T%z')
#!/usr/bin/env bash
+
+# Note: do not use `setq' for setting variables in Emacs tests because
+# it affects other tests that may run in the same Emacs instance. Use
+# `let' instead so the scope of the changed variables is limited to a
+# single test.
+
test_description="emacs interface"
. test-lib.sh
-EXPECTED=../emacs.expected-output
+EXPECTED=$TEST_DIRECTORY/emacs.expected-output
add_email_corpus
test_begin_subtest "Basic notmuch-hello view in emacs"
-test_emacs '(notmuch-hello) (princ (buffer-string))' >OUTPUT
+test_emacs '(notmuch-hello)
+ (test-output)'
test_expect_equal_file OUTPUT $EXPECTED/notmuch-hello
test_begin_subtest "Saved search with 0 results"
-test_emacs '(setq notmuch-show-empty-saved-searches t) (setq notmuch-saved-searches '\''(("inbox" . "tag:inbox") ("unread" . "tag:unread") ("empty" . "tag:doesnotexist"))) (notmuch-hello) (princ (buffer-string))' >OUTPUT
+test_emacs '(let ((notmuch-show-empty-saved-searches t)
+ (notmuch-saved-searches
+ '\''(("inbox" . "tag:inbox")
+ ("unread" . "tag:unread")
+ ("empty" . "tag:doesnotexist"))))
+ (notmuch-hello)
+ (test-output))'
test_expect_equal_file OUTPUT $EXPECTED/notmuch-hello-with-empty
test_begin_subtest "No saved searches displayed (all with 0 results)"
-test_emacs '(setq notmuch-saved-searches '\''(("empty" . "tag:doesnotexist"))) (notmuch-hello) (princ (buffer-string))' >OUTPUT
+test_emacs '(let ((notmuch-saved-searches
+ '\''(("empty" . "tag:doesnotexist"))))
+ (notmuch-hello)
+ (test-output))'
test_expect_equal_file OUTPUT $EXPECTED/notmuch-hello-no-saved-searches
test_begin_subtest "Basic notmuch-search view in emacs"
-test_emacs '(notmuch-search "tag:inbox") (notmuch-test-wait) (princ (buffer-string))' >OUTPUT
+test_emacs '(notmuch-search "tag:inbox")
+ (notmuch-test-wait)
+ (test-output)'
test_expect_equal_file OUTPUT $EXPECTED/notmuch-search-tag-inbox
test_begin_subtest "Navigation of notmuch-hello to search results"
-test_emacs '(notmuch-hello) (goto-char (point-min)) (re-search-forward "inbox") (widget-button-press (point)) (notmuch-test-wait) (princ (buffer-string))' >OUTPUT
+test_emacs '(notmuch-hello)
+ (goto-char (point-min))
+ (re-search-forward "inbox")
+ (widget-button-press (point))
+ (notmuch-test-wait)
+ (test-output)'
test_expect_equal_file OUTPUT $EXPECTED/notmuch-hello-view-inbox
test_begin_subtest "Basic notmuch-show view in emacs"
maildir_storage_thread=$(notmuch search --output=threads id:20091117190054.GU3165@dottiness.seas.harvard.edu)
-test_emacs "(notmuch-show \"$maildir_storage_thread\") (princ (buffer-string))" >OUTPUT
+test_emacs "(notmuch-show \"$maildir_storage_thread\")
+ (test-output)"
test_expect_equal_file OUTPUT $EXPECTED/notmuch-show-thread-maildir-storage
test_begin_subtest "notmuch-show for message with invalid From"
-add_message "[subject]=\"message-with-invalid-from\"" "[from]=\"\\\"Invalid \\\" From\\\" <test_suite@notmuchmail.org>\""
+add_message "[subject]=\"message-with-invalid-from\"" \
+ "[from]=\"\\\"Invalid \\\" From\\\" <test_suite@notmuchmail.org>\""
thread=$(notmuch search --output=threads subject:message-with-invalid-from)
-output=$(test_emacs "(notmuch-show \"$thread\") (princ (buffer-string))")
-test_expect_equal "$output" \
-'"Invalid " From" <test_suite@notmuchmail.org> (2001-01-05) (inbox)
+test_emacs "(notmuch-show \"$thread\")
+ (test-output)"
+cat <<EOF >EXPECTED
+"Invalid " From" <test_suite@notmuchmail.org> (2001-01-05) (inbox)
Subject: message-with-invalid-from
To: Notmuch Test Suite <test_suite@notmuchmail.org>
Date: Tue, 05 Jan 2001 15:43:57 -0000
-This is just a test message (#1)'
+This is just a test message (#1)
+EOF
+test_expect_equal_file OUTPUT EXPECTED
test_begin_subtest "Navigation of notmuch-search to thread view"
-test_emacs '(notmuch-search "tag:inbox") (notmuch-test-wait) (goto-char (point-min)) (re-search-forward "Working with Maildir") (notmuch-search-show-thread) (notmuch-test-wait) (princ (buffer-string))' >OUTPUT
+test_emacs '(notmuch-search "tag:inbox")
+ (notmuch-test-wait)
+ (goto-char (point-min))
+ (re-search-forward "Working with Maildir")
+ (notmuch-search-show-thread)
+ (notmuch-test-wait)
+ (test-output)'
test_expect_equal_file OUTPUT $EXPECTED/notmuch-show-thread-maildir-storage
test_begin_subtest "Add tag from search view"
os_x_darwin_thread=$(notmuch search --output=threads id:ddd65cda0911171950o4eea4389v86de9525e46052d3@mail.gmail.com)
-test_emacs "(notmuch-search \"$os_x_darwin_thread\") (notmuch-test-wait) (notmuch-search-add-tag \"tag-from-search-view\")"
+test_emacs "(notmuch-search \"$os_x_darwin_thread\")
+ (notmuch-test-wait)
+ (notmuch-search-add-tag \"tag-from-search-view\")"
output=$(notmuch search $os_x_darwin_thread | notmuch_search_sanitize)
test_expect_equal "$output" "thread:XXX 2009-11-18 [4/4] Jjgod Jiang, Alexander Botero-Lowry; [notmuch] Mac OS X/Darwin compatibility issues (inbox tag-from-search-view unread)"
test_begin_subtest "Remove tag from search view"
-test_emacs "(notmuch-search \"$os_x_darwin_thread\") (notmuch-test-wait) (notmuch-search-remove-tag \"tag-from-search-view\")"
+test_emacs "(notmuch-search \"$os_x_darwin_thread\")
+ (notmuch-test-wait)
+ (notmuch-search-remove-tag \"tag-from-search-view\")"
output=$(notmuch search $os_x_darwin_thread | notmuch_search_sanitize)
test_expect_equal "$output" "thread:XXX 2009-11-18 [4/4] Jjgod Jiang, Alexander Botero-Lowry; [notmuch] Mac OS X/Darwin compatibility issues (inbox unread)"
test_begin_subtest "Add tag from notmuch-show view"
-test_emacs "(notmuch-show \"$os_x_darwin_thread\") (notmuch-show-add-tag \"tag-from-show-view\")"
+test_emacs "(notmuch-show \"$os_x_darwin_thread\")
+ (notmuch-show-add-tag \"tag-from-show-view\")"
output=$(notmuch search $os_x_darwin_thread | notmuch_search_sanitize)
test_expect_equal "$output" "thread:XXX 2009-11-18 [4/4] Jjgod Jiang, Alexander Botero-Lowry; [notmuch] Mac OS X/Darwin compatibility issues (inbox tag-from-show-view unread)"
test_begin_subtest "Remove tag from notmuch-show view"
-test_emacs "(notmuch-show \"$os_x_darwin_thread\") (notmuch-show-remove-tag \"tag-from-show-view\")"
+test_emacs "(notmuch-show \"$os_x_darwin_thread\")
+ (notmuch-show-remove-tag \"tag-from-show-view\")"
output=$(notmuch search $os_x_darwin_thread | notmuch_search_sanitize)
test_expect_equal "$output" "thread:XXX 2009-11-18 [4/4] Jjgod Jiang, Alexander Botero-Lowry; [notmuch] Mac OS X/Darwin compatibility issues (inbox unread)"
test_begin_subtest "Message with .. in Message-Id:"
add_message [id]=123..456@example '[subject]="Message with .. in Message-Id"'
-test_emacs '(notmuch-search "id:\"123..456@example\"") (notmuch-test-wait) (notmuch-search-add-tag "search-add") (notmuch-search-add-tag "search-remove") (notmuch-search-remove-tag "search-remove") (notmuch-show "id:\"123..456@example\"") (notmuch-test-wait) (notmuch-show-add-tag "show-add") (notmuch-show-add-tag "show-remove") (notmuch-show-remove-tag "show-remove")'
+test_emacs '(notmuch-search "id:\"123..456@example\"")
+ (notmuch-test-wait)
+ (notmuch-search-add-tag "search-add")
+ (notmuch-search-add-tag "search-remove")
+ (notmuch-search-remove-tag "search-remove")
+ (notmuch-show "id:\"123..456@example\"")
+ (notmuch-test-wait)
+ (notmuch-show-add-tag "show-add")
+ (notmuch-show-add-tag "show-remove")
+ (notmuch-show-remove-tag "show-remove")'
output=$(notmuch search 'id:"123..456@example"' | notmuch_search_sanitize)
test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Message with .. in Message-Id (inbox search-add show-add)"
test_begin_subtest "Sending a message via (fake) SMTP"
-
-# Before we can send a message, we have to prepare the FCC maildir
-mkdir -p mail/sent/cur
-mkdir -p mail/sent/new
-mkdir -p mail/sent/tmp
-
-../smtp-dummy sent_message &
-smtp_dummy_pid=$!
-test_emacs "(setq message-send-mail-function 'message-smtpmail-send-it) (setq smtpmail-smtp-server \"localhost\") (setq smtpmail-smtp-service \"25025\") (notmuch-hello) (notmuch-mua-mail) (message-goto-to) (insert \"user@example.com\nDate: Fri, 29 Mar 1974 10:00:00 -0000\") (message-goto-subject) (insert \"Testing message sent via SMTP\") (message-goto-body) (insert \"This is a test that messages are sent via SMTP\") (message-send-and-exit)" >/dev/null 2>&1
-wait ${smtp_dummy_pid}
-
+emacs_deliver_message \
+ 'Testing message sent via SMTP' \
+ 'This is a test that messages are sent via SMTP' \
+ '(message-goto-to)
+ (kill-whole-line)
+ (insert "To: user@example.com\n")'
sed \
-e s',^User-Agent: Notmuch/.* Emacs/.*,User-Agent: Notmuch/XXX Emacs/XXX,' \
-e s',^Message-ID: <.*>$,Message-ID: <XXX>,' < sent_message >OUTPUT
From: Notmuch Test Suite <test_suite@notmuchmail.org>
To: user@example.com
Subject: Testing message sent via SMTP
-Date: Fri, 29 Mar 1974 10:00:00 -0000
+Date: 01 Jan 2000 12:00:00 -0000
User-Agent: Notmuch/XXX Emacs/XXX
Message-ID: <XXX>
MIME-Version: 1.0
test_begin_subtest "Verify that sent messages are saved/searchable (via FCC)"
notmuch new > /dev/null
output=$(notmuch search 'subject:"testing message sent via SMTP"' | notmuch_search_sanitize)
-test_expect_equal "$output" "thread:XXX 1974-03-29 [1/1] Notmuch Test Suite; Testing message sent via SMTP (inbox)"
+test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; Testing message sent via SMTP (inbox)"
test_begin_subtest "notmuch-fcc-dirs set to nil"
-test_emacs "(setq notmuch-fcc-dirs nil) (notmuch-mua-mail) (princ (buffer-string))" > OUTPUT
+test_emacs "(let ((notmuch-fcc-dirs nil))
+ (notmuch-mua-mail)
+ (test-output))"
cat <<EOF >EXPECTED
From: Notmuch Test Suite <test_suite@notmuchmail.org>
To:
mkdir -p mail/sent-string/tmp
test_begin_subtest "notmuch-fcc-dirs set to a string"
-test_emacs "(setq notmuch-fcc-dirs \"sent-string\") (notmuch-mua-mail) (princ (buffer-string))" > OUTPUT
+test_emacs "(let ((notmuch-fcc-dirs \"sent-string\"))
+ (notmuch-mua-mail)
+ (test-output))"
cat <<EOF >EXPECTED
From: Notmuch Test Suite <test_suite@notmuchmail.org>
To:
mkdir -p mail/failure/tmp
test_begin_subtest "notmuch-fcc-dirs set to a list (with match)"
-test_emacs "(setq notmuch-fcc-dirs '((\"notmuchmail.org\" . \"sent-list-match\") (\".*\" . \"failure\"))) (notmuch-mua-mail) (princ (buffer-string))" > OUTPUT
+test_emacs "(let ((notmuch-fcc-dirs
+ '((\"notmuchmail.org\" . \"sent-list-match\")
+ (\".*\" . \"failure\"))))
+ (notmuch-mua-mail)
+ (test-output))"
cat <<EOF >EXPECTED
From: Notmuch Test Suite <test_suite@notmuchmail.org>
To:
mkdir -p mail/sent-list-catch-all/tmp
test_begin_subtest "notmuch-fcc-dirs set to a list (catch-all)"
-test_emacs "(setq notmuch-fcc-dirs '((\"example.com\" . \"failure\") (\".*\" . \"sent-list-catch-all\"))) (notmuch-mua-mail) (princ (buffer-string))" > OUTPUT
+test_emacs "(let ((notmuch-fcc-dirs
+ '((\"example.com\" . \"failure\")
+ (\".*\" . \"sent-list-catch-all\"))))
+ (notmuch-mua-mail)
+ (test-output))"
cat <<EOF >EXPECTED
From: Notmuch Test Suite <test_suite@notmuchmail.org>
To:
test_expect_equal_file OUTPUT EXPECTED
test_begin_subtest "notmuch-fcc-dirs set to a list (no match)"
-test_emacs "(setq notmuch-fcc-dirs '((\"example.com\" . \"failure\") (\"nomatchhere.net\" . \"failure\"))) (notmuch-mua-mail) (princ (buffer-string))" > OUTPUT
+test_emacs "(let ((notmuch-fcc-dirs
+ '((\"example.com\" . \"failure\")
+ (\"nomatchhere.net\" . \"failure\"))))
+ (notmuch-mua-mail)
+ (test-output))"
cat <<EOF >EXPECTED
From: Notmuch Test Suite <test_suite@notmuchmail.org>
To:
test_expect_equal_file OUTPUT EXPECTED
test_begin_subtest "Reply within emacs"
-# We sed away everything before the ^From in the output to avoid getting
-# confused by messages such as "Parsing /home/cworth/.mailrc... done"
-test_emacs '(notmuch-search "subject:\"testing message sent via SMTP\"") (notmuch-test-wait) (notmuch-search-reply-to-thread) (princ (buffer-string))' | sed -ne '/^From/,$ p' | sed -e 's/^In-Reply-To: <.*>$/In-Reply-To: <XXX>/' >OUTPUT
+test_emacs '(notmuch-search "subject:\"testing message sent via SMTP\"")
+ (notmuch-test-wait)
+ (notmuch-search-reply-to-thread)
+ (test-output)'
+sed -i -e 's/^In-Reply-To: <.*>$/In-Reply-To: <XXX>/' OUTPUT
cat <<EOF >EXPECTED
From: Notmuch Test Suite <test_suite@notmuchmail.org>
To: user@example.com
In-Reply-To: <XXX>
Fcc: $(pwd)/mail/sent
--text follows this line--
-On Fri, 29 Mar 1974 10:00:00 -0000, Notmuch Test Suite <test_suite@notmuchmail.org> wrote:
+On 01 Jan 2000 12:00:00 -0000, Notmuch Test Suite <test_suite@notmuchmail.org> wrote:
> This is a test that messages are sent via SMTP
EOF
test_expect_equal_file OUTPUT EXPECTED
test_begin_subtest "Save attachment from within emacs using notmuch-show-save-attachments"
# save as archive to test that Emacs does not re-compress .gz
-echo ./attachment1.gz | test_emacs '(notmuch-show "id:cf0c4d610911171136h1713aa59w9cf9aa31f052ad0a@mail.gmail.com") (notmuch-show-save-attachments)' > /dev/null 2>&1
-test_expect_equal_file "$EXPECTED/attachment" attachment1.gz
+test_emacs '(let ((standard-input "\"attachment1.gz\""))
+ (notmuch-show "id:cf0c4d610911171136h1713aa59w9cf9aa31f052ad0a@mail.gmail.com")
+ (notmuch-show-save-attachments))' > /dev/null 2>&1
+test_expect_equal_file attachment1.gz "$EXPECTED/attachment"
test_begin_subtest "Save attachment from within emacs using notmuch-show-save-part"
# save as archive to test that Emacs does not re-compress .gz
-echo ./attachment2.gz | test_emacs '(notmuch-show-save-part "id:cf0c4d610911171136h1713aa59w9cf9aa31f052ad0a@mail.gmail.com" 5)' > /dev/null 2>&1
-test_expect_equal_file "$EXPECTED/attachment" attachment2.gz
+test_emacs '(let ((standard-input "\"attachment2.gz\""))
+ (notmuch-show-save-part "id:cf0c4d610911171136h1713aa59w9cf9aa31f052ad0a@mail.gmail.com" 5))' > /dev/null 2>&1
+test_expect_equal_file attachment2.gz "$EXPECTED/attachment"
test_begin_subtest "View raw message within emacs"
-first_line=$(head -n1 $EXPECTED/raw-message-cf0c4d-52ad0a)
-test_emacs '(notmuch-show "id:cf0c4d610911171136h1713aa59w9cf9aa31f052ad0a@mail.gmail.com") (notmuch-show-view-raw-message) (princ (buffer-string))' | sed -ne "/$first_line/,\$ p" >OUTPUT
+test_emacs '(notmuch-show "id:cf0c4d610911171136h1713aa59w9cf9aa31f052ad0a@mail.gmail.com")
+ (notmuch-show-view-raw-message)
+ (test-output)'
test_expect_equal_file OUTPUT $EXPECTED/raw-message-cf0c4d-52ad0a
test_begin_subtest "Hiding/showing signature in notmuch-show view"
(button-activate (button-at (point)))
(search-backward \"Click/Enter to hide.\")
(button-activate (button-at (point)))
- (princ (buffer-string))" >OUTPUT
+ (test-output)"
test_expect_equal_file OUTPUT $EXPECTED/notmuch-show-thread-maildir-storage
test_begin_subtest "Detection and hiding of top-post quoting of message"
A: Top-posting.
Q: What is the most annoying thing in e-mail?"'
test_emacs "(notmuch-show \"top-posting\")
- (princ (visible-buffer-string))" >OUTPUT
+ (test-visible-output)"
echo "Notmuch Test Suite <test_suite@notmuchmail.org> (2001-01-05) (inbox)
Subject: The problem with top-posting
To: Notmuch Test Suite <test_suite@notmuchmail.org>
test_expect_equal_file OUTPUT EXPECTED
test_begin_subtest "Hiding message in notmuch-show view"
-output=$(test_emacs '(notmuch-show "id:f35dbb950911171438k5df6eb56k77b6c0944e2e79ae@mail.gmail.com")
- (notmuch-show-toggle-message)
- (princ (visible-buffer-string))')
-expected=$(cat $EXPECTED/notmuch-show-thread-with-hidden-messages)
-test_expect_equal "$output" "$expected"
+test_emacs '(notmuch-show "id:f35dbb950911171438k5df6eb56k77b6c0944e2e79ae@mail.gmail.com")
+ (notmuch-show-toggle-message)
+ (test-visible-output)'
+test_expect_equal_file OUTPUT $EXPECTED/notmuch-show-thread-with-hidden-messages
test_begin_subtest "Hiding message with visible citation in notmuch-show view"
-output=$(test_emacs '(notmuch-show "id:f35dbb950911171438k5df6eb56k77b6c0944e2e79ae@mail.gmail.com")
- (search-forward "Click/Enter to show.")
- (button-activate (button-at (point)))
- (notmuch-show-toggle-message)
- (princ (visible-buffer-string))')
-expected=$(cat $EXPECTED/notmuch-show-thread-with-hidden-messages)
-test_expect_equal "$output" "$expected"
+test_emacs '(notmuch-show "id:f35dbb950911171438k5df6eb56k77b6c0944e2e79ae@mail.gmail.com")
+ (search-forward "Click/Enter to show.")
+ (button-activate (button-at (point)))
+ (notmuch-show-toggle-message)
+ (test-visible-output)'
+test_expect_equal_file OUTPUT $EXPECTED/notmuch-show-thread-with-hidden-messages
test_done
notmuch new > /dev/null
test_begin_subtest "Ensure that emacs doesn't drop results"
-expected="$(notmuch search '*' | sed -e 's/^thread:[0-9a-f]* //' -e 's/;//' -e 's/xx*/[BLOB]/')
-End of search results."
+notmuch search '*' > EXPEXTED
+sed -i -e 's/^thread:[0-9a-f]* //' -e 's/;//' -e 's/xx*/[BLOB]/' EXPEXTED
+echo 'End of search results.' >> EXPEXTED
-output=$(test_emacs '(notmuch-search "*") (notmuch-test-wait) (princ (buffer-string))' | sed -e s', *, ,g' -e 's/xxx*/[BLOB]/g')
-test_expect_equal "$output" "$expected"
+test_emacs '(notmuch-search "*")
+ (notmuch-test-wait)
+ (test-output)'
+sed -i -e s', *, ,g' -e 's/xxx*/[BLOB]/g' OUTPUT
+test_expect_equal_file OUTPUT EXPEXTED
test_begin_subtest "Ensure that emacs doesn't drop error messages"
-output=$(test_emacs '(notmuch-search "--this-option-does-not-exist") (notmuch-test-wait) (princ (buffer-string))')
-test_expect_equal "$output" "Error: Unexpected output from notmuch search:
+test_emacs '(notmuch-search "--this-option-does-not-exist")
+ (notmuch-test-wait)
+ (test-output)'
+cat <<EOF >EXPEXTED
+Error: Unexpected output from notmuch search:
Unrecognized option: --this-option-does-not-exist
-End of search results. (process returned 1)"
+End of search results. (process returned 1)
+EOF
+test_expect_equal_file OUTPUT EXPEXTED
test_done
output+="
"
mv "${gen_msg_filename}" "${gen_msg_filename}S"
-increment_mtime "$(dirname "${gen_msg_filename}")"
output+=$(NOTMUCH_NEW)
output+="
"
test_expect_success 'notmuch reply works with renamed file (without notmuch new)' 'notmuch reply id:${gen_msg_id}'
test_begin_subtest "notmuch new detects no file rename after tag->flag synchronization"
-increment_mtime "$(dirname ${gen_msg_filename})"
output=$(NOTMUCH_NEW)
test_expect_equal "$output" "No new mail."
test_expect_equal "$output" "message-to-move-to-cur:2,S"
test_begin_subtest "No rename should be detected by notmuch new"
-increment_mtime "$MAIL_DIR/cur"
output=$(NOTMUCH_NEW)
test_expect_equal "$output" "No new mail."
# (*) If notmuch new was not run we've got "Processed 1 file in almost
# test created directory document in the database but this document
# was not linked as subdirectory of $MAIL_DIR. Therefore notmuch new
# could not reach the cur/ directory and its files in it during
-# recurive traversal.
+# recursive traversal.
#
# XXX: The above sounds like a bug that should be fixed. If notmuch is
# creating new directories in the mail store, then it should be
output+="
"
mv "${gen_msg_filename}" "${gen_msg_filename%S}"
-increment_mtime "$(dirname "${gen_msg_filename}")"
output+=$(NOTMUCH_NEW)
output+="
"
add_message [subject]='"Message to lose maildir info"' [filename]='message-to-lose-maildir-info' [dir]=cur
notmuch tag -unread subject:"Message to lose maildir info"
mv "$MAIL_DIR/cur/message-to-lose-maildir-info:2,S" "$MAIL_DIR/cur/message-without-maildir-info"
-increment_mtime "$MAIL_DIR/cur"
output=$(NOTMUCH_NEW)
output+="
"
mv $MAIL_DIR/cur/adding-s-flag:2,S $MAIL_DIR/cur/adding-s-flag:2,
mv $MAIL_DIR/cur/adding-with-s-flag:2,S $MAIL_DIR/cur/adding-with-s-flag:2,RS
mv $MAIL_DIR/cur/message-to-move-to-cur:2,S $MAIL_DIR/cur/message-to-move-to-cur:2,DS
-increment_mtime $MAIL_DIR/cur
notmuch dump dump.txt
NOTMUCH_NEW >/dev/null
notmuch restore dump.txt
test_begin_subtest 'Adding flags to duplicate message tags the mail'
add_message [subject]='"Duplicated message"' [dir]=cur [filename]='duplicated-message:2,'
cp "$MAIL_DIR/cur/duplicated-message:2," "$MAIL_DIR/cur/duplicated-message-copy:2,RS"
-increment_mtime $MAIL_DIR/cur
NOTMUCH_NEW > output
notmuch search subject:"Duplicated message" | notmuch_search_sanitize >> output
test_expect_equal "$(< output)" "No new mail.
test_begin_subtest "Adding duplicate message without flags does not remove tags"
cp "$MAIL_DIR/cur/duplicated-message-copy:2,RS" "$MAIL_DIR/cur/duplicated-message-another-copy:2,"
-increment_mtime $MAIL_DIR/cur
NOTMUCH_NEW > output
notmuch search subject:"Duplicated message" | notmuch_search_sanitize >> output
test_expect_equal "$(< output)" "No new mail.
7w0K
--==-=-=--
EOF
-increment_mtime "$MAIL_DIR"
notmuch new > /dev/null
test_begin_subtest "--format=text --part=0, full message"
Non-text part: text/html
\fpart}
\fpart}
-\fattachment{ ID: 5, Content-type: text/plain
-Attachment: attachment (text/plain)
+\fattachment{ ID: 5, Filename: attachment, Content-type: text/plain
This is a text attachment.
\fattachment}
\fpart{ ID: 6, Content-type: text/plain
Non-text part: text/html
\fpart}
\fpart}
-\fattachment{ ID: 5, Content-type: text/plain
-Attachment: attachment (text/plain)
+\fattachment{ ID: 5, Filename: attachment, Content-type: text/plain
This is a text attachment.
\fattachment}
\fpart{ ID: 6, Content-type: text/plain
Non-text part: text/html
\fpart}
\fpart}
-\fattachment{ ID: 5, Content-type: text/plain
-Attachment: attachment (text/plain)
+\fattachment{ ID: 5, Filename: attachment, Content-type: text/plain
This is a text attachment.
\fattachment}
\fpart{ ID: 6, Content-type: text/plain
EOF
test_expect_equal_file OUTPUT EXPECTED
-test_begin_subtest "--format=text --part=5, inline attachement"
+test_begin_subtest "--format=text --part=5, inline attachment"
notmuch show --format=text --part=5 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT
cat <<EOF >EXPECTED
-\fattachment{ ID: 5, Content-type: text/plain
-Attachment: attachment (text/plain)
+\fattachment{ ID: 5, Filename: attachment, Content-type: text/plain
This is a text attachment.
\fattachment}
EOF
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)
test_expect_equal "$output" "Added 1 new message to the database."
generate_message
notmuch new > /dev/null
mv "$gen_msg_filename" "${gen_msg_filename}"-renamed
-increment_mtime "${MAIL_DIR}"
output=$(NOTMUCH_NEW)
test_expect_equal "$output" "No new mail. Detected 1 file rename."
test_begin_subtest "Deleted message"
rm "${gen_msg_filename}"-renamed
-increment_mtime "${MAIL_DIR}"
output=$(NOTMUCH_NEW)
test_expect_equal "$output" "No new mail. Removed 1 message."
notmuch new > /dev/null
mv "${MAIL_DIR}"/dir "${MAIL_DIR}"/dir-renamed
-increment_mtime "${MAIL_DIR}"
output=$(NOTMUCH_NEW)
test_expect_equal "$output" "No new mail. Detected 3 file renames."
test_begin_subtest "Deleted directory"
rm -rf "${MAIL_DIR}"/dir-renamed
-increment_mtime "${MAIL_DIR}"
output=$(NOTMUCH_NEW)
test_expect_equal "$output" "No new mail. Removed 3 messages."
test_begin_subtest "Deleted directory (end of list)"
rm -rf "${MAIL_DIR}"/zzz
-increment_mtime "${MAIL_DIR}"
output=$(NOTMUCH_NEW)
test_expect_equal "$output" "No new mail. Removed 3 messages."
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)
test_expect_equal "$output" "Added 1 new message to the database."
test_begin_subtest "Deleted two-level directory"
rm -rf "${MAIL_DIR}"/two
-increment_mtime "${MAIL_DIR}"
output=$(NOTMUCH_NEW)
test_expect_equal "$output" "No new mail. Removed 3 messages."
test_begin_subtest "After removing duplicate instance of matching path"
rm -r "${MAIL_DIR}/bad/news"
-increment_mtime "${MAIL_DIR}/bad"
notmuch new
output=$(notmuch search folder:bad/news | notmuch_search_sanitize)
test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Bears (inbox unread)"
test_begin_subtest "After rename, old path returns nothing"
mv "${MAIL_DIR}/duplicate/bad/news" "${MAIL_DIR}/duplicate/bad/olds"
-increment_mtime "${MAIL_DIR}/duplicate/bad"
notmuch new
output=$(notmuch search folder:bad/news | notmuch_search_sanitize)
test_expect_equal "$output" ""
test_begin_subtest "Remove folder:spam copy of email"
rm $dir/spam/$(basename $file_x)
-increment_mtime $dir/spam
output=$(NOTMUCH_NEW)
test_expect_equal "$output" "No new mail. Detected 1 file rename."
MAIL_DIR/cur/21:2,
MAIL_DIR/cur/19:2,
MAIL_DIR/cur/18:2,
+MAIL_DIR/cur/51:2,
MAIL_DIR/cur/20:2,
MAIL_DIR/cur/17:2,
MAIL_DIR/cur/16:2,
"MAIL_DIR/cur/21:2,",
"MAIL_DIR/cur/19:2,",
"MAIL_DIR/cur/18:2,",
+"MAIL_DIR/cur/51:2,",
"MAIL_DIR/cur/20:2,",
"MAIL_DIR/cur/17:2,",
"MAIL_DIR/cur/16:2,",
. ./test-lib.sh
run_test(){
- result=$(LD_LIBRARY_PATH=../../lib ./symbol-test 2>&1)
+ result=$(LD_LIBRARY_PATH=$TEST_DIRECTORY/../lib ./symbol-test 2>&1)
}
output="A Xapian exception occurred opening database: Couldn't stat 'fakedb/.notmuch/xapian'
caught No chert database found at path \`./nonexistant'"
-g++ -o symbol-test -I../../lib ../symbol-test.cc -L../../lib -lnotmuch -lxapian
+g++ -o symbol-test -I$TEST_DIRECTORY/../lib $TEST_DIRECTORY/symbol-test.cc -L$TEST_DIRECTORY/../lib -lnotmuch -lxapian
mkdir -p fakedb/.notmuch
test_expect_success 'running test' run_test
test_begin_subtest 'checking output'
;;
;; Authors: Dmitry Kurochkin <dmitry.kurochkin@gmail.com>
+;; avoid crazy 10-column default of --batch
+(set-frame-width (window-frame (get-buffer-window)) 80)
+
+;; `read-file-name' by default uses `completing-read' function to read
+;; user input. It does not respect `standard-input' variable which we
+;; use in tests to provide user input. So replace it with a plain
+;; `read' call.
+(setq read-file-name-function (lambda (&rest _) (read)))
+
+(defun notmuch-test-wait ()
+ "Wait for process completion."
+ (while (get-buffer-process (current-buffer))
+ (sleep-for 0.1)))
+
+(defun test-output (&optional filename)
+ "Save current buffer to file FILENAME. Default FILENAME is OUTPUT."
+ (write-region (point-min) (point-max) (or filename "OUTPUT")))
+
+(defun test-visible-output (&optional filename)
+ "Save visible text in current buffer to file FILENAME. Default
+FILENAME is OUTPUT."
+ (let ((text (visible-buffer-string)))
+ (with-temp-file (or filename "OUTPUT") (insert text))))
+
(defun visible-buffer-string ()
"Same as `buffer-string', but excludes invisible text."
(visible-buffer-substring (point-min) (point-max)))
(setq str (concat str (buffer-substring start next-pos))))
(setq start next-pos)))
str))
+
+(defun orphan-watchdog (pid)
+ "Periodically check that the process with id PID is still
+running, quit if it terminated."
+ (if (not (process-attributes pid))
+ (kill-emacs)
+ (run-at-time "1 min" nil 'orphan-watchdog pid)))
tr '\015' Q | sed -e 's/Q$//'
}
-# 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"
-}
-
# Generate a new message in the mail directory, with a unique message
# ID and subject. The message is not added to the index.
#
${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 database.
shift 2
# before we can send a message, we have to prepare the FCC maildir
mkdir -p "$MAIL_DIR"/sent/{cur,new,tmp}
- ../smtp-dummy sent_message &
+ $TEST_DIRECTORY/smtp-dummy sent_message &
smtp_dummy_pid=$!
- test_emacs "(setq message-send-mail-function 'message-smtpmail-send-it) (setq smtpmail-smtp-server \"localhost\") (setq smtpmail-smtp-service \"25025\") (notmuch-hello) (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)" >/dev/null 2>&1
+ test_emacs \
+ "(let ((message-send-mail-function 'message-smtpmail-send-it)
+ (smtpmail-smtp-server \"localhost\")
+ (smtpmail-smtp-service \"25025\"))
+ (notmuch-hello)
+ (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))" >/dev/null 2>&1
wait ${smtp_dummy_pid}
notmuch new >/dev/null
}
add_email_corpus ()
{
rm -rf ${MAIL_DIR}
- if [ -d ../corpus.mail ]; then
- cp -a ../corpus.mail ${MAIL_DIR}
+ if [ -d $TEST_DIRECTORY/corpus.mail ]; then
+ cp -a $TEST_DIRECTORY/corpus.mail ${MAIL_DIR}
else
- cp -a ../corpus ${MAIL_DIR}
+ cp -a $TEST_DIRECTORY/corpus ${MAIL_DIR}
notmuch new >/dev/null
- cp -a ${MAIL_DIR} ../corpus.mail
+ cp -a ${MAIL_DIR} $TEST_DIRECTORY/corpus.mail
fi
}
error "bug in test script: Missing test_expect_equal in ${BASH_SOURCE[1]}:${BASH_LINENO[0]}"
fi
test_subtest_name="$1"
- # Remember stdout and stderr file descriptios and redirect test
+ # 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
echo
+ [ -n "$EMACS_SERVER" ] && test_emacs '(kill-emacs)'
+
if [ "$test_failure" = "0" ]; then
if [ "$test_broken" = "0" ]; then
rm -rf "$remove_tmp"
fi
}
-test_emacs () {
+emacs_generate_script () {
# Construct a little test script here for the benefit of the user,
# (who can easily run "run_emacs" to get the same emacs environment
# for investigating any failures).
- cat <<EOF > run_emacs
+ cat <<EOF >"$TMP_DIRECTORY/run_emacs"
#!/bin/sh
export PATH=$PATH
export NOTMUCH_CONFIG=$NOTMUCH_CONFIG
-# We assume that the user will give a command-line argument only if
-# wanting to run in batch mode.
-if [ \$# -gt 0 ]; then
- BATCH=--batch
-fi
-
# Here's what we are using here:
#
-# --batch: Quit after given commands and print all (messages)
-#
# --no-init-file Don't load users ~/.emacs
#
# --no-site-file Don't load the site-wide startup stuff
# --directory Ensure that the local elisp sources are found
#
# --load Force loading of notmuch.el and test-lib.el
-#
-# notmuch-test-wait Function for tests to use to wait for process completion
-#
-# message-signature Avoiding appending user's signature on messages
-#
-# set-frame-width 80 columns (avoids crazy 10-column default of --batch)
-
-emacs \$BATCH --no-init-file --no-site-file \
- --directory ../../emacs --load notmuch.el \
- --directory .. --load test-lib.el \
- --eval "(defun notmuch-test-wait ()
- (while (get-buffer-process (current-buffer))
- (sleep-for 0.1)))" \
- --eval "(setq message-signature nil)" \
- --eval "(progn (set-frame-width (window-frame (get-buffer-window)) 80) \$@)"
+
+emacs --no-init-file --no-site-file \
+ --directory "$TEST_DIRECTORY/../emacs" --load notmuch.el \
+ --directory "$TEST_DIRECTORY" --load test-lib.el \
+ "\$@"
EOF
- chmod a+x ./run_emacs
- ./run_emacs "$@"
+ chmod a+x "$TMP_DIRECTORY/run_emacs"
+}
+
+test_emacs () {
+ if [ -z "$EMACS_SERVER" ]; then
+ EMACS_SERVER="notmuch-test-suite-$$"
+ "$TMP_DIRECTORY/run_emacs" \
+ --daemon \
+ --eval "(setq server-name \"$EMACS_SERVER\")" \
+ --eval "(orphan-watchdog $$)" || return
+ fi
+
+ emacsclient --socket-name="$EMACS_SERVER" --eval "(progn $@)"
}
test ! -d "$symlink_target" &&
test "#!" != "$(head -c 2 < "$symlink_target")"
then
- symlink_target=../valgrind.sh
+ symlink_target=$TEST_DIRECTORY/valgrind.sh
fi
case "$base" in
*.sh|*.perl)
- symlink_target=../unprocessed-script
+ symlink_target=$TEST_DIRECTORY/unprocessed-script
esac
# create the link, or replace it if it is out of date
make_symlink "$symlink_target" "$GIT_VALGRIND/bin/$base" || exit
other_email=test_suite_other@notmuchmail.org;test_suite@otherdomain.org
EOF
+emacs_generate_script
+
# Use -P to resolve symlinks in our working directory so that the cwd
# in subprocesses like git equals our $PWD (for pathname comparisons).
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:
+this content beforeuudata . Then we begin the uuencoded data itself:
begin 644 bogus-uuencoded-data
M0123456789012345678901234567890123456789012345678901234567890
-MOBVIOUSLY, THIS IS NOT ANY SORT OF USEFUL UUNECODED DATA.
+MOBVIOUSLY, THIS IS NOT ANY SORT OF USEFUL UUENCODED 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
You are presented with the search results when you run :NotMuch.
Keybindings:
- <Space> - show the selected thread colapsing unmatched items
+ <Space> - show the selected thread collapsing unmatched items
<Enter> - show the entire selected thread
a - archive message (remove inbox tag)
f - filter the current search terms
if part_end
" FIXME: this is a hack for handling two folds being added for one line
- " we should handle addinga fold in a function
+ " we should handle adding a fold in a function
if len(foldinfo) && foldinfo[1] < foldinfo[2]
call add(info['folds'], foldinfo[0:3])
let info['foldtext'][foldinfo[1]] = foldinfo[4]
function! s:NM_tag(filter, tags)
let filter = len(a:filter) ? a:filter : [<SID>NM_search_thread_id()]
if !len(filter)
- throw 'Eeek! I couldn''t find the thead id!'
+ throw 'Eeek! I couldn''t find the thread id!'
endif
let args = ['tag']
call extend(args, a:tags)