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