Merge branch 'test-framework' of git://github.com/sit/todo.txt-cli into sit/test-framework

* 'test-framework' of git://github.com/sit/todo.txt-cli:
  tests: Update documentation to reflect recent changes.
  tests: add testshell.sh and port old testsuite.txt
  tests: Explicitly control the date for todo.sh.
  tests: Make test writing simpler and add two new tests.
This commit is contained in:
Gina Trapani
2009-04-13 19:26:06 -04:00
7 changed files with 648 additions and 3 deletions

View File

@@ -176,6 +176,23 @@ Test harness library
There are a handful helper functions defined in the test harness There are a handful helper functions defined in the test harness
library for your script to use. library for your script to use.
- test_todo_session <message> < transcript
This takes a single string as a parameter, which is treated
as a base description of what is being tested, and then
reads from standard input a transcript of todo.sh commands
and expected output. Each command is run in the current
test environment and the output is compared with the
expected output. (See below for how to generate transcripts
easily.)
- test_tick [interval]
The test harness has an internal view of time which is
implemented by wrapping the date command. This takes a single
optional positive integer parameter which indicates how much
to advance the internal time. The default value is one day.
- test_expect_success <message> <script> - test_expect_success <message> <script>
This takes two strings as parameter, and evaluates the This takes two strings as parameter, and evaluates the
@@ -211,9 +228,31 @@ library for your script to use.
exit with an appropriate error code. exit with an appropriate error code.
Generating test transcripts
---------------------------
You can generate test scripts from screenshots as following:
$ ./testshell.sh
You'll be in a special test environment with an empty todo.txt
and the dates and timestamps will be artificially fixed.
Then the session can be used to make a unit test thanks to
test_todo_session, see the existing tests as examples.
Be careful to replace all occurences of the full path to the test
directory by $HOME as testshell.sh will explain you when you execute it
otherwise the tests will work properly only on your own computer.
Don't use "script" as this would log every keystroke, not only what's
visible!!
Credits Credits
------- -------
This test framework was derived from the framework used by This test framework was derived from the framework used by
git itself, written originally by Junio Hamano and licensed git itself, written originally by Junio Hamano and licensed
for use under the GPL. for use under the GPL. It was specialized for todo.txt-cli
by Emil Sit and Philippe Teuwen.

58
tests/t1000-addlist.sh Executable file
View File

@@ -0,0 +1,58 @@
#!/bin/sh
test_description='basic add and list functionality
This test just makes sure the basic add and list
command work, including support for filtering.
'
. ./test-lib.sh
#
# Add and list
#
test_todo_session 'basic add/list' <<EOF
>>> todo.sh add notice the daisies
TODO: 'notice the daisies' added on line 1.
>>> todo.sh list
1 notice the daisies
--
TODO: 1 of 1 tasks shown from $HOME/todo.txt
>>> todo.sh add smell the roses
TODO: 'smell the roses' added on line 2.
>>> todo.sh list
1 notice the daisies
2 smell the roses
--
TODO: 2 of 2 tasks shown from $HOME/todo.txt
EOF
#
# Filter
#
test_todo_session 'basic list filtering' <<EOF
>>> todo.sh list daisies
1 notice the daisies
--
TODO: 1 of 2 tasks shown from $HOME/todo.txt
>>> todo.sh list smell
2 smell the roses
--
TODO: 1 of 2 tasks shown from $HOME/todo.txt
EOF
test_todo_session 'case-insensitive filtering' <<EOF
>>> todo.sh add smell the uppercase Roses
TODO: 'smell the uppercase Roses' added on line 3.
>>> todo.sh list roses
2 smell the roses
3 smell the uppercase Roses
--
TODO: 2 of 3 tasks shown from $HOME/todo.txt
EOF
test_done

69
tests/t1010-add-date.sh Executable file
View File

@@ -0,0 +1,69 @@
#!/bin/sh
test_description='test the date on add feature
Tests paths by which we might automatically add
a date to each item.
'
. ./test-lib.sh
#
# Add and list
#
test_todo_session 'cmd line first day' <<EOF
>>> todo.sh -t add notice the daisies
TODO: '2009-02-13 notice the daisies' added on line 1.
>>> todo.sh list
1 2009-02-13 notice the daisies
--
TODO: 1 of 1 tasks shown from $HOME/todo.txt
EOF
test_tick
test_todo_session 'cmd line second day' <<EOF
>>> todo.sh -t add smell the roses
TODO: '2009-02-14 smell the roses' added on line 2.
>>> todo.sh list
1 2009-02-13 notice the daisies
2 2009-02-14 smell the roses
--
TODO: 2 of 2 tasks shown from $HOME/todo.txt
EOF
test_tick
test_todo_session 'cmd line third day' <<EOF
>>> todo.sh -t add mow the lawn
TODO: '2009-02-15 mow the lawn' added on line 3.
>>> todo.sh list
1 2009-02-13 notice the daisies
2 2009-02-14 smell the roses
3 2009-02-15 mow the lawn
--
TODO: 3 of 3 tasks shown from $HOME/todo.txt
EOF
# Switch to config file
echo "export TODOTXT_DATE_ON_ADD=1" >> todo.cfg
# Bump the clock, for good measure.
test_tick 3600
test_todo_session 'config file third day' <<EOF
>>> todo.sh add take out the trash
TODO: '2009-02-15 take out the trash' added on line 4.
>>> todo.sh list
1 2009-02-13 notice the daisies
2 2009-02-14 smell the roses
3 2009-02-15 mow the lawn
4 2009-02-15 take out the trash
--
TODO: 4 of 4 tasks shown from $HOME/todo.txt
EOF
test_done

71
tests/t1100-replace.sh Executable file
View File

@@ -0,0 +1,71 @@
#!/bin/sh
test_description='basic replace functionality
Ensure we can replace items successfully.
'
. ./test-lib.sh
#
# Set up the basic todo.txt
#
todo.sh add notice the daisies > /dev/null
test_todo_session 'replace usage' <<EOF
>>> todo.sh replace adf asdfa
=== 1
usage: $(which todo.sh) replace ITEM# "UPDATED ITEM"
EOF
test_todo_session 'basic replace' <<EOF
>>> todo.sh replace 1 "smell the cows"
1: notice the daisies
replaced with
1: smell the cows
>>> todo.sh list
1 smell the cows
--
TODO: 1 of 1 tasks shown from $HOME/todo.txt
>>> todo.sh replace 1 smell the roses
1: smell the cows
replaced with
1: smell the roses
>>> todo.sh list
1 smell the roses
--
TODO: 1 of 1 tasks shown from $HOME/todo.txt
EOF
cat > todo.txt <<EOF
smell the cows
grow some corn
thrash some hay
chase the chickens
EOF
test_todo_session 'replace in multi-item file' <<EOF
>>> todo.sh replace 1 smell the cheese
1: smell the cows
replaced with
1: smell the cheese
>>> todo.sh replace 3 jump on hay
3: thrash some hay
replaced with
3: jump on hay
>>> todo.sh replace 4 collect the eggs
4: chase the chickens
replaced with
4: collect the eggs
EOF
test_todo_session 'replace error' << EOF
>>> todo.sh replace 10 "hej!"
=== 1
10: No such todo.
EOF
test_done

312
tests/t9999-testsuite_example.sh Executable file
View File

@@ -0,0 +1,312 @@
#!/bin/sh
test_description='basic tests imported from previous framework
'
. ./test-lib.sh
test_todo_session 'basic tests' <<EOF
>>> todo.sh add "notice the daisies"
TODO: 'notice the daisies' added on line 1.
>>> todo.sh list
1 notice the daisies
--
TODO: 1 of 1 tasks shown from $HOME/todo.txt
>>> todo.sh replace adf asdfa
usage: $HOME/bin/todo.sh replace ITEM# "UPDATED ITEM"
=== 1
>>> todo.sh replace 1 "smell the cows"
1: notice the daisies
replaced with
1: smell the cows
>>> todo.sh list
1 smell the cows
--
TODO: 1 of 1 tasks shown from $HOME/todo.txt
>>> todo.sh replace 1 smell the roses
1: smell the cows
replaced with
1: smell the roses
>>> todo.sh list
1 smell the roses
--
TODO: 1 of 1 tasks shown from $HOME/todo.txt
>>> todo.sh replace 1 smell the uppercase Roses
1: smell the roses
replaced with
1: smell the uppercase Roses
>>> todo.sh list
1 smell the uppercase Roses
--
TODO: 1 of 1 tasks shown from $HOME/todo.txt
>>> todo.sh list roses
1 smell the uppercase Roses
--
TODO: 1 of 1 tasks shown from $HOME/todo.txt
>>> todo.sh add notice the sunflowers
TODO: 'notice the sunflowers' added on line 2.
>>> todo.sh list
2 notice the sunflowers
1 smell the uppercase Roses
--
TODO: 2 of 2 tasks shown from $HOME/todo.txt
>>> todo.sh append 1 +flowers @outside
1: smell the uppercase Roses +flowers @outside
>>> todo.sh list
2 notice the sunflowers
1 smell the uppercase Roses +flowers @outside
--
TODO: 2 of 2 tasks shown from $HOME/todo.txt
>>> todo.sh add "stop"
TODO: 'stop' added on line 3.
>>> todo.sh list
2 notice the sunflowers
1 smell the uppercase Roses +flowers @outside
3 stop
--
TODO: 3 of 3 tasks shown from $HOME/todo.txt
>>> todo.sh pri B B
usage: $HOME/bin/todo.sh pri ITEM# PRIORITY
note: PRIORITY must be anywhere from A to Z.
=== 1
>>> todo.sh pri 1 B
1: (B) smell the uppercase Roses +flowers @outside
TODO: 1 prioritized (B).
>>> todo.sh list
1 (B) smell the uppercase Roses +flowers @outside
2 notice the sunflowers
3 stop
--
TODO: 3 of 3 tasks shown from $HOME/todo.txt
>>> todo.sh -p list
1 (B) smell the uppercase Roses +flowers @outside
2 notice the sunflowers
3 stop
--
TODO: 3 of 3 tasks shown from $HOME/todo.txt
>>> todo.sh pri 2 C
2: (C) notice the sunflowers
TODO: 2 prioritized (C).
>>> todo.sh -p list
1 (B) smell the uppercase Roses +flowers @outside
2 (C) notice the sunflowers
3 stop
--
TODO: 3 of 3 tasks shown from $HOME/todo.txt
>>> todo.sh pri 2 A
2: (A) notice the sunflowers
TODO: 2 prioritized (A).
>>> todo.sh -p list
2 (A) notice the sunflowers
1 (B) smell the uppercase Roses +flowers @outside
3 stop
--
TODO: 3 of 3 tasks shown from $HOME/todo.txt
>>> todo.sh pri 2 a
2: (A) notice the sunflowers
TODO: 2 prioritized (A).
>>> todo.sh -p listpri
2 (A) notice the sunflowers
1 (B) smell the uppercase Roses +flowers @outside
--
TODO: 2 of 3 tasks shown from $HOME/todo.txt
>>> todo.sh add "smell the coffee +wakeup"
TODO: 'smell the coffee +wakeup' added on line 4.
>>> todo.sh -p list
2 (A) notice the sunflowers
1 (B) smell the uppercase Roses +flowers @outside
4 smell the coffee +wakeup
3 stop
--
TODO: 4 of 4 tasks shown from $HOME/todo.txt
>>> todo.sh -p list +flowers
1 (B) smell the uppercase Roses +flowers @outside
--
TODO: 1 of 4 tasks shown from $HOME/todo.txt
>>> todo.sh -p list flowers
2 (A) notice the sunflowers
1 (B) smell the uppercase Roses +flowers @outside
--
TODO: 2 of 4 tasks shown from $HOME/todo.txt
>>> todo.sh -p list flowers out
1 (B) smell the uppercase Roses +flowers @outside
--
TODO: 1 of 4 tasks shown from $HOME/todo.txt
>>> todo.sh -a do 2
2: x 2009-02-13 notice the sunflowers
TODO: 2 marked as done.
>>> todo.sh -p list
1 (B) smell the uppercase Roses +flowers @outside
4 smell the coffee +wakeup
3 stop
2 x 2009-02-13 notice the sunflowers
--
TODO: 4 of 4 tasks shown from $HOME/todo.txt
>>> todo.sh add "make the coffee +wakeup"
TODO: 'make the coffee +wakeup' added on line 5.
>>> todo.sh -p list coffee
5 make the coffee +wakeup
4 smell the coffee +wakeup
--
TODO: 2 of 5 tasks shown from $HOME/todo.txt
>>> todo.sh add "visit http://example.com"
TODO: 'visit http://example.com' added on line 6.
>>> todo.sh -p list
1 (B) smell the uppercase Roses +flowers @outside
5 make the coffee +wakeup
4 smell the coffee +wakeup
3 stop
6 visit http://example.com
2 x 2009-02-13 notice the sunflowers
--
TODO: 6 of 6 tasks shown from $HOME/todo.txt
>>> todo.sh archive
x 2009-02-13 notice the sunflowers
TODO: $HOME/todo.txt archived.
>>> todo.sh -p list
1 (B) smell the uppercase Roses +flowers @outside
4 make the coffee +wakeup
3 smell the coffee +wakeup
2 stop
5 visit http://example.com
--
TODO: 5 of 5 tasks shown from $HOME/todo.txt
>>> todo.sh report
TODO: Report file updated.
2009-02-13-04:40:00 5 1
>>> todo.sh report
TODO: Report file updated.
2009-02-13-04:40:00 5 1
2009-02-13-04:40:00 5 1
>>> todo.sh append g a
usage: $HOME/bin/todo.sh append ITEM# "TEXT TO APPEND"
=== 1
>>> todo.sh append 2 and think
2: stop and think
>>> todo.sh -p list
1 (B) smell the uppercase Roses +flowers @outside
4 make the coffee +wakeup
3 smell the coffee +wakeup
2 stop and think
5 visit http://example.com
--
TODO: 5 of 5 tasks shown from $HOME/todo.txt
>>> todo.sh pri 2 C
2: (C) stop and think
TODO: 2 prioritized (C).
>>> todo.sh replace 10 "hej!"
10: No such todo.
=== 1
>>> todo.sh -p list
1 (B) smell the uppercase Roses +flowers @outside
2 (C) stop and think
4 make the coffee +wakeup
3 smell the coffee +wakeup
5 visit http://example.com
--
TODO: 5 of 5 tasks shown from $HOME/todo.txt
>>> todo.sh append 10 "hej!"
10: No such todo.
=== 1
>>> todo.sh -p list
1 (B) smell the uppercase Roses +flowers @outside
2 (C) stop and think
4 make the coffee +wakeup
3 smell the coffee +wakeup
5 visit http://example.com
--
TODO: 5 of 5 tasks shown from $HOME/todo.txt
>>> todo.sh do 10
10: No such todo.
=== 1
>>> todo.sh -p list
1 (B) smell the uppercase Roses +flowers @outside
2 (C) stop and think
4 make the coffee +wakeup
3 smell the coffee +wakeup
5 visit http://example.com
--
TODO: 5 of 5 tasks shown from $HOME/todo.txt
>>> todo.sh add "the coffee +wakeup"
TODO: 'the coffee +wakeup' added on line 6.
>>> todo.sh -p list
1 (B) smell the uppercase Roses +flowers @outside
2 (C) stop and think
4 make the coffee +wakeup
3 smell the coffee +wakeup
6 the coffee +wakeup
5 visit http://example.com
--
TODO: 6 of 6 tasks shown from $HOME/todo.txt
>>> todo.sh prepend 6 "make"
6: make the coffee +wakeup
>>> todo.sh -p list
1 (B) smell the uppercase Roses +flowers @outside
2 (C) stop and think
4 make the coffee +wakeup
6 make the coffee +wakeup
3 smell the coffee +wakeup
5 visit http://example.com
--
TODO: 6 of 6 tasks shown from $HOME/todo.txt
>>> todo.sh remdup
Usage: todo.sh [-fhpantvV] [-d todo_config] action [task_number] [task_description]
Try 'todo.sh -h' for more information.
=== 1
EOF
test_done

View File

@@ -407,9 +407,8 @@ test_done () {
esac esac
} }
# Make sure we are testing the latest version. # Record our location for reference.
TEST_DIRECTORY=$(pwd) TEST_DIRECTORY=$(pwd)
PATH=$TEST_DIRECTORY/..:$PATH
# Test repository # Test repository
test="trash directory.$(basename "$0" .sh)" test="trash directory.$(basename "$0" .sh)"
@@ -431,9 +430,100 @@ test_init_todo () {
cd "$root" || error "Cannot setup todo dir in $root" cd "$root" || error "Cannot setup todo dir in $root"
# Initialize the configuration file. Carefully quoted. # Initialize the configuration file. Carefully quoted.
sed -e 's|TODO_DIR=.*$|TODO_DIR="'"$TEST_DIRECTORY/$test"'"|' $TEST_DIRECTORY/../todo.cfg > todo.cfg sed -e 's|TODO_DIR=.*$|TODO_DIR="'"$TEST_DIRECTORY/$test"'"|' $TEST_DIRECTORY/../todo.cfg > todo.cfg
# Install latest todo.sh
mkdir bin
ln -s "$TEST_DIRECTORY/../todo.sh" bin/todo.sh
# Initialize a hack date script
TODO_TEST_REAL_DATE=$(which date)
TODO_TEST_TIME=1234500000
export PATH TODO_TEST_REAL_DATE TODO_TEST_TIME
cat > bin/date <<-EOF
#!/bin/sh
# Assumes GNU date.
exec "$TODO_TEST_REAL_DATE" -d @\$TODO_TEST_TIME \$@
EOF
chmod 755 bin/date
# Ensure a correct PATH for testing.
PATH=$owd/$root/bin:$PATH
export PATH
cd "$owd" cd "$owd"
} }
# Usage: test_tick [increment]
test_tick () {
TODO_TEST_TIME=$(($TODO_TEST_TIME + ${1:-86400}))
}
# Generate and run a series of tests based on a transcript.
# Usage: test_todo_session "description" <<EOF
# >>> command
# output1
# output2
# >>> command
# === exit status
# output3
# output4
# EOF
test_todo_session () {
test "$#" = 1 ||
error "bug in the test script: extra args to test_todo_session"
subnum=1
cmd=""
status=0
> expect
while read line
do
case $line in
">>> "*)
test -z "$cmd" || error "bug in the test script: missing blank line separator in test_todo_session"
cmd=${line#>>> }
;;
"=== "*)
status=${line#=== }
;;
"")
if [ ! -z "$cmd" ]; then
if [ $status = 0 ]; then
test_expect_success "$1 $subnum" "$cmd > output && test_cmp expect output"
else
test_expect_success "$1 $subnum" "$cmd > output || test $? = $status && test_cmp expect output"
fi
subnum=$(($subnum + 1))
cmd=""
status=0
> expect
fi
;;
*)
echo $line >> expect
;;
esac
done
if [ ! -z "$cmd" ]; then
if [ $status = 0 ]; then
test_expect_success "$1 $subnum" "$cmd > output && test_cmp expect output"
else
test_expect_success "$1 $subnum" "$cmd > output || test $? = $status && test_cmp expect output"
fi
fi
}
test_shell () {
trap - EXIT
export PS1='$(ret_val=$?; [ "$ret_val" != "0" ] && echo -e "=== $ret_val\n\n>>> "||echo "\n>>> ")'
cat <<EOF
Do your tests session here and
don't forget to replace the hardcoded path with \$HOME in the transcript:
$HOME/todo.txt => \$HOME/todo.txt
EOF
bash --noprofile --norc
exit 0
}
test_init_todo "$test" test_init_todo "$test"
# Use -P to resolve symlinks in our working directory so that the cwd # Use -P to resolve symlinks in our working directory so that the cwd

6
tests/testshell.sh Executable file
View File

@@ -0,0 +1,6 @@
#!/bin/sh
test_description='Providing an interactive shell in the proper environment'
. ./test-lib.sh
test_shell