Re: [feature request] emacs: use `notmuch insert` for FCC
[notmuch-archives.git] / 12 / 73625eb762981f4e4da70f128c2ea920e00768
1 Return-Path: <amdragon@mit.edu>\r
2 X-Original-To: notmuch@notmuchmail.org\r
3 Delivered-To: notmuch@notmuchmail.org\r
4 Received: from localhost (localhost [127.0.0.1])\r
5         by olra.theworths.org (Postfix) with ESMTP id 3E434431FAF\r
6         for <notmuch@notmuchmail.org>; Tue, 13 Mar 2012 09:49:09 -0700 (PDT)\r
7 X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
8 X-Spam-Flag: NO\r
9 X-Spam-Score: -0.7\r
10 X-Spam-Level: \r
11 X-Spam-Status: No, score=-0.7 tagged_above=-999 required=5\r
12         tests=[RCVD_IN_DNSWL_LOW=-0.7] autolearn=disabled\r
13 Received: from olra.theworths.org ([127.0.0.1])\r
14         by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
15         with ESMTP id duc7cK61wKaQ for <notmuch@notmuchmail.org>;\r
16         Tue, 13 Mar 2012 09:49:05 -0700 (PDT)\r
17 Received: from dmz-mailsec-scanner-4.mit.edu (DMZ-MAILSEC-SCANNER-4.MIT.EDU\r
18         [18.9.25.15])\r
19         by olra.theworths.org (Postfix) with ESMTP id 4012C431FAE\r
20         for <notmuch@notmuchmail.org>; Tue, 13 Mar 2012 09:49:05 -0700 (PDT)\r
21 X-AuditID: 1209190f-b7f8a6d000000914-60-4f5f7a80452b\r
22 Received: from mailhub-auth-4.mit.edu ( [18.7.62.39])\r
23         by dmz-mailsec-scanner-4.mit.edu (Symantec Messaging Gateway) with SMTP\r
24         id 6F.4A.02324.08A7F5F4; Tue, 13 Mar 2012 12:49:04 -0400 (EDT)\r
25 Received: from outgoing.mit.edu (OUTGOING-AUTH.MIT.EDU [18.7.22.103])\r
26         by mailhub-auth-4.mit.edu (8.13.8/8.9.2) with ESMTP id q2DGn3lk007299; \r
27         Tue, 13 Mar 2012 12:49:04 -0400\r
28 Received: from awakening.csail.mit.edu (awakening.csail.mit.edu [18.26.4.91])\r
29         (authenticated bits=0)\r
30         (User authenticated as amdragon@ATHENA.MIT.EDU)\r
31         by outgoing.mit.edu (8.13.6/8.12.4) with ESMTP id q2DGn2gJ011704\r
32         (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NOT);\r
33         Tue, 13 Mar 2012 12:49:03 -0400 (EDT)\r
34 Received: from amthrax by awakening.csail.mit.edu with local (Exim 4.77)\r
35         (envelope-from <amdragon@mit.edu>)\r
36         id 1S7UuE-0004GO-1R; Tue, 13 Mar 2012 12:49:02 -0400\r
37 Date: Tue, 13 Mar 2012 12:49:02 -0400\r
38 From: Austin Clements <amdragon@MIT.EDU>\r
39 To: Adam Wolfe Gordon <awg+notmuch@xvx.ca>\r
40 Subject: Re: [PATCH v7 01/10] test: Add broken test for the new JSON reply\r
41         format.\r
42 Message-ID: <20120313164901.GD2787@mit.edu>\r
43 References: <1331525142-30539-1-git-send-email-awg+notmuch@xvx.ca>\r
44         <1331525142-30539-2-git-send-email-awg+notmuch@xvx.ca>\r
45 MIME-Version: 1.0\r
46 Content-Type: text/plain; charset=us-ascii\r
47 Content-Disposition: inline\r
48 In-Reply-To: <1331525142-30539-2-git-send-email-awg+notmuch@xvx.ca>\r
49 User-Agent: Mutt/1.5.21 (2010-09-15)\r
50 X-Brightmail-Tracker:\r
51  H4sIAAAAAAAAA+NgFprGKsWRmVeSWpSXmKPExsUixG6nrttQFe9vsHWdqsWRPbPYLa7fnMns\r
52         wOTxbNUtZo+mH4tZA5iiuGxSUnMyy1KL9O0SuDIOXVrIWPBjPVPFqn3LGBsYT71h7GLk5JAQ\r
53         MJFYPPMnO4QtJnHh3no2EFtIYB+jROsZyS5GLiB7A6PE8fmfmSGck0wS8+cfZIVwljBK/LwA\r
54         4nBysAioSkxvXsYEYrMJaEhs278cbIWIgJbEj/VfwWqYBaQlvv1uBqsRFgiRmD7lIVicV0Bb\r
55         YvvSZ+wQq6slHq+byAIRF5Q4OfMJC0SvlsSNfy+BejnA5iz/xwFicgo4SzRPFwGpEBVQkZhy\r
56         chvbBEahWUiaZyFpnoXQvICReRWjbEpulW5uYmZOcWqybnFyYl5eapGuiV5uZoleakrpJkZQ\r
57         YHNK8u9g/HZQ6RCjAAejEg+vokicvxBrYllxZe4hRkkOJiVRXo+KeH8hvqT8lMqMxOKM+KLS\r
58         nNTiQ4wSHMxKIrw2pUA53pTEyqrUonyYlDQHi5I4r5rWOz8hgfTEktTs1NSC1CKYrAwHh5IE\r
59         77ZKoEbBotT01Iq0zJwShDQTByfIcB6g4RNBaniLCxJzizPTIfKnGI057p5fdYmR4+KftZcY\r
60         hVjy8vNSpcR5u0BKBUBKM0rz4KbBktMrRnGg54R514NU8QATG9y8V0CrmIBWlXyLA1lVkoiQ\r
61         kmpgjKz17ctIkDbiZY1Ol967sXSHbvS9oP8iql6T7JnUl+zsOPT5aIKJw7wi67ftjcI7hS9s\r
62         erPyzb07Cw55adYx28+KDizZqa2/by7PrZvlzFqLF2XnqRhX/pEr+7M1+kvL3KrcJ4GTPx89\r
63         yJZguVv46Zocb22/+9lJ1/7fez7HdZKp2WJTF7dUJZbijERDLeai4kQAT4pmFSkDAAA=\r
64 Cc: notmuch@notmuchmail.org\r
65 X-BeenThere: notmuch@notmuchmail.org\r
66 X-Mailman-Version: 2.1.13\r
67 Precedence: list\r
68 List-Id: "Use and development of the notmuch mail system."\r
69         <notmuch.notmuchmail.org>\r
70 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
71         <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
72 List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
73 List-Post: <mailto:notmuch@notmuchmail.org>\r
74 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
75 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
76         <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
77 X-List-Received-Date: Tue, 13 Mar 2012 16:49:09 -0000\r
78 \r
79 Quoth Adam Wolfe Gordon on Mar 11 at 10:05 pm:\r
80 > ---\r
81 >  test/multipart |   53 +++\r
82 >  test/test-lib  | 1242 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++\r
83 >  2 files changed, 1295 insertions(+), 0 deletions(-)\r
84 >  create mode 100755 test/test-lib\r
85\r
86 > diff --git a/test/multipart b/test/multipart\r
87 > index 53782c6..80d6e88 100755\r
88 > --- a/test/multipart\r
89 > +++ b/test/multipart\r
90 > @@ -589,6 +589,59 @@ Non-text part: text/html\r
91 >  EOF\r
92 >  test_expect_equal_file OUTPUT EXPECTED\r
93 >  \r
94 > +test_begin_subtest "'notmuch reply' to a multipart message with json format"\r
95 > +test_subtest_known_broken\r
96 > +notmuch reply --format=json 'id:87liy5ap00.fsf@yoom.home.cworth.org' | notmuch_json_show_sanitize >OUTPUT\r
97 > +cat <<EOF >EXPECTED\r
98 > +{"reply-headers": {"Subject": "Re: Multipart message",\r
99 > + "From": "Notmuch Test Suite <test_suite@notmuchmail.org>",\r
100 > + "To": "Carl Worth <cworth@cworth.org>,\r
101 > + cworth@cworth.org",\r
102 > + "In-reply-to": "<87liy5ap00.fsf@yoom.home.cworth.org>",\r
103 > + "References": " <87liy5ap00.fsf@yoom.home.cworth.org>"},\r
104 > + "original": {"id": "XXXXX",\r
105 > + "match": false,\r
106 > + "excluded": false,\r
107 > + "filename": "YYYYY",\r
108 > + "timestamp": 978709437,\r
109 > + "date_relative": "2001-01-05",\r
110 > + "tags": ["attachment","inbox","signed","unread"],\r
111 > + "headers": {"Subject": "Multipart message",\r
112 > + "From": "Carl Worth <cworth@cworth.org>",\r
113 > + "To": "cworth@cworth.org",\r
114 > + "Date": "Fri,\r
115 > + 05 Jan 2001 15:43:57 +0000"},\r
116 > + "body": [{"id": 1,\r
117 > + "content-type": "multipart/signed",\r
118 > + "content": [{"id": 2,\r
119 > + "content-type": "multipart/mixed",\r
120 > + "content": [{"id": 3,\r
121 > + "content-type": "message/rfc822",\r
122 > + "content": [{"headers": {"Subject": "html message",\r
123 > + "From": "Carl Worth <cworth@cworth.org>",\r
124 > + "To": "cworth@cworth.org",\r
125 > + "Date": "Fri,\r
126 > + 05 Jan 2001 15:42:57 +0000"},\r
127 > + "body": [{"id": 4,\r
128 > + "content-type": "multipart/alternative",\r
129 > + "content": [{"id": 5,\r
130 > + "content-type": "text/html"},\r
131 > + {"id": 6,\r
132 > + "content-type": "text/plain",\r
133 > + "content": "This is an embedded message,\r
134 > + with a multipart/alternative part.\n"}]}]}]},\r
135 > + {"id": 7,\r
136 > + "content-type": "text/plain",\r
137 > + "filename": "YYYYY",\r
138 > + "content": "This is a text attachment.\n"},\r
139 > + {"id": 8,\r
140 > + "content-type": "text/plain",\r
141 > + "content": "And this message is signed.\n\n-Carl\n"}]},\r
142 > + {"id": 9,\r
143 > + "content-type": "application/pgp-signature"}]}]}}\r
144 > +EOF\r
145 > +test_expect_equal_file OUTPUT EXPECTED\r
146 > +\r
147 >  test_begin_subtest "'notmuch show --part' does not corrupt a part with CRLF pair"\r
148 >  notmuch show --format=raw --part=3 id:base64-part-with-crlf > crlf.out\r
149 >  echo -n -e "\xEF\x0D\x0A" > crlf.expected\r
150 > diff --git a/test/test-lib b/test/test-lib\r
151 > new file mode 100755\r
152 > index 0000000..8158328\r
153 > --- /dev/null\r
154 > +++ b/test/test-lib\r
155 \r
156 Spurious git add?  (IIRC, this is what test-lib.sh used to be called,\r
157 so I'd guess you have an old copy of this file laying around.)\r
158 \r
159 > @@ -0,0 +1,1242 @@\r
160 > +#\r
161 > +# Copyright (c) 2005 Junio C Hamano\r
162 > +#\r
163 > +# This program is free software: you can redistribute it and/or modify\r
164 > +# it under the terms of the GNU General Public License as published by\r
165 > +# the Free Software Foundation, either version 2 of the License, or\r
166 > +# (at your option) any later version.\r
167 > +#\r
168 > +# This program is distributed in the hope that it will be useful,\r
169 > +# but WITHOUT ANY WARRANTY; without even the implied warranty of\r
170 > +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
171 > +# GNU General Public License for more details.\r
172 > +#\r
173 > +# You should have received a copy of the GNU General Public License\r
174 > +# along with this program.  If not, see http://www.gnu.org/licenses/ .\r
175 > +\r
176 > +if [ ${BASH_VERSINFO[0]} -lt 4 ]; then\r
177 > +    echo "Error: The notmuch test suite requires a bash version >= 4.0"\r
178 > +    echo "due to use of associative arrays within the test suite."\r
179 > +    echo "Please try again with a newer bash (or help us fix the"\r
180 > +    echo "test suite to be more portable). Thanks."\r
181 > +    exit 1\r
182 > +fi\r
183 > +\r
184 > +# if --tee was passed, write the output not only to the terminal, but\r
185 > +# additionally to the file test-results/$BASENAME.out, too.\r
186 > +case "$GIT_TEST_TEE_STARTED, $* " in\r
187 > +done,*)\r
188 > +     # do not redirect again\r
189 > +     ;;\r
190 > +*' --tee '*|*' --va'*)\r
191 > +     mkdir -p test-results\r
192 > +     BASE=test-results/$(basename "$0" .sh)\r
193 > +     (GIT_TEST_TEE_STARTED=done ${SHELL-sh} "$0" "$@" 2>&1;\r
194 > +      echo $? > $BASE.exit) | tee $BASE.out\r
195 > +     test "$(cat $BASE.exit)" = 0\r
196 > +     exit\r
197 > +     ;;\r
198 > +esac\r
199 > +\r
200 > +# Keep the original TERM for say_color and test_emacs\r
201 > +ORIGINAL_TERM=$TERM\r
202 > +\r
203 > +# For repeatability, reset the environment to known value.\r
204 > +LANG=C\r
205 > +LC_ALL=C\r
206 > +PAGER=cat\r
207 > +TZ=UTC\r
208 > +TERM=dumb\r
209 > +export LANG LC_ALL PAGER TERM TZ\r
210 > +GIT_TEST_CMP=${GIT_TEST_CMP:-diff -u}\r
211 > +TEST_EMACS=${TEST_EMACS:-${EMACS:-emacs}}\r
212 > +\r
213 > +# Protect ourselves from common misconfiguration to export\r
214 > +# CDPATH into the environment\r
215 > +unset CDPATH\r
216 > +\r
217 > +unset GREP_OPTIONS\r
218 > +\r
219 > +# Convenience\r
220 > +#\r
221 > +# A regexp to match 5 and 40 hexdigits\r
222 > +_x05='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'\r
223 > +_x40="$_x05$_x05$_x05$_x05$_x05$_x05$_x05$_x05"\r
224 > +\r
225 > +_x04='[0-9a-f][0-9a-f][0-9a-f][0-9a-f]'\r
226 > +_x32="$_x04$_x04$_x04$_x04$_x04$_x04$_x04$_x04"\r
227 > +\r
228 > +# Each test should start with something like this, after copyright notices:\r
229 > +#\r
230 > +# test_description='Description of this test...\r
231 > +# This test checks if command xyzzy does the right thing...\r
232 > +# '\r
233 > +# . ./test-lib.sh\r
234 > +[ "x$ORIGINAL_TERM" != "xdumb" ] && (\r
235 > +             TERM=$ORIGINAL_TERM &&\r
236 > +             export TERM &&\r
237 > +             [ -t 1 ] &&\r
238 > +             tput bold >/dev/null 2>&1 &&\r
239 > +             tput setaf 1 >/dev/null 2>&1 &&\r
240 > +             tput sgr0 >/dev/null 2>&1\r
241 > +     ) &&\r
242 > +     color=t\r
243 > +\r
244 > +while test "$#" -ne 0\r
245 > +do\r
246 > +     case "$1" in\r
247 > +     -d|--d|--de|--deb|--debu|--debug)\r
248 > +             debug=t; shift ;;\r
249 > +     -i|--i|--im|--imm|--imme|--immed|--immedi|--immedia|--immediat|--immediate)\r
250 > +             immediate=t; shift ;;\r
251 > +     -l|--l|--lo|--lon|--long|--long-|--long-t|--long-te|--long-tes|--long-test|--long-tests)\r
252 > +             GIT_TEST_LONG=t; export GIT_TEST_LONG; shift ;;\r
253 > +     -h|--h|--he|--hel|--help)\r
254 > +             help=t; shift ;;\r
255 > +     -v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose)\r
256 > +             verbose=t; shift ;;\r
257 > +     -q|--q|--qu|--qui|--quie|--quiet)\r
258 > +             quiet=t; shift ;;\r
259 > +     --with-dashes)\r
260 > +             with_dashes=t; shift ;;\r
261 > +     --no-color)\r
262 > +             color=; shift ;;\r
263 > +     --no-python)\r
264 > +             # noop now...\r
265 > +             shift ;;\r
266 > +     --va|--val|--valg|--valgr|--valgri|--valgrin|--valgrind)\r
267 > +             valgrind=t; verbose=t; shift ;;\r
268 > +     --tee)\r
269 > +             shift ;; # was handled already\r
270 > +     --root=*)\r
271 > +             root=$(expr "z$1" : 'z[^=]*=\(.*\)')\r
272 > +             shift ;;\r
273 > +     *)\r
274 > +             echo "error: unknown test option '$1'" >&2; exit 1 ;;\r
275 > +     esac\r
276 > +done\r
277 > +\r
278 > +if test -n "$debug"; then\r
279 > +    print_subtest () {\r
280 > +     printf " %-4s" "[$((test_count - 1))]"\r
281 > +    }\r
282 > +else\r
283 > +    print_subtest () {\r
284 > +     true\r
285 > +    }\r
286 > +fi\r
287 > +\r
288 > +if test -n "$color"; then\r
289 > +     say_color () {\r
290 > +             (\r
291 > +             TERM=$ORIGINAL_TERM\r
292 > +             export TERM\r
293 > +             case "$1" in\r
294 > +                     error) tput bold; tput setaf 1;; # bold red\r
295 > +                     skip)  tput bold; tput setaf 2;; # bold green\r
296 > +                     pass)  tput setaf 2;;            # green\r
297 > +                     info)  tput setaf 3;;            # brown\r
298 > +                     *) test -n "$quiet" && return;;\r
299 > +             esac\r
300 > +             shift\r
301 > +             printf " "\r
302 > +             printf "$@"\r
303 > +             tput sgr0\r
304 > +             print_subtest\r
305 > +             )\r
306 > +     }\r
307 > +else\r
308 > +     say_color() {\r
309 > +             test -z "$1" && test -n "$quiet" && return\r
310 > +             shift\r
311 > +             printf " "\r
312 > +             printf "$@"\r
313 > +             print_subtest\r
314 > +     }\r
315 > +fi\r
316 > +\r
317 > +error () {\r
318 > +     say_color error "error: $*\n"\r
319 > +     GIT_EXIT_OK=t\r
320 > +     exit 1\r
321 > +}\r
322 > +\r
323 > +say () {\r
324 > +     say_color info "$*"\r
325 > +}\r
326 > +\r
327 > +test "${test_description}" != "" ||\r
328 > +error "Test script did not set test_description."\r
329 > +\r
330 > +if test "$help" = "t"\r
331 > +then\r
332 > +     echo "Tests ${test_description}"\r
333 > +     exit 0\r
334 > +fi\r
335 > +\r
336 > +echo $(basename "$0"): "Testing ${test_description}"\r
337 > +\r
338 > +exec 5>&1\r
339 > +\r
340 > +test_failure=0\r
341 > +test_count=0\r
342 > +test_fixed=0\r
343 > +test_broken=0\r
344 > +test_success=0\r
345 > +\r
346 > +die () {\r
347 > +     code=$?\r
348 > +     rm -rf "$TEST_TMPDIR"\r
349 > +     if test -n "$GIT_EXIT_OK"\r
350 > +     then\r
351 > +             exit $code\r
352 > +     else\r
353 > +             echo >&5 "FATAL: Unexpected exit with code $code"\r
354 > +             exit 1\r
355 > +     fi\r
356 > +}\r
357 > +\r
358 > +GIT_EXIT_OK=\r
359 > +# Note: TEST_TMPDIR *NOT* exported!\r
360 > +TEST_TMPDIR=$(mktemp -d "${TMPDIR:-/tmp}/notmuch-test-$$.XXXXXX")\r
361 > +trap 'die' EXIT\r
362 > +\r
363 > +test_decode_color () {\r
364 > +     sed     -e 's/.\[1m/<WHITE>/g' \\r
365 > +             -e 's/.\[31m/<RED>/g' \\r
366 > +             -e 's/.\[32m/<GREEN>/g' \\r
367 > +             -e 's/.\[33m/<YELLOW>/g' \\r
368 > +             -e 's/.\[34m/<BLUE>/g' \\r
369 > +             -e 's/.\[35m/<MAGENTA>/g' \\r
370 > +             -e 's/.\[36m/<CYAN>/g' \\r
371 > +             -e 's/.\[m/<RESET>/g'\r
372 > +}\r
373 > +\r
374 > +q_to_nul () {\r
375 > +     perl -pe 'y/Q/\000/'\r
376 > +}\r
377 > +\r
378 > +q_to_cr () {\r
379 > +     tr Q '\015'\r
380 > +}\r
381 > +\r
382 > +append_cr () {\r
383 > +     sed -e 's/$/Q/' | tr Q '\015'\r
384 > +}\r
385 > +\r
386 > +remove_cr () {\r
387 > +     tr '\015' Q | sed -e 's/Q$//'\r
388 > +}\r
389 > +\r
390 > +# Generate a new message in the mail directory, with a unique message\r
391 > +# ID and subject. The message is not added to the index.\r
392 > +#\r
393 > +# After this function returns, the filename of the generated message\r
394 > +# is available as $gen_msg_filename and the message ID is available as\r
395 > +# $gen_msg_id .\r
396 > +#\r
397 > +# This function supports named parameters with the bash syntax for\r
398 > +# assigning a value to an associative array ([name]=value). The\r
399 > +# supported parameters are:\r
400 > +#\r
401 > +#  [dir]=directory/of/choice\r
402 > +#\r
403 > +#    Generate the message in directory 'directory/of/choice' within\r
404 > +#    the mail store. The directory will be created if necessary.\r
405 > +#\r
406 > +#  [filename]=name\r
407 > +#\r
408 > +#    Store the message in file 'name'. The default is to store it\r
409 > +#    in 'msg-<count>', where <count> is three-digit number of the\r
410 > +#    message.\r
411 > +#\r
412 > +#  [body]=text\r
413 > +#\r
414 > +#    Text to use as the body of the email message\r
415 > +#\r
416 > +#  '[from]="Some User <user@example.com>"'\r
417 > +#  '[to]="Some User <user@example.com>"'\r
418 > +#  '[subject]="Subject of email message"'\r
419 > +#  '[date]="RFC 822 Date"'\r
420 > +#\r
421 > +#    Values for email headers. If not provided, default values will\r
422 > +#    be generated instead.\r
423 > +#\r
424 > +#  '[cc]="Some User <user@example.com>"'\r
425 > +#  [reply-to]=some-address\r
426 > +#  [in-reply-to]=<message-id>\r
427 > +#  [references]=<message-id>\r
428 > +#  [content-type]=content-type-specification\r
429 > +#  '[header]=full header line, including keyword'\r
430 > +#\r
431 > +#    Additional values for email headers. If these are not provided\r
432 > +#    then the relevant headers will simply not appear in the\r
433 > +#    message.\r
434 > +#\r
435 > +#  '[id]=message-id'\r
436 > +#\r
437 > +#    Controls the message-id of the created message.\r
438 > +gen_msg_cnt=0\r
439 > +gen_msg_filename=""\r
440 > +gen_msg_id=""\r
441 > +generate_message ()\r
442 > +{\r
443 > +    # This is our (bash-specific) magic for doing named parameters\r
444 > +    local -A template="($@)"\r
445 > +    local additional_headers\r
446 > +\r
447 > +    gen_msg_cnt=$((gen_msg_cnt + 1))\r
448 > +    if [ -z "${template[filename]}" ]; then\r
449 > +     gen_msg_name="msg-$(printf "%03d" $gen_msg_cnt)"\r
450 > +    else\r
451 > +     gen_msg_name=${template[filename]}\r
452 > +    fi\r
453 > +\r
454 > +    if [ -z "${template[id]}" ]; then\r
455 > +     gen_msg_id="${gen_msg_name%:2,*}@notmuch-test-suite"\r
456 > +    else\r
457 > +     gen_msg_id="${template[id]}"\r
458 > +    fi\r
459 > +\r
460 > +    if [ -z "${template[dir]}" ]; then\r
461 > +     gen_msg_filename="${MAIL_DIR}/$gen_msg_name"\r
462 > +    else\r
463 > +     gen_msg_filename="${MAIL_DIR}/${template[dir]}/$gen_msg_name"\r
464 > +     mkdir -p "$(dirname "$gen_msg_filename")"\r
465 > +    fi\r
466 > +\r
467 > +    if [ -z "${template[body]}" ]; then\r
468 > +     template[body]="This is just a test message (#${gen_msg_cnt})"\r
469 > +    fi\r
470 > +\r
471 > +    if [ -z "${template[from]}" ]; then\r
472 > +     template[from]="Notmuch Test Suite <test_suite@notmuchmail.org>"\r
473 > +    fi\r
474 > +\r
475 > +    if [ -z "${template[to]}" ]; then\r
476 > +     template[to]="Notmuch Test Suite <test_suite@notmuchmail.org>"\r
477 > +    fi\r
478 > +\r
479 > +    if [ -z "${template[subject]}" ]; then\r
480 > +     template[subject]="Test message #${gen_msg_cnt}"\r
481 > +    fi\r
482 > +\r
483 > +    if [ -z "${template[date]}" ]; then\r
484 > +     template[date]="Fri, 05 Jan 2001 15:43:57 +0000"\r
485 > +    fi\r
486 > +\r
487 > +    additional_headers=""\r
488 > +    if [ ! -z "${template[header]}" ]; then\r
489 > +     additional_headers="${template[header]}\r
490 > +${additional_headers}"\r
491 > +    fi\r
492 > +\r
493 > +    if [ ! -z "${template[reply-to]}" ]; then\r
494 > +     additional_headers="Reply-To: ${template[reply-to]}\r
495 > +${additional_headers}"\r
496 > +    fi\r
497 > +\r
498 > +    if [ ! -z "${template[in-reply-to]}" ]; then\r
499 > +     additional_headers="In-Reply-To: ${template[in-reply-to]}\r
500 > +${additional_headers}"\r
501 > +    fi\r
502 > +\r
503 > +    if [ ! -z "${template[cc]}" ]; then\r
504 > +     additional_headers="Cc: ${template[cc]}\r
505 > +${additional_headers}"\r
506 > +    fi\r
507 > +\r
508 > +    if [ ! -z "${template[references]}" ]; then\r
509 > +     additional_headers="References: ${template[references]}\r
510 > +${additional_headers}"\r
511 > +    fi\r
512 > +\r
513 > +    if [ ! -z "${template[content-type]}" ]; then\r
514 > +     additional_headers="Content-Type: ${template[content-type]}\r
515 > +${additional_headers}"\r
516 > +    fi\r
517 > +\r
518 > +    # Note that in the way we're setting it above and using it below,\r
519 > +    # `additional_headers' will also serve as the header / body separator\r
520 > +    # (empty line in between).\r
521 > +\r
522 > +    cat <<EOF >"$gen_msg_filename"\r
523 > +From: ${template[from]}\r
524 > +To: ${template[to]}\r
525 > +Message-Id: <${gen_msg_id}>\r
526 > +Subject: ${template[subject]}\r
527 > +Date: ${template[date]}\r
528 > +${additional_headers}\r
529 > +${template[body]}\r
530 > +EOF\r
531 > +}\r
532 > +\r
533 > +# Generate a new message and add it to the database.\r
534 > +#\r
535 > +# All of the arguments and return values supported by generate_message\r
536 > +# are also supported here, so see that function for details.\r
537 > +add_message ()\r
538 > +{\r
539 > +    generate_message "$@" &&\r
540 > +    notmuch new > /dev/null\r
541 > +}\r
542 > +\r
543 > +# Deliver a message with emacs and add it to the database\r
544 > +#\r
545 > +# Uses emacs to generate and deliver a message to the mail store.\r
546 > +# Accepts arbitrary extra emacs/elisp functions to modify the message\r
547 > +# before sending, which is useful to doing things like attaching files\r
548 > +# to the message and encrypting/signing.\r
549 > +emacs_deliver_message ()\r
550 > +{\r
551 > +    local subject="$1"\r
552 > +    local body="$2"\r
553 > +    shift 2\r
554 > +    # before we can send a message, we have to prepare the FCC maildir\r
555 > +    mkdir -p "$MAIL_DIR"/sent/{cur,new,tmp}\r
556 > +    $TEST_DIRECTORY/smtp-dummy sent_message &\r
557 > +    smtp_dummy_pid=$!\r
558 > +    test_emacs \\r
559 > +     "(let ((message-send-mail-function 'message-smtpmail-send-it)\r
560 > +            (smtpmail-smtp-server \"localhost\")\r
561 > +            (smtpmail-smtp-service \"25025\"))\r
562 > +        (notmuch-hello)\r
563 > +        (notmuch-mua-mail)\r
564 > +        (message-goto-to)\r
565 > +        (insert \"test_suite@notmuchmail.org\nDate: 01 Jan 2000 12:00:00 -0000\")\r
566 > +        (message-goto-subject)\r
567 > +        (insert \"${subject}\")\r
568 > +        (message-goto-body)\r
569 > +        (insert \"${body}\")\r
570 > +        $@\r
571 > +        (message-send-and-exit))"\r
572 > +    # opportunistically quit smtp-dummy in case above fails.\r
573 > +    { echo QUIT > /dev/tcp/localhost/25025; } 2>/dev/null\r
574 > +    wait ${smtp_dummy_pid}\r
575 > +    notmuch new >/dev/null\r
576 > +}\r
577 > +\r
578 > +# Generate a corpus of email and add it to the database.\r
579 > +#\r
580 > +# This corpus is fixed, (it happens to be 50 messages from early in\r
581 > +# the history of the notmuch mailing list), which allows for reliably\r
582 > +# testing commands that need to operate on a not-totally-trivial\r
583 > +# number of messages.\r
584 > +add_email_corpus ()\r
585 > +{\r
586 > +    rm -rf ${MAIL_DIR}\r
587 > +    if [ -d $TEST_DIRECTORY/corpus.mail ]; then\r
588 > +     cp -a $TEST_DIRECTORY/corpus.mail ${MAIL_DIR}\r
589 > +    else\r
590 > +     cp -a $TEST_DIRECTORY/corpus ${MAIL_DIR}\r
591 > +     notmuch new >/dev/null\r
592 > +     cp -a ${MAIL_DIR} $TEST_DIRECTORY/corpus.mail\r
593 > +    fi\r
594 > +}\r
595 > +\r
596 > +test_begin_subtest ()\r
597 > +{\r
598 > +    if [ -n "$inside_subtest" ]; then\r
599 > +     exec 1>&6 2>&7          # Restore stdout and stderr\r
600 > +     error "bug in test script: Missing test_expect_equal in ${BASH_SOURCE[1]}:${BASH_LINENO[0]}"\r
601 > +    fi\r
602 > +    test_subtest_name="$1"\r
603 > +    test_reset_state_\r
604 > +    # Remember stdout and stderr file descriptors and redirect test\r
605 > +    # output to the previously prepared file descriptors 3 and 4 (see\r
606 > +    # below)\r
607 > +    if test "$verbose" != "t"; then exec 4>test.output 3>&4; fi\r
608 > +    exec 6>&1 7>&2 >&3 2>&4\r
609 > +    inside_subtest=t\r
610 > +}\r
611 > +\r
612 > +# Pass test if two arguments match\r
613 > +#\r
614 > +# Note: Unlike all other test_expect_* functions, this function does\r
615 > +# not accept a test name. Instead, the caller should call\r
616 > +# test_begin_subtest before calling this function in order to set the\r
617 > +# name.\r
618 > +test_expect_equal ()\r
619 > +{\r
620 > +     exec 1>&6 2>&7          # Restore stdout and stderr\r
621 > +     inside_subtest=\r
622 > +     test "$#" = 3 && { prereq=$1; shift; } || prereq=\r
623 > +     test "$#" = 2 ||\r
624 > +     error "bug in the test script: not 2 or 3 parameters to test_expect_equal"\r
625 > +\r
626 > +     output="$1"\r
627 > +     expected="$2"\r
628 > +     if ! test_skip "$test_subtest_name"\r
629 > +     then\r
630 > +             if [ "$output" = "$expected" ]; then\r
631 > +                     test_ok_ "$test_subtest_name"\r
632 > +             else\r
633 > +                     testname=$this_test.$test_count\r
634 > +                     echo "$expected" > $testname.expected\r
635 > +                     echo "$output" > $testname.output\r
636 > +                     test_failure_ "$test_subtest_name" "$(diff -u $testname.expected $testname.output)"\r
637 > +             fi\r
638 > +    fi\r
639 > +}\r
640 > +\r
641 > +# Like test_expect_equal, but takes two filenames.\r
642 > +test_expect_equal_file ()\r
643 > +{\r
644 > +     exec 1>&6 2>&7          # Restore stdout and stderr\r
645 > +     inside_subtest=\r
646 > +     test "$#" = 3 && { prereq=$1; shift; } || prereq=\r
647 > +     test "$#" = 2 ||\r
648 > +     error "bug in the test script: not 2 or 3 parameters to test_expect_equal"\r
649 > +\r
650 > +     output="$1"\r
651 > +     expected="$2"\r
652 > +     if ! test_skip "$test_subtest_name"\r
653 > +     then\r
654 > +             if diff -q "$expected" "$output" >/dev/null ; then\r
655 > +                     test_ok_ "$test_subtest_name"\r
656 > +             else\r
657 > +                     testname=$this_test.$test_count\r
658 > +                     cp "$output" $testname.output\r
659 > +                     cp "$expected" $testname.expected\r
660 > +                     test_failure_ "$test_subtest_name" "$(diff -u $testname.expected $testname.output)"\r
661 > +             fi\r
662 > +    fi\r
663 > +}\r
664 > +\r
665 > +test_emacs_expect_t () {\r
666 > +     test "$#" = 2 && { prereq=$1; shift; } || prereq=\r
667 > +     test "$#" = 1 ||\r
668 > +     error "bug in the test script: not 1 or 2 parameters to test_emacs_expect_t"\r
669 > +\r
670 > +     # Run the test.\r
671 > +     if ! test_skip "$test_subtest_name"\r
672 > +     then\r
673 > +             test_emacs "(notmuch-test-run $1)" >/dev/null\r
674 > +\r
675 > +             # Restore state after the test.\r
676 > +             exec 1>&6 2>&7          # Restore stdout and stderr\r
677 > +             inside_subtest=\r
678 > +\r
679 > +             # Report success/failure.\r
680 > +             result=$(cat OUTPUT)\r
681 > +             if [ "$result" = t ]\r
682 > +             then\r
683 > +                     test_ok_ "$test_subtest_name"\r
684 > +             else\r
685 > +                     test_failure_ "$test_subtest_name" "${result}"\r
686 > +             fi\r
687 > +     else\r
688 > +             # Restore state after the (non) test.\r
689 > +             exec 1>&6 2>&7          # Restore stdout and stderr\r
690 > +             inside_subtest=\r
691 > +     fi\r
692 > +}\r
693 > +\r
694 > +NOTMUCH_NEW ()\r
695 > +{\r
696 > +    notmuch new | grep -v -E -e '^Processed [0-9]*( total)? file|Found [0-9]* total file'\r
697 > +}\r
698 > +\r
699 > +notmuch_search_sanitize ()\r
700 > +{\r
701 > +    sed -r -e 's/("?thread"?: ?)("?)................("?)/\1\2XXX\3/'\r
702 > +}\r
703 > +\r
704 > +NOTMUCH_SHOW_FILENAME_SQUELCH='s,filename:.*/mail,filename:/XXX/mail,'\r
705 > +notmuch_show_sanitize ()\r
706 > +{\r
707 > +    sed -e "$NOTMUCH_SHOW_FILENAME_SQUELCH"\r
708 > +}\r
709 > +notmuch_show_sanitize_all ()\r
710 > +{\r
711 > +    sed \\r
712 > +     -e 's| filename:.*| filename:XXXXX|' \\r
713 > +     -e 's| id:[^ ]* | id:XXXXX |'\r
714 > +}\r
715 > +\r
716 > +notmuch_json_show_sanitize ()\r
717 > +{\r
718 > +    sed -e 's|, |,\n |g' | \\r
719 > +     sed \\r
720 > +     -e 's|"id": "[^"]*",|"id": "XXXXX",|' \\r
721 > +     -e 's|"filename": "[^"]*",|"filename": "YYYYY",|'\r
722 > +}\r
723 > +\r
724 > +# End of notmuch helper functions\r
725 > +\r
726 > +# Use test_set_prereq to tell that a particular prerequisite is available.\r
727 > +# The prerequisite can later be checked for in two ways:\r
728 > +#\r
729 > +# - Explicitly using test_have_prereq.\r
730 > +#\r
731 > +# - Implicitly by specifying the prerequisite tag in the calls to\r
732 > +#   test_expect_{success,failure,code}.\r
733 > +#\r
734 > +# The single parameter is the prerequisite tag (a simple word, in all\r
735 > +# capital letters by convention).\r
736 > +\r
737 > +test_set_prereq () {\r
738 > +     satisfied="$satisfied$1 "\r
739 > +}\r
740 > +satisfied=" "\r
741 > +\r
742 > +test_have_prereq () {\r
743 > +     case $satisfied in\r
744 > +     *" $1 "*)\r
745 > +             : yes, have it ;;\r
746 > +     *)\r
747 > +             ! : nope ;;\r
748 > +     esac\r
749 > +}\r
750 > +\r
751 > +# declare prerequisite for the given external binary\r
752 > +test_declare_external_prereq () {\r
753 > +     binary="$1"\r
754 > +     test "$#" = 2 && name=$2 || name="$binary(1)"\r
755 > +\r
756 > +     hash $binary 2>/dev/null || eval "\r
757 > +     test_missing_external_prereq_${binary}_=t\r
758 > +$binary () {\r
759 > +     echo -n \"\$test_subtest_missing_external_prereqs_ \" | grep -qe \" $name \" ||\r
760 > +     test_subtest_missing_external_prereqs_=\"\$test_subtest_missing_external_prereqs_ $name\"\r
761 > +     false\r
762 > +}"\r
763 > +}\r
764 > +\r
765 > +# Explicitly require external prerequisite.  Useful when binary is\r
766 > +# called indirectly (e.g. from emacs).\r
767 > +# Returns success if dependency is available, failure otherwise.\r
768 > +test_require_external_prereq () {\r
769 > +     binary="$1"\r
770 > +     if [ "$(eval echo -n \$test_missing_external_prereq_${binary}_)" = t ]; then\r
771 > +             # dependency is missing, call the replacement function to note it\r
772 > +             eval "$binary"\r
773 > +     else\r
774 > +             true\r
775 > +     fi\r
776 > +}\r
777 > +\r
778 > +# You are not expected to call test_ok_ and test_failure_ directly, use\r
779 > +# the text_expect_* functions instead.\r
780 > +\r
781 > +test_ok_ () {\r
782 > +     if test "$test_subtest_known_broken_" = "t"; then\r
783 > +             test_known_broken_ok_ "$@"\r
784 > +             return\r
785 > +     fi\r
786 > +     test_success=$(($test_success + 1))\r
787 > +     say_color pass "%-6s" "PASS"\r
788 > +     echo " $@"\r
789 > +}\r
790 > +\r
791 > +test_failure_ () {\r
792 > +     if test "$test_subtest_known_broken_" = "t"; then\r
793 > +             test_known_broken_failure_ "$@"\r
794 > +             return\r
795 > +     fi\r
796 > +     test_failure=$(($test_failure + 1))\r
797 > +     test_failure_message_ "FAIL" "$@"\r
798 > +     test "$immediate" = "" || { GIT_EXIT_OK=t; exit 1; }\r
799 > +     return 1\r
800 > +}\r
801 > +\r
802 > +test_failure_message_ () {\r
803 > +     say_color error "%-6s" "$1"\r
804 > +     echo " $2"\r
805 > +     shift 2\r
806 > +     echo "$@" | sed -e 's/^/        /'\r
807 > +     if test "$verbose" != "t"; then cat test.output; fi\r
808 > +}\r
809 > +\r
810 > +test_known_broken_ok_ () {\r
811 > +     test_reset_state_\r
812 > +     test_fixed=$(($test_fixed+1))\r
813 > +     say_color pass "%-6s" "FIXED"\r
814 > +     echo " $@"\r
815 > +}\r
816 > +\r
817 > +test_known_broken_failure_ () {\r
818 > +     test_reset_state_\r
819 > +     test_broken=$(($test_broken+1))\r
820 > +     test_failure_message_ "BROKEN" "$@"\r
821 > +     return 1\r
822 > +}\r
823 > +\r
824 > +test_debug () {\r
825 > +     test "$debug" = "" || eval "$1"\r
826 > +}\r
827 > +\r
828 > +test_run_ () {\r
829 > +     test_cleanup=:\r
830 > +     if test "$verbose" != "t"; then exec 4>test.output 3>&4; fi\r
831 > +     eval >&3 2>&4 "$1"\r
832 > +     eval_ret=$?\r
833 > +     eval >&3 2>&4 "$test_cleanup"\r
834 > +     return 0\r
835 > +}\r
836 > +\r
837 > +test_skip () {\r
838 > +     test_count=$(($test_count+1))\r
839 > +     to_skip=\r
840 > +     for skp in $NOTMUCH_SKIP_TESTS\r
841 > +     do\r
842 > +             case $this_test.$test_count in\r
843 > +             $skp)\r
844 > +                     to_skip=t\r
845 > +             esac\r
846 > +     done\r
847 > +     if test -z "$to_skip" && test -n "$prereq" &&\r
848 > +        ! test_have_prereq "$prereq"\r
849 > +     then\r
850 > +             to_skip=t\r
851 > +     fi\r
852 > +     case "$to_skip" in\r
853 > +     t)\r
854 > +             test_report_skip_ "$@"\r
855 > +             ;;\r
856 > +     *)\r
857 > +             test_check_missing_external_prereqs_ "$@"\r
858 > +             ;;\r
859 > +     esac\r
860 > +}\r
861 > +\r
862 > +test_check_missing_external_prereqs_ () {\r
863 > +     if test -n "$test_subtest_missing_external_prereqs_"; then\r
864 > +             say_color skip >&3 "missing prerequisites:"\r
865 > +             echo "$test_subtest_missing_external_prereqs_" >&3\r
866 > +             test_report_skip_ "$@"\r
867 > +     else\r
868 > +             false\r
869 > +     fi\r
870 > +}\r
871 > +\r
872 > +test_report_skip_ () {\r
873 > +     test_reset_state_\r
874 > +     say_color skip >&3 "skipping test:"\r
875 > +     echo " $@" >&3\r
876 > +     say_color skip "%-6s" "SKIP"\r
877 > +     echo " $1"\r
878 > +}\r
879 > +\r
880 > +test_subtest_known_broken () {\r
881 > +     test_subtest_known_broken_=t\r
882 > +}\r
883 > +\r
884 > +test_expect_success () {\r
885 > +     test "$#" = 3 && { prereq=$1; shift; } || prereq=\r
886 > +     test "$#" = 2 ||\r
887 > +     error "bug in the test script: not 2 or 3 parameters to test-expect-success"\r
888 > +     test_reset_state_\r
889 > +     if ! test_skip "$@"\r
890 > +     then\r
891 > +             test_run_ "$2"\r
892 > +             run_ret="$?"\r
893 > +             # test_run_ may update missing external prerequisites\r
894 > +             test_check_missing_external_prereqs_ "$@" ||\r
895 > +             if [ "$run_ret" = 0 -a "$eval_ret" = 0 ]\r
896 > +             then\r
897 > +                     test_ok_ "$1"\r
898 > +             else\r
899 > +                     test_failure_ "$@"\r
900 > +             fi\r
901 > +     fi\r
902 > +}\r
903 > +\r
904 > +test_expect_code () {\r
905 > +     test "$#" = 4 && { prereq=$1; shift; } || prereq=\r
906 > +     test "$#" = 3 ||\r
907 > +     error "bug in the test script: not 3 or 4 parameters to test-expect-code"\r
908 > +     test_reset_state_\r
909 > +     if ! test_skip "$@"\r
910 > +     then\r
911 > +             test_run_ "$3"\r
912 > +             run_ret="$?"\r
913 > +             # test_run_ may update missing external prerequisites,\r
914 > +             test_check_missing_external_prereqs_ "$@" ||\r
915 > +             if [ "$run_ret" = 0 -a "$eval_ret" = "$1" ]\r
916 > +             then\r
917 > +                     test_ok_ "$2"\r
918 > +             else\r
919 > +                     test_failure_ "$@"\r
920 > +             fi\r
921 > +     fi\r
922 > +}\r
923 > +\r
924 > +# test_external runs external test scripts that provide continuous\r
925 > +# test output about their progress, and succeeds/fails on\r
926 > +# zero/non-zero exit code.  It outputs the test output on stdout even\r
927 > +# in non-verbose mode, and announces the external script with "* run\r
928 > +# <n>: ..." before running it.  When providing relative paths, keep in\r
929 > +# mind that all scripts run in "trash directory".\r
930 > +# Usage: test_external description command arguments...\r
931 > +# Example: test_external 'Perl API' perl ../path/to/test.pl\r
932 > +test_external () {\r
933 > +     test "$#" = 4 && { prereq=$1; shift; } || prereq=\r
934 > +     test "$#" = 3 ||\r
935 > +     error >&5 "bug in the test script: not 3 or 4 parameters to test_external"\r
936 > +     descr="$1"\r
937 > +     shift\r
938 > +     test_reset_state_\r
939 > +     if ! test_skip "$descr" "$@"\r
940 > +     then\r
941 > +             # Announce the script to reduce confusion about the\r
942 > +             # test output that follows.\r
943 > +             say_color "" " run $test_count: $descr ($*)"\r
944 > +             # Run command; redirect its stderr to &4 as in\r
945 > +             # test_run_, but keep its stdout on our stdout even in\r
946 > +             # non-verbose mode.\r
947 > +             "$@" 2>&4\r
948 > +             if [ "$?" = 0 ]\r
949 > +             then\r
950 > +                     test_ok_ "$descr"\r
951 > +             else\r
952 > +                     test_failure_ "$descr" "$@"\r
953 > +             fi\r
954 > +     fi\r
955 > +}\r
956 > +\r
957 > +# Like test_external, but in addition tests that the command generated\r
958 > +# no output on stderr.\r
959 > +test_external_without_stderr () {\r
960 > +     # The temporary file has no (and must have no) security\r
961 > +     # implications.\r
962 > +     tmp="$TMPDIR"; if [ -z "$tmp" ]; then tmp=/tmp; fi\r
963 > +     stderr="$tmp/git-external-stderr.$$.tmp"\r
964 > +     test_external "$@" 4> "$stderr"\r
965 > +     [ -f "$stderr" ] || error "Internal error: $stderr disappeared."\r
966 > +     descr="no stderr: $1"\r
967 > +     shift\r
968 > +     if [ ! -s "$stderr" ]; then\r
969 > +             rm "$stderr"\r
970 > +             test_ok_ "$descr"\r
971 > +     else\r
972 > +             if [ "$verbose" = t ]; then\r
973 > +                     output=`echo; echo Stderr is:; cat "$stderr"`\r
974 > +             else\r
975 > +                     output=\r
976 > +             fi\r
977 > +             # rm first in case test_failure exits.\r
978 > +             rm "$stderr"\r
979 > +             test_failure_ "$descr" "$@" "$output"\r
980 > +     fi\r
981 > +}\r
982 > +\r
983 > +# This is not among top-level (test_expect_success)\r
984 > +# but is a prefix that can be used in the test script, like:\r
985 > +#\r
986 > +#    test_expect_success 'complain and die' '\r
987 > +#           do something &&\r
988 > +#           do something else &&\r
989 > +#        test_must_fail git checkout ../outerspace\r
990 > +#    '\r
991 > +#\r
992 > +# Writing this as "! git checkout ../outerspace" is wrong, because\r
993 > +# the failure could be due to a segv.  We want a controlled failure.\r
994 > +\r
995 > +test_must_fail () {\r
996 > +     "$@"\r
997 > +     test $? -gt 0 -a $? -le 129 -o $? -gt 192\r
998 > +}\r
999 > +\r
1000 > +# test_cmp is a helper function to compare actual and expected output.\r
1001 > +# You can use it like:\r
1002 > +#\r
1003 > +#    test_expect_success 'foo works' '\r
1004 > +#            echo expected >expected &&\r
1005 > +#            foo >actual &&\r
1006 > +#            test_cmp expected actual\r
1007 > +#    '\r
1008 > +#\r
1009 > +# This could be written as either "cmp" or "diff -u", but:\r
1010 > +# - cmp's output is not nearly as easy to read as diff -u\r
1011 > +# - not all diff versions understand "-u"\r
1012 > +\r
1013 > +test_cmp() {\r
1014 > +     $GIT_TEST_CMP "$@"\r
1015 > +}\r
1016 > +\r
1017 > +# This function can be used to schedule some commands to be run\r
1018 > +# unconditionally at the end of the test to restore sanity:\r
1019 > +#\r
1020 > +#    test_expect_success 'test core.capslock' '\r
1021 > +#            git config core.capslock true &&\r
1022 > +#            test_when_finished "git config --unset core.capslock" &&\r
1023 > +#            hello world\r
1024 > +#    '\r
1025 > +#\r
1026 > +# That would be roughly equivalent to\r
1027 > +#\r
1028 > +#    test_expect_success 'test core.capslock' '\r
1029 > +#            git config core.capslock true &&\r
1030 > +#            hello world\r
1031 > +#            git config --unset core.capslock\r
1032 > +#    '\r
1033 > +#\r
1034 > +# except that the greeting and config --unset must both succeed for\r
1035 > +# the test to pass.\r
1036 > +\r
1037 > +test_when_finished () {\r
1038 > +     test_cleanup="{ $*\r
1039 > +             } && (exit \"\$eval_ret\"); eval_ret=\$?; $test_cleanup"\r
1040 > +}\r
1041 > +\r
1042 > +test_done () {\r
1043 > +     GIT_EXIT_OK=t\r
1044 > +     test_results_dir="$TEST_DIRECTORY/test-results"\r
1045 > +     mkdir -p "$test_results_dir"\r
1046 > +     test_results_path="$test_results_dir/${0%.sh}-$$"\r
1047 > +\r
1048 > +     echo "total $test_count" >> $test_results_path\r
1049 > +     echo "success $test_success" >> $test_results_path\r
1050 > +     echo "fixed $test_fixed" >> $test_results_path\r
1051 > +     echo "broken $test_broken" >> $test_results_path\r
1052 > +     echo "failed $test_failure" >> $test_results_path\r
1053 > +     echo "" >> $test_results_path\r
1054 > +\r
1055 > +     echo\r
1056 > +\r
1057 > +     [ -n "$EMACS_SERVER" ] && test_emacs '(kill-emacs)'\r
1058 > +\r
1059 > +     if [ "$test_failure" = "0" ]; then\r
1060 > +         if [ "$test_broken" = "0" ]; then\r
1061 > +             rm -rf "$remove_tmp"\r
1062 > +         fi\r
1063 > +         exit 0\r
1064 > +     else\r
1065 > +         exit 1\r
1066 > +     fi\r
1067 > +}\r
1068 > +\r
1069 > +emacs_generate_script () {\r
1070 > +     # Construct a little test script here for the benefit of the user,\r
1071 > +     # (who can easily run "run_emacs" to get the same emacs environment\r
1072 > +     # for investigating any failures).\r
1073 > +     cat <<EOF >"$TMP_DIRECTORY/run_emacs"\r
1074 > +#!/bin/sh\r
1075 > +export PATH=$PATH\r
1076 > +export NOTMUCH_CONFIG=$NOTMUCH_CONFIG\r
1077 > +\r
1078 > +# Here's what we are using here:\r
1079 > +#\r
1080 > +# --no-init-file     Don't load users ~/.emacs\r
1081 > +#\r
1082 > +# --no-site-file     Don't load the site-wide startup stuff\r
1083 > +#\r
1084 > +# --directory                Ensure that the local elisp sources are found\r
1085 > +#\r
1086 > +# --load             Force loading of notmuch.el and test-lib.el\r
1087 > +\r
1088 > +exec ${TEST_EMACS} --no-init-file --no-site-file \\r
1089 > +     --directory "$TEST_DIRECTORY/../emacs" --load notmuch.el \\r
1090 > +     --directory "$TEST_DIRECTORY" --load test-lib.el \\r
1091 > +     "\$@"\r
1092 > +EOF\r
1093 > +     chmod a+x "$TMP_DIRECTORY/run_emacs"\r
1094 > +}\r
1095 > +\r
1096 > +test_emacs () {\r
1097 > +     # test dependencies beforehand to avoid the waiting loop below\r
1098 > +     missing_dependencies=\r
1099 > +     test_require_external_prereq dtach || missing_dependencies=1\r
1100 > +     test_require_external_prereq emacs || missing_dependencies=1\r
1101 > +     test_require_external_prereq emacsclient || missing_dependencies=1\r
1102 > +     test -z "$missing_dependencies" || return\r
1103 > +\r
1104 > +     if [ -z "$EMACS_SERVER" ]; then\r
1105 > +             server_name="notmuch-test-suite-$$"\r
1106 > +             # start a detached session with an emacs server\r
1107 > +             # user's TERM is given to dtach which assumes a minimally\r
1108 > +             # VT100-compatible terminal -- and emacs inherits that\r
1109 > +             TERM=$ORIGINAL_TERM dtach -n "$TEST_TMPDIR/emacs-dtach-socket.$$" \\r
1110 > +                     sh -c "stty rows 24 cols 80; exec '$TMP_DIRECTORY/run_emacs' \\r
1111 > +                             --no-window-system \\r
1112 > +                             --eval '(setq server-name \"$server_name\")' \\r
1113 > +                             --eval '(server-start)' \\r
1114 > +                             --eval '(orphan-watchdog $$)'" || return\r
1115 > +             EMACS_SERVER="$server_name"\r
1116 > +             # wait until the emacs server is up\r
1117 > +             until test_emacs '()' >/dev/null 2>/dev/null; do\r
1118 > +                     sleep 1\r
1119 > +             done\r
1120 > +     fi\r
1121 > +\r
1122 > +     emacsclient --socket-name="$EMACS_SERVER" --eval "(progn $@)"\r
1123 > +}\r
1124 > +\r
1125 > +test_python() {\r
1126 > +     export LD_LIBRARY_PATH=$TEST_DIRECTORY/../lib\r
1127 > +     export PYTHONPATH=$TEST_DIRECTORY/../bindings/python\r
1128 > +\r
1129 > +     # Some distros (e.g. Arch Linux) ship Python 2.* as /usr/bin/python2,\r
1130 > +     # most others as /usr/bin/python. So first try python2, and fallback to\r
1131 > +     # python if python2 doesn't exist.\r
1132 > +     cmd=python2\r
1133 > +     [[ "$test_missing_external_prereq_python2_" = t ]] && cmd=python\r
1134 > +\r
1135 > +     (echo "import sys; _orig_stdout=sys.stdout; sys.stdout=open('OUTPUT', 'w')"; cat) \\r
1136 > +             | $cmd -\r
1137 > +}\r
1138 > +\r
1139 > +# Creates a script that counts how much time it is executed and calls\r
1140 > +# notmuch.  $notmuch_counter_command is set to the path to the\r
1141 > +# generated script.  Use notmuch_counter_value() function to get the\r
1142 > +# current counter value.\r
1143 > +notmuch_counter_reset () {\r
1144 > +     notmuch_counter_command="$TMP_DIRECTORY/notmuch_counter"\r
1145 > +     if [ ! -x "$notmuch_counter_command" ]; then\r
1146 > +             notmuch_counter_state_path="$TMP_DIRECTORY/notmuch_counter.state"\r
1147 > +             cat >"$notmuch_counter_command" <<EOF || return\r
1148 > +#!/bin/sh\r
1149 > +\r
1150 > +read count < "$notmuch_counter_state_path"\r
1151 > +echo \$((count + 1)) > "$notmuch_counter_state_path"\r
1152 > +\r
1153 > +exec notmuch "\$@"\r
1154 > +EOF\r
1155 > +             chmod +x "$notmuch_counter_command" || return\r
1156 > +     fi\r
1157 > +\r
1158 > +     echo 0 > "$notmuch_counter_state_path"\r
1159 > +}\r
1160 > +\r
1161 > +# Returns the current notmuch counter value.\r
1162 > +notmuch_counter_value () {\r
1163 > +     if [ -r "$notmuch_counter_state_path" ]; then\r
1164 > +             read count < "$notmuch_counter_state_path"\r
1165 > +     else\r
1166 > +             count=0\r
1167 > +     fi\r
1168 > +     echo $count\r
1169 > +}\r
1170 > +\r
1171 > +test_reset_state_ () {\r
1172 > +     test -z "$test_init_done_" && test_init_\r
1173 > +\r
1174 > +     test_subtest_known_broken_=\r
1175 > +     test_subtest_missing_external_prereqs_=\r
1176 > +}\r
1177 > +\r
1178 > +# called once before the first subtest\r
1179 > +test_init_ () {\r
1180 > +     test_init_done_=t\r
1181 > +\r
1182 > +     # skip all tests if there were external prerequisites missing during init\r
1183 > +     test_check_missing_external_prereqs_ "all tests in $this_test" && test_done\r
1184 > +}\r
1185 > +\r
1186 > +\r
1187 > +find_notmuch_path ()\r
1188 > +{\r
1189 > +    dir="$1"\r
1190 > +\r
1191 > +    while [ -n "$dir" ]; do\r
1192 > +     bin="$dir/notmuch"\r
1193 > +     if [ -x "$bin" ]; then\r
1194 > +         echo "$dir"\r
1195 > +         return\r
1196 > +     fi\r
1197 > +     dir="$(dirname "$dir")"\r
1198 > +     if [ "$dir" = "/" ]; then\r
1199 > +         break\r
1200 > +     fi\r
1201 > +    done\r
1202 > +}\r
1203 > +\r
1204 > +# Test the binaries we have just built.  The tests are kept in\r
1205 > +# test/ subdirectory and are run in 'trash directory' subdirectory.\r
1206 > +TEST_DIRECTORY=$(pwd)\r
1207 > +if test -n "$valgrind"\r
1208 > +then\r
1209 > +     make_symlink () {\r
1210 > +             test -h "$2" &&\r
1211 > +             test "$1" = "$(readlink "$2")" || {\r
1212 > +                     # be super paranoid\r
1213 > +                     if mkdir "$2".lock\r
1214 > +                     then\r
1215 > +                             rm -f "$2" &&\r
1216 > +                             ln -s "$1" "$2" &&\r
1217 > +                             rm -r "$2".lock\r
1218 > +                     else\r
1219 > +                             while test -d "$2".lock\r
1220 > +                             do\r
1221 > +                                     say "Waiting for lock on $2."\r
1222 > +                                     sleep 1\r
1223 > +                             done\r
1224 > +                     fi\r
1225 > +             }\r
1226 > +     }\r
1227 > +\r
1228 > +     make_valgrind_symlink () {\r
1229 > +             # handle only executables\r
1230 > +             test -x "$1" || return\r
1231 > +\r
1232 > +             base=$(basename "$1")\r
1233 > +             symlink_target=$TEST_DIRECTORY/../$base\r
1234 > +             # do not override scripts\r
1235 > +             if test -x "$symlink_target" &&\r
1236 > +                 test ! -d "$symlink_target" &&\r
1237 > +                 test "#!" != "$(head -c 2 < "$symlink_target")"\r
1238 > +             then\r
1239 > +                     symlink_target=$TEST_DIRECTORY/valgrind.sh\r
1240 > +             fi\r
1241 > +             case "$base" in\r
1242 > +             *.sh|*.perl)\r
1243 > +                     symlink_target=$TEST_DIRECTORY/unprocessed-script\r
1244 > +             esac\r
1245 > +             # create the link, or replace it if it is out of date\r
1246 > +             make_symlink "$symlink_target" "$GIT_VALGRIND/bin/$base" || exit\r
1247 > +     }\r
1248 > +\r
1249 > +     # override notmuch executable in TEST_DIRECTORY/..\r
1250 > +     GIT_VALGRIND=$TEST_DIRECTORY/valgrind\r
1251 > +     mkdir -p "$GIT_VALGRIND"/bin\r
1252 > +     make_valgrind_symlink $TEST_DIRECTORY/../notmuch\r
1253 > +     OLDIFS=$IFS\r
1254 > +     IFS=:\r
1255 > +     for path in $PATH\r
1256 > +     do\r
1257 > +             ls "$path"/notmuch 2> /dev/null |\r
1258 > +             while read file\r
1259 > +             do\r
1260 > +                     make_valgrind_symlink "$file"\r
1261 > +             done\r
1262 > +     done\r
1263 > +     IFS=$OLDIFS\r
1264 > +     PATH=$GIT_VALGRIND/bin:$PATH\r
1265 > +     GIT_EXEC_PATH=$GIT_VALGRIND/bin\r
1266 > +     export GIT_VALGRIND\r
1267 > +else # normal case\r
1268 > +     notmuch_path=`find_notmuch_path "$TEST_DIRECTORY"`\r
1269 > +     test -n "$notmuch_path" && PATH="$notmuch_path:$PATH"\r
1270 > +fi\r
1271 > +export PATH\r
1272 > +\r
1273 > +# Test repository\r
1274 > +test="tmp.$(basename "$0" .sh)"\r
1275 > +test -n "$root" && test="$root/$test"\r
1276 > +case "$test" in\r
1277 > +/*) TMP_DIRECTORY="$test" ;;\r
1278 > + *) TMP_DIRECTORY="$TEST_DIRECTORY/$test" ;;\r
1279 > +esac\r
1280 > +test ! -z "$debug" || remove_tmp=$TMP_DIRECTORY\r
1281 > +rm -fr "$test" || {\r
1282 > +     GIT_EXIT_OK=t\r
1283 > +     echo >&5 "FATAL: Cannot prepare test area"\r
1284 > +     exit 1\r
1285 > +}\r
1286 > +\r
1287 > +# A temporary home directory is needed by at least:\r
1288 > +# - emacs/"Sending a message via (fake) SMTP"\r
1289 > +# - emacs/"Reply within emacs"\r
1290 > +# - crypto/emacs_deliver_message\r
1291 > +export HOME="${TMP_DIRECTORY}/home"\r
1292 > +mkdir -p "${HOME}"\r
1293 > +\r
1294 > +MAIL_DIR="${TMP_DIRECTORY}/mail"\r
1295 > +export GNUPGHOME="${TMP_DIRECTORY}/gnupg"\r
1296 > +export NOTMUCH_CONFIG="${TMP_DIRECTORY}/notmuch-config"\r
1297 > +\r
1298 > +mkdir -p "${test}"\r
1299 > +mkdir -p "${MAIL_DIR}"\r
1300 > +\r
1301 > +cat <<EOF >"${NOTMUCH_CONFIG}"\r
1302 > +[database]\r
1303 > +path=${MAIL_DIR}\r
1304 > +\r
1305 > +[user]\r
1306 > +name=Notmuch Test Suite\r
1307 > +primary_email=test_suite@notmuchmail.org\r
1308 > +other_email=test_suite_other@notmuchmail.org;test_suite@otherdomain.org\r
1309 > +EOF\r
1310 > +\r
1311 > +emacs_generate_script\r
1312 > +\r
1313 > +\r
1314 > +# Use -P to resolve symlinks in our working directory so that the cwd\r
1315 > +# in subprocesses like git equals our $PWD (for pathname comparisons).\r
1316 > +cd -P "$test" || error "Cannot setup test environment"\r
1317 > +\r
1318 > +if test "$verbose" = "t"\r
1319 > +then\r
1320 > +     exec 4>&2 3>&1\r
1321 > +else\r
1322 > +     exec 4>test.output 3>&4\r
1323 > +fi\r
1324 > +\r
1325 > +this_test=${0##*/}\r
1326 > +for skp in $NOTMUCH_SKIP_TESTS\r
1327 > +do\r
1328 > +     to_skip=\r
1329 > +     for skp in $NOTMUCH_SKIP_TESTS\r
1330 > +     do\r
1331 > +             case "$this_test" in\r
1332 > +             $skp)\r
1333 > +                     to_skip=t\r
1334 > +             esac\r
1335 > +     done\r
1336 > +     case "$to_skip" in\r
1337 > +     t)\r
1338 > +             say_color skip >&3 "skipping test $this_test altogether"\r
1339 > +             say_color skip "skip all tests in $this_test"\r
1340 > +             test_done\r
1341 > +     esac\r
1342 > +done\r
1343 > +\r
1344 > +# Provide an implementation of the 'yes' utility\r
1345 > +yes () {\r
1346 > +     if test $# = 0\r
1347 > +     then\r
1348 > +             y=y\r
1349 > +     else\r
1350 > +             y="$*"\r
1351 > +     fi\r
1352 > +\r
1353 > +     while echo "$y"\r
1354 > +     do\r
1355 > +             :\r
1356 > +     done\r
1357 > +}\r
1358 > +\r
1359 > +# Fix some commands on Windows\r
1360 > +case $(uname -s) in\r
1361 > +*MINGW*)\r
1362 > +     # Windows has its own (incompatible) sort and find\r
1363 > +     sort () {\r
1364 > +             /usr/bin/sort "$@"\r
1365 > +     }\r
1366 > +     find () {\r
1367 > +             /usr/bin/find "$@"\r
1368 > +     }\r
1369 > +     sum () {\r
1370 > +             md5sum "$@"\r
1371 > +     }\r
1372 > +     # git sees Windows-style pwd\r
1373 > +     pwd () {\r
1374 > +             builtin pwd -W\r
1375 > +     }\r
1376 > +     # no POSIX permissions\r
1377 > +     # backslashes in pathspec are converted to '/'\r
1378 > +     # exec does not inherit the PID\r
1379 > +     ;;\r
1380 > +*)\r
1381 > +     test_set_prereq POSIXPERM\r
1382 > +     test_set_prereq BSLASHPSPEC\r
1383 > +     test_set_prereq EXECKEEPSPID\r
1384 > +     ;;\r
1385 > +esac\r
1386 > +\r
1387 > +test -z "$NO_PERL" && test_set_prereq PERL\r
1388 > +test -z "$NO_PYTHON" && test_set_prereq PYTHON\r
1389 > +\r
1390 > +# test whether the filesystem supports symbolic links\r
1391 > +ln -s x y 2>/dev/null && test -h y 2>/dev/null && test_set_prereq SYMLINKS\r
1392 > +rm -f y\r
1393 > +\r
1394 > +# declare prerequisites for external binaries used in tests\r
1395 > +test_declare_external_prereq dtach\r
1396 > +test_declare_external_prereq emacs\r
1397 > +test_declare_external_prereq emacsclient\r
1398 > +test_declare_external_prereq gdb\r
1399 > +test_declare_external_prereq gpg\r
1400 > +test_declare_external_prereq python\r
1401 > +test_declare_external_prereq python2\r