2 test_description='"notmuch search" in several variations'
3 . $(dirname "$0")/test-lib.sh || exit 1
5 if [ $NOTMUCH_HAVE_SFSEXP -ne 1 ]; then
6 printf "Skipping due to missing sfsexp library\n"
12 for query in '()' '(not)' '(and)' '(or ())' '(or (not))' '(or (and))' \
13 '(or (and) (or) (not (and)))'; do
14 test_begin_subtest "all messages: $query"
15 notmuch search '*' > EXPECTED
16 notmuch search --query=sexp "$query" > OUTPUT
17 test_expect_equal_file EXPECTED OUTPUT
20 for query in '(or)' '(not ())' '(not (not))' '(not (and))' \
21 '(not (or (and) (or) (not (and))))'; do
22 test_begin_subtest "no messages: $query"
23 notmuch search --query=sexp "$query" > OUTPUT
24 test_expect_equal_file /dev/null OUTPUT
27 test_begin_subtest "and of exact terms"
28 notmuch search --query=sexp '(and "wonderful" "wizard")' | notmuch_search_sanitize > OUTPUT
30 thread:XXX 2009-11-18 [1/3] Carl Worth| Jan Janak; [notmuch] What a great idea! (inbox unread)
32 test_expect_equal_file EXPECTED OUTPUT
34 test_begin_subtest "or of exact terms"
35 notmuch search --query=sexp '(or "php" "wizard")' | notmuch_search_sanitize > OUTPUT
37 thread:XXX 2010-12-29 [1/1] François Boulogne; [aur-general] Guidelines: cp, mkdir vs install (inbox unread)
38 thread:XXX 2009-11-18 [1/3] Carl Worth| Jan Janak; [notmuch] What a great idea! (inbox unread)
40 test_expect_equal_file EXPECTED OUTPUT
42 test_begin_subtest "single term in body"
43 notmuch search --query=sexp 'wizard' | notmuch_search_sanitize>OUTPUT
45 thread:XXX 2009-11-18 [1/3] Carl Worth| Jan Janak; [notmuch] What a great idea! (inbox unread)
47 test_expect_equal_file EXPECTED OUTPUT
49 test_begin_subtest "single term in body (case insensitive)"
50 notmuch search --query=sexp 'Wizard' | notmuch_search_sanitize>OUTPUT
52 thread:XXX 2009-11-18 [1/3] Carl Worth| Jan Janak; [notmuch] What a great idea! (inbox unread)
54 test_expect_equal_file EXPECTED OUTPUT
56 test_begin_subtest "single term in body, stemmed version"
57 notmuch search arriv > EXPECTED
58 notmuch search --query=sexp arriv > OUTPUT
59 test_expect_equal_file EXPECTED OUTPUT
61 test_begin_subtest "single term in body, unstemmed version"
62 notmuch search --query=sexp '"arriv"' > OUTPUT
63 test_expect_equal_file /dev/null OUTPUT
65 test_begin_subtest "Search by 'subject'"
66 add_message [subject]=subjectsearchtest '[date]="Sat, 01 Jan 2000 12:00:00 -0000"'
67 output=$(notmuch search --query=sexp '(subject subjectsearchtest)' | notmuch_search_sanitize)
68 test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; subjectsearchtest (inbox unread)"
70 test_begin_subtest "Search by 'subject' (case insensitive)"
71 notmuch search tag:inbox and subject:maildir | notmuch_search_sanitize > EXPECTED
72 notmuch search --query=sexp '(subject "Maildir")' | notmuch_search_sanitize > OUTPUT
73 test_expect_equal_file EXPECTED OUTPUT
75 test_begin_subtest "Search by 'subject' (utf-8):"
76 add_message [subject]=utf8-sübjéct '[date]="Sat, 01 Jan 2000 12:00:00 -0000"'
77 output=$(notmuch search --query=sexp '(subject utf8 sübjéct)' | notmuch_search_sanitize)
78 test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; utf8-sübjéct (inbox unread)"
80 test_begin_subtest "Search by 'subject' (utf-8, and):"
81 output=$(notmuch search --query=sexp '(subject (and utf8 sübjéct))' | notmuch_search_sanitize)
82 test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; utf8-sübjéct (inbox unread)"
84 test_begin_subtest "Search by 'subject' (utf-8, and outside):"
85 output=$(notmuch search --query=sexp '(and (subject utf8) (subject sübjéct))' | notmuch_search_sanitize)
86 test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; utf8-sübjéct (inbox unread)"
88 test_begin_subtest "Search by 'subject' (utf-8, or):"
89 notmuch search --query=sexp '(subject (or utf8 subjectsearchtest))' | notmuch_search_sanitize > OUTPUT
91 thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; subjectsearchtest (inbox unread)
92 thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; utf8-sübjéct (inbox unread)
94 test_expect_equal_file EXPECTED OUTPUT
96 test_begin_subtest "Search by 'subject' (utf-8, or outside):"
97 notmuch search --query=sexp '(or (subject utf8) (subject subjectsearchtest))' | notmuch_search_sanitize > OUTPUT
99 thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; subjectsearchtest (inbox unread)
100 thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; utf8-sübjéct (inbox unread)
102 test_expect_equal_file EXPECTED OUTPUT
104 test_begin_subtest "Search by 'attachment'"
105 notmuch search attachment:notmuch-help.patch > EXPECTED
106 notmuch search --query=sexp '(attachment notmuch-help.patch)' > OUTPUT
107 test_expect_equal_file EXPECTED OUTPUT
109 test_begin_subtest "Search by 'body'"
110 add_message '[subject]="body search"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' [body]=bodysearchtest
111 output=$(notmuch search --query=sexp '(body bodysearchtest)' | notmuch_search_sanitize)
112 test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; body search (inbox unread)"
114 test_begin_subtest "Search by 'body' (phrase)"
115 add_message '[subject]="body search (phrase)"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' '[body]="body search (phrase)"'
116 add_message '[subject]="negative result"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' '[body]="This phrase should not match the body search"'
117 output=$(notmuch search --query=sexp '(body "body search phrase")' | notmuch_search_sanitize)
118 test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; body search (phrase) (inbox unread)"
120 test_begin_subtest "Search by 'body' (utf-8):"
121 add_message '[subject]="utf8-message-body-subject"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' '[body]="message body utf8: bödý"'
122 output=$(notmuch search --query=sexp '(body bödý)' | notmuch_search_sanitize)
123 test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; utf8-message-body-subject (inbox unread)"
125 add_message "[body]=thebody-1" "[subject]=kryptonite-1"
126 add_message "[body]=nothing-to-see-here-1" "[subject]=thebody-1"
128 test_begin_subtest 'search without body: prefix'
129 notmuch search thebody > EXPECTED
130 notmuch search --query=sexp '(and thebody)' > OUTPUT
131 test_expect_equal_file EXPECTED OUTPUT
133 test_begin_subtest 'negated body: prefix'
134 notmuch search thebody and not body:thebody > EXPECTED
135 notmuch search --query=sexp '(and (not (body thebody)) thebody)' > OUTPUT
136 test_expect_equal_file EXPECTED OUTPUT
138 test_begin_subtest 'search unprefixed for prefixed term'
139 notmuch search kryptonite > EXPECTED
140 notmuch search --query=sexp '(and kryptonite)' > OUTPUT
141 test_expect_equal_file EXPECTED OUTPUT
143 test_begin_subtest 'search with body: prefix for term only in subject'
144 notmuch search body:kryptonite > EXPECTED
145 notmuch search --query=sexp '(body kryptonite)' > OUTPUT
146 test_expect_equal_file EXPECTED OUTPUT
148 test_begin_subtest "Search by 'from'"
149 add_message '[subject]="search by from"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' [from]=searchbyfrom
150 output=$(notmuch search --query=sexp '(from searchbyfrom)' | notmuch_search_sanitize)
151 test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] searchbyfrom; search by from (inbox unread)"
153 test_begin_subtest "Search by 'from' (address)"
154 add_message '[subject]="search by from (address)"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' [from]=searchbyfrom@example.com
155 output=$(notmuch search --query=sexp '(from searchbyfrom@example.com)' | notmuch_search_sanitize)
156 test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] searchbyfrom@example.com; search by from (address) (inbox unread)"
158 test_begin_subtest "Search by 'from' (name)"
159 add_message '[subject]="search by from (name)"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' '[from]="Search By From Name <test@example.com>"'
160 output=$(notmuch search --query=sexp '(from "Search By From Name")' | notmuch_search_sanitize)
161 test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Search By From Name; search by from (name) (inbox unread)"
163 test_begin_subtest "Search by 'from' (name and address)"
164 output=$(notmuch search --query=sexp '(from "Search By From Name <test@example.com>")' | notmuch_search_sanitize)
165 test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Search By From Name; search by from (name) (inbox unread)"
167 add_message '[dir]=bad' '[subject]="To the bone"'
168 add_message '[dir]=.' '[subject]="Top level"'
169 add_message '[dir]=bad/news' '[subject]="Bears"'
170 mkdir -p "${MAIL_DIR}/duplicate/bad/news"
171 cp "$gen_msg_filename" "${MAIL_DIR}/duplicate/bad/news"
173 add_message '[dir]=things' '[subject]="These are a few"'
174 add_message '[dir]=things/favorite' '[subject]="Raindrops, whiskers, kettles"'
175 add_message '[dir]=things/bad' '[subject]="Bites, stings, sad feelings"'
177 test_begin_subtest "Search by 'folder' (multiple)"
178 output=$(notmuch search --query=sexp '(folder bad bad/news things/bad)' | notmuch_search_sanitize)
179 test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; To the bone (inbox unread)
180 thread:XXX 2001-01-05 [1/1(2)] Notmuch Test Suite; Bears (inbox unread)
181 thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Bites, stings, sad feelings (inbox unread)"
183 test_begin_subtest "Search by 'folder': top level."
184 notmuch search folder:'""' > EXPECTED
185 notmuch search --query=sexp '(folder "")' > OUTPUT
186 test_expect_equal_file EXPECTED OUTPUT
188 test_begin_subtest "Search by 'id'"
189 add_message '[subject]="search by id"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"'
190 output=$(notmuch search --query=sexp "(id ${gen_msg_id})" | notmuch_search_sanitize)
191 test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by id (inbox unread)"
193 test_begin_subtest "Search by 'id' (or)"
194 add_message '[subject]="search by id"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"'
195 output=$(notmuch search --query=sexp "(id non-existent-mid ${gen_msg_id})" | notmuch_search_sanitize)
196 test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by id (inbox unread)"
198 test_begin_subtest "Search by 'is' (multiple)"
199 notmuch tag -inbox tag:searchbytag
200 notmuch search is:inbox AND is:unread | notmuch_search_sanitize > EXPECTED
201 notmuch search --query=sexp '(is inbox unread)' | notmuch_search_sanitize > OUTPUT
202 notmuch tag +inbox tag:searchbytag
203 test_expect_equal_file EXPECTED OUTPUT
205 test_begin_subtest "Search by 'mid'"
206 add_message '[subject]="search by mid"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"'
207 output=$(notmuch search --query=sexp "(mid ${gen_msg_id})" | notmuch_search_sanitize)
208 test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by mid (inbox unread)"
210 test_begin_subtest "Search by 'mid' (or)"
211 add_message '[subject]="search by mid"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"'
212 output=$(notmuch search --query=sexp "(mid non-existent-mid ${gen_msg_id})" | notmuch_search_sanitize)
213 test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by mid (inbox unread)"
215 test_begin_subtest "Search by 'mimetype'"
216 notmuch search mimetype:text/html > EXPECTED
217 notmuch search --query=sexp '(mimetype text html)' > OUTPUT
218 test_expect_equal_file EXPECTED OUTPUT
220 QUERYSTR="date:2009-11-18..2009-11-18 and tag:unread"
221 QUERYSTR2="query:test and subject:Maildir"
222 notmuch config set --database query.test "$QUERYSTR"
223 notmuch config set query.test2 "$QUERYSTR2"
225 test_begin_subtest "ill-formed named query search"
226 notmuch search --query=sexp '(query)' > OUTPUT 2>&1
228 notmuch search: Syntax error in query
229 'query' expects single atom as argument
231 test_expect_equal_file EXPECTED OUTPUT
233 test_begin_subtest "ill-formed named query search 2"
234 notmuch search --query=sexp '(to (query))' > OUTPUT 2>&1
236 notmuch search: Syntax error in query
237 'query' not supported inside 'to'
239 test_expect_equal_file EXPECTED OUTPUT
241 test_begin_subtest "search named query"
242 notmuch search --query=sexp '(query test)' > OUTPUT
243 notmuch search $QUERYSTR > EXPECTED
244 test_expect_equal_file EXPECTED OUTPUT
246 test_begin_subtest "Search by 'subject' (utf-8, phrase-token):"
247 output=$(notmuch search --query=sexp '(subject utf8-sübjéct)' | notmuch_search_sanitize)
248 test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; utf8-sübjéct (inbox unread)"
250 test_begin_subtest "search named query with other terms"
251 notmuch search --query=sexp '(and (query test) (subject Maildir))' > OUTPUT
252 notmuch search $QUERYSTR and subject:Maildir > EXPECTED
253 test_expect_equal_file EXPECTED OUTPUT
255 test_begin_subtest "search nested named query"
256 notmuch search --query=sexp '(query test2)' > OUTPUT
257 notmuch search $QUERYSTR2 > EXPECTED
258 test_expect_equal_file EXPECTED OUTPUT
260 test_begin_subtest "Search by 'subject' (utf-8, quoted string):"
261 output=$(notmuch search --query=sexp '(subject "utf8 sübjéct")' | notmuch_search_sanitize)
262 test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; utf8-sübjéct (inbox unread)"
264 test_begin_subtest "Search by 'subject' (combine phrase, term):"
265 output=$(notmuch search --query=sexp '(subject Mac "compatibility issues")' | notmuch_search_sanitize)
266 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)"
268 test_begin_subtest "Search by 'subject' (combine phrase, term 2):"
269 notmuch search --query=sexp '(subject (or utf8 "compatibility issues"))' | notmuch_search_sanitize > OUTPUT
271 thread:XXX 2009-11-18 [4/4] Jjgod Jiang, Alexander Botero-Lowry; [notmuch] Mac OS X/Darwin compatibility issues (inbox unread)
272 thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; utf8-sübjéct (inbox unread)
273 thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; utf8-message-body-subject (inbox unread)
275 test_expect_equal_file EXPECTED OUTPUT
277 test_begin_subtest "Search by 'subject' (combine phrase, term 3):"
278 notmuch search --query=sexp '(subject issues X/Darwin)' | notmuch_search_sanitize > OUTPUT
280 thread:XXX 2009-11-18 [4/4] Jjgod Jiang, Alexander Botero-Lowry; [notmuch] Mac OS X/Darwin compatibility issues (inbox unread)
282 test_expect_equal_file EXPECTED OUTPUT
284 test_begin_subtest "Search by 'tag'"
285 add_message '[subject]="search by tag"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"'
286 notmuch tag +searchbytag id:${gen_msg_id}
287 output=$(notmuch search --query=sexp '(tag searchbytag)' | notmuch_search_sanitize)
288 test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by tag (inbox searchbytag unread)"
290 test_begin_subtest "Search by 'tag' (multiple)"
291 notmuch tag -inbox tag:searchbytag
292 notmuch search tag:inbox AND tag:unread | notmuch_search_sanitize > EXPECTED
293 notmuch search --query=sexp '(tag inbox unread)' | notmuch_search_sanitize > OUTPUT
294 notmuch tag +inbox tag:searchbytag
295 test_expect_equal_file EXPECTED OUTPUT
297 test_begin_subtest "Search by 'tag' and 'subject'"
298 notmuch search tag:inbox and subject:maildir | notmuch_search_sanitize > EXPECTED
299 notmuch search --query=sexp '(and (tag inbox) (subject maildir))' | notmuch_search_sanitize > OUTPUT
300 test_expect_equal_file EXPECTED OUTPUT
302 test_begin_subtest "Search by 'thread'"
303 add_message '[subject]="search by thread"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"'
304 thread_id=$(notmuch search id:${gen_msg_id} | sed -e "s/thread:\([a-f0-9]*\).*/\1/")
305 output=$(notmuch search --query=sexp "(thread ${thread_id})" | notmuch_search_sanitize)
306 test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by thread (inbox unread)"
308 test_begin_subtest "Search by 'to'"
309 add_message '[subject]="search by to"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' [to]=searchbyto
310 output=$(notmuch search --query=sexp '(to searchbyto)' | notmuch_search_sanitize)
311 test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by to (inbox unread)"
313 test_begin_subtest "Search by 'to' (address)"
314 add_message '[subject]="search by to (address)"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' [to]=searchbyto@example.com
315 output=$(notmuch search --query=sexp '(to searchbyto@example.com)' | notmuch_search_sanitize)
316 test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by to (address) (inbox unread)"
318 test_begin_subtest "Search by 'to' (name)"
319 add_message '[subject]="search by to (name)"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' '[to]="Search By To Name <test@example.com>"'
320 output=$(notmuch search --query=sexp '(to "Search By To Name")' | notmuch_search_sanitize)
321 test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by to (name) (inbox unread)"
323 test_begin_subtest "Search by 'to' (name and address)"
324 output=$(notmuch search --query=sexp '(to "Search By To Name <test@example.com>")' | notmuch_search_sanitize)
325 test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by to (name) (inbox unread)"
327 test_begin_subtest "starts-with, no prefix"
328 output=$(notmuch search --query=sexp '(starts-with prelim)' | notmuch_search_sanitize)
329 test_expect_equal "$output" "thread:XXX 2009-11-17 [2/2] Alex Botero-Lowry, Carl Worth; [notmuch] preliminary FreeBSD support (attachment inbox unread)"
331 test_begin_subtest "starts-with, case-insensitive"
332 notmuch search --query=sexp '(starts-with FreeB)' | notmuch_search_sanitize > OUTPUT
334 thread:XXX 2009-11-18 [3/4] Alexander Botero-Lowry, Jjgod Jiang; [notmuch] Mac OS X/Darwin compatibility issues (inbox unread)
335 thread:XXX 2009-11-17 [2/2] Alex Botero-Lowry, Carl Worth; [notmuch] preliminary FreeBSD support (attachment inbox unread)
337 test_expect_equal_file EXPECTED OUTPUT
339 test_begin_subtest "starts-with, no prefix, all messages"
340 notmuch search --query=sexp '(starts-with "")' | notmuch_search_sanitize > OUTPUT
341 notmuch search '*' | notmuch_search_sanitize > EXPECTED
342 test_expect_equal_file EXPECTED OUTPUT
344 test_begin_subtest "starts-with, attachment"
345 output=$(notmuch search --query=sexp '(attachment (starts-with not))' | notmuch_search_sanitize)
346 test_expect_equal "$output" 'thread:XXX 2009-11-18 [2/2] Lars Kellogg-Stedman; [notmuch] "notmuch help" outputs to stderr? (attachment inbox signed unread)'
348 test_begin_subtest "starts-with, folder"
349 notmuch search --output=files --query=sexp '(folder (starts-with bad))' | notmuch_dir_sanitize | sed 's/[0-9]*$/XXX/' > OUTPUT
352 MAIL_DIR/bad/news/msg-XXX
353 MAIL_DIR/duplicate/bad/news/msg-XXX
355 test_expect_equal_file EXPECTED OUTPUT
357 test_begin_subtest "starts-with, from"
358 notmuch search --query=sexp '(from (starts-with Mik))' | notmuch_search_sanitize > OUTPUT
360 thread:XXX 2009-11-17 [1/1] Mikhail Gusarov; [notmuch] [PATCH] Handle rename of message file (inbox unread)
361 thread:XXX 2009-11-17 [2/7] Mikhail Gusarov| Lars Kellogg-Stedman, Keith Packard, Carl Worth; [notmuch] Working with Maildir storage? (inbox signed unread)
362 thread:XXX 2009-11-17 [2/5] Mikhail Gusarov| Carl Worth, Keith Packard; [notmuch] [PATCH 2/2] Include <stdint.h> to get uint32_t in C++ file with gcc 4.4 (inbox unread)
364 test_expect_equal_file EXPECTED OUTPUT
366 test_begin_subtest "starts-with, id"
367 notmuch search --query=sexp --output=messages '(id (starts-with 877))' > OUTPUT
369 id:877h1wv7mg.fsf@inf-8657.int-evry.fr
370 id:877htoqdbo.fsf@yoom.home.cworth.org
372 test_expect_equal_file EXPECTED OUTPUT
374 test_begin_subtest "starts-with, is"
375 output=$(notmuch search --query=sexp '(is (starts-with searchby))' | notmuch_search_sanitize)
376 test_expect_equal "$output" 'thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by tag (inbox searchbytag unread)'
378 test_begin_subtest "starts-with, mid"
379 notmuch search --query=sexp --output=messages '(mid (starts-with 877))' > OUTPUT
381 id:877h1wv7mg.fsf@inf-8657.int-evry.fr
382 id:877htoqdbo.fsf@yoom.home.cworth.org
384 test_expect_equal_file EXPECTED OUTPUT
386 test_begin_subtest "starts-with, mimetype"
387 notmuch search --query=sexp '(mimetype (starts-with sig))' | notmuch_search_sanitize > OUTPUT
389 thread:XXX 2009-11-18 [2/2] Lars Kellogg-Stedman; [notmuch] "notmuch help" outputs to stderr? (attachment inbox signed unread)
390 thread:XXX 2009-11-18 [4/7] Lars Kellogg-Stedman, Mikhail Gusarov| Keith Packard, Carl Worth; [notmuch] Working with Maildir storage? (inbox signed unread)
391 thread:XXX 2009-11-17 [1/3] Adrian Perez de Castro| Keith Packard, Carl Worth; [notmuch] Introducing myself (inbox signed unread)
393 test_expect_equal_file EXPECTED OUTPUT
395 add_message '[subject]="message with properties"'
396 notmuch restore <<EOF
397 #= ${gen_msg_id} foo=bar
400 test_begin_subtest "starts-with, property"
401 notmuch search --query=sexp '(property (starts-with foo=))' | notmuch_search_sanitize > OUTPUT
403 thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; message with properties (inbox unread)
405 test_expect_equal_file EXPECTED OUTPUT
407 test_begin_subtest "starts-with, subject"
408 notmuch search --query=sexp '(subject (starts-with FreeB))' | notmuch_search_sanitize > OUTPUT
410 thread:XXX 2009-11-17 [2/2] Alex Botero-Lowry, Carl Worth; [notmuch] preliminary FreeBSD support (attachment inbox unread)
412 test_expect_equal_file EXPECTED OUTPUT
414 test_begin_subtest "starts-with, tag"
415 output=$(notmuch search --query=sexp '(tag (starts-with searchby))' | notmuch_search_sanitize)
416 test_expect_equal "$output" 'thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by tag (inbox searchbytag unread)'
418 add_message '[subject]="no tags"'
419 notag_mid=${gen_msg_id}
420 notmuch tag -unread -inbox id:${notag_mid}
422 test_begin_subtest "negated starts-with, tag"
423 output=$(notmuch search --query=sexp '(tag (not (starts-with in)))' | notmuch_search_sanitize)
424 test_expect_equal "$output" 'thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; no tags ()'
426 test_begin_subtest "negated starts-with, tag 2"
427 output=$(notmuch search --query=sexp '(not (tag (starts-with in)))' | notmuch_search_sanitize)
428 test_expect_equal "$output" 'thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; no tags ()'
430 test_begin_subtest "negated starts-with, tag 3"
431 output=$(notmuch search --query=sexp '(not (tag (starts-with "")))' | notmuch_search_sanitize)
432 test_expect_equal "$output" 'thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; no tags ()'
434 test_begin_subtest "starts-with, thread"
435 notmuch search --query=sexp '(thread (starts-with "00"))' > OUTPUT
436 notmuch search '*' > EXPECTED
437 test_expect_equal_file EXPECTED OUTPUT
439 test_begin_subtest "starts-with, to"
440 notmuch search --query=sexp '(to (starts-with "search"))' | notmuch_search_sanitize > OUTPUT
442 thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by to (inbox unread)
443 thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by to (address) (inbox unread)
444 thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by to (name) (inbox unread)
446 test_expect_equal_file EXPECTED OUTPUT
448 test_begin_subtest "wildcard search for 'is'"
449 notmuch search not id:${notag_mid} > EXPECTED
450 notmuch search --query=sexp '(is *)' > OUTPUT
451 test_expect_equal_file EXPECTED OUTPUT
453 test_begin_subtest "negated wildcard search for 'is'"
454 notmuch search id:${notag_mid} > EXPECTED
455 notmuch search --query=sexp '(not (is *))' > OUTPUT
456 test_expect_equal_file EXPECTED OUTPUT
458 test_begin_subtest "wildcard search for 'property'"
459 notmuch search property:foo=bar > EXPECTED
460 notmuch search --query=sexp '(property *)' > OUTPUT
461 test_expect_equal_file EXPECTED OUTPUT
463 test_begin_subtest "wildcard search for 'tag'"
464 notmuch search not id:${notag_mid} > EXPECTED
465 notmuch search --query=sexp '(tag *)' > OUTPUT
466 test_expect_equal_file EXPECTED OUTPUT
468 test_begin_subtest "negated wildcard search for 'tag'"
469 notmuch search id:${notag_mid} > EXPECTED
470 notmuch search --query=sexp '(not (tag *))' > OUTPUT
471 test_expect_equal_file EXPECTED OUTPUT
473 add_message '[subject]="message with tag \"*\""'
474 notmuch tag '+*' id:${gen_msg_id}
476 test_begin_subtest "search for 'tag' \"*\""
477 output=$(notmuch search --query=sexp --output=messages '(tag "*")')
478 test_expect_equal "$output" "id:$gen_msg_id"
480 test_begin_subtest "search for missing / empty to"
481 add_message [to]="undisclosed-recipients:"
482 notmuch search --query=sexp '(not (to *))' | notmuch_search_sanitize > OUTPUT
484 thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; search for missing / empty to (inbox unread)
486 test_expect_equal_file EXPECTED OUTPUT
488 test_begin_subtest "Unbalanced parens"
489 # A code 1 indicates the error was handled (a crash will return e.g. 139).
490 test_expect_code 1 "notmuch search --query=sexp '('"
492 test_begin_subtest "Unbalanced parens, error message"
493 notmuch search --query=sexp '(' >OUTPUT 2>&1
495 notmuch search: Syntax error in query
496 invalid s-expression: '('
498 test_expect_equal_file EXPECTED OUTPUT
500 test_begin_subtest "unknown prefix"
501 notmuch search --query=sexp '(foo)' >OUTPUT 2>&1
503 notmuch search: Syntax error in query
506 test_expect_equal_file EXPECTED OUTPUT
508 test_begin_subtest "list as prefix"
509 notmuch search --query=sexp '((foo))' >OUTPUT 2>&1
511 notmuch search: Syntax error in query
512 unexpected list in field/operation position
514 test_expect_equal_file EXPECTED OUTPUT
516 test_begin_subtest "illegal nesting"
517 notmuch search --query=sexp '(subject (subject foo))' >OUTPUT 2>&1
519 notmuch search: Syntax error in query
520 nested field: 'subject' inside 'subject'
522 test_expect_equal_file EXPECTED OUTPUT
524 test_begin_subtest "starts-with, no argument"
525 notmuch search --query=sexp '(starts-with)' >OUTPUT 2>&1
527 notmuch search: Syntax error in query
528 'starts-with' expects single atom as argument
530 test_expect_equal_file EXPECTED OUTPUT
532 test_begin_subtest "starts-with, list argument"
533 notmuch search --query=sexp '(starts-with (stuff))' >OUTPUT 2>&1
535 notmuch search: Syntax error in query
536 'starts-with' expects single atom as argument
538 test_expect_equal_file EXPECTED OUTPUT
540 test_begin_subtest "starts-with, too many arguments"
541 notmuch search --query=sexp '(starts-with a b c)' >OUTPUT 2>&1
543 notmuch search: Syntax error in query
544 'starts-with' expects single atom as argument
546 test_expect_equal_file EXPECTED OUTPUT
548 test_begin_subtest "starts-with, illegal field"
549 notmuch search --query=sexp '(body (starts-with foo))' >OUTPUT 2>&1
551 notmuch search: Syntax error in query
552 'body' does not support wildcard queries
554 test_expect_equal_file EXPECTED OUTPUT
556 test_begin_subtest "wildcard, illegal field"
557 notmuch search --query=sexp '(body *)' >OUTPUT 2>&1
559 notmuch search: Syntax error in query
560 'body' does not support wildcard queries
562 test_expect_equal_file EXPECTED OUTPUT
564 test_begin_subtest "Search, exclude \"deleted\" messages from search"
565 notmuch config set search.exclude_tags deleted
566 generate_message '[subject]="Not deleted"'
567 not_deleted_id=$gen_msg_id
568 generate_message '[subject]="Deleted"'
569 notmuch new > /dev/null
570 notmuch tag +deleted id:$gen_msg_id
571 deleted_id=$gen_msg_id
572 output=$(notmuch search --query=sexp '(subject deleted)' | notmuch_search_sanitize)
573 test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Not deleted (inbox unread)"
575 test_begin_subtest "Search, exclude \"deleted\" messages from message search --exclude=false"
576 output=$(notmuch search --query=sexp --exclude=false --output=messages '(subject deleted)' | notmuch_search_sanitize)
577 test_expect_equal "$output" "id:$not_deleted_id
580 test_begin_subtest "Search, exclude \"deleted\" messages from search, overridden"
581 notmuch search --query=sexp '(and (subject deleted) (tag deleted))' | notmuch_search_sanitize > OUTPUT
583 thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Deleted (deleted inbox unread)
585 test_expect_equal_file EXPECTED OUTPUT
587 test_begin_subtest "Search, exclude \"deleted\" messages from threads"
588 add_message '[subject]="Not deleted reply"' '[in-reply-to]="<$gen_msg_id>"'
589 output=$(notmuch search --query=sexp '(subject deleted)' | notmuch_search_sanitize)
590 test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Not deleted (inbox unread)
591 thread:XXX 2001-01-05 [1/2] Notmuch Test Suite; Not deleted reply (deleted inbox unread)"
593 test_begin_subtest "Search, don't exclude \"deleted\" messages when --exclude=flag specified"
594 output=$(notmuch search --query=sexp --exclude=flag '(subject deleted)' | notmuch_search_sanitize)
595 test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Not deleted (inbox unread)
596 thread:XXX 2001-01-05 [1/2] Notmuch Test Suite; Deleted (deleted inbox unread)"
598 test_begin_subtest "Search, don't exclude \"deleted\" messages from search if not configured"
599 notmuch config set search.exclude_tags
600 output=$(notmuch search --query=sexp '(subject deleted)' | notmuch_search_sanitize)
601 test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Not deleted (inbox unread)
602 thread:XXX 2001-01-05 [2/2] Notmuch Test Suite; Deleted (deleted inbox unread)"
604 test_begin_subtest "regex at top level"
605 notmuch search --query=sexp '(rx foo)' >& OUTPUT
607 notmuch search: Syntax error in query
608 illegal 'rx' outside field
610 test_expect_equal_file EXPECTED OUTPUT
612 test_begin_subtest "regex in illegal field"
613 notmuch search --query=sexp '(body (regex foo))' >& OUTPUT
615 notmuch search: Syntax error in query
616 'regex' not supported in field 'body'
618 test_expect_equal_file EXPECTED OUTPUT
620 notmuch search --output=messages from:cworth > cworth.msg-ids
622 test_begin_subtest "regexp 'from' search"
623 notmuch search --output=messages --query=sexp '(from (rx cworth))' > OUTPUT
624 test_expect_equal_file cworth.msg-ids OUTPUT
626 test_begin_subtest "regexp search for 'from' 2"
627 notmuch search from:/cworth@cworth.org/ and subject:patch | notmuch_search_sanitize > EXPECTED
628 notmuch search --query=sexp '(and (from (rx cworth@cworth.org)) (subject patch))' \
629 | notmuch_search_sanitize > OUTPUT
630 test_expect_equal_file EXPECTED OUTPUT
632 test_begin_subtest "regexp 'folder' search"
633 notmuch search 'folder:/^bar$/' | notmuch_search_sanitize > EXPECTED
634 notmuch search --query=sexp '(folder (rx ^bar$))' | notmuch_search_sanitize > OUTPUT
635 test_expect_equal_file EXPECTED OUTPUT
637 test_begin_subtest "regexp 'id' search"
638 notmuch search --output=messages --query=sexp '(id (rx yoom))' > OUTPUT
639 test_expect_equal_file cworth.msg-ids OUTPUT
641 test_begin_subtest "unanchored 'is' search"
642 notmuch search tag:signed or tag:inbox > EXPECTED
643 notmuch search --query=sexp '(is (rx i))' > OUTPUT
644 test_expect_equal_file EXPECTED OUTPUT
646 test_begin_subtest "anchored 'is' search"
647 notmuch search tag:signed > EXPECTED
648 notmuch search --query=sexp '(is (rx ^si))' > OUTPUT
649 test_expect_equal_file EXPECTED OUTPUT
651 test_begin_subtest "combine regexp mid and subject"
652 notmuch search subject:/-C/ and mid:/y..m/ | notmuch_search_sanitize > EXPECTED
653 notmuch search --query=sexp '(and (subject (rx -C)) (mid (rx y..m)))' | notmuch_search_sanitize > OUTPUT
654 test_expect_equal_file EXPECTED OUTPUT
656 test_begin_subtest "regexp 'path' search"
657 notmuch search 'path:/^bar$/' | notmuch_search_sanitize > EXPECTED
658 notmuch search --query=sexp '(path (rx ^bar$))' | notmuch_search_sanitize > OUTPUT
659 test_expect_equal_file EXPECTED OUTPUT
661 test_begin_subtest "regexp 'property' search"
662 notmuch search property:foo=bar > EXPECTED
663 notmuch search --query=sexp '(property (rx foo=.*))' > OUTPUT
664 test_expect_equal_file EXPECTED OUTPUT
666 test_begin_subtest "anchored 'tag' search"
667 notmuch search tag:signed > EXPECTED
668 notmuch search --query=sexp '(tag (rx ^si))' > OUTPUT
669 test_expect_equal_file EXPECTED OUTPUT
671 test_begin_subtest "regexp 'thread' search"
672 notmuch search --output=threads '*' | grep '7$' > EXPECTED
673 notmuch search --output=threads --query=sexp '(thread (rx 7$))' > OUTPUT
674 test_expect_equal_file EXPECTED OUTPUT
676 test_begin_subtest "Basic query that matches no messages"
677 count=$(notmuch count from:keithp and to:keithp)
678 test_expect_equal 0 "$count"
680 test_begin_subtest "Same query against threads"
681 notmuch search --query=sexp '(and (thread (of (from keithp))) (thread (matching (to keithp))))' \
682 | notmuch_search_sanitize > OUTPUT
684 thread:XXX 2009-11-18 [7/7] Lars Kellogg-Stedman, Mikhail Gusarov, Keith Packard, Carl Worth; [notmuch] Working with Maildir storage? (inbox signed unread)
686 test_expect_equal_file EXPECTED OUTPUT
688 test_begin_subtest "Mix thread and non-threads query"
689 notmuch search --query=sexp '(and (thread (matching keithp)) (to keithp))' | notmuch_search_sanitize > OUTPUT
691 thread:XXX 2009-11-18 [1/7] Lars Kellogg-Stedman| Mikhail Gusarov, Keith Packard, Carl Worth; [notmuch] Working with Maildir storage? (inbox signed unread)
693 test_expect_equal_file EXPECTED OUTPUT
695 test_begin_subtest "Compound subquery"
696 notmuch search --query=sexp '(thread (of (from keithp) (subject Maildir)))' | notmuch_search_sanitize > OUTPUT
698 thread:XXX 2009-11-18 [7/7] Lars Kellogg-Stedman, Mikhail Gusarov, Keith Packard, Carl Worth; [notmuch] Working with Maildir storage? (inbox signed unread)
700 test_expect_equal_file EXPECTED OUTPUT
702 test_begin_subtest "empty subquery"
703 notmuch search --query=sexp '(thread (of))' 1>OUTPUT 2>&1
704 notmuch search '*' > EXPECTED
705 test_expect_equal_file EXPECTED OUTPUT
707 test_begin_subtest "illegal expansion"
708 notmuch search --query=sexp '(id (of ego))' 1>OUTPUT 2>&1
710 notmuch search: Syntax error in query
711 'of' unsupported inside 'id'
713 test_expect_equal_file EXPECTED OUTPUT
715 test_begin_subtest "(folder (of subquery))"
716 notmuch search --query=sexp --output=messages '(folder (of (id yun3a4cegoa.fsf@aiko.keithp.com)))' > OUTPUT
718 id:yun1vjwegii.fsf@aiko.keithp.com
719 id:yun3a4cegoa.fsf@aiko.keithp.com
720 id:1258509400-32511-1-git-send-email-stewart@flamingspork.com
721 id:1258506353-20352-1-git-send-email-stewart@flamingspork.com
722 id:20091118010116.GC25380@dottiness.seas.harvard.edu
723 id:20091118005829.GB25380@dottiness.seas.harvard.edu
724 id:cf0c4d610911171136h1713aa59w9cf9aa31f052ad0a@mail.gmail.com
726 test_expect_equal_file EXPECTED OUTPUT
728 test_begin_subtest "infix query"
729 notmuch search to:searchbyto | notmuch_search_sanitize > EXPECTED
730 notmuch search --query=sexp '(infix "to:searchbyto")' | notmuch_search_sanitize > OUTPUT
731 test_expect_equal_file EXPECTED OUTPUT
733 test_begin_subtest "bad infix query 1"
734 notmuch search --query=sexp '(infix "from:/unbalanced")' 2>&1| notmuch_search_sanitize > OUTPUT
736 notmuch search: Syntax error in query
737 Syntax error in infix query: from:/unbalanced
739 test_expect_equal_file EXPECTED OUTPUT
741 test_begin_subtest "bad infix query 2"
742 notmuch search --query=sexp '(infix "thread:{unbalanced")' 2>&1| notmuch_search_sanitize > OUTPUT
744 notmuch search: Syntax error in query
745 Syntax error in infix query: thread:{unbalanced
747 test_expect_equal_file EXPECTED OUTPUT
749 test_begin_subtest "bad infix query 3: bad nesting"
750 notmuch search --query=sexp '(subject (infix "tag:inbox"))' 2>&1| notmuch_search_sanitize > OUTPUT
752 notmuch search: Syntax error in query
753 'infix' not supported inside 'subject'
755 test_expect_equal_file EXPECTED OUTPUT
757 test_begin_subtest "infix query that matches no messages"
758 notmuch search --query=sexp '(and (infix "from:keithp") (infix "to:keithp"))' > OUTPUT
759 test_expect_equal_file /dev/null OUTPUT
761 test_begin_subtest "compound infix query"
762 notmuch search date:2009-11-18..2009-11-18 and tag:unread > EXPECTED
763 notmuch search --query=sexp '(infix "date:2009-11-18..2009-11-18 and tag:unread")' > OUTPUT
764 test_expect_equal_file EXPECTED OUTPUT
766 test_begin_subtest "compound infix query 2"
767 notmuch search date:2009-11-18..2009-11-18 and tag:unread > EXPECTED
768 notmuch search --query=sexp '(and (infix "date:2009-11-18..2009-11-18") (infix "tag:unread"))' > OUTPUT
769 test_expect_equal_file EXPECTED OUTPUT
771 test_begin_subtest "date query, empty"
772 notmuch search from:keithp | notmuch_search_sanitize > EXPECTED
773 notmuch search --query=sexp '(and (date) (from keithp))'| notmuch_search_sanitize > OUTPUT
774 test_expect_equal_file EXPECTED OUTPUT
776 test_begin_subtest "date query, one argument"
777 notmuch search date:2009-11-18 and from:keithp | notmuch_search_sanitize > EXPECTED
778 notmuch search --query=sexp '(and (date 2009-11-18) (from keithp))' | notmuch_search_sanitize > OUTPUT
779 test_expect_equal_file EXPECTED OUTPUT
781 test_begin_subtest "date query, two arguments"
782 notmuch search date:2009-11-17..2009-11-18 and from:keithp | notmuch_search_sanitize > EXPECTED
783 notmuch search --query=sexp '(and (date 2009-11-17 2009-11-18) (from keithp))' | notmuch_search_sanitize > OUTPUT
784 test_expect_equal_file EXPECTED OUTPUT
786 test_begin_subtest "date query, illegal nesting 1"
787 notmuch search --query=sexp '(to (date))' > OUTPUT 2>&1
789 notmuch search: Syntax error in query
790 nested field: 'date' inside 'to'
792 test_expect_equal_file EXPECTED OUTPUT
794 test_begin_subtest "date query, illegal nesting 2"
795 notmuch search --query=sexp '(to (date 2021-11-18))' > OUTPUT 2>&1
797 notmuch search: Syntax error in query
798 nested field: 'date' inside 'to'
800 test_expect_equal_file EXPECTED OUTPUT
802 test_begin_subtest "date query, illegal nesting 3"
803 notmuch search --query=sexp '(date (to))' > OUTPUT 2>&1
805 notmuch search: Syntax error in query
806 expected atom as first argument of 'date'
808 test_expect_equal_file EXPECTED OUTPUT
810 test_begin_subtest "date query, illegal nesting 4"
811 notmuch search --query=sexp '(date today (to))' > OUTPUT 2>&1
813 notmuch search: Syntax error in query
814 expected atom as second argument of 'date'
816 test_expect_equal_file EXPECTED OUTPUT
818 test_begin_subtest "date query, too many arguments"
819 notmuch search --query=sexp '(date yesterday and tommorow)' > OUTPUT 2>&1
821 notmuch search: Syntax error in query
822 'date' expects maximum of two arguments
824 test_expect_equal_file EXPECTED OUTPUT
826 test_begin_subtest "date query, bad date"
827 notmuch search --query=sexp '(date "hawaiian-pizza-day")' > OUTPUT 2>&1
829 notmuch search: Syntax error in query
830 Didn't understand date specification 'hawaiian-pizza-day'
832 test_expect_equal_file EXPECTED OUTPUT
834 test_begin_subtest "lastmod query, empty"
835 test_subtest_known_broken
836 notmuch search from:keithp | notmuch_search_sanitize > EXPECTED
837 notmuch search --query=sexp '(and (lastmod) (from keithp))'| notmuch_search_sanitize > OUTPUT
838 test_expect_equal_file EXPECTED OUTPUT
840 test_begin_subtest "lastmod query, one argument"
841 test_subtest_known_broken
842 notmuch tag +4EFC743A.3060609@april.org id:4EFC743A.3060609@april.org
843 revision=$(notmuch count --lastmod '*' | cut -f3)
844 notmuch search lastmod:$revision..$revision | notmuch_search_sanitize > EXPECTED
845 notmuch search --query=sexp "(and (lastmod $revision))" | notmuch_search_sanitize > OUTPUT
846 test_expect_equal_file EXPECTED OUTPUT
848 test_begin_subtest "lastmod query, two arguments"
849 test_subtest_known_broken
850 notmuch tag +keithp from:keithp
851 revision2=$(notmuch count --lastmod '*' | cut -f3)
852 notmuch search lastmod:$revision..$revision2 | notmuch_search_sanitize > EXPECTED
853 notmuch search --query=sexp "(and (lastmod $revision $revision2))" | notmuch_search_sanitize > OUTPUT
854 test_expect_equal_file EXPECTED OUTPUT
856 test_begin_subtest "lastmod query, illegal nesting 1"
857 test_subtest_known_broken
858 notmuch search --query=sexp '(to (lastmod))' > OUTPUT 2>&1
860 notmuch search: Syntax error in query
861 nested field: 'lastmod' inside 'to'
863 test_expect_equal_file EXPECTED OUTPUT
865 test_begin_subtest "lastmod query, bad from revision"
866 test_subtest_known_broken
867 notmuch search --query=sexp '(lastmod apples)' > OUTPUT 2>&1
869 notmuch search: Syntax error in query
870 bad 'from' revision: 'apples'
872 test_expect_equal_file EXPECTED OUTPUT
874 test_begin_subtest "lastmod query, bad to revision"
875 test_subtest_known_broken
876 notmuch search --query=sexp '(lastmod 0 apples)' > OUTPUT 2>&1
878 notmuch search: Syntax error in query
879 bad 'to' revision: 'apples'
881 test_expect_equal_file EXPECTED OUTPUT
883 test_begin_subtest "lastmod query, illegal nesting 2"
884 test_subtest_known_broken
885 notmuch search --query=sexp '(to (lastmod 2021-11-18))' > OUTPUT 2>&1
887 notmuch search: Syntax error in query
888 nested field: 'lastmod' inside 'to'
890 test_expect_equal_file EXPECTED OUTPUT
892 test_begin_subtest "lastmod query, illegal nesting 3"
893 test_subtest_known_broken
894 notmuch search --query=sexp '(lastmod (to))' > OUTPUT 2>&1
896 notmuch search: Syntax error in query
897 expected atom as first argument of 'lastmod'
899 test_expect_equal_file EXPECTED OUTPUT
901 test_begin_subtest "lastmod query, illegal nesting 4"
902 test_subtest_known_broken
903 notmuch search --query=sexp '(lastmod today (to))' > OUTPUT 2>&1
905 notmuch search: Syntax error in query
906 expected atom as second argument of 'lastmod'
908 test_expect_equal_file EXPECTED OUTPUT
910 test_begin_subtest "lastmod query, too many arguments"
911 test_subtest_known_broken
912 notmuch search --query=sexp '(lastmod yesterday and tommorow)' > OUTPUT 2>&1
914 notmuch search: Syntax error in query
915 'lastmod' expects maximum of two arguments
917 test_expect_equal_file EXPECTED OUTPUT
919 test_begin_subtest "user header (unknown header)"
920 notmuch search --query=sexp '(FooBar)' >& OUTPUT
922 notmuch search: Syntax error in query
923 unknown prefix 'FooBar'
925 test_expect_equal_file EXPECTED OUTPUT
927 test_begin_subtest "adding user header"
928 test_expect_code 0 "notmuch config set index.header.List \"List-Id\""
930 test_begin_subtest "reindexing"
931 test_expect_code 0 'notmuch reindex "*"'
933 test_begin_subtest "wildcard search for user header"
934 grep -Ril List-Id ${MAIL_DIR} | sort | notmuch_dir_sanitize > EXPECTED
935 notmuch search --output=files --query=sexp '(List *)' | sort | notmuch_dir_sanitize > OUTPUT
936 test_expect_equal_file EXPECTED OUTPUT
938 test_begin_subtest "wildcard search for user header 2"
939 grep -Ril List-Id ${MAIL_DIR} | sort | notmuch_dir_sanitize > EXPECTED
940 notmuch search --output=files --query=sexp '(List (starts-with not))' | sort | notmuch_dir_sanitize > OUTPUT
941 test_expect_equal_file EXPECTED OUTPUT
943 test_begin_subtest "search for user header"
944 notmuch search List:notmuch | notmuch_search_sanitize > EXPECTED
945 notmuch search --query=sexp '(List notmuch)' | notmuch_search_sanitize > OUTPUT
946 test_expect_equal_file EXPECTED OUTPUT
948 test_begin_subtest "search for user header (list token)"
949 notmuch search List:notmuch | notmuch_search_sanitize > EXPECTED
950 notmuch search --query=sexp '(List notmuch.notmuchmail.org)' | notmuch_search_sanitize > OUTPUT
951 test_expect_equal_file EXPECTED OUTPUT
953 test_begin_subtest "search for user header (quoted string)"
954 notmuch search 'List:"notmuch notmuchmail org"' | notmuch_search_sanitize > EXPECTED
955 notmuch search --query=sexp '(List "notmuch notmuchmail org")' | notmuch_search_sanitize > OUTPUT
956 test_expect_equal_file EXPECTED OUTPUT
958 test_begin_subtest "search for user header (atoms)"
959 notmuch search 'List:"notmuch notmuchmail org"' | notmuch_search_sanitize > EXPECTED
960 notmuch search --query=sexp '(List notmuch notmuchmail org)' | notmuch_search_sanitize > OUTPUT
961 test_expect_equal_file EXPECTED OUTPUT
963 test_begin_subtest "check saved query name"
964 test_expect_code 1 "notmuch config set squery.test '(subject utf8-sübjéct)'"
966 test_begin_subtest "roundtrip saved query (database)"
967 notmuch config set --database squery.Test '(subject utf8-sübjéct)'
968 output=$(notmuch config get squery.Test)
969 test_expect_equal "$output" '(subject utf8-sübjéct)'
971 test_begin_subtest "roundtrip saved query"
972 notmuch config set squery.Test '(subject override subject)'
973 output=$(notmuch config get squery.Test)
974 test_expect_equal "$output" '(subject override subject)'
976 test_begin_subtest "unknown saved query"
977 notmuch search --query=sexp '(Unknown foo bar)' >OUTPUT 2>&1
979 notmuch search: Syntax error in query
980 unknown prefix 'Unknown'
982 test_expect_equal_file EXPECTED OUTPUT
984 test_begin_subtest "syntax error in saved query"
985 notmuch config set squery.Bad '(Bad'
986 notmuch search --query=sexp '(Bad foo bar)' >OUTPUT 2>&1
988 notmuch search: Syntax error in query
989 invalid saved s-expression query: '(Bad'
991 test_expect_equal_file EXPECTED OUTPUT
993 test_begin_subtest "Saved Search by 'tag' and 'subject'"
994 notmuch search tag:inbox and subject:maildir | notmuch_search_sanitize > EXPECTED
995 notmuch config set squery.TagSubject '(and (tag inbox) (subject maildir))'
996 notmuch search --query=sexp '(TagSubject)' | notmuch_search_sanitize > OUTPUT
997 test_expect_equal_file EXPECTED OUTPUT
999 test_begin_subtest "Saved Search: illegal nesting"
1000 notmuch config set squery.TagSubject '(and (tag inbox) (subject maildir))'
1001 notmuch search --query=sexp '(subject (TagSubject))' >OUTPUT 2>&1
1002 cat <<EOF > EXPECTED
1003 notmuch search: Syntax error in query
1004 nested field: 'tag' inside 'subject'
1006 test_expect_equal_file EXPECTED OUTPUT
1008 test_begin_subtest "Saved Search: list as prefix"
1009 notmuch config set squery.Bad2 '((and) (tag inbox) (subject maildir))'
1010 notmuch search --query=sexp '(Bad2)' >OUTPUT 2>&1
1011 cat <<EOF > EXPECTED
1012 notmuch search: Syntax error in query
1013 unexpected list in field/operation position
1015 test_expect_equal_file EXPECTED OUTPUT
1017 test_begin_subtest "Saved Search: bad parameter syntax"
1018 notmuch config set squery.Bad3 '(macro a b)'
1019 notmuch search --query=sexp '(Bad3)' >OUTPUT 2>&1
1020 cat <<EOF > EXPECTED
1021 notmuch search: Syntax error in query
1022 missing (possibly empty) list of arguments to macro
1024 test_expect_equal_file EXPECTED OUTPUT
1026 test_begin_subtest "Saved Search: bad parameter syntax 2"
1027 notmuch config set squery.Bad4 '(macro ((a b)) a)'
1028 notmuch search --query=sexp '(Bad4 1)' >OUTPUT 2>&1
1029 cat <<EOF > EXPECTED
1030 notmuch search: Syntax error in query
1031 macro parameters must be unquoted atoms
1033 test_expect_equal_file EXPECTED OUTPUT
1035 test_begin_subtest "Saved Search: bad parameter syntax 3"
1036 notmuch config set squery.Bad5 '(macro (a b) a)'
1037 notmuch search --query=sexp '(Bad5 1)' >OUTPUT 2>&1
1038 cat <<EOF > EXPECTED
1039 notmuch search: Syntax error in query
1040 too few arguments to macro
1042 test_expect_equal_file EXPECTED OUTPUT
1044 test_begin_subtest "Saved Search: bad parameter syntax 4"
1045 notmuch search --query=sexp '(Bad5 1 2 3)' >OUTPUT 2>&1
1046 cat <<EOF > EXPECTED
1047 notmuch search: Syntax error in query
1048 too many arguments to macro
1050 test_expect_equal_file EXPECTED OUTPUT
1052 test_begin_subtest "Saved Search: macro without body"
1053 notmuch config set squery.Bad3 '(macro (a b))'
1054 notmuch search --query=sexp '(Bad3)' >OUTPUT 2>&1
1055 cat <<EOF > EXPECTED
1056 notmuch search: Syntax error in query
1057 missing body of macro
1059 test_expect_equal_file EXPECTED OUTPUT
1061 test_begin_subtest "macro in query"
1062 notmuch search --query=sexp '(macro (a) (and ,b (subject maildir)))' >OUTPUT 2>&1
1063 cat <<EOF > EXPECTED
1064 notmuch search: Syntax error in query
1065 macro definition not permitted here
1067 test_expect_equal_file EXPECTED OUTPUT
1069 test_begin_subtest "zero argument macro"
1070 notmuch search tag:inbox and subject:maildir | notmuch_search_sanitize > EXPECTED
1071 notmuch config set squery.TagSubject0 '(macro () (and (tag inbox) (subject maildir)))'
1072 notmuch search --query=sexp '(TagSubject0)' | notmuch_search_sanitize > OUTPUT
1073 test_expect_equal_file EXPECTED OUTPUT
1075 test_begin_subtest "undefined argument"
1076 notmuch search tag:inbox and subject:maildir | notmuch_search_sanitize > EXPECTED
1077 notmuch config set squery.Bad6 '(macro (a) (and ,b (subject maildir)))'
1078 notmuch search --query=sexp '(Bad6 foo)' >OUTPUT 2>&1
1079 cat <<EOF > EXPECTED
1080 notmuch search: Syntax error in query
1081 undefined parameter b
1083 test_expect_equal_file EXPECTED OUTPUT
1085 test_begin_subtest "Single argument macro"
1086 notmuch search tag:inbox and subject:maildir | notmuch_search_sanitize > EXPECTED
1087 notmuch config set squery.TagSubject1 '(macro (tagname) (and (tag ,tagname) (subject maildir)))'
1088 notmuch search --query=sexp '(TagSubject1 inbox)' | notmuch_search_sanitize > OUTPUT
1089 test_expect_equal_file EXPECTED OUTPUT
1091 test_begin_subtest "Single argument macro, list argument"
1092 notmuch search tag:inbox and subject:maildir | notmuch_search_sanitize > EXPECTED
1093 notmuch config set squery.ThingSubject '(macro (thing) (and ,thing (subject maildir)))'
1094 notmuch search --query=sexp '(ThingSubject (tag inbox))' | notmuch_search_sanitize > OUTPUT
1095 test_expect_equal_file EXPECTED OUTPUT
1097 test_begin_subtest "two argument macro"
1098 notmuch search tag:inbox and subject:maildir | notmuch_search_sanitize > EXPECTED
1099 notmuch config set squery.TagSubject2 '(macro (tagname subj) (and (tag ,tagname) (subject ,subj)))'
1100 notmuch search --query=sexp '(TagSubject2 inbox maildir)' | notmuch_search_sanitize > OUTPUT
1101 test_expect_equal_file EXPECTED OUTPUT
1103 test_begin_subtest "nested macros (shadowing)"
1104 notmuch search tag:inbox and subject:maildir | notmuch_search_sanitize > EXPECTED
1105 notmuch config set squery.Inner '(macro (x) (subject ,x))'
1106 notmuch config set squery.Outer '(macro (x y) (and (tag ,x) (Inner ,y)))'
1107 notmuch search --query=sexp '(Outer inbox maildir)' | notmuch_search_sanitize > OUTPUT
1108 test_expect_equal_file EXPECTED OUTPUT
1110 test_begin_subtest "nested macros (no dynamic scope)"
1111 notmuch config set squery.Inner2 '(macro (x) (subject ,y))'
1112 notmuch config set squery.Outer2 '(macro (x y) (and (tag ,x) (Inner2 ,y)))'
1113 notmuch search --query=sexp '(Outer2 inbox maildir)' > OUTPUT 2>&1
1114 cat <<EOF > EXPECTED
1115 notmuch search: Syntax error in query
1116 undefined parameter y
1118 test_expect_equal_file EXPECTED OUTPUT
1120 test_begin_subtest "combine macro and user defined header"
1121 notmuch config set squery.About '(macro (name) (or (subject ,name) (List ,name)))'
1122 notmuch search subject:notmuch or List:notmuch | notmuch_search_sanitize > EXPECTED
1123 notmuch search --query=sexp '(About notmuch)' | notmuch_search_sanitize > OUTPUT
1124 test_expect_equal_file EXPECTED OUTPUT
1127 test_begin_subtest "combine macro and user defined header"
1128 notmuch config set squery.About '(macro (name) (or (subject ,name) (List ,name)))'
1129 notmuch search subject:notmuch or List:notmuch | notmuch_search_sanitize > EXPECTED
1130 notmuch search --query=sexp '(About notmuch)' | notmuch_search_sanitize > OUTPUT
1131 test_expect_equal_file EXPECTED OUTPUT