]> git.notmuchmail.org Git - notmuch/blob - test/T081-sexpr-search.sh
lib/database: delete stemmer on destroy
[notmuch] / test / T081-sexpr-search.sh
1 #!/usr/bin/env bash
2 test_description='"notmuch search" in several variations'
3 . $(dirname "$0")/test-lib.sh || exit 1
4
5 if [ $NOTMUCH_HAVE_SFSEXP -ne 1 ]; then
6     printf "Skipping due to missing sfsexp library\n"
7     test_done
8 fi
9
10 add_email_corpus
11
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
18 done
19
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
25 done
26
27 test_begin_subtest "and of exact terms"
28 notmuch search --query=sexp '(and "wonderful" "wizard")' | notmuch_search_sanitize > OUTPUT
29 cat <<EOF > EXPECTED
30 thread:XXX   2009-11-18 [1/3] Carl Worth| Jan Janak; [notmuch] What a great idea! (inbox unread)
31 EOF
32 test_expect_equal_file EXPECTED OUTPUT
33
34 test_begin_subtest "or of exact terms"
35 notmuch search --query=sexp '(or "php" "wizard")' | notmuch_search_sanitize > OUTPUT
36 cat <<EOF > EXPECTED
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)
39 EOF
40 test_expect_equal_file EXPECTED OUTPUT
41
42 test_begin_subtest "single term in body"
43 notmuch search --query=sexp 'wizard' | notmuch_search_sanitize>OUTPUT
44 cat <<EOF > EXPECTED
45 thread:XXX   2009-11-18 [1/3] Carl Worth| Jan Janak; [notmuch] What a great idea! (inbox unread)
46 EOF
47 test_expect_equal_file EXPECTED OUTPUT
48
49 test_begin_subtest "single term in body (case insensitive)"
50 notmuch search --query=sexp 'Wizard' | notmuch_search_sanitize>OUTPUT
51 cat <<EOF > EXPECTED
52 thread:XXX   2009-11-18 [1/3] Carl Worth| Jan Janak; [notmuch] What a great idea! (inbox unread)
53 EOF
54 test_expect_equal_file EXPECTED OUTPUT
55
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
60
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
64
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)"
69
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
74
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)"
79
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)"
83
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)"
87
88 test_begin_subtest "Search by 'subject' (utf-8, or):"
89 notmuch search --query=sexp '(subject (or utf8 subjectsearchtest))' | notmuch_search_sanitize > OUTPUT
90 cat <<EOF > EXPECTED
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)
93 EOF
94 test_expect_equal_file EXPECTED OUTPUT
95
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
98 cat <<EOF > EXPECTED
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)
101 EOF
102 test_expect_equal_file EXPECTED OUTPUT
103
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
108
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)"
113
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)"
119
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)"
124
125 add_message "[body]=thebody-1" "[subject]=kryptonite-1"
126 add_message "[body]=nothing-to-see-here-1" "[subject]=thebody-1"
127
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
132
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
137
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
142
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
147
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)"
152
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)"
157
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)"
162
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)"
166
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"
172
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"'
176
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)"
182
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
187
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)"
192
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)"
197
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
204
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)"
209
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)"
214
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
219
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"
224
225 test_begin_subtest "ill-formed named query search"
226 notmuch search --query=sexp '(query)' > OUTPUT 2>&1
227 cat <<EOF > EXPECTED
228 notmuch search: Syntax error in query
229 'query' expects single atom as argument
230 EOF
231 test_expect_equal_file EXPECTED OUTPUT
232
233 test_begin_subtest "ill-formed named query search 2"
234 notmuch search --query=sexp '(to (query))' > OUTPUT 2>&1
235 cat <<EOF > EXPECTED
236 notmuch search: Syntax error in query
237 'query' not supported inside 'to'
238 EOF
239 test_expect_equal_file EXPECTED OUTPUT
240
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
245
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)"
249
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
254
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
259
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)"
263
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)"
267
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
270 cat <<EOF > EXPECTED
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)
274 EOF
275 test_expect_equal_file EXPECTED OUTPUT
276
277 test_begin_subtest "Search by 'subject' (combine phrase, term 3):"
278 notmuch search --query=sexp '(subject issues X/Darwin)' | notmuch_search_sanitize > OUTPUT
279 cat <<EOF > EXPECTED
280 thread:XXX   2009-11-18 [4/4] Jjgod Jiang, Alexander Botero-Lowry; [notmuch] Mac OS X/Darwin compatibility issues (inbox unread)
281 EOF
282 test_expect_equal_file EXPECTED OUTPUT
283
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)"
289
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
296
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
301
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)"
307
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)"
312
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)"
317
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)"
322
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)"
326
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)"
330
331 test_begin_subtest "starts-with, case-insensitive"
332 notmuch search --query=sexp '(starts-with FreeB)' | notmuch_search_sanitize > OUTPUT
333 cat <<EOF > EXPECTED
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)
336 EOF
337 test_expect_equal_file EXPECTED OUTPUT
338
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
343
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)'
347
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
350 cat <<EOF > EXPECTED
351 MAIL_DIR/bad/msg-XXX
352 MAIL_DIR/bad/news/msg-XXX
353 MAIL_DIR/duplicate/bad/news/msg-XXX
354 EOF
355 test_expect_equal_file EXPECTED OUTPUT
356
357 test_begin_subtest "starts-with, from"
358 notmuch search --query=sexp '(from (starts-with Mik))' | notmuch_search_sanitize > OUTPUT
359 cat <<EOF > EXPECTED
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)
363 EOF
364 test_expect_equal_file EXPECTED OUTPUT
365
366 test_begin_subtest "starts-with, id"
367 notmuch search --query=sexp --output=messages '(id (starts-with 877))' > OUTPUT
368 cat <<EOF > EXPECTED
369 id:877h1wv7mg.fsf@inf-8657.int-evry.fr
370 id:877htoqdbo.fsf@yoom.home.cworth.org
371 EOF
372 test_expect_equal_file EXPECTED OUTPUT
373
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)'
377
378 test_begin_subtest "starts-with, mid"
379 notmuch search --query=sexp --output=messages '(mid (starts-with 877))' > OUTPUT
380 cat <<EOF > EXPECTED
381 id:877h1wv7mg.fsf@inf-8657.int-evry.fr
382 id:877htoqdbo.fsf@yoom.home.cworth.org
383 EOF
384 test_expect_equal_file EXPECTED OUTPUT
385
386 test_begin_subtest "starts-with, mimetype"
387 notmuch search --query=sexp '(mimetype (starts-with sig))' | notmuch_search_sanitize > OUTPUT
388 cat <<EOF > EXPECTED
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)
392 EOF
393 test_expect_equal_file EXPECTED OUTPUT
394
395 add_message '[subject]="message with properties"'
396 notmuch restore <<EOF
397 #= ${gen_msg_id} foo=bar
398 EOF
399
400 test_begin_subtest "starts-with, property"
401 notmuch search --query=sexp '(property (starts-with foo=))' | notmuch_search_sanitize > OUTPUT
402 cat <<EOF > EXPECTED
403 thread:XXX   2001-01-05 [1/1] Notmuch Test Suite; message with properties (inbox unread)
404 EOF
405 test_expect_equal_file EXPECTED OUTPUT
406
407 test_begin_subtest "starts-with, subject"
408 notmuch search --query=sexp '(subject (starts-with FreeB))' | notmuch_search_sanitize > OUTPUT
409 cat <<EOF > EXPECTED
410 thread:XXX   2009-11-17 [2/2] Alex Botero-Lowry, Carl Worth; [notmuch] preliminary FreeBSD support (attachment inbox unread)
411 EOF
412 test_expect_equal_file EXPECTED OUTPUT
413
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)'
417
418 add_message '[subject]="no tags"'
419 notag_mid=${gen_msg_id}
420 notmuch tag -unread -inbox id:${notag_mid}
421
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 ()'
425
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 ()'
429
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 ()'
433
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
438
439 test_begin_subtest "starts-with, to"
440 notmuch search --query=sexp '(to (starts-with "search"))' | notmuch_search_sanitize > OUTPUT
441 cat <<EOF > EXPECTED
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)
445 EOF
446 test_expect_equal_file EXPECTED OUTPUT
447
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
452
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
457
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
462
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
467
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
472
473 add_message '[subject]="message with tag \"*\""'
474 notmuch tag '+*' id:${gen_msg_id}
475
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"
479
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
483 cat <<EOF > EXPECTED
484 thread:XXX   2001-01-05 [1/1] Notmuch Test Suite; search for missing / empty to (inbox unread)
485 EOF
486 test_expect_equal_file EXPECTED OUTPUT
487
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 '('"
491
492 test_begin_subtest "Unbalanced parens, error message"
493 notmuch search --query=sexp '(' >OUTPUT 2>&1
494 cat <<EOF > EXPECTED
495 notmuch search: Syntax error in query
496 invalid s-expression: '('
497 EOF
498 test_expect_equal_file EXPECTED OUTPUT
499
500 test_begin_subtest "unknown prefix"
501 notmuch search --query=sexp '(foo)' >OUTPUT 2>&1
502 cat <<EOF > EXPECTED
503 notmuch search: Syntax error in query
504 unknown prefix 'foo'
505 EOF
506 test_expect_equal_file EXPECTED OUTPUT
507
508 test_begin_subtest "list as prefix"
509 notmuch search --query=sexp '((foo))' >OUTPUT 2>&1
510 cat <<EOF > EXPECTED
511 notmuch search: Syntax error in query
512 unexpected list in field/operation position
513 EOF
514 test_expect_equal_file EXPECTED OUTPUT
515
516 test_begin_subtest "illegal nesting"
517 notmuch search --query=sexp '(subject (subject foo))' >OUTPUT 2>&1
518 cat <<EOF > EXPECTED
519 notmuch search: Syntax error in query
520 nested field: 'subject' inside 'subject'
521 EOF
522 test_expect_equal_file EXPECTED OUTPUT
523
524 test_begin_subtest "starts-with, no argument"
525 notmuch search --query=sexp '(starts-with)' >OUTPUT 2>&1
526 cat <<EOF > EXPECTED
527 notmuch search: Syntax error in query
528 'starts-with' expects single atom as argument
529 EOF
530 test_expect_equal_file EXPECTED OUTPUT
531
532 test_begin_subtest "starts-with, list argument"
533 notmuch search --query=sexp '(starts-with (stuff))' >OUTPUT 2>&1
534 cat <<EOF > EXPECTED
535 notmuch search: Syntax error in query
536 'starts-with' expects single atom as argument
537 EOF
538 test_expect_equal_file EXPECTED OUTPUT
539
540 test_begin_subtest "starts-with, too many arguments"
541 notmuch search --query=sexp '(starts-with a b c)' >OUTPUT 2>&1
542 cat <<EOF > EXPECTED
543 notmuch search: Syntax error in query
544 'starts-with' expects single atom as argument
545 EOF
546 test_expect_equal_file EXPECTED OUTPUT
547
548 test_begin_subtest "starts-with, illegal field"
549 notmuch search --query=sexp '(body (starts-with foo))' >OUTPUT 2>&1
550 cat <<EOF > EXPECTED
551 notmuch search: Syntax error in query
552 'body' does not support wildcard queries
553 EOF
554 test_expect_equal_file EXPECTED OUTPUT
555
556 test_begin_subtest "wildcard, illegal field"
557 notmuch search --query=sexp '(body *)' >OUTPUT 2>&1
558 cat <<EOF > EXPECTED
559 notmuch search: Syntax error in query
560 'body' does not support wildcard queries
561 EOF
562 test_expect_equal_file EXPECTED OUTPUT
563
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)"
574
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
578 id:$deleted_id"
579
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
582 cat <<EOF > EXPECTED
583 thread:XXX   2001-01-05 [1/1] Notmuch Test Suite; Deleted (deleted inbox unread)
584 EOF
585 test_expect_equal_file EXPECTED OUTPUT
586
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)"
592
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)"
597
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)"
603
604 test_begin_subtest "regex at top level"
605 notmuch search --query=sexp '(rx foo)' >& OUTPUT
606 cat <<EOF > EXPECTED
607 notmuch search: Syntax error in query
608 illegal 'rx' outside field
609 EOF
610 test_expect_equal_file EXPECTED OUTPUT
611
612 test_begin_subtest "regex in illegal field"
613 notmuch search --query=sexp '(body (regex foo))' >& OUTPUT
614 cat <<EOF > EXPECTED
615 notmuch search: Syntax error in query
616 'regex' not supported in field 'body'
617 EOF
618 test_expect_equal_file EXPECTED OUTPUT
619
620 notmuch search --output=messages from:cworth > cworth.msg-ids
621
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
625
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
631
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
636
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
640
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
645
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
650
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
655
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
660
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
665
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
670
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
675
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"
679
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
683 cat<<EOF > EXPECTED
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)
685 EOF
686 test_expect_equal_file EXPECTED OUTPUT
687
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
690 cat<<EOF > EXPECTED
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)
692 EOF
693 test_expect_equal_file EXPECTED OUTPUT
694
695 test_begin_subtest "Compound subquery"
696 notmuch search --query=sexp '(thread (of (from keithp) (subject Maildir)))' | notmuch_search_sanitize > OUTPUT
697 cat<<EOF > EXPECTED
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)
699 EOF
700 test_expect_equal_file EXPECTED OUTPUT
701
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
706
707 test_begin_subtest "illegal expansion"
708 notmuch search --query=sexp '(id (of ego))' 1>OUTPUT 2>&1
709 cat<<EOF > EXPECTED
710 notmuch search: Syntax error in query
711 'of' unsupported inside 'id'
712 EOF
713 test_expect_equal_file EXPECTED OUTPUT
714
715 test_begin_subtest "(folder (of subquery))"
716 notmuch search --query=sexp --output=messages '(folder (of (id yun3a4cegoa.fsf@aiko.keithp.com)))' > OUTPUT
717 cat <<EOF > EXPECTED
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
725 EOF
726 test_expect_equal_file EXPECTED OUTPUT
727
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
732
733 test_begin_subtest "bad infix query 1"
734 notmuch search --query=sexp '(infix "from:/unbalanced")' 2>&1|  notmuch_search_sanitize > OUTPUT
735 cat <<EOF > EXPECTED
736 notmuch search: Syntax error in query
737 Syntax error in infix query: from:/unbalanced
738 EOF
739 test_expect_equal_file EXPECTED OUTPUT
740
741 test_begin_subtest "bad infix query 2"
742 notmuch search --query=sexp '(infix "thread:{unbalanced")' 2>&1|  notmuch_search_sanitize > OUTPUT
743 cat <<EOF > EXPECTED
744 notmuch search: Syntax error in query
745 Syntax error in infix query: thread:{unbalanced
746 EOF
747 test_expect_equal_file EXPECTED OUTPUT
748
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
751 cat <<EOF > EXPECTED
752 notmuch search: Syntax error in query
753 'infix' not supported inside 'subject'
754 EOF
755 test_expect_equal_file EXPECTED OUTPUT
756
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
760
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
765
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
770
771 test_begin_subtest "user header (unknown header)"
772 notmuch search --query=sexp '(FooBar)' >& OUTPUT
773 cat <<EOF > EXPECTED
774 notmuch search: Syntax error in query
775 unknown prefix 'FooBar'
776 EOF
777 test_expect_equal_file EXPECTED OUTPUT
778
779 test_begin_subtest "adding user header"
780 test_expect_code 0 "notmuch config set index.header.List \"List-Id\""
781
782 test_begin_subtest "reindexing"
783 test_expect_code 0 'notmuch reindex "*"'
784
785 test_begin_subtest "wildcard search for user header"
786 grep -Ril List-Id ${MAIL_DIR} | sort | notmuch_dir_sanitize > EXPECTED
787 notmuch search --output=files --query=sexp '(List *)' | sort | notmuch_dir_sanitize > OUTPUT
788 test_expect_equal_file EXPECTED OUTPUT
789
790 test_begin_subtest "wildcard search for user header 2"
791 grep -Ril List-Id ${MAIL_DIR} | sort | notmuch_dir_sanitize > EXPECTED
792 notmuch search --output=files --query=sexp '(List (starts-with not))' | sort | notmuch_dir_sanitize > OUTPUT
793 test_expect_equal_file EXPECTED OUTPUT
794
795 test_begin_subtest "search for user header"
796 notmuch search List:notmuch | notmuch_search_sanitize > EXPECTED
797 notmuch search --query=sexp '(List notmuch)' | notmuch_search_sanitize > OUTPUT
798 test_expect_equal_file EXPECTED OUTPUT
799
800 test_begin_subtest "search for user header (list token)"
801 notmuch search List:notmuch | notmuch_search_sanitize > EXPECTED
802 notmuch search --query=sexp '(List notmuch.notmuchmail.org)' | notmuch_search_sanitize > OUTPUT
803 test_expect_equal_file EXPECTED OUTPUT
804
805 test_begin_subtest "search for user header (quoted string)"
806 notmuch search 'List:"notmuch notmuchmail org"' | notmuch_search_sanitize > EXPECTED
807 notmuch search --query=sexp '(List "notmuch notmuchmail org")' | notmuch_search_sanitize > OUTPUT
808 test_expect_equal_file EXPECTED OUTPUT
809
810 test_begin_subtest "search for user header (atoms)"
811 notmuch search 'List:"notmuch notmuchmail org"' | notmuch_search_sanitize > EXPECTED
812 notmuch search --query=sexp '(List notmuch notmuchmail org)' | notmuch_search_sanitize > OUTPUT
813 test_expect_equal_file EXPECTED OUTPUT
814
815 test_begin_subtest "check saved query name"
816 test_expect_code 1 "notmuch config set squery.test '(subject utf8-sübjéct)'"
817
818 test_begin_subtest "roundtrip saved query (database)"
819 notmuch config set --database squery.Test '(subject utf8-sübjéct)'
820 output=$(notmuch config get squery.Test)
821 test_expect_equal "$output" '(subject utf8-sübjéct)'
822
823 test_begin_subtest "roundtrip saved query"
824 notmuch config set squery.Test '(subject override subject)'
825 output=$(notmuch config get squery.Test)
826 test_expect_equal "$output" '(subject override subject)'
827
828 test_begin_subtest "unknown saved query"
829 notmuch search --query=sexp '(Unknown foo bar)' >OUTPUT 2>&1
830 cat <<EOF > EXPECTED
831 notmuch search: Syntax error in query
832 unknown prefix 'Unknown'
833 EOF
834 test_expect_equal_file EXPECTED OUTPUT
835
836 test_begin_subtest "syntax error in saved query"
837 notmuch config set squery.Bad '(Bad'
838 notmuch search --query=sexp '(Bad foo bar)' >OUTPUT 2>&1
839 cat <<EOF > EXPECTED
840 notmuch search: Syntax error in query
841 invalid saved s-expression query: '(Bad'
842 EOF
843 test_expect_equal_file EXPECTED OUTPUT
844
845 test_begin_subtest "Saved Search by 'tag' and 'subject'"
846 notmuch search tag:inbox and subject:maildir | notmuch_search_sanitize > EXPECTED
847 notmuch config set squery.TagSubject  '(and (tag inbox) (subject maildir))'
848 notmuch search --query=sexp '(TagSubject)' | notmuch_search_sanitize > OUTPUT
849 test_expect_equal_file EXPECTED OUTPUT
850
851 test_begin_subtest "Saved Search: illegal nesting"
852 notmuch config set squery.TagSubject  '(and (tag inbox) (subject maildir))'
853 notmuch search --query=sexp '(subject (TagSubject))' >OUTPUT 2>&1
854 cat <<EOF > EXPECTED
855 notmuch search: Syntax error in query
856 nested field: 'tag' inside 'subject'
857 EOF
858 test_expect_equal_file EXPECTED OUTPUT
859
860 test_begin_subtest "Saved Search: list as prefix"
861 notmuch config set squery.Bad2  '((and) (tag inbox) (subject maildir))'
862 notmuch search --query=sexp '(Bad2)' >OUTPUT 2>&1
863 cat <<EOF > EXPECTED
864 notmuch search: Syntax error in query
865 unexpected list in field/operation position
866 EOF
867 test_expect_equal_file EXPECTED OUTPUT
868
869 test_begin_subtest "Saved Search: bad parameter syntax"
870 notmuch config set squery.Bad3  '(macro a b)'
871 notmuch search --query=sexp '(Bad3)' >OUTPUT 2>&1
872 cat <<EOF > EXPECTED
873 notmuch search: Syntax error in query
874 missing (possibly empty) list of arguments to macro
875 EOF
876 test_expect_equal_file EXPECTED OUTPUT
877
878 test_begin_subtest "Saved Search: bad parameter syntax 2"
879 notmuch config set squery.Bad4  '(macro ((a b)) a)'
880 notmuch search --query=sexp '(Bad4 1)' >OUTPUT 2>&1
881 cat <<EOF > EXPECTED
882 notmuch search: Syntax error in query
883 macro parameters must be unquoted atoms
884 EOF
885 test_expect_equal_file EXPECTED OUTPUT
886
887 test_begin_subtest "Saved Search: bad parameter syntax 3"
888 notmuch config set squery.Bad5  '(macro (a b) a)'
889 notmuch search --query=sexp '(Bad5 1)' >OUTPUT 2>&1
890 cat <<EOF > EXPECTED
891 notmuch search: Syntax error in query
892 too few arguments to macro
893 EOF
894 test_expect_equal_file EXPECTED OUTPUT
895
896 test_begin_subtest "Saved Search: bad parameter syntax 4"
897 notmuch search --query=sexp '(Bad5 1 2 3)' >OUTPUT 2>&1
898 cat <<EOF > EXPECTED
899 notmuch search: Syntax error in query
900 too many arguments to macro
901 EOF
902 test_expect_equal_file EXPECTED OUTPUT
903
904 test_begin_subtest "Saved Search: macro without body"
905 notmuch config set squery.Bad3  '(macro (a b))'
906 notmuch search --query=sexp '(Bad3)' >OUTPUT 2>&1
907 cat <<EOF > EXPECTED
908 notmuch search: Syntax error in query
909 missing body of macro
910 EOF
911 test_expect_equal_file EXPECTED OUTPUT
912
913 test_begin_subtest "macro in query"
914 notmuch search --query=sexp '(macro (a) (and ,b (subject maildir)))' >OUTPUT 2>&1
915 cat <<EOF > EXPECTED
916 notmuch search: Syntax error in query
917 macro definition not permitted here
918 EOF
919 test_expect_equal_file EXPECTED OUTPUT
920
921 test_begin_subtest "zero argument macro"
922 notmuch search tag:inbox and subject:maildir | notmuch_search_sanitize > EXPECTED
923 notmuch config set squery.TagSubject0  '(macro () (and (tag inbox) (subject maildir)))'
924 notmuch search --query=sexp '(TagSubject0)' | notmuch_search_sanitize > OUTPUT
925 test_expect_equal_file EXPECTED OUTPUT
926
927 test_begin_subtest "undefined argument"
928 notmuch search tag:inbox and subject:maildir | notmuch_search_sanitize > EXPECTED
929 notmuch config set squery.Bad6  '(macro (a) (and ,b (subject maildir)))'
930 notmuch search --query=sexp '(Bad6 foo)' >OUTPUT 2>&1
931 cat <<EOF > EXPECTED
932 notmuch search: Syntax error in query
933 undefined parameter b
934 EOF
935 test_expect_equal_file EXPECTED OUTPUT
936
937 test_begin_subtest "Single argument macro"
938 notmuch search tag:inbox and subject:maildir | notmuch_search_sanitize > EXPECTED
939 notmuch config set squery.TagSubject1  '(macro (tagname) (and (tag ,tagname) (subject maildir)))'
940 notmuch search --query=sexp '(TagSubject1 inbox)' | notmuch_search_sanitize > OUTPUT
941 test_expect_equal_file EXPECTED OUTPUT
942
943 test_begin_subtest "Single argument macro, list argument"
944 notmuch search tag:inbox and subject:maildir | notmuch_search_sanitize > EXPECTED
945 notmuch config set squery.ThingSubject  '(macro (thing) (and ,thing (subject maildir)))'
946 notmuch search --query=sexp '(ThingSubject (tag inbox))' | notmuch_search_sanitize > OUTPUT
947 test_expect_equal_file EXPECTED OUTPUT
948
949 test_begin_subtest "two argument macro"
950 notmuch search tag:inbox and subject:maildir | notmuch_search_sanitize > EXPECTED
951 notmuch config set squery.TagSubject2  '(macro (tagname subj) (and (tag ,tagname) (subject ,subj)))'
952 notmuch search --query=sexp '(TagSubject2 inbox maildir)' | notmuch_search_sanitize > OUTPUT
953 test_expect_equal_file EXPECTED OUTPUT
954
955 test_begin_subtest "nested macros (shadowing)"
956 notmuch search tag:inbox and subject:maildir | notmuch_search_sanitize > EXPECTED
957 notmuch config set squery.Inner '(macro (x) (subject ,x))'
958 notmuch config set squery.Outer  '(macro (x y) (and (tag ,x) (Inner ,y)))'
959 notmuch search --query=sexp '(Outer inbox maildir)' | notmuch_search_sanitize > OUTPUT
960 test_expect_equal_file EXPECTED OUTPUT
961
962 test_begin_subtest "nested macros (no dynamic scope)"
963 notmuch config set squery.Inner2 '(macro (x) (subject ,y))'
964 notmuch config set squery.Outer2  '(macro (x y) (and (tag ,x) (Inner2 ,y)))'
965 notmuch search --query=sexp '(Outer2 inbox maildir)' > OUTPUT 2>&1
966 cat <<EOF > EXPECTED
967 notmuch search: Syntax error in query
968 undefined parameter y
969 EOF
970 test_expect_equal_file EXPECTED OUTPUT
971
972 test_begin_subtest "combine macro and user defined header"
973 notmuch config set squery.About '(macro (name) (or (subject ,name) (List ,name)))'
974 notmuch search subject:notmuch or List:notmuch | notmuch_search_sanitize > EXPECTED
975 notmuch search --query=sexp '(About notmuch)' | notmuch_search_sanitize > OUTPUT
976 test_expect_equal_file EXPECTED OUTPUT
977
978
979 test_begin_subtest "combine macro and user defined header"
980 notmuch config set squery.About '(macro (name) (or (subject ,name) (List ,name)))'
981 notmuch search subject:notmuch or List:notmuch | notmuch_search_sanitize > EXPECTED
982 notmuch search --query=sexp '(About notmuch)' | notmuch_search_sanitize > OUTPUT
983 test_expect_equal_file EXPECTED OUTPUT
984
985
986 test_done