gmime-filter-reply.c \
hooks.c \
notmuch.c \
+ notmuch-client-init.c \
notmuch-compact.c \
notmuch-config.c \
notmuch-count.c \
+Notmuch 0.33 (UNRELEASED)
+=========================
+
+Vim
+---
+
+Respect excluded tags when showing a thread.
+
Notmuch 0.32.1 (2021-05-15)
===========================
# define RSTRING_PTR(v) (RSTRING((v))->ptr)
#endif /* !defined (RSTRING_PTR) */
-#define Data_Get_Notmuch_Database(obj, ptr) \
+#define Data_Get_Notmuch_Object(obj, type, message, ptr) \
do { \
- Check_Type ((obj), T_DATA); \
- if (DATA_PTR ((obj)) == NULL) \
- rb_raise (rb_eRuntimeError, "database closed"); \
- Data_Get_Struct ((obj), notmuch_database_t, (ptr)); \
+ Data_Get_Struct ((obj), type, (ptr)); \
+ if (!(ptr)) \
+ rb_raise (rb_eRuntimeError, (message)); \
} while (0)
-#define Data_Get_Notmuch_Directory(obj, ptr) \
- do { \
- Check_Type ((obj), T_DATA); \
- if (DATA_PTR ((obj)) == NULL) \
- rb_raise (rb_eRuntimeError, "directory destroyed"); \
- Data_Get_Struct ((obj), notmuch_directory_t, (ptr)); \
- } while (0)
+#define Data_Get_Notmuch_Database(obj, ptr) \
+ Data_Get_Notmuch_Object ((obj), notmuch_database_t, "database closed", (ptr))
-#define Data_Get_Notmuch_FileNames(obj, ptr) \
- do { \
- Check_Type ((obj), T_DATA); \
- if (DATA_PTR ((obj)) == NULL) \
- rb_raise (rb_eRuntimeError, "filenames destroyed"); \
- Data_Get_Struct ((obj), notmuch_filenames_t, (ptr)); \
- } while (0)
+#define Data_Get_Notmuch_Directory(obj, ptr) \
+ Data_Get_Notmuch_Object ((obj), notmuch_directory_t, "directory destroyed", (ptr))
-#define Data_Get_Notmuch_Query(obj, ptr) \
- do { \
- Check_Type ((obj), T_DATA); \
- if (DATA_PTR ((obj)) == NULL) \
- rb_raise (rb_eRuntimeError, "query destroyed"); \
- Data_Get_Struct ((obj), notmuch_query_t, (ptr)); \
- } while (0)
+#define Data_Get_Notmuch_FileNames(obj, ptr) \
+ Data_Get_Notmuch_Object ((obj), notmuch_filenames_t, "filenames destroyed", (ptr))
-#define Data_Get_Notmuch_Threads(obj, ptr) \
- do { \
- Check_Type ((obj), T_DATA); \
- if (DATA_PTR ((obj)) == NULL) \
- rb_raise (rb_eRuntimeError, "threads destroyed"); \
- Data_Get_Struct ((obj), notmuch_threads_t, (ptr)); \
- } while (0)
+#define Data_Get_Notmuch_Query(obj, ptr) \
+ Data_Get_Notmuch_Object ((obj), notmuch_query_t, "query destroyed", (ptr))
-#define Data_Get_Notmuch_Messages(obj, ptr) \
- do { \
- Check_Type ((obj), T_DATA); \
- if (DATA_PTR ((obj)) == NULL) \
- rb_raise (rb_eRuntimeError, "messages destroyed"); \
- Data_Get_Struct ((obj), notmuch_messages_t, (ptr)); \
- } while (0)
+#define Data_Get_Notmuch_Threads(obj, ptr) \
+ Data_Get_Notmuch_Object ((obj), notmuch_threads_t, "threads destroyed", (ptr))
-#define Data_Get_Notmuch_Thread(obj, ptr) \
- do { \
- Check_Type ((obj), T_DATA); \
- if (DATA_PTR ((obj)) == NULL) \
- rb_raise (rb_eRuntimeError, "thread destroyed"); \
- Data_Get_Struct ((obj), notmuch_thread_t, (ptr)); \
- } while (0)
+#define Data_Get_Notmuch_Messages(obj, ptr) \
+ Data_Get_Notmuch_Object ((obj), notmuch_messages_t, "messages destroyed", (ptr))
-#define Data_Get_Notmuch_Message(obj, ptr) \
- do { \
- Check_Type ((obj), T_DATA); \
- if (DATA_PTR ((obj)) == NULL) \
- rb_raise (rb_eRuntimeError, "message destroyed"); \
- Data_Get_Struct ((obj), notmuch_message_t, (ptr)); \
- } while (0)
+#define Data_Get_Notmuch_Thread(obj, ptr) \
+ Data_Get_Notmuch_Object ((obj), notmuch_thread_t, "thread destroyed", (ptr))
-#define Data_Get_Notmuch_Tags(obj, ptr) \
- do { \
- Check_Type ((obj), T_DATA); \
- if (DATA_PTR ((obj)) == NULL) \
- rb_raise (rb_eRuntimeError, "tags destroyed"); \
- Data_Get_Struct ((obj), notmuch_tags_t, (ptr)); \
- } while (0)
+#define Data_Get_Notmuch_Message(obj, ptr) \
+ Data_Get_Notmuch_Object ((obj), notmuch_message_t, "message destroyed", (ptr))
+
+#define Data_Get_Notmuch_Tags(obj, ptr) \
+ Data_Get_Notmuch_Object ((obj), notmuch_tags_t, "tags destroyed", (ptr))
/* status.c */
void
{
notmuch_directory_t *dir;
- Data_Get_Struct (self, notmuch_directory_t, dir);
+ Data_Get_Notmuch_Directory (self, dir);
notmuch_directory_destroy (dir);
DATA_PTR (self) = NULL;
{
notmuch_threads_t *threads;
- Data_Get_Struct (self, notmuch_threads_t, threads);
+ Data_Get_Notmuch_Threads (self, threads);
notmuch_threads_destroy (threads);
DATA_PTR (self) = NULL;
static GMimeFilterClass *parent_class = NULL;
+static GType type = 0;
+static const GTypeInfo info = {
+ .class_size = sizeof (GMimeFilterReplyClass),
+ .base_init = NULL,
+ .base_finalize = NULL,
+ .class_init = (GClassInitFunc) g_mime_filter_reply_class_init,
+ .class_finalize = NULL,
+ .class_data = NULL,
+ .instance_size = sizeof (GMimeFilterReply),
+ .n_preallocs = 0,
+ .instance_init = (GInstanceInitFunc) g_mime_filter_reply_init,
+ .value_table = NULL,
+};
+
+
+void
+g_mime_filter_reply_module_init (void)
+{
+ type = g_type_register_static (GMIME_TYPE_FILTER, "GMimeFilterReply", &info, (GTypeFlags) 0);
+ parent_class = (GMimeFilterClass *) g_type_class_ref (GMIME_TYPE_FILTER);
+}
GType
g_mime_filter_reply_get_type (void)
{
- static GType type = 0;
-
- if (! type) {
- static const GTypeInfo info = {
- .class_size = sizeof (GMimeFilterReplyClass),
- .base_init = NULL,
- .base_finalize = NULL,
- .class_init = (GClassInitFunc) g_mime_filter_reply_class_init,
- .class_finalize = NULL,
- .class_data = NULL,
- .instance_size = sizeof (GMimeFilterReply),
- .n_preallocs = 0,
- .instance_init = (GInstanceInitFunc) g_mime_filter_reply_init,
- .value_table = NULL,
- };
-
- type = g_type_register_static (GMIME_TYPE_FILTER, "GMimeFilterReply", &info, (GTypeFlags) 0);
- }
-
return type;
}
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GMimeFilterClass *filter_class = GMIME_FILTER_CLASS (klass);
- parent_class = (GMimeFilterClass *) g_type_class_ref (GMIME_TYPE_FILTER);
-
object_class->finalize = g_mime_filter_reply_finalize;
filter_class->copy = filter_copy;
#include <gmime/gmime-filter.h>
+void g_mime_filter_reply_module_init (void);
+
G_BEGIN_DECLS
#define GMIME_TYPE_FILTER_REPLY (g_mime_filter_reply_get_type ())
$(dir)/thread-fp.cc \
$(dir)/features.cc \
$(dir)/prefix.cc \
- $(dir)/open.cc
+ $(dir)/open.cc \
+ $(dir)/init.cc
libnotmuch_modules := $(libnotmuch_c_srcs:.c=.o) $(libnotmuch_cxx_srcs:.cc=.o)
static const char *
_notmuch_database_generate_thread_id (notmuch_database_t *notmuch)
{
- /* 16 bytes (+ terminator) for hexadecimal representation of
- * a 64-bit integer. */
- static char thread_id[17];
notmuch->last_thread_id++;
- sprintf (thread_id, "%016" PRIx64, notmuch->last_thread_id);
+ sprintf (notmuch->thread_id_str, "%016" PRIx64, notmuch->last_thread_id);
- notmuch->writable_xapian_db->set_metadata ("last_thread_id", thread_id);
+ notmuch->writable_xapian_db->set_metadata ("last_thread_id", notmuch->thread_id_str);
- return thread_id;
+ return notmuch->thread_id_str;
}
static char *
enum _notmuch_features features;
unsigned int last_doc_id;
+
+ /* 16 bytes (+ terminator) for hexadecimal representation of
+ * a 64-bit integer. */
+ char thread_id_str[17];
uint64_t last_thread_id;
/* error reporting; this value persists only until the
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GMimeFilterClass *filter_class = GMIME_FILTER_CLASS (klass);
- parent_class = (GMimeFilterClass *) g_type_class_ref (GMIME_TYPE_FILTER);
-
object_class->finalize = notmuch_filter_discard_non_term_finalize;
filter_class->copy = filter_copy;
*
* Returns: a new #NotmuchFilterDiscardNonTerm filter.
**/
+static GType type = 0;
+
+static const GTypeInfo info = {
+ .class_size = sizeof (NotmuchFilterDiscardNonTermClass),
+ .base_init = NULL,
+ .base_finalize = NULL,
+ .class_init = (GClassInitFunc) notmuch_filter_discard_non_term_class_init,
+ .class_finalize = NULL,
+ .class_data = NULL,
+ .instance_size = sizeof (NotmuchFilterDiscardNonTerm),
+ .n_preallocs = 0,
+ .instance_init = NULL,
+ .value_table = NULL,
+};
+
+void
+_notmuch_filter_init () {
+ type = g_type_register_static (GMIME_TYPE_FILTER, "NotmuchFilterDiscardNonTerm", &info,
+ (GTypeFlags) 0);
+ parent_class = (GMimeFilterClass *) g_type_class_ref (GMIME_TYPE_FILTER);
+}
+
static GMimeFilter *
notmuch_filter_discard_non_term_new (GMimeContentType *content_type)
{
- static GType type = 0;
NotmuchFilterDiscardNonTerm *filter;
- if (! type) {
- static const GTypeInfo info = {
- .class_size = sizeof (NotmuchFilterDiscardNonTermClass),
- .base_init = NULL,
- .base_finalize = NULL,
- .class_init = (GClassInitFunc) notmuch_filter_discard_non_term_class_init,
- .class_finalize = NULL,
- .class_data = NULL,
- .instance_size = sizeof (NotmuchFilterDiscardNonTerm),
- .n_preallocs = 0,
- .instance_init = NULL,
- .value_table = NULL,
- };
-
- type = g_type_register_static (GMIME_TYPE_FILTER, "NotmuchFilterDiscardNonTerm", &info,
- (GTypeFlags) 0);
- }
-
filter = (NotmuchFilterDiscardNonTerm *) g_object_new (type, NULL);
filter->content_type = content_type;
filter->state = 0;
--- /dev/null
+#include "notmuch-private.h"
+
+#include <mutex>
+
+static void do_init ()
+{
+ /* Initialize the GLib type system and threads */
+#if ! GLIB_CHECK_VERSION (2, 35, 1)
+ g_type_init ();
+#endif
+
+ g_mime_init ();
+ _notmuch_filter_init ();
+}
+
+void
+_notmuch_init ()
+{
+ static std::once_flag initialized;
+ std::call_once (initialized, do_init);
+}
{
GMimeParser *parser;
notmuch_status_t status = NOTMUCH_STATUS_SUCCESS;
- static int initialized = 0;
bool is_mbox;
if (message->message)
is_mbox = _is_mbox (message->stream);
- if (! initialized) {
- g_mime_init ();
- initialized = 1;
- }
+ _notmuch_init ();
message->headers = g_hash_table_new_full (strcase_hash, strcase_equal,
free, g_free);
};
/* ASCII ordered table of Maildir flags and associated tags */
-static struct maildir_flag_tag flag2tag[] = {
+static const struct maildir_flag_tag flag2tag[] = {
{ 'D', "draft", false },
{ 'F', "flagged", false },
{ 'P', "passed", false },
const char **thread_id);
/* index.cc */
+void
+_notmuch_filter_init ();
+
notmuch_status_t
_notmuch_message_index_file (notmuch_message_t *message,
notmuch_indexopts_t *indexopts,
notmuch_message_file_t *message_file);
+/* init.cc */
+void
+_notmuch_init ();
+
/* messages.c */
typedef struct _notmuch_message_node {
_notmuch_config_cache (notmuch, NOTMUCH_CONFIG_DATABASE_PATH, path);
}
-static void
-_init_libs ()
-{
-
- static int initialized = 0;
-
- /* Initialize the GLib type system and threads */
-#if ! GLIB_CHECK_VERSION (2, 35, 1)
- g_type_init ();
-#endif
-
- /* Initialize gmime */
- if (! initialized) {
- g_mime_init ();
- initialized = 1;
- }
-}
-
static void
_load_database_state (notmuch_database_t *notmuch)
{
GKeyFile *key_file = NULL;
bool split = false;
- _init_libs ();
+ _notmuch_init ();
notmuch = _alloc_notmuch ();
if (! notmuch) {
int err;
bool split = false;
- _init_libs ();
+ _notmuch_init ();
notmuch = _alloc_notmuch ();
if (! notmuch) {
GKeyFile *key_file = NULL;
bool split = false;
- _init_libs ();
+ _notmuch_init ();
notmuch = _alloc_notmuch ();
if (! notmuch) {
--- /dev/null
+#include "notmuch-client.h"
+#include "gmime-filter-reply.h"
+
+/* Caller is responsible for only calling this once */
+
+void
+notmuch_client_init (void)
+{
+#if ! GLIB_CHECK_VERSION (2, 35, 1)
+ g_type_init ();
+#endif
+
+ g_mime_init ();
+
+ g_mime_filter_reply_module_init ();
+
+ talloc_enable_null_tracking ();
+}
char *
json_quote_str (const void *ctx, const char *str);
+/* notmuch-client-init.c */
+
+void notmuch_client_init (void);
+
/* notmuch-config.c */
typedef enum {
"\n"
" For more information about notmuch, see https://notmuchmail.org";
-struct config_group {
+static const struct config_group {
const char *group_name;
const char *comment;
} group_comment_table [] = {
bool (*validate)(const char *);
} config_key_info_t;
-static struct config_key
+static const struct config_key
config_key_table[] = {
{ "index.decrypt", false, NULL },
{ "index.header.", true, validate_field_name },
{ "query.", true, NULL },
};
-static config_key_info_t *
+static const config_key_info_t *
_config_key_info (const char *item)
{
for (size_t i = 0; i < ARRAY_SIZE (config_key_table); i++) {
int argc, char *argv[])
{
char *group, *key;
- config_key_info_t *key_info;
+ const config_key_info_t *key_info;
notmuch_conffile_t *config;
bool update_database = false;
int opt_index, ret;
static void
handle_sigint (unused (int sig))
{
- static char msg[] = "Stopping... \n";
+ static const char msg[] = "Stopping... \n";
/* This write is "opportunistic", so it's okay to ignore the
* result. It is not required for correctness, and if it does
static void
handle_sigint (unused (int sig))
{
- static char msg[] = "Stopping... \n";
+ static const char msg[] = "Stopping... \n";
/* This write is "opportunistic", so it's okay to ignore the
* result. It is not required for correctness, and if it does
static void
handle_sigint (unused (int sig))
{
- static char msg[] = "Stopping... \n";
+ static const char msg[] = "Stopping... \n";
/* This write is "opportunistic", so it's okay to ignore the
* result. It is not required for correctness, and if it does
static void
handle_sigint (unused (int sig))
{
- static char msg[] = "Stopping... \n";
+ static const char msg[] = "Stopping... \n";
/* This write is "opportunistic", so it's okay to ignore the
* result. It is not required for correctness, and if it does
}
-static command_t commands[] = {
+static const command_t commands[] = {
{ NULL, notmuch_command, NOTMUCH_COMMAND_CONFIG_CREATE | NOTMUCH_COMMAND_CONFIG_LOAD,
"Notmuch main command." },
{ "setup", notmuch_setup_command, NOTMUCH_COMMAND_CONFIG_CREATE | NOTMUCH_COMMAND_CONFIG_LOAD,
const char *summary;
} help_topic_t;
-static help_topic_t help_topics[] = {
+static const help_topic_t help_topics[] = {
{ "search-terms",
"Common search term syntax." },
{ "hooks",
"Message property conventions and documentation." },
};
-static command_t *
+static const command_t *
find_command (const char *name)
{
size_t i;
static void
usage (FILE *out)
{
- command_t *command;
- help_topic_t *topic;
+ const command_t *command;
+ const help_topic_t *topic;
unsigned int i;
fprintf (out,
static int
_help_for (const char *topic_name)
{
- command_t *command;
- help_topic_t *topic;
+ const command_t *command;
+ const help_topic_t *topic;
unsigned int i;
if (! topic_name) {
void *local;
char *talloc_report;
const char *command_name = NULL;
- command_t *command;
+ const command_t *command;
const char *config_file_name = NULL;
notmuch_database_t *notmuch = NULL;
int opt_index;
{ }
};
- talloc_enable_null_tracking ();
+ notmuch_client_init ();
local = talloc_new (NULL);
- g_mime_init ();
-#if ! GLIB_CHECK_VERSION (2, 35, 1)
- g_type_init ();
-#endif
-
/* Globally default to the current output format version. */
notmuch_format_version = NOTMUCH_FORMAT_CUR;
- xz. Some speedup can be gotten by installing "pixz", but this is
probably only worthwhile if you are debugging the tests.
- valgrind (for the memory tests)
+- perf (optional, for more fine-grained timing)
Getting set up to run tests:
----------------------------
--small / --medium / --large Choose corpus size.
--debug Enable debugging. In particular don't delete
- temporary directories.
+ temporary directories.
+--perf Run perf record in place of /usr/bin/time. Perf output can be
+ found in a log directory.
+--call-graph {fp,lbr,dwarf} Call graph option for perf record. Default is 'lbr'.
When using the make targets, you can pass arguments to all test
scripts by defining the make variable OPTIONS.
+Log Directory
+-------------
+
+The memory tests, and the time tests when option '--perf' is given
+save their output in a directory named as follows
+
+ log.$test_name-$corpus_size-$timestamp
+
+These directories are removed by "make clean".
+
Writing tests
-------------
. $(dirname "$0")/version.sh || exit 1
+debug=""
corpus_size=large
+perf_callgraph=lbr
+use_perf=0
while test "$#" -ne 0
do
debug=t;
shift
;;
+ -p|--perf)
+ use_perf=1;
+ shift
+ ;;
+ -c|--call-graph)
+ shift
+ perf_callgraph=$1
+ shift
+ ;;
-s|--small)
corpus_size=small;
shift
fi
}
+make_log_dir () {
+ local timestamp=$(date +%Y%m%dT%H%M%S)
+ log_dir=${TEST_DIRECTORY}/log.$(basename $0)-$corpus_size-${timestamp}
+ mkdir -p "${log_dir}"
+}
+
time_start ()
{
add_email_corpus
+ if [[ "$use_perf" = 1 ]]; then
+ make_log_dir
+ fi
+
print_header
notmuch_new_with_cache time_run
{
add_email_corpus
- local timestamp=$(date +%Y%m%dT%H%M%S)
- log_dir="${TEST_DIRECTORY}/log.$(basename $0)-$corpus_size-${timestamp}"
- mkdir -p ${log_dir}
+ make_log_dir
notmuch_new_with_cache memory_run
}
printf " %-22s" "$1"
test_count=$(($test_count+1))
if test "$verbose" != "t"; then exec 4>test.output 3>&4; fi
- if ! eval >&3 "/usr/bin/time -f '%e\t%U\t%S\t%M\t%I/%O' $2" ; then
+ if [[ "$use_perf" = 1 ]]; then
+ command_str="perf record --call-graph=${perf_callgraph} -o ${log_dir}/${test_count}.perf $2"
+ else
+ command_str="/usr/bin/time -f '%e\t%U\t%S\t%M\t%I/%O' $2"
+ fi
+
+ if ! eval >&3 "$command_str" ; then
test_failure=$(($test_failure + 1))
return 1
fi
EXPECTED=$NOTMUCH_SRCDIR/test/emacs.expected-output
+test_require_emacs
add_email_corpus
# syntax errors in test-lib.el cause mysterious failures
##################################################
+test_require_emacs
add_gnupg_home
test_begin_subtest "emacs delivery of signed message"
test_description='S/MIME signature verification and decryption'
. $(dirname "$0")/test-lib.sh || exit 1
+test_require_emacs
test_require_external_prereq openssl
test_require_external_prereq gpgsm
##################################################
+test_require_emacs
add_gnupg_home
# create a test encrypted message
add_email_corpus
+test_ruby() {
+ (
+ cat <<-EOF
+ require 'notmuch'
+ db = Notmuch::Database.new('$MAIL_DIR')
+ EOF
+ cat
+ ) | $NOTMUCH_RUBY -I "$NOTMUCH_BUILDDIR/bindings/ruby"> OUTPUT
+ test_expect_equal_file EXPECTED OUTPUT
+}
+
test_begin_subtest "compare thread ids"
+notmuch search --sort=oldest-first --output=threads tag:inbox > EXPECTED
test_ruby <<"EOF"
-require 'notmuch'
-$maildir = ENV['MAIL_DIR']
-if not $maildir then
- abort('environment variable MAIL_DIR must be set')
-end
-@db = Notmuch::Database.new($maildir)
-@q = @db.query('tag:inbox')
-@q.sort = Notmuch::SORT_OLDEST_FIRST
-for t in @q.search_threads do
- print t.thread_id, "\n"
+q = db.query('tag:inbox')
+q.sort = Notmuch::SORT_OLDEST_FIRST
+q.search_threads.each do |t|
+ puts 'thread:%s' % t.thread_id
end
EOF
-notmuch search --sort=oldest-first --output=threads tag:inbox | sed s/^thread:// > EXPECTED
-test_expect_equal_file EXPECTED OUTPUT
test_begin_subtest "compare message ids"
+notmuch search --sort=oldest-first --output=messages tag:inbox > EXPECTED
test_ruby <<"EOF"
-require 'notmuch'
-$maildir = ENV['MAIL_DIR']
-if not $maildir then
- abort('environment variable MAIL_DIR must be set')
-end
-@db = Notmuch::Database.new($maildir)
-@q = @db.query('tag:inbox')
-@q.sort = Notmuch::SORT_OLDEST_FIRST
-for m in @q.search_messages do
- print m.message_id, "\n"
+q = db.query('tag:inbox')
+q.sort = Notmuch::SORT_OLDEST_FIRST
+q.search_messages.each do |m|
+ puts 'id:%s' % m.message_id
end
EOF
-notmuch search --sort=oldest-first --output=messages tag:inbox | sed s/^id:// > EXPECTED
-test_expect_equal_file EXPECTED OUTPUT
test_begin_subtest "get non-existent file"
+echo nil > EXPECTED
test_ruby <<"EOF"
-require 'notmuch'
-$maildir = ENV['MAIL_DIR']
-if not $maildir then
- abort('environment variable MAIL_DIR must be set')
-end
-@db = Notmuch::Database.new($maildir)
-result = @db.find_message_by_filename('i-dont-exist')
-print (result == nil)
+p db.find_message_by_filename('i-dont-exist')
EOF
-test_expect_equal "$(cat OUTPUT)" "true"
test_begin_subtest "count messages"
+notmuch count --output=messages tag:inbox > EXPECTED
test_ruby <<"EOF"
-require 'notmuch'
-$maildir = ENV['MAIL_DIR']
-if not $maildir then
- abort('environment variable MAIL_DIR must be set')
-end
-@db = Notmuch::Database.new($maildir)
-@q = @db.query('tag:inbox')
-print @q.count_messages(),"\n"
+puts db.query('tag:inbox').count_messages()
EOF
-notmuch count --output=messages tag:inbox > EXPECTED
-test_expect_equal_file EXPECTED OUTPUT
test_begin_subtest "count threads"
+notmuch count --output=threads tag:inbox > EXPECTED
test_ruby <<"EOF"
-require 'notmuch'
-$maildir = ENV['MAIL_DIR']
-if not $maildir then
- abort('environment variable MAIL_DIR must be set')
-end
-@db = Notmuch::Database.new($maildir)
-@q = @db.query('tag:inbox')
-print @q.count_threads(),"\n"
+puts db.query('tag:inbox').count_threads()
EOF
-notmuch count --output=threads tag:inbox > EXPECTED
-test_expect_equal_file EXPECTED OUTPUT
test_begin_subtest "get all tags"
+notmuch search --output=tags '*' > EXPECTED
test_ruby <<"EOF"
-require 'notmuch'
-$maildir = ENV['MAIL_DIR']
-if not $maildir then
- abort('environment variable MAIL_DIR must be set')
-end
-@db = Notmuch::Database.new($maildir)
-@t = @db.all_tags()
-for tag in @t do
- print tag,"\n"
+db.all_tags.each do |tag|
+ puts tag
end
EOF
-notmuch search --output=tags '*' > EXPECTED
-test_expect_equal_file EXPECTED OUTPUT
test_done
EXPECTED=$NOTMUCH_SRCDIR/test/emacs-show.expected-output
+test_require_emacs
add_email_corpus
test_begin_subtest "Hiding Original Message region at beginning of a message"
EXPECTED=$NOTMUCH_SRCDIR/test/emacs-tree.expected-output
+test_require_emacs
add_email_corpus
test_begin_subtest "Basic notmuch-tree view in emacs"
test_description="emacs forwarding"
. $(dirname "$0")/test-lib.sh || exit 1
+test_require_emacs
+
test_begin_subtest "Forward setting the correct references header"
# Check that, when forwarding a message, the new message has
# a References-header pointing to the original (forwarded) message.
# for reproducibility
unset EMAIL
+unset NAME
+
+test_require_emacs () {
+ test_require_external_prereq emacs
+ test_require_external_prereq ${TEST_EMACSCLIENT}
+ test_require_external_prereq dtach
+}
add_gnupg_home ()
{
exec 1>&6 2>&7 # Restore stdout and stderr
inside_subtest=
+ # test_emacs may update missing external prerequisites
+ test_check_missing_external_prereqs_ "$test_subtest_name" && return
+
# Report success/failure.
result=$(cat OUTPUT)
if [ "$result" = t ]
pw = pwd.getpwuid(os.getuid())
user = pw.pw_name
name = pw.pw_gecos.partition(",")[0]
-fqdn = socket.getfqdn()
+fqdn = socket.getaddrinfo(socket.gethostname(), 0, 0, socket.SOCK_STREAM, 0, socket.AI_CANONNAME)[0][3]
for l in sys.stdin:
- l = l.replace(user, "USERNAME").replace(fqdn, "FQDN").replace(".(none)","").replace(name, "USER_FULL_NAME")
+ if user:
+ l = l.replace(user, "USERNAME")
+ if fqdn:
+ l = l.replace(fqdn, "FQDN").replace(".(none)","")
+ if name:
+ l = l.replace(name, "USER_FULL_NAME")
sys.stdout.write(l)
'
}
test_run_ "$1"
run_ret="$?"
# test_run_ may update missing external prerequisites
- test_check_missing_external_prereqs_ "$@" ||
+ test_check_missing_external_prereqs_ "$test_subtest_name" ||
if [ "$run_ret" = 0 -a "$eval_ret" = 0 ]
then
test_ok_
test_run_ "$2"
run_ret="$?"
# test_run_ may update missing external prerequisites,
- test_check_missing_external_prereqs_ "$@" ||
+ test_check_missing_external_prereqs_ "$test_subtest_name" ||
if [ "$run_ret" = 0 -a "$eval_ret" = "$1" ]
then
test_ok_
$NOTMUCH_PYTHON -B - > OUTPUT
}
-test_ruby() {
- MAIL_DIR=$MAIL_DIR $NOTMUCH_RUBY -I "$NOTMUCH_BUILDDIR/bindings/ruby"> OUTPUT
-}
-
test_C () {
local exec_file test_file
exec_file="test${test_count}"
$curbuf.render do |b|
q = $curbuf.query(get_cur_view)
q.sort = Notmuch::SORT_OLDEST_FIRST
+ $exclude_tags.each { |t|
+ q.add_tag_exclude(t)
+ }
msgs = q.search_messages
msgs.each do |msg|
m = Mail.read(msg.filename)