Compare commits

..

193 Commits

Author SHA1 Message Date
Ingo Karkat
4359290b3c Avoid external TR when replacing , with space.
No need for an external tool, Bash can do a global literal substitution itself.
2012-01-07 23:17:38 +01:00
Gina Trapani
f8a6e5f8d6 Merge pull request #59 from inkarkat/bug-pri-no-existence-check
BUG: pri doesn't issue an error when the task does not exist.
2011-12-18 21:50:18 -08:00
Ingo Karkat
388ae745af Refactoring: Extract getPrefix() for more consistent move error.
I think that the error on the "move dest src" action should be given like "SRC: No task 42" instead of "TODO: No task 42 in /path/to/src.txt", to be consistent with the addto and listfile actions. Extracted and exposed getPrefix(), again to remove a bit of duplication, and because this can be useful in custom add-ons, too.
2011-12-18 21:44:47 +01:00
Ingo Karkat
cb908bd454 Refactoring: Extract getTodo() and getNewtodo() functions.
The retrieval of a task text for $item and associated error handling so far was scattered around the individual actions. This is now consolidated in two new utility functions, which directly set $todo or $newtodo, respectively. (Inconsistent variable names like $NEWTODO have been adapted.) This ensures that all actions perform the same error checking, reduces a bit of duplication, and allows custom add-ons to benefit from these exported functions. Ah, and the error messages for the "move" action is now more in line with the other errors; unfortunately, this isn't yet covered by a test.

Note that the check whether $item is numeric must not use the +([0-9]) extglob any more, as such functions cannot be exported; a new Bash doesn't have the "shopt -s extglob" and complains with a syntax error. Fortunately, it is possible to perform the same check via standard Bash mechanisms.
2011-12-17 23:26:25 +01:00
Ingo Karkat
55679d136f BUG: pri doesn't issue error when task does not exist. 2011-12-17 21:29:18 +01:00
Gina Trapani
c0847b0b25 Merge pull request #58 from inkarkat/bug-quoting-negative-term
FIX: Correct quoting for negative -TERM filtering.
2011-12-07 09:31:28 -08:00
Gina Trapani
76fb1cb3ee Merge pull request #57 from inkarkat/filename-completion
Add file completion for addto, listfile, and move.
2011-12-07 09:21:17 -08:00
Gina Trapani
ac090fa30b Merge pull request #56 from inkarkat/todo_completion
Incorporate Bash completion from the Wiki page into the distribution.
2011-12-07 09:20:07 -08:00
Ingo Karkat
ea0e7c7b25 FIX: Correct quoting for negative -TERM filtering.
This oversight was recently introduced with the new filtercommand() in a0f39480bf.
I've enhanced the test to cover -TERM filtering, too.
2011-12-03 16:55:13 +01:00
Ingo Karkat
cd7d2f2fda ENH: Add file completion for move. 2011-11-20 17:07:59 +01:00
Ingo Karkat
395465b5f2 ENH: Add file completion for addto and listfile.
This enhancement to todo_completion requires a small enhancement to the listfile action: When no SRC is specified, the list of text files in the todo.txt directory is printed. This is probably also useful on its own, and better than the original behavior of printing "TODO: File  does not exist."

Note: I intentionally omitted bullet-proof error handling ($TODO_DIR non-existing or no text files contained), to avoid over-complicating this.
2011-11-20 16:30:31 +01:00
Ingo Karkat
d2e0f6e38d FIX: Support $HOME and $TODOTXT_ACTIONS_DIR containing spaces.
And document a minor discrepancy in action completion to todo.sh.
2011-11-20 15:17:50 +01:00
Ingo Karkat
b1d894f65d Add recently added "shorthelp" built-in command. 2011-11-20 15:17:50 +01:00
Ingo Karkat
f5270be463 ENH: Append task text as shell comment when completing task number.
This is useful for the paranoid before a destructive todo.txt operation. Appending the text as a shell comment doesn't affect the todo.txt command itself, but shows that the task number corresponds to the task you had in mind.
2011-11-20 15:17:45 +01:00
Ingo Karkat
8cba7533b9 Avoid leaking internal variables into the shell + robustness against add-ons.
Use "local" to avoid that the internal completion variables are accessible from the user's shell.
Use "todo.sh command" for the context/project lookups to avoid interference with custom add-ons of the same name, and reset TODOTXT_VERBOSE to avoid adding any message output (currently there is none).
2011-11-20 14:53:18 +01:00
Ingo Karkat
285d5039f2 Add shebang line and check for Bash.
The shebang is ignored when sourcing the script (but still helps many text editors auto-detect the file type), and will cause an error when the script is mistakenly executed.
The Bash check allows to have this called from a generic place (e.g. .profile), and do no harm when under a different shell.
2011-11-20 14:26:52 +01:00
Ingo Karkat
9b67a76833 Do not automatically complete for guessed aliases.
Don't infringe against the principle of least astonishment (they user may have completely unrelated aliases). Rather, if the user sets up his own alias, make him apply the same to todo_completion.
2011-11-20 14:22:48 +01:00
Ingo Karkat
2b0921f4ec Add todo_completion to todo.txt distribution. 2011-11-20 14:20:25 +01:00
Ingo Karkat
202f892e85 Include todo Bash completion from the todo.txt Wiki.
This is f32aba2 of https://github.com/ginatrapani/todo.txt-cli/wiki/Tips-and-Tricks, last edited 30-Oct-2011.
2011-11-20 14:17:22 +01:00
Ingo Karkat
417e86ae7a FIX: Handle special shell characters when filtering TERM.
The double quotes used in the filter_command erroneously expand $VARIABLE, and due to missing quoting in the eval() of filter_command, multiple spaces are condensed into a single space.
Introduce a new function shellquote() to correctly quote each filter TERM.
2011-11-10 14:21:47 -08:00
Ingo Karkat
cb982391de Implement listproj with factored out filtercommand() function.
_list() is way too large and monolithic for many (re-)use cases. As a first step, factor out the building of the filter_command and reuse that for the listproj filtering.
Enhance the listproj test with special cases that show the problems with the previous implementation directly using _list: Option -+, custom final filters, and non-ANSI colors cause it to break.
2011-11-10 14:21:47 -08:00
jmoore
b8244792cc Accept filters for lsprj 2011-11-10 14:21:47 -08:00
Ingo Karkat
a433c5828e shorthelp consistency
- Restore alphabetical order for "addto".
- Keep "depri" shorthand after the long form as all other.
Closes #50

Implement shorthelp listing add-on action one-line usage.
-h and an additional new "shorthelp" action list not just the usage of the built-in actions, but also from add-ons. This assumes that add-ons use the same usage indentation structure as todo.sh. (They should, anyway, for consistency of the full help message.)
Closes #12
2011-11-10 14:16:05 -08:00
Ingo Karkat
7742d3c115 Restructure help text to put built-in and add-on actions together.
I find it annoying that the built-in actions are printed first, and the add-on actions last, although for the user, the distinction is hardly important. Therefore, moving the "options" block first (as it is short and contains the stuff most difficult to memorize), then built-in, then add-on actions.
As environment variables are hardly used in day-to-day operations, only once for customizing the config, they are now omitted by default and only included when -vv is given.
2011-11-10 14:11:31 -08:00
Gina Trapani
7ca2b4c687 Merge pull request #49 from inkarkat/bug-disable-filter-not-propagating
BUG: disable filter not propagating to add-ons
2011-11-10 13:33:46 -08:00
Gina Trapani
239f7234ab Merge pull request #48 from inkarkat/bug-unrestrained-pri-matching
BUG: unrestrained pri "(X)" matching
2011-11-10 13:33:28 -08:00
Ingo Karkat
e3fce6f12b Revert to safer POSIX AWK regexp.
AWK from Ubuntu 8.04 (mawk) doesn't support [[:space:]]; so for backwards compatibility use a plain ASCII space instead.
2011-11-03 18:37:36 +01:00
Ingo Karkat
65d39319f1 TODOTXT_DISABLE_FILTER missing from help text.
Should be in there for consistency; corresponding option is -x.
2011-09-30 09:15:56 +02:00
Ingo Karkat
62d3ff2977 BUG: Option -x isn't propagated to custom actions.
Somehow, no default is set for TODOTXT_DISABLE_FILTER, so that it isn't exported, and therefore does not apply to the sourced actions, so you cannot disable filtering for "myaction" via todo.sh -x myaction.
2011-09-30 09:11:54 +02:00
Ingo Karkat
227b9d2c0a BUG: Pattern "(X) " anywhere hidden with -P.
The regular expression HIDE_PRIORITY_SUBSTITUTION is not anchored, so strings that look like a priority but are not at the beginning are filtered, too.
Anchoring the regexp in the step after the highlighting has been applied is problematic due to the prepended dynamic priority highlighting string, and it also cannot be done before that because highlighting needs the information. Therefore, the filtering is moved into the AWK highlighting itself.
2011-09-23 16:27:30 +02:00
Ingo Karkat
99fa15da36 BUG: Pattern "(X)" anywhere highlighted as prioritized.
According to the "Todo.txt Format" specs, "Rule 1: If a priority exists, it ALWAYS appears first."

Adapt AWK filtering to match priorities only directly after the task number added by the _list processing, and also matching the required trailing space.
2011-09-23 15:40:23 +02:00
Ingo Karkat
72fe73f3d8 nobacktick test: Use literal backtick
* Fix sed error on Mac OS, also ignore entire commented lines.
* With proper quoting, the non-POSIX \d96 escape isn't necessary, and the check should work also on Mac OS.
2011-08-04 10:15:54 -07:00
Ingo Karkat
8f6070e702 Re-applying the listpri stuff still missing from the pull requests. 2011-07-10 22:04:51 +02:00
Ingo Karkat
2891472630 Add test to enforce use of $(...) code style in todo.sh.
Pull request #26 by trajano (e24777fa2c) changed `...` to $(...), but the following commit 7900ad7e1b already added another old-style one. I think the tests can also be used for some simple enforcement of coding style, so here is a first shot at it.

Closes #46
2011-07-09 14:11:10 -07:00
Ingo Karkat
f3af778d3e depri: Check for unprioritized task and print message.
The existing check didn't do much good, and one could deprioritize any normal task without notice. Instead, check that the task to be deprioritized actually has a priority and alert via "TODO: 42 is not prioritized." if that is not the case.
2011-07-09 13:43:36 -07:00
Ingo Karkat
c14788e764 Cosmetics: Add TODO: prefix to todo.txt do message on already done task. 2011-07-09 13:43:26 -07:00
Ingo Karkat
32c84781d2 pri: Check for existing priority and adapt message.
The existing check (as with depri) didn't do much good. Instead, fetch the existing priority and use that information to print more specific messages:
- TODO: 42 re-prioritized from (C) to (A)
- TODO: 42 already prioritized (A)
2011-07-09 13:43:00 -07:00
Ingo Karkat
6e740f748e Consistency: Use /(.)/ as generic pattern for priority in replaceOrPrepend().
Even though Gina's todo.txt syntax reference only mentions uppercase A-Z priorities, this is handled in two different ways in the code. I think the following guideline is useful: For a user-supplied priority (in the listpri and pri commands), use a strict check for A-Z. In general list and edit operations that need to be aware of the optional priority at the beginning of a task, use the general /^(.) / regexp. This allows addons to use different priority-like markers (e.g. "(-) no do"), have them ignored as priorities, but still maintained by replacements.
2011-07-09 13:42:14 -07:00
Ingo Karkat
0fa5f6d1dd BUG: listpri picked up non-priority patterns.
The regexp for the priority wasn't anchored to the beginning of the task. (As the filtering is done inside the _list pipeline, the task number has already been prepended.)
Also, by passing the regexp directly to _list, a case-insensitive search was performed, so despite [A-Z], lowercase characters were picked up, too. Need to make use of post_filter_command to inject a separate, case-sensitive grep into the pipeline.

Bonus: Added test for highlighting of listpri command.
2011-07-09 13:41:20 -07:00
Ingo Karkat
f8b66f117a ENH: Allow listpri filtering via TERM.
This even simplified the argument handling, since there can be no invalid priority any more; all other strings are taken as TERMs. And the check for empty ${1:-} was superfluous, anyway. Apart from these simplifications, it's basically just passing $@ to _list.
2011-07-09 13:36:14 -07:00
Ingo Karkat
b00ca1074a Simplified check for done task.
Use simple comparison with slice of string (already used e.g. in _list()) instead of grep -c pipeline.

Closes #42
2011-07-07 23:29:45 -07:00
Ingo Karkat
a60dfb668d Perform cleaninput() filtering without tr.
Again, Bash's global pattern substitution can be used. This only depends on the "extquote" shell option, which is set by default, but we set this just to be sure.
2011-07-07 23:14:11 -07:00
Ingo Karkat
899687f0ef BUG: Multiple whitespace was condensed, CR/LF not turned to space.
Missing quoting inside cleaninput() condensed multiple subsequent spaces into a single space, even when the user took pains to preserve whitespace by properly quoting the task in the shell.
The 'tr' command completely removed CR and LF characters instead of replacing them with a single space.
Add test cases for the whitespace handling to the add, append, prepend and replace actions.
2011-07-07 23:14:11 -07:00
Ingo Karkat
301dbcf297 Expose cleaninput() for use in addons.
Despite its hard-coded use of $input, this can be useful in addons, too.
(I, for example, use this in a "todo.sh subst" addon that delegates to the "todo.sh replace" action after performing a sed-style replacement on the passed pattern and replacement.)
2011-07-07 23:13:47 -07:00
Ingo Karkat
e79b1629f5 Perform cleaninput() escaping without sed.
No need for invoking sed; Bash's global pattern substitution can be used.
2011-07-07 23:13:47 -07:00
Ingo Karkat
a4db95166d Escape the substitution separator in cleaninput().
Improving on the previous fix and commit, no search for an unused substitution separator is actually needed; sed supports escaping of the substitution separator. Revert the $inputSep abstraction in favor of the former, hard-coded "|" character.
2011-07-07 23:13:47 -07:00
Ingo Karkat
afe6d9dfd5 FIX: cleaninput() for sed-replacement needs more escaping and unique separator.
Commit 8e4364f5e1 removed the deletion of the "|" character from cleaninput. That was okay for the cleaninput() use in _addto(), but not in those cases that used $input for replacement via sed.

Added corresponding tests for replace, append and prepend actions similar to what was added for the add action in the above commit.

To really fix the problem (and not just remove all "|" characters from the text), a separator character must be found that is not part of $input, and this must be used in the sed expression. As cleaninput() already modifies the global $input variable, another $inputSep global variable is used to pass back this information.

In addition, backslashes must be escaped in $input, or replacements like \1 wreak havoc.
2011-07-07 23:13:47 -07:00
Ingo Karkat
ab705cd670 Configure cleaninput() sed-escaping via argument instead of magic words.
Encoding the actions that require the additional sed-escaping inside cleaninput() is cumbersome and error-prone. Instead, let the calling action tell cleaninput() that it wants this.
2011-07-07 23:13:47 -07:00
Ingo Karkat
e0ad2292a2 Remove no-op passing of $input to cleaninput().
The function actually uses and modifies the global variable directly.
2011-07-07 23:12:35 -07:00
Ingo Karkat
c4670b6502 Made replace test sessions independent from each other.
When the tests depend on the todo.txt contents from the previous sessions, errors will cascade and make it more difficult to pinpoint the problem.
2011-07-07 23:12:35 -07:00
Tom Scogland
7900ad7e1b Added sed line to allow priorities to be added on the command line with auto add date enabled.
Inserted test for this case in the t1010-add-date.sh test case.
2011-07-07 22:55:08 -07:00
Archimedes Trajano
e24777fa2c Changed backquotes to use $() instead.
$(...) has superceded the `...` notation.  This can be found by
searching in Google "command substitution superseded"

Closes #28
2011-07-07 22:05:11 -07:00
Devon Jones
dae6f2bcaf Environment variables override config, flags override environment variables
* Added more flags to give action developers more control over commands
that are leveraged inside their actions.
* Writing a better message for the help screen
2011-02-14 10:14:17 -08:00
Archimedes Trajano
0c5bdf3b0a Added quotes to dirname call.
This allows the todo.sh to exist in a path with spaces.
2011-02-14 10:11:32 -08:00
Matt Henkel
5afd734dcb Change the default TODO_DIR so that it's the same as the todo.sh dir.
This change makes todo.sh work out-of-the-box, and allows for excellent portable usage within Dropbox or on a flash drive.
2011-02-14 10:11:32 -08:00
Matt Henkel
990bc293ba Todo.sh will now check for the config in the same directory as the script--if it's not specified or found in HOME.
This is really nice if todo.sh is kept in dropbox and accessed from multiple computers.
2011-02-14 10:11:32 -08:00
Nick Wilson
8e4364f5e1 Fix erroneously removing pipe chars from input
cleaninput() unintentionally deletes the '|' character from input.  This
commit fixes it and adds test for adding tasks with a bunch of symbols.
2011-01-31 21:07:35 -08:00
Nick Wilson
f1d339a537 Fix substitution for hiding contexts/projects
When using the -+ or -@ option to hide project or context names in list
output, the color reset sequence was being deleted if the project/context
was at the end of the line.

For example, with the following tasks:

    (B) with priority, ending in a +project
    task that shouldn't be highlighted

Running 'todo.sh -+ list' would hide the "+project" from the first task,
but would also remove the color reset sequence ^[[0m at the end.  The
color from the prioritized task would continue to the next lines.

This commit fixes the problem and adds a test to verify the fix.
2011-01-23 16:09:09 -08:00
Gina Trapani
82c8349499 Merge branch 'inkarkat/master'
* inkarkat/master:
  Cosmetics: Corrected inconsistent indentation.
  Skipping 'nonexecutable action' test on Cygwin.
  Factored out generation of custom action scripts.
  Fixed test environment for escaped test output.
  MINOR: Removed unnecessary empty & reference in sed substitution.
  Avoiding todo.sh help error when .todo.actions.d contains subdirs.
  BUG: interpretation of \033 escape sequences in task
  BUG: task listing aborted on embedded \c escape sequence
  BUG: tr: extra operand `d' error caused by missing quoting
2011-01-20 10:24:20 -08:00
Ingo Karkat
9a5668a51c Cosmetics: Corrected inconsistent indentation. 2011-01-20 16:08:20 +01:00
Ingo Karkat
a82fd58363 Skipping 'nonexecutable action' test on Cygwin.
On Cygwin, clearing the executable flag may have no effect, as the Windows ACL may still grant execution rights. In this case, we skip the test instead of failing.
2011-01-20 15:34:46 +01:00
Ingo Karkat
819a8285cc Factored out generation of custom action scripts.
- Reduced duplication via common make_action() function.
- ENH: Adding proper shebang line to the custom action scripts.
- Changed output of custom action to better differentiate from todo.sh output.
2011-01-20 15:07:47 +01:00
Ingo Karkat
2df5f9fee9 Fixed test environment for escaped test output.
- test-lib uses 'read -r' to parse the test session input literally, without interpretation of backslashes.
- FIX: Use quoting to maintain original whitespace (tabs and multiple spaces) from the test session input (instead of condensing into a single space).
- Using Bash instead of POSIX shell for t1340-listescapes.sh, so that the interpretation of escape sequences is not dependent on the POSIX shell being used.
- Changed Makefile so that the shell selected by the shebang line is actually used when invoking tests, not the POSIX shell.
- Above changes obsolete the multiple escaping of the test session data; now, the test session can actually be pasted as-is into a test script, even when it contains backslashes. (I.e. works as expected now.)
2011-01-20 13:23:06 +01:00
Gina Trapani
07baa2c1bd Added GPL license 2011-01-18 20:32:23 -08:00
Ingo Karkat
a117b7cb3c MINOR: Removed unnecessary empty & reference in sed substitution. 2010-12-30 23:19:57 +01:00
Ingo Karkat
9760ee23c7 Avoiding todo.sh help error when .todo.actions.d contains subdirs.
I have placed tests for my custom todo actions in ~/.todo.actions.d/tests/; this causes a ".../.todo.actions.d/tests: is a directory" error on todo.sh help.
Added condition for regular files to the executable check in order to exclude subdirectories.
2010-10-21 12:27:30 +02:00
Ingo Karkat
ce501c5362 BUG: interpretation of \033 escape sequences in task
The global substitution in the AWK highlighting of prioritized and done tasks also affected the task text itself, not just the inserted color definitions.
Factored out the evaluation of the color variables and interpretation of \033 into a highlight() AWK function.
Added test cases which check that \a, \t, \n, \x.. and \0.. escape characters in the task text are listed as-is, without interpretation.
2010-10-21 11:30:31 +02:00
Ingo Karkat
824101defd BUG: task listing aborted on embedded \c escape sequence
Fixed by removing the -e option that causes the echo command to interpret escape characters. Coloring of done tasks (the only step in the _list pipeline that required this interpretation) has been moved into the AWK pipeline step which is responsible for the priority coloring, and which does the escape character interpretation internally.
As a nice side effect, this shortening of the _list pipeline should also speed up the listing a wee bit.
2010-10-21 10:26:45 +02:00
Ingo Karkat
194a062c2d BUG: tr: extra operand `d' error caused by missing quoting
Reported by Bill Goffe on the todotxt mailing list.
2010-08-09 08:06:09 +02:00
Ingo Karkat
94325f57cd Improved color map instructions.
Clarified the use of ANSI escape codes.
Added motivation why to change, e.g. when using Conky.
Added requirement to uncomment color defaults when changing the color map, based on a support request on the mailing list.
2010-07-17 21:29:55 +02:00
Ingo Karkat
938bbc1ec2 Aligned PRI_X comment with updated one in config.
As an addendum to commit 9b7f85bea1.
2010-07-17 09:47:39 +02:00
Ingo Karkat
99f8911c8f Added fallback for $TODO_DIR/${FILE}.txt.
This allows to leave off the .txt file extension in commands like "todo.sh listfile done".
Plus: Minor coding style alignment, replaced $1 argument with existing $FILE variable.
2010-07-16 16:15:45 +02:00
Ingo Karkat
f5d4249078 ENH: Added highlighting of done (but not yet archived) tasks.
This makes done tasks more stand out (like prioritized tasks) in the task list. Default highlighting is LIGHT_GREY, which seems to be modest and go well with the assumed dark terminal background.
Reintroduced the OSX-compatible sed filter that was introduced by commit 8b7e2e6aad and superseded by the PRI_X coloring generalization.
2010-07-15 16:14:46 +02:00
Ingo Karkat
9b7f85bea1 Config file addendum to generalization of PRI_X color support.
Adapts the config file comments to the generalization of PRI_X color support to all priorities (commit e7b5841721).
2010-07-15 15:19:38 +02:00
Ingo Karkat
a7afc7917d Minor: aligned capitalization in fatal error message. 2010-07-15 15:19:24 +02:00
Ingo Karkat
4d29e68e89 Aligned "no such task" error message with verbose messages.
The message now also starts with "TODO:", like all other messages (except for the usage messages).
Before: 42: No such task.
After:  TODO: No task 42.
2010-07-15 13:48:24 +02:00
Ingo Karkat
b383b1f0c5 Aligned verbose message output of tasks with normal task output.
I.e. removed the colon after the ITEM#. Updated tasks are now listed like the 'todo.sh ls' command does, e.g.
    42 smell the roses
This is in preparation to eventually use a function factored out from _list() for the verbose task output, which would enable coloring in the verbose message and thus align the verbose message output even more with the normal task output.
2010-07-14 18:01:39 +02:00
Ingo Karkat
8a95a66749 Using die() for some more error messages. 2010-07-14 17:31:11 +02:00
Ingo Karkat
83053fd0c1 Better verbose messages for 'replace' and 'del TERM'.
Added "TODO:" prefix and simplified messages.
2010-07-14 17:18:57 +02:00
Ingo Karkat
74fa07d26a Aligned implementations of verbose output.
Replaced multi-line [ ] && { ... } with if-then.
2010-07-14 16:47:03 +02:00
Ingo Karkat
3e597ce20e Merge commit 'upstream/master' 2010-07-13 18:15:54 +02:00
Ingo Karkat
da466c9361 Improved 'move' command.
- Removed (accidental) printing of the task (without leading ITEM#) when checking for existence of the task; using empty check of task text as done elsewhere.
- Simplified error handling and using die() for proper exit code.
- Aligned verbose move message with the verbose output of other commands.
2010-07-13 18:11:05 +02:00
Ingo Karkat
72caab8bbd Added test for del preserving line numbers. 2010-07-13 17:49:40 +02:00
Ingo Karkat
7501b225c2 ENH: Improved 'del ITEM# TERM' command.
- Condensing whitespace around TERM into a single space and removing leading/trailing spaces if at the beginning/end of the task.
- Proper error message if TERM not found.
- Aligned verbose removal message with the verbose output of the 'replace' command.
In addition, removed (accidental) printing of the task (without leading ITEM#) when checking for existence of the task; using empty check of task text as done elsewhere.
2010-07-13 17:48:54 +02:00
Ingo Karkat
bcbf93ebe4 Fixed todo.sh del usage and exit code. 2010-07-13 16:18:02 +02:00
Gina Trapani
cea6d07735 Merge branch 'inkarkat/master' 2010-07-13 01:07:24 -07:00
Ingo Karkat
2f4ba26994 ENH: Sentence delimiters for append action.
This fixes a personal annoyance.
If the text to be appended to the task begins with one of the delimiter characters, no whitespace is inserted in between. This makes appending to an enumeration (todo.sh add 42 ", foo") syntactically correct.
The list of delimiters is configurable (for personal preferences / non-English languages) via SENTENCE_DELIMITERS in the config file.
2010-07-05 13:49:58 +02:00
Ingo Karkat
5e44868261 ENH: 'prepend' and 'replace' actions keep prepended date.
Generalized and simplified the logic that already kept an existing priority to also keep a date added via todo.sh -t / TODOTXT_DATE_ON_ADD (unless the replaced text also starts with a date).
2010-07-05 11:24:19 +02:00
Ingo Karkat
2f6d9ae329 Factored out 'prepend' and 'replace' actions.
They contained much duplication, which has been consolidated into replaceOrPrepend().
2010-07-05 09:38:10 +02:00
Gina Trapani
d46a12f14a Merge branch 'inkarkat/master' 2010-06-29 10:50:58 -07:00
Gina Trapani
95919765f7 Merge branch 'master' of git@github.com:ginatrapani/todo.txt-cli 2010-06-29 10:12:56 -07:00
Ingo Karkat
2d0efff9a8 Also exporting the die() function; it's often useful in custom actions. 2010-06-29 12:52:56 +02:00
Ingo Karkat
c58317258e Refactoring: Moved cleanup() calls from individual actions to end of script. 2010-06-29 11:26:07 +02:00
Ingo Karkat
38e2b8847f BUG: Failure of custom actions is not reflected in todo.sh exit status.
No further actions are done after cleanup() calls, so the change from "exit" to "return" is safe. Further refactoring of the cleanup() calls is pending.
2010-06-29 11:07:40 +02:00
Ingo Karkat
f72c1034ee Added tests for custom actions (TODO_ACTIONS_DIR).
t0002-actions.sh for locating the .todo.actions.d directory.
t8000-actions.sh for the contract between todo.sh and custom actions.
2010-06-29 10:43:53 +02:00
Ingo Karkat
37fcc53b26 BUG: test_todo_session with error exit doesn't work
BUG 1: didn't report non-error exit
A test that enforces a non-zero exit code via "=== N" would succeed when the command under test returned with success (0); only differing exit codes would be correctly reported.
Corrected logic so that the check for the exit code would always run, not just when the command under test failed.

BUG 2: too early evaluation of $?
In the test expression, the evaluation of $? must be deferred until the test expression itself is evaluated.
Escaping $? to prevent premature evaluation in the context of the expression definition.
2010-06-29 08:00:24 +02:00
Glyn Faulkner
e7b5841721 Generalizes the PRI_X color support to all priorities.
It allows you to assign a distinct color to any priority, not just A, B and C. Submitted to the todo.txt mailing list on 3-Jun-2010; committed on behalf of the author because there was no follow-up; cp. http://tech.groups.yahoo.com/group/todotxt/message/2619
Also committed this because it fixes a sed expression error when there are spaces in a $PRI_... variable, which occurred in my integration with Conky.
Note: This commit obsoletes and replaces the previous fix to colorization in commit 8b7e2e6aad.
Added tests for highlighting of priorities.
2010-06-21 15:25:42 +02:00
Ingo Karkat
0b16bae2e8 Merge commit 'upstream/master' 2010-06-21 12:41:24 +02:00
Ed Blackman
8b7e2e6aad Replace colorization sed scripts with ones that are more compatible with OSX
sed and NLS todo items.  They're also more consistent with other internal usage
of sed.
2010-06-10 13:20:35 +08:00
Ingo Karkat
9f03cf6847 Made verbose message of _addto() consistent with other task messages.
In verbose mode, commands first print the updated task, then summarize the change in the following line.
The add/addm/addto commands deviated from this, using "TODO: '<task>' added on line N."
This change splits this into two separate lines, obsoletes the implementation jargon of "line", and makes it easier to visually parse the message.
This is also a preparation for a possible future use of a _list()-like function, so that the updated task is processed and highlighted like the normal task output.
2010-06-10 13:20:07 +08:00
Ingo Karkat
821b9d2795 Bugfix: _list() cannot handle filter TERM starting with space.
Added proper quoting at check for search term starting with a dash.
Added tests for ls use with TERM, both with literal text and regexps. Seems that use case was missing from the tests so far.
Extra: Removed unnecessary "$@" argument to for() loop.
2010-06-10 13:20:05 +08:00
Ingo Karkat
c52d9c33af Removed unnecessary echo within echo. 2010-06-10 13:20:04 +08:00
Ingo Karkat
70b2c4ca40 Made verbose message of _addto() consistent with other task messages.
In verbose mode, commands first print the updated task, then summarize the change in the following line.
The add/addm/addto commands deviated from this, using "TODO: '<task>' added on line N."
This change splits this into two separate lines, obsoletes the implementation jargon of "line", and makes it easier to visually parse the message.
This is also a preparation for a possible future use of a _list()-like function, so that the updated task is processed and highlighted like the normal task output.
2010-06-04 16:50:09 +02:00
Ingo Karkat
69e756a2cd Bugfix: _list() cannot handle filter TERM starting with space.
Added proper quoting at check for search term starting with a dash.
Added tests for ls use with TERM, both with literal text and regexps. Seems that use case was missing from the tests so far.
Extra: Removed unnecessary "$@" argument to for() loop.
2010-06-04 16:22:15 +02:00
Ingo Karkat
52b9db310f Removed unnecessary echo within echo. 2010-06-03 22:13:17 +02:00
Gina Trapani
26bee144bd Merge branch 'inkarkat/master' 2010-05-30 19:09:58 -07:00
Ingo Karkat
8ff3a7ce4a Cleaned up terms in command error messages.
The messages now consistently use "task"; the use of "todo" is deprecated.
2010-05-27 15:48:37 +02:00
Ingo Karkat
8bddb08196 Cleaned up terms in help.
The help and messages now consistently use "task"; the use of "todo" is deprecated.
"ITEM#" is used to refer to the number of the task. This may be more consistently expressed as "TASK#". On the other hand, that could lead to more confusion between TASK (the text) and TASK# (the number).
The implementation still leaks through in the phrase "on line ITEM#"; ideally, todo.txt would abstract over the line-based textual representation.
2010-05-27 15:11:33 +02:00
Ingo Karkat
391064e4f0 Replaced "NUMBER" with "ITEM#" in help and shorthelp.
This makes the help output consistent with the syntax error messages of individual commands.
2010-05-27 14:49:07 +02:00
Ingo Karkat
d52a1a7bd2 Bugfix: Doubled help output on TTY with PAGER.
On "todo.sh help", first the long help output is printed through the pager, and
after quitting the pager the output is printed once more in full.
Didn't write a test for this, as this requires a connected terminal and cannot
be observed in the test harness.

Fix: The "exec" command has no effect inside a pipe; added an explicit "exit 0".

Also simplified check for PAGER: No "exec" necessary, combining stderr and
stdout.
Also added quoting for PAGER so that it can contain spaces.
2010-05-25 13:42:04 +02:00
Ingo Karkat
15084aa4d7 Allow passing multiple items to depri, like for the do command. 2010-05-25 13:27:28 +02:00
Ingo Karkat
5876cc0437 Bugfix: depri first checks validity of item argument syntax before searching for todo.
Added testcase for the basic depriority command.
2010-05-25 13:08:27 +02:00
Ingo Karkat
370abbbf36 Aligned short help for "do" with correct long help text. 2010-05-25 10:23:07 +02:00
Ingo Karkat
97eaa24b06 Corrected typo in comment. 2010-05-25 10:15:53 +02:00
Ingo Karkat
9e5e6aef39 Printing usage message if no ITEM# given to "todo.sh do". 2010-05-25 10:10:09 +02:00
Ingo Karkat
edac86a94d Aligned "todo.sh do" usage message with existing support of passing multiple numbers. 2010-05-25 09:44:22 +02:00
Gina Trapani
948686a501 Merge branch 'master' of git@github.com:ginatrapani/todo.txt-cli 2010-05-14 18:37:43 -07:00
Yujie Wu
2a65615c7a Added a case for the fixed replace command. 2010-05-08 08:52:59 +08:00
Yujie Wu
d7e194b09d Fixed bug for replace command. 2010-05-08 08:52:59 +08:00
Yujie Wu
fd10678257 Added a case for the fixed replace command. 2010-05-07 17:47:41 -07:00
Jared Cordasco
a4ab8a808a Tab fixes. 2010-04-16 06:12:00 +08:00
Gina Trapani
e395ac78d8 Fix line endings 2010-03-26 12:55:55 -07:00
Paul Mansfield
6fc2d81919 Bugfix: Old versions of bash do not have =~
Versions of bash before 3.0 do not have =~ syntax to match on a regex.
Changed to using a simple grep -c test instead.
Fixes issues with osx and Solaris 9 and before.
2010-02-23 23:05:03 +00:00
Jared Cordasco
b6467eaa64 Updated _list() output to match updated addto. Adjusted tests to match.
- _list() now shows the capitalized filename in place of 'TODO:'.
  For example, listing garden.txt produces a output prefixed by 'GARDEN:'
  This eliminates the ' from $FILE' part of the _list() output. All tests
  were adjusted to match this new output.
2010-01-12 14:42:02 -05:00
Jared Cordasco
2d3820394a Refactored various add functionality to one function. Added tests.
- 'add' and 'addm' now 'addto' with $TODO_FILE instead of user supplied file

- 'addto' now shows the capitalized filename in place of 'TODO:'.
  For example, adding to garden.txt produces a output prefixed by 'GARDEN:'
  (Probably the most controversial part of this commit and up for
  discussion. If kept, the 'listfile' output should be made to match.
  Note that this convention would then minimize standard output by
  dropping the file name.)

- All existing add/addm/add-date tests pass. Two new test sequences were
  added to test 'addto' and 'listfile' functionality.

- A space/tab nuissance was cleared up in the tests/README file.
2010-01-10 01:16:11 -05:00
Jared Cordasco
394c4c748a Correctly fixed regexp quoting issue for bash v3.1.x and v3.2.x.
See: http://stackoverflow.com/questions/218156/bash-regex-with-quotes
2010-01-06 21:05:22 -05:00
Jared Cordasco
4c76f04a82 Merge branch 'master' into personal_opts (w/ spacing corrections) 2010-01-05 23:26:08 -06:00
Gina Trapani
bf537934d7 Removed vim plugin; should be in separate repo for addons 2010-01-05 20:54:14 -08:00
Jared Cordasco
2bb14eb9bc Consolidated TODOTXT_VERBOSE tests. 2010-01-05 15:45:36 -05:00
Jared Cordasco
99511169c3 Fixed erroneous hide/show comments. 2010-01-05 15:38:24 -05:00
Jared Cordasco
acc881f0dd Faster here document outputs. (Help/Usage messages) 2010-01-05 15:33:34 -05:00
Jared Cordasco
d337933fd9 Changed odd tabs to spaces. 2010-01-05 15:33:34 -05:00
Jared Cordasco
0a7e6337b2 Quoting regexp to parse properly. 2010-01-04 17:01:29 -05:00
Brian Phillips
0e326067e3 fixed tabs/spaces, also set height on new window 2009-12-03 13:14:13 -06:00
Brian Phillips
f6cf3fe76f fixed auto-complete function name for contexts 2009-12-02 15:55:59 -06:00
Brian Phillips
20e04d5a4d more 'silent' additions 2009-12-02 15:38:46 -06:00
Brian Phillips
9c56d2137a added 'silent' to a bunch of calls 2009-12-02 15:26:32 -06:00
Brian Phillips
ceed8bf841 more tweaks 2009-12-02 15:17:12 -06:00
Brian Phillips
b8ced51a22 added some additional mappings, plus a project context 2009-12-02 14:37:36 -06:00
Brian Phillips
9a56bdd4ed vim support! (first cut, anyway) 2009-12-02 12:09:51 -06:00
Brian Phillips
9b580acf14 support PAGER pipe for help output 2009-12-02 08:55:46 -06:00
Paul Mansfield
0d5904658e Portability fixes
* Removed last echo -e instances, no support in OSX
2009-09-21 03:17:10 +01:00
Paul Mansfield
97866082e6 Small change for addm test case.
* Seems echo -e isn't multiplatform compatible. Using >> for append
  instead.
2009-09-17 23:52:43 +01:00
Mike West
5f9fd4c759 Bug Fix: tasks whose ID begins with '0' ought to be ignored.
*   Fixed regex in `_list` to exclude lines that begin with whitespace,
    as the ' ' => '0' replacement hadn't yet been performed.

*   Added test cases to `t1300-ls.sh` to check for this condition.
2009-09-14 21:21:25 +02:00
Gina Trapani
5a49f4b5d5 Merge branch 'the1ts/addm' 2009-09-08 11:58:04 -07:00
Gina Trapani
f8e6a8d69d Merge branch 'the1ts/master' 2009-09-08 11:57:20 -07:00
Paul Mansfield
2983917f25 whitespace fix 2009-09-06 19:05:46 +01:00
Paul Mansfield
7a87077dfc Added new action addm
This allows addition of multiple todo items by sending multiple lines.
2009-09-06 18:53:31 +01:00
Paul Mansfield
51dd50b41d Tighten the regex in Issue 6 bugfix.
Checks for complete action names before escaping &'s
2009-09-05 23:55:22 +01:00
Paul Mansfield
ddaf9ade22 Bug Fix: Issue 6 append and replace unexpected behavior if there's an & in task (even in quotes)
Using the cleaninput function, to escape &'s on certain actions.
Currently the actions needing escaped &'s are append, prepend and replace.
Other actions including add need unescaped &'s.
2009-09-05 20:36:38 +01:00
Gina Trapani
ce8a0a7875 Merge branch 'the1ts/master' 2009-09-04 16:11:50 -07:00
Paul Mansfield
5e71728cda Added a new variable $TODO_FULL_SH
This gives access to the full path of the script. It may prove useful
for addon developers to rerun todo.sh from within their addons, in order
to populate variables for context, projects etc. As we have the config
and actions directory available via variables, this is a missing piece.
2009-09-04 13:37:07 +01:00
Paul Mansfield
f44bcfb067 Bug Fix, better fix for "add does not escape line breaks"
Now removes windows and unix style line breaks. Each test has a windows
and a unix style line break.
2009-09-04 12:23:48 +01:00
Gina Trapani
a19a3616c4 Merge branch 'the1ts/master' 2009-09-03 10:45:03 -07:00
Paul Mansfield
229737bd2f Bug Fix: Issue 1
Added a cleanitem function, this replaces newlines with a space.
Currently this is used in the add, append, prepend and replace actions.
2009-09-02 23:30:14 +01:00
Gina Trapani
857121090a Merge branch 'FND/disable_final_filter' 2009-09-01 09:53:37 -07:00
FND
490f5d34e8 added option to disable final filter
The option marker was chosen as "-x" here.
Alternatives might be "-X" or "-*".
2009-08-30 09:48:44 +01:00
Paul Mansfield
7baf051942 Bug Fix: do: no safeguard to do twice
Tests item is not marked done before attempting to mark item as "done".
2009-08-29 21:13:38 +01:00
Gina Trapani
266d9e1258 Merge branch 'mivok/master' 2009-08-26 16:21:14 -07:00
Gina Trapani
e0b3ea1da9 Added new multiple do capability to help message 2009-08-26 15:51:27 -07:00
Gina Trapani
35e80b3f33 Merge branch 'the1ts/master' 2009-08-26 15:34:39 -07:00
David A. Harding
294e2ac9a4 Fixed issue #14: invalid date range. Changed regex [ -~] to [ ~-]. 2009-08-22 16:01:20 -04:00
Paul Mansfield
8d78cc6053 Merge branch 'issues11' of git@github.com:the1ts/todo.txt-cli 2009-07-04 11:07:41 +01:00
Paul Mansfield
092e83404f Bug Fix: prepend not correct on prioritized tasks
Check for priority, if one exists, remove, prepend and add back.
If priority doesn't exist just runs the normal prepend functionality.
2009-06-27 12:51:48 +01:00
Paul Mansfield
91126e38aa Issue fix: Multiple do items
Can now do multiple items in one go.
Either comma seperated list or a whitespace seperated list
2009-06-25 00:14:00 +01:00
Paul Mansfield
5df58793a0 Bug fix: for replace with priority
Checks for priority, removes, does replace then reinserts priority
2009-06-24 23:25:33 +01:00
Paul Mansfield
d2e892049d Bugfix: Replace with priority set
Checks for a priority, if found removes priority does the replace
then adds back the priority.

Added a test for replace with priority set.
2009-06-24 19:24:53 +01:00
Paul Mansfield
0e2798acce Added test for prepend and priority fix 2009-06-24 14:06:25 +01:00
Mark Harrison
98569d5f8c Tests for additional default config file location 2009-06-22 22:34:45 -04:00
Mark Harrison
75622c4a72 Support use of $HOME/.todo/ for all todo.sh configuration 2009-06-22 22:26:16 -04:00
Paul Mansfield
f9bb135068 Fixing prepend and priority issue.
Check for priority, delete if found, prepend and add back priority.
Uses awk and sed, works in linux.
2009-06-22 22:47:13 +01:00
Emil Sit
a4227dfec1 listcon/listproj: Work around bug in older GNU greps.
Commit df4f9150 introduced the use of "grep -w -o".  This
combination was broken from the introduction of -o (in 2001) until
subsequent release of GNU grep 2.5.3 in 2007---see changelog for
2005-11-10.  In particular, OS X uses a pre-2.5.3 version
of GNU grep.

Work around by replacing with two greps: one to find maximal
strings with @s in them (still relying on -o) and the second to
extract contexts.

Reported by Jon Smajda <jon@smajda.com>; fix developed
in conjunction with Philippe Teuwen <phil@teuwen.org>.

Signed-off-by: Emil Sit <sit@emilsit.net>
2009-05-11 12:53:59 -04:00
Emil Sit
78850255e0 tests: Add tests to validate listcon and listproj.
Two basic tests to ensure that listcon and listproj
function as expected.

Signed-off-by: Emil Sit <sit@emilsit.net>
2009-05-10 21:49:37 -04:00
ginatrapani
4dda7e27e4 Updated Known Bugs link to GitHub's Issues Tracker 2009-04-26 10:07:43 -07:00
Philippe Teuwen
cace5eb2d9 Bugfix: TODOTXT_DEFAULT_ACTION was not exported, now exports TODOTXT_*
Simplify the export of TODOTXT variables by having bash construct
the export list dynamically.

Signed-off-by: Emil Sit <sit@emilsit.net>
2009-04-25 20:27:59 -04:00
Philippe Teuwen
701c30c04f test-lib.sh: unset some more TODOTXT env vars for extra safety
While preparing a setup where env vars overload config file,
I had the bad experience that my actual todo.txt was messed up
by the testsuite so it's safer to unset everything.

Even so, some tests could have failed if some TODOTXT_ were set
in the user environment, for example:
export TODOTXT_PLAIN=1
./t1200-pri.sh

Since test-lib.sh does not depend on bash currently, calculate
the list of variables to be unset using set|sed.

Signed-off-by: Emil Sit <sit@emilsit.net>
2009-04-25 20:06:09 -04:00
Philippe Teuwen
2e62536f90 Bugfix: t0000-config test config file was wrong
$TODO_DIR were not protected therefore evaluated to null string
Hopefully it was used only to test for its own presence
but better to fix it in case someone wants to reuse that code

Signed-off-by: Emil Sit <sit@emilsit.net>
2009-04-20 10:04:45 -04:00
Philippe Teuwen
678283b69e Bugfix: typo in addto help msg skipped name of command
Signed-off-by: Emil Sit <sit@emilsit.net>
2009-04-20 10:04:45 -04:00
Philippe Teuwen
c490e773cf test-lib.sh: Fixing grep for date detection on Mac OS X, thanks Dave!
Signed-off-by: Emil Sit <sit@emilsit.net>
2009-04-20 10:04:44 -04:00
Dave Hein
a67d0de625 Add TODOTXT_FINAL_FILTER to provide a final custom list filter.
The idea behind this is to allow a config file or addon to inject
a list output filter after all the other filtering has been
performed. The existing TODOTXT_SORT_COMMAND provides a hook
for a custom filter prior to colorization and priority/context/proj
hiding; this new TODOTXT_FINAL_FILTER provides a hook for custom
filtering after the colorization and pri/con/proj hiding.

(I found this hook was needed when I wanted to trim the output to a
maximum line length.)

Note: I've added a number of tests of the list command, including
one for this new variable, as part of this change.

Signed-off-by: Emil Sit <sit@emilsit.net>
2009-04-19 20:30:53 -04:00
Philippe Teuwen
55015f5071 Bugfix: support commands combination for TODOTXT_SORT_COMMAND
So now e.g. piped commands can be used:
export TODOTXT_SORT_COMMAND=" env LC_COLLATE=C sort -f -k2 - | grep -m 10 ."
2009-04-19 20:30:53 -04:00
Philippe Teuwen
c8fc661256 Bugfix: test-lib.sh TEST_DIRECTORY could still contain symlink 2009-04-19 20:30:53 -04:00
Emil Sit
fee3133547 Uniformly use $TODO_SH to refer to script.
Set $TODO_SH to just be $(basename "$0") at the beginning
of the script and use it in all usage messages.

This happens to simplify testing because it allows us to refer to
the script as "todo.sh" in all output.  For general use, if the
user has aliased to file to something else, the usage messages will
still reflect that alias.

Signed-off-by: Emil Sit <sit@emilsit.net>
2009-04-18 21:26:42 -04:00
Emil Sit
825c60514f tests: Factor basic add/list, replace, priority testing out of t9999
add/list and replace are already covered by existing tests.
Add a new test, t1200-pri.sh, that handles the priority tests.

Signed-off-by: Emil Sit <sit@emilsit.net>
2009-04-15 01:28:01 -04:00
ginatrapani
90d113b77d Added wiki front page link 2009-04-14 19:47:52 -07:00
ginatrapani
4caee7d9c0 Consolidated docs under one header 2009-04-14 19:46:30 -07:00
Gina Trapani
fe99926bb2 Added date detection for Macs 2009-04-14 22:37:58 -04:00
Gina Trapani
fd9e2c05a7 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.
2009-04-13 19:26:06 -04:00
Emil Sit
10bca653a0 tests: Update documentation to reflect recent changes.
Merge Phil's README_generate-test into the main README
and also update the test library documentation to reflect
test_todo_session and test_tick.

Signed-off-by: Emil Sit <sit@emilsit.net>
2009-04-12 10:14:09 -04:00
Philippe Teuwen
d6c57e4230 tests: add testshell.sh and port old testsuite.txt
Add a simple helper script testshell.sh that can be called
to set up an environment for generating test case transcripts
that can then be pasted into an actual test script.

Port old testsuite.txt into t9999-testsuite_example.sh
with the aim of refactoring it later into smaller tests.

Also, change test_todo_session to count from one instead of zero when
autogenerating tests.

Signed-off-by: Emil Sit <sit@emilsit.net>
2009-04-12 10:01:34 -04:00
Gina Trapani
25616bd198 Ported README to Textile 2009-04-12 02:45:54 -04:00
Emil Sit
b238a29430 tests: Explicitly control the date for todo.sh.
Create a custom date view for todo.sh tests -- the time
is set in TODO_TEST_TIME as seconds since the Unix epoch
and a custom wrapper in the testing directory is put at the
front of the path to intercept todo.sh calls to date for
date formatting.

This will only work as long as todo.sh calls $(date) for
date formatting.  It also assumes a date command that
supports the -d flag (such as the one in GNU coreutils.)

Add a test for TODOTXT_DATE_ON_ADD to exercise this functionality.

Signed-off-by: Emil Sit <sit@emilsit.net>
2009-04-11 22:01:31 -04:00
Emil Sit
16a5103668 tests: Make test writing simpler and add two new tests.
Add a test_todo_session function to test-lib.sh that enables
easy recording of input and output from todo.sh (including
annotation of exit status for testing error cases).

Begin to port and re-factor testsuite.txt into smaller
test cases, starting with basic add list functionality
and replace functionality.

Thanks to Philippe Teuwen <phil@teuwen.org> for feedback
and improvements.

Signed-off-by: Emil Sit <sit@emilsit.net>
2009-04-11 22:00:49 -04:00
40 changed files with 4646 additions and 975 deletions

View File

@@ -1,10 +0,0 @@
TODO.TXT CLI Add-ons
adda (symlink to aa for fewer keystrokes)
* Adds a task and prioritizes it A in one shot
addx (symlink ax for fewer keystrokes)
* Adds a task and marks it as complete in one shot
birdseye (requires Python in path and birdseye.py file)
* Generates a textual report of open and complete tasks in all contexts and projects

View File

@@ -1,20 +0,0 @@
#!/bin/bash
action=$1
shift
[ "$action" = "usage" ] && {
echo " Add and prioritize A:"
curcmd=`basename $0`
echo " $curcmd \"THING I NEED TO DO +project @context\""
echo " Add an item and prioritize it A in one step"
echo ""
exit
}
if "$TODO_SH" command add "$@"; then
# figure out the line of what we just added, and prioritize it A
line=`sed -n '$ =' "$TODO_FILE"`
echo "$line"
"$TODO_SH" command pri "$line" A
fi

View File

@@ -1,20 +0,0 @@
#!/bin/bash
action=$1
shift
[ "$action" = "usage" ] && {
echo " Add and do:"
curcmd=`basename $0`
echo " $curcmd \"THING I DID +project @context\""
echo " Add an item and mark it as done in one step"
echo ""
exit
}
if "$TODO_SH" command add "$@"; then
# figure out the line of what we just added, and prioritize it A
line=`sed -n '$ =' "$TODO_FILE"`
echo "$line"
"$TODO_SH" command do "$line"
fi

View File

@@ -1,16 +0,0 @@
#!/bin/bash
action=$1
shift
[ "$action" = "usage" ] && {
echo " Bird's eye report:"
echo " birdseye"
echo " generates a textual report of pending and completed tasks in all projects and contexts"
echo ""
exit
}
[ "$action" = "birdseye" ] && {
python ${TODO_ACTIONS_DIR}/birdseye.py "$TODO_FILE" "$DONE_FILE"
}

View File

@@ -1,202 +0,0 @@
#!/usr/bin/python
""" TODO.TXT Bird's Eye View Reporter
USAGE:
birdseye.py [todo.txt] [done.txt]
USAGE NOTES:
Expects two text files as parameters, each of which formatted as follows:
- One todo per line, ie, "call Mom"
- with an optional project association indicated as such: "+projectname"
- with the context in which the tasks should be completed, indicated as such: "@context"
- with the task priority optionally listed at the front of the line, in parens, ie, "(A)"
For example, 4 lines of todo.txt might look like this:
+garagesale @phone schedule Goodwill pickup
(A) @phone Tell Mom I love her
+writing draft Great American Novel
(B) smell the roses
The done.txt file is a list of completed todos from todo.txt.
See more on todo.txt here:
http://todotxt.com
OUTPUT:
Displays a list of:
- working projects and their percentage complete
- contexts in which open todos exist
- contexts and projects with tasks that have been prioritized
- projects which are completely done (don't have any open todos)
CHANGELOG:
2016.03.17 - Update for Python 3. Tx, JonathanReeve!
2006.07.29 - Now supports p:, p- and + project notation. Tx, Pedro!
2006.05.02 - Released
"""
import sys
__version__ = "1.2"
__date__ = "2006/05/02"
__updated__ = "2016/03/17"
__author__ = "Gina Trapani (ginatrapani@gmail.com)"
__copyright__ = "Copyright 2006 - 2016, Gina Trapani"
__license__ = "GPL"
__history__ = """
1.2 - Update for Python 3. Tx, JonathanReeve!
1.1 - Now supports p:, p- and + project notation. Tx, Pedro!
1.0 - Released.
"""
def usage():
print("USAGE: %s [todo.txt] [done.txt]" % (sys.argv[0], ))
def printTaskGroups(title, taskDict, priorityList, percentages):
print("")
print("%s"% (title,))
separator("-")
if not taskDict:
print("No items to list.")
else:
# sort the dictionary by value
# http://python.fyxm.net/peps/pep-0265.html
items = [(v, k) for k, v in list(taskDict.items())]
items.sort()
items.reverse() # so largest is first
items = [(k, v) for v, k in items]
for item in items:
if item[0] in priorityList:
if item[0] not in percentages:
printTaskGroup(item, -1, "*")
else:
printTaskGroup(item, percentages[item[0]], "*")
for item in items:
if item[0] not in priorityList:
if item[0] not in percentages:
printTaskGroup(item, -1, " ")
else:
printTaskGroup(item, percentages[item[0]], " ")
def printTaskGroup(p, pctage, star):
if pctage > -1:
progressBar = ""
numStars = int(pctage//10)
progressBar = "=" * numStars
numSpaces = 10 - numStars
for n in range(numSpaces):
progressBar += " "
if pctage > 9:
displayTotal = " %d%%"% (pctage, );
else:
displayTotal = " %d%%"% (pctage, );
print("%s %s [%s] %s (%d todos)"% (star, displayTotal, progressBar, p[0], p[1],))
else:
print("%s %s (%d todos)"% (star, p[0], p[1], ))
def separator(c):
sep = ""
sep = c * 42
print(sep)
def main(argv):
# make sure you have all your args
if len(argv) < 2:
usage()
sys.exit(2)
# process todo.txt
try:
f = open (argv[0], "r")
projects = {}
contexts = {}
projectPriority = []
contextPriority = []
for line in f:
prioritized = False
words = line.split()
if words and words[0].startswith("("):
prioritized = True
for word in words:
if word[0:2] == "p:" or word[0:2] == "p-" or word[0:1] == "+":
if word not in projects:
projects[word] = 1
else:
projects[word] = projects.setdefault(word,0) + 1
if prioritized:
projectPriority.append(word)
if word[0:1] == "@":
if word not in contexts:
contexts[word] = 1
else:
contexts[word] = contexts.setdefault(word, 0) + 1
if prioritized:
contextPriority.append(word)
f.close()
except IOError:
print("ERROR: The file named %s could not be read."% (argv[0], ))
usage()
sys.exit(2)
# process done.txt
try:
completedTasks = {}
f = open (argv[1], "r")
for line in f:
words = line.split()
for word in words:
if word[0:2] == "p:" or word[0:2] == "p-" or word[0:1] == "+":
if word not in completedTasks:
completedTasks[word] = 1
else:
completedTasks[word] = completedTasks.setdefault(word, 0) + 1
f.close()
except IOError:
print("ERROR: The file named %s could not be read."% (argv[1], ))
usage()
sys.exit(2)
# calculate percentages
projectPercentages = {}
for project in projects:
openTasks = projects[project]
if project in completedTasks:
closedTasks = completedTasks[project]
else:
closedTasks = 0
totalTasks = openTasks + closedTasks
projectPercentages[project] = (closedTasks*100) / totalTasks
# get projects all done
projectsWithNoIncompletes = {}
for task in completedTasks:
if task not in projects:
projectsWithNoIncompletes[task] = 0
# print out useful info
#print "TODO.TXT Bird's Eye View Report %s"% ( datetime.date.today().isoformat(), )
print("")
print("TODO.TXT Bird's Eye View Report")
separator("=")
printTaskGroups("Projects with Open TODOs", projects, projectPriority, projectPercentages)
printTaskGroups("Contexts with Open TODOs", contexts, contextPriority, projectPercentages)
printTaskGroups("Completed Projects (No open TODOs)", projectsWithNoIncompletes, projectPriority, projectPercentages)
print("")
print("* Projects and contexts with an asterisk next to them denote prioritized tasks.")
print("Project with prioritized tasks are listed first, then sorted by number of open todos.")
print("")
if __name__ == "__main__":
main(sys.argv[1:])

View File

@@ -1,199 +0,0 @@
#!/usr/bin/python
""" TODO.TXT Weekly Review
USAGE:
weeklyreview.py [todo.txt] [done.txt] [projects.txt]
USAGE NOTES:
Expects three text files as parameters:
1 & 2. Properly-formatted todo.txt and done.txt files.
3. A projects.txt file which lists one project per line, and any number of #goals associated with it.
See more on todo.txt here:
http://todotxt.com
OUTPUT:
Displays a count of how many tasks were completed associated with a goal.
"""
import sys
import datetime
__version__ = "1.2"
__date__ = "2016/03/17"
__updated__ = "2016/03/17"
__author__ = "Gina Trapani (ginatrapani@gmail.com)"
__copyright__ = "Copyright 2016, Gina Trapani"
__license__ = "GPL"
__history__ = """
0.1 - WIP
"""
def usage():
print("USAGE: %s [todo.txt] [done.txt] [projects.txt]" % (sys.argv[0], ))
def separator(c, r=42):
sep = ""
sep = c * r
print(sep)
def printTitle(text):
print("")
r = len(text)
print(text)
separator("=", r)
def printHeader(text):
r = len(text)
print("")
print(text)
separator("-", r)
def main(argv):
# make sure you have all your args
if len(argv) < 3:
usage()
sys.exit(2)
goal_projects = getGoalProjects(argv)
#print(goal_projects)
last_7_days = getLast7Days()
#print(last_7_days)
last_7_days_of_completions = getLast7DaysOfCompletions(argv, last_7_days)
#print(last_7_days_of_completions)
project_completions = getProjectCompletions(argv, last_7_days_of_completions)
#print(project_completions)
goal_completions = getGoalCompletions(goal_projects, project_completions)
# print(goal_completions)
# Print report: For each item in goal_projects, print the goal, the number of tasks completed,
# then each project and the number of tasks completed
printTitle("Weekly Review for the past 7 days")
goals_not_moved = []
goals_moved = []
for goal in goal_projects:
total_done = 0
if goal in goal_completions:
total_done = len(goal_completions[goal])
goal_header = goal + " - " + str(total_done) + " done"
if total_done > 0:
printHeader(goal_header)
for project in goal_projects[goal]:
if project in project_completions:
print(project + " - " + str(len(project_completions[project])) + " done" )
for task in project_completions[project]:
print(" " + task.strip())
goals_moved.append(goal)
else:
goals_not_moved.append(goal)
# Print a list of goals that had no movement
if len(goals_not_moved) > 0:
printTitle("Goals with no progress")
for goal in goals_not_moved:
print(goal)
# Print summary
print("")
summary = str(len(last_7_days_of_completions)) + " completed tasks moved " + str(len(goals_moved)) + " out of " + str(len(goal_projects)) + " goals forward."
separator("-", len(summary))
print(summary)
separator("-", len(summary))
# Warnings
crossCheckCompletedProjects(project_completions, goal_projects)
# Return an array of goals with total tasks completed.
def getGoalCompletions(goal_projects, project_completions):
goal_completions = {}
goals = goal_projects.keys()
for goal in goal_projects:
for project in project_completions:
if project in goal_projects[goal]:
if goal not in goal_completions:
goal_completions[goal] = project_completions[project]
else:
goal_completions[goal] = goal_completions[goal] + project_completions[project]
return goal_completions
# Return the goal/project list as an array of arrays goalProjects[goal] = projects[]
def getGoalProjects(argv):
try:
goal_projects = {}
f = open (argv[2], "r")
for line in f:
words = line.split()
for word in words:
# Project
if word[0:1] == "+":
current_project = word
# Goal
if word[0:1] == "#":
if word not in goal_projects:
goal_projects[word] = [current_project];
else:
goal_projects[word].append(current_project)
f.close()
return goal_projects
except IOError:
print("ERROR: The file named %s could not be read."% (argv[1], ))
usage()
sys.exit(2)
# Get the last 7 days as an array of todo.txt-formatted dates.
def getLast7Days():
today = datetime.date.today()
last7Days = []
for d in range(8):
day_this_week = today - datetime.timedelta(days=d)
last7Days.append(day_this_week.strftime('%Y-%m-%d'))
return last7Days
# Return last 7 days of completed tasks from done.txt
def getLast7DaysOfCompletions(argv, last_7_days):
try:
last_7_days_of_completions = []
f = open (argv[1], "r")
for line in f:
words = line.split()
if len(words) > 2 and words[1] in last_7_days:
last_7_days_of_completions.append(line)
f.close()
return last_7_days_of_completions
except IOError:
print("ERROR: The file named %s could not be read."% (argv[1], ))
usage()
sys.exit(2)
# Return an array of projects with the total tasks completed.
def getProjectCompletions(argv, last_7_days_of_completions):
project_completions = {}
for task in last_7_days_of_completions:
words = task.split()
for word in words:
if word[0:2] == "p:" or word[0:2] == "p-" or word[0:1] == "+":
if word not in project_completions:
project_completions[word] = [task]
else:
project_completions[word].append(task)
return project_completions
def crossCheckCompletedProjects(project_completions, goal_projects):
for project in project_completions:
goal_in_project = False
for goal in goal_projects:
if project in goal_projects[goal]:
goal_in_project = True
if goal_in_project == False:
print("WARNING: Project " + project + " not in goal.")
if __name__ == "__main__":
main(sys.argv[1:])

674
LICENSE Normal file
View File

@@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.

View File

@@ -13,7 +13,7 @@ VERSION-FILE: .FORCE-VERSION-FILE
todo.sh: VERSION-FILE todo.sh: VERSION-FILE
# For packaging # For packaging
DISTFILES := todo.cfg DISTFILES := todo.cfg todo_completion
DISTNAME=todo.txt_cli-$(VERSION) DISTNAME=todo.txt_cli-$(VERSION)
dist: $(DISTFILES) todo.sh dist: $(DISTFILES) todo.sh
@@ -42,7 +42,7 @@ test-pre-clean:
aggregate-results: $(TESTS) aggregate-results: $(TESTS)
$(TESTS): test-pre-clean $(TESTS): test-pre-clean
-cd tests && sh $(notdir $@) $(TEST_OPTIONS) -cd tests && ./$(notdir $@) $(TEST_OPTIONS)
test: aggregate-results test: aggregate-results
tests/aggregate-results.sh tests/test-results/t*-* tests/aggregate-results.sh tests/test-results/t*-*

View File

@@ -23,4 +23,4 @@ h2. Quick Links
* Licensed under the "GPL":http://www.gnu.org/copyleft/gpl.html * Licensed under the "GPL":http://www.gnu.org/copyleft/gpl.html
* "Add-on Directory":http://wiki.github.com/ginatrapani/todo.txt-cli/todosh-add-on-directory * "Add-on Directory":http://wiki.github.com/ginatrapani/todo.txt-cli/todosh-add-on-directory
* "Changelog":http://wiki.github.com/ginatrapani/todo.txt-cli/todosh-changelog * "Changelog":http://wiki.github.com/ginatrapani/todo.txt-cli/todosh-changelog
* "Known Bugs":http://wiki.github.com/ginatrapani/todo.txt-cli/known-bugs * "Known Bugs":http://github.com/ginatrapani/todo.txt-cli/issues

View File

@@ -105,7 +105,7 @@ First digit tells the family:
0 - the absolute basics and global stuff 0 - the absolute basics and global stuff
1 - basic every-day usage 1 - basic every-day usage
2 - add ins 2 - add ins
Second digit tells the particular command we are testing. Second digit tells the particular command we are testing.
@@ -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.

View File

@@ -10,7 +10,7 @@ to find it somewhere else.
# Remove the pre-created todo.cfg to test behavior in its absence # Remove the pre-created todo.cfg to test behavior in its absence
rm -f todo.cfg rm -f todo.cfg
echo "Fatal error: Cannot read configuration file $HOME/todo.cfg" > expect echo "Fatal Error: Cannot read configuration file $HOME/.todo/config" > expect
test_expect_success 'no config file' ' test_expect_success 'no config file' '
todo.sh > output 2>&1 || test_cmp expect output todo.sh > output 2>&1 || test_cmp expect output
' '
@@ -23,15 +23,24 @@ EOF
cat > test.cfg << EOF cat > test.cfg << EOF
export TODO_DIR=. export TODO_DIR=.
export TODO_FILE="$TODO_DIR/todo.txt" export TODO_FILE="\$TODO_DIR/todo.txt"
export DONE_FILE="$TODO_DIR/done.txt" export DONE_FILE="\$TODO_DIR/done.txt"
export REPORT_FILE="$TODO_DIR/report.txt" export REPORT_FILE="\$TODO_DIR/report.txt"
export TMP_FILE="$TODO_DIR/todo.tmp" export TMP_FILE="\$TODO_DIR/todo.tmp"
touch used_config touch used_config
EOF EOF
rm -f used_config rm -f used_config
test_expect_success 'config file (default location 1)' ' test_expect_success 'config file (default location 1)' '
mkdir .todo
cp test.cfg .todo/config
todo.sh > output;
test_cmp expect output && test -f used_config &&
rm -rf .todo
'
rm -f used_config
test_expect_success 'config file (default location 2)' '
cp test.cfg todo.cfg cp test.cfg todo.cfg
todo.sh > output; todo.sh > output;
test_cmp expect output && test -f used_config && test_cmp expect output && test -f used_config &&
@@ -39,7 +48,7 @@ test_expect_success 'config file (default location 1)' '
' '
rm -f used_config rm -f used_config
test_expect_success 'config file (default location 2)' ' test_expect_success 'config file (default location 3)' '
cp test.cfg .todo.cfg cp test.cfg .todo.cfg
todo.sh > output; todo.sh > output;
test_cmp expect output && test -f used_config && test_cmp expect output && test -f used_config &&

View File

@@ -12,7 +12,7 @@ when there are no todos.
# #
cat > expect <<EOF cat > expect <<EOF
-- --
TODO: 0 of 0 tasks shown from $HOME/todo.txt TODO: 0 of 0 tasks shown
EOF EOF
test_expect_success 'null ls' ' test_expect_success 'null ls' '
@@ -44,7 +44,7 @@ test_expect_success 'null listpri a' '
# #
cat > expect <<EOF cat > expect <<EOF
-- --
TODO: 0 of 0 tasks shown from $HOME/todo.tmp TODO: 0 of 0 tasks shown
EOF EOF
test_expect_success 'null lsa' ' test_expect_success 'null lsa' '

40
tests/t0002-actions.sh Executable file
View File

@@ -0,0 +1,40 @@
#!/bin/sh
test_description='todo.sh actions.d
This test just makes sure that todo.sh can locate custom actions.
'
. ./test-lib.sh
# All the below tests will output the custom action message
cat > expect << EOF
TODO: foo
EOF
cat > foo << EOF
echo "TODO: foo"
EOF
chmod +x foo
test_expect_success 'custom action (default location 1)' '
mkdir .todo.actions.d
cp foo .todo.actions.d/
todo.sh foo > output;
test_cmp expect output && rm -rf .todo.actions.d
'
test_expect_success 'custom action (default location 2)' '
mkdir -p .todo/actions
cp foo .todo/actions/
todo.sh foo > output;
test_cmp expect output && rm -rf .todo/actions
'
test_expect_success 'custom action (env variable)' '
mkdir myactions
cp foo myactions/
TODO_ACTIONS_DIR=myactions todo.sh foo > output;
test_cmp expect output && rm -rf myactions
'
test_done

16
tests/t0100-code-nobacktick.sh Executable file
View File

@@ -0,0 +1,16 @@
#!/bin/sh
test_description='no old-style backtick command substitution
This test checks the todo.sh script itself for occurrences
of old-style backtick command substitution, which should be
replaced with $(...).
On failure, it will print each offending line number and line.
'
. ./test-lib.sh
test_todo_session 'no old-style backtick command substitution' <<EOF
>>> sed -n -e 's/\(^\|[ \t]\)#.*//' -e '/\`/{' -e '=;p' -e '}' "$(which todo.sh)"
EOF
test_done

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

@@ -0,0 +1,113 @@
#!/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
1 notice the daisies
TODO: 1 added.
>>> todo.sh list
1 notice the daisies
--
TODO: 1 of 1 tasks shown
>>> todo.sh add smell the roses
2 smell the roses
TODO: 2 added.
>>> todo.sh list
1 notice the daisies
2 smell the roses
--
TODO: 2 of 2 tasks shown
EOF
#
# Filter
#
test_todo_session 'basic list filtering' <<EOF
>>> todo.sh list daisies
1 notice the daisies
--
TODO: 1 of 2 tasks shown
>>> todo.sh list smell
2 smell the roses
--
TODO: 1 of 2 tasks shown
EOF
test_todo_session 'case-insensitive filtering' <<EOF
>>> todo.sh add smell the uppercase Roses
3 smell the uppercase Roses
TODO: 3 added.
>>> todo.sh list roses
2 smell the roses
3 smell the uppercase Roses
--
TODO: 2 of 3 tasks shown
EOF
test_todo_session 'add with symbols' <<EOF
>>> todo.sh add "~@#$%^&*()-_=+[{]}|;:',<.>/?"
4 ~@#$%^&*()-_=+[{]}|;:',<.>/?
TODO: 4 added.
>>> todo.sh add '\`!\\"'
5 \`!\\"
TODO: 5 added.
>>> todo.sh list
1 notice the daisies
2 smell the roses
3 smell the uppercase Roses
5 \`!\\"
4 ~@#$%^&*()-_=+[{]}|;:',<.>/?
--
TODO: 5 of 5 tasks shown
EOF
#
# Advanced add
#
cat /dev/null > todo.txt
test_todo_session 'add with spaces' <<EOF
>>> todo.sh add "notice the three spaces"
1 notice the three spaces
TODO: 1 added.
>>> todo.sh add notice how the spaces get lost
2 notice how the spaces get lost
TODO: 2 added.
>>> todo.sh list
2 notice how the spaces get lost
1 notice the three spaces
--
TODO: 2 of 2 tasks shown
EOF
cat /dev/null > todo.txt
test_todo_session 'add with CR' <<EOF
>>> todo.sh add "smell the
Carriage Return"
1 smell the Carriage Return
TODO: 1 added.
>>> todo.sh list
1 smell the Carriage Return
--
TODO: 1 of 1 tasks shown
EOF

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

@@ -0,0 +1,89 @@
#!/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
1 2009-02-13 notice the daisies
TODO: 1 added.
>>> todo.sh list
1 2009-02-13 notice the daisies
--
TODO: 1 of 1 tasks shown
EOF
test_todo_session 'cmd line first day with priority' <<EOF
>>> todo.sh -pt add '(A) notice the daisies'
2 (A) 2009-02-13 notice the daisies
TODO: 2 added.
>>> todo.sh -p list
2 (A) 2009-02-13 notice the daisies
1 2009-02-13 notice the daisies
--
TODO: 2 of 2 tasks shown
>>> todo.sh -npf del 2
2 (A) 2009-02-13 notice the daisies
TODO: 2 deleted.
EOF
test_tick
test_todo_session 'cmd line second day' <<EOF
>>> todo.sh -t add smell the roses
2 2009-02-14 smell the roses
TODO: 2 added.
>>> todo.sh list
1 2009-02-13 notice the daisies
2 2009-02-14 smell the roses
--
TODO: 2 of 2 tasks shown
EOF
test_tick
test_todo_session 'cmd line third day' <<EOF
>>> todo.sh -t add mow the lawn
3 2009-02-15 mow the lawn
TODO: 3 added.
>>> 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
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
4 2009-02-15 take out the trash
TODO: 4 added.
>>> 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
EOF
test_done

101
tests/t1020-addtolistfile.sh Executable file
View File

@@ -0,0 +1,101 @@
#!/bin/sh
test_description='basic addto and list functionality
This test just makes sure the basic addto and listfile
commands work, including support for filtering.
'
. ./test-lib.sh
#
# Addto and listfile
#
test_todo_session 'nonexistant file' <<EOF
>>> todo.sh addto garden.txt notice the daisies
TODO: Destination file $HOME/garden.txt does not exist.
=== 1
EOF
touch "$HOME/garden.txt"
test_todo_session 'basic addto/listfile' <<EOF
>>> todo.sh addto garden.txt notice the daisies
1 notice the daisies
GARDEN: 1 added.
>>> todo.sh listfile garden.txt
1 notice the daisies
--
GARDEN: 1 of 1 tasks shown
>>> todo.sh addto garden.txt smell the roses
2 smell the roses
GARDEN: 2 added.
>>> todo.sh listfile garden.txt
1 notice the daisies
2 smell the roses
--
GARDEN: 2 of 2 tasks shown
EOF
#
# List available files
#
test_todo_session 'list available files' <<EOF
>>> todo.sh listfile
Files in the todo.txt directory:
done.txt
garden.txt
report.txt
todo.txt
>>> TODOTXT_VERBOSE=0 todo.sh listfile
done.txt
garden.txt
report.txt
todo.txt
EOF
#
# Filter
#
test_todo_session 'basic listfile filtering' <<EOF
>>> todo.sh listfile garden.txt daisies
1 notice the daisies
--
GARDEN: 1 of 2 tasks shown
>>> todo.sh listfile garden.txt smell
2 smell the roses
--
GARDEN: 1 of 2 tasks shown
EOF
test_todo_session 'case-insensitive filtering' <<EOF
>>> todo.sh addto garden.txt smell the uppercase Roses
3 smell the uppercase Roses
GARDEN: 3 added.
>>> todo.sh listfile garden.txt roses
2 smell the roses
3 smell the uppercase Roses
--
GARDEN: 2 of 3 tasks shown
EOF
test_todo_session 'addto with &' <<EOF
>>> todo.sh addto garden.txt "dig the garden & water the flowers"
4 dig the garden & water the flowers
GARDEN: 4 added.
>>> todo.sh listfile garden.txt
4 dig the garden & water the flowers
1 notice the daisies
2 smell the roses
3 smell the uppercase Roses
--
GARDEN: 4 of 4 tasks shown
EOF
test_done

75
tests/t1030-addto-date.sh Executable file
View File

@@ -0,0 +1,75 @@
#!/bin/sh
test_description='test the date on addto feature
Tests paths by which we might automatically add
a date to each item.
'
. ./test-lib.sh
touch "$HOME/garden.txt"
#
# Add and list
#
test_todo_session 'cmd line first day' <<EOF
>>> todo.sh -t addto garden.txt notice the daisies
1 2009-02-13 notice the daisies
GARDEN: 1 added.
>>> todo.sh listfile garden.txt
1 2009-02-13 notice the daisies
--
GARDEN: 1 of 1 tasks shown
EOF
test_tick
test_todo_session 'cmd line second day' <<EOF
>>> todo.sh -t addto garden.txt smell the roses
2 2009-02-14 smell the roses
GARDEN: 2 added.
>>> todo.sh listfile garden.txt
1 2009-02-13 notice the daisies
2 2009-02-14 smell the roses
--
GARDEN: 2 of 2 tasks shown
EOF
test_tick
test_todo_session 'cmd line third day' <<EOF
>>> todo.sh -t addto garden.txt mow the lawn
3 2009-02-15 mow the lawn
GARDEN: 3 added.
>>> todo.sh listfile garden.txt
1 2009-02-13 notice the daisies
2 2009-02-14 smell the roses
3 2009-02-15 mow the lawn
--
GARDEN: 3 of 3 tasks shown
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 addto garden.txt take out the trash
4 2009-02-15 take out the trash
GARDEN: 4 added.
>>> todo.sh listfile garden.txt
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
--
GARDEN: 4 of 4 tasks shown
EOF
test_done

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

@@ -0,0 +1,167 @@
#!/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: todo.sh replace ITEM# "UPDATED ITEM"
EOF
test_todo_session 'basic replace' <<EOF
>>> todo.sh replace 1 "smell the cows"
1 notice the daisies
TODO: Replaced task with:
1 smell the cows
>>> todo.sh list
1 smell the cows
--
TODO: 1 of 1 tasks shown
>>> todo.sh replace 1 smell the roses
1 smell the cows
TODO: Replaced task with:
1 smell the roses
>>> todo.sh list
1 smell the roses
--
TODO: 1 of 1 tasks shown
EOF
cat > todo.txt <<EOF
smell the cows
grow some corn
thrash some hay
chase the chickens
EOF
test_todo_session 'replace error' << EOF
>>> todo.sh replace 10 "hej!"
=== 1
TODO: No task 10.
EOF
test_todo_session 'replace in multi-item file' <<EOF
>>> todo.sh replace 1 smell the cheese
1 smell the cows
TODO: Replaced task with:
1 smell the cheese
>>> todo.sh replace 3 jump on hay
3 thrash some hay
TODO: Replaced task with:
3 jump on hay
>>> todo.sh replace 4 collect the eggs
4 chase the chickens
TODO: Replaced task with:
4 collect the eggs
EOF
echo '(A) collect the eggs' > todo.txt
test_todo_session 'replace with priority' <<EOF
>>> todo.sh replace 1 "collect the bread"
1 (A) collect the eggs
TODO: Replaced task with:
1 (A) collect the bread
>>> todo.sh replace 1 collect the eggs
1 (A) collect the bread
TODO: Replaced task with:
1 (A) collect the eggs
EOF
echo 'jump on hay' > todo.txt
test_todo_session 'replace with &' << EOF
>>> todo.sh replace 1 "thrash the hay & thrash the wheat"
1 jump on hay
TODO: Replaced task with:
1 thrash the hay & thrash the wheat
EOF
echo 'jump on hay' > todo.txt
test_todo_session 'replace with spaces' <<EOF
>>> todo.sh replace 1 "notice the three spaces"
1 jump on hay
TODO: Replaced task with:
1 notice the three spaces
EOF
cat > todo.txt <<EOF
smell the cows
grow some corn
thrash some hay
chase the chickens
EOF
test_todo_session 'replace with symbols' <<EOF
>>> todo.sh replace 1 "~@#$%^&*()-_=+[{]}|;:',<.>/?"
1 smell the cows
TODO: Replaced task with:
1 ~@#$%^&*()-_=+[{]}|;:',<.>/?
>>> todo.sh replace 2 '\`!\\"'
2 grow some corn
TODO: Replaced task with:
2 \`!\\"
>>> todo.sh list
4 chase the chickens
3 thrash some hay
2 \`!\\"
1 ~@#$%^&*()-_=+[{]}|;:',<.>/?
--
TODO: 4 of 4 tasks shown
EOF
cat /dev/null > todo.txt
test_todo_session 'replace handling prepended date on add' <<EOF
>>> todo.sh -t add "new task"
1 2009-02-13 new task
TODO: 1 added.
>>> todo.sh replace 1 this is just a new one
1 2009-02-13 new task
TODO: Replaced task with:
1 2009-02-13 this is just a new one
>>> todo.sh replace 1 2010-07-04 this also has a new date
1 2009-02-13 this is just a new one
TODO: Replaced task with:
1 2010-07-04 this also has a new date
EOF
cat /dev/null > todo.txt
test_todo_session 'replace handling priority and prepended date on add' <<EOF
>>> todo.sh -t add "new task"
1 2009-02-13 new task
TODO: 1 added.
>>> todo.sh pri 1 A
1 (A) 2009-02-13 new task
TODO: 1 prioritized (A).
>>> todo.sh replace 1 this is just a new one
1 (A) 2009-02-13 new task
TODO: Replaced task with:
1 (A) 2009-02-13 this is just a new one
EOF
echo '(A) 2009-02-13 this is just a new one' > todo.txt
test_todo_session 'replace with prepended date replaces existing date' <<EOF
>>> todo.sh replace 1 2010-07-04 this also has a new date
1 (A) 2009-02-13 this is just a new one
TODO: Replaced task with:
1 (A) 2010-07-04 this also has a new date
EOF
test_done

103
tests/t1200-pri.sh Executable file
View File

@@ -0,0 +1,103 @@
#!/bin/sh
test_description='basic priority functionality
'
. ./test-lib.sh
test_todo_session 'priority usage' <<EOF
>>> todo.sh pri B B
usage: todo.sh pri ITEM# PRIORITY
note: PRIORITY must be anywhere from A to Z.
=== 1
EOF
cat > todo.txt <<EOF
smell the uppercase Roses +flowers @outside
notice the sunflowers
stop
EOF
test_todo_session 'basic priority' <<EOF
>>> todo.sh list
2 notice the sunflowers
1 smell the uppercase Roses +flowers @outside
3 stop
--
TODO: 3 of 3 tasks shown
>>> 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
>>> todo.sh -p list
1 (B) smell the uppercase Roses +flowers @outside
2 notice the sunflowers
3 stop
--
TODO: 3 of 3 tasks shown
>>> 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
>>> todo.sh add "smell the coffee +wakeup"
4 smell the coffee +wakeup
TODO: 4 added.
>>> todo.sh -p list
1 (B) smell the uppercase Roses +flowers @outside
2 (C) notice the sunflowers
4 smell the coffee +wakeup
3 stop
--
TODO: 4 of 4 tasks shown
EOF
test_todo_session 'priority error' <<EOF
>>> todo.sh pri 10 B
=== 1
TODO: No task 10.
EOF
cat > todo.txt <<EOF
(B) smell the uppercase Roses +flowers @outside
(C) notice the sunflowers
stop
EOF
test_todo_session 'reprioritize' <<EOF
>>> todo.sh pri 2 A
2 (A) notice the sunflowers
TODO: 2 re-prioritized from (C) to (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
>>> todo.sh pri 2 a
2 (A) notice the sunflowers
TODO: 2 already 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
EOF
test_done

95
tests/t1250-listpri.sh Executable file
View File

@@ -0,0 +1,95 @@
#!/bin/sh
test_description='list priority functionality
'
. ./test-lib.sh
cat > todo.txt <<EOF
(B) smell the uppercase Roses +flowers @outside
(C) notice the sunflowers
stop
EOF
test_todo_session 'basic listpri' <<EOF
>>> todo.sh listpri A
--
TODO: 0 of 3 tasks shown
>>> todo.sh -p listpri c
2 (C) notice the sunflowers
--
TODO: 1 of 3 tasks shown
EOF
test_todo_session 'listpri highlighting' <<EOF
>>> todo.sh listpri
1 (B) smell the uppercase Roses +flowers @outside
2 (C) notice the sunflowers
--
TODO: 2 of 3 tasks shown
EOF
cat > todo.txt <<EOF
(B) smell the uppercase Roses +flowers @outside
(C) notice the sunflowers
(m)others will notice this
(n) not a prioritized task
notice the (C)opyright
EOF
test_todo_session 'listpri filtering priorities' <<EOF
>>> todo.sh -p listpri
1 (B) smell the uppercase Roses +flowers @outside
2 (C) notice the sunflowers
--
TODO: 2 of 5 tasks shown
>>> todo.sh -p listpri b
1 (B) smell the uppercase Roses +flowers @outside
--
TODO: 1 of 5 tasks shown
>>> todo.sh -p listpri c
2 (C) notice the sunflowers
--
TODO: 1 of 5 tasks shown
>>> todo.sh -p listpri m
--
TODO: 0 of 5 tasks shown
>>> todo.sh -p listpri n
--
TODO: 0 of 5 tasks shown
EOF
cat > todo.txt <<EOF
(B) ccc xxx this line should be third.
ccc xxx this line should be third.
(A) aaa zzz this line should be first.
aaa zzz this line should be first.
(B) bbb yyy this line should be second.
bbb yyy this line should be second.
EOF
test_todo_session 'listpri filtering of TERM' <<EOF
>>> todo.sh -p listpri "should be"
3 (A) aaa zzz this line should be first.
5 (B) bbb yyy this line should be second.
1 (B) ccc xxx this line should be third.
--
TODO: 3 of 6 tasks shown
>>> todo.sh -p listpri a "should be"
3 (A) aaa zzz this line should be first.
--
TODO: 1 of 6 tasks shown
>>> todo.sh -p listpri b second
5 (B) bbb yyy this line should be second.
--
TODO: 1 of 6 tasks shown
>>> todo.sh -p listpri x "should be"
--
TODO: 0 of 6 tasks shown
EOF
test_done

42
tests/t1260-listprj.sh Executable file
View File

@@ -0,0 +1,42 @@
#!/bin/sh
test_description='list project functionality
'
. ./test-lib.sh
cat > todo.txt <<EOF
(B) smell the uppercase Roses +roses @outside +shared
(C) notice the sunflowers +sunflowers @garden +shared +landscape
stop
EOF
test_todo_session 'basic listproj' <<EOF
>>> todo.sh listproj
+landscape
+roses
+shared
+sunflowers
EOF
test_todo_session 'listproj with context' <<EOF
>>> todo.sh listproj @garden
+landscape
+shared
+sunflowers
EOF
TEST_TODO_CUSTOM=todo-custom.cfg
cat todo.cfg > "$TEST_TODO_CUSTOM"
cat >> "$TEST_TODO_CUSTOM" <<'EOF'
export DEFAULT='</color>'
export PRI_B='<color type=green>'
export PRI_C='<color type=blue>'
export TODOTXT_FINAL_FILTER='grep -i roses'
EOF
test_todo_session 'listproj with context special cases' <<EOF
>>> todo.sh -+ -d "$TEST_TODO_CUSTOM" listproj @garden
+landscape
+shared
+sunflowers
EOF
test_done

721
tests/t1300-ls.sh Executable file
View File

@@ -0,0 +1,721 @@
#!/bin/sh
#
test_description='list functionality
This test checks various list functionality including
sorting, output filtering and line numbering.
'
. ./test-lib.sh
TEST_TODO_=todo.cfg
cat > todo.txt <<EOF
ccc xxx this line should be third.
aaa zzz this line should be first.
bbb yyy this line should be second.
EOF
#
# check the sort filter
#
TEST_TODO1_=todo1.cfg
sed -e "s/^.*export TODOTXT_SORT_COMMAND=.*$/export TODOTXT_SORT_COMMAND='env LC_COLLATE=C sort -r -f -k2'/" "${TEST_TODO_}" > "${TEST_TODO1_}"
test_todo_session 'checking TODOTXT_SORT_COMMAND' <<EOF
>>> todo.sh ls
2 aaa zzz this line should be first.
3 bbb yyy this line should be second.
1 ccc xxx this line should be third.
--
TODO: 3 of 3 tasks shown
>>> todo.sh -d "$TEST_TODO1_" ls
1 ccc xxx this line should be third.
3 bbb yyy this line should be second.
2 aaa zzz this line should be first.
--
TODO: 3 of 3 tasks shown
EOF
#
# check the final filter
#
TEST_TODO2_=todo2.cfg
sed -e "s%^.*export TODOTXT_FINAL_FILTER=.*$%export TODOTXT_FINAL_FILTER=\"sed 's/^\\\(..\\\{20\\\}\\\).....*$/\\\1.../'\"%" "${TEST_TODO_}" > "${TEST_TODO2_}"
test_todo_session 'checking TODOTXT_FINAL_FILTER' <<EOF
>>> todo.sh -d "$TEST_TODO2_" ls
2 aaa zzz this line s...
3 bbb yyy this line s...
1 ccc xxx this line s...
--
TODO: 3 of 3 tasks shown
EOF
#
# check the filtering of TERM
#
test_todo_session 'checking filtering of TERM' <<EOF
>>> todo.sh ls second
3 bbb yyy this line should be second.
--
TODO: 1 of 3 tasks shown
>>> todo.sh ls "should be f"
2 aaa zzz this line should be first.
--
TODO: 1 of 3 tasks shown
>>> todo.sh ls " zzz"
2 aaa zzz this line should be first.
--
TODO: 1 of 3 tasks shown
EOF
#
# check negative filtering via -TERM
#
test_todo_session 'checking negative filtering via -TERM' <<EOF
>>> todo.sh ls -second
2 aaa zzz this line should be first.
1 ccc xxx this line should be third.
--
TODO: 2 of 3 tasks shown
>>> todo.sh ls "-should be f"
3 bbb yyy this line should be second.
1 ccc xxx this line should be third.
--
TODO: 2 of 3 tasks shown
>>> todo.sh ls "- zzz"
3 bbb yyy this line should be second.
1 ccc xxx this line should be third.
--
TODO: 2 of 3 tasks shown
EOF
#
# check the filtering of TERM with regexp
#
test_todo_session 'checking filtering of TERM with regexp' <<EOF
>>> todo.sh ls "ir[ds]"
2 aaa zzz this line should be first.
1 ccc xxx this line should be third.
--
TODO: 2 of 3 tasks shown
>>> todo.sh ls "f.*t"
2 aaa zzz this line should be first.
--
TODO: 1 of 3 tasks shown
>>> todo.sh ls "ir[ds]" xxx
1 ccc xxx this line should be third.
--
TODO: 1 of 3 tasks shown
EOF
#
# check the filtering of TERM containing characters that are special to the
# shell, like variables, quotes, and multiple subsequent spaces.
#
cat > todo.txt <<'EOF'
earn some pennies
earn some $$
earn some "money"
get money from O'Brian
just get money!
EOF
test_todo_session 'checking filtering of special characters' <<'EOF'
>>> todo.sh ls '$$'
2 earn some $$
--
TODO: 1 of 5 tasks shown
>>> todo.sh ls '"money"'
3 earn some "money"
--
TODO: 1 of 5 tasks shown
>>> todo.sh ls "O'Brian"
4 get money from O'Brian
--
TODO: 1 of 5 tasks shown
>>> todo.sh ls "get money"
5 just get money!
--
TODO: 1 of 5 tasks shown
EOF
#
# check the x command line option
#
TEST_TODO3_=todo3.cfg
sed -e "s%^.*export TODOTXT_FINAL_FILTER=.*$%export TODOTXT_FINAL_FILTER=\"grep -v xxx\"%" "${TEST_TODO_}" > "${TEST_TODO3_}"
cat > todo.txt <<EOF
foo
bar xxx
baz
EOF
test_todo_session 'final filter suppression' <<EOF
>>> todo.sh -d "$TEST_TODO3_" ls
3 baz
1 foo
--
TODO: 2 of 3 tasks shown
>>> todo.sh -d "$TEST_TODO3_" -x ls
2 bar xxx
3 baz
1 foo
--
TODO: 3 of 3 tasks shown
EOF
#
# check the p command line option
#
cat > todo.txt <<EOF
(A) @con01 +prj01 -- Some project 01 task, pri A
(A) @con01 +prj02 -- Some project 02 task, pri A
(A) @con02 +prj03 -- Some project 03 task, pri A
(A) @con02 +prj04 -- Some project 04 task, pri A
(B) @con01 +prj01 -- Some project 01 task, pri B
(B) @con01 +prj02 -- Some project 02 task, pri B
(B) @con02 +prj03 -- Some project 03 task, pri B
(B) @con02 +prj04 -- Some project 04 task, pri B
(C) @con01 +prj01 -- Some project 01 task, pri C
(C) @con01 +prj02 -- Some project 02 task, pri C
(C) @con02 +prj03 -- Some project 03 task, pri C
(C) @con02 +prj04 -- Some project 04 task, pri C
(D) @con01 +prj01 -- Some project 01 task, pri D
(D) @con01 +prj02 -- Some project 02 task, pri D
(D) @con02 +prj03 -- Some project 03 task, pri D
(D) @con02 +prj04 -- Some project 04 task, pri D
@con01 +prj01 -- Some project 01 task, no priority
@con01 +prj02 -- Some project(S) 02 task, no priority
@con02 +prj03 -- Some project 03 task, no priorty
@con02 +prj04 -- Some project 04 task, no priority
EOF
test_todo_session 'plain mode option' <<EOF
>>> todo.sh ls
01 (A) @con01 +prj01 -- Some project 01 task, pri A
02 (A) @con01 +prj02 -- Some project 02 task, pri A
03 (A) @con02 +prj03 -- Some project 03 task, pri A
04 (A) @con02 +prj04 -- Some project 04 task, pri A
05 (B) @con01 +prj01 -- Some project 01 task, pri B
06 (B) @con01 +prj02 -- Some project 02 task, pri B
07 (B) @con02 +prj03 -- Some project 03 task, pri B
08 (B) @con02 +prj04 -- Some project 04 task, pri B
09 (C) @con01 +prj01 -- Some project 01 task, pri C
10 (C) @con01 +prj02 -- Some project 02 task, pri C
11 (C) @con02 +prj03 -- Some project 03 task, pri C
12 (C) @con02 +prj04 -- Some project 04 task, pri C
13 (D) @con01 +prj01 -- Some project 01 task, pri D
14 (D) @con01 +prj02 -- Some project 02 task, pri D
15 (D) @con02 +prj03 -- Some project 03 task, pri D
16 (D) @con02 +prj04 -- Some project 04 task, pri D
17 @con01 +prj01 -- Some project 01 task, no priority
18 @con01 +prj02 -- Some project(S) 02 task, no priority
19 @con02 +prj03 -- Some project 03 task, no priorty
20 @con02 +prj04 -- Some project 04 task, no priority
--
TODO: 20 of 20 tasks shown
>>> todo.sh -p ls
01 (A) @con01 +prj01 -- Some project 01 task, pri A
02 (A) @con01 +prj02 -- Some project 02 task, pri A
03 (A) @con02 +prj03 -- Some project 03 task, pri A
04 (A) @con02 +prj04 -- Some project 04 task, pri A
05 (B) @con01 +prj01 -- Some project 01 task, pri B
06 (B) @con01 +prj02 -- Some project 02 task, pri B
07 (B) @con02 +prj03 -- Some project 03 task, pri B
08 (B) @con02 +prj04 -- Some project 04 task, pri B
09 (C) @con01 +prj01 -- Some project 01 task, pri C
10 (C) @con01 +prj02 -- Some project 02 task, pri C
11 (C) @con02 +prj03 -- Some project 03 task, pri C
12 (C) @con02 +prj04 -- Some project 04 task, pri C
13 (D) @con01 +prj01 -- Some project 01 task, pri D
14 (D) @con01 +prj02 -- Some project 02 task, pri D
15 (D) @con02 +prj03 -- Some project 03 task, pri D
16 (D) @con02 +prj04 -- Some project 04 task, pri D
17 @con01 +prj01 -- Some project 01 task, no priority
18 @con01 +prj02 -- Some project(S) 02 task, no priority
19 @con02 +prj03 -- Some project 03 task, no priorty
20 @con02 +prj04 -- Some project 04 task, no priority
--
TODO: 20 of 20 tasks shown
EOF
#
# check the P,@,+ command line options
#
cat > todo.txt <<EOF
(A) @con01 +prj01 -- Some project 01 task, pri A
(A) @con01 +prj02 -- Some project 02 task, pri A
(A) @con02 +prj03 -- Some project 03 task, pri A
(A) @con02 +prj04 -- Some project 04 task, pri A
(B) @con01 +prj01 -- Some project 01 task, pri B
(B) @con01 +prj02 -- Some project 02 task, pri B
(B) @con02 +prj03 -- Some project 03 task, pri B
(B) @con02 +prj04 -- Some project 04 task, pri B
(C) @con01 +prj01 -- Some project 01 task, pri C
(C) @con01 +prj02 -- Some project 02 task, pri C
(C) @con02 +prj03 -- Some project 03 task, pri C
(C) @con02 +prj04 -- Some project 04 task, pri C
(D) @con01 +prj01 -- Some project 01 task, pri D
(D) @con01 +prj02 -- Some project 02 task, pri D
(D) @con02 +prj03 -- Some project 03 task, pri D
(D) @con02 +prj04 -- Some project 04 task, pri D
@con01 +prj01 -- Some project 01 task, no priority
@con01 +prj02 -- Some project(S) 02 task, no priority
@con02 +prj03 -- Some project 03 task, no priorty
@con02 +prj04 -- Some project 04 task, no priority
EOF
test_todo_session 'context, project, and priority suppression' <<EOF
>>> todo.sh ls
01 (A) @con01 +prj01 -- Some project 01 task, pri A
02 (A) @con01 +prj02 -- Some project 02 task, pri A
03 (A) @con02 +prj03 -- Some project 03 task, pri A
04 (A) @con02 +prj04 -- Some project 04 task, pri A
05 (B) @con01 +prj01 -- Some project 01 task, pri B
06 (B) @con01 +prj02 -- Some project 02 task, pri B
07 (B) @con02 +prj03 -- Some project 03 task, pri B
08 (B) @con02 +prj04 -- Some project 04 task, pri B
09 (C) @con01 +prj01 -- Some project 01 task, pri C
10 (C) @con01 +prj02 -- Some project 02 task, pri C
11 (C) @con02 +prj03 -- Some project 03 task, pri C
12 (C) @con02 +prj04 -- Some project 04 task, pri C
13 (D) @con01 +prj01 -- Some project 01 task, pri D
14 (D) @con01 +prj02 -- Some project 02 task, pri D
15 (D) @con02 +prj03 -- Some project 03 task, pri D
16 (D) @con02 +prj04 -- Some project 04 task, pri D
17 @con01 +prj01 -- Some project 01 task, no priority
18 @con01 +prj02 -- Some project(S) 02 task, no priority
19 @con02 +prj03 -- Some project 03 task, no priorty
20 @con02 +prj04 -- Some project 04 task, no priority
--
TODO: 20 of 20 tasks shown
>>> todo.sh ls @con01
01 (A) @con01 +prj01 -- Some project 01 task, pri A
02 (A) @con01 +prj02 -- Some project 02 task, pri A
05 (B) @con01 +prj01 -- Some project 01 task, pri B
06 (B) @con01 +prj02 -- Some project 02 task, pri B
09 (C) @con01 +prj01 -- Some project 01 task, pri C
10 (C) @con01 +prj02 -- Some project 02 task, pri C
13 (D) @con01 +prj01 -- Some project 01 task, pri D
14 (D) @con01 +prj02 -- Some project 02 task, pri D
17 @con01 +prj01 -- Some project 01 task, no priority
18 @con01 +prj02 -- Some project(S) 02 task, no priority
--
TODO: 10 of 20 tasks shown
>>> todo.sh -P ls @con01
01 @con01 +prj01 -- Some project 01 task, pri A
02 @con01 +prj02 -- Some project 02 task, pri A
05 @con01 +prj01 -- Some project 01 task, pri B
06 @con01 +prj02 -- Some project 02 task, pri B
09 @con01 +prj01 -- Some project 01 task, pri C
10 @con01 +prj02 -- Some project 02 task, pri C
13 @con01 +prj01 -- Some project 01 task, pri D
14 @con01 +prj02 -- Some project 02 task, pri D
17 @con01 +prj01 -- Some project 01 task, no priority
18 @con01 +prj02 -- Some project(S) 02 task, no priority
--
TODO: 10 of 20 tasks shown
>>> todo.sh -+ ls @con01
01 (A) @con01 -- Some project 01 task, pri A
02 (A) @con01 -- Some project 02 task, pri A
05 (B) @con01 -- Some project 01 task, pri B
06 (B) @con01 -- Some project 02 task, pri B
09 (C) @con01 -- Some project 01 task, pri C
10 (C) @con01 -- Some project 02 task, pri C
13 (D) @con01 -- Some project 01 task, pri D
14 (D) @con01 -- Some project 02 task, pri D
17 @con01 -- Some project 01 task, no priority
18 @con01 -- Some project(S) 02 task, no priority
--
TODO: 10 of 20 tasks shown
>>> todo.sh -@ ls @con01
01 (A) +prj01 -- Some project 01 task, pri A
02 (A) +prj02 -- Some project 02 task, pri A
05 (B) +prj01 -- Some project 01 task, pri B
06 (B) +prj02 -- Some project 02 task, pri B
09 (C) +prj01 -- Some project 01 task, pri C
10 (C) +prj02 -- Some project 02 task, pri C
13 (D) +prj01 -- Some project 01 task, pri D
14 (D) +prj02 -- Some project 02 task, pri D
17 +prj01 -- Some project 01 task, no priority
18 +prj02 -- Some project(S) 02 task, no priority
--
TODO: 10 of 20 tasks shown
>>> todo.sh -P -@ ls @con01
01 +prj01 -- Some project 01 task, pri A
02 +prj02 -- Some project 02 task, pri A
05 +prj01 -- Some project 01 task, pri B
06 +prj02 -- Some project 02 task, pri B
09 +prj01 -- Some project 01 task, pri C
10 +prj02 -- Some project 02 task, pri C
13 +prj01 -- Some project 01 task, pri D
14 +prj02 -- Some project 02 task, pri D
17 +prj01 -- Some project 01 task, no priority
18 +prj02 -- Some project(S) 02 task, no priority
--
TODO: 10 of 20 tasks shown
>>> todo.sh -P -@ -+ -P -@ -+ ls @con01
01 (A) @con01 +prj01 -- Some project 01 task, pri A
02 (A) @con01 +prj02 -- Some project 02 task, pri A
05 (B) @con01 +prj01 -- Some project 01 task, pri B
06 (B) @con01 +prj02 -- Some project 02 task, pri B
09 (C) @con01 +prj01 -- Some project 01 task, pri C
10 (C) @con01 +prj02 -- Some project 02 task, pri C
13 (D) @con01 +prj01 -- Some project 01 task, pri D
14 (D) @con01 +prj02 -- Some project 02 task, pri D
17 @con01 +prj01 -- Some project 01 task, no priority
18 @con01 +prj02 -- Some project(S) 02 task, no priority
--
TODO: 10 of 20 tasks shown
>>> todo.sh -P -@ -+ -P -@ -+ -P -@ -+ ls @con01
01 -- Some project 01 task, pri A
02 -- Some project 02 task, pri A
05 -- Some project 01 task, pri B
06 -- Some project 02 task, pri B
09 -- Some project 01 task, pri C
10 -- Some project 02 task, pri C
13 -- Some project 01 task, pri D
14 -- Some project 02 task, pri D
17 -- Some project 01 task, no priority
18 -- Some project(S) 02 task, no priority
--
TODO: 10 of 20 tasks shown
EOF
#
# check the line number padding
#
cat > todo.txt <<EOF
hex00 this is one line
hex01 this is another line
hex02 this is another line
hex03 this is another line
hex04 this is another line
hex05 this is another line
hex06 this is another line
hex07 this is another line
hex08 this is another line
hex09 this is another line
hex0A this is another line
hex0B this is another line
hex0C this is another line
hex0D this is another line
hex0E this is another line
hex0F this is another line
hex10 this is line is a multiple of 16
hex11 this is another line
hex12 this is another line
hex13 this is another line
hex14 this is another line
hex15 this is another line
hex16 this is another line
hex17 this is another line
hex18 this is another line
hex19 this is another line
hex1A this is another line
hex1B this is another line
hex1C this is another line
hex1D this is another line
hex1E this is another line
hex1F this is another line
hex20 this is line is a multiple of 16
hex21 this is another line
hex22 this is another line
hex23 this is another line
hex24 this is another line
hex25 this is another line
hex26 this is another line
hex27 this is another line
hex28 this is another line
hex29 this is another line
hex2A this is another line
hex2B this is another line
hex2C this is another line
hex2D this is another line
hex2E this is another line
hex2F this is another line
hex30 this is line is a multiple of 16
hex31 this is another line
hex32 this is another line
hex33 this is another line
hex34 this is another line
hex35 this is another line
hex36 this is another line
hex37 this is another line
hex38 this is another line
hex39 this is another line
hex3A this is another line
hex3B this is another line
hex3C this is another line
hex3D this is another line
hex3E this is another line
hex3F this is another line
hex40 this is line is a multiple of 16
hex41 this is another line
hex42 this is another line
hex43 this is another line
hex44 this is another line
hex45 this is another line
hex46 this is another line
hex47 this is another line
hex48 this is another line
hex49 this is another line
hex4A this is another line
hex4B this is another line
hex4C this is another line
hex4D this is another line
hex4E this is another line
hex4F this is another line
hex50 this is line is a multiple of 16
hex51 this is another line
hex52 this is another line
hex53 this is another line
hex54 this is another line
hex55 this is another line
hex56 this is another line
hex57 this is another line
hex58 this is another line
hex59 this is another line
hex5A this is another line
hex5B this is another line
hex5C this is another line
hex5D this is another line
hex5E this is another line
hex5F this is another line
hex60 this is line is a multiple of 16
hex61 this is another line
hex62 this is another line
hex63 this is another line
hex64 this is another line
hex65 this is another line
hex66 this is another line
hex67 this is another line
hex68 this is another line
hex69 this is another line
hex6A this is another line
hex6B this is another line
hex6C this is another line
hex6D this is another line
hex6E this is another line
hex6F this is another line
EOF
test_todo_session 'check line number padding, out to 3 digits' <<EOF
>>> todo.sh ls
001 hex00 this is one line
002 hex01 this is another line
003 hex02 this is another line
004 hex03 this is another line
005 hex04 this is another line
006 hex05 this is another line
007 hex06 this is another line
008 hex07 this is another line
009 hex08 this is another line
010 hex09 this is another line
011 hex0A this is another line
012 hex0B this is another line
013 hex0C this is another line
014 hex0D this is another line
015 hex0E this is another line
016 hex0F this is another line
017 hex10 this is line is a multiple of 16
018 hex11 this is another line
019 hex12 this is another line
020 hex13 this is another line
021 hex14 this is another line
022 hex15 this is another line
023 hex16 this is another line
024 hex17 this is another line
025 hex18 this is another line
026 hex19 this is another line
027 hex1A this is another line
028 hex1B this is another line
029 hex1C this is another line
030 hex1D this is another line
031 hex1E this is another line
032 hex1F this is another line
033 hex20 this is line is a multiple of 16
034 hex21 this is another line
035 hex22 this is another line
036 hex23 this is another line
037 hex24 this is another line
038 hex25 this is another line
039 hex26 this is another line
040 hex27 this is another line
041 hex28 this is another line
042 hex29 this is another line
043 hex2A this is another line
044 hex2B this is another line
045 hex2C this is another line
046 hex2D this is another line
047 hex2E this is another line
048 hex2F this is another line
049 hex30 this is line is a multiple of 16
050 hex31 this is another line
051 hex32 this is another line
052 hex33 this is another line
053 hex34 this is another line
054 hex35 this is another line
055 hex36 this is another line
056 hex37 this is another line
057 hex38 this is another line
058 hex39 this is another line
059 hex3A this is another line
060 hex3B this is another line
061 hex3C this is another line
062 hex3D this is another line
063 hex3E this is another line
064 hex3F this is another line
065 hex40 this is line is a multiple of 16
066 hex41 this is another line
067 hex42 this is another line
068 hex43 this is another line
069 hex44 this is another line
070 hex45 this is another line
071 hex46 this is another line
072 hex47 this is another line
073 hex48 this is another line
074 hex49 this is another line
075 hex4A this is another line
076 hex4B this is another line
077 hex4C this is another line
078 hex4D this is another line
079 hex4E this is another line
080 hex4F this is another line
081 hex50 this is line is a multiple of 16
082 hex51 this is another line
083 hex52 this is another line
084 hex53 this is another line
085 hex54 this is another line
086 hex55 this is another line
087 hex56 this is another line
088 hex57 this is another line
089 hex58 this is another line
090 hex59 this is another line
091 hex5A this is another line
092 hex5B this is another line
093 hex5C this is another line
094 hex5D this is another line
095 hex5E this is another line
096 hex5F this is another line
097 hex60 this is line is a multiple of 16
098 hex61 this is another line
099 hex62 this is another line
100 hex63 this is another line
101 hex64 this is another line
102 hex65 this is another line
103 hex66 this is another line
104 hex67 this is another line
105 hex68 this is another line
106 hex69 this is another line
107 hex6A this is another line
108 hex6B this is another line
109 hex6C this is another line
110 hex6D this is another line
111 hex6E this is another line
112 hex6F this is another line
--
TODO: 112 of 112 tasks shown
EOF
#
# check that blank lines are ignored.
#
# Less than 10
cat > todo.txt <<EOF
hex00 this is one line
hex02 this is another line
hex03 this is another line
hex04 this is another line
hex05 this is another line
hex06 this is another line
hex07 this is another line
EOF
test_todo_session 'check that blank lines are ignored for less than 10 items' <<EOF
>>> todo.sh ls
1 hex00 this is one line
3 hex02 this is another line
4 hex03 this is another line
5 hex04 this is another line
6 hex05 this is another line
7 hex06 this is another line
8 hex07 this is another line
--
TODO: 7 of 7 tasks shown
EOF
# More than 10
cat > todo.txt <<EOF
hex00 this is one line
hex02 this is another line
hex03 this is another line
hex04 this is another line
hex05 this is another line
hex06 this is another line
hex07 this is another line
hex08 this is another line
hex09 this is another line
EOF
test_todo_session 'check that blank lines are ignored for blank lines whose ID begins with `0` (one blank)' <<EOF
>>> todo.sh ls
01 hex00 this is one line
03 hex02 this is another line
04 hex03 this is another line
05 hex04 this is another line
06 hex05 this is another line
07 hex06 this is another line
08 hex07 this is another line
09 hex08 this is another line
10 hex09 this is another line
--
TODO: 9 of 9 tasks shown
EOF
cat > todo.txt <<EOF
hex00 this is one line
hex02 this is another line
hex03 this is another line
hex04 this is another line
hex05 this is another line
hex07 this is another line
hex08 this is another line
hex09 this is another line
EOF
test_todo_session 'check that blank lines are ignored for blank lines whose ID begins with `0` (many blanks)' <<EOF
>>> todo.sh ls
01 hex00 this is one line
03 hex02 this is another line
04 hex03 this is another line
05 hex04 this is another line
06 hex05 this is another line
08 hex07 this is another line
09 hex08 this is another line
10 hex09 this is another line
--
TODO: 8 of 8 tasks shown
EOF
test_done

58
tests/t1310-listcon.sh Executable file
View File

@@ -0,0 +1,58 @@
#!/bin/sh
#
test_description='listcon functionality
This test checks basic context listing functionality
'
. ./test-lib.sh
cat > todo.txt <<EOF
item 1
item 2
item 3
EOF
test_expect_success 'listcon no contexts' '
todo.sh listcon > output && ! test -s output
'
cat > todo.txt <<EOF
(A) @1 -- Some context 1 task, whitespace, one char
(A) @c2 -- Some context 2 task, whitespace, two char
@con03 -- Some context 3 task, no whitespace
@con04 -- Some context 4 task, no whitespace
@con05@con06 -- weird context
EOF
test_todo_session 'Single context per line' <<EOF
>>> todo.sh listcon
@1
@c2
@con03
@con04
@con05@con06
EOF
cat > todo.txt <<EOF
@con01 -- Some context 1 task
@con02 -- Some context 2 task
@con02 @con03 -- Multi-context task
EOF
test_todo_session 'Multi-context per line' <<EOF
>>> todo.sh listcon
@con01
@con02
@con03
EOF
cat > todo.txt <<EOF
@con01 -- Some context 1 task
@con02 -- Some context 2 task
@con02 ginatrapani@gmail.com -- Some context 2 task
EOF
test_todo_session 'listcon e-mail address test' <<EOF
>>> todo.sh listcon
@con01
@con02
EOF
test_done

58
tests/t1320-listproj.sh Executable file
View File

@@ -0,0 +1,58 @@
#!/bin/sh
#
test_description='listproj functionality
This test checks basic project listing functionality
'
. ./test-lib.sh
cat > todo.txt <<EOF
item 1
item 2
item 3
EOF
test_expect_success 'listproj no projects' '
todo.sh listproj > output && ! test -s output
'
cat > todo.txt <<EOF
(A) +1 -- Some project 1 task, whitespace, one char
(A) +p2 -- Some project 2 task, whitespace, two char
+prj03 -- Some project 3 task, no whitespace
+prj04 -- Some project 4 task, no whitespace
+prj05+prj06 -- weird project
EOF
test_todo_session 'Single project per line' <<EOF
>>> todo.sh listproj
+1
+p2
+prj03
+prj04
+prj05+prj06
EOF
cat > todo.txt <<EOF
+prj01 -- Some project 1 task
+prj02 -- Some project 2 task
+prj02 +prj03 -- Multi-project task
EOF
test_todo_session 'Multi-project per line' <<EOF
>>> todo.sh listproj
+prj01
+prj02
+prj03
EOF
cat > todo.txt <<EOF
+prj01 -- Some project 1 task
+prj02 -- Some project 2 task
+prj02 ginatrapani+todo@gmail.com -- Some project 2 task
EOF
test_todo_session 'listproj embedded + test' <<EOF
>>> todo.sh listproj
+prj01
+prj02
EOF
test_done

185
tests/t1330-ls-highlighting.sh Executable file
View File

@@ -0,0 +1,185 @@
#!/bin/sh
#
test_description='list highlighting
This test checks the highlighting (with colors) of prioritized tasks.
'
. ./test-lib.sh
TEST_TODO_=todo.cfg
#
# check the highlighting of prioritized tasks
#
cat > todo.txt <<EOF
(A) @con01 +prj01 -- Some project 01 task, pri A
(B) @con02 +prj02 -- Some project 02 task, pri B
(C) @con01 +prj01 -- Some project 01 task, pri C
(D) @con02 +prj02 -- Some project 02 task, pri D
(E) @con01 +prj01 -- Some project 01 task, pri E
(Z) @con02 +prj02 -- Some project 02 task, pri Z
@con01 +prj01 -- Some project 01 task, no priority
@con02 +prj02 -- Some project 02 task, no priority
EOF
test_todo_session 'default highlighting' <<EOF
>>> todo.sh ls
1 (A) @con01 +prj01 -- Some project 01 task, pri A
2 (B) @con02 +prj02 -- Some project 02 task, pri B
3 (C) @con01 +prj01 -- Some project 01 task, pri C
4 (D) @con02 +prj02 -- Some project 02 task, pri D
5 (E) @con01 +prj01 -- Some project 01 task, pri E
6 (Z) @con02 +prj02 -- Some project 02 task, pri Z
7 @con01 +prj01 -- Some project 01 task, no priority
8 @con02 +prj02 -- Some project 02 task, no priority
--
TODO: 8 of 8 tasks shown
EOF
#
# check changing the color definitions into something other than ANSI color
# escape sequences
#
TEST_TODO_CUSTOM=todo-custom.cfg
cat todo.cfg > "$TEST_TODO_CUSTOM"
cat >> "$TEST_TODO_CUSTOM" <<'EOF'
export YELLOW='${color yellow}'
export GREEN='${color green}'
export LIGHT_BLUE='${color LightBlue}'
export WHITE='${color white}'
export DEFAULT='${color}'
export PRI_A=$YELLOW
export PRI_B=$GREEN
export PRI_C=$LIGHT_BLUE
export PRI_X=$WHITE
EOF
test_todo_session 'customized highlighting' <<'EOF'
>>> todo.sh -d "$TEST_TODO_CUSTOM" ls
${color yellow}1 (A) @con01 +prj01 -- Some project 01 task, pri A${color}
${color green}2 (B) @con02 +prj02 -- Some project 02 task, pri B${color}
${color LightBlue}3 (C) @con01 +prj01 -- Some project 01 task, pri C${color}
${color white}4 (D) @con02 +prj02 -- Some project 02 task, pri D${color}
${color white}5 (E) @con01 +prj01 -- Some project 01 task, pri E${color}
${color white}6 (Z) @con02 +prj02 -- Some project 02 task, pri Z${color}
7 @con01 +prj01 -- Some project 01 task, no priority
8 @con02 +prj02 -- Some project 02 task, no priority
--
TODO: 8 of 8 tasks shown
EOF
#
# check defining highlightings for more priorities than the default A, B, C
#
TEST_TODO_ADDITIONAL=todo-additional.cfg
cat todo.cfg > "$TEST_TODO_ADDITIONAL"
cat >> "$TEST_TODO_ADDITIONAL" <<'EOF'
export PRI_E=$BROWN
export PRI_Z=$LIGHT_PURPLE
EOF
test_todo_session 'additional highlighting pri E+Z' <<'EOF'
>>> todo.sh -d "$TEST_TODO_ADDITIONAL" ls
1 (A) @con01 +prj01 -- Some project 01 task, pri A
2 (B) @con02 +prj02 -- Some project 02 task, pri B
3 (C) @con01 +prj01 -- Some project 01 task, pri C
4 (D) @con02 +prj02 -- Some project 02 task, pri D
5 (E) @con01 +prj01 -- Some project 01 task, pri E
6 (Z) @con02 +prj02 -- Some project 02 task, pri Z
7 @con01 +prj01 -- Some project 01 task, no priority
8 @con02 +prj02 -- Some project 02 task, no priority
--
TODO: 8 of 8 tasks shown
EOF
# check changing the fallback highlighting for undefined priorities
#
TEST_TODO_PRI_X=todo-pri-x.cfg
cat todo.cfg > "$TEST_TODO_PRI_X"
cat >> "$TEST_TODO_PRI_X" <<'EOF'
export PRI_X=$BROWN
EOF
test_todo_session 'different highlighting for pri X' <<'EOF'
>>> todo.sh -d "$TEST_TODO_PRI_X" ls
1 (A) @con01 +prj01 -- Some project 01 task, pri A
2 (B) @con02 +prj02 -- Some project 02 task, pri B
3 (C) @con01 +prj01 -- Some project 01 task, pri C
4 (D) @con02 +prj02 -- Some project 02 task, pri D
5 (E) @con01 +prj01 -- Some project 01 task, pri E
6 (Z) @con02 +prj02 -- Some project 02 task, pri Z
7 @con01 +prj01 -- Some project 01 task, no priority
8 @con02 +prj02 -- Some project 02 task, no priority
--
TODO: 8 of 8 tasks shown
EOF
# check highlighting of done (but not yet archived) tasks
#
cat > todo.txt <<EOF
(A) smell the uppercase Roses +flowers @outside
remove1
notice the sunflowers
remove2
stop
EOF
test_todo_session 'highlighting of done tasks' <<EOF
>>> todo.sh -a do 2
2 x 2009-02-13 remove1
TODO: 2 marked as done.
>>> todo.sh list
1 (A) smell the uppercase Roses +flowers @outside
3 notice the sunflowers
4 remove2
5 stop
2 x 2009-02-13 remove1
--
TODO: 5 of 5 tasks shown
>>> todo.sh -a do 4
4 x 2009-02-13 remove2
TODO: 4 marked as done.
>>> todo.sh list
1 (A) smell the uppercase Roses +flowers @outside
3 notice the sunflowers
5 stop
2 x 2009-02-13 remove1
4 x 2009-02-13 remove2
--
TODO: 5 of 5 tasks shown
EOF
# check highlighting with hidden contexts/projects
#
cat > todo.txt <<EOF
(A) +project at the beginning, with priority
(B) with priority, ending in a +project
(C) @context at the beginning, with priority
(Z) with priority, ending in a @context
EOF
test_todo_session 'highlighting with hidden contexts/projects' <<EOF
>>> todo.sh -+ -@ list
1 (A) at the beginning, with priority
2 (B) with priority, ending in a
3 (C) at the beginning, with priority
4 (Z) with priority, ending in a
--
TODO: 4 of 4 tasks shown
EOF
# check that priorities are only matched at the start of the task
#
cat > todo.txt <<EOF
(D) some prioritized task
not prioritized
should not be seen as PRIORITIZE(D) task
EOF
test_todo_session 'highlighting priority position' <<EOF
>>> todo.sh ls
1 (D) some prioritized task
2 not prioritized
3 should not be seen as PRIORITIZE(D) task
--
TODO: 3 of 3 tasks shown
EOF
test_done

65
tests/t1340-listescapes.sh Executable file
View File

@@ -0,0 +1,65 @@
#!/bin/bash
#
test_description='list with escape sequences
This test checks listing of tasks that have embedded escape sequences in them.
'
. ./test-lib.sh
#
# check aborted list output on \c escape sequence
#
cat > todo.txt <<'EOF'
first todo
second todo run C:\WINDOWS\sysnative\cscript.exe
third todo
EOF
test_todo_session 'aborted list output on backslash-c' <<'EOF'
>>> todo.sh ls
1 first todo
2 second todo run C:\WINDOWS\sysnative\cscript.exe
3 third todo
--
TODO: 3 of 3 tasks shown
>>> todo.sh ls 2
2 second todo run C:\WINDOWS\sysnative\cscript.exe
--
TODO: 1 of 3 tasks shown
EOF
#
# check various escape sequences
#
cat > todo.txt <<'EOF'
first todo with \\, \a and \t
second todo with \r\n line break
third todo with \x42\x55\x47 and \033[0;31m color codes \033[0;30m
EOF
test_todo_session 'various escape sequences' <<'EOF'
>>> todo.sh ls
1 first todo with \\, \a and \t
2 second todo with \r\n line break
3 third todo with \x42\x55\x47 and \033[0;31m color codes \033[0;30m
--
TODO: 3 of 3 tasks shown
EOF
#
# check embedding of actual color sequence
#
cat > todo.txt <<'EOF'
A task with  actual color 
EOF
test_todo_session 'embedding of actual color sequence' <<'EOF'
>>> todo.sh ls
1 A task with  actual color 
--
TODO: 1 of 1 tasks shown
EOF
test_done

122
tests/t1400-prepend.sh Executable file
View File

@@ -0,0 +1,122 @@
#!/bin/sh
test_description='basic prepend functionality
'
. ./test-lib.sh
test_todo_session 'prepend usage' <<EOF
>>> todo.sh prepend B B
usage: todo.sh prepend ITEM# "TEXT TO PREPEND"
=== 1
EOF
cat > todo.txt <<EOF
(B) smell the uppercase Roses +flowers @outside
notice the sunflowers
stop
EOF
test_todo_session 'basic prepend' <<EOF
>>> todo.sh list
1 (B) smell the uppercase Roses +flowers @outside
2 notice the sunflowers
3 stop
--
TODO: 3 of 3 tasks shown
>>> todo.sh -p list
1 (B) smell the uppercase Roses +flowers @outside
2 notice the sunflowers
3 stop
--
TODO: 3 of 3 tasks shown
>>> todo.sh prepend 2 test
2 test notice the sunflowers
>>> todo.sh -p list
1 (B) smell the uppercase Roses +flowers @outside
3 stop
2 test notice the sunflowers
--
TODO: 3 of 3 tasks shown
>>> todo.sh prepend 1 test
1 (B) test smell the uppercase Roses +flowers @outside
>>> todo.sh -p list
1 (B) test smell the uppercase Roses +flowers @outside
3 stop
2 test notice the sunflowers
--
TODO: 3 of 3 tasks shown
EOF
test_todo_session 'prepend with &' <<EOF
>>> todo.sh prepend 3 "no running & jumping now"
3 no running & jumping now stop
EOF
echo 'jump on hay' > todo.txt
test_todo_session 'prepend with spaces' <<EOF
>>> todo.sh prepend 1 "notice the three spaces and"
1 notice the three spaces and jump on hay
EOF
cat > todo.txt <<EOF
smell the cows
grow some corn
thrash some hay
chase the chickens
EOF
test_todo_session 'prepend with symbols' <<EOF
>>> todo.sh prepend 1 "~@#$%^&*()-_=+[{]}|;:',<.>/?"
1 ~@#$%^&*()-_=+[{]}|;:',<.>/? smell the cows
>>> todo.sh prepend 2 '\`!\\"'
2 \`!\\" grow some corn
>>> todo.sh list
4 chase the chickens
3 thrash some hay
2 \`!\\" grow some corn
1 ~@#$%^&*()-_=+[{]}|;:',<.>/? smell the cows
--
TODO: 4 of 4 tasks shown
EOF
cat /dev/null > todo.txt
test_todo_session 'prepend handling prepended date on add' <<EOF
>>> todo.sh -t add "new task"
1 2009-02-13 new task
TODO: 1 added.
>>> todo.sh prepend 1 "this is just a"
1 2009-02-13 this is just a new task
EOF
cat /dev/null > todo.txt
test_todo_session 'prepend handling priority and prepended date on add' <<EOF
>>> todo.sh -t add "new task"
1 2009-02-13 new task
TODO: 1 added.
>>> todo.sh pri 1 A
1 (A) 2009-02-13 new task
TODO: 1 prioritized (A).
>>> todo.sh prepend 1 "this is just a"
1 (A) 2009-02-13 this is just a new task
EOF
cat /dev/null > todo.txt
test_todo_session 'prepend with prepended date keeps both' <<EOF
>>> todo.sh -t add "new task"
1 2009-02-13 new task
TODO: 1 added.
>>> todo.sh prepend 1 "2010-07-04 this is just a"
1 2009-02-13 2010-07-04 this is just a new task
EOF
test_done

86
tests/t1500-do.sh Executable file
View File

@@ -0,0 +1,86 @@
#!/bin/sh
test_description='do functionality
'
. ./test-lib.sh
#DATE=`date '+%Y-%m-%d'`
test_todo_session 'do usage' <<EOF
>>> todo.sh do B B
usage: todo.sh do ITEM#[, ITEM#, ITEM#, ...]
=== 1
EOF
test_todo_session 'do missing ITEM#' <<EOF
>>> todo.sh do
usage: todo.sh do ITEM#[, ITEM#, ITEM#, ...]
=== 1
EOF
cat > todo.txt <<EOF
smell the uppercase Roses +flowers @outside
notice the sunflowers
stop
remove1
remove2
remove3
remove4
EOF
test_todo_session 'basic do' <<EOF
>>> todo.sh list
2 notice the sunflowers
4 remove1
5 remove2
6 remove3
7 remove4
1 smell the uppercase Roses +flowers @outside
3 stop
--
TODO: 7 of 7 tasks shown
>>> todo.sh do 7,6
7 x 2009-02-13 remove4
TODO: 7 marked as done.
6 x 2009-02-13 remove3
TODO: 6 marked as done.
x 2009-02-13 remove3
x 2009-02-13 remove4
TODO: $HOME/todo.txt archived.
>>> todo.sh -p list
2 notice the sunflowers
4 remove1
5 remove2
1 smell the uppercase Roses +flowers @outside
3 stop
--
TODO: 5 of 5 tasks shown
>>> todo.sh do 5 4
5 x 2009-02-13 remove2
TODO: 5 marked as done.
4 x 2009-02-13 remove1
TODO: 4 marked as done.
x 2009-02-13 remove1
x 2009-02-13 remove2
TODO: $HOME/todo.txt archived.
>>> todo.sh -p list
2 notice the sunflowers
1 smell the uppercase Roses +flowers @outside
3 stop
--
TODO: 3 of 3 tasks shown
EOF
test_todo_session 'fail multiple do attempts' <<EOF
>>> todo.sh -a do 3
3 x 2009-02-13 stop
TODO: 3 marked as done.
>>> todo.sh -a do 3
TODO: 3 is already marked done.
EOF
test_done

103
tests/t1600-append.sh Executable file
View File

@@ -0,0 +1,103 @@
#!/bin/sh
test_description='basic append functionality
Ensure we can append items successfully.
'
. ./test-lib.sh
#
# Set up the basic todo.txt
#
todo.sh add notice the daisies > /dev/null
test_todo_session 'append usage' <<EOF
>>> todo.sh append adf asdfa
=== 1
usage: todo.sh append ITEM# "TEXT TO APPEND"
EOF
test_todo_session 'append error' << EOF
>>> todo.sh append 10 "hej!"
=== 1
TODO: No task 10.
EOF
test_todo_session 'basic append' <<EOF
>>> todo.sh append 1 "smell the roses"
1 notice the daisies smell the roses
>>> todo.sh list
1 notice the daisies smell the roses
--
TODO: 1 of 1 tasks shown
EOF
test_todo_session 'basic append with &' <<EOF
>>> todo.sh append 1 "see the wasps & bees"
1 notice the daisies smell the roses see the wasps & bees
>>> todo.sh list
1 notice the daisies smell the roses see the wasps & bees
--
TODO: 1 of 1 tasks shown
EOF
echo 'jump on hay' > todo.txt
test_todo_session 'append with spaces' <<EOF
>>> todo.sh append 1 "and notice the three spaces"
1 jump on hay and notice the three spaces
EOF
cat > todo.txt <<EOF
smell the cows
grow some corn
thrash some hay
chase the chickens
EOF
test_todo_session 'append with symbols' <<EOF
>>> todo.sh append 1 "~@#$%^&*()-_=+[{]}|;:',<.>/?"
1 smell the cows ~@#$%^&*()-_=+[{]}|;:',<.>/?
>>> todo.sh append 2 '\`!\\"'
2 grow some corn \`!\\"
>>> todo.sh list
4 chase the chickens
2 grow some corn \`!\\"
1 smell the cows ~@#$%^&*()-_=+[{]}|;:',<.>/?
3 thrash some hay
--
TODO: 4 of 4 tasks shown
EOF
cat > todo.txt <<EOF
notice the daisies
EOF
test_todo_session 'append of current sentence' <<EOF
>>> todo.sh append 1 ", lilies and roses"
1 notice the daisies, lilies and roses
>>> todo.sh append 1 "; see the wasps"
1 notice the daisies, lilies and roses; see the wasps
>>> todo.sh append 1 "& bees"
1 notice the daisies, lilies and roses; see the wasps & bees
EOF
cp todo.cfg special-delimiters.cfg
cat >> special-delimiters.cfg <<EOF
export SENTENCE_DELIMITERS='*,.:;&'
EOF
test_todo_session 'append of current sentence SENTENCE_DELIMITERS' <<EOF
>>> todo.sh -d special-delimiters.cfg append 1 "&beans"
1 notice the daisies, lilies and roses; see the wasps & bees&beans
>>> todo.sh -d special-delimiters.cfg append 1 "%foo"
1 notice the daisies, lilies and roses; see the wasps & bees&beans %foo
>>> todo.sh -d special-delimiters.cfg append 1 "*2"
1 notice the daisies, lilies and roses; see the wasps & bees&beans %foo*2
EOF
test_done

97
tests/t1700-depri.sh Executable file
View File

@@ -0,0 +1,97 @@
#!/bin/sh
test_description='basic depriority functionality
'
. ./test-lib.sh
test_todo_session 'depriority usage' <<EOF
>>> todo.sh depri B B
usage: todo.sh depri ITEM#[, ITEM#, ITEM#, ...]
=== 1
EOF
test_todo_session 'depriority nonexistant item' <<EOF
>>> todo.sh depri 42
TODO: No task 42.
=== 1
EOF
cat > todo.txt <<EOF
(B) smell the uppercase Roses +flowers @outside
(A) notice the sunflowers
stop
EOF
test_todo_session 'basic depriority' <<EOF
>>> 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
>>> todo.sh depri 1
1 smell the uppercase Roses +flowers @outside
TODO: 1 deprioritized.
>>> todo.sh -p list
2 (A) notice the sunflowers
1 smell the uppercase Roses +flowers @outside
3 stop
--
TODO: 3 of 3 tasks shown
EOF
cat > todo.txt <<EOF
(B) smell the uppercase Roses +flowers @outside
(A) notice the sunflowers
(C) stop
EOF
test_todo_session 'multiple depriority' <<EOF
>>> todo.sh -p list
2 (A) notice the sunflowers
1 (B) smell the uppercase Roses +flowers @outside
3 (C) stop
--
TODO: 3 of 3 tasks shown
>>> todo.sh depri 3 2
3 stop
TODO: 3 deprioritized.
2 notice the sunflowers
TODO: 2 deprioritized.
>>> todo.sh -p list
1 (B) smell the uppercase Roses +flowers @outside
2 notice the sunflowers
3 stop
--
TODO: 3 of 3 tasks shown
EOF
cat > todo.txt <<EOF
(B) smell the uppercase Roses +flowers @outside
(A) notice the sunflowers
stop
EOF
test_todo_session 'depriority of unprioritized task' <<EOF
>>> 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
>>> todo.sh depri 3 2
TODO: 3 is not prioritized.
2 notice the sunflowers
TODO: 2 deprioritized.
>>> todo.sh -p list
1 (B) smell the uppercase Roses +flowers @outside
2 notice the sunflowers
3 stop
--
TODO: 3 of 3 tasks shown
EOF
test_done

153
tests/t1800-del.sh Executable file
View File

@@ -0,0 +1,153 @@
#!/bin/sh
test_description='basic del functionality
'
. ./test-lib.sh
test_todo_session 'del usage' <<EOF
>>> todo.sh del B
usage: todo.sh del ITEM# [TERM]
=== 1
EOF
test_todo_session 'del nonexistant item' <<EOF
>>> todo.sh -f del 42
TODO: No task 42.
=== 1
>>> todo.sh -f del 42 Roses
TODO: No task 42.
=== 1
EOF
cat > todo.txt <<EOF
(B) smell the uppercase Roses +flowers @outside
(A) notice the sunflowers
stop
EOF
test_todo_session 'basic del' <<EOF
>>> 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
>>> todo.sh -f del 1
1 (B) smell the uppercase Roses +flowers @outside
TODO: 1 deleted.
>>> todo.sh -p list
2 (A) notice the sunflowers
3 stop
--
TODO: 2 of 2 tasks shown
EOF
cat > todo.txt <<EOF
(B) smell the uppercase Roses +flowers @outside
(A) notice the sunflowers
stop
EOF
test_todo_session 'del preserving line numbers' <<EOF
>>> todo.sh -f del 1
1 (B) smell the uppercase Roses +flowers @outside
TODO: 1 deleted.
>>> todo.sh -f del 1
TODO: No task 1.
=== 1
>>> todo.sh add A new task
4 A new task
TODO: 4 added.
>>> todo.sh -p list
2 (A) notice the sunflowers
4 A new task
3 stop
--
TODO: 3 of 3 tasks shown
>>> todo.sh -f -n del 2
2 (A) notice the sunflowers
TODO: 2 deleted.
>>> todo.sh add Another new task
3 Another new task
TODO: 3 added.
>>> todo.sh -p list
2 A new task
3 Another new task
1 stop
--
TODO: 3 of 3 tasks shown
EOF
cat > todo.txt <<EOF
(B) smell the uppercase Roses +flowers @outside
(A) notice the sunflowers
(C) stop
EOF
test_todo_session 'basic del TERM' <<EOF
>>> todo.sh -p list
2 (A) notice the sunflowers
1 (B) smell the uppercase Roses +flowers @outside
3 (C) stop
--
TODO: 3 of 3 tasks shown
>>> todo.sh del 1 uppercase
1 (B) smell the uppercase Roses +flowers @outside
TODO: Removed 'uppercase' from task.
1 (B) smell the Roses +flowers @outside
>>> todo.sh -p list
2 (A) notice the sunflowers
1 (B) smell the Roses +flowers @outside
3 (C) stop
--
TODO: 3 of 3 tasks shown
>>> todo.sh del 1 "the Roses"
1 (B) smell the Roses +flowers @outside
TODO: Removed 'the Roses' from task.
1 (B) smell +flowers @outside
>>> todo.sh del 1 m
1 (B) smell +flowers @outside
TODO: Removed 'm' from task.
1 (B) sell +flowers @outside
>>> todo.sh del 1 @outside
1 (B) sell +flowers @outside
TODO: Removed '@outside' from task.
1 (B) sell +flowers
>>> todo.sh del 1 sell
1 (B) sell +flowers
TODO: Removed 'sell' from task.
1 (B) +flowers
EOF
cat > todo.txt <<EOF
(B) smell the uppercase Roses +flowers @outside
(A) notice the sunflowers
(C) stop
EOF
test_todo_session 'del nonexistant TERM' <<EOF
>>> todo.sh del 1 dung
1 (B) smell the uppercase Roses +flowers @outside
TODO: 'dung' not found; no removal done.
=== 1
>>> todo.sh -p list
2 (A) notice the sunflowers
1 (B) smell the uppercase Roses +flowers @outside
3 (C) stop
--
TODO: 3 of 3 tasks shown
EOF
test_done

136
tests/t2000-multiline.sh Executable file
View File

@@ -0,0 +1,136 @@
#!/bin/sh
test_description='Multi-line functionality'
. ./test-lib.sh
## Replace test
# Create the expected file
echo "1 smell the cheese
TODO: Replaced task with:
1 eat apples eat oranges drink milk">$HOME/expect.multi
test_expect_success 'multiline squash item replace' '
(
# Prepare single line todo file
cat /dev/null > $HOME/todo.txt
"$HOME/bin/todo.sh" add smell the cheese
# Run replace
"$HOME/bin/todo.sh" replace 1 "eat apples
eat oranges
drink milk" > $HOME/output.multi
# Test output against expected
diff "$HOME/output.multi" "$HOME/expect.multi"
if [ $? -ne 0 ]; then
exit 1
else
exit 0
fi
)
'
## Add test
# Create the expected file
echo "2 eat apples eat oranges drink milk
TODO: 2 added.">$HOME/expect.multi
test_expect_success 'multiline squash item add' '
(
# Prepare single line todo file
cat /dev/null > $HOME/todo.txt
"$HOME/bin/todo.sh" add smell the cheese
# Run add
"$HOME/bin/todo.sh" add "eat apples
eat oranges
drink milk" > $HOME/output.multi
# Test output against expected
diff "$HOME/output.multi" "$HOME/expect.multi"
if [ $? -ne 0 ]; then
exit 1
else
exit 0
fi
)
'
## Append test
# Create the expected file
echo "1 smell the cheese eat apples eat oranges drink milk">$HOME/expect.multi
test_expect_success 'multiline squash item append' '
(
# Prepare single line todo file
cat /dev/null > $HOME/todo.txt
"$HOME/bin/todo.sh" add smell the cheese
# Run append
"$HOME/bin/todo.sh" append 1 "eat apples
eat oranges
drink milk" > $HOME/output.multi
# Test output against expected
diff "$HOME/output.multi" "$HOME/expect.multi"
if [ $? -ne 0 ]; then
exit 1
else
exit 0
fi
)
'
## Prepend test
# Create the expected file
echo "1 eat apples eat oranges drink milk smell the cheese">$HOME/expect.multi
test_expect_success 'multiline squash item prepend' '
(
# Prepare single line todo file
cat /dev/null > $HOME/todo.txt
"$HOME/bin/todo.sh" add smell the cheese
# Run prepend
"$HOME/bin/todo.sh" prepend 1 "eat apples
eat oranges
drink milk" > $HOME/output.multi
# Test output against expected
diff "$HOME/output.multi" "$HOME/expect.multi"
if [ $? -ne 0 ]; then
exit 1
else
exit 0
fi
)
'
## Multiple line addition
# Create the expected file
echo "2 eat apples
TODO: 2 added." > $HOME/expect.multi
echo "3 eat oranges
TODO: 3 added." >>$HOME/expect.multi
echo "4 drink milk
TODO: 4 added." >> $HOME/expect.multi
test_expect_success 'actual multiline add' '
(
# Run addm
"$HOME/bin/todo.sh" addm "eat apples
eat oranges
drink milk" > $HOME/output.multi
# Test output against expected
diff "$HOME/output.multi" "$HOME/expect.multi"
if [ $? -ne 0 ]; then
exit 1
else
exit 0
fi
)
'
test_done

57
tests/t8000-actions.sh Executable file
View File

@@ -0,0 +1,57 @@
#!/bin/sh
test_description='custom actions functionality
This test covers the contract between todo.sh and custom actions.
'
. ./test-lib.sh
unset TODO_ACTIONS_DIR
mkdir .todo.actions.d
make_action()
{
cat > ".todo.actions.d/$1" <<- EOF
#!/bin/bash
echo "custom action $1"
EOF
chmod +x ".todo.actions.d/$1"
}
make_action "foo"
test_todo_session 'executable action' <<EOF
>>> todo.sh foo
custom action foo
EOF
chmod -x .todo.actions.d/foo
# On Cygwin, clearing the executable flag may have no effect, as the Windows ACL
# may still grant execution rights. In this case, we skip the test.
if [ -x .todo.actions.d/foo ]; then
SKIP_TESTS="${SKIP_TESTS}${SKIP_TESTS+ }t8000.2"
fi
test_todo_session 'nonexecutable action' <<EOF
>>> todo.sh foo
Usage: todo.sh [-fhpantvV] [-d todo_config] action [task_number] [task_description]
Try 'todo.sh -h' for more information.
=== 1
EOF
make_action "ls"
test_todo_session 'overriding built-in action' <<EOF
>>> todo.sh ls
custom action ls
>>> todo.sh command ls
--
TODO: 0 of 0 tasks shown
EOF
make_action "bad"
echo "exit 42" >> .todo.actions.d/bad
test_todo_session 'failing action' <<EOF
>>> todo.sh bad
custom action bad
=== 42
EOF
test_done

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

@@ -0,0 +1,171 @@
#!/bin/sh
test_description='basic tests imported from previous framework
'
. ./test-lib.sh
cat > todo.txt <<EOF
(B) smell the uppercase Roses +flowers @outside
(A) notice the sunflowers
stop
smell the coffee +wakeup
EOF
test_todo_session 'basic tests' <<EOF
>>> 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
>>> todo.sh -p list +flowers
1 (B) smell the uppercase Roses +flowers @outside
--
TODO: 1 of 4 tasks shown
>>> todo.sh -p list flowers
2 (A) notice the sunflowers
1 (B) smell the uppercase Roses +flowers @outside
--
TODO: 2 of 4 tasks shown
>>> todo.sh -p list flowers out
1 (B) smell the uppercase Roses +flowers @outside
--
TODO: 1 of 4 tasks shown
>>> 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
>>> todo.sh add "make the coffee +wakeup"
5 make the coffee +wakeup
TODO: 5 added.
>>> todo.sh -p list coffee
5 make the coffee +wakeup
4 smell the coffee +wakeup
--
TODO: 2 of 5 tasks shown
>>> todo.sh add "visit http://example.com"
6 visit http://example.com
TODO: 6 added.
>>> 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
>>> 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
>>> 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: 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
>>> todo.sh append 10 "hej!"
TODO: No task 10.
=== 1
>>> 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
>>> todo.sh do 10
TODO: No task 10.
=== 1
>>> 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
>>> todo.sh add "the coffee +wakeup"
6 the coffee +wakeup
TODO: 6 added.
>>> 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
6 the coffee +wakeup
5 visit http://example.com
--
TODO: 6 of 6 tasks shown
>>> todo.sh prepend 6 "make"
6 make the coffee +wakeup
>>> todo.sh -p list
1 (B) smell the uppercase Roses +flowers @outside
4 make the coffee +wakeup
6 make the coffee +wakeup
3 smell the coffee +wakeup
2 stop and think
5 visit http://example.com
--
TODO: 6 of 6 tasks shown
>>> 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

@@ -12,8 +12,10 @@ done,*)
*' --tee '*|*' --va'*) *' --tee '*|*' --va'*)
mkdir -p test-results mkdir -p test-results
BASE=test-results/$(basename "$0" .sh) BASE=test-results/$(basename "$0" .sh)
(TEST_TEE_STARTED=done ${SHELL-sh} "$0" "$@" 2>&1; (
echo $? > $BASE.exit) | tee $BASE.out TEST_TEE_STARTED=done ${SHELL-sh} "$0" "$@" 2>&1;
echo $? > $BASE.exit
) | tee $BASE.out
test "$(cat $BASE.exit)" = 0 test "$(cat $BASE.exit)" = 0
exit exit
;; ;;
@@ -37,7 +39,9 @@ VISUAL=:
unset CDPATH unset CDPATH
# Protect ourselves from using predefined TODOTXT_CFG_FILE # Protect ourselves from using predefined TODOTXT_CFG_FILE
unset TODOTXT_CFG_FILE unset TODOTXT_CFG_FILE $(set|sed '/^TODOTXT_/!d;s/=.*//')
# To prevent any damage if someone has still those exported somehow in his env:
unset TODO_FILE DONE_FILE REPORT_FILE TMP_FILE
# Each test should start with something like this, after copyright notices: # Each test should start with something like this, after copyright notices:
# #
@@ -393,7 +397,7 @@ test_done () {
0) 0)
say_color pass "passed all $msg" say_color pass "passed all $msg"
# Clean up this test. # Clean up this test.
test -d "$remove_trash" && test -d "$remove_trash" &&
cd "$(dirname "$remove_trash")" && cd "$(dirname "$remove_trash")" &&
rm -rf "$(basename "$remove_trash")" rm -rf "$(basename "$remove_trash")"
@@ -407,9 +411,12 @@ test_done () {
esac esac
} }
# Make sure we are testing the latest version. # Use -P to resolve symlinks in our working directory so that the pwd
# in subprocesses equals our $PWD (for pathname comparisons).
cd -P .
# 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)"
@@ -429,14 +436,151 @@ test_init_todo () {
root="$1" root="$1"
mkdir -p "$root" mkdir -p "$root"
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
# Trying to detect the version of "date" on current system
DATE_STYLE=unknown
# on GNU systems (versions may vary):
#date --version
#date (GNU coreutils) 6.10
#...
if date --version 2>&1 | grep -q "GNU"; then
DATE_STYLE=GNU
# on Mac OS X 10.5:
#date --version
#date: illegal option -- -
#usage: date [-jnu] [-d dst] [-r seconds] [-t west] [-v[+|-]val[ymwdHMS]] ...
#[-f fmt date | [[[mm]dd]HH]MM[[cc]yy][.ss]] [+format]
elif date --version 2>&1 | grep -q -e "-jnu"; then
DATE_STYLE=Mac10.5
# on Mac OS X 10.4:
#date --version
#date: illegal option -- -
#usage: date [-nu] [-r seconds] [+format]
# date [[[[[cc]yy]mm]dd]hh]mm[.ss]
elif date --version 2>&1 | grep -q -e "-nu"; then
DATE_STYLE=Mac10.4
fi
case $DATE_STYLE in
GNU)
cat > bin/date <<-EOF
#!/bin/sh
exec "$TODO_TEST_REAL_DATE" -d @\$TODO_TEST_TIME \$@
EOF
chmod 755 bin/date
;;
Mac10.5)
cat > bin/date <<-EOF
#!/bin/sh
exec "$TODO_TEST_REAL_DATE" -j -f %s \$TODO_TEST_TIME \$@
EOF
chmod 755 bin/date
;;
Mac10.4)
cat > bin/date <<-EOF
#!/bin/sh
exec "$TODO_TEST_REAL_DATE" -r \$TODO_TEST_TIME \$@
EOF
chmod 755 bin/date
;;
*)
echo "WARNING: Current date executable not recognized"
echo "So today date will be used, expect false negative tests..."
;;
esac
# 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 -r 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 pwd
# in subprocesses equals our $PWD (for pathname comparisons). # in subprocesses equals our $PWD (for pathname comparisons).
cd -P "$test" || exit 1 cd -P "$test" || exit 1

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

View File

@@ -2,7 +2,7 @@
# Your todo.txt directory # Your todo.txt directory
#export TODO_DIR="/Users/gina/Documents/todo" #export TODO_DIR="/Users/gina/Documents/todo"
export TODO_DIR="C:/Documents and Settings/gina/My Documents" export TODO_DIR=`dirname "$0"`
# Your todo/done/report.txt locations # Your todo/done/report.txt locations
export TODO_FILE="$TODO_DIR/todo.txt" export TODO_FILE="$TODO_DIR/todo.txt"
@@ -17,8 +17,13 @@ export TMP_FILE="$TODO_DIR/todo.tmp"
# === COLOR MAP === # === COLOR MAP ===
## If you have re-mapped your color codes, you may need to ## Text coloring and formatting is done by inserting ANSI escape codes.
## If you have re-mapped your color codes, or use the todo.txt
## output in another output system (like Conky), you may need to
## over-ride by uncommenting and editing these defaults. ## over-ride by uncommenting and editing these defaults.
## If you change any of these here, you also need to uncomment
## the defaults in the COLORS section below. Otherwise, todo.txt
## will still use the defaults!
# export BLACK='\\033[0;30m' # export BLACK='\\033[0;30m'
# export RED='\\033[0;31m' # export RED='\\033[0;31m'
@@ -38,18 +43,38 @@ export TMP_FILE="$TODO_DIR/todo.tmp"
# export WHITE='\\033[1;37m' # export WHITE='\\033[1;37m'
# export DEFAULT='\\033[0m' # export DEFAULT='\\033[0m'
# === PRIORITY COLORS === # === COLORS ===
## Priorities can be any upper-case letter.
## Colors are supported for the first three.
## Uncomment and edit to override these defaults. ## Uncomment and edit to override these defaults.
## Reference the constants from the color map above,
## or use $NONE to disable highlighting.
#
# Priorities can be any upper-case letter.
# A,B,C are highlighted; you can add coloring for more.
#
# export PRI_A=$YELLOW # color for A priority # export PRI_A=$YELLOW # color for A priority
# export PRI_B=$GREEN # color for B priority # export PRI_B=$GREEN # color for B priority
# export PRI_C=$LIGHT_BLUE # color for C priority # export PRI_C=$LIGHT_BLUE # color for C priority
# export PRI_X=$WHITE # color for rest of them # export PRI_D=... # define your own
# export PRI_X=$WHITE # color unless explicitly defined
# There is highlighting for tasks that have been done,
# but haven't been archived yet.
#
# export COLOR_DONE=$LIGHT_GREY
# === BEHAVIOR === # === BEHAVIOR ===
## customize list output ## customize list output
#
# TODOTXT_SORT_COMMAND will filter after line numbers are
# inserted, but before colorization, and before hiding of
# priority, context, and project.
#
# export TODOTXT_SORT_COMMAND='env LC_COLLATE=C sort -f -k2' # export TODOTXT_SORT_COMMAND='env LC_COLLATE=C sort -f -k2'
# TODOTXT_FINAL_FILTER will filter list output after colorization,
# priority hiding, context hiding, and project hiding. That is,
# just before the list output is displayed.
#
# export TODOTXT_FINAL_FILTER='cat'

1275
todo.sh

File diff suppressed because it is too large Load Diff

71
todo_completion Normal file
View File

@@ -0,0 +1,71 @@
#!/bin/bash source-this-script
[ "$BASH_VERSION" ] || return
_todo()
{
local cur prev opts
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
local -r OPTS="-@ -@@ -+ -++ -d -f -h -p -P -PP -a -n -t -v -vv -V -x"
local -r COMMANDS="\
add a addto addm append app archive command del \
rm depri dp do help list ls listall lsa listcon \
lsc listfile lf listpri lsp listproj lsprj move \
mv prepend prep pri p replace report shorthelp"
# Add custom commands from add-ons, if installed.
# TODO: Filter for executable flag of files found in $TODO_ACTIONS_DIR.
local allCommands="$COMMANDS $('ls' "${TODO_ACTIONS_DIR:-$HOME/.todo.actions.d}/" 2>/dev/null)"
local completions
if [ $COMP_CWORD -eq 1 ]; then
completions="$allCommands $OPTS"
elif [[ $COMP_CWORD -gt 2 && ( \
"${COMP_WORDS[COMP_CWORD-2]}" =~ ^(move|mv)$ || \
"${COMP_WORDS[COMP_CWORD-3]}" =~ ^(move|mv)$ ) ]]; then
# "move ITEM# DEST [SRC]" has file arguments on positions 2 and 3.
completions=$(TODOTXT_VERBOSE=0 todo.sh command listfile)
else
case "$prev" in
command)
completions=$COMMANDS;;
addto|listfile|lf)
completions=$(TODOTXT_VERBOSE=0 todo.sh command listfile);;
-*) completions="$allCommands $OPTS";;
*) case "$cur" in
+*) completions=$(TODOTXT_VERBOSE=0 todo.sh command listproj);;
@*) completions=$(TODOTXT_VERBOSE=0 todo.sh command listcon);;
*) if [[ "$cur" =~ ^[0-9]+$ ]]; then
local item=$(TODOTXT_VERBOSE=0 todo.sh -@ -+ -p -x command ls "^ *${cur} " | head -n 1)
# Remove the (padded) task number; we prepend the
# user-provided $cur.
item=${item#* }
# Remove the timestamp prepended by the -t option;
# there's no todo.txt option for that yet.
item=${item#[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] }
# Append task text as a shell comment. This
# completion can be a safety check before a
# destructive todo.txt operation.
[ "$item" ] && COMPREPLY[0]="$cur # $item"
return 0
else
return 0
fi
;;
esac
;;
esac
fi
COMPREPLY=( $( compgen -W "$completions" -- $cur ))
return 0
}
complete -F _todo todo.sh
# If you define an alias (e.g. "t") to todo.sh, you need to explicitly enable
# completion for it, too:
#complete -F _todo t