From: David Bremner Date: Sat, 22 Feb 2014 01:05:05 +0000 (-0400) Subject: Merge tag 'debian/0.17-4' X-Git-Tag: 0.18_rc0~139 X-Git-Url: https://git.notmuchmail.org/git?p=notmuch;a=commitdiff_plain;h=957fc2e1a7d00636c7eaaf487edae65e7a63dc8f;hp=c35dcb7704460f803fef2b7b6567dd3b0e5621ea Merge tag 'debian/0.17-4' uploaded to Debian unstable --- diff --git a/Makefile.local b/Makefile.local index 72524eb3..174506c5 100644 --- a/Makefile.local +++ b/Makefile.local @@ -236,11 +236,11 @@ endif quiet ?= $($(shell echo $1 | sed -e s'/ .*//')) %.o: %.cc $(global_deps) - @mkdir -p .deps/$(@D) + @mkdir -p $(patsubst %/.,%,.deps/$(@D)) $(call quiet,CXX $(CPPFLAGS) $(CXXFLAGS)) -c $(FINAL_CXXFLAGS) $< -o $@ -MD -MP -MF .deps/$*.d %.o: %.c $(global_deps) - @mkdir -p .deps/$(@D) + @mkdir -p $(patsubst %/.,%,.deps/$(@D)) $(call quiet,CC $(CPPFLAGS) $(CFLAGS)) -c $(FINAL_CFLAGS) $< -o $@ -MD -MP -MF .deps/$*.d .PHONY : clean @@ -325,3 +325,5 @@ DISTCLEAN := $(DISTCLEAN) .first-build-message Makefile.config DEPS := $(SRCS:%.c=.deps/%.d) DEPS := $(DEPS:%.cc=.deps/%.d) -include $(DEPS) + +.SUFFIXES: # Delete the default suffixes. Old-Fashioned Suffix Rules not used. diff --git a/NEWS b/NEWS index 28788d8d..65679ebb 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,13 @@ +Notmuch 0.18 (UNRELEASED) +========================= + +Command-Line Interface +---------------------- + +`notmuch dump` now defaults to `batch-tag` format. + + The old format is still available with `--format=sup`. + Notmuch 0.17 (2013-12-30) ========================= diff --git a/compat/have_d_type.c b/compat/have_d_type.c new file mode 100644 index 00000000..9ca6c6e0 --- /dev/null +++ b/compat/have_d_type.c @@ -0,0 +1,10 @@ +#include + +int main() +{ + struct dirent ent; + + (void) ent.d_type; + + return 0; +} diff --git a/completion/notmuch-completion.bash b/completion/notmuch-completion.bash index 04324bbb..0f132043 100644 --- a/completion/notmuch-completion.bash +++ b/completion/notmuch-completion.bash @@ -208,7 +208,7 @@ _notmuch_new() case "${cur}" in -*) - local options="--no-hooks" + local options="--no-hooks --quiet" COMPREPLY=( $(compgen -W "${options}" -- ${cur}) ) ;; esac diff --git a/configure b/configure index 13b60620..2eaed4a1 100755 --- a/configure +++ b/configure @@ -360,6 +360,14 @@ else have_valgrind=0 fi +printf "Checking for bash-completion (>= 1.90)... " +if pkg-config --atleast-version=1.90 bash-completion; then + printf "Yes.\n" +else + printf "No (will not install bash completion).\n" + WITH_BASH=0 +fi + if [ -z "${EMACSLISPDIR}" ]; then if pkg-config --exists emacs; then EMACSLISPDIR=$(pkg-config emacs --variable sitepkglispdir) @@ -570,6 +578,17 @@ else fi rm -f compat/have_timegm +printf "Checking for dirent.d_type... " +if ${CC} -o compat/have_d_type "$srcdir"/compat/have_d_type.c > /dev/null 2>&1 +then + printf "Yes.\n" + have_d_type="1" +else + printf "No (will use stat instead).\n" + have_d_type="0" +fi +rm -f compat/have_d_type + printf "Checking for standard version of getpwuid_r... " if ${CC} -o compat/check_getpwuid "$srcdir"/compat/check_getpwuid.c > /dev/null 2>&1 then @@ -761,6 +780,9 @@ HAVE_STRCASESTR = ${have_strcasestr} # build its own version) HAVE_STRSEP = ${have_strsep} +# Whether struct dirent has d_type (if not, then notmuch will use stat) +HAVE_D_TYPE = ${have_d_type} + # Whether the Xapian version in use supports compaction HAVE_XAPIAN_COMPACT = ${have_xapian_compact} @@ -821,6 +843,7 @@ CONFIGURE_CFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS) \\ \$(VALGRIND_CFLAGS) \\ -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) \\ -DHAVE_STRSEP=\$(HAVE_STRSEP) \\ + -DHAVE_D_TYPE=\$(HAVE_D_TYPE) \\ -DSTD_GETPWUID=\$(STD_GETPWUID) \\ -DSTD_ASCTIME=\$(STD_ASCTIME) \\ -DHAVE_XAPIAN_COMPACT=\$(HAVE_XAPIAN_COMPACT) \\ @@ -831,6 +854,7 @@ CONFIGURE_CXXFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS) \\ \$(VALGRIND_CFLAGS) \$(XAPIAN_CXXFLAGS) \\ -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) \\ -DHAVE_STRSEP=\$(HAVE_STRSEP) \\ + -DHAVE_D_TYPE=\$(HAVE_D_TYPE) \\ -DSTD_GETPWUID=\$(STD_GETPWUID) \\ -DSTD_ASCTIME=\$(STD_ASCTIME) \\ -DHAVE_XAPIAN_COMPACT=\$(HAVE_XAPIAN_COMPACT) \\ diff --git a/devel/doxygen.cfg b/devel/doxygen.cfg new file mode 100644 index 00000000..65d5fb50 --- /dev/null +++ b/devel/doxygen.cfg @@ -0,0 +1,304 @@ +# Doxyfile 1.8.4 + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +DOXYFILE_ENCODING = UTF-8 +PROJECT_NAME = "Notmuch 0.17" +PROJECT_NUMBER = +PROJECT_BRIEF = +PROJECT_LOGO = +OUTPUT_DIRECTORY = +CREATE_SUBDIRS = NO +OUTPUT_LANGUAGE = English +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = NO +STRIP_FROM_PATH = +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = YES +QT_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO +INHERIT_DOCS = YES +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 8 +ALIASES = +TCL_SUBST = +OPTIMIZE_OUTPUT_FOR_C = YES +OPTIMIZE_OUTPUT_JAVA = NO +OPTIMIZE_FOR_FORTRAN = NO +OPTIMIZE_OUTPUT_VHDL = NO +EXTENSION_MAPPING = +MARKDOWN_SUPPORT = YES +AUTOLINK_SUPPORT = YES +BUILTIN_STL_SUPPORT = NO +CPP_CLI_SUPPORT = NO +SIP_SUPPORT = NO +IDL_PROPERTY_SUPPORT = YES +DISTRIBUTE_GROUP_DOC = NO +SUBGROUPING = YES +INLINE_GROUPED_CLASSES = NO +INLINE_SIMPLE_STRUCTS = NO +TYPEDEF_HIDES_STRUCT = YES +LOOKUP_CACHE_SIZE = 0 +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = NO +EXTRACT_PRIVATE = NO +EXTRACT_PACKAGE = NO +EXTRACT_STATIC = NO +EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_METHODS = NO +EXTRACT_ANON_NSPACES = NO +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = NO +FORCE_LOCAL_INCLUDES = NO +INLINE_INFO = YES +SORT_MEMBER_DOCS = NO +SORT_BRIEF_DOCS = NO +SORT_MEMBERS_CTORS_1ST = NO +SORT_GROUP_NAMES = NO +SORT_BY_SCOPE_NAME = NO +STRICT_PROTO_MATCHING = NO +GENERATE_TODOLIST = NO +GENERATE_TESTLIST = NO +GENERATE_BUGLIST = NO +GENERATE_DEPRECATEDLIST= NO +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = NO +SHOW_FILES = NO +SHOW_NAMESPACES = NO +FILE_VERSION_FILTER = +LAYOUT_FILE = +CITE_BIB_FILES = +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = YES +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = lib/notmuch.h +INPUT_ENCODING = UTF-8 +FILE_PATTERNS = +RECURSIVE = NO +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXCLUDE_SYMBOLS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +FILTER_SOURCE_PATTERNS = +USE_MDFILE_AS_MAINPAGE = +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = NO +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = NO +REFERENCES_RELATION = NO +REFERENCES_LINK_SOURCE = YES +USE_HTAGS = NO +VERBATIM_HEADERS = NO +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = NO +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = NO +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_EXTRA_STYLESHEET = +HTML_EXTRA_FILES = +HTML_COLORSTYLE_HUE = 220 +HTML_COLORSTYLE_SAT = 100 +HTML_COLORSTYLE_GAMMA = 80 +HTML_TIMESTAMP = YES +HTML_DYNAMIC_SECTIONS = NO +HTML_INDEX_NUM_ENTRIES = 100 +GENERATE_DOCSET = NO +DOCSET_FEEDNAME = "Doxygen generated docs" +DOCSET_BUNDLE_ID = org.doxygen.Project +DOCSET_PUBLISHER_ID = org.doxygen.Publisher +DOCSET_PUBLISHER_NAME = Publisher +GENERATE_HTMLHELP = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +CHM_INDEX_ENCODING = +BINARY_TOC = NO +TOC_EXPAND = NO +GENERATE_QHP = NO +QCH_FILE = +QHP_NAMESPACE = org.doxygen.Project +QHP_VIRTUAL_FOLDER = doc +QHP_CUST_FILTER_NAME = +QHP_CUST_FILTER_ATTRS = +QHP_SECT_FILTER_ATTRS = +QHG_LOCATION = +GENERATE_ECLIPSEHELP = NO +ECLIPSE_DOC_ID = org.doxygen.Project +DISABLE_INDEX = NO +GENERATE_TREEVIEW = NO +ENUM_VALUES_PER_LINE = 4 +TREEVIEW_WIDTH = 250 +EXT_LINKS_IN_WINDOW = NO +FORMULA_FONTSIZE = 10 +FORMULA_TRANSPARENT = YES +USE_MATHJAX = NO +MATHJAX_FORMAT = HTML-CSS +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest +MATHJAX_EXTENSIONS = +MATHJAX_CODEFILE = +SEARCHENGINE = YES +SERVER_BASED_SEARCH = NO +EXTERNAL_SEARCH = NO +SEARCHENGINE_URL = +SEARCHDATA_FILE = searchdata.xml +EXTERNAL_SEARCH_ID = +EXTRA_SEARCH_MAPPINGS = +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4 +EXTRA_PACKAGES = +LATEX_HEADER = +LATEX_FOOTER = +LATEX_EXTRA_FILES = +PDF_HYPERLINKS = YES +USE_PDFLATEX = YES +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +LATEX_SOURCE_CODE = NO +LATEX_BIB_STYLE = plain +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = YES +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +XML_PROGRAMLISTING = YES +#--------------------------------------------------------------------------- +# configuration options related to the DOCBOOK output +#--------------------------------------------------------------------------- +GENERATE_DOCBOOK = NO +DOCBOOK_OUTPUT = docbook +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = NO +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = __DOXYGEN__ +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = NO +EXTERNAL_PAGES = NO +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = NO +MSCGEN_PATH = +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = NO +DOT_NUM_THREADS = 0 +DOT_FONTNAME = Helvetica +DOT_FONTSIZE = 10 +DOT_FONTPATH = +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +GROUP_GRAPHS = YES +UML_LOOK = NO +UML_LIMIT_NUM_FIELDS = 10 +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = NO +INCLUDED_BY_GRAPH = NO +CALL_GRAPH = NO +CALLER_GRAPH = NO +GRAPHICAL_HIERARCHY = NO +DIRECTORY_GRAPH = NO +DOT_IMAGE_FORMAT = png +INTERACTIVE_SVG = NO +DOT_PATH = +DOTFILE_DIRS = +MSCFILE_DIRS = +DOT_GRAPH_MAX_NODES = 50 +MAX_DOT_GRAPH_DEPTH = 0 +DOT_TRANSPARENT = NO +DOT_MULTI_TARGETS = YES +GENERATE_LEGEND = NO +DOT_CLEANUP = YES diff --git a/devel/nmbug/nmbug-status b/devel/nmbug/nmbug-status index 934c895f..ef7169a6 100755 --- a/devel/nmbug/nmbug-status +++ b/devel/nmbug/nmbug-status @@ -6,185 +6,330 @@ # - python 2.6 for json # - argparse; either python 2.7, or install separately +from __future__ import print_function +from __future__ import unicode_literals + +import codecs +import collections import datetime -import rfc822 -import urllib +import email.utils +try: # Python 3 + from urllib.parse import quote +except ImportError: # Python 2 + from urllib import quote import json import argparse import os +import re import sys import subprocess +import xml.sax.saxutils + + +_ENCODING = 'UTF-8' +_PAGES = {} + + +if not hasattr(collections, 'OrderedDict'): # Python 2.6 or earlier + class _OrderedDict (dict): + "Just enough of a stub to get through Page._get_threads" + def __init__(self, *args, **kwargs): + super(_OrderedDict, self).__init__(*args, **kwargs) + self._keys = [] # record key order + + def __setitem__(self, key, value): + super(_OrderedDict, self).__setitem__(key, value) + self._keys.append(key) + + def __values__(self): + for key in self._keys: + yield self[key] + + + collections.OrderedDict = _OrderedDict + + +def read_config(path=None, encoding=None): + "Read config from json file" + if not encoding: + encoding = _ENCODING + if path: + fp = open(path) + else: + nmbhome = os.getenv('NMBGIT', os.path.expanduser('~/.nmbug')) + + # read only the first line from the pipe + sha1_bytes = subprocess.Popen( + ['git', '--git-dir', nmbhome, 'show-ref', '-s', 'config'], + stdout=subprocess.PIPE).stdout.readline() + sha1 = sha1_bytes.decode(encoding).rstrip() + + fp_byte_stream = subprocess.Popen( + ['git', '--git-dir', nmbhome, 'cat-file', 'blob', + sha1+':status-config.json'], + stdout=subprocess.PIPE).stdout + fp = codecs.getreader(encoding=encoding)(stream=fp_byte_stream) + + return json.load(fp) + + +class Thread (list): + def __init__(self): + self.running_data = {} + + +class Page (object): + def __init__(self, header=None, footer=None): + self.header = header + self.footer = footer + + def write(self, database, views, stream=None): + if not stream: + try: # Python 3 + byte_stream = sys.stdout.buffer + except AttributeError: # Python 2 + byte_stream = sys.stdout + stream = codecs.getwriter(encoding=_ENCODING)(stream=byte_stream) + self._write_header(views=views, stream=stream) + for view in views: + self._write_view(database=database, view=view, stream=stream) + self._write_footer(views=views, stream=stream) + + def _write_header(self, views, stream): + if self.header: + stream.write(self.header) + + def _write_footer(self, views, stream): + if self.footer: + stream.write(self.footer) + + def _write_view(self, database, view, stream): + if 'query-string' not in view: + query = view['query'] + view['query-string'] = ' and '.join(query) + q = notmuch.Query(database, view['query-string']) + q.set_sort(notmuch.Query.SORT.OLDEST_FIRST) + threads = self._get_threads(messages=q.search_messages()) + self._write_view_header(view=view, stream=stream) + self._write_threads(threads=threads, stream=stream) + + def _get_threads(self, messages): + threads = collections.OrderedDict() + for message in messages: + thread_id = message.get_thread_id() + if thread_id in threads: + thread = threads[thread_id] + else: + thread = Thread() + threads[thread_id] = thread + thread.running_data, display_data = self._message_display_data( + running_data=thread.running_data, message=message) + thread.append(display_data) + return list(threads.values()) + + def _write_view_header(self, view, stream): + pass + + def _write_threads(self, threads, stream): + for thread in threads: + for message_display_data in thread: + stream.write( + ('{date:10.10s} {from:20.20s} {subject:40.40s}\n' + '{message-id-term:>72}\n' + ).format(**message_display_data)) + if thread != threads[-1]: + stream.write('\n') + + def _message_display_data(self, running_data, message): + headers = ('thread-id', 'message-id', 'date', 'from', 'subject') + data = {} + for header in headers: + if header == 'thread-id': + value = message.get_thread_id() + elif header == 'message-id': + value = message.get_message_id() + data['message-id-term'] = 'id:"{0}"'.format(value) + elif header == 'date': + value = str(datetime.datetime.utcfromtimestamp( + message.get_date()).date()) + else: + value = message.get_header(header) + if header == 'from': + (value, addr) = email.utils.parseaddr(value) + if not value: + value = addr.split('@')[0] + data[header] = value + next_running_data = data.copy() + for header, value in data.items(): + if header in ['message-id', 'subject']: + continue + if value == running_data.get(header, None): + data[header] = '' + return (next_running_data, data) + + +class HtmlPage (Page): + _slug_regexp = re.compile('\W+') + + def _write_header(self, views, stream): + super(HtmlPage, self)._write_header(views=views, stream=stream) + stream.write('\n') + + def _write_view_header(self, view, stream): + stream.write('

{title}

\n'.format(**view)) + stream.write('

\n') + if 'comment' in view: + stream.write(view['comment']) + stream.write('\n') + for line in [ + 'The view is generated from the following query:', + '

', + '

', + ' ', + view['query-string'], + ' ', + '

', + ]: + stream.write(line) + stream.write('\n') + + def _write_threads(self, threads, stream): + if not threads: + return + stream.write('\n') + for thread in threads: + stream.write(' \n') + for message_display_data in thread: + stream.write(( + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ).format(**message_display_data)) + stream.write(' \n') + if thread != threads[-1]: + stream.write( + ' \n') + stream.write('
{date}{message-id-term}
{from}{subject}

\n') + + def _message_display_data(self, *args, **kwargs): + running_data, display_data = super( + HtmlPage, self)._message_display_data( + *args, **kwargs) + if 'subject' in display_data and 'message-id' in display_data: + d = { + 'message-id': quote(display_data['message-id']), + 'subject': xml.sax.saxutils.escape(display_data['subject']), + } + display_data['subject'] = ( + '{subject}' + ).format(**d) + for key in ['message-id', 'from']: + if key in display_data: + display_data[key] = xml.sax.saxutils.escape(display_data[key]) + return (running_data, display_data) + + def _slug(self, string): + return self._slug_regexp.sub('-', string) + + +_PAGES['text'] = Page() +_PAGES['html'] = HtmlPage( + header=''' + + + + Notmuch Patches + + + +

Notmuch Patches

+

+Generated: {date}
+For more infomation see nmbug +

+

Views

+'''.format(date=datetime.datetime.utcnow().date(), + encoding=_ENCODING, + inter_message_padding='0.25em', + border_radius='0.5em'), + footer='\n\n', + ) -# parse command line arguments parser = argparse.ArgumentParser() parser.add_argument('--text', help='output plain text format', action='store_true') -parser.add_argument('--config', help='load config from given file') +parser.add_argument('--config', help='load config from given file', + metavar='PATH') parser.add_argument('--list-views', help='list views', action='store_true') -parser.add_argument('--get-query', help='get query for view') +parser.add_argument('--get-query', help='get query for view', + metavar='VIEW') args = parser.parse_args() -# read config from json file - -if args.config != None: - fp = open(args.config) -else: - nmbhome = os.getenv('NMBGIT', os.path.expanduser('~/.nmbug')) - - # read only the first line from the pipe - sha1 = subprocess.Popen(['git', '--git-dir', nmbhome, - 'show-ref', '-s', 'config'], - stdout=subprocess.PIPE).stdout.readline() - - sha1 = sha1.rstrip() - - fp = subprocess.Popen(['git', '--git-dir', nmbhome, - 'cat-file', 'blob', sha1+':status-config.json'], - stdout=subprocess.PIPE).stdout - -config = json.load(fp) +config = read_config(path=args.config) if args.list_views: for view in config['views']: - print view['title'] + print(view['title']) sys.exit(0) elif args.get_query != None: for view in config['views']: if args.get_query == view['title']: - print ' and '.join(view['query']) + print(' and '.join(view['query'])) sys.exit(0) else: # only import notmuch if needed import notmuch if args.text: - output_format = 'text' + page = _PAGES['text'] else: - output_format = 'html' - -class Thread: - def __init__(self, last, lines): - self.last = last - self.lines = lines - - def join_utf8_with_newlines(self): - return '\n'.join( (line.encode('utf-8') for line in self.lines) ) - -def output_with_separator(threadlist, sep): - outputs = (thread.join_utf8_with_newlines() for thread in threadlist) - print sep.join(outputs) - -headers = ['date', 'from', 'subject'] - -def print_view(title, query, comment): - - query_string = ' and '.join(query) - q_new = notmuch.Query(db, query_string) - q_new.set_sort(notmuch.Query.SORT.OLDEST_FIRST) - - last_thread_id = '' - threads = {} - threadlist = [] - out = {} - last = None - lines = None - - if output_format == 'html': - print '

%s

' % (title, title) - print comment - print 'The view is generated from the following query:' - print '
' - print query_string - print '
' - print '\n' - - for m in q_new.search_messages(): - - thread_id = m.get_thread_id() - - if thread_id != last_thread_id: - if threads.has_key(thread_id): - last = threads[thread_id].last - lines = threads[thread_id].lines - else: - last = {} - lines = [] - thread = Thread(last, lines) - threads[thread_id] = thread - for h in headers: - last[h] = '' - threadlist.append(thread) - last_thread_id = thread_id - - for header in headers: - val = m.get_header(header) - - if header == 'date': - val = str.join(' ', val.split(None)[1:4]) - val = str(datetime.datetime.strptime(val, '%d %b %Y').date()) - elif header == 'from': - (val, addr) = rfc822.parseaddr(val) - if val == '': - val = addr.split('@')[0] - - if header != 'subject' and last[header] == val: - out[header] = '' - else: - out[header] = val - last[header] = val - - mid = m.get_message_id() - out['id'] = 'id:"%s"' % mid - - if output_format == 'html': - - out['subject'] = '%s' \ - % (urllib.quote(mid), out['subject']) - - lines.append(' ') - lines.append(' ') - else: - lines.append('%(date)-10.10s %(from)-20.20s %(subject)-40.40s\n%(id)72s' % out) - - if output_format == 'html': - output_with_separator(threadlist, - '\n\n') - print '
%s' % out['date']) - lines.append('%s' % out['id']) - lines.append('
%s' % out['from']) - lines.append('%s' % out['subject']) - lines.append('

' - else: - output_with_separator(threadlist, '\n\n') - -# main program - -db = notmuch.Database(mode=notmuch.Database.MODE.READ_WRITE) - -if output_format == 'html': - print ''' - - - - -Notmuch Patches - -''' - print '

Notmuch Patches

' - print 'Generated: %s
' % datetime.datetime.utcnow().date() - print 'For more infomation see nmbug' - - print '

Views

' - print '' - -for view in config['views']: - print_view(**view) + page = _PAGES['html'] -if output_format == 'html': - print '\n' +db = notmuch.Database(mode=notmuch.Database.MODE.READ_ONLY) +page.write(database=db, views=config['views']) diff --git a/emacs/Makefile.local b/emacs/Makefile.local index 92467a31..42bfbd96 100644 --- a/emacs/Makefile.local +++ b/emacs/Makefile.local @@ -29,19 +29,24 @@ emacs_bytecode = $(emacs_sources:.el=.elc) # the byte compiler may load an old .elc file when processing a # "require" or we may fail to rebuild a .elc that depended on a macro # from an updated file. +ifeq ($(HAVE_EMACS),1) $(dir)/.eldeps: $(dir)/Makefile.local $(dir)/make-deps.el $(emacs_sources) $(call quiet,EMACS) --directory emacs -batch -l make-deps.el \ -f batch-make-deps $(emacs_sources) > $@.tmp && \ (cmp -s $@.tmp $@ || mv $@.tmp $@) -include $(dir)/.eldeps +endif CLEAN+=$(dir)/.eldeps $(dir)/.eldeps.tmp +ifeq ($(HAVE_EMACS),1) %.elc: %.el $(global_deps) $(call quiet,EMACS) --directory emacs -batch -f batch-byte-compile $< +endif ifeq ($(WITH_EMACS),1) ifeq ($(HAVE_EMACS),1) all: $(emacs_bytecode) +install-emacs: $(emacs_bytecode) endif install: install-emacs diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el index 55c416ac..7b3d76b7 100644 --- a/emacs/notmuch-hello.el +++ b/emacs/notmuch-hello.el @@ -788,6 +788,7 @@ following: "Run notmuch and display saved searches, known tags, etc." (interactive) + (notmuch-assert-cli-sane) ;; This may cause a window configuration change, so if the ;; auto-refresh hook is already installed, avoid recursive refresh. (let ((notmuch-hello-auto-refresh nil)) diff --git a/emacs/notmuch-lib.el b/emacs/notmuch-lib.el index 49fe6445..fa35fa9f 100644 --- a/emacs/notmuch-lib.el +++ b/emacs/notmuch-lib.el @@ -168,6 +168,24 @@ Otherwise the output will be returned" (notmuch-check-exit-status status (cons notmuch-command args) output) output))) +(defvar notmuch--cli-sane-p nil + "Cache whether the CLI seems to be configured sanely.") + +(defun notmuch-cli-sane-p () + "Return t if the cli seems to be configured sanely." + (unless notmuch--cli-sane-p + (let ((status (call-process notmuch-command nil nil nil + "config" "get" "user.primary_email"))) + (setq notmuch--cli-sane-p (= status 0)))) + notmuch--cli-sane-p) + +(defun notmuch-assert-cli-sane () + (unless (notmuch-cli-sane-p) + (notmuch-logged-error + "notmuch cli seems misconfigured or unconfigured." +"Perhaps you haven't run \"notmuch setup\" yet? Try running this +on the command line, and then retry your notmuch command"))) + (defun notmuch-version () "Return a string with the notmuch version number." (let ((long-string @@ -231,7 +249,8 @@ depending on the value of `notmuch-poll-script'." "Given a prefix key code, return a human-readable string representation. This is basically just `format-kbd-macro' but we also convert ESC to M-." - (let ((desc (format-kbd-macro (vector key)))) + (let* ((key-vector (if (vectorp key) key (vector key))) + (desc (format-kbd-macro key-vector))) (if (string= desc "ESC") "M-" (concat desc " ")))) @@ -337,6 +356,28 @@ of its command symbol." (set-buffer-modified-p nil) (view-buffer (current-buffer) 'kill-buffer-if-not-modified)))) +(defun notmuch-subkeymap-help () + "Show help for a subkeymap." + (interactive) + (let* ((key (this-command-keys-vector)) + (prefix (make-vector (1- (length key)) nil)) + (i 0)) + (while (< i (length prefix)) + (aset prefix i (aref key i)) + (setq i (1+ i))) + + (let* ((subkeymap (key-binding prefix)) + (ua-keys (where-is-internal 'universal-argument nil t)) + (prefix-string (notmuch-prefix-key-description prefix)) + (desc-alist (notmuch-describe-keymap subkeymap ua-keys subkeymap prefix-string)) + (desc-list (mapcar (lambda (arg) (concat (car arg) "\t" (cdr arg))) desc-alist)) + (desc (mapconcat #'identity desc-list "\n"))) + (with-help-window (help-buffer) + (with-current-buffer standard-output + (insert "\nPress 'q' to quit this window.\n\n") + (insert desc))) + (pop-to-buffer (help-buffer))))) + (defvar notmuch-buffer-refresh-function nil "Function to call to refresh the current buffer.") (make-variable-buffer-local 'notmuch-buffer-refresh-function) @@ -490,7 +531,8 @@ the given type." (if (>= emacs-major-version 24) (defadvice mm-shr (before load-gnus-arts activate) (require 'gnus-art nil t) - (ad-disable-advice 'mm-shr 'before 'load-gnus-arts))) + (ad-disable-advice 'mm-shr 'before 'load-gnus-arts) + (ad-activate 'mm-shr))) (defun notmuch-mm-display-part-inline (msg part nth content-type process-crypto) "Use the mm-decode/mm-view functions to display a part in the diff --git a/emacs/notmuch-mua.el b/emacs/notmuch-mua.el index 00cd9808..481abd7c 100644 --- a/emacs/notmuch-mua.el +++ b/emacs/notmuch-mua.el @@ -287,6 +287,19 @@ the From: header is already filled in by notmuch." (defvar notmuch-mua-sender-history nil) +;; Workaround: Running `ido-completing-read' in emacs 23.1, 23.2 and 23.3 +;; without some explicit initialization fill freeze the operation. +;; Hence, we advice `ido-completing-read' to ensure required initialization +;; is done. +(if (and (= emacs-major-version 23) (< emacs-minor-version 4)) + (defadvice ido-completing-read (before notmuch-ido-mode-init activate) + (ido-init-completion-maps) + (add-hook 'minibuffer-setup-hook 'ido-minibuffer-setup) + (add-hook 'choose-completion-string-functions + 'ido-choose-completion-string) + (ad-disable-advice 'ido-completing-read 'before 'notmuch-ido-mode-init) + (ad-activate 'ido-completing-read))) + (defun notmuch-mua-prompt-for-sender () (interactive) (let (name addresses one-name-only) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index 784644cd..88752f17 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -171,7 +171,7 @@ each attachment handler is logged in buffers with names beginning (defcustom notmuch-show-stash-mlarchive-link-alist '(("Gmane" . "http://mid.gmane.org/") ("MARC" . "http://marc.info/?i=") - ("Mail Archive, The" . "http://mail-archive.com/search?l=mid&q=") + ("Mail Archive, The" . "http://mid.mail-archive.com/") ("LKML" . "http://lkml.kernel.org/r/") ;; FIXME: can these services be searched by `Message-Id' ? ;; ("MarkMail" . "http://markmail.org/") @@ -1241,6 +1241,7 @@ reset based on the original query." (define-key map "t" 'notmuch-show-stash-to) (define-key map "l" 'notmuch-show-stash-mlarchive-link) (define-key map "L" 'notmuch-show-stash-mlarchive-link-and-go) + (define-key map "?" 'notmuch-subkeymap-help) map) "Submap for stash commands") (fset 'notmuch-show-stash-map notmuch-show-stash-map) @@ -1251,6 +1252,7 @@ reset based on the original query." (define-key map "v" 'notmuch-show-view-part) (define-key map "o" 'notmuch-show-interactively-view-part) (define-key map "|" 'notmuch-show-pipe-part) + (define-key map "?" 'notmuch-subkeymap-help) map) "Submap for part commands") (fset 'notmuch-show-part-map notmuch-show-part-map) diff --git a/emacs/notmuch-tag.el b/emacs/notmuch-tag.el index b60f46c7..908e7ade 100644 --- a/emacs/notmuch-tag.el +++ b/emacs/notmuch-tag.el @@ -148,15 +148,16 @@ This can be used with `notmuch-tag-format-image-data'." (dolist (format (cdr formats) tag) (setq tag (eval format)))))))) -(defun notmuch-tag-format-tags (tags) +(defun notmuch-tag-format-tags (tags &optional face) "Return a string representing formatted TAGS." - (notmuch-combine-face-text-property-string - (mapconcat #'identity - ;; nil indicated that the tag was deliberately hidden - (delq nil (mapcar #'notmuch-tag-format-tag tags)) - " ") - 'notmuch-tag-face - t)) + (let ((face (or face 'notmuch-tag-face))) + (notmuch-combine-face-text-property-string + (mapconcat #'identity + ;; nil indicated that the tag was deliberately hidden + (delq nil (mapcar #'notmuch-tag-format-tag tags)) + " ") + face + t))) (defcustom notmuch-before-tag-hook nil "Hooks that are run before tags of a message are modified. diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el index 8d59e65f..4f2ac028 100644 --- a/emacs/notmuch-tree.el +++ b/emacs/notmuch-tree.el @@ -70,8 +70,14 @@ Note the author string should not contain :group 'notmuch-tree) ;; Faces for messages that match the query. -(defface notmuch-tree-match-date-face +(defface notmuch-tree-match-face '((t :inherit default)) + "Default face used in tree mode face for matching messages" + :group 'notmuch-tree + :group 'notmuch-faces) + +(defface notmuch-tree-match-date-face + nil "Face used in tree mode for the date in messages matching the query." :group 'notmuch-tree :group 'notmuch-faces) @@ -90,13 +96,13 @@ Note the author string should not contain :group 'notmuch-faces) (defface notmuch-tree-match-subject-face - '((t :inherit default)) + nil "Face used in tree mode for the subject in messages matching the query." :group 'notmuch-tree :group 'notmuch-faces) (defface notmuch-tree-match-tree-face - '((t :inherit default)) + nil "Face used in tree mode for the thread tree block graphics in messages matching the query." :group 'notmuch-tree :group 'notmuch-faces) @@ -115,32 +121,38 @@ Note the author string should not contain :group 'notmuch-faces) ;; Faces for messages that do not match the query. -(defface notmuch-tree-no-match-date-face +(defface notmuch-tree-no-match-face '((t (:foreground "gray"))) + "Default face used in tree mode face for non-matching messages" + :group 'notmuch-tree + :group 'notmuch-faces) + +(defface notmuch-tree-no-match-date-face + nil "Face used in tree mode for non-matching dates." :group 'notmuch-tree :group 'notmuch-faces) (defface notmuch-tree-no-match-subject-face - '((t (:foreground "gray"))) + nil "Face used in tree mode for non-matching subjects." :group 'notmuch-tree :group 'notmuch-faces) (defface notmuch-tree-no-match-tree-face - '((t (:foreground "gray"))) + nil "Face used in tree mode for the thread tree block graphics in messages matching the query." :group 'notmuch-tree :group 'notmuch-faces) (defface notmuch-tree-no-match-author-face - '((t (:foreground "gray"))) + nil "Face used in tree mode for the date in messages matching the query." :group 'notmuch-tree :group 'notmuch-faces) (defface notmuch-tree-no-match-tag-face - '((t (:foreground "gray"))) + nil "Face used in tree mode face for non-matching tags." :group 'notmuch-tree :group 'notmuch-faces) @@ -319,11 +331,13 @@ correct message properties." "Return the tags of the current message." (notmuch-tree-get-prop :tags)) -(defun notmuch-tree-get-message-id () +(defun notmuch-tree-get-message-id (&optional bare) "Return the message id of the current message." (let ((id (notmuch-tree-get-prop :id))) (if id - (notmuch-id-to-query id) + (if bare + id + (notmuch-id-to-query id)) nil))) (defun notmuch-tree-get-match () @@ -690,17 +704,18 @@ unchanged ADDRESS if parsing fails." (face (if match 'notmuch-tree-match-tag-face 'notmuch-tree-no-match-tag-face))) - (propertize (format format-string - (mapconcat #'identity tags ", ")) - 'face face)))))) - + (format format-string (notmuch-tag-format-tags tags face))))))) (defun notmuch-tree-format-field-list (field-list msg) "Format fields of MSG according to FIELD-LIST and return string" - (let (result-string) + (let ((face (if (plist-get msg :match) + 'notmuch-tree-match-face + 'notmuch-tree-no-match-face)) + (result-string)) (dolist (spec field-list result-string) (let ((field-string (notmuch-tree-format-field (car spec) (cdr spec) msg))) - (setq result-string (concat result-string field-string)))))) + (setq result-string (concat result-string field-string)))) + (notmuch-combine-face-text-property-string result-string face t))) (defun notmuch-tree-insert-msg (msg) "Insert the message MSG according to notmuch-tree-result-format" diff --git a/emacs/notmuch.el b/emacs/notmuch.el index c9bc2f22..04717500 100644 --- a/emacs/notmuch.el +++ b/emacs/notmuch.el @@ -165,6 +165,7 @@ To enter a line break in customize, press \\[quoted-insert] C-j." (defvar notmuch-search-stash-map (let ((map (make-sparse-keymap))) (define-key map "i" 'notmuch-search-stash-thread-id) + (define-key map "?" 'notmuch-subkeymap-help) map) "Submap for stash commands") (fset 'notmuch-search-stash-map notmuch-search-stash-map) diff --git a/lib/message.cc b/lib/message.cc index 1b463795..c91f3a59 100644 --- a/lib/message.cc +++ b/lib/message.cc @@ -412,19 +412,27 @@ _notmuch_message_ensure_message_file (notmuch_message_t *message) const char * notmuch_message_get_header (notmuch_message_t *message, const char *header) { - std::string value; + try { + std::string value; - /* Fetch header from the appropriate xapian value field if - * available */ - if (strcasecmp (header, "from") == 0) - value = message->doc.get_value (NOTMUCH_VALUE_FROM); - else if (strcasecmp (header, "subject") == 0) - value = message->doc.get_value (NOTMUCH_VALUE_SUBJECT); - else if (strcasecmp (header, "message-id") == 0) - value = message->doc.get_value (NOTMUCH_VALUE_MESSAGE_ID); + /* Fetch header from the appropriate xapian value field if + * available */ + if (strcasecmp (header, "from") == 0) + value = message->doc.get_value (NOTMUCH_VALUE_FROM); + else if (strcasecmp (header, "subject") == 0) + value = message->doc.get_value (NOTMUCH_VALUE_SUBJECT); + else if (strcasecmp (header, "message-id") == 0) + value = message->doc.get_value (NOTMUCH_VALUE_MESSAGE_ID); - if (!value.empty()) - return talloc_strdup (message, value.c_str ()); + if (!value.empty()) + return talloc_strdup (message, value.c_str ()); + + } catch (Xapian::Error &error) { + fprintf (stderr, "A Xapian exception occurred when reading header: %s\n", + error.get_msg().c_str()); + message->notmuch->exception_reported = TRUE; + return NULL; + } /* Otherwise fall back to parsing the file */ _notmuch_message_ensure_message_file (message); @@ -766,7 +774,9 @@ notmuch_message_get_date (notmuch_message_t *message) try { value = message->doc.get_value (NOTMUCH_VALUE_TIMESTAMP); } catch (Xapian::Error &error) { - INTERNAL_ERROR ("Failed to read timestamp value from document."); + fprintf (stderr, "A Xapian exception occurred when reading date: %s\n", + error.get_msg().c_str()); + message->notmuch->exception_reported = TRUE; return 0; } diff --git a/lib/notmuch.h b/lib/notmuch.h index d30768d9..350bed8b 100644 --- a/lib/notmuch.h +++ b/lib/notmuch.h @@ -18,9 +18,19 @@ * Author: Carl Worth */ +/** + * @defgroup notmuch The notmuch API + * + * Not much of an email library, (just index and search) + * + * @{ + */ + #ifndef NOTMUCH_H #define NOTMUCH_H +#ifndef __DOXYGEN__ + #ifdef __cplusplus # define NOTMUCH_BEGIN_DECLS extern "C" { # define NOTMUCH_END_DECLS } @@ -49,19 +59,28 @@ NOTMUCH_BEGIN_DECLS #define LIBNOTMUCH_MINOR_VERSION 1 #define LIBNOTMUCH_MICRO_VERSION 0 -/* +#endif /* __DOXYGEN__ */ + +/** * Check the version of the notmuch library being compiled against. * * Return true if the library being compiled against is of the * specified version or above. For example: * + * @code * #if LIBNOTMUCH_CHECK_VERSION(3, 1, 0) * (code requiring libnotmuch 3.1.0 or above) * #endif + * @endcode * - * LIBNOTMUCH_CHECK_VERSION has been defined since version 3.1.0; you - * can use #if !defined(NOTMUCH_CHECK_VERSION) to check for versions - * prior to that. + * LIBNOTMUCH_CHECK_VERSION has been defined since version 3.1.0; to + * check for versions prior to that, use: + * + * @code + * #if !defined(NOTMUCH_CHECK_VERSION) + * (code requiring libnotmuch prior to 3.1.0) + * #endif + * @endcode */ #define LIBNOTMUCH_CHECK_VERSION (major, minor, micro) \ (LIBNOTMUCH_MAJOR_VERSION > (major) || \ @@ -69,72 +88,86 @@ NOTMUCH_BEGIN_DECLS (LIBNOTMUCH_MAJOR_VERSION == (major) && LIBNOTMUCH_MINOR_VERSION == (minor) && \ LIBNOTMUCH_MICRO_VERSION >= (micro))) +/** + * Notmuch boolean type. + */ typedef int notmuch_bool_t; -/* Status codes used for the return values of most functions. +/** + * Status codes used for the return values of most functions. * * A zero value (NOTMUCH_STATUS_SUCCESS) indicates that the function - * completed without error. Any other value indicates an error as - * follows: - * - * NOTMUCH_STATUS_SUCCESS: No error occurred. - * - * NOTMUCH_STATUS_OUT_OF_MEMORY: Out of memory - * - * XXX: We don't really want to expose this lame XAPIAN_EXCEPTION - * value. Instead we should map to things like DATABASE_LOCKED or - * whatever. - * - * NOTMUCH_STATUS_READ_ONLY_DATABASE: An attempt was made to write to - * a database opened in read-only mode. - * - * NOTMUCH_STATUS_XAPIAN_EXCEPTION: A Xapian exception occurred - * - * NOTMUCH_STATUS_FILE_ERROR: An error occurred trying to read or - * write to a file (this could be file not found, permission - * denied, etc.) - * - * NOTMUCH_STATUS_FILE_NOT_EMAIL: A file was presented that doesn't - * appear to be an email message. - * - * NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID: A file contains a message ID - * that is identical to a message already in the database. - * - * NOTMUCH_STATUS_NULL_POINTER: The user erroneously passed a NULL - * pointer to a notmuch function. - * - * NOTMUCH_STATUS_TAG_TOO_LONG: A tag value is too long (exceeds - * NOTMUCH_TAG_MAX) - * - * NOTMUCH_STATUS_UNBALANCED_FREEZE_THAW: The notmuch_message_thaw - * function has been called more times than notmuch_message_freeze. - * - * NOTMUCH_STATUS_UNBALANCED_ATOMIC: notmuch_database_end_atomic has - * been called more times than notmuch_database_begin_atomic. - * - * And finally: - * - * NOTMUCH_STATUS_LAST_STATUS: Not an actual status value. Just a way - * to find out how many valid status values there are. + * completed without error. Any other value indicates an error. */ typedef enum _notmuch_status { + /** + * No error occurred. + */ NOTMUCH_STATUS_SUCCESS = 0, + /** + * Out of memory. + */ NOTMUCH_STATUS_OUT_OF_MEMORY, + /** + * An attempt was made to write to a database opened in read-only + * mode. + */ NOTMUCH_STATUS_READ_ONLY_DATABASE, + /** + * A Xapian exception occurred. + */ NOTMUCH_STATUS_XAPIAN_EXCEPTION, + /** + * An error occurred trying to read or write to a file (this could + * be file not found, permission denied, etc.) + * + * @todo We don't really want to expose this lame XAPIAN_EXCEPTION + * value. Instead we should map to things like DATABASE_LOCKED or + * whatever. + */ NOTMUCH_STATUS_FILE_ERROR, + /** + * A file was presented that doesn't appear to be an email + * message. + */ NOTMUCH_STATUS_FILE_NOT_EMAIL, + /** + * A file contains a message ID that is identical to a message + * already in the database. + */ NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID, + /** + * The user erroneously passed a NULL pointer to a notmuch + * function. + */ NOTMUCH_STATUS_NULL_POINTER, + /** + * A tag value is too long (exceeds NOTMUCH_TAG_MAX). + */ NOTMUCH_STATUS_TAG_TOO_LONG, + /** + * The notmuch_message_thaw function has been called more times + * than notmuch_message_freeze. + */ NOTMUCH_STATUS_UNBALANCED_FREEZE_THAW, + /** + * notmuch_database_end_atomic has been called more times than + * notmuch_database_begin_atomic. + */ NOTMUCH_STATUS_UNBALANCED_ATOMIC, + /** + * The operation is not supported. + */ NOTMUCH_STATUS_UNSUPPORTED_OPERATION, - + /** + * Not an actual status value. Just a way to find out how many + * valid status values there are. + */ NOTMUCH_STATUS_LAST_STATUS } notmuch_status_t; -/* Get a string representation of a notmuch_status_t value. +/** + * Get a string representation of a notmuch_status_t value. * * The result is read-only. */ @@ -143,6 +176,7 @@ notmuch_status_to_string (notmuch_status_t status); /* Various opaque data types. For each notmuch__t see the various * notmuch_ functions below. */ +#ifndef __DOXYGEN__ typedef struct _notmuch_database notmuch_database_t; typedef struct _notmuch_query notmuch_query_t; typedef struct _notmuch_threads notmuch_threads_t; @@ -152,8 +186,10 @@ typedef struct _notmuch_message notmuch_message_t; typedef struct _notmuch_tags notmuch_tags_t; typedef struct _notmuch_directory notmuch_directory_t; typedef struct _notmuch_filenames notmuch_filenames_t; +#endif /* __DOXYGEN__ */ -/* Create a new, empty notmuch database located at 'path'. +/** + * Create a new, empty notmuch database located at 'path'. * * The path should be a top-level directory to a collection of * plain-text email messages (one message per file). This call will @@ -189,12 +225,22 @@ typedef struct _notmuch_filenames notmuch_filenames_t; notmuch_status_t notmuch_database_create (const char *path, notmuch_database_t **database); +/** + * Database open mode for notmuch_database_open. + */ typedef enum { + /** + * Open database for reading only. + */ NOTMUCH_DATABASE_MODE_READ_ONLY = 0, + /** + * Open database for reading and writing. + */ NOTMUCH_DATABASE_MODE_READ_WRITE } notmuch_database_mode_t; -/* Open an existing notmuch database located at 'path'. +/** + * Open an existing notmuch database located at 'path'. * * The database should have been created at some time in the past, * (not necessarily by this process), by calling @@ -230,7 +276,8 @@ notmuch_database_open (const char *path, notmuch_database_mode_t mode, notmuch_database_t **database); -/* Close the given notmuch database. +/** + * Close the given notmuch database. * * After notmuch_database_close has been called, calls to other * functions on objects derived from this database may either behave @@ -244,12 +291,14 @@ notmuch_database_open (const char *path, void notmuch_database_close (notmuch_database_t *database); -/* A callback invoked by notmuch_database_compact to notify the user +/** + * A callback invoked by notmuch_database_compact to notify the user * of the progress of the compaction process. */ typedef void (*notmuch_compact_status_cb_t)(const char *message, void *closure); -/* Compact a notmuch database, backing up the original database to the +/** + * Compact a notmuch database, backing up the original database to the * given path. * * The database will be opened with NOTMUCH_DATABASE_MODE_READ_WRITE @@ -265,33 +314,41 @@ notmuch_database_compact (const char* path, notmuch_compact_status_cb_t status_cb, void *closure); -/* Destroy the notmuch database, closing it if necessary and freeing +/** + * Destroy the notmuch database, closing it if necessary and freeing * all associated resources. */ void notmuch_database_destroy (notmuch_database_t *database); -/* Return the database path of the given database. +/** + * Return the database path of the given database. * * The return value is a string owned by notmuch so should not be - * modified nor freed by the caller. */ + * modified nor freed by the caller. + */ const char * notmuch_database_get_path (notmuch_database_t *database); -/* Return the database format version of the given database. */ +/** + * Return the database format version of the given database. + */ unsigned int notmuch_database_get_version (notmuch_database_t *database); -/* Does this database need to be upgraded before writing to it? +/** + * Does this database need to be upgraded before writing to it? * * If this function returns TRUE then no functions that modify the * database (notmuch_database_add_message, notmuch_message_add_tag, * notmuch_directory_set_mtime, etc.) will work unless the function - * notmuch_database_upgrade is called successfully first. */ + * notmuch_database_upgrade is called successfully first. + */ notmuch_bool_t notmuch_database_needs_upgrade (notmuch_database_t *database); -/* Upgrade the current database. +/** + * Upgrade the current database. * * After opening a database in read-write mode, the client should * check if an upgrade is needed (notmuch_database_needs_upgrade) and @@ -310,7 +367,8 @@ notmuch_database_upgrade (notmuch_database_t *database, double progress), void *closure); -/* Begin an atomic database operation. +/** + * Begin an atomic database operation. * * Any modifications performed between a successful begin and a * notmuch_database_end_atomic will be applied to the database @@ -331,7 +389,8 @@ notmuch_database_upgrade (notmuch_database_t *database, notmuch_status_t notmuch_database_begin_atomic (notmuch_database_t *notmuch); -/* Indicate the end of an atomic database operation. +/** + * Indicate the end of an atomic database operation. * * Return value: * @@ -346,7 +405,8 @@ notmuch_database_begin_atomic (notmuch_database_t *notmuch); notmuch_status_t notmuch_database_end_atomic (notmuch_database_t *notmuch); -/* Retrieve a directory object from the database for 'path'. +/** + * Retrieve a directory object from the database for 'path'. * * Here, 'path' should be a path relative to the path of 'database' * (see notmuch_database_get_path), or else should be an absolute path @@ -355,6 +415,10 @@ notmuch_database_end_atomic (notmuch_database_t *notmuch); * If this directory object does not exist in the database, this * returns NOTMUCH_STATUS_SUCCESS and sets *directory to NULL. * + * Otherwise the returned directory object is owned by the database + * and as such, will only be valid until notmuch_database_destroy is + * called. + * * Return value: * * NOTMUCH_STATUS_SUCCESS: Successfully retrieved directory. @@ -369,7 +433,8 @@ notmuch_database_get_directory (notmuch_database_t *database, const char *path, notmuch_directory_t **directory); -/* Add a new message to the given notmuch database or associate an +/** + * Add a new message to the given notmuch database or associate an * additional filename with an existing message. * * Here, 'filename' should be a path relative to the path of @@ -420,7 +485,8 @@ notmuch_database_add_message (notmuch_database_t *database, const char *filename, notmuch_message_t **message); -/* Remove a message filename from the given notmuch database. If the +/** + * Remove a message filename from the given notmuch database. If the * message has no more filenames, remove the message. * * If the same message (as determined by the message ID) is still @@ -448,7 +514,8 @@ notmuch_status_t notmuch_database_remove_message (notmuch_database_t *database, const char *filename); -/* Find a message with the given message_id. +/** + * Find a message with the given message_id. * * If a message with the given message_id is found then, on successful return * (NOTMUCH_STATUS_SUCCESS) '*message' will be initialized to a message @@ -475,7 +542,8 @@ notmuch_database_find_message (notmuch_database_t *database, const char *message_id, notmuch_message_t **message); -/* Find a message with the given filename. +/** + * Find a message with the given filename. * * If the database contains a message with the given filename then, on * successful return (NOTMUCH_STATUS_SUCCESS) '*message' will be initialized to @@ -502,7 +570,8 @@ notmuch_database_find_message_by_filename (notmuch_database_t *notmuch, const char *filename, notmuch_message_t **message); -/* Return a list of all tags found in the database. +/** + * Return a list of all tags found in the database. * * This function creates a list of all tags found in the database. The * resulting list contains all tags from all messages found in the database. @@ -512,7 +581,8 @@ notmuch_database_find_message_by_filename (notmuch_database_t *notmuch, notmuch_tags_t * notmuch_database_get_all_tags (notmuch_database_t *db); -/* Create a new query for 'database'. +/** + * Create a new query for 'database'. * * Here, 'database' should be an open database, (see * notmuch_database_open and notmuch_database_create). @@ -540,19 +610,36 @@ notmuch_query_t * notmuch_query_create (notmuch_database_t *database, const char *query_string); -/* Sort values for notmuch_query_set_sort */ +/** + * Sort values for notmuch_query_set_sort. + */ typedef enum { + /** + * Oldest first. + */ NOTMUCH_SORT_OLDEST_FIRST, + /** + * Newest first. + */ NOTMUCH_SORT_NEWEST_FIRST, + /** + * Sort by message-id. + */ NOTMUCH_SORT_MESSAGE_ID, + /** + * Do not sort. + */ NOTMUCH_SORT_UNSORTED } notmuch_sort_t; -/* Return the query_string of this query. See notmuch_query_create. */ +/** + * Return the query_string of this query. See notmuch_query_create. + */ const char * notmuch_query_get_query_string (notmuch_query_t *query); -/* Exclude values for notmuch_query_set_omit_excluded. The strange +/** + * Exclude values for notmuch_query_set_omit_excluded. The strange * order is to maintain backward compatibility: the old FALSE/TRUE * options correspond to the new * NOTMUCH_EXCLUDE_FLAG/NOTMUCH_EXCLUDE_TRUE options. @@ -564,7 +651,8 @@ typedef enum { NOTMUCH_EXCLUDE_ALL } notmuch_exclude_t; -/* Specify whether to omit excluded results or simply flag them. By +/** + * Specify whether to omit excluded results or simply flag them. By * default, this is set to TRUE. * * If set to TRUE or ALL, notmuch_query_search_messages will omit excluded @@ -594,21 +682,29 @@ void notmuch_query_set_omit_excluded (notmuch_query_t *query, notmuch_exclude_t omit_excluded); -/* Specify the sorting desired for this query. */ +/** + * Specify the sorting desired for this query. + */ void notmuch_query_set_sort (notmuch_query_t *query, notmuch_sort_t sort); -/* Return the sort specified for this query. See notmuch_query_set_sort. */ +/** + * Return the sort specified for this query. See + * notmuch_query_set_sort. + */ notmuch_sort_t notmuch_query_get_sort (notmuch_query_t *query); -/* Add a tag that will be excluded from the query results by default. +/** + * Add a tag that will be excluded from the query results by default. * This exclusion will be overridden if this tag appears explicitly in - * the query. */ + * the query. + */ void notmuch_query_add_tag_exclude (notmuch_query_t *query, const char *tag); -/* Execute a query for threads, returning a notmuch_threads_t object +/** + * Execute a query for threads, returning a notmuch_threads_t object * which can be used to iterate over the results. The returned threads * object is owned by the query and as such, will only be valid until * notmuch_query_destroy. @@ -649,7 +745,8 @@ notmuch_query_add_tag_exclude (notmuch_query_t *query, const char *tag); notmuch_threads_t * notmuch_query_search_threads (notmuch_query_t *query); -/* Execute a query for messages, returning a notmuch_messages_t object +/** + * Execute a query for messages, returning a notmuch_messages_t object * which can be used to iterate over the results. The returned * messages object is owned by the query and as such, will only be * valid until notmuch_query_destroy. @@ -690,7 +787,8 @@ notmuch_query_search_threads (notmuch_query_t *query); notmuch_messages_t * notmuch_query_search_messages (notmuch_query_t *query); -/* Destroy a notmuch_query_t along with any associated resources. +/** + * Destroy a notmuch_query_t along with any associated resources. * * This will in turn destroy any notmuch_threads_t and * notmuch_messages_t objects generated by this query, (and in @@ -701,19 +799,23 @@ notmuch_query_search_messages (notmuch_query_t *query); void notmuch_query_destroy (notmuch_query_t *query); -/* Is the given 'threads' iterator pointing at a valid thread. +/** + * Is the given 'threads' iterator pointing at a valid thread. * * When this function returns TRUE, notmuch_threads_get will return a * valid object. Whereas when this function returns FALSE, * notmuch_threads_get will return NULL. * + * If passed a NULL pointer, this function returns FALSE + * * See the documentation of notmuch_query_search_threads for example * code showing how to iterate over a notmuch_threads_t object. */ notmuch_bool_t notmuch_threads_valid (notmuch_threads_t *threads); -/* Get the current thread from 'threads' as a notmuch_thread_t. +/** + * Get the current thread from 'threads' as a notmuch_thread_t. * * Note: The returned thread belongs to 'threads' and has a lifetime * identical to it (and the query to which it belongs). @@ -727,7 +829,8 @@ notmuch_threads_valid (notmuch_threads_t *threads); notmuch_thread_t * notmuch_threads_get (notmuch_threads_t *threads); -/* Move the 'threads' iterator to the next thread. +/** + * Move the 'threads' iterator to the next thread. * * If 'threads' is already pointing at the last thread then the * iterator will be moved to a point just beyond that last thread, @@ -740,7 +843,8 @@ notmuch_threads_get (notmuch_threads_t *threads); void notmuch_threads_move_to_next (notmuch_threads_t *threads); -/* Destroy a notmuch_threads_t object. +/** + * Destroy a notmuch_threads_t object. * * It's not strictly necessary to call this function. All memory from * the notmuch_threads_t object will be reclaimed when the @@ -749,7 +853,8 @@ notmuch_threads_move_to_next (notmuch_threads_t *threads); void notmuch_threads_destroy (notmuch_threads_t *threads); -/* Return an estimate of the number of messages matching a search +/** + * Return an estimate of the number of messages matching a search. * * This function performs a search and returns Xapian's best * guess as to number of matching messages. @@ -759,8 +864,9 @@ notmuch_threads_destroy (notmuch_threads_t *threads); */ unsigned notmuch_query_count_messages (notmuch_query_t *query); - -/* Return the number of threads matching a search. + +/** + * Return the number of threads matching a search. * * This function performs a search and returns the number of unique thread IDs * in the matching messages. This is the same as number of threads matching a @@ -774,7 +880,8 @@ notmuch_query_count_messages (notmuch_query_t *query); unsigned notmuch_query_count_threads (notmuch_query_t *query); -/* Get the thread ID of 'thread'. +/** + * Get the thread ID of 'thread'. * * The returned string belongs to 'thread' and as such, should not be * modified by the caller and will only be valid for as long as the @@ -784,7 +891,8 @@ notmuch_query_count_threads (notmuch_query_t *query); const char * notmuch_thread_get_thread_id (notmuch_thread_t *thread); -/* Get the total number of messages in 'thread'. +/** + * Get the total number of messages in 'thread'. * * This count consists of all messages in the database belonging to * this thread. Contrast with notmuch_thread_get_matched_messages() . @@ -792,7 +900,8 @@ notmuch_thread_get_thread_id (notmuch_thread_t *thread); int notmuch_thread_get_total_messages (notmuch_thread_t *thread); -/* Get a notmuch_messages_t iterator for the top-level messages in +/** + * Get a notmuch_messages_t iterator for the top-level messages in * 'thread' in oldest-first order. * * This iterator will not necessarily iterate over all of the messages @@ -804,7 +913,8 @@ notmuch_thread_get_total_messages (notmuch_thread_t *thread); notmuch_messages_t * notmuch_thread_get_toplevel_messages (notmuch_thread_t *thread); -/* Get a notmuch_thread_t iterator for all messages in 'thread' in +/** + * Get a notmuch_thread_t iterator for all messages in 'thread' in * oldest-first order. * * The returned list will be destroyed when the thread is destroyed. @@ -812,7 +922,8 @@ notmuch_thread_get_toplevel_messages (notmuch_thread_t *thread); notmuch_messages_t * notmuch_thread_get_messages (notmuch_thread_t *thread); -/* Get the number of messages in 'thread' that matched the search. +/** + * Get the number of messages in 'thread' that matched the search. * * This count includes only the messages in this thread that were * matched by the search from which the thread was created and were @@ -823,7 +934,8 @@ notmuch_thread_get_messages (notmuch_thread_t *thread); int notmuch_thread_get_matched_messages (notmuch_thread_t *thread); -/* Get the authors of 'thread' as a UTF-8 string. +/** + * Get the authors of 'thread' as a UTF-8 string. * * The returned string is a comma-separated list of the names of the * authors of mail messages in the query results that belong to this @@ -837,7 +949,8 @@ notmuch_thread_get_matched_messages (notmuch_thread_t *thread); const char * notmuch_thread_get_authors (notmuch_thread_t *thread); -/* Get the subject of 'thread' as a UTF-8 string. +/** + * Get the subject of 'thread' as a UTF-8 string. * * The subject is taken from the first message (according to the query * order---see notmuch_query_set_sort) in the query results that @@ -851,17 +964,20 @@ notmuch_thread_get_authors (notmuch_thread_t *thread); const char * notmuch_thread_get_subject (notmuch_thread_t *thread); -/* Get the date of the oldest message in 'thread' as a time_t value. +/** + * Get the date of the oldest message in 'thread' as a time_t value. */ time_t notmuch_thread_get_oldest_date (notmuch_thread_t *thread); -/* Get the date of the newest message in 'thread' as a time_t value. +/** + * Get the date of the newest message in 'thread' as a time_t value. */ time_t notmuch_thread_get_newest_date (notmuch_thread_t *thread); -/* Get the tags for 'thread', returning a notmuch_tags_t object which +/** + * Get the tags for 'thread', returning a notmuch_tags_t object which * can be used to iterate over all tags. * * Note: In the Notmuch database, tags are stored on individual @@ -884,7 +1000,7 @@ notmuch_thread_get_newest_date (notmuch_thread_t *thread); * * for (tags = notmuch_thread_get_tags (thread); * notmuch_tags_valid (tags); - * notmuch_result_move_to_next (tags)) + * notmuch_tags_move_to_next (tags)) * { * tag = notmuch_tags_get (tags); * .... @@ -900,11 +1016,14 @@ notmuch_thread_get_newest_date (notmuch_thread_t *thread); notmuch_tags_t * notmuch_thread_get_tags (notmuch_thread_t *thread); -/* Destroy a notmuch_thread_t object. */ +/** + * Destroy a notmuch_thread_t object. + */ void notmuch_thread_destroy (notmuch_thread_t *thread); -/* Is the given 'messages' iterator pointing at a valid message. +/** + * Is the given 'messages' iterator pointing at a valid message. * * When this function returns TRUE, notmuch_messages_get will return a * valid object. Whereas when this function returns FALSE, @@ -916,7 +1035,8 @@ notmuch_thread_destroy (notmuch_thread_t *thread); notmuch_bool_t notmuch_messages_valid (notmuch_messages_t *messages); -/* Get the current message from 'messages' as a notmuch_message_t. +/** + * Get the current message from 'messages' as a notmuch_message_t. * * Note: The returned message belongs to 'messages' and has a lifetime * identical to it (and the query to which it belongs). @@ -930,7 +1050,8 @@ notmuch_messages_valid (notmuch_messages_t *messages); notmuch_message_t * notmuch_messages_get (notmuch_messages_t *messages); -/* Move the 'messages' iterator to the next message. +/** + * Move the 'messages' iterator to the next message. * * If 'messages' is already pointing at the last message then the * iterator will be moved to a point just beyond that last message, @@ -943,7 +1064,8 @@ notmuch_messages_get (notmuch_messages_t *messages); void notmuch_messages_move_to_next (notmuch_messages_t *messages); -/* Destroy a notmuch_messages_t object. +/** + * Destroy a notmuch_messages_t object. * * It's not strictly necessary to call this function. All memory from * the notmuch_messages_t object will be reclaimed when the containing @@ -952,7 +1074,8 @@ notmuch_messages_move_to_next (notmuch_messages_t *messages); void notmuch_messages_destroy (notmuch_messages_t *messages); -/* Return a list of tags from all messages. +/** + * Return a list of tags from all messages. * * The resulting list is guaranteed not to contain duplicated tags. * @@ -967,7 +1090,8 @@ notmuch_messages_destroy (notmuch_messages_t *messages); notmuch_tags_t * notmuch_messages_collect_tags (notmuch_messages_t *messages); -/* Get the message ID of 'message'. +/** + * Get the message ID of 'message'. * * The returned string belongs to 'message' and as such, should not be * modified by the caller and will only be valid for as long as the @@ -981,7 +1105,8 @@ notmuch_messages_collect_tags (notmuch_messages_t *messages); const char * notmuch_message_get_message_id (notmuch_message_t *message); -/* Get the thread ID of 'message'. +/** + * Get the thread ID of 'message'. * * The returned string belongs to 'message' and as such, should not be * modified by the caller and will only be valid for as long as the @@ -995,7 +1120,8 @@ notmuch_message_get_message_id (notmuch_message_t *message); const char * notmuch_message_get_thread_id (notmuch_message_t *message); -/* Get a notmuch_messages_t iterator for all of the replies to +/** + * Get a notmuch_messages_t iterator for all of the replies to * 'message'. * * Note: This call only makes sense if 'message' was ultimately @@ -1015,7 +1141,8 @@ notmuch_message_get_thread_id (notmuch_message_t *message); notmuch_messages_t * notmuch_message_get_replies (notmuch_message_t *message); -/* Get a filename for the email corresponding to 'message'. +/** + * Get a filename for the email corresponding to 'message'. * * The returned filename is an absolute filename, (the initial * component will match notmuch_database_get_path() ). @@ -1033,7 +1160,8 @@ notmuch_message_get_replies (notmuch_message_t *message); const char * notmuch_message_get_filename (notmuch_message_t *message); -/* Get all filenames for the email corresponding to 'message'. +/** + * Get all filenames for the email corresponding to 'message'. * * Returns a notmuch_filenames_t iterator listing all the filenames * associated with 'message'. These files may not have identical @@ -1045,31 +1173,40 @@ notmuch_message_get_filename (notmuch_message_t *message); notmuch_filenames_t * notmuch_message_get_filenames (notmuch_message_t *message); -/* Message flags */ +/** + * Message flags. + */ typedef enum _notmuch_message_flag { NOTMUCH_MESSAGE_FLAG_MATCH, NOTMUCH_MESSAGE_FLAG_EXCLUDED } notmuch_message_flag_t; -/* Get a value of a flag for the email corresponding to 'message'. */ +/** + * Get a value of a flag for the email corresponding to 'message'. + */ notmuch_bool_t notmuch_message_get_flag (notmuch_message_t *message, notmuch_message_flag_t flag); -/* Set a value of a flag for the email corresponding to 'message'. */ +/** + * Set a value of a flag for the email corresponding to 'message'. + */ void notmuch_message_set_flag (notmuch_message_t *message, notmuch_message_flag_t flag, notmuch_bool_t value); -/* Get the date of 'message' as a time_t value. +/** + * Get the date of 'message' as a time_t value. * * For the original textual representation of the Date header from the * message call notmuch_message_get_header() with a header value of - * "date". */ + * "date". + */ time_t notmuch_message_get_date (notmuch_message_t *message); -/* Get the value of the specified header from 'message' as a UTF-8 string. +/** + * Get the value of the specified header from 'message' as a UTF-8 string. * * Common headers are stored in the database when the message is * indexed and will be returned from the database. Other headers will @@ -1087,7 +1224,8 @@ notmuch_message_get_date (notmuch_message_t *message); const char * notmuch_message_get_header (notmuch_message_t *message, const char *header); -/* Get the tags for 'message', returning a notmuch_tags_t object which +/** + * Get the tags for 'message', returning a notmuch_tags_t object which * can be used to iterate over all tags. * * The tags object is owned by the message and as such, will only be @@ -1104,7 +1242,7 @@ notmuch_message_get_header (notmuch_message_t *message, const char *header); * * for (tags = notmuch_message_get_tags (message); * notmuch_tags_valid (tags); - * notmuch_result_move_to_next (tags)) + * notmuch_tags_move_to_next (tags)) * { * tag = notmuch_tags_get (tags); * .... @@ -1120,10 +1258,13 @@ notmuch_message_get_header (notmuch_message_t *message, const char *header); notmuch_tags_t * notmuch_message_get_tags (notmuch_message_t *message); -/* The longest possible tag value. */ +/** + * The longest possible tag value. + */ #define NOTMUCH_TAG_MAX 200 -/* Add a tag to the given message. +/** + * Add a tag to the given message. * * Return value: * @@ -1140,7 +1281,8 @@ notmuch_message_get_tags (notmuch_message_t *message); notmuch_status_t notmuch_message_add_tag (notmuch_message_t *message, const char *tag); -/* Remove a tag from the given message. +/** + * Remove a tag from the given message. * * Return value: * @@ -1157,7 +1299,8 @@ notmuch_message_add_tag (notmuch_message_t *message, const char *tag); notmuch_status_t notmuch_message_remove_tag (notmuch_message_t *message, const char *tag); -/* Remove all tags from the given message. +/** + * Remove all tags from the given message. * * See notmuch_message_freeze for an example showing how to safely * replace tag values. @@ -1168,7 +1311,8 @@ notmuch_message_remove_tag (notmuch_message_t *message, const char *tag); notmuch_status_t notmuch_message_remove_all_tags (notmuch_message_t *message); -/* Add/remove tags according to maildir flags in the message filename(s) +/** + * Add/remove tags according to maildir flags in the message filename(s). * * This function examines the filenames of 'message' for maildir * flags, and adds or removes tags on 'message' as follows when these @@ -1202,7 +1346,8 @@ notmuch_message_remove_all_tags (notmuch_message_t *message); notmuch_status_t notmuch_message_maildir_flags_to_tags (notmuch_message_t *message); -/* Rename message filename(s) to encode tags as maildir flags +/** + * Rename message filename(s) to encode tags as maildir flags. * * Specifically, for each filename corresponding to this message: * @@ -1238,7 +1383,8 @@ notmuch_message_maildir_flags_to_tags (notmuch_message_t *message); notmuch_status_t notmuch_message_tags_to_maildir_flags (notmuch_message_t *message); -/* Freeze the current state of 'message' within the database. +/** + * Freeze the current state of 'message' within the database. * * This means that changes to the message state, (via * notmuch_message_add_tag, notmuch_message_remove_tag, and @@ -1281,7 +1427,8 @@ notmuch_message_tags_to_maildir_flags (notmuch_message_t *message); notmuch_status_t notmuch_message_freeze (notmuch_message_t *message); -/* Thaw the current 'message', synchronizing any changes that may have +/** + * Thaw the current 'message', synchronizing any changes that may have * occurred while 'message' was frozen into the notmuch database. * * See notmuch_message_freeze for an example of how to use this @@ -1304,7 +1451,8 @@ notmuch_message_freeze (notmuch_message_t *message); notmuch_status_t notmuch_message_thaw (notmuch_message_t *message); -/* Destroy a notmuch_message_t object. +/** + * Destroy a notmuch_message_t object. * * It can be useful to call this function in the case of a single * query object with many messages in the result, (such as iterating @@ -1315,7 +1463,8 @@ notmuch_message_thaw (notmuch_message_t *message); void notmuch_message_destroy (notmuch_message_t *message); -/* Is the given 'tags' iterator pointing at a valid tag. +/** + * Is the given 'tags' iterator pointing at a valid tag. * * When this function returns TRUE, notmuch_tags_get will return a * valid string. Whereas when this function returns FALSE, @@ -1327,7 +1476,8 @@ notmuch_message_destroy (notmuch_message_t *message); notmuch_bool_t notmuch_tags_valid (notmuch_tags_t *tags); -/* Get the current tag from 'tags' as a string. +/** + * Get the current tag from 'tags' as a string. * * Note: The returned string belongs to 'tags' and has a lifetime * identical to it (and the query to which it ultimately belongs). @@ -1338,7 +1488,8 @@ notmuch_tags_valid (notmuch_tags_t *tags); const char * notmuch_tags_get (notmuch_tags_t *tags); -/* Move the 'tags' iterator to the next tag. +/** + * Move the 'tags' iterator to the next tag. * * If 'tags' is already pointing at the last tag then the iterator * will be moved to a point just beyond that last tag, (where @@ -1351,7 +1502,8 @@ notmuch_tags_get (notmuch_tags_t *tags); void notmuch_tags_move_to_next (notmuch_tags_t *tags); -/* Destroy a notmuch_tags_t object. +/** + * Destroy a notmuch_tags_t object. * * It's not strictly necessary to call this function. All memory from * the notmuch_tags_t object will be reclaimed when the containing @@ -1360,7 +1512,8 @@ notmuch_tags_move_to_next (notmuch_tags_t *tags); void notmuch_tags_destroy (notmuch_tags_t *tags); -/* Store an mtime within the database for 'directory'. +/** + * Store an mtime within the database for 'directory'. * * The 'directory' should be an object retrieved from the database * with notmuch_database_get_directory for a particular path. @@ -1400,35 +1553,44 @@ notmuch_status_t notmuch_directory_set_mtime (notmuch_directory_t *directory, time_t mtime); -/* Get the mtime of a directory, (as previously stored with +/** + * Get the mtime of a directory, (as previously stored with * notmuch_directory_set_mtime). * * Returns 0 if no mtime has previously been stored for this - * directory.*/ + * directory. + */ time_t notmuch_directory_get_mtime (notmuch_directory_t *directory); -/* Get a notmuch_filenames_t iterator listing all the filenames of +/** + * Get a notmuch_filenames_t iterator listing all the filenames of * messages in the database within the given directory. * * The returned filenames will be the basename-entries only (not - * complete paths). */ + * complete paths). + */ notmuch_filenames_t * notmuch_directory_get_child_files (notmuch_directory_t *directory); -/* Get a notmuch_filenams_t iterator listing all the filenames of +/** + * Get a notmuch_filenams_t iterator listing all the filenames of * sub-directories in the database within the given directory. * * The returned filenames will be the basename-entries only (not - * complete paths). */ + * complete paths). + */ notmuch_filenames_t * notmuch_directory_get_child_directories (notmuch_directory_t *directory); -/* Destroy a notmuch_directory_t object. */ +/** + * Destroy a notmuch_directory_t object. + */ void notmuch_directory_destroy (notmuch_directory_t *directory); -/* Is the given 'filenames' iterator pointing at a valid filename. +/** + * Is the given 'filenames' iterator pointing at a valid filename. * * When this function returns TRUE, notmuch_filenames_get will return * a valid string. Whereas when this function returns FALSE, @@ -1440,7 +1602,8 @@ notmuch_directory_destroy (notmuch_directory_t *directory); notmuch_bool_t notmuch_filenames_valid (notmuch_filenames_t *filenames); -/* Get the current filename from 'filenames' as a string. +/** + * Get the current filename from 'filenames' as a string. * * Note: The returned string belongs to 'filenames' and has a lifetime * identical to it (and the directory to which it ultimately belongs). @@ -1451,7 +1614,8 @@ notmuch_filenames_valid (notmuch_filenames_t *filenames); const char * notmuch_filenames_get (notmuch_filenames_t *filenames); -/* Move the 'filenames' iterator to the next filename. +/** + * Move the 'filenames' iterator to the next filename. * * If 'filenames' is already pointing at the last filename then the * iterator will be moved to a point just beyond that last filename, @@ -1464,7 +1628,8 @@ notmuch_filenames_get (notmuch_filenames_t *filenames); void notmuch_filenames_move_to_next (notmuch_filenames_t *filenames); -/* Destroy a notmuch_filenames_t object. +/** + * Destroy a notmuch_filenames_t object. * * It's not strictly necessary to call this function. All memory from * the notmuch_filenames_t object will be reclaimed when the @@ -1476,6 +1641,8 @@ notmuch_filenames_move_to_next (notmuch_filenames_t *filenames); void notmuch_filenames_destroy (notmuch_filenames_t *filenames); +/* @} */ + NOTMUCH_END_DECLS #endif diff --git a/lib/query.cc b/lib/query.cc index ec60e2e4..60ff8bd9 100644 --- a/lib/query.cc +++ b/lib/query.cc @@ -462,6 +462,9 @@ notmuch_threads_valid (notmuch_threads_t *threads) { unsigned int doc_id; + if (! threads) + return FALSE; + while (threads->doc_id_pos < threads->doc_ids->len) { doc_id = g_array_index (threads->doc_ids, unsigned int, threads->doc_id_pos); diff --git a/lib/thread.cc b/lib/thread.cc index 4dcf7053..8f53e122 100644 --- a/lib/thread.cc +++ b/lib/thread.cc @@ -524,7 +524,7 @@ _notmuch_thread_create (void *ctx, _resolve_thread_relationships (thread); /* Commit to returning thread. */ - talloc_steal (ctx, thread); + (void) talloc_steal (ctx, thread); DONE: talloc_free (local); diff --git a/man/man1/notmuch-dump.1 b/man/man1/notmuch-dump.1 index 0c52d1b7..16e72eb0 100644 --- a/man/man1/notmuch-dump.1 +++ b/man/man1/notmuch-dump.1 @@ -26,6 +26,34 @@ incremental backup than the native database files.) Notmuch restore supports two plain text dump formats, both with one message-id per line, followed by a list of tags. +.RS 4 +.TP 4 +.B batch-tag + +The default +.B batch-tag +dump format is intended to more robust against malformed message-ids +and tags containing whitespace or non-\fBascii\fR(7) characters. +Each line has the form + +.RS 4 +.RI "+<" "encoded-tag" "> " "" "+<" "encoded-tag" "> ... -- " "" " id:<" quoted-message-id > + +Tags are hex-encoded by replacing every byte not matching the regex +.B [A-Za-z0-9@=.,_+-] +with +.B %nn +where nn is the two digit hex encoding. The message ID is a valid Xapian +query, quoted using Xapian boolean term quoting rules: if the ID contains +whitespace or a close paren or starts with a double quote, it must be +enclosed in double quotes and double quotes inside the ID must be doubled. +The astute reader will notice this is a special case of the batch input +format for \fBnotmuch-tag\fR(1); note that the single message-id query is +mandatory for \fBnotmuch-restore\fR(1). + +.RE +.RE + .RS 4 .TP 4 .B sup @@ -52,32 +80,6 @@ that tags with spaces will not be correctly restored with this format. .RE -.RE -.RS 4 -.TP 4 -.B batch-tag - -The -.B batch-tag -dump format is intended to more robust against malformed message-ids -and tags containing whitespace or non-\fBascii\fR(7) characters. -Each line has the form - -.RS 4 -.RI "+<" "encoded-tag" "> " "" "+<" "encoded-tag" "> ... -- " "" " id:<" quoted-message-id > - -Tags are hex-encoded by replacing every byte not matching the regex -.B [A-Za-z0-9@=.,_+-] -with -.B %nn -where nn is the two digit hex encoding. The message ID is a valid Xapian -query, quoted using Xapian boolean term quoting rules: if the ID contains -whitespace or a close paren or starts with a double quote, it must be -enclosed in double quotes and double quotes inside the ID must be doubled. -The astute reader will notice this is a special case of the batch input -format for \fBnotmuch-tag\fR(1); note that the single message-id query is -mandatory for \fBnotmuch-restore\fR(1). - .RE diff --git a/man/man1/notmuch-new.1 b/man/man1/notmuch-new.1 index 5725b7d8..7e719262 100644 --- a/man/man1/notmuch-new.1 +++ b/man/man1/notmuch-new.1 @@ -60,6 +60,11 @@ include Prevents hooks from being run. .RE +.RS 4 +.TP 4 +.BR \-\-quiet +Do not print progress or results. +.RE .RE .SH SEE ALSO diff --git a/notmuch-compact.c b/notmuch-compact.c index 8b820c0d..2fc012a9 100644 --- a/notmuch-compact.c +++ b/notmuch-compact.c @@ -32,7 +32,7 @@ notmuch_compact_command (notmuch_config_t *config, int argc, char *argv[]) const char *path = notmuch_config_get_database_path (config); const char *backup_path = NULL; notmuch_status_t ret; - notmuch_bool_t quiet; + notmuch_bool_t quiet = FALSE; int opt_index; notmuch_opt_desc_t options[] = { @@ -42,7 +42,7 @@ notmuch_compact_command (notmuch_config_t *config, int argc, char *argv[]) opt_index = parse_arguments (argc, argv, options, 1); if (opt_index < 0) - return 1; + return EXIT_FAILURE; if (! quiet) printf ("Compacting database...\n"); @@ -50,7 +50,7 @@ notmuch_compact_command (notmuch_config_t *config, int argc, char *argv[]) quiet ? NULL : status_update_cb, NULL); if (ret) { fprintf (stderr, "Compaction failed: %s\n", notmuch_status_to_string (ret)); - return 1; + return EXIT_FAILURE; } if (! quiet) { @@ -60,5 +60,5 @@ notmuch_compact_command (notmuch_config_t *config, int argc, char *argv[]) printf ("Done.\n"); } - return 0; + return EXIT_SUCCESS; } diff --git a/notmuch-config.c b/notmuch-config.c index 6845e3c3..8d286538 100644 --- a/notmuch-config.c +++ b/notmuch-config.c @@ -496,6 +496,32 @@ notmuch_config_is_new (notmuch_config_t *config) return config->is_new; } +static const char * +_config_get (notmuch_config_t *config, char **field, + const char *group, const char *key) +{ + /* read from config file and cache value, if not cached already */ + if (*field == NULL) { + char *value; + value = g_key_file_get_string (config->key_file, group, key, NULL); + if (value) { + *field = talloc_strdup (config, value); + free (value); + } + } + return *field; +} + +static void +_config_set (notmuch_config_t *config, char **field, + const char *group, const char *key, const char *value) +{ + g_key_file_set_string (config->key_file, group, key, value); + + /* drop the cached value */ + talloc_free (*field); + *field = NULL; +} static const char ** _config_get_list (notmuch_config_t *config, @@ -504,6 +530,7 @@ _config_get_list (notmuch_config_t *config, { assert(outlist); + /* read from config file and cache value, if not cached already */ if (*outlist == NULL) { char **inlist = g_key_file_get_string_list (config->key_file, @@ -535,6 +562,8 @@ _config_set_list (notmuch_config_t *config, size_t length, const char ***config_var ) { g_key_file_set_string_list (config->key_file, group, name, list, length); + + /* drop the cached value */ talloc_free (*config_var); *config_var = NULL; } @@ -542,85 +571,40 @@ _config_set_list (notmuch_config_t *config, const char * notmuch_config_get_database_path (notmuch_config_t *config) { - char *path; - - if (config->database_path == NULL) { - path = g_key_file_get_string (config->key_file, - "database", "path", NULL); - if (path) { - config->database_path = talloc_strdup (config, path); - free (path); - } - } - - return config->database_path; + return _config_get (config, &config->database_path, "database", "path"); } void notmuch_config_set_database_path (notmuch_config_t *config, const char *database_path) { - g_key_file_set_string (config->key_file, - "database", "path", database_path); - - talloc_free (config->database_path); - config->database_path = NULL; + _config_set (config, &config->database_path, "database", "path", database_path); } const char * notmuch_config_get_user_name (notmuch_config_t *config) { - char *name; - - if (config->user_name == NULL) { - name = g_key_file_get_string (config->key_file, - "user", "name", NULL); - if (name) { - config->user_name = talloc_strdup (config, name); - free (name); - } - } - - return config->user_name; + return _config_get (config, &config->user_name, "user", "name"); } void notmuch_config_set_user_name (notmuch_config_t *config, const char *user_name) { - g_key_file_set_string (config->key_file, - "user", "name", user_name); - - talloc_free (config->user_name); - config->user_name = NULL; + _config_set (config, &config->user_name, "user", "name", user_name); } const char * notmuch_config_get_user_primary_email (notmuch_config_t *config) { - char *email; - - if (config->user_primary_email == NULL) { - email = g_key_file_get_string (config->key_file, - "user", "primary_email", NULL); - if (email) { - config->user_primary_email = talloc_strdup (config, email); - free (email); - } - } - - return config->user_primary_email; + return _config_get (config, &config->user_primary_email, "user", "primary_email"); } void notmuch_config_set_user_primary_email (notmuch_config_t *config, const char *primary_email) { - g_key_file_set_string (config->key_file, - "user", "primary_email", primary_email); - - talloc_free (config->user_primary_email); - config->user_primary_email = NULL; + _config_set (config, &config->user_primary_email, "user", "primary_email", primary_email); } const char ** @@ -839,34 +823,39 @@ notmuch_config_command_list (notmuch_config_t *config) int notmuch_config_command (notmuch_config_t *config, int argc, char *argv[]) { + int ret; + argc--; argv++; /* skip subcommand argument */ if (argc < 1) { fprintf (stderr, "Error: notmuch config requires at least one argument.\n"); - return 1; + return EXIT_FAILURE; } if (strcmp (argv[0], "get") == 0) { if (argc != 2) { fprintf (stderr, "Error: notmuch config get requires exactly " "one argument.\n"); - return 1; + return EXIT_FAILURE; } - return notmuch_config_command_get (config, argv[1]); + ret = notmuch_config_command_get (config, argv[1]); } else if (strcmp (argv[0], "set") == 0) { if (argc < 2) { fprintf (stderr, "Error: notmuch config set requires at least " "one argument.\n"); - return 1; + return EXIT_FAILURE; } - return notmuch_config_command_set (config, argv[1], argc - 2, argv + 2); + ret = notmuch_config_command_set (config, argv[1], argc - 2, argv + 2); } else if (strcmp (argv[0], "list") == 0) { - return notmuch_config_command_list (config); + ret = notmuch_config_command_list (config); + } else { + fprintf (stderr, "Unrecognized argument for notmuch config: %s\n", + argv[0]); + return EXIT_FAILURE; } - fprintf (stderr, "Unrecognized argument for notmuch config: %s\n", - argv[0]); - return 1; + return ret ? EXIT_FAILURE : EXIT_SUCCESS; + } notmuch_bool_t diff --git a/notmuch-count.c b/notmuch-count.c index 01e4e301..6058f7c9 100644 --- a/notmuch-count.c +++ b/notmuch-count.c @@ -150,10 +150,8 @@ notmuch_count_command (notmuch_config_t *config, int argc, char *argv[]) }; opt_index = parse_arguments (argc, argv, options, 1); - - if (opt_index < 0) { - return 1; - } + if (opt_index < 0) + return EXIT_FAILURE; if (input_file_name) { batch = TRUE; @@ -161,23 +159,23 @@ notmuch_count_command (notmuch_config_t *config, int argc, char *argv[]) if (input == NULL) { fprintf (stderr, "Error opening %s for reading: %s\n", input_file_name, strerror (errno)); - return 1; + return EXIT_FAILURE; } } if (batch && opt_index != argc) { fprintf (stderr, "--batch and query string are not compatible\n"); - return 1; + return EXIT_FAILURE; } if (notmuch_database_open (notmuch_config_get_database_path (config), NOTMUCH_DATABASE_MODE_READ_ONLY, ¬much)) - return 1; + return EXIT_FAILURE; query_str = query_string_from_args (config, argc-opt_index, argv+opt_index); if (query_str == NULL) { fprintf (stderr, "Out of memory.\n"); - return 1; + return EXIT_FAILURE; } if (exclude == EXCLUDE_TRUE) { @@ -197,5 +195,5 @@ notmuch_count_command (notmuch_config_t *config, int argc, char *argv[]) if (input != stdin) fclose (input); - return ret; + return ret ? EXIT_FAILURE : EXIT_SUCCESS; } diff --git a/notmuch-dump.c b/notmuch-dump.c index 2024e303..158142f5 100644 --- a/notmuch-dump.c +++ b/notmuch-dump.c @@ -35,12 +35,12 @@ notmuch_dump_command (notmuch_config_t *config, int argc, char *argv[]) if (notmuch_database_open (notmuch_config_get_database_path (config), NOTMUCH_DATABASE_MODE_READ_ONLY, ¬much)) - return 1; + return EXIT_FAILURE; char *output_file_name = NULL; int opt_index; - int output_format = DUMP_FORMAT_SUP; + int output_format = DUMP_FORMAT_BATCH_TAG; notmuch_opt_desc_t options[] = { { NOTMUCH_OPT_KEYWORD, &output_format, "format", 'f', @@ -52,18 +52,15 @@ notmuch_dump_command (notmuch_config_t *config, int argc, char *argv[]) }; opt_index = parse_arguments (argc, argv, options, 1); - - if (opt_index < 0) { - /* diagnostics already printed */ - return 1; - } + if (opt_index < 0) + return EXIT_FAILURE; if (output_file_name) { output = fopen (output_file_name, "w"); if (output == NULL) { fprintf (stderr, "Error opening %s for writing: %s\n", output_file_name, strerror (errno)); - return 1; + return EXIT_FAILURE; } } @@ -72,14 +69,14 @@ notmuch_dump_command (notmuch_config_t *config, int argc, char *argv[]) query_str = query_string_from_args (notmuch, argc - opt_index, argv + opt_index); if (query_str == NULL) { fprintf (stderr, "Out of memory.\n"); - return 1; + return EXIT_FAILURE; } } query = notmuch_query_create (notmuch, query_str); if (query == NULL) { fprintf (stderr, "Out of memory\n"); - return 1; + return EXIT_FAILURE; } /* Don't ask xapian to sort by Message-ID. Xapian optimizes returning the * first results quickly at the expense of total time. @@ -131,7 +128,7 @@ notmuch_dump_command (notmuch_config_t *config, int argc, char *argv[]) &buffer, &buffer_size) != HEX_SUCCESS) { fprintf (stderr, "Error: failed to hex-encode tag %s\n", tag_str); - return 1; + return EXIT_FAILURE; } fprintf (output, "+%s", buffer); } @@ -144,7 +141,7 @@ notmuch_dump_command (notmuch_config_t *config, int argc, char *argv[]) &buffer, &buffer_size)) { fprintf (stderr, "Error quoting message id %s: %s\n", message_id, strerror (errno)); - return 1; + return EXIT_FAILURE; } fprintf (output, " -- %s\n", buffer); } @@ -158,5 +155,5 @@ notmuch_dump_command (notmuch_config_t *config, int argc, char *argv[]) notmuch_query_destroy (query); notmuch_database_destroy (notmuch); - return 0; + return EXIT_SUCCESS; } diff --git a/notmuch-insert.c b/notmuch-insert.c index 2207b1e8..cd6de88f 100644 --- a/notmuch-insert.c +++ b/notmuch-insert.c @@ -295,7 +295,7 @@ copy_stdin (int fdin, int fdout) * The file is renamed to encode notmuch tags as maildir flags. */ static void add_file_to_database (notmuch_database_t *notmuch, const char *path, - tag_op_list_t *tag_ops) + tag_op_list_t *tag_ops, notmuch_bool_t synchronize_flags) { notmuch_message_t *message; notmuch_status_t status; @@ -323,11 +323,15 @@ add_file_to_database (notmuch_database_t *notmuch, const char *path, if (status == NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID) { /* Don't change tags of an existing message. */ - status = notmuch_message_tags_to_maildir_flags (message); - if (status != NOTMUCH_STATUS_SUCCESS) - fprintf (stderr, "Error: failed to sync tags to maildir flags\n"); + if (synchronize_flags) { + status = notmuch_message_tags_to_maildir_flags (message); + if (status != NOTMUCH_STATUS_SUCCESS) + fprintf (stderr, "Error: failed to sync tags to maildir flags\n"); + } } else { - tag_op_list_apply (message, tag_ops, TAG_FLAG_MAILDIR_SYNC); + tag_op_flag_t flags = synchronize_flags ? TAG_FLAG_MAILDIR_SYNC : 0; + + tag_op_list_apply (message, tag_ops, flags); } notmuch_message_destroy (message); @@ -335,7 +339,8 @@ add_file_to_database (notmuch_database_t *notmuch, const char *path, static notmuch_bool_t insert_message (void *ctx, notmuch_database_t *notmuch, int fdin, - const char *dir, tag_op_list_t *tag_ops) + const char *dir, tag_op_list_t *tag_ops, + notmuch_bool_t synchronize_flags) { char *tmppath; char *newpath; @@ -377,7 +382,7 @@ insert_message (void *ctx, notmuch_database_t *notmuch, int fdin, /* Even if adding the message to the notmuch database fails, * the message is on disk and we consider the delivery completed. */ - add_file_to_database (notmuch, newpath, tag_ops); + add_file_to_database (notmuch, newpath, tag_ops, synchronize_flags); return TRUE; @@ -400,6 +405,7 @@ notmuch_insert_command (notmuch_config_t *config, int argc, char *argv[]) char *query_string = NULL; const char *folder = NULL; notmuch_bool_t create_folder = FALSE; + notmuch_bool_t synchronize_flags; const char *maildir; int opt_index; unsigned int i; @@ -412,32 +418,30 @@ notmuch_insert_command (notmuch_config_t *config, int argc, char *argv[]) }; opt_index = parse_arguments (argc, argv, options, 1); - - if (opt_index < 0) { - /* diagnostics already printed */ - return 1; - } + if (opt_index < 0) + return EXIT_FAILURE; db_path = notmuch_config_get_database_path (config); new_tags = notmuch_config_get_new_tags (config, &new_tags_length); + synchronize_flags = notmuch_config_get_maildir_synchronize_flags (config); tag_ops = tag_op_list_create (config); if (tag_ops == NULL) { fprintf (stderr, "Out of memory.\n"); - return 1; + return EXIT_FAILURE; } for (i = 0; i < new_tags_length; i++) { if (tag_op_list_append (tag_ops, new_tags[i], FALSE)) - return 1; + return EXIT_FAILURE; } if (parse_tag_command_line (config, argc - opt_index, argv + opt_index, &query_string, tag_ops)) - return 1; + return EXIT_FAILURE; if (*query_string != '\0') { fprintf (stderr, "Error: unexpected query string: %s\n", query_string); - return 1; + return EXIT_FAILURE; } if (folder == NULL) { @@ -445,17 +449,17 @@ notmuch_insert_command (notmuch_config_t *config, int argc, char *argv[]) } else { if (! check_folder_name (folder)) { fprintf (stderr, "Error: bad folder name: %s\n", folder); - return 1; + return EXIT_FAILURE; } maildir = talloc_asprintf (config, "%s/%s", db_path, folder); if (! maildir) { fprintf (stderr, "Out of memory\n"); - return 1; + return EXIT_FAILURE; } if (create_folder && ! maildir_create_folder (config, maildir)) { fprintf (stderr, "Error: creating maildir %s: %s\n", maildir, strerror (errno)); - return 1; + return EXIT_FAILURE; } } @@ -469,11 +473,12 @@ notmuch_insert_command (notmuch_config_t *config, int argc, char *argv[]) if (notmuch_database_open (notmuch_config_get_database_path (config), NOTMUCH_DATABASE_MODE_READ_WRITE, ¬much)) - return 1; + return EXIT_FAILURE; - ret = insert_message (config, notmuch, STDIN_FILENO, maildir, tag_ops); + ret = insert_message (config, notmuch, STDIN_FILENO, maildir, tag_ops, + synchronize_flags); notmuch_database_destroy (notmuch); - return (ret) ? 0 : 1; + return ret ? EXIT_SUCCESS : EXIT_FAILURE; } diff --git a/notmuch-new.c b/notmuch-new.c index ba05cb41..8529fdd3 100644 --- a/notmuch-new.c +++ b/notmuch-new.c @@ -34,9 +34,15 @@ typedef struct _filename_list { _filename_node_t **tail; } _filename_list_t; +enum verbosity { + VERBOSITY_QUIET, + VERBOSITY_NORMAL, + VERBOSITY_VERBOSE, +}; + typedef struct { int output_is_a_tty; - notmuch_bool_t verbose; + enum verbosity verbosity; notmuch_bool_t debug; const char **new_tags; size_t new_tags_length; @@ -167,7 +173,7 @@ dirent_type (const char *path, const struct dirent *entry) char *abspath; int err, saved_errno; -#ifdef _DIRENT_HAVE_D_TYPE +#if HAVE_D_TYPE /* Mapping from d_type to stat mode_t. We omit DT_LNK so that * we'll fall through to stat and get the real file type. */ static const mode_t modes[] = { @@ -240,6 +246,60 @@ _entry_in_ignore_list (const char *entry, add_files_state_t *state) return FALSE; } +/* Add a single file to the database. */ +static notmuch_status_t +add_file (notmuch_database_t *notmuch, const char *filename, + add_files_state_t *state) +{ + notmuch_message_t *message = NULL; + const char **tag; + notmuch_status_t status; + + status = notmuch_database_begin_atomic (notmuch); + if (status) + goto DONE; + + status = notmuch_database_add_message (notmuch, filename, &message); + switch (status) { + /* Success. */ + case NOTMUCH_STATUS_SUCCESS: + state->added_messages++; + notmuch_message_freeze (message); + for (tag = state->new_tags; *tag != NULL; tag++) + notmuch_message_add_tag (message, *tag); + if (state->synchronize_flags) + notmuch_message_maildir_flags_to_tags (message); + notmuch_message_thaw (message); + break; + /* Non-fatal issues (go on to next file). */ + case NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID: + if (state->synchronize_flags) + notmuch_message_maildir_flags_to_tags (message); + break; + case NOTMUCH_STATUS_FILE_NOT_EMAIL: + fprintf (stderr, "Note: Ignoring non-mail file: %s\n", filename); + break; + /* Fatal issues. Don't process anymore. */ + case NOTMUCH_STATUS_READ_ONLY_DATABASE: + case NOTMUCH_STATUS_XAPIAN_EXCEPTION: + case NOTMUCH_STATUS_OUT_OF_MEMORY: + fprintf (stderr, "Error: %s. Halting processing.\n", + notmuch_status_to_string (status)); + goto DONE; + default: + INTERNAL_ERROR ("add_message returned unexpected value: %d", status); + goto DONE; + } + + status = notmuch_database_end_atomic (notmuch); + + DONE: + if (message) + notmuch_message_destroy (message); + + return status; +} + /* Examine 'path' recursively as follows: * * o Ask the filesystem for the mtime of 'path' (fs_mtime) @@ -291,7 +351,6 @@ add_files (notmuch_database_t *notmuch, char *next = NULL; time_t fs_mtime, db_mtime; notmuch_status_t status, ret = NOTMUCH_STATUS_SUCCESS; - notmuch_message_t *message = NULL; struct dirent **fs_entries = NULL; int i, num_fs_entries = 0, entry_type; notmuch_directory_t *directory; @@ -300,7 +359,6 @@ add_files (notmuch_database_t *notmuch, time_t stat_time; struct stat st; notmuch_bool_t is_maildir; - const char **tag; if (stat (path, &st)) { fprintf (stderr, "Error reading directory %s: %s\n", @@ -514,76 +572,23 @@ add_files (notmuch_database_t *notmuch, state->processed_files++; - if (state->verbose) { + if (state->verbosity >= VERBOSITY_VERBOSE) { if (state->output_is_a_tty) printf("\r\033[K"); - printf ("%i/%i: %s", - state->processed_files, - state->total_files, + printf ("%i/%i: %s", state->processed_files, state->total_files, next); putchar((state->output_is_a_tty) ? '\r' : '\n'); fflush (stdout); } - status = notmuch_database_begin_atomic (notmuch); + status = add_file (notmuch, next, state); if (status) { ret = status; goto DONE; } - status = notmuch_database_add_message (notmuch, next, &message); - switch (status) { - /* success */ - case NOTMUCH_STATUS_SUCCESS: - state->added_messages++; - notmuch_message_freeze (message); - for (tag=state->new_tags; *tag != NULL; tag++) - notmuch_message_add_tag (message, *tag); - if (state->synchronize_flags == TRUE) - notmuch_message_maildir_flags_to_tags (message); - notmuch_message_thaw (message); - break; - /* Non-fatal issues (go on to next file) */ - case NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID: - if (state->synchronize_flags == TRUE) - notmuch_message_maildir_flags_to_tags (message); - break; - case NOTMUCH_STATUS_FILE_NOT_EMAIL: - fprintf (stderr, "Note: Ignoring non-mail file: %s\n", - next); - break; - /* Fatal issues. Don't process anymore. */ - case NOTMUCH_STATUS_READ_ONLY_DATABASE: - case NOTMUCH_STATUS_XAPIAN_EXCEPTION: - case NOTMUCH_STATUS_OUT_OF_MEMORY: - fprintf (stderr, "Error: %s. Halting processing.\n", - notmuch_status_to_string (status)); - ret = status; - goto DONE; - default: - case NOTMUCH_STATUS_FILE_ERROR: - case NOTMUCH_STATUS_NULL_POINTER: - case NOTMUCH_STATUS_TAG_TOO_LONG: - case NOTMUCH_STATUS_UNBALANCED_FREEZE_THAW: - case NOTMUCH_STATUS_UNBALANCED_ATOMIC: - case NOTMUCH_STATUS_LAST_STATUS: - INTERNAL_ERROR ("add_message returned unexpected value: %d", status); - goto DONE; - } - - status = notmuch_database_end_atomic (notmuch); - if (status) { - ret = status; - goto DONE; - } - - if (message) { - notmuch_message_destroy (message); - message = NULL; - } - if (do_print_progress) { do_print_progress = 0; generic_print_progress ("Processed", "files", state->tv_start, @@ -701,10 +706,9 @@ count_files (const char *path, int *count, add_files_state_t *state) { struct dirent *entry = NULL; char *next; - struct stat st; struct dirent **fs_entries = NULL; int num_fs_entries = scandir (path, &fs_entries, 0, dirent_sort_inode); - int i = 0; + int entry_type, i; if (num_fs_entries == -1) { fprintf (stderr, "Warning: failed to open directory %s: %s\n", @@ -712,11 +716,8 @@ count_files (const char *path, int *count, add_files_state_t *state) goto DONE; } - while (!interrupted) { - if (i == num_fs_entries) - break; - - entry = fs_entries[i++]; + for (i = 0; i < num_fs_entries && ! interrupted; i++) { + entry = fs_entries[i]; /* Ignore special directories to avoid infinite recursion. * Also ignore the .notmuch directory and files/directories @@ -727,7 +728,7 @@ count_files (const char *path, int *count, add_files_state_t *state) strcmp (entry->d_name, ".notmuch") == 0 || _entry_in_ignore_list (entry->d_name, state)) { - if (_entry_in_ignore_list (entry->d_name, state) && state->debug) + if (state->debug && _entry_in_ignore_list (entry->d_name, state)) printf ("(D) count_files: explicitly ignoring %s/%s\n", path, entry->d_name); @@ -741,15 +742,14 @@ count_files (const char *path, int *count, add_files_state_t *state) continue; } - stat (next, &st); - - if (S_ISREG (st.st_mode)) { + entry_type = dirent_type (path, entry); + if (entry_type == S_IFREG) { *count = *count + 1; - if (*count % 1000 == 0) { + if (*count % 1000 == 0 && state->verbosity >= VERBOSITY_NORMAL) { printf ("Found %d files so far.\r", *count); fflush (stdout); } - } else if (S_ISDIR (st.st_mode)) { + } else if (entry_type == S_IFDIR) { count_files (next, count, state); } @@ -868,13 +868,49 @@ _remove_directory (void *ctx, return status; } +static void +print_results (const add_files_state_t *state) +{ + double elapsed; + struct timeval tv_now; + + gettimeofday (&tv_now, NULL); + elapsed = notmuch_time_elapsed (state->tv_start, tv_now); + + if (state->processed_files) { + printf ("Processed %d %s in ", state->processed_files, + state->processed_files == 1 ? "file" : "total files"); + notmuch_time_print_formatted_seconds (elapsed); + if (elapsed > 1) + printf (" (%d files/sec.).\033[K\n", + (int) (state->processed_files / elapsed)); + else + printf (".\033[K\n"); + } + + if (state->added_messages) + printf ("Added %d new %s to the database.", state->added_messages, + state->added_messages == 1 ? "message" : "messages"); + else + printf ("No new mail."); + + if (state->removed_messages) + printf (" Removed %d %s.", state->removed_messages, + state->removed_messages == 1 ? "message" : "messages"); + + if (state->renamed_messages) + printf (" Detected %d file %s.", state->renamed_messages, + state->renamed_messages == 1 ? "rename" : "renames"); + + printf ("\n"); +} + int notmuch_new_command (notmuch_config_t *config, int argc, char *argv[]) { notmuch_database_t *notmuch; add_files_state_t add_files_state; - double elapsed; - struct timeval tv_now, tv_start; + struct timeval tv_start; int ret = 0; struct stat st; const char *db_path; @@ -885,23 +921,29 @@ notmuch_new_command (notmuch_config_t *config, int argc, char *argv[]) int i; notmuch_bool_t timer_is_active = FALSE; notmuch_bool_t no_hooks = FALSE; + notmuch_bool_t quiet = FALSE, verbose = FALSE; - add_files_state.verbose = FALSE; + add_files_state.verbosity = VERBOSITY_NORMAL; add_files_state.debug = FALSE; add_files_state.output_is_a_tty = isatty (fileno (stdout)); notmuch_opt_desc_t options[] = { - { NOTMUCH_OPT_BOOLEAN, &add_files_state.verbose, "verbose", 'v', 0 }, + { NOTMUCH_OPT_BOOLEAN, &quiet, "quiet", 'q', 0 }, + { NOTMUCH_OPT_BOOLEAN, &verbose, "verbose", 'v', 0 }, { NOTMUCH_OPT_BOOLEAN, &add_files_state.debug, "debug", 'd', 0 }, { NOTMUCH_OPT_BOOLEAN, &no_hooks, "no-hooks", 'n', 0 }, { 0, 0, 0, 0, 0 } }; opt_index = parse_arguments (argc, argv, options, 1); - if (opt_index < 0) { - /* diagnostics already printed */ - return 1; - } + if (opt_index < 0) + return EXIT_FAILURE; + + /* quiet trumps verbose */ + if (quiet) + add_files_state.verbosity = VERBOSITY_QUIET; + else if (verbose) + add_files_state.verbosity = VERBOSITY_VERBOSE; add_files_state.new_tags = notmuch_config_get_new_tags (config, &add_files_state.new_tags_length); add_files_state.new_ignore = notmuch_config_get_new_ignore (config, &add_files_state.new_ignore_length); @@ -911,7 +953,7 @@ notmuch_new_command (notmuch_config_t *config, int argc, char *argv[]) if (!no_hooks) { ret = notmuch_run_hook (db_path, "pre-new"); if (ret) - return ret; + return EXIT_FAILURE; } dot_notmuch_path = talloc_asprintf (config, "%s/%s", db_path, ".notmuch"); @@ -922,23 +964,27 @@ notmuch_new_command (notmuch_config_t *config, int argc, char *argv[]) count = 0; count_files (db_path, &count, &add_files_state); if (interrupted) - return 1; + return EXIT_FAILURE; - printf ("Found %d total files (that's not much mail).\n", count); + if (add_files_state.verbosity >= VERBOSITY_NORMAL) + printf ("Found %d total files (that's not much mail).\n", count); if (notmuch_database_create (db_path, ¬much)) - return 1; + return EXIT_FAILURE; add_files_state.total_files = count; } else { if (notmuch_database_open (db_path, NOTMUCH_DATABASE_MODE_READ_WRITE, ¬much)) - return 1; + return EXIT_FAILURE; if (notmuch_database_needs_upgrade (notmuch)) { - printf ("Welcome to a new version of notmuch! Your database will now be upgraded.\n"); + if (add_files_state.verbosity >= VERBOSITY_NORMAL) + printf ("Welcome to a new version of notmuch! Your database will now be upgraded.\n"); gettimeofday (&add_files_state.tv_start, NULL); - notmuch_database_upgrade (notmuch, upgrade_print_progress, + notmuch_database_upgrade (notmuch, + add_files_state.verbosity >= VERBOSITY_NORMAL ? upgrade_print_progress : NULL, &add_files_state); - printf ("Your notmuch database has now been upgraded to database format version %u.\n", + if (add_files_state.verbosity >= VERBOSITY_NORMAL) + printf ("Your notmuch database has now been upgraded to database format version %u.\n", notmuch_database_get_version (notmuch)); } @@ -946,7 +992,7 @@ notmuch_new_command (notmuch_config_t *config, int argc, char *argv[]) } if (notmuch == NULL) - return 1; + return EXIT_FAILURE; /* Setup our handler for SIGINT. We do this after having * potentially done a database upgrade we this interrupt handler @@ -969,8 +1015,8 @@ notmuch_new_command (notmuch_config_t *config, int argc, char *argv[]) add_files_state.removed_directories = _filename_list_create (config); add_files_state.directory_mtimes = _filename_list_create (config); - if (! debugger_is_active () && add_files_state.output_is_a_tty - && ! add_files_state.verbose) { + if (add_files_state.verbosity == VERBOSITY_NORMAL && + add_files_state.output_is_a_tty && ! debugger_is_active ()) { setup_progress_printing_timer (); timer_is_active = TRUE; } @@ -1023,45 +1069,8 @@ notmuch_new_command (notmuch_config_t *config, int argc, char *argv[]) if (timer_is_active) stop_progress_printing_timer (); - gettimeofday (&tv_now, NULL); - elapsed = notmuch_time_elapsed (add_files_state.tv_start, - tv_now); - - if (add_files_state.processed_files) { - printf ("Processed %d %s in ", add_files_state.processed_files, - add_files_state.processed_files == 1 ? - "file" : "total files"); - notmuch_time_print_formatted_seconds (elapsed); - if (elapsed > 1) { - printf (" (%d files/sec.).\033[K\n", - (int) (add_files_state.processed_files / elapsed)); - } else { - printf (".\033[K\n"); - } - } - - if (add_files_state.added_messages) { - printf ("Added %d new %s to the database.", - add_files_state.added_messages, - add_files_state.added_messages == 1 ? - "message" : "messages"); - } else { - printf ("No new mail."); - } - - if (add_files_state.removed_messages) { - printf (" Removed %d %s.", - add_files_state.removed_messages, - add_files_state.removed_messages == 1 ? "message" : "messages"); - } - - if (add_files_state.renamed_messages) { - printf (" Detected %d file %s.", - add_files_state.renamed_messages, - add_files_state.renamed_messages == 1 ? "rename" : "renames"); - } - - printf ("\n"); + if (add_files_state.verbosity >= VERBOSITY_NORMAL) + print_results (&add_files_state); if (ret) fprintf (stderr, "Note: A fatal error was encountered: %s\n", @@ -1072,5 +1081,5 @@ notmuch_new_command (notmuch_config_t *config, int argc, char *argv[]) if (!no_hooks && !ret && !interrupted) ret = notmuch_run_hook (db_path, "post-new"); - return ret || interrupted; + return ret || interrupted ? EXIT_FAILURE : EXIT_SUCCESS; } diff --git a/notmuch-reply.c b/notmuch-reply.c index 9d6f8436..79cdc833 100644 --- a/notmuch-reply.c +++ b/notmuch-reply.c @@ -704,7 +704,7 @@ notmuch_reply_command (notmuch_config_t *config, int argc, char *argv[]) notmuch_database_t *notmuch; notmuch_query_t *query; char *query_string; - int opt_index, ret = 0; + int opt_index; int (*reply_format_func) (void *ctx, notmuch_config_t *config, notmuch_query_t *query, @@ -739,10 +739,8 @@ notmuch_reply_command (notmuch_config_t *config, int argc, char *argv[]) }; opt_index = parse_arguments (argc, argv, options, 1); - if (opt_index < 0) { - /* diagnostics already printed */ - return 1; - } + if (opt_index < 0) + return EXIT_FAILURE; if (format == FORMAT_HEADERS_ONLY) { reply_format_func = notmuch_reply_format_headers_only; @@ -761,30 +759,30 @@ notmuch_reply_command (notmuch_config_t *config, int argc, char *argv[]) query_string = query_string_from_args (config, argc-opt_index, argv+opt_index); if (query_string == NULL) { fprintf (stderr, "Out of memory\n"); - return 1; + return EXIT_FAILURE; } if (*query_string == '\0') { fprintf (stderr, "Error: notmuch reply requires at least one search term.\n"); - return 1; + return EXIT_FAILURE; } if (notmuch_database_open (notmuch_config_get_database_path (config), NOTMUCH_DATABASE_MODE_READ_ONLY, ¬much)) - return 1; + return EXIT_FAILURE; query = notmuch_query_create (notmuch, query_string); if (query == NULL) { fprintf (stderr, "Out of memory\n"); - return 1; + return EXIT_FAILURE; } if (reply_format_func (config, config, query, ¶ms, reply_all, sp) != 0) - return 1; + return EXIT_FAILURE; notmuch_crypto_cleanup (¶ms.crypto); notmuch_query_destroy (query); notmuch_database_destroy (notmuch); - return ret; + return EXIT_SUCCESS; } diff --git a/notmuch-restore.c b/notmuch-restore.c index 1419621c..f23ab983 100644 --- a/notmuch-restore.c +++ b/notmuch-restore.c @@ -140,7 +140,7 @@ notmuch_restore_command (notmuch_config_t *config, int argc, char *argv[]) if (notmuch_database_open (notmuch_config_get_database_path (config), NOTMUCH_DATABASE_MODE_READ_WRITE, ¬much)) - return 1; + return EXIT_FAILURE; if (notmuch_config_get_maildir_synchronize_flags (config)) flags |= TAG_FLAG_MAILDIR_SYNC; @@ -157,11 +157,8 @@ notmuch_restore_command (notmuch_config_t *config, int argc, char *argv[]) }; opt_index = parse_arguments (argc, argv, options, 1); - - if (opt_index < 0) { - /* diagnostics already printed */ - return 1; - } + if (opt_index < 0) + return EXIT_FAILURE; if (! accumulate) flags |= TAG_FLAG_REMOVE_ALL; @@ -171,21 +168,19 @@ notmuch_restore_command (notmuch_config_t *config, int argc, char *argv[]) if (input == NULL) { fprintf (stderr, "Error opening %s for reading: %s\n", input_file_name, strerror (errno)); - return 1; + return EXIT_FAILURE; } } if (opt_index < argc) { - fprintf (stderr, - "Unused positional parameter: %s\n", - argv[opt_index]); - return 1; + fprintf (stderr, "Unused positional parameter: %s\n", argv[opt_index]); + return EXIT_FAILURE; } tag_ops = tag_op_list_create (config); if (tag_ops == NULL) { fprintf (stderr, "Out of memory.\n"); - return 1; + return EXIT_FAILURE; } do { @@ -193,7 +188,7 @@ notmuch_restore_command (notmuch_config_t *config, int argc, char *argv[]) /* empty input file not considered an error */ if (line_len < 0) - return 0; + return EXIT_SUCCESS; } while ((line_len == 0) || (line[0] == '#') || @@ -275,5 +270,5 @@ notmuch_restore_command (notmuch_config_t *config, int argc, char *argv[]) if (input != stdin) fclose (input); - return ret; + return ret ? EXIT_FAILURE : EXIT_SUCCESS; } diff --git a/notmuch-search.c b/notmuch-search.c index 7c973b3d..91b5d105 100644 --- a/notmuch-search.c +++ b/notmuch-search.c @@ -401,10 +401,8 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[]) }; opt_index = parse_arguments (argc, argv, options, 1); - - if (opt_index < 0) { - return 1; - } + if (opt_index < 0) + return EXIT_FAILURE; switch (format_sel) { case NOTMUCH_FORMAT_TEXT: @@ -413,7 +411,7 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[]) case NOTMUCH_FORMAT_TEXT0: if (output == OUTPUT_SUMMARY) { fprintf (stderr, "Error: --format=text0 is not compatible with --output=summary.\n"); - return 1; + return EXIT_FAILURE; } format = sprinter_text0_create (config, stdout); break; @@ -432,22 +430,22 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[]) if (notmuch_database_open (notmuch_config_get_database_path (config), NOTMUCH_DATABASE_MODE_READ_ONLY, ¬much)) - return 1; + return EXIT_FAILURE; query_str = query_string_from_args (notmuch, argc-opt_index, argv+opt_index); if (query_str == NULL) { fprintf (stderr, "Out of memory.\n"); - return 1; + return EXIT_FAILURE; } if (*query_str == '\0') { fprintf (stderr, "Error: notmuch search requires at least one search term.\n"); - return 1; + return EXIT_FAILURE; } query = notmuch_query_create (notmuch, query_str); if (query == NULL) { fprintf (stderr, "Out of memory\n"); - return 1; + return EXIT_FAILURE; } notmuch_query_set_sort (query, sort); @@ -491,5 +489,5 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[]) talloc_free (format); - return ret; + return ret ? EXIT_FAILURE : EXIT_SUCCESS; } diff --git a/notmuch-setup.c b/notmuch-setup.c index 475248b1..36a6171a 100644 --- a/notmuch-setup.c +++ b/notmuch-setup.c @@ -140,7 +140,7 @@ notmuch_setup_command (notmuch_config_t *config, fflush (stdout); \ if (getline (&response, &response_size, stdin) < 0) { \ printf ("Exiting.\n"); \ - exit (1); \ + exit (EXIT_FAILURE); \ } \ chomp_newline (response); \ } while (0) @@ -223,12 +223,11 @@ notmuch_setup_command (notmuch_config_t *config, g_ptr_array_free (tags, TRUE); } + if (notmuch_config_save (config)) + return EXIT_FAILURE; - if (! notmuch_config_save (config)) { - if (notmuch_config_is_new (config)) - welcome_message_post_setup (); - return 0; - } else { - return 1; - } + if (notmuch_config_is_new (config)) + welcome_message_post_setup (); + + return EXIT_SUCCESS; } diff --git a/notmuch-show.c b/notmuch-show.c index c07f8871..d416fbd5 100644 --- a/notmuch-show.c +++ b/notmuch-show.c @@ -1015,9 +1015,13 @@ do_show (void *ctx, notmuch_messages_t *messages; notmuch_status_t status, res = NOTMUCH_STATUS_SUCCESS; + threads = notmuch_query_search_threads (query); + if (! threads) + return 1; + sp->begin_list (sp); - for (threads = notmuch_query_search_threads (query); + for ( ; notmuch_threads_valid (threads); notmuch_threads_move_to_next (threads)) { @@ -1113,10 +1117,8 @@ notmuch_show_command (notmuch_config_t *config, int argc, char *argv[]) }; opt_index = parse_arguments (argc, argv, options, 1); - if (opt_index < 0) { - /* diagnostics already printed */ - return 1; - } + if (opt_index < 0) + return EXIT_FAILURE; /* decryption implies verification */ if (params.crypto.decrypt) @@ -1143,7 +1145,7 @@ notmuch_show_command (notmuch_config_t *config, int argc, char *argv[]) case NOTMUCH_FORMAT_MBOX: if (params.part > 0) { fprintf (stderr, "Error: specifying parts is incompatible with mbox output format.\n"); - return 1; + return EXIT_FAILURE; } format = &format_mbox; @@ -1193,22 +1195,22 @@ notmuch_show_command (notmuch_config_t *config, int argc, char *argv[]) query_string = query_string_from_args (config, argc-opt_index, argv+opt_index); if (query_string == NULL) { fprintf (stderr, "Out of memory\n"); - return 1; + return EXIT_FAILURE; } if (*query_string == '\0') { fprintf (stderr, "Error: notmuch show requires at least one search term.\n"); - return 1; + return EXIT_FAILURE; } if (notmuch_database_open (notmuch_config_get_database_path (config), NOTMUCH_DATABASE_MODE_READ_ONLY, ¬much)) - return 1; + return EXIT_FAILURE; query = notmuch_query_create (notmuch, query_string); if (query == NULL) { fprintf (stderr, "Out of memory\n"); - return 1; + return EXIT_FAILURE; } /* Create structure printer. */ @@ -1242,5 +1244,5 @@ notmuch_show_command (notmuch_config_t *config, int argc, char *argv[]) notmuch_query_destroy (query); notmuch_database_destroy (notmuch); - return ret; + return ret ? EXIT_FAILURE : EXIT_SUCCESS; } diff --git a/notmuch-tag.c b/notmuch-tag.c index 3b09df99..5b2f1e48 100644 --- a/notmuch-tag.c +++ b/notmuch-tag.c @@ -193,7 +193,7 @@ notmuch_tag_command (notmuch_config_t *config, int argc, char *argv[]) FILE *input = stdin; char *input_file_name = NULL; int opt_index; - int ret = 0; + int ret; /* Setup our handler for SIGINT */ memset (&action, 0, sizeof (struct sigaction)); @@ -211,7 +211,7 @@ notmuch_tag_command (notmuch_config_t *config, int argc, char *argv[]) opt_index = parse_arguments (argc, argv, options, 1); if (opt_index < 0) - return 1; + return EXIT_FAILURE; if (input_file_name) { batch = TRUE; @@ -219,44 +219,44 @@ notmuch_tag_command (notmuch_config_t *config, int argc, char *argv[]) if (input == NULL) { fprintf (stderr, "Error opening %s for reading: %s\n", input_file_name, strerror (errno)); - return 1; + return EXIT_FAILURE; } } if (batch) { if (opt_index != argc) { fprintf (stderr, "Can't specify both cmdline and stdin!\n"); - return 1; + return EXIT_FAILURE; } if (remove_all) { fprintf (stderr, "Can't specify both --remove-all and --batch\n"); - return 1; + return EXIT_FAILURE; } } else { tag_ops = tag_op_list_create (config); if (tag_ops == NULL) { fprintf (stderr, "Out of memory.\n"); - return 1; + return EXIT_FAILURE; } if (parse_tag_command_line (config, argc - opt_index, argv + opt_index, &query_string, tag_ops)) - return 1; + return EXIT_FAILURE; if (tag_op_list_size (tag_ops) == 0 && ! remove_all) { fprintf (stderr, "Error: 'notmuch tag' requires at least one tag to add or remove.\n"); - return 1; + return EXIT_FAILURE; } if (*query_string == '\0') { fprintf (stderr, "Error: notmuch tag requires at least one search term.\n"); - return 1; + return EXIT_FAILURE; } } if (notmuch_database_open (notmuch_config_get_database_path (config), NOTMUCH_DATABASE_MODE_READ_WRITE, ¬much)) - return 1; + return EXIT_FAILURE; if (notmuch_config_get_maildir_synchronize_flags (config)) tag_flags |= TAG_FLAG_MAILDIR_SYNC; @@ -274,5 +274,5 @@ notmuch_tag_command (notmuch_config_t *config, int argc, char *argv[]) if (input != stdin) fclose (input); - return ret || interrupted; + return ret || interrupted ? EXIT_FAILURE : EXIT_SUCCESS; } diff --git a/notmuch.c b/notmuch.c index 54f46c68..b3fa9f37 100644 --- a/notmuch.c +++ b/notmuch.c @@ -22,6 +22,12 @@ #include "notmuch-client.h" +/* + * Notmuch subcommand hook. + * + * The return value will be used as notmuch exit status code, + * preferrably EXIT_SUCCESS or EXIT_FAILURE. + */ typedef int (*command_function_t) (notmuch_config_t *config, int argc, char *argv[]); typedef struct command { @@ -156,7 +162,7 @@ notmuch_help_command (notmuch_config_t *config, int argc, char *argv[]) if (argc == 0) { printf ("The notmuch mail system.\n\n"); usage (stdout); - return 0; + return EXIT_SUCCESS; } if (strcmp (argv[0], "help") == 0) { @@ -165,7 +171,7 @@ notmuch_help_command (notmuch_config_t *config, int argc, char *argv[]) "\tof difficulties check that MANPATH includes the pages\n" "\tinstalled by notmuch.\n\n" "\tTry \"notmuch help\" for a list of topics.\n"); - return 0; + return EXIT_SUCCESS; } command = find_command (argv[0]); @@ -183,7 +189,7 @@ notmuch_help_command (notmuch_config_t *config, int argc, char *argv[]) fprintf (stderr, "\nSorry, %s is not a known command. There's not much I can do to help.\n\n", argv[0]); - return 1; + return EXIT_FAILURE; } /* Handle the case of "notmuch" being invoked with no command @@ -211,7 +217,7 @@ notmuch_command (notmuch_config_t *config, if (errno != ENOENT) { fprintf (stderr, "Error looking for notmuch database at %s: %s\n", db_path, strerror (errno)); - return 1; + return EXIT_FAILURE; } printf ("Notmuch is configured, but there's not yet a database at\n\n\t%s\n\n", db_path); @@ -219,7 +225,7 @@ notmuch_command (notmuch_config_t *config, "Note that the first run of \"notmuch new\" can take a very long time\n" "and that the resulting database will use roughly the same amount of\n" "storage space as the email being indexed.\n\n"); - return 0; + return EXIT_SUCCESS; } printf ("Notmuch is configured and appears to have a database. Excellent!\n\n" @@ -239,7 +245,7 @@ notmuch_command (notmuch_config_t *config, notmuch_config_get_user_name (config), notmuch_config_get_user_primary_email (config)); - return 0; + return EXIT_SUCCESS; } int @@ -250,10 +256,10 @@ main (int argc, char *argv[]) const char *command_name = NULL; command_t *command; char *config_file_name = NULL; - notmuch_config_t *config; + notmuch_config_t *config = NULL; notmuch_bool_t print_help=FALSE, print_version=FALSE; int opt_index; - int ret = 0; + int ret; notmuch_opt_desc_t options[] = { { NOTMUCH_OPT_BOOLEAN, &print_help, "help", 'h', 0 }, @@ -276,16 +282,19 @@ main (int argc, char *argv[]) opt_index = parse_arguments (argc, argv, options, 1); if (opt_index < 0) { - /* diagnostics already printed */ - return 1; + ret = EXIT_FAILURE; + goto DONE; } - if (print_help) - return notmuch_help_command (NULL, argc - 1, &argv[1]); + if (print_help) { + ret = notmuch_help_command (NULL, argc - 1, &argv[1]); + goto DONE; + } if (print_version) { printf ("notmuch " STRINGIFY(NOTMUCH_VERSION) "\n"); - return 0; + ret = EXIT_SUCCESS; + goto DONE; } if (opt_index < argc) @@ -295,16 +304,21 @@ main (int argc, char *argv[]) if (!command) { fprintf (stderr, "Error: Unknown command '%s' (see \"notmuch help\")\n", command_name); - return 1; + ret = EXIT_FAILURE; + goto DONE; } config = notmuch_config_open (local, config_file_name, command->create_config); - if (!config) - return 1; + if (!config) { + ret = EXIT_FAILURE; + goto DONE; + } ret = (command->function)(config, argc - opt_index, argv + opt_index); - notmuch_config_close (config); + DONE: + if (config) + notmuch_config_close (config); talloc_report = getenv ("NOTMUCH_TALLOC_REPORT"); if (talloc_report && strcmp (talloc_report, "") != 0) { diff --git a/performance-test/download/notmuch-email-corpus-0.4.tar.xz.asc b/performance-test/download/notmuch-email-corpus-0.4.tar.xz.asc new file mode 100644 index 00000000..72dedd8b --- /dev/null +++ b/performance-test/download/notmuch-email-corpus-0.4.tar.xz.asc @@ -0,0 +1,14 @@ +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1.4.15 (GNU/Linux) + +iQGcBAABCAAGBQJSdaDkAAoJEPIClx2kp54sQ54L/ikkvF1fy88hjLitN59v6g2J +vw85YNRifNHyp/UXI6nt2eXFzyWJiRHuvHFoBgmEsJVxauOKw61Gs2zd53x9Ear4 +MGcQWyiM1cnwX/nD7GvxRQNh33f+FEamTjg+QhG47K0A2YdLWcDC7r9GMatGT11x +5KE24WQGOqtgQn/9qNtJvkiKIehpRiDTaW/QJ7mTCYeJFjIHJUY8dxyfiTtkJ0z7 +cJ6omehvWSw4STbEg65XJgqykxMdltNEavfvSbAT73FgmkkyXxul0s5hDZ/esd0n +re3dyDxGt085POiAgPti05a4tJI5EQC2wLBUFri0s2JdMtazcD6yVuHNbVzZ4Do3 +nL/sgwKGUq5wRrPqPWp6HXtZ9zG+/V7hFNrr/l42qGrLqsSh0bqvEnUiwczZLBGy +NEs4G8VjmfS2cMKePsWaekBAvFUtb47PSB6JIPwpCNvKXDrcCb28eOQVB2atgj1h +9SktOtWYJhWIQp2YW9iae30Z6lhCcdPRRHTFMQq2nQ== +=eSMY +-----END PGP SIGNATURE----- diff --git a/performance-test/perf-test-lib.sh b/performance-test/perf-test-lib.sh index 9ee76613..44708cfd 100644 --- a/performance-test/perf-test-lib.sh +++ b/performance-test/perf-test-lib.sh @@ -41,52 +41,70 @@ add_email_corpus () { rm -rf ${MAIL_DIR} - case "$corpus_size" in - small) - mail_subdir="mail/enron/bailey-s" - check_for="${TEST_DIRECTORY}/corpus/$mail_subdir" - ;; - medium) - mail_subdir="mail/notmuch-archive" - check_for="${TEST_DIRECTORY}/corpus/$mail_subdir" - ;; - *) - mail_subdir=mail - check_for="${TEST_DIRECTORY}/corpus/$mail_subdir/enron/wolfe-j" - esac + CORPUS_DIR=${TEST_DIRECTORY}/corpus + mkdir -p "${CORPUS_DIR}" - MAIL_CORPUS="${TEST_DIRECTORY}/corpus/$mail_subdir" - TAG_CORPUS="${TEST_DIRECTORY}/corpus/tags" + MAIL_CORPUS="${CORPUS_DIR}/mail.${corpus_size}" + TAG_CORPUS="${CORPUS_DIR}/tags" - args=() - if [ ! -d "$TAG_CORPUS" ] ; then - args+=("notmuch-email-corpus/tags") + if command -v pixz > /dev/null; then + XZ=pixz + else + XZ=xz fi - if [ ! -d "$check_for" ] ; then - args+=("notmuch-email-corpus/$mail_subdir") + if [ ! -d "${CORPUS_DIR}/manifest" ]; then + + printf "Unpacking manifests\n" + tar --extract --use-compress-program ${XZ} --strip-components=1 \ + --directory ${TEST_DIRECTORY}/corpus \ + --wildcards --file ../download/notmuch-email-corpus-${PERFTEST_VERSION}.tar.xz \ + 'notmuch-email-corpus/manifest/*' fi - if [[ ${#args[@]} > 0 ]]; then - if command -v pixz > /dev/null; then - XZ=pixz + file_list=$(mktemp file_listXXXXXX) + if [ ! -d "$TAG_CORPUS" ] ; then + echo "notmuch-email-corpus/tags" >> $file_list + fi + + if [ ! -d "$MAIL_CORPUS" ] ; then + if [[ "$corpus_size" != "large" ]]; then + sed s,^,notmuch-email-corpus/, < \ + ${TEST_DIRECTORY}/corpus/manifest/MANIFEST.${corpus_size} >> $file_list else - XZ=xz + echo "notmuch-email-corpus/mail" >> $file_list fi + fi - printf "Unpacking corpus\n" - mkdir -p "${TEST_DIRECTORY}/corpus" + if [[ -s $file_list ]]; then + printf "Unpacking corpus\n" tar --checkpoint=.5000 --extract --strip-components=1 \ --directory ${TEST_DIRECTORY}/corpus \ --use-compress-program ${XZ} \ --file ../download/notmuch-email-corpus-${PERFTEST_VERSION}.tar.xz \ - "${args[@]}" + --anchored --recursion \ + --files-from $file_list printf "\n" + if [[ ! -d ${MAIL_CORPUS} ]]; then + printf "creating link farm\n" + + if [[ "$corpus_size" = large ]]; then + cp -rl ${TEST_DIRECTORY}/corpus/mail ${MAIL_CORPUS} + else + while read -r file; do + tdir=${MAIL_CORPUS}/$(dirname $file) + mkdir -p $tdir + ln ${TEST_DIRECTORY}/corpus/$file $tdir + done <${TEST_DIRECTORY}/corpus/manifest/MANIFEST.${corpus_size} + fi + fi + fi + rm $file_list cp -lr $TAG_CORPUS $TMP_DIRECTORY/corpus.tags cp -lr $MAIL_CORPUS $MAIL_DIR } diff --git a/performance-test/version.sh b/performance-test/version.sh index afafc737..f02527a7 100644 --- a/performance-test/version.sh +++ b/performance-test/version.sh @@ -1,3 +1,3 @@ # this should be both a valid Makefile fragment and valid POSIX(ish) shell. -PERFTEST_VERSION=0.3 +PERFTEST_VERSION=0.4 diff --git a/test/README b/test/README index d12cff24..79a9b1b2 100644 --- a/test/README +++ b/test/README @@ -76,6 +76,14 @@ the tests in one of the following ways. TEST_EMACS=my-special-emacs TEST_EMACSCLIENT=my-emacsclient ./emacs make test TEST_EMACS=my-special-emacs TEST_EMACSCLIENT=my-emacsclient +Quiet Execution +--------------- + +Normally, when new script starts and when test PASSes you get a message +printed on screen. This printing can be disabled by setting the +NOTMUCH_TEST_QUIET variable to a non-null value. Message on test +failures and skips are still printed. + Skipping Tests -------------- If, for any reason, you need to skip one or more tests, you can do so diff --git a/test/T000-basic.sh b/test/T000-basic.sh new file mode 100755 index 00000000..9c94b62c --- /dev/null +++ b/test/T000-basic.sh @@ -0,0 +1,93 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2005 Junio C Hamano +# + +test_description='the test framework itself.' + +################################################################ +# It appears that people try to run tests without building... + +if ! test -x ../notmuch +then + echo >&2 'You do not seem to have built notmuch yet.' + exit 1 +fi + +. ./test-lib.sh + +################################################################ +# Test harness +test_expect_success 'success is reported like this' ' + : +' +test_set_prereq HAVEIT +haveit=no +test_expect_success HAVEIT 'test runs if prerequisite is satisfied' ' + test_have_prereq HAVEIT && + haveit=yes +' + +clean=no +test_expect_success 'tests clean up after themselves' ' + test_when_finished clean=yes +' + +cleaner=no +test_expect_code 1 'tests clean up even after a failure' ' + test_when_finished cleaner=yes && + (exit 1) +' + +if test $clean$cleaner != yesyes +then + say "bug in test framework: cleanup commands do not work reliably" + exit 1 +fi + +test_expect_code 2 'failure to clean up causes the test to fail' ' + test_when_finished "(exit 2)" +' + +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_DIRECTORY; NOTMUCH_TEST_QUIET= ./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_DIRECTORY; NOTMUCH_TEST_QUIET= ./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 +rm -r $TEST_DIRECTORY/tmp.test-verbose +test_expect_equal "$output" "$expected" + + +################################################################ +# Test mail store prepared in test-lib.sh + +test_expect_success \ + 'test that mail store was created' \ + 'test -d "${MAIL_DIR}"' + + +find "${MAIL_DIR}" -type f -print >should-be-empty +test_expect_success \ + 'mail store should be empty' \ + 'cmp -s /dev/null should-be-empty' + +test_expect_success \ + 'NOTMUCH_CONFIG is set and points to an existing file' \ + 'test -f "${NOTMUCH_CONFIG}"' + +test_expect_success \ + 'PATH is set to this repository' \ + 'test "`echo $PATH|cut -f1 -d: | sed -e 's,/test/valgrind/bin$,,'`" = "`dirname ${TEST_DIRECTORY}`"' + +test_done diff --git a/test/T010-help-test.sh b/test/T010-help-test.sh new file mode 100755 index 00000000..f7df725e --- /dev/null +++ b/test/T010-help-test.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +test_description="online help" +. ./test-lib.sh + +test_expect_success 'notmuch --help' 'notmuch --help' +test_expect_success 'notmuch --help tag' 'notmuch --help tag' +test_expect_success 'notmuch help' 'notmuch help' +test_expect_success 'notmuch help tag' 'notmuch help tag' +test_expect_success 'notmuch --version' 'notmuch --version' + +test_done diff --git a/test/T020-compact.sh b/test/T020-compact.sh new file mode 100755 index 00000000..ac174cec --- /dev/null +++ b/test/T020-compact.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +test_description='"notmuch compact"' +. ./test-lib.sh + +add_message '[subject]=One' +add_message '[subject]=Two' +add_message '[subject]=Three' + +notmuch tag +tag1 \* +notmuch tag +tag2 subject:Two +notmuch tag -tag1 +tag3 subject:Three + +test_expect_success "Running compact" "notmuch compact --backup=${TEST_DIRECTORY}/xapian.old" + +test_begin_subtest "Compact preserves database" +output=$(notmuch search \* | notmuch_search_sanitize) +test_expect_equal "$output" "\ +thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; One (inbox tag1 unread) +thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Two (inbox tag1 tag2 unread) +thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Three (inbox tag3 unread)" + +test_expect_success 'Restoring Backup' \ + 'rm -Rf ${MAIL_DIR}/.notmuch/xapian && + mv ${TEST_DIRECTORY}/xapian.old ${MAIL_DIR}/.notmuch/xapian' + +test_begin_subtest "Checking restored backup" +output=$(notmuch search \* | notmuch_search_sanitize) +test_expect_equal "$output" "\ +thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; One (inbox tag1 unread) +thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Two (inbox tag1 tag2 unread) +thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Three (inbox tag3 unread)" + +test_done diff --git a/test/T030-config.sh b/test/T030-config.sh new file mode 100755 index 00000000..ca4cf330 --- /dev/null +++ b/test/T030-config.sh @@ -0,0 +1,83 @@ +#!/usr/bin/env bash + +test_description='"notmuch config"' +. ./test-lib.sh + +test_begin_subtest "Get string value" +test_expect_equal "$(notmuch config get user.name)" "Notmuch Test Suite" + +test_begin_subtest "Get list value" +test_expect_equal "$(notmuch config get new.tags)" "\ +unread +inbox" + +test_begin_subtest "Set string value" +notmuch config set foo.string "this is a string value" +test_expect_equal "$(notmuch config get foo.string)" "this is a string value" + +test_begin_subtest "Set string value again" +notmuch config set foo.string "this is another string value" +test_expect_equal "$(notmuch config get foo.string)" "this is another string value" + +test_begin_subtest "Set list value" +notmuch config set foo.list this "is a" "list value" +test_expect_equal "$(notmuch config get foo.list)" "\ +this +is a +list value" + +test_begin_subtest "Set list value again" +notmuch config set foo.list this "is another" "list value" +test_expect_equal "$(notmuch config get foo.list)" "\ +this +is another +list value" + +test_begin_subtest "Remove key" +notmuch config set foo.remove baz +notmuch config set foo.remove +test_expect_equal "$(notmuch config get foo.remove)" "" + +test_begin_subtest "Remove non-existent key" +notmuch config set foo.nonexistent +test_expect_equal "$(notmuch config get foo.nonexistent)" "" + +test_begin_subtest "List all items" +notmuch config set database.path "/canonical/path" +output=$(notmuch config list) +test_expect_equal "$output" "\ +database.path=/canonical/path +user.name=Notmuch Test Suite +user.primary_email=test_suite@notmuchmail.org +user.other_email=test_suite_other@notmuchmail.org;test_suite@otherdomain.org +new.tags=unread;inbox; +new.ignore= +search.exclude_tags= +maildir.synchronize_flags=true +foo.string=this is another string value +foo.list=this;is another;list value;" + +test_begin_subtest "Top level --config=FILE option" +cp "${NOTMUCH_CONFIG}" alt-config +notmuch --config=alt-config config set user.name "Another Name" +test_expect_equal "$(notmuch --config=alt-config config get user.name)" \ + "Another Name" + +test_begin_subtest "Top level --config=FILE option changed the right file" +test_expect_equal "$(notmuch config get user.name)" \ + "Notmuch Test Suite" + +test_begin_subtest "Read config file through a symlink" +ln -s alt-config alt-config-link +test_expect_equal "$(notmuch --config=alt-config-link config get user.name)" \ + "Another Name" + +test_begin_subtest "Write config file through a symlink" +notmuch --config=alt-config-link config set user.name "Link Name" +test_expect_equal "$(notmuch --config=alt-config-link config get user.name)" \ + "Link Name" + +test_begin_subtest "Writing config file through symlink follows symlink" +test_expect_equal "$(readlink alt-config-link)" "alt-config" + +test_done diff --git a/test/T040-setup.sh b/test/T040-setup.sh new file mode 100755 index 00000000..124ef1c8 --- /dev/null +++ b/test/T040-setup.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +test_description='"notmuch setup"' +. ./test-lib.sh + +test_begin_subtest "Create a new config interactively" +notmuch --config=new-notmuch-config > /dev/null < /dev/null +mv "$tmp_msg_filename" "$gen_msg_filename" +output=$(NOTMUCH_NEW) +test_expect_equal "$output" "Added 1 new message to the database." + + +test_begin_subtest "Renamed message" + +generate_message +notmuch new > /dev/null +mv "$gen_msg_filename" "${gen_msg_filename}"-renamed +output=$(NOTMUCH_NEW) +test_expect_equal "$output" "No new mail. Detected 1 file rename." + + +test_begin_subtest "Deleted message" + +rm "${gen_msg_filename}"-renamed +output=$(NOTMUCH_NEW) +test_expect_equal "$output" "No new mail. Removed 1 message." + + +test_begin_subtest "Renamed directory" + +generate_message [dir]=dir +generate_message [dir]=dir +generate_message [dir]=dir + +notmuch new > /dev/null + +mv "${MAIL_DIR}"/dir "${MAIL_DIR}"/dir-renamed + +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 + +output=$(NOTMUCH_NEW) +test_expect_equal "$output" "No new mail. Removed 3 messages." + + +test_begin_subtest "New directory (at end of list)" + +generate_message [dir]=zzz +generate_message [dir]=zzz +generate_message [dir]=zzz + +output=$(NOTMUCH_NEW) +test_expect_equal "$output" "Added 3 new messages to the database." + + +test_begin_subtest "Deleted directory (end of list)" + +rm -rf "${MAIL_DIR}"/zzz + +output=$(NOTMUCH_NEW) +test_expect_equal "$output" "No new mail. Removed 3 messages." + + +test_begin_subtest "New symlink to directory" + +rm -rf "${MAIL_DIR}"/.notmuch +mv "${MAIL_DIR}" "${TMP_DIRECTORY}"/actual_maildir + +mkdir "${MAIL_DIR}" +ln -s "${TMP_DIRECTORY}"/actual_maildir "${MAIL_DIR}"/symlink + +output=$(NOTMUCH_NEW) +test_expect_equal "$output" "Added 1 new message to the database." + + +test_begin_subtest "New symlink to a file" +generate_message +external_msg_filename="${TMP_DIRECTORY}"/external/"$(basename "$gen_msg_filename")" +mkdir -p "$(dirname "$external_msg_filename")" +mv "$gen_msg_filename" "$external_msg_filename" +ln -s "$external_msg_filename" "$gen_msg_filename" +output=$(NOTMUCH_NEW) +test_expect_equal "$output" "Added 1 new message to the database." + + +test_begin_subtest "Broken symlink aborts" +ln -s does-not-exist "${MAIL_DIR}/broken" +output=$(NOTMUCH_NEW 2>&1) +test_expect_equal "$output" \ +"Error reading file ${MAIL_DIR}/broken: No such file or directory +Note: A fatal error was encountered: Something went wrong trying to read or write a file +No new mail." +rm "${MAIL_DIR}/broken" + + +test_begin_subtest "New two-level directory" + +generate_message [dir]=two/levels +generate_message [dir]=two/levels +generate_message [dir]=two/levels + +output=$(NOTMUCH_NEW) +test_expect_equal "$output" "Added 3 new messages to the database." + + +test_begin_subtest "Deleted two-level directory" + +rm -rf "${MAIL_DIR}"/two + +output=$(NOTMUCH_NEW) +test_expect_equal "$output" "No new mail. Removed 3 messages." + +test_begin_subtest "Support single-message mbox (deprecated)" +cat > "${MAIL_DIR}"/mbox_file1 < +To: Notmuch Test Suite +Subject: Test mbox message 1 + +Body. +EOF +output=$(NOTMUCH_NEW 2>&1) +test_expect_equal "$output" \ +"Warning: ${MAIL_DIR}/mbox_file1 is an mbox containing a single message, +likely caused by misconfigured mail delivery. Support for single-message +mboxes is deprecated and may be removed in the future. +Added 1 new message to the database." + +# This test requires that notmuch new has been run at least once. +test_begin_subtest "Skip and report non-mail files" +generate_message +mkdir -p "${MAIL_DIR}"/.git && touch "${MAIL_DIR}"/.git/config +touch "${MAIL_DIR}"/ignored_file +touch "${MAIL_DIR}"/.ignored_hidden_file +cat > "${MAIL_DIR}"/mbox_file < +To: Notmuch Test Suite +Subject: Test mbox message 1 + +Body. + +From test_suite@notmuchmail.org Fri Jan 5 15:43:57 2001 +From: Notmuch Test Suite +To: Notmuch Test Suite +Subject: Test mbox message 2 + +Body 2. +EOF +output=$(NOTMUCH_NEW 2>&1) +test_expect_equal "$output" \ +"Note: Ignoring non-mail file: ${MAIL_DIR}/.git/config +Note: Ignoring non-mail file: ${MAIL_DIR}/.ignored_hidden_file +Note: Ignoring non-mail file: ${MAIL_DIR}/ignored_file +Note: Ignoring non-mail file: ${MAIL_DIR}/mbox_file +Added 1 new message to the database." +rm "${MAIL_DIR}"/mbox_file + +test_begin_subtest "Ignore files and directories specified in new.ignore" +generate_message +notmuch config set new.ignore .git ignored_file .ignored_hidden_file +touch "${MAIL_DIR}"/.git # change .git's mtime for notmuch new to rescan. +output=$(NOTMUCH_NEW 2>&1) +test_expect_equal "$output" "Added 1 new message to the database." + +test_begin_subtest "Ignore files and directories specified in new.ignore (multiple occurrences)" +notmuch config set new.ignore .git ignored_file .ignored_hidden_file +notmuch new > /dev/null # ensure that files/folders will be printed in ASCII order. +touch "${MAIL_DIR}"/.git # change .git's mtime for notmuch new to rescan. +touch "${MAIL_DIR}" # likewise for MAIL_DIR +mkdir -p "${MAIL_DIR}"/one/two/three/.git +touch "${MAIL_DIR}"/{one,one/two,one/two/three}/ignored_file +output=$(NOTMUCH_NEW --debug 2>&1 | sort) +test_expect_equal "$output" \ +"(D) add_files_recursive, pass 1: explicitly ignoring ${MAIL_DIR}/.git +(D) add_files_recursive, pass 1: explicitly ignoring ${MAIL_DIR}/.ignored_hidden_file +(D) add_files_recursive, pass 1: explicitly ignoring ${MAIL_DIR}/ignored_file +(D) add_files_recursive, pass 1: explicitly ignoring ${MAIL_DIR}/one/ignored_file +(D) add_files_recursive, pass 1: explicitly ignoring ${MAIL_DIR}/one/two/ignored_file +(D) add_files_recursive, pass 1: explicitly ignoring ${MAIL_DIR}/one/two/three/.git +(D) add_files_recursive, pass 1: explicitly ignoring ${MAIL_DIR}/one/two/three/ignored_file +(D) add_files_recursive, pass 2: explicitly ignoring ${MAIL_DIR}/.git +(D) add_files_recursive, pass 2: explicitly ignoring ${MAIL_DIR}/.ignored_hidden_file +(D) add_files_recursive, pass 2: explicitly ignoring ${MAIL_DIR}/ignored_file +(D) add_files_recursive, pass 2: explicitly ignoring ${MAIL_DIR}/one/ignored_file +(D) add_files_recursive, pass 2: explicitly ignoring ${MAIL_DIR}/one/two/ignored_file +(D) add_files_recursive, pass 2: explicitly ignoring ${MAIL_DIR}/one/two/three/.git +(D) add_files_recursive, pass 2: explicitly ignoring ${MAIL_DIR}/one/two/three/ignored_file +No new mail." + + +test_begin_subtest "Don't stop for ignored broken symlinks" +notmuch config set new.ignore .git ignored_file .ignored_hidden_file broken_link +ln -s i_do_not_exist "${MAIL_DIR}"/broken_link +output=$(NOTMUCH_NEW 2>&1) +test_expect_equal "$output" "No new mail." + +test_begin_subtest "Quiet: No new mail." +output=$(NOTMUCH_NEW --quiet) +test_expect_equal "$output" "" + +test_begin_subtest "Quiet: new, removed and renamed messages." +# new +generate_message +# deleted +notmuch search --format=text0 --output=files --limit=1 '*' | xargs -0 rm +# moved +mkdir "${MAIL_DIR}"/moved_messages +notmuch search --format=text0 --output=files --offset=1 --limit=1 '*' | xargs -0 -I {} mv {} "${MAIL_DIR}"/moved_messages +output=$(NOTMUCH_NEW --quiet) +test_expect_equal "$output" "" + +test_done diff --git a/test/T060-count.sh b/test/T060-count.sh new file mode 100755 index 00000000..da86c8cc --- /dev/null +++ b/test/T060-count.sh @@ -0,0 +1,97 @@ +#!/usr/bin/env bash +test_description='"notmuch count" for messages and threads' +. ./test-lib.sh + +add_email_corpus + +# Note: The 'wc -l' results below are wrapped in arithmetic evaluation +# $((...)) to strip whitespace. This is for portability, as 'wc -l' +# emits whitespace on some BSD variants. + +test_begin_subtest "message count is the default for notmuch count" +test_expect_equal \ + "$((`notmuch search --output=messages '*' | wc -l`))" \ + "`notmuch count '*'`" + +test_begin_subtest "message count with --output=messages" +test_expect_equal \ + "$((`notmuch search --output=messages '*' | wc -l`))" \ + "`notmuch count --output=messages '*'`" + +test_begin_subtest "thread count with --output=threads" +test_expect_equal \ + "$((`notmuch search --output=threads '*' | wc -l`))" \ + "`notmuch count --output=threads '*'`" + +test_begin_subtest "thread count is the default for notmuch search" +test_expect_equal \ + "$((`notmuch search '*' | wc -l`))" \ + "`notmuch count --output=threads '*'`" + +test_begin_subtest "files count" +test_expect_equal \ + "$((`notmuch search --output=files '*' | wc -l`))" \ + "`notmuch count --output=files '*'`" + +test_begin_subtest "files count for a duplicate message-id" +test_expect_equal \ + "2" \ + "`notmuch count --output=files id:20091117232137.GA7669@griffis1.net`" + +test_begin_subtest "count with no matching messages" +test_expect_equal \ + "0" \ + "`notmuch count --output=messages from:cworth and not from:cworth`" + +test_begin_subtest "count with no matching threads" +test_expect_equal \ + "0" \ + "`notmuch count --output=threads from:cworth and not from:cworth`" + +test_begin_subtest "message count is the default for batch count" +notmuch count --batch >OUTPUT <EXPECTED +notmuch count --output=messages from:cworth >>EXPECTED +test_expect_equal_file EXPECTED OUTPUT + +test_begin_subtest "batch message count" +notmuch count --batch --output=messages >OUTPUT <EXPECTED +notmuch count --output=messages >>EXPECTED +notmuch count --output=messages tag:inbox >>EXPECTED +test_expect_equal_file EXPECTED OUTPUT + +test_begin_subtest "batch thread count" +notmuch count --batch --output=threads >OUTPUT <EXPECTED +notmuch count --output=threads from:cworth >>EXPECTED +notmuch count --output=threads from:cworth and not from:cworth >>EXPECTED +notmuch count --output=threads foo >>EXPECTED +test_expect_equal_file EXPECTED OUTPUT + +test_begin_subtest "batch message count with input file" +cat >INPUT <OUTPUT +notmuch count --output=messages from:cworth >EXPECTED +notmuch count --output=messages >>EXPECTED +notmuch count --output=messages tag:inbox >>EXPECTED +test_expect_equal_file EXPECTED OUTPUT + + +test_done diff --git a/test/T070-insert.sh b/test/T070-insert.sh new file mode 100755 index 00000000..e8dc4c09 --- /dev/null +++ b/test/T070-insert.sh @@ -0,0 +1,167 @@ +#!/usr/bin/env bash +test_description='"notmuch insert"' +. ./test-lib.sh + +# Create directories and database before inserting. +mkdir -p "$MAIL_DIR"/{cur,new,tmp} +mkdir -p "$MAIL_DIR"/Drafts/{cur,new,tmp} +notmuch new > /dev/null + +# We use generate_message to create the temporary message files. +# They happen to be in the mail directory already but that is okay +# since we do not call notmuch new hereafter. + +gen_insert_msg() { + generate_message \ + "[subject]=\"insert-subject\"" \ + "[date]=\"Sat, 01 Jan 2000 12:00:00 -0000\"" \ + "[body]=\"insert-message\"" +} + +test_expect_code 1 "Insert zero-length file" \ + "notmuch insert < /dev/null" + +# This test is a proxy for other errors that may occur while trying to +# add a message to the notmuch database, e.g. database locked. +test_expect_code 0 "Insert non-message" \ + "echo bad_message | notmuch insert" + +test_begin_subtest "Database empty so far" +test_expect_equal "0" "`notmuch count --output=messages '*'`" + +test_begin_subtest "Insert message" +gen_insert_msg +notmuch insert < "$gen_msg_filename" +cur_msg_filename=$(notmuch search --output=files "subject:insert-subject") +test_expect_equal_file "$cur_msg_filename" "$gen_msg_filename" + +test_begin_subtest "Insert message adds default tags" +output=$(notmuch show --format=json "subject:insert-subject") +expected='[[[{ + "id": "'"${gen_msg_id}"'", + "match": true, + "excluded": false, + "filename": "'"${cur_msg_filename}"'", + "timestamp": 946728000, + "date_relative": "2000-01-01", + "tags": ["inbox","unread"], + "headers": { + "Subject": "insert-subject", + "From": "Notmuch Test Suite ", + "To": "Notmuch Test Suite ", + "Date": "Sat, 01 Jan 2000 12:00:00 +0000"}, + "body": [{"id": 1, + "content-type": "text/plain", + "content": "insert-message\n"}]}, + []]]]' +test_expect_equal_json "$output" "$expected" + +test_begin_subtest "Insert duplicate message" +notmuch insert +duptag -unread < "$gen_msg_filename" +output=$(notmuch search --output=files "subject:insert-subject" | wc -l) +test_expect_equal "$output" 2 + +test_begin_subtest "Duplicate message does not change tags" +output=$(notmuch search --format=json --output=tags "subject:insert-subject") +test_expect_equal_json "$output" '["inbox", "unread"]' + +test_begin_subtest "Insert message, add tag" +gen_insert_msg +notmuch insert +custom < "$gen_msg_filename" +output=$(notmuch search --output=messages tag:custom) +test_expect_equal "$output" "id:$gen_msg_id" + +test_begin_subtest "Insert message, add/remove tags" +gen_insert_msg +notmuch insert +custom -unread < "$gen_msg_filename" +output=$(notmuch search --output=messages tag:custom NOT tag:unread) +test_expect_equal "$output" "id:$gen_msg_id" + +test_begin_subtest "Insert message with default tags stays in new/" +gen_insert_msg +notmuch insert < "$gen_msg_filename" +output=$(notmuch search --output=files id:$gen_msg_id) +dirname=$(dirname "$output") +test_expect_equal "$dirname" "$MAIL_DIR/new" + +test_begin_subtest "Insert message with non-maildir synced tags stays in new/" +gen_insert_msg +notmuch insert +custom -inbox < "$gen_msg_filename" +output=$(notmuch search --output=files id:$gen_msg_id) +dirname=$(dirname "$output") +test_expect_equal "$dirname" "$MAIL_DIR/new" + +test_begin_subtest "Insert message with custom new.tags goes to cur/" +OLDCONFIG=$(notmuch config get new.tags) +notmuch config set new.tags test +gen_insert_msg +notmuch insert < "$gen_msg_filename" +output=$(notmuch search --output=files id:$gen_msg_id) +dirname=$(dirname "$output") +notmuch config set new.tags $OLDCONFIG +test_expect_equal "$dirname" "$MAIL_DIR/cur" + +# additional check on the previous message +test_begin_subtest "Insert message with custom new.tags actually gets the tags" +output=$(notmuch search --output=tags id:$gen_msg_id) +test_expect_equal "$output" "test" + +test_begin_subtest "Insert message with maildir synced tags goes to cur/" +gen_insert_msg +notmuch insert +flagged < "$gen_msg_filename" +output=$(notmuch search --output=files id:$gen_msg_id) +dirname=$(dirname "$output") +test_expect_equal "$dirname" "$MAIL_DIR/cur" + +test_begin_subtest "Insert message with maildir sync off goes to new/" +OLDCONFIG=$(notmuch config get maildir.synchronize_flags) +notmuch config set maildir.synchronize_flags false +gen_insert_msg +notmuch insert +flagged < "$gen_msg_filename" +output=$(notmuch search --output=files id:$gen_msg_id) +dirname=$(dirname "$output") +notmuch config set maildir.synchronize_flags $OLDCONFIG +test_expect_equal "$dirname" "$MAIL_DIR/new" + +test_begin_subtest "Insert message into folder" +gen_insert_msg +notmuch insert --folder=Drafts < "$gen_msg_filename" +output=$(notmuch search --output=files folder:Drafts) +dirname=$(dirname "$output") +test_expect_equal "$dirname" "$MAIL_DIR/Drafts/new" + +test_begin_subtest "Insert message into folder, add/remove tags" +gen_insert_msg +notmuch insert --folder=Drafts +draft -unread < "$gen_msg_filename" +output=$(notmuch search --output=messages folder:Drafts tag:draft NOT tag:unread) +test_expect_equal "$output" "id:$gen_msg_id" + +gen_insert_msg +test_expect_code 1 "Insert message into non-existent folder" \ + "notmuch insert --folder=nonesuch < $gen_msg_filename" + +test_begin_subtest "Insert message, create folder" +gen_insert_msg +notmuch insert --folder=F --create-folder +folder < "$gen_msg_filename" +output=$(notmuch search --output=files folder:F tag:folder) +basename=$(basename "$output") +test_expect_equal_file "$gen_msg_filename" "$MAIL_DIR/F/new/${basename}" + +test_begin_subtest "Insert message, create subfolder" +gen_insert_msg +notmuch insert --folder=F/G/H/I/J --create-folder +folder < "$gen_msg_filename" +output=$(notmuch search --output=files folder:F/G/H/I/J tag:folder) +basename=$(basename "$output") +test_expect_equal_file "$gen_msg_filename" "${MAIL_DIR}/F/G/H/I/J/new/${basename}" + +test_begin_subtest "Insert message, create existing subfolder" +gen_insert_msg +notmuch insert --folder=F/G/H/I/J --create-folder +folder < "$gen_msg_filename" +output=$(notmuch count folder:F/G/H/I/J tag:folder) +test_expect_equal "$output" "2" + +gen_insert_msg +test_expect_code 1 "Insert message, create invalid subfolder" \ + "notmuch insert --folder=../G --create-folder $gen_msg_filename" + +test_done diff --git a/test/T080-search.sh b/test/T080-search.sh new file mode 100755 index 00000000..a7a0b18d --- /dev/null +++ b/test/T080-search.sh @@ -0,0 +1,132 @@ +#!/usr/bin/env bash +test_description='"notmuch search" in several variations' +. ./test-lib.sh + +add_email_corpus + +test_begin_subtest "Search body" +add_message '[subject]="body search"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' [body]=bodysearchtest +output=$(notmuch search bodysearchtest | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; body search (inbox unread)" + +test_begin_subtest "Search by from:" +add_message '[subject]="search by from"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' [from]=searchbyfrom +output=$(notmuch search from:searchbyfrom | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] searchbyfrom; search by from (inbox unread)" + +test_begin_subtest "Search by to:" +add_message '[subject]="search by to"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' [to]=searchbyto +output=$(notmuch search to:searchbyto | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by to (inbox unread)" + +test_begin_subtest "Search by subject:" +add_message [subject]=subjectsearchtest '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' +output=$(notmuch search subject:subjectsearchtest | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; subjectsearchtest (inbox unread)" + +test_begin_subtest "Search by subject (utf-8):" +add_message [subject]=utf8-sübjéct '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' +output=$(notmuch search subject:utf8-sübjéct | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; utf8-sübjéct (inbox unread)" + +test_begin_subtest "Search by id:" +add_message '[subject]="search by id"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' +output=$(notmuch search id:${gen_msg_id} | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by id (inbox unread)" + +test_begin_subtest "Search by tag:" +add_message '[subject]="search by tag"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' +notmuch tag +searchbytag id:${gen_msg_id} +output=$(notmuch search tag:searchbytag | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by tag (inbox searchbytag unread)" + +test_begin_subtest "Search by thread:" +add_message '[subject]="search by thread"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' +thread_id=$(notmuch search id:${gen_msg_id} | sed -e "s/thread:\([a-f0-9]*\).*/\1/") +output=$(notmuch search thread:${thread_id} | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by thread (inbox unread)" + +test_begin_subtest "Search body (phrase)" +add_message '[subject]="body search (phrase)"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' '[body]="body search (phrase)"' +add_message '[subject]="negative result"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' '[body]="This phrase should not match the body search"' +output=$(notmuch search '"body search (phrase)"' | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; body search (phrase) (inbox unread)" + +test_begin_subtest "Search by from: (address)" +add_message '[subject]="search by from (address)"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' [from]=searchbyfrom@example.com +output=$(notmuch search from:searchbyfrom@example.com | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] searchbyfrom@example.com; search by from (address) (inbox unread)" + +test_begin_subtest "Search by from: (name)" +add_message '[subject]="search by from (name)"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' '[from]="Search By From Name "' +output=$(notmuch search from:"Search By From Name" | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Search By From Name; search by from (name) (inbox unread)" + +test_begin_subtest "Search by to: (address)" +add_message '[subject]="search by to (address)"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' [to]=searchbyto@example.com +output=$(notmuch search to:searchbyto@example.com | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by to (address) (inbox unread)" + +test_begin_subtest "Search by to: (name)" +add_message '[subject]="search by to (name)"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' '[to]="Search By To Name "' +output=$(notmuch search to:"Search By To Name" | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by to (name) (inbox unread)" + +test_begin_subtest "Search by subject: (phrase)" +add_message '[subject]="subject search test (phrase)"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' +add_message '[subject]="this phrase should not match the subject search test"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' +output=$(notmuch search 'subject:"subject search test (phrase)"' | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; subject search test (phrase) (inbox unread)" + +test_begin_subtest 'Search for all messages ("*")' +notmuch search '*' | notmuch_search_sanitize > OUTPUT +cat <EXPECTED +thread:XXX 2010-12-29 [1/1] François Boulogne; [aur-general] Guidelines: cp, mkdir vs install (inbox unread) +thread:XXX 2010-12-16 [1/1] Olivier Berger; Essai accentué (inbox unread) +thread:XXX 2009-11-18 [1/1] Chris Wilson; [notmuch] [PATCH 1/2] Makefile: evaluate pkg-config once (inbox unread) +thread:XXX 2009-11-18 [2/2] Alex Botero-Lowry, Carl Worth; [notmuch] [PATCH] Error out if no query is supplied to search instead of going into an infinite loop (attachment inbox unread) +thread:XXX 2009-11-18 [2/2] Ingmar Vanhassel, Carl Worth; [notmuch] [PATCH] Typsos (inbox unread) +thread:XXX 2009-11-18 [3/3] Adrian Perez de Castro, Keith Packard, Carl Worth; [notmuch] Introducing myself (inbox signed unread) +thread:XXX 2009-11-18 [3/3] Israel Herraiz, Keith Packard, Carl Worth; [notmuch] New to the list (inbox unread) +thread:XXX 2009-11-18 [3/3] Jan Janak, Carl Worth; [notmuch] What a great idea! (inbox unread) +thread:XXX 2009-11-18 [2/2] Jan Janak, Carl Worth; [notmuch] [PATCH] Older versions of install do not support -C. (inbox unread) +thread:XXX 2009-11-18 [3/3] Aron Griffis, Keith Packard, Carl Worth; [notmuch] archive (inbox unread) +thread:XXX 2009-11-18 [2/2] Keith Packard, Carl Worth; [notmuch] [PATCH] Make notmuch-show 'X' (and 'x') commands remove inbox (and unread) tags (inbox unread) +thread:XXX 2009-11-18 [7/7] Lars Kellogg-Stedman, Mikhail Gusarov, Keith Packard, Carl Worth; [notmuch] Working with Maildir storage? (inbox signed unread) +thread:XXX 2009-11-18 [5/5] Mikhail Gusarov, Carl Worth, Keith Packard; [notmuch] [PATCH 1/2] Close message file after parsing message headers (inbox unread) +thread:XXX 2009-11-18 [2/2] Keith Packard, Alexander Botero-Lowry; [notmuch] [PATCH] Create a default notmuch-show-hook that highlights URLs and uses word-wrap (inbox unread) +thread:XXX 2009-11-18 [1/1] Alexander Botero-Lowry; [notmuch] request for pull (inbox unread) +thread:XXX 2009-11-18 [4/4] Jjgod Jiang, Alexander Botero-Lowry; [notmuch] Mac OS X/Darwin compatibility issues (inbox unread) +thread:XXX 2009-11-18 [1/1] Rolland Santimano; [notmuch] Link to mailing list archives ? (inbox unread) +thread:XXX 2009-11-18 [1/1] Jan Janak; [notmuch] [PATCH] notmuch new: Support for conversion of spool subdirectories into tags (inbox unread) +thread:XXX 2009-11-18 [1/1] Stewart Smith; [notmuch] [PATCH] count_files: sort directory in inode order before statting (inbox unread) +thread:XXX 2009-11-18 [1/1] Stewart Smith; [notmuch] [PATCH 2/2] Read mail directory in inode number order (inbox unread) +thread:XXX 2009-11-18 [1/1] Stewart Smith; [notmuch] [PATCH] Fix linking with gcc to use g++ to link in C++ libs. (inbox unread) +thread:XXX 2009-11-18 [2/2] Lars Kellogg-Stedman; [notmuch] "notmuch help" outputs to stderr? (attachment inbox signed unread) +thread:XXX 2009-11-17 [1/1] Mikhail Gusarov; [notmuch] [PATCH] Handle rename of message file (inbox unread) +thread:XXX 2009-11-17 [2/2] Alex Botero-Lowry, Carl Worth; [notmuch] preliminary FreeBSD support (attachment inbox unread) +thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; body search (inbox unread) +thread:XXX 2000-01-01 [1/1] searchbyfrom; search by from (inbox unread) +thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by to (inbox unread) +thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; subjectsearchtest (inbox unread) +thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; utf8-sübjéct (inbox unread) +thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by id (inbox unread) +thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by tag (inbox searchbytag unread) +thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by thread (inbox unread) +thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; body search (phrase) (inbox unread) +thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; negative result (inbox unread) +thread:XXX 2000-01-01 [1/1] searchbyfrom@example.com; search by from (address) (inbox unread) +thread:XXX 2000-01-01 [1/1] Search By From Name; search by from (name) (inbox unread) +thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by to (address) (inbox unread) +thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by to (name) (inbox unread) +thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; subject search test (phrase) (inbox unread) +thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; this phrase should not match the subject search test (inbox unread) +EOF +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "Search body (utf-8):" +add_message '[subject]="utf8-message-body-subject"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' '[body]="message body utf8: bödý"' +output=$(notmuch search "bödý" | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; utf8-message-body-subject (inbox unread)" + +test_done diff --git a/test/T090-search-output.sh b/test/T090-search-output.sh new file mode 100755 index 00000000..5ccfeaf9 --- /dev/null +++ b/test/T090-search-output.sh @@ -0,0 +1,405 @@ +#!/usr/bin/env bash +test_description='various settings for "notmuch search --output="' +. ./test-lib.sh + +add_email_corpus + +test_begin_subtest "--output=threads" +notmuch search --output=threads '*' | sed -e s/thread:.*/thread:THREADID/ >OUTPUT +cat <EXPECTED +thread:THREADID +thread:THREADID +thread:THREADID +thread:THREADID +thread:THREADID +thread:THREADID +thread:THREADID +thread:THREADID +thread:THREADID +thread:THREADID +thread:THREADID +thread:THREADID +thread:THREADID +thread:THREADID +thread:THREADID +thread:THREADID +thread:THREADID +thread:THREADID +thread:THREADID +thread:THREADID +thread:THREADID +thread:THREADID +thread:THREADID +thread:THREADID +EOF +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "--output=threads --format=json" +notmuch search --format=json --output=threads '*' | sed -e s/\".*\"/\"THREADID\"/ >OUTPUT +cat <EXPECTED +["THREADID", +"THREADID", +"THREADID", +"THREADID", +"THREADID", +"THREADID", +"THREADID", +"THREADID", +"THREADID", +"THREADID", +"THREADID", +"THREADID", +"THREADID", +"THREADID", +"THREADID", +"THREADID", +"THREADID", +"THREADID", +"THREADID", +"THREADID", +"THREADID", +"THREADID", +"THREADID", +"THREADID"] +EOF +test_expect_equal_json "$(cat OUTPUT)" "$(cat EXPECTED)" + +test_begin_subtest "--output=messages" +notmuch search --output=messages '*' >OUTPUT +cat <EXPECTED +id:4EFC743A.3060609@april.org +id:877h1wv7mg.fsf@inf-8657.int-evry.fr +id:1258544095-16616-1-git-send-email-chris@chris-wilson.co.uk +id:877htoqdbo.fsf@yoom.home.cworth.org +id:878we4qdqf.fsf@yoom.home.cworth.org +id:87aaykqe24.fsf@yoom.home.cworth.org +id:87bpj0qeng.fsf@yoom.home.cworth.org +id:87fx8cqf8v.fsf@yoom.home.cworth.org +id:87hbssqfix.fsf@yoom.home.cworth.org +id:87iqd8qgiz.fsf@yoom.home.cworth.org +id:87k4xoqgnl.fsf@yoom.home.cworth.org +id:87ocn0qh6d.fsf@yoom.home.cworth.org +id:87pr7gqidx.fsf@yoom.home.cworth.org +id:867hto2p0t.fsf@fortitudo.i-did-not-set--mail-host-address--so-tickle-me +id:1258532999-9316-1-git-send-email-keithp@keithp.com +id:86aayk2rbj.fsf@fortitudo.i-did-not-set--mail-host-address--so-tickle-me +id:86d43g2w3y.fsf@fortitudo.i-did-not-set--mail-host-address--so-tickle-me +id:ddd65cda0911172214t60d22b63hcfeb5a19ab54a39b@mail.gmail.com +id:86einw2xof.fsf@fortitudo.i-did-not-set--mail-host-address--so-tickle-me +id:736613.51770.qm@web113505.mail.gq1.yahoo.com +id:1258520223-15328-1-git-send-email-jan@ryngle.com +id:ddd65cda0911171950o4eea4389v86de9525e46052d3@mail.gmail.com +id:1258510940-7018-1-git-send-email-stewart@flamingspork.com +id:yunzl6kd1w0.fsf@aiko.keithp.com +id:yun1vjwegii.fsf@aiko.keithp.com +id:yun3a4cegoa.fsf@aiko.keithp.com +id:1258509400-32511-1-git-send-email-stewart@flamingspork.com +id:1258506353-20352-1-git-send-email-stewart@flamingspork.com +id:20091118010116.GC25380@dottiness.seas.harvard.edu +id:20091118005829.GB25380@dottiness.seas.harvard.edu +id:20091118005040.GA25380@dottiness.seas.harvard.edu +id:cf0c4d610911171623q3e27a0adx802e47039b57604b@mail.gmail.com +id:1258500222-32066-1-git-send-email-ingmar@exherbo.org +id:20091117232137.GA7669@griffis1.net +id:20091118002059.067214ed@hikari +id:1258498485-sup-142@elly +id:f35dbb950911171438k5df6eb56k77b6c0944e2e79ae@mail.gmail.com +id:f35dbb950911171435ieecd458o853c873e35f4be95@mail.gmail.com +id:1258496327-12086-1-git-send-email-jan@ryngle.com +id:1258493565-13508-1-git-send-email-keithp@keithp.com +id:yunaayketfm.fsf@aiko.keithp.com +id:yunbpj0etua.fsf@aiko.keithp.com +id:1258491078-29658-1-git-send-email-dottedmag@dottedmag.net +id:87fx8can9z.fsf@vertex.dottedmag +id:20091117203301.GV3165@dottiness.seas.harvard.edu +id:87lji4lx9v.fsf@yoom.home.cworth.org +id:cf0c4d610911171136h1713aa59w9cf9aa31f052ad0a@mail.gmail.com +id:87iqd9rn3l.fsf@vertex.dottedmag +id:20091117190054.GU3165@dottiness.seas.harvard.edu +id:87lji5cbwo.fsf@yoom.home.cworth.org +id:1258471718-6781-2-git-send-email-dottedmag@dottedmag.net +id:1258471718-6781-1-git-send-email-dottedmag@dottedmag.net +EOF +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "--output=messages --format=json" +notmuch search --format=json --output=messages '*' >OUTPUT +cat <EXPECTED +["4EFC743A.3060609@april.org", +"877h1wv7mg.fsf@inf-8657.int-evry.fr", +"1258544095-16616-1-git-send-email-chris@chris-wilson.co.uk", +"877htoqdbo.fsf@yoom.home.cworth.org", +"878we4qdqf.fsf@yoom.home.cworth.org", +"87aaykqe24.fsf@yoom.home.cworth.org", +"87bpj0qeng.fsf@yoom.home.cworth.org", +"87fx8cqf8v.fsf@yoom.home.cworth.org", +"87hbssqfix.fsf@yoom.home.cworth.org", +"87iqd8qgiz.fsf@yoom.home.cworth.org", +"87k4xoqgnl.fsf@yoom.home.cworth.org", +"87ocn0qh6d.fsf@yoom.home.cworth.org", +"87pr7gqidx.fsf@yoom.home.cworth.org", +"867hto2p0t.fsf@fortitudo.i-did-not-set--mail-host-address--so-tickle-me", +"1258532999-9316-1-git-send-email-keithp@keithp.com", +"86aayk2rbj.fsf@fortitudo.i-did-not-set--mail-host-address--so-tickle-me", +"86d43g2w3y.fsf@fortitudo.i-did-not-set--mail-host-address--so-tickle-me", +"ddd65cda0911172214t60d22b63hcfeb5a19ab54a39b@mail.gmail.com", +"86einw2xof.fsf@fortitudo.i-did-not-set--mail-host-address--so-tickle-me", +"736613.51770.qm@web113505.mail.gq1.yahoo.com", +"1258520223-15328-1-git-send-email-jan@ryngle.com", +"ddd65cda0911171950o4eea4389v86de9525e46052d3@mail.gmail.com", +"1258510940-7018-1-git-send-email-stewart@flamingspork.com", +"yunzl6kd1w0.fsf@aiko.keithp.com", +"yun1vjwegii.fsf@aiko.keithp.com", +"yun3a4cegoa.fsf@aiko.keithp.com", +"1258509400-32511-1-git-send-email-stewart@flamingspork.com", +"1258506353-20352-1-git-send-email-stewart@flamingspork.com", +"20091118010116.GC25380@dottiness.seas.harvard.edu", +"20091118005829.GB25380@dottiness.seas.harvard.edu", +"20091118005040.GA25380@dottiness.seas.harvard.edu", +"cf0c4d610911171623q3e27a0adx802e47039b57604b@mail.gmail.com", +"1258500222-32066-1-git-send-email-ingmar@exherbo.org", +"20091117232137.GA7669@griffis1.net", +"20091118002059.067214ed@hikari", +"1258498485-sup-142@elly", +"f35dbb950911171438k5df6eb56k77b6c0944e2e79ae@mail.gmail.com", +"f35dbb950911171435ieecd458o853c873e35f4be95@mail.gmail.com", +"1258496327-12086-1-git-send-email-jan@ryngle.com", +"1258493565-13508-1-git-send-email-keithp@keithp.com", +"yunaayketfm.fsf@aiko.keithp.com", +"yunbpj0etua.fsf@aiko.keithp.com", +"1258491078-29658-1-git-send-email-dottedmag@dottedmag.net", +"87fx8can9z.fsf@vertex.dottedmag", +"20091117203301.GV3165@dottiness.seas.harvard.edu", +"87lji4lx9v.fsf@yoom.home.cworth.org", +"cf0c4d610911171136h1713aa59w9cf9aa31f052ad0a@mail.gmail.com", +"87iqd9rn3l.fsf@vertex.dottedmag", +"20091117190054.GU3165@dottiness.seas.harvard.edu", +"87lji5cbwo.fsf@yoom.home.cworth.org", +"1258471718-6781-2-git-send-email-dottedmag@dottedmag.net", +"1258471718-6781-1-git-send-email-dottedmag@dottedmag.net"] +EOF +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "--output=files" +notmuch search --output=files '*' | sed -e "s,$MAIL_DIR,MAIL_DIR," >OUTPUT +cat <EXPECTED +MAIL_DIR/cur/52:2, +MAIL_DIR/cur/53:2, +MAIL_DIR/cur/50:2, +MAIL_DIR/cur/49:2, +MAIL_DIR/cur/48:2, +MAIL_DIR/cur/47:2, +MAIL_DIR/cur/46:2, +MAIL_DIR/cur/45:2, +MAIL_DIR/cur/44:2, +MAIL_DIR/cur/43:2, +MAIL_DIR/cur/42:2, +MAIL_DIR/cur/41:2, +MAIL_DIR/cur/40:2, +MAIL_DIR/cur/39:2, +MAIL_DIR/cur/38:2, +MAIL_DIR/cur/37:2, +MAIL_DIR/cur/36:2, +MAIL_DIR/cur/35:2, +MAIL_DIR/cur/34:2, +MAIL_DIR/cur/33:2, +MAIL_DIR/cur/32:2, +MAIL_DIR/cur/31:2, +MAIL_DIR/cur/30:2, +MAIL_DIR/cur/29:2, +MAIL_DIR/cur/28:2, +MAIL_DIR/cur/27:2, +MAIL_DIR/cur/26:2, +MAIL_DIR/cur/25:2, +MAIL_DIR/cur/24:2, +MAIL_DIR/cur/23:2, +MAIL_DIR/cur/22: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, +MAIL_DIR/cur/15:2, +MAIL_DIR/cur/14:2, +MAIL_DIR/cur/13:2, +MAIL_DIR/cur/12:2, +MAIL_DIR/cur/11:2, +MAIL_DIR/cur/10:2, +MAIL_DIR/cur/09:2, +MAIL_DIR/cur/08:2, +MAIL_DIR/cur/06:2, +MAIL_DIR/cur/05:2, +MAIL_DIR/cur/04:2, +MAIL_DIR/cur/03:2, +MAIL_DIR/cur/07:2, +MAIL_DIR/cur/02:2, +MAIL_DIR/cur/01:2, +EOF +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "--output=files --duplicate=1" +notmuch search --output=files --duplicate=1 '*' | sed -e "s,$MAIL_DIR,MAIL_DIR," >OUTPUT +cat <EXPECTED +MAIL_DIR/cur/52:2, +MAIL_DIR/cur/53:2, +MAIL_DIR/cur/50:2, +MAIL_DIR/cur/49:2, +MAIL_DIR/cur/48:2, +MAIL_DIR/cur/47:2, +MAIL_DIR/cur/46:2, +MAIL_DIR/cur/45:2, +MAIL_DIR/cur/44:2, +MAIL_DIR/cur/43:2, +MAIL_DIR/cur/42:2, +MAIL_DIR/cur/41:2, +MAIL_DIR/cur/40:2, +MAIL_DIR/cur/39:2, +MAIL_DIR/cur/38:2, +MAIL_DIR/cur/37:2, +MAIL_DIR/cur/36:2, +MAIL_DIR/cur/35:2, +MAIL_DIR/cur/34:2, +MAIL_DIR/cur/33:2, +MAIL_DIR/cur/32:2, +MAIL_DIR/cur/31:2, +MAIL_DIR/cur/30:2, +MAIL_DIR/cur/29:2, +MAIL_DIR/cur/28:2, +MAIL_DIR/cur/27:2, +MAIL_DIR/cur/26:2, +MAIL_DIR/cur/25:2, +MAIL_DIR/cur/24:2, +MAIL_DIR/cur/23:2, +MAIL_DIR/cur/22:2, +MAIL_DIR/cur/21:2, +MAIL_DIR/cur/19:2, +MAIL_DIR/cur/18:2, +MAIL_DIR/cur/20:2, +MAIL_DIR/cur/17:2, +MAIL_DIR/cur/16:2, +MAIL_DIR/cur/15:2, +MAIL_DIR/cur/14:2, +MAIL_DIR/cur/13:2, +MAIL_DIR/cur/12:2, +MAIL_DIR/cur/11:2, +MAIL_DIR/cur/10:2, +MAIL_DIR/cur/09:2, +MAIL_DIR/cur/08:2, +MAIL_DIR/cur/06:2, +MAIL_DIR/cur/05:2, +MAIL_DIR/cur/04:2, +MAIL_DIR/cur/03:2, +MAIL_DIR/cur/07:2, +MAIL_DIR/cur/02:2, +MAIL_DIR/cur/01:2, +EOF +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "--output=files --format=json" +notmuch search --format=json --output=files '*' | sed -e "s,$MAIL_DIR,MAIL_DIR," >OUTPUT +cat <EXPECTED +["MAIL_DIR/cur/52:2,", +"MAIL_DIR/cur/53:2,", +"MAIL_DIR/cur/50:2,", +"MAIL_DIR/cur/49:2,", +"MAIL_DIR/cur/48:2,", +"MAIL_DIR/cur/47:2,", +"MAIL_DIR/cur/46:2,", +"MAIL_DIR/cur/45:2,", +"MAIL_DIR/cur/44:2,", +"MAIL_DIR/cur/43:2,", +"MAIL_DIR/cur/42:2,", +"MAIL_DIR/cur/41:2,", +"MAIL_DIR/cur/40:2,", +"MAIL_DIR/cur/39:2,", +"MAIL_DIR/cur/38:2,", +"MAIL_DIR/cur/37:2,", +"MAIL_DIR/cur/36:2,", +"MAIL_DIR/cur/35:2,", +"MAIL_DIR/cur/34:2,", +"MAIL_DIR/cur/33:2,", +"MAIL_DIR/cur/32:2,", +"MAIL_DIR/cur/31:2,", +"MAIL_DIR/cur/30:2,", +"MAIL_DIR/cur/29:2,", +"MAIL_DIR/cur/28:2,", +"MAIL_DIR/cur/27:2,", +"MAIL_DIR/cur/26:2,", +"MAIL_DIR/cur/25:2,", +"MAIL_DIR/cur/24:2,", +"MAIL_DIR/cur/23:2,", +"MAIL_DIR/cur/22: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,", +"MAIL_DIR/cur/15:2,", +"MAIL_DIR/cur/14:2,", +"MAIL_DIR/cur/13:2,", +"MAIL_DIR/cur/12:2,", +"MAIL_DIR/cur/11:2,", +"MAIL_DIR/cur/10:2,", +"MAIL_DIR/cur/09:2,", +"MAIL_DIR/cur/08:2,", +"MAIL_DIR/cur/06:2,", +"MAIL_DIR/cur/05:2,", +"MAIL_DIR/cur/04:2,", +"MAIL_DIR/cur/03:2,", +"MAIL_DIR/cur/07:2,", +"MAIL_DIR/cur/02:2,", +"MAIL_DIR/cur/01:2,"] +EOF +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "--output=files --format=json --duplicate=2" +notmuch search --format=json --output=files --duplicate=2 '*' | sed -e "s,$MAIL_DIR,MAIL_DIR," >OUTPUT +cat <EXPECTED +["MAIL_DIR/cur/51:2,"] +EOF +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "--output=tags" +notmuch search --output=tags '*' >OUTPUT +cat <EXPECTED +attachment +inbox +signed +unread +EOF +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "--output=tags --format=json" +notmuch search --format=json --output=tags '*' >OUTPUT +cat <EXPECTED +["attachment", +"inbox", +"signed", +"unread"] +EOF +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "sanitize output for quoted-printable line-breaks in author and subject" +add_message "[subject]='two =?ISO-8859-1?Q?line=0A_subject?= + headers'" +notmuch search id:"$gen_msg_id" | notmuch_search_sanitize >OUTPUT +cat <EXPECTED +thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; two line? subject headers (inbox unread) +EOF +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "search for non-existent message prints nothing" +notmuch search "no-message-matches-this" > OUTPUT +echo -n >EXPECTED +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "search --format=json for non-existent message prints proper empty json" +notmuch search --format=json "no-message-matches-this" > OUTPUT +echo "[]" >EXPECTED +test_expect_equal_file OUTPUT EXPECTED + +test_done diff --git a/test/T100-search-by-folder.sh b/test/T100-search-by-folder.sh new file mode 100755 index 00000000..5cc2ca8d --- /dev/null +++ b/test/T100-search-by-folder.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash +test_description='"notmuch search" by folder: (with variations)' +. ./test-lib.sh + +add_message '[dir]=bad' '[subject]="To the bone"' +add_message '[dir]=bad/news' '[subject]="Bears"' +mkdir -p "${MAIL_DIR}/duplicate/bad/news" +cp "$gen_msg_filename" "${MAIL_DIR}/duplicate/bad/news" + +add_message '[dir]=things' '[subject]="These are a few"' +add_message '[dir]=things/favorite' '[subject]="Raindrops, whiskers, kettles"' +add_message '[dir]=things/bad' '[subject]="Bites, stings, sad feelings"' + +test_begin_subtest "Single-world folder: specification (multiple results)" +output=$(notmuch search folder:bad | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; To the bone (inbox unread) +thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Bears (inbox unread) +thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Bites, stings, sad feelings (inbox unread)" + +test_begin_subtest "Two-word path to narrow results to one" +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 removing duplicate instance of matching path" +rm -r "${MAIL_DIR}/bad/news" +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" +notmuch new +output=$(notmuch search folder:bad/news | notmuch_search_sanitize) +test_expect_equal "$output" "" + +test_begin_subtest "After rename, new path returns result" +output=$(notmuch search folder:bad/olds | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Bears (inbox unread)" + +test_done diff --git a/test/T110-search-position-overlap-bug.sh b/test/T110-search-position-overlap-bug.sh new file mode 100755 index 00000000..5da6ad6f --- /dev/null +++ b/test/T110-search-position-overlap-bug.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +# Test to demonstrate a position overlap bug. +# +# At one point, notmuch would index terms incorrectly in the case of +# calling index_terms multiple times for a single field. The term +# generator was being reset to position 0 each time. This means that +# with text such as: +# +# To: a@b.c, x@y.z +# +# one could get a bogus match by searching for: +# +# To: a@y.c +# +# Thanks to Mark Anderson for reporting the bug, (and providing a nice, +# minimal test case that inspired what is used here), in +# id:3wd4o8wa7fx.fsf@testarossa.amd.com + +test_description='that notmuch does not overlap term positions' +. ./test-lib.sh + +add_message '[to]="a@b.c, x@y.z"' + +test_begin_subtest "Search for a@b.c matches" +output=$(notmuch search a@b.c | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Test message #1 (inbox unread)" + +test_begin_subtest "Search for x@y.z matches" +output=$(notmuch search x@y.z | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Test message #1 (inbox unread)" + +test_begin_subtest "Search for a@y.c must not match" +output=$(notmuch search a@y.c | notmuch_search_sanitize) +test_expect_equal "$output" "" + +test_done diff --git a/test/T120-search-insufficient-from-quoting.sh b/test/T120-search-insufficient-from-quoting.sh new file mode 100755 index 00000000..e83ea3d1 --- /dev/null +++ b/test/T120-search-insufficient-from-quoting.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +test_description='messages with unquoted . in name' +. ./test-lib.sh + +add_message \ + '[from]="Some.Name for Someone "' \ + '[subject]="This message needs more quoting on the From line"' + +add_message \ + '[from]="\"Some.Name for Someone\" "' \ + '[subject]="This message has necessary quoting in place"' + +add_message \ + '[from]="No.match Here "' \ + '[subject]="This message needs more quoting on the From line"' + +add_message \ + '[from]="\"No.match Here\" "' \ + '[subject]="This message has necessary quoting in place"' + + +test_begin_subtest "Search by first name" +output=$(notmuch search from:Some.Name | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Some.Name for Someone; This message needs more quoting on the From line (inbox unread) +thread:XXX 2001-01-05 [1/1] Some.Name for Someone; This message has necessary quoting in place (inbox unread)" + +test_begin_subtest "Search by last name:" +output=$(notmuch search from:Someone | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Some.Name for Someone; This message needs more quoting on the From line (inbox unread) +thread:XXX 2001-01-05 [1/1] Some.Name for Someone; This message has necessary quoting in place (inbox unread)" + +test_begin_subtest "Search by address:" +output=$(notmuch search from:bugs@quoting.com | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Some.Name for Someone; This message needs more quoting on the From line (inbox unread) +thread:XXX 2001-01-05 [1/1] Some.Name for Someone; This message has necessary quoting in place (inbox unread)" + +test_begin_subtest "Search for all messages:" +output=$(notmuch search '*' | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Some.Name for Someone; This message needs more quoting on the From line (inbox unread) +thread:XXX 2001-01-05 [1/1] Some.Name for Someone; This message has necessary quoting in place (inbox unread) +thread:XXX 2001-01-05 [1/1] No.match Here; This message needs more quoting on the From line (inbox unread) +thread:XXX 2001-01-05 [1/1] No.match Here; This message has necessary quoting in place (inbox unread)" + +test_done diff --git a/test/T130-search-limiting.sh b/test/T130-search-limiting.sh new file mode 100755 index 00000000..303762cf --- /dev/null +++ b/test/T130-search-limiting.sh @@ -0,0 +1,71 @@ +#!/usr/bin/env bash +test_description='"notmuch search" --offset and --limit parameters' +. ./test-lib.sh + +add_email_corpus + +for outp in messages threads; do + test_begin_subtest "${outp}: limit does the right thing" + notmuch search --output=${outp} "*" | head -n 20 >expected + notmuch search --output=${outp} --limit=20 "*" >output + test_expect_equal_file expected output + + test_begin_subtest "${outp}: concatenation of limited searches" + notmuch search --output=${outp} "*" | head -n 20 >expected + notmuch search --output=${outp} --limit=10 "*" >output + notmuch search --output=${outp} --limit=10 --offset=10 "*" >>output + test_expect_equal_file expected output + + test_begin_subtest "${outp}: limit larger than result set" + N=`notmuch count --output=${outp} "*"` + notmuch search --output=${outp} "*" >expected + notmuch search --output=${outp} --limit=$((1 + ${N})) "*" >output + test_expect_equal_file expected output + + test_begin_subtest "${outp}: limit = 0" + test_expect_equal "`notmuch search --output=${outp} --limit=0 "*"`" "" + + test_begin_subtest "${outp}: offset does the right thing" + # note: tail -n +N is 1-based + notmuch search --output=${outp} "*" | tail -n +21 >expected + notmuch search --output=${outp} --offset=20 "*" >output + test_expect_equal_file expected output + + test_begin_subtest "${outp}: offset = 0" + notmuch search --output=${outp} "*" >expected + notmuch search --output=${outp} --offset=0 "*" >output + test_expect_equal_file expected output + + test_begin_subtest "${outp}: negative offset" + notmuch search --output=${outp} "*" | tail -n 20 >expected + notmuch search --output=${outp} --offset=-20 "*" >output + test_expect_equal_file expected output + + test_begin_subtest "${outp}: negative offset" + notmuch search --output=${outp} "*" | tail -n 1 >expected + notmuch search --output=${outp} --offset=-1 "*" >output + test_expect_equal_file expected output + + test_begin_subtest "${outp}: negative offset combined with limit" + notmuch search --output=${outp} "*" | tail -n 20 | head -n 10 >expected + notmuch search --output=${outp} --offset=-20 --limit=10 "*" >output + test_expect_equal_file expected output + + test_begin_subtest "${outp}: negative offset combined with equal limit" + notmuch search --output=${outp} "*" | tail -n 20 >expected + notmuch search --output=${outp} --offset=-20 --limit=20 "*" >output + test_expect_equal_file expected output + + test_begin_subtest "${outp}: negative offset combined with large limit" + notmuch search --output=${outp} "*" | tail -n 20 >expected + notmuch search --output=${outp} --offset=-20 --limit=50 "*" >output + test_expect_equal_file expected output + + test_begin_subtest "${outp}: negative offset larger then results" + N=`notmuch count --output=${outp} "*"` + notmuch search --output=${outp} "*" >expected + notmuch search --output=${outp} --offset=-$((1 + ${N})) "*" >output + test_expect_equal_file expected output +done + +test_done diff --git a/test/T140-excludes.sh b/test/T140-excludes.sh new file mode 100755 index 00000000..8bbbc2dd --- /dev/null +++ b/test/T140-excludes.sh @@ -0,0 +1,445 @@ +#!/usr/bin/env bash +test_description='"notmuch search, count and show" with excludes in several variations' +. ./test-lib.sh + +# Generates a thread consisting of a top level message and 'length' +# replies. The subject of the top message 'subject: top message" +# and the subject of the nth reply in the thread is "subject: reply n" +generate_thread () +{ + local subject="$1" + local length="$2" + generate_message '[subject]="'"${subject}: top message"'"' '[body]="'"body of top message"'"' + parent_id=$gen_msg_id + gen_thread_msg_id[0]=$gen_msg_id + for i in `seq 1 $length` + do + generate_message '[subject]="'"${subject}: reply $i"'"' \ + "[in-reply-to]=\<$parent_id\>" \ + '[body]="'"body of reply $i"'"' + gen_thread_msg_id[$i]=$gen_msg_id + parent_id=$gen_msg_id + done + notmuch new > /dev/null + # We cannot retrieve the thread_id until after we have run notmuch new. + gen_thread_id=`notmuch search --output=threads id:${gen_thread_msg_id[0]}` +} + +############################################# +# These are the original search exclude tests. + +test_begin_subtest "Search, exclude \"deleted\" messages from search" +notmuch config set search.exclude_tags deleted +generate_message '[subject]="Not deleted"' +not_deleted_id=$gen_msg_id +generate_message '[subject]="Deleted"' +notmuch new > /dev/null +notmuch tag +deleted id:$gen_msg_id +deleted_id=$gen_msg_id +output=$(notmuch search subject:deleted | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Not deleted (inbox unread)" + +test_begin_subtest "Search, exclude \"deleted\" messages from message search" +output=$(notmuch search --output=messages subject:deleted | notmuch_search_sanitize) +test_expect_equal "$output" "id:$not_deleted_id" + +test_begin_subtest "Search, exclude \"deleted\" messages from message search --exclude=false" +output=$(notmuch search --exclude=false --output=messages subject:deleted | notmuch_search_sanitize) +test_expect_equal "$output" "id:$not_deleted_id +id:$deleted_id" + +test_begin_subtest "Search, exclude \"deleted\" messages from message search (non-existent exclude-tag)" +notmuch config set search.exclude_tags deleted non_existent_tag +output=$(notmuch search --output=messages subject:deleted | notmuch_search_sanitize) +test_expect_equal "$output" "id:$not_deleted_id" +notmuch config set search.exclude_tags deleted + +test_begin_subtest "Search, exclude \"deleted\" messages from search, overridden" +output=$(notmuch search subject:deleted and tag:deleted | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Deleted (deleted inbox unread)" + +test_begin_subtest "Search, exclude \"deleted\" messages from threads" +add_message '[subject]="Not deleted reply"' '[in-reply-to]="<$gen_msg_id>"' +output=$(notmuch search subject:deleted | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Not deleted (inbox unread) +thread:XXX 2001-01-05 [1/2] Notmuch Test Suite; Not deleted reply (deleted inbox unread)" + +test_begin_subtest "Search, don't exclude \"deleted\" messages when --exclude=flag specified" +output=$(notmuch search --exclude=flag subject:deleted | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Not deleted (inbox unread) +thread:XXX 2001-01-05 [1/2] Notmuch Test Suite; Deleted (deleted inbox unread)" + +test_begin_subtest "Search, don't exclude \"deleted\" messages from search if not configured" +notmuch config set search.exclude_tags +output=$(notmuch search subject:deleted | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Not deleted (inbox unread) +thread:XXX 2001-01-05 [2/2] Notmuch Test Suite; Deleted (deleted inbox unread)" + + +######################################################## +# We construct some threads for the tests. We use the tag "test" to +# indicate which messages we will search for. + +# A thread of deleted messages; test matches one of them. +generate_thread "All messages excluded: single match" 5 +notmuch tag +deleted $gen_thread_id +notmuch tag +test id:${gen_thread_msg_id[2]} + +# A thread of deleted messages; test matches two of them. +generate_thread "All messages excluded: double match" 5 +notmuch tag +deleted $gen_thread_id +notmuch tag +test id:${gen_thread_msg_id[2]} +notmuch tag +test id:${gen_thread_msg_id[4]} + +# A thread some messages deleted; test only matches a deleted message. +generate_thread "Some messages excluded: single excluded match" 5 +notmuch tag +deleted +test id:${gen_thread_msg_id[3]} + +# A thread some messages deleted; test only matches a non-deleted message. +generate_thread "Some messages excluded: single non-excluded match" 5 +notmuch tag +deleted id:${gen_thread_msg_id[2]} +notmuch tag +test id:${gen_thread_msg_id[4]} + +# A thread no messages deleted; test matches a message. +generate_thread "No messages excluded: single match" 5 +notmuch tag +test id:${gen_thread_msg_id[3]} + +# Temporarily remove excludes to get list of matching messages +notmuch config set search.exclude_tags +matching_message_ids=( `notmuch search --output=messages tag:test` ) +notmuch config set search.exclude_tags deleted + +######################################### +# Notmuch search tests + +test_begin_subtest "Search, default exclusion (thread summary)" +output=$(notmuch search tag:test | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2001-01-05 [1/6] Notmuch Test Suite; Some messages excluded: single non-excluded match: reply 4 (deleted inbox test unread) +thread:XXX 2001-01-05 [1/6] Notmuch Test Suite; No messages excluded: single match: reply 3 (inbox test unread)" + +test_begin_subtest "Search, default exclusion (messages)" +output=$(notmuch search --output=messages tag:test | notmuch_search_sanitize) +test_expect_equal "$output" "${matching_message_ids[4]} +${matching_message_ids[5]}" + +test_begin_subtest "Search, exclude=true (thread summary)" +output=$(notmuch search --exclude=true tag:test | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2001-01-05 [1/6] Notmuch Test Suite; Some messages excluded: single non-excluded match: reply 4 (deleted inbox test unread) +thread:XXX 2001-01-05 [1/6] Notmuch Test Suite; No messages excluded: single match: reply 3 (inbox test unread)" + +test_begin_subtest "Search, exclude=true (messages)" +output=$(notmuch search --exclude=true --output=messages tag:test | notmuch_search_sanitize) +test_expect_equal "$output" "${matching_message_ids[4]} +${matching_message_ids[5]}" + +test_begin_subtest "Search, exclude=false (thread summary)" +output=$(notmuch search --exclude=false tag:test | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2001-01-05 [1/6] Notmuch Test Suite; All messages excluded: single match: reply 2 (deleted inbox test unread) +thread:XXX 2001-01-05 [2/6] Notmuch Test Suite; All messages excluded: double match: reply 2 (deleted inbox test unread) +thread:XXX 2001-01-05 [1/6] Notmuch Test Suite; Some messages excluded: single excluded match: reply 3 (deleted inbox test unread) +thread:XXX 2001-01-05 [1/6] Notmuch Test Suite; Some messages excluded: single non-excluded match: reply 4 (deleted inbox test unread) +thread:XXX 2001-01-05 [1/6] Notmuch Test Suite; No messages excluded: single match: reply 3 (inbox test unread)" + +test_begin_subtest "Search, exclude=false (messages)" +output=$(notmuch search --exclude=false --output=messages tag:test | notmuch_search_sanitize) +test_expect_equal "$output" "${matching_message_ids[0]} +${matching_message_ids[1]} +${matching_message_ids[2]} +${matching_message_ids[3]} +${matching_message_ids[4]} +${matching_message_ids[5]}" + +test_begin_subtest "Search, exclude=flag (thread summary)" +output=$(notmuch search --exclude=flag tag:test | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2001-01-05 [0/6] Notmuch Test Suite; All messages excluded: single match: reply 2 (deleted inbox test unread) +thread:XXX 2001-01-05 [0/6] Notmuch Test Suite; All messages excluded: double match: reply 2 (deleted inbox test unread) +thread:XXX 2001-01-05 [0/6] Notmuch Test Suite; Some messages excluded: single excluded match: reply 3 (deleted inbox test unread) +thread:XXX 2001-01-05 [1/6] Notmuch Test Suite; Some messages excluded: single non-excluded match: reply 4 (deleted inbox test unread) +thread:XXX 2001-01-05 [1/6] Notmuch Test Suite; No messages excluded: single match: reply 3 (inbox test unread)" + +test_begin_subtest "Search, exclude=flag (messages)" +output=$(notmuch search --exclude=flag --output=messages tag:test | notmuch_search_sanitize) +test_expect_equal "$output" "${matching_message_ids[0]} +${matching_message_ids[1]} +${matching_message_ids[2]} +${matching_message_ids[3]} +${matching_message_ids[4]} +${matching_message_ids[5]}" + +test_begin_subtest "Search, exclude=all (thread summary)" +output=$(notmuch search --exclude=all tag:test | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2001-01-05 [1/5] Notmuch Test Suite; Some messages excluded: single non-excluded match: reply 4 (inbox test unread) +thread:XXX 2001-01-05 [1/6] Notmuch Test Suite; No messages excluded: single match: reply 3 (inbox test unread)" + +test_begin_subtest "Search, exclude=all (messages)" +output=$(notmuch search --exclude=all --output=messages tag:test | notmuch_search_sanitize) +test_expect_equal "$output" "${matching_message_ids[4]} +${matching_message_ids[5]}" + +test_begin_subtest "Search, default exclusion: tag in query (thread summary)" +output=$(notmuch search tag:test and tag:deleted | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2001-01-05 [1/6] Notmuch Test Suite; All messages excluded: single match: reply 2 (deleted inbox test unread) +thread:XXX 2001-01-05 [2/6] Notmuch Test Suite; All messages excluded: double match: reply 2 (deleted inbox test unread) +thread:XXX 2001-01-05 [1/6] Notmuch Test Suite; Some messages excluded: single excluded match: reply 3 (deleted inbox test unread)" + +test_begin_subtest "Search, default exclusion: tag in query (messages)" +output=$(notmuch search --output=messages tag:test and tag:deleted | notmuch_search_sanitize) +test_expect_equal "$output" "${matching_message_ids[0]} +${matching_message_ids[1]} +${matching_message_ids[2]} +${matching_message_ids[3]}" + +test_begin_subtest "Search, exclude=true: tag in query (thread summary)" +output=$(notmuch search --exclude=true tag:test and tag:deleted | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2001-01-05 [1/6] Notmuch Test Suite; All messages excluded: single match: reply 2 (deleted inbox test unread) +thread:XXX 2001-01-05 [2/6] Notmuch Test Suite; All messages excluded: double match: reply 2 (deleted inbox test unread) +thread:XXX 2001-01-05 [1/6] Notmuch Test Suite; Some messages excluded: single excluded match: reply 3 (deleted inbox test unread)" + +test_begin_subtest "Search, exclude=true: tag in query (messages)" +output=$(notmuch search --exclude=true --output=messages tag:test and tag:deleted | notmuch_search_sanitize) +test_expect_equal "$output" "${matching_message_ids[0]} +${matching_message_ids[1]} +${matching_message_ids[2]} +${matching_message_ids[3]}" + +test_begin_subtest "Search, exclude=false: tag in query (thread summary)" +output=$(notmuch search --exclude=false tag:test and tag:deleted | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2001-01-05 [1/6] Notmuch Test Suite; All messages excluded: single match: reply 2 (deleted inbox test unread) +thread:XXX 2001-01-05 [2/6] Notmuch Test Suite; All messages excluded: double match: reply 2 (deleted inbox test unread) +thread:XXX 2001-01-05 [1/6] Notmuch Test Suite; Some messages excluded: single excluded match: reply 3 (deleted inbox test unread)" + +test_begin_subtest "Search, exclude=false: tag in query (messages)" +output=$(notmuch search --exclude=false --output=messages tag:test and tag:deleted | notmuch_search_sanitize) +test_expect_equal "$output" "${matching_message_ids[0]} +${matching_message_ids[1]} +${matching_message_ids[2]} +${matching_message_ids[3]}" + +test_begin_subtest "Search, exclude=flag: tag in query (thread summary)" +output=$(notmuch search --exclude=flag tag:test and tag:deleted | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2001-01-05 [1/6] Notmuch Test Suite; All messages excluded: single match: reply 2 (deleted inbox test unread) +thread:XXX 2001-01-05 [2/6] Notmuch Test Suite; All messages excluded: double match: reply 2 (deleted inbox test unread) +thread:XXX 2001-01-05 [1/6] Notmuch Test Suite; Some messages excluded: single excluded match: reply 3 (deleted inbox test unread)" + +test_begin_subtest "Search, exclude=flag: tag in query (messages)" +output=$(notmuch search --exclude=flag --output=messages tag:test and tag:deleted | notmuch_search_sanitize) +test_expect_equal "$output" "${matching_message_ids[0]} +${matching_message_ids[1]} +${matching_message_ids[2]} +${matching_message_ids[3]}" + +test_begin_subtest "Search, exclude=all: tag in query (thread summary)" +output=$(notmuch search --exclude=all tag:test and tag:deleted | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2001-01-05 [1/6] Notmuch Test Suite; All messages excluded: single match: reply 2 (deleted inbox test unread) +thread:XXX 2001-01-05 [2/6] Notmuch Test Suite; All messages excluded: double match: reply 2 (deleted inbox test unread) +thread:XXX 2001-01-05 [1/6] Notmuch Test Suite; Some messages excluded: single excluded match: reply 3 (deleted inbox test unread)" + +test_begin_subtest "Search, exclude=all: tag in query (messages)" +output=$(notmuch search --exclude=all --output=messages tag:test and tag:deleted | notmuch_search_sanitize) +test_expect_equal "$output" "${matching_message_ids[0]} +${matching_message_ids[1]} +${matching_message_ids[2]} +${matching_message_ids[3]}" + +######################################################### +# Notmuch count tests + +test_begin_subtest "Count, default exclusion (messages)" +output=$(notmuch count tag:test) +test_expect_equal "$output" "2" + +test_begin_subtest "Count, default exclusion (threads)" +output=$(notmuch count --output=threads tag:test) +test_expect_equal "$output" "2" + +test_begin_subtest "Count, exclude=true (messages)" +output=$(notmuch count --exclude=true tag:test) +test_expect_equal "$output" "2" + +test_begin_subtest "Count, exclude=true (threads)" +output=$(notmuch count --output=threads --exclude=true tag:test) +test_expect_equal "$output" "2" + +test_begin_subtest "Count, exclude=false (messages)" +output=$(notmuch count --exclude=false tag:test) +test_expect_equal "$output" "6" + +test_begin_subtest "Count, exclude=false (threads)" +output=$(notmuch count --output=threads --exclude=false tag:test) +test_expect_equal "$output" "5" + +test_begin_subtest "Count, default exclusion: tag in query (messages)" +output=$(notmuch count tag:test and tag:deleted) +test_expect_equal "$output" "4" + +test_begin_subtest "Count, default exclusion: tag in query (threads)" +output=$(notmuch count --output=threads tag:test and tag:deleted) +test_expect_equal "$output" "3" + +test_begin_subtest "Count, exclude=true: tag in query (messages)" +output=$(notmuch count --exclude=true tag:test and tag:deleted) +test_expect_equal "$output" "4" + +test_begin_subtest "Count, exclude=true: tag in query (threads)" +output=$(notmuch count --output=threads --exclude=true tag:test and tag:deleted) +test_expect_equal "$output" "3" + +test_begin_subtest "Count, exclude=false: tag in query (messages)" +output=$(notmuch count --exclude=false tag:test and tag:deleted) +test_expect_equal "$output" "4" + +test_begin_subtest "Count, exclude=false: tag in query (threads)" +output=$(notmuch count --output=threads --exclude=false tag:test and tag:deleted) +test_expect_equal "$output" "3" + +############################################################# +# Show tests + +test_begin_subtest "Show, default exclusion" +output=$(notmuch show tag:test | notmuch_show_sanitize_all | egrep "Subject:|message{") +test_expect_equal "$output" " message{ id:XXXXX depth:0 match:1 excluded:0 filename:XXXXX +Subject: Some messages excluded: single non-excluded match: reply 4 + message{ id:XXXXX depth:0 match:1 excluded:0 filename:XXXXX +Subject: No messages excluded: single match: reply 3" + +test_begin_subtest "Show, default exclusion (entire-thread)" +output=$(notmuch show --entire-thread tag:test | notmuch_show_sanitize_all | egrep "Subject:|message{") +test_expect_equal "$output" " message{ id:XXXXX depth:0 match:0 excluded:0 filename:XXXXX +Subject: Some messages excluded: single non-excluded match: top message + message{ id:XXXXX depth:1 match:0 excluded:0 filename:XXXXX +Subject: Some messages excluded: single non-excluded match: reply 1 + message{ id:XXXXX depth:2 match:0 excluded:1 filename:XXXXX +Subject: Some messages excluded: single non-excluded match: reply 2 + message{ id:XXXXX depth:3 match:0 excluded:0 filename:XXXXX +Subject: Some messages excluded: single non-excluded match: reply 3 + message{ id:XXXXX depth:4 match:1 excluded:0 filename:XXXXX +Subject: Some messages excluded: single non-excluded match: reply 4 + message{ id:XXXXX depth:5 match:0 excluded:0 filename:XXXXX +Subject: Some messages excluded: single non-excluded match: reply 5 + message{ id:XXXXX depth:0 match:0 excluded:0 filename:XXXXX +Subject: No messages excluded: single match: top message + message{ id:XXXXX depth:1 match:0 excluded:0 filename:XXXXX +Subject: No messages excluded: single match: reply 1 + message{ id:XXXXX depth:2 match:0 excluded:0 filename:XXXXX +Subject: No messages excluded: single match: reply 2 + message{ id:XXXXX depth:3 match:1 excluded:0 filename:XXXXX +Subject: No messages excluded: single match: reply 3 + message{ id:XXXXX depth:4 match:0 excluded:0 filename:XXXXX +Subject: No messages excluded: single match: reply 4 + message{ id:XXXXX depth:5 match:0 excluded:0 filename:XXXXX +Subject: No messages excluded: single match: reply 5" + +test_begin_subtest "Show, exclude=true" +output=$(notmuch show --exclude=true tag:test | notmuch_show_sanitize_all | egrep "Subject:|message{") +test_expect_equal "$output" " message{ id:XXXXX depth:0 match:1 excluded:0 filename:XXXXX +Subject: Some messages excluded: single non-excluded match: reply 4 + message{ id:XXXXX depth:0 match:1 excluded:0 filename:XXXXX +Subject: No messages excluded: single match: reply 3" + +test_begin_subtest "Show, exclude=true (entire-thread)" +output=$(notmuch show --entire-thread --exclude=true tag:test | notmuch_show_sanitize_all | egrep "Subject:|message{") +test_expect_equal "$output" " message{ id:XXXXX depth:0 match:0 excluded:0 filename:XXXXX +Subject: Some messages excluded: single non-excluded match: top message + message{ id:XXXXX depth:1 match:0 excluded:0 filename:XXXXX +Subject: Some messages excluded: single non-excluded match: reply 1 + message{ id:XXXXX depth:2 match:0 excluded:1 filename:XXXXX +Subject: Some messages excluded: single non-excluded match: reply 2 + message{ id:XXXXX depth:3 match:0 excluded:0 filename:XXXXX +Subject: Some messages excluded: single non-excluded match: reply 3 + message{ id:XXXXX depth:4 match:1 excluded:0 filename:XXXXX +Subject: Some messages excluded: single non-excluded match: reply 4 + message{ id:XXXXX depth:5 match:0 excluded:0 filename:XXXXX +Subject: Some messages excluded: single non-excluded match: reply 5 + message{ id:XXXXX depth:0 match:0 excluded:0 filename:XXXXX +Subject: No messages excluded: single match: top message + message{ id:XXXXX depth:1 match:0 excluded:0 filename:XXXXX +Subject: No messages excluded: single match: reply 1 + message{ id:XXXXX depth:2 match:0 excluded:0 filename:XXXXX +Subject: No messages excluded: single match: reply 2 + message{ id:XXXXX depth:3 match:1 excluded:0 filename:XXXXX +Subject: No messages excluded: single match: reply 3 + message{ id:XXXXX depth:4 match:0 excluded:0 filename:XXXXX +Subject: No messages excluded: single match: reply 4 + message{ id:XXXXX depth:5 match:0 excluded:0 filename:XXXXX +Subject: No messages excluded: single match: reply 5" + +test_begin_subtest "Show, exclude=false" +output=$(notmuch show --exclude=false tag:test | notmuch_show_sanitize_all | egrep "Subject:|message{") +test_expect_equal "$output" " message{ id:XXXXX depth:0 match:1 excluded:1 filename:XXXXX +Subject: All messages excluded: single match: reply 2 + message{ id:XXXXX depth:0 match:1 excluded:1 filename:XXXXX +Subject: All messages excluded: double match: reply 2 + message{ id:XXXXX depth:1 match:1 excluded:1 filename:XXXXX +Subject: All messages excluded: double match: reply 4 + message{ id:XXXXX depth:0 match:1 excluded:1 filename:XXXXX +Subject: Some messages excluded: single excluded match: reply 3 + message{ id:XXXXX depth:0 match:1 excluded:0 filename:XXXXX +Subject: Some messages excluded: single non-excluded match: reply 4 + message{ id:XXXXX depth:0 match:1 excluded:0 filename:XXXXX +Subject: No messages excluded: single match: reply 3" + +test_begin_subtest "Show, exclude=false (entire-thread)" +output=$(notmuch show --entire-thread --exclude=false tag:test | notmuch_show_sanitize_all | egrep "Subject:|message{") +test_expect_equal "$output" " message{ id:XXXXX depth:0 match:0 excluded:1 filename:XXXXX +Subject: All messages excluded: single match: top message + message{ id:XXXXX depth:1 match:0 excluded:1 filename:XXXXX +Subject: All messages excluded: single match: reply 1 + message{ id:XXXXX depth:2 match:1 excluded:1 filename:XXXXX +Subject: All messages excluded: single match: reply 2 + message{ id:XXXXX depth:3 match:0 excluded:1 filename:XXXXX +Subject: All messages excluded: single match: reply 3 + message{ id:XXXXX depth:4 match:0 excluded:1 filename:XXXXX +Subject: All messages excluded: single match: reply 4 + message{ id:XXXXX depth:5 match:0 excluded:1 filename:XXXXX +Subject: All messages excluded: single match: reply 5 + message{ id:XXXXX depth:0 match:0 excluded:1 filename:XXXXX +Subject: All messages excluded: double match: top message + message{ id:XXXXX depth:1 match:0 excluded:1 filename:XXXXX +Subject: All messages excluded: double match: reply 1 + message{ id:XXXXX depth:2 match:1 excluded:1 filename:XXXXX +Subject: All messages excluded: double match: reply 2 + message{ id:XXXXX depth:3 match:0 excluded:1 filename:XXXXX +Subject: All messages excluded: double match: reply 3 + message{ id:XXXXX depth:4 match:1 excluded:1 filename:XXXXX +Subject: All messages excluded: double match: reply 4 + message{ id:XXXXX depth:5 match:0 excluded:1 filename:XXXXX +Subject: All messages excluded: double match: reply 5 + message{ id:XXXXX depth:0 match:0 excluded:0 filename:XXXXX +Subject: Some messages excluded: single excluded match: top message + message{ id:XXXXX depth:1 match:0 excluded:0 filename:XXXXX +Subject: Some messages excluded: single excluded match: reply 1 + message{ id:XXXXX depth:2 match:0 excluded:0 filename:XXXXX +Subject: Some messages excluded: single excluded match: reply 2 + message{ id:XXXXX depth:3 match:1 excluded:1 filename:XXXXX +Subject: Some messages excluded: single excluded match: reply 3 + message{ id:XXXXX depth:4 match:0 excluded:0 filename:XXXXX +Subject: Some messages excluded: single excluded match: reply 4 + message{ id:XXXXX depth:5 match:0 excluded:0 filename:XXXXX +Subject: Some messages excluded: single excluded match: reply 5 + message{ id:XXXXX depth:0 match:0 excluded:0 filename:XXXXX +Subject: Some messages excluded: single non-excluded match: top message + message{ id:XXXXX depth:1 match:0 excluded:0 filename:XXXXX +Subject: Some messages excluded: single non-excluded match: reply 1 + message{ id:XXXXX depth:2 match:0 excluded:1 filename:XXXXX +Subject: Some messages excluded: single non-excluded match: reply 2 + message{ id:XXXXX depth:3 match:0 excluded:0 filename:XXXXX +Subject: Some messages excluded: single non-excluded match: reply 3 + message{ id:XXXXX depth:4 match:1 excluded:0 filename:XXXXX +Subject: Some messages excluded: single non-excluded match: reply 4 + message{ id:XXXXX depth:5 match:0 excluded:0 filename:XXXXX +Subject: Some messages excluded: single non-excluded match: reply 5 + message{ id:XXXXX depth:0 match:0 excluded:0 filename:XXXXX +Subject: No messages excluded: single match: top message + message{ id:XXXXX depth:1 match:0 excluded:0 filename:XXXXX +Subject: No messages excluded: single match: reply 1 + message{ id:XXXXX depth:2 match:0 excluded:0 filename:XXXXX +Subject: No messages excluded: single match: reply 2 + message{ id:XXXXX depth:3 match:1 excluded:0 filename:XXXXX +Subject: No messages excluded: single match: reply 3 + message{ id:XXXXX depth:4 match:0 excluded:0 filename:XXXXX +Subject: No messages excluded: single match: reply 4 + message{ id:XXXXX depth:5 match:0 excluded:0 filename:XXXXX +Subject: No messages excluded: single match: reply 5" + + +test_done diff --git a/test/T150-tagging.sh b/test/T150-tagging.sh new file mode 100755 index 00000000..dc118f33 --- /dev/null +++ b/test/T150-tagging.sh @@ -0,0 +1,264 @@ +#!/usr/bin/env bash +test_description='"notmuch tag"' +. ./test-lib.sh + +add_message '[subject]=One' +add_message '[subject]=Two' + +test_begin_subtest "Adding tags" +notmuch tag +tag1 +tag2 +tag3 \* +output=$(notmuch search \* | notmuch_search_sanitize) +test_expect_equal "$output" "\ +thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; One (inbox tag1 tag2 tag3 unread) +thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Two (inbox tag1 tag2 tag3 unread)" + +test_begin_subtest "Removing tags" +notmuch tag -tag1 -tag2 \* +output=$(notmuch search \* | notmuch_search_sanitize) +test_expect_equal "$output" "\ +thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; One (inbox tag3 unread) +thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Two (inbox tag3 unread)" + +test_expect_code 1 "No tag operations" 'notmuch tag One' +test_expect_code 1 "No query" 'notmuch tag +tag2' + +test_begin_subtest "Redundant tagging" +notmuch tag +tag1 -tag3 One +notmuch tag +tag1 -tag3 \* +output=$(notmuch search \* | notmuch_search_sanitize) +test_expect_equal "$output" "\ +thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; One (inbox tag1 unread) +thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Two (inbox tag1 unread)" + +test_begin_subtest "Remove all" +notmuch tag --remove-all One +notmuch tag --remove-all +tag5 +tag6 +unread Two +output=$(notmuch search \* | notmuch_search_sanitize) +test_expect_equal "$output" "\ +thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; One () +thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Two (tag5 tag6 unread)" + +test_begin_subtest "Remove all with a no-op" +notmuch tag +inbox +tag1 +unread One +notmuch tag --remove-all +foo +inbox +tag1 -foo +unread Two +output=$(notmuch search \* | notmuch_search_sanitize) +test_expect_equal "$output" "\ +thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; One (inbox tag1 unread) +thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Two (inbox tag1 unread)" + +test_begin_subtest "Special characters in tags" +notmuch tag +':" ' \* +notmuch tag -':" ' Two +output=$(notmuch search \* | notmuch_search_sanitize) +test_expect_equal "$output" "\ +thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; One (:\" inbox tag1 unread) +thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Two (inbox tag1 unread)" + +test_begin_subtest "Tagging order" +notmuch tag +tag4 -tag4 One +notmuch tag -tag4 +tag4 Two +output=$(notmuch search \* | notmuch_search_sanitize) +test_expect_equal "$output" "\ +thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; One (:\" inbox tag1 unread) +thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Two (inbox tag1 tag4 unread)" + +test_begin_subtest "--batch" +notmuch tag --batch < batch.in < batch.expected < backup.tags +notmuch tag --input=batch.in +notmuch search \* | notmuch_search_sanitize > OUTPUT +notmuch restore --format=batch-tag < backup.tags +test_expect_equal_file batch.expected OUTPUT + +test_begin_subtest "--batch --input" +notmuch dump --format=batch-tag > backup.tags +notmuch tag --batch --input=batch.in +notmuch search \* | notmuch_search_sanitize > OUTPUT +notmuch restore --format=batch-tag < backup.tags +test_expect_equal_file batch.expected OUTPUT + +test_begin_subtest "--batch, blank lines and comments" +notmuch dump | sort > EXPECTED +notmuch tag --batch < OUTPUT +test_expect_equal_file EXPECTED OUTPUT + +test_begin_subtest '--batch: checking error messages' +notmuch dump --format=batch-tag > BACKUP +notmuch tag --batch <OUTPUT +# the next line has a space + +# this line has no tag operations, but this is permitted in batch format. +a ++0 ++a +b +# trailing whitespace ++a +b ++c +d -- +# this is a harmless comment, do not yell about it. + +# the previous line was blank; also no yelling please ++%zz -- id:whatever +# the next non-comment line should report an an empty tag error for +# batch tagging, but not for restore ++ +e -- id:foo ++- -- id:foo +EOF + +cat < EXPECTED +Warning: no query string [+0] +Warning: no query string [+a +b] +Warning: missing query string [+a +b ] +Warning: no query string after -- [+c +d --] +Warning: hex decoding of tag %zz failed [+%zz -- id:whatever] +Warning: empty tag forbidden [+ +e -- id:foo] +Warning: tag starting with '-' forbidden [+- -- id:foo] +EOF + +notmuch restore --format=batch-tag < BACKUP +test_expect_equal_file EXPECTED OUTPUT + +test_begin_subtest '--batch: tags with quotes' +notmuch dump --format=batch-tag > BACKUP + +notmuch tag --batch < EXPECTED ++%22%27%22%22%22%27 +inbox +tag5 +unread -- id:msg-001@notmuch-test-suite ++%22%27%22%27%22%22%27%27 +inbox +tag4 +tag5 +unread -- id:msg-002@notmuch-test-suite +EOF + +notmuch dump --format=batch-tag | sort > OUTPUT +notmuch restore --format=batch-tag < BACKUP +test_expect_equal_file EXPECTED OUTPUT + +test_begin_subtest '--batch: tags with punctuation and space' +notmuch dump --format=batch-tag > BACKUP + +notmuch tag --batch < EXPECTED ++%21@%23%20%24%25%5e%26%2a%29-_=+%5b%7b%5c%20%7c%3b%3a%27%20%22,.%3c%60%7e +inbox +tag4 +tag5 +unread -- id:msg-002@notmuch-test-suite ++%21@%23%20%24%25%5e%26%2a%29-_=+%5b%7b%5c%20%7c%3b%3a%27%20%22,.%3c%60%7e +inbox +tag5 +unread -- id:msg-001@notmuch-test-suite +EOF + +notmuch dump --format=batch-tag | sort > OUTPUT +notmuch restore --format=batch-tag < BACKUP +test_expect_equal_file EXPECTED OUTPUT + +test_begin_subtest '--batch: unicode tags' +notmuch dump --format=batch-tag > BACKUP + +notmuch tag --batch < EXPECTED ++%2a@%7d%cf%b5%f4%85%80%adO3%da%a7 +=%e0%ac%95%c8%b3+%ef%aa%95%c8%a64w%c7%9d%c9%a2%cf%b3%d6%82%24B%c4%a9%c5%a1UX%ee%99%b0%27E7%ca%a4%d0%8b%5d +A%e1%a0%bc%de%8b%d5%b2V%d9%9b%f3%b5%a2%a3M%d8%a1u@%f0%a0%ac%948%7e%f0%ab%86%af%27 +L%df%85%ef%a1%a5m@%d3%96%c2%ab%d4%9f%ca%b8%f3%b3%a2%bf%c7%b1_u%d7%b4%c7%b1 +P%c4%98%2f +R +inbox +tag4 +tag5 +unread +%7e%d1%8b%25%ec%a0%ae%d1%a0M%3b%e3%b6%b7%e9%a4%87%3c%db%9a%cc%a8%e1%96%9d +%c4%bf7%c7%ab9H%c4%99k%ea%91%bd%c3%8ck%e2%b3%8dk%c5%952V%e4%99%b2%d9%b3%e4%8b%bda%5b%24%c7%9b +%da%88=f%cc%b9I%ce%af%7b%c9%97%e3%b9%8bH%cb%92X%d2%8c6 +%dc%9crh%d2%86B%e5%97%a2%22t%ed%99%82d -- id:msg-002@notmuch-test-suite ++%2a@%7d%cf%b5%f4%85%80%adO3%da%a7 +=%e0%ac%95%c8%b3+%ef%aa%95%c8%a64w%c7%9d%c9%a2%cf%b3%d6%82%24B%c4%a9%c5%a1UX%ee%99%b0%27E7%ca%a4%d0%8b%5d +A%e1%a0%bc%de%8b%d5%b2V%d9%9b%f3%b5%a2%a3M%d8%a1u@%f0%a0%ac%948%7e%f0%ab%86%af%27 +L%df%85%ef%a1%a5m@%d3%96%c2%ab%d4%9f%ca%b8%f3%b3%a2%bf%c7%b1_u%d7%b4%c7%b1 +P%c4%98%2f +R +inbox +tag5 +unread +%7e%d1%8b%25%ec%a0%ae%d1%a0M%3b%e3%b6%b7%e9%a4%87%3c%db%9a%cc%a8%e1%96%9d +%c4%bf7%c7%ab9H%c4%99k%ea%91%bd%c3%8ck%e2%b3%8dk%c5%952V%e4%99%b2%d9%b3%e4%8b%bda%5b%24%c7%9b +%da%88=f%cc%b9I%ce%af%7b%c9%97%e3%b9%8bH%cb%92X%d2%8c6 +%dc%9crh%d2%86B%e5%97%a2%22t%ed%99%82d -- id:msg-001@notmuch-test-suite +EOF + +notmuch dump --format=batch-tag | sort > OUTPUT +notmuch restore --format=batch-tag < BACKUP +test_expect_equal_file EXPECTED OUTPUT + +test_begin_subtest "--batch: only space and % needs to be encoded." +notmuch dump --format=batch-tag > BACKUP + +notmuch tag --batch < EXPECTED ++%23possible%5c +%26are +%28tags%29 +crazy%7b +inbox +match%2acrazy +space%20in%20tags +tag4 +tag5 +unread +winner -- id:msg-002@notmuch-test-suite ++foo%3a%3abar%25 +found%3a%3ait +inbox +tag5 +unread +winner -- id:msg-001@notmuch-test-suite +EOF + +notmuch dump --format=batch-tag | sort > OUTPUT +notmuch restore --format=batch-tag < BACKUP +test_expect_equal_file EXPECTED OUTPUT + +test_begin_subtest '--batch: unicode message-ids' + +${TEST_DIRECTORY}/random-corpus --config-path=${NOTMUCH_CONFIG} \ + --num-messages=100 + +notmuch dump --format=batch-tag | sed 's/^.* -- /+common_tag -- /' | \ + sort > EXPECTED + +notmuch dump --format=batch-tag | sed 's/^.* -- / -- /' | \ + notmuch restore --format=batch-tag + +notmuch tag --batch < EXPECTED + +notmuch dump --format=batch-tag| \ + sort > OUTPUT + +test_expect_equal_file EXPECTED OUTPUT + +test_expect_code 1 "Empty tag names" 'notmuch tag + One' + +test_expect_code 1 "Tag name beginning with -" 'notmuch tag +- One' + +test_done diff --git a/test/T160-json.sh b/test/T160-json.sh new file mode 100755 index 00000000..c1cf649d --- /dev/null +++ b/test/T160-json.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env bash +test_description="--format=json output" +. ./test-lib.sh + +test_begin_subtest "Show message: json" +add_message "[subject]=\"json-show-subject\"" "[date]=\"Sat, 01 Jan 2000 12:00:00 -0000\"" "[bcc]=\"test_suite+bcc@notmuchmail.org\"" "[reply-to]=\"test_suite+replyto@notmuchmail.org\"" "[body]=\"json-show-message\"" +output=$(notmuch show --format=json "json-show-message") +test_expect_equal_json "$output" "[[[{\"id\": \"${gen_msg_id}\", \"match\": true, \"excluded\": false, \"filename\": \"${gen_msg_filename}\", \"timestamp\": 946728000, \"date_relative\": \"2000-01-01\", \"tags\": [\"inbox\",\"unread\"], \"headers\": {\"Subject\": \"json-show-subject\", \"From\": \"Notmuch Test Suite \", \"To\": \"Notmuch Test Suite \", \"Bcc\": \"test_suite+bcc@notmuchmail.org\", \"Reply-To\": \"test_suite+replyto@notmuchmail.org\", \"Date\": \"Sat, 01 Jan 2000 12:00:00 +0000\"}, \"body\": [{\"id\": 1, \"content-type\": \"text/plain\", \"content\": \"json-show-message\n\"}]}, []]]]" + +# This should be the same output as above. +test_begin_subtest "Show message: json --body=true" +output=$(notmuch show --format=json --body=true "json-show-message") +test_expect_equal_json "$output" "[[[{\"id\": \"${gen_msg_id}\", \"match\": true, \"excluded\": false, \"filename\": \"${gen_msg_filename}\", \"timestamp\": 946728000, \"date_relative\": \"2000-01-01\", \"tags\": [\"inbox\",\"unread\"], \"headers\": {\"Subject\": \"json-show-subject\", \"From\": \"Notmuch Test Suite \", \"To\": \"Notmuch Test Suite \", \"Bcc\": \"test_suite+bcc@notmuchmail.org\", \"Reply-To\": \"test_suite+replyto@notmuchmail.org\", \"Date\": \"Sat, 01 Jan 2000 12:00:00 +0000\"}, \"body\": [{\"id\": 1, \"content-type\": \"text/plain\", \"content\": \"json-show-message\n\"}]}, []]]]" + +test_begin_subtest "Show message: json --body=false" +output=$(notmuch show --format=json --body=false "json-show-message") +test_expect_equal_json "$output" "[[[{\"id\": \"${gen_msg_id}\", \"match\": true, \"excluded\": false, \"filename\": \"${gen_msg_filename}\", \"timestamp\": 946728000, \"date_relative\": \"2000-01-01\", \"tags\": [\"inbox\",\"unread\"], \"headers\": {\"Subject\": \"json-show-subject\", \"From\": \"Notmuch Test Suite \", \"To\": \"Notmuch Test Suite \", \"Bcc\": \"test_suite+bcc@notmuchmail.org\", \"Reply-To\": \"test_suite+replyto@notmuchmail.org\", \"Date\": \"Sat, 01 Jan 2000 12:00:00 +0000\"}}, []]]]" + +test_begin_subtest "Search message: json" +add_message "[subject]=\"json-search-subject\"" "[date]=\"Sat, 01 Jan 2000 12:00:00 -0000\"" "[body]=\"json-search-message\"" +output=$(notmuch search --format=json "json-search-message" | notmuch_search_sanitize) +test_expect_equal_json "$output" "[{\"thread\": \"XXX\", + \"timestamp\": 946728000, + \"date_relative\": \"2000-01-01\", + \"matched\": 1, + \"total\": 1, + \"authors\": \"Notmuch Test Suite\", + \"subject\": \"json-search-subject\", + \"query\": [\"id:$gen_msg_id\", null], + \"tags\": [\"inbox\", + \"unread\"]}]" + +test_begin_subtest "Show message: json, utf-8" +add_message "[subject]=\"json-show-utf8-body-sübjéct\"" "[date]=\"Sat, 01 Jan 2000 12:00:00 -0000\"" "[body]=\"jsön-show-méssage\"" +output=$(notmuch show --format=json "jsön-show-méssage") +test_expect_equal_json "$output" "[[[{\"id\": \"${gen_msg_id}\", \"match\": true, \"excluded\": false, \"filename\": \"${gen_msg_filename}\", \"timestamp\": 946728000, \"date_relative\": \"2000-01-01\", \"tags\": [\"inbox\",\"unread\"], \"headers\": {\"Subject\": \"json-show-utf8-body-sübjéct\", \"From\": \"Notmuch Test Suite \", \"To\": \"Notmuch Test Suite \", \"Date\": \"Sat, 01 Jan 2000 12:00:00 +0000\"}, \"body\": [{\"id\": 1, \"content-type\": \"text/plain\", \"content\": \"jsön-show-méssage\n\"}]}, []]]]" + +test_begin_subtest "Show message: json, inline attachment filename" +subject='json-show-inline-attachment-filename' +id="json-show-inline-attachment-filename@notmuchmail.org" +emacs_fcc_message \ + "$subject" \ + 'This is a test message with inline attachment with a filename' \ + "(mml-attach-file \"$TEST_DIRECTORY/README\" nil nil \"inline\") + (message-goto-eoh) + (insert \"Message-ID: <$id>\n\")" +output=$(notmuch show --format=json "id:$id") +filename=$(notmuch search --output=files "id:$id") +# Get length of README after base64-encoding, minus additional newline. +attachment_length=$(( $(base64 $TEST_DIRECTORY/README | wc -c) - 1 )) +test_expect_equal_json "$output" "[[[{\"id\": \"$id\", \"match\": true, \"excluded\": false, \"filename\": \"$filename\", \"timestamp\": 946728000, \"date_relative\": \"2000-01-01\", \"tags\": [\"inbox\"], \"headers\": {\"Subject\": \"$subject\", \"From\": \"Notmuch Test Suite \", \"To\": \"test_suite@notmuchmail.org\", \"Date\": \"Sat, 01 Jan 2000 12:00:00 +0000\"}, \"body\": [{\"id\": 1, \"content-type\": \"multipart/mixed\", \"content\": [{\"id\": 2, \"content-type\": \"text/plain\", \"content\": \"This is a test message with inline attachment with a filename\"}, {\"id\": 3, \"content-type\": \"application/octet-stream\", \"content-length\": $attachment_length, \"content-transfer-encoding\": \"base64\", \"filename\": \"README\"}]}]}, []]]]" + +test_begin_subtest "Search message: json, utf-8" +add_message "[subject]=\"json-search-utf8-body-sübjéct\"" "[date]=\"Sat, 01 Jan 2000 12:00:00 -0000\"" "[body]=\"jsön-search-méssage\"" +output=$(notmuch search --format=json "jsön-search-méssage" | notmuch_search_sanitize) +test_expect_equal_json "$output" "[{\"thread\": \"XXX\", + \"timestamp\": 946728000, + \"date_relative\": \"2000-01-01\", + \"matched\": 1, + \"total\": 1, + \"authors\": \"Notmuch Test Suite\", + \"subject\": \"json-search-utf8-body-sübjéct\", + \"query\": [\"id:$gen_msg_id\", null], + \"tags\": [\"inbox\", + \"unread\"]}]" + +test_expect_code 20 "Format version: too low" \ + "notmuch search --format-version=0 \\*" + +test_expect_code 21 "Format version: too high" \ + "notmuch search --format-version=999 \\*" + +test_done diff --git a/test/T170-sexp.sh b/test/T170-sexp.sh new file mode 100755 index 00000000..667e3195 --- /dev/null +++ b/test/T170-sexp.sh @@ -0,0 +1,50 @@ +#!/usr/bin/env bash +test_description="--format=sexp output" +. ./test-lib.sh + +test_begin_subtest "Show message: sexp" +add_message "[subject]=\"sexp-show-subject\"" "[date]=\"Sat, 01 Jan 2000 12:00:00 -0000\"" "[bcc]=\"test_suite+bcc@notmuchmail.org\"" "[reply-to]=\"test_suite+replyto@notmuchmail.org\"" "[body]=\"sexp-show-message\"" +output=$(notmuch show --format=sexp "sexp-show-message") +test_expect_equal "$output" "((((:id \"${gen_msg_id}\" :match t :excluded nil :filename \"${gen_msg_filename}\" :timestamp 946728000 :date_relative \"2000-01-01\" :tags (\"inbox\" \"unread\") :headers (:Subject \"sexp-show-subject\" :From \"Notmuch Test Suite \" :To \"Notmuch Test Suite \" :Bcc \"test_suite+bcc@notmuchmail.org\" :Reply-To \"test_suite+replyto@notmuchmail.org\" :Date \"Sat, 01 Jan 2000 12:00:00 +0000\") :body ((:id 1 :content-type \"text/plain\" :content \"sexp-show-message\n\"))) ())))" + +# This should be the same output as above. +test_begin_subtest "Show message: sexp --body=true" +output=$(notmuch show --format=sexp --body=true "sexp-show-message") +test_expect_equal "$output" "((((:id \"${gen_msg_id}\" :match t :excluded nil :filename \"${gen_msg_filename}\" :timestamp 946728000 :date_relative \"2000-01-01\" :tags (\"inbox\" \"unread\") :headers (:Subject \"sexp-show-subject\" :From \"Notmuch Test Suite \" :To \"Notmuch Test Suite \" :Bcc \"test_suite+bcc@notmuchmail.org\" :Reply-To \"test_suite+replyto@notmuchmail.org\" :Date \"Sat, 01 Jan 2000 12:00:00 +0000\") :body ((:id 1 :content-type \"text/plain\" :content \"sexp-show-message\n\"))) ())))" + +test_begin_subtest "Show message: sexp --body=false" +output=$(notmuch show --format=sexp --body=false "sexp-show-message") +test_expect_equal "$output" "((((:id \"${gen_msg_id}\" :match t :excluded nil :filename \"${gen_msg_filename}\" :timestamp 946728000 :date_relative \"2000-01-01\" :tags (\"inbox\" \"unread\") :headers (:Subject \"sexp-show-subject\" :From \"Notmuch Test Suite \" :To \"Notmuch Test Suite \" :Bcc \"test_suite+bcc@notmuchmail.org\" :Reply-To \"test_suite+replyto@notmuchmail.org\" :Date \"Sat, 01 Jan 2000 12:00:00 +0000\")) ())))" + +test_begin_subtest "Search message: sexp" +add_message "[subject]=\"sexp-search-subject\"" "[date]=\"Sat, 01 Jan 2000 12:00:00 -0000\"" "[body]=\"sexp-search-message\"" +output=$(notmuch search --format=sexp "sexp-search-message" | notmuch_search_sanitize) +test_expect_equal "$output" "((:thread \"0000000000000002\" :timestamp 946728000 :date_relative \"2000-01-01\" :matched 1 :total 1 :authors \"Notmuch Test Suite\" :subject \"sexp-search-subject\" :query (\"id:$gen_msg_id\" nil) :tags (\"inbox\" \"unread\")))" + +test_begin_subtest "Show message: sexp, utf-8" +add_message "[subject]=\"sexp-show-utf8-body-sübjéct\"" "[date]=\"Sat, 01 Jan 2000 12:00:00 -0000\"" "[body]=\"jsön-show-méssage\"" +output=$(notmuch show --format=sexp "jsön-show-méssage") +test_expect_equal "$output" "((((:id \"${gen_msg_id}\" :match t :excluded nil :filename \"${gen_msg_filename}\" :timestamp 946728000 :date_relative \"2000-01-01\" :tags (\"inbox\" \"unread\") :headers (:Subject \"sexp-show-utf8-body-sübjéct\" :From \"Notmuch Test Suite \" :To \"Notmuch Test Suite \" :Date \"Sat, 01 Jan 2000 12:00:00 +0000\") :body ((:id 1 :content-type \"text/plain\" :content \"jsön-show-méssage\n\"))) ())))" + +test_begin_subtest "Show message: sexp, inline attachment filename" +subject='sexp-show-inline-attachment-filename' +id="sexp-show-inline-attachment-filename@notmuchmail.org" +emacs_fcc_message \ + "$subject" \ + 'This is a test message with inline attachment with a filename' \ + "(mml-attach-file \"$TEST_DIRECTORY/README\" nil nil \"inline\") + (message-goto-eoh) + (insert \"Message-ID: <$id>\n\")" +output=$(notmuch show --format=sexp "id:$id") +filename=$(notmuch search --output=files "id:$id") +# Get length of README after base64-encoding, minus additional newline. +attachment_length=$(( $(base64 $TEST_DIRECTORY/README | wc -c) - 1 )) +test_expect_equal "$output" "((((:id \"$id\" :match t :excluded nil :filename \"$filename\" :timestamp 946728000 :date_relative \"2000-01-01\" :tags (\"inbox\") :headers (:Subject \"sexp-show-inline-attachment-filename\" :From \"Notmuch Test Suite \" :To \"test_suite@notmuchmail.org\" :Date \"Sat, 01 Jan 2000 12:00:00 +0000\") :body ((:id 1 :content-type \"multipart/mixed\" :content ((:id 2 :content-type \"text/plain\" :content \"This is a test message with inline attachment with a filename\") (:id 3 :content-type \"application/octet-stream\" :filename \"README\" :content-transfer-encoding \"base64\" :content-length $attachment_length))))) ())))" + +test_begin_subtest "Search message: sexp, utf-8" +add_message "[subject]=\"sexp-search-utf8-body-sübjéct\"" "[date]=\"Sat, 01 Jan 2000 12:00:00 -0000\"" "[body]=\"jsön-search-méssage\"" +output=$(notmuch search --format=sexp "jsön-search-méssage" | notmuch_search_sanitize) +test_expect_equal "$output" "((:thread \"0000000000000005\" :timestamp 946728000 :date_relative \"2000-01-01\" :matched 1 :total 1 :authors \"Notmuch Test Suite\" :subject \"sexp-search-utf8-body-sübjéct\" :query (\"id:$gen_msg_id\" nil) :tags (\"inbox\" \"unread\")))" + + +test_done diff --git a/test/T180-text.sh b/test/T180-text.sh new file mode 100755 index 00000000..b5ccefc9 --- /dev/null +++ b/test/T180-text.sh @@ -0,0 +1,88 @@ +#!/usr/bin/env bash +test_description="--format=text output" +. ./test-lib.sh + +test_begin_subtest "Show message: text" +add_message "[subject]=\"text-show-subject\"" "[date]=\"Sat, 01 Jan 2000 12:00:00 -0000\"" "[body]=\"text-show-message\"" +output=$(notmuch show --format=text "text-show-message" | notmuch_show_sanitize_all) +test_expect_equal "$output" "\ + message{ id:XXXXX depth:0 match:1 excluded:0 filename:XXXXX + header{ +Notmuch Test Suite (2000-01-01) (inbox unread) +Subject: text-show-subject +From: Notmuch Test Suite +To: Notmuch Test Suite +Date: Sat, 01 Jan 2000 12:00:00 +0000 + header} + body{ + part{ ID: 1, Content-type: text/plain +text-show-message + part} + body} + message}" + +test_begin_subtest "Search message: text" +add_message "[subject]=\"text-search-subject\"" "[date]=\"Sat, 01 Jan 2000 12:00:00 -0000\"" "[body]=\"text-search-message\"" +output=$(notmuch search --format=text "text-search-message" | notmuch_search_sanitize) +test_expect_equal "$output" \ +"thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; text-search-subject (inbox unread)" + +test_begin_subtest "Show message: text, utf-8" +add_message "[subject]=\"text-show-utf8-body-sübjéct\"" "[date]=\"Sat, 01 Jan 2000 12:00:00 -0000\"" "[body]=\"tëxt-show-méssage\"" +output=$(notmuch show --format=text "tëxt-show-méssage" | notmuch_show_sanitize_all) +test_expect_equal "$output" "\ + message{ id:XXXXX depth:0 match:1 excluded:0 filename:XXXXX + header{ +Notmuch Test Suite (2000-01-01) (inbox unread) +Subject: text-show-utf8-body-sübjéct +From: Notmuch Test Suite +To: Notmuch Test Suite +Date: Sat, 01 Jan 2000 12:00:00 +0000 + header} + body{ + part{ ID: 1, Content-type: text/plain +tëxt-show-méssage + part} + body} + message}" + +test_begin_subtest "Search message: text, utf-8" +add_message "[subject]=\"text-search-utf8-body-sübjéct\"" "[date]=\"Sat, 01 Jan 2000 12:00:00 -0000\"" "[body]=\"tëxt-search-méssage\"" +output=$(notmuch search --format=text "tëxt-search-méssage" | notmuch_search_sanitize) +test_expect_equal "$output" \ +"thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; text-search-utf8-body-sübjéct (inbox unread)" + +add_email_corpus + +test_begin_subtest "Search message tags: text0" +cat < EXPECTED +attachment inbox signed unread +EOF +notmuch search --format=text0 --output=tags '*' | xargs -0 | notmuch_search_sanitize > OUTPUT +test_expect_equal_file EXPECTED OUTPUT + +# Use tr(1) to convert --output=text0 to --output=text for +# comparison. Also translate newlines to spaces to fail with more +# noise if they are present as delimiters instead of null +# characters. This assumes there are no newlines in the data. +test_begin_subtest "Compare text vs. text0 for threads" +notmuch search --format=text --output=threads '*' | notmuch_search_sanitize > EXPECTED +notmuch search --format=text0 --output=threads '*' | tr "\n\0" " \n" | notmuch_search_sanitize > OUTPUT +test_expect_equal_file EXPECTED OUTPUT + +test_begin_subtest "Compare text vs. text0 for messages" +notmuch search --format=text --output=messages '*' | notmuch_search_sanitize > EXPECTED +notmuch search --format=text0 --output=messages '*' | tr "\n\0" " \n" | notmuch_search_sanitize > OUTPUT +test_expect_equal_file EXPECTED OUTPUT + +test_begin_subtest "Compare text vs. text0 for files" +notmuch search --format=text --output=files '*' | notmuch_search_sanitize > EXPECTED +notmuch search --format=text0 --output=files '*' | tr "\n\0" " \n" | notmuch_search_sanitize > OUTPUT +test_expect_equal_file EXPECTED OUTPUT + +test_begin_subtest "Compare text vs. text0 for tags" +notmuch search --format=text --output=tags '*' | notmuch_search_sanitize > EXPECTED +notmuch search --format=text0 --output=tags '*' | tr "\n\0" " \n" | notmuch_search_sanitize > OUTPUT +test_expect_equal_file EXPECTED OUTPUT + +test_done diff --git a/test/T190-multipart.sh b/test/T190-multipart.sh new file mode 100755 index 00000000..85cbf672 --- /dev/null +++ b/test/T190-multipart.sh @@ -0,0 +1,730 @@ +#!/usr/bin/env bash +test_description="output of multipart message" +. ./test-lib.sh + +cat < embedded_message +From: Carl Worth +To: cworth@cworth.org +Subject: html message +Date: Fri, 05 Jan 2001 15:42:57 +0000 +User-Agent: Notmuch/0.5 (http://notmuchmail.org) Emacs/23.3.1 (i486-pc-linux-gnu) +Message-ID: <87liy5ap01.fsf@yoom.home.cworth.org> +MIME-Version: 1.0 +Content-Type: multipart/alternative; boundary="==-=-==" + +--==-=-== +Content-Type: text/html + +

This is an embedded message, with a multipart/alternative part.

+ +--==-=-== +Content-Type: text/plain + +This is an embedded message, with a multipart/alternative part. + +--==-=-==-- +EOF + +cat < ${MAIL_DIR}/multipart +From: Carl Worth +To: cworth@cworth.org +Subject: Multipart message +Date: Fri, 05 Jan 2001 15:43:57 +0000 +User-Agent: Notmuch/0.5 (http://notmuchmail.org) Emacs/23.3.1 (i486-pc-linux-gnu) +Message-ID: <87liy5ap00.fsf@yoom.home.cworth.org> +MIME-Version: 1.0 +Content-Type: multipart/signed; boundary="==-=-="; + micalg=pgp-sha1; protocol="application/pgp-signature" + +--==-=-= +Content-Type: multipart/mixed; boundary="=-=-=" + +--=-=-= +Content-Type: message/rfc822 +Content-Disposition: inline + +EOF +cat embedded_message >> ${MAIL_DIR}/multipart +cat <> ${MAIL_DIR}/multipart + +--=-=-= +Content-Disposition: attachment; filename=attachment + +This is a text attachment. + +--=-=-= + +And this message is signed. + +-Carl + +--=-=-=-- + +--==-=-= +Content-Type: application/pgp-signature + +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1.4.11 (GNU/Linux) + +iEYEARECAAYFAk3SA/gACgkQ6JDdNq8qSWj0sACghqVJEQJUs3yV8zbTzhgnSIcD +W6cAmQE4dcYrx/LPLtYLZm1jsGauE5hE +=zkga +-----END PGP SIGNATURE----- +--==-=-=-- +EOF + +cat < ${MAIL_DIR}/base64-part-with-crlf +From: Carl Worth +To: cworth@cworth.org +Subject: Test message with a BASE64 encoded binary containing CRLF pair +Date: Fri, 05 Jan 2001 15:43:57 +0000 +User-Agent: Notmuch/0.5 (http://notmuchmail.org) Emacs/23.3.1 (i486-pc-linux-gnu) +Message-ID: +MIME-Version: 1.0 +Content-Type: multipart/mixed; boundary="==-=-="; + +--==-=-= + +The attached BASE64-encoded part expands to a binary containing a CRLF +pair (that is one bye of 0x0D followed by one byte of 0x0A). This is +designed to ensure that notmuch is not corrupting the output of this +part by converting the CRLF pair to an LF only (as would be appropriate +for display of a text part on a Linux system, for example). + +The part should be a 3-byte file with the following sequence of 3 +hexadecimal bytes: + + EF 0D 0A + +--==-=-= +Content-Type: application/octet-stream +Content-Disposition: attachment; filename=crlf.bin +Content-Transfer-Encoding: base64 + +7w0K +--==-=-=-- +EOF +notmuch new > /dev/null + +test_begin_subtest "--format=text --part=0, full message" +notmuch show --format=text --part=0 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT +cat <EXPECTED + message{ id:87liy5ap00.fsf@yoom.home.cworth.org depth:0 match:1 excluded:0 filename:${MAIL_DIR}/multipart + header{ +Carl Worth (2001-01-05) (attachment inbox signed unread) +Subject: Multipart message +From: Carl Worth +To: cworth@cworth.org +Date: Fri, 05 Jan 2001 15:43:57 +0000 + header} + body{ + part{ ID: 1, Content-type: multipart/signed + part{ ID: 2, Content-type: multipart/mixed + part{ ID: 3, Content-type: message/rfc822 + header{ +Subject: html message +From: Carl Worth +To: cworth@cworth.org +Date: Fri, 05 Jan 2001 15:42:57 +0000 + header} + body{ + part{ ID: 4, Content-type: multipart/alternative + part{ ID: 5, Content-type: text/html +Non-text part: text/html + part} + part{ ID: 6, Content-type: text/plain +This is an embedded message, with a multipart/alternative part. + part} + part} + body} + part} + attachment{ ID: 7, Filename: attachment, Content-type: text/plain +This is a text attachment. + attachment} + part{ ID: 8, Content-type: text/plain +And this message is signed. + +-Carl + part} + part} + part{ ID: 9, Content-type: application/pgp-signature +Non-text part: application/pgp-signature + part} + part} + body} + message} +EOF +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "--format=text --part=1, message body" +notmuch show --format=text --part=1 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT +cat <EXPECTED + part{ ID: 1, Content-type: multipart/signed + part{ ID: 2, Content-type: multipart/mixed + part{ ID: 3, Content-type: message/rfc822 + header{ +Subject: html message +From: Carl Worth +To: cworth@cworth.org +Date: Fri, 05 Jan 2001 15:42:57 +0000 + header} + body{ + part{ ID: 4, Content-type: multipart/alternative + part{ ID: 5, Content-type: text/html +Non-text part: text/html + part} + part{ ID: 6, Content-type: text/plain +This is an embedded message, with a multipart/alternative part. + part} + part} + body} + part} + attachment{ ID: 7, Filename: attachment, Content-type: text/plain +This is a text attachment. + attachment} + part{ ID: 8, Content-type: text/plain +And this message is signed. + +-Carl + part} + part} + part{ ID: 9, Content-type: application/pgp-signature +Non-text part: application/pgp-signature + part} + part} +EOF +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "--format=text --part=2, multipart/mixed" +notmuch show --format=text --part=2 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT +cat <EXPECTED + part{ ID: 2, Content-type: multipart/mixed + part{ ID: 3, Content-type: message/rfc822 + header{ +Subject: html message +From: Carl Worth +To: cworth@cworth.org +Date: Fri, 05 Jan 2001 15:42:57 +0000 + header} + body{ + part{ ID: 4, Content-type: multipart/alternative + part{ ID: 5, Content-type: text/html +Non-text part: text/html + part} + part{ ID: 6, Content-type: text/plain +This is an embedded message, with a multipart/alternative part. + part} + part} + body} + part} + attachment{ ID: 7, Filename: attachment, Content-type: text/plain +This is a text attachment. + attachment} + part{ ID: 8, Content-type: text/plain +And this message is signed. + +-Carl + part} + part} +EOF +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "--format=text --part=3, rfc822 part" +notmuch show --format=text --part=3 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT +cat <EXPECTED + part{ ID: 3, Content-type: message/rfc822 + header{ +Subject: html message +From: Carl Worth +To: cworth@cworth.org +Date: Fri, 05 Jan 2001 15:42:57 +0000 + header} + body{ + part{ ID: 4, Content-type: multipart/alternative + part{ ID: 5, Content-type: text/html +Non-text part: text/html + part} + part{ ID: 6, Content-type: text/plain +This is an embedded message, with a multipart/alternative part. + part} + part} + body} + part} +EOF +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "--format=text --part=4, rfc822's multipart" +notmuch show --format=text --part=4 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT +cat <EXPECTED + part{ ID: 4, Content-type: multipart/alternative + part{ ID: 5, Content-type: text/html +Non-text part: text/html + part} + part{ ID: 6, Content-type: text/plain +This is an embedded message, with a multipart/alternative part. + part} + part} +EOF +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "--format=text --part=5, rfc822's html part" +notmuch show --format=text --part=5 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT +cat <EXPECTED + part{ ID: 5, Content-type: text/html +Non-text part: text/html + part} +EOF +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "--format=text --part=6, rfc822's text part" +notmuch show --format=text --part=6 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT +cat <EXPECTED + part{ ID: 6, Content-type: text/plain +This is an embedded message, with a multipart/alternative part. + part} +EOF +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "--format=text --part=7, inline attachement" +notmuch show --format=text --part=7 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT +cat <EXPECTED + attachment{ ID: 7, Filename: attachment, Content-type: text/plain +This is a text attachment. + attachment} +EOF +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "--format=text --part=8, plain text part" +notmuch show --format=text --part=8 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT +cat <EXPECTED + part{ ID: 8, Content-type: text/plain +And this message is signed. + +-Carl + part} +EOF +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "--format=text --part=9, pgp signature (unverified)" +notmuch show --format=text --part=9 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT +cat <EXPECTED + part{ ID: 9, Content-type: application/pgp-signature +Non-text part: application/pgp-signature + part} +EOF +test_expect_equal_file OUTPUT EXPECTED + +test_expect_success \ + "--format=text --part=8, no part, expect error" \ + "notmuch show --format=text --part=8 'id:87liy5ap00.fsf@yoom.home.cworth.org'" + +test_begin_subtest "--format=json --part=0, full message" +notmuch show --format=json --part=0 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT +cat <EXPECTED +{"id": "87liy5ap00.fsf@yoom.home.cworth.org", "match": true, "excluded": false, "filename": "${MAIL_DIR}/multipart", "timestamp": 978709437, "date_relative": "2001-01-05", "tags": ["attachment","inbox","signed","unread"], "headers": {"Subject": "Multipart message", "From": "Carl Worth ", "To": "cworth@cworth.org", "Date": "Fri, 05 Jan 2001 15:43:57 +0000"}, "body": [ +{"id": 1, "content-type": "multipart/signed", "content": [ +{"id": 2, "content-type": "multipart/mixed", "content": [ +{"id": 3, "content-type": "message/rfc822", "content": [{"headers": {"Subject": "html message", "From": "Carl Worth ", "To": "cworth@cworth.org", "Date": "Fri, 05 Jan 2001 15:42:57 +0000"}, "body": [ +{"id": 4, "content-type": "multipart/alternative", "content": [ +{"id": 5, "content-type": "text/html", "content-length": 71}, +{"id": 6, "content-type": "text/plain", "content": "This is an embedded message, with a multipart/alternative part.\n"}]}]}]}, +{"id": 7, "content-type": "text/plain", "filename": "attachment", "content": "This is a text attachment.\n"}, +{"id": 8, "content-type": "text/plain", "content": "And this message is signed.\n\n-Carl\n"}]}, +{"id": 9, "content-type": "application/pgp-signature", "content-length": 197}]}]} +EOF +test_expect_equal_json "$(cat OUTPUT)" "$(cat EXPECTED)" + +test_begin_subtest "--format=json --part=1, message body" +notmuch show --format=json --part=1 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT +cat <EXPECTED +{"id": 1, "content-type": "multipart/signed", "content": [ +{"id": 2, "content-type": "multipart/mixed", "content": [ +{"id": 3, "content-type": "message/rfc822", "content": [{"headers": {"Subject": "html message", "From": "Carl Worth ", "To": "cworth@cworth.org", "Date": "Fri, 05 Jan 2001 15:42:57 +0000"}, "body": [ +{"id": 4, "content-type": "multipart/alternative", "content": [ +{"id": 5, "content-type": "text/html", "content-length": 71}, +{"id": 6, "content-type": "text/plain", "content": "This is an embedded message, with a multipart/alternative part.\n"}]}]}]}, +{"id": 7, "content-type": "text/plain", "filename": "attachment", "content": "This is a text attachment.\n"}, +{"id": 8, "content-type": "text/plain", "content": "And this message is signed.\n\n-Carl\n"}]}, +{"id": 9, "content-type": "application/pgp-signature", "content-length": 197}]} +EOF +test_expect_equal_json "$(cat OUTPUT)" "$(cat EXPECTED)" + +test_begin_subtest "--format=json --part=2, multipart/mixed" +notmuch show --format=json --part=2 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT +cat <EXPECTED +{"id": 2, "content-type": "multipart/mixed", "content": [ +{"id": 3, "content-type": "message/rfc822", "content": [{"headers": {"Subject": "html message", "From": "Carl Worth ", "To": "cworth@cworth.org", "Date": "Fri, 05 Jan 2001 15:42:57 +0000"}, "body": [ +{"id": 4, "content-type": "multipart/alternative", "content": [ +{"id": 5, "content-type": "text/html", "content-length": 71}, +{"id": 6, "content-type": "text/plain", "content": "This is an embedded message, with a multipart/alternative part.\n"}]}]}]}, +{"id": 7, "content-type": "text/plain", "filename": "attachment", "content": "This is a text attachment.\n"}, +{"id": 8, "content-type": "text/plain", "content": "And this message is signed.\n\n-Carl\n"}]} +EOF +test_expect_equal_json "$(cat OUTPUT)" "$(cat EXPECTED)" + +test_begin_subtest "--format=json --part=3, rfc822 part" +notmuch show --format=json --part=3 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT +cat <EXPECTED +{"id": 3, "content-type": "message/rfc822", "content": [{"headers": {"Subject": "html message", "From": "Carl Worth ", "To": "cworth@cworth.org", "Date": "Fri, 05 Jan 2001 15:42:57 +0000"}, "body": [ +{"id": 4, "content-type": "multipart/alternative", "content": [ +{"id": 5, "content-type": "text/html", "content-length": 71}, +{"id": 6, "content-type": "text/plain", "content": "This is an embedded message, with a multipart/alternative part.\n"}]}]}]} +EOF +test_expect_equal_json "$(cat OUTPUT)" "$(cat EXPECTED)" + +test_begin_subtest "--format=json --part=4, rfc822's multipart/alternative" +notmuch show --format=json --part=4 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT +cat <EXPECTED +{"id": 4, "content-type": "multipart/alternative", "content": [ +{"id": 5, "content-type": "text/html", "content-length": 71}, +{"id": 6, "content-type": "text/plain", "content": "This is an embedded message, with a multipart/alternative part.\n"}]} +EOF +test_expect_equal_json "$(cat OUTPUT)" "$(cat EXPECTED)" + +test_begin_subtest "--format=json --part=5, rfc822's html part" +notmuch show --format=json --part=5 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT +cat <EXPECTED +{"id": 5, "content-type": "text/html", "content-length": 71} +EOF +test_expect_equal_json "$(cat OUTPUT)" "$(cat EXPECTED)" + +test_begin_subtest "--format=json --part=6, rfc822's text part" +notmuch show --format=json --part=6 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT +cat <EXPECTED +{"id": 6, "content-type": "text/plain", "content": "This is an embedded message, with a multipart/alternative part.\n"} +EOF +test_expect_equal_json "$(cat OUTPUT)" "$(cat EXPECTED)" + +test_begin_subtest "--format=json --part=7, inline attachment" +notmuch show --format=json --part=7 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT +cat <EXPECTED +{"id": 7, "content-type": "text/plain", "filename": "attachment", "content": "This is a text attachment.\n"} +EOF +test_expect_equal_json "$(cat OUTPUT)" "$(cat EXPECTED)" + +test_begin_subtest "--format=json --part=8, plain text part" +notmuch show --format=json --part=8 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT +cat <EXPECTED +{"id": 8, "content-type": "text/plain", "content": "And this message is signed.\n\n-Carl\n"} +EOF +test_expect_equal_json "$(cat OUTPUT)" "$(cat EXPECTED)" + +test_begin_subtest "--format=json --part=9, pgp signature (unverified)" +notmuch show --format=json --part=9 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT +cat <EXPECTED +{"id": 9, "content-type": "application/pgp-signature", "content-length": 197} +EOF +test_expect_equal_json "$(cat OUTPUT)" "$(cat EXPECTED)" + +test_expect_success \ + "--format=json --part=10, no part, expect error" \ + "notmuch show --format=json --part=10 'id:87liy5ap00.fsf@yoom.home.cworth.org'" + +test_begin_subtest "--format=raw" +notmuch show --format=raw 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT +test_expect_equal_file OUTPUT "${MAIL_DIR}"/multipart + +test_begin_subtest "--format=raw --part=0, full message" +notmuch show --format=raw --part=0 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT +test_expect_equal_file OUTPUT "${MAIL_DIR}"/multipart + +test_begin_subtest "--format=raw --part=1, message body" +notmuch show --format=raw --part=1 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT +test_expect_equal_file OUTPUT "${MAIL_DIR}"/multipart + +test_begin_subtest "--format=raw --part=2, multipart/mixed" +notmuch show --format=raw --part=2 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT +cat <EXPECTED +Content-Type: multipart/mixed; boundary="=-=-=" + +--=-=-= +Content-Type: message/rfc822 +Content-Disposition: inline + +From: Carl Worth +To: cworth@cworth.org +Subject: html message +Date: Fri, 05 Jan 2001 15:42:57 +0000 +User-Agent: Notmuch/0.5 (http://notmuchmail.org) Emacs/23.3.1 (i486-pc-linux-gnu) +Message-ID: <87liy5ap01.fsf@yoom.home.cworth.org> +MIME-Version: 1.0 +Content-Type: multipart/alternative; boundary="==-=-==" + +--==-=-== +Content-Type: text/html + +

This is an embedded message, with a multipart/alternative part.

+ +--==-=-== +Content-Type: text/plain + +This is an embedded message, with a multipart/alternative part. + +--==-=-==-- + +--=-=-= +Content-Disposition: attachment; filename=attachment + +This is a text attachment. + +--=-=-= + +And this message is signed. + +-Carl + +--=-=-=-- +EOF +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "--format=raw --part=3, rfc822 part" +notmuch show --format=raw --part=3 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT +test_expect_equal_file OUTPUT embedded_message + +test_begin_subtest "--format=raw --part=4, rfc822's multipart" +notmuch show --format=raw --part=4 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT +cat <EXPECTED +From: Carl Worth +To: cworth@cworth.org +Subject: html message +Date: Fri, 05 Jan 2001 15:42:57 +0000 +User-Agent: Notmuch/0.5 (http://notmuchmail.org) Emacs/23.3.1 (i486-pc-linux-gnu) +Message-ID: <87liy5ap01.fsf@yoom.home.cworth.org> +MIME-Version: 1.0 +Content-Type: multipart/alternative; boundary="==-=-==" + +--==-=-== +Content-Type: text/html + +

This is an embedded message, with a multipart/alternative part.

+ +--==-=-== +Content-Type: text/plain + +This is an embedded message, with a multipart/alternative part. + +--==-=-==-- +EOF +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "--format=raw --part=5, rfc822's html part" +notmuch show --format=raw --part=5 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT +cat <EXPECTED +

This is an embedded message, with a multipart/alternative part.

+EOF +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "--format=raw --part=6, rfc822's text part" +notmuch show --format=raw --part=6 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT +cat <EXPECTED +This is an embedded message, with a multipart/alternative part. +EOF +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "--format=raw --part=7, inline attachment" +notmuch show --format=raw --part=7 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT +cat <EXPECTED +This is a text attachment. +EOF +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "--format=raw --part=8, plain text part" +notmuch show --format=raw --part=8 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT +cat <EXPECTED +And this message is signed. + +-Carl +EOF +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "--format=raw --part=9, pgp signature (unverified)" +notmuch show --format=raw --part=9 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT +# output should *not* include newline +echo >>OUTPUT +cat <EXPECTED +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1.4.11 (GNU/Linux) + +iEYEARECAAYFAk3SA/gACgkQ6JDdNq8qSWj0sACghqVJEQJUs3yV8zbTzhgnSIcD +W6cAmQE4dcYrx/LPLtYLZm1jsGauE5hE +=zkga +-----END PGP SIGNATURE----- +EOF +test_expect_equal_file OUTPUT EXPECTED + +test_expect_success \ + "--format=raw --part=10, no part, expect error" \ + "notmuch show --format=raw --part=8 'id:87liy5ap00.fsf@yoom.home.cworth.org'" + +test_begin_subtest "--format=mbox" +notmuch show --format=mbox 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT +printf "From cworth@cworth.org Fri Jan 5 15:43:57 2001\n" >EXPECTED +cat "${MAIL_DIR}"/multipart >>EXPECTED +# mbox output is expected to include a blank line +echo >>EXPECTED +test_expect_equal_file OUTPUT EXPECTED + +test_expect_success \ + "--format=mbox --part=1, incompatible, expect error" \ + "! notmuch show --format=mbox --part=1 'id:87liy5ap00.fsf@yoom.home.cworth.org'" + +test_begin_subtest "'notmuch reply' to a multipart message" +notmuch reply 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT +cat <EXPECTED +From: Notmuch Test Suite +Subject: Re: Multipart message +To: Carl Worth , cworth@cworth.org +In-Reply-To: <87liy5ap00.fsf@yoom.home.cworth.org> +References: <87liy5ap00.fsf@yoom.home.cworth.org> + +On Fri, 05 Jan 2001 15:43:57 +0000, Carl Worth wrote: +> From: Carl Worth +> To: cworth@cworth.org +> Subject: html message +> Date: Fri, 05 Jan 2001 15:42:57 +0000 +> +Non-text part: text/html +> This is an embedded message, with a multipart/alternative part. +> This is a text attachment. +> And this message is signed. +> +> -Carl +EOF +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "'notmuch reply' to a multipart message with json format" +notmuch reply --format=json 'id:87liy5ap00.fsf@yoom.home.cworth.org' | notmuch_json_show_sanitize >OUTPUT +notmuch_json_show_sanitize <EXPECTED +{"reply-headers": {"Subject": "Re: Multipart message", + "From": "Notmuch Test Suite ", + "To": "Carl Worth , cworth@cworth.org", + "In-reply-to": "<87liy5ap00.fsf@yoom.home.cworth.org>", + "References": "<87liy5ap00.fsf@yoom.home.cworth.org>"}, + "original": {"id": "XXXXX", + "match": false, + "excluded": false, + "filename": "YYYYY", + "timestamp": 978709437, + "date_relative": "2001-01-05", + "tags": ["attachment","inbox","signed","unread"], + "headers": {"Subject": "Multipart message", + "From": "Carl Worth ", + "To": "cworth@cworth.org", + "Date": "Fri, 05 Jan 2001 15:43:57 +0000"}, + "body": [{"id": 1, + "content-type": "multipart/signed", + "content": [{"id": 2, + "content-type": "multipart/mixed", + "content": [{"id": 3, + "content-type": "message/rfc822", + "content": [{"headers": {"Subject": "html message", + "From": "Carl Worth ", + "To": "cworth@cworth.org", + "Date": "Fri, 05 Jan 2001 15:42:57 +0000"}, + "body": [{"id": 4, + "content-type": "multipart/alternative", + "content": [{"id": 5, + "content-type": "text/html", + "content-length": 71}, + {"id": 6, + "content-type": "text/plain", + "content": "This is an embedded message, with a multipart/alternative part.\n"}]}]}]}, + {"id": 7, + "content-type": "text/plain", + "filename": "attachment", + "content": "This is a text attachment.\n"}, + {"id": 8, + "content-type": "text/plain", + "content": "And this message is signed.\n\n-Carl\n"}]}, + {"id": 9, + "content-type": "application/pgp-signature", + "content-length": 197}]}]}} +EOF +test_expect_equal_json "$(cat OUTPUT)" "$(cat EXPECTED)" + +test_begin_subtest "'notmuch show --part' does not corrupt a part with CRLF pair" +notmuch show --format=raw --part=3 id:base64-part-with-crlf > crlf.out +echo -n -e "\xEF\x0D\x0A" > crlf.expected +test_expect_equal_file crlf.out crlf.expected + + +# The ISO-8859-1 encoding of U+00BD is a single byte: octal 275 +# (Portability note: Dollar-Single ($'...', ANSI C-style escape sequences) +# quoting works on bash, ksh, zsh, *BSD sh but not on dash, ash nor busybox sh) +readonly u_00bd_latin1=$'\275' + +# The Unicode fraction symbol 1/2 is U+00BD and is encoded +# in UTF-8 as two bytes: octal 302 275 +readonly u_00bd_utf8=$'\302\275' + +cat < ${MAIL_DIR}/include-html +From: A +To: B +Subject: html message +Date: Sat, 01 January 2000 00:00:00 +0000 +Message-ID: +MIME-Version: 1.0 +Content-Type: multipart/alternative; boundary="==-==" + +--==-== +Content-Type: text/html; charset=UTF-8 + +

0.5 equals ${u_00bd_utf8}

+ +--==-== +Content-Type: text/html; charset=ISO-8859-1 + +

0.5 equals ${u_00bd_latin1}

+ +--==-== +Content-Type: text/plain; charset=UTF-8 + +0.5 equals ${u_00bd_utf8} + +--==-==-- +EOF + +notmuch new > /dev/null + +cat_expected_head () +{ + cat <", + "Subject": "html message", "To": "B "}, + "body": [{ + "content-type": "multipart/alternative", "id": 1, +EOF +} + +cat_expected_head > EXPECTED.nohtml +cat <> EXPECTED.nohtml +"content": [ + { "id": 2, "content-charset": "UTF-8", "content-length": 21, "content-type": "text/html"}, + { "id": 3, "content-charset": "ISO-8859-1", "content-length": 20, "content-type": "text/html"}, + { "id": 4, "content-type": "text/plain", "content": "0.5 equals \\u00bd\\n"} +]}]},[]]]] +EOF + +# Both the UTF-8 and ISO-8859-1 part should have U+00BD +cat_expected_head > EXPECTED.withhtml +cat <> EXPECTED.withhtml +"content": [ + { "id": 2, "content-type": "text/html", "content": "

0.5 equals \\u00bd

\\n"}, + { "id": 3, "content-type": "text/html", "content": "

0.5 equals \\u00bd

\\n"}, + { "id": 4, "content-type": "text/plain", "content": "0.5 equals \\u00bd\\n"} +]}]},[]]]] +EOF + +test_begin_subtest "html parts excluded by default" +notmuch show --format=json id:htmlmessage > OUTPUT +test_expect_equal_json "$(cat OUTPUT)" "$(cat EXPECTED.nohtml)" + +test_begin_subtest "html parts included" +notmuch show --format=json --include-html id:htmlmessage > OUTPUT +test_expect_equal_json "$(cat OUTPUT)" "$(cat EXPECTED.withhtml)" + +test_done diff --git a/test/T200-thread-naming.sh b/test/T200-thread-naming.sh new file mode 100755 index 00000000..1a1a48f6 --- /dev/null +++ b/test/T200-thread-naming.sh @@ -0,0 +1,180 @@ +#!/usr/bin/env bash +test_description="naming of threads with changing subject" +. ./test-lib.sh + +test_begin_subtest "Initial thread name (oldest-first search)" +add_message '[subject]="thread-naming: Initial thread subject"' \ + '[date]="Fri, 05 Jan 2001 15:43:56 -0000"' +first=${gen_msg_cnt} +parent=${gen_msg_id} +add_message '[subject]="thread-naming: Older changed subject"' \ + '[date]="Sat, 06 Jan 2001 15:43:56 -0000"' \ + "[in-reply-to]=\<$parent\>" +add_message '[subject]="thread-naming: Newer changed subject"' \ + '[date]="Sun, 07 Jan 2001 15:43:56 -0000"' \ + "[in-reply-to]=\<$parent\>" +add_message '[subject]="thread-naming: Final thread subject"' \ + '[date]="Mon, 08 Jan 2001 15:43:56 -0000"' \ + "[in-reply-to]=\<$parent\>" +final=${gen_msg_id} +output=$(notmuch search --sort=oldest-first thread-naming and tag:inbox | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2001-01-05 [4/4] Notmuch Test Suite; thread-naming: Initial thread subject (inbox unread)" + +test_begin_subtest "Initial thread name (newest-first search)" +output=$(notmuch search --sort=newest-first thread-naming and tag:inbox | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2001-01-08 [4/4] Notmuch Test Suite; thread-naming: Final thread subject (inbox unread)" + +# Remove oldest and newest messages from search results +notmuch tag -inbox id:$parent or id:$final + +test_begin_subtest "Changed thread name (oldest-first search)" +output=$(notmuch search --sort=oldest-first thread-naming and tag:inbox | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2001-01-06 [2/4] Notmuch Test Suite; thread-naming: Older changed subject (inbox unread)" + +test_begin_subtest "Changed thread name (newest-first search)" +output=$(notmuch search --sort=newest-first thread-naming and tag:inbox | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2001-01-07 [2/4] Notmuch Test Suite; thread-naming: Newer changed subject (inbox unread)" + +test_begin_subtest "Ignore added reply prefix (Re:)" +add_message '[subject]="Re: thread-naming: Initial thread subject"' \ + '[date]="Tue, 09 Jan 2001 15:43:45 -0000"' \ + "[in-reply-to]=\<$parent\>" +output=$(notmuch search --sort=newest-first thread-naming and tag:inbox | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2001-01-09 [3/5] Notmuch Test Suite; thread-naming: Initial thread subject (inbox unread)" + +test_begin_subtest "Ignore added reply prefix (Aw:)" +add_message '[subject]="Aw: thread-naming: Initial thread subject"' \ + '[date]="Wed, 10 Jan 2001 15:43:45 -0000"' \ + "[in-reply-to]=\<$parent\>" +output=$(notmuch search --sort=newest-first thread-naming and tag:inbox | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2001-01-10 [4/6] Notmuch Test Suite; thread-naming: Initial thread subject (inbox unread)" + +test_begin_subtest "Ignore added reply prefix (Vs:)" +add_message '[subject]="Vs: thread-naming: Initial thread subject"' \ + '[date]="Thu, 11 Jan 2001 15:43:45 -0000"' \ + "[in-reply-to]=\<$parent\>" +output=$(notmuch search --sort=newest-first thread-naming and tag:inbox | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2001-01-11 [5/7] Notmuch Test Suite; thread-naming: Initial thread subject (inbox unread)" + +test_begin_subtest "Ignore added reply prefix (Sv:)" +add_message '[subject]="Sv: thread-naming: Initial thread subject"' \ + '[date]="Fri, 12 Jan 2001 15:43:45 -0000"' \ + "[in-reply-to]=\<$parent\>" +output=$(notmuch search --sort=newest-first thread-naming and tag:inbox | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2001-01-12 [6/8] Notmuch Test Suite; thread-naming: Initial thread subject (inbox unread)" + +test_begin_subtest 'Test order of messages in "notmuch show"' +output=$(notmuch show thread-naming | notmuch_show_sanitize) +test_expect_equal "$output" " message{ id:msg-$(printf "%03d" $first)@notmuch-test-suite depth:0 match:1 excluded:0 filename:/XXX/mail/msg-$(printf "%03d" $first) + header{ +Notmuch Test Suite (2001-01-05) (unread) +Subject: thread-naming: Initial thread subject +From: Notmuch Test Suite +To: Notmuch Test Suite +Date: Fri, 05 Jan 2001 15:43:56 +0000 + header} + body{ + part{ ID: 1, Content-type: text/plain +This is just a test message (#$first) + part} + body} + message} + message{ id:msg-$(printf "%03d" $((first + 1)))@notmuch-test-suite depth:1 match:1 excluded:0 filename:/XXX/mail/msg-$(printf "%03d" $((first + 1))) + header{ +Notmuch Test Suite (2001-01-06) (inbox unread) +Subject: thread-naming: Older changed subject +From: Notmuch Test Suite +To: Notmuch Test Suite +Date: Sat, 06 Jan 2001 15:43:56 +0000 + header} + body{ + part{ ID: 1, Content-type: text/plain +This is just a test message (#$((first + 1))) + part} + body} + message} + message{ id:msg-$(printf "%03d" $((first + 2)))@notmuch-test-suite depth:1 match:1 excluded:0 filename:/XXX/mail/msg-$(printf "%03d" $((first + 2))) + header{ +Notmuch Test Suite (2001-01-07) (inbox unread) +Subject: thread-naming: Newer changed subject +From: Notmuch Test Suite +To: Notmuch Test Suite +Date: Sun, 07 Jan 2001 15:43:56 +0000 + header} + body{ + part{ ID: 1, Content-type: text/plain +This is just a test message (#$((first + 2))) + part} + body} + message} + message{ id:msg-$(printf "%03d" $((first + 3)))@notmuch-test-suite depth:1 match:1 excluded:0 filename:/XXX/mail/msg-$(printf "%03d" $((first + 3))) + header{ +Notmuch Test Suite (2001-01-08) (unread) +Subject: thread-naming: Final thread subject +From: Notmuch Test Suite +To: Notmuch Test Suite +Date: Mon, 08 Jan 2001 15:43:56 +0000 + header} + body{ + part{ ID: 1, Content-type: text/plain +This is just a test message (#$((first + 3))) + part} + body} + message} + message{ id:msg-$(printf "%03d" $((first + 4)))@notmuch-test-suite depth:1 match:1 excluded:0 filename:/XXX/mail/msg-$(printf "%03d" $((first + 4))) + header{ +Notmuch Test Suite (2001-01-09) (inbox unread) +Subject: Re: thread-naming: Initial thread subject +From: Notmuch Test Suite +To: Notmuch Test Suite +Date: Tue, 09 Jan 2001 15:43:45 +0000 + header} + body{ + part{ ID: 1, Content-type: text/plain +This is just a test message (#$((first + 4))) + part} + body} + message} + message{ id:msg-$(printf "%03d" $((first + 5)))@notmuch-test-suite depth:1 match:1 excluded:0 filename:/XXX/mail/msg-$(printf "%03d" $((first + 5))) + header{ +Notmuch Test Suite (2001-01-10) (inbox unread) +Subject: Aw: thread-naming: Initial thread subject +From: Notmuch Test Suite +To: Notmuch Test Suite +Date: Wed, 10 Jan 2001 15:43:45 +0000 + header} + body{ + part{ ID: 1, Content-type: text/plain +This is just a test message (#$((first + 5))) + part} + body} + message} + message{ id:msg-$(printf "%03d" $((first + 6)))@notmuch-test-suite depth:1 match:1 excluded:0 filename:/XXX/mail/msg-$(printf "%03d" $((first + 6))) + header{ +Notmuch Test Suite (2001-01-11) (inbox unread) +Subject: Vs: thread-naming: Initial thread subject +From: Notmuch Test Suite +To: Notmuch Test Suite +Date: Thu, 11 Jan 2001 15:43:45 +0000 + header} + body{ + part{ ID: 1, Content-type: text/plain +This is just a test message (#$((first + 6))) + part} + body} + message} + message{ id:msg-$(printf "%03d" $((first + 7)))@notmuch-test-suite depth:1 match:1 excluded:0 filename:/XXX/mail/msg-$(printf "%03d" $((first + 7))) + header{ +Notmuch Test Suite (2001-01-12) (inbox unread) +Subject: Sv: thread-naming: Initial thread subject +From: Notmuch Test Suite +To: Notmuch Test Suite +Date: Fri, 12 Jan 2001 15:43:45 +0000 + header} + body{ + part{ ID: 1, Content-type: text/plain +This is just a test message (#$((first + 7))) + part} + body} + message}" +test_done diff --git a/test/T210-raw.sh b/test/T210-raw.sh new file mode 100755 index 00000000..daf5735c --- /dev/null +++ b/test/T210-raw.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash + +test_description='notmuch show --format=raw' +. ./test-lib.sh + +add_message +add_message + +test_begin_subtest "Attempt to show multiple raw messages" +output=$(notmuch show --format=raw "*" 2>&1) +test_expect_equal "$output" "Error: search term did not match precisely one message." + +test_begin_subtest "Show a raw message" +output=$(notmuch show --format=raw id:msg-001@notmuch-test-suite | notmuch_date_sanitize) +test_expect_equal "$output" "From: Notmuch Test Suite +To: Notmuch Test Suite +Message-Id: +Subject: Test message #1 +Date: GENERATED_DATE + +This is just a test message (#1)" + +test_begin_subtest "Show another raw message" +output=$(notmuch show --format=raw id:msg-002@notmuch-test-suite | notmuch_date_sanitize) +test_expect_equal "$output" "From: Notmuch Test Suite +To: Notmuch Test Suite +Message-Id: +Subject: Test message #2 +Date: GENERATED_DATE + +This is just a test message (#2)" + +test_done diff --git a/test/T220-reply.sh b/test/T220-reply.sh new file mode 100755 index 00000000..b0d854a1 --- /dev/null +++ b/test/T220-reply.sh @@ -0,0 +1,257 @@ +#!/usr/bin/env bash +test_description="\"notmuch reply\" in several variations" +. ./test-lib.sh + +test_begin_subtest "Basic reply" +add_message '[from]="Sender "' \ + [to]=test_suite@notmuchmail.org \ + [subject]=notmuch-reply-test \ + '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ + '[body]="basic reply test"' + +output=$(notmuch reply id:${gen_msg_id}) +test_expect_equal "$output" "From: Notmuch Test Suite +Subject: Re: notmuch-reply-test +To: Sender +In-Reply-To: <${gen_msg_id}> +References: <${gen_msg_id}> + +On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: +> basic reply test" + +test_begin_subtest "Multiple recipients" +add_message '[from]="Sender "' \ + '[to]="test_suite@notmuchmail.org, Someone Else "' \ + [subject]=notmuch-reply-test \ + '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ + '[body]="Multiple recipients"' + +output=$(notmuch reply id:${gen_msg_id}) +test_expect_equal "$output" "From: Notmuch Test Suite +Subject: Re: notmuch-reply-test +To: Sender , Someone Else +In-Reply-To: <${gen_msg_id}> +References: <${gen_msg_id}> + +On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: +> Multiple recipients" + +test_begin_subtest "Reply with CC" +add_message '[from]="Sender "' \ + [to]=test_suite@notmuchmail.org \ + '[cc]="Other Parties "' \ + [subject]=notmuch-reply-test \ + '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ + '[body]="reply with CC"' + +output=$(notmuch reply id:${gen_msg_id}) +test_expect_equal "$output" "From: Notmuch Test Suite +Subject: Re: notmuch-reply-test +To: Sender +Cc: Other Parties +In-Reply-To: <${gen_msg_id}> +References: <${gen_msg_id}> + +On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: +> reply with CC" + +test_begin_subtest "Reply from alternate address" +add_message '[from]="Sender "' \ + [to]=test_suite_other@notmuchmail.org \ + [subject]=notmuch-reply-test \ + '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ + '[body]="reply from alternate address"' + +output=$(notmuch reply id:${gen_msg_id}) +test_expect_equal "$output" "From: Notmuch Test Suite +Subject: Re: notmuch-reply-test +To: Sender +In-Reply-To: <${gen_msg_id}> +References: <${gen_msg_id}> + +On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: +> reply from alternate address" + +test_begin_subtest "Reply from address in named group list" +add_message '[from]="Sender "' \ + '[to]=group:test_suite@notmuchmail.org,someone@example.com\;' \ + [cc]=test_suite_other@notmuchmail.org \ + [subject]=notmuch-reply-test \ + '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ + '[body]="Reply from address in named group list"' + +output=$(notmuch reply id:${gen_msg_id}) +test_expect_equal "$output" "From: Notmuch Test Suite +Subject: Re: notmuch-reply-test +To: Sender , someone@example.com +In-Reply-To: <${gen_msg_id}> +References: <${gen_msg_id}> + +On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: +> Reply from address in named group list" + +test_begin_subtest "Support for Reply-To" +add_message '[from]="Sender "' \ + [to]=test_suite@notmuchmail.org \ + [subject]=notmuch-reply-test \ + '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ + '[body]="support for reply-to"' \ + '[reply-to]="Sender "' + +output=$(notmuch reply id:${gen_msg_id}) +test_expect_equal "$output" "From: Notmuch Test Suite +Subject: Re: notmuch-reply-test +To: Sender +In-Reply-To: <${gen_msg_id}> +References: <${gen_msg_id}> + +On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: +> support for reply-to" + +test_begin_subtest "Un-munging Reply-To" +add_message '[from]="Sender "' \ + '[to]="Some List "' \ + [subject]=notmuch-reply-test \ + '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ + '[body]="Un-munging Reply-To"' \ + '[reply-to]="Evil Munging List "' + +output=$(notmuch reply id:${gen_msg_id}) +test_expect_equal "$output" "From: Notmuch Test Suite +Subject: Re: notmuch-reply-test +To: Sender , Some List +In-Reply-To: <${gen_msg_id}> +References: <${gen_msg_id}> + +On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: +> Un-munging Reply-To" + +test_begin_subtest "Message with header of exactly 200 bytes" +add_message '[subject]="This subject is exactly 200 bytes in length. Other than its length there is not much of note here. Note that the length of 200 bytes includes the Subject: and Re: prefixes with two spaces"' \ + '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ + '[body]="200-byte header"' +output=$(notmuch reply id:${gen_msg_id}) +test_expect_equal "$output" "From: Notmuch Test Suite +Subject: Re: This subject is exactly 200 bytes in length. Other than its + length there is not much of note here. Note that the length of 200 bytes + includes the Subject: and Re: prefixes with two spaces +In-Reply-To: <${gen_msg_id}> +References: <${gen_msg_id}> + +On Tue, 05 Jan 2010 15:43:56 -0000, Notmuch Test Suite wrote: +> 200-byte header" + +test_begin_subtest "From guessing: Envelope-To" +add_message '[from]="Sender "' \ + '[to]="Recipient "' \ + '[subject]="From guessing"' \ + '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ + '[body]="From guessing"' \ + '[header]="Envelope-To: test_suite_other@notmuchmail.org"' + +output=$(notmuch reply id:${gen_msg_id}) +test_expect_equal "$output" "From: Notmuch Test Suite +Subject: Re: From guessing +To: Sender , Recipient +In-Reply-To: <${gen_msg_id}> +References: <${gen_msg_id}> + +On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: +> From guessing" + +test_begin_subtest "From guessing: X-Original-To" +add_message '[from]="Sender "' \ + '[to]="Recipient "' \ + '[subject]="From guessing"' \ + '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ + '[body]="From guessing"' \ + '[header]="X-Original-To: test_suite@otherdomain.org"' + +output=$(notmuch reply id:${gen_msg_id}) +test_expect_equal "$output" "From: Notmuch Test Suite +Subject: Re: From guessing +To: Sender , Recipient +In-Reply-To: <${gen_msg_id}> +References: <${gen_msg_id}> + +On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: +> From guessing" + +test_begin_subtest "From guessing: Delivered-To" +add_message '[from]="Sender "' \ + '[to]="Recipient "' \ + '[subject]="From guessing"' \ + '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ + '[body]="From guessing"' \ + '[header]="Delivered-To: test_suite_other@notmuchmail.org"' + +output=$(notmuch reply id:${gen_msg_id}) +test_expect_equal "$output" "From: Notmuch Test Suite +Subject: Re: From guessing +To: Sender , Recipient +In-Reply-To: <${gen_msg_id}> +References: <${gen_msg_id}> + +On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: +> From guessing" + +test_begin_subtest "Reply with RFC 2047-encoded headers" +add_message '[subject]="=?iso-8859-1?q?=e0=df=e7?="' \ + '[from]="=?utf-8?q?=e2=98=83?= "' \ + '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ + '[body]="Encoding"' + +# GMime happens to change from Q- to B-encoding. We canonicalize the +# case of the encoding and charset because different versions of GMime +# capitalize the encoding differently. +output=$(notmuch reply id:${gen_msg_id} | perl -pe 's/=\?[^?]+\?[bB]\?/lc($&)/ge') +test_expect_equal "$output" "\ +From: Notmuch Test Suite +Subject: Re: =?iso-8859-1?b?4N/n?= +To: =?utf-8?b?4piD?= +In-Reply-To: <${gen_msg_id}> +References: <${gen_msg_id}> + +On Tue, 05 Jan 2010 15:43:56 -0000, ☃ wrote: +> Encoding" + +test_begin_subtest "Reply with RFC 2047-encoded headers (JSON)" +output=$(notmuch reply --format=json id:${gen_msg_id}) +test_expect_equal_json "$output" ' +{ + "original": { + "body": [ + { + "content": "Encoding\n", + "content-type": "text/plain", + "id": 1 + } + ], + "date_relative": "2010-01-05", + "excluded": false, + "filename": "'${MAIL_DIR}'/msg-012", + "headers": { + "Date": "Tue, 05 Jan 2010 15:43:56 +0000", + "From": "\u2603 ", + "Subject": "\u00e0\u00df\u00e7", + "To": "Notmuch Test Suite " + }, + "id": "'${gen_msg_id}'", + "match": false, + "tags": [ + "inbox", + "unread" + ], + "timestamp": 1262706236 + }, + "reply-headers": { + "From": "Notmuch Test Suite ", + "In-reply-to": "<'${gen_msg_id}'>", + "References": "<'${gen_msg_id}'>", + "Subject": "Re: \u00e0\u00df\u00e7", + "To": "\u2603 " + } +}' + + +test_done diff --git a/test/T230-reply-to-sender.sh b/test/T230-reply-to-sender.sh new file mode 100755 index 00000000..30e5e385 --- /dev/null +++ b/test/T230-reply-to-sender.sh @@ -0,0 +1,211 @@ +#!/usr/bin/env bash +test_description="\"notmuch reply --reply-to=sender\" in several variations" +. ./test-lib.sh + +test_begin_subtest "Basic reply-to-sender" +add_message '[from]="Sender "' \ + [to]=test_suite@notmuchmail.org \ + [subject]=notmuch-reply-test \ + '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ + '[body]="basic reply-to-sender test"' + +output=$(notmuch reply --reply-to=sender id:${gen_msg_id}) +test_expect_equal "$output" "From: Notmuch Test Suite +Subject: Re: notmuch-reply-test +To: Sender +In-Reply-To: <${gen_msg_id}> +References: <${gen_msg_id}> + +On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: +> basic reply-to-sender test" + +test_begin_subtest "From Us, Basic reply to message" +add_message '[from]="Notmuch Test Suite "' \ + '[to]="Recipient "' \ + [subject]=notmuch-reply-test \ + '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ + '[body]="basic reply-to-from-us test"' + +output=$(notmuch reply --reply-to=sender id:${gen_msg_id}) +test_expect_equal "$output" "From: Notmuch Test Suite +Subject: Re: notmuch-reply-test +To: Recipient +In-Reply-To: <${gen_msg_id}> +References: <${gen_msg_id}> + +On Tue, 05 Jan 2010 15:43:56 -0000, Notmuch Test Suite wrote: +> basic reply-to-from-us test" + +test_begin_subtest "Multiple recipients" +add_message '[from]="Sender "' \ + '[to]="test_suite@notmuchmail.org, Someone Else "' \ + [subject]=notmuch-reply-test \ + '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ + '[body]="Multiple recipients"' + +output=$(notmuch reply --reply-to=sender id:${gen_msg_id}) +test_expect_equal "$output" "From: Notmuch Test Suite +Subject: Re: notmuch-reply-test +To: Sender +In-Reply-To: <${gen_msg_id}> +References: <${gen_msg_id}> + +On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: +> Multiple recipients" + +test_begin_subtest "From Us, Multiple TO recipients" +add_message '[from]="Notmuch Test Suite "' \ + '[to]="Recipient , Someone Else "' \ + [subject]=notmuch-reply-test \ + '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ + '[body]="From Us, Multiple TO recipients"' + +output=$(notmuch reply --reply-to=sender id:${gen_msg_id}) +test_expect_equal "$output" "From: Notmuch Test Suite +Subject: Re: notmuch-reply-test +To: Recipient , Someone Else +In-Reply-To: <${gen_msg_id}> +References: <${gen_msg_id}> + +On Tue, 05 Jan 2010 15:43:56 -0000, Notmuch Test Suite wrote: +> From Us, Multiple TO recipients" + +test_begin_subtest "Reply with CC" +add_message '[from]="Sender "' \ + [to]=test_suite@notmuchmail.org \ + '[cc]="Other Parties "' \ + [subject]=notmuch-reply-test \ + '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ + '[body]="reply with CC"' + +output=$(notmuch reply --reply-to=sender id:${gen_msg_id}) +test_expect_equal "$output" "From: Notmuch Test Suite +Subject: Re: notmuch-reply-test +To: Sender +In-Reply-To: <${gen_msg_id}> +References: <${gen_msg_id}> + +On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: +> reply with CC" + +test_begin_subtest "From Us, Reply with CC" +add_message '[from]="Notmuch Test Suite "' \ + '[to]="Recipient "' \ + '[cc]="Other Parties "' \ + [subject]=notmuch-reply-test \ + '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ + '[body]="reply with CC"' + +output=$(notmuch reply --reply-to=sender id:${gen_msg_id}) +test_expect_equal "$output" "From: Notmuch Test Suite +Subject: Re: notmuch-reply-test +To: Recipient +In-Reply-To: <${gen_msg_id}> +References: <${gen_msg_id}> + +On Tue, 05 Jan 2010 15:43:56 -0000, Notmuch Test Suite wrote: +> reply with CC" + +test_begin_subtest "From Us, Reply no TO but with CC" +add_message '[from]="Notmuch Test Suite "' \ + '[cc]="Other Parties "' \ + [subject]=notmuch-reply-test \ + '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ + '[body]="reply with CC"' + +output=$(notmuch reply --reply-to=sender id:${gen_msg_id}) +test_expect_equal "$output" "From: Notmuch Test Suite +Subject: Re: notmuch-reply-test +Cc: Other Parties +In-Reply-To: <${gen_msg_id}> +References: <${gen_msg_id}> + +On Tue, 05 Jan 2010 15:43:56 -0000, Notmuch Test Suite wrote: +> reply with CC" + +test_begin_subtest "Reply from alternate address" +add_message '[from]="Sender "' \ + [to]=test_suite_other@notmuchmail.org \ + [subject]=notmuch-reply-test \ + '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ + '[body]="reply from alternate address"' + +output=$(notmuch reply --reply-to=sender id:${gen_msg_id}) +test_expect_equal "$output" "From: Notmuch Test Suite +Subject: Re: notmuch-reply-test +To: Sender +In-Reply-To: <${gen_msg_id}> +References: <${gen_msg_id}> + +On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: +> reply from alternate address" + +test_begin_subtest "Support for Reply-To" +add_message '[from]="Sender "' \ + [to]=test_suite@notmuchmail.org \ + [subject]=notmuch-reply-test \ + '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ + '[body]="support for reply-to"' \ + '[reply-to]="Sender "' + +output=$(notmuch reply --reply-to=sender id:${gen_msg_id}) +test_expect_equal "$output" "From: Notmuch Test Suite +Subject: Re: notmuch-reply-test +To: Sender +In-Reply-To: <${gen_msg_id}> +References: <${gen_msg_id}> + +On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: +> support for reply-to" + +test_begin_subtest "Support for Reply-To with multiple recipients" +add_message '[from]="Sender "' \ + '[to]="test_suite@notmuchmail.org, Someone Else "' \ + [subject]=notmuch-reply-test \ + '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ + '[body]="support for reply-to with multiple recipients"' \ + '[reply-to]="Sender "' + +output=$(notmuch reply --reply-to=sender id:${gen_msg_id}) +test_expect_equal "$output" "From: Notmuch Test Suite +Subject: Re: notmuch-reply-test +To: Sender +In-Reply-To: <${gen_msg_id}> +References: <${gen_msg_id}> + +On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: +> support for reply-to with multiple recipients" + +test_begin_subtest "Un-munging Reply-To" +add_message '[from]="Sender "' \ + '[to]="Some List "' \ + [subject]=notmuch-reply-test \ + '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ + '[body]="Un-munging Reply-To"' \ + '[reply-to]="Evil Munging List "' + +output=$(notmuch reply --reply-to=sender id:${gen_msg_id}) +test_expect_equal "$output" "From: Notmuch Test Suite +Subject: Re: notmuch-reply-test +To: Sender +In-Reply-To: <${gen_msg_id}> +References: <${gen_msg_id}> + +On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: +> Un-munging Reply-To" + +test_begin_subtest "Message with header of exactly 200 bytes" +add_message '[subject]="This subject is exactly 200 bytes in length. Other than its length there is not much of note here. Note that the length of 200 bytes includes the Subject: and Re: prefixes with two spaces"' \ + '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ + '[body]="200-byte header"' +output=$(notmuch reply --reply-to=sender id:${gen_msg_id}) +test_expect_equal "$output" "From: Notmuch Test Suite +Subject: Re: This subject is exactly 200 bytes in length. Other than its + length there is not much of note here. Note that the length of 200 bytes + includes the Subject: and Re: prefixes with two spaces +In-Reply-To: <${gen_msg_id}> +References: <${gen_msg_id}> + +On Tue, 05 Jan 2010 15:43:56 -0000, Notmuch Test Suite wrote: +> 200-byte header" +test_done diff --git a/test/T240-dump-restore.sh b/test/T240-dump-restore.sh new file mode 100755 index 00000000..0004438d --- /dev/null +++ b/test/T240-dump-restore.sh @@ -0,0 +1,293 @@ +#!/usr/bin/env bash +test_description="\"notmuch dump\" and \"notmuch restore\"" +. ./test-lib.sh + +add_email_corpus + +test_expect_success 'Dumping all tags' \ + 'generate_message && + notmuch new && + notmuch dump > dump.expected' + +# The use of from:cworth is rather arbitrary: it matches some of the +# email corpus' messages, but not all of them. + +test_expect_success 'Dumping all tags II' \ + 'notmuch tag +ABC +DEF -- from:cworth && + notmuch dump > dump-ABC_DEF.expected && + ! cmp dump.expected dump-ABC_DEF.expected' + +test_expect_success 'Clearing all tags' \ + 'sed -e "s/(\([^(]*\))$/()/" < dump.expected > clear.expected && + notmuch restore --input=clear.expected && + notmuch dump > clear.actual && + test_cmp clear.expected clear.actual' + +test_expect_success 'Accumulate original tags' \ + 'notmuch tag +ABC +DEF -- from:cworth && + notmuch restore --accumulate < dump.expected && + notmuch dump > dump.actual && + test_cmp dump-ABC_DEF.expected dump.actual' + +test_expect_success 'Restoring original tags' \ + 'notmuch restore --input=dump.expected && + notmuch dump > dump.actual && + test_cmp dump.expected dump.actual' + +test_expect_success 'Restore with nothing to do' \ + 'notmuch restore < dump.expected && + notmuch dump > dump.actual && + test_cmp dump.expected dump.actual' + +test_expect_success 'Accumulate with existing tags' \ + 'notmuch restore --accumulate --input=dump.expected && + notmuch dump > dump.actual && + test_cmp dump.expected dump.actual' + +test_expect_success 'Accumulate with no tags' \ + 'notmuch restore --accumulate < clear.expected && + notmuch dump > dump.actual && + test_cmp dump.expected dump.actual' + +test_expect_success 'Accumulate with new tags' \ + 'notmuch restore --input=dump.expected && + notmuch restore --accumulate --input=dump-ABC_DEF.expected && + notmuch dump > OUTPUT.$test_count && + notmuch restore --input=dump.expected && + test_cmp dump-ABC_DEF.expected OUTPUT.$test_count' + +# notmuch restore currently only considers the first argument. +test_expect_success 'Invalid restore invocation' \ + 'test_must_fail notmuch restore --input=dump.expected another_one' + +test_begin_subtest "dump --output=outfile" +notmuch dump --output=dump-outfile.actual +test_expect_equal_file dump.expected dump-outfile.actual + +test_begin_subtest "dump --output=outfile --" +notmuch dump --output=dump-1-arg-dash.actual -- +test_expect_equal_file dump.expected dump-1-arg-dash.actual + +# Note, we assume all messages from cworth have a message-id +# containing cworth.org + +grep 'cworth[.]org' dump.expected > dump-cworth.expected + +test_begin_subtest "dump -- from:cworth" +notmuch dump -- from:cworth > dump-dash-cworth.actual +test_expect_equal_file dump-cworth.expected dump-dash-cworth.actual + +test_begin_subtest "dump --output=outfile from:cworth" +notmuch dump --output=dump-outfile-cworth.actual from:cworth +test_expect_equal_file dump-cworth.expected dump-outfile-cworth.actual + +test_begin_subtest "dump --output=outfile -- from:cworth" +notmuch dump --output=dump-outfile-dash-inbox.actual -- from:cworth +test_expect_equal_file dump-cworth.expected dump-outfile-dash-inbox.actual + +test_begin_subtest "Check for a safe set of message-ids" +notmuch search --output=messages from:cworth | sed s/^id:// > EXPECTED +notmuch search --output=messages from:cworth | sed s/^id:// |\ + $TEST_DIRECTORY/hex-xcode --direction=encode > OUTPUT +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "format=batch-tag, dump sanity check." +notmuch dump --format=sup from:cworth | cut -f1 -d' ' | \ + sort > EXPECTED.$test_count +notmuch dump --format=batch-tag from:cworth | sed 's/^.*-- id://' | \ + sort > OUTPUT.$test_count +test_expect_equal_file EXPECTED.$test_count OUTPUT.$test_count + +test_begin_subtest "format=batch-tag, # round-trip" +notmuch dump --format=sup | sort > EXPECTED.$test_count +notmuch dump --format=batch-tag | notmuch restore --format=batch-tag +notmuch dump --format=sup | sort > OUTPUT.$test_count +test_expect_equal_file EXPECTED.$test_count OUTPUT.$test_count + +test_begin_subtest "format=batch-tag, # blank lines and comments" +notmuch dump --format=batch-tag| sort > EXPECTED.$test_count +notmuch restore < OUTPUT.$test_count +test_expect_equal_file EXPECTED.$test_count OUTPUT.$test_count + +test_begin_subtest "format=batch-tag, # reverse-round-trip empty tag" +cat <EXPECTED.$test_count ++ -- id:20091117232137.GA7669@griffis1.net +EOF +notmuch restore --format=batch-tag < EXPECTED.$test_count +notmuch dump --format=batch-tag id:20091117232137.GA7669@griffis1.net > OUTPUT.$test_count +test_expect_equal_file EXPECTED.$test_count OUTPUT.$test_count + +tag1='comic_swear=$&^%$^%\\//-+$^%$' +enc1=$($TEST_DIRECTORY/hex-xcode --direction=encode "$tag1") + +tag2=$(printf 'this\n tag\t has\n spaces') +enc2=$($TEST_DIRECTORY/hex-xcode --direction=encode "$tag2") + +enc3='%c3%91%c3%a5%c3%b0%c3%a3%c3%a5%c3%a9-%c3%8f%c3%8a' +tag3=$($TEST_DIRECTORY/hex-xcode --direction=decode $enc3) + +notmuch dump --format=batch-tag > BACKUP + +notmuch tag +"$tag1" +"$tag2" +"$tag3" -inbox -unread "*" + +# initial segment of file used for several tests below. +cat < comments-and-blanks +# this is a comment + +# next line has leading whitespace + + +EOF + +test_begin_subtest 'restoring empty file is not an error' +notmuch restore < /dev/null 2>OUTPUT.$test_count +cp /dev/null EXPECTED +test_expect_equal_file EXPECTED OUTPUT.$test_count + +test_begin_subtest 'file of comments and blank lines is not an error' +notmuch restore --input=comments-and-blanks +ret_val=$? +test_expect_equal "$ret_val" "0" + +cp comments-and-blanks leading-comments-blanks-batch-tag +echo "+some_tag -- id:yun1vjwegii.fsf@aiko.keithp.com" \ + >> leading-comments-blanks-batch-tag + +test_begin_subtest 'detect format=batch-tag with leading comments and blanks' +notmuch restore --input=leading-comments-blanks-batch-tag +notmuch search --output=tags id:yun1vjwegii.fsf@aiko.keithp.com > OUTPUT.$test_count +echo "some_tag" > EXPECTED +test_expect_equal_file EXPECTED OUTPUT.$test_count + +cp comments-and-blanks leading-comments-blanks-sup +echo "yun1vjwegii.fsf@aiko.keithp.com (another_tag)" \ + >> leading-comments-blanks-sup + +test_begin_subtest 'detect format=sup with leading comments and blanks' +notmuch restore --input=leading-comments-blanks-sup +notmuch search --output=tags id:yun1vjwegii.fsf@aiko.keithp.com > OUTPUT.$test_count +echo "another_tag" > EXPECTED +test_expect_equal_file EXPECTED OUTPUT.$test_count + +test_begin_subtest 'format=batch-tag, round trip with strange tags' +notmuch dump --format=batch-tag > EXPECTED.$test_count +notmuch dump --format=batch-tag | notmuch restore --format=batch-tag +notmuch dump --format=batch-tag > OUTPUT.$test_count +test_expect_equal_file EXPECTED.$test_count OUTPUT.$test_count + +test_begin_subtest 'format=batch-tag, checking encoded output' +notmuch dump --format=batch-tag -- from:cworth |\ + awk "{ print \"+$enc1 +$enc2 +$enc3 -- \" \$5 }" > EXPECTED.$test_count +notmuch dump --format=batch-tag -- from:cworth > OUTPUT.$test_count +test_expect_equal_file EXPECTED.$test_count OUTPUT.$test_count + +test_begin_subtest 'restoring sane tags' +notmuch restore --format=batch-tag < BACKUP +notmuch dump --format=batch-tag > OUTPUT.$test_count +test_expect_equal_file BACKUP OUTPUT.$test_count + +test_begin_subtest 'format=batch-tag, restore=auto' +notmuch dump --format=batch-tag > EXPECTED.$test_count +notmuch tag -inbox -unread "*" +notmuch restore --format=auto < EXPECTED.$test_count +notmuch dump --format=batch-tag > OUTPUT.$test_count +test_expect_equal_file EXPECTED.$test_count OUTPUT.$test_count + +test_begin_subtest 'format=sup, restore=auto' +notmuch dump --format=sup > EXPECTED.$test_count +notmuch tag -inbox -unread "*" +notmuch restore --format=auto < EXPECTED.$test_count +notmuch dump --format=sup > OUTPUT.$test_count +test_expect_equal_file EXPECTED.$test_count OUTPUT.$test_count + +test_begin_subtest 'format=batch-tag, restore=default' +notmuch dump --format=batch-tag > EXPECTED.$test_count +notmuch tag -inbox -unread "*" +notmuch restore < EXPECTED.$test_count +notmuch dump --format=batch-tag > OUTPUT.$test_count +test_expect_equal_file EXPECTED.$test_count OUTPUT.$test_count + +test_begin_subtest 'format=sup, restore=default' +notmuch dump --format=sup > EXPECTED.$test_count +notmuch tag -inbox -unread "*" +notmuch restore < EXPECTED.$test_count +notmuch dump --format=sup > OUTPUT.$test_count +test_expect_equal_file EXPECTED.$test_count OUTPUT.$test_count + +test_begin_subtest 'restore: checking error messages' +notmuch restore <OUTPUT +# the next line has a space + +a ++0 ++a +b +# trailing whitespace ++a +b ++c +d -- +# this is a harmless comment, do not yell about it. + +# the previous line was blank; also no yelling please ++%zz -- id:whatever ++e +f id:" ++e +f tag:abc +# the next non-comment line should report an an empty tag error for +# batch tagging, but not for restore ++ +e -- id:20091117232137.GA7669@griffis1.net +# valid id, but warning about missing message ++e id:missing_message_id +# exercise parser ++e -- id:some)stuff ++e -- id:some stuff ++e -- id:some"stuff ++e -- id:"a_message_id_with""_a_quote" ++e -- id:"a message id with spaces" ++e -- id:an_id_with_leading_and_trailing_ws \ + +EOF + +cat < EXPECTED +Warning: cannot parse query: a (skipping) +Warning: no query string [+0] +Warning: no query string [+a +b] +Warning: missing query string [+a +b ] +Warning: no query string after -- [+c +d --] +Warning: hex decoding of tag %zz failed [+%zz -- id:whatever] +Warning: cannot parse query: id:" (skipping) +Warning: not an id query: tag:abc (skipping) +Warning: cannot apply tags to missing message: missing_message_id +Warning: cannot parse query: id:some)stuff (skipping) +Warning: cannot parse query: id:some stuff (skipping) +Warning: cannot apply tags to missing message: some"stuff +Warning: cannot apply tags to missing message: a_message_id_with"_a_quote +Warning: cannot apply tags to missing message: a message id with spaces +Warning: cannot apply tags to missing message: an_id_with_leading_and_trailing_ws +EOF + +test_expect_equal_file EXPECTED OUTPUT + +test_begin_subtest 'roundtripping random message-ids and tags' + + ${TEST_DIRECTORY}/random-corpus --config-path=${NOTMUCH_CONFIG} \ + --num-messages=100 + + notmuch dump --format=batch-tag| \ + sort > EXPECTED.$test_count + + notmuch tag +this_tag_is_very_unlikely_to_be_random '*' + + notmuch restore --format=batch-tag < EXPECTED.$test_count + + notmuch dump --format=batch-tag| \ + sort > OUTPUT.$test_count + +test_expect_equal_file EXPECTED.$test_count OUTPUT.$test_count + +test_done + +# Note the database is "poisoned" for sup format at this point. diff --git a/test/T250-uuencode.sh b/test/T250-uuencode.sh new file mode 100755 index 00000000..b3e1ac19 --- /dev/null +++ b/test/T250-uuencode.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash +test_description="handling of uuencoded data" +. ./test-lib.sh + +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 begin the uuencoded data itself: + +begin 644 bogus-uuencoded-data +M0123456789012345678901234567890123456789012345678901234567890 +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 +MSEARCH RESULT. +\\\` +end + +Finally, we have our afteruudata marker as well."' + +test_begin_subtest "Ensure content before uu data is indexed" +output=$(notmuch search beforeuudata | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; uuencodetest (inbox unread)" + +test_begin_subtest "Ensure uu data is not indexed" +output=$(notmuch search DURINGUUDATA | notmuch_search_sanitize) +test_expect_equal "$output" "" + +test_begin_subtest "Ensure content after uu data is indexed" +output=$(notmuch search afteruudata | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; uuencodetest (inbox unread)" + +test_done diff --git a/test/T260-thread-order.sh b/test/T260-thread-order.sh new file mode 100755 index 00000000..6c3a4b3f --- /dev/null +++ b/test/T260-thread-order.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash +test_description="threading when messages received out of order" +. ./test-lib.sh + +test_begin_subtest "Adding initial child message" +generate_message [body]=foo "[in-reply-to]=\" [subject]=brokenthreadtest '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' +output=$(NOTMUCH_NEW) +test_expect_equal "$output" "Added 1 new message to the database." + +test_begin_subtest "Searching returns the message" +output=$(notmuch search foo | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; brokenthreadtest (inbox unread)" + +test_begin_subtest "Adding second child message" +generate_message [body]=foo "[in-reply-to]=\" [subject]=brokenthreadtest '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' +output=$(NOTMUCH_NEW) +test_expect_equal "$output" "Added 1 new message to the database." + +test_begin_subtest "Searching returns both messages in one thread" +output=$(notmuch search foo | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2000-01-01 [2/2] Notmuch Test Suite; brokenthreadtest (inbox unread)" + +test_begin_subtest "Adding parent message" +generate_message [body]=foo [id]=parent-id [subject]=brokenthreadtest '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' +output=$(NOTMUCH_NEW) +test_expect_equal "$output" "Added 1 new message to the database." + +test_begin_subtest "Searching returns all three messages in one thread" +output=$(notmuch search foo | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2000-01-01 [3/3] Notmuch Test Suite; brokenthreadtest (inbox unread)" + +test_done diff --git a/test/T270-author-order.sh b/test/T270-author-order.sh new file mode 100755 index 00000000..6ffeffc7 --- /dev/null +++ b/test/T270-author-order.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash +test_description="author reordering;" +. ./test-lib.sh + +test_begin_subtest "Adding parent message" +generate_message [body]=findme [id]=new-parent-id [subject]=author-reorder-threadtest '[from]="User "' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' +output=$(NOTMUCH_NEW) +test_expect_equal "$output" "Added 1 new message to the database." + +test_begin_subtest "Adding initial child message" +generate_message [body]=findme "[in-reply-to]=\" [subject]=author-reorder-threadtest '[from]="User1 "' '[date]="Sat, 01 Jan 2000 12:01:00 -0000"' +output=$(NOTMUCH_NEW) +test_expect_equal "$output" "Added 1 new message to the database." + +test_begin_subtest "Adding second child message" +generate_message [body]=findme "[in-reply-to]=\" [subject]=author-reorder-threadtest '[from]="User2 "' '[date]="Sat, 01 Jan 2000 12:02:00 -0000"' +output=$(NOTMUCH_NEW) +test_expect_equal "$output" "Added 1 new message to the database." + +test_begin_subtest "Searching when all three messages match" +output=$(notmuch search findme | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2000-01-01 [3/3] User, User1, User2; author-reorder-threadtest (inbox unread)" + +test_begin_subtest "Searching when two messages match" +output=$(notmuch search User1 or User2 | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2000-01-01 [2/3] User1, User2| User; author-reorder-threadtest (inbox unread)" + +test_begin_subtest "Searching when only one message matches" +output=$(notmuch search User2 | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2000-01-01 [1/3] User2| User, User1; author-reorder-threadtest (inbox unread)" + +test_begin_subtest "Searching when only first message matches" +output=$(notmuch search User | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2000-01-01 [1/3] User| User1, User2; author-reorder-threadtest (inbox unread)" + +test_begin_subtest "Adding duplicate author" +generate_message [body]=findme "[in-reply-to]=\" [subject]=author-reorder-threadtest '[from]="User1 "' '[date]="Sat, 01 Jan 2000 12:03:00 -0000"' +output=$(NOTMUCH_NEW) +test_expect_equal "$output" "Added 1 new message to the database." + +test_begin_subtest "Searching when all four messages match" +output=$(notmuch search findme | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2000-01-01 [4/4] User, User1, User2; author-reorder-threadtest (inbox unread)" + +test_begin_subtest "Adding non-monotonic child message" +generate_message [body]=findme "[in-reply-to]=\" [subject]=author-reorder-threadtest '[from]="User0 "' '[date]="Sat, 01 Jan 2000 11:00:00 -0000"' +output=$(NOTMUCH_NEW) +test_expect_equal "$output" "Added 1 new message to the database." + +test_begin_subtest "Searching non-monotonic messages (oldest-first)" +output=$(notmuch search --sort=oldest-first findme | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2000-01-01 [5/5] User0, User, User1, User2; author-reorder-threadtest (inbox unread)" + +test_begin_subtest "Searching non-monotonic messages (newest-first)" +output=$(notmuch search --sort=newest-first findme | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2000-01-01 [5/5] User0, User, User1, User2; author-reorder-threadtest (inbox unread)" + +test_done diff --git a/test/T280-from-guessing.sh b/test/T280-from-guessing.sh new file mode 100755 index 00000000..6dfaa40a --- /dev/null +++ b/test/T280-from-guessing.sh @@ -0,0 +1,217 @@ +#!/usr/bin/env bash +test_description="From line heuristics (with multiple configured addresses)" +. ./test-lib.sh + +test_begin_subtest "Magic from guessing (nothing to go on)" +add_message '[from]="Sender "' \ + [to]=mailinglist@notmuchmail.org \ + [subject]=notmuch-reply-test \ + '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ + '[body]="from guessing test"' + +output=$(notmuch reply id:${gen_msg_id}) +test_expect_equal "$output" "From: Notmuch Test Suite +Subject: Re: notmuch-reply-test +To: Sender , mailinglist@notmuchmail.org +In-Reply-To: <${gen_msg_id}> +References: <${gen_msg_id}> + +On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: +> from guessing test" + +test_begin_subtest "Magic from guessing (Envelope-to:)" +add_message '[from]="Sender "' \ + [to]=mailinglist@notmuchmail.org \ + [subject]=notmuch-reply-test \ + '[header]="Envelope-To: test_suite_other@notmuchmail.org"' \ + '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ + '[body]="from guessing test"' + +output=$(notmuch reply id:${gen_msg_id}) +test_expect_equal "$output" "From: Notmuch Test Suite +Subject: Re: notmuch-reply-test +To: Sender , mailinglist@notmuchmail.org +In-Reply-To: <${gen_msg_id}> +References: <${gen_msg_id}> + +On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: +> from guessing test" + +test_begin_subtest "Magic from guessing (X-Original-To:)" +add_message '[from]="Sender "' \ + [to]=mailinglist@notmuchmail.org \ + [subject]=notmuch-reply-test \ + '[header]="X-Original-To: test_suite_other@notmuchmail.org"' \ + '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ + '[body]="from guessing test"' + +output=$(notmuch reply id:${gen_msg_id}) +test_expect_equal "$output" "From: Notmuch Test Suite +Subject: Re: notmuch-reply-test +To: Sender , mailinglist@notmuchmail.org +In-Reply-To: <${gen_msg_id}> +References: <${gen_msg_id}> + +On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: +> from guessing test" + +test_begin_subtest "Magic from guessing (Received: .. for ..)" +add_message '[from]="Sender "' \ + [to]=mailinglist@notmuchmail.org \ + [subject]=notmuch-reply-test \ + "[header]=\"Received: from mail.example.com (mail.example.com [1.1.1.1]) + by mail.notmuchmail.org (some MTA) with ESMTP id 12345678 + for ; Sat, 10 Apr 2010 07:54:51 -0400 (EDT)\"" \ + '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ + '[body]="from guessing test"' + +output=$(notmuch reply id:${gen_msg_id}) +test_expect_equal "$output" "From: Notmuch Test Suite +Subject: Re: notmuch-reply-test +To: Sender , mailinglist@notmuchmail.org +In-Reply-To: <${gen_msg_id}> +References: <${gen_msg_id}> + +On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: +> from guessing test" + +test_begin_subtest "Magic from guessing (Received: domain)" +add_message '[from]="Sender "' \ + [to]=mailinglist@notmuchmail.org \ + [subject]=notmuch-reply-test \ + "[header]=\"Received: from mail.example.com (mail.example.com [1.1.1.1]) + by mail.otherdomain.org (some MTA) with ESMTP id 12345678 + Sat, 10 Apr 2010 07:54:51 -0400 (EDT)\"" \ + '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ + '[body]="from guessing test"' + +output=$(notmuch reply id:${gen_msg_id}) +test_expect_equal "$output" "From: Notmuch Test Suite +Subject: Re: notmuch-reply-test +To: Sender , mailinglist@notmuchmail.org +In-Reply-To: <${gen_msg_id}> +References: <${gen_msg_id}> + +On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: +> from guessing test" + +test_begin_subtest "Magic from guessing (multiple Received: headers)" +add_message '[from]="Sender "' \ + [to]=mailinglist@notmuchmail.org \ + [subject]=notmuch-reply-test \ + "[header]=\"Received: from extraneous.example.com (extraneous.example.com [1.1.1.1]) +Received: from mail.example.com (mail.example.com [1.1.1.1]) + by mail.otherdomain.org (some MTA) with ESMTP id 12345678 + for ; Sat, 10 Apr 2010 07:54:51 -0400 (EDT) +Received: from extraneous.example.com (extraneous.example.com [1.1.1.1])\"" \ + '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ + '[body]="from guessing test"' + +output="$(notmuch reply id:${gen_msg_id})" +test_expect_equal "$output" "From: Notmuch Test Suite +Subject: Re: notmuch-reply-test +To: Sender , mailinglist@notmuchmail.org +In-Reply-To: <${gen_msg_id}> +References: <${gen_msg_id}> + +On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: +> from guessing test" + +test_begin_subtest "Testing From line heuristics (with single configured address)" +sed -i -e "s/^other_email.*//" "${NOTMUCH_CONFIG}" +test_expect_equal '' '' + +test_begin_subtest "Magic from guessing (nothing to go on)" +add_message '[from]="Sender "' \ + [to]=mailinglist@notmuchmail.org \ + [subject]=notmuch-reply-test \ + '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ + '[body]="from guessing test"' + +output=$(notmuch reply id:${gen_msg_id}) +test_expect_equal "$output" "From: Notmuch Test Suite +Subject: Re: notmuch-reply-test +To: Sender , mailinglist@notmuchmail.org +In-Reply-To: <${gen_msg_id}> +References: <${gen_msg_id}> + +On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: +> from guessing test" + +test_begin_subtest "Magic from guessing (Envelope-to:)" +add_message '[from]="Sender "' \ + [to]=mailinglist@notmuchmail.org \ + [subject]=notmuch-reply-test \ + '[header]="Envelope-To: test_suite_other@notmuchmail.org"' \ + '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ + '[body]="from guessing test"' + +output=$(notmuch reply id:${gen_msg_id}) +test_expect_equal "$output" "From: Notmuch Test Suite +Subject: Re: notmuch-reply-test +To: Sender , mailinglist@notmuchmail.org +In-Reply-To: <${gen_msg_id}> +References: <${gen_msg_id}> + +On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: +> from guessing test" + +test_begin_subtest "Magic from guessing (X-Original-To:)" +add_message '[from]="Sender "' \ + [to]=mailinglist@notmuchmail.org \ + [subject]=notmuch-reply-test \ + '[header]="X-Original-To: test_suite_other@notmuchmail.org"' \ + '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ + '[body]="from guessing test"' + +output=$(notmuch reply id:${gen_msg_id}) +test_expect_equal "$output" "From: Notmuch Test Suite +Subject: Re: notmuch-reply-test +To: Sender , mailinglist@notmuchmail.org +In-Reply-To: <${gen_msg_id}> +References: <${gen_msg_id}> + +On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: +> from guessing test" + +test_begin_subtest "Magic from guessing (Received: .. for ..)" +add_message '[from]="Sender "' \ + [to]=mailinglist@notmuchmail.org \ + [subject]=notmuch-reply-test \ + "[header]=\"Received: from mail.example.com (mail.example.com [1.1.1.1]) + by mail.notmuchmail.org (some MTA) with ESMTP id 12345678 + for ; Sat, 10 Apr 2010 07:54:51 -0400 (EDT)\"" \ + '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ + '[body]="from guessing test"' + +output=$(notmuch reply id:${gen_msg_id}) +test_expect_equal "$output" "From: Notmuch Test Suite +Subject: Re: notmuch-reply-test +To: Sender , mailinglist@notmuchmail.org +In-Reply-To: <${gen_msg_id}> +References: <${gen_msg_id}> + +On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: +> from guessing test" + +test_begin_subtest "Magic from guessing (Received: domain)" +add_message '[from]="Sender "' \ + [to]=mailinglist@notmuchmail.org \ + [subject]=notmuch-reply-test \ + "[header]=\"Received: from mail.example.com (mail.example.com [1.1.1.1]) + by mail.otherdomain.org (some MTA) with ESMTP id 12345678 + Sat, 10 Apr 2010 07:54:51 -0400 (EDT)\"" \ + '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ + '[body]="from guessing test"' + +output=$(notmuch reply id:${gen_msg_id}) +test_expect_equal "$output" "From: Notmuch Test Suite +Subject: Re: notmuch-reply-test +To: Sender , mailinglist@notmuchmail.org +In-Reply-To: <${gen_msg_id}> +References: <${gen_msg_id}> + +On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: +> from guessing test" + +test_done diff --git a/test/T290-long-id.sh b/test/T290-long-id.sh new file mode 100755 index 00000000..85e620fa --- /dev/null +++ b/test/T290-long-id.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +test_description="messages with ridiculously-long message IDs" +. ./test-lib.sh + +test_begin_subtest "Referencing long ID before adding" +generate_message '[subject]="Reference of ridiculously-long message ID"' \ + "[references]=\" +output=$(NOTMUCH_NEW) +test_expect_equal "$output" "Added 1 new message to the database." + +test_begin_subtest "Adding message with long ID" +generate_message '[subject]="A ridiculously-long message ID"' \ + "[id]=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-" +output=$(NOTMUCH_NEW) +test_expect_equal "$output" "Added 1 new message to the database." + +test_begin_subtest "Referencing long ID after adding" +generate_message '[subject]="Reply to ridiculously-long message ID"' \ + "[in-reply-to]=\" +output=$(NOTMUCH_NEW) +test_expect_equal "$output" "Added 1 new message to the database." + +test_begin_subtest "Ensure all messages were threaded together" +output=$(notmuch search 'subject:"a ridiculously-long message ID"' | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2001-01-05 [1/3] Notmuch Test Suite; A ridiculously-long message ID (inbox unread)" + +test_done diff --git a/test/T300-encoding.sh b/test/T300-encoding.sh new file mode 100755 index 00000000..b6c86bf0 --- /dev/null +++ b/test/T300-encoding.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash +test_description="encoding issues" +. ./test-lib.sh + +test_begin_subtest "Message with text of unknown charset" +add_message '[content-type]="text/plain; charset=unknown-8bit"' \ + "[body]=irrelevant" +output=$(notmuch show id:${gen_msg_id} 2>&1 | notmuch_show_sanitize_all) +test_expect_equal "$output" " message{ id:XXXXX depth:0 match:1 excluded:0 filename:XXXXX + header{ +Notmuch Test Suite (2001-01-05) (inbox unread) +Subject: Message with text of unknown charset +From: Notmuch Test Suite +To: Notmuch Test Suite +Date: GENERATED_DATE + header} + body{ + part{ ID: 1, Content-type: text/plain +irrelevant + part} + body} + message}" + +test_begin_subtest "Search for ISO-8859-2 encoded message" +add_message '[content-type]="text/plain; charset=iso-8859-2"' \ + '[content-transfer-encoding]=8bit' \ + '[subject]="ISO-8859-2 encoded message"' \ + "[body]=$'Czech word tu\350\362\341\350\350\355 means pinguin\'s.'" # ISO-8859-2 characters are generated by shell's escape sequences +output=$(notmuch search tučňáččí 2>&1 | notmuch_show_sanitize_all) +test_expect_equal "$output" "thread:0000000000000002 2001-01-05 [1/1] Notmuch Test Suite; ISO-8859-2 encoded message (inbox unread)" + +test_begin_subtest "RFC 2047 encoded word with spaces" +add_message '[subject]="=?utf-8?q?encoded word with spaces?="' +output=$(notmuch search id:${gen_msg_id} 2>&1 | notmuch_show_sanitize) +test_expect_equal "$output" "thread:0000000000000003 2001-01-05 [1/1] Notmuch Test Suite; encoded word with spaces (inbox unread)" + +test_begin_subtest "RFC 2047 encoded words back to back" +add_message '[subject]="=?utf-8?q?encoded-words-back?==?utf-8?q?to-back?="' +output=$(notmuch search id:${gen_msg_id} 2>&1 | notmuch_show_sanitize) +test_expect_equal "$output" "thread:0000000000000004 2001-01-05 [1/1] Notmuch Test Suite; encoded-words-backto-back (inbox unread)" + +test_begin_subtest "RFC 2047 encoded words without space before or after" +add_message '[subject]="=?utf-8?q?encoded?=word without=?utf-8?q?space?=" ' +output=$(notmuch search id:${gen_msg_id} 2>&1 | notmuch_show_sanitize) +test_expect_equal "$output" "thread:0000000000000005 2001-01-05 [1/1] Notmuch Test Suite; encodedword withoutspace (inbox unread)" + +test_done diff --git a/test/T310-emacs.sh b/test/T310-emacs.sh new file mode 100755 index 00000000..00ae96a8 --- /dev/null +++ b/test/T310-emacs.sh @@ -0,0 +1,956 @@ +#!/usr/bin/env bash + +test_description="emacs interface" +. ./test-lib.sh + +EXPECTED=$TEST_DIRECTORY/emacs.expected-output + +add_email_corpus + +# syntax errors in test-lib.el cause mysterious failures +test_expect_success 'Syntax of emacs test library' \ + "${TEST_EMACS} -Q --batch --load $TEST_DIRECTORY/test-lib.el" + +test_begin_subtest "Basic notmuch-hello view in emacs" +test_emacs '(notmuch-hello) + (test-output)' +test_expect_equal_file OUTPUT $EXPECTED/notmuch-hello + +test_begin_subtest "Saved search with 0 results" +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 '(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) + (test-output)' +test_expect_equal_file OUTPUT $EXPECTED/notmuch-search-tag-inbox + +test_begin_subtest "Incremental parsing of search results" +test_emacs "(ad-enable-advice 'notmuch-search-process-filter 'around 'pessimal) + (ad-activate 'notmuch-search-process-filter) + (notmuch-search \"tag:inbox\") + (notmuch-test-wait) + (ad-disable-advice 'notmuch-search-process-filter 'around 'pessimal) + (ad-activate 'notmuch-search-process-filter) + (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 (1- (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\") + (test-output)" +test_expect_equal_file OUTPUT $EXPECTED/notmuch-show-thread-maildir-storage + +test_begin_subtest "Basic notmuch-show view in emacs default indentation" +maildir_storage_thread=$(notmuch search --output=threads id:20091117190054.GU3165@dottiness.seas.harvard.edu) +test_emacs "(let ((notmuch-show-indent-messages-width 1)) + (notmuch-show \"$maildir_storage_thread\") + (test-output))" +test_expect_equal_file OUTPUT $EXPECTED/notmuch-show-thread-maildir-storage + +test_begin_subtest "Basic notmuch-show view in emacs without indentation" +maildir_storage_thread=$(notmuch search --output=threads id:20091117190054.GU3165@dottiness.seas.harvard.edu) +test_emacs "(let ((notmuch-show-indent-messages-width 0)) + (notmuch-show \"$maildir_storage_thread\") + (test-output))" +test_expect_equal_file OUTPUT $EXPECTED/notmuch-show-thread-maildir-storage-without-indentation + +test_begin_subtest "Basic notmuch-show view in emacs with fourfold indentation" +maildir_storage_thread=$(notmuch search --output=threads id:20091117190054.GU3165@dottiness.seas.harvard.edu) +test_emacs "(let ((notmuch-show-indent-messages-width 4)) + (notmuch-show \"$maildir_storage_thread\") + (test-output))" +test_expect_equal_file OUTPUT $EXPECTED/notmuch-show-thread-maildir-storage-with-fourfold-indentation + +test_begin_subtest "notmuch-show for message with invalid From" +add_message "[subject]=\"message-with-invalid-from\"" \ + "[from]=\"\\\"Invalid \\\" From\\\" \"" +thread=$(notmuch search --output=threads subject:message-with-invalid-from) +test_emacs "(notmuch-show \"$thread\") + (test-output \"OUTPUT.raw\")" +cat <EXPECTED +"Invalid " (2001-01-05) (inbox) +Subject: message-with-invalid-from +To: Notmuch Test Suite +Date: GENERATED_DATE + +This is just a test message (#1) +EOF +notmuch_date_sanitize < OUTPUT.raw > OUTPUT +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) + (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) + (execute-kbd-macro \"+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) + (execute-kbd-macro \"-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 (large query)" +# We use a long query to force us into batch mode and use a funny tag +# that requires escaping for batch tagging. +test_emacs "(notmuch-tag (concat \"$os_x_darwin_thread\" \" or \" (make-string notmuch-tag-argument-limit ?x)) (list \"+tag-from-%-large-query\"))" +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-%-large-query unread)" +notmuch tag -tag-from-%-large-query $os_x_darwin_thread + +test_begin_subtest "notmuch-show: add single tag to single message" +test_emacs "(notmuch-show \"$os_x_darwin_thread\") + (execute-kbd-macro \"+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 "notmuch-show: remove single tag from single message" +test_emacs "(notmuch-show \"$os_x_darwin_thread\") + (execute-kbd-macro \"-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 "notmuch-show: add multiple tags to single message" +test_emacs "(notmuch-show \"$os_x_darwin_thread\") + (execute-kbd-macro \"+tag1-from-show-view +tag2-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 tag1-from-show-view tag2-from-show-view unread)" + +test_begin_subtest "notmuch-show: remove multiple tags from single message" +test_emacs "(notmuch-show \"$os_x_darwin_thread\") + (execute-kbd-macro \"-tag1-from-show-view -tag2-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) + (execute-kbd-macro "+search-add") + (execute-kbd-macro "+search-remove") + (execute-kbd-macro "-search-remove") + (notmuch-show "id:\"123..456@example\"") + (notmuch-test-wait) + (execute-kbd-macro "+show-add") + (execute-kbd-macro "+show-remove") + (execute-kbd-macro "-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 "Message with quote in Message-Id:" +add_message '[id]="\"quote\"@example"' '[subject]="Message with quote in Message-Id"' +test_emacs '(notmuch-search "subject:\"Message with quote\"") + (notmuch-test-wait) + (execute-kbd-macro "+search-add") + (notmuch-search-show-thread) + (notmuch-test-wait) + (execute-kbd-macro "+show-add")' +output=$(notmuch search 'id:"""quote""@example"' | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Message with quote in Message-Id (inbox search-add show-add)" + +test_begin_subtest "Sending a message via (fake) SMTP" +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: ,' \ + -e s',^\(Content-Type: text/plain\); charset=us-ascii$,\1,' < sent_message >OUTPUT +cat <EXPECTED +From: Notmuch Test Suite +To: user@example.com +Subject: Testing message sent via SMTP +Date: 01 Jan 2000 12:00:00 -0000 +User-Agent: Notmuch/XXX Emacs/XXX +Message-ID: +MIME-Version: 1.0 +Content-Type: text/plain + +This is a test that messages are sent via SMTP +EOF +test_expect_equal_file OUTPUT EXPECTED + +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 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 "(let ((notmuch-fcc-dirs nil)) + (notmuch-mua-mail) + (test-output))" +cat <EXPECTED +From: Notmuch Test Suite +To: +Subject: +--text follows this line-- +EOF +test_expect_equal_file OUTPUT EXPECTED + +# Make another FCC maildir specific for the next test +mkdir -p mail/sent-string/cur +mkdir -p mail/sent-string/new +mkdir -p mail/sent-string/tmp + +test_begin_subtest "notmuch-fcc-dirs set to a string" +test_emacs "(let ((notmuch-fcc-dirs \"sent-string\")) + (notmuch-mua-mail) + (test-output))" +cat <EXPECTED +From: Notmuch Test Suite +To: +Subject: +Fcc: ${MAIL_DIR}/sent-string +--text follows this line-- +EOF +test_expect_equal_file OUTPUT EXPECTED + +# Make more FCC maildirs specific for the next test +mkdir -p mail/sent-list-match/cur +mkdir -p mail/sent-list-match/new +mkdir -p mail/sent-list-match/tmp +mkdir -p mail/failure/cur +mkdir -p mail/failure/new +mkdir -p mail/failure/tmp + +test_begin_subtest "notmuch-fcc-dirs set to a list (with match)" +test_emacs "(let ((notmuch-fcc-dirs + '((\"notmuchmail.org\" . \"sent-list-match\") + (\".*\" . \"failure\")))) + (notmuch-mua-mail) + (test-output))" +cat <EXPECTED +From: Notmuch Test Suite +To: +Subject: +Fcc: ${MAIL_DIR}/sent-list-match +--text follows this line-- +EOF +test_expect_equal_file OUTPUT EXPECTED + +# Make another FCC maildir specific for the next test +mkdir -p mail/sent-list-catch-all/cur +mkdir -p mail/sent-list-catch-all/new +mkdir -p mail/sent-list-catch-all/tmp + +test_begin_subtest "notmuch-fcc-dirs set to a list (catch-all)" +test_emacs "(let ((notmuch-fcc-dirs + '((\"example.com\" . \"failure\") + (\".*\" . \"sent-list-catch-all\")))) + (notmuch-mua-mail) + (test-output))" +cat <EXPECTED +From: Notmuch Test Suite +To: +Subject: +Fcc: ${MAIL_DIR}/sent-list-catch-all +--text follows this line-- +EOF +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "notmuch-fcc-dirs set to a list (no match)" +test_emacs "(let ((notmuch-fcc-dirs + '((\"example.com\" . \"failure\") + (\"nomatchhere.net\" . \"failure\")))) + (notmuch-mua-mail) + (test-output))" +cat <EXPECTED +From: Notmuch Test Suite +To: +Subject: +--text follows this line-- +EOF +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "Reply within emacs" +test_emacs '(let ((message-hidden-headers ''())) + (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: /' OUTPUT +sed -i -e 's/^References: <.*>$/References: /' OUTPUT +sed -i -e 's,^User-Agent: Notmuch/.* Emacs/.*,User-Agent: Notmuch/XXX Emacs/XXX,' OUTPUT +cat <EXPECTED +From: Notmuch Test Suite +To: user@example.com +Subject: Re: Testing message sent via SMTP +In-Reply-To: +Fcc: ${MAIL_DIR}/sent +References: +User-Agent: Notmuch/XXX Emacs/XXX +--text follows this line-- +Notmuch Test Suite writes: + +> This is a test that messages are sent via SMTP +EOF +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "Reply from alternate address within emacs" +add_message '[from]="Sender "' \ + [to]=test_suite_other@notmuchmail.org + +test_emacs "(let ((message-hidden-headers '())) + (notmuch-search \"id:\\\"${gen_msg_id}\\\"\") + (notmuch-test-wait) + (notmuch-search-reply-to-thread) + (test-output))" +sed -i -e 's,^User-Agent: Notmuch/.* Emacs/.*,User-Agent: Notmuch/XXX Emacs/XXX,' OUTPUT +cat <EXPECTED +From: Notmuch Test Suite +To: Sender +Subject: Re: ${test_subtest_name} +In-Reply-To: <${gen_msg_id}> +Fcc: ${MAIL_DIR}/sent +References: <${gen_msg_id}> +User-Agent: Notmuch/XXX Emacs/XXX +--text follows this line-- +Sender writes: + +> This is just a test message (#${gen_msg_cnt}) +EOF +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "Reply from address in named group list within emacs" +add_message '[from]="Sender "' \ + '[to]=group:test_suite@notmuchmail.org,someone@example.com\;' \ + [cc]=test_suite_other@notmuchmail.org + +test_emacs "(let ((message-hidden-headers '())) + (notmuch-search \"id:\\\"${gen_msg_id}\\\"\") + (notmuch-test-wait) + (notmuch-search-reply-to-thread) + (test-output))" +sed -i -e 's,^User-Agent: Notmuch/.* Emacs/.*,User-Agent: Notmuch/XXX Emacs/XXX,' OUTPUT +cat <EXPECTED +From: Notmuch Test Suite +To: Sender , someone@example.com +Subject: Re: ${test_subtest_name} +In-Reply-To: <${gen_msg_id}> +Fcc: ${MAIL_DIR}/sent +References: <${gen_msg_id}> +User-Agent: Notmuch/XXX Emacs/XXX +--text follows this line-- +Sender writes: + +> This is just a test message (#${gen_msg_cnt}) +EOF +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "Reply within emacs to a multipart/mixed message" +test_emacs '(let ((message-hidden-headers ''())) + (notmuch-show "id:20091118002059.067214ed@hikari") + (notmuch-show-reply) + (test-output))' +sed -i -e 's,^User-Agent: Notmuch/.* Emacs/.*,User-Agent: Notmuch/XXX Emacs/XXX,' OUTPUT +cat <EXPECTED +From: Notmuch Test Suite +To: Adrian Perez de Castro , notmuch@notmuchmail.org +Subject: Re: [notmuch] Introducing myself +In-Reply-To: <20091118002059.067214ed@hikari> +Fcc: ${MAIL_DIR}/sent +References: <20091118002059.067214ed@hikari> +User-Agent: Notmuch/XXX Emacs/XXX +--text follows this line-- +Adrian Perez de Castro writes: + +> Hello to all, +> +> I have just heard about Not Much today in some random Linux-related news +> site (LWN?), my name is Adrian Perez and I work as systems administrator +> (although I can do some code as well :P). I have always thought that the +> ideas behind Sup were great, but after some time using it, I got tired of +> the oddities that it has. I also do not like doing things like having to +> install Ruby just for reading and sorting mails. Some time ago I thought +> about doing something like Not Much and in fact I played a bit with the +> Python+Xapian and the Python+Whoosh combinations, because I find relaxing +> to code things in Python when I am not working and also it is installed +> by default on most distribution. I got to have some mailboxes indexed and +> basic searching working a couple of months ago. Lately I have been very +> busy and had no time for coding, and them... boom! Not Much appears -- and +> it is almost exactly what I was trying to do, but faster. I have been +> playing a bit with Not Much today, and I think it has potential. +> +> Also, I would like to share one idea I had in mind, that you might find +> interesting: One thing I have found very annoying is having to re-tag my +> mail when the indexes get b0rked (it happened a couple of times to me while +> using Sup), so I was planning to mails as read/unread and adding the tags +> not just to the index, but to the mail text itself, e.g. by adding a +> "X-Tags" header field or by reusing the "Keywords" one. This way, the index +> could be totally recreated by re-reading the mail directories, and this +> would also allow to a tools like OfflineIMAP [1] to get the mails into a +> local maildir, tagging and indexing the mails with the e-mail reader and +> then syncing back the messages with the "X-Tags" header to the IMAP server. +> This would allow to use the mail reader from a different computer and still +> have everything tagged finely. +> +> Best regards, +> +> +> --- +> [1] http://software.complete.org/software/projects/show/offlineimap +> +> -- +> Adrian Perez de Castro +> Igalia - Free Software Engineering +> _______________________________________________ +> notmuch mailing list +> notmuch@notmuchmail.org +> http://notmuchmail.org/mailman/listinfo/notmuch +EOF +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "Reply within emacs to a multipart/alternative message" +test_emacs '(let ((message-hidden-headers ''())) + (notmuch-show "id:cf0c4d610911171136h1713aa59w9cf9aa31f052ad0a@mail.gmail.com") + (notmuch-show-reply) + (test-output))' +sed -i -e 's,^User-Agent: Notmuch/.* Emacs/.*,User-Agent: Notmuch/XXX Emacs/XXX,' OUTPUT +cat <EXPECTED +From: Notmuch Test Suite +To: Alex Botero-Lowry , notmuch@notmuchmail.org +Subject: Re: [notmuch] preliminary FreeBSD support +In-Reply-To: +Fcc: ${MAIL_DIR}/sent +References: +User-Agent: Notmuch/XXX Emacs/XXX +--text follows this line-- +Alex Botero-Lowry writes: + +> I saw the announcement this morning, and was very excited, as I had been +> hoping sup would be turned into a library, +> since I like the concept more than the UI (I'd rather an emacs interface). +> +> I did a preliminary compile which worked out fine, but +> sysconf(_SC_SC_GETPW_R_SIZE_MAX) returns -1 on +> FreeBSD, so notmuch_config_open segfaulted. +> +> Attached is a patch that supplies a default buffer size of 64 in cases where +> -1 is returned. +> +> http://www.opengroup.org/austin/docs/austin_328.txt - seems to indicate this +> is acceptable behavior, +> and http://mail-index.netbsd.org/pkgsrc-bugs/2006/06/07/msg016808.htmlspecifically +> uses 64 as the +> buffer size. +> _______________________________________________ +> notmuch mailing list +> notmuch@notmuchmail.org +> http://notmuchmail.org/mailman/listinfo/notmuch +EOF +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "Reply within emacs to an html-only message" +add_message '[content-type]="text/html"' \ + '[body]="Hi,
This is an HTML test message.

OK?"' +test_emacs "(let ((message-hidden-headers '()) (mm-text-html-renderer 'html2text)) + (notmuch-show \"id:${gen_msg_id}\") + (notmuch-show-reply) + (test-output))" +sed -i -e 's,^User-Agent: Notmuch/.* Emacs/.*,User-Agent: Notmuch/XXX Emacs/XXX,' OUTPUT +cat <EXPECTED +From: Notmuch Test Suite +To: +Subject: Re: Reply within emacs to an html-only message +In-Reply-To: <${gen_msg_id}> +Fcc: ${MAIL_DIR}/sent +References: <${gen_msg_id}> +User-Agent: Notmuch/XXX Emacs/XXX +--text follows this line-- +Notmuch Test Suite writes: + +> Hi,This is an HTML test message.OK? +EOF +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "Quote MML tags in reply" +message_id='test-emacs-mml-quoting@message.id' +add_message [id]="$message_id" \ + "[subject]='$test_subtest_name'" \ + '[body]="<#part disposition=inline>"' +test_emacs "(let ((message-hidden-headers '())) + (notmuch-show \"id:$message_id\") + (notmuch-show-reply) + (test-output))" +sed -i -e 's,^User-Agent: Notmuch/.* Emacs/.*,User-Agent: Notmuch/XXX Emacs/XXX,' OUTPUT +cat <EXPECTED +From: Notmuch Test Suite +To: +Subject: Re: Quote MML tags in reply +In-Reply-To: +Fcc: ${MAIL_DIR}/sent +References: +User-Agent: Notmuch/XXX Emacs/XXX +--text follows this line-- +Notmuch Test Suite writes: + +> <#!part disposition=inline> +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 +test_emacs '(let ((standard-input "\"attachment1.gz\"")) + (notmuch-show "id:cf0c4d610911171136h1713aa59w9cf9aa31f052ad0a@mail.gmail.com") + (notmuch-show-save-attachments))' +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 +test_emacs '(let ((standard-input "\"attachment2.gz\"")) + (notmuch-show "id:cf0c4d610911171136h1713aa59w9cf9aa31f052ad0a@mail.gmail.com") + (search-forward "0001-Deal-with") + (notmuch-show-save-part))' +test_expect_equal_file attachment2.gz "$EXPECTED/attachment" + +test_begin_subtest "Save 8bit attachment from within emacs using notmuch-show-save-attachments" + +add_message '[subject]="Attachment with 8bit chars"' \ + '[header]="MIME-Version: 1.0"' \ + '[content-type]="multipart/mixed; boundary=\"abcd\""' \ + '[body]="--abcd +Content-Type: text/plain + +Attachment follows: + +--abcd +Content-Type: application/octet-stream; name=\"sample\" +Content-Transfer-Encoding: 8bit +Content-Disposition: attachment; filename=\"sample\" + +“¡ Hey ! It compiles ¡ Ship it !” + +--abcd-- +"' +test_emacs '(notmuch-show "id:'"${gen_msg_id}"'") + (delete-file "OUTPUT") + (let ((standard-input "\"OUTPUT\"")) + (notmuch-show-save-attachments))' + +test_expect_equal "$(cat OUTPUT)" '“¡ Hey ! It compiles ¡ Ship it !”' + +test_begin_subtest "View raw message within emacs" +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" +maildir_storage_thread=$(notmuch search --output=threads id:20091117190054.GU3165@dottiness.seas.harvard.edu) +test_emacs "(notmuch-show \"$maildir_storage_thread\") + (search-forward \"Click/Enter to show.\") + (button-activate (button-at (point))) + (search-backward \"Click/Enter to hide.\") + (button-activate (button-at (point))) + (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" +add_message '[subject]="The problem with top-posting"' \ + [id]=top-post-target \ + '[body]="A: Because it messes up the order in which people normally read text. +Q: Why is top-posting such a bad thing? +A: Top-posting. +Q: What is the most annoying thing in e-mail?"' +add_message '[from]="Top Poster "' \ + [in-reply-to]=top-post-target \ + [references]=top-post-target \ + '[subject]="Re: The problem with top-posting"' \ + '[body]="Thanks for the advice! I will be sure to put it to good use. + +-Top Poster + +----- Original Message ----- +From: Notmuch Test Suite +To: Notmuch Test Suite +Sent: Fri, 05 Jan 2001 15:43:57 +0000 +Subject: The problem with top-posting + +Q: Why is top-posting such a bad thing? +A: Top-posting. +Q: What is the most annoying thing in e-mail?"' +test_emacs "(notmuch-show \"top-posting\") + (test-visible-output \"OUTPUT.raw\")" +echo "Notmuch Test Suite (2001-01-05) (inbox) +Subject: The problem with top-posting +To: Notmuch Test Suite +Date: GENERATED_DATE + +A: Because it messes up the order in which people normally read text. +Q: Why is top-posting such a bad thing? +A: Top-posting. +Q: What is the most annoying thing in e-mail? +Top Poster (2001-01-05) (inbox unread) +Subject: Re: The problem with top-posting +To: Notmuch Test Suite +Date: GENERATED_DATE + +Thanks for the advice! I will be sure to put it to good use. + +-Top Poster + +[ 9-line hidden original message. Click/Enter to show. ]" > EXPECTED +notmuch_date_sanitize < OUTPUT.raw > OUTPUT +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "Hiding message in notmuch-show view" +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" +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_begin_subtest "notmuch-show: show message headers" +test_emacs \ + '(let ((notmuch-message-headers '\''("Subject" "To" "Cc" "Date")) + (notmuch-message-headers-visible t)) + (notmuch-show "id:f35dbb950911171438k5df6eb56k77b6c0944e2e79ae@mail.gmail.com") + (test-visible-output))' +test_expect_equal_file OUTPUT $EXPECTED/notmuch-show-message-with-headers-visible + +test_begin_subtest "notmuch-show: hide message headers" +test_emacs \ + '(let ((notmuch-message-headers '\''("Subject" "To" "Cc" "Date")) + (notmuch-message-headers-visible nil)) + (notmuch-show "id:f35dbb950911171438k5df6eb56k77b6c0944e2e79ae@mail.gmail.com") + (test-visible-output))' +test_expect_equal_file OUTPUT $EXPECTED/notmuch-show-message-with-headers-hidden + +test_begin_subtest "notmuch-show: hide message headers (w/ notmuch-show-toggle-visibility-headers)" +test_emacs \ + '(let ((notmuch-message-headers '\''("Subject" "To" "Cc" "Date")) + (notmuch-message-headers-visible t)) + (notmuch-show "id:f35dbb950911171438k5df6eb56k77b6c0944e2e79ae@mail.gmail.com") + (notmuch-show-toggle-visibility-headers) + (test-visible-output))' +test_expect_equal_file OUTPUT $EXPECTED/notmuch-show-message-with-headers-hidden + +test_begin_subtest "notmuch-show: collapse all messages in thread" +test_emacs '(notmuch-show "id:f35dbb950911171435ieecd458o853c873e35f4be95@mail.gmail.com") + (let ((current-prefix-arg t)) + (notmuch-show-open-or-close-all) + (test-visible-output))' +test_expect_equal_file OUTPUT $EXPECTED/notmuch-show-thread-with-all-messages-collapsed + +test_begin_subtest "notmuch-show: uncollapse all messages in thread" +test_emacs '(notmuch-show "id:f35dbb950911171435ieecd458o853c873e35f4be95@mail.gmail.com") + (notmuch-show-open-or-close-all) + (test-visible-output)' +test_expect_equal_file OUTPUT $EXPECTED/notmuch-show-thread-with-all-messages-uncollapsed + +test_begin_subtest "Stashing in notmuch-show" +add_message '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' \ + '[from]="Some One "' \ + '[to]="Some One Else "' \ + '[cc]="Notmuch "' \ + '[subject]="Stash my stashables"' \ + '[id]="bought"' \ + '[body]="Unable to stash body. Where did you get it in the first place?!?"' +notmuch tag +stashtest id:${gen_msg_id} +test_emacs '(notmuch-show "id:\"bought\"") + (notmuch-show-stash-date) + (notmuch-show-stash-from) + (notmuch-show-stash-to) + (notmuch-show-stash-cc) + (notmuch-show-stash-subject) + (notmuch-show-stash-message-id) + (notmuch-show-stash-message-id-stripped) + (notmuch-show-stash-tags) + (notmuch-show-stash-filename) + (notmuch-show-stash-mlarchive-link "Gmane") + (notmuch-show-stash-mlarchive-link "MARC") + (notmuch-show-stash-mlarchive-link "Mail Archive, The") + (switch-to-buffer + (generate-new-buffer "*test-stashing*")) + (dotimes (i 12) + (yank) + (insert "\n") + (rotate-yank-pointer 1)) + (reverse-region (point-min) (point-max)) + (test-output)' +cat <EXPECTED +Sat, 01 Jan 2000 12:00:00 +0000 +Some One +Some One Else +Notmuch +Stash my stashables +id:bought +bought +inbox,stashtest +${gen_msg_filename} +http://mid.gmane.org/bought +http://marc.info/?i=bought +http://mid.mail-archive.com/bought +EOF +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "Stashing in notmuch-search" +test_emacs '(notmuch-search "id:\"bought\"") + (notmuch-test-wait) + (notmuch-search-stash-thread-id) + (switch-to-buffer + (generate-new-buffer "*test-stashing*")) + (yank) + (test-output)' +sed -i -e 's/^thread:.*$/thread:XXX/' OUTPUT +test_expect_equal "$(cat OUTPUT)" "thread:XXX" + +test_begin_subtest 'notmuch-show-advance-and-archive with invisible signature' +message1='id:20091118010116.GC25380@dottiness.seas.harvard.edu' +message2='id:1258491078-29658-1-git-send-email-dottedmag@dottedmag.net' +test_emacs "(notmuch-show \"$message2\") + (test-output \"EXPECTED\")" +test_emacs "(notmuch-search \"$message1 or $message2\") + (notmuch-test-wait) + (notmuch-search-show-thread) + (goto-char (point-max)) + (redisplay) + (notmuch-show-advance-and-archive) + (test-output)" +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "Refresh show buffer" +test_emacs '(notmuch-show "id:f35dbb950911171438k5df6eb56k77b6c0944e2e79ae@mail.gmail.com") + (test-visible-output "EXPECTED") + (notmuch-show-refresh-view) + (test-visible-output)' +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "Refresh modified show buffer" +test_emacs '(notmuch-show "id:f35dbb950911171438k5df6eb56k77b6c0944e2e79ae@mail.gmail.com") + (notmuch-show-toggle-message) + (notmuch-show-next-message) + (notmuch-show-toggle-message) + (test-visible-output "EXPECTED") + (notmuch-show-refresh-view) + (test-visible-output)' +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "Do not call notmuch for non-inlinable application/mpeg parts" +id='message-with-application/mpeg-attachment@notmuchmail.org' +emacs_fcc_message \ + 'Message with application/mpeg attachment' \ + '' \ + "(message-goto-eoh) + (insert \"Message-ID: <$id>\n\") + (message-goto-body) + (mml-insert-part \"application/mpeg\") + (insert \"a fake mp3 file\")" +notmuch_counter_reset +test_emacs "(let ((notmuch-command \"$notmuch_counter_command\")) + (notmuch-show \"id:$id\"))" +test_expect_equal $(notmuch_counter_value) 1 + +test_begin_subtest "Do not call notmuch for non-inlinable audio/mpeg parts" +id='message-with-audio/mpeg-attachment@notmuchmail.org' +emacs_fcc_message \ + 'Message with audio/mpeg attachment' \ + '' \ + "(message-goto-eoh) + (insert \"Message-ID: <$id>\n\") + (message-goto-body) + (mml-insert-part \"audio/mpeg\") + (insert \"a fake mp3 file\")" +notmuch_counter_reset +test_emacs "(let ((notmuch-command \"$notmuch_counter_command\")) + (notmuch-show \"id:$id\"))" +test_expect_equal $(notmuch_counter_value) 1 + +test_begin_subtest "notmuch-hello-mode hook is called" +counter=$(test_emacs \ + '(let ((notmuch-hello-mode-hook-counter 0)) + (kill-buffer "*notmuch-hello*") + (notmuch-hello) + notmuch-hello-mode-hook-counter)' +) +test_expect_equal "$counter" 1 + +test_begin_subtest "notmuch-hello-mode hook is not called on updates" +counter=$(test_emacs \ + '(let ((notmuch-hello-mode-hook-counter 0)) + (kill-buffer "*notmuch-hello*") + (notmuch-hello) + (notmuch-hello-update) + notmuch-hello-mode-hook-counter)' +) +test_expect_equal "$counter" 1 + +test_begin_subtest "notmuch-hello-refresh hook is called" +counter=$(test_emacs \ + '(let ((notmuch-hello-refresh-hook-counter 0)) + (kill-buffer "*notmuch-hello*") + (notmuch-hello) + notmuch-hello-refresh-hook-counter)' +) +test_expect_equal "$counter" 1 + +test_begin_subtest "notmuch-hello-refresh hook is called on updates" +counter=$(test_emacs \ + '(let ((notmuch-hello-refresh-hook-counter 0)) + (kill-buffer "*notmuch-hello*") + (notmuch-hello) + (notmuch-hello-update) + notmuch-hello-refresh-hook-counter)' +) +test_expect_equal "$counter" 2 + + +add_message '[subject]="HTML mail with images"' \ + '[content-type]="multipart/related; boundary=abcd"' \ + '[body]="--abcd +Content-Type: text/html + + smiley + +--abcd +Content-Type: image/gif +Content-Transfer-Encoding: base64 +Content-ID: <330@goomoji.gmail> + +R0lGODlhDAAMAKIFAF5LAP/zxAAAANyuAP/gaP///wAAAAAAACH5BAEAAAUALAAAAAAMAAwAAAMl +WLPcGjDKFYi9lxKBOaGcF35DhWHamZUW0K4mAbiwWtuf0uxFAgA7 +--abcd--"' +test_emacs "(let ((mm-text-html-renderer + (if (assq 'shr mm-text-html-renderer-alist) + 'shr 'html2text))) + (notmuch-show \"id:${gen_msg_id}\")) + (test-output)" > /dev/null +# Different Emacs versions and renderers give very different results, +# so just check that something reasonable showed up. We first cat the +# output so the test framework will print it if the test fails. +test_expect_success "Rendering HTML mail with images" \ + 'cat OUTPUT && grep -q smiley OUTPUT' + + +test_begin_subtest "Search handles subprocess error exit codes" +cat > notmuch_fail < notmuch_fail <&2 +echo This is another warning >&2 +exit 0 +EOF +chmod a+x notmuch_fail +test_emacs "(let ((notmuch-command \"$PWD/notmuch_fail\")) + (with-current-buffer \"*Messages*\" (erase-buffer)) + (with-current-buffer (get-buffer-create \"*Notmuch errors*\") + (erase-buffer)) + (notmuch-search \"tag:inbox\") + (notmuch-test-wait) + (with-current-buffer \"*Messages*\" + (test-output \"MESSAGES\")) + (with-current-buffer \"*Notmuch errors*\" + (test-output \"ERROR\")) + (test-output))" +sed -i -e 's/^\[.*\]$/[XXX]/' ERROR +test_expect_equal "$(cat OUTPUT; echo ---; cat MESSAGES; echo ---; cat ERROR)" "\ +End of search results. +--- +This is a warning (see *Notmuch errors* for more details) +--- +[XXX] +This is a warning +This is another warning" + +test_begin_subtest "Search thread tag operations are race-free" +add_message '[subject]="Search race test"' +gen_msg_id_1=$gen_msg_id +generate_message '[in-reply-to]="<'$gen_msg_id_1'>"' \ + '[references]="<'$gen_msg_id_1'>"' \ + '[subject]="Search race test two"' +test_emacs '(notmuch-search "subject:\"search race test\"") + (notmuch-test-wait) + (notmuch-poll) + (execute-kbd-macro "+search-thread-race-tag")' +output=$(notmuch search --output=messages 'tag:search-thread-race-tag') +test_expect_equal "$output" "id:$gen_msg_id_1" + +test_begin_subtest "Search global tag operations are race-free" +generate_message '[in-reply-to]="<'$gen_msg_id_1'>"' \ + '[references]="<'$gen_msg_id_1'>"' \ + '[subject]="Re: Search race test"' +test_emacs '(notmuch-search "subject:\"search race test\" -subject:two") + (notmuch-test-wait) + (notmuch-poll) + (execute-kbd-macro "*+search-global-race-tag")' +output=$(notmuch search --output=messages 'tag:search-global-race-tag') +test_expect_equal "$output" "id:$gen_msg_id_1" + +test_done diff --git a/test/T320-emacs-large-search-buffer.sh b/test/T320-emacs-large-search-buffer.sh new file mode 100755 index 00000000..8b1251fe --- /dev/null +++ b/test/T320-emacs-large-search-buffer.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash +test_description="Emacs with large search results buffer" +. ./test-lib.sh + +x=xxxxxxxxxx # 10 +x=$x$x$x$x$x$x$x$x$x$x # 100 +x=$x$x$x$x$x$x$x$x$x # 900 + +# We generate a long subject here (over 900 bytes) so that the emacs +# search results get large quickly. With 30 such messages we should +# cross several 4kB page boundaries and see the bug. +n=30 +for i in $(seq 1 $n); do + # Roughly 100B2 KiB per message. That is, we need two messages in order to + # exceed the typical size of the pipe buffer (4 KiB on commodity systems). + generate_message '[subject]="$x $i of $n"' +done + +notmuch new > /dev/null + +test_begin_subtest "Ensure that emacs doesn't drop results" +notmuch search '*' > EXPECTED +sed -i -e 's/^thread:[0-9a-f]* //' -e 's/;//' -e 's/xx*/[BLOB]/' EXPECTED +echo 'End of search results.' >> 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 EXPECTED + +test_done diff --git a/test/T330-emacs-subject-to-filename.sh b/test/T330-emacs-subject-to-filename.sh new file mode 100755 index 00000000..230c324d --- /dev/null +++ b/test/T330-emacs-subject-to-filename.sh @@ -0,0 +1,138 @@ +#!/usr/bin/env bash + +test_description="emacs: mail subject to filename" +. ./test-lib.sh + +# emacs server can't be started in a child process with $(test_emacs ...) +test_emacs '(ignore)' > /dev/null + +# test notmuch-wash-subject-to-patch-sequence-number (subject) +test_begin_subtest "no patch sequence number" +output=$(test_emacs '(format "%S" (notmuch-wash-subject-to-patch-sequence-number + "[PATCH] A normal patch subject without numbers"))' +) +test_expect_equal "$output" '"nil"' + +test_begin_subtest "patch sequence number #1" +output=$(test_emacs '(notmuch-wash-subject-to-patch-sequence-number + "[PATCH 2/3] A most regular patch subject")' +) +test_expect_equal "$output" 2 + +test_begin_subtest "patch sequence number #2" +output=$(test_emacs '(notmuch-wash-subject-to-patch-sequence-number + " [dummy list prefix] [RFC PATCH v2 13/42] Special prefixes")' +) +test_expect_equal "$output" 13 + +test_begin_subtest "patch sequence number #3" +output=$(test_emacs '(notmuch-wash-subject-to-patch-sequence-number + "[PATCH 2/3] [PATCH 032/037] use the last prefix")' +) +test_expect_equal "$output" 32 + +test_begin_subtest "patch sequence number #4" +output=$(test_emacs '(notmuch-wash-subject-to-patch-sequence-number + "[dummy list prefix] [PATCH 2/3] PATCH 3/3] do not use a broken prefix")' +) +test_expect_equal "$output" 2 + +test_begin_subtest "patch sequence number #5" +output=$(test_emacs '(notmuch-wash-subject-to-patch-sequence-number + "[RFC][PATCH 3/5][PATCH 4/5][PATCH 5/5] A made up test")' +) +test_expect_equal "$output" 5 + +test_begin_subtest "patch sequence number #6" +output=$(test_emacs '(notmuch-wash-subject-to-patch-sequence-number + "[PATCH 2/3] this -> [PATCH 3/3] is not a prefix anymore [nor this 4/4]")' +) +test_expect_equal "$output" 2 + +test_begin_subtest "patch sequence number #7" +output=$(test_emacs '(notmuch-wash-subject-to-patch-sequence-number + "[liberally accept crapola right before123/456and after] the numbers")' +) +test_expect_equal "$output" 123 + +# test notmuch-wash-subject-to-filename (subject &optional maxlen) +test_begin_subtest "filename #1" +output=$(test_emacs '(notmuch-wash-subject-to-filename + "just a subject line")' +) +test_expect_equal "$output" '"just-a-subject-line"' + +test_begin_subtest "filename #2" +output=$(test_emacs '(notmuch-wash-subject-to-filename + " [any] [prefixes are ] [removed!] from the subject")' +) +test_expect_equal "$output" '"from-the-subject"' + +test_begin_subtest "filename #3" +output=$(test_emacs '(notmuch-wash-subject-to-filename + " leading and trailing space ")' +) +test_expect_equal "$output" '"leading-and-trailing-space"' + +test_begin_subtest "filename #4" +output=$(test_emacs '(notmuch-wash-subject-to-filename + "!# leading ()// &%, and in between_and_trailing garbage ()(&%%")' +) +test_expect_equal "$output" '"-leading-and-in-between_and_trailing-garbage"' + +test_begin_subtest "filename #5" +output=$(test_emacs '(notmuch-wash-subject-to-filename + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.-_01234567890")' +) +test_expect_equal "$output" '"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.-_01234567890"' + +test_begin_subtest "filename #6" +output=$(test_emacs '(notmuch-wash-subject-to-filename + "sequences of ... are squashed and trailing are removed ...")' +) +test_expect_equal "$output" '"sequences-of-.-are-squashed-and-trailing-are-removed"' + +test_begin_subtest "filename #7" +output=$(test_emacs '(notmuch-wash-subject-to-filename + "max length test" 1)' +) +test_expect_equal "$output" '"m"' + +test_begin_subtest "filename #8" +output=$(test_emacs '(notmuch-wash-subject-to-filename + "max length test /&(/%&/%%&¤%¤" 20)' +) +test_expect_equal "$output" '"max-length-test"' + +test_begin_subtest "filename #9" +output=$(test_emacs '(notmuch-wash-subject-to-filename + "[a prefix] [is only separated] by [spaces], so \"by\" is not okay!")' +) +test_expect_equal "$output" '"by-spaces-so-by-is-not-okay"' + +# test notmuch-wash-subject-to-patch-filename (subject) +test_begin_subtest "patch filename #1" +output=$(test_emacs '(notmuch-wash-subject-to-patch-filename + "[RFC][PATCH 099/100] rewrite notmuch")' +) +test_expect_equal "$output" '"0099-rewrite-notmuch.patch"' + +test_begin_subtest "patch filename #2" +output=$(test_emacs '(notmuch-wash-subject-to-patch-filename + "[RFC PATCH v1] has no patch number, default to 1")' +) +test_expect_equal "$output" '"0001-has-no-patch-number-default-to-1.patch"' + +test_begin_subtest "patch filename #3" +output=$(test_emacs '(notmuch-wash-subject-to-patch-filename + "[PATCH 4/5] the maximum length of a patch filename is 52 + patch sequence number + .patch extension")' +) +test_expect_equal "$output" '"0004-the-maximum-length-of-a-patch-filename-is-52-patch-s.patch"' + +test_begin_subtest "patch filename #4" +output=$(test_emacs '(notmuch-wash-subject-to-patch-filename + "[PATCH 4/5] the maximum length of a patch filename is 52 + patchh ! sequence number + .patch extension, *before* trimming trailing - and .")' +) +test_expect_equal "$output" '"0004-the-maximum-length-of-a-patch-filename-is-52-patchh.patch"' + +test_done diff --git a/test/T340-maildir-sync.sh b/test/T340-maildir-sync.sh new file mode 100755 index 00000000..3186e70f --- /dev/null +++ b/test/T340-maildir-sync.sh @@ -0,0 +1,189 @@ +#!/usr/bin/env bash + +test_description="maildir synchronization" + +. ./test-lib.sh + +# Create the expected maildir structure +mkdir $MAIL_DIR/cur +mkdir $MAIL_DIR/new +mkdir $MAIL_DIR/tmp + +test_begin_subtest "Adding 'S' flag to existing filename removes 'unread' tag" +add_message [subject]='"Adding S flag"' [filename]='adding-s-flag:2,' [dir]=cur +output=$(notmuch search subject:"Adding S flag" | notmuch_search_sanitize) +output+=" +" +mv "${gen_msg_filename}" "${gen_msg_filename}S" +output+=$(NOTMUCH_NEW) +output+=" +" +output+=$(notmuch search subject:"Adding S flag" | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Adding S flag (inbox unread) +No new mail. Detected 1 file rename. +thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Adding S flag (inbox)" + +test_begin_subtest "Adding message with 'S' flag prevents 'unread' tag" +add_message [subject]='"Adding message with S"' [filename]='adding-with-s-flag:2,S' [dir]=cur +output=$(notmuch search subject:"Adding message with S" | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Adding message with S (inbox)" + +test_begin_subtest "Adding 'replied' tag adds 'R' flag to filename" +add_message [subject]='"Adding replied tag"' [filename]='adding-replied-tag:2,S' [dir]=cur +notmuch tag +replied subject:"Adding replied tag" +output=$(cd ${MAIL_DIR}/cur; ls -1 adding-replied*) +test_expect_equal "$output" "adding-replied-tag:2,RS" + +test_begin_subtest "notmuch show works with renamed file (without notmuch new)" +output=$(notmuch show --format=json id:${gen_msg_id} | notmuch_json_show_sanitize) +test_expect_equal_json "$output" '[[[{"id": "XXXXX", +"match": true, +"excluded": false, +"filename": "YYYYY", +"timestamp": 42, +"date_relative": "2001-01-05", +"tags": ["inbox","replied"], +"headers": {"Subject": "Adding replied tag", +"From": "Notmuch Test Suite ", +"To": "Notmuch Test Suite ", +"Date": "GENERATED_DATE"}, +"body": [{"id": 1, +"content-type": "text/plain", +"content": "This is just a test message (#3)\n"}]}, +[]]]]' + +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" +output=$(NOTMUCH_NEW) +test_expect_equal "$output" "No new mail." + +test_begin_subtest "When read, message moved from new to cur" +add_message [subject]='"Message to move to cur"' [date]='"Sat, 01 Jan 2000 12:00:00 -0000"' [filename]='message-to-move-to-cur' [dir]=new +notmuch tag -unread subject:"Message to move to cur" +output=$(cd "$MAIL_DIR/cur"; ls message-to-move*) +test_expect_equal "$output" "message-to-move-to-cur:2,S" + +test_begin_subtest "No rename should be detected by notmuch new" +output=$(NOTMUCH_NEW) +test_expect_equal "$output" "No new mail." +# (*) If notmuch new was not run we've got "Processed 1 file in almost +# no time" here. The reason is that removing unread tag in a previous +# 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 +# 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 +# creating all necessary database state for those directories. + +test_begin_subtest "Adding non-maildir tags does not move message from new to cur" +add_message [subject]='"Message to stay in new"' \ + [date]='"Sat, 01 Jan 2000 12:00:00 -0000"' \ + [filename]='message-to-stay-in-new' [dir]=new +notmuch tag +donotmove subject:"Message to stay in new" +output=$(cd "$MAIL_DIR"; ls */message-to-stay-in-new*) +test_expect_equal "$output" "new/message-to-stay-in-new" + +test_begin_subtest "Message in cur lacking maildir info gets one on any tag change" +add_message [filename]='message-to-get-maildir-info' [dir]=cur +notmuch tag +anytag id:$gen_msg_id +output=$(cd "$MAIL_DIR"; ls */message-to-get-maildir-info*) +test_expect_equal "$output" "cur/message-to-get-maildir-info:2," + +test_begin_subtest "Message in new with maildir info is moved to cur on any tag change" +add_message [filename]='message-with-info-to-be-moved-to-cur:2,' [dir]=new +notmuch tag +anytag id:$gen_msg_id +output=$(cd "$MAIL_DIR"; ls */message-with-info-to-be-moved-to-cur*) +test_expect_equal "$output" "cur/message-with-info-to-be-moved-to-cur:2," + +test_begin_subtest "Removing 'S' flag from existing filename adds 'unread' tag" +add_message [subject]='"Removing S flag"' [filename]='removing-s-flag:2,S' [dir]=cur +output=$(notmuch search subject:"Removing S flag" | notmuch_search_sanitize) +output+=" +" +mv "${gen_msg_filename}" "${gen_msg_filename%S}" +output+=$(NOTMUCH_NEW) +output+=" +" +output+=$(notmuch search subject:"Removing S flag" | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Removing S flag (inbox) +No new mail. Detected 1 file rename. +thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Removing S flag (inbox unread)" + +test_begin_subtest "Removing info from filename leaves tags unchanged" +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" +output=$(NOTMUCH_NEW) +output+=" +" +output+=$(notmuch search subject:"Message to lose maildir info" | notmuch_search_sanitize) +test_expect_equal "$output" "No new mail. Detected 1 file rename. +thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Message to lose maildir info (inbox)" + +add_message [subject]='"Non-maildir message"' [dir]=notmaildir [filename]='non-maildir-message' +expected=$(notmuch search --output=files subject:"Non-maildir message") +test_expect_success "Can remove unread tag from message in non-maildir directory" 'notmuch tag -unread subject:"Non-maildir message"' + +test_begin_subtest "Message in non-maildir directory does not get renamed" +output=$(notmuch search --output=files subject:"Non-maildir message") +test_expect_equal "$output" "$expected" + +test_begin_subtest "notmuch dump/restore re-synchronizes maildir tags with flags" +# Capture current filename state +expected=$(ls $MAIL_DIR/cur) +# Add/remove some flags from filenames +mv $MAIL_DIR/cur/adding-replied-tag:2,RS $MAIL_DIR/cur/adding-replied-tag:2,S +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 +notmuch dump --output=dump.txt +NOTMUCH_NEW >/dev/null +notmuch restore --input=dump.txt +output=$(ls $MAIL_DIR/cur) +test_expect_equal "$output" "$expected" + +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" +NOTMUCH_NEW > output +notmuch search subject:"Duplicated message" | notmuch_search_sanitize >> output +test_expect_equal "$(< output)" "No new mail. +thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Duplicated message (inbox replied)" + +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," +NOTMUCH_NEW > output +notmuch search subject:"Duplicated message" | notmuch_search_sanitize >> output +test_expect_equal "$(< output)" "No new mail. +thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Duplicated message (inbox replied)" + +test_begin_subtest "Tag changes modify flags of multiple files" +notmuch tag -replied subject:"Duplicated message" +(cd $MAIL_DIR/cur/; ls duplicated*) > actual +test_expect_equal "$(< actual)" "duplicated-message-another-copy:2,S +duplicated-message-copy:2,S +duplicated-message:2,S" + +test_begin_subtest "Synchronizing tag changes preserves unsupported maildir flags" +add_message [subject]='"Unsupported maildir flags"' [dir]=cur [filename]='unsupported-maildir-flags:2,FSZxyz' +notmuch tag +unread +draft -flagged subject:"Unsupported maildir flags" +test_expect_equal "$(cd $MAIL_DIR/cur/; ls unsupported*)" "unsupported-maildir-flags:2,DZxyz" + +test_begin_subtest "A file with non-compliant maildir info will not be renamed" +add_message [subject]='"Non-compliant maildir info"' [dir]=cur [filename]='non-compliant-maildir-info:2,These-are-not-flags-in-ASCII-order-donottouch' +notmuch tag +unread +draft -flagged subject:"Non-compliant maildir info" +test_expect_equal "$(cd $MAIL_DIR/cur/; ls non-compliant*)" "non-compliant-maildir-info:2,These-are-not-flags-in-ASCII-order-donottouch" + +test_begin_subtest "Files in new/ get default synchronized tags" +OLDCONFIG=$(notmuch config get new.tags) +notmuch config set new.tags test +add_message [subject]='"File in new/"' [dir]=new [filename]='file-in-new' +notmuch config set new.tags $OLDCONFIG +notmuch search 'subject:"File in new"' | notmuch_search_sanitize > output +test_expect_equal "$(< output)" \ +"thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; File in new/ (test unread)" + +test_done diff --git a/test/T350-crypto.sh b/test/T350-crypto.sh new file mode 100755 index 00000000..477b397e --- /dev/null +++ b/test/T350-crypto.sh @@ -0,0 +1,360 @@ +#!/usr/bin/env bash + +# TODO: +# - decryption/verification with signer key not available +# - verification of signatures from expired/revoked keys + +test_description='PGP/MIME signature verification and decryption' +. ./test-lib.sh + +add_gnupg_home () +{ + local output + [ -d ${GNUPGHOME} ] && return + mkdir -m 0700 "$GNUPGHOME" + 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 + elif (gpg --debug-quick-random --version >/dev/null 2>&1) ; then + echo debug-quick-random >> "$GNUPGHOME"/gpg.conf + fi + echo no-emit-version >> "$GNUPGHOME"/gpg.conf +} + +################################################## + +add_gnupg_home +# get key fingerprint +FINGERPRINT=$(gpg --no-tty --list-secret-keys --with-colons --fingerprint | grep '^fpr:' | cut -d: -f10) + +test_expect_success 'emacs delivery of signed message' \ +'emacs_fcc_message \ + "test signed message 001" \ + "This is a test signed message." \ + "(mml-secure-message-sign)"' + +test_begin_subtest "signature verification" +output=$(notmuch show --format=json --verify subject:"test signed message 001" \ + | notmuch_json_show_sanitize \ + | sed -e 's|"created": [1234567890]*|"created": 946728000|') +expected='[[[{"id": "XXXXX", + "match": true, + "excluded": false, + "filename": "YYYYY", + "timestamp": 946728000, + "date_relative": "2000-01-01", + "tags": ["inbox","signed"], + "headers": {"Subject": "test signed message 001", + "From": "Notmuch Test Suite ", + "To": "test_suite@notmuchmail.org", + "Date": "Sat, 01 Jan 2000 12:00:00 +0000"}, + "body": [{"id": 1, + "sigstatus": [{"status": "good", + "fingerprint": "'$FINGERPRINT'", + "created": 946728000}], + "content-type": "multipart/signed", + "content": [{"id": 2, + "content-type": "text/plain", + "content": "This is a test signed message.\n"}, + {"id": 3, + "content-type": "application/pgp-signature", + "content-length": 280}]}]}, + []]]]' +test_expect_equal_json \ + "$output" \ + "$expected" + +test_begin_subtest "signature verification with full owner trust" +# give the key full owner trust +echo "${FINGERPRINT}:6:" | gpg --no-tty --import-ownertrust >>"$GNUPGHOME"/trust.log 2>&1 +gpg --no-tty --check-trustdb >>"$GNUPGHOME"/trust.log 2>&1 +output=$(notmuch show --format=json --verify subject:"test signed message 001" \ + | notmuch_json_show_sanitize \ + | sed -e 's|"created": [1234567890]*|"created": 946728000|') +expected='[[[{"id": "XXXXX", + "match": true, + "excluded": false, + "filename": "YYYYY", + "timestamp": 946728000, + "date_relative": "2000-01-01", + "tags": ["inbox","signed"], + "headers": {"Subject": "test signed message 001", + "From": "Notmuch Test Suite ", + "To": "test_suite@notmuchmail.org", + "Date": "Sat, 01 Jan 2000 12:00:00 +0000"}, + "body": [{"id": 1, + "sigstatus": [{"status": "good", + "fingerprint": "'$FINGERPRINT'", + "created": 946728000, + "userid": " Notmuch Test Suite (INSECURE!)"}], + "content-type": "multipart/signed", + "content": [{"id": 2, + "content-type": "text/plain", + "content": "This is a test signed message.\n"}, + {"id": 3, + "content-type": "application/pgp-signature", + "content-length": 280}]}]}, + []]]]' +test_expect_equal_json \ + "$output" \ + "$expected" + +test_begin_subtest "signature verification with signer key unavailable" +# move the gnupghome temporarily out of the way +mv "${GNUPGHOME}"{,.bak} +output=$(notmuch show --format=json --verify subject:"test signed message 001" \ + | notmuch_json_show_sanitize \ + | sed -e 's|"created": [1234567890]*|"created": 946728000|') +expected='[[[{"id": "XXXXX", + "match": true, + "excluded": false, + "filename": "YYYYY", + "timestamp": 946728000, + "date_relative": "2000-01-01", + "tags": ["inbox","signed"], + "headers": {"Subject": "test signed message 001", + "From": "Notmuch Test Suite ", + "To": "test_suite@notmuchmail.org", + "Date": "Sat, 01 Jan 2000 12:00:00 +0000"}, + "body": [{"id": 1, + "sigstatus": [{"status": "error", + "keyid": "'$(echo $FINGERPRINT | cut -c 25-)'", + "errors": 2}], + "content-type": "multipart/signed", + "content": [{"id": 2, + "content-type": "text/plain", + "content": "This is a test signed message.\n"}, + {"id": 3, + "content-type": "application/pgp-signature", + "content-length": 280}]}]}, + []]]]' +test_expect_equal_json \ + "$output" \ + "$expected" +mv "${GNUPGHOME}"{.bak,} + +# create a test encrypted message with attachment +cat <TESTATTACHMENT +This is a test file. +EOF +test_expect_success 'emacs delivery of encrypted message with attachment' \ +'emacs_fcc_message \ + "test encrypted message 001" \ + "This is a test encrypted message.\n" \ + "(mml-attach-file \"TESTATTACHMENT\") (mml-secure-message-encrypt)"' + +test_begin_subtest "decryption, --format=text" +output=$(notmuch show --format=text --decrypt subject:"test encrypted message 001" \ + | notmuch_show_sanitize_all \ + | sed -e 's|"created": [1234567890]*|"created": 946728000|') +expected=' message{ id:XXXXX depth:0 match:1 excluded:0 filename:XXXXX + header{ +Notmuch Test Suite (2000-01-01) (encrypted inbox) +Subject: test encrypted message 001 +From: Notmuch Test Suite +To: test_suite@notmuchmail.org +Date: Sat, 01 Jan 2000 12:00:00 +0000 + header} + body{ + part{ ID: 1, Content-type: multipart/encrypted + part{ ID: 2, Content-type: application/pgp-encrypted +Non-text part: application/pgp-encrypted + part} + part{ ID: 3, Content-type: multipart/mixed + part{ ID: 4, Content-type: text/plain +This is a test encrypted message. + part} + attachment{ ID: 5, Filename: TESTATTACHMENT, Content-type: application/octet-stream +Non-text part: application/octet-stream + attachment} + part} + part} + body} + message}' +test_expect_equal \ + "$output" \ + "$expected" + +test_begin_subtest "decryption, --format=json" +output=$(notmuch show --format=json --decrypt subject:"test encrypted message 001" \ + | notmuch_json_show_sanitize \ + | sed -e 's|"created": [1234567890]*|"created": 946728000|') +expected='[[[{"id": "XXXXX", + "match": true, + "excluded": false, + "filename": "YYYYY", + "timestamp": 946728000, + "date_relative": "2000-01-01", + "tags": ["encrypted","inbox"], + "headers": {"Subject": "test encrypted message 001", + "From": "Notmuch Test Suite ", + "To": "test_suite@notmuchmail.org", + "Date": "Sat, 01 Jan 2000 12:00:00 +0000"}, + "body": [{"id": 1, + "encstatus": [{"status": "good"}], + "sigstatus": [], + "content-type": "multipart/encrypted", + "content": [{"id": 2, + "content-type": "application/pgp-encrypted", + "content-length": 11}, + {"id": 3, + "content-type": "multipart/mixed", + "content": [{"id": 4, + "content-type": "text/plain", + "content": "This is a test encrypted message.\n"}, + {"id": 5, + "content-type": "application/octet-stream", + "content-length": 28, + "content-transfer-encoding": "base64", + "filename": "TESTATTACHMENT"}]}]}]}, + []]]]' +test_expect_equal_json \ + "$output" \ + "$expected" + +test_begin_subtest "decryption, --format=json, --part=4" +output=$(notmuch show --format=json --part=4 --decrypt subject:"test encrypted message 001" \ + | notmuch_json_show_sanitize \ + | sed -e 's|"created": [1234567890]*|"created": 946728000|') +expected='{"id": 4, + "content-type": "text/plain", + "content": "This is a test encrypted message.\n"}' +test_expect_equal_json \ + "$output" \ + "$expected" + +test_begin_subtest "decrypt attachment (--part=5 --format=raw)" +notmuch show \ + --format=raw \ + --part=5 \ + --decrypt \ + subject:"test encrypted message 001" >OUTPUT +test_expect_equal_file OUTPUT TESTATTACHMENT + +test_begin_subtest "decryption failure with missing key" +mv "${GNUPGHOME}"{,.bak} +# The length of the encrypted attachment varies so must be normalized. +output=$(notmuch show --format=json --decrypt subject:"test encrypted message 001" \ + | notmuch_json_show_sanitize \ + | sed -e 's|"created": [1234567890]*|"created": 946728000|' \ + | sed -e 's|"content-length": 6[1234567890]*|"content-length": 652|') +expected='[[[{"id": "XXXXX", + "match": true, + "excluded": false, + "filename": "YYYYY", + "timestamp": 946728000, + "date_relative": "2000-01-01", + "tags": ["encrypted","inbox"], + "headers": {"Subject": "test encrypted message 001", + "From": "Notmuch Test Suite ", + "To": "test_suite@notmuchmail.org", + "Date": "Sat, 01 Jan 2000 12:00:00 +0000"}, + "body": [{"id": 1, + "encstatus": [{"status": "bad"}], + "content-type": "multipart/encrypted", + "content": [{"id": 2, + "content-type": "application/pgp-encrypted", + "content-length": 11}, + {"id": 3, + "content-type": "application/octet-stream", + "content-length": 652}]}]}, + []]]]' +test_expect_equal_json \ + "$output" \ + "$expected" +mv "${GNUPGHOME}"{.bak,} + +test_expect_success 'emacs delivery of encrypted + signed message' \ +'emacs_fcc_message \ + "test encrypted message 002" \ + "This is another test encrypted message.\n" \ + "(mml-secure-message-sign-encrypt)"' + +test_begin_subtest "decryption + signature verification" +output=$(notmuch show --format=json --decrypt subject:"test encrypted message 002" \ + | notmuch_json_show_sanitize \ + | sed -e 's|"created": [1234567890]*|"created": 946728000|') +expected='[[[{"id": "XXXXX", + "match": true, + "excluded": false, + "filename": "YYYYY", + "timestamp": 946728000, + "date_relative": "2000-01-01", + "tags": ["encrypted","inbox"], + "headers": {"Subject": "test encrypted message 002", + "From": "Notmuch Test Suite ", + "To": "test_suite@notmuchmail.org", + "Date": "Sat, 01 Jan 2000 12:00:00 +0000"}, + "body": [{"id": 1, + "encstatus": [{"status": "good"}], + "sigstatus": [{"status": "good", + "fingerprint": "'$FINGERPRINT'", + "created": 946728000, + "userid": " Notmuch Test Suite (INSECURE!)"}], + "content-type": "multipart/encrypted", + "content": [{"id": 2, + "content-type": "application/pgp-encrypted", + "content-length": 11}, + {"id": 3, + "content-type": "text/plain", + "content": "This is another test encrypted message.\n"}]}]}, + []]]]' +test_expect_equal_json \ + "$output" \ + "$expected" + +test_begin_subtest "reply to encrypted message" +output=$(notmuch reply --decrypt subject:"test encrypted message 002" \ + | grep -v -e '^In-Reply-To:' -e '^References:') +expected='From: Notmuch Test Suite +Subject: Re: test encrypted message 002 + +On 01 Jan 2000 12:00:00 -0000, Notmuch Test Suite wrote: +> This is another test encrypted message.' +test_expect_equal \ + "$output" \ + "$expected" + +test_begin_subtest "signature verification with revoked key" +# generate revocation certificate and load it to revoke key +echo "y +1 +Notmuch Test Suite key revocation (automated) $(date '+%F_%T%z') + +y + +" \ + | gpg --no-tty --quiet --command-fd 0 --armor --gen-revoke "0x${FINGERPRINT}!" 2>/dev/null \ + | gpg --no-tty --quiet --import +output=$(notmuch show --format=json --verify subject:"test signed message 001" \ + | notmuch_json_show_sanitize \ + | sed -e 's|"created": [1234567890]*|"created": 946728000|') +expected='[[[{"id": "XXXXX", + "match": true, + "excluded": false, + "filename": "YYYYY", + "timestamp": 946728000, + "date_relative": "2000-01-01", + "tags": ["inbox","signed"], + "headers": {"Subject": "test signed message 001", + "From": "Notmuch Test Suite ", + "To": "test_suite@notmuchmail.org", + "Date": "Sat, 01 Jan 2000 12:00:00 +0000"}, + "body": [{"id": 1, + "sigstatus": [{"status": "error", + "keyid": "6D92612D94E46381", + "errors": 8}], + "content-type": "multipart/signed", + "content": [{"id": 2, + "content-type": "text/plain", + "content": "This is a test signed message.\n"}, + {"id": 3, + "content-type": "application/pgp-signature", + "content-length": 280}]}]}, + []]]]' +test_expect_equal_json \ + "$output" \ + "$expected" + +test_done diff --git a/test/T360-symbol-hiding.sh b/test/T360-symbol-hiding.sh new file mode 100755 index 00000000..636ec917 --- /dev/null +++ b/test/T360-symbol-hiding.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2011 David Bremner +# + +# This test tests whether hiding Xapian::Error symbols in libnotmuch +# also hides them for other users of libxapian. This is motivated by +# the discussion in http://gcc.gnu.org/wiki/Visibility' + +test_description='exception symbol hiding' + +. ./test-lib.sh + +run_test(){ + result=$(LD_LIBRARY_PATH="$TEST_DIRECTORY/../lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" $TEST_DIRECTORY/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'" + +mkdir -p fakedb/.notmuch + +test_expect_success 'running test' run_test + +test_begin_subtest 'checking output' +test_expect_equal "$result" "$output" + +test_begin_subtest 'comparing existing to exported symbols' +objdump -t $TEST_DIRECTORY/../lib/*.o | awk '$4 == ".text" && $6 ~ "^notmuch" {print $6}' | sort | uniq > ACTUAL +sed -n 's/[[:blank:]]*\(notmuch_[^;]*\);/\1/p' $TEST_DIRECTORY/../notmuch.sym | sort | uniq > EXPORTED +test_expect_equal_file EXPORTED ACTUAL + +test_done diff --git a/test/T370-search-folder-coherence.sh b/test/T370-search-folder-coherence.sh new file mode 100755 index 00000000..3f6ec763 --- /dev/null +++ b/test/T370-search-folder-coherence.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash +test_description='folder tags removed and added through file renames remain consistent' +. ./test-lib.sh + +test_begin_subtest "No new messages" +output=$(NOTMUCH_NEW) +test_expect_equal "$output" "No new mail." + + +test_begin_subtest "Single new message" +generate_message +file_x=$gen_msg_filename +id_x=$gen_msg_id +output=$(NOTMUCH_NEW) +test_expect_equal "$output" "Added 1 new message to the database." + +test_begin_subtest "Add second folder for same message" +dir=$(dirname $file_x) +mkdir $dir/spam +cp $file_x $dir/spam +output=$(NOTMUCH_NEW) +test_expect_equal "$output" "No new mail." + + +test_begin_subtest "Multiple files for same message" +cat <EXPECTED +MAIL_DIR/msg-001 +MAIL_DIR/spam/msg-001 +EOF +notmuch search --output=files id:$id_x | sed -e "s,$MAIL_DIR,MAIL_DIR," >OUTPUT +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "Test matches folder:spam" +output=$(notmuch search folder:spam) +test_expect_equal "$output" "thread:0000000000000001 2001-01-05 [1/1] Notmuch Test Suite; Single new message (inbox unread)" + +test_begin_subtest "Remove folder:spam copy of email" +rm $dir/spam/$(basename $file_x) +output=$(NOTMUCH_NEW) +test_expect_equal "$output" "No new mail. Detected 1 file rename." + +test_begin_subtest "No mails match the folder:spam search" +output=$(notmuch search folder:spam) +test_expect_equal "$output" "" + +test_done diff --git a/test/T380-atomicity.sh b/test/T380-atomicity.sh new file mode 100755 index 00000000..1c786fa2 --- /dev/null +++ b/test/T380-atomicity.sh @@ -0,0 +1,100 @@ +#!/usr/bin/env bash +test_description='atomicity' +. ./test-lib.sh + +# This script tests the effects of killing and restarting "notmuch +# new" at arbitrary points. If notmuch new is properly atomic, the +# final database contents should be the same regardless of when (or +# if) it is killed and restarted. + +if test_require_external_prereq gdb; then + +# Create a maildir structure to also stress flag synchronization + mkdir $MAIL_DIR/cur + mkdir $MAIL_DIR/new + mkdir $MAIL_DIR/tmp + mkdir $MAIL_DIR/.remove-dir + + # Prepare the initial database + generate_message [subject]='Duplicate' [filename]='duplicate:2,' [dir]=cur + generate_message [subject]='Remove' [filename]='remove:2,' [dir]=cur + generate_message [subject]='"Remove duplicate"' [filename]='remove-duplicate:2,' [dir]=cur + cp $MAIL_DIR/cur/remove-duplicate:2, $MAIL_DIR/cur/remove-duplicate-copy:2, + generate_message [subject]='Rename' [filename]='rename:2,' [dir]=cur + generate_message [subject]='"Rename duplicate"' [filename]='rename-duplicate:2,' [dir]=cur + generate_message [subject]='"Move 1"' [filename]='move1:2,' [dir]=cur + generate_message [subject]='"Move 2"' [filename]='move2:2,' [dir]=new + generate_message [subject]='Flag' [filename]='flag:2,' [dir]=cur + generate_message [subject]='"Flag duplicate"' [filename]='flag-duplicate:2,' [dir]=cur + cp $MAIL_DIR/cur/flag-duplicate:2, $MAIL_DIR/cur/flag-duplicate-copy:2,F + generate_message [subject]='"Remove directory"' [filename]='remove-directory:2,' [dir]=.remove-dir + generate_message [subject]='"Remove directory duplicate"' [filename]='remove-directory-duplicate:2,' [dir]=.remove-dir + cp $MAIL_DIR/.remove-dir/remove-directory-duplicate:2, $MAIL_DIR/cur/ + notmuch new > /dev/null + + # Make all maildir changes, but *don't* update the database + generate_message [subject]='Added' [filename]='added:2,' [dir]=cur + cp $MAIL_DIR/cur/duplicate:2, $MAIL_DIR/cur/duplicate-copy:2, + generate_message [subject]='"Add duplicate"' [filename]='add-duplicate:2,' [dir]=cur + generate_message [subject]='"Add duplicate copy"' [filename]='add-duplicate-copy:2,' [dir]=cur + rm $MAIL_DIR/cur/remove:2, + rm $MAIL_DIR/cur/remove-duplicate-copy:2, + mv $MAIL_DIR/cur/rename:2, $MAIL_DIR/cur/renamed:2, + mv $MAIL_DIR/cur/rename-duplicate:2, $MAIL_DIR/cur/renamed-duplicate:2, + mv $MAIL_DIR/cur/move1:2, $MAIL_DIR/new/move1:2, + mv $MAIL_DIR/new/move2:2, $MAIL_DIR/cur/move2:2, + mv $MAIL_DIR/cur/flag:2, $MAIL_DIR/cur/flag:2,F + rm $MAIL_DIR/cur/flag-duplicate-copy:2,F + rm $MAIL_DIR/.remove-dir/remove-directory:2, + rm $MAIL_DIR/.remove-dir/remove-directory-duplicate:2, + rmdir $MAIL_DIR/.remove-dir + + # Prepare a snapshot of the updated maildir. The gdb script will + # update the database in this snapshot as it goes. + cp -a $MAIL_DIR $MAIL_DIR.snap + cp ${NOTMUCH_CONFIG} ${NOTMUCH_CONFIG}.snap + NOTMUCH_CONFIG=${NOTMUCH_CONFIG}.snap notmuch config set database.path $MAIL_DIR.snap + + + + # Execute notmuch new and, at every call to rename, snapshot the + # database, run notmuch new again on the snapshot, and capture the + # results of search. + # + # -tty /dev/null works around a conflict between the 'timeout' wrapper + # and gdb's attempt to control the TTY. + export MAIL_DIR + gdb -tty /dev/null -batch -x $TEST_DIRECTORY/atomicity.gdb notmuch >/dev/null 2>/dev/null + + # Get the final, golden output + notmuch search '*' > expected + + # Check output against golden output + outcount=$(cat outcount) + echo -n > searchall + echo -n > expectall + for ((i = 0; i < $outcount; i++)); do + if ! cmp -s search.$i expected; then + # Find the range of interruptions that match this output + for ((end = $i + 1 ; end < $outcount; end++)); do + if ! cmp -s search.$i search.$end; then + break + fi + done + echo "When interrupted after $test/backtrace.$(expr $i - 1) (abort points $i-$(expr $end - 1))" >> searchall + cat search.$i >> searchall + cat expected >> expectall + echo >> searchall + echo >> expectall + + i=$(expr $end - 1) + fi + done +fi + +test_begin_subtest '"notmuch new" is idempotent under arbitrary aborts' +test_expect_equal_file searchall expectall + +test_expect_success "detected $outcount>10 abort points" "test $outcount -gt 10" + +test_done diff --git a/test/T390-python.sh b/test/T390-python.sh new file mode 100755 index 00000000..3f03a2e3 --- /dev/null +++ b/test/T390-python.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +test_description="python bindings" +. ./test-lib.sh + +add_email_corpus + +test_begin_subtest "compare thread ids" +test_python < EXPECTED +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "compare message ids" +test_python < EXPECTED +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "get non-existent file" +test_python <"${HOOK_DIR}/${1}" +#!/bin/sh +echo "${TOKEN}" > ${3} +EOF + chmod +x "${HOOK_DIR}/${1}" + echo "${TOKEN}" > ${2} +} + +create_failing_hook () { + mkdir -p ${HOOK_DIR} + cat <"${HOOK_DIR}/${1}" +#!/bin/sh +exit 13 +EOF + chmod +x "${HOOK_DIR}/${1}" +} + +rm_hooks () { + rm -rf ${HOOK_DIR} +} + +# add a message to generate mail dir and database +add_message + +test_begin_subtest "pre-new is run" +rm_hooks +generate_message +create_echo_hook "pre-new" expected output +notmuch new > /dev/null +test_expect_equal_file expected output + +test_begin_subtest "post-new is run" +rm_hooks +generate_message +create_echo_hook "post-new" expected output +notmuch new > /dev/null +test_expect_equal_file expected output + +test_begin_subtest "pre-new is run before post-new" +rm_hooks +generate_message +create_echo_hook "pre-new" pre-new.expected pre-new.output +create_echo_hook "post-new" post-new.expected post-new.output +notmuch new > /dev/null +test_expect_equal_file post-new.expected post-new.output + +test_begin_subtest "pre-new non-zero exit status (hook status)" +rm_hooks +generate_message +create_failing_hook "pre-new" +output=`notmuch new 2>&1` +test_expect_equal "$output" "Error: pre-new hook failed with status 13" + +# depends on the previous subtest leaving broken hook behind +test_expect_code 1 "pre-new non-zero exit status (notmuch status)" "notmuch new" + +# depends on the previous subtests leaving 1 new message behind +test_begin_subtest "pre-new non-zero exit status aborts new" +rm_hooks +output=$(NOTMUCH_NEW) +test_expect_equal "$output" "Added 1 new message to the database." + +test_begin_subtest "post-new non-zero exit status (hook status)" +rm_hooks +generate_message +create_failing_hook "post-new" +NOTMUCH_NEW 2>output.stderr >output +cat output.stderr >> output +echo "Added 1 new message to the database." > expected +echo "Error: post-new hook failed with status 13" >> expected +test_expect_equal_file expected output + +# depends on the previous subtest leaving broken hook behind +test_expect_code 1 "post-new non-zero exit status (notmuch status)" "notmuch new" + +# test_begin_subtest "hook without executable permissions" +rm_hooks +mkdir -p ${HOOK_DIR} +cat <"${HOOK_DIR}/pre-new" +#!/bin/sh +echo foo +EOF +output=`notmuch new 2>&1` +test_expect_code 1 "hook without executable permissions" "notmuch new" + +# test_begin_subtest "hook execution failure" +rm_hooks +mkdir -p ${HOOK_DIR} +cat <"${HOOK_DIR}/pre-new" +no hashbang, execl fails +EOF +chmod +x "${HOOK_DIR}/pre-new" +test_expect_code 1 "hook execution failure" "notmuch new" + +test_done diff --git a/test/T410-argument-parsing.sh b/test/T410-argument-parsing.sh new file mode 100755 index 00000000..94e90874 --- /dev/null +++ b/test/T410-argument-parsing.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +test_description="argument parsing" +. ./test-lib.sh + +test_begin_subtest "sanity check" +$TEST_DIRECTORY/arg-test pos1 --keyword=one --string=foo pos2 --int=7 > OUTPUT +cat < EXPECTED +keyword 1 +int 7 +string foo +positional arg 1 pos1 +positional arg 2 pos2 +EOF +test_expect_equal_file OUTPUT EXPECTED + +test_done diff --git a/test/T420-emacs-test-functions.sh b/test/T420-emacs-test-functions.sh new file mode 100755 index 00000000..ca4a7988 --- /dev/null +++ b/test/T420-emacs-test-functions.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +test_description="emacs test function sanity" +. ./test-lib.sh + +test_begin_subtest "emacs test function sanity" +test_emacs_expect_t 't' + +test_done diff --git a/test/T430-emacs-address-cleaning.sh b/test/T430-emacs-address-cleaning.sh new file mode 100755 index 00000000..04723467 --- /dev/null +++ b/test/T430-emacs-address-cleaning.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +test_description="emacs address cleaning" +. ./test-lib.sh + +test_begin_subtest "notmuch-test-address-clean part 1" +test_emacs_expect_t '(notmuch-test-address-cleaning-1)' + +test_begin_subtest "notmuch-test-address-clean part 2" +test_emacs_expect_t '(notmuch-test-address-cleaning-2)' + +test_begin_subtest "notmuch-test-address-clean part 3" +test_emacs_expect_t '(notmuch-test-address-cleaning-3)' + +test_done diff --git a/test/T440-emacs-hello.sh b/test/T440-emacs-hello.sh new file mode 100755 index 00000000..f7296166 --- /dev/null +++ b/test/T440-emacs-hello.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash + +test_description="emacs notmuch-hello view" +. ./test-lib.sh + +EXPECTED=$TEST_DIRECTORY/emacs.expected-output + +add_email_corpus + +test_begin_subtest "User-defined section with inbox tag" +test_emacs "(let ((notmuch-hello-sections + (list (lambda () (notmuch-hello-insert-searches + \"Test\" '((\"inbox\" . \"tag:inbox\"))))))) + (notmuch-hello) + (test-output))" +test_expect_equal_file OUTPUT $EXPECTED/notmuch-hello-new-section + +test_begin_subtest "User-defined section with empty, hidden entry" +test_emacs "(let ((notmuch-hello-sections + (list (lambda () (notmuch-hello-insert-searches + \"Test-with-empty\" + '((\"inbox\" . \"tag:inbox\") + (\"doesnotexist\" . \"tag:doesnotexist\")) + :hide-empty-searches t))))) + (notmuch-hello) + (test-output))" +test_expect_equal_file OUTPUT $EXPECTED/notmuch-hello-section-with-empty + +test_begin_subtest "User-defined section, unread tag filtered out" +test_emacs "(let ((notmuch-hello-sections + (list (lambda () (notmuch-hello-insert-tags-section + \"Test-with-filtered\" + :hide-tags '(\"unread\")))))) + (notmuch-hello) + (test-output))" +test_expect_equal_file OUTPUT $EXPECTED/notmuch-hello-section-hidden-tag + +test_begin_subtest "User-defined section, different query for counts" +test_emacs "(let ((notmuch-hello-sections + (list (lambda () (notmuch-hello-insert-tags-section + \"Test-with-counts\" + :filter-count \"tag:signed\"))))) + (notmuch-hello) + (test-output))" +test_expect_equal_file OUTPUT $EXPECTED/notmuch-hello-section-counts + +test_begin_subtest "Empty custom tags section" +test_emacs "(let* ((widget (widget-create 'notmuch-hello-tags-section)) + (notmuch-hello-sections (list (widget-value widget)))) + (notmuch-hello) + (test-output))" +test_expect_equal_file OUTPUT $EXPECTED/notmuch-hello-empty-custom-tags-section + +test_begin_subtest "Empty custom queries section" +test_emacs "(let* ((widget (widget-create 'notmuch-hello-query-section)) + (notmuch-hello-sections (list (widget-value widget)))) + (notmuch-hello) + (test-output))" +test_expect_equal_file OUTPUT $EXPECTED/notmuch-hello-empty-custom-queries-section + +test_begin_subtest "Column alignment for tag/queries with long names" +tag=a-very-long-tag # length carefully calculated for 80 characters window width +notmuch tag +$tag '*' +test_emacs '(notmuch-hello) + (test-output)' +notmuch tag -$tag '*' +test_expect_equal_file OUTPUT $EXPECTED/notmuch-hello-long-names + +test_done diff --git a/test/T450-emacs-show.sh b/test/T450-emacs-show.sh new file mode 100755 index 00000000..2a3a5356 --- /dev/null +++ b/test/T450-emacs-show.sh @@ -0,0 +1,201 @@ +#!/usr/bin/env bash + +test_description="emacs notmuch-show view" +. ./test-lib.sh + +EXPECTED=$TEST_DIRECTORY/emacs-show.expected-output + +add_email_corpus + +test_begin_subtest "Hiding Original Message region at beginning of a message" +message_id='OriginalMessageHiding.1@notmuchmail.org' +add_message \ + [id]="$message_id" \ + '[subject]="Hiding Original Message region at beginning of a message"' \ + '[body]="-----Original Message----- +Text here."' + +cat <EXPECTED +Notmuch Test Suite (2001-01-05) (inbox) +Subject: Hiding Original Message region at beginning of a message +To: Notmuch Test Suite +Date: GENERATED_DATE + +[ 2-line hidden original message. Click/Enter to show. ] +EOF + +test_emacs "(notmuch-show \"id:$message_id\") + (test-visible-output \"OUTPUT.raw\")" +notmuch_date_sanitize < OUTPUT.raw > OUTPUT +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "Bare subject #1" +output=$(test_emacs '(notmuch-show-strip-re "Re: subject")') +test_expect_equal "$output" '"subject"' + +test_begin_subtest "Bare subject #2" +output=$(test_emacs '(notmuch-show-strip-re "re:Re: re: Re: re:subject")') +test_expect_equal "$output" '"subject"' + +test_begin_subtest "Bare subject #3" +output=$(test_emacs '(notmuch-show-strip-re "the cure: fix the regexp")') +test_expect_equal "$output" '"the cure: fix the regexp"' + +test_begin_subtest "don't process cryptographic MIME parts" +test_emacs '(let ((notmuch-crypto-process-mime nil)) + (notmuch-show "id:20091117203301.GV3165@dottiness.seas.harvard.edu") + (test-visible-output))' +test_expect_equal_file OUTPUT $EXPECTED/notmuch-show-process-crypto-mime-parts-off + +test_begin_subtest "process cryptographic MIME parts" +test_emacs '(let ((notmuch-crypto-process-mime t)) + (notmuch-show "id:20091117203301.GV3165@dottiness.seas.harvard.edu") + (test-visible-output))' +test_expect_equal_file OUTPUT $EXPECTED/notmuch-show-process-crypto-mime-parts-on + +test_begin_subtest "process cryptographic MIME parts (w/ notmuch-show-toggle-process-crypto)" +test_emacs '(let ((notmuch-crypto-process-mime nil)) + (notmuch-show "id:20091117203301.GV3165@dottiness.seas.harvard.edu") + (notmuch-show-toggle-process-crypto) + (test-visible-output))' +test_expect_equal_file OUTPUT $EXPECTED/notmuch-show-process-crypto-mime-parts-on + +test_begin_subtest "notmuch-show: don't elide non-matching messages" +test_emacs '(let ((notmuch-show-only-matching-messages nil)) + (notmuch-search "from:lars@seas.harvard.edu and subject:\"Maildir storage\"") + (notmuch-test-wait) + (notmuch-search-show-thread) + (notmuch-test-wait) + (test-visible-output))' +test_expect_equal_file OUTPUT $EXPECTED/notmuch-show-elide-non-matching-messages-off + +test_begin_subtest "notmuch-show: elide non-matching messages" +test_emacs '(let ((notmuch-show-only-matching-messages t)) + (notmuch-search "from:lars@seas.harvard.edu and subject:\"Maildir storage\"") + (notmuch-test-wait) + (notmuch-search-show-thread) + (notmuch-test-wait) + (test-visible-output))' +test_expect_equal_file OUTPUT $EXPECTED/notmuch-show-elide-non-matching-messages-on + +test_begin_subtest "notmuch-show: elide non-matching messages (w/ notmuch-show-toggle-elide-non-matching)" +test_emacs '(let ((notmuch-show-only-matching-messages nil)) + (notmuch-search "from:lars@seas.harvard.edu and subject:\"Maildir storage\"") + (notmuch-test-wait) + (notmuch-search-show-thread) + (notmuch-test-wait) + (notmuch-show-toggle-elide-non-matching) + (test-visible-output))' +test_expect_equal_file OUTPUT $EXPECTED/notmuch-show-elide-non-matching-messages-on + +test_begin_subtest "notmuch-show: elide non-matching messages (w/ prefix arg to notmuch-show)" +test_emacs '(let ((notmuch-show-only-matching-messages nil)) + (notmuch-search "from:lars@seas.harvard.edu and subject:\"Maildir storage\"") + (notmuch-test-wait) + (notmuch-search-show-thread t) + (notmuch-test-wait) + (test-visible-output))' +test_expect_equal_file OUTPUT $EXPECTED/notmuch-show-elide-non-matching-messages-on + +test_begin_subtest "notmuch-show: disable indentation of thread content (w/ notmuch-show-toggle-thread-indentation)" +test_emacs '(notmuch-search "from:lars@seas.harvard.edu and subject:\"Maildir storage\"") + (notmuch-test-wait) + (notmuch-search-show-thread) + (notmuch-test-wait) + (notmuch-show-toggle-thread-indentation) + (test-visible-output)' +test_expect_equal_file OUTPUT $EXPECTED/notmuch-show-indent-thread-content-off + +test_begin_subtest "id buttonization" +add_message '[body]=" +id:abc +id:abc.def. id:abc,def, id:abc;def; id:abc:def: +id:foo@bar.?baz? id:foo@bar!.baz! +(id:foo@bar.baz) [id:foo@bar.baz] +id:foo@bar.baz... +id:2+2=5 +id:=_-:/.[]@$%+ +id:abc)def +id:ab\"c def +id:\"abc\"def +id:\"ab\"\"c\"def +id:\"ab c\"def +id:\"abc\".def +id:\"abc +\" +id:) +id: +cid:xxx +mid:abc mid:abc/def +mid:abc%20def +mid:abc. mid:abc, mid:abc;"' +test_emacs '(notmuch-show "id:'$gen_msg_id'") + (notmuch-test-mark-links) + (test-visible-output "OUTPUT.raw")' +cat <EXPECTED +Notmuch Test Suite (2001-01-05) (inbox) +Subject: id buttonization +To: Notmuch Test Suite +Date: GENERATED_DATE + +<> +<>. <>, <>; <>: +<>? <>! +(<>) [<>] +<>... +<> +<> +<>)def +<> def +<>def +<>def +<>def +<>.def +id:"abc +" +id:) +id: +cid:xxx +<> <> +<> +<>. <>, <>; +EOF +notmuch_date_sanitize < OUTPUT.raw > OUTPUT +test_expect_equal_file OUTPUT EXPECTED + + +test_begin_subtest "Show handles subprocess errors" +cat > notmuch_fail <&2 +exit 1 +EOF +chmod a+x notmuch_fail +test_emacs "(let ((notmuch-command \"$PWD/notmuch_fail\")) + (with-current-buffer \"*Messages*\" (erase-buffer)) + (condition-case err + (notmuch-show \"*\") + (error (message \"%s\" (second err)))) + (notmuch-test-wait) + (with-current-buffer \"*Messages*\" + (test-output \"MESSAGES\")) + (with-current-buffer \"*Notmuch errors*\" + (test-output \"ERROR\")) + (test-output))" +test_expect_equal "$(notmuch_emacs_error_sanitize notmuch_fail OUTPUT MESSAGES ERROR)" "\ +=== OUTPUT === +=== MESSAGES === +This is an error (see *Notmuch errors* for more details) +=== ERROR === +[XXX] +This is an error +command: YYY/notmuch_fail show --format\\=sexp --format-version\\=1 --exclude\\=false \\' \\* \\' +exit status: 1 +stderr: +This is an error +stdout: +This is output" + + +test_done diff --git a/test/T460-emacs-tree.sh b/test/T460-emacs-tree.sh new file mode 100755 index 00000000..8e9f37cb --- /dev/null +++ b/test/T460-emacs-tree.sh @@ -0,0 +1,181 @@ +#!/usr/bin/env bash + +test_description="emacs tree view interface" +. test-lib.sh + +EXPECTED=$TEST_DIRECTORY/tree.expected-output + +add_email_corpus + +test_begin_subtest "Basic notmuch-tree view in emacs" +test_emacs '(notmuch-tree "tag:inbox") + (notmuch-test-wait) + (test-output) + (delete-other-windows)' +test_expect_equal_file OUTPUT $EXPECTED/notmuch-tree-tag-inbox + +test_begin_subtest "Refreshed notmuch-tree view in emacs" +test_emacs '(notmuch-tree "tag:inbox") + (notmuch-test-wait) + (notmuch-tree-refresh-view) + (notmuch-test-wait) + (test-output) + (delete-other-windows)' +test_expect_equal_file OUTPUT $EXPECTED/notmuch-tree-tag-inbox + +# In the following tag tests we make sure the display is updated +# correctly and, in a separate test, that the database is updated +# correctly. + +test_begin_subtest "Tag message in notmuch tree view (display)" +test_emacs '(notmuch-tree "tag:inbox") + (notmuch-test-wait) + (forward-line) + (notmuch-tree-tag (list "+test_tag")) + (test-output) + (delete-other-windows)' +test_expect_equal_file OUTPUT $EXPECTED/notmuch-tree-tag-inbox-tagged + +test_begin_subtest "Tag message in notmuch tree view (database)" +output=$(notmuch search --output=messages 'tag:test_tag') +test_expect_equal "$output" "id:877h1wv7mg.fsf@inf-8657.int-evry.fr" + +test_begin_subtest "Untag message in notmuch tree view" +test_emacs '(notmuch-tree "tag:inbox") + (notmuch-test-wait) + (forward-line) + (notmuch-tree-tag (list "-test_tag")) + (test-output) + (delete-other-windows)' +test_expect_equal_file OUTPUT $EXPECTED/notmuch-tree-tag-inbox + +test_begin_subtest "Untag message in notmuch tree view (database)" +output=$(notmuch search --output=messages 'tag:test_tag') +test_expect_equal "$output" "" + +test_begin_subtest "Tag thread in notmuch tree view" +test_emacs '(notmuch-tree "tag:inbox") + (notmuch-test-wait) + ;; move to a sizable thread + (forward-line 26) + (notmuch-tree-tag-thread (list "+test_thread_tag")) + (test-output) + (delete-other-windows)' +test_expect_equal_file OUTPUT $EXPECTED/notmuch-tree-tag-inbox-thread-tagged + +test_begin_subtest "Tag message in notmuch tree view (database)" +output=$(notmuch search --output=messages 'tag:test_thread_tag') +test_expect_equal "$output" \ +"id:87ocn0qh6d.fsf@yoom.home.cworth.org +id:20091118005040.GA25380@dottiness.seas.harvard.edu +id:yunaayketfm.fsf@aiko.keithp.com +id:87fx8can9z.fsf@vertex.dottedmag +id:20091117203301.GV3165@dottiness.seas.harvard.edu +id:87iqd9rn3l.fsf@vertex.dottedmag +id:20091117190054.GU3165@dottiness.seas.harvard.edu" + +test_begin_subtest "Untag thread in notmuch tree view" +test_emacs '(notmuch-tree "tag:inbox") + (notmuch-test-wait) + ;; move to the same sizable thread as above + (forward-line 26) + (notmuch-tree-tag-thread (list "-test_thread_tag")) + (test-output) + (delete-other-windows)' +test_expect_equal_file OUTPUT $EXPECTED/notmuch-tree-tag-inbox + +test_begin_subtest "Untag message in notmuch tree view (database)" +output=$(notmuch search --output=messages 'tag:test_thread_tag') +test_expect_equal "$output" "" + +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 (1- (point))) + (notmuch-test-wait) + (notmuch-tree-from-search-current-query) + (notmuch-test-wait) + (test-output) + (delete-other-windows)' +test_expect_equal_file OUTPUT $EXPECTED/notmuch-tree-tag-inbox + +test_begin_subtest "Tree view of a single thread (from search)" +test_emacs '(notmuch-hello) + (goto-char (point-min)) + (re-search-forward "inbox") + (widget-button-press (1- (point))) + (notmuch-test-wait) + (notmuch-tree-from-search-thread) + (notmuch-test-wait) + (test-output) + (delete-other-windows)' +test_expect_equal_file OUTPUT $EXPECTED/notmuch-tree-single-thread + +test_begin_subtest "Tree view of a single thread (from show)" +test_emacs '(notmuch-hello) + (goto-char (point-min)) + (re-search-forward "inbox") + (widget-button-press (1- (point))) + (notmuch-test-wait) + (notmuch-search-show-thread) + (notmuch-tree-from-show-current-query) + (notmuch-test-wait) + (test-output) + (delete-other-windows)' +test_expect_equal_file OUTPUT $EXPECTED/notmuch-tree-single-thread + +test_begin_subtest "Message window of tree view" +test_emacs '(notmuch-hello) + (goto-char (point-min)) + (re-search-forward "inbox") + (widget-button-press (1- (point))) + (notmuch-test-wait) + (notmuch-search-next-thread) + (notmuch-tree-from-search-thread) + (notmuch-test-wait) + (select-window notmuch-tree-message-window) + (test-output) + (delete-other-windows)' +cp OUTPUT /tmp/mjwout +test_expect_equal_file OUTPUT $EXPECTED/notmuch-tree-show-window + +test_begin_subtest "Stash id" +output=$(test_emacs '(notmuch-tree "id:1258498485-sup-142@elly") + (notmuch-test-wait) + (notmuch-show-stash-message-id)') +test_expect_equal "$output" "\"Stashed: id:1258498485-sup-142@elly\"" + +test_begin_subtest "Move to next matching message" +output=$(test_emacs '(notmuch-tree "from:cworth") + (notmuch-test-wait) + (notmuch-tree-next-matching-message) + (notmuch-show-stash-message-id)') +test_expect_equal "$output" "\"Stashed: id:878we4qdqf.fsf@yoom.home.cworth.org\"" + +test_begin_subtest "Move to next thread" +output=$(test_emacs '(notmuch-tree "tag:inbox") + (notmuch-test-wait) + (forward-line 26) + (notmuch-tree-next-thread) + (notmuch-show-stash-message-id)') +test_expect_equal "$output" "\"Stashed: id:1258471718-6781-1-git-send-email-dottedmag@dottedmag.net\"" + +test_begin_subtest "Move to previous thread" +output=$(test_emacs '(notmuch-tree "tag:inbox") + (notmuch-test-wait) + (forward-line 26) + (notmuch-tree-prev-thread) + (notmuch-show-stash-message-id)') +test_expect_equal "$output" "\"Stashed: id:20091117190054.GU3165@dottiness.seas.harvard.edu\"" + +test_begin_subtest "Move to previous previous thread" +output=$(test_emacs '(notmuch-tree "tag:inbox") + (notmuch-test-wait) + (forward-line 26) + (notmuch-tree-prev-thread) + (notmuch-tree-prev-thread) + (notmuch-show-stash-message-id)') +test_expect_equal "$output" "\"Stashed: id:1258493565-13508-1-git-send-email-keithp@keithp.com\"" + +test_done diff --git a/test/T470-missing-headers.sh b/test/T470-missing-headers.sh new file mode 100755 index 00000000..cb38301c --- /dev/null +++ b/test/T470-missing-headers.sh @@ -0,0 +1,164 @@ +#!/usr/bin/env bash +test_description='messages with missing headers' +. ./test-lib.sh + +# Notmuch requires at least one of from, subject, or to or it will +# ignore the file. Generate two messages so that together they cover +# all possible missing headers. We also give one of the messages a +# date to ensure stable result ordering. + +cat < "${MAIL_DIR}/msg-2" +To: Notmuch Test Suite +Date: Fri, 05 Jan 2001 15:43:57 +0000 + +Body +EOF + +cat < "${MAIL_DIR}/msg-1" +From: Notmuch Test Suite + +Body +EOF + +NOTMUCH_NEW + +test_begin_subtest "Search: text" +output=$(notmuch search '*' | notmuch_search_sanitize) +test_expect_equal "$output" "\ +thread:XXX 2001-01-05 [1/1] (null); (inbox unread) +thread:XXX 1970-01-01 [1/1] Notmuch Test Suite; (inbox unread)" + +test_begin_subtest "Search: json" +output=$(notmuch search --format=json '*' | notmuch_search_sanitize) +test_expect_equal_json "$output" ' +[ + { + "authors": "", + "date_relative": "2001-01-05", + "matched": 1, + "subject": "", + "tags": [ + "inbox", + "unread" + ], + "thread": "XXX", + "timestamp": 978709437, + "total": 1, + "query": ["id:notmuch-sha1-7a6e4eac383ef958fcd3ebf2143db71b8ff01161", null] + }, + { + "authors": "Notmuch Test Suite", + "date_relative": "1970-01-01", + "matched": 1, + "subject": "", + "tags": [ + "inbox", + "unread" + ], + "thread": "XXX", + "timestamp": 0, + "total": 1, + "query": ["id:notmuch-sha1-ca55943aff7a72baf2ab21fa74fab3d632401334", null] + } +]' + +test_begin_subtest "Show: text" +output=$(notmuch show '*' | notmuch_show_sanitize) +test_expect_equal "$output" "\ + message{ id:notmuch-sha1-7a6e4eac383ef958fcd3ebf2143db71b8ff01161 depth:0 match:1 excluded:0 filename:/XXX/mail/msg-2 + header{ + (2001-01-05) (inbox unread) +Subject: (null) +From: (null) +To: Notmuch Test Suite +Date: Fri, 05 Jan 2001 15:43:57 +0000 + header} + body{ + part{ ID: 1, Content-type: text/plain +Body + part} + body} + message} + message{ id:notmuch-sha1-ca55943aff7a72baf2ab21fa74fab3d632401334 depth:0 match:1 excluded:0 filename:/XXX/mail/msg-1 + header{ +Notmuch Test Suite (1970-01-01) (inbox unread) +Subject: (null) +From: Notmuch Test Suite +Date: Thu, 01 Jan 1970 00:00:00 +0000 + header} + body{ + part{ ID: 1, Content-type: text/plain +Body + part} + body} + message}" + +test_begin_subtest "Show: json" +output=$(notmuch show --format=json '*' | notmuch_json_show_sanitize) +expected=$(notmuch_json_show_sanitize <" + }, + "id": "XXXXX", + "match": true, + "tags": [ + "inbox", + "unread" + ], + "timestamp": 978709437 + }, + [] + ] + ], + [ + [ + { + "body": [ + { + "content": "Body\n", + "content-type": "text/plain", + "id": 1 + } + ], + "date_relative": "1970-01-01", + "excluded": false, + "filename": "YYYYY", + "headers": { + "Date": "Thu, 01 Jan 1970 00:00:00 +0000", + "From": "Notmuch Test Suite ", + "Subject": "" + }, + "id": "XXXXX", + "match": true, + "tags": [ + "inbox", + "unread" + ], + "timestamp": 0 + }, + [] + ] + ] +] +EOF +) +test_expect_equal_json "$output" "$expected" + +test_done diff --git a/test/T480-hex-escaping.sh b/test/T480-hex-escaping.sh new file mode 100755 index 00000000..ad50e1bc --- /dev/null +++ b/test/T480-hex-escaping.sh @@ -0,0 +1,50 @@ +#!/usr/bin/env bash +test_description="hex encoding and decoding" +. ./test-lib.sh + +test_begin_subtest "round trip" +find $TEST_DIRECTORY/corpus -type f -print | sort | xargs cat > EXPECTED +$TEST_DIRECTORY/hex-xcode --direction=encode < EXPECTED | $TEST_DIRECTORY/hex-xcode --direction=decode > OUTPUT +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "punctuation" +tag1='comic_swear=$&^%$^%\\//-+$^%$' +tag_enc1=$($TEST_DIRECTORY/hex-xcode --direction=encode "$tag1") +test_expect_equal "$tag_enc1" "comic_swear=%24%26%5e%25%24%5e%25%5c%5c%2f%2f-+%24%5e%25%24" + +test_begin_subtest "round trip newlines" +printf 'this\n tag\t has\n spaces\n' > EXPECTED.$test_count +$TEST_DIRECTORY/hex-xcode --direction=encode < EXPECTED.$test_count |\ + $TEST_DIRECTORY/hex-xcode --direction=decode > OUTPUT.$test_count +test_expect_equal_file EXPECTED.$test_count OUTPUT.$test_count + +test_begin_subtest "round trip 8bit chars" +echo '%c3%91%c3%a5%c3%b0%c3%a3%c3%a5%c3%a9-%c3%8f%c3%8a' > EXPECTED.$test_count +$TEST_DIRECTORY/hex-xcode --direction=decode < EXPECTED.$test_count |\ + $TEST_DIRECTORY/hex-xcode --direction=encode > OUTPUT.$test_count +test_expect_equal_file EXPECTED.$test_count OUTPUT.$test_count + +test_begin_subtest "round trip (in-place)" +find $TEST_DIRECTORY/corpus -type f -print | sort | xargs cat > EXPECTED +$TEST_DIRECTORY/hex-xcode --in-place --direction=encode < EXPECTED |\ + $TEST_DIRECTORY/hex-xcode --in-place --direction=decode > OUTPUT +test_expect_equal_file OUTPUT EXPECTED + +test_begin_subtest "punctuation (in-place)" +tag1='comic_swear=$&^%$^%\\//-+$^%$' +tag_enc1=$($TEST_DIRECTORY/hex-xcode --in-place --direction=encode "$tag1") +test_expect_equal "$tag_enc1" "comic_swear=%24%26%5e%25%24%5e%25%5c%5c%2f%2f-+%24%5e%25%24" + +test_begin_subtest "round trip newlines (in-place)" +printf 'this\n tag\t has\n spaces\n' > EXPECTED.$test_count +$TEST_DIRECTORY/hex-xcode --in-place --direction=encode < EXPECTED.$test_count |\ + $TEST_DIRECTORY/hex-xcode --in-place --direction=decode > OUTPUT.$test_count +test_expect_equal_file EXPECTED.$test_count OUTPUT.$test_count + +test_begin_subtest "round trip 8bit chars (in-place)" +echo '%c3%91%c3%a5%c3%b0%c3%a3%c3%a5%c3%a9-%c3%8f%c3%8a' > EXPECTED.$test_count +$TEST_DIRECTORY/hex-xcode --in-place --direction=decode < EXPECTED.$test_count |\ + $TEST_DIRECTORY/hex-xcode --in-place --direction=encode > OUTPUT.$test_count +test_expect_equal_file EXPECTED.$test_count OUTPUT.$test_count + +test_done diff --git a/test/T490-parse-time-string.sh b/test/T490-parse-time-string.sh new file mode 100755 index 00000000..8ae0b4c2 --- /dev/null +++ b/test/T490-parse-time-string.sh @@ -0,0 +1,78 @@ +#!/usr/bin/env bash +test_description="date/time parser module" +. ./test-lib.sh + +# Sanity/smoke tests for the date/time parser independent of notmuch + +_date () +{ + date -d "$*" +%s +} + +_parse_time () +{ + ${TEST_DIRECTORY}/parse-time --format=%s "$*" +} + +test_begin_subtest "date(1) default format without TZ code" +test_expect_equal "$(_parse_time Fri Aug 3 23:06:06 2012)" "$(_date Fri Aug 3 23:06:06 2012)" + +test_begin_subtest "date(1) --rfc-2822 format" +test_expect_equal "$(_parse_time Fri, 03 Aug 2012 23:07:46 +0100)" "$(_date Fri, 03 Aug 2012 23:07:46 +0100)" + +test_begin_subtest "date(1) --rfc=3339=seconds format" +test_expect_equal "$(_parse_time 2012-08-03 23:09:37+03:00)" "$(_date 2012-08-03 23:09:37+03:00)" + +test_begin_subtest "Date parser tests" +REFERENCE=$(_date Tue Jan 11 11:11:00 +0000 2011) +cat < INPUT +now ==> Tue Jan 11 11:11:00 +0000 2011 +2010-1-1 ==> ERROR: DATEFORMAT +Jan 2 ==> Sun Jan 02 11:11:00 +0000 2011 +Mon ==> Mon Jan 10 11:11:00 +0000 2011 +last Friday ==> ERROR: FORMAT +2 hours ago ==> Tue Jan 11 09:11:00 +0000 2011 +last month ==> Sat Dec 11 11:11:00 +0000 2010 +month ago ==> Sat Dec 11 11:11:00 +0000 2010 +two mo ==> Thu Nov 11 11:11:00 +0000 2010 +3M ==> Mon Oct 11 11:11:00 +0000 2010 +4-mont ==> Sat Sep 11 11:11:00 +0000 2010 +5m ==> Tue Jan 11 11:06:00 +0000 2011 +dozen mi ==> Tue Jan 11 10:59:00 +0000 2011 +8am ==> Tue Jan 11 08:00:00 +0000 2011 +9:15 ==> Tue Jan 11 09:15:00 +0000 2011 +12:34 ==> Tue Jan 11 12:34:00 +0000 2011 +monday ==> Mon Jan 10 11:11:00 +0000 2011 +yesterday ==> Mon Jan 10 11:11:00 +0000 2011 +tomorrow ==> ERROR: KEYWORD + ==> Tue Jan 11 11:11:00 +0000 2011 # empty string is reference time + +Aug 3 23:06:06 2012 ==> Fri Aug 03 23:06:06 +0000 2012 # date(1) default format without TZ code +Fri, 03 Aug 2012 23:07:46 +0100 ==> Fri Aug 03 22:07:46 +0000 2012 # rfc-2822 +2012-08-03 23:09:37+03:00 ==> Fri Aug 03 20:09:37 +0000 2012 # rfc-3339 seconds + +10s ==> Tue Jan 11 11:10:50 +0000 2011 +19701223s ==> Fri May 28 10:37:17 +0000 2010 +19701223 ==> Wed Dec 23 11:11:00 +0000 1970 + +19701223 +0100 ==> Wed Dec 23 11:11:00 +0000 1970 # Timezone is ignored without an error + +today ==^^> Wed Jan 12 00:00:00 +0000 2011 +today ==^> Tue Jan 11 23:59:59 +0000 2011 +today ==_> Tue Jan 11 00:00:00 +0000 2011 + +this week ==^^> Sun Jan 16 00:00:00 +0000 2011 +this week ==^> Sat Jan 15 23:59:59 +0000 2011 +this week ==_> Sun Jan 09 00:00:00 +0000 2011 + +two months ago ==> Thu Nov 11 11:11:00 +0000 2010 +two months ==> Thu Nov 11 11:11:00 +0000 2010 + +@1348569850 ==> Tue Sep 25 10:44:10 +0000 2012 +@10 ==> Thu Jan 01 00:00:10 +0000 1970 +EOF + +${TEST_DIRECTORY}/parse-time --ref=${REFERENCE} < INPUT > OUTPUT +test_expect_equal_file INPUT OUTPUT + +test_done diff --git a/test/T500-search-date.sh b/test/T500-search-date.sh new file mode 100755 index 00000000..70bcf344 --- /dev/null +++ b/test/T500-search-date.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash +test_description="date:since..until queries" +. ./test-lib.sh + +add_email_corpus + +test_begin_subtest "Absolute date range" +output=$(notmuch search date:2010-12-16..12/16/2010 | notmuch_search_sanitize) +test_expect_equal "$output" "thread:XXX 2010-12-16 [1/1] Olivier Berger; Essai accentué (inbox unread)" + +test_begin_subtest "Absolute time range with TZ" +notmuch search date:18-Nov-2009_02:19:26-0800..2009-11-18_04:49:52-06:00 | notmuch_search_sanitize > OUTPUT +cat <EXPECTED +thread:XXX 2009-11-18 [1/3] Carl Worth| Jan Janak; [notmuch] What a great idea! (inbox unread) +thread:XXX 2009-11-18 [1/2] Carl Worth| Jan Janak; [notmuch] [PATCH] Older versions of install do not support -C. (inbox unread) +thread:XXX 2009-11-18 [1/3] Carl Worth| Aron Griffis, Keith Packard; [notmuch] archive (inbox unread) +thread:XXX 2009-11-18 [1/2] Carl Worth| Keith Packard; [notmuch] [PATCH] Make notmuch-show 'X' (and 'x') commands remove inbox (and unread) tags (inbox unread) +EOF +test_expect_equal_file OUTPUT EXPECTED + +test_done diff --git a/test/T510-thread-replies.sh b/test/T510-thread-replies.sh new file mode 100755 index 00000000..eeb70d06 --- /dev/null +++ b/test/T510-thread-replies.sh @@ -0,0 +1,141 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2013 Aaron Ecay +# + +test_description='test of proper handling of in-reply-to and references headers' + +# This test makes sure that the thread structure in the notmuch +# database is constructed properly, even in the presence of +# non-RFC-compliant headers' + +. ./test-lib.sh + +test_begin_subtest "Use References when In-Reply-To is broken" +add_message '[id]="foo@one.com"' \ + '[subject]=one' +add_message '[in-reply-to]="mumble"' \ + '[references]=""' \ + '[subject]="Re: one"' +output=$(notmuch show --format=json 'subject:one' | notmuch_json_show_sanitize) +expected='[[[{"id": "foo@one.com", + "match": true, + "excluded": false, + "filename": "YYYYY", + "timestamp": 978709437, + "date_relative": "2001-01-05", + "tags": ["inbox", "unread"], + "headers": {"Subject": "one", + "From": "Notmuch Test Suite ", + "To": "Notmuch Test Suite ", + "Date": "Fri, 05 Jan 2001 15:43:57 +0000"}, + "body": [{"id": 1, + "content-type": "text/plain", + "content": "This is just a test message (#1)\n"}]}, + [[{"id": "msg-002@notmuch-test-suite", + "match": true, "excluded": false, + "filename": "YYYYY", + "timestamp": 978709437, "date_relative": "2001-01-05", + "tags": ["inbox", "unread"], "headers": {"Subject": "Re: one", + "From": "Notmuch Test Suite ", + "To": "Notmuch Test Suite ", + "Date": "Fri, 05 Jan 2001 15:43:57 +0000"}, + "body": [{"id": 1, "content-type": "text/plain", + "content": "This is just a test message (#2)\n"}]}, []]]]]]' +expected=`echo "$expected" | notmuch_json_show_sanitize` +test_expect_equal_json "$output" "$expected" + +test_begin_subtest "Prefer References to In-Reply-To" +add_message '[id]="foo@two.com"' \ + '[subject]=two' +add_message '[in-reply-to]=""' \ + '[references]=""' \ + '[subject]="Re: two"' +output=$(notmuch show --format=json 'subject:two' | notmuch_json_show_sanitize) +expected='[[[{"id": "foo@two.com", + "match": true, "excluded": false, + "filename": "YYYYY", + "timestamp": 978709437, "date_relative": "2001-01-05", "tags": ["inbox", "unread"], + "headers": {"Subject": "two", + "From": "Notmuch Test Suite ", + "To": "Notmuch Test Suite ", + "Date": "Fri, 05 Jan 2001 15:43:57 +0000"}, + "body": [{"id": 1, "content-type": "text/plain", + "content": "This is just a test message (#3)\n"}]}, + [[{"id": "msg-004@notmuch-test-suite", "match": true, "excluded": false, + "filename": "YYYYY", + "timestamp": 978709437, "date_relative": "2001-01-05", "tags": ["inbox", "unread"], + "headers": {"Subject": "Re: two", + "From": "Notmuch Test Suite ", + "To": "Notmuch Test Suite ", + "Date": "Fri, 05 Jan 2001 15:43:57 +0000"}, + "body": [{"id": 1, + "content-type": "text/plain", "content": "This is just a test message (#4)\n"}]}, + []]]]]]' +expected=`echo "$expected" | notmuch_json_show_sanitize` +test_expect_equal_json "$output" "$expected" + +test_begin_subtest "Use In-Reply-To when no References" +add_message '[id]="foo@three.com"' \ + '[subject]="three"' +add_message '[in-reply-to]=""' \ + '[subject]="Re: three"' +output=$(notmuch show --format=json 'subject:three' | notmuch_json_show_sanitize) +expected='[[[{"id": "foo@three.com", "match": true, "excluded": false, + "filename": "YYYYY", + "timestamp": 978709437, "date_relative": "2001-01-05", "tags": ["inbox", "unread"], + "headers": {"Subject": "three", + "From": "Notmuch Test Suite ", + "To": "Notmuch Test Suite ", + "Date": "Fri, 05 Jan 2001 15:43:57 +0000"}, "body": [{"id": 1, + "content-type": "text/plain", "content": "This is just a test message (#5)\n"}]}, + [[{"id": "msg-006@notmuch-test-suite", "match": true, "excluded": false, + "filename": "YYYYY", + "timestamp": 978709437, "date_relative": "2001-01-05", "tags": ["inbox", "unread"], + "headers": {"Subject": "Re: three", + "From": "Notmuch Test Suite ", + "To": "Notmuch Test Suite ", + "Date": "Fri, 05 Jan 2001 15:43:57 +0000"}, "body": [{"id": 1, + "content-type": "text/plain", "content": "This is just a test message (#6)\n"}]}, + []]]]]]' +expected=`echo "$expected" | notmuch_json_show_sanitize` +test_expect_equal_json "$output" "$expected" + +test_begin_subtest "Use last Reference" +add_message '[id]="foo@four.com"' \ + '[subject]="four"' +add_message '[id]="bar@four.com"' \ + '[subject]="not-four"' +add_message '[in-reply-to]=""' \ + '[references]=" "' \ + '[subject]="neither"' +output=$(notmuch show --format=json 'subject:four' | notmuch_json_show_sanitize) +expected='[[[{"id": "foo@four.com", "match": true, "excluded": false, + "filename": "YYYYY", + "timestamp": 978709437, "date_relative": "2001-01-05", "tags": ["inbox", "unread"], + "headers": {"Subject": "four", + "From": "Notmuch Test Suite ", + "To": "Notmuch Test Suite ", + "Date": "Fri, 05 Jan 2001 15:43:57 +0000"}, "body": [{"id": 1, + "content-type": "text/plain", "content": "This is just a test message (#7)\n"}]}, + [[{"id": "msg-009@notmuch-test-suite", "match": false, "excluded": false, + "filename": "YYYYY", + "timestamp": 978709437, "date_relative": "2001-01-05", "tags": ["inbox", "unread"], + "headers": {"Subject": "neither", + "From": "Notmuch Test Suite ", + "To": "Notmuch Test Suite ", + "Date": "Fri, 05 Jan 2001 15:43:57 +0000"}, "body": [{"id": 1, + "content-type": "text/plain", "content": "This is just a test message (#9)\n"}]}, + []]]]], [[{"id": "bar@four.com", "match": true, "excluded": false, + "filename": "YYYYY", + "timestamp": 978709437, "date_relative": "2001-01-05", "tags": ["inbox", "unread"], + "headers": {"Subject": "not-four", + "From": "Notmuch Test Suite ", + "To": "Notmuch Test Suite ", + "Date": "Fri, 05 Jan 2001 15:43:57 +0000"}, "body": [{"id": 1, + "content-type": "text/plain", "content": "This is just a test message (#8)\n"}]}, []]]]' +expected=`echo "$expected" | notmuch_json_show_sanitize` +test_expect_equal_json "$output" "$expected" + + +test_done diff --git a/test/T520-show.sh b/test/T520-show.sh new file mode 100755 index 00000000..0657c993 --- /dev/null +++ b/test/T520-show.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +test_description='"notmuch show"' + +. ./test-lib.sh + +add_email_corpus + +test_begin_subtest "exit code for show invalid query" +notmuch show foo.. +exit_code=$? +test_expect_equal 1 $exit_code + +test_done diff --git a/test/argument-parsing b/test/argument-parsing deleted file mode 100755 index 94e90874..00000000 --- a/test/argument-parsing +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env bash -test_description="argument parsing" -. ./test-lib.sh - -test_begin_subtest "sanity check" -$TEST_DIRECTORY/arg-test pos1 --keyword=one --string=foo pos2 --int=7 > OUTPUT -cat < EXPECTED -keyword 1 -int 7 -string foo -positional arg 1 pos1 -positional arg 2 pos2 -EOF -test_expect_equal_file OUTPUT EXPECTED - -test_done diff --git a/test/atomicity b/test/atomicity deleted file mode 100755 index 1c786fa2..00000000 --- a/test/atomicity +++ /dev/null @@ -1,100 +0,0 @@ -#!/usr/bin/env bash -test_description='atomicity' -. ./test-lib.sh - -# This script tests the effects of killing and restarting "notmuch -# new" at arbitrary points. If notmuch new is properly atomic, the -# final database contents should be the same regardless of when (or -# if) it is killed and restarted. - -if test_require_external_prereq gdb; then - -# Create a maildir structure to also stress flag synchronization - mkdir $MAIL_DIR/cur - mkdir $MAIL_DIR/new - mkdir $MAIL_DIR/tmp - mkdir $MAIL_DIR/.remove-dir - - # Prepare the initial database - generate_message [subject]='Duplicate' [filename]='duplicate:2,' [dir]=cur - generate_message [subject]='Remove' [filename]='remove:2,' [dir]=cur - generate_message [subject]='"Remove duplicate"' [filename]='remove-duplicate:2,' [dir]=cur - cp $MAIL_DIR/cur/remove-duplicate:2, $MAIL_DIR/cur/remove-duplicate-copy:2, - generate_message [subject]='Rename' [filename]='rename:2,' [dir]=cur - generate_message [subject]='"Rename duplicate"' [filename]='rename-duplicate:2,' [dir]=cur - generate_message [subject]='"Move 1"' [filename]='move1:2,' [dir]=cur - generate_message [subject]='"Move 2"' [filename]='move2:2,' [dir]=new - generate_message [subject]='Flag' [filename]='flag:2,' [dir]=cur - generate_message [subject]='"Flag duplicate"' [filename]='flag-duplicate:2,' [dir]=cur - cp $MAIL_DIR/cur/flag-duplicate:2, $MAIL_DIR/cur/flag-duplicate-copy:2,F - generate_message [subject]='"Remove directory"' [filename]='remove-directory:2,' [dir]=.remove-dir - generate_message [subject]='"Remove directory duplicate"' [filename]='remove-directory-duplicate:2,' [dir]=.remove-dir - cp $MAIL_DIR/.remove-dir/remove-directory-duplicate:2, $MAIL_DIR/cur/ - notmuch new > /dev/null - - # Make all maildir changes, but *don't* update the database - generate_message [subject]='Added' [filename]='added:2,' [dir]=cur - cp $MAIL_DIR/cur/duplicate:2, $MAIL_DIR/cur/duplicate-copy:2, - generate_message [subject]='"Add duplicate"' [filename]='add-duplicate:2,' [dir]=cur - generate_message [subject]='"Add duplicate copy"' [filename]='add-duplicate-copy:2,' [dir]=cur - rm $MAIL_DIR/cur/remove:2, - rm $MAIL_DIR/cur/remove-duplicate-copy:2, - mv $MAIL_DIR/cur/rename:2, $MAIL_DIR/cur/renamed:2, - mv $MAIL_DIR/cur/rename-duplicate:2, $MAIL_DIR/cur/renamed-duplicate:2, - mv $MAIL_DIR/cur/move1:2, $MAIL_DIR/new/move1:2, - mv $MAIL_DIR/new/move2:2, $MAIL_DIR/cur/move2:2, - mv $MAIL_DIR/cur/flag:2, $MAIL_DIR/cur/flag:2,F - rm $MAIL_DIR/cur/flag-duplicate-copy:2,F - rm $MAIL_DIR/.remove-dir/remove-directory:2, - rm $MAIL_DIR/.remove-dir/remove-directory-duplicate:2, - rmdir $MAIL_DIR/.remove-dir - - # Prepare a snapshot of the updated maildir. The gdb script will - # update the database in this snapshot as it goes. - cp -a $MAIL_DIR $MAIL_DIR.snap - cp ${NOTMUCH_CONFIG} ${NOTMUCH_CONFIG}.snap - NOTMUCH_CONFIG=${NOTMUCH_CONFIG}.snap notmuch config set database.path $MAIL_DIR.snap - - - - # Execute notmuch new and, at every call to rename, snapshot the - # database, run notmuch new again on the snapshot, and capture the - # results of search. - # - # -tty /dev/null works around a conflict between the 'timeout' wrapper - # and gdb's attempt to control the TTY. - export MAIL_DIR - gdb -tty /dev/null -batch -x $TEST_DIRECTORY/atomicity.gdb notmuch >/dev/null 2>/dev/null - - # Get the final, golden output - notmuch search '*' > expected - - # Check output against golden output - outcount=$(cat outcount) - echo -n > searchall - echo -n > expectall - for ((i = 0; i < $outcount; i++)); do - if ! cmp -s search.$i expected; then - # Find the range of interruptions that match this output - for ((end = $i + 1 ; end < $outcount; end++)); do - if ! cmp -s search.$i search.$end; then - break - fi - done - echo "When interrupted after $test/backtrace.$(expr $i - 1) (abort points $i-$(expr $end - 1))" >> searchall - cat search.$i >> searchall - cat expected >> expectall - echo >> searchall - echo >> expectall - - i=$(expr $end - 1) - fi - done -fi - -test_begin_subtest '"notmuch new" is idempotent under arbitrary aborts' -test_expect_equal_file searchall expectall - -test_expect_success "detected $outcount>10 abort points" "test $outcount -gt 10" - -test_done diff --git a/test/author-order b/test/author-order deleted file mode 100755 index 6ffeffc7..00000000 --- a/test/author-order +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/env bash -test_description="author reordering;" -. ./test-lib.sh - -test_begin_subtest "Adding parent message" -generate_message [body]=findme [id]=new-parent-id [subject]=author-reorder-threadtest '[from]="User "' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' -output=$(NOTMUCH_NEW) -test_expect_equal "$output" "Added 1 new message to the database." - -test_begin_subtest "Adding initial child message" -generate_message [body]=findme "[in-reply-to]=\" [subject]=author-reorder-threadtest '[from]="User1 "' '[date]="Sat, 01 Jan 2000 12:01:00 -0000"' -output=$(NOTMUCH_NEW) -test_expect_equal "$output" "Added 1 new message to the database." - -test_begin_subtest "Adding second child message" -generate_message [body]=findme "[in-reply-to]=\" [subject]=author-reorder-threadtest '[from]="User2 "' '[date]="Sat, 01 Jan 2000 12:02:00 -0000"' -output=$(NOTMUCH_NEW) -test_expect_equal "$output" "Added 1 new message to the database." - -test_begin_subtest "Searching when all three messages match" -output=$(notmuch search findme | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2000-01-01 [3/3] User, User1, User2; author-reorder-threadtest (inbox unread)" - -test_begin_subtest "Searching when two messages match" -output=$(notmuch search User1 or User2 | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2000-01-01 [2/3] User1, User2| User; author-reorder-threadtest (inbox unread)" - -test_begin_subtest "Searching when only one message matches" -output=$(notmuch search User2 | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2000-01-01 [1/3] User2| User, User1; author-reorder-threadtest (inbox unread)" - -test_begin_subtest "Searching when only first message matches" -output=$(notmuch search User | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2000-01-01 [1/3] User| User1, User2; author-reorder-threadtest (inbox unread)" - -test_begin_subtest "Adding duplicate author" -generate_message [body]=findme "[in-reply-to]=\" [subject]=author-reorder-threadtest '[from]="User1 "' '[date]="Sat, 01 Jan 2000 12:03:00 -0000"' -output=$(NOTMUCH_NEW) -test_expect_equal "$output" "Added 1 new message to the database." - -test_begin_subtest "Searching when all four messages match" -output=$(notmuch search findme | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2000-01-01 [4/4] User, User1, User2; author-reorder-threadtest (inbox unread)" - -test_begin_subtest "Adding non-monotonic child message" -generate_message [body]=findme "[in-reply-to]=\" [subject]=author-reorder-threadtest '[from]="User0 "' '[date]="Sat, 01 Jan 2000 11:00:00 -0000"' -output=$(NOTMUCH_NEW) -test_expect_equal "$output" "Added 1 new message to the database." - -test_begin_subtest "Searching non-monotonic messages (oldest-first)" -output=$(notmuch search --sort=oldest-first findme | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2000-01-01 [5/5] User0, User, User1, User2; author-reorder-threadtest (inbox unread)" - -test_begin_subtest "Searching non-monotonic messages (newest-first)" -output=$(notmuch search --sort=newest-first findme | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2000-01-01 [5/5] User0, User, User1, User2; author-reorder-threadtest (inbox unread)" - -test_done diff --git a/test/basic b/test/basic deleted file mode 100755 index 64eb7d74..00000000 --- a/test/basic +++ /dev/null @@ -1,111 +0,0 @@ -#!/usr/bin/env bash -# -# Copyright (c) 2005 Junio C Hamano -# - -test_description='the test framework itself.' - -################################################################ -# It appears that people try to run tests without building... - -if ! test -x ../notmuch -then - echo >&2 'You do not seem to have built notmuch yet.' - exit 1 -fi - -. ./test-lib.sh - -################################################################ -# Test harness -test_expect_success 'success is reported like this' ' - : -' -test_set_prereq HAVEIT -haveit=no -test_expect_success HAVEIT 'test runs if prerequisite is satisfied' ' - test_have_prereq HAVEIT && - haveit=yes -' - -clean=no -test_expect_success 'tests clean up after themselves' ' - test_when_finished clean=yes -' - -cleaner=no -test_expect_code 1 'tests clean up even after a failure' ' - test_when_finished cleaner=yes && - (exit 1) -' - -if test $clean$cleaner != yesyes -then - say "bug in test framework: cleanup commands do not work reliably" - exit 1 -fi - -test_expect_code 2 'failure to clean up causes the test to fail' ' - test_when_finished "(exit 2)" -' - -# 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' $TEST_DIRECTORY/notmuch-test) -tests_in_suite=$(for i in $TESTS; do echo $i; done | sort) -available=$(find "$TEST_DIRECTORY" -maxdepth 1 -type f \ - '(' -perm -100 -o -perm -10 -o -perm -1 ')' \ - ! -name aggregate-results.sh \ - ! -name arg-test \ - ! -name hex-xcode \ - ! -name notmuch-test \ - ! -name parse-time \ - ! -name random-corpus \ - ! -name smtp-dummy \ - ! -name symbol-test \ - ! -name test-verbose \ - | sed 's,.*/,,' | sort) -test_expect_equal "$tests_in_suite" "$available" - -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_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_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 -rm -r $TEST_DIRECTORY/tmp.test-verbose -test_expect_equal "$output" "$expected" - - -################################################################ -# Test mail store prepared in test-lib.sh - -test_expect_success \ - 'test that mail store was created' \ - 'test -d "${MAIL_DIR}"' - - -find "${MAIL_DIR}" -type f -print >should-be-empty -test_expect_success \ - 'mail store should be empty' \ - 'cmp -s /dev/null should-be-empty' - -test_expect_success \ - 'NOTMUCH_CONFIG is set and points to an existing file' \ - 'test -f "${NOTMUCH_CONFIG}"' - -test_expect_success \ - 'PATH is set to this repository' \ - 'test "`echo $PATH|cut -f1 -d: | sed -e 's,/test/valgrind/bin$,,'`" = "`dirname ${TEST_DIRECTORY}`"' - -test_done diff --git a/test/compact b/test/compact deleted file mode 100755 index ac174cec..00000000 --- a/test/compact +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env bash -test_description='"notmuch compact"' -. ./test-lib.sh - -add_message '[subject]=One' -add_message '[subject]=Two' -add_message '[subject]=Three' - -notmuch tag +tag1 \* -notmuch tag +tag2 subject:Two -notmuch tag -tag1 +tag3 subject:Three - -test_expect_success "Running compact" "notmuch compact --backup=${TEST_DIRECTORY}/xapian.old" - -test_begin_subtest "Compact preserves database" -output=$(notmuch search \* | notmuch_search_sanitize) -test_expect_equal "$output" "\ -thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; One (inbox tag1 unread) -thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Two (inbox tag1 tag2 unread) -thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Three (inbox tag3 unread)" - -test_expect_success 'Restoring Backup' \ - 'rm -Rf ${MAIL_DIR}/.notmuch/xapian && - mv ${TEST_DIRECTORY}/xapian.old ${MAIL_DIR}/.notmuch/xapian' - -test_begin_subtest "Checking restored backup" -output=$(notmuch search \* | notmuch_search_sanitize) -test_expect_equal "$output" "\ -thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; One (inbox tag1 unread) -thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Two (inbox tag1 tag2 unread) -thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Three (inbox tag3 unread)" - -test_done diff --git a/test/config b/test/config deleted file mode 100755 index ca4cf330..00000000 --- a/test/config +++ /dev/null @@ -1,83 +0,0 @@ -#!/usr/bin/env bash - -test_description='"notmuch config"' -. ./test-lib.sh - -test_begin_subtest "Get string value" -test_expect_equal "$(notmuch config get user.name)" "Notmuch Test Suite" - -test_begin_subtest "Get list value" -test_expect_equal "$(notmuch config get new.tags)" "\ -unread -inbox" - -test_begin_subtest "Set string value" -notmuch config set foo.string "this is a string value" -test_expect_equal "$(notmuch config get foo.string)" "this is a string value" - -test_begin_subtest "Set string value again" -notmuch config set foo.string "this is another string value" -test_expect_equal "$(notmuch config get foo.string)" "this is another string value" - -test_begin_subtest "Set list value" -notmuch config set foo.list this "is a" "list value" -test_expect_equal "$(notmuch config get foo.list)" "\ -this -is a -list value" - -test_begin_subtest "Set list value again" -notmuch config set foo.list this "is another" "list value" -test_expect_equal "$(notmuch config get foo.list)" "\ -this -is another -list value" - -test_begin_subtest "Remove key" -notmuch config set foo.remove baz -notmuch config set foo.remove -test_expect_equal "$(notmuch config get foo.remove)" "" - -test_begin_subtest "Remove non-existent key" -notmuch config set foo.nonexistent -test_expect_equal "$(notmuch config get foo.nonexistent)" "" - -test_begin_subtest "List all items" -notmuch config set database.path "/canonical/path" -output=$(notmuch config list) -test_expect_equal "$output" "\ -database.path=/canonical/path -user.name=Notmuch Test Suite -user.primary_email=test_suite@notmuchmail.org -user.other_email=test_suite_other@notmuchmail.org;test_suite@otherdomain.org -new.tags=unread;inbox; -new.ignore= -search.exclude_tags= -maildir.synchronize_flags=true -foo.string=this is another string value -foo.list=this;is another;list value;" - -test_begin_subtest "Top level --config=FILE option" -cp "${NOTMUCH_CONFIG}" alt-config -notmuch --config=alt-config config set user.name "Another Name" -test_expect_equal "$(notmuch --config=alt-config config get user.name)" \ - "Another Name" - -test_begin_subtest "Top level --config=FILE option changed the right file" -test_expect_equal "$(notmuch config get user.name)" \ - "Notmuch Test Suite" - -test_begin_subtest "Read config file through a symlink" -ln -s alt-config alt-config-link -test_expect_equal "$(notmuch --config=alt-config-link config get user.name)" \ - "Another Name" - -test_begin_subtest "Write config file through a symlink" -notmuch --config=alt-config-link config set user.name "Link Name" -test_expect_equal "$(notmuch --config=alt-config-link config get user.name)" \ - "Link Name" - -test_begin_subtest "Writing config file through symlink follows symlink" -test_expect_equal "$(readlink alt-config-link)" "alt-config" - -test_done diff --git a/test/count b/test/count deleted file mode 100755 index da86c8cc..00000000 --- a/test/count +++ /dev/null @@ -1,97 +0,0 @@ -#!/usr/bin/env bash -test_description='"notmuch count" for messages and threads' -. ./test-lib.sh - -add_email_corpus - -# Note: The 'wc -l' results below are wrapped in arithmetic evaluation -# $((...)) to strip whitespace. This is for portability, as 'wc -l' -# emits whitespace on some BSD variants. - -test_begin_subtest "message count is the default for notmuch count" -test_expect_equal \ - "$((`notmuch search --output=messages '*' | wc -l`))" \ - "`notmuch count '*'`" - -test_begin_subtest "message count with --output=messages" -test_expect_equal \ - "$((`notmuch search --output=messages '*' | wc -l`))" \ - "`notmuch count --output=messages '*'`" - -test_begin_subtest "thread count with --output=threads" -test_expect_equal \ - "$((`notmuch search --output=threads '*' | wc -l`))" \ - "`notmuch count --output=threads '*'`" - -test_begin_subtest "thread count is the default for notmuch search" -test_expect_equal \ - "$((`notmuch search '*' | wc -l`))" \ - "`notmuch count --output=threads '*'`" - -test_begin_subtest "files count" -test_expect_equal \ - "$((`notmuch search --output=files '*' | wc -l`))" \ - "`notmuch count --output=files '*'`" - -test_begin_subtest "files count for a duplicate message-id" -test_expect_equal \ - "2" \ - "`notmuch count --output=files id:20091117232137.GA7669@griffis1.net`" - -test_begin_subtest "count with no matching messages" -test_expect_equal \ - "0" \ - "`notmuch count --output=messages from:cworth and not from:cworth`" - -test_begin_subtest "count with no matching threads" -test_expect_equal \ - "0" \ - "`notmuch count --output=threads from:cworth and not from:cworth`" - -test_begin_subtest "message count is the default for batch count" -notmuch count --batch >OUTPUT <EXPECTED -notmuch count --output=messages from:cworth >>EXPECTED -test_expect_equal_file EXPECTED OUTPUT - -test_begin_subtest "batch message count" -notmuch count --batch --output=messages >OUTPUT <EXPECTED -notmuch count --output=messages >>EXPECTED -notmuch count --output=messages tag:inbox >>EXPECTED -test_expect_equal_file EXPECTED OUTPUT - -test_begin_subtest "batch thread count" -notmuch count --batch --output=threads >OUTPUT <EXPECTED -notmuch count --output=threads from:cworth >>EXPECTED -notmuch count --output=threads from:cworth and not from:cworth >>EXPECTED -notmuch count --output=threads foo >>EXPECTED -test_expect_equal_file EXPECTED OUTPUT - -test_begin_subtest "batch message count with input file" -cat >INPUT <OUTPUT -notmuch count --output=messages from:cworth >EXPECTED -notmuch count --output=messages >>EXPECTED -notmuch count --output=messages tag:inbox >>EXPECTED -test_expect_equal_file EXPECTED OUTPUT - - -test_done diff --git a/test/crypto b/test/crypto deleted file mode 100755 index 477b397e..00000000 --- a/test/crypto +++ /dev/null @@ -1,360 +0,0 @@ -#!/usr/bin/env bash - -# TODO: -# - decryption/verification with signer key not available -# - verification of signatures from expired/revoked keys - -test_description='PGP/MIME signature verification and decryption' -. ./test-lib.sh - -add_gnupg_home () -{ - local output - [ -d ${GNUPGHOME} ] && return - mkdir -m 0700 "$GNUPGHOME" - 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 - elif (gpg --debug-quick-random --version >/dev/null 2>&1) ; then - echo debug-quick-random >> "$GNUPGHOME"/gpg.conf - fi - echo no-emit-version >> "$GNUPGHOME"/gpg.conf -} - -################################################## - -add_gnupg_home -# get key fingerprint -FINGERPRINT=$(gpg --no-tty --list-secret-keys --with-colons --fingerprint | grep '^fpr:' | cut -d: -f10) - -test_expect_success 'emacs delivery of signed message' \ -'emacs_fcc_message \ - "test signed message 001" \ - "This is a test signed message." \ - "(mml-secure-message-sign)"' - -test_begin_subtest "signature verification" -output=$(notmuch show --format=json --verify subject:"test signed message 001" \ - | notmuch_json_show_sanitize \ - | sed -e 's|"created": [1234567890]*|"created": 946728000|') -expected='[[[{"id": "XXXXX", - "match": true, - "excluded": false, - "filename": "YYYYY", - "timestamp": 946728000, - "date_relative": "2000-01-01", - "tags": ["inbox","signed"], - "headers": {"Subject": "test signed message 001", - "From": "Notmuch Test Suite ", - "To": "test_suite@notmuchmail.org", - "Date": "Sat, 01 Jan 2000 12:00:00 +0000"}, - "body": [{"id": 1, - "sigstatus": [{"status": "good", - "fingerprint": "'$FINGERPRINT'", - "created": 946728000}], - "content-type": "multipart/signed", - "content": [{"id": 2, - "content-type": "text/plain", - "content": "This is a test signed message.\n"}, - {"id": 3, - "content-type": "application/pgp-signature", - "content-length": 280}]}]}, - []]]]' -test_expect_equal_json \ - "$output" \ - "$expected" - -test_begin_subtest "signature verification with full owner trust" -# give the key full owner trust -echo "${FINGERPRINT}:6:" | gpg --no-tty --import-ownertrust >>"$GNUPGHOME"/trust.log 2>&1 -gpg --no-tty --check-trustdb >>"$GNUPGHOME"/trust.log 2>&1 -output=$(notmuch show --format=json --verify subject:"test signed message 001" \ - | notmuch_json_show_sanitize \ - | sed -e 's|"created": [1234567890]*|"created": 946728000|') -expected='[[[{"id": "XXXXX", - "match": true, - "excluded": false, - "filename": "YYYYY", - "timestamp": 946728000, - "date_relative": "2000-01-01", - "tags": ["inbox","signed"], - "headers": {"Subject": "test signed message 001", - "From": "Notmuch Test Suite ", - "To": "test_suite@notmuchmail.org", - "Date": "Sat, 01 Jan 2000 12:00:00 +0000"}, - "body": [{"id": 1, - "sigstatus": [{"status": "good", - "fingerprint": "'$FINGERPRINT'", - "created": 946728000, - "userid": " Notmuch Test Suite (INSECURE!)"}], - "content-type": "multipart/signed", - "content": [{"id": 2, - "content-type": "text/plain", - "content": "This is a test signed message.\n"}, - {"id": 3, - "content-type": "application/pgp-signature", - "content-length": 280}]}]}, - []]]]' -test_expect_equal_json \ - "$output" \ - "$expected" - -test_begin_subtest "signature verification with signer key unavailable" -# move the gnupghome temporarily out of the way -mv "${GNUPGHOME}"{,.bak} -output=$(notmuch show --format=json --verify subject:"test signed message 001" \ - | notmuch_json_show_sanitize \ - | sed -e 's|"created": [1234567890]*|"created": 946728000|') -expected='[[[{"id": "XXXXX", - "match": true, - "excluded": false, - "filename": "YYYYY", - "timestamp": 946728000, - "date_relative": "2000-01-01", - "tags": ["inbox","signed"], - "headers": {"Subject": "test signed message 001", - "From": "Notmuch Test Suite ", - "To": "test_suite@notmuchmail.org", - "Date": "Sat, 01 Jan 2000 12:00:00 +0000"}, - "body": [{"id": 1, - "sigstatus": [{"status": "error", - "keyid": "'$(echo $FINGERPRINT | cut -c 25-)'", - "errors": 2}], - "content-type": "multipart/signed", - "content": [{"id": 2, - "content-type": "text/plain", - "content": "This is a test signed message.\n"}, - {"id": 3, - "content-type": "application/pgp-signature", - "content-length": 280}]}]}, - []]]]' -test_expect_equal_json \ - "$output" \ - "$expected" -mv "${GNUPGHOME}"{.bak,} - -# create a test encrypted message with attachment -cat <TESTATTACHMENT -This is a test file. -EOF -test_expect_success 'emacs delivery of encrypted message with attachment' \ -'emacs_fcc_message \ - "test encrypted message 001" \ - "This is a test encrypted message.\n" \ - "(mml-attach-file \"TESTATTACHMENT\") (mml-secure-message-encrypt)"' - -test_begin_subtest "decryption, --format=text" -output=$(notmuch show --format=text --decrypt subject:"test encrypted message 001" \ - | notmuch_show_sanitize_all \ - | sed -e 's|"created": [1234567890]*|"created": 946728000|') -expected=' message{ id:XXXXX depth:0 match:1 excluded:0 filename:XXXXX - header{ -Notmuch Test Suite (2000-01-01) (encrypted inbox) -Subject: test encrypted message 001 -From: Notmuch Test Suite -To: test_suite@notmuchmail.org -Date: Sat, 01 Jan 2000 12:00:00 +0000 - header} - body{ - part{ ID: 1, Content-type: multipart/encrypted - part{ ID: 2, Content-type: application/pgp-encrypted -Non-text part: application/pgp-encrypted - part} - part{ ID: 3, Content-type: multipart/mixed - part{ ID: 4, Content-type: text/plain -This is a test encrypted message. - part} - attachment{ ID: 5, Filename: TESTATTACHMENT, Content-type: application/octet-stream -Non-text part: application/octet-stream - attachment} - part} - part} - body} - message}' -test_expect_equal \ - "$output" \ - "$expected" - -test_begin_subtest "decryption, --format=json" -output=$(notmuch show --format=json --decrypt subject:"test encrypted message 001" \ - | notmuch_json_show_sanitize \ - | sed -e 's|"created": [1234567890]*|"created": 946728000|') -expected='[[[{"id": "XXXXX", - "match": true, - "excluded": false, - "filename": "YYYYY", - "timestamp": 946728000, - "date_relative": "2000-01-01", - "tags": ["encrypted","inbox"], - "headers": {"Subject": "test encrypted message 001", - "From": "Notmuch Test Suite ", - "To": "test_suite@notmuchmail.org", - "Date": "Sat, 01 Jan 2000 12:00:00 +0000"}, - "body": [{"id": 1, - "encstatus": [{"status": "good"}], - "sigstatus": [], - "content-type": "multipart/encrypted", - "content": [{"id": 2, - "content-type": "application/pgp-encrypted", - "content-length": 11}, - {"id": 3, - "content-type": "multipart/mixed", - "content": [{"id": 4, - "content-type": "text/plain", - "content": "This is a test encrypted message.\n"}, - {"id": 5, - "content-type": "application/octet-stream", - "content-length": 28, - "content-transfer-encoding": "base64", - "filename": "TESTATTACHMENT"}]}]}]}, - []]]]' -test_expect_equal_json \ - "$output" \ - "$expected" - -test_begin_subtest "decryption, --format=json, --part=4" -output=$(notmuch show --format=json --part=4 --decrypt subject:"test encrypted message 001" \ - | notmuch_json_show_sanitize \ - | sed -e 's|"created": [1234567890]*|"created": 946728000|') -expected='{"id": 4, - "content-type": "text/plain", - "content": "This is a test encrypted message.\n"}' -test_expect_equal_json \ - "$output" \ - "$expected" - -test_begin_subtest "decrypt attachment (--part=5 --format=raw)" -notmuch show \ - --format=raw \ - --part=5 \ - --decrypt \ - subject:"test encrypted message 001" >OUTPUT -test_expect_equal_file OUTPUT TESTATTACHMENT - -test_begin_subtest "decryption failure with missing key" -mv "${GNUPGHOME}"{,.bak} -# The length of the encrypted attachment varies so must be normalized. -output=$(notmuch show --format=json --decrypt subject:"test encrypted message 001" \ - | notmuch_json_show_sanitize \ - | sed -e 's|"created": [1234567890]*|"created": 946728000|' \ - | sed -e 's|"content-length": 6[1234567890]*|"content-length": 652|') -expected='[[[{"id": "XXXXX", - "match": true, - "excluded": false, - "filename": "YYYYY", - "timestamp": 946728000, - "date_relative": "2000-01-01", - "tags": ["encrypted","inbox"], - "headers": {"Subject": "test encrypted message 001", - "From": "Notmuch Test Suite ", - "To": "test_suite@notmuchmail.org", - "Date": "Sat, 01 Jan 2000 12:00:00 +0000"}, - "body": [{"id": 1, - "encstatus": [{"status": "bad"}], - "content-type": "multipart/encrypted", - "content": [{"id": 2, - "content-type": "application/pgp-encrypted", - "content-length": 11}, - {"id": 3, - "content-type": "application/octet-stream", - "content-length": 652}]}]}, - []]]]' -test_expect_equal_json \ - "$output" \ - "$expected" -mv "${GNUPGHOME}"{.bak,} - -test_expect_success 'emacs delivery of encrypted + signed message' \ -'emacs_fcc_message \ - "test encrypted message 002" \ - "This is another test encrypted message.\n" \ - "(mml-secure-message-sign-encrypt)"' - -test_begin_subtest "decryption + signature verification" -output=$(notmuch show --format=json --decrypt subject:"test encrypted message 002" \ - | notmuch_json_show_sanitize \ - | sed -e 's|"created": [1234567890]*|"created": 946728000|') -expected='[[[{"id": "XXXXX", - "match": true, - "excluded": false, - "filename": "YYYYY", - "timestamp": 946728000, - "date_relative": "2000-01-01", - "tags": ["encrypted","inbox"], - "headers": {"Subject": "test encrypted message 002", - "From": "Notmuch Test Suite ", - "To": "test_suite@notmuchmail.org", - "Date": "Sat, 01 Jan 2000 12:00:00 +0000"}, - "body": [{"id": 1, - "encstatus": [{"status": "good"}], - "sigstatus": [{"status": "good", - "fingerprint": "'$FINGERPRINT'", - "created": 946728000, - "userid": " Notmuch Test Suite (INSECURE!)"}], - "content-type": "multipart/encrypted", - "content": [{"id": 2, - "content-type": "application/pgp-encrypted", - "content-length": 11}, - {"id": 3, - "content-type": "text/plain", - "content": "This is another test encrypted message.\n"}]}]}, - []]]]' -test_expect_equal_json \ - "$output" \ - "$expected" - -test_begin_subtest "reply to encrypted message" -output=$(notmuch reply --decrypt subject:"test encrypted message 002" \ - | grep -v -e '^In-Reply-To:' -e '^References:') -expected='From: Notmuch Test Suite -Subject: Re: test encrypted message 002 - -On 01 Jan 2000 12:00:00 -0000, Notmuch Test Suite wrote: -> This is another test encrypted message.' -test_expect_equal \ - "$output" \ - "$expected" - -test_begin_subtest "signature verification with revoked key" -# generate revocation certificate and load it to revoke key -echo "y -1 -Notmuch Test Suite key revocation (automated) $(date '+%F_%T%z') - -y - -" \ - | gpg --no-tty --quiet --command-fd 0 --armor --gen-revoke "0x${FINGERPRINT}!" 2>/dev/null \ - | gpg --no-tty --quiet --import -output=$(notmuch show --format=json --verify subject:"test signed message 001" \ - | notmuch_json_show_sanitize \ - | sed -e 's|"created": [1234567890]*|"created": 946728000|') -expected='[[[{"id": "XXXXX", - "match": true, - "excluded": false, - "filename": "YYYYY", - "timestamp": 946728000, - "date_relative": "2000-01-01", - "tags": ["inbox","signed"], - "headers": {"Subject": "test signed message 001", - "From": "Notmuch Test Suite ", - "To": "test_suite@notmuchmail.org", - "Date": "Sat, 01 Jan 2000 12:00:00 +0000"}, - "body": [{"id": 1, - "sigstatus": [{"status": "error", - "keyid": "6D92612D94E46381", - "errors": 8}], - "content-type": "multipart/signed", - "content": [{"id": 2, - "content-type": "text/plain", - "content": "This is a test signed message.\n"}, - {"id": 3, - "content-type": "application/pgp-signature", - "content-length": 280}]}]}, - []]]]' -test_expect_equal_json \ - "$output" \ - "$expected" - -test_done diff --git a/test/dump-restore b/test/dump-restore deleted file mode 100755 index 0004438d..00000000 --- a/test/dump-restore +++ /dev/null @@ -1,293 +0,0 @@ -#!/usr/bin/env bash -test_description="\"notmuch dump\" and \"notmuch restore\"" -. ./test-lib.sh - -add_email_corpus - -test_expect_success 'Dumping all tags' \ - 'generate_message && - notmuch new && - notmuch dump > dump.expected' - -# The use of from:cworth is rather arbitrary: it matches some of the -# email corpus' messages, but not all of them. - -test_expect_success 'Dumping all tags II' \ - 'notmuch tag +ABC +DEF -- from:cworth && - notmuch dump > dump-ABC_DEF.expected && - ! cmp dump.expected dump-ABC_DEF.expected' - -test_expect_success 'Clearing all tags' \ - 'sed -e "s/(\([^(]*\))$/()/" < dump.expected > clear.expected && - notmuch restore --input=clear.expected && - notmuch dump > clear.actual && - test_cmp clear.expected clear.actual' - -test_expect_success 'Accumulate original tags' \ - 'notmuch tag +ABC +DEF -- from:cworth && - notmuch restore --accumulate < dump.expected && - notmuch dump > dump.actual && - test_cmp dump-ABC_DEF.expected dump.actual' - -test_expect_success 'Restoring original tags' \ - 'notmuch restore --input=dump.expected && - notmuch dump > dump.actual && - test_cmp dump.expected dump.actual' - -test_expect_success 'Restore with nothing to do' \ - 'notmuch restore < dump.expected && - notmuch dump > dump.actual && - test_cmp dump.expected dump.actual' - -test_expect_success 'Accumulate with existing tags' \ - 'notmuch restore --accumulate --input=dump.expected && - notmuch dump > dump.actual && - test_cmp dump.expected dump.actual' - -test_expect_success 'Accumulate with no tags' \ - 'notmuch restore --accumulate < clear.expected && - notmuch dump > dump.actual && - test_cmp dump.expected dump.actual' - -test_expect_success 'Accumulate with new tags' \ - 'notmuch restore --input=dump.expected && - notmuch restore --accumulate --input=dump-ABC_DEF.expected && - notmuch dump > OUTPUT.$test_count && - notmuch restore --input=dump.expected && - test_cmp dump-ABC_DEF.expected OUTPUT.$test_count' - -# notmuch restore currently only considers the first argument. -test_expect_success 'Invalid restore invocation' \ - 'test_must_fail notmuch restore --input=dump.expected another_one' - -test_begin_subtest "dump --output=outfile" -notmuch dump --output=dump-outfile.actual -test_expect_equal_file dump.expected dump-outfile.actual - -test_begin_subtest "dump --output=outfile --" -notmuch dump --output=dump-1-arg-dash.actual -- -test_expect_equal_file dump.expected dump-1-arg-dash.actual - -# Note, we assume all messages from cworth have a message-id -# containing cworth.org - -grep 'cworth[.]org' dump.expected > dump-cworth.expected - -test_begin_subtest "dump -- from:cworth" -notmuch dump -- from:cworth > dump-dash-cworth.actual -test_expect_equal_file dump-cworth.expected dump-dash-cworth.actual - -test_begin_subtest "dump --output=outfile from:cworth" -notmuch dump --output=dump-outfile-cworth.actual from:cworth -test_expect_equal_file dump-cworth.expected dump-outfile-cworth.actual - -test_begin_subtest "dump --output=outfile -- from:cworth" -notmuch dump --output=dump-outfile-dash-inbox.actual -- from:cworth -test_expect_equal_file dump-cworth.expected dump-outfile-dash-inbox.actual - -test_begin_subtest "Check for a safe set of message-ids" -notmuch search --output=messages from:cworth | sed s/^id:// > EXPECTED -notmuch search --output=messages from:cworth | sed s/^id:// |\ - $TEST_DIRECTORY/hex-xcode --direction=encode > OUTPUT -test_expect_equal_file OUTPUT EXPECTED - -test_begin_subtest "format=batch-tag, dump sanity check." -notmuch dump --format=sup from:cworth | cut -f1 -d' ' | \ - sort > EXPECTED.$test_count -notmuch dump --format=batch-tag from:cworth | sed 's/^.*-- id://' | \ - sort > OUTPUT.$test_count -test_expect_equal_file EXPECTED.$test_count OUTPUT.$test_count - -test_begin_subtest "format=batch-tag, # round-trip" -notmuch dump --format=sup | sort > EXPECTED.$test_count -notmuch dump --format=batch-tag | notmuch restore --format=batch-tag -notmuch dump --format=sup | sort > OUTPUT.$test_count -test_expect_equal_file EXPECTED.$test_count OUTPUT.$test_count - -test_begin_subtest "format=batch-tag, # blank lines and comments" -notmuch dump --format=batch-tag| sort > EXPECTED.$test_count -notmuch restore < OUTPUT.$test_count -test_expect_equal_file EXPECTED.$test_count OUTPUT.$test_count - -test_begin_subtest "format=batch-tag, # reverse-round-trip empty tag" -cat <EXPECTED.$test_count -+ -- id:20091117232137.GA7669@griffis1.net -EOF -notmuch restore --format=batch-tag < EXPECTED.$test_count -notmuch dump --format=batch-tag id:20091117232137.GA7669@griffis1.net > OUTPUT.$test_count -test_expect_equal_file EXPECTED.$test_count OUTPUT.$test_count - -tag1='comic_swear=$&^%$^%\\//-+$^%$' -enc1=$($TEST_DIRECTORY/hex-xcode --direction=encode "$tag1") - -tag2=$(printf 'this\n tag\t has\n spaces') -enc2=$($TEST_DIRECTORY/hex-xcode --direction=encode "$tag2") - -enc3='%c3%91%c3%a5%c3%b0%c3%a3%c3%a5%c3%a9-%c3%8f%c3%8a' -tag3=$($TEST_DIRECTORY/hex-xcode --direction=decode $enc3) - -notmuch dump --format=batch-tag > BACKUP - -notmuch tag +"$tag1" +"$tag2" +"$tag3" -inbox -unread "*" - -# initial segment of file used for several tests below. -cat < comments-and-blanks -# this is a comment - -# next line has leading whitespace - - -EOF - -test_begin_subtest 'restoring empty file is not an error' -notmuch restore < /dev/null 2>OUTPUT.$test_count -cp /dev/null EXPECTED -test_expect_equal_file EXPECTED OUTPUT.$test_count - -test_begin_subtest 'file of comments and blank lines is not an error' -notmuch restore --input=comments-and-blanks -ret_val=$? -test_expect_equal "$ret_val" "0" - -cp comments-and-blanks leading-comments-blanks-batch-tag -echo "+some_tag -- id:yun1vjwegii.fsf@aiko.keithp.com" \ - >> leading-comments-blanks-batch-tag - -test_begin_subtest 'detect format=batch-tag with leading comments and blanks' -notmuch restore --input=leading-comments-blanks-batch-tag -notmuch search --output=tags id:yun1vjwegii.fsf@aiko.keithp.com > OUTPUT.$test_count -echo "some_tag" > EXPECTED -test_expect_equal_file EXPECTED OUTPUT.$test_count - -cp comments-and-blanks leading-comments-blanks-sup -echo "yun1vjwegii.fsf@aiko.keithp.com (another_tag)" \ - >> leading-comments-blanks-sup - -test_begin_subtest 'detect format=sup with leading comments and blanks' -notmuch restore --input=leading-comments-blanks-sup -notmuch search --output=tags id:yun1vjwegii.fsf@aiko.keithp.com > OUTPUT.$test_count -echo "another_tag" > EXPECTED -test_expect_equal_file EXPECTED OUTPUT.$test_count - -test_begin_subtest 'format=batch-tag, round trip with strange tags' -notmuch dump --format=batch-tag > EXPECTED.$test_count -notmuch dump --format=batch-tag | notmuch restore --format=batch-tag -notmuch dump --format=batch-tag > OUTPUT.$test_count -test_expect_equal_file EXPECTED.$test_count OUTPUT.$test_count - -test_begin_subtest 'format=batch-tag, checking encoded output' -notmuch dump --format=batch-tag -- from:cworth |\ - awk "{ print \"+$enc1 +$enc2 +$enc3 -- \" \$5 }" > EXPECTED.$test_count -notmuch dump --format=batch-tag -- from:cworth > OUTPUT.$test_count -test_expect_equal_file EXPECTED.$test_count OUTPUT.$test_count - -test_begin_subtest 'restoring sane tags' -notmuch restore --format=batch-tag < BACKUP -notmuch dump --format=batch-tag > OUTPUT.$test_count -test_expect_equal_file BACKUP OUTPUT.$test_count - -test_begin_subtest 'format=batch-tag, restore=auto' -notmuch dump --format=batch-tag > EXPECTED.$test_count -notmuch tag -inbox -unread "*" -notmuch restore --format=auto < EXPECTED.$test_count -notmuch dump --format=batch-tag > OUTPUT.$test_count -test_expect_equal_file EXPECTED.$test_count OUTPUT.$test_count - -test_begin_subtest 'format=sup, restore=auto' -notmuch dump --format=sup > EXPECTED.$test_count -notmuch tag -inbox -unread "*" -notmuch restore --format=auto < EXPECTED.$test_count -notmuch dump --format=sup > OUTPUT.$test_count -test_expect_equal_file EXPECTED.$test_count OUTPUT.$test_count - -test_begin_subtest 'format=batch-tag, restore=default' -notmuch dump --format=batch-tag > EXPECTED.$test_count -notmuch tag -inbox -unread "*" -notmuch restore < EXPECTED.$test_count -notmuch dump --format=batch-tag > OUTPUT.$test_count -test_expect_equal_file EXPECTED.$test_count OUTPUT.$test_count - -test_begin_subtest 'format=sup, restore=default' -notmuch dump --format=sup > EXPECTED.$test_count -notmuch tag -inbox -unread "*" -notmuch restore < EXPECTED.$test_count -notmuch dump --format=sup > OUTPUT.$test_count -test_expect_equal_file EXPECTED.$test_count OUTPUT.$test_count - -test_begin_subtest 'restore: checking error messages' -notmuch restore <OUTPUT -# the next line has a space - -a -+0 -+a +b -# trailing whitespace -+a +b -+c +d -- -# this is a harmless comment, do not yell about it. - -# the previous line was blank; also no yelling please -+%zz -- id:whatever -+e +f id:" -+e +f tag:abc -# the next non-comment line should report an an empty tag error for -# batch tagging, but not for restore -+ +e -- id:20091117232137.GA7669@griffis1.net -# valid id, but warning about missing message -+e id:missing_message_id -# exercise parser -+e -- id:some)stuff -+e -- id:some stuff -+e -- id:some"stuff -+e -- id:"a_message_id_with""_a_quote" -+e -- id:"a message id with spaces" -+e -- id:an_id_with_leading_and_trailing_ws \ - -EOF - -cat < EXPECTED -Warning: cannot parse query: a (skipping) -Warning: no query string [+0] -Warning: no query string [+a +b] -Warning: missing query string [+a +b ] -Warning: no query string after -- [+c +d --] -Warning: hex decoding of tag %zz failed [+%zz -- id:whatever] -Warning: cannot parse query: id:" (skipping) -Warning: not an id query: tag:abc (skipping) -Warning: cannot apply tags to missing message: missing_message_id -Warning: cannot parse query: id:some)stuff (skipping) -Warning: cannot parse query: id:some stuff (skipping) -Warning: cannot apply tags to missing message: some"stuff -Warning: cannot apply tags to missing message: a_message_id_with"_a_quote -Warning: cannot apply tags to missing message: a message id with spaces -Warning: cannot apply tags to missing message: an_id_with_leading_and_trailing_ws -EOF - -test_expect_equal_file EXPECTED OUTPUT - -test_begin_subtest 'roundtripping random message-ids and tags' - - ${TEST_DIRECTORY}/random-corpus --config-path=${NOTMUCH_CONFIG} \ - --num-messages=100 - - notmuch dump --format=batch-tag| \ - sort > EXPECTED.$test_count - - notmuch tag +this_tag_is_very_unlikely_to_be_random '*' - - notmuch restore --format=batch-tag < EXPECTED.$test_count - - notmuch dump --format=batch-tag| \ - sort > OUTPUT.$test_count - -test_expect_equal_file EXPECTED.$test_count OUTPUT.$test_count - -test_done - -# Note the database is "poisoned" for sup format at this point. diff --git a/test/emacs b/test/emacs deleted file mode 100755 index 863219d9..00000000 --- a/test/emacs +++ /dev/null @@ -1,952 +0,0 @@ -#!/usr/bin/env bash - -test_description="emacs interface" -. ./test-lib.sh - -EXPECTED=$TEST_DIRECTORY/emacs.expected-output - -add_email_corpus - -test_begin_subtest "Basic notmuch-hello view in emacs" -test_emacs '(notmuch-hello) - (test-output)' -test_expect_equal_file OUTPUT $EXPECTED/notmuch-hello - -test_begin_subtest "Saved search with 0 results" -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 '(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) - (test-output)' -test_expect_equal_file OUTPUT $EXPECTED/notmuch-search-tag-inbox - -test_begin_subtest "Incremental parsing of search results" -test_emacs "(ad-enable-advice 'notmuch-search-process-filter 'around 'pessimal) - (ad-activate 'notmuch-search-process-filter) - (notmuch-search \"tag:inbox\") - (notmuch-test-wait) - (ad-disable-advice 'notmuch-search-process-filter 'around 'pessimal) - (ad-activate 'notmuch-search-process-filter) - (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 (1- (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\") - (test-output)" -test_expect_equal_file OUTPUT $EXPECTED/notmuch-show-thread-maildir-storage - -test_begin_subtest "Basic notmuch-show view in emacs default indentation" -maildir_storage_thread=$(notmuch search --output=threads id:20091117190054.GU3165@dottiness.seas.harvard.edu) -test_emacs "(let ((notmuch-show-indent-messages-width 1)) - (notmuch-show \"$maildir_storage_thread\") - (test-output))" -test_expect_equal_file OUTPUT $EXPECTED/notmuch-show-thread-maildir-storage - -test_begin_subtest "Basic notmuch-show view in emacs without indentation" -maildir_storage_thread=$(notmuch search --output=threads id:20091117190054.GU3165@dottiness.seas.harvard.edu) -test_emacs "(let ((notmuch-show-indent-messages-width 0)) - (notmuch-show \"$maildir_storage_thread\") - (test-output))" -test_expect_equal_file OUTPUT $EXPECTED/notmuch-show-thread-maildir-storage-without-indentation - -test_begin_subtest "Basic notmuch-show view in emacs with fourfold indentation" -maildir_storage_thread=$(notmuch search --output=threads id:20091117190054.GU3165@dottiness.seas.harvard.edu) -test_emacs "(let ((notmuch-show-indent-messages-width 4)) - (notmuch-show \"$maildir_storage_thread\") - (test-output))" -test_expect_equal_file OUTPUT $EXPECTED/notmuch-show-thread-maildir-storage-with-fourfold-indentation - -test_begin_subtest "notmuch-show for message with invalid From" -add_message "[subject]=\"message-with-invalid-from\"" \ - "[from]=\"\\\"Invalid \\\" From\\\" \"" -thread=$(notmuch search --output=threads subject:message-with-invalid-from) -test_emacs "(notmuch-show \"$thread\") - (test-output \"OUTPUT.raw\")" -cat <EXPECTED -"Invalid " (2001-01-05) (inbox) -Subject: message-with-invalid-from -To: Notmuch Test Suite -Date: GENERATED_DATE - -This is just a test message (#1) -EOF -notmuch_date_sanitize < OUTPUT.raw > OUTPUT -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) - (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) - (execute-kbd-macro \"+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) - (execute-kbd-macro \"-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 (large query)" -# We use a long query to force us into batch mode and use a funny tag -# that requires escaping for batch tagging. -test_emacs "(notmuch-tag (concat \"$os_x_darwin_thread\" \" or \" (make-string notmuch-tag-argument-limit ?x)) (list \"+tag-from-%-large-query\"))" -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-%-large-query unread)" -notmuch tag -tag-from-%-large-query $os_x_darwin_thread - -test_begin_subtest "notmuch-show: add single tag to single message" -test_emacs "(notmuch-show \"$os_x_darwin_thread\") - (execute-kbd-macro \"+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 "notmuch-show: remove single tag from single message" -test_emacs "(notmuch-show \"$os_x_darwin_thread\") - (execute-kbd-macro \"-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 "notmuch-show: add multiple tags to single message" -test_emacs "(notmuch-show \"$os_x_darwin_thread\") - (execute-kbd-macro \"+tag1-from-show-view +tag2-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 tag1-from-show-view tag2-from-show-view unread)" - -test_begin_subtest "notmuch-show: remove multiple tags from single message" -test_emacs "(notmuch-show \"$os_x_darwin_thread\") - (execute-kbd-macro \"-tag1-from-show-view -tag2-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) - (execute-kbd-macro "+search-add") - (execute-kbd-macro "+search-remove") - (execute-kbd-macro "-search-remove") - (notmuch-show "id:\"123..456@example\"") - (notmuch-test-wait) - (execute-kbd-macro "+show-add") - (execute-kbd-macro "+show-remove") - (execute-kbd-macro "-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 "Message with quote in Message-Id:" -add_message '[id]="\"quote\"@example"' '[subject]="Message with quote in Message-Id"' -test_emacs '(notmuch-search "subject:\"Message with quote\"") - (notmuch-test-wait) - (execute-kbd-macro "+search-add") - (notmuch-search-show-thread) - (notmuch-test-wait) - (execute-kbd-macro "+show-add")' -output=$(notmuch search 'id:"""quote""@example"' | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Message with quote in Message-Id (inbox search-add show-add)" - -test_begin_subtest "Sending a message via (fake) SMTP" -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: ,' \ - -e s',^\(Content-Type: text/plain\); charset=us-ascii$,\1,' < sent_message >OUTPUT -cat <EXPECTED -From: Notmuch Test Suite -To: user@example.com -Subject: Testing message sent via SMTP -Date: 01 Jan 2000 12:00:00 -0000 -User-Agent: Notmuch/XXX Emacs/XXX -Message-ID: -MIME-Version: 1.0 -Content-Type: text/plain - -This is a test that messages are sent via SMTP -EOF -test_expect_equal_file OUTPUT EXPECTED - -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 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 "(let ((notmuch-fcc-dirs nil)) - (notmuch-mua-mail) - (test-output))" -cat <EXPECTED -From: Notmuch Test Suite -To: -Subject: ---text follows this line-- -EOF -test_expect_equal_file OUTPUT EXPECTED - -# Make another FCC maildir specific for the next test -mkdir -p mail/sent-string/cur -mkdir -p mail/sent-string/new -mkdir -p mail/sent-string/tmp - -test_begin_subtest "notmuch-fcc-dirs set to a string" -test_emacs "(let ((notmuch-fcc-dirs \"sent-string\")) - (notmuch-mua-mail) - (test-output))" -cat <EXPECTED -From: Notmuch Test Suite -To: -Subject: -Fcc: ${MAIL_DIR}/sent-string ---text follows this line-- -EOF -test_expect_equal_file OUTPUT EXPECTED - -# Make more FCC maildirs specific for the next test -mkdir -p mail/sent-list-match/cur -mkdir -p mail/sent-list-match/new -mkdir -p mail/sent-list-match/tmp -mkdir -p mail/failure/cur -mkdir -p mail/failure/new -mkdir -p mail/failure/tmp - -test_begin_subtest "notmuch-fcc-dirs set to a list (with match)" -test_emacs "(let ((notmuch-fcc-dirs - '((\"notmuchmail.org\" . \"sent-list-match\") - (\".*\" . \"failure\")))) - (notmuch-mua-mail) - (test-output))" -cat <EXPECTED -From: Notmuch Test Suite -To: -Subject: -Fcc: ${MAIL_DIR}/sent-list-match ---text follows this line-- -EOF -test_expect_equal_file OUTPUT EXPECTED - -# Make another FCC maildir specific for the next test -mkdir -p mail/sent-list-catch-all/cur -mkdir -p mail/sent-list-catch-all/new -mkdir -p mail/sent-list-catch-all/tmp - -test_begin_subtest "notmuch-fcc-dirs set to a list (catch-all)" -test_emacs "(let ((notmuch-fcc-dirs - '((\"example.com\" . \"failure\") - (\".*\" . \"sent-list-catch-all\")))) - (notmuch-mua-mail) - (test-output))" -cat <EXPECTED -From: Notmuch Test Suite -To: -Subject: -Fcc: ${MAIL_DIR}/sent-list-catch-all ---text follows this line-- -EOF -test_expect_equal_file OUTPUT EXPECTED - -test_begin_subtest "notmuch-fcc-dirs set to a list (no match)" -test_emacs "(let ((notmuch-fcc-dirs - '((\"example.com\" . \"failure\") - (\"nomatchhere.net\" . \"failure\")))) - (notmuch-mua-mail) - (test-output))" -cat <EXPECTED -From: Notmuch Test Suite -To: -Subject: ---text follows this line-- -EOF -test_expect_equal_file OUTPUT EXPECTED - -test_begin_subtest "Reply within emacs" -test_emacs '(let ((message-hidden-headers ''())) - (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: /' OUTPUT -sed -i -e 's/^References: <.*>$/References: /' OUTPUT -sed -i -e 's,^User-Agent: Notmuch/.* Emacs/.*,User-Agent: Notmuch/XXX Emacs/XXX,' OUTPUT -cat <EXPECTED -From: Notmuch Test Suite -To: user@example.com -Subject: Re: Testing message sent via SMTP -In-Reply-To: -Fcc: ${MAIL_DIR}/sent -References: -User-Agent: Notmuch/XXX Emacs/XXX ---text follows this line-- -Notmuch Test Suite writes: - -> This is a test that messages are sent via SMTP -EOF -test_expect_equal_file OUTPUT EXPECTED - -test_begin_subtest "Reply from alternate address within emacs" -add_message '[from]="Sender "' \ - [to]=test_suite_other@notmuchmail.org - -test_emacs "(let ((message-hidden-headers '())) - (notmuch-search \"id:\\\"${gen_msg_id}\\\"\") - (notmuch-test-wait) - (notmuch-search-reply-to-thread) - (test-output))" -sed -i -e 's,^User-Agent: Notmuch/.* Emacs/.*,User-Agent: Notmuch/XXX Emacs/XXX,' OUTPUT -cat <EXPECTED -From: Notmuch Test Suite -To: Sender -Subject: Re: ${test_subtest_name} -In-Reply-To: <${gen_msg_id}> -Fcc: ${MAIL_DIR}/sent -References: <${gen_msg_id}> -User-Agent: Notmuch/XXX Emacs/XXX ---text follows this line-- -Sender writes: - -> This is just a test message (#${gen_msg_cnt}) -EOF -test_expect_equal_file OUTPUT EXPECTED - -test_begin_subtest "Reply from address in named group list within emacs" -add_message '[from]="Sender "' \ - '[to]=group:test_suite@notmuchmail.org,someone@example.com\;' \ - [cc]=test_suite_other@notmuchmail.org - -test_emacs "(let ((message-hidden-headers '())) - (notmuch-search \"id:\\\"${gen_msg_id}\\\"\") - (notmuch-test-wait) - (notmuch-search-reply-to-thread) - (test-output))" -sed -i -e 's,^User-Agent: Notmuch/.* Emacs/.*,User-Agent: Notmuch/XXX Emacs/XXX,' OUTPUT -cat <EXPECTED -From: Notmuch Test Suite -To: Sender , someone@example.com -Subject: Re: ${test_subtest_name} -In-Reply-To: <${gen_msg_id}> -Fcc: ${MAIL_DIR}/sent -References: <${gen_msg_id}> -User-Agent: Notmuch/XXX Emacs/XXX ---text follows this line-- -Sender writes: - -> This is just a test message (#${gen_msg_cnt}) -EOF -test_expect_equal_file OUTPUT EXPECTED - -test_begin_subtest "Reply within emacs to a multipart/mixed message" -test_emacs '(let ((message-hidden-headers ''())) - (notmuch-show "id:20091118002059.067214ed@hikari") - (notmuch-show-reply) - (test-output))' -sed -i -e 's,^User-Agent: Notmuch/.* Emacs/.*,User-Agent: Notmuch/XXX Emacs/XXX,' OUTPUT -cat <EXPECTED -From: Notmuch Test Suite -To: Adrian Perez de Castro , notmuch@notmuchmail.org -Subject: Re: [notmuch] Introducing myself -In-Reply-To: <20091118002059.067214ed@hikari> -Fcc: ${MAIL_DIR}/sent -References: <20091118002059.067214ed@hikari> -User-Agent: Notmuch/XXX Emacs/XXX ---text follows this line-- -Adrian Perez de Castro writes: - -> Hello to all, -> -> I have just heard about Not Much today in some random Linux-related news -> site (LWN?), my name is Adrian Perez and I work as systems administrator -> (although I can do some code as well :P). I have always thought that the -> ideas behind Sup were great, but after some time using it, I got tired of -> the oddities that it has. I also do not like doing things like having to -> install Ruby just for reading and sorting mails. Some time ago I thought -> about doing something like Not Much and in fact I played a bit with the -> Python+Xapian and the Python+Whoosh combinations, because I find relaxing -> to code things in Python when I am not working and also it is installed -> by default on most distribution. I got to have some mailboxes indexed and -> basic searching working a couple of months ago. Lately I have been very -> busy and had no time for coding, and them... boom! Not Much appears -- and -> it is almost exactly what I was trying to do, but faster. I have been -> playing a bit with Not Much today, and I think it has potential. -> -> Also, I would like to share one idea I had in mind, that you might find -> interesting: One thing I have found very annoying is having to re-tag my -> mail when the indexes get b0rked (it happened a couple of times to me while -> using Sup), so I was planning to mails as read/unread and adding the tags -> not just to the index, but to the mail text itself, e.g. by adding a -> "X-Tags" header field or by reusing the "Keywords" one. This way, the index -> could be totally recreated by re-reading the mail directories, and this -> would also allow to a tools like OfflineIMAP [1] to get the mails into a -> local maildir, tagging and indexing the mails with the e-mail reader and -> then syncing back the messages with the "X-Tags" header to the IMAP server. -> This would allow to use the mail reader from a different computer and still -> have everything tagged finely. -> -> Best regards, -> -> -> --- -> [1] http://software.complete.org/software/projects/show/offlineimap -> -> -- -> Adrian Perez de Castro -> Igalia - Free Software Engineering -> _______________________________________________ -> notmuch mailing list -> notmuch@notmuchmail.org -> http://notmuchmail.org/mailman/listinfo/notmuch -EOF -test_expect_equal_file OUTPUT EXPECTED - -test_begin_subtest "Reply within emacs to a multipart/alternative message" -test_emacs '(let ((message-hidden-headers ''())) - (notmuch-show "id:cf0c4d610911171136h1713aa59w9cf9aa31f052ad0a@mail.gmail.com") - (notmuch-show-reply) - (test-output))' -sed -i -e 's,^User-Agent: Notmuch/.* Emacs/.*,User-Agent: Notmuch/XXX Emacs/XXX,' OUTPUT -cat <EXPECTED -From: Notmuch Test Suite -To: Alex Botero-Lowry , notmuch@notmuchmail.org -Subject: Re: [notmuch] preliminary FreeBSD support -In-Reply-To: -Fcc: ${MAIL_DIR}/sent -References: -User-Agent: Notmuch/XXX Emacs/XXX ---text follows this line-- -Alex Botero-Lowry writes: - -> I saw the announcement this morning, and was very excited, as I had been -> hoping sup would be turned into a library, -> since I like the concept more than the UI (I'd rather an emacs interface). -> -> I did a preliminary compile which worked out fine, but -> sysconf(_SC_SC_GETPW_R_SIZE_MAX) returns -1 on -> FreeBSD, so notmuch_config_open segfaulted. -> -> Attached is a patch that supplies a default buffer size of 64 in cases where -> -1 is returned. -> -> http://www.opengroup.org/austin/docs/austin_328.txt - seems to indicate this -> is acceptable behavior, -> and http://mail-index.netbsd.org/pkgsrc-bugs/2006/06/07/msg016808.htmlspecifically -> uses 64 as the -> buffer size. -> _______________________________________________ -> notmuch mailing list -> notmuch@notmuchmail.org -> http://notmuchmail.org/mailman/listinfo/notmuch -EOF -test_expect_equal_file OUTPUT EXPECTED - -test_begin_subtest "Reply within emacs to an html-only message" -add_message '[content-type]="text/html"' \ - '[body]="Hi,
This is an HTML test message.

OK?"' -test_emacs "(let ((message-hidden-headers '()) (mm-text-html-renderer 'html2text)) - (notmuch-show \"id:${gen_msg_id}\") - (notmuch-show-reply) - (test-output))" -sed -i -e 's,^User-Agent: Notmuch/.* Emacs/.*,User-Agent: Notmuch/XXX Emacs/XXX,' OUTPUT -cat <EXPECTED -From: Notmuch Test Suite -To: -Subject: Re: Reply within emacs to an html-only message -In-Reply-To: <${gen_msg_id}> -Fcc: ${MAIL_DIR}/sent -References: <${gen_msg_id}> -User-Agent: Notmuch/XXX Emacs/XXX ---text follows this line-- -Notmuch Test Suite writes: - -> Hi,This is an HTML test message.OK? -EOF -test_expect_equal_file OUTPUT EXPECTED - -test_begin_subtest "Quote MML tags in reply" -message_id='test-emacs-mml-quoting@message.id' -add_message [id]="$message_id" \ - "[subject]='$test_subtest_name'" \ - '[body]="<#part disposition=inline>"' -test_emacs "(let ((message-hidden-headers '())) - (notmuch-show \"id:$message_id\") - (notmuch-show-reply) - (test-output))" -sed -i -e 's,^User-Agent: Notmuch/.* Emacs/.*,User-Agent: Notmuch/XXX Emacs/XXX,' OUTPUT -cat <EXPECTED -From: Notmuch Test Suite -To: -Subject: Re: Quote MML tags in reply -In-Reply-To: -Fcc: ${MAIL_DIR}/sent -References: -User-Agent: Notmuch/XXX Emacs/XXX ---text follows this line-- -Notmuch Test Suite writes: - -> <#!part disposition=inline> -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 -test_emacs '(let ((standard-input "\"attachment1.gz\"")) - (notmuch-show "id:cf0c4d610911171136h1713aa59w9cf9aa31f052ad0a@mail.gmail.com") - (notmuch-show-save-attachments))' -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 -test_emacs '(let ((standard-input "\"attachment2.gz\"")) - (notmuch-show "id:cf0c4d610911171136h1713aa59w9cf9aa31f052ad0a@mail.gmail.com") - (search-forward "0001-Deal-with") - (notmuch-show-save-part))' -test_expect_equal_file attachment2.gz "$EXPECTED/attachment" - -test_begin_subtest "Save 8bit attachment from within emacs using notmuch-show-save-attachments" - -add_message '[subject]="Attachment with 8bit chars"' \ - '[header]="MIME-Version: 1.0"' \ - '[content-type]="multipart/mixed; boundary=\"abcd\""' \ - '[body]="--abcd -Content-Type: text/plain - -Attachment follows: - ---abcd -Content-Type: application/octet-stream; name=\"sample\" -Content-Transfer-Encoding: 8bit -Content-Disposition: attachment; filename=\"sample\" - -“¡ Hey ! It compiles ¡ Ship it !” - ---abcd-- -"' -test_emacs '(notmuch-show "id:'"${gen_msg_id}"'") - (delete-file "OUTPUT") - (let ((standard-input "\"OUTPUT\"")) - (notmuch-show-save-attachments))' - -test_expect_equal "$(cat OUTPUT)" '“¡ Hey ! It compiles ¡ Ship it !”' - -test_begin_subtest "View raw message within emacs" -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" -maildir_storage_thread=$(notmuch search --output=threads id:20091117190054.GU3165@dottiness.seas.harvard.edu) -test_emacs "(notmuch-show \"$maildir_storage_thread\") - (search-forward \"Click/Enter to show.\") - (button-activate (button-at (point))) - (search-backward \"Click/Enter to hide.\") - (button-activate (button-at (point))) - (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" -add_message '[subject]="The problem with top-posting"' \ - [id]=top-post-target \ - '[body]="A: Because it messes up the order in which people normally read text. -Q: Why is top-posting such a bad thing? -A: Top-posting. -Q: What is the most annoying thing in e-mail?"' -add_message '[from]="Top Poster "' \ - [in-reply-to]=top-post-target \ - [references]=top-post-target \ - '[subject]="Re: The problem with top-posting"' \ - '[body]="Thanks for the advice! I will be sure to put it to good use. - --Top Poster - ------ Original Message ----- -From: Notmuch Test Suite -To: Notmuch Test Suite -Sent: Fri, 05 Jan 2001 15:43:57 +0000 -Subject: The problem with top-posting - -Q: Why is top-posting such a bad thing? -A: Top-posting. -Q: What is the most annoying thing in e-mail?"' -test_emacs "(notmuch-show \"top-posting\") - (test-visible-output \"OUTPUT.raw\")" -echo "Notmuch Test Suite (2001-01-05) (inbox) -Subject: The problem with top-posting -To: Notmuch Test Suite -Date: GENERATED_DATE - -A: Because it messes up the order in which people normally read text. -Q: Why is top-posting such a bad thing? -A: Top-posting. -Q: What is the most annoying thing in e-mail? -Top Poster (2001-01-05) (inbox unread) -Subject: Re: The problem with top-posting -To: Notmuch Test Suite -Date: GENERATED_DATE - -Thanks for the advice! I will be sure to put it to good use. - --Top Poster - -[ 9-line hidden original message. Click/Enter to show. ]" > EXPECTED -notmuch_date_sanitize < OUTPUT.raw > OUTPUT -test_expect_equal_file OUTPUT EXPECTED - -test_begin_subtest "Hiding message in notmuch-show view" -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" -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_begin_subtest "notmuch-show: show message headers" -test_emacs \ - '(let ((notmuch-message-headers '\''("Subject" "To" "Cc" "Date")) - (notmuch-message-headers-visible t)) - (notmuch-show "id:f35dbb950911171438k5df6eb56k77b6c0944e2e79ae@mail.gmail.com") - (test-visible-output))' -test_expect_equal_file OUTPUT $EXPECTED/notmuch-show-message-with-headers-visible - -test_begin_subtest "notmuch-show: hide message headers" -test_emacs \ - '(let ((notmuch-message-headers '\''("Subject" "To" "Cc" "Date")) - (notmuch-message-headers-visible nil)) - (notmuch-show "id:f35dbb950911171438k5df6eb56k77b6c0944e2e79ae@mail.gmail.com") - (test-visible-output))' -test_expect_equal_file OUTPUT $EXPECTED/notmuch-show-message-with-headers-hidden - -test_begin_subtest "notmuch-show: hide message headers (w/ notmuch-show-toggle-visibility-headers)" -test_emacs \ - '(let ((notmuch-message-headers '\''("Subject" "To" "Cc" "Date")) - (notmuch-message-headers-visible t)) - (notmuch-show "id:f35dbb950911171438k5df6eb56k77b6c0944e2e79ae@mail.gmail.com") - (notmuch-show-toggle-visibility-headers) - (test-visible-output))' -test_expect_equal_file OUTPUT $EXPECTED/notmuch-show-message-with-headers-hidden - -test_begin_subtest "notmuch-show: collapse all messages in thread" -test_emacs '(notmuch-show "id:f35dbb950911171435ieecd458o853c873e35f4be95@mail.gmail.com") - (let ((current-prefix-arg t)) - (notmuch-show-open-or-close-all) - (test-visible-output))' -test_expect_equal_file OUTPUT $EXPECTED/notmuch-show-thread-with-all-messages-collapsed - -test_begin_subtest "notmuch-show: uncollapse all messages in thread" -test_emacs '(notmuch-show "id:f35dbb950911171435ieecd458o853c873e35f4be95@mail.gmail.com") - (notmuch-show-open-or-close-all) - (test-visible-output)' -test_expect_equal_file OUTPUT $EXPECTED/notmuch-show-thread-with-all-messages-uncollapsed - -test_begin_subtest "Stashing in notmuch-show" -add_message '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' \ - '[from]="Some One "' \ - '[to]="Some One Else "' \ - '[cc]="Notmuch "' \ - '[subject]="Stash my stashables"' \ - '[id]="bought"' \ - '[body]="Unable to stash body. Where did you get it in the first place?!?"' -notmuch tag +stashtest id:${gen_msg_id} -test_emacs '(notmuch-show "id:\"bought\"") - (notmuch-show-stash-date) - (notmuch-show-stash-from) - (notmuch-show-stash-to) - (notmuch-show-stash-cc) - (notmuch-show-stash-subject) - (notmuch-show-stash-message-id) - (notmuch-show-stash-message-id-stripped) - (notmuch-show-stash-tags) - (notmuch-show-stash-filename) - (notmuch-show-stash-mlarchive-link "Gmane") - (notmuch-show-stash-mlarchive-link "MARC") - (notmuch-show-stash-mlarchive-link "Mail Archive, The") - (switch-to-buffer - (generate-new-buffer "*test-stashing*")) - (dotimes (i 12) - (yank) - (insert "\n") - (rotate-yank-pointer 1)) - (reverse-region (point-min) (point-max)) - (test-output)' -cat <EXPECTED -Sat, 01 Jan 2000 12:00:00 +0000 -Some One -Some One Else -Notmuch -Stash my stashables -id:bought -bought -inbox,stashtest -${gen_msg_filename} -http://mid.gmane.org/bought -http://marc.info/?i=bought -http://mail-archive.com/search?l=mid&q=bought -EOF -test_expect_equal_file OUTPUT EXPECTED - -test_begin_subtest "Stashing in notmuch-search" -test_emacs '(notmuch-search "id:\"bought\"") - (notmuch-test-wait) - (notmuch-search-stash-thread-id) - (switch-to-buffer - (generate-new-buffer "*test-stashing*")) - (yank) - (test-output)' -sed -i -e 's/^thread:.*$/thread:XXX/' OUTPUT -test_expect_equal "$(cat OUTPUT)" "thread:XXX" - -test_begin_subtest 'notmuch-show-advance-and-archive with invisible signature' -message1='id:20091118010116.GC25380@dottiness.seas.harvard.edu' -message2='id:1258491078-29658-1-git-send-email-dottedmag@dottedmag.net' -test_emacs "(notmuch-show \"$message2\") - (test-output \"EXPECTED\")" -test_emacs "(notmuch-search \"$message1 or $message2\") - (notmuch-test-wait) - (notmuch-search-show-thread) - (goto-char (point-max)) - (redisplay) - (notmuch-show-advance-and-archive) - (test-output)" -test_expect_equal_file OUTPUT EXPECTED - -test_begin_subtest "Refresh show buffer" -test_emacs '(notmuch-show "id:f35dbb950911171438k5df6eb56k77b6c0944e2e79ae@mail.gmail.com") - (test-visible-output "EXPECTED") - (notmuch-show-refresh-view) - (test-visible-output)' -test_expect_equal_file OUTPUT EXPECTED - -test_begin_subtest "Refresh modified show buffer" -test_emacs '(notmuch-show "id:f35dbb950911171438k5df6eb56k77b6c0944e2e79ae@mail.gmail.com") - (notmuch-show-toggle-message) - (notmuch-show-next-message) - (notmuch-show-toggle-message) - (test-visible-output "EXPECTED") - (notmuch-show-refresh-view) - (test-visible-output)' -test_expect_equal_file OUTPUT EXPECTED - -test_begin_subtest "Do not call notmuch for non-inlinable application/mpeg parts" -id='message-with-application/mpeg-attachment@notmuchmail.org' -emacs_fcc_message \ - 'Message with application/mpeg attachment' \ - '' \ - "(message-goto-eoh) - (insert \"Message-ID: <$id>\n\") - (message-goto-body) - (mml-insert-part \"application/mpeg\") - (insert \"a fake mp3 file\")" -notmuch_counter_reset -test_emacs "(let ((notmuch-command \"$notmuch_counter_command\")) - (notmuch-show \"id:$id\"))" -test_expect_equal $(notmuch_counter_value) 1 - -test_begin_subtest "Do not call notmuch for non-inlinable audio/mpeg parts" -id='message-with-audio/mpeg-attachment@notmuchmail.org' -emacs_fcc_message \ - 'Message with audio/mpeg attachment' \ - '' \ - "(message-goto-eoh) - (insert \"Message-ID: <$id>\n\") - (message-goto-body) - (mml-insert-part \"audio/mpeg\") - (insert \"a fake mp3 file\")" -notmuch_counter_reset -test_emacs "(let ((notmuch-command \"$notmuch_counter_command\")) - (notmuch-show \"id:$id\"))" -test_expect_equal $(notmuch_counter_value) 1 - -test_begin_subtest "notmuch-hello-mode hook is called" -counter=$(test_emacs \ - '(let ((notmuch-hello-mode-hook-counter 0)) - (kill-buffer "*notmuch-hello*") - (notmuch-hello) - notmuch-hello-mode-hook-counter)' -) -test_expect_equal "$counter" 1 - -test_begin_subtest "notmuch-hello-mode hook is not called on updates" -counter=$(test_emacs \ - '(let ((notmuch-hello-mode-hook-counter 0)) - (kill-buffer "*notmuch-hello*") - (notmuch-hello) - (notmuch-hello-update) - notmuch-hello-mode-hook-counter)' -) -test_expect_equal "$counter" 1 - -test_begin_subtest "notmuch-hello-refresh hook is called" -counter=$(test_emacs \ - '(let ((notmuch-hello-refresh-hook-counter 0)) - (kill-buffer "*notmuch-hello*") - (notmuch-hello) - notmuch-hello-refresh-hook-counter)' -) -test_expect_equal "$counter" 1 - -test_begin_subtest "notmuch-hello-refresh hook is called on updates" -counter=$(test_emacs \ - '(let ((notmuch-hello-refresh-hook-counter 0)) - (kill-buffer "*notmuch-hello*") - (notmuch-hello) - (notmuch-hello-update) - notmuch-hello-refresh-hook-counter)' -) -test_expect_equal "$counter" 2 - - -add_message '[subject]="HTML mail with images"' \ - '[content-type]="multipart/related; boundary=abcd"' \ - '[body]="--abcd -Content-Type: text/html - - smiley - ---abcd -Content-Type: image/gif -Content-Transfer-Encoding: base64 -Content-ID: <330@goomoji.gmail> - -R0lGODlhDAAMAKIFAF5LAP/zxAAAANyuAP/gaP///wAAAAAAACH5BAEAAAUALAAAAAAMAAwAAAMl -WLPcGjDKFYi9lxKBOaGcF35DhWHamZUW0K4mAbiwWtuf0uxFAgA7 ---abcd--"' -test_emacs "(let ((mm-text-html-renderer - (if (assq 'shr mm-text-html-renderer-alist) - 'shr 'html2text))) - (notmuch-show \"id:${gen_msg_id}\")) - (test-output)" > /dev/null -# Different Emacs versions and renderers give very different results, -# so just check that something reasonable showed up. We first cat the -# output so the test framework will print it if the test fails. -test_expect_success "Rendering HTML mail with images" \ - 'cat OUTPUT && grep -q smiley OUTPUT' - - -test_begin_subtest "Search handles subprocess error exit codes" -cat > notmuch_fail < notmuch_fail <&2 -echo This is another warning >&2 -exit 0 -EOF -chmod a+x notmuch_fail -test_emacs "(let ((notmuch-command \"$PWD/notmuch_fail\")) - (with-current-buffer \"*Messages*\" (erase-buffer)) - (with-current-buffer (get-buffer-create \"*Notmuch errors*\") - (erase-buffer)) - (notmuch-search \"tag:inbox\") - (notmuch-test-wait) - (with-current-buffer \"*Messages*\" - (test-output \"MESSAGES\")) - (with-current-buffer \"*Notmuch errors*\" - (test-output \"ERROR\")) - (test-output))" -sed -i -e 's/^\[.*\]$/[XXX]/' ERROR -test_expect_equal "$(cat OUTPUT; echo ---; cat MESSAGES; echo ---; cat ERROR)" "\ -End of search results. ---- -This is a warning (see *Notmuch errors* for more details) ---- -[XXX] -This is a warning -This is another warning" - -test_begin_subtest "Search thread tag operations are race-free" -add_message '[subject]="Search race test"' -gen_msg_id_1=$gen_msg_id -generate_message '[in-reply-to]="<'$gen_msg_id_1'>"' \ - '[references]="<'$gen_msg_id_1'>"' \ - '[subject]="Search race test two"' -test_emacs '(notmuch-search "subject:\"search race test\"") - (notmuch-test-wait) - (notmuch-poll) - (execute-kbd-macro "+search-thread-race-tag")' -output=$(notmuch search --output=messages 'tag:search-thread-race-tag') -test_expect_equal "$output" "id:$gen_msg_id_1" - -test_begin_subtest "Search global tag operations are race-free" -generate_message '[in-reply-to]="<'$gen_msg_id_1'>"' \ - '[references]="<'$gen_msg_id_1'>"' \ - '[subject]="Re: Search race test"' -test_emacs '(notmuch-search "subject:\"search race test\" -subject:two") - (notmuch-test-wait) - (notmuch-poll) - (execute-kbd-macro "*+search-global-race-tag")' -output=$(notmuch search --output=messages 'tag:search-global-race-tag') -test_expect_equal "$output" "id:$gen_msg_id_1" - -test_done diff --git a/test/emacs-address-cleaning b/test/emacs-address-cleaning deleted file mode 100755 index 04723467..00000000 --- a/test/emacs-address-cleaning +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env bash - -test_description="emacs address cleaning" -. ./test-lib.sh - -test_begin_subtest "notmuch-test-address-clean part 1" -test_emacs_expect_t '(notmuch-test-address-cleaning-1)' - -test_begin_subtest "notmuch-test-address-clean part 2" -test_emacs_expect_t '(notmuch-test-address-cleaning-2)' - -test_begin_subtest "notmuch-test-address-clean part 3" -test_emacs_expect_t '(notmuch-test-address-cleaning-3)' - -test_done diff --git a/test/emacs-hello b/test/emacs-hello deleted file mode 100755 index f7296166..00000000 --- a/test/emacs-hello +++ /dev/null @@ -1,69 +0,0 @@ -#!/usr/bin/env bash - -test_description="emacs notmuch-hello view" -. ./test-lib.sh - -EXPECTED=$TEST_DIRECTORY/emacs.expected-output - -add_email_corpus - -test_begin_subtest "User-defined section with inbox tag" -test_emacs "(let ((notmuch-hello-sections - (list (lambda () (notmuch-hello-insert-searches - \"Test\" '((\"inbox\" . \"tag:inbox\"))))))) - (notmuch-hello) - (test-output))" -test_expect_equal_file OUTPUT $EXPECTED/notmuch-hello-new-section - -test_begin_subtest "User-defined section with empty, hidden entry" -test_emacs "(let ((notmuch-hello-sections - (list (lambda () (notmuch-hello-insert-searches - \"Test-with-empty\" - '((\"inbox\" . \"tag:inbox\") - (\"doesnotexist\" . \"tag:doesnotexist\")) - :hide-empty-searches t))))) - (notmuch-hello) - (test-output))" -test_expect_equal_file OUTPUT $EXPECTED/notmuch-hello-section-with-empty - -test_begin_subtest "User-defined section, unread tag filtered out" -test_emacs "(let ((notmuch-hello-sections - (list (lambda () (notmuch-hello-insert-tags-section - \"Test-with-filtered\" - :hide-tags '(\"unread\")))))) - (notmuch-hello) - (test-output))" -test_expect_equal_file OUTPUT $EXPECTED/notmuch-hello-section-hidden-tag - -test_begin_subtest "User-defined section, different query for counts" -test_emacs "(let ((notmuch-hello-sections - (list (lambda () (notmuch-hello-insert-tags-section - \"Test-with-counts\" - :filter-count \"tag:signed\"))))) - (notmuch-hello) - (test-output))" -test_expect_equal_file OUTPUT $EXPECTED/notmuch-hello-section-counts - -test_begin_subtest "Empty custom tags section" -test_emacs "(let* ((widget (widget-create 'notmuch-hello-tags-section)) - (notmuch-hello-sections (list (widget-value widget)))) - (notmuch-hello) - (test-output))" -test_expect_equal_file OUTPUT $EXPECTED/notmuch-hello-empty-custom-tags-section - -test_begin_subtest "Empty custom queries section" -test_emacs "(let* ((widget (widget-create 'notmuch-hello-query-section)) - (notmuch-hello-sections (list (widget-value widget)))) - (notmuch-hello) - (test-output))" -test_expect_equal_file OUTPUT $EXPECTED/notmuch-hello-empty-custom-queries-section - -test_begin_subtest "Column alignment for tag/queries with long names" -tag=a-very-long-tag # length carefully calculated for 80 characters window width -notmuch tag +$tag '*' -test_emacs '(notmuch-hello) - (test-output)' -notmuch tag -$tag '*' -test_expect_equal_file OUTPUT $EXPECTED/notmuch-hello-long-names - -test_done diff --git a/test/emacs-large-search-buffer b/test/emacs-large-search-buffer deleted file mode 100755 index 8b1251fe..00000000 --- a/test/emacs-large-search-buffer +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env bash -test_description="Emacs with large search results buffer" -. ./test-lib.sh - -x=xxxxxxxxxx # 10 -x=$x$x$x$x$x$x$x$x$x$x # 100 -x=$x$x$x$x$x$x$x$x$x # 900 - -# We generate a long subject here (over 900 bytes) so that the emacs -# search results get large quickly. With 30 such messages we should -# cross several 4kB page boundaries and see the bug. -n=30 -for i in $(seq 1 $n); do - # Roughly 100B2 KiB per message. That is, we need two messages in order to - # exceed the typical size of the pipe buffer (4 KiB on commodity systems). - generate_message '[subject]="$x $i of $n"' -done - -notmuch new > /dev/null - -test_begin_subtest "Ensure that emacs doesn't drop results" -notmuch search '*' > EXPECTED -sed -i -e 's/^thread:[0-9a-f]* //' -e 's/;//' -e 's/xx*/[BLOB]/' EXPECTED -echo 'End of search results.' >> 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 EXPECTED - -test_done diff --git a/test/emacs-show b/test/emacs-show deleted file mode 100755 index 2a3a5356..00000000 --- a/test/emacs-show +++ /dev/null @@ -1,201 +0,0 @@ -#!/usr/bin/env bash - -test_description="emacs notmuch-show view" -. ./test-lib.sh - -EXPECTED=$TEST_DIRECTORY/emacs-show.expected-output - -add_email_corpus - -test_begin_subtest "Hiding Original Message region at beginning of a message" -message_id='OriginalMessageHiding.1@notmuchmail.org' -add_message \ - [id]="$message_id" \ - '[subject]="Hiding Original Message region at beginning of a message"' \ - '[body]="-----Original Message----- -Text here."' - -cat <EXPECTED -Notmuch Test Suite (2001-01-05) (inbox) -Subject: Hiding Original Message region at beginning of a message -To: Notmuch Test Suite -Date: GENERATED_DATE - -[ 2-line hidden original message. Click/Enter to show. ] -EOF - -test_emacs "(notmuch-show \"id:$message_id\") - (test-visible-output \"OUTPUT.raw\")" -notmuch_date_sanitize < OUTPUT.raw > OUTPUT -test_expect_equal_file OUTPUT EXPECTED - -test_begin_subtest "Bare subject #1" -output=$(test_emacs '(notmuch-show-strip-re "Re: subject")') -test_expect_equal "$output" '"subject"' - -test_begin_subtest "Bare subject #2" -output=$(test_emacs '(notmuch-show-strip-re "re:Re: re: Re: re:subject")') -test_expect_equal "$output" '"subject"' - -test_begin_subtest "Bare subject #3" -output=$(test_emacs '(notmuch-show-strip-re "the cure: fix the regexp")') -test_expect_equal "$output" '"the cure: fix the regexp"' - -test_begin_subtest "don't process cryptographic MIME parts" -test_emacs '(let ((notmuch-crypto-process-mime nil)) - (notmuch-show "id:20091117203301.GV3165@dottiness.seas.harvard.edu") - (test-visible-output))' -test_expect_equal_file OUTPUT $EXPECTED/notmuch-show-process-crypto-mime-parts-off - -test_begin_subtest "process cryptographic MIME parts" -test_emacs '(let ((notmuch-crypto-process-mime t)) - (notmuch-show "id:20091117203301.GV3165@dottiness.seas.harvard.edu") - (test-visible-output))' -test_expect_equal_file OUTPUT $EXPECTED/notmuch-show-process-crypto-mime-parts-on - -test_begin_subtest "process cryptographic MIME parts (w/ notmuch-show-toggle-process-crypto)" -test_emacs '(let ((notmuch-crypto-process-mime nil)) - (notmuch-show "id:20091117203301.GV3165@dottiness.seas.harvard.edu") - (notmuch-show-toggle-process-crypto) - (test-visible-output))' -test_expect_equal_file OUTPUT $EXPECTED/notmuch-show-process-crypto-mime-parts-on - -test_begin_subtest "notmuch-show: don't elide non-matching messages" -test_emacs '(let ((notmuch-show-only-matching-messages nil)) - (notmuch-search "from:lars@seas.harvard.edu and subject:\"Maildir storage\"") - (notmuch-test-wait) - (notmuch-search-show-thread) - (notmuch-test-wait) - (test-visible-output))' -test_expect_equal_file OUTPUT $EXPECTED/notmuch-show-elide-non-matching-messages-off - -test_begin_subtest "notmuch-show: elide non-matching messages" -test_emacs '(let ((notmuch-show-only-matching-messages t)) - (notmuch-search "from:lars@seas.harvard.edu and subject:\"Maildir storage\"") - (notmuch-test-wait) - (notmuch-search-show-thread) - (notmuch-test-wait) - (test-visible-output))' -test_expect_equal_file OUTPUT $EXPECTED/notmuch-show-elide-non-matching-messages-on - -test_begin_subtest "notmuch-show: elide non-matching messages (w/ notmuch-show-toggle-elide-non-matching)" -test_emacs '(let ((notmuch-show-only-matching-messages nil)) - (notmuch-search "from:lars@seas.harvard.edu and subject:\"Maildir storage\"") - (notmuch-test-wait) - (notmuch-search-show-thread) - (notmuch-test-wait) - (notmuch-show-toggle-elide-non-matching) - (test-visible-output))' -test_expect_equal_file OUTPUT $EXPECTED/notmuch-show-elide-non-matching-messages-on - -test_begin_subtest "notmuch-show: elide non-matching messages (w/ prefix arg to notmuch-show)" -test_emacs '(let ((notmuch-show-only-matching-messages nil)) - (notmuch-search "from:lars@seas.harvard.edu and subject:\"Maildir storage\"") - (notmuch-test-wait) - (notmuch-search-show-thread t) - (notmuch-test-wait) - (test-visible-output))' -test_expect_equal_file OUTPUT $EXPECTED/notmuch-show-elide-non-matching-messages-on - -test_begin_subtest "notmuch-show: disable indentation of thread content (w/ notmuch-show-toggle-thread-indentation)" -test_emacs '(notmuch-search "from:lars@seas.harvard.edu and subject:\"Maildir storage\"") - (notmuch-test-wait) - (notmuch-search-show-thread) - (notmuch-test-wait) - (notmuch-show-toggle-thread-indentation) - (test-visible-output)' -test_expect_equal_file OUTPUT $EXPECTED/notmuch-show-indent-thread-content-off - -test_begin_subtest "id buttonization" -add_message '[body]=" -id:abc -id:abc.def. id:abc,def, id:abc;def; id:abc:def: -id:foo@bar.?baz? id:foo@bar!.baz! -(id:foo@bar.baz) [id:foo@bar.baz] -id:foo@bar.baz... -id:2+2=5 -id:=_-:/.[]@$%+ -id:abc)def -id:ab\"c def -id:\"abc\"def -id:\"ab\"\"c\"def -id:\"ab c\"def -id:\"abc\".def -id:\"abc -\" -id:) -id: -cid:xxx -mid:abc mid:abc/def -mid:abc%20def -mid:abc. mid:abc, mid:abc;"' -test_emacs '(notmuch-show "id:'$gen_msg_id'") - (notmuch-test-mark-links) - (test-visible-output "OUTPUT.raw")' -cat <EXPECTED -Notmuch Test Suite (2001-01-05) (inbox) -Subject: id buttonization -To: Notmuch Test Suite -Date: GENERATED_DATE - -<> -<>. <>, <>; <>: -<>? <>! -(<>) [<>] -<>... -<> -<> -<>)def -<> def -<>def -<>def -<>def -<>.def -id:"abc -" -id:) -id: -cid:xxx -<> <> -<> -<>. <>, <>; -EOF -notmuch_date_sanitize < OUTPUT.raw > OUTPUT -test_expect_equal_file OUTPUT EXPECTED - - -test_begin_subtest "Show handles subprocess errors" -cat > notmuch_fail <&2 -exit 1 -EOF -chmod a+x notmuch_fail -test_emacs "(let ((notmuch-command \"$PWD/notmuch_fail\")) - (with-current-buffer \"*Messages*\" (erase-buffer)) - (condition-case err - (notmuch-show \"*\") - (error (message \"%s\" (second err)))) - (notmuch-test-wait) - (with-current-buffer \"*Messages*\" - (test-output \"MESSAGES\")) - (with-current-buffer \"*Notmuch errors*\" - (test-output \"ERROR\")) - (test-output))" -test_expect_equal "$(notmuch_emacs_error_sanitize notmuch_fail OUTPUT MESSAGES ERROR)" "\ -=== OUTPUT === -=== MESSAGES === -This is an error (see *Notmuch errors* for more details) -=== ERROR === -[XXX] -This is an error -command: YYY/notmuch_fail show --format\\=sexp --format-version\\=1 --exclude\\=false \\' \\* \\' -exit status: 1 -stderr: -This is an error -stdout: -This is output" - - -test_done diff --git a/test/emacs-subject-to-filename b/test/emacs-subject-to-filename deleted file mode 100755 index 230c324d..00000000 --- a/test/emacs-subject-to-filename +++ /dev/null @@ -1,138 +0,0 @@ -#!/usr/bin/env bash - -test_description="emacs: mail subject to filename" -. ./test-lib.sh - -# emacs server can't be started in a child process with $(test_emacs ...) -test_emacs '(ignore)' > /dev/null - -# test notmuch-wash-subject-to-patch-sequence-number (subject) -test_begin_subtest "no patch sequence number" -output=$(test_emacs '(format "%S" (notmuch-wash-subject-to-patch-sequence-number - "[PATCH] A normal patch subject without numbers"))' -) -test_expect_equal "$output" '"nil"' - -test_begin_subtest "patch sequence number #1" -output=$(test_emacs '(notmuch-wash-subject-to-patch-sequence-number - "[PATCH 2/3] A most regular patch subject")' -) -test_expect_equal "$output" 2 - -test_begin_subtest "patch sequence number #2" -output=$(test_emacs '(notmuch-wash-subject-to-patch-sequence-number - " [dummy list prefix] [RFC PATCH v2 13/42] Special prefixes")' -) -test_expect_equal "$output" 13 - -test_begin_subtest "patch sequence number #3" -output=$(test_emacs '(notmuch-wash-subject-to-patch-sequence-number - "[PATCH 2/3] [PATCH 032/037] use the last prefix")' -) -test_expect_equal "$output" 32 - -test_begin_subtest "patch sequence number #4" -output=$(test_emacs '(notmuch-wash-subject-to-patch-sequence-number - "[dummy list prefix] [PATCH 2/3] PATCH 3/3] do not use a broken prefix")' -) -test_expect_equal "$output" 2 - -test_begin_subtest "patch sequence number #5" -output=$(test_emacs '(notmuch-wash-subject-to-patch-sequence-number - "[RFC][PATCH 3/5][PATCH 4/5][PATCH 5/5] A made up test")' -) -test_expect_equal "$output" 5 - -test_begin_subtest "patch sequence number #6" -output=$(test_emacs '(notmuch-wash-subject-to-patch-sequence-number - "[PATCH 2/3] this -> [PATCH 3/3] is not a prefix anymore [nor this 4/4]")' -) -test_expect_equal "$output" 2 - -test_begin_subtest "patch sequence number #7" -output=$(test_emacs '(notmuch-wash-subject-to-patch-sequence-number - "[liberally accept crapola right before123/456and after] the numbers")' -) -test_expect_equal "$output" 123 - -# test notmuch-wash-subject-to-filename (subject &optional maxlen) -test_begin_subtest "filename #1" -output=$(test_emacs '(notmuch-wash-subject-to-filename - "just a subject line")' -) -test_expect_equal "$output" '"just-a-subject-line"' - -test_begin_subtest "filename #2" -output=$(test_emacs '(notmuch-wash-subject-to-filename - " [any] [prefixes are ] [removed!] from the subject")' -) -test_expect_equal "$output" '"from-the-subject"' - -test_begin_subtest "filename #3" -output=$(test_emacs '(notmuch-wash-subject-to-filename - " leading and trailing space ")' -) -test_expect_equal "$output" '"leading-and-trailing-space"' - -test_begin_subtest "filename #4" -output=$(test_emacs '(notmuch-wash-subject-to-filename - "!# leading ()// &%, and in between_and_trailing garbage ()(&%%")' -) -test_expect_equal "$output" '"-leading-and-in-between_and_trailing-garbage"' - -test_begin_subtest "filename #5" -output=$(test_emacs '(notmuch-wash-subject-to-filename - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.-_01234567890")' -) -test_expect_equal "$output" '"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.-_01234567890"' - -test_begin_subtest "filename #6" -output=$(test_emacs '(notmuch-wash-subject-to-filename - "sequences of ... are squashed and trailing are removed ...")' -) -test_expect_equal "$output" '"sequences-of-.-are-squashed-and-trailing-are-removed"' - -test_begin_subtest "filename #7" -output=$(test_emacs '(notmuch-wash-subject-to-filename - "max length test" 1)' -) -test_expect_equal "$output" '"m"' - -test_begin_subtest "filename #8" -output=$(test_emacs '(notmuch-wash-subject-to-filename - "max length test /&(/%&/%%&¤%¤" 20)' -) -test_expect_equal "$output" '"max-length-test"' - -test_begin_subtest "filename #9" -output=$(test_emacs '(notmuch-wash-subject-to-filename - "[a prefix] [is only separated] by [spaces], so \"by\" is not okay!")' -) -test_expect_equal "$output" '"by-spaces-so-by-is-not-okay"' - -# test notmuch-wash-subject-to-patch-filename (subject) -test_begin_subtest "patch filename #1" -output=$(test_emacs '(notmuch-wash-subject-to-patch-filename - "[RFC][PATCH 099/100] rewrite notmuch")' -) -test_expect_equal "$output" '"0099-rewrite-notmuch.patch"' - -test_begin_subtest "patch filename #2" -output=$(test_emacs '(notmuch-wash-subject-to-patch-filename - "[RFC PATCH v1] has no patch number, default to 1")' -) -test_expect_equal "$output" '"0001-has-no-patch-number-default-to-1.patch"' - -test_begin_subtest "patch filename #3" -output=$(test_emacs '(notmuch-wash-subject-to-patch-filename - "[PATCH 4/5] the maximum length of a patch filename is 52 + patch sequence number + .patch extension")' -) -test_expect_equal "$output" '"0004-the-maximum-length-of-a-patch-filename-is-52-patch-s.patch"' - -test_begin_subtest "patch filename #4" -output=$(test_emacs '(notmuch-wash-subject-to-patch-filename - "[PATCH 4/5] the maximum length of a patch filename is 52 + patchh ! sequence number + .patch extension, *before* trimming trailing - and .")' -) -test_expect_equal "$output" '"0004-the-maximum-length-of-a-patch-filename-is-52-patchh.patch"' - -test_done diff --git a/test/emacs-test-functions b/test/emacs-test-functions deleted file mode 100755 index ca4a7988..00000000 --- a/test/emacs-test-functions +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env bash - -test_description="emacs test function sanity" -. ./test-lib.sh - -test_begin_subtest "emacs test function sanity" -test_emacs_expect_t 't' - -test_done diff --git a/test/emacs-tree b/test/emacs-tree deleted file mode 100755 index 4bdfddd2..00000000 --- a/test/emacs-tree +++ /dev/null @@ -1,197 +0,0 @@ -#!/usr/bin/env bash - -test_description="emacs tree view interface" -. test-lib.sh - -EXPECTED=$TEST_DIRECTORY/tree.expected-output - -add_email_corpus - -test_begin_subtest "Basic notmuch-tree view in emacs" -test_emacs '(add-to-list (quote load-path) "'$PICK_DIR'") - (notmuch-tree "tag:inbox") - (notmuch-test-wait) - (test-output) - (delete-other-windows)' -test_expect_equal_file OUTPUT $EXPECTED/notmuch-tree-tag-inbox - -test_begin_subtest "Refreshed notmuch-tree view in emacs" -test_emacs '(add-to-list (quote load-path) "'$PICK_DIR'") - (notmuch-tree "tag:inbox") - (notmuch-test-wait) - (notmuch-tree-refresh-view) - (notmuch-test-wait) - (test-output) - (delete-other-windows)' -test_expect_equal_file OUTPUT $EXPECTED/notmuch-tree-tag-inbox - -# In the following tag tests we make sure the display is updated -# correctly and, in a separate test, that the database is updated -# correctly. - -test_begin_subtest "Tag message in notmuch tree view (display)" -test_emacs '(add-to-list (quote load-path) "'$PICK_DIR'") - (notmuch-tree "tag:inbox") - (notmuch-test-wait) - (forward-line) - (notmuch-tree-tag (list "+test_tag")) - (test-output) - (delete-other-windows)' -test_expect_equal_file OUTPUT $EXPECTED/notmuch-tree-tag-inbox-tagged - -test_begin_subtest "Tag message in notmuch tree view (database)" -output=$(notmuch search --output=messages 'tag:test_tag') -test_expect_equal "$output" "id:877h1wv7mg.fsf@inf-8657.int-evry.fr" - -test_begin_subtest "Untag message in notmuch tree view" -test_emacs '(add-to-list (quote load-path) "'$PICK_DIR'") - (notmuch-tree "tag:inbox") - (notmuch-test-wait) - (forward-line) - (notmuch-tree-tag (list "-test_tag")) - (test-output) - (delete-other-windows)' -test_expect_equal_file OUTPUT $EXPECTED/notmuch-tree-tag-inbox - -test_begin_subtest "Untag message in notmuch tree view (database)" -output=$(notmuch search --output=messages 'tag:test_tag') -test_expect_equal "$output" "" - -test_begin_subtest "Tag thread in notmuch tree view" -test_emacs '(add-to-list (quote load-path) "'$PICK_DIR'") - (notmuch-tree "tag:inbox") - (notmuch-test-wait) - ;; move to a sizable thread - (forward-line 26) - (notmuch-tree-tag-thread (list "+test_thread_tag")) - (test-output) - (delete-other-windows)' -test_expect_equal_file OUTPUT $EXPECTED/notmuch-tree-tag-inbox-thread-tagged - -test_begin_subtest "Tag message in notmuch tree view (database)" -output=$(notmuch search --output=messages 'tag:test_thread_tag') -test_expect_equal "$output" \ -"id:87ocn0qh6d.fsf@yoom.home.cworth.org -id:20091118005040.GA25380@dottiness.seas.harvard.edu -id:yunaayketfm.fsf@aiko.keithp.com -id:87fx8can9z.fsf@vertex.dottedmag -id:20091117203301.GV3165@dottiness.seas.harvard.edu -id:87iqd9rn3l.fsf@vertex.dottedmag -id:20091117190054.GU3165@dottiness.seas.harvard.edu" - -test_begin_subtest "Untag thread in notmuch tree view" -test_emacs '(add-to-list (quote load-path) "'$PICK_DIR'") - (notmuch-tree "tag:inbox") - (notmuch-test-wait) - ;; move to the same sizable thread as above - (forward-line 26) - (notmuch-tree-tag-thread (list "-test_thread_tag")) - (test-output) - (delete-other-windows)' -test_expect_equal_file OUTPUT $EXPECTED/notmuch-tree-tag-inbox - -test_begin_subtest "Untag message in notmuch tree view (database)" -output=$(notmuch search --output=messages 'tag:test_thread_tag') -test_expect_equal "$output" "" - -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 (1- (point))) - (notmuch-test-wait) - (notmuch-tree-from-search-current-query) - (notmuch-test-wait) - (test-output) - (delete-other-windows)' -test_expect_equal_file OUTPUT $EXPECTED/notmuch-tree-tag-inbox - -test_begin_subtest "Tree view of a single thread (from search)" -test_emacs '(notmuch-hello) - (goto-char (point-min)) - (re-search-forward "inbox") - (widget-button-press (1- (point))) - (notmuch-test-wait) - (notmuch-tree-from-search-thread) - (notmuch-test-wait) - (test-output) - (delete-other-windows)' -test_expect_equal_file OUTPUT $EXPECTED/notmuch-tree-single-thread - -test_begin_subtest "Tree view of a single thread (from show)" -test_emacs '(notmuch-hello) - (goto-char (point-min)) - (re-search-forward "inbox") - (widget-button-press (1- (point))) - (notmuch-test-wait) - (notmuch-search-show-thread) - (notmuch-tree-from-show-current-query) - (notmuch-test-wait) - (test-output) - (delete-other-windows)' -test_expect_equal_file OUTPUT $EXPECTED/notmuch-tree-single-thread - -test_begin_subtest "Message window of tree view" -test_emacs '(notmuch-hello) - (goto-char (point-min)) - (re-search-forward "inbox") - (widget-button-press (1- (point))) - (notmuch-test-wait) - (notmuch-search-next-thread) - (notmuch-tree-from-search-thread) - (notmuch-test-wait) - (select-window notmuch-tree-message-window) - (test-output) - (delete-other-windows)' -cp OUTPUT /tmp/mjwout -test_expect_equal_file OUTPUT $EXPECTED/notmuch-tree-show-window - -test_begin_subtest "Stash id" -output=$(test_emacs '(add-to-list (quote load-path) "'$PICK_DIR'") - (require (quote notmuch-tree)) - (notmuch-tree "id:1258498485-sup-142@elly") - (notmuch-test-wait) - (notmuch-show-stash-message-id)') -test_expect_equal "$output" "\"Stashed: id:1258498485-sup-142@elly\"" - -test_begin_subtest "Move to next matching message" -output=$(test_emacs '(add-to-list (quote load-path) "'$PICK_DIR'") - (require (quote notmuch-tree)) - (notmuch-tree "from:cworth") - (notmuch-test-wait) - (notmuch-tree-next-matching-message) - (notmuch-show-stash-message-id)') -test_expect_equal "$output" "\"Stashed: id:878we4qdqf.fsf@yoom.home.cworth.org\"" - -test_begin_subtest "Move to next thread" -output=$(test_emacs '(add-to-list (quote load-path) "'$PICK_DIR'") - (require (quote notmuch-tree)) - (notmuch-tree "tag:inbox") - (notmuch-test-wait) - (forward-line 26) - (notmuch-tree-next-thread) - (notmuch-show-stash-message-id)') -test_expect_equal "$output" "\"Stashed: id:1258471718-6781-1-git-send-email-dottedmag@dottedmag.net\"" - -test_begin_subtest "Move to previous thread" -output=$(test_emacs '(add-to-list (quote load-path) "'$PICK_DIR'") - (require (quote notmuch-tree)) - (notmuch-tree "tag:inbox") - (notmuch-test-wait) - (forward-line 26) - (notmuch-tree-prev-thread) - (notmuch-show-stash-message-id)') -test_expect_equal "$output" "\"Stashed: id:20091117190054.GU3165@dottiness.seas.harvard.edu\"" - -test_begin_subtest "Move to previous previous thread" -output=$(test_emacs '(add-to-list (quote load-path) "'$PICK_DIR'") - (require (quote notmuch-tree)) - (notmuch-tree "tag:inbox") - (notmuch-test-wait) - (forward-line 26) - (notmuch-tree-prev-thread) - (notmuch-tree-prev-thread) - (notmuch-show-stash-message-id)') -test_expect_equal "$output" "\"Stashed: id:1258493565-13508-1-git-send-email-keithp@keithp.com\"" - -test_done diff --git a/test/encoding b/test/encoding deleted file mode 100755 index b6c86bf0..00000000 --- a/test/encoding +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env bash -test_description="encoding issues" -. ./test-lib.sh - -test_begin_subtest "Message with text of unknown charset" -add_message '[content-type]="text/plain; charset=unknown-8bit"' \ - "[body]=irrelevant" -output=$(notmuch show id:${gen_msg_id} 2>&1 | notmuch_show_sanitize_all) -test_expect_equal "$output" " message{ id:XXXXX depth:0 match:1 excluded:0 filename:XXXXX - header{ -Notmuch Test Suite (2001-01-05) (inbox unread) -Subject: Message with text of unknown charset -From: Notmuch Test Suite -To: Notmuch Test Suite -Date: GENERATED_DATE - header} - body{ - part{ ID: 1, Content-type: text/plain -irrelevant - part} - body} - message}" - -test_begin_subtest "Search for ISO-8859-2 encoded message" -add_message '[content-type]="text/plain; charset=iso-8859-2"' \ - '[content-transfer-encoding]=8bit' \ - '[subject]="ISO-8859-2 encoded message"' \ - "[body]=$'Czech word tu\350\362\341\350\350\355 means pinguin\'s.'" # ISO-8859-2 characters are generated by shell's escape sequences -output=$(notmuch search tučňáččí 2>&1 | notmuch_show_sanitize_all) -test_expect_equal "$output" "thread:0000000000000002 2001-01-05 [1/1] Notmuch Test Suite; ISO-8859-2 encoded message (inbox unread)" - -test_begin_subtest "RFC 2047 encoded word with spaces" -add_message '[subject]="=?utf-8?q?encoded word with spaces?="' -output=$(notmuch search id:${gen_msg_id} 2>&1 | notmuch_show_sanitize) -test_expect_equal "$output" "thread:0000000000000003 2001-01-05 [1/1] Notmuch Test Suite; encoded word with spaces (inbox unread)" - -test_begin_subtest "RFC 2047 encoded words back to back" -add_message '[subject]="=?utf-8?q?encoded-words-back?==?utf-8?q?to-back?="' -output=$(notmuch search id:${gen_msg_id} 2>&1 | notmuch_show_sanitize) -test_expect_equal "$output" "thread:0000000000000004 2001-01-05 [1/1] Notmuch Test Suite; encoded-words-backto-back (inbox unread)" - -test_begin_subtest "RFC 2047 encoded words without space before or after" -add_message '[subject]="=?utf-8?q?encoded?=word without=?utf-8?q?space?=" ' -output=$(notmuch search id:${gen_msg_id} 2>&1 | notmuch_show_sanitize) -test_expect_equal "$output" "thread:0000000000000005 2001-01-05 [1/1] Notmuch Test Suite; encodedword withoutspace (inbox unread)" - -test_done diff --git a/test/excludes b/test/excludes deleted file mode 100755 index 8bbbc2dd..00000000 --- a/test/excludes +++ /dev/null @@ -1,445 +0,0 @@ -#!/usr/bin/env bash -test_description='"notmuch search, count and show" with excludes in several variations' -. ./test-lib.sh - -# Generates a thread consisting of a top level message and 'length' -# replies. The subject of the top message 'subject: top message" -# and the subject of the nth reply in the thread is "subject: reply n" -generate_thread () -{ - local subject="$1" - local length="$2" - generate_message '[subject]="'"${subject}: top message"'"' '[body]="'"body of top message"'"' - parent_id=$gen_msg_id - gen_thread_msg_id[0]=$gen_msg_id - for i in `seq 1 $length` - do - generate_message '[subject]="'"${subject}: reply $i"'"' \ - "[in-reply-to]=\<$parent_id\>" \ - '[body]="'"body of reply $i"'"' - gen_thread_msg_id[$i]=$gen_msg_id - parent_id=$gen_msg_id - done - notmuch new > /dev/null - # We cannot retrieve the thread_id until after we have run notmuch new. - gen_thread_id=`notmuch search --output=threads id:${gen_thread_msg_id[0]}` -} - -############################################# -# These are the original search exclude tests. - -test_begin_subtest "Search, exclude \"deleted\" messages from search" -notmuch config set search.exclude_tags deleted -generate_message '[subject]="Not deleted"' -not_deleted_id=$gen_msg_id -generate_message '[subject]="Deleted"' -notmuch new > /dev/null -notmuch tag +deleted id:$gen_msg_id -deleted_id=$gen_msg_id -output=$(notmuch search subject:deleted | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Not deleted (inbox unread)" - -test_begin_subtest "Search, exclude \"deleted\" messages from message search" -output=$(notmuch search --output=messages subject:deleted | notmuch_search_sanitize) -test_expect_equal "$output" "id:$not_deleted_id" - -test_begin_subtest "Search, exclude \"deleted\" messages from message search --exclude=false" -output=$(notmuch search --exclude=false --output=messages subject:deleted | notmuch_search_sanitize) -test_expect_equal "$output" "id:$not_deleted_id -id:$deleted_id" - -test_begin_subtest "Search, exclude \"deleted\" messages from message search (non-existent exclude-tag)" -notmuch config set search.exclude_tags deleted non_existent_tag -output=$(notmuch search --output=messages subject:deleted | notmuch_search_sanitize) -test_expect_equal "$output" "id:$not_deleted_id" -notmuch config set search.exclude_tags deleted - -test_begin_subtest "Search, exclude \"deleted\" messages from search, overridden" -output=$(notmuch search subject:deleted and tag:deleted | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Deleted (deleted inbox unread)" - -test_begin_subtest "Search, exclude \"deleted\" messages from threads" -add_message '[subject]="Not deleted reply"' '[in-reply-to]="<$gen_msg_id>"' -output=$(notmuch search subject:deleted | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Not deleted (inbox unread) -thread:XXX 2001-01-05 [1/2] Notmuch Test Suite; Not deleted reply (deleted inbox unread)" - -test_begin_subtest "Search, don't exclude \"deleted\" messages when --exclude=flag specified" -output=$(notmuch search --exclude=flag subject:deleted | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Not deleted (inbox unread) -thread:XXX 2001-01-05 [1/2] Notmuch Test Suite; Deleted (deleted inbox unread)" - -test_begin_subtest "Search, don't exclude \"deleted\" messages from search if not configured" -notmuch config set search.exclude_tags -output=$(notmuch search subject:deleted | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Not deleted (inbox unread) -thread:XXX 2001-01-05 [2/2] Notmuch Test Suite; Deleted (deleted inbox unread)" - - -######################################################## -# We construct some threads for the tests. We use the tag "test" to -# indicate which messages we will search for. - -# A thread of deleted messages; test matches one of them. -generate_thread "All messages excluded: single match" 5 -notmuch tag +deleted $gen_thread_id -notmuch tag +test id:${gen_thread_msg_id[2]} - -# A thread of deleted messages; test matches two of them. -generate_thread "All messages excluded: double match" 5 -notmuch tag +deleted $gen_thread_id -notmuch tag +test id:${gen_thread_msg_id[2]} -notmuch tag +test id:${gen_thread_msg_id[4]} - -# A thread some messages deleted; test only matches a deleted message. -generate_thread "Some messages excluded: single excluded match" 5 -notmuch tag +deleted +test id:${gen_thread_msg_id[3]} - -# A thread some messages deleted; test only matches a non-deleted message. -generate_thread "Some messages excluded: single non-excluded match" 5 -notmuch tag +deleted id:${gen_thread_msg_id[2]} -notmuch tag +test id:${gen_thread_msg_id[4]} - -# A thread no messages deleted; test matches a message. -generate_thread "No messages excluded: single match" 5 -notmuch tag +test id:${gen_thread_msg_id[3]} - -# Temporarily remove excludes to get list of matching messages -notmuch config set search.exclude_tags -matching_message_ids=( `notmuch search --output=messages tag:test` ) -notmuch config set search.exclude_tags deleted - -######################################### -# Notmuch search tests - -test_begin_subtest "Search, default exclusion (thread summary)" -output=$(notmuch search tag:test | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2001-01-05 [1/6] Notmuch Test Suite; Some messages excluded: single non-excluded match: reply 4 (deleted inbox test unread) -thread:XXX 2001-01-05 [1/6] Notmuch Test Suite; No messages excluded: single match: reply 3 (inbox test unread)" - -test_begin_subtest "Search, default exclusion (messages)" -output=$(notmuch search --output=messages tag:test | notmuch_search_sanitize) -test_expect_equal "$output" "${matching_message_ids[4]} -${matching_message_ids[5]}" - -test_begin_subtest "Search, exclude=true (thread summary)" -output=$(notmuch search --exclude=true tag:test | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2001-01-05 [1/6] Notmuch Test Suite; Some messages excluded: single non-excluded match: reply 4 (deleted inbox test unread) -thread:XXX 2001-01-05 [1/6] Notmuch Test Suite; No messages excluded: single match: reply 3 (inbox test unread)" - -test_begin_subtest "Search, exclude=true (messages)" -output=$(notmuch search --exclude=true --output=messages tag:test | notmuch_search_sanitize) -test_expect_equal "$output" "${matching_message_ids[4]} -${matching_message_ids[5]}" - -test_begin_subtest "Search, exclude=false (thread summary)" -output=$(notmuch search --exclude=false tag:test | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2001-01-05 [1/6] Notmuch Test Suite; All messages excluded: single match: reply 2 (deleted inbox test unread) -thread:XXX 2001-01-05 [2/6] Notmuch Test Suite; All messages excluded: double match: reply 2 (deleted inbox test unread) -thread:XXX 2001-01-05 [1/6] Notmuch Test Suite; Some messages excluded: single excluded match: reply 3 (deleted inbox test unread) -thread:XXX 2001-01-05 [1/6] Notmuch Test Suite; Some messages excluded: single non-excluded match: reply 4 (deleted inbox test unread) -thread:XXX 2001-01-05 [1/6] Notmuch Test Suite; No messages excluded: single match: reply 3 (inbox test unread)" - -test_begin_subtest "Search, exclude=false (messages)" -output=$(notmuch search --exclude=false --output=messages tag:test | notmuch_search_sanitize) -test_expect_equal "$output" "${matching_message_ids[0]} -${matching_message_ids[1]} -${matching_message_ids[2]} -${matching_message_ids[3]} -${matching_message_ids[4]} -${matching_message_ids[5]}" - -test_begin_subtest "Search, exclude=flag (thread summary)" -output=$(notmuch search --exclude=flag tag:test | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2001-01-05 [0/6] Notmuch Test Suite; All messages excluded: single match: reply 2 (deleted inbox test unread) -thread:XXX 2001-01-05 [0/6] Notmuch Test Suite; All messages excluded: double match: reply 2 (deleted inbox test unread) -thread:XXX 2001-01-05 [0/6] Notmuch Test Suite; Some messages excluded: single excluded match: reply 3 (deleted inbox test unread) -thread:XXX 2001-01-05 [1/6] Notmuch Test Suite; Some messages excluded: single non-excluded match: reply 4 (deleted inbox test unread) -thread:XXX 2001-01-05 [1/6] Notmuch Test Suite; No messages excluded: single match: reply 3 (inbox test unread)" - -test_begin_subtest "Search, exclude=flag (messages)" -output=$(notmuch search --exclude=flag --output=messages tag:test | notmuch_search_sanitize) -test_expect_equal "$output" "${matching_message_ids[0]} -${matching_message_ids[1]} -${matching_message_ids[2]} -${matching_message_ids[3]} -${matching_message_ids[4]} -${matching_message_ids[5]}" - -test_begin_subtest "Search, exclude=all (thread summary)" -output=$(notmuch search --exclude=all tag:test | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2001-01-05 [1/5] Notmuch Test Suite; Some messages excluded: single non-excluded match: reply 4 (inbox test unread) -thread:XXX 2001-01-05 [1/6] Notmuch Test Suite; No messages excluded: single match: reply 3 (inbox test unread)" - -test_begin_subtest "Search, exclude=all (messages)" -output=$(notmuch search --exclude=all --output=messages tag:test | notmuch_search_sanitize) -test_expect_equal "$output" "${matching_message_ids[4]} -${matching_message_ids[5]}" - -test_begin_subtest "Search, default exclusion: tag in query (thread summary)" -output=$(notmuch search tag:test and tag:deleted | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2001-01-05 [1/6] Notmuch Test Suite; All messages excluded: single match: reply 2 (deleted inbox test unread) -thread:XXX 2001-01-05 [2/6] Notmuch Test Suite; All messages excluded: double match: reply 2 (deleted inbox test unread) -thread:XXX 2001-01-05 [1/6] Notmuch Test Suite; Some messages excluded: single excluded match: reply 3 (deleted inbox test unread)" - -test_begin_subtest "Search, default exclusion: tag in query (messages)" -output=$(notmuch search --output=messages tag:test and tag:deleted | notmuch_search_sanitize) -test_expect_equal "$output" "${matching_message_ids[0]} -${matching_message_ids[1]} -${matching_message_ids[2]} -${matching_message_ids[3]}" - -test_begin_subtest "Search, exclude=true: tag in query (thread summary)" -output=$(notmuch search --exclude=true tag:test and tag:deleted | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2001-01-05 [1/6] Notmuch Test Suite; All messages excluded: single match: reply 2 (deleted inbox test unread) -thread:XXX 2001-01-05 [2/6] Notmuch Test Suite; All messages excluded: double match: reply 2 (deleted inbox test unread) -thread:XXX 2001-01-05 [1/6] Notmuch Test Suite; Some messages excluded: single excluded match: reply 3 (deleted inbox test unread)" - -test_begin_subtest "Search, exclude=true: tag in query (messages)" -output=$(notmuch search --exclude=true --output=messages tag:test and tag:deleted | notmuch_search_sanitize) -test_expect_equal "$output" "${matching_message_ids[0]} -${matching_message_ids[1]} -${matching_message_ids[2]} -${matching_message_ids[3]}" - -test_begin_subtest "Search, exclude=false: tag in query (thread summary)" -output=$(notmuch search --exclude=false tag:test and tag:deleted | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2001-01-05 [1/6] Notmuch Test Suite; All messages excluded: single match: reply 2 (deleted inbox test unread) -thread:XXX 2001-01-05 [2/6] Notmuch Test Suite; All messages excluded: double match: reply 2 (deleted inbox test unread) -thread:XXX 2001-01-05 [1/6] Notmuch Test Suite; Some messages excluded: single excluded match: reply 3 (deleted inbox test unread)" - -test_begin_subtest "Search, exclude=false: tag in query (messages)" -output=$(notmuch search --exclude=false --output=messages tag:test and tag:deleted | notmuch_search_sanitize) -test_expect_equal "$output" "${matching_message_ids[0]} -${matching_message_ids[1]} -${matching_message_ids[2]} -${matching_message_ids[3]}" - -test_begin_subtest "Search, exclude=flag: tag in query (thread summary)" -output=$(notmuch search --exclude=flag tag:test and tag:deleted | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2001-01-05 [1/6] Notmuch Test Suite; All messages excluded: single match: reply 2 (deleted inbox test unread) -thread:XXX 2001-01-05 [2/6] Notmuch Test Suite; All messages excluded: double match: reply 2 (deleted inbox test unread) -thread:XXX 2001-01-05 [1/6] Notmuch Test Suite; Some messages excluded: single excluded match: reply 3 (deleted inbox test unread)" - -test_begin_subtest "Search, exclude=flag: tag in query (messages)" -output=$(notmuch search --exclude=flag --output=messages tag:test and tag:deleted | notmuch_search_sanitize) -test_expect_equal "$output" "${matching_message_ids[0]} -${matching_message_ids[1]} -${matching_message_ids[2]} -${matching_message_ids[3]}" - -test_begin_subtest "Search, exclude=all: tag in query (thread summary)" -output=$(notmuch search --exclude=all tag:test and tag:deleted | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2001-01-05 [1/6] Notmuch Test Suite; All messages excluded: single match: reply 2 (deleted inbox test unread) -thread:XXX 2001-01-05 [2/6] Notmuch Test Suite; All messages excluded: double match: reply 2 (deleted inbox test unread) -thread:XXX 2001-01-05 [1/6] Notmuch Test Suite; Some messages excluded: single excluded match: reply 3 (deleted inbox test unread)" - -test_begin_subtest "Search, exclude=all: tag in query (messages)" -output=$(notmuch search --exclude=all --output=messages tag:test and tag:deleted | notmuch_search_sanitize) -test_expect_equal "$output" "${matching_message_ids[0]} -${matching_message_ids[1]} -${matching_message_ids[2]} -${matching_message_ids[3]}" - -######################################################### -# Notmuch count tests - -test_begin_subtest "Count, default exclusion (messages)" -output=$(notmuch count tag:test) -test_expect_equal "$output" "2" - -test_begin_subtest "Count, default exclusion (threads)" -output=$(notmuch count --output=threads tag:test) -test_expect_equal "$output" "2" - -test_begin_subtest "Count, exclude=true (messages)" -output=$(notmuch count --exclude=true tag:test) -test_expect_equal "$output" "2" - -test_begin_subtest "Count, exclude=true (threads)" -output=$(notmuch count --output=threads --exclude=true tag:test) -test_expect_equal "$output" "2" - -test_begin_subtest "Count, exclude=false (messages)" -output=$(notmuch count --exclude=false tag:test) -test_expect_equal "$output" "6" - -test_begin_subtest "Count, exclude=false (threads)" -output=$(notmuch count --output=threads --exclude=false tag:test) -test_expect_equal "$output" "5" - -test_begin_subtest "Count, default exclusion: tag in query (messages)" -output=$(notmuch count tag:test and tag:deleted) -test_expect_equal "$output" "4" - -test_begin_subtest "Count, default exclusion: tag in query (threads)" -output=$(notmuch count --output=threads tag:test and tag:deleted) -test_expect_equal "$output" "3" - -test_begin_subtest "Count, exclude=true: tag in query (messages)" -output=$(notmuch count --exclude=true tag:test and tag:deleted) -test_expect_equal "$output" "4" - -test_begin_subtest "Count, exclude=true: tag in query (threads)" -output=$(notmuch count --output=threads --exclude=true tag:test and tag:deleted) -test_expect_equal "$output" "3" - -test_begin_subtest "Count, exclude=false: tag in query (messages)" -output=$(notmuch count --exclude=false tag:test and tag:deleted) -test_expect_equal "$output" "4" - -test_begin_subtest "Count, exclude=false: tag in query (threads)" -output=$(notmuch count --output=threads --exclude=false tag:test and tag:deleted) -test_expect_equal "$output" "3" - -############################################################# -# Show tests - -test_begin_subtest "Show, default exclusion" -output=$(notmuch show tag:test | notmuch_show_sanitize_all | egrep "Subject:|message{") -test_expect_equal "$output" " message{ id:XXXXX depth:0 match:1 excluded:0 filename:XXXXX -Subject: Some messages excluded: single non-excluded match: reply 4 - message{ id:XXXXX depth:0 match:1 excluded:0 filename:XXXXX -Subject: No messages excluded: single match: reply 3" - -test_begin_subtest "Show, default exclusion (entire-thread)" -output=$(notmuch show --entire-thread tag:test | notmuch_show_sanitize_all | egrep "Subject:|message{") -test_expect_equal "$output" " message{ id:XXXXX depth:0 match:0 excluded:0 filename:XXXXX -Subject: Some messages excluded: single non-excluded match: top message - message{ id:XXXXX depth:1 match:0 excluded:0 filename:XXXXX -Subject: Some messages excluded: single non-excluded match: reply 1 - message{ id:XXXXX depth:2 match:0 excluded:1 filename:XXXXX -Subject: Some messages excluded: single non-excluded match: reply 2 - message{ id:XXXXX depth:3 match:0 excluded:0 filename:XXXXX -Subject: Some messages excluded: single non-excluded match: reply 3 - message{ id:XXXXX depth:4 match:1 excluded:0 filename:XXXXX -Subject: Some messages excluded: single non-excluded match: reply 4 - message{ id:XXXXX depth:5 match:0 excluded:0 filename:XXXXX -Subject: Some messages excluded: single non-excluded match: reply 5 - message{ id:XXXXX depth:0 match:0 excluded:0 filename:XXXXX -Subject: No messages excluded: single match: top message - message{ id:XXXXX depth:1 match:0 excluded:0 filename:XXXXX -Subject: No messages excluded: single match: reply 1 - message{ id:XXXXX depth:2 match:0 excluded:0 filename:XXXXX -Subject: No messages excluded: single match: reply 2 - message{ id:XXXXX depth:3 match:1 excluded:0 filename:XXXXX -Subject: No messages excluded: single match: reply 3 - message{ id:XXXXX depth:4 match:0 excluded:0 filename:XXXXX -Subject: No messages excluded: single match: reply 4 - message{ id:XXXXX depth:5 match:0 excluded:0 filename:XXXXX -Subject: No messages excluded: single match: reply 5" - -test_begin_subtest "Show, exclude=true" -output=$(notmuch show --exclude=true tag:test | notmuch_show_sanitize_all | egrep "Subject:|message{") -test_expect_equal "$output" " message{ id:XXXXX depth:0 match:1 excluded:0 filename:XXXXX -Subject: Some messages excluded: single non-excluded match: reply 4 - message{ id:XXXXX depth:0 match:1 excluded:0 filename:XXXXX -Subject: No messages excluded: single match: reply 3" - -test_begin_subtest "Show, exclude=true (entire-thread)" -output=$(notmuch show --entire-thread --exclude=true tag:test | notmuch_show_sanitize_all | egrep "Subject:|message{") -test_expect_equal "$output" " message{ id:XXXXX depth:0 match:0 excluded:0 filename:XXXXX -Subject: Some messages excluded: single non-excluded match: top message - message{ id:XXXXX depth:1 match:0 excluded:0 filename:XXXXX -Subject: Some messages excluded: single non-excluded match: reply 1 - message{ id:XXXXX depth:2 match:0 excluded:1 filename:XXXXX -Subject: Some messages excluded: single non-excluded match: reply 2 - message{ id:XXXXX depth:3 match:0 excluded:0 filename:XXXXX -Subject: Some messages excluded: single non-excluded match: reply 3 - message{ id:XXXXX depth:4 match:1 excluded:0 filename:XXXXX -Subject: Some messages excluded: single non-excluded match: reply 4 - message{ id:XXXXX depth:5 match:0 excluded:0 filename:XXXXX -Subject: Some messages excluded: single non-excluded match: reply 5 - message{ id:XXXXX depth:0 match:0 excluded:0 filename:XXXXX -Subject: No messages excluded: single match: top message - message{ id:XXXXX depth:1 match:0 excluded:0 filename:XXXXX -Subject: No messages excluded: single match: reply 1 - message{ id:XXXXX depth:2 match:0 excluded:0 filename:XXXXX -Subject: No messages excluded: single match: reply 2 - message{ id:XXXXX depth:3 match:1 excluded:0 filename:XXXXX -Subject: No messages excluded: single match: reply 3 - message{ id:XXXXX depth:4 match:0 excluded:0 filename:XXXXX -Subject: No messages excluded: single match: reply 4 - message{ id:XXXXX depth:5 match:0 excluded:0 filename:XXXXX -Subject: No messages excluded: single match: reply 5" - -test_begin_subtest "Show, exclude=false" -output=$(notmuch show --exclude=false tag:test | notmuch_show_sanitize_all | egrep "Subject:|message{") -test_expect_equal "$output" " message{ id:XXXXX depth:0 match:1 excluded:1 filename:XXXXX -Subject: All messages excluded: single match: reply 2 - message{ id:XXXXX depth:0 match:1 excluded:1 filename:XXXXX -Subject: All messages excluded: double match: reply 2 - message{ id:XXXXX depth:1 match:1 excluded:1 filename:XXXXX -Subject: All messages excluded: double match: reply 4 - message{ id:XXXXX depth:0 match:1 excluded:1 filename:XXXXX -Subject: Some messages excluded: single excluded match: reply 3 - message{ id:XXXXX depth:0 match:1 excluded:0 filename:XXXXX -Subject: Some messages excluded: single non-excluded match: reply 4 - message{ id:XXXXX depth:0 match:1 excluded:0 filename:XXXXX -Subject: No messages excluded: single match: reply 3" - -test_begin_subtest "Show, exclude=false (entire-thread)" -output=$(notmuch show --entire-thread --exclude=false tag:test | notmuch_show_sanitize_all | egrep "Subject:|message{") -test_expect_equal "$output" " message{ id:XXXXX depth:0 match:0 excluded:1 filename:XXXXX -Subject: All messages excluded: single match: top message - message{ id:XXXXX depth:1 match:0 excluded:1 filename:XXXXX -Subject: All messages excluded: single match: reply 1 - message{ id:XXXXX depth:2 match:1 excluded:1 filename:XXXXX -Subject: All messages excluded: single match: reply 2 - message{ id:XXXXX depth:3 match:0 excluded:1 filename:XXXXX -Subject: All messages excluded: single match: reply 3 - message{ id:XXXXX depth:4 match:0 excluded:1 filename:XXXXX -Subject: All messages excluded: single match: reply 4 - message{ id:XXXXX depth:5 match:0 excluded:1 filename:XXXXX -Subject: All messages excluded: single match: reply 5 - message{ id:XXXXX depth:0 match:0 excluded:1 filename:XXXXX -Subject: All messages excluded: double match: top message - message{ id:XXXXX depth:1 match:0 excluded:1 filename:XXXXX -Subject: All messages excluded: double match: reply 1 - message{ id:XXXXX depth:2 match:1 excluded:1 filename:XXXXX -Subject: All messages excluded: double match: reply 2 - message{ id:XXXXX depth:3 match:0 excluded:1 filename:XXXXX -Subject: All messages excluded: double match: reply 3 - message{ id:XXXXX depth:4 match:1 excluded:1 filename:XXXXX -Subject: All messages excluded: double match: reply 4 - message{ id:XXXXX depth:5 match:0 excluded:1 filename:XXXXX -Subject: All messages excluded: double match: reply 5 - message{ id:XXXXX depth:0 match:0 excluded:0 filename:XXXXX -Subject: Some messages excluded: single excluded match: top message - message{ id:XXXXX depth:1 match:0 excluded:0 filename:XXXXX -Subject: Some messages excluded: single excluded match: reply 1 - message{ id:XXXXX depth:2 match:0 excluded:0 filename:XXXXX -Subject: Some messages excluded: single excluded match: reply 2 - message{ id:XXXXX depth:3 match:1 excluded:1 filename:XXXXX -Subject: Some messages excluded: single excluded match: reply 3 - message{ id:XXXXX depth:4 match:0 excluded:0 filename:XXXXX -Subject: Some messages excluded: single excluded match: reply 4 - message{ id:XXXXX depth:5 match:0 excluded:0 filename:XXXXX -Subject: Some messages excluded: single excluded match: reply 5 - message{ id:XXXXX depth:0 match:0 excluded:0 filename:XXXXX -Subject: Some messages excluded: single non-excluded match: top message - message{ id:XXXXX depth:1 match:0 excluded:0 filename:XXXXX -Subject: Some messages excluded: single non-excluded match: reply 1 - message{ id:XXXXX depth:2 match:0 excluded:1 filename:XXXXX -Subject: Some messages excluded: single non-excluded match: reply 2 - message{ id:XXXXX depth:3 match:0 excluded:0 filename:XXXXX -Subject: Some messages excluded: single non-excluded match: reply 3 - message{ id:XXXXX depth:4 match:1 excluded:0 filename:XXXXX -Subject: Some messages excluded: single non-excluded match: reply 4 - message{ id:XXXXX depth:5 match:0 excluded:0 filename:XXXXX -Subject: Some messages excluded: single non-excluded match: reply 5 - message{ id:XXXXX depth:0 match:0 excluded:0 filename:XXXXX -Subject: No messages excluded: single match: top message - message{ id:XXXXX depth:1 match:0 excluded:0 filename:XXXXX -Subject: No messages excluded: single match: reply 1 - message{ id:XXXXX depth:2 match:0 excluded:0 filename:XXXXX -Subject: No messages excluded: single match: reply 2 - message{ id:XXXXX depth:3 match:1 excluded:0 filename:XXXXX -Subject: No messages excluded: single match: reply 3 - message{ id:XXXXX depth:4 match:0 excluded:0 filename:XXXXX -Subject: No messages excluded: single match: reply 4 - message{ id:XXXXX depth:5 match:0 excluded:0 filename:XXXXX -Subject: No messages excluded: single match: reply 5" - - -test_done diff --git a/test/from-guessing b/test/from-guessing deleted file mode 100755 index 6dfaa40a..00000000 --- a/test/from-guessing +++ /dev/null @@ -1,217 +0,0 @@ -#!/usr/bin/env bash -test_description="From line heuristics (with multiple configured addresses)" -. ./test-lib.sh - -test_begin_subtest "Magic from guessing (nothing to go on)" -add_message '[from]="Sender "' \ - [to]=mailinglist@notmuchmail.org \ - [subject]=notmuch-reply-test \ - '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ - '[body]="from guessing test"' - -output=$(notmuch reply id:${gen_msg_id}) -test_expect_equal "$output" "From: Notmuch Test Suite -Subject: Re: notmuch-reply-test -To: Sender , mailinglist@notmuchmail.org -In-Reply-To: <${gen_msg_id}> -References: <${gen_msg_id}> - -On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: -> from guessing test" - -test_begin_subtest "Magic from guessing (Envelope-to:)" -add_message '[from]="Sender "' \ - [to]=mailinglist@notmuchmail.org \ - [subject]=notmuch-reply-test \ - '[header]="Envelope-To: test_suite_other@notmuchmail.org"' \ - '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ - '[body]="from guessing test"' - -output=$(notmuch reply id:${gen_msg_id}) -test_expect_equal "$output" "From: Notmuch Test Suite -Subject: Re: notmuch-reply-test -To: Sender , mailinglist@notmuchmail.org -In-Reply-To: <${gen_msg_id}> -References: <${gen_msg_id}> - -On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: -> from guessing test" - -test_begin_subtest "Magic from guessing (X-Original-To:)" -add_message '[from]="Sender "' \ - [to]=mailinglist@notmuchmail.org \ - [subject]=notmuch-reply-test \ - '[header]="X-Original-To: test_suite_other@notmuchmail.org"' \ - '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ - '[body]="from guessing test"' - -output=$(notmuch reply id:${gen_msg_id}) -test_expect_equal "$output" "From: Notmuch Test Suite -Subject: Re: notmuch-reply-test -To: Sender , mailinglist@notmuchmail.org -In-Reply-To: <${gen_msg_id}> -References: <${gen_msg_id}> - -On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: -> from guessing test" - -test_begin_subtest "Magic from guessing (Received: .. for ..)" -add_message '[from]="Sender "' \ - [to]=mailinglist@notmuchmail.org \ - [subject]=notmuch-reply-test \ - "[header]=\"Received: from mail.example.com (mail.example.com [1.1.1.1]) - by mail.notmuchmail.org (some MTA) with ESMTP id 12345678 - for ; Sat, 10 Apr 2010 07:54:51 -0400 (EDT)\"" \ - '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ - '[body]="from guessing test"' - -output=$(notmuch reply id:${gen_msg_id}) -test_expect_equal "$output" "From: Notmuch Test Suite -Subject: Re: notmuch-reply-test -To: Sender , mailinglist@notmuchmail.org -In-Reply-To: <${gen_msg_id}> -References: <${gen_msg_id}> - -On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: -> from guessing test" - -test_begin_subtest "Magic from guessing (Received: domain)" -add_message '[from]="Sender "' \ - [to]=mailinglist@notmuchmail.org \ - [subject]=notmuch-reply-test \ - "[header]=\"Received: from mail.example.com (mail.example.com [1.1.1.1]) - by mail.otherdomain.org (some MTA) with ESMTP id 12345678 - Sat, 10 Apr 2010 07:54:51 -0400 (EDT)\"" \ - '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ - '[body]="from guessing test"' - -output=$(notmuch reply id:${gen_msg_id}) -test_expect_equal "$output" "From: Notmuch Test Suite -Subject: Re: notmuch-reply-test -To: Sender , mailinglist@notmuchmail.org -In-Reply-To: <${gen_msg_id}> -References: <${gen_msg_id}> - -On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: -> from guessing test" - -test_begin_subtest "Magic from guessing (multiple Received: headers)" -add_message '[from]="Sender "' \ - [to]=mailinglist@notmuchmail.org \ - [subject]=notmuch-reply-test \ - "[header]=\"Received: from extraneous.example.com (extraneous.example.com [1.1.1.1]) -Received: from mail.example.com (mail.example.com [1.1.1.1]) - by mail.otherdomain.org (some MTA) with ESMTP id 12345678 - for ; Sat, 10 Apr 2010 07:54:51 -0400 (EDT) -Received: from extraneous.example.com (extraneous.example.com [1.1.1.1])\"" \ - '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ - '[body]="from guessing test"' - -output="$(notmuch reply id:${gen_msg_id})" -test_expect_equal "$output" "From: Notmuch Test Suite -Subject: Re: notmuch-reply-test -To: Sender , mailinglist@notmuchmail.org -In-Reply-To: <${gen_msg_id}> -References: <${gen_msg_id}> - -On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: -> from guessing test" - -test_begin_subtest "Testing From line heuristics (with single configured address)" -sed -i -e "s/^other_email.*//" "${NOTMUCH_CONFIG}" -test_expect_equal '' '' - -test_begin_subtest "Magic from guessing (nothing to go on)" -add_message '[from]="Sender "' \ - [to]=mailinglist@notmuchmail.org \ - [subject]=notmuch-reply-test \ - '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ - '[body]="from guessing test"' - -output=$(notmuch reply id:${gen_msg_id}) -test_expect_equal "$output" "From: Notmuch Test Suite -Subject: Re: notmuch-reply-test -To: Sender , mailinglist@notmuchmail.org -In-Reply-To: <${gen_msg_id}> -References: <${gen_msg_id}> - -On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: -> from guessing test" - -test_begin_subtest "Magic from guessing (Envelope-to:)" -add_message '[from]="Sender "' \ - [to]=mailinglist@notmuchmail.org \ - [subject]=notmuch-reply-test \ - '[header]="Envelope-To: test_suite_other@notmuchmail.org"' \ - '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ - '[body]="from guessing test"' - -output=$(notmuch reply id:${gen_msg_id}) -test_expect_equal "$output" "From: Notmuch Test Suite -Subject: Re: notmuch-reply-test -To: Sender , mailinglist@notmuchmail.org -In-Reply-To: <${gen_msg_id}> -References: <${gen_msg_id}> - -On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: -> from guessing test" - -test_begin_subtest "Magic from guessing (X-Original-To:)" -add_message '[from]="Sender "' \ - [to]=mailinglist@notmuchmail.org \ - [subject]=notmuch-reply-test \ - '[header]="X-Original-To: test_suite_other@notmuchmail.org"' \ - '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ - '[body]="from guessing test"' - -output=$(notmuch reply id:${gen_msg_id}) -test_expect_equal "$output" "From: Notmuch Test Suite -Subject: Re: notmuch-reply-test -To: Sender , mailinglist@notmuchmail.org -In-Reply-To: <${gen_msg_id}> -References: <${gen_msg_id}> - -On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: -> from guessing test" - -test_begin_subtest "Magic from guessing (Received: .. for ..)" -add_message '[from]="Sender "' \ - [to]=mailinglist@notmuchmail.org \ - [subject]=notmuch-reply-test \ - "[header]=\"Received: from mail.example.com (mail.example.com [1.1.1.1]) - by mail.notmuchmail.org (some MTA) with ESMTP id 12345678 - for ; Sat, 10 Apr 2010 07:54:51 -0400 (EDT)\"" \ - '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ - '[body]="from guessing test"' - -output=$(notmuch reply id:${gen_msg_id}) -test_expect_equal "$output" "From: Notmuch Test Suite -Subject: Re: notmuch-reply-test -To: Sender , mailinglist@notmuchmail.org -In-Reply-To: <${gen_msg_id}> -References: <${gen_msg_id}> - -On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: -> from guessing test" - -test_begin_subtest "Magic from guessing (Received: domain)" -add_message '[from]="Sender "' \ - [to]=mailinglist@notmuchmail.org \ - [subject]=notmuch-reply-test \ - "[header]=\"Received: from mail.example.com (mail.example.com [1.1.1.1]) - by mail.otherdomain.org (some MTA) with ESMTP id 12345678 - Sat, 10 Apr 2010 07:54:51 -0400 (EDT)\"" \ - '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ - '[body]="from guessing test"' - -output=$(notmuch reply id:${gen_msg_id}) -test_expect_equal "$output" "From: Notmuch Test Suite -Subject: Re: notmuch-reply-test -To: Sender , mailinglist@notmuchmail.org -In-Reply-To: <${gen_msg_id}> -References: <${gen_msg_id}> - -On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: -> from guessing test" - -test_done diff --git a/test/help-test b/test/help-test deleted file mode 100755 index f7df725e..00000000 --- a/test/help-test +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash - -test_description="online help" -. ./test-lib.sh - -test_expect_success 'notmuch --help' 'notmuch --help' -test_expect_success 'notmuch --help tag' 'notmuch --help tag' -test_expect_success 'notmuch help' 'notmuch help' -test_expect_success 'notmuch help tag' 'notmuch help tag' -test_expect_success 'notmuch --version' 'notmuch --version' - -test_done diff --git a/test/hex-escaping b/test/hex-escaping deleted file mode 100755 index ad50e1bc..00000000 --- a/test/hex-escaping +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env bash -test_description="hex encoding and decoding" -. ./test-lib.sh - -test_begin_subtest "round trip" -find $TEST_DIRECTORY/corpus -type f -print | sort | xargs cat > EXPECTED -$TEST_DIRECTORY/hex-xcode --direction=encode < EXPECTED | $TEST_DIRECTORY/hex-xcode --direction=decode > OUTPUT -test_expect_equal_file OUTPUT EXPECTED - -test_begin_subtest "punctuation" -tag1='comic_swear=$&^%$^%\\//-+$^%$' -tag_enc1=$($TEST_DIRECTORY/hex-xcode --direction=encode "$tag1") -test_expect_equal "$tag_enc1" "comic_swear=%24%26%5e%25%24%5e%25%5c%5c%2f%2f-+%24%5e%25%24" - -test_begin_subtest "round trip newlines" -printf 'this\n tag\t has\n spaces\n' > EXPECTED.$test_count -$TEST_DIRECTORY/hex-xcode --direction=encode < EXPECTED.$test_count |\ - $TEST_DIRECTORY/hex-xcode --direction=decode > OUTPUT.$test_count -test_expect_equal_file EXPECTED.$test_count OUTPUT.$test_count - -test_begin_subtest "round trip 8bit chars" -echo '%c3%91%c3%a5%c3%b0%c3%a3%c3%a5%c3%a9-%c3%8f%c3%8a' > EXPECTED.$test_count -$TEST_DIRECTORY/hex-xcode --direction=decode < EXPECTED.$test_count |\ - $TEST_DIRECTORY/hex-xcode --direction=encode > OUTPUT.$test_count -test_expect_equal_file EXPECTED.$test_count OUTPUT.$test_count - -test_begin_subtest "round trip (in-place)" -find $TEST_DIRECTORY/corpus -type f -print | sort | xargs cat > EXPECTED -$TEST_DIRECTORY/hex-xcode --in-place --direction=encode < EXPECTED |\ - $TEST_DIRECTORY/hex-xcode --in-place --direction=decode > OUTPUT -test_expect_equal_file OUTPUT EXPECTED - -test_begin_subtest "punctuation (in-place)" -tag1='comic_swear=$&^%$^%\\//-+$^%$' -tag_enc1=$($TEST_DIRECTORY/hex-xcode --in-place --direction=encode "$tag1") -test_expect_equal "$tag_enc1" "comic_swear=%24%26%5e%25%24%5e%25%5c%5c%2f%2f-+%24%5e%25%24" - -test_begin_subtest "round trip newlines (in-place)" -printf 'this\n tag\t has\n spaces\n' > EXPECTED.$test_count -$TEST_DIRECTORY/hex-xcode --in-place --direction=encode < EXPECTED.$test_count |\ - $TEST_DIRECTORY/hex-xcode --in-place --direction=decode > OUTPUT.$test_count -test_expect_equal_file EXPECTED.$test_count OUTPUT.$test_count - -test_begin_subtest "round trip 8bit chars (in-place)" -echo '%c3%91%c3%a5%c3%b0%c3%a3%c3%a5%c3%a9-%c3%8f%c3%8a' > EXPECTED.$test_count -$TEST_DIRECTORY/hex-xcode --in-place --direction=decode < EXPECTED.$test_count |\ - $TEST_DIRECTORY/hex-xcode --in-place --direction=encode > OUTPUT.$test_count -test_expect_equal_file EXPECTED.$test_count OUTPUT.$test_count - -test_done diff --git a/test/hooks b/test/hooks deleted file mode 100755 index 77e8569b..00000000 --- a/test/hooks +++ /dev/null @@ -1,104 +0,0 @@ -#!/usr/bin/env bash -test_description='hooks' -. ./test-lib.sh - -HOOK_DIR=${MAIL_DIR}/.notmuch/hooks - -create_echo_hook () { - local TOKEN="${RANDOM}" - mkdir -p ${HOOK_DIR} - cat <"${HOOK_DIR}/${1}" -#!/bin/sh -echo "${TOKEN}" > ${3} -EOF - chmod +x "${HOOK_DIR}/${1}" - echo "${TOKEN}" > ${2} -} - -create_failing_hook () { - mkdir -p ${HOOK_DIR} - cat <"${HOOK_DIR}/${1}" -#!/bin/sh -exit 13 -EOF - chmod +x "${HOOK_DIR}/${1}" -} - -rm_hooks () { - rm -rf ${HOOK_DIR} -} - -# add a message to generate mail dir and database -add_message - -test_begin_subtest "pre-new is run" -rm_hooks -generate_message -create_echo_hook "pre-new" expected output -notmuch new > /dev/null -test_expect_equal_file expected output - -test_begin_subtest "post-new is run" -rm_hooks -generate_message -create_echo_hook "post-new" expected output -notmuch new > /dev/null -test_expect_equal_file expected output - -test_begin_subtest "pre-new is run before post-new" -rm_hooks -generate_message -create_echo_hook "pre-new" pre-new.expected pre-new.output -create_echo_hook "post-new" post-new.expected post-new.output -notmuch new > /dev/null -test_expect_equal_file post-new.expected post-new.output - -test_begin_subtest "pre-new non-zero exit status (hook status)" -rm_hooks -generate_message -create_failing_hook "pre-new" -output=`notmuch new 2>&1` -test_expect_equal "$output" "Error: pre-new hook failed with status 13" - -# depends on the previous subtest leaving broken hook behind -test_expect_code 1 "pre-new non-zero exit status (notmuch status)" "notmuch new" - -# depends on the previous subtests leaving 1 new message behind -test_begin_subtest "pre-new non-zero exit status aborts new" -rm_hooks -output=$(NOTMUCH_NEW) -test_expect_equal "$output" "Added 1 new message to the database." - -test_begin_subtest "post-new non-zero exit status (hook status)" -rm_hooks -generate_message -create_failing_hook "post-new" -NOTMUCH_NEW 2>output.stderr >output -cat output.stderr >> output -echo "Added 1 new message to the database." > expected -echo "Error: post-new hook failed with status 13" >> expected -test_expect_equal_file expected output - -# depends on the previous subtest leaving broken hook behind -test_expect_code 1 "post-new non-zero exit status (notmuch status)" "notmuch new" - -# test_begin_subtest "hook without executable permissions" -rm_hooks -mkdir -p ${HOOK_DIR} -cat <"${HOOK_DIR}/pre-new" -#!/bin/sh -echo foo -EOF -output=`notmuch new 2>&1` -test_expect_code 1 "hook without executable permissions" "notmuch new" - -# test_begin_subtest "hook execution failure" -rm_hooks -mkdir -p ${HOOK_DIR} -cat <"${HOOK_DIR}/pre-new" -no hashbang, execl fails -EOF -chmod +x "${HOOK_DIR}/pre-new" -test_expect_code 1 "hook execution failure" "notmuch new" - -test_done diff --git a/test/insert b/test/insert deleted file mode 100755 index 550b4132..00000000 --- a/test/insert +++ /dev/null @@ -1,157 +0,0 @@ -#!/usr/bin/env bash -test_description='"notmuch insert"' -. ./test-lib.sh - -# Create directories and database before inserting. -mkdir -p "$MAIL_DIR"/{cur,new,tmp} -mkdir -p "$MAIL_DIR"/Drafts/{cur,new,tmp} -notmuch new > /dev/null - -# We use generate_message to create the temporary message files. -# They happen to be in the mail directory already but that is okay -# since we do not call notmuch new hereafter. - -gen_insert_msg() { - generate_message \ - "[subject]=\"insert-subject\"" \ - "[date]=\"Sat, 01 Jan 2000 12:00:00 -0000\"" \ - "[body]=\"insert-message\"" -} - -test_expect_code 1 "Insert zero-length file" \ - "notmuch insert < /dev/null" - -# This test is a proxy for other errors that may occur while trying to -# add a message to the notmuch database, e.g. database locked. -test_expect_code 0 "Insert non-message" \ - "echo bad_message | notmuch insert" - -test_begin_subtest "Database empty so far" -test_expect_equal "0" "`notmuch count --output=messages '*'`" - -test_begin_subtest "Insert message" -gen_insert_msg -notmuch insert < "$gen_msg_filename" -cur_msg_filename=$(notmuch search --output=files "subject:insert-subject") -test_expect_equal_file "$cur_msg_filename" "$gen_msg_filename" - -test_begin_subtest "Insert message adds default tags" -output=$(notmuch show --format=json "subject:insert-subject") -expected='[[[{ - "id": "'"${gen_msg_id}"'", - "match": true, - "excluded": false, - "filename": "'"${cur_msg_filename}"'", - "timestamp": 946728000, - "date_relative": "2000-01-01", - "tags": ["inbox","unread"], - "headers": { - "Subject": "insert-subject", - "From": "Notmuch Test Suite ", - "To": "Notmuch Test Suite ", - "Date": "Sat, 01 Jan 2000 12:00:00 +0000"}, - "body": [{"id": 1, - "content-type": "text/plain", - "content": "insert-message\n"}]}, - []]]]' -test_expect_equal_json "$output" "$expected" - -test_begin_subtest "Insert duplicate message" -notmuch insert +duptag -unread < "$gen_msg_filename" -output=$(notmuch search --output=files "subject:insert-subject" | wc -l) -test_expect_equal "$output" 2 - -test_begin_subtest "Duplicate message does not change tags" -output=$(notmuch search --format=json --output=tags "subject:insert-subject") -test_expect_equal_json "$output" '["inbox", "unread"]' - -test_begin_subtest "Insert message, add tag" -gen_insert_msg -notmuch insert +custom < "$gen_msg_filename" -output=$(notmuch search --output=messages tag:custom) -test_expect_equal "$output" "id:$gen_msg_id" - -test_begin_subtest "Insert message, add/remove tags" -gen_insert_msg -notmuch insert +custom -unread < "$gen_msg_filename" -output=$(notmuch search --output=messages tag:custom NOT tag:unread) -test_expect_equal "$output" "id:$gen_msg_id" - -test_begin_subtest "Insert message with default tags stays in new/" -gen_insert_msg -notmuch insert < "$gen_msg_filename" -output=$(notmuch search --output=files id:$gen_msg_id) -dirname=$(dirname "$output") -test_expect_equal "$dirname" "$MAIL_DIR/new" - -test_begin_subtest "Insert message with non-maildir synced tags stays in new/" -gen_insert_msg -notmuch insert +custom -inbox < "$gen_msg_filename" -output=$(notmuch search --output=files id:$gen_msg_id) -dirname=$(dirname "$output") -test_expect_equal "$dirname" "$MAIL_DIR/new" - -test_begin_subtest "Insert message with custom new.tags goes to cur/" -OLDCONFIG=$(notmuch config get new.tags) -notmuch config set new.tags test -gen_insert_msg -notmuch insert < "$gen_msg_filename" -output=$(notmuch search --output=files id:$gen_msg_id) -dirname=$(dirname "$output") -notmuch config set new.tags $OLDCONFIG -test_expect_equal "$dirname" "$MAIL_DIR/cur" - -# additional check on the previous message -test_begin_subtest "Insert message with custom new.tags actually gets the tags" -output=$(notmuch search --output=tags id:$gen_msg_id) -test_expect_equal "$output" "test" - -test_begin_subtest "Insert message with maildir synced tags goes to cur/" -gen_insert_msg -notmuch insert +flagged < "$gen_msg_filename" -output=$(notmuch search --output=files id:$gen_msg_id) -dirname=$(dirname "$output") -test_expect_equal "$dirname" "$MAIL_DIR/cur" - -test_begin_subtest "Insert message into folder" -gen_insert_msg -notmuch insert --folder=Drafts < "$gen_msg_filename" -output=$(notmuch search --output=files folder:Drafts) -dirname=$(dirname "$output") -test_expect_equal "$dirname" "$MAIL_DIR/Drafts/new" - -test_begin_subtest "Insert message into folder, add/remove tags" -gen_insert_msg -notmuch insert --folder=Drafts +draft -unread < "$gen_msg_filename" -output=$(notmuch search --output=messages folder:Drafts tag:draft NOT tag:unread) -test_expect_equal "$output" "id:$gen_msg_id" - -gen_insert_msg -test_expect_code 1 "Insert message into non-existent folder" \ - "notmuch insert --folder=nonesuch < $gen_msg_filename" - -test_begin_subtest "Insert message, create folder" -gen_insert_msg -notmuch insert --folder=F --create-folder +folder < "$gen_msg_filename" -output=$(notmuch search --output=files folder:F tag:folder) -basename=$(basename "$output") -test_expect_equal_file "$gen_msg_filename" "$MAIL_DIR/F/new/${basename}" - -test_begin_subtest "Insert message, create subfolder" -gen_insert_msg -notmuch insert --folder=F/G/H/I/J --create-folder +folder < "$gen_msg_filename" -output=$(notmuch search --output=files folder:F/G/H/I/J tag:folder) -basename=$(basename "$output") -test_expect_equal_file "$gen_msg_filename" "${MAIL_DIR}/F/G/H/I/J/new/${basename}" - -test_begin_subtest "Insert message, create existing subfolder" -gen_insert_msg -notmuch insert --folder=F/G/H/I/J --create-folder +folder < "$gen_msg_filename" -output=$(notmuch count folder:F/G/H/I/J tag:folder) -test_expect_equal "$output" "2" - -gen_insert_msg -test_expect_code 1 "Insert message, create invalid subfolder" \ - "notmuch insert --folder=../G --create-folder $gen_msg_filename" - -test_done diff --git a/test/json b/test/json deleted file mode 100755 index c1cf649d..00000000 --- a/test/json +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env bash -test_description="--format=json output" -. ./test-lib.sh - -test_begin_subtest "Show message: json" -add_message "[subject]=\"json-show-subject\"" "[date]=\"Sat, 01 Jan 2000 12:00:00 -0000\"" "[bcc]=\"test_suite+bcc@notmuchmail.org\"" "[reply-to]=\"test_suite+replyto@notmuchmail.org\"" "[body]=\"json-show-message\"" -output=$(notmuch show --format=json "json-show-message") -test_expect_equal_json "$output" "[[[{\"id\": \"${gen_msg_id}\", \"match\": true, \"excluded\": false, \"filename\": \"${gen_msg_filename}\", \"timestamp\": 946728000, \"date_relative\": \"2000-01-01\", \"tags\": [\"inbox\",\"unread\"], \"headers\": {\"Subject\": \"json-show-subject\", \"From\": \"Notmuch Test Suite \", \"To\": \"Notmuch Test Suite \", \"Bcc\": \"test_suite+bcc@notmuchmail.org\", \"Reply-To\": \"test_suite+replyto@notmuchmail.org\", \"Date\": \"Sat, 01 Jan 2000 12:00:00 +0000\"}, \"body\": [{\"id\": 1, \"content-type\": \"text/plain\", \"content\": \"json-show-message\n\"}]}, []]]]" - -# This should be the same output as above. -test_begin_subtest "Show message: json --body=true" -output=$(notmuch show --format=json --body=true "json-show-message") -test_expect_equal_json "$output" "[[[{\"id\": \"${gen_msg_id}\", \"match\": true, \"excluded\": false, \"filename\": \"${gen_msg_filename}\", \"timestamp\": 946728000, \"date_relative\": \"2000-01-01\", \"tags\": [\"inbox\",\"unread\"], \"headers\": {\"Subject\": \"json-show-subject\", \"From\": \"Notmuch Test Suite \", \"To\": \"Notmuch Test Suite \", \"Bcc\": \"test_suite+bcc@notmuchmail.org\", \"Reply-To\": \"test_suite+replyto@notmuchmail.org\", \"Date\": \"Sat, 01 Jan 2000 12:00:00 +0000\"}, \"body\": [{\"id\": 1, \"content-type\": \"text/plain\", \"content\": \"json-show-message\n\"}]}, []]]]" - -test_begin_subtest "Show message: json --body=false" -output=$(notmuch show --format=json --body=false "json-show-message") -test_expect_equal_json "$output" "[[[{\"id\": \"${gen_msg_id}\", \"match\": true, \"excluded\": false, \"filename\": \"${gen_msg_filename}\", \"timestamp\": 946728000, \"date_relative\": \"2000-01-01\", \"tags\": [\"inbox\",\"unread\"], \"headers\": {\"Subject\": \"json-show-subject\", \"From\": \"Notmuch Test Suite \", \"To\": \"Notmuch Test Suite \", \"Bcc\": \"test_suite+bcc@notmuchmail.org\", \"Reply-To\": \"test_suite+replyto@notmuchmail.org\", \"Date\": \"Sat, 01 Jan 2000 12:00:00 +0000\"}}, []]]]" - -test_begin_subtest "Search message: json" -add_message "[subject]=\"json-search-subject\"" "[date]=\"Sat, 01 Jan 2000 12:00:00 -0000\"" "[body]=\"json-search-message\"" -output=$(notmuch search --format=json "json-search-message" | notmuch_search_sanitize) -test_expect_equal_json "$output" "[{\"thread\": \"XXX\", - \"timestamp\": 946728000, - \"date_relative\": \"2000-01-01\", - \"matched\": 1, - \"total\": 1, - \"authors\": \"Notmuch Test Suite\", - \"subject\": \"json-search-subject\", - \"query\": [\"id:$gen_msg_id\", null], - \"tags\": [\"inbox\", - \"unread\"]}]" - -test_begin_subtest "Show message: json, utf-8" -add_message "[subject]=\"json-show-utf8-body-sübjéct\"" "[date]=\"Sat, 01 Jan 2000 12:00:00 -0000\"" "[body]=\"jsön-show-méssage\"" -output=$(notmuch show --format=json "jsön-show-méssage") -test_expect_equal_json "$output" "[[[{\"id\": \"${gen_msg_id}\", \"match\": true, \"excluded\": false, \"filename\": \"${gen_msg_filename}\", \"timestamp\": 946728000, \"date_relative\": \"2000-01-01\", \"tags\": [\"inbox\",\"unread\"], \"headers\": {\"Subject\": \"json-show-utf8-body-sübjéct\", \"From\": \"Notmuch Test Suite \", \"To\": \"Notmuch Test Suite \", \"Date\": \"Sat, 01 Jan 2000 12:00:00 +0000\"}, \"body\": [{\"id\": 1, \"content-type\": \"text/plain\", \"content\": \"jsön-show-méssage\n\"}]}, []]]]" - -test_begin_subtest "Show message: json, inline attachment filename" -subject='json-show-inline-attachment-filename' -id="json-show-inline-attachment-filename@notmuchmail.org" -emacs_fcc_message \ - "$subject" \ - 'This is a test message with inline attachment with a filename' \ - "(mml-attach-file \"$TEST_DIRECTORY/README\" nil nil \"inline\") - (message-goto-eoh) - (insert \"Message-ID: <$id>\n\")" -output=$(notmuch show --format=json "id:$id") -filename=$(notmuch search --output=files "id:$id") -# Get length of README after base64-encoding, minus additional newline. -attachment_length=$(( $(base64 $TEST_DIRECTORY/README | wc -c) - 1 )) -test_expect_equal_json "$output" "[[[{\"id\": \"$id\", \"match\": true, \"excluded\": false, \"filename\": \"$filename\", \"timestamp\": 946728000, \"date_relative\": \"2000-01-01\", \"tags\": [\"inbox\"], \"headers\": {\"Subject\": \"$subject\", \"From\": \"Notmuch Test Suite \", \"To\": \"test_suite@notmuchmail.org\", \"Date\": \"Sat, 01 Jan 2000 12:00:00 +0000\"}, \"body\": [{\"id\": 1, \"content-type\": \"multipart/mixed\", \"content\": [{\"id\": 2, \"content-type\": \"text/plain\", \"content\": \"This is a test message with inline attachment with a filename\"}, {\"id\": 3, \"content-type\": \"application/octet-stream\", \"content-length\": $attachment_length, \"content-transfer-encoding\": \"base64\", \"filename\": \"README\"}]}]}, []]]]" - -test_begin_subtest "Search message: json, utf-8" -add_message "[subject]=\"json-search-utf8-body-sübjéct\"" "[date]=\"Sat, 01 Jan 2000 12:00:00 -0000\"" "[body]=\"jsön-search-méssage\"" -output=$(notmuch search --format=json "jsön-search-méssage" | notmuch_search_sanitize) -test_expect_equal_json "$output" "[{\"thread\": \"XXX\", - \"timestamp\": 946728000, - \"date_relative\": \"2000-01-01\", - \"matched\": 1, - \"total\": 1, - \"authors\": \"Notmuch Test Suite\", - \"subject\": \"json-search-utf8-body-sübjéct\", - \"query\": [\"id:$gen_msg_id\", null], - \"tags\": [\"inbox\", - \"unread\"]}]" - -test_expect_code 20 "Format version: too low" \ - "notmuch search --format-version=0 \\*" - -test_expect_code 21 "Format version: too high" \ - "notmuch search --format-version=999 \\*" - -test_done diff --git a/test/long-id b/test/long-id deleted file mode 100755 index 85e620fa..00000000 --- a/test/long-id +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env bash -test_description="messages with ridiculously-long message IDs" -. ./test-lib.sh - -test_begin_subtest "Referencing long ID before adding" -generate_message '[subject]="Reference of ridiculously-long message ID"' \ - "[references]=\" -output=$(NOTMUCH_NEW) -test_expect_equal "$output" "Added 1 new message to the database." - -test_begin_subtest "Adding message with long ID" -generate_message '[subject]="A ridiculously-long message ID"' \ - "[id]=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-" -output=$(NOTMUCH_NEW) -test_expect_equal "$output" "Added 1 new message to the database." - -test_begin_subtest "Referencing long ID after adding" -generate_message '[subject]="Reply to ridiculously-long message ID"' \ - "[in-reply-to]=\" -output=$(NOTMUCH_NEW) -test_expect_equal "$output" "Added 1 new message to the database." - -test_begin_subtest "Ensure all messages were threaded together" -output=$(notmuch search 'subject:"a ridiculously-long message ID"' | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2001-01-05 [1/3] Notmuch Test Suite; A ridiculously-long message ID (inbox unread)" - -test_done diff --git a/test/maildir-sync b/test/maildir-sync deleted file mode 100755 index 3186e70f..00000000 --- a/test/maildir-sync +++ /dev/null @@ -1,189 +0,0 @@ -#!/usr/bin/env bash - -test_description="maildir synchronization" - -. ./test-lib.sh - -# Create the expected maildir structure -mkdir $MAIL_DIR/cur -mkdir $MAIL_DIR/new -mkdir $MAIL_DIR/tmp - -test_begin_subtest "Adding 'S' flag to existing filename removes 'unread' tag" -add_message [subject]='"Adding S flag"' [filename]='adding-s-flag:2,' [dir]=cur -output=$(notmuch search subject:"Adding S flag" | notmuch_search_sanitize) -output+=" -" -mv "${gen_msg_filename}" "${gen_msg_filename}S" -output+=$(NOTMUCH_NEW) -output+=" -" -output+=$(notmuch search subject:"Adding S flag" | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Adding S flag (inbox unread) -No new mail. Detected 1 file rename. -thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Adding S flag (inbox)" - -test_begin_subtest "Adding message with 'S' flag prevents 'unread' tag" -add_message [subject]='"Adding message with S"' [filename]='adding-with-s-flag:2,S' [dir]=cur -output=$(notmuch search subject:"Adding message with S" | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Adding message with S (inbox)" - -test_begin_subtest "Adding 'replied' tag adds 'R' flag to filename" -add_message [subject]='"Adding replied tag"' [filename]='adding-replied-tag:2,S' [dir]=cur -notmuch tag +replied subject:"Adding replied tag" -output=$(cd ${MAIL_DIR}/cur; ls -1 adding-replied*) -test_expect_equal "$output" "adding-replied-tag:2,RS" - -test_begin_subtest "notmuch show works with renamed file (without notmuch new)" -output=$(notmuch show --format=json id:${gen_msg_id} | notmuch_json_show_sanitize) -test_expect_equal_json "$output" '[[[{"id": "XXXXX", -"match": true, -"excluded": false, -"filename": "YYYYY", -"timestamp": 42, -"date_relative": "2001-01-05", -"tags": ["inbox","replied"], -"headers": {"Subject": "Adding replied tag", -"From": "Notmuch Test Suite ", -"To": "Notmuch Test Suite ", -"Date": "GENERATED_DATE"}, -"body": [{"id": 1, -"content-type": "text/plain", -"content": "This is just a test message (#3)\n"}]}, -[]]]]' - -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" -output=$(NOTMUCH_NEW) -test_expect_equal "$output" "No new mail." - -test_begin_subtest "When read, message moved from new to cur" -add_message [subject]='"Message to move to cur"' [date]='"Sat, 01 Jan 2000 12:00:00 -0000"' [filename]='message-to-move-to-cur' [dir]=new -notmuch tag -unread subject:"Message to move to cur" -output=$(cd "$MAIL_DIR/cur"; ls message-to-move*) -test_expect_equal "$output" "message-to-move-to-cur:2,S" - -test_begin_subtest "No rename should be detected by notmuch new" -output=$(NOTMUCH_NEW) -test_expect_equal "$output" "No new mail." -# (*) If notmuch new was not run we've got "Processed 1 file in almost -# no time" here. The reason is that removing unread tag in a previous -# 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 -# 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 -# creating all necessary database state for those directories. - -test_begin_subtest "Adding non-maildir tags does not move message from new to cur" -add_message [subject]='"Message to stay in new"' \ - [date]='"Sat, 01 Jan 2000 12:00:00 -0000"' \ - [filename]='message-to-stay-in-new' [dir]=new -notmuch tag +donotmove subject:"Message to stay in new" -output=$(cd "$MAIL_DIR"; ls */message-to-stay-in-new*) -test_expect_equal "$output" "new/message-to-stay-in-new" - -test_begin_subtest "Message in cur lacking maildir info gets one on any tag change" -add_message [filename]='message-to-get-maildir-info' [dir]=cur -notmuch tag +anytag id:$gen_msg_id -output=$(cd "$MAIL_DIR"; ls */message-to-get-maildir-info*) -test_expect_equal "$output" "cur/message-to-get-maildir-info:2," - -test_begin_subtest "Message in new with maildir info is moved to cur on any tag change" -add_message [filename]='message-with-info-to-be-moved-to-cur:2,' [dir]=new -notmuch tag +anytag id:$gen_msg_id -output=$(cd "$MAIL_DIR"; ls */message-with-info-to-be-moved-to-cur*) -test_expect_equal "$output" "cur/message-with-info-to-be-moved-to-cur:2," - -test_begin_subtest "Removing 'S' flag from existing filename adds 'unread' tag" -add_message [subject]='"Removing S flag"' [filename]='removing-s-flag:2,S' [dir]=cur -output=$(notmuch search subject:"Removing S flag" | notmuch_search_sanitize) -output+=" -" -mv "${gen_msg_filename}" "${gen_msg_filename%S}" -output+=$(NOTMUCH_NEW) -output+=" -" -output+=$(notmuch search subject:"Removing S flag" | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Removing S flag (inbox) -No new mail. Detected 1 file rename. -thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Removing S flag (inbox unread)" - -test_begin_subtest "Removing info from filename leaves tags unchanged" -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" -output=$(NOTMUCH_NEW) -output+=" -" -output+=$(notmuch search subject:"Message to lose maildir info" | notmuch_search_sanitize) -test_expect_equal "$output" "No new mail. Detected 1 file rename. -thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Message to lose maildir info (inbox)" - -add_message [subject]='"Non-maildir message"' [dir]=notmaildir [filename]='non-maildir-message' -expected=$(notmuch search --output=files subject:"Non-maildir message") -test_expect_success "Can remove unread tag from message in non-maildir directory" 'notmuch tag -unread subject:"Non-maildir message"' - -test_begin_subtest "Message in non-maildir directory does not get renamed" -output=$(notmuch search --output=files subject:"Non-maildir message") -test_expect_equal "$output" "$expected" - -test_begin_subtest "notmuch dump/restore re-synchronizes maildir tags with flags" -# Capture current filename state -expected=$(ls $MAIL_DIR/cur) -# Add/remove some flags from filenames -mv $MAIL_DIR/cur/adding-replied-tag:2,RS $MAIL_DIR/cur/adding-replied-tag:2,S -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 -notmuch dump --output=dump.txt -NOTMUCH_NEW >/dev/null -notmuch restore --input=dump.txt -output=$(ls $MAIL_DIR/cur) -test_expect_equal "$output" "$expected" - -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" -NOTMUCH_NEW > output -notmuch search subject:"Duplicated message" | notmuch_search_sanitize >> output -test_expect_equal "$(< output)" "No new mail. -thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Duplicated message (inbox replied)" - -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," -NOTMUCH_NEW > output -notmuch search subject:"Duplicated message" | notmuch_search_sanitize >> output -test_expect_equal "$(< output)" "No new mail. -thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Duplicated message (inbox replied)" - -test_begin_subtest "Tag changes modify flags of multiple files" -notmuch tag -replied subject:"Duplicated message" -(cd $MAIL_DIR/cur/; ls duplicated*) > actual -test_expect_equal "$(< actual)" "duplicated-message-another-copy:2,S -duplicated-message-copy:2,S -duplicated-message:2,S" - -test_begin_subtest "Synchronizing tag changes preserves unsupported maildir flags" -add_message [subject]='"Unsupported maildir flags"' [dir]=cur [filename]='unsupported-maildir-flags:2,FSZxyz' -notmuch tag +unread +draft -flagged subject:"Unsupported maildir flags" -test_expect_equal "$(cd $MAIL_DIR/cur/; ls unsupported*)" "unsupported-maildir-flags:2,DZxyz" - -test_begin_subtest "A file with non-compliant maildir info will not be renamed" -add_message [subject]='"Non-compliant maildir info"' [dir]=cur [filename]='non-compliant-maildir-info:2,These-are-not-flags-in-ASCII-order-donottouch' -notmuch tag +unread +draft -flagged subject:"Non-compliant maildir info" -test_expect_equal "$(cd $MAIL_DIR/cur/; ls non-compliant*)" "non-compliant-maildir-info:2,These-are-not-flags-in-ASCII-order-donottouch" - -test_begin_subtest "Files in new/ get default synchronized tags" -OLDCONFIG=$(notmuch config get new.tags) -notmuch config set new.tags test -add_message [subject]='"File in new/"' [dir]=new [filename]='file-in-new' -notmuch config set new.tags $OLDCONFIG -notmuch search 'subject:"File in new"' | notmuch_search_sanitize > output -test_expect_equal "$(< output)" \ -"thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; File in new/ (test unread)" - -test_done diff --git a/test/missing-headers b/test/missing-headers deleted file mode 100755 index cb38301c..00000000 --- a/test/missing-headers +++ /dev/null @@ -1,164 +0,0 @@ -#!/usr/bin/env bash -test_description='messages with missing headers' -. ./test-lib.sh - -# Notmuch requires at least one of from, subject, or to or it will -# ignore the file. Generate two messages so that together they cover -# all possible missing headers. We also give one of the messages a -# date to ensure stable result ordering. - -cat < "${MAIL_DIR}/msg-2" -To: Notmuch Test Suite -Date: Fri, 05 Jan 2001 15:43:57 +0000 - -Body -EOF - -cat < "${MAIL_DIR}/msg-1" -From: Notmuch Test Suite - -Body -EOF - -NOTMUCH_NEW - -test_begin_subtest "Search: text" -output=$(notmuch search '*' | notmuch_search_sanitize) -test_expect_equal "$output" "\ -thread:XXX 2001-01-05 [1/1] (null); (inbox unread) -thread:XXX 1970-01-01 [1/1] Notmuch Test Suite; (inbox unread)" - -test_begin_subtest "Search: json" -output=$(notmuch search --format=json '*' | notmuch_search_sanitize) -test_expect_equal_json "$output" ' -[ - { - "authors": "", - "date_relative": "2001-01-05", - "matched": 1, - "subject": "", - "tags": [ - "inbox", - "unread" - ], - "thread": "XXX", - "timestamp": 978709437, - "total": 1, - "query": ["id:notmuch-sha1-7a6e4eac383ef958fcd3ebf2143db71b8ff01161", null] - }, - { - "authors": "Notmuch Test Suite", - "date_relative": "1970-01-01", - "matched": 1, - "subject": "", - "tags": [ - "inbox", - "unread" - ], - "thread": "XXX", - "timestamp": 0, - "total": 1, - "query": ["id:notmuch-sha1-ca55943aff7a72baf2ab21fa74fab3d632401334", null] - } -]' - -test_begin_subtest "Show: text" -output=$(notmuch show '*' | notmuch_show_sanitize) -test_expect_equal "$output" "\ - message{ id:notmuch-sha1-7a6e4eac383ef958fcd3ebf2143db71b8ff01161 depth:0 match:1 excluded:0 filename:/XXX/mail/msg-2 - header{ - (2001-01-05) (inbox unread) -Subject: (null) -From: (null) -To: Notmuch Test Suite -Date: Fri, 05 Jan 2001 15:43:57 +0000 - header} - body{ - part{ ID: 1, Content-type: text/plain -Body - part} - body} - message} - message{ id:notmuch-sha1-ca55943aff7a72baf2ab21fa74fab3d632401334 depth:0 match:1 excluded:0 filename:/XXX/mail/msg-1 - header{ -Notmuch Test Suite (1970-01-01) (inbox unread) -Subject: (null) -From: Notmuch Test Suite -Date: Thu, 01 Jan 1970 00:00:00 +0000 - header} - body{ - part{ ID: 1, Content-type: text/plain -Body - part} - body} - message}" - -test_begin_subtest "Show: json" -output=$(notmuch show --format=json '*' | notmuch_json_show_sanitize) -expected=$(notmuch_json_show_sanitize <" - }, - "id": "XXXXX", - "match": true, - "tags": [ - "inbox", - "unread" - ], - "timestamp": 978709437 - }, - [] - ] - ], - [ - [ - { - "body": [ - { - "content": "Body\n", - "content-type": "text/plain", - "id": 1 - } - ], - "date_relative": "1970-01-01", - "excluded": false, - "filename": "YYYYY", - "headers": { - "Date": "Thu, 01 Jan 1970 00:00:00 +0000", - "From": "Notmuch Test Suite ", - "Subject": "" - }, - "id": "XXXXX", - "match": true, - "tags": [ - "inbox", - "unread" - ], - "timestamp": 0 - }, - [] - ] - ] -] -EOF -) -test_expect_equal_json "$output" "$expected" - -test_done diff --git a/test/multipart b/test/multipart deleted file mode 100755 index 85cbf672..00000000 --- a/test/multipart +++ /dev/null @@ -1,730 +0,0 @@ -#!/usr/bin/env bash -test_description="output of multipart message" -. ./test-lib.sh - -cat < embedded_message -From: Carl Worth -To: cworth@cworth.org -Subject: html message -Date: Fri, 05 Jan 2001 15:42:57 +0000 -User-Agent: Notmuch/0.5 (http://notmuchmail.org) Emacs/23.3.1 (i486-pc-linux-gnu) -Message-ID: <87liy5ap01.fsf@yoom.home.cworth.org> -MIME-Version: 1.0 -Content-Type: multipart/alternative; boundary="==-=-==" - ---==-=-== -Content-Type: text/html - -

This is an embedded message, with a multipart/alternative part.

- ---==-=-== -Content-Type: text/plain - -This is an embedded message, with a multipart/alternative part. - ---==-=-==-- -EOF - -cat < ${MAIL_DIR}/multipart -From: Carl Worth -To: cworth@cworth.org -Subject: Multipart message -Date: Fri, 05 Jan 2001 15:43:57 +0000 -User-Agent: Notmuch/0.5 (http://notmuchmail.org) Emacs/23.3.1 (i486-pc-linux-gnu) -Message-ID: <87liy5ap00.fsf@yoom.home.cworth.org> -MIME-Version: 1.0 -Content-Type: multipart/signed; boundary="==-=-="; - micalg=pgp-sha1; protocol="application/pgp-signature" - ---==-=-= -Content-Type: multipart/mixed; boundary="=-=-=" - ---=-=-= -Content-Type: message/rfc822 -Content-Disposition: inline - -EOF -cat embedded_message >> ${MAIL_DIR}/multipart -cat <> ${MAIL_DIR}/multipart - ---=-=-= -Content-Disposition: attachment; filename=attachment - -This is a text attachment. - ---=-=-= - -And this message is signed. - --Carl - ---=-=-=-- - ---==-=-= -Content-Type: application/pgp-signature - ------BEGIN PGP SIGNATURE----- -Version: GnuPG v1.4.11 (GNU/Linux) - -iEYEARECAAYFAk3SA/gACgkQ6JDdNq8qSWj0sACghqVJEQJUs3yV8zbTzhgnSIcD -W6cAmQE4dcYrx/LPLtYLZm1jsGauE5hE -=zkga ------END PGP SIGNATURE----- ---==-=-=-- -EOF - -cat < ${MAIL_DIR}/base64-part-with-crlf -From: Carl Worth -To: cworth@cworth.org -Subject: Test message with a BASE64 encoded binary containing CRLF pair -Date: Fri, 05 Jan 2001 15:43:57 +0000 -User-Agent: Notmuch/0.5 (http://notmuchmail.org) Emacs/23.3.1 (i486-pc-linux-gnu) -Message-ID: -MIME-Version: 1.0 -Content-Type: multipart/mixed; boundary="==-=-="; - ---==-=-= - -The attached BASE64-encoded part expands to a binary containing a CRLF -pair (that is one bye of 0x0D followed by one byte of 0x0A). This is -designed to ensure that notmuch is not corrupting the output of this -part by converting the CRLF pair to an LF only (as would be appropriate -for display of a text part on a Linux system, for example). - -The part should be a 3-byte file with the following sequence of 3 -hexadecimal bytes: - - EF 0D 0A - ---==-=-= -Content-Type: application/octet-stream -Content-Disposition: attachment; filename=crlf.bin -Content-Transfer-Encoding: base64 - -7w0K ---==-=-=-- -EOF -notmuch new > /dev/null - -test_begin_subtest "--format=text --part=0, full message" -notmuch show --format=text --part=0 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT -cat <EXPECTED - message{ id:87liy5ap00.fsf@yoom.home.cworth.org depth:0 match:1 excluded:0 filename:${MAIL_DIR}/multipart - header{ -Carl Worth (2001-01-05) (attachment inbox signed unread) -Subject: Multipart message -From: Carl Worth -To: cworth@cworth.org -Date: Fri, 05 Jan 2001 15:43:57 +0000 - header} - body{ - part{ ID: 1, Content-type: multipart/signed - part{ ID: 2, Content-type: multipart/mixed - part{ ID: 3, Content-type: message/rfc822 - header{ -Subject: html message -From: Carl Worth -To: cworth@cworth.org -Date: Fri, 05 Jan 2001 15:42:57 +0000 - header} - body{ - part{ ID: 4, Content-type: multipart/alternative - part{ ID: 5, Content-type: text/html -Non-text part: text/html - part} - part{ ID: 6, Content-type: text/plain -This is an embedded message, with a multipart/alternative part. - part} - part} - body} - part} - attachment{ ID: 7, Filename: attachment, Content-type: text/plain -This is a text attachment. - attachment} - part{ ID: 8, Content-type: text/plain -And this message is signed. - --Carl - part} - part} - part{ ID: 9, Content-type: application/pgp-signature -Non-text part: application/pgp-signature - part} - part} - body} - message} -EOF -test_expect_equal_file OUTPUT EXPECTED - -test_begin_subtest "--format=text --part=1, message body" -notmuch show --format=text --part=1 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT -cat <EXPECTED - part{ ID: 1, Content-type: multipart/signed - part{ ID: 2, Content-type: multipart/mixed - part{ ID: 3, Content-type: message/rfc822 - header{ -Subject: html message -From: Carl Worth -To: cworth@cworth.org -Date: Fri, 05 Jan 2001 15:42:57 +0000 - header} - body{ - part{ ID: 4, Content-type: multipart/alternative - part{ ID: 5, Content-type: text/html -Non-text part: text/html - part} - part{ ID: 6, Content-type: text/plain -This is an embedded message, with a multipart/alternative part. - part} - part} - body} - part} - attachment{ ID: 7, Filename: attachment, Content-type: text/plain -This is a text attachment. - attachment} - part{ ID: 8, Content-type: text/plain -And this message is signed. - --Carl - part} - part} - part{ ID: 9, Content-type: application/pgp-signature -Non-text part: application/pgp-signature - part} - part} -EOF -test_expect_equal_file OUTPUT EXPECTED - -test_begin_subtest "--format=text --part=2, multipart/mixed" -notmuch show --format=text --part=2 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT -cat <EXPECTED - part{ ID: 2, Content-type: multipart/mixed - part{ ID: 3, Content-type: message/rfc822 - header{ -Subject: html message -From: Carl Worth -To: cworth@cworth.org -Date: Fri, 05 Jan 2001 15:42:57 +0000 - header} - body{ - part{ ID: 4, Content-type: multipart/alternative - part{ ID: 5, Content-type: text/html -Non-text part: text/html - part} - part{ ID: 6, Content-type: text/plain -This is an embedded message, with a multipart/alternative part. - part} - part} - body} - part} - attachment{ ID: 7, Filename: attachment, Content-type: text/plain -This is a text attachment. - attachment} - part{ ID: 8, Content-type: text/plain -And this message is signed. - --Carl - part} - part} -EOF -test_expect_equal_file OUTPUT EXPECTED - -test_begin_subtest "--format=text --part=3, rfc822 part" -notmuch show --format=text --part=3 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT -cat <EXPECTED - part{ ID: 3, Content-type: message/rfc822 - header{ -Subject: html message -From: Carl Worth -To: cworth@cworth.org -Date: Fri, 05 Jan 2001 15:42:57 +0000 - header} - body{ - part{ ID: 4, Content-type: multipart/alternative - part{ ID: 5, Content-type: text/html -Non-text part: text/html - part} - part{ ID: 6, Content-type: text/plain -This is an embedded message, with a multipart/alternative part. - part} - part} - body} - part} -EOF -test_expect_equal_file OUTPUT EXPECTED - -test_begin_subtest "--format=text --part=4, rfc822's multipart" -notmuch show --format=text --part=4 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT -cat <EXPECTED - part{ ID: 4, Content-type: multipart/alternative - part{ ID: 5, Content-type: text/html -Non-text part: text/html - part} - part{ ID: 6, Content-type: text/plain -This is an embedded message, with a multipart/alternative part. - part} - part} -EOF -test_expect_equal_file OUTPUT EXPECTED - -test_begin_subtest "--format=text --part=5, rfc822's html part" -notmuch show --format=text --part=5 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT -cat <EXPECTED - part{ ID: 5, Content-type: text/html -Non-text part: text/html - part} -EOF -test_expect_equal_file OUTPUT EXPECTED - -test_begin_subtest "--format=text --part=6, rfc822's text part" -notmuch show --format=text --part=6 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT -cat <EXPECTED - part{ ID: 6, Content-type: text/plain -This is an embedded message, with a multipart/alternative part. - part} -EOF -test_expect_equal_file OUTPUT EXPECTED - -test_begin_subtest "--format=text --part=7, inline attachement" -notmuch show --format=text --part=7 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT -cat <EXPECTED - attachment{ ID: 7, Filename: attachment, Content-type: text/plain -This is a text attachment. - attachment} -EOF -test_expect_equal_file OUTPUT EXPECTED - -test_begin_subtest "--format=text --part=8, plain text part" -notmuch show --format=text --part=8 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT -cat <EXPECTED - part{ ID: 8, Content-type: text/plain -And this message is signed. - --Carl - part} -EOF -test_expect_equal_file OUTPUT EXPECTED - -test_begin_subtest "--format=text --part=9, pgp signature (unverified)" -notmuch show --format=text --part=9 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT -cat <EXPECTED - part{ ID: 9, Content-type: application/pgp-signature -Non-text part: application/pgp-signature - part} -EOF -test_expect_equal_file OUTPUT EXPECTED - -test_expect_success \ - "--format=text --part=8, no part, expect error" \ - "notmuch show --format=text --part=8 'id:87liy5ap00.fsf@yoom.home.cworth.org'" - -test_begin_subtest "--format=json --part=0, full message" -notmuch show --format=json --part=0 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT -cat <EXPECTED -{"id": "87liy5ap00.fsf@yoom.home.cworth.org", "match": true, "excluded": false, "filename": "${MAIL_DIR}/multipart", "timestamp": 978709437, "date_relative": "2001-01-05", "tags": ["attachment","inbox","signed","unread"], "headers": {"Subject": "Multipart message", "From": "Carl Worth ", "To": "cworth@cworth.org", "Date": "Fri, 05 Jan 2001 15:43:57 +0000"}, "body": [ -{"id": 1, "content-type": "multipart/signed", "content": [ -{"id": 2, "content-type": "multipart/mixed", "content": [ -{"id": 3, "content-type": "message/rfc822", "content": [{"headers": {"Subject": "html message", "From": "Carl Worth ", "To": "cworth@cworth.org", "Date": "Fri, 05 Jan 2001 15:42:57 +0000"}, "body": [ -{"id": 4, "content-type": "multipart/alternative", "content": [ -{"id": 5, "content-type": "text/html", "content-length": 71}, -{"id": 6, "content-type": "text/plain", "content": "This is an embedded message, with a multipart/alternative part.\n"}]}]}]}, -{"id": 7, "content-type": "text/plain", "filename": "attachment", "content": "This is a text attachment.\n"}, -{"id": 8, "content-type": "text/plain", "content": "And this message is signed.\n\n-Carl\n"}]}, -{"id": 9, "content-type": "application/pgp-signature", "content-length": 197}]}]} -EOF -test_expect_equal_json "$(cat OUTPUT)" "$(cat EXPECTED)" - -test_begin_subtest "--format=json --part=1, message body" -notmuch show --format=json --part=1 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT -cat <EXPECTED -{"id": 1, "content-type": "multipart/signed", "content": [ -{"id": 2, "content-type": "multipart/mixed", "content": [ -{"id": 3, "content-type": "message/rfc822", "content": [{"headers": {"Subject": "html message", "From": "Carl Worth ", "To": "cworth@cworth.org", "Date": "Fri, 05 Jan 2001 15:42:57 +0000"}, "body": [ -{"id": 4, "content-type": "multipart/alternative", "content": [ -{"id": 5, "content-type": "text/html", "content-length": 71}, -{"id": 6, "content-type": "text/plain", "content": "This is an embedded message, with a multipart/alternative part.\n"}]}]}]}, -{"id": 7, "content-type": "text/plain", "filename": "attachment", "content": "This is a text attachment.\n"}, -{"id": 8, "content-type": "text/plain", "content": "And this message is signed.\n\n-Carl\n"}]}, -{"id": 9, "content-type": "application/pgp-signature", "content-length": 197}]} -EOF -test_expect_equal_json "$(cat OUTPUT)" "$(cat EXPECTED)" - -test_begin_subtest "--format=json --part=2, multipart/mixed" -notmuch show --format=json --part=2 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT -cat <EXPECTED -{"id": 2, "content-type": "multipart/mixed", "content": [ -{"id": 3, "content-type": "message/rfc822", "content": [{"headers": {"Subject": "html message", "From": "Carl Worth ", "To": "cworth@cworth.org", "Date": "Fri, 05 Jan 2001 15:42:57 +0000"}, "body": [ -{"id": 4, "content-type": "multipart/alternative", "content": [ -{"id": 5, "content-type": "text/html", "content-length": 71}, -{"id": 6, "content-type": "text/plain", "content": "This is an embedded message, with a multipart/alternative part.\n"}]}]}]}, -{"id": 7, "content-type": "text/plain", "filename": "attachment", "content": "This is a text attachment.\n"}, -{"id": 8, "content-type": "text/plain", "content": "And this message is signed.\n\n-Carl\n"}]} -EOF -test_expect_equal_json "$(cat OUTPUT)" "$(cat EXPECTED)" - -test_begin_subtest "--format=json --part=3, rfc822 part" -notmuch show --format=json --part=3 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT -cat <EXPECTED -{"id": 3, "content-type": "message/rfc822", "content": [{"headers": {"Subject": "html message", "From": "Carl Worth ", "To": "cworth@cworth.org", "Date": "Fri, 05 Jan 2001 15:42:57 +0000"}, "body": [ -{"id": 4, "content-type": "multipart/alternative", "content": [ -{"id": 5, "content-type": "text/html", "content-length": 71}, -{"id": 6, "content-type": "text/plain", "content": "This is an embedded message, with a multipart/alternative part.\n"}]}]}]} -EOF -test_expect_equal_json "$(cat OUTPUT)" "$(cat EXPECTED)" - -test_begin_subtest "--format=json --part=4, rfc822's multipart/alternative" -notmuch show --format=json --part=4 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT -cat <EXPECTED -{"id": 4, "content-type": "multipart/alternative", "content": [ -{"id": 5, "content-type": "text/html", "content-length": 71}, -{"id": 6, "content-type": "text/plain", "content": "This is an embedded message, with a multipart/alternative part.\n"}]} -EOF -test_expect_equal_json "$(cat OUTPUT)" "$(cat EXPECTED)" - -test_begin_subtest "--format=json --part=5, rfc822's html part" -notmuch show --format=json --part=5 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT -cat <EXPECTED -{"id": 5, "content-type": "text/html", "content-length": 71} -EOF -test_expect_equal_json "$(cat OUTPUT)" "$(cat EXPECTED)" - -test_begin_subtest "--format=json --part=6, rfc822's text part" -notmuch show --format=json --part=6 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT -cat <EXPECTED -{"id": 6, "content-type": "text/plain", "content": "This is an embedded message, with a multipart/alternative part.\n"} -EOF -test_expect_equal_json "$(cat OUTPUT)" "$(cat EXPECTED)" - -test_begin_subtest "--format=json --part=7, inline attachment" -notmuch show --format=json --part=7 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT -cat <EXPECTED -{"id": 7, "content-type": "text/plain", "filename": "attachment", "content": "This is a text attachment.\n"} -EOF -test_expect_equal_json "$(cat OUTPUT)" "$(cat EXPECTED)" - -test_begin_subtest "--format=json --part=8, plain text part" -notmuch show --format=json --part=8 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT -cat <EXPECTED -{"id": 8, "content-type": "text/plain", "content": "And this message is signed.\n\n-Carl\n"} -EOF -test_expect_equal_json "$(cat OUTPUT)" "$(cat EXPECTED)" - -test_begin_subtest "--format=json --part=9, pgp signature (unverified)" -notmuch show --format=json --part=9 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT -cat <EXPECTED -{"id": 9, "content-type": "application/pgp-signature", "content-length": 197} -EOF -test_expect_equal_json "$(cat OUTPUT)" "$(cat EXPECTED)" - -test_expect_success \ - "--format=json --part=10, no part, expect error" \ - "notmuch show --format=json --part=10 'id:87liy5ap00.fsf@yoom.home.cworth.org'" - -test_begin_subtest "--format=raw" -notmuch show --format=raw 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT -test_expect_equal_file OUTPUT "${MAIL_DIR}"/multipart - -test_begin_subtest "--format=raw --part=0, full message" -notmuch show --format=raw --part=0 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT -test_expect_equal_file OUTPUT "${MAIL_DIR}"/multipart - -test_begin_subtest "--format=raw --part=1, message body" -notmuch show --format=raw --part=1 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT -test_expect_equal_file OUTPUT "${MAIL_DIR}"/multipart - -test_begin_subtest "--format=raw --part=2, multipart/mixed" -notmuch show --format=raw --part=2 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT -cat <EXPECTED -Content-Type: multipart/mixed; boundary="=-=-=" - ---=-=-= -Content-Type: message/rfc822 -Content-Disposition: inline - -From: Carl Worth -To: cworth@cworth.org -Subject: html message -Date: Fri, 05 Jan 2001 15:42:57 +0000 -User-Agent: Notmuch/0.5 (http://notmuchmail.org) Emacs/23.3.1 (i486-pc-linux-gnu) -Message-ID: <87liy5ap01.fsf@yoom.home.cworth.org> -MIME-Version: 1.0 -Content-Type: multipart/alternative; boundary="==-=-==" - ---==-=-== -Content-Type: text/html - -

This is an embedded message, with a multipart/alternative part.

- ---==-=-== -Content-Type: text/plain - -This is an embedded message, with a multipart/alternative part. - ---==-=-==-- - ---=-=-= -Content-Disposition: attachment; filename=attachment - -This is a text attachment. - ---=-=-= - -And this message is signed. - --Carl - ---=-=-=-- -EOF -test_expect_equal_file OUTPUT EXPECTED - -test_begin_subtest "--format=raw --part=3, rfc822 part" -notmuch show --format=raw --part=3 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT -test_expect_equal_file OUTPUT embedded_message - -test_begin_subtest "--format=raw --part=4, rfc822's multipart" -notmuch show --format=raw --part=4 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT -cat <EXPECTED -From: Carl Worth -To: cworth@cworth.org -Subject: html message -Date: Fri, 05 Jan 2001 15:42:57 +0000 -User-Agent: Notmuch/0.5 (http://notmuchmail.org) Emacs/23.3.1 (i486-pc-linux-gnu) -Message-ID: <87liy5ap01.fsf@yoom.home.cworth.org> -MIME-Version: 1.0 -Content-Type: multipart/alternative; boundary="==-=-==" - ---==-=-== -Content-Type: text/html - -

This is an embedded message, with a multipart/alternative part.

- ---==-=-== -Content-Type: text/plain - -This is an embedded message, with a multipart/alternative part. - ---==-=-==-- -EOF -test_expect_equal_file OUTPUT EXPECTED - -test_begin_subtest "--format=raw --part=5, rfc822's html part" -notmuch show --format=raw --part=5 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT -cat <EXPECTED -

This is an embedded message, with a multipart/alternative part.

-EOF -test_expect_equal_file OUTPUT EXPECTED - -test_begin_subtest "--format=raw --part=6, rfc822's text part" -notmuch show --format=raw --part=6 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT -cat <EXPECTED -This is an embedded message, with a multipart/alternative part. -EOF -test_expect_equal_file OUTPUT EXPECTED - -test_begin_subtest "--format=raw --part=7, inline attachment" -notmuch show --format=raw --part=7 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT -cat <EXPECTED -This is a text attachment. -EOF -test_expect_equal_file OUTPUT EXPECTED - -test_begin_subtest "--format=raw --part=8, plain text part" -notmuch show --format=raw --part=8 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT -cat <EXPECTED -And this message is signed. - --Carl -EOF -test_expect_equal_file OUTPUT EXPECTED - -test_begin_subtest "--format=raw --part=9, pgp signature (unverified)" -notmuch show --format=raw --part=9 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT -# output should *not* include newline -echo >>OUTPUT -cat <EXPECTED ------BEGIN PGP SIGNATURE----- -Version: GnuPG v1.4.11 (GNU/Linux) - -iEYEARECAAYFAk3SA/gACgkQ6JDdNq8qSWj0sACghqVJEQJUs3yV8zbTzhgnSIcD -W6cAmQE4dcYrx/LPLtYLZm1jsGauE5hE -=zkga ------END PGP SIGNATURE----- -EOF -test_expect_equal_file OUTPUT EXPECTED - -test_expect_success \ - "--format=raw --part=10, no part, expect error" \ - "notmuch show --format=raw --part=8 'id:87liy5ap00.fsf@yoom.home.cworth.org'" - -test_begin_subtest "--format=mbox" -notmuch show --format=mbox 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT -printf "From cworth@cworth.org Fri Jan 5 15:43:57 2001\n" >EXPECTED -cat "${MAIL_DIR}"/multipart >>EXPECTED -# mbox output is expected to include a blank line -echo >>EXPECTED -test_expect_equal_file OUTPUT EXPECTED - -test_expect_success \ - "--format=mbox --part=1, incompatible, expect error" \ - "! notmuch show --format=mbox --part=1 'id:87liy5ap00.fsf@yoom.home.cworth.org'" - -test_begin_subtest "'notmuch reply' to a multipart message" -notmuch reply 'id:87liy5ap00.fsf@yoom.home.cworth.org' >OUTPUT -cat <EXPECTED -From: Notmuch Test Suite -Subject: Re: Multipart message -To: Carl Worth , cworth@cworth.org -In-Reply-To: <87liy5ap00.fsf@yoom.home.cworth.org> -References: <87liy5ap00.fsf@yoom.home.cworth.org> - -On Fri, 05 Jan 2001 15:43:57 +0000, Carl Worth wrote: -> From: Carl Worth -> To: cworth@cworth.org -> Subject: html message -> Date: Fri, 05 Jan 2001 15:42:57 +0000 -> -Non-text part: text/html -> This is an embedded message, with a multipart/alternative part. -> This is a text attachment. -> And this message is signed. -> -> -Carl -EOF -test_expect_equal_file OUTPUT EXPECTED - -test_begin_subtest "'notmuch reply' to a multipart message with json format" -notmuch reply --format=json 'id:87liy5ap00.fsf@yoom.home.cworth.org' | notmuch_json_show_sanitize >OUTPUT -notmuch_json_show_sanitize <EXPECTED -{"reply-headers": {"Subject": "Re: Multipart message", - "From": "Notmuch Test Suite ", - "To": "Carl Worth , cworth@cworth.org", - "In-reply-to": "<87liy5ap00.fsf@yoom.home.cworth.org>", - "References": "<87liy5ap00.fsf@yoom.home.cworth.org>"}, - "original": {"id": "XXXXX", - "match": false, - "excluded": false, - "filename": "YYYYY", - "timestamp": 978709437, - "date_relative": "2001-01-05", - "tags": ["attachment","inbox","signed","unread"], - "headers": {"Subject": "Multipart message", - "From": "Carl Worth ", - "To": "cworth@cworth.org", - "Date": "Fri, 05 Jan 2001 15:43:57 +0000"}, - "body": [{"id": 1, - "content-type": "multipart/signed", - "content": [{"id": 2, - "content-type": "multipart/mixed", - "content": [{"id": 3, - "content-type": "message/rfc822", - "content": [{"headers": {"Subject": "html message", - "From": "Carl Worth ", - "To": "cworth@cworth.org", - "Date": "Fri, 05 Jan 2001 15:42:57 +0000"}, - "body": [{"id": 4, - "content-type": "multipart/alternative", - "content": [{"id": 5, - "content-type": "text/html", - "content-length": 71}, - {"id": 6, - "content-type": "text/plain", - "content": "This is an embedded message, with a multipart/alternative part.\n"}]}]}]}, - {"id": 7, - "content-type": "text/plain", - "filename": "attachment", - "content": "This is a text attachment.\n"}, - {"id": 8, - "content-type": "text/plain", - "content": "And this message is signed.\n\n-Carl\n"}]}, - {"id": 9, - "content-type": "application/pgp-signature", - "content-length": 197}]}]}} -EOF -test_expect_equal_json "$(cat OUTPUT)" "$(cat EXPECTED)" - -test_begin_subtest "'notmuch show --part' does not corrupt a part with CRLF pair" -notmuch show --format=raw --part=3 id:base64-part-with-crlf > crlf.out -echo -n -e "\xEF\x0D\x0A" > crlf.expected -test_expect_equal_file crlf.out crlf.expected - - -# The ISO-8859-1 encoding of U+00BD is a single byte: octal 275 -# (Portability note: Dollar-Single ($'...', ANSI C-style escape sequences) -# quoting works on bash, ksh, zsh, *BSD sh but not on dash, ash nor busybox sh) -readonly u_00bd_latin1=$'\275' - -# The Unicode fraction symbol 1/2 is U+00BD and is encoded -# in UTF-8 as two bytes: octal 302 275 -readonly u_00bd_utf8=$'\302\275' - -cat < ${MAIL_DIR}/include-html -From: A -To: B -Subject: html message -Date: Sat, 01 January 2000 00:00:00 +0000 -Message-ID: -MIME-Version: 1.0 -Content-Type: multipart/alternative; boundary="==-==" - ---==-== -Content-Type: text/html; charset=UTF-8 - -

0.5 equals ${u_00bd_utf8}

- ---==-== -Content-Type: text/html; charset=ISO-8859-1 - -

0.5 equals ${u_00bd_latin1}

- ---==-== -Content-Type: text/plain; charset=UTF-8 - -0.5 equals ${u_00bd_utf8} - ---==-==-- -EOF - -notmuch new > /dev/null - -cat_expected_head () -{ - cat <", - "Subject": "html message", "To": "B "}, - "body": [{ - "content-type": "multipart/alternative", "id": 1, -EOF -} - -cat_expected_head > EXPECTED.nohtml -cat <> EXPECTED.nohtml -"content": [ - { "id": 2, "content-charset": "UTF-8", "content-length": 21, "content-type": "text/html"}, - { "id": 3, "content-charset": "ISO-8859-1", "content-length": 20, "content-type": "text/html"}, - { "id": 4, "content-type": "text/plain", "content": "0.5 equals \\u00bd\\n"} -]}]},[]]]] -EOF - -# Both the UTF-8 and ISO-8859-1 part should have U+00BD -cat_expected_head > EXPECTED.withhtml -cat <> EXPECTED.withhtml -"content": [ - { "id": 2, "content-type": "text/html", "content": "

0.5 equals \\u00bd

\\n"}, - { "id": 3, "content-type": "text/html", "content": "

0.5 equals \\u00bd

\\n"}, - { "id": 4, "content-type": "text/plain", "content": "0.5 equals \\u00bd\\n"} -]}]},[]]]] -EOF - -test_begin_subtest "html parts excluded by default" -notmuch show --format=json id:htmlmessage > OUTPUT -test_expect_equal_json "$(cat OUTPUT)" "$(cat EXPECTED.nohtml)" - -test_begin_subtest "html parts included" -notmuch show --format=json --include-html id:htmlmessage > OUTPUT -test_expect_equal_json "$(cat OUTPUT)" "$(cat EXPECTED.withhtml)" - -test_done diff --git a/test/new b/test/new deleted file mode 100755 index f27423da..00000000 --- a/test/new +++ /dev/null @@ -1,251 +0,0 @@ -#!/usr/bin/env bash -test_description='"notmuch new" in several variations' -. ./test-lib.sh - -test_begin_subtest "No new messages" -output=$(NOTMUCH_NEW) -test_expect_equal "$output" "No new mail." - - -test_begin_subtest "Single new message" -generate_message -output=$(NOTMUCH_NEW) -test_expect_equal "$output" "Added 1 new message to the database." - - -test_begin_subtest "Multiple new messages" -generate_message -generate_message -output=$(NOTMUCH_NEW) -test_expect_equal "$output" "Added 2 new messages to the database." - - -test_begin_subtest "No new messages (non-empty DB)" -output=$(NOTMUCH_NEW) -test_expect_equal "$output" "No new mail." - - -test_begin_subtest "New directories" -rm -rf "${MAIL_DIR}"/* "${MAIL_DIR}"/.notmuch -mkdir "${MAIL_DIR}"/def -mkdir "${MAIL_DIR}"/ghi -generate_message [dir]=def - -output=$(NOTMUCH_NEW) -test_expect_equal "$output" "Added 1 new message to the database." - - -test_begin_subtest "Alternate inode order" - -rm -rf "${MAIL_DIR}"/.notmuch -mv "${MAIL_DIR}"/ghi "${MAIL_DIR}"/abc -rm "${MAIL_DIR}"/def/* -generate_message [dir]=abc - -output=$(NOTMUCH_NEW) -test_expect_equal "$output" "Added 1 new message to the database." - - -test_begin_subtest "Message moved in" -rm -rf "${MAIL_DIR}"/* "${MAIL_DIR}"/.notmuch -generate_message -tmp_msg_filename=tmp/"$gen_msg_filename" -mkdir -p "$(dirname "$tmp_msg_filename")" -mv "$gen_msg_filename" "$tmp_msg_filename" -notmuch new > /dev/null -mv "$tmp_msg_filename" "$gen_msg_filename" -output=$(NOTMUCH_NEW) -test_expect_equal "$output" "Added 1 new message to the database." - - -test_begin_subtest "Renamed message" - -generate_message -notmuch new > /dev/null -mv "$gen_msg_filename" "${gen_msg_filename}"-renamed -output=$(NOTMUCH_NEW) -test_expect_equal "$output" "No new mail. Detected 1 file rename." - - -test_begin_subtest "Deleted message" - -rm "${gen_msg_filename}"-renamed -output=$(NOTMUCH_NEW) -test_expect_equal "$output" "No new mail. Removed 1 message." - - -test_begin_subtest "Renamed directory" - -generate_message [dir]=dir -generate_message [dir]=dir -generate_message [dir]=dir - -notmuch new > /dev/null - -mv "${MAIL_DIR}"/dir "${MAIL_DIR}"/dir-renamed - -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 - -output=$(NOTMUCH_NEW) -test_expect_equal "$output" "No new mail. Removed 3 messages." - - -test_begin_subtest "New directory (at end of list)" - -generate_message [dir]=zzz -generate_message [dir]=zzz -generate_message [dir]=zzz - -output=$(NOTMUCH_NEW) -test_expect_equal "$output" "Added 3 new messages to the database." - - -test_begin_subtest "Deleted directory (end of list)" - -rm -rf "${MAIL_DIR}"/zzz - -output=$(NOTMUCH_NEW) -test_expect_equal "$output" "No new mail. Removed 3 messages." - - -test_begin_subtest "New symlink to directory" - -rm -rf "${MAIL_DIR}"/.notmuch -mv "${MAIL_DIR}" "${TMP_DIRECTORY}"/actual_maildir - -mkdir "${MAIL_DIR}" -ln -s "${TMP_DIRECTORY}"/actual_maildir "${MAIL_DIR}"/symlink - -output=$(NOTMUCH_NEW) -test_expect_equal "$output" "Added 1 new message to the database." - - -test_begin_subtest "New symlink to a file" -generate_message -external_msg_filename="${TMP_DIRECTORY}"/external/"$(basename "$gen_msg_filename")" -mkdir -p "$(dirname "$external_msg_filename")" -mv "$gen_msg_filename" "$external_msg_filename" -ln -s "$external_msg_filename" "$gen_msg_filename" -output=$(NOTMUCH_NEW) -test_expect_equal "$output" "Added 1 new message to the database." - - -test_begin_subtest "Broken symlink aborts" -ln -s does-not-exist "${MAIL_DIR}/broken" -output=$(NOTMUCH_NEW 2>&1) -test_expect_equal "$output" \ -"Error reading file ${MAIL_DIR}/broken: No such file or directory -Note: A fatal error was encountered: Something went wrong trying to read or write a file -No new mail." -rm "${MAIL_DIR}/broken" - - -test_begin_subtest "New two-level directory" - -generate_message [dir]=two/levels -generate_message [dir]=two/levels -generate_message [dir]=two/levels - -output=$(NOTMUCH_NEW) -test_expect_equal "$output" "Added 3 new messages to the database." - - -test_begin_subtest "Deleted two-level directory" - -rm -rf "${MAIL_DIR}"/two - -output=$(NOTMUCH_NEW) -test_expect_equal "$output" "No new mail. Removed 3 messages." - -test_begin_subtest "Support single-message mbox (deprecated)" -cat > "${MAIL_DIR}"/mbox_file1 < -To: Notmuch Test Suite -Subject: Test mbox message 1 - -Body. -EOF -output=$(NOTMUCH_NEW 2>&1) -test_expect_equal "$output" \ -"Warning: ${MAIL_DIR}/mbox_file1 is an mbox containing a single message, -likely caused by misconfigured mail delivery. Support for single-message -mboxes is deprecated and may be removed in the future. -Added 1 new message to the database." - -# This test requires that notmuch new has been run at least once. -test_begin_subtest "Skip and report non-mail files" -generate_message -mkdir -p "${MAIL_DIR}"/.git && touch "${MAIL_DIR}"/.git/config -touch "${MAIL_DIR}"/ignored_file -touch "${MAIL_DIR}"/.ignored_hidden_file -cat > "${MAIL_DIR}"/mbox_file < -To: Notmuch Test Suite -Subject: Test mbox message 1 - -Body. - -From test_suite@notmuchmail.org Fri Jan 5 15:43:57 2001 -From: Notmuch Test Suite -To: Notmuch Test Suite -Subject: Test mbox message 2 - -Body 2. -EOF -output=$(NOTMUCH_NEW 2>&1) -test_expect_equal "$output" \ -"Note: Ignoring non-mail file: ${MAIL_DIR}/.git/config -Note: Ignoring non-mail file: ${MAIL_DIR}/.ignored_hidden_file -Note: Ignoring non-mail file: ${MAIL_DIR}/ignored_file -Note: Ignoring non-mail file: ${MAIL_DIR}/mbox_file -Added 1 new message to the database." -rm "${MAIL_DIR}"/mbox_file - -test_begin_subtest "Ignore files and directories specified in new.ignore" -generate_message -notmuch config set new.ignore .git ignored_file .ignored_hidden_file -touch "${MAIL_DIR}"/.git # change .git's mtime for notmuch new to rescan. -output=$(NOTMUCH_NEW 2>&1) -test_expect_equal "$output" "Added 1 new message to the database." - -test_begin_subtest "Ignore files and directories specified in new.ignore (multiple occurrences)" -notmuch config set new.ignore .git ignored_file .ignored_hidden_file -notmuch new > /dev/null # ensure that files/folders will be printed in ASCII order. -touch "${MAIL_DIR}"/.git # change .git's mtime for notmuch new to rescan. -touch "${MAIL_DIR}" # likewise for MAIL_DIR -mkdir -p "${MAIL_DIR}"/one/two/three/.git -touch "${MAIL_DIR}"/{one,one/two,one/two/three}/ignored_file -output=$(NOTMUCH_NEW --debug 2>&1 | sort) -test_expect_equal "$output" \ -"(D) add_files_recursive, pass 1: explicitly ignoring ${MAIL_DIR}/.git -(D) add_files_recursive, pass 1: explicitly ignoring ${MAIL_DIR}/.ignored_hidden_file -(D) add_files_recursive, pass 1: explicitly ignoring ${MAIL_DIR}/ignored_file -(D) add_files_recursive, pass 1: explicitly ignoring ${MAIL_DIR}/one/ignored_file -(D) add_files_recursive, pass 1: explicitly ignoring ${MAIL_DIR}/one/two/ignored_file -(D) add_files_recursive, pass 1: explicitly ignoring ${MAIL_DIR}/one/two/three/.git -(D) add_files_recursive, pass 1: explicitly ignoring ${MAIL_DIR}/one/two/three/ignored_file -(D) add_files_recursive, pass 2: explicitly ignoring ${MAIL_DIR}/.git -(D) add_files_recursive, pass 2: explicitly ignoring ${MAIL_DIR}/.ignored_hidden_file -(D) add_files_recursive, pass 2: explicitly ignoring ${MAIL_DIR}/ignored_file -(D) add_files_recursive, pass 2: explicitly ignoring ${MAIL_DIR}/one/ignored_file -(D) add_files_recursive, pass 2: explicitly ignoring ${MAIL_DIR}/one/two/ignored_file -(D) add_files_recursive, pass 2: explicitly ignoring ${MAIL_DIR}/one/two/three/.git -(D) add_files_recursive, pass 2: explicitly ignoring ${MAIL_DIR}/one/two/three/ignored_file -No new mail." - - -test_begin_subtest "Don't stop for ignored broken symlinks" -notmuch config set new.ignore .git ignored_file .ignored_hidden_file broken_link -ln -s i_do_not_exist "${MAIL_DIR}"/broken_link -output=$(NOTMUCH_NEW 2>&1) -test_expect_equal "$output" "No new mail." - -test_done diff --git a/test/notmuch-test b/test/notmuch-test index 18593f61..b8437127 100755 --- a/test/notmuch-test +++ b/test/notmuch-test @@ -16,61 +16,7 @@ fi cd $(dirname "$0") -TESTS=" - basic - help-test - compact - config - setup - new - count - insert - search - search-output - search-by-folder - search-position-overlap-bug - search-insufficient-from-quoting - search-limiting - excludes - tagging - json - sexp - text - multipart - thread-naming - raw - reply - reply-to-sender - dump-restore - uuencode - thread-order - author-order - from-guessing - long-id - encoding - emacs - emacs-large-search-buffer - emacs-subject-to-filename - maildir-sync - crypto - symbol-hiding - search-folder-coherence - atomicity - python - hooks - argument-parsing - emacs-test-functions - emacs-address-cleaning - emacs-hello - emacs-show - emacs-tree - missing-headers - hex-escaping - parse-time-string - search-date - thread-replies -" -TESTS=${NOTMUCH_TESTS:=$TESTS} +TESTS=${NOTMUCH_TESTS:-`echo T[0-9][0-9][0-9]-*.sh`} # Clean up any results from a previous run rm -r test-results >/dev/null 2>/dev/null @@ -98,6 +44,7 @@ done trap - HUP INT TERM # Report results +echo ./aggregate-results.sh test-results/* ev=$? diff --git a/test/parse-time-string b/test/parse-time-string deleted file mode 100755 index 8ae0b4c2..00000000 --- a/test/parse-time-string +++ /dev/null @@ -1,78 +0,0 @@ -#!/usr/bin/env bash -test_description="date/time parser module" -. ./test-lib.sh - -# Sanity/smoke tests for the date/time parser independent of notmuch - -_date () -{ - date -d "$*" +%s -} - -_parse_time () -{ - ${TEST_DIRECTORY}/parse-time --format=%s "$*" -} - -test_begin_subtest "date(1) default format without TZ code" -test_expect_equal "$(_parse_time Fri Aug 3 23:06:06 2012)" "$(_date Fri Aug 3 23:06:06 2012)" - -test_begin_subtest "date(1) --rfc-2822 format" -test_expect_equal "$(_parse_time Fri, 03 Aug 2012 23:07:46 +0100)" "$(_date Fri, 03 Aug 2012 23:07:46 +0100)" - -test_begin_subtest "date(1) --rfc=3339=seconds format" -test_expect_equal "$(_parse_time 2012-08-03 23:09:37+03:00)" "$(_date 2012-08-03 23:09:37+03:00)" - -test_begin_subtest "Date parser tests" -REFERENCE=$(_date Tue Jan 11 11:11:00 +0000 2011) -cat < INPUT -now ==> Tue Jan 11 11:11:00 +0000 2011 -2010-1-1 ==> ERROR: DATEFORMAT -Jan 2 ==> Sun Jan 02 11:11:00 +0000 2011 -Mon ==> Mon Jan 10 11:11:00 +0000 2011 -last Friday ==> ERROR: FORMAT -2 hours ago ==> Tue Jan 11 09:11:00 +0000 2011 -last month ==> Sat Dec 11 11:11:00 +0000 2010 -month ago ==> Sat Dec 11 11:11:00 +0000 2010 -two mo ==> Thu Nov 11 11:11:00 +0000 2010 -3M ==> Mon Oct 11 11:11:00 +0000 2010 -4-mont ==> Sat Sep 11 11:11:00 +0000 2010 -5m ==> Tue Jan 11 11:06:00 +0000 2011 -dozen mi ==> Tue Jan 11 10:59:00 +0000 2011 -8am ==> Tue Jan 11 08:00:00 +0000 2011 -9:15 ==> Tue Jan 11 09:15:00 +0000 2011 -12:34 ==> Tue Jan 11 12:34:00 +0000 2011 -monday ==> Mon Jan 10 11:11:00 +0000 2011 -yesterday ==> Mon Jan 10 11:11:00 +0000 2011 -tomorrow ==> ERROR: KEYWORD - ==> Tue Jan 11 11:11:00 +0000 2011 # empty string is reference time - -Aug 3 23:06:06 2012 ==> Fri Aug 03 23:06:06 +0000 2012 # date(1) default format without TZ code -Fri, 03 Aug 2012 23:07:46 +0100 ==> Fri Aug 03 22:07:46 +0000 2012 # rfc-2822 -2012-08-03 23:09:37+03:00 ==> Fri Aug 03 20:09:37 +0000 2012 # rfc-3339 seconds - -10s ==> Tue Jan 11 11:10:50 +0000 2011 -19701223s ==> Fri May 28 10:37:17 +0000 2010 -19701223 ==> Wed Dec 23 11:11:00 +0000 1970 - -19701223 +0100 ==> Wed Dec 23 11:11:00 +0000 1970 # Timezone is ignored without an error - -today ==^^> Wed Jan 12 00:00:00 +0000 2011 -today ==^> Tue Jan 11 23:59:59 +0000 2011 -today ==_> Tue Jan 11 00:00:00 +0000 2011 - -this week ==^^> Sun Jan 16 00:00:00 +0000 2011 -this week ==^> Sat Jan 15 23:59:59 +0000 2011 -this week ==_> Sun Jan 09 00:00:00 +0000 2011 - -two months ago ==> Thu Nov 11 11:11:00 +0000 2010 -two months ==> Thu Nov 11 11:11:00 +0000 2010 - -@1348569850 ==> Tue Sep 25 10:44:10 +0000 2012 -@10 ==> Thu Jan 01 00:00:10 +0000 1970 -EOF - -${TEST_DIRECTORY}/parse-time --ref=${REFERENCE} < INPUT > OUTPUT -test_expect_equal_file INPUT OUTPUT - -test_done diff --git a/test/python b/test/python deleted file mode 100755 index 3f03a2e3..00000000 --- a/test/python +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env bash -test_description="python bindings" -. ./test-lib.sh - -add_email_corpus - -test_begin_subtest "compare thread ids" -test_python < EXPECTED -test_expect_equal_file OUTPUT EXPECTED - -test_begin_subtest "compare message ids" -test_python < EXPECTED -test_expect_equal_file OUTPUT EXPECTED - -test_begin_subtest "get non-existent file" -test_python <&1) -test_expect_equal "$output" "Error: search term did not match precisely one message." - -test_begin_subtest "Show a raw message" -output=$(notmuch show --format=raw id:msg-001@notmuch-test-suite | notmuch_date_sanitize) -test_expect_equal "$output" "From: Notmuch Test Suite -To: Notmuch Test Suite -Message-Id: -Subject: Test message #1 -Date: GENERATED_DATE - -This is just a test message (#1)" - -test_begin_subtest "Show another raw message" -output=$(notmuch show --format=raw id:msg-002@notmuch-test-suite | notmuch_date_sanitize) -test_expect_equal "$output" "From: Notmuch Test Suite -To: Notmuch Test Suite -Message-Id: -Subject: Test message #2 -Date: GENERATED_DATE - -This is just a test message (#2)" - -test_done diff --git a/test/reply b/test/reply deleted file mode 100755 index b0d854a1..00000000 --- a/test/reply +++ /dev/null @@ -1,257 +0,0 @@ -#!/usr/bin/env bash -test_description="\"notmuch reply\" in several variations" -. ./test-lib.sh - -test_begin_subtest "Basic reply" -add_message '[from]="Sender "' \ - [to]=test_suite@notmuchmail.org \ - [subject]=notmuch-reply-test \ - '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ - '[body]="basic reply test"' - -output=$(notmuch reply id:${gen_msg_id}) -test_expect_equal "$output" "From: Notmuch Test Suite -Subject: Re: notmuch-reply-test -To: Sender -In-Reply-To: <${gen_msg_id}> -References: <${gen_msg_id}> - -On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: -> basic reply test" - -test_begin_subtest "Multiple recipients" -add_message '[from]="Sender "' \ - '[to]="test_suite@notmuchmail.org, Someone Else "' \ - [subject]=notmuch-reply-test \ - '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ - '[body]="Multiple recipients"' - -output=$(notmuch reply id:${gen_msg_id}) -test_expect_equal "$output" "From: Notmuch Test Suite -Subject: Re: notmuch-reply-test -To: Sender , Someone Else -In-Reply-To: <${gen_msg_id}> -References: <${gen_msg_id}> - -On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: -> Multiple recipients" - -test_begin_subtest "Reply with CC" -add_message '[from]="Sender "' \ - [to]=test_suite@notmuchmail.org \ - '[cc]="Other Parties "' \ - [subject]=notmuch-reply-test \ - '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ - '[body]="reply with CC"' - -output=$(notmuch reply id:${gen_msg_id}) -test_expect_equal "$output" "From: Notmuch Test Suite -Subject: Re: notmuch-reply-test -To: Sender -Cc: Other Parties -In-Reply-To: <${gen_msg_id}> -References: <${gen_msg_id}> - -On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: -> reply with CC" - -test_begin_subtest "Reply from alternate address" -add_message '[from]="Sender "' \ - [to]=test_suite_other@notmuchmail.org \ - [subject]=notmuch-reply-test \ - '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ - '[body]="reply from alternate address"' - -output=$(notmuch reply id:${gen_msg_id}) -test_expect_equal "$output" "From: Notmuch Test Suite -Subject: Re: notmuch-reply-test -To: Sender -In-Reply-To: <${gen_msg_id}> -References: <${gen_msg_id}> - -On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: -> reply from alternate address" - -test_begin_subtest "Reply from address in named group list" -add_message '[from]="Sender "' \ - '[to]=group:test_suite@notmuchmail.org,someone@example.com\;' \ - [cc]=test_suite_other@notmuchmail.org \ - [subject]=notmuch-reply-test \ - '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ - '[body]="Reply from address in named group list"' - -output=$(notmuch reply id:${gen_msg_id}) -test_expect_equal "$output" "From: Notmuch Test Suite -Subject: Re: notmuch-reply-test -To: Sender , someone@example.com -In-Reply-To: <${gen_msg_id}> -References: <${gen_msg_id}> - -On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: -> Reply from address in named group list" - -test_begin_subtest "Support for Reply-To" -add_message '[from]="Sender "' \ - [to]=test_suite@notmuchmail.org \ - [subject]=notmuch-reply-test \ - '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ - '[body]="support for reply-to"' \ - '[reply-to]="Sender "' - -output=$(notmuch reply id:${gen_msg_id}) -test_expect_equal "$output" "From: Notmuch Test Suite -Subject: Re: notmuch-reply-test -To: Sender -In-Reply-To: <${gen_msg_id}> -References: <${gen_msg_id}> - -On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: -> support for reply-to" - -test_begin_subtest "Un-munging Reply-To" -add_message '[from]="Sender "' \ - '[to]="Some List "' \ - [subject]=notmuch-reply-test \ - '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ - '[body]="Un-munging Reply-To"' \ - '[reply-to]="Evil Munging List "' - -output=$(notmuch reply id:${gen_msg_id}) -test_expect_equal "$output" "From: Notmuch Test Suite -Subject: Re: notmuch-reply-test -To: Sender , Some List -In-Reply-To: <${gen_msg_id}> -References: <${gen_msg_id}> - -On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: -> Un-munging Reply-To" - -test_begin_subtest "Message with header of exactly 200 bytes" -add_message '[subject]="This subject is exactly 200 bytes in length. Other than its length there is not much of note here. Note that the length of 200 bytes includes the Subject: and Re: prefixes with two spaces"' \ - '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ - '[body]="200-byte header"' -output=$(notmuch reply id:${gen_msg_id}) -test_expect_equal "$output" "From: Notmuch Test Suite -Subject: Re: This subject is exactly 200 bytes in length. Other than its - length there is not much of note here. Note that the length of 200 bytes - includes the Subject: and Re: prefixes with two spaces -In-Reply-To: <${gen_msg_id}> -References: <${gen_msg_id}> - -On Tue, 05 Jan 2010 15:43:56 -0000, Notmuch Test Suite wrote: -> 200-byte header" - -test_begin_subtest "From guessing: Envelope-To" -add_message '[from]="Sender "' \ - '[to]="Recipient "' \ - '[subject]="From guessing"' \ - '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ - '[body]="From guessing"' \ - '[header]="Envelope-To: test_suite_other@notmuchmail.org"' - -output=$(notmuch reply id:${gen_msg_id}) -test_expect_equal "$output" "From: Notmuch Test Suite -Subject: Re: From guessing -To: Sender , Recipient -In-Reply-To: <${gen_msg_id}> -References: <${gen_msg_id}> - -On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: -> From guessing" - -test_begin_subtest "From guessing: X-Original-To" -add_message '[from]="Sender "' \ - '[to]="Recipient "' \ - '[subject]="From guessing"' \ - '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ - '[body]="From guessing"' \ - '[header]="X-Original-To: test_suite@otherdomain.org"' - -output=$(notmuch reply id:${gen_msg_id}) -test_expect_equal "$output" "From: Notmuch Test Suite -Subject: Re: From guessing -To: Sender , Recipient -In-Reply-To: <${gen_msg_id}> -References: <${gen_msg_id}> - -On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: -> From guessing" - -test_begin_subtest "From guessing: Delivered-To" -add_message '[from]="Sender "' \ - '[to]="Recipient "' \ - '[subject]="From guessing"' \ - '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ - '[body]="From guessing"' \ - '[header]="Delivered-To: test_suite_other@notmuchmail.org"' - -output=$(notmuch reply id:${gen_msg_id}) -test_expect_equal "$output" "From: Notmuch Test Suite -Subject: Re: From guessing -To: Sender , Recipient -In-Reply-To: <${gen_msg_id}> -References: <${gen_msg_id}> - -On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: -> From guessing" - -test_begin_subtest "Reply with RFC 2047-encoded headers" -add_message '[subject]="=?iso-8859-1?q?=e0=df=e7?="' \ - '[from]="=?utf-8?q?=e2=98=83?= "' \ - '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ - '[body]="Encoding"' - -# GMime happens to change from Q- to B-encoding. We canonicalize the -# case of the encoding and charset because different versions of GMime -# capitalize the encoding differently. -output=$(notmuch reply id:${gen_msg_id} | perl -pe 's/=\?[^?]+\?[bB]\?/lc($&)/ge') -test_expect_equal "$output" "\ -From: Notmuch Test Suite -Subject: Re: =?iso-8859-1?b?4N/n?= -To: =?utf-8?b?4piD?= -In-Reply-To: <${gen_msg_id}> -References: <${gen_msg_id}> - -On Tue, 05 Jan 2010 15:43:56 -0000, ☃ wrote: -> Encoding" - -test_begin_subtest "Reply with RFC 2047-encoded headers (JSON)" -output=$(notmuch reply --format=json id:${gen_msg_id}) -test_expect_equal_json "$output" ' -{ - "original": { - "body": [ - { - "content": "Encoding\n", - "content-type": "text/plain", - "id": 1 - } - ], - "date_relative": "2010-01-05", - "excluded": false, - "filename": "'${MAIL_DIR}'/msg-012", - "headers": { - "Date": "Tue, 05 Jan 2010 15:43:56 +0000", - "From": "\u2603 ", - "Subject": "\u00e0\u00df\u00e7", - "To": "Notmuch Test Suite " - }, - "id": "'${gen_msg_id}'", - "match": false, - "tags": [ - "inbox", - "unread" - ], - "timestamp": 1262706236 - }, - "reply-headers": { - "From": "Notmuch Test Suite ", - "In-reply-to": "<'${gen_msg_id}'>", - "References": "<'${gen_msg_id}'>", - "Subject": "Re: \u00e0\u00df\u00e7", - "To": "\u2603 " - } -}' - - -test_done diff --git a/test/reply-to-sender b/test/reply-to-sender deleted file mode 100755 index 30e5e385..00000000 --- a/test/reply-to-sender +++ /dev/null @@ -1,211 +0,0 @@ -#!/usr/bin/env bash -test_description="\"notmuch reply --reply-to=sender\" in several variations" -. ./test-lib.sh - -test_begin_subtest "Basic reply-to-sender" -add_message '[from]="Sender "' \ - [to]=test_suite@notmuchmail.org \ - [subject]=notmuch-reply-test \ - '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ - '[body]="basic reply-to-sender test"' - -output=$(notmuch reply --reply-to=sender id:${gen_msg_id}) -test_expect_equal "$output" "From: Notmuch Test Suite -Subject: Re: notmuch-reply-test -To: Sender -In-Reply-To: <${gen_msg_id}> -References: <${gen_msg_id}> - -On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: -> basic reply-to-sender test" - -test_begin_subtest "From Us, Basic reply to message" -add_message '[from]="Notmuch Test Suite "' \ - '[to]="Recipient "' \ - [subject]=notmuch-reply-test \ - '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ - '[body]="basic reply-to-from-us test"' - -output=$(notmuch reply --reply-to=sender id:${gen_msg_id}) -test_expect_equal "$output" "From: Notmuch Test Suite -Subject: Re: notmuch-reply-test -To: Recipient -In-Reply-To: <${gen_msg_id}> -References: <${gen_msg_id}> - -On Tue, 05 Jan 2010 15:43:56 -0000, Notmuch Test Suite wrote: -> basic reply-to-from-us test" - -test_begin_subtest "Multiple recipients" -add_message '[from]="Sender "' \ - '[to]="test_suite@notmuchmail.org, Someone Else "' \ - [subject]=notmuch-reply-test \ - '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ - '[body]="Multiple recipients"' - -output=$(notmuch reply --reply-to=sender id:${gen_msg_id}) -test_expect_equal "$output" "From: Notmuch Test Suite -Subject: Re: notmuch-reply-test -To: Sender -In-Reply-To: <${gen_msg_id}> -References: <${gen_msg_id}> - -On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: -> Multiple recipients" - -test_begin_subtest "From Us, Multiple TO recipients" -add_message '[from]="Notmuch Test Suite "' \ - '[to]="Recipient , Someone Else "' \ - [subject]=notmuch-reply-test \ - '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ - '[body]="From Us, Multiple TO recipients"' - -output=$(notmuch reply --reply-to=sender id:${gen_msg_id}) -test_expect_equal "$output" "From: Notmuch Test Suite -Subject: Re: notmuch-reply-test -To: Recipient , Someone Else -In-Reply-To: <${gen_msg_id}> -References: <${gen_msg_id}> - -On Tue, 05 Jan 2010 15:43:56 -0000, Notmuch Test Suite wrote: -> From Us, Multiple TO recipients" - -test_begin_subtest "Reply with CC" -add_message '[from]="Sender "' \ - [to]=test_suite@notmuchmail.org \ - '[cc]="Other Parties "' \ - [subject]=notmuch-reply-test \ - '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ - '[body]="reply with CC"' - -output=$(notmuch reply --reply-to=sender id:${gen_msg_id}) -test_expect_equal "$output" "From: Notmuch Test Suite -Subject: Re: notmuch-reply-test -To: Sender -In-Reply-To: <${gen_msg_id}> -References: <${gen_msg_id}> - -On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: -> reply with CC" - -test_begin_subtest "From Us, Reply with CC" -add_message '[from]="Notmuch Test Suite "' \ - '[to]="Recipient "' \ - '[cc]="Other Parties "' \ - [subject]=notmuch-reply-test \ - '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ - '[body]="reply with CC"' - -output=$(notmuch reply --reply-to=sender id:${gen_msg_id}) -test_expect_equal "$output" "From: Notmuch Test Suite -Subject: Re: notmuch-reply-test -To: Recipient -In-Reply-To: <${gen_msg_id}> -References: <${gen_msg_id}> - -On Tue, 05 Jan 2010 15:43:56 -0000, Notmuch Test Suite wrote: -> reply with CC" - -test_begin_subtest "From Us, Reply no TO but with CC" -add_message '[from]="Notmuch Test Suite "' \ - '[cc]="Other Parties "' \ - [subject]=notmuch-reply-test \ - '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ - '[body]="reply with CC"' - -output=$(notmuch reply --reply-to=sender id:${gen_msg_id}) -test_expect_equal "$output" "From: Notmuch Test Suite -Subject: Re: notmuch-reply-test -Cc: Other Parties -In-Reply-To: <${gen_msg_id}> -References: <${gen_msg_id}> - -On Tue, 05 Jan 2010 15:43:56 -0000, Notmuch Test Suite wrote: -> reply with CC" - -test_begin_subtest "Reply from alternate address" -add_message '[from]="Sender "' \ - [to]=test_suite_other@notmuchmail.org \ - [subject]=notmuch-reply-test \ - '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ - '[body]="reply from alternate address"' - -output=$(notmuch reply --reply-to=sender id:${gen_msg_id}) -test_expect_equal "$output" "From: Notmuch Test Suite -Subject: Re: notmuch-reply-test -To: Sender -In-Reply-To: <${gen_msg_id}> -References: <${gen_msg_id}> - -On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: -> reply from alternate address" - -test_begin_subtest "Support for Reply-To" -add_message '[from]="Sender "' \ - [to]=test_suite@notmuchmail.org \ - [subject]=notmuch-reply-test \ - '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ - '[body]="support for reply-to"' \ - '[reply-to]="Sender "' - -output=$(notmuch reply --reply-to=sender id:${gen_msg_id}) -test_expect_equal "$output" "From: Notmuch Test Suite -Subject: Re: notmuch-reply-test -To: Sender -In-Reply-To: <${gen_msg_id}> -References: <${gen_msg_id}> - -On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: -> support for reply-to" - -test_begin_subtest "Support for Reply-To with multiple recipients" -add_message '[from]="Sender "' \ - '[to]="test_suite@notmuchmail.org, Someone Else "' \ - [subject]=notmuch-reply-test \ - '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ - '[body]="support for reply-to with multiple recipients"' \ - '[reply-to]="Sender "' - -output=$(notmuch reply --reply-to=sender id:${gen_msg_id}) -test_expect_equal "$output" "From: Notmuch Test Suite -Subject: Re: notmuch-reply-test -To: Sender -In-Reply-To: <${gen_msg_id}> -References: <${gen_msg_id}> - -On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: -> support for reply-to with multiple recipients" - -test_begin_subtest "Un-munging Reply-To" -add_message '[from]="Sender "' \ - '[to]="Some List "' \ - [subject]=notmuch-reply-test \ - '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ - '[body]="Un-munging Reply-To"' \ - '[reply-to]="Evil Munging List "' - -output=$(notmuch reply --reply-to=sender id:${gen_msg_id}) -test_expect_equal "$output" "From: Notmuch Test Suite -Subject: Re: notmuch-reply-test -To: Sender -In-Reply-To: <${gen_msg_id}> -References: <${gen_msg_id}> - -On Tue, 05 Jan 2010 15:43:56 -0000, Sender wrote: -> Un-munging Reply-To" - -test_begin_subtest "Message with header of exactly 200 bytes" -add_message '[subject]="This subject is exactly 200 bytes in length. Other than its length there is not much of note here. Note that the length of 200 bytes includes the Subject: and Re: prefixes with two spaces"' \ - '[date]="Tue, 05 Jan 2010 15:43:56 -0000"' \ - '[body]="200-byte header"' -output=$(notmuch reply --reply-to=sender id:${gen_msg_id}) -test_expect_equal "$output" "From: Notmuch Test Suite -Subject: Re: This subject is exactly 200 bytes in length. Other than its - length there is not much of note here. Note that the length of 200 bytes - includes the Subject: and Re: prefixes with two spaces -In-Reply-To: <${gen_msg_id}> -References: <${gen_msg_id}> - -On Tue, 05 Jan 2010 15:43:56 -0000, Notmuch Test Suite wrote: -> 200-byte header" -test_done diff --git a/test/search b/test/search deleted file mode 100755 index a7a0b18d..00000000 --- a/test/search +++ /dev/null @@ -1,132 +0,0 @@ -#!/usr/bin/env bash -test_description='"notmuch search" in several variations' -. ./test-lib.sh - -add_email_corpus - -test_begin_subtest "Search body" -add_message '[subject]="body search"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' [body]=bodysearchtest -output=$(notmuch search bodysearchtest | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; body search (inbox unread)" - -test_begin_subtest "Search by from:" -add_message '[subject]="search by from"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' [from]=searchbyfrom -output=$(notmuch search from:searchbyfrom | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] searchbyfrom; search by from (inbox unread)" - -test_begin_subtest "Search by to:" -add_message '[subject]="search by to"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' [to]=searchbyto -output=$(notmuch search to:searchbyto | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by to (inbox unread)" - -test_begin_subtest "Search by subject:" -add_message [subject]=subjectsearchtest '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' -output=$(notmuch search subject:subjectsearchtest | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; subjectsearchtest (inbox unread)" - -test_begin_subtest "Search by subject (utf-8):" -add_message [subject]=utf8-sübjéct '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' -output=$(notmuch search subject:utf8-sübjéct | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; utf8-sübjéct (inbox unread)" - -test_begin_subtest "Search by id:" -add_message '[subject]="search by id"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' -output=$(notmuch search id:${gen_msg_id} | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by id (inbox unread)" - -test_begin_subtest "Search by tag:" -add_message '[subject]="search by tag"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' -notmuch tag +searchbytag id:${gen_msg_id} -output=$(notmuch search tag:searchbytag | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by tag (inbox searchbytag unread)" - -test_begin_subtest "Search by thread:" -add_message '[subject]="search by thread"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' -thread_id=$(notmuch search id:${gen_msg_id} | sed -e "s/thread:\([a-f0-9]*\).*/\1/") -output=$(notmuch search thread:${thread_id} | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by thread (inbox unread)" - -test_begin_subtest "Search body (phrase)" -add_message '[subject]="body search (phrase)"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' '[body]="body search (phrase)"' -add_message '[subject]="negative result"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' '[body]="This phrase should not match the body search"' -output=$(notmuch search '"body search (phrase)"' | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; body search (phrase) (inbox unread)" - -test_begin_subtest "Search by from: (address)" -add_message '[subject]="search by from (address)"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' [from]=searchbyfrom@example.com -output=$(notmuch search from:searchbyfrom@example.com | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] searchbyfrom@example.com; search by from (address) (inbox unread)" - -test_begin_subtest "Search by from: (name)" -add_message '[subject]="search by from (name)"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' '[from]="Search By From Name "' -output=$(notmuch search from:"Search By From Name" | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Search By From Name; search by from (name) (inbox unread)" - -test_begin_subtest "Search by to: (address)" -add_message '[subject]="search by to (address)"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' [to]=searchbyto@example.com -output=$(notmuch search to:searchbyto@example.com | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by to (address) (inbox unread)" - -test_begin_subtest "Search by to: (name)" -add_message '[subject]="search by to (name)"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' '[to]="Search By To Name "' -output=$(notmuch search to:"Search By To Name" | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by to (name) (inbox unread)" - -test_begin_subtest "Search by subject: (phrase)" -add_message '[subject]="subject search test (phrase)"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' -add_message '[subject]="this phrase should not match the subject search test"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' -output=$(notmuch search 'subject:"subject search test (phrase)"' | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; subject search test (phrase) (inbox unread)" - -test_begin_subtest 'Search for all messages ("*")' -notmuch search '*' | notmuch_search_sanitize > OUTPUT -cat <EXPECTED -thread:XXX 2010-12-29 [1/1] François Boulogne; [aur-general] Guidelines: cp, mkdir vs install (inbox unread) -thread:XXX 2010-12-16 [1/1] Olivier Berger; Essai accentué (inbox unread) -thread:XXX 2009-11-18 [1/1] Chris Wilson; [notmuch] [PATCH 1/2] Makefile: evaluate pkg-config once (inbox unread) -thread:XXX 2009-11-18 [2/2] Alex Botero-Lowry, Carl Worth; [notmuch] [PATCH] Error out if no query is supplied to search instead of going into an infinite loop (attachment inbox unread) -thread:XXX 2009-11-18 [2/2] Ingmar Vanhassel, Carl Worth; [notmuch] [PATCH] Typsos (inbox unread) -thread:XXX 2009-11-18 [3/3] Adrian Perez de Castro, Keith Packard, Carl Worth; [notmuch] Introducing myself (inbox signed unread) -thread:XXX 2009-11-18 [3/3] Israel Herraiz, Keith Packard, Carl Worth; [notmuch] New to the list (inbox unread) -thread:XXX 2009-11-18 [3/3] Jan Janak, Carl Worth; [notmuch] What a great idea! (inbox unread) -thread:XXX 2009-11-18 [2/2] Jan Janak, Carl Worth; [notmuch] [PATCH] Older versions of install do not support -C. (inbox unread) -thread:XXX 2009-11-18 [3/3] Aron Griffis, Keith Packard, Carl Worth; [notmuch] archive (inbox unread) -thread:XXX 2009-11-18 [2/2] Keith Packard, Carl Worth; [notmuch] [PATCH] Make notmuch-show 'X' (and 'x') commands remove inbox (and unread) tags (inbox unread) -thread:XXX 2009-11-18 [7/7] Lars Kellogg-Stedman, Mikhail Gusarov, Keith Packard, Carl Worth; [notmuch] Working with Maildir storage? (inbox signed unread) -thread:XXX 2009-11-18 [5/5] Mikhail Gusarov, Carl Worth, Keith Packard; [notmuch] [PATCH 1/2] Close message file after parsing message headers (inbox unread) -thread:XXX 2009-11-18 [2/2] Keith Packard, Alexander Botero-Lowry; [notmuch] [PATCH] Create a default notmuch-show-hook that highlights URLs and uses word-wrap (inbox unread) -thread:XXX 2009-11-18 [1/1] Alexander Botero-Lowry; [notmuch] request for pull (inbox unread) -thread:XXX 2009-11-18 [4/4] Jjgod Jiang, Alexander Botero-Lowry; [notmuch] Mac OS X/Darwin compatibility issues (inbox unread) -thread:XXX 2009-11-18 [1/1] Rolland Santimano; [notmuch] Link to mailing list archives ? (inbox unread) -thread:XXX 2009-11-18 [1/1] Jan Janak; [notmuch] [PATCH] notmuch new: Support for conversion of spool subdirectories into tags (inbox unread) -thread:XXX 2009-11-18 [1/1] Stewart Smith; [notmuch] [PATCH] count_files: sort directory in inode order before statting (inbox unread) -thread:XXX 2009-11-18 [1/1] Stewart Smith; [notmuch] [PATCH 2/2] Read mail directory in inode number order (inbox unread) -thread:XXX 2009-11-18 [1/1] Stewart Smith; [notmuch] [PATCH] Fix linking with gcc to use g++ to link in C++ libs. (inbox unread) -thread:XXX 2009-11-18 [2/2] Lars Kellogg-Stedman; [notmuch] "notmuch help" outputs to stderr? (attachment inbox signed unread) -thread:XXX 2009-11-17 [1/1] Mikhail Gusarov; [notmuch] [PATCH] Handle rename of message file (inbox unread) -thread:XXX 2009-11-17 [2/2] Alex Botero-Lowry, Carl Worth; [notmuch] preliminary FreeBSD support (attachment inbox unread) -thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; body search (inbox unread) -thread:XXX 2000-01-01 [1/1] searchbyfrom; search by from (inbox unread) -thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by to (inbox unread) -thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; subjectsearchtest (inbox unread) -thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; utf8-sübjéct (inbox unread) -thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by id (inbox unread) -thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by tag (inbox searchbytag unread) -thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by thread (inbox unread) -thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; body search (phrase) (inbox unread) -thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; negative result (inbox unread) -thread:XXX 2000-01-01 [1/1] searchbyfrom@example.com; search by from (address) (inbox unread) -thread:XXX 2000-01-01 [1/1] Search By From Name; search by from (name) (inbox unread) -thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by to (address) (inbox unread) -thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by to (name) (inbox unread) -thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; subject search test (phrase) (inbox unread) -thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; this phrase should not match the subject search test (inbox unread) -EOF -test_expect_equal_file OUTPUT EXPECTED - -test_begin_subtest "Search body (utf-8):" -add_message '[subject]="utf8-message-body-subject"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' '[body]="message body utf8: bödý"' -output=$(notmuch search "bödý" | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; utf8-message-body-subject (inbox unread)" - -test_done diff --git a/test/search-by-folder b/test/search-by-folder deleted file mode 100755 index 5cc2ca8d..00000000 --- a/test/search-by-folder +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env bash -test_description='"notmuch search" by folder: (with variations)' -. ./test-lib.sh - -add_message '[dir]=bad' '[subject]="To the bone"' -add_message '[dir]=bad/news' '[subject]="Bears"' -mkdir -p "${MAIL_DIR}/duplicate/bad/news" -cp "$gen_msg_filename" "${MAIL_DIR}/duplicate/bad/news" - -add_message '[dir]=things' '[subject]="These are a few"' -add_message '[dir]=things/favorite' '[subject]="Raindrops, whiskers, kettles"' -add_message '[dir]=things/bad' '[subject]="Bites, stings, sad feelings"' - -test_begin_subtest "Single-world folder: specification (multiple results)" -output=$(notmuch search folder:bad | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; To the bone (inbox unread) -thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Bears (inbox unread) -thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Bites, stings, sad feelings (inbox unread)" - -test_begin_subtest "Two-word path to narrow results to one" -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 removing duplicate instance of matching path" -rm -r "${MAIL_DIR}/bad/news" -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" -notmuch new -output=$(notmuch search folder:bad/news | notmuch_search_sanitize) -test_expect_equal "$output" "" - -test_begin_subtest "After rename, new path returns result" -output=$(notmuch search folder:bad/olds | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Bears (inbox unread)" - -test_done diff --git a/test/search-date b/test/search-date deleted file mode 100755 index 70bcf344..00000000 --- a/test/search-date +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env bash -test_description="date:since..until queries" -. ./test-lib.sh - -add_email_corpus - -test_begin_subtest "Absolute date range" -output=$(notmuch search date:2010-12-16..12/16/2010 | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2010-12-16 [1/1] Olivier Berger; Essai accentué (inbox unread)" - -test_begin_subtest "Absolute time range with TZ" -notmuch search date:18-Nov-2009_02:19:26-0800..2009-11-18_04:49:52-06:00 | notmuch_search_sanitize > OUTPUT -cat <EXPECTED -thread:XXX 2009-11-18 [1/3] Carl Worth| Jan Janak; [notmuch] What a great idea! (inbox unread) -thread:XXX 2009-11-18 [1/2] Carl Worth| Jan Janak; [notmuch] [PATCH] Older versions of install do not support -C. (inbox unread) -thread:XXX 2009-11-18 [1/3] Carl Worth| Aron Griffis, Keith Packard; [notmuch] archive (inbox unread) -thread:XXX 2009-11-18 [1/2] Carl Worth| Keith Packard; [notmuch] [PATCH] Make notmuch-show 'X' (and 'x') commands remove inbox (and unread) tags (inbox unread) -EOF -test_expect_equal_file OUTPUT EXPECTED - -test_done diff --git a/test/search-folder-coherence b/test/search-folder-coherence deleted file mode 100755 index 3f6ec763..00000000 --- a/test/search-folder-coherence +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/env bash -test_description='folder tags removed and added through file renames remain consistent' -. ./test-lib.sh - -test_begin_subtest "No new messages" -output=$(NOTMUCH_NEW) -test_expect_equal "$output" "No new mail." - - -test_begin_subtest "Single new message" -generate_message -file_x=$gen_msg_filename -id_x=$gen_msg_id -output=$(NOTMUCH_NEW) -test_expect_equal "$output" "Added 1 new message to the database." - -test_begin_subtest "Add second folder for same message" -dir=$(dirname $file_x) -mkdir $dir/spam -cp $file_x $dir/spam -output=$(NOTMUCH_NEW) -test_expect_equal "$output" "No new mail." - - -test_begin_subtest "Multiple files for same message" -cat <EXPECTED -MAIL_DIR/msg-001 -MAIL_DIR/spam/msg-001 -EOF -notmuch search --output=files id:$id_x | sed -e "s,$MAIL_DIR,MAIL_DIR," >OUTPUT -test_expect_equal_file OUTPUT EXPECTED - -test_begin_subtest "Test matches folder:spam" -output=$(notmuch search folder:spam) -test_expect_equal "$output" "thread:0000000000000001 2001-01-05 [1/1] Notmuch Test Suite; Single new message (inbox unread)" - -test_begin_subtest "Remove folder:spam copy of email" -rm $dir/spam/$(basename $file_x) -output=$(NOTMUCH_NEW) -test_expect_equal "$output" "No new mail. Detected 1 file rename." - -test_begin_subtest "No mails match the folder:spam search" -output=$(notmuch search folder:spam) -test_expect_equal "$output" "" - -test_done diff --git a/test/search-insufficient-from-quoting b/test/search-insufficient-from-quoting deleted file mode 100755 index e83ea3d1..00000000 --- a/test/search-insufficient-from-quoting +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env bash -test_description='messages with unquoted . in name' -. ./test-lib.sh - -add_message \ - '[from]="Some.Name for Someone "' \ - '[subject]="This message needs more quoting on the From line"' - -add_message \ - '[from]="\"Some.Name for Someone\" "' \ - '[subject]="This message has necessary quoting in place"' - -add_message \ - '[from]="No.match Here "' \ - '[subject]="This message needs more quoting on the From line"' - -add_message \ - '[from]="\"No.match Here\" "' \ - '[subject]="This message has necessary quoting in place"' - - -test_begin_subtest "Search by first name" -output=$(notmuch search from:Some.Name | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Some.Name for Someone; This message needs more quoting on the From line (inbox unread) -thread:XXX 2001-01-05 [1/1] Some.Name for Someone; This message has necessary quoting in place (inbox unread)" - -test_begin_subtest "Search by last name:" -output=$(notmuch search from:Someone | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Some.Name for Someone; This message needs more quoting on the From line (inbox unread) -thread:XXX 2001-01-05 [1/1] Some.Name for Someone; This message has necessary quoting in place (inbox unread)" - -test_begin_subtest "Search by address:" -output=$(notmuch search from:bugs@quoting.com | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Some.Name for Someone; This message needs more quoting on the From line (inbox unread) -thread:XXX 2001-01-05 [1/1] Some.Name for Someone; This message has necessary quoting in place (inbox unread)" - -test_begin_subtest "Search for all messages:" -output=$(notmuch search '*' | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Some.Name for Someone; This message needs more quoting on the From line (inbox unread) -thread:XXX 2001-01-05 [1/1] Some.Name for Someone; This message has necessary quoting in place (inbox unread) -thread:XXX 2001-01-05 [1/1] No.match Here; This message needs more quoting on the From line (inbox unread) -thread:XXX 2001-01-05 [1/1] No.match Here; This message has necessary quoting in place (inbox unread)" - -test_done diff --git a/test/search-limiting b/test/search-limiting deleted file mode 100755 index 303762cf..00000000 --- a/test/search-limiting +++ /dev/null @@ -1,71 +0,0 @@ -#!/usr/bin/env bash -test_description='"notmuch search" --offset and --limit parameters' -. ./test-lib.sh - -add_email_corpus - -for outp in messages threads; do - test_begin_subtest "${outp}: limit does the right thing" - notmuch search --output=${outp} "*" | head -n 20 >expected - notmuch search --output=${outp} --limit=20 "*" >output - test_expect_equal_file expected output - - test_begin_subtest "${outp}: concatenation of limited searches" - notmuch search --output=${outp} "*" | head -n 20 >expected - notmuch search --output=${outp} --limit=10 "*" >output - notmuch search --output=${outp} --limit=10 --offset=10 "*" >>output - test_expect_equal_file expected output - - test_begin_subtest "${outp}: limit larger than result set" - N=`notmuch count --output=${outp} "*"` - notmuch search --output=${outp} "*" >expected - notmuch search --output=${outp} --limit=$((1 + ${N})) "*" >output - test_expect_equal_file expected output - - test_begin_subtest "${outp}: limit = 0" - test_expect_equal "`notmuch search --output=${outp} --limit=0 "*"`" "" - - test_begin_subtest "${outp}: offset does the right thing" - # note: tail -n +N is 1-based - notmuch search --output=${outp} "*" | tail -n +21 >expected - notmuch search --output=${outp} --offset=20 "*" >output - test_expect_equal_file expected output - - test_begin_subtest "${outp}: offset = 0" - notmuch search --output=${outp} "*" >expected - notmuch search --output=${outp} --offset=0 "*" >output - test_expect_equal_file expected output - - test_begin_subtest "${outp}: negative offset" - notmuch search --output=${outp} "*" | tail -n 20 >expected - notmuch search --output=${outp} --offset=-20 "*" >output - test_expect_equal_file expected output - - test_begin_subtest "${outp}: negative offset" - notmuch search --output=${outp} "*" | tail -n 1 >expected - notmuch search --output=${outp} --offset=-1 "*" >output - test_expect_equal_file expected output - - test_begin_subtest "${outp}: negative offset combined with limit" - notmuch search --output=${outp} "*" | tail -n 20 | head -n 10 >expected - notmuch search --output=${outp} --offset=-20 --limit=10 "*" >output - test_expect_equal_file expected output - - test_begin_subtest "${outp}: negative offset combined with equal limit" - notmuch search --output=${outp} "*" | tail -n 20 >expected - notmuch search --output=${outp} --offset=-20 --limit=20 "*" >output - test_expect_equal_file expected output - - test_begin_subtest "${outp}: negative offset combined with large limit" - notmuch search --output=${outp} "*" | tail -n 20 >expected - notmuch search --output=${outp} --offset=-20 --limit=50 "*" >output - test_expect_equal_file expected output - - test_begin_subtest "${outp}: negative offset larger then results" - N=`notmuch count --output=${outp} "*"` - notmuch search --output=${outp} "*" >expected - notmuch search --output=${outp} --offset=-$((1 + ${N})) "*" >output - test_expect_equal_file expected output -done - -test_done diff --git a/test/search-output b/test/search-output deleted file mode 100755 index 5ccfeaf9..00000000 --- a/test/search-output +++ /dev/null @@ -1,405 +0,0 @@ -#!/usr/bin/env bash -test_description='various settings for "notmuch search --output="' -. ./test-lib.sh - -add_email_corpus - -test_begin_subtest "--output=threads" -notmuch search --output=threads '*' | sed -e s/thread:.*/thread:THREADID/ >OUTPUT -cat <EXPECTED -thread:THREADID -thread:THREADID -thread:THREADID -thread:THREADID -thread:THREADID -thread:THREADID -thread:THREADID -thread:THREADID -thread:THREADID -thread:THREADID -thread:THREADID -thread:THREADID -thread:THREADID -thread:THREADID -thread:THREADID -thread:THREADID -thread:THREADID -thread:THREADID -thread:THREADID -thread:THREADID -thread:THREADID -thread:THREADID -thread:THREADID -thread:THREADID -EOF -test_expect_equal_file OUTPUT EXPECTED - -test_begin_subtest "--output=threads --format=json" -notmuch search --format=json --output=threads '*' | sed -e s/\".*\"/\"THREADID\"/ >OUTPUT -cat <EXPECTED -["THREADID", -"THREADID", -"THREADID", -"THREADID", -"THREADID", -"THREADID", -"THREADID", -"THREADID", -"THREADID", -"THREADID", -"THREADID", -"THREADID", -"THREADID", -"THREADID", -"THREADID", -"THREADID", -"THREADID", -"THREADID", -"THREADID", -"THREADID", -"THREADID", -"THREADID", -"THREADID", -"THREADID"] -EOF -test_expect_equal_json "$(cat OUTPUT)" "$(cat EXPECTED)" - -test_begin_subtest "--output=messages" -notmuch search --output=messages '*' >OUTPUT -cat <EXPECTED -id:4EFC743A.3060609@april.org -id:877h1wv7mg.fsf@inf-8657.int-evry.fr -id:1258544095-16616-1-git-send-email-chris@chris-wilson.co.uk -id:877htoqdbo.fsf@yoom.home.cworth.org -id:878we4qdqf.fsf@yoom.home.cworth.org -id:87aaykqe24.fsf@yoom.home.cworth.org -id:87bpj0qeng.fsf@yoom.home.cworth.org -id:87fx8cqf8v.fsf@yoom.home.cworth.org -id:87hbssqfix.fsf@yoom.home.cworth.org -id:87iqd8qgiz.fsf@yoom.home.cworth.org -id:87k4xoqgnl.fsf@yoom.home.cworth.org -id:87ocn0qh6d.fsf@yoom.home.cworth.org -id:87pr7gqidx.fsf@yoom.home.cworth.org -id:867hto2p0t.fsf@fortitudo.i-did-not-set--mail-host-address--so-tickle-me -id:1258532999-9316-1-git-send-email-keithp@keithp.com -id:86aayk2rbj.fsf@fortitudo.i-did-not-set--mail-host-address--so-tickle-me -id:86d43g2w3y.fsf@fortitudo.i-did-not-set--mail-host-address--so-tickle-me -id:ddd65cda0911172214t60d22b63hcfeb5a19ab54a39b@mail.gmail.com -id:86einw2xof.fsf@fortitudo.i-did-not-set--mail-host-address--so-tickle-me -id:736613.51770.qm@web113505.mail.gq1.yahoo.com -id:1258520223-15328-1-git-send-email-jan@ryngle.com -id:ddd65cda0911171950o4eea4389v86de9525e46052d3@mail.gmail.com -id:1258510940-7018-1-git-send-email-stewart@flamingspork.com -id:yunzl6kd1w0.fsf@aiko.keithp.com -id:yun1vjwegii.fsf@aiko.keithp.com -id:yun3a4cegoa.fsf@aiko.keithp.com -id:1258509400-32511-1-git-send-email-stewart@flamingspork.com -id:1258506353-20352-1-git-send-email-stewart@flamingspork.com -id:20091118010116.GC25380@dottiness.seas.harvard.edu -id:20091118005829.GB25380@dottiness.seas.harvard.edu -id:20091118005040.GA25380@dottiness.seas.harvard.edu -id:cf0c4d610911171623q3e27a0adx802e47039b57604b@mail.gmail.com -id:1258500222-32066-1-git-send-email-ingmar@exherbo.org -id:20091117232137.GA7669@griffis1.net -id:20091118002059.067214ed@hikari -id:1258498485-sup-142@elly -id:f35dbb950911171438k5df6eb56k77b6c0944e2e79ae@mail.gmail.com -id:f35dbb950911171435ieecd458o853c873e35f4be95@mail.gmail.com -id:1258496327-12086-1-git-send-email-jan@ryngle.com -id:1258493565-13508-1-git-send-email-keithp@keithp.com -id:yunaayketfm.fsf@aiko.keithp.com -id:yunbpj0etua.fsf@aiko.keithp.com -id:1258491078-29658-1-git-send-email-dottedmag@dottedmag.net -id:87fx8can9z.fsf@vertex.dottedmag -id:20091117203301.GV3165@dottiness.seas.harvard.edu -id:87lji4lx9v.fsf@yoom.home.cworth.org -id:cf0c4d610911171136h1713aa59w9cf9aa31f052ad0a@mail.gmail.com -id:87iqd9rn3l.fsf@vertex.dottedmag -id:20091117190054.GU3165@dottiness.seas.harvard.edu -id:87lji5cbwo.fsf@yoom.home.cworth.org -id:1258471718-6781-2-git-send-email-dottedmag@dottedmag.net -id:1258471718-6781-1-git-send-email-dottedmag@dottedmag.net -EOF -test_expect_equal_file OUTPUT EXPECTED - -test_begin_subtest "--output=messages --format=json" -notmuch search --format=json --output=messages '*' >OUTPUT -cat <EXPECTED -["4EFC743A.3060609@april.org", -"877h1wv7mg.fsf@inf-8657.int-evry.fr", -"1258544095-16616-1-git-send-email-chris@chris-wilson.co.uk", -"877htoqdbo.fsf@yoom.home.cworth.org", -"878we4qdqf.fsf@yoom.home.cworth.org", -"87aaykqe24.fsf@yoom.home.cworth.org", -"87bpj0qeng.fsf@yoom.home.cworth.org", -"87fx8cqf8v.fsf@yoom.home.cworth.org", -"87hbssqfix.fsf@yoom.home.cworth.org", -"87iqd8qgiz.fsf@yoom.home.cworth.org", -"87k4xoqgnl.fsf@yoom.home.cworth.org", -"87ocn0qh6d.fsf@yoom.home.cworth.org", -"87pr7gqidx.fsf@yoom.home.cworth.org", -"867hto2p0t.fsf@fortitudo.i-did-not-set--mail-host-address--so-tickle-me", -"1258532999-9316-1-git-send-email-keithp@keithp.com", -"86aayk2rbj.fsf@fortitudo.i-did-not-set--mail-host-address--so-tickle-me", -"86d43g2w3y.fsf@fortitudo.i-did-not-set--mail-host-address--so-tickle-me", -"ddd65cda0911172214t60d22b63hcfeb5a19ab54a39b@mail.gmail.com", -"86einw2xof.fsf@fortitudo.i-did-not-set--mail-host-address--so-tickle-me", -"736613.51770.qm@web113505.mail.gq1.yahoo.com", -"1258520223-15328-1-git-send-email-jan@ryngle.com", -"ddd65cda0911171950o4eea4389v86de9525e46052d3@mail.gmail.com", -"1258510940-7018-1-git-send-email-stewart@flamingspork.com", -"yunzl6kd1w0.fsf@aiko.keithp.com", -"yun1vjwegii.fsf@aiko.keithp.com", -"yun3a4cegoa.fsf@aiko.keithp.com", -"1258509400-32511-1-git-send-email-stewart@flamingspork.com", -"1258506353-20352-1-git-send-email-stewart@flamingspork.com", -"20091118010116.GC25380@dottiness.seas.harvard.edu", -"20091118005829.GB25380@dottiness.seas.harvard.edu", -"20091118005040.GA25380@dottiness.seas.harvard.edu", -"cf0c4d610911171623q3e27a0adx802e47039b57604b@mail.gmail.com", -"1258500222-32066-1-git-send-email-ingmar@exherbo.org", -"20091117232137.GA7669@griffis1.net", -"20091118002059.067214ed@hikari", -"1258498485-sup-142@elly", -"f35dbb950911171438k5df6eb56k77b6c0944e2e79ae@mail.gmail.com", -"f35dbb950911171435ieecd458o853c873e35f4be95@mail.gmail.com", -"1258496327-12086-1-git-send-email-jan@ryngle.com", -"1258493565-13508-1-git-send-email-keithp@keithp.com", -"yunaayketfm.fsf@aiko.keithp.com", -"yunbpj0etua.fsf@aiko.keithp.com", -"1258491078-29658-1-git-send-email-dottedmag@dottedmag.net", -"87fx8can9z.fsf@vertex.dottedmag", -"20091117203301.GV3165@dottiness.seas.harvard.edu", -"87lji4lx9v.fsf@yoom.home.cworth.org", -"cf0c4d610911171136h1713aa59w9cf9aa31f052ad0a@mail.gmail.com", -"87iqd9rn3l.fsf@vertex.dottedmag", -"20091117190054.GU3165@dottiness.seas.harvard.edu", -"87lji5cbwo.fsf@yoom.home.cworth.org", -"1258471718-6781-2-git-send-email-dottedmag@dottedmag.net", -"1258471718-6781-1-git-send-email-dottedmag@dottedmag.net"] -EOF -test_expect_equal_file OUTPUT EXPECTED - -test_begin_subtest "--output=files" -notmuch search --output=files '*' | sed -e "s,$MAIL_DIR,MAIL_DIR," >OUTPUT -cat <EXPECTED -MAIL_DIR/cur/52:2, -MAIL_DIR/cur/53:2, -MAIL_DIR/cur/50:2, -MAIL_DIR/cur/49:2, -MAIL_DIR/cur/48:2, -MAIL_DIR/cur/47:2, -MAIL_DIR/cur/46:2, -MAIL_DIR/cur/45:2, -MAIL_DIR/cur/44:2, -MAIL_DIR/cur/43:2, -MAIL_DIR/cur/42:2, -MAIL_DIR/cur/41:2, -MAIL_DIR/cur/40:2, -MAIL_DIR/cur/39:2, -MAIL_DIR/cur/38:2, -MAIL_DIR/cur/37:2, -MAIL_DIR/cur/36:2, -MAIL_DIR/cur/35:2, -MAIL_DIR/cur/34:2, -MAIL_DIR/cur/33:2, -MAIL_DIR/cur/32:2, -MAIL_DIR/cur/31:2, -MAIL_DIR/cur/30:2, -MAIL_DIR/cur/29:2, -MAIL_DIR/cur/28:2, -MAIL_DIR/cur/27:2, -MAIL_DIR/cur/26:2, -MAIL_DIR/cur/25:2, -MAIL_DIR/cur/24:2, -MAIL_DIR/cur/23:2, -MAIL_DIR/cur/22: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, -MAIL_DIR/cur/15:2, -MAIL_DIR/cur/14:2, -MAIL_DIR/cur/13:2, -MAIL_DIR/cur/12:2, -MAIL_DIR/cur/11:2, -MAIL_DIR/cur/10:2, -MAIL_DIR/cur/09:2, -MAIL_DIR/cur/08:2, -MAIL_DIR/cur/06:2, -MAIL_DIR/cur/05:2, -MAIL_DIR/cur/04:2, -MAIL_DIR/cur/03:2, -MAIL_DIR/cur/07:2, -MAIL_DIR/cur/02:2, -MAIL_DIR/cur/01:2, -EOF -test_expect_equal_file OUTPUT EXPECTED - -test_begin_subtest "--output=files --duplicate=1" -notmuch search --output=files --duplicate=1 '*' | sed -e "s,$MAIL_DIR,MAIL_DIR," >OUTPUT -cat <EXPECTED -MAIL_DIR/cur/52:2, -MAIL_DIR/cur/53:2, -MAIL_DIR/cur/50:2, -MAIL_DIR/cur/49:2, -MAIL_DIR/cur/48:2, -MAIL_DIR/cur/47:2, -MAIL_DIR/cur/46:2, -MAIL_DIR/cur/45:2, -MAIL_DIR/cur/44:2, -MAIL_DIR/cur/43:2, -MAIL_DIR/cur/42:2, -MAIL_DIR/cur/41:2, -MAIL_DIR/cur/40:2, -MAIL_DIR/cur/39:2, -MAIL_DIR/cur/38:2, -MAIL_DIR/cur/37:2, -MAIL_DIR/cur/36:2, -MAIL_DIR/cur/35:2, -MAIL_DIR/cur/34:2, -MAIL_DIR/cur/33:2, -MAIL_DIR/cur/32:2, -MAIL_DIR/cur/31:2, -MAIL_DIR/cur/30:2, -MAIL_DIR/cur/29:2, -MAIL_DIR/cur/28:2, -MAIL_DIR/cur/27:2, -MAIL_DIR/cur/26:2, -MAIL_DIR/cur/25:2, -MAIL_DIR/cur/24:2, -MAIL_DIR/cur/23:2, -MAIL_DIR/cur/22:2, -MAIL_DIR/cur/21:2, -MAIL_DIR/cur/19:2, -MAIL_DIR/cur/18:2, -MAIL_DIR/cur/20:2, -MAIL_DIR/cur/17:2, -MAIL_DIR/cur/16:2, -MAIL_DIR/cur/15:2, -MAIL_DIR/cur/14:2, -MAIL_DIR/cur/13:2, -MAIL_DIR/cur/12:2, -MAIL_DIR/cur/11:2, -MAIL_DIR/cur/10:2, -MAIL_DIR/cur/09:2, -MAIL_DIR/cur/08:2, -MAIL_DIR/cur/06:2, -MAIL_DIR/cur/05:2, -MAIL_DIR/cur/04:2, -MAIL_DIR/cur/03:2, -MAIL_DIR/cur/07:2, -MAIL_DIR/cur/02:2, -MAIL_DIR/cur/01:2, -EOF -test_expect_equal_file OUTPUT EXPECTED - -test_begin_subtest "--output=files --format=json" -notmuch search --format=json --output=files '*' | sed -e "s,$MAIL_DIR,MAIL_DIR," >OUTPUT -cat <EXPECTED -["MAIL_DIR/cur/52:2,", -"MAIL_DIR/cur/53:2,", -"MAIL_DIR/cur/50:2,", -"MAIL_DIR/cur/49:2,", -"MAIL_DIR/cur/48:2,", -"MAIL_DIR/cur/47:2,", -"MAIL_DIR/cur/46:2,", -"MAIL_DIR/cur/45:2,", -"MAIL_DIR/cur/44:2,", -"MAIL_DIR/cur/43:2,", -"MAIL_DIR/cur/42:2,", -"MAIL_DIR/cur/41:2,", -"MAIL_DIR/cur/40:2,", -"MAIL_DIR/cur/39:2,", -"MAIL_DIR/cur/38:2,", -"MAIL_DIR/cur/37:2,", -"MAIL_DIR/cur/36:2,", -"MAIL_DIR/cur/35:2,", -"MAIL_DIR/cur/34:2,", -"MAIL_DIR/cur/33:2,", -"MAIL_DIR/cur/32:2,", -"MAIL_DIR/cur/31:2,", -"MAIL_DIR/cur/30:2,", -"MAIL_DIR/cur/29:2,", -"MAIL_DIR/cur/28:2,", -"MAIL_DIR/cur/27:2,", -"MAIL_DIR/cur/26:2,", -"MAIL_DIR/cur/25:2,", -"MAIL_DIR/cur/24:2,", -"MAIL_DIR/cur/23:2,", -"MAIL_DIR/cur/22: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,", -"MAIL_DIR/cur/15:2,", -"MAIL_DIR/cur/14:2,", -"MAIL_DIR/cur/13:2,", -"MAIL_DIR/cur/12:2,", -"MAIL_DIR/cur/11:2,", -"MAIL_DIR/cur/10:2,", -"MAIL_DIR/cur/09:2,", -"MAIL_DIR/cur/08:2,", -"MAIL_DIR/cur/06:2,", -"MAIL_DIR/cur/05:2,", -"MAIL_DIR/cur/04:2,", -"MAIL_DIR/cur/03:2,", -"MAIL_DIR/cur/07:2,", -"MAIL_DIR/cur/02:2,", -"MAIL_DIR/cur/01:2,"] -EOF -test_expect_equal_file OUTPUT EXPECTED - -test_begin_subtest "--output=files --format=json --duplicate=2" -notmuch search --format=json --output=files --duplicate=2 '*' | sed -e "s,$MAIL_DIR,MAIL_DIR," >OUTPUT -cat <EXPECTED -["MAIL_DIR/cur/51:2,"] -EOF -test_expect_equal_file OUTPUT EXPECTED - -test_begin_subtest "--output=tags" -notmuch search --output=tags '*' >OUTPUT -cat <EXPECTED -attachment -inbox -signed -unread -EOF -test_expect_equal_file OUTPUT EXPECTED - -test_begin_subtest "--output=tags --format=json" -notmuch search --format=json --output=tags '*' >OUTPUT -cat <EXPECTED -["attachment", -"inbox", -"signed", -"unread"] -EOF -test_expect_equal_file OUTPUT EXPECTED - -test_begin_subtest "sanitize output for quoted-printable line-breaks in author and subject" -add_message "[subject]='two =?ISO-8859-1?Q?line=0A_subject?= - headers'" -notmuch search id:"$gen_msg_id" | notmuch_search_sanitize >OUTPUT -cat <EXPECTED -thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; two line? subject headers (inbox unread) -EOF -test_expect_equal_file OUTPUT EXPECTED - -test_begin_subtest "search for non-existent message prints nothing" -notmuch search "no-message-matches-this" > OUTPUT -echo -n >EXPECTED -test_expect_equal_file OUTPUT EXPECTED - -test_begin_subtest "search --format=json for non-existent message prints proper empty json" -notmuch search --format=json "no-message-matches-this" > OUTPUT -echo "[]" >EXPECTED -test_expect_equal_file OUTPUT EXPECTED - -test_done diff --git a/test/search-position-overlap-bug b/test/search-position-overlap-bug deleted file mode 100755 index 5da6ad6f..00000000 --- a/test/search-position-overlap-bug +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env bash - -# Test to demonstrate a position overlap bug. -# -# At one point, notmuch would index terms incorrectly in the case of -# calling index_terms multiple times for a single field. The term -# generator was being reset to position 0 each time. This means that -# with text such as: -# -# To: a@b.c, x@y.z -# -# one could get a bogus match by searching for: -# -# To: a@y.c -# -# Thanks to Mark Anderson for reporting the bug, (and providing a nice, -# minimal test case that inspired what is used here), in -# id:3wd4o8wa7fx.fsf@testarossa.amd.com - -test_description='that notmuch does not overlap term positions' -. ./test-lib.sh - -add_message '[to]="a@b.c, x@y.z"' - -test_begin_subtest "Search for a@b.c matches" -output=$(notmuch search a@b.c | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Test message #1 (inbox unread)" - -test_begin_subtest "Search for x@y.z matches" -output=$(notmuch search x@y.z | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Test message #1 (inbox unread)" - -test_begin_subtest "Search for a@y.c must not match" -output=$(notmuch search a@y.c | notmuch_search_sanitize) -test_expect_equal "$output" "" - -test_done diff --git a/test/setup b/test/setup deleted file mode 100755 index 124ef1c8..00000000 --- a/test/setup +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env bash - -test_description='"notmuch setup"' -. ./test-lib.sh - -test_begin_subtest "Create a new config interactively" -notmuch --config=new-notmuch-config > /dev/null <\" :To \"Notmuch Test Suite \" :Bcc \"test_suite+bcc@notmuchmail.org\" :Reply-To \"test_suite+replyto@notmuchmail.org\" :Date \"Sat, 01 Jan 2000 12:00:00 +0000\") :body ((:id 1 :content-type \"text/plain\" :content \"sexp-show-message\n\"))) ())))" - -# This should be the same output as above. -test_begin_subtest "Show message: sexp --body=true" -output=$(notmuch show --format=sexp --body=true "sexp-show-message") -test_expect_equal "$output" "((((:id \"${gen_msg_id}\" :match t :excluded nil :filename \"${gen_msg_filename}\" :timestamp 946728000 :date_relative \"2000-01-01\" :tags (\"inbox\" \"unread\") :headers (:Subject \"sexp-show-subject\" :From \"Notmuch Test Suite \" :To \"Notmuch Test Suite \" :Bcc \"test_suite+bcc@notmuchmail.org\" :Reply-To \"test_suite+replyto@notmuchmail.org\" :Date \"Sat, 01 Jan 2000 12:00:00 +0000\") :body ((:id 1 :content-type \"text/plain\" :content \"sexp-show-message\n\"))) ())))" - -test_begin_subtest "Show message: sexp --body=false" -output=$(notmuch show --format=sexp --body=false "sexp-show-message") -test_expect_equal "$output" "((((:id \"${gen_msg_id}\" :match t :excluded nil :filename \"${gen_msg_filename}\" :timestamp 946728000 :date_relative \"2000-01-01\" :tags (\"inbox\" \"unread\") :headers (:Subject \"sexp-show-subject\" :From \"Notmuch Test Suite \" :To \"Notmuch Test Suite \" :Bcc \"test_suite+bcc@notmuchmail.org\" :Reply-To \"test_suite+replyto@notmuchmail.org\" :Date \"Sat, 01 Jan 2000 12:00:00 +0000\")) ())))" - -test_begin_subtest "Search message: sexp" -add_message "[subject]=\"sexp-search-subject\"" "[date]=\"Sat, 01 Jan 2000 12:00:00 -0000\"" "[body]=\"sexp-search-message\"" -output=$(notmuch search --format=sexp "sexp-search-message" | notmuch_search_sanitize) -test_expect_equal "$output" "((:thread \"0000000000000002\" :timestamp 946728000 :date_relative \"2000-01-01\" :matched 1 :total 1 :authors \"Notmuch Test Suite\" :subject \"sexp-search-subject\" :query (\"id:$gen_msg_id\" nil) :tags (\"inbox\" \"unread\")))" - -test_begin_subtest "Show message: sexp, utf-8" -add_message "[subject]=\"sexp-show-utf8-body-sübjéct\"" "[date]=\"Sat, 01 Jan 2000 12:00:00 -0000\"" "[body]=\"jsön-show-méssage\"" -output=$(notmuch show --format=sexp "jsön-show-méssage") -test_expect_equal "$output" "((((:id \"${gen_msg_id}\" :match t :excluded nil :filename \"${gen_msg_filename}\" :timestamp 946728000 :date_relative \"2000-01-01\" :tags (\"inbox\" \"unread\") :headers (:Subject \"sexp-show-utf8-body-sübjéct\" :From \"Notmuch Test Suite \" :To \"Notmuch Test Suite \" :Date \"Sat, 01 Jan 2000 12:00:00 +0000\") :body ((:id 1 :content-type \"text/plain\" :content \"jsön-show-méssage\n\"))) ())))" - -test_begin_subtest "Show message: sexp, inline attachment filename" -subject='sexp-show-inline-attachment-filename' -id="sexp-show-inline-attachment-filename@notmuchmail.org" -emacs_fcc_message \ - "$subject" \ - 'This is a test message with inline attachment with a filename' \ - "(mml-attach-file \"$TEST_DIRECTORY/README\" nil nil \"inline\") - (message-goto-eoh) - (insert \"Message-ID: <$id>\n\")" -output=$(notmuch show --format=sexp "id:$id") -filename=$(notmuch search --output=files "id:$id") -# Get length of README after base64-encoding, minus additional newline. -attachment_length=$(( $(base64 $TEST_DIRECTORY/README | wc -c) - 1 )) -test_expect_equal "$output" "((((:id \"$id\" :match t :excluded nil :filename \"$filename\" :timestamp 946728000 :date_relative \"2000-01-01\" :tags (\"inbox\") :headers (:Subject \"sexp-show-inline-attachment-filename\" :From \"Notmuch Test Suite \" :To \"test_suite@notmuchmail.org\" :Date \"Sat, 01 Jan 2000 12:00:00 +0000\") :body ((:id 1 :content-type \"multipart/mixed\" :content ((:id 2 :content-type \"text/plain\" :content \"This is a test message with inline attachment with a filename\") (:id 3 :content-type \"application/octet-stream\" :filename \"README\" :content-transfer-encoding \"base64\" :content-length $attachment_length))))) ())))" - -test_begin_subtest "Search message: sexp, utf-8" -add_message "[subject]=\"sexp-search-utf8-body-sübjéct\"" "[date]=\"Sat, 01 Jan 2000 12:00:00 -0000\"" "[body]=\"jsön-search-méssage\"" -output=$(notmuch search --format=sexp "jsön-search-méssage" | notmuch_search_sanitize) -test_expect_equal "$output" "((:thread \"0000000000000005\" :timestamp 946728000 :date_relative \"2000-01-01\" :matched 1 :total 1 :authors \"Notmuch Test Suite\" :subject \"sexp-search-utf8-body-sübjéct\" :query (\"id:$gen_msg_id\" nil) :tags (\"inbox\" \"unread\")))" - - -test_done diff --git a/test/symbol-hiding b/test/symbol-hiding deleted file mode 100755 index 636ec917..00000000 --- a/test/symbol-hiding +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env bash -# -# Copyright (c) 2011 David Bremner -# - -# This test tests whether hiding Xapian::Error symbols in libnotmuch -# also hides them for other users of libxapian. This is motivated by -# the discussion in http://gcc.gnu.org/wiki/Visibility' - -test_description='exception symbol hiding' - -. ./test-lib.sh - -run_test(){ - result=$(LD_LIBRARY_PATH="$TEST_DIRECTORY/../lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" $TEST_DIRECTORY/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'" - -mkdir -p fakedb/.notmuch - -test_expect_success 'running test' run_test - -test_begin_subtest 'checking output' -test_expect_equal "$result" "$output" - -test_begin_subtest 'comparing existing to exported symbols' -objdump -t $TEST_DIRECTORY/../lib/*.o | awk '$4 == ".text" && $6 ~ "^notmuch" {print $6}' | sort | uniq > ACTUAL -sed -n 's/[[:blank:]]*\(notmuch_[^;]*\);/\1/p' $TEST_DIRECTORY/../notmuch.sym | sort | uniq > EXPORTED -test_expect_equal_file EXPORTED ACTUAL - -test_done diff --git a/test/tagging b/test/tagging deleted file mode 100755 index dc118f33..00000000 --- a/test/tagging +++ /dev/null @@ -1,264 +0,0 @@ -#!/usr/bin/env bash -test_description='"notmuch tag"' -. ./test-lib.sh - -add_message '[subject]=One' -add_message '[subject]=Two' - -test_begin_subtest "Adding tags" -notmuch tag +tag1 +tag2 +tag3 \* -output=$(notmuch search \* | notmuch_search_sanitize) -test_expect_equal "$output" "\ -thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; One (inbox tag1 tag2 tag3 unread) -thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Two (inbox tag1 tag2 tag3 unread)" - -test_begin_subtest "Removing tags" -notmuch tag -tag1 -tag2 \* -output=$(notmuch search \* | notmuch_search_sanitize) -test_expect_equal "$output" "\ -thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; One (inbox tag3 unread) -thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Two (inbox tag3 unread)" - -test_expect_code 1 "No tag operations" 'notmuch tag One' -test_expect_code 1 "No query" 'notmuch tag +tag2' - -test_begin_subtest "Redundant tagging" -notmuch tag +tag1 -tag3 One -notmuch tag +tag1 -tag3 \* -output=$(notmuch search \* | notmuch_search_sanitize) -test_expect_equal "$output" "\ -thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; One (inbox tag1 unread) -thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Two (inbox tag1 unread)" - -test_begin_subtest "Remove all" -notmuch tag --remove-all One -notmuch tag --remove-all +tag5 +tag6 +unread Two -output=$(notmuch search \* | notmuch_search_sanitize) -test_expect_equal "$output" "\ -thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; One () -thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Two (tag5 tag6 unread)" - -test_begin_subtest "Remove all with a no-op" -notmuch tag +inbox +tag1 +unread One -notmuch tag --remove-all +foo +inbox +tag1 -foo +unread Two -output=$(notmuch search \* | notmuch_search_sanitize) -test_expect_equal "$output" "\ -thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; One (inbox tag1 unread) -thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Two (inbox tag1 unread)" - -test_begin_subtest "Special characters in tags" -notmuch tag +':" ' \* -notmuch tag -':" ' Two -output=$(notmuch search \* | notmuch_search_sanitize) -test_expect_equal "$output" "\ -thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; One (:\" inbox tag1 unread) -thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Two (inbox tag1 unread)" - -test_begin_subtest "Tagging order" -notmuch tag +tag4 -tag4 One -notmuch tag -tag4 +tag4 Two -output=$(notmuch search \* | notmuch_search_sanitize) -test_expect_equal "$output" "\ -thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; One (:\" inbox tag1 unread) -thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Two (inbox tag1 tag4 unread)" - -test_begin_subtest "--batch" -notmuch tag --batch < batch.in < batch.expected < backup.tags -notmuch tag --input=batch.in -notmuch search \* | notmuch_search_sanitize > OUTPUT -notmuch restore --format=batch-tag < backup.tags -test_expect_equal_file batch.expected OUTPUT - -test_begin_subtest "--batch --input" -notmuch dump --format=batch-tag > backup.tags -notmuch tag --batch --input=batch.in -notmuch search \* | notmuch_search_sanitize > OUTPUT -notmuch restore --format=batch-tag < backup.tags -test_expect_equal_file batch.expected OUTPUT - -test_begin_subtest "--batch, blank lines and comments" -notmuch dump | sort > EXPECTED -notmuch tag --batch < OUTPUT -test_expect_equal_file EXPECTED OUTPUT - -test_begin_subtest '--batch: checking error messages' -notmuch dump --format=batch-tag > BACKUP -notmuch tag --batch <OUTPUT -# the next line has a space - -# this line has no tag operations, but this is permitted in batch format. -a -+0 -+a +b -# trailing whitespace -+a +b -+c +d -- -# this is a harmless comment, do not yell about it. - -# the previous line was blank; also no yelling please -+%zz -- id:whatever -# the next non-comment line should report an an empty tag error for -# batch tagging, but not for restore -+ +e -- id:foo -+- -- id:foo -EOF - -cat < EXPECTED -Warning: no query string [+0] -Warning: no query string [+a +b] -Warning: missing query string [+a +b ] -Warning: no query string after -- [+c +d --] -Warning: hex decoding of tag %zz failed [+%zz -- id:whatever] -Warning: empty tag forbidden [+ +e -- id:foo] -Warning: tag starting with '-' forbidden [+- -- id:foo] -EOF - -notmuch restore --format=batch-tag < BACKUP -test_expect_equal_file EXPECTED OUTPUT - -test_begin_subtest '--batch: tags with quotes' -notmuch dump --format=batch-tag > BACKUP - -notmuch tag --batch < EXPECTED -+%22%27%22%22%22%27 +inbox +tag5 +unread -- id:msg-001@notmuch-test-suite -+%22%27%22%27%22%22%27%27 +inbox +tag4 +tag5 +unread -- id:msg-002@notmuch-test-suite -EOF - -notmuch dump --format=batch-tag | sort > OUTPUT -notmuch restore --format=batch-tag < BACKUP -test_expect_equal_file EXPECTED OUTPUT - -test_begin_subtest '--batch: tags with punctuation and space' -notmuch dump --format=batch-tag > BACKUP - -notmuch tag --batch < EXPECTED -+%21@%23%20%24%25%5e%26%2a%29-_=+%5b%7b%5c%20%7c%3b%3a%27%20%22,.%3c%60%7e +inbox +tag4 +tag5 +unread -- id:msg-002@notmuch-test-suite -+%21@%23%20%24%25%5e%26%2a%29-_=+%5b%7b%5c%20%7c%3b%3a%27%20%22,.%3c%60%7e +inbox +tag5 +unread -- id:msg-001@notmuch-test-suite -EOF - -notmuch dump --format=batch-tag | sort > OUTPUT -notmuch restore --format=batch-tag < BACKUP -test_expect_equal_file EXPECTED OUTPUT - -test_begin_subtest '--batch: unicode tags' -notmuch dump --format=batch-tag > BACKUP - -notmuch tag --batch < EXPECTED -+%2a@%7d%cf%b5%f4%85%80%adO3%da%a7 +=%e0%ac%95%c8%b3+%ef%aa%95%c8%a64w%c7%9d%c9%a2%cf%b3%d6%82%24B%c4%a9%c5%a1UX%ee%99%b0%27E7%ca%a4%d0%8b%5d +A%e1%a0%bc%de%8b%d5%b2V%d9%9b%f3%b5%a2%a3M%d8%a1u@%f0%a0%ac%948%7e%f0%ab%86%af%27 +L%df%85%ef%a1%a5m@%d3%96%c2%ab%d4%9f%ca%b8%f3%b3%a2%bf%c7%b1_u%d7%b4%c7%b1 +P%c4%98%2f +R +inbox +tag4 +tag5 +unread +%7e%d1%8b%25%ec%a0%ae%d1%a0M%3b%e3%b6%b7%e9%a4%87%3c%db%9a%cc%a8%e1%96%9d +%c4%bf7%c7%ab9H%c4%99k%ea%91%bd%c3%8ck%e2%b3%8dk%c5%952V%e4%99%b2%d9%b3%e4%8b%bda%5b%24%c7%9b +%da%88=f%cc%b9I%ce%af%7b%c9%97%e3%b9%8bH%cb%92X%d2%8c6 +%dc%9crh%d2%86B%e5%97%a2%22t%ed%99%82d -- id:msg-002@notmuch-test-suite -+%2a@%7d%cf%b5%f4%85%80%adO3%da%a7 +=%e0%ac%95%c8%b3+%ef%aa%95%c8%a64w%c7%9d%c9%a2%cf%b3%d6%82%24B%c4%a9%c5%a1UX%ee%99%b0%27E7%ca%a4%d0%8b%5d +A%e1%a0%bc%de%8b%d5%b2V%d9%9b%f3%b5%a2%a3M%d8%a1u@%f0%a0%ac%948%7e%f0%ab%86%af%27 +L%df%85%ef%a1%a5m@%d3%96%c2%ab%d4%9f%ca%b8%f3%b3%a2%bf%c7%b1_u%d7%b4%c7%b1 +P%c4%98%2f +R +inbox +tag5 +unread +%7e%d1%8b%25%ec%a0%ae%d1%a0M%3b%e3%b6%b7%e9%a4%87%3c%db%9a%cc%a8%e1%96%9d +%c4%bf7%c7%ab9H%c4%99k%ea%91%bd%c3%8ck%e2%b3%8dk%c5%952V%e4%99%b2%d9%b3%e4%8b%bda%5b%24%c7%9b +%da%88=f%cc%b9I%ce%af%7b%c9%97%e3%b9%8bH%cb%92X%d2%8c6 +%dc%9crh%d2%86B%e5%97%a2%22t%ed%99%82d -- id:msg-001@notmuch-test-suite -EOF - -notmuch dump --format=batch-tag | sort > OUTPUT -notmuch restore --format=batch-tag < BACKUP -test_expect_equal_file EXPECTED OUTPUT - -test_begin_subtest "--batch: only space and % needs to be encoded." -notmuch dump --format=batch-tag > BACKUP - -notmuch tag --batch < EXPECTED -+%23possible%5c +%26are +%28tags%29 +crazy%7b +inbox +match%2acrazy +space%20in%20tags +tag4 +tag5 +unread +winner -- id:msg-002@notmuch-test-suite -+foo%3a%3abar%25 +found%3a%3ait +inbox +tag5 +unread +winner -- id:msg-001@notmuch-test-suite -EOF - -notmuch dump --format=batch-tag | sort > OUTPUT -notmuch restore --format=batch-tag < BACKUP -test_expect_equal_file EXPECTED OUTPUT - -test_begin_subtest '--batch: unicode message-ids' - -${TEST_DIRECTORY}/random-corpus --config-path=${NOTMUCH_CONFIG} \ - --num-messages=100 - -notmuch dump --format=batch-tag | sed 's/^.* -- /+common_tag -- /' | \ - sort > EXPECTED - -notmuch dump --format=batch-tag | sed 's/^.* -- / -- /' | \ - notmuch restore --format=batch-tag - -notmuch tag --batch < EXPECTED - -notmuch dump --format=batch-tag| \ - sort > OUTPUT - -test_expect_equal_file EXPECTED OUTPUT - -test_expect_code 1 "Empty tag names" 'notmuch tag + One' - -test_expect_code 1 "Tag name beginning with -" 'notmuch tag +- One' - -test_done diff --git a/test/test-lib.sh b/test/test-lib.sh index efa9fb6f..78af170f 100644 --- a/test/test-lib.sh +++ b/test/test-lib.sh @@ -25,6 +25,10 @@ fi # Make sure echo builtin does not expand backslash-escape sequences by default. shopt -u xpg_echo +this_test=${0##*/} +this_test=${this_test%.sh} +this_test_bare=${this_test#T[0-9][0-9][0-9]-} + # if --tee was passed, write the output not only to the terminal, but # additionally to the file test-results/$BASENAME.out, too. case "$GIT_TEST_TEE_STARTED, $* " in @@ -33,7 +37,7 @@ done,*) ;; *' --tee '*|*' --va'*) mkdir -p test-results - BASE=test-results/$(basename "$0" .sh) + BASE=test-results/$this_test (GIT_TEST_TEE_STARTED=done ${SHELL-sh} "$0" "$@" 2>&1; echo $? > $BASE.exit) | tee $BASE.out test "$(cat $BASE.exit)" = 0 @@ -187,7 +191,18 @@ then exit 0 fi -echo $(basename "$0"): "Testing ${test_description}" +test_description_printed= +print_test_description () +{ + test -z "$test_description_printed" || return 0 + echo + echo $this_test_bare: "Testing ${test_description}" + test_description_printed=1 +} +if [ -z "$NOTMUCH_TEST_QUIET" ] +then + print_test_description +fi exec 5>&1 @@ -748,6 +763,9 @@ test_ok_ () { return fi test_success=$(($test_success + 1)) + if test -n "$NOTMUCH_TEST_QUIET"; then + return 0 + fi say_color pass "%-6s" "PASS" echo " $test_subtest_name" } @@ -758,6 +776,7 @@ test_failure_ () { return fi test_failure=$(($test_failure + 1)) + print_test_description test_failure_message_ "FAIL" "$test_subtest_name" "$@" test "$immediate" = "" || { GIT_EXIT_OK=t; exit 1; } return 1 @@ -1009,7 +1028,7 @@ test_done () { GIT_EXIT_OK=t test_results_dir="$TEST_DIRECTORY/test-results" mkdir -p "$test_results_dir" - test_results_path="$test_results_dir/${0%.sh}" + test_results_path="$test_results_dir/$this_test" echo "total $test_count" >> $test_results_path echo "success $test_success" >> $test_results_path @@ -1018,8 +1037,6 @@ test_done () { echo "failed $test_failure" >> $test_results_path echo "" >> $test_results_path - echo - [ -n "$EMACS_SERVER" ] && test_emacs '(kill-emacs)' if [ "$test_failure" = "0" ]; then @@ -1068,7 +1085,7 @@ test_emacs () { test -z "$missing_dependencies" || return if [ -z "$EMACS_SERVER" ]; then - emacs_tests="$(basename $0).el" + emacs_tests="${this_test_bare}.el" if [ -f "$TEST_DIRECTORY/$emacs_tests" ]; then load_emacs_tests="--eval '(load \"$emacs_tests\")'" else @@ -1182,7 +1199,6 @@ else exec 4>test.output 3>&4 fi -this_test=${0##*/} for skp in $NOTMUCH_SKIP_TESTS do to_skip= diff --git a/test/test.expected-output/test-verbose-no b/test/test.expected-output/test-verbose-no index 0bca7540..1a2ff619 100644 --- a/test/test.expected-output/test-verbose-no +++ b/test/test.expected-output/test-verbose-no @@ -1,3 +1,4 @@ + test-verbose: Testing the verbosity options of the test framework itself. PASS print something in test_expect_success and pass FAIL print something in test_expect_success and fail diff --git a/test/test.expected-output/test-verbose-yes b/test/test.expected-output/test-verbose-yes index ebe51874..d25466e9 100644 --- a/test/test.expected-output/test-verbose-yes +++ b/test/test.expected-output/test-verbose-yes @@ -1,3 +1,4 @@ + test-verbose: Testing the verbosity options of the test framework itself. hello stdout hello stderr diff --git a/test/text b/test/text deleted file mode 100755 index b5ccefc9..00000000 --- a/test/text +++ /dev/null @@ -1,88 +0,0 @@ -#!/usr/bin/env bash -test_description="--format=text output" -. ./test-lib.sh - -test_begin_subtest "Show message: text" -add_message "[subject]=\"text-show-subject\"" "[date]=\"Sat, 01 Jan 2000 12:00:00 -0000\"" "[body]=\"text-show-message\"" -output=$(notmuch show --format=text "text-show-message" | notmuch_show_sanitize_all) -test_expect_equal "$output" "\ - message{ id:XXXXX depth:0 match:1 excluded:0 filename:XXXXX - header{ -Notmuch Test Suite (2000-01-01) (inbox unread) -Subject: text-show-subject -From: Notmuch Test Suite -To: Notmuch Test Suite -Date: Sat, 01 Jan 2000 12:00:00 +0000 - header} - body{ - part{ ID: 1, Content-type: text/plain -text-show-message - part} - body} - message}" - -test_begin_subtest "Search message: text" -add_message "[subject]=\"text-search-subject\"" "[date]=\"Sat, 01 Jan 2000 12:00:00 -0000\"" "[body]=\"text-search-message\"" -output=$(notmuch search --format=text "text-search-message" | notmuch_search_sanitize) -test_expect_equal "$output" \ -"thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; text-search-subject (inbox unread)" - -test_begin_subtest "Show message: text, utf-8" -add_message "[subject]=\"text-show-utf8-body-sübjéct\"" "[date]=\"Sat, 01 Jan 2000 12:00:00 -0000\"" "[body]=\"tëxt-show-méssage\"" -output=$(notmuch show --format=text "tëxt-show-méssage" | notmuch_show_sanitize_all) -test_expect_equal "$output" "\ - message{ id:XXXXX depth:0 match:1 excluded:0 filename:XXXXX - header{ -Notmuch Test Suite (2000-01-01) (inbox unread) -Subject: text-show-utf8-body-sübjéct -From: Notmuch Test Suite -To: Notmuch Test Suite -Date: Sat, 01 Jan 2000 12:00:00 +0000 - header} - body{ - part{ ID: 1, Content-type: text/plain -tëxt-show-méssage - part} - body} - message}" - -test_begin_subtest "Search message: text, utf-8" -add_message "[subject]=\"text-search-utf8-body-sübjéct\"" "[date]=\"Sat, 01 Jan 2000 12:00:00 -0000\"" "[body]=\"tëxt-search-méssage\"" -output=$(notmuch search --format=text "tëxt-search-méssage" | notmuch_search_sanitize) -test_expect_equal "$output" \ -"thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; text-search-utf8-body-sübjéct (inbox unread)" - -add_email_corpus - -test_begin_subtest "Search message tags: text0" -cat < EXPECTED -attachment inbox signed unread -EOF -notmuch search --format=text0 --output=tags '*' | xargs -0 | notmuch_search_sanitize > OUTPUT -test_expect_equal_file EXPECTED OUTPUT - -# Use tr(1) to convert --output=text0 to --output=text for -# comparison. Also translate newlines to spaces to fail with more -# noise if they are present as delimiters instead of null -# characters. This assumes there are no newlines in the data. -test_begin_subtest "Compare text vs. text0 for threads" -notmuch search --format=text --output=threads '*' | notmuch_search_sanitize > EXPECTED -notmuch search --format=text0 --output=threads '*' | tr "\n\0" " \n" | notmuch_search_sanitize > OUTPUT -test_expect_equal_file EXPECTED OUTPUT - -test_begin_subtest "Compare text vs. text0 for messages" -notmuch search --format=text --output=messages '*' | notmuch_search_sanitize > EXPECTED -notmuch search --format=text0 --output=messages '*' | tr "\n\0" " \n" | notmuch_search_sanitize > OUTPUT -test_expect_equal_file EXPECTED OUTPUT - -test_begin_subtest "Compare text vs. text0 for files" -notmuch search --format=text --output=files '*' | notmuch_search_sanitize > EXPECTED -notmuch search --format=text0 --output=files '*' | tr "\n\0" " \n" | notmuch_search_sanitize > OUTPUT -test_expect_equal_file EXPECTED OUTPUT - -test_begin_subtest "Compare text vs. text0 for tags" -notmuch search --format=text --output=tags '*' | notmuch_search_sanitize > EXPECTED -notmuch search --format=text0 --output=tags '*' | tr "\n\0" " \n" | notmuch_search_sanitize > OUTPUT -test_expect_equal_file EXPECTED OUTPUT - -test_done diff --git a/test/thread-naming b/test/thread-naming deleted file mode 100755 index 1a1a48f6..00000000 --- a/test/thread-naming +++ /dev/null @@ -1,180 +0,0 @@ -#!/usr/bin/env bash -test_description="naming of threads with changing subject" -. ./test-lib.sh - -test_begin_subtest "Initial thread name (oldest-first search)" -add_message '[subject]="thread-naming: Initial thread subject"' \ - '[date]="Fri, 05 Jan 2001 15:43:56 -0000"' -first=${gen_msg_cnt} -parent=${gen_msg_id} -add_message '[subject]="thread-naming: Older changed subject"' \ - '[date]="Sat, 06 Jan 2001 15:43:56 -0000"' \ - "[in-reply-to]=\<$parent\>" -add_message '[subject]="thread-naming: Newer changed subject"' \ - '[date]="Sun, 07 Jan 2001 15:43:56 -0000"' \ - "[in-reply-to]=\<$parent\>" -add_message '[subject]="thread-naming: Final thread subject"' \ - '[date]="Mon, 08 Jan 2001 15:43:56 -0000"' \ - "[in-reply-to]=\<$parent\>" -final=${gen_msg_id} -output=$(notmuch search --sort=oldest-first thread-naming and tag:inbox | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2001-01-05 [4/4] Notmuch Test Suite; thread-naming: Initial thread subject (inbox unread)" - -test_begin_subtest "Initial thread name (newest-first search)" -output=$(notmuch search --sort=newest-first thread-naming and tag:inbox | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2001-01-08 [4/4] Notmuch Test Suite; thread-naming: Final thread subject (inbox unread)" - -# Remove oldest and newest messages from search results -notmuch tag -inbox id:$parent or id:$final - -test_begin_subtest "Changed thread name (oldest-first search)" -output=$(notmuch search --sort=oldest-first thread-naming and tag:inbox | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2001-01-06 [2/4] Notmuch Test Suite; thread-naming: Older changed subject (inbox unread)" - -test_begin_subtest "Changed thread name (newest-first search)" -output=$(notmuch search --sort=newest-first thread-naming and tag:inbox | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2001-01-07 [2/4] Notmuch Test Suite; thread-naming: Newer changed subject (inbox unread)" - -test_begin_subtest "Ignore added reply prefix (Re:)" -add_message '[subject]="Re: thread-naming: Initial thread subject"' \ - '[date]="Tue, 09 Jan 2001 15:43:45 -0000"' \ - "[in-reply-to]=\<$parent\>" -output=$(notmuch search --sort=newest-first thread-naming and tag:inbox | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2001-01-09 [3/5] Notmuch Test Suite; thread-naming: Initial thread subject (inbox unread)" - -test_begin_subtest "Ignore added reply prefix (Aw:)" -add_message '[subject]="Aw: thread-naming: Initial thread subject"' \ - '[date]="Wed, 10 Jan 2001 15:43:45 -0000"' \ - "[in-reply-to]=\<$parent\>" -output=$(notmuch search --sort=newest-first thread-naming and tag:inbox | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2001-01-10 [4/6] Notmuch Test Suite; thread-naming: Initial thread subject (inbox unread)" - -test_begin_subtest "Ignore added reply prefix (Vs:)" -add_message '[subject]="Vs: thread-naming: Initial thread subject"' \ - '[date]="Thu, 11 Jan 2001 15:43:45 -0000"' \ - "[in-reply-to]=\<$parent\>" -output=$(notmuch search --sort=newest-first thread-naming and tag:inbox | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2001-01-11 [5/7] Notmuch Test Suite; thread-naming: Initial thread subject (inbox unread)" - -test_begin_subtest "Ignore added reply prefix (Sv:)" -add_message '[subject]="Sv: thread-naming: Initial thread subject"' \ - '[date]="Fri, 12 Jan 2001 15:43:45 -0000"' \ - "[in-reply-to]=\<$parent\>" -output=$(notmuch search --sort=newest-first thread-naming and tag:inbox | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2001-01-12 [6/8] Notmuch Test Suite; thread-naming: Initial thread subject (inbox unread)" - -test_begin_subtest 'Test order of messages in "notmuch show"' -output=$(notmuch show thread-naming | notmuch_show_sanitize) -test_expect_equal "$output" " message{ id:msg-$(printf "%03d" $first)@notmuch-test-suite depth:0 match:1 excluded:0 filename:/XXX/mail/msg-$(printf "%03d" $first) - header{ -Notmuch Test Suite (2001-01-05) (unread) -Subject: thread-naming: Initial thread subject -From: Notmuch Test Suite -To: Notmuch Test Suite -Date: Fri, 05 Jan 2001 15:43:56 +0000 - header} - body{ - part{ ID: 1, Content-type: text/plain -This is just a test message (#$first) - part} - body} - message} - message{ id:msg-$(printf "%03d" $((first + 1)))@notmuch-test-suite depth:1 match:1 excluded:0 filename:/XXX/mail/msg-$(printf "%03d" $((first + 1))) - header{ -Notmuch Test Suite (2001-01-06) (inbox unread) -Subject: thread-naming: Older changed subject -From: Notmuch Test Suite -To: Notmuch Test Suite -Date: Sat, 06 Jan 2001 15:43:56 +0000 - header} - body{ - part{ ID: 1, Content-type: text/plain -This is just a test message (#$((first + 1))) - part} - body} - message} - message{ id:msg-$(printf "%03d" $((first + 2)))@notmuch-test-suite depth:1 match:1 excluded:0 filename:/XXX/mail/msg-$(printf "%03d" $((first + 2))) - header{ -Notmuch Test Suite (2001-01-07) (inbox unread) -Subject: thread-naming: Newer changed subject -From: Notmuch Test Suite -To: Notmuch Test Suite -Date: Sun, 07 Jan 2001 15:43:56 +0000 - header} - body{ - part{ ID: 1, Content-type: text/plain -This is just a test message (#$((first + 2))) - part} - body} - message} - message{ id:msg-$(printf "%03d" $((first + 3)))@notmuch-test-suite depth:1 match:1 excluded:0 filename:/XXX/mail/msg-$(printf "%03d" $((first + 3))) - header{ -Notmuch Test Suite (2001-01-08) (unread) -Subject: thread-naming: Final thread subject -From: Notmuch Test Suite -To: Notmuch Test Suite -Date: Mon, 08 Jan 2001 15:43:56 +0000 - header} - body{ - part{ ID: 1, Content-type: text/plain -This is just a test message (#$((first + 3))) - part} - body} - message} - message{ id:msg-$(printf "%03d" $((first + 4)))@notmuch-test-suite depth:1 match:1 excluded:0 filename:/XXX/mail/msg-$(printf "%03d" $((first + 4))) - header{ -Notmuch Test Suite (2001-01-09) (inbox unread) -Subject: Re: thread-naming: Initial thread subject -From: Notmuch Test Suite -To: Notmuch Test Suite -Date: Tue, 09 Jan 2001 15:43:45 +0000 - header} - body{ - part{ ID: 1, Content-type: text/plain -This is just a test message (#$((first + 4))) - part} - body} - message} - message{ id:msg-$(printf "%03d" $((first + 5)))@notmuch-test-suite depth:1 match:1 excluded:0 filename:/XXX/mail/msg-$(printf "%03d" $((first + 5))) - header{ -Notmuch Test Suite (2001-01-10) (inbox unread) -Subject: Aw: thread-naming: Initial thread subject -From: Notmuch Test Suite -To: Notmuch Test Suite -Date: Wed, 10 Jan 2001 15:43:45 +0000 - header} - body{ - part{ ID: 1, Content-type: text/plain -This is just a test message (#$((first + 5))) - part} - body} - message} - message{ id:msg-$(printf "%03d" $((first + 6)))@notmuch-test-suite depth:1 match:1 excluded:0 filename:/XXX/mail/msg-$(printf "%03d" $((first + 6))) - header{ -Notmuch Test Suite (2001-01-11) (inbox unread) -Subject: Vs: thread-naming: Initial thread subject -From: Notmuch Test Suite -To: Notmuch Test Suite -Date: Thu, 11 Jan 2001 15:43:45 +0000 - header} - body{ - part{ ID: 1, Content-type: text/plain -This is just a test message (#$((first + 6))) - part} - body} - message} - message{ id:msg-$(printf "%03d" $((first + 7)))@notmuch-test-suite depth:1 match:1 excluded:0 filename:/XXX/mail/msg-$(printf "%03d" $((first + 7))) - header{ -Notmuch Test Suite (2001-01-12) (inbox unread) -Subject: Sv: thread-naming: Initial thread subject -From: Notmuch Test Suite -To: Notmuch Test Suite -Date: Fri, 12 Jan 2001 15:43:45 +0000 - header} - body{ - part{ ID: 1, Content-type: text/plain -This is just a test message (#$((first + 7))) - part} - body} - message}" -test_done diff --git a/test/thread-order b/test/thread-order deleted file mode 100755 index 6c3a4b3f..00000000 --- a/test/thread-order +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env bash -test_description="threading when messages received out of order" -. ./test-lib.sh - -test_begin_subtest "Adding initial child message" -generate_message [body]=foo "[in-reply-to]=\" [subject]=brokenthreadtest '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' -output=$(NOTMUCH_NEW) -test_expect_equal "$output" "Added 1 new message to the database." - -test_begin_subtest "Searching returns the message" -output=$(notmuch search foo | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; brokenthreadtest (inbox unread)" - -test_begin_subtest "Adding second child message" -generate_message [body]=foo "[in-reply-to]=\" [subject]=brokenthreadtest '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' -output=$(NOTMUCH_NEW) -test_expect_equal "$output" "Added 1 new message to the database." - -test_begin_subtest "Searching returns both messages in one thread" -output=$(notmuch search foo | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2000-01-01 [2/2] Notmuch Test Suite; brokenthreadtest (inbox unread)" - -test_begin_subtest "Adding parent message" -generate_message [body]=foo [id]=parent-id [subject]=brokenthreadtest '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' -output=$(NOTMUCH_NEW) -test_expect_equal "$output" "Added 1 new message to the database." - -test_begin_subtest "Searching returns all three messages in one thread" -output=$(notmuch search foo | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2000-01-01 [3/3] Notmuch Test Suite; brokenthreadtest (inbox unread)" - -test_done diff --git a/test/thread-replies b/test/thread-replies deleted file mode 100755 index eeb70d06..00000000 --- a/test/thread-replies +++ /dev/null @@ -1,141 +0,0 @@ -#!/usr/bin/env bash -# -# Copyright (c) 2013 Aaron Ecay -# - -test_description='test of proper handling of in-reply-to and references headers' - -# This test makes sure that the thread structure in the notmuch -# database is constructed properly, even in the presence of -# non-RFC-compliant headers' - -. ./test-lib.sh - -test_begin_subtest "Use References when In-Reply-To is broken" -add_message '[id]="foo@one.com"' \ - '[subject]=one' -add_message '[in-reply-to]="mumble"' \ - '[references]=""' \ - '[subject]="Re: one"' -output=$(notmuch show --format=json 'subject:one' | notmuch_json_show_sanitize) -expected='[[[{"id": "foo@one.com", - "match": true, - "excluded": false, - "filename": "YYYYY", - "timestamp": 978709437, - "date_relative": "2001-01-05", - "tags": ["inbox", "unread"], - "headers": {"Subject": "one", - "From": "Notmuch Test Suite ", - "To": "Notmuch Test Suite ", - "Date": "Fri, 05 Jan 2001 15:43:57 +0000"}, - "body": [{"id": 1, - "content-type": "text/plain", - "content": "This is just a test message (#1)\n"}]}, - [[{"id": "msg-002@notmuch-test-suite", - "match": true, "excluded": false, - "filename": "YYYYY", - "timestamp": 978709437, "date_relative": "2001-01-05", - "tags": ["inbox", "unread"], "headers": {"Subject": "Re: one", - "From": "Notmuch Test Suite ", - "To": "Notmuch Test Suite ", - "Date": "Fri, 05 Jan 2001 15:43:57 +0000"}, - "body": [{"id": 1, "content-type": "text/plain", - "content": "This is just a test message (#2)\n"}]}, []]]]]]' -expected=`echo "$expected" | notmuch_json_show_sanitize` -test_expect_equal_json "$output" "$expected" - -test_begin_subtest "Prefer References to In-Reply-To" -add_message '[id]="foo@two.com"' \ - '[subject]=two' -add_message '[in-reply-to]=""' \ - '[references]=""' \ - '[subject]="Re: two"' -output=$(notmuch show --format=json 'subject:two' | notmuch_json_show_sanitize) -expected='[[[{"id": "foo@two.com", - "match": true, "excluded": false, - "filename": "YYYYY", - "timestamp": 978709437, "date_relative": "2001-01-05", "tags": ["inbox", "unread"], - "headers": {"Subject": "two", - "From": "Notmuch Test Suite ", - "To": "Notmuch Test Suite ", - "Date": "Fri, 05 Jan 2001 15:43:57 +0000"}, - "body": [{"id": 1, "content-type": "text/plain", - "content": "This is just a test message (#3)\n"}]}, - [[{"id": "msg-004@notmuch-test-suite", "match": true, "excluded": false, - "filename": "YYYYY", - "timestamp": 978709437, "date_relative": "2001-01-05", "tags": ["inbox", "unread"], - "headers": {"Subject": "Re: two", - "From": "Notmuch Test Suite ", - "To": "Notmuch Test Suite ", - "Date": "Fri, 05 Jan 2001 15:43:57 +0000"}, - "body": [{"id": 1, - "content-type": "text/plain", "content": "This is just a test message (#4)\n"}]}, - []]]]]]' -expected=`echo "$expected" | notmuch_json_show_sanitize` -test_expect_equal_json "$output" "$expected" - -test_begin_subtest "Use In-Reply-To when no References" -add_message '[id]="foo@three.com"' \ - '[subject]="three"' -add_message '[in-reply-to]=""' \ - '[subject]="Re: three"' -output=$(notmuch show --format=json 'subject:three' | notmuch_json_show_sanitize) -expected='[[[{"id": "foo@three.com", "match": true, "excluded": false, - "filename": "YYYYY", - "timestamp": 978709437, "date_relative": "2001-01-05", "tags": ["inbox", "unread"], - "headers": {"Subject": "three", - "From": "Notmuch Test Suite ", - "To": "Notmuch Test Suite ", - "Date": "Fri, 05 Jan 2001 15:43:57 +0000"}, "body": [{"id": 1, - "content-type": "text/plain", "content": "This is just a test message (#5)\n"}]}, - [[{"id": "msg-006@notmuch-test-suite", "match": true, "excluded": false, - "filename": "YYYYY", - "timestamp": 978709437, "date_relative": "2001-01-05", "tags": ["inbox", "unread"], - "headers": {"Subject": "Re: three", - "From": "Notmuch Test Suite ", - "To": "Notmuch Test Suite ", - "Date": "Fri, 05 Jan 2001 15:43:57 +0000"}, "body": [{"id": 1, - "content-type": "text/plain", "content": "This is just a test message (#6)\n"}]}, - []]]]]]' -expected=`echo "$expected" | notmuch_json_show_sanitize` -test_expect_equal_json "$output" "$expected" - -test_begin_subtest "Use last Reference" -add_message '[id]="foo@four.com"' \ - '[subject]="four"' -add_message '[id]="bar@four.com"' \ - '[subject]="not-four"' -add_message '[in-reply-to]=""' \ - '[references]=" "' \ - '[subject]="neither"' -output=$(notmuch show --format=json 'subject:four' | notmuch_json_show_sanitize) -expected='[[[{"id": "foo@four.com", "match": true, "excluded": false, - "filename": "YYYYY", - "timestamp": 978709437, "date_relative": "2001-01-05", "tags": ["inbox", "unread"], - "headers": {"Subject": "four", - "From": "Notmuch Test Suite ", - "To": "Notmuch Test Suite ", - "Date": "Fri, 05 Jan 2001 15:43:57 +0000"}, "body": [{"id": 1, - "content-type": "text/plain", "content": "This is just a test message (#7)\n"}]}, - [[{"id": "msg-009@notmuch-test-suite", "match": false, "excluded": false, - "filename": "YYYYY", - "timestamp": 978709437, "date_relative": "2001-01-05", "tags": ["inbox", "unread"], - "headers": {"Subject": "neither", - "From": "Notmuch Test Suite ", - "To": "Notmuch Test Suite ", - "Date": "Fri, 05 Jan 2001 15:43:57 +0000"}, "body": [{"id": 1, - "content-type": "text/plain", "content": "This is just a test message (#9)\n"}]}, - []]]]], [[{"id": "bar@four.com", "match": true, "excluded": false, - "filename": "YYYYY", - "timestamp": 978709437, "date_relative": "2001-01-05", "tags": ["inbox", "unread"], - "headers": {"Subject": "not-four", - "From": "Notmuch Test Suite ", - "To": "Notmuch Test Suite ", - "Date": "Fri, 05 Jan 2001 15:43:57 +0000"}, "body": [{"id": 1, - "content-type": "text/plain", "content": "This is just a test message (#8)\n"}]}, []]]]' -expected=`echo "$expected" | notmuch_json_show_sanitize` -test_expect_equal_json "$output" "$expected" - - -test_done diff --git a/test/tree.expected-output/notmuch-tree-single-thread b/test/tree.expected-output/notmuch-tree-single-thread index c9e5ef82..2285d10e 100644 --- a/test/tree.expected-output/notmuch-tree-single-thread +++ b/test/tree.expected-output/notmuch-tree-single-thread @@ -1,6 +1,6 @@ 2009-11-17 Mikhail Gusarov ┬►[notmuch] [PATCH 1/2] Close message file after parsing message headers (inbox) - 2009-11-17 Mikhail Gusarov ├─►[notmuch] [PATCH 2/2] Include to get uint32_t in C++ file with gcc 4.4 (inbox, unread) - 2009-11-17 Carl Worth ╰┬►[notmuch] [PATCH 1/2] Close message file after parsing message headers (inbox, unread) - 2009-11-17 Keith Packard ╰┬► ... (inbox, unread) - 2009-11-18 Carl Worth ╰─► ... (inbox, unread) + 2009-11-17 Mikhail Gusarov ├─►[notmuch] [PATCH 2/2] Include to get uint32_t in C++ file with gcc 4.4 (inbox unread) + 2009-11-17 Carl Worth ╰┬►[notmuch] [PATCH 1/2] Close message file after parsing message headers (inbox unread) + 2009-11-17 Keith Packard ╰┬► ... (inbox unread) + 2009-11-18 Carl Worth ╰─► ... (inbox unread) End of search results. diff --git a/test/tree.expected-output/notmuch-tree-tag-inbox b/test/tree.expected-output/notmuch-tree-tag-inbox index 484141ec..f28d4856 100644 --- a/test/tree.expected-output/notmuch-tree-tag-inbox +++ b/test/tree.expected-output/notmuch-tree-tag-inbox @@ -1,53 +1,53 @@ - 2010-12-29 François Boulogne ─►[aur-general] Guidelines: cp, mkdir vs install (inbox, unread) - 2010-12-16 Olivier Berger ─►Essai accentué (inbox, unread) - 2009-11-18 Chris Wilson ─►[notmuch] [PATCH 1/2] Makefile: evaluate pkg-config once (inbox, unread) - 2009-11-18 Alex Botero-Lowry ┬►[notmuch] [PATCH] Error out if no query is supplied to search instead of going into an infinite loop (attachment, inbox, unread) - 2009-11-18 Carl Worth ╰─►[notmuch] [PATCH] Error out if no query is supplied to search instead of going into an infinite loop (inbox, unread) - 2009-11-17 Ingmar Vanhassel ┬►[notmuch] [PATCH] Typsos (inbox, unread) - 2009-11-18 Carl Worth ╰─► ... (inbox, unread) - 2009-11-17 Adrian Perez de Cast ┬►[notmuch] Introducing myself (inbox, signed, unread) - 2009-11-18 Keith Packard ├─► ... (inbox, unread) - 2009-11-18 Carl Worth ╰─► ... (inbox, unread) - 2009-11-17 Israel Herraiz ┬►[notmuch] New to the list (inbox, unread) - 2009-11-18 Keith Packard ├─► ... (inbox, unread) - 2009-11-18 Carl Worth ╰─► ... (inbox, unread) - 2009-11-17 Jan Janak ┬►[notmuch] What a great idea! (inbox, unread) - 2009-11-17 Jan Janak ├─► ... (inbox, unread) - 2009-11-18 Carl Worth ╰─► ... (inbox, unread) - 2009-11-17 Jan Janak ┬►[notmuch] [PATCH] Older versions of install do not support -C. (inbox, unread) - 2009-11-18 Carl Worth ╰─► ... (inbox, unread) - 2009-11-17 Aron Griffis ┬►[notmuch] archive (inbox, unread) - 2009-11-18 Keith Packard ╰┬► ... (inbox, unread) - 2009-11-18 Carl Worth ╰─► ... (inbox, unread) - 2009-11-17 Keith Packard ┬►[notmuch] [PATCH] Make notmuch-show 'X' (and 'x') commands remove inbox (and unread) tags (inbox, unread) - 2009-11-18 Carl Worth ╰─►[notmuch] [PATCH] Make notmuch-show 'X' (and 'x') commands remove inbox (and unread) tags (inbox, unread) - 2009-11-17 Lars Kellogg-Stedman ┬►[notmuch] Working with Maildir storage? (inbox, signed, unread) - 2009-11-17 Mikhail Gusarov ├┬► ... (inbox, signed, unread) - 2009-11-17 Lars Kellogg-Stedman │╰┬► ... (inbox, signed, unread) - 2009-11-17 Mikhail Gusarov │ ├─► ... (inbox, unread) - 2009-11-17 Keith Packard │ ╰┬► ... (inbox, unread) - 2009-11-18 Lars Kellogg-Stedman │ ╰─► ... (inbox, signed, unread) - 2009-11-18 Carl Worth ╰─► ... (inbox, unread) - 2009-11-17 Mikhail Gusarov ┬►[notmuch] [PATCH 1/2] Close message file after parsing message headers (inbox, unread) - 2009-11-17 Mikhail Gusarov ├─►[notmuch] [PATCH 2/2] Include to get uint32_t in C++ file with gcc 4.4 (inbox, unread) - 2009-11-17 Carl Worth ╰┬►[notmuch] [PATCH 1/2] Close message file after parsing message headers (inbox, unread) - 2009-11-17 Keith Packard ╰┬► ... (inbox, unread) - 2009-11-18 Carl Worth ╰─► ... (inbox, unread) - 2009-11-18 Keith Packard ┬►[notmuch] [PATCH] Create a default notmuch-show-hook that highlights URLs and uses word-wrap (inbox, unread) - 2009-11-18 Alexander Botero-Low ╰─►[notmuch] [PATCH] Create a default notmuch-show-hook that highlights URLs and uses word-wrap (inbox, unread) - 2009-11-18 Alexander Botero-Low ─►[notmuch] request for pull (inbox, unread) - 2009-11-18 Jjgod Jiang ┬►[notmuch] Mac OS X/Darwin compatibility issues (inbox, unread) - 2009-11-18 Alexander Botero-Low ╰┬► ... (inbox, unread) - 2009-11-18 Jjgod Jiang ╰┬► ... (inbox, unread) - 2009-11-18 Alexander Botero-Low ╰─► ... (inbox, unread) - 2009-11-18 Rolland Santimano ─►[notmuch] Link to mailing list archives ? (inbox, unread) - 2009-11-18 Jan Janak ─►[notmuch] [PATCH] notmuch new: Support for conversion of spool subdirectories into tags (inbox, unread) - 2009-11-18 Stewart Smith ─►[notmuch] [PATCH] count_files: sort directory in inode order before statting (inbox, unread) - 2009-11-18 Stewart Smith ─►[notmuch] [PATCH 2/2] Read mail directory in inode number order (inbox, unread) - 2009-11-18 Stewart Smith ─►[notmuch] [PATCH] Fix linking with gcc to use g++ to link in C++ libs. (inbox, unread) - 2009-11-18 Lars Kellogg-Stedman ┬►[notmuch] "notmuch help" outputs to stderr? (attachment, inbox, signed, unread) - 2009-11-18 Lars Kellogg-Stedman ╰─► ... (attachment, inbox, signed, unread) - 2009-11-17 Mikhail Gusarov ─►[notmuch] [PATCH] Handle rename of message file (inbox, unread) - 2009-11-17 Alex Botero-Lowry ┬►[notmuch] preliminary FreeBSD support (attachment, inbox, unread) - 2009-11-17 Carl Worth ╰─► ... (inbox, unread) + 2010-12-29 François Boulogne ─►[aur-general] Guidelines: cp, mkdir vs install (inbox unread) + 2010-12-16 Olivier Berger ─►Essai accentué (inbox unread) + 2009-11-18 Chris Wilson ─►[notmuch] [PATCH 1/2] Makefile: evaluate pkg-config once (inbox unread) + 2009-11-18 Alex Botero-Lowry ┬►[notmuch] [PATCH] Error out if no query is supplied to search instead of going into an infinite loop (attachment inbox unread) + 2009-11-18 Carl Worth ╰─►[notmuch] [PATCH] Error out if no query is supplied to search instead of going into an infinite loop (inbox unread) + 2009-11-17 Ingmar Vanhassel ┬►[notmuch] [PATCH] Typsos (inbox unread) + 2009-11-18 Carl Worth ╰─► ... (inbox unread) + 2009-11-17 Adrian Perez de Cast ┬►[notmuch] Introducing myself (inbox signed unread) + 2009-11-18 Keith Packard ├─► ... (inbox unread) + 2009-11-18 Carl Worth ╰─► ... (inbox unread) + 2009-11-17 Israel Herraiz ┬►[notmuch] New to the list (inbox unread) + 2009-11-18 Keith Packard ├─► ... (inbox unread) + 2009-11-18 Carl Worth ╰─► ... (inbox unread) + 2009-11-17 Jan Janak ┬►[notmuch] What a great idea! (inbox unread) + 2009-11-17 Jan Janak ├─► ... (inbox unread) + 2009-11-18 Carl Worth ╰─► ... (inbox unread) + 2009-11-17 Jan Janak ┬►[notmuch] [PATCH] Older versions of install do not support -C. (inbox unread) + 2009-11-18 Carl Worth ╰─► ... (inbox unread) + 2009-11-17 Aron Griffis ┬►[notmuch] archive (inbox unread) + 2009-11-18 Keith Packard ╰┬► ... (inbox unread) + 2009-11-18 Carl Worth ╰─► ... (inbox unread) + 2009-11-17 Keith Packard ┬►[notmuch] [PATCH] Make notmuch-show 'X' (and 'x') commands remove inbox (and unread) tags (inbox unread) + 2009-11-18 Carl Worth ╰─►[notmuch] [PATCH] Make notmuch-show 'X' (and 'x') commands remove inbox (and unread) tags (inbox unread) + 2009-11-17 Lars Kellogg-Stedman ┬►[notmuch] Working with Maildir storage? (inbox signed unread) + 2009-11-17 Mikhail Gusarov ├┬► ... (inbox signed unread) + 2009-11-17 Lars Kellogg-Stedman │╰┬► ... (inbox signed unread) + 2009-11-17 Mikhail Gusarov │ ├─► ... (inbox unread) + 2009-11-17 Keith Packard │ ╰┬► ... (inbox unread) + 2009-11-18 Lars Kellogg-Stedman │ ╰─► ... (inbox signed unread) + 2009-11-18 Carl Worth ╰─► ... (inbox unread) + 2009-11-17 Mikhail Gusarov ┬►[notmuch] [PATCH 1/2] Close message file after parsing message headers (inbox unread) + 2009-11-17 Mikhail Gusarov ├─►[notmuch] [PATCH 2/2] Include to get uint32_t in C++ file with gcc 4.4 (inbox unread) + 2009-11-17 Carl Worth ╰┬►[notmuch] [PATCH 1/2] Close message file after parsing message headers (inbox unread) + 2009-11-17 Keith Packard ╰┬► ... (inbox unread) + 2009-11-18 Carl Worth ╰─► ... (inbox unread) + 2009-11-18 Keith Packard ┬►[notmuch] [PATCH] Create a default notmuch-show-hook that highlights URLs and uses word-wrap (inbox unread) + 2009-11-18 Alexander Botero-Low ╰─►[notmuch] [PATCH] Create a default notmuch-show-hook that highlights URLs and uses word-wrap (inbox unread) + 2009-11-18 Alexander Botero-Low ─►[notmuch] request for pull (inbox unread) + 2009-11-18 Jjgod Jiang ┬►[notmuch] Mac OS X/Darwin compatibility issues (inbox unread) + 2009-11-18 Alexander Botero-Low ╰┬► ... (inbox unread) + 2009-11-18 Jjgod Jiang ╰┬► ... (inbox unread) + 2009-11-18 Alexander Botero-Low ╰─► ... (inbox unread) + 2009-11-18 Rolland Santimano ─►[notmuch] Link to mailing list archives ? (inbox unread) + 2009-11-18 Jan Janak ─►[notmuch] [PATCH] notmuch new: Support for conversion of spool subdirectories into tags (inbox unread) + 2009-11-18 Stewart Smith ─►[notmuch] [PATCH] count_files: sort directory in inode order before statting (inbox unread) + 2009-11-18 Stewart Smith ─►[notmuch] [PATCH 2/2] Read mail directory in inode number order (inbox unread) + 2009-11-18 Stewart Smith ─►[notmuch] [PATCH] Fix linking with gcc to use g++ to link in C++ libs. (inbox unread) + 2009-11-18 Lars Kellogg-Stedman ┬►[notmuch] "notmuch help" outputs to stderr? (attachment inbox signed unread) + 2009-11-18 Lars Kellogg-Stedman ╰─► ... (attachment inbox signed unread) + 2009-11-17 Mikhail Gusarov ─►[notmuch] [PATCH] Handle rename of message file (inbox unread) + 2009-11-17 Alex Botero-Lowry ┬►[notmuch] preliminary FreeBSD support (attachment inbox unread) + 2009-11-17 Carl Worth ╰─► ... (inbox unread) End of search results. diff --git a/test/tree.expected-output/notmuch-tree-tag-inbox-tagged b/test/tree.expected-output/notmuch-tree-tag-inbox-tagged index 1f75a34b..428c0ae8 100644 --- a/test/tree.expected-output/notmuch-tree-tag-inbox-tagged +++ b/test/tree.expected-output/notmuch-tree-tag-inbox-tagged @@ -1,53 +1,53 @@ - 2010-12-29 François Boulogne ─►[aur-general] Guidelines: cp, mkdir vs install (inbox, unread) - 2010-12-16 Olivier Berger ─►Essai accentué (inbox, test_tag, unread) - 2009-11-18 Chris Wilson ─►[notmuch] [PATCH 1/2] Makefile: evaluate pkg-config once (inbox, unread) - 2009-11-18 Alex Botero-Lowry ┬►[notmuch] [PATCH] Error out if no query is supplied to search instead of going into an infinite loop (attachment, inbox, unread) - 2009-11-18 Carl Worth ╰─►[notmuch] [PATCH] Error out if no query is supplied to search instead of going into an infinite loop (inbox, unread) - 2009-11-17 Ingmar Vanhassel ┬►[notmuch] [PATCH] Typsos (inbox, unread) - 2009-11-18 Carl Worth ╰─► ... (inbox, unread) - 2009-11-17 Adrian Perez de Cast ┬►[notmuch] Introducing myself (inbox, signed, unread) - 2009-11-18 Keith Packard ├─► ... (inbox, unread) - 2009-11-18 Carl Worth ╰─► ... (inbox, unread) - 2009-11-17 Israel Herraiz ┬►[notmuch] New to the list (inbox, unread) - 2009-11-18 Keith Packard ├─► ... (inbox, unread) - 2009-11-18 Carl Worth ╰─► ... (inbox, unread) - 2009-11-17 Jan Janak ┬►[notmuch] What a great idea! (inbox, unread) - 2009-11-17 Jan Janak ├─► ... (inbox, unread) - 2009-11-18 Carl Worth ╰─► ... (inbox, unread) - 2009-11-17 Jan Janak ┬►[notmuch] [PATCH] Older versions of install do not support -C. (inbox, unread) - 2009-11-18 Carl Worth ╰─► ... (inbox, unread) - 2009-11-17 Aron Griffis ┬►[notmuch] archive (inbox, unread) - 2009-11-18 Keith Packard ╰┬► ... (inbox, unread) - 2009-11-18 Carl Worth ╰─► ... (inbox, unread) - 2009-11-17 Keith Packard ┬►[notmuch] [PATCH] Make notmuch-show 'X' (and 'x') commands remove inbox (and unread) tags (inbox, unread) - 2009-11-18 Carl Worth ╰─►[notmuch] [PATCH] Make notmuch-show 'X' (and 'x') commands remove inbox (and unread) tags (inbox, unread) - 2009-11-17 Lars Kellogg-Stedman ┬►[notmuch] Working with Maildir storage? (inbox, signed, unread) - 2009-11-17 Mikhail Gusarov ├┬► ... (inbox, signed, unread) - 2009-11-17 Lars Kellogg-Stedman │╰┬► ... (inbox, signed, unread) - 2009-11-17 Mikhail Gusarov │ ├─► ... (inbox, unread) - 2009-11-17 Keith Packard │ ╰┬► ... (inbox, unread) - 2009-11-18 Lars Kellogg-Stedman │ ╰─► ... (inbox, signed, unread) - 2009-11-18 Carl Worth ╰─► ... (inbox, unread) - 2009-11-17 Mikhail Gusarov ┬►[notmuch] [PATCH 1/2] Close message file after parsing message headers (inbox, unread) - 2009-11-17 Mikhail Gusarov ├─►[notmuch] [PATCH 2/2] Include to get uint32_t in C++ file with gcc 4.4 (inbox, unread) - 2009-11-17 Carl Worth ╰┬►[notmuch] [PATCH 1/2] Close message file after parsing message headers (inbox, unread) - 2009-11-17 Keith Packard ╰┬► ... (inbox, unread) - 2009-11-18 Carl Worth ╰─► ... (inbox, unread) - 2009-11-18 Keith Packard ┬►[notmuch] [PATCH] Create a default notmuch-show-hook that highlights URLs and uses word-wrap (inbox, unread) - 2009-11-18 Alexander Botero-Low ╰─►[notmuch] [PATCH] Create a default notmuch-show-hook that highlights URLs and uses word-wrap (inbox, unread) - 2009-11-18 Alexander Botero-Low ─►[notmuch] request for pull (inbox, unread) - 2009-11-18 Jjgod Jiang ┬►[notmuch] Mac OS X/Darwin compatibility issues (inbox, unread) - 2009-11-18 Alexander Botero-Low ╰┬► ... (inbox, unread) - 2009-11-18 Jjgod Jiang ╰┬► ... (inbox, unread) - 2009-11-18 Alexander Botero-Low ╰─► ... (inbox, unread) - 2009-11-18 Rolland Santimano ─►[notmuch] Link to mailing list archives ? (inbox, unread) - 2009-11-18 Jan Janak ─►[notmuch] [PATCH] notmuch new: Support for conversion of spool subdirectories into tags (inbox, unread) - 2009-11-18 Stewart Smith ─►[notmuch] [PATCH] count_files: sort directory in inode order before statting (inbox, unread) - 2009-11-18 Stewart Smith ─►[notmuch] [PATCH 2/2] Read mail directory in inode number order (inbox, unread) - 2009-11-18 Stewart Smith ─►[notmuch] [PATCH] Fix linking with gcc to use g++ to link in C++ libs. (inbox, unread) - 2009-11-18 Lars Kellogg-Stedman ┬►[notmuch] "notmuch help" outputs to stderr? (attachment, inbox, signed, unread) - 2009-11-18 Lars Kellogg-Stedman ╰─► ... (attachment, inbox, signed, unread) - 2009-11-17 Mikhail Gusarov ─►[notmuch] [PATCH] Handle rename of message file (inbox, unread) - 2009-11-17 Alex Botero-Lowry ┬►[notmuch] preliminary FreeBSD support (attachment, inbox, unread) - 2009-11-17 Carl Worth ╰─► ... (inbox, unread) + 2010-12-29 François Boulogne ─►[aur-general] Guidelines: cp, mkdir vs install (inbox unread) + 2010-12-16 Olivier Berger ─►Essai accentué (inbox test_tag unread) + 2009-11-18 Chris Wilson ─►[notmuch] [PATCH 1/2] Makefile: evaluate pkg-config once (inbox unread) + 2009-11-18 Alex Botero-Lowry ┬►[notmuch] [PATCH] Error out if no query is supplied to search instead of going into an infinite loop (attachment inbox unread) + 2009-11-18 Carl Worth ╰─►[notmuch] [PATCH] Error out if no query is supplied to search instead of going into an infinite loop (inbox unread) + 2009-11-17 Ingmar Vanhassel ┬►[notmuch] [PATCH] Typsos (inbox unread) + 2009-11-18 Carl Worth ╰─► ... (inbox unread) + 2009-11-17 Adrian Perez de Cast ┬►[notmuch] Introducing myself (inbox signed unread) + 2009-11-18 Keith Packard ├─► ... (inbox unread) + 2009-11-18 Carl Worth ╰─► ... (inbox unread) + 2009-11-17 Israel Herraiz ┬►[notmuch] New to the list (inbox unread) + 2009-11-18 Keith Packard ├─► ... (inbox unread) + 2009-11-18 Carl Worth ╰─► ... (inbox unread) + 2009-11-17 Jan Janak ┬►[notmuch] What a great idea! (inbox unread) + 2009-11-17 Jan Janak ├─► ... (inbox unread) + 2009-11-18 Carl Worth ╰─► ... (inbox unread) + 2009-11-17 Jan Janak ┬►[notmuch] [PATCH] Older versions of install do not support -C. (inbox unread) + 2009-11-18 Carl Worth ╰─► ... (inbox unread) + 2009-11-17 Aron Griffis ┬►[notmuch] archive (inbox unread) + 2009-11-18 Keith Packard ╰┬► ... (inbox unread) + 2009-11-18 Carl Worth ╰─► ... (inbox unread) + 2009-11-17 Keith Packard ┬►[notmuch] [PATCH] Make notmuch-show 'X' (and 'x') commands remove inbox (and unread) tags (inbox unread) + 2009-11-18 Carl Worth ╰─►[notmuch] [PATCH] Make notmuch-show 'X' (and 'x') commands remove inbox (and unread) tags (inbox unread) + 2009-11-17 Lars Kellogg-Stedman ┬►[notmuch] Working with Maildir storage? (inbox signed unread) + 2009-11-17 Mikhail Gusarov ├┬► ... (inbox signed unread) + 2009-11-17 Lars Kellogg-Stedman │╰┬► ... (inbox signed unread) + 2009-11-17 Mikhail Gusarov │ ├─► ... (inbox unread) + 2009-11-17 Keith Packard │ ╰┬► ... (inbox unread) + 2009-11-18 Lars Kellogg-Stedman │ ╰─► ... (inbox signed unread) + 2009-11-18 Carl Worth ╰─► ... (inbox unread) + 2009-11-17 Mikhail Gusarov ┬►[notmuch] [PATCH 1/2] Close message file after parsing message headers (inbox unread) + 2009-11-17 Mikhail Gusarov ├─►[notmuch] [PATCH 2/2] Include to get uint32_t in C++ file with gcc 4.4 (inbox unread) + 2009-11-17 Carl Worth ╰┬►[notmuch] [PATCH 1/2] Close message file after parsing message headers (inbox unread) + 2009-11-17 Keith Packard ╰┬► ... (inbox unread) + 2009-11-18 Carl Worth ╰─► ... (inbox unread) + 2009-11-18 Keith Packard ┬►[notmuch] [PATCH] Create a default notmuch-show-hook that highlights URLs and uses word-wrap (inbox unread) + 2009-11-18 Alexander Botero-Low ╰─►[notmuch] [PATCH] Create a default notmuch-show-hook that highlights URLs and uses word-wrap (inbox unread) + 2009-11-18 Alexander Botero-Low ─►[notmuch] request for pull (inbox unread) + 2009-11-18 Jjgod Jiang ┬►[notmuch] Mac OS X/Darwin compatibility issues (inbox unread) + 2009-11-18 Alexander Botero-Low ╰┬► ... (inbox unread) + 2009-11-18 Jjgod Jiang ╰┬► ... (inbox unread) + 2009-11-18 Alexander Botero-Low ╰─► ... (inbox unread) + 2009-11-18 Rolland Santimano ─►[notmuch] Link to mailing list archives ? (inbox unread) + 2009-11-18 Jan Janak ─►[notmuch] [PATCH] notmuch new: Support for conversion of spool subdirectories into tags (inbox unread) + 2009-11-18 Stewart Smith ─►[notmuch] [PATCH] count_files: sort directory in inode order before statting (inbox unread) + 2009-11-18 Stewart Smith ─►[notmuch] [PATCH 2/2] Read mail directory in inode number order (inbox unread) + 2009-11-18 Stewart Smith ─►[notmuch] [PATCH] Fix linking with gcc to use g++ to link in C++ libs. (inbox unread) + 2009-11-18 Lars Kellogg-Stedman ┬►[notmuch] "notmuch help" outputs to stderr? (attachment inbox signed unread) + 2009-11-18 Lars Kellogg-Stedman ╰─► ... (attachment inbox signed unread) + 2009-11-17 Mikhail Gusarov ─►[notmuch] [PATCH] Handle rename of message file (inbox unread) + 2009-11-17 Alex Botero-Lowry ┬►[notmuch] preliminary FreeBSD support (attachment inbox unread) + 2009-11-17 Carl Worth ╰─► ... (inbox unread) End of search results. diff --git a/test/tree.expected-output/notmuch-tree-tag-inbox-thread-tagged b/test/tree.expected-output/notmuch-tree-tag-inbox-thread-tagged index a7aba6e2..828c5251 100644 --- a/test/tree.expected-output/notmuch-tree-tag-inbox-thread-tagged +++ b/test/tree.expected-output/notmuch-tree-tag-inbox-thread-tagged @@ -1,53 +1,53 @@ - 2010-12-29 François Boulogne ─►[aur-general] Guidelines: cp, mkdir vs install (inbox, unread) - 2010-12-16 Olivier Berger ─►Essai accentué (inbox, unread) - 2009-11-18 Chris Wilson ─►[notmuch] [PATCH 1/2] Makefile: evaluate pkg-config once (inbox, unread) - 2009-11-18 Alex Botero-Lowry ┬►[notmuch] [PATCH] Error out if no query is supplied to search instead of going into an infinite loop (attachment, inbox, unread) - 2009-11-18 Carl Worth ╰─►[notmuch] [PATCH] Error out if no query is supplied to search instead of going into an infinite loop (inbox, unread) - 2009-11-17 Ingmar Vanhassel ┬►[notmuch] [PATCH] Typsos (inbox, unread) - 2009-11-18 Carl Worth ╰─► ... (inbox, unread) - 2009-11-17 Adrian Perez de Cast ┬►[notmuch] Introducing myself (inbox, signed, unread) - 2009-11-18 Keith Packard ├─► ... (inbox, unread) - 2009-11-18 Carl Worth ╰─► ... (inbox, unread) - 2009-11-17 Israel Herraiz ┬►[notmuch] New to the list (inbox, unread) - 2009-11-18 Keith Packard ├─► ... (inbox, unread) - 2009-11-18 Carl Worth ╰─► ... (inbox, unread) - 2009-11-17 Jan Janak ┬►[notmuch] What a great idea! (inbox, unread) - 2009-11-17 Jan Janak ├─► ... (inbox, unread) - 2009-11-18 Carl Worth ╰─► ... (inbox, unread) - 2009-11-17 Jan Janak ┬►[notmuch] [PATCH] Older versions of install do not support -C. (inbox, unread) - 2009-11-18 Carl Worth ╰─► ... (inbox, unread) - 2009-11-17 Aron Griffis ┬►[notmuch] archive (inbox, unread) - 2009-11-18 Keith Packard ╰┬► ... (inbox, unread) - 2009-11-18 Carl Worth ╰─► ... (inbox, unread) - 2009-11-17 Keith Packard ┬►[notmuch] [PATCH] Make notmuch-show 'X' (and 'x') commands remove inbox (and unread) tags (inbox, unread) - 2009-11-18 Carl Worth ╰─►[notmuch] [PATCH] Make notmuch-show 'X' (and 'x') commands remove inbox (and unread) tags (inbox, unread) - 2009-11-17 Lars Kellogg-Stedman ┬►[notmuch] Working with Maildir storage? (inbox, signed, test_thread_tag, unread) - 2009-11-17 Mikhail Gusarov ├┬► ... (inbox, signed, test_thread_tag, unread) - 2009-11-17 Lars Kellogg-Stedman │╰┬► ... (inbox, signed, test_thread_tag, unread) - 2009-11-17 Mikhail Gusarov │ ├─► ... (inbox, test_thread_tag, unread) - 2009-11-17 Keith Packard │ ╰┬► ... (inbox, test_thread_tag, unread) - 2009-11-18 Lars Kellogg-Stedman │ ╰─► ... (inbox, signed, test_thread_tag, unread) - 2009-11-18 Carl Worth ╰─► ... (inbox, test_thread_tag, unread) - 2009-11-17 Mikhail Gusarov ┬►[notmuch] [PATCH 1/2] Close message file after parsing message headers (inbox, unread) - 2009-11-17 Mikhail Gusarov ├─►[notmuch] [PATCH 2/2] Include to get uint32_t in C++ file with gcc 4.4 (inbox, unread) - 2009-11-17 Carl Worth ╰┬►[notmuch] [PATCH 1/2] Close message file after parsing message headers (inbox, unread) - 2009-11-17 Keith Packard ╰┬► ... (inbox, unread) - 2009-11-18 Carl Worth ╰─► ... (inbox, unread) - 2009-11-18 Keith Packard ┬►[notmuch] [PATCH] Create a default notmuch-show-hook that highlights URLs and uses word-wrap (inbox, unread) - 2009-11-18 Alexander Botero-Low ╰─►[notmuch] [PATCH] Create a default notmuch-show-hook that highlights URLs and uses word-wrap (inbox, unread) - 2009-11-18 Alexander Botero-Low ─►[notmuch] request for pull (inbox, unread) - 2009-11-18 Jjgod Jiang ┬►[notmuch] Mac OS X/Darwin compatibility issues (inbox, unread) - 2009-11-18 Alexander Botero-Low ╰┬► ... (inbox, unread) - 2009-11-18 Jjgod Jiang ╰┬► ... (inbox, unread) - 2009-11-18 Alexander Botero-Low ╰─► ... (inbox, unread) - 2009-11-18 Rolland Santimano ─►[notmuch] Link to mailing list archives ? (inbox, unread) - 2009-11-18 Jan Janak ─►[notmuch] [PATCH] notmuch new: Support for conversion of spool subdirectories into tags (inbox, unread) - 2009-11-18 Stewart Smith ─►[notmuch] [PATCH] count_files: sort directory in inode order before statting (inbox, unread) - 2009-11-18 Stewart Smith ─►[notmuch] [PATCH 2/2] Read mail directory in inode number order (inbox, unread) - 2009-11-18 Stewart Smith ─►[notmuch] [PATCH] Fix linking with gcc to use g++ to link in C++ libs. (inbox, unread) - 2009-11-18 Lars Kellogg-Stedman ┬►[notmuch] "notmuch help" outputs to stderr? (attachment, inbox, signed, unread) - 2009-11-18 Lars Kellogg-Stedman ╰─► ... (attachment, inbox, signed, unread) - 2009-11-17 Mikhail Gusarov ─►[notmuch] [PATCH] Handle rename of message file (inbox, unread) - 2009-11-17 Alex Botero-Lowry ┬►[notmuch] preliminary FreeBSD support (attachment, inbox, unread) - 2009-11-17 Carl Worth ╰─► ... (inbox, unread) + 2010-12-29 François Boulogne ─►[aur-general] Guidelines: cp, mkdir vs install (inbox unread) + 2010-12-16 Olivier Berger ─►Essai accentué (inbox unread) + 2009-11-18 Chris Wilson ─►[notmuch] [PATCH 1/2] Makefile: evaluate pkg-config once (inbox unread) + 2009-11-18 Alex Botero-Lowry ┬►[notmuch] [PATCH] Error out if no query is supplied to search instead of going into an infinite loop (attachment inbox unread) + 2009-11-18 Carl Worth ╰─►[notmuch] [PATCH] Error out if no query is supplied to search instead of going into an infinite loop (inbox unread) + 2009-11-17 Ingmar Vanhassel ┬►[notmuch] [PATCH] Typsos (inbox unread) + 2009-11-18 Carl Worth ╰─► ... (inbox unread) + 2009-11-17 Adrian Perez de Cast ┬►[notmuch] Introducing myself (inbox signed unread) + 2009-11-18 Keith Packard ├─► ... (inbox unread) + 2009-11-18 Carl Worth ╰─► ... (inbox unread) + 2009-11-17 Israel Herraiz ┬►[notmuch] New to the list (inbox unread) + 2009-11-18 Keith Packard ├─► ... (inbox unread) + 2009-11-18 Carl Worth ╰─► ... (inbox unread) + 2009-11-17 Jan Janak ┬►[notmuch] What a great idea! (inbox unread) + 2009-11-17 Jan Janak ├─► ... (inbox unread) + 2009-11-18 Carl Worth ╰─► ... (inbox unread) + 2009-11-17 Jan Janak ┬►[notmuch] [PATCH] Older versions of install do not support -C. (inbox unread) + 2009-11-18 Carl Worth ╰─► ... (inbox unread) + 2009-11-17 Aron Griffis ┬►[notmuch] archive (inbox unread) + 2009-11-18 Keith Packard ╰┬► ... (inbox unread) + 2009-11-18 Carl Worth ╰─► ... (inbox unread) + 2009-11-17 Keith Packard ┬►[notmuch] [PATCH] Make notmuch-show 'X' (and 'x') commands remove inbox (and unread) tags (inbox unread) + 2009-11-18 Carl Worth ╰─►[notmuch] [PATCH] Make notmuch-show 'X' (and 'x') commands remove inbox (and unread) tags (inbox unread) + 2009-11-17 Lars Kellogg-Stedman ┬►[notmuch] Working with Maildir storage? (inbox signed test_thread_tag unread) + 2009-11-17 Mikhail Gusarov ├┬► ... (inbox signed test_thread_tag unread) + 2009-11-17 Lars Kellogg-Stedman │╰┬► ... (inbox signed test_thread_tag unread) + 2009-11-17 Mikhail Gusarov │ ├─► ... (inbox test_thread_tag unread) + 2009-11-17 Keith Packard │ ╰┬► ... (inbox test_thread_tag unread) + 2009-11-18 Lars Kellogg-Stedman │ ╰─► ... (inbox signed test_thread_tag unread) + 2009-11-18 Carl Worth ╰─► ... (inbox test_thread_tag unread) + 2009-11-17 Mikhail Gusarov ┬►[notmuch] [PATCH 1/2] Close message file after parsing message headers (inbox unread) + 2009-11-17 Mikhail Gusarov ├─►[notmuch] [PATCH 2/2] Include to get uint32_t in C++ file with gcc 4.4 (inbox unread) + 2009-11-17 Carl Worth ╰┬►[notmuch] [PATCH 1/2] Close message file after parsing message headers (inbox unread) + 2009-11-17 Keith Packard ╰┬► ... (inbox unread) + 2009-11-18 Carl Worth ╰─► ... (inbox unread) + 2009-11-18 Keith Packard ┬►[notmuch] [PATCH] Create a default notmuch-show-hook that highlights URLs and uses word-wrap (inbox unread) + 2009-11-18 Alexander Botero-Low ╰─►[notmuch] [PATCH] Create a default notmuch-show-hook that highlights URLs and uses word-wrap (inbox unread) + 2009-11-18 Alexander Botero-Low ─►[notmuch] request for pull (inbox unread) + 2009-11-18 Jjgod Jiang ┬►[notmuch] Mac OS X/Darwin compatibility issues (inbox unread) + 2009-11-18 Alexander Botero-Low ╰┬► ... (inbox unread) + 2009-11-18 Jjgod Jiang ╰┬► ... (inbox unread) + 2009-11-18 Alexander Botero-Low ╰─► ... (inbox unread) + 2009-11-18 Rolland Santimano ─►[notmuch] Link to mailing list archives ? (inbox unread) + 2009-11-18 Jan Janak ─►[notmuch] [PATCH] notmuch new: Support for conversion of spool subdirectories into tags (inbox unread) + 2009-11-18 Stewart Smith ─►[notmuch] [PATCH] count_files: sort directory in inode order before statting (inbox unread) + 2009-11-18 Stewart Smith ─►[notmuch] [PATCH 2/2] Read mail directory in inode number order (inbox unread) + 2009-11-18 Stewart Smith ─►[notmuch] [PATCH] Fix linking with gcc to use g++ to link in C++ libs. (inbox unread) + 2009-11-18 Lars Kellogg-Stedman ┬►[notmuch] "notmuch help" outputs to stderr? (attachment inbox signed unread) + 2009-11-18 Lars Kellogg-Stedman ╰─► ... (attachment inbox signed unread) + 2009-11-17 Mikhail Gusarov ─►[notmuch] [PATCH] Handle rename of message file (inbox unread) + 2009-11-17 Alex Botero-Lowry ┬►[notmuch] preliminary FreeBSD support (attachment inbox unread) + 2009-11-17 Carl Worth ╰─► ... (inbox unread) End of search results. diff --git a/test/uuencode b/test/uuencode deleted file mode 100755 index b3e1ac19..00000000 --- a/test/uuencode +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env bash -test_description="handling of uuencoded data" -. ./test-lib.sh - -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 begin the uuencoded data itself: - -begin 644 bogus-uuencoded-data -M0123456789012345678901234567890123456789012345678901234567890 -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 -MSEARCH RESULT. -\\\` -end - -Finally, we have our afteruudata marker as well."' - -test_begin_subtest "Ensure content before uu data is indexed" -output=$(notmuch search beforeuudata | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; uuencodetest (inbox unread)" - -test_begin_subtest "Ensure uu data is not indexed" -output=$(notmuch search DURINGUUDATA | notmuch_search_sanitize) -test_expect_equal "$output" "" - -test_begin_subtest "Ensure content after uu data is indexed" -output=$(notmuch search afteruudata | notmuch_search_sanitize) -test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; uuencodetest (inbox unread)" - -test_done