subcommand 1.0.2 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,44 @@
1
+ #!/bin/sh
2
+ test_description="Testing out boo_zoo "
3
+ . ./test-lib.sh
4
+
5
+
6
+
7
+
8
+ test_todo_session "Testing of boo_zoo" <<EOF
9
+ >>> ruby bin/subcommand.rb boo
10
+ cmd: foo
11
+ options ......
12
+ {:force=>true}
13
+ ARGV:
14
+ []
15
+ >>> end
16
+ >>> ruby bin/subcommand.rb boo ruby
17
+ cmd: foo
18
+ options ......
19
+ {:force=>true}
20
+ ARGV:
21
+ ["ruby"]
22
+ >>> end
23
+ >>> ruby bin/subcommand.rb zoo
24
+ cmd: foo
25
+ options ......
26
+ {}
27
+ ARGV:
28
+ ["ruby"]
29
+ >>> end
30
+ >>> ruby bin/subcommand.rb zoo duby
31
+ cmd: foo
32
+ options ......
33
+ {}
34
+ ARGV:
35
+ ["ruby", "duby"]
36
+ >>> end
37
+ >>> ruby bin/subcommand.rb help zoo
38
+ Usage: foo [options]
39
+ desc for foo
40
+ -f, --[no-]force force verbosely
41
+ >>> end
42
+
43
+ EOF
44
+ test_done
data/tests/test-lib.sh ADDED
@@ -0,0 +1,618 @@
1
+ #!/bin/sh
2
+ #
3
+ # Copyright (c) 2005 Junio C Hamano
4
+ #
5
+
6
+ # if --tee was passed, write the output not only to the terminal, but
7
+ # additionally to the file test-results/$BASENAME.out, too.
8
+ case "$TEST_TEE_STARTED, $* " in
9
+ done,*)
10
+ # do not redirect again
11
+ ;;
12
+ *' --tee '*|*' --va'*)
13
+ mkdir -p test-results
14
+ BASE=test-results/$(basename "$0" .sh)
15
+ (TEST_TEE_STARTED=done ${SHELL-sh} "$0" "$@" 2>&1;
16
+ echo $? > $BASE.exit) | tee $BASE.out
17
+ test "$(cat $BASE.exit)" = 0
18
+ exit
19
+ ;;
20
+ esac
21
+
22
+ # Keep the original TERM for say_color
23
+ ORIGINAL_TERM=$TERM
24
+
25
+ # For repeatability, reset the environment to known value.
26
+ LANG=C
27
+ LC_ALL=C
28
+ PAGER=cat
29
+ TZ=UTC
30
+ TERM=dumb
31
+ export LANG LC_ALL PAGER TERM TZ
32
+ EDITOR=:
33
+ VISUAL=:
34
+
35
+ # Protect ourselves from common misconfiguration to export
36
+ # CDPATH into the environment
37
+ unset CDPATH
38
+
39
+ # Protect ourselves from using predefined TODOTXT_CFG_FILE
40
+ unset TODOTXT_CFG_FILE $(set|sed '/^TODOTXT_/!d;s/=.*//')
41
+ # To prevent any damage if someone has still those exported somehow in his env:
42
+ unset TODO_FILE DONE_FILE REPORT_FILE TMP_FILE
43
+
44
+ # Each test should start with something like this, after copyright notices:
45
+ #
46
+ # test_description='Description of this test...
47
+ # This test checks if command xyzzy does the right thing...
48
+ # '
49
+ # . ./test-lib.sh
50
+ [ "x$ORIGINAL_TERM" != "xdumb" ] && (
51
+ TERM=$ORIGINAL_TERM &&
52
+ export TERM &&
53
+ [ -t 1 ] &&
54
+ tput bold >/dev/null 2>&1 &&
55
+ tput setaf 1 >/dev/null 2>&1 &&
56
+ tput sgr0 >/dev/null 2>&1
57
+ ) &&
58
+ color=t
59
+
60
+ while test "$#" -ne 0
61
+ do
62
+ case "$1" in
63
+ -d|--d|--de|--deb|--debu|--debug)
64
+ debug=t; shift ;;
65
+ -i|--i|--im|--imm|--imme|--immed|--immedi|--immedia|--immediat|--immediate)
66
+ immediate=t; shift ;;
67
+ -l|--l|--lo|--lon|--long|--long-|--long-t|--long-te|--long-tes|--long-test|--long-tests)
68
+ TODOTXT_TEST_LONG=t; export TODOTXT_TEST_LONG; shift ;;
69
+ -h|--h|--he|--hel|--help)
70
+ help=t; shift ;;
71
+ -v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose)
72
+ verbose=t; shift ;;
73
+ -q|--q|--qu|--qui|--quie|--quiet)
74
+ quiet=t; shift ;;
75
+ --no-color)
76
+ color=; shift ;;
77
+ --no-python)
78
+ # noop now...
79
+ shift ;;
80
+ --tee)
81
+ shift ;; # was handled already
82
+ *)
83
+ break ;;
84
+ esac
85
+ done
86
+
87
+ if test -n "$color"; then
88
+ say_color () {
89
+ (
90
+ TERM=$ORIGINAL_TERM
91
+ export TERM
92
+ case "$1" in
93
+ error) tput bold; tput setaf 1;; # bold red
94
+ skip) tput bold; tput setaf 2;; # bold green
95
+ pass) tput setaf 2;; # green
96
+ info) tput setaf 3;; # brown
97
+ *) test -n "$quiet" && return;;
98
+ esac
99
+ shift
100
+ printf "* %s" "$*"
101
+ tput sgr0
102
+ echo
103
+ )
104
+ }
105
+ else
106
+ say_color() {
107
+ test -z "$1" && test -n "$quiet" && return
108
+ shift
109
+ echo "* $*"
110
+ }
111
+ fi
112
+
113
+ error () {
114
+ say_color error "error: $*"
115
+ trap - EXIT
116
+ exit 1
117
+ }
118
+
119
+ say () {
120
+ say_color info "$*"
121
+ }
122
+
123
+ test "${test_description}" != "" ||
124
+ error "Test script did not set test_description."
125
+
126
+ if test "$help" = "t"
127
+ then
128
+ echo "$test_description"
129
+ exit 0
130
+ fi
131
+
132
+ exec 5>&1
133
+ if test "$verbose" = "t"
134
+ then
135
+ exec 4>&2 3>&1
136
+ else
137
+ exec 4>/dev/null 3>/dev/null
138
+ fi
139
+
140
+ test_failure=0
141
+ test_count=0
142
+ test_fixed=0
143
+ test_broken=0
144
+ test_success=0
145
+
146
+ die () {
147
+ echo >&5 "FATAL: Unexpected exit with code $?"
148
+ exit 1
149
+ }
150
+
151
+ trap 'die' EXIT
152
+
153
+ # The semantics of the editor variables are that of invoking
154
+ # sh -c "$EDITOR \"$@\"" files ...
155
+ #
156
+ # If our trash directory contains shell metacharacters, they will be
157
+ # interpreted if we just set $EDITOR directly, so do a little dance with
158
+ # environment variables to work around this.
159
+ #
160
+ # In particular, quoting isn't enough, as the path may contain the same quote
161
+ # that we're using.
162
+ test_set_editor () {
163
+ FAKE_EDITOR="$1"
164
+ export FAKE_EDITOR
165
+ VISUAL='"$FAKE_EDITOR"'
166
+ export VISUAL
167
+ }
168
+
169
+ # You are not expected to call test_ok_ and test_failure_ directly, use
170
+ # the text_expect_* functions instead.
171
+
172
+ test_ok_ () {
173
+ test_success=$(($test_success + 1))
174
+ say_color "" " ok $test_count: $@"
175
+ }
176
+
177
+ test_failure_ () {
178
+ test_failure=$(($test_failure + 1))
179
+ say_color error "FAIL $test_count: $1"
180
+ shift
181
+ echo "$@" | sed -e 's/^/ /'
182
+ test "$immediate" = "" || { trap - EXIT; exit 1; }
183
+ }
184
+
185
+ test_known_broken_ok_ () {
186
+ test_fixed=$(($test_fixed+1))
187
+ say_color "" " FIXED $test_count: $@"
188
+ }
189
+
190
+ test_known_broken_failure_ () {
191
+ test_broken=$(($test_broken+1))
192
+ say_color skip " still broken $test_count: $@"
193
+ }
194
+
195
+ test_debug () {
196
+ test "$debug" = "" || eval "$1"
197
+ }
198
+
199
+ test_run_ () {
200
+ eval >&3 2>&4 "$1"
201
+ eval_ret="$?"
202
+ return 0
203
+ }
204
+
205
+ test_skip () {
206
+ test_count=$(($test_count+1))
207
+ to_skip=
208
+ for skp in $SKIP_TESTS
209
+ do
210
+ case $this_test.$test_count in
211
+ $skp)
212
+ to_skip=t
213
+ esac
214
+ done
215
+ case "$to_skip" in
216
+ t)
217
+ say_color skip >&3 "skipping test: $@"
218
+ say_color skip "skip $test_count: $1"
219
+ : true
220
+ ;;
221
+ *)
222
+ false
223
+ ;;
224
+ esac
225
+ }
226
+
227
+ test_expect_failure () {
228
+ test "$#" = 2 ||
229
+ error "bug in the test script: not 2 parameters to test-expect-failure"
230
+ if ! test_skip "$@"
231
+ then
232
+ say >&3 "checking known breakage: $2"
233
+ test_run_ "$2"
234
+ if [ "$?" = 0 -a "$eval_ret" = 0 ]
235
+ then
236
+ test_known_broken_ok_ "$1"
237
+ else
238
+ test_known_broken_failure_ "$1"
239
+ fi
240
+ fi
241
+ echo >&3 ""
242
+ }
243
+
244
+ test_expect_success () {
245
+ test "$#" = 2 ||
246
+ error "bug in the test script: not 2 parameters to test-expect-success"
247
+ if ! test_skip "$@"
248
+ then
249
+ say >&3 "expecting success: $2"
250
+ test_run_ "$2"
251
+ if [ "$?" = 0 -a "$eval_ret" = 0 ]
252
+ then
253
+ test_ok_ "$1"
254
+ else
255
+ test_failure_ "$@"
256
+ fi
257
+ fi
258
+ echo >&3 ""
259
+ }
260
+
261
+ test_expect_code () {
262
+ test "$#" = 3 ||
263
+ error "bug in the test script: not 3 parameters to test-expect-code"
264
+ if ! test_skip "$@"
265
+ then
266
+ say >&3 "expecting exit code $1: $3"
267
+ test_run_ "$3"
268
+ if [ "$?" = 0 -a "$eval_ret" = "$1" ]
269
+ then
270
+ test_ok_ "$2"
271
+ else
272
+ test_failure_ "$@"
273
+ fi
274
+ fi
275
+ echo >&3 ""
276
+ }
277
+
278
+ # test_external runs external test scripts that provide continuous
279
+ # test output about their progress, and succeeds/fails on
280
+ # zero/non-zero exit code. It outputs the test output on stdout even
281
+ # in non-verbose mode, and announces the external script with "* run
282
+ # <n>: ..." before running it. When providing relative paths, keep in
283
+ # mind that all scripts run in "trash directory".
284
+ # Usage: test_external description command arguments...
285
+ # Example: test_external 'Perl API' perl ../path/to/test.pl
286
+ test_external () {
287
+ test "$#" -eq 3 ||
288
+ error >&5 "bug in the test script: not 3 parameters to test_external"
289
+ descr="$1"
290
+ shift
291
+ if ! test_skip "$descr" "$@"
292
+ then
293
+ # Announce the script to reduce confusion about the
294
+ # test output that follows.
295
+ say_color "" " run $test_count: $descr ($*)"
296
+ # Run command; redirect its stderr to &4 as in
297
+ # test_run_, but keep its stdout on our stdout even in
298
+ # non-verbose mode.
299
+ "$@" 2>&4
300
+ if [ "$?" = 0 ]
301
+ then
302
+ test_ok_ "$descr"
303
+ else
304
+ test_failure_ "$descr" "$@"
305
+ fi
306
+ fi
307
+ }
308
+
309
+ # Like test_external, but in addition tests that the command generated
310
+ # no output on stderr.
311
+ test_external_without_stderr () {
312
+ # The temporary file has no (and must have no) security
313
+ # implications.
314
+ tmp="$TMPDIR"; if [ -z "$tmp" ]; then tmp=/tmp; fi
315
+ stderr="$tmp/todotxt-external-stderr.$$.tmp"
316
+ test_external "$@" 4> "$stderr"
317
+ [ -f "$stderr" ] || error "Internal error: $stderr disappeared."
318
+ descr="no stderr: $1"
319
+ shift
320
+ say >&3 "expecting no stderr from previous command"
321
+ if [ ! -s "$stderr" ]; then
322
+ rm "$stderr"
323
+ test_ok_ "$descr"
324
+ else
325
+ if [ "$verbose" = t ]; then
326
+ output=`echo; echo Stderr is:; cat "$stderr"`
327
+ else
328
+ output=
329
+ fi
330
+ # rm first in case test_failure exits.
331
+ rm "$stderr"
332
+ test_failure_ "$descr" "$@" "$output"
333
+ fi
334
+ }
335
+
336
+ # This is not among top-level (test_expect_success | test_expect_failure)
337
+ # but is a prefix that can be used in the test script, like:
338
+ #
339
+ # test_expect_success 'complain and die' '
340
+ # do something &&
341
+ # do something else &&
342
+ # test_must_fail git checkout ../outerspace
343
+ # '
344
+ #
345
+ # Writing this as "! git checkout ../outerspace" is wrong, because
346
+ # the failure could be due to a segv. We want a controlled failure.
347
+
348
+ test_must_fail () {
349
+ "$@"
350
+ test $? -gt 0 -a $? -le 129 -o $? -gt 192
351
+ }
352
+
353
+ # test_cmp is a helper function to compare actual and expected output.
354
+ # You can use it like:
355
+ #
356
+ # test_expect_success 'foo works' '
357
+ # echo expected >expected &&
358
+ # foo >actual &&
359
+ # test_cmp expected actual
360
+ # '
361
+ #
362
+ # This could be written as either "cmp" or "diff -u", but:
363
+ # - cmp's output is not nearly as easy to read as diff -u
364
+ # - not all diff versions understand "-u"
365
+
366
+ test_cmp() {
367
+ diff -u "$@"
368
+ }
369
+
370
+ test_done () {
371
+ trap - EXIT
372
+ test_results_dir="$TEST_DIRECTORY/test-results"
373
+ mkdir -p "$test_results_dir"
374
+ test_results_path="$test_results_dir/${0%.sh}-$$"
375
+
376
+ echo "total $test_count" >> $test_results_path
377
+ echo "success $test_success" >> $test_results_path
378
+ echo "fixed $test_fixed" >> $test_results_path
379
+ echo "broken $test_broken" >> $test_results_path
380
+ echo "failed $test_failure" >> $test_results_path
381
+ echo "" >> $test_results_path
382
+
383
+ if test "$test_fixed" != 0
384
+ then
385
+ say_color pass "fixed $test_fixed known breakage(s)"
386
+ fi
387
+ if test "$test_broken" != 0
388
+ then
389
+ say_color error "still have $test_broken known breakage(s)"
390
+ msg="remaining $(($test_count-$test_broken)) test(s)"
391
+ else
392
+ msg="$test_count test(s)"
393
+ fi
394
+ case "$test_failure" in
395
+ 0)
396
+ say_color pass "passed all $msg"
397
+
398
+ # Clean up this test.
399
+ test -d "$remove_trash" &&
400
+ cd "$(dirname "$remove_trash")" &&
401
+ rm -rf "$(basename "$remove_trash")"
402
+
403
+ exit 0 ;;
404
+
405
+ *)
406
+ say_color error "failed $test_failure among $msg"
407
+ exit 1 ;;
408
+
409
+ esac
410
+ }
411
+
412
+ # Use -P to resolve symlinks in our working directory so that the pwd
413
+ # in subprocesses equals our $PWD (for pathname comparisons).
414
+ cd -P .
415
+
416
+ # Record our location for reference.
417
+ TEST_DIRECTORY=$(pwd)
418
+
419
+ # Test repository
420
+ #test="trash directory.$(basename "$0" .sh)" # RK CHANGED
421
+ test="trashdirectory.$(basename "$0" .sh)"
422
+ test ! -z "$debug" || remove_trash="$TEST_DIRECTORY/$test"
423
+ rm -fr "$test" || {
424
+ trap - EXIT
425
+ echo >&5 "FATAL: Cannot prepare test area"
426
+ exit 1
427
+ }
428
+
429
+ # Most tests can use the created repository, but some may need to create more.
430
+ # Usage: test_init_todo <directory>
431
+ test_init_todo () {
432
+ test "$#" = 1 ||
433
+ error "bug in the test script: not 1 parameter to test_init_todo"
434
+ owd=`pwd`
435
+ root="$1"
436
+ mkdir -p "$root"
437
+ cd "$root" || error "Cannot setup todo dir in $root"
438
+ # Initialize the configuration file. Carefully quoted.
439
+ #sed -e 's|TODO_DIR=.*$|TODO_DIR="'"$TEST_DIRECTORY/$test"'"|' $TEST_DIRECTORY/../todo.cfg > todo.cfg
440
+
441
+ # Install latest todo.sh
442
+ mkdir bin
443
+ # TODO: XXX
444
+ #ln -s "$TEST_DIRECTORY/../todoapp.sh" bin/todoapp.sh
445
+ # ln -s ~/bin/todorb bin/todorb
446
+ ln -s ../../../lib/subcommand.rb bin/subcommand.rb
447
+
448
+ # Initialize a hack date script
449
+ TODO_TEST_REAL_DATE=$(which date)
450
+ TODO_TEST_TIME=1234500000
451
+ export PATH TODO_TEST_REAL_DATE TODO_TEST_TIME
452
+
453
+ # Trying to detect the version of "date" on current system
454
+ DATE_STYLE=unknown
455
+ # on GNU systems (versions may vary):
456
+ #date --version
457
+ #date (GNU coreutils) 6.10
458
+ #...
459
+ if date --version 2>&1 | grep -q "GNU"; then
460
+ DATE_STYLE=GNU
461
+ # on Mac OS X 10.5:
462
+ #date --version
463
+ #date: illegal option -- -
464
+ #usage: date [-jnu] [-d dst] [-r seconds] [-t west] [-v[+|-]val[ymwdHMS]] ...
465
+ #[-f fmt date | [[[mm]dd]HH]MM[[cc]yy][.ss]] [+format]
466
+ elif date --version 2>&1 | grep -q -e "-jnu"; then
467
+ DATE_STYLE=Mac10.5
468
+ # on Mac OS X 10.4:
469
+ #date --version
470
+ #date: illegal option -- -
471
+ #usage: date [-nu] [-r seconds] [+format]
472
+ # date [[[[[cc]yy]mm]dd]hh]mm[.ss]
473
+ elif date --version 2>&1 | grep -q -e "-nu"; then
474
+ DATE_STYLE=Mac10.4
475
+ fi
476
+
477
+ case $DATE_STYLE in
478
+ GNU)
479
+ cat > bin/date <<-EOF
480
+ #!/bin/sh
481
+ exec "$TODO_TEST_REAL_DATE" -d @\$TODO_TEST_TIME \$@
482
+ EOF
483
+ chmod 755 bin/date
484
+ ;;
485
+ Mac10.5)
486
+ cat > bin/date <<-EOF
487
+ #!/bin/sh
488
+ exec "$TODO_TEST_REAL_DATE" -j -f %s \$TODO_TEST_TIME \$@
489
+ EOF
490
+ chmod 755 bin/date
491
+ ;;
492
+ Mac10.4)
493
+ cat > bin/date <<-EOF
494
+ #!/bin/sh
495
+ exec "$TODO_TEST_REAL_DATE" -r \$TODO_TEST_TIME \$@
496
+ EOF
497
+ chmod 755 bin/date
498
+ ;;
499
+ *)
500
+ echo "WARNING: Current date executable not recognized"
501
+ echo "So today date will be used, expect false negative tests..."
502
+ ;;
503
+ esac
504
+
505
+ # Ensure a correct PATH for testing.
506
+ PATH=$owd/$root/bin:$PATH
507
+ export PATH
508
+
509
+ cd "$owd"
510
+ }
511
+
512
+ # Usage: test_tick [increment]
513
+ test_tick () {
514
+ TODO_TEST_TIME=$(($TODO_TEST_TIME + ${1:-86400}))
515
+ }
516
+
517
+ # Generate and run a series of tests based on a transcript.
518
+ # Usage: test_todo_session "description" <<EOF
519
+ # >>> command
520
+ # output1
521
+ # output2
522
+ # >>> command
523
+ # === exit status
524
+ # output3
525
+ # output4
526
+ # EOF
527
+ test_todo_session () {
528
+ test "$#" = 1 ||
529
+ error "bug in the test script: extra args to test_todo_session"
530
+ subnum=1
531
+ cmd=""
532
+ status=0
533
+ > expect
534
+ #while read line
535
+ # earlier the program would stop expect on a blank line which is unacceptable
536
+ # i pass an explicit end, since my output does have blank lines
537
+ while IFS='' read line
538
+ do
539
+ case $line in
540
+ ">>> end")
541
+ if [ ! -z "$cmd" ]; then
542
+ if [ $status = 0 ]; then
543
+ test_expect_success "$1 $subnum" "$cmd > output && test_cmp expect output"
544
+ else
545
+ #test_expect_success "$1 $subnum" "$cmd > output || test $? = $status && test_cmp expect output"
546
+ test_expect_success "$1 $subnum" "$cmd > output 2>&1 || test $? = $status && test_cmp expect output"
547
+ fi
548
+
549
+ subnum=$(($subnum + 1))
550
+ cmd=""
551
+ status=0
552
+ > expect
553
+ fi
554
+ ;;
555
+ ">>> "*)
556
+ test -z "$cmd" || error "bug in the test script: missing blank line separator in test_todo_session"
557
+ cmd=${line#>>> }
558
+ ;;
559
+ "=== "*)
560
+ status=${line#=== }
561
+ ;;
562
+ *)
563
+ # WARNING please NOTE XXX that a blank line in output terminates what goes into expect !!! See above
564
+ echo "$line" >> expect
565
+ ;;
566
+ esac
567
+ done
568
+ if [ ! -z "$cmd" ]; then
569
+ if [ $status = 0 ]; then
570
+ test_expect_success "$1 $subnum" "$cmd > output && test_cmp expect output"
571
+ else
572
+ test_expect_success "$1 $subnum" "$cmd > output || test $? = $status && test_cmp expect output"
573
+ fi
574
+ fi
575
+ }
576
+
577
+ test_shell () {
578
+ trap - EXIT
579
+ export PS1='$(ret_val=$?; [ "$ret_val" != "0" ] && echo -e "=== $ret_val\n\n>>> "||echo "\n>>> ")'
580
+ cat <<EOF
581
+ Do your tests session here and
582
+ don't forget to replace the hardcoded path with \$HOME in the transcript:
583
+ $HOME/todo.txt => \$HOME/todo.txt
584
+ EOF
585
+ bash --noprofile --norc
586
+ exit 0
587
+ }
588
+
589
+ test_init_todo "$test"
590
+ # Use -P to resolve symlinks in our working directory so that the pwd
591
+ # in subprocesses equals our $PWD (for pathname comparisons).
592
+ cd -P "$test" || exit 1
593
+
594
+ # Since todo.sh refers to the home directory often,
595
+ # make sure we don't accidentally grab the tester's config
596
+ # but use something specified by the framework.
597
+ HOME=$(pwd)
598
+ export HOME
599
+
600
+ this_test=${0##*/}
601
+ this_test=${this_test%%-*}
602
+ for skp in $SKIP_TESTS
603
+ do
604
+ to_skip=
605
+ for skp in $SKIP_TESTS
606
+ do
607
+ case "$this_test" in
608
+ $skp)
609
+ to_skip=t
610
+ esac
611
+ done
612
+ case "$to_skip" in
613
+ t)
614
+ say_color skip >&3 "skipping test $this_test altogether"
615
+ say_color skip "skip all tests in $this_test"
616
+ test_done
617
+ esac
618
+ done