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 'folder' with --output=files"
189 output=$(notmuch search --output=files --query=sexp '(folder bad/news)' | notmuch_search_files_sanitize)
190 test_expect_equal "$output" "MAIL_DIR/bad/news/msg-XXX
191 MAIL_DIR/duplicate/bad/news/msg-XXX"
193 test_begin_subtest "Search by 'folder' with --output=files (trailing /)"
194 test_subtest_known_broken
195 output=$(notmuch search --output=files --query=sexp '(folder bad/news/)' | notmuch_search_files_sanitize)
196 test_expect_equal "$output" "MAIL_DIR/bad/news/msg-XXX
197 MAIL_DIR/duplicate/bad/news/msg-XXX"
199 test_begin_subtest "Search by 'folder' (multiple)"
200 output=$(notmuch search --query=sexp '(folder bad bad/news things/bad)' | notmuch_search_sanitize)
201 test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; To the bone (inbox unread)
202 thread:XXX 2001-01-05 [1/1(2)] Notmuch Test Suite; Bears (inbox unread)
203 thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Bites, stings, sad feelings (inbox unread)"
205 test_begin_subtest "Search by 'folder' (multiple, trailing /)"
206 test_subtest_known_broken
207 output=$(notmuch search --query=sexp '(folder bad bad/news/ things/bad)' | notmuch_search_sanitize)
208 test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; To the bone (inbox unread)
209 thread:XXX 2001-01-05 [1/1(2)] Notmuch Test Suite; Bears (inbox unread)
210 thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Bites, stings, sad feelings (inbox unread)"
212 test_begin_subtest "Search by 'path' with --output=files"
213 output=$(notmuch search --output=files --query=sexp '(path bad/news)' | notmuch_search_files_sanitize)
214 test_expect_equal "$output" "MAIL_DIR/bad/news/msg-XXX
215 MAIL_DIR/duplicate/bad/news/msg-XXX"
217 test_begin_subtest "Search by 'path' with --output=files (trailing /)"
218 test_subtest_known_broken
219 output=$(notmuch search --output=files --query=sexp '(path bad/news/)' | notmuch_search_files_sanitize)
220 test_expect_equal "$output" "MAIL_DIR/bad/news/msg-XXX
221 MAIL_DIR/duplicate/bad/news/msg-XXX"
223 test_begin_subtest "Search by 'path' specification (multiple)"
224 output=$(notmuch search --query=sexp '(path bad bad/news things/bad)' | notmuch_search_sanitize)
225 test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; To the bone (inbox unread)
226 thread:XXX 2001-01-05 [1/1(2)] Notmuch Test Suite; Bears (inbox unread)
227 thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Bites, stings, sad feelings (inbox unread)"
229 test_begin_subtest "Search by 'path' specification (multiple, trailing /)"
230 test_subtest_known_broken
231 output=$(notmuch search --query=sexp '(path bad bad/news/ things/bad)' | notmuch_search_sanitize)
232 test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; To the bone (inbox unread)
233 thread:XXX 2001-01-05 [1/1(2)] Notmuch Test Suite; Bears (inbox unread)
234 thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Bites, stings, sad feelings (inbox unread)"
236 test_begin_subtest "Search by 'id'"
237 add_message '[subject]="search by id"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"'
238 output=$(notmuch search --query=sexp "(id ${gen_msg_id})" | notmuch_search_sanitize)
239 test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by id (inbox unread)"
241 test_begin_subtest "Search by 'id' (or)"
242 add_message '[subject]="search by id"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"'
243 output=$(notmuch search --query=sexp "(id non-existent-mid ${gen_msg_id})" | notmuch_search_sanitize)
244 test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by id (inbox unread)"
246 test_begin_subtest "Search by 'is' (multiple)"
247 notmuch tag -inbox tag:searchbytag
248 notmuch search is:inbox AND is:unread | notmuch_search_sanitize > EXPECTED
249 notmuch search --query=sexp '(is inbox unread)' | notmuch_search_sanitize > OUTPUT
250 notmuch tag +inbox tag:searchbytag
251 test_expect_equal_file EXPECTED OUTPUT
253 test_begin_subtest "Search by 'mid'"
254 add_message '[subject]="search by mid"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"'
255 output=$(notmuch search --query=sexp "(mid ${gen_msg_id})" | notmuch_search_sanitize)
256 test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by mid (inbox unread)"
258 test_begin_subtest "Search by 'mid' (or)"
259 add_message '[subject]="search by mid"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"'
260 output=$(notmuch search --query=sexp "(mid non-existent-mid ${gen_msg_id})" | notmuch_search_sanitize)
261 test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by mid (inbox unread)"
263 test_begin_subtest "Search by 'mimetype'"
264 notmuch search mimetype:text/html > EXPECTED
265 notmuch search --query=sexp '(mimetype text html)' > OUTPUT
266 test_expect_equal_file EXPECTED OUTPUT
268 QUERYSTR="date:2009-11-18..2009-11-18 and tag:unread"
269 QUERYSTR2="query:test and subject:Maildir"
270 notmuch config set --database query.test "$QUERYSTR"
271 notmuch config set query.test2 "$QUERYSTR2"
273 test_begin_subtest "ill-formed named query search"
274 notmuch search --query=sexp '(query)' > OUTPUT 2>&1
276 notmuch search: Syntax error in query
277 'query' expects single atom as argument
279 test_expect_equal_file EXPECTED OUTPUT
281 test_begin_subtest "ill-formed named query search 2"
282 notmuch search --query=sexp '(to (query))' > OUTPUT 2>&1
284 notmuch search: Syntax error in query
285 'query' not supported inside 'to'
287 test_expect_equal_file EXPECTED OUTPUT
289 test_begin_subtest "search named query"
290 notmuch search --query=sexp '(query test)' > OUTPUT
291 notmuch search $QUERYSTR > EXPECTED
292 test_expect_equal_file EXPECTED OUTPUT
294 test_begin_subtest "Search by 'subject' (utf-8, phrase-token):"
295 output=$(notmuch search --query=sexp '(subject utf8-sübjéct)' | notmuch_search_sanitize)
296 test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; utf8-sübjéct (inbox unread)"
298 test_begin_subtest "search named query with other terms"
299 notmuch search --query=sexp '(and (query test) (subject Maildir))' > OUTPUT
300 notmuch search $QUERYSTR and subject:Maildir > EXPECTED
301 test_expect_equal_file EXPECTED OUTPUT
303 test_begin_subtest "search nested named query"
304 notmuch search --query=sexp '(query test2)' > OUTPUT
305 notmuch search $QUERYSTR2 > EXPECTED
306 test_expect_equal_file EXPECTED OUTPUT
308 test_begin_subtest "Search by 'subject' (utf-8, quoted string):"
309 output=$(notmuch search --query=sexp '(subject "utf8 sübjéct")' | notmuch_search_sanitize)
310 test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; utf8-sübjéct (inbox unread)"
312 test_begin_subtest "Search by 'subject' (combine phrase, term):"
313 output=$(notmuch search --query=sexp '(subject Mac "compatibility issues")' | notmuch_search_sanitize)
314 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)"
316 test_begin_subtest "Search by 'subject' (combine phrase, term 2):"
317 notmuch search --query=sexp '(subject (or utf8 "compatibility issues"))' | notmuch_search_sanitize > OUTPUT
319 thread:XXX 2009-11-18 [4/4] Jjgod Jiang, Alexander Botero-Lowry; [notmuch] Mac OS X/Darwin compatibility issues (inbox unread)
320 thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; utf8-sübjéct (inbox unread)
321 thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; utf8-message-body-subject (inbox unread)
323 test_expect_equal_file EXPECTED OUTPUT
325 test_begin_subtest "Search by 'subject' (combine phrase, term 3):"
326 notmuch search --query=sexp '(subject issues X/Darwin)' | notmuch_search_sanitize > OUTPUT
328 thread:XXX 2009-11-18 [4/4] Jjgod Jiang, Alexander Botero-Lowry; [notmuch] Mac OS X/Darwin compatibility issues (inbox unread)
330 test_expect_equal_file EXPECTED OUTPUT
332 test_begin_subtest "Search by 'tag'"
333 add_message '[subject]="search by tag"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"'
334 notmuch tag +searchbytag id:${gen_msg_id}
335 output=$(notmuch search --query=sexp '(tag searchbytag)' | notmuch_search_sanitize)
336 test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by tag (inbox searchbytag unread)"
338 test_begin_subtest "Search by 'tag' (multiple)"
339 notmuch tag -inbox tag:searchbytag
340 notmuch search tag:inbox AND tag:unread | notmuch_search_sanitize > EXPECTED
341 notmuch search --query=sexp '(tag inbox unread)' | notmuch_search_sanitize > OUTPUT
342 notmuch tag +inbox tag:searchbytag
343 test_expect_equal_file EXPECTED OUTPUT
345 test_begin_subtest "Search by 'tag' and 'subject'"
346 notmuch search tag:inbox and subject:maildir | notmuch_search_sanitize > EXPECTED
347 notmuch search --query=sexp '(and (tag inbox) (subject maildir))' | notmuch_search_sanitize > OUTPUT
348 test_expect_equal_file EXPECTED OUTPUT
350 test_begin_subtest "Search by 'thread'"
351 add_message '[subject]="search by thread"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"'
352 thread_id=$(notmuch search id:${gen_msg_id} | sed -e "s/thread:\([a-f0-9]*\).*/\1/")
353 output=$(notmuch search --query=sexp "(thread ${thread_id})" | notmuch_search_sanitize)
354 test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by thread (inbox unread)"
356 test_begin_subtest "Search by 'to'"
357 add_message '[subject]="search by to"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' [to]=searchbyto
358 output=$(notmuch search --query=sexp '(to searchbyto)' | notmuch_search_sanitize)
359 test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by to (inbox unread)"
361 test_begin_subtest "Search by 'to' (address)"
362 add_message '[subject]="search by to (address)"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' [to]=searchbyto@example.com
363 output=$(notmuch search --query=sexp '(to searchbyto@example.com)' | notmuch_search_sanitize)
364 test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by to (address) (inbox unread)"
366 test_begin_subtest "Search by 'to' (name)"
367 add_message '[subject]="search by to (name)"' '[date]="Sat, 01 Jan 2000 12:00:00 -0000"' '[to]="Search By To Name <test@example.com>"'
368 output=$(notmuch search --query=sexp '(to "Search By To Name")' | notmuch_search_sanitize)
369 test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by to (name) (inbox unread)"
371 test_begin_subtest "Search by 'to' (name and address)"
372 output=$(notmuch search --query=sexp '(to "Search By To Name <test@example.com>")' | notmuch_search_sanitize)
373 test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by to (name) (inbox unread)"
375 test_begin_subtest "starts-with, no prefix"
376 output=$(notmuch search --query=sexp '(starts-with prelim)' | notmuch_search_sanitize)
377 test_expect_equal "$output" "thread:XXX 2009-11-17 [2/2] Alex Botero-Lowry, Carl Worth; [notmuch] preliminary FreeBSD support (attachment inbox unread)"
379 test_begin_subtest "starts-with, case-insensitive"
380 notmuch search --query=sexp '(starts-with FreeB)' | notmuch_search_sanitize > OUTPUT
382 thread:XXX 2009-11-18 [3/4] Alexander Botero-Lowry, Jjgod Jiang; [notmuch] Mac OS X/Darwin compatibility issues (inbox unread)
383 thread:XXX 2009-11-17 [2/2] Alex Botero-Lowry, Carl Worth; [notmuch] preliminary FreeBSD support (attachment inbox unread)
385 test_expect_equal_file EXPECTED OUTPUT
387 test_begin_subtest "starts-with, no prefix, all messages"
388 notmuch search --query=sexp '(starts-with "")' | notmuch_search_sanitize > OUTPUT
389 notmuch search '*' | notmuch_search_sanitize > EXPECTED
390 test_expect_equal_file EXPECTED OUTPUT
392 test_begin_subtest "starts-with, attachment"
393 output=$(notmuch search --query=sexp '(attachment (starts-with not))' | notmuch_search_sanitize)
394 test_expect_equal "$output" 'thread:XXX 2009-11-18 [2/2] Lars Kellogg-Stedman; [notmuch] "notmuch help" outputs to stderr? (attachment inbox signed unread)'
396 test_begin_subtest "starts-with, folder"
397 notmuch search --output=files --query=sexp '(folder (starts-with bad))' | notmuch_search_files_sanitize > OUTPUT
400 MAIL_DIR/bad/news/msg-XXX
401 MAIL_DIR/duplicate/bad/news/msg-XXX
403 test_expect_equal_file EXPECTED OUTPUT
405 test_begin_subtest "starts-with, from"
406 notmuch search --query=sexp '(from (starts-with Mik))' | notmuch_search_sanitize > OUTPUT
408 thread:XXX 2009-11-17 [1/1] Mikhail Gusarov; [notmuch] [PATCH] Handle rename of message file (inbox unread)
409 thread:XXX 2009-11-17 [2/7] Mikhail Gusarov| Lars Kellogg-Stedman, Keith Packard, Carl Worth; [notmuch] Working with Maildir storage? (inbox signed unread)
410 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)
412 test_expect_equal_file EXPECTED OUTPUT
414 test_begin_subtest "starts-with, id"
415 notmuch search --query=sexp --output=messages '(id (starts-with 877))' > OUTPUT
417 id:877h1wv7mg.fsf@inf-8657.int-evry.fr
418 id:877htoqdbo.fsf@yoom.home.cworth.org
420 test_expect_equal_file EXPECTED OUTPUT
422 test_begin_subtest "starts-with, is"
423 output=$(notmuch search --query=sexp '(is (starts-with searchby))' | notmuch_search_sanitize)
424 test_expect_equal "$output" 'thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by tag (inbox searchbytag unread)'
426 test_begin_subtest "starts-with, mid"
427 notmuch search --query=sexp --output=messages '(mid (starts-with 877))' > OUTPUT
429 id:877h1wv7mg.fsf@inf-8657.int-evry.fr
430 id:877htoqdbo.fsf@yoom.home.cworth.org
432 test_expect_equal_file EXPECTED OUTPUT
434 test_begin_subtest "starts-with, mimetype"
435 notmuch search --query=sexp '(mimetype (starts-with sig))' | notmuch_search_sanitize > OUTPUT
437 thread:XXX 2009-11-18 [2/2] Lars Kellogg-Stedman; [notmuch] "notmuch help" outputs to stderr? (attachment inbox signed unread)
438 thread:XXX 2009-11-18 [4/7] Lars Kellogg-Stedman, Mikhail Gusarov| Keith Packard, Carl Worth; [notmuch] Working with Maildir storage? (inbox signed unread)
439 thread:XXX 2009-11-17 [1/3] Adrian Perez de Castro| Keith Packard, Carl Worth; [notmuch] Introducing myself (inbox signed unread)
441 test_expect_equal_file EXPECTED OUTPUT
443 add_message '[subject]="message with properties"'
444 notmuch restore <<EOF
445 #= ${gen_msg_id} foo=bar
448 test_begin_subtest "starts-with, property"
449 notmuch search --query=sexp '(property (starts-with foo=))' | notmuch_search_sanitize > OUTPUT
451 thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; message with properties (inbox unread)
453 test_expect_equal_file EXPECTED OUTPUT
455 test_begin_subtest "starts-with, subject"
456 notmuch search --query=sexp '(subject (starts-with FreeB))' | notmuch_search_sanitize > OUTPUT
458 thread:XXX 2009-11-17 [2/2] Alex Botero-Lowry, Carl Worth; [notmuch] preliminary FreeBSD support (attachment inbox unread)
460 test_expect_equal_file EXPECTED OUTPUT
462 test_begin_subtest "starts-with, tag"
463 output=$(notmuch search --query=sexp '(tag (starts-with searchby))' | notmuch_search_sanitize)
464 test_expect_equal "$output" 'thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by tag (inbox searchbytag unread)'
466 add_message '[subject]="no tags"'
467 notag_mid=${gen_msg_id}
468 notmuch tag -unread -inbox id:${notag_mid}
470 test_begin_subtest "negated starts-with, tag"
471 output=$(notmuch search --query=sexp '(tag (not (starts-with in)))' | notmuch_search_sanitize)
472 test_expect_equal "$output" 'thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; no tags ()'
474 test_begin_subtest "negated starts-with, tag 2"
475 output=$(notmuch search --query=sexp '(not (tag (starts-with in)))' | notmuch_search_sanitize)
476 test_expect_equal "$output" 'thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; no tags ()'
478 test_begin_subtest "negated starts-with, tag 3"
479 output=$(notmuch search --query=sexp '(not (tag (starts-with "")))' | notmuch_search_sanitize)
480 test_expect_equal "$output" 'thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; no tags ()'
482 test_begin_subtest "starts-with, thread"
483 notmuch search --query=sexp '(thread (starts-with "00"))' > OUTPUT
484 notmuch search '*' > EXPECTED
485 test_expect_equal_file EXPECTED OUTPUT
487 test_begin_subtest "starts-with, to"
488 notmuch search --query=sexp '(to (starts-with "search"))' | notmuch_search_sanitize > OUTPUT
490 thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by to (inbox unread)
491 thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by to (address) (inbox unread)
492 thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; search by to (name) (inbox unread)
494 test_expect_equal_file EXPECTED OUTPUT
496 test_begin_subtest "wildcard search for 'is'"
497 notmuch search not id:${notag_mid} > EXPECTED
498 notmuch search --query=sexp '(is *)' > OUTPUT
499 test_expect_equal_file EXPECTED OUTPUT
501 test_begin_subtest "negated wildcard search for 'is'"
502 notmuch search id:${notag_mid} > EXPECTED
503 notmuch search --query=sexp '(not (is *))' > OUTPUT
504 test_expect_equal_file EXPECTED OUTPUT
506 test_begin_subtest "wildcard search for 'property'"
507 notmuch search property:foo=bar > EXPECTED
508 notmuch search --query=sexp '(property *)' > OUTPUT
509 test_expect_equal_file EXPECTED OUTPUT
511 test_begin_subtest "wildcard search for 'tag'"
512 notmuch search not id:${notag_mid} > EXPECTED
513 notmuch search --query=sexp '(tag *)' > OUTPUT
514 test_expect_equal_file EXPECTED OUTPUT
516 test_begin_subtest "negated wildcard search for 'tag'"
517 notmuch search id:${notag_mid} > EXPECTED
518 notmuch search --query=sexp '(not (tag *))' > OUTPUT
519 test_expect_equal_file EXPECTED OUTPUT
521 add_message '[subject]="message with tag \"*\""'
522 notmuch tag '+*' id:${gen_msg_id}
524 test_begin_subtest "search for 'tag' \"*\""
525 output=$(notmuch search --query=sexp --output=messages '(tag "*")')
526 test_expect_equal "$output" "id:$gen_msg_id"
528 test_begin_subtest "search for missing / empty to"
529 add_message [to]="undisclosed-recipients:"
530 notmuch search --query=sexp '(not (to *))' | notmuch_search_sanitize > OUTPUT
532 thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; search for missing / empty to (inbox unread)
534 test_expect_equal_file EXPECTED OUTPUT
536 test_begin_subtest "Unbalanced parens"
537 # A code 1 indicates the error was handled (a crash will return e.g. 139).
538 test_expect_code 1 "notmuch search --query=sexp '('"
540 test_begin_subtest "Unbalanced parens, error message"
541 notmuch search --query=sexp '(' >OUTPUT 2>&1
543 notmuch search: Syntax error in query
544 invalid s-expression: '('
546 test_expect_equal_file EXPECTED OUTPUT
548 test_begin_subtest "unknown prefix"
549 notmuch search --query=sexp '(foo)' >OUTPUT 2>&1
551 notmuch search: Syntax error in query
554 test_expect_equal_file EXPECTED OUTPUT
556 test_begin_subtest "list as prefix"
557 notmuch search --query=sexp '((foo))' >OUTPUT 2>&1
559 notmuch search: Syntax error in query
560 unexpected list in field/operation position
562 test_expect_equal_file EXPECTED OUTPUT
564 test_begin_subtest "illegal nesting"
565 notmuch search --query=sexp '(subject (subject foo))' >OUTPUT 2>&1
567 notmuch search: Syntax error in query
568 nested field: 'subject' inside 'subject'
570 test_expect_equal_file EXPECTED OUTPUT
572 test_begin_subtest "starts-with, no argument"
573 notmuch search --query=sexp '(starts-with)' >OUTPUT 2>&1
575 notmuch search: Syntax error in query
576 'starts-with' expects single atom as argument
578 test_expect_equal_file EXPECTED OUTPUT
580 test_begin_subtest "starts-with, list argument"
581 notmuch search --query=sexp '(starts-with (stuff))' >OUTPUT 2>&1
583 notmuch search: Syntax error in query
584 'starts-with' expects single atom as argument
586 test_expect_equal_file EXPECTED OUTPUT
588 test_begin_subtest "starts-with, too many arguments"
589 notmuch search --query=sexp '(starts-with a b c)' >OUTPUT 2>&1
591 notmuch search: Syntax error in query
592 'starts-with' expects single atom as argument
594 test_expect_equal_file EXPECTED OUTPUT
596 test_begin_subtest "starts-with, illegal field"
597 notmuch search --query=sexp '(body (starts-with foo))' >OUTPUT 2>&1
599 notmuch search: Syntax error in query
600 'body' does not support wildcard queries
602 test_expect_equal_file EXPECTED OUTPUT
604 test_begin_subtest "wildcard, illegal field"
605 notmuch search --query=sexp '(body *)' >OUTPUT 2>&1
607 notmuch search: Syntax error in query
608 'body' does not support wildcard queries
610 test_expect_equal_file EXPECTED OUTPUT
612 test_begin_subtest "Search, exclude \"deleted\" messages from search"
613 notmuch config set search.exclude_tags deleted
614 generate_message '[subject]="Not deleted"'
615 not_deleted_id=$gen_msg_id
616 generate_message '[subject]="Deleted"'
617 notmuch new > /dev/null
618 notmuch tag +deleted id:$gen_msg_id
619 deleted_id=$gen_msg_id
620 output=$(notmuch search --query=sexp '(subject deleted)' | notmuch_search_sanitize)
621 test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Not deleted (inbox unread)"
623 test_begin_subtest "Search, exclude \"deleted\" messages from message search --exclude=false"
624 output=$(notmuch search --query=sexp --exclude=false --output=messages '(subject deleted)' | notmuch_search_sanitize)
625 test_expect_equal "$output" "id:$not_deleted_id
628 test_begin_subtest "Search, exclude \"deleted\" messages from search, overridden"
629 notmuch search --query=sexp '(and (subject deleted) (tag deleted))' | notmuch_search_sanitize > OUTPUT
631 thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Deleted (deleted inbox unread)
633 test_expect_equal_file EXPECTED OUTPUT
635 test_begin_subtest "Search, exclude \"deleted\" messages from threads"
636 add_message '[subject]="Not deleted reply"' '[in-reply-to]="<$gen_msg_id>"'
637 output=$(notmuch search --query=sexp '(subject deleted)' | notmuch_search_sanitize)
638 test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Not deleted (inbox unread)
639 thread:XXX 2001-01-05 [1/2] Notmuch Test Suite; Not deleted reply (deleted inbox unread)"
641 test_begin_subtest "Search, don't exclude \"deleted\" messages when --exclude=flag specified"
642 output=$(notmuch search --query=sexp --exclude=flag '(subject deleted)' | notmuch_search_sanitize)
643 test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Not deleted (inbox unread)
644 thread:XXX 2001-01-05 [1/2] Notmuch Test Suite; Deleted (deleted inbox unread)"
646 test_begin_subtest "Search, don't exclude \"deleted\" messages from search if not configured"
647 notmuch config set search.exclude_tags
648 output=$(notmuch search --query=sexp '(subject deleted)' | notmuch_search_sanitize)
649 test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Not deleted (inbox unread)
650 thread:XXX 2001-01-05 [2/2] Notmuch Test Suite; Deleted (deleted inbox unread)"
652 test_begin_subtest "regex at top level"
653 notmuch search --query=sexp '(rx foo)' >& OUTPUT
655 notmuch search: Syntax error in query
656 illegal 'rx' outside field
658 test_expect_equal_file EXPECTED OUTPUT
660 test_begin_subtest "regex in illegal field"
661 notmuch search --query=sexp '(body (regex foo))' >& OUTPUT
663 notmuch search: Syntax error in query
664 'regex' not supported in field 'body'
666 test_expect_equal_file EXPECTED OUTPUT
668 notmuch search --output=messages from:cworth > cworth.msg-ids
670 test_begin_subtest "regexp 'from' search"
671 notmuch search --output=messages --query=sexp '(from (rx cworth))' > OUTPUT
672 test_expect_equal_file cworth.msg-ids OUTPUT
674 test_begin_subtest "regexp search for 'from' 2"
675 notmuch search from:/cworth@cworth.org/ and subject:patch | notmuch_search_sanitize > EXPECTED
676 notmuch search --query=sexp '(and (from (rx cworth@cworth.org)) (subject patch))' \
677 | notmuch_search_sanitize > OUTPUT
678 test_expect_equal_file EXPECTED OUTPUT
680 test_begin_subtest "regexp 'folder' search"
681 notmuch search 'folder:/^bar$/' | notmuch_search_sanitize > EXPECTED
682 notmuch search --query=sexp '(folder (rx ^bar$))' | notmuch_search_sanitize > OUTPUT
683 test_expect_equal_file EXPECTED OUTPUT
685 test_begin_subtest "regexp 'id' search"
686 notmuch search --output=messages --query=sexp '(id (rx yoom))' > OUTPUT
687 test_expect_equal_file cworth.msg-ids OUTPUT
689 test_begin_subtest "unanchored 'is' search"
690 notmuch search tag:signed or tag:inbox > EXPECTED
691 notmuch search --query=sexp '(is (rx i))' > OUTPUT
692 test_expect_equal_file EXPECTED OUTPUT
694 test_begin_subtest "anchored 'is' search"
695 notmuch search tag:signed > EXPECTED
696 notmuch search --query=sexp '(is (rx ^si))' > OUTPUT
697 test_expect_equal_file EXPECTED OUTPUT
699 test_begin_subtest "combine regexp mid and subject"
700 notmuch search subject:/-C/ and mid:/y..m/ | notmuch_search_sanitize > EXPECTED
701 notmuch search --query=sexp '(and (subject (rx -C)) (mid (rx y..m)))' | notmuch_search_sanitize > OUTPUT
702 test_expect_equal_file EXPECTED OUTPUT
704 test_begin_subtest "regexp 'path' search"
705 notmuch search 'path:/^bar$/' | notmuch_search_sanitize > EXPECTED
706 notmuch search --query=sexp '(path (rx ^bar$))' | notmuch_search_sanitize > OUTPUT
707 test_expect_equal_file EXPECTED OUTPUT
709 test_begin_subtest "regexp 'property' search"
710 notmuch search property:foo=bar > EXPECTED
711 notmuch search --query=sexp '(property (rx foo=.*))' > OUTPUT
712 test_expect_equal_file EXPECTED OUTPUT
714 test_begin_subtest "anchored 'tag' search"
715 notmuch search tag:signed > EXPECTED
716 notmuch search --query=sexp '(tag (rx ^si))' > OUTPUT
717 test_expect_equal_file EXPECTED OUTPUT
719 test_begin_subtest "regexp 'thread' search"
720 notmuch search --output=threads '*' | grep '7$' > EXPECTED
721 notmuch search --output=threads --query=sexp '(thread (rx 7$))' > OUTPUT
722 test_expect_equal_file EXPECTED OUTPUT
724 test_begin_subtest "Basic query that matches no messages"
725 count=$(notmuch count from:keithp and to:keithp)
726 test_expect_equal 0 "$count"
728 test_begin_subtest "Same query against threads"
729 notmuch search --query=sexp '(and (thread (of (from keithp))) (thread (matching (to keithp))))' \
730 | notmuch_search_sanitize > OUTPUT
732 thread:XXX 2009-11-18 [7/7] Lars Kellogg-Stedman, Mikhail Gusarov, Keith Packard, Carl Worth; [notmuch] Working with Maildir storage? (inbox signed unread)
734 test_expect_equal_file EXPECTED OUTPUT
736 test_begin_subtest "Mix thread and non-threads query"
737 notmuch search --query=sexp '(and (thread (matching keithp)) (to keithp))' | notmuch_search_sanitize > OUTPUT
739 thread:XXX 2009-11-18 [1/7] Lars Kellogg-Stedman| Mikhail Gusarov, Keith Packard, Carl Worth; [notmuch] Working with Maildir storage? (inbox signed unread)
741 test_expect_equal_file EXPECTED OUTPUT
743 test_begin_subtest "Compound subquery"
744 notmuch search --query=sexp '(thread (of (from keithp) (subject Maildir)))' | notmuch_search_sanitize > OUTPUT
746 thread:XXX 2009-11-18 [7/7] Lars Kellogg-Stedman, Mikhail Gusarov, Keith Packard, Carl Worth; [notmuch] Working with Maildir storage? (inbox signed unread)
748 test_expect_equal_file EXPECTED OUTPUT
750 test_begin_subtest "empty subquery"
751 notmuch search --query=sexp '(thread (of))' 1>OUTPUT 2>&1
752 notmuch search '*' > EXPECTED
753 test_expect_equal_file EXPECTED OUTPUT
755 test_begin_subtest "illegal expansion"
756 notmuch search --query=sexp '(id (of ego))' 1>OUTPUT 2>&1
758 notmuch search: Syntax error in query
759 'of' unsupported inside 'id'
761 test_expect_equal_file EXPECTED OUTPUT
763 test_begin_subtest "(folder (of subquery))"
764 notmuch search --query=sexp --output=messages '(folder (of (id yun3a4cegoa.fsf@aiko.keithp.com)))' > OUTPUT
766 id:yun1vjwegii.fsf@aiko.keithp.com
767 id:yun3a4cegoa.fsf@aiko.keithp.com
768 id:1258509400-32511-1-git-send-email-stewart@flamingspork.com
769 id:1258506353-20352-1-git-send-email-stewart@flamingspork.com
770 id:20091118010116.GC25380@dottiness.seas.harvard.edu
771 id:20091118005829.GB25380@dottiness.seas.harvard.edu
772 id:cf0c4d610911171136h1713aa59w9cf9aa31f052ad0a@mail.gmail.com
774 test_expect_equal_file EXPECTED OUTPUT
776 test_begin_subtest "infix query"
777 notmuch search to:searchbyto | notmuch_search_sanitize > EXPECTED
778 notmuch search --query=sexp '(infix "to:searchbyto")' | notmuch_search_sanitize > OUTPUT
779 test_expect_equal_file EXPECTED OUTPUT
781 test_begin_subtest "bad infix query 1"
782 notmuch search --query=sexp '(infix "from:/unbalanced")' 2>&1| notmuch_search_sanitize > OUTPUT
784 notmuch search: Syntax error in query
785 Syntax error in infix query: from:/unbalanced
787 test_expect_equal_file EXPECTED OUTPUT
789 test_begin_subtest "bad infix query 2"
790 notmuch search --query=sexp '(infix "thread:{unbalanced")' 2>&1| notmuch_search_sanitize > OUTPUT
792 notmuch search: Syntax error in query
793 Syntax error in infix query: thread:{unbalanced
795 test_expect_equal_file EXPECTED OUTPUT
797 test_begin_subtest "bad infix query 3: bad nesting"
798 notmuch search --query=sexp '(subject (infix "tag:inbox"))' 2>&1| notmuch_search_sanitize > OUTPUT
800 notmuch search: Syntax error in query
801 'infix' not supported inside 'subject'
803 test_expect_equal_file EXPECTED OUTPUT
805 test_begin_subtest "infix query that matches no messages"
806 notmuch search --query=sexp '(and (infix "from:keithp") (infix "to:keithp"))' > OUTPUT
807 test_expect_equal_file /dev/null OUTPUT
809 test_begin_subtest "compound infix query"
810 notmuch search date:2009-11-18..2009-11-18 and tag:unread > EXPECTED
811 notmuch search --query=sexp '(infix "date:2009-11-18..2009-11-18 and tag:unread")' > OUTPUT
812 test_expect_equal_file EXPECTED OUTPUT
814 test_begin_subtest "compound infix query 2"
815 notmuch search date:2009-11-18..2009-11-18 and tag:unread > EXPECTED
816 notmuch search --query=sexp '(and (infix "date:2009-11-18..2009-11-18") (infix "tag:unread"))' > OUTPUT
817 test_expect_equal_file EXPECTED OUTPUT
819 test_begin_subtest "date query, empty"
820 notmuch search from:keithp | notmuch_search_sanitize > EXPECTED
821 notmuch search --query=sexp '(and (date) (from keithp))'| notmuch_search_sanitize > OUTPUT
822 test_expect_equal_file EXPECTED OUTPUT
824 test_begin_subtest "date query, one argument"
825 notmuch search date:2009-11-18 and from:keithp | notmuch_search_sanitize > EXPECTED
826 notmuch search --query=sexp '(and (date 2009-11-18) (from keithp))' | notmuch_search_sanitize > OUTPUT
827 test_expect_equal_file EXPECTED OUTPUT
829 test_begin_subtest "date query, two arguments"
830 notmuch search date:2009-11-17..2009-11-18 and from:keithp | notmuch_search_sanitize > EXPECTED
831 notmuch search --query=sexp '(and (date 2009-11-17 2009-11-18) (from keithp))' | notmuch_search_sanitize > OUTPUT
832 test_expect_equal_file EXPECTED OUTPUT
834 test_begin_subtest "date query, illegal nesting 1"
835 notmuch search --query=sexp '(to (date))' > OUTPUT 2>&1
837 notmuch search: Syntax error in query
838 nested field: 'date' inside 'to'
840 test_expect_equal_file EXPECTED OUTPUT
842 test_begin_subtest "date query, illegal nesting 2"
843 notmuch search --query=sexp '(to (date 2021-11-18))' > OUTPUT 2>&1
845 notmuch search: Syntax error in query
846 nested field: 'date' inside 'to'
848 test_expect_equal_file EXPECTED OUTPUT
850 test_begin_subtest "date query, illegal nesting 3"
851 notmuch search --query=sexp '(date (to))' > OUTPUT 2>&1
853 notmuch search: Syntax error in query
854 expected atom as first argument of 'date'
856 test_expect_equal_file EXPECTED OUTPUT
858 test_begin_subtest "date query, illegal nesting 4"
859 notmuch search --query=sexp '(date today (to))' > OUTPUT 2>&1
861 notmuch search: Syntax error in query
862 expected atom as second argument of 'date'
864 test_expect_equal_file EXPECTED OUTPUT
866 test_begin_subtest "date query, too many arguments"
867 notmuch search --query=sexp '(date yesterday and tommorow)' > OUTPUT 2>&1
869 notmuch search: Syntax error in query
870 'date' expects maximum of two arguments
872 test_expect_equal_file EXPECTED OUTPUT
874 test_begin_subtest "date query, bad date"
875 notmuch search --query=sexp '(date "hawaiian-pizza-day")' > OUTPUT 2>&1
877 notmuch search: Syntax error in query
878 Didn't understand date specification 'hawaiian-pizza-day'
880 test_expect_equal_file EXPECTED OUTPUT
882 test_begin_subtest "lastmod query, empty"
883 notmuch search from:keithp | notmuch_search_sanitize > EXPECTED
884 notmuch search --query=sexp '(and (lastmod) (from keithp))'| notmuch_search_sanitize > OUTPUT
885 test_expect_equal_file EXPECTED OUTPUT
887 test_begin_subtest "lastmod query, one argument"
888 notmuch tag +4EFC743A.3060609@april.org id:4EFC743A.3060609@april.org
889 revision=$(notmuch count --lastmod '*' | cut -f3)
890 notmuch search lastmod:$revision..$revision | notmuch_search_sanitize > EXPECTED
891 notmuch search --query=sexp "(and (lastmod $revision))" | notmuch_search_sanitize > OUTPUT
892 test_expect_equal_file EXPECTED OUTPUT
894 test_begin_subtest "lastmod query, two arguments"
895 notmuch tag +keithp from:keithp
896 revision2=$(notmuch count --lastmod '*' | cut -f3)
897 notmuch search lastmod:$revision..$revision2 | notmuch_search_sanitize > EXPECTED
898 notmuch search --query=sexp "(and (lastmod $revision $revision2))" | notmuch_search_sanitize > OUTPUT
899 test_expect_equal_file EXPECTED OUTPUT
901 test_begin_subtest "lastmod query, illegal nesting 1"
902 notmuch search --query=sexp '(to (lastmod))' > OUTPUT 2>&1
904 notmuch search: Syntax error in query
905 nested field: 'lastmod' inside 'to'
907 test_expect_equal_file EXPECTED OUTPUT
909 test_begin_subtest "lastmod query, bad from revision"
910 notmuch search --query=sexp '(lastmod apples)' > OUTPUT 2>&1
912 notmuch search: Syntax error in query
913 bad 'from' revision: 'apples'
915 test_expect_equal_file EXPECTED OUTPUT
917 test_begin_subtest "lastmod query, bad to revision"
918 notmuch search --query=sexp '(lastmod 0 apples)' > OUTPUT 2>&1
920 notmuch search: Syntax error in query
921 bad 'to' revision: 'apples'
923 test_expect_equal_file EXPECTED OUTPUT
925 test_begin_subtest "lastmod query, illegal nesting 2"
926 notmuch search --query=sexp '(to (lastmod 2021-11-18))' > OUTPUT 2>&1
928 notmuch search: Syntax error in query
929 nested field: 'lastmod' inside 'to'
931 test_expect_equal_file EXPECTED OUTPUT
933 test_begin_subtest "lastmod query, illegal nesting 3"
934 notmuch search --query=sexp '(lastmod (to))' > OUTPUT 2>&1
936 notmuch search: Syntax error in query
937 expected atom as first argument of 'lastmod'
939 test_expect_equal_file EXPECTED OUTPUT
941 test_begin_subtest "lastmod query, illegal nesting 4"
942 notmuch search --query=sexp '(lastmod today (to))' > OUTPUT 2>&1
944 notmuch search: Syntax error in query
945 expected atom as second argument of 'lastmod'
947 test_expect_equal_file EXPECTED OUTPUT
949 test_begin_subtest "lastmod query, too many arguments"
950 notmuch search --query=sexp '(lastmod yesterday and tommorow)' > OUTPUT 2>&1
952 notmuch search: Syntax error in query
953 'lastmod' expects maximum of two arguments
955 test_expect_equal_file EXPECTED OUTPUT
957 test_begin_subtest "user header (unknown header)"
958 notmuch search --query=sexp '(FooBar)' >& OUTPUT
960 notmuch search: Syntax error in query
961 unknown prefix 'FooBar'
963 test_expect_equal_file EXPECTED OUTPUT
965 test_begin_subtest "adding user header"
966 test_expect_code 0 "notmuch config set index.header.List \"List-Id\""
968 test_begin_subtest "reindexing"
969 test_expect_code 0 'notmuch reindex "*"'
971 test_begin_subtest "wildcard search for user header"
972 grep -Ril List-Id ${MAIL_DIR} | sort | notmuch_dir_sanitize > EXPECTED
973 notmuch search --output=files --query=sexp '(List *)' | sort | notmuch_dir_sanitize > OUTPUT
974 test_expect_equal_file EXPECTED OUTPUT
976 test_begin_subtest "wildcard search for user header 2"
977 grep -Ril List-Id ${MAIL_DIR} | sort | notmuch_dir_sanitize > EXPECTED
978 notmuch search --output=files --query=sexp '(List (starts-with not))' | sort | notmuch_dir_sanitize > OUTPUT
979 test_expect_equal_file EXPECTED OUTPUT
981 test_begin_subtest "search for user header"
982 notmuch search List:notmuch | notmuch_search_sanitize > EXPECTED
983 notmuch search --query=sexp '(List notmuch)' | notmuch_search_sanitize > OUTPUT
984 test_expect_equal_file EXPECTED OUTPUT
986 test_begin_subtest "search for user header (list token)"
987 notmuch search List:notmuch | notmuch_search_sanitize > EXPECTED
988 notmuch search --query=sexp '(List notmuch.notmuchmail.org)' | notmuch_search_sanitize > OUTPUT
989 test_expect_equal_file EXPECTED OUTPUT
991 test_begin_subtest "search for user header (quoted string)"
992 notmuch search 'List:"notmuch notmuchmail org"' | notmuch_search_sanitize > EXPECTED
993 notmuch search --query=sexp '(List "notmuch notmuchmail org")' | notmuch_search_sanitize > OUTPUT
994 test_expect_equal_file EXPECTED OUTPUT
996 test_begin_subtest "search for user header (atoms)"
997 notmuch search 'List:"notmuch notmuchmail org"' | notmuch_search_sanitize > EXPECTED
998 notmuch search --query=sexp '(List notmuch notmuchmail org)' | notmuch_search_sanitize > OUTPUT
999 test_expect_equal_file EXPECTED OUTPUT
1001 test_begin_subtest "check saved query name"
1002 test_expect_code 1 "notmuch config set squery.test '(subject utf8-sübjéct)'"
1004 test_begin_subtest "roundtrip saved query (database)"
1005 notmuch config set --database squery.Test '(subject utf8-sübjéct)'
1006 output=$(notmuch config get squery.Test)
1007 test_expect_equal "$output" '(subject utf8-sübjéct)'
1009 test_begin_subtest "roundtrip saved query"
1010 notmuch config set squery.Test '(subject override subject)'
1011 output=$(notmuch config get squery.Test)
1012 test_expect_equal "$output" '(subject override subject)'
1014 test_begin_subtest "unknown saved query"
1015 notmuch search --query=sexp '(Unknown foo bar)' >OUTPUT 2>&1
1016 cat <<EOF > EXPECTED
1017 notmuch search: Syntax error in query
1018 unknown prefix 'Unknown'
1020 test_expect_equal_file EXPECTED OUTPUT
1022 test_begin_subtest "syntax error in saved query"
1023 notmuch config set squery.Bad '(Bad'
1024 notmuch search --query=sexp '(Bad foo bar)' >OUTPUT 2>&1
1025 cat <<EOF > EXPECTED
1026 notmuch search: Syntax error in query
1027 invalid saved s-expression query: '(Bad'
1029 test_expect_equal_file EXPECTED OUTPUT
1031 test_begin_subtest "Saved Search by 'tag' and 'subject'"
1032 notmuch search tag:inbox and subject:maildir | notmuch_search_sanitize > EXPECTED
1033 notmuch config set squery.TagSubject '(and (tag inbox) (subject maildir))'
1034 notmuch search --query=sexp '(TagSubject)' | notmuch_search_sanitize > OUTPUT
1035 test_expect_equal_file EXPECTED OUTPUT
1037 test_begin_subtest "Saved Search: illegal nesting"
1038 notmuch config set squery.TagSubject '(and (tag inbox) (subject maildir))'
1039 notmuch search --query=sexp '(subject (TagSubject))' >OUTPUT 2>&1
1040 cat <<EOF > EXPECTED
1041 notmuch search: Syntax error in query
1042 nested field: 'tag' inside 'subject'
1044 test_expect_equal_file EXPECTED OUTPUT
1046 test_begin_subtest "Saved Search: list as prefix"
1047 notmuch config set squery.Bad2 '((and) (tag inbox) (subject maildir))'
1048 notmuch search --query=sexp '(Bad2)' >OUTPUT 2>&1
1049 cat <<EOF > EXPECTED
1050 notmuch search: Syntax error in query
1051 unexpected list in field/operation position
1053 test_expect_equal_file EXPECTED OUTPUT
1055 test_begin_subtest "Saved Search: bad parameter syntax"
1056 notmuch config set squery.Bad3 '(macro a b)'
1057 notmuch search --query=sexp '(Bad3)' >OUTPUT 2>&1
1058 cat <<EOF > EXPECTED
1059 notmuch search: Syntax error in query
1060 missing (possibly empty) list of arguments to macro
1062 test_expect_equal_file EXPECTED OUTPUT
1064 test_begin_subtest "Saved Search: bad parameter syntax 2"
1065 notmuch config set squery.Bad4 '(macro ((a b)) a)'
1066 notmuch search --query=sexp '(Bad4 1)' >OUTPUT 2>&1
1067 cat <<EOF > EXPECTED
1068 notmuch search: Syntax error in query
1069 macro parameters must be unquoted atoms
1071 test_expect_equal_file EXPECTED OUTPUT
1073 test_begin_subtest "Saved Search: bad parameter syntax 3"
1074 notmuch config set squery.Bad5 '(macro (a b) a)'
1075 notmuch search --query=sexp '(Bad5 1)' >OUTPUT 2>&1
1076 cat <<EOF > EXPECTED
1077 notmuch search: Syntax error in query
1078 too few arguments to macro
1080 test_expect_equal_file EXPECTED OUTPUT
1082 test_begin_subtest "Saved Search: bad parameter syntax 4"
1083 notmuch search --query=sexp '(Bad5 1 2 3)' >OUTPUT 2>&1
1084 cat <<EOF > EXPECTED
1085 notmuch search: Syntax error in query
1086 too many arguments to macro
1088 test_expect_equal_file EXPECTED OUTPUT
1090 test_begin_subtest "Saved Search: macro without body"
1091 notmuch config set squery.Bad3 '(macro (a b))'
1092 notmuch search --query=sexp '(Bad3)' >OUTPUT 2>&1
1093 cat <<EOF > EXPECTED
1094 notmuch search: Syntax error in query
1095 missing body of macro
1097 test_expect_equal_file EXPECTED OUTPUT
1099 test_begin_subtest "macro in query"
1100 notmuch search --query=sexp '(macro (a) (and ,b (subject maildir)))' >OUTPUT 2>&1
1101 cat <<EOF > EXPECTED
1102 notmuch search: Syntax error in query
1103 macro definition not permitted here
1105 test_expect_equal_file EXPECTED OUTPUT
1107 test_begin_subtest "zero argument macro"
1108 notmuch search tag:inbox and subject:maildir | notmuch_search_sanitize > EXPECTED
1109 notmuch config set squery.TagSubject0 '(macro () (and (tag inbox) (subject maildir)))'
1110 notmuch search --query=sexp '(TagSubject0)' | notmuch_search_sanitize > OUTPUT
1111 test_expect_equal_file EXPECTED OUTPUT
1113 test_begin_subtest "undefined argument"
1114 notmuch search tag:inbox and subject:maildir | notmuch_search_sanitize > EXPECTED
1115 notmuch config set squery.Bad6 '(macro (a) (and ,b (subject maildir)))'
1116 notmuch search --query=sexp '(Bad6 foo)' >OUTPUT 2>&1
1117 cat <<EOF > EXPECTED
1118 notmuch search: Syntax error in query
1119 undefined parameter b
1121 test_expect_equal_file EXPECTED OUTPUT
1123 test_begin_subtest "Single argument macro"
1124 notmuch search tag:inbox and subject:maildir | notmuch_search_sanitize > EXPECTED
1125 notmuch config set squery.TagSubject1 '(macro (tagname) (and (tag ,tagname) (subject maildir)))'
1126 notmuch search --query=sexp '(TagSubject1 inbox)' | notmuch_search_sanitize > OUTPUT
1127 test_expect_equal_file EXPECTED OUTPUT
1129 test_begin_subtest "Single argument macro, list argument"
1130 notmuch search tag:inbox and subject:maildir | notmuch_search_sanitize > EXPECTED
1131 notmuch config set squery.ThingSubject '(macro (thing) (and ,thing (subject maildir)))'
1132 notmuch search --query=sexp '(ThingSubject (tag inbox))' | notmuch_search_sanitize > OUTPUT
1133 test_expect_equal_file EXPECTED OUTPUT
1135 test_begin_subtest "two argument macro"
1136 notmuch search tag:inbox and subject:maildir | notmuch_search_sanitize > EXPECTED
1137 notmuch config set squery.TagSubject2 '(macro (tagname subj) (and (tag ,tagname) (subject ,subj)))'
1138 notmuch search --query=sexp '(TagSubject2 inbox maildir)' | notmuch_search_sanitize > OUTPUT
1139 test_expect_equal_file EXPECTED OUTPUT
1141 test_begin_subtest "nested macros (shadowing)"
1142 notmuch search tag:inbox and subject:maildir | notmuch_search_sanitize > EXPECTED
1143 notmuch config set squery.Inner '(macro (x) (subject ,x))'
1144 notmuch config set squery.Outer '(macro (x y) (and (tag ,x) (Inner ,y)))'
1145 notmuch search --query=sexp '(Outer inbox maildir)' | notmuch_search_sanitize > OUTPUT
1146 test_expect_equal_file EXPECTED OUTPUT
1148 test_begin_subtest "nested macros (no dynamic scope)"
1149 notmuch config set squery.Inner2 '(macro (x) (subject ,y))'
1150 notmuch config set squery.Outer2 '(macro (x y) (and (tag ,x) (Inner2 ,y)))'
1151 notmuch search --query=sexp '(Outer2 inbox maildir)' > OUTPUT 2>&1
1152 cat <<EOF > EXPECTED
1153 notmuch search: Syntax error in query
1154 undefined parameter y
1156 test_expect_equal_file EXPECTED OUTPUT
1158 test_begin_subtest "combine macro and user defined header"
1159 notmuch config set squery.About '(macro (name) (or (subject ,name) (List ,name)))'
1160 notmuch search subject:notmuch or List:notmuch | notmuch_search_sanitize > EXPECTED
1161 notmuch search --query=sexp '(About notmuch)' | notmuch_search_sanitize > OUTPUT
1162 test_expect_equal_file EXPECTED OUTPUT
1165 test_begin_subtest "combine macro and user defined header"
1166 notmuch config set squery.About '(macro (name) (or (subject ,name) (List ,name)))'
1167 notmuch search subject:notmuch or List:notmuch | notmuch_search_sanitize > EXPECTED
1168 notmuch search --query=sexp '(About notmuch)' | notmuch_search_sanitize > OUTPUT
1169 test_expect_equal_file EXPECTED OUTPUT