Commit 68f9288d authored by Bram Schoenmakers's avatar Bram Schoenmakers

Merge branch 'master' into stable

parents 40b96592 41e534bf
language: python language: python
python: python:
- "2.7" - "2.7"
- "3.2"
- "3.3"
- "3.4"
install: install:
- "pip install ." - "pip install ."
- "pip install icalendar" - "pip install icalendar"
- "pip install pylint" - "pip install pylint"
script: "python setup.py test && pylint --errors-only topydo test" script: "./run-tests.sh"
notifications: notifications:
webhooks: webhooks:
urls: urls:
......
0.4
---
* A new prompt mode with autocompletion. To enable, run `pip install
prompt-toolkit`, then `topydo prompt`.
* Support for Python 3.2, 3.3 and 3.4 (note that iCalendar output does not
work in Python 3.2)
* Better Unicode support.
* `add` command has the `-f` flag to add todo items from a file (or use `-` to
read from standard input) (Jacek Sowiński - @mruwek)
* Customizable colors + additional highlighting of tags and URLs (Jacek
Sowiński (@mruwek) and @kidpixo).
* Make sure that the `edit` subcommand always uses the correct todo.txt file.
* `ls` subcommand has the `-f` flag to specify the output format. Currently,
three formats are supported:
* `text` - The default plain text format.
* `ical` - iCalendar (WARNING: this deprecates the `ical` subcommand)
* `json` - Javascript Object Notation (JSON)
* Resolve `~` to home directory if used in a configuration file
(@robertvanbregt).
* Various minor fixes.
Again, I'd like to thank Jacek (@mruwek) for his assistance and contributions
in this release.
0.3.2 0.3.2
----- -----
...@@ -27,7 +52,7 @@ ...@@ -27,7 +52,7 @@
* Fix assignment of dependency IDs: in some cases two distinct todos get the * Fix assignment of dependency IDs: in some cases two distinct todos get the
same dependency ID. same dependency ID.
Big thanks to Jacek for his contributions in this release. Big thanks to Jacek (@mruwek) for his contributions in this release.
0.2 0.2
--- ---
......
If you're reading this, you may have interest in enhancing topydo. Thank you! If you're reading this, you may have interest in enhancing topydo. Thank you!
Please read the following guidelines to get your enhancement / bug fixes smoothly into topydo: Please read the following guidelines to get your enhancement / bug fixes
smoothly into topydo:
* This Github page defaults to the **stable** branch which is for **bug fixes only**. If you would like to add a new * This Github page defaults to the **stable** branch which is for **bug fixes
feature, make sure to make a Pull Request on the `master` branch. only**. If you would like to add a new feature, make sure to make a Pull
Request on the `master` branch.
* Run tests with: * Run tests with:
python2 setup.py test ./run-tests.sh [python2|python3]
python3 setup.py test
Obviously, I won't accept anything that makes the tests fail. When you submit
Obviously, I won't accept anything that makes the tests fail. When you submit a Pull Request, Travis CI will a Pull Request, Travis CI will automatically run all tests for various Python
automatically run all tests for various Python versions, but it's better if you run the tests locally first. versions, but it's better if you run the tests locally first.
Make sure you have the `mock` package installed if you test on a Python version older than 3.3. Make sure you have the `mock` package installed if you test on a Python
version older than 3.3.
* Add tests for your change(s): * Add tests for your change(s):
* Bugfixes: add a testcase that covers your bugfix, so the bug won't happen ever again. * Bugfixes: add a testcase that covers your bugfix, so the bug won't happen
* Features: add testcases that checks various inputs and outputs of your feature. Be creative in trying to break the ever again.
feature you've just implemented. * Features: add testcases that checks various inputs and outputs of your
feature. Be creative in trying to break the feature you've just implemented.
* Use descriptive commit messages. * Use descriptive commit messages.
### Coding style ### Coding style
* Please try to adhere to the coding style dictated by `pylint` as much possible. I won't be very picky about long lines, * Please try to adhere to the coding style dictated by `pylint` as much
but please try to avoid them. possible. I won't be very picky about long lines, but please try to avoid
* I strongly prefer simple and short functions, doing only one thing. I'll request you to refactor functions with them.
massive indentation or don't fit otherwise on a screen. * I strongly prefer simple and short functions, doing only one thing. I'll
request you to refactor functions with massive indentation or don't fit
otherwise on a screen.
#!/bin/bash
if [ "$1" = "python2" ] || [ "$1" = "python3" ]; then
PYTHON=$1
else
# run whatever is active
PYTHON=python
fi
# Run normal tests
if ! $PYTHON setup.py test; then
exit 1
fi
# pylint is not supported on 3.2, so skip the test there
if $PYTHON --version 2>&1 | grep 'Python 3\.2' > /dev/null; then
exit 0
fi
if ! $PYTHON -m pylint --errors-only topydo test; then
exit 1
fi
exit 0
[bdist_wheel]
universal = 1
from setuptools import setup from setuptools import setup, find_packages
setup( setup(
name = "topydo", name = "topydo",
packages = ["topydo", "topydo.lib", "topydo.cli"], packages = find_packages(exclude=["test"]),
version = "0.3.2", version = "0.4",
description = "A command-line todo list application using the todo.txt format.", description = "A command-line todo list application using the todo.txt format.",
author = "Bram Schoenmakers", author = "Bram Schoenmakers",
author_email = "me@bramschoenmakers.nl", author_email = "me@bramschoenmakers.nl",
url = "https://github.com/bram85/topydo", url = "https://github.com/bram85/topydo",
install_requires = [
'six >= 1.9.0',
],
extras_require = { extras_require = {
'ical': ['icalendar'], 'ical': ['icalendar'],
'prompt-toolkit': ['prompt-toolkit >= 0.37'],
'edit-cmd-tests': ['mock'], 'edit-cmd-tests': ['mock'],
}, },
entry_points= { entry_points= {
'console_scripts': ['topydo = topydo.cli.Main:main'], 'console_scripts': ['topydo = topydo.cli.UILoader:main'],
}, },
classifiers = [ classifiers = [
"Development Status :: 4 - Beta", "Development Status :: 4 - Beta",
...@@ -22,6 +26,9 @@ setup( ...@@ -22,6 +26,9 @@ setup(
"License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)", "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)",
"Natural Language :: English", "Natural Language :: English",
"Programming Language :: Python :: 2.7", "Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3.2",
"Programming Language :: Python :: 3.3",
"Programming Language :: Python :: 3.4",
"Topic :: Utilities", "Topic :: Utilities",
], ],
long_description = """\ long_description = """\
......
...@@ -17,13 +17,23 @@ ...@@ -17,13 +17,23 @@
from datetime import date from datetime import date
import unittest import unittest
from topydo.lib import AddCommand # We're searching for 'mock'
from topydo.lib import ListCommand # pylint: disable=no-name-in-module
import CommandTest try:
from unittest import mock
except ImportError:
import mock
from six import u
from io import StringIO
from topydo.commands import AddCommand
from topydo.commands import ListCommand
from test.CommandTest import CommandTest, utf8
from topydo.lib.Config import config from topydo.lib.Config import config
from topydo.lib import TodoList from topydo.lib import TodoList
class AddCommandTest(CommandTest.CommandTest): class AddCommandTest(CommandTest):
def setUp(self): def setUp(self):
super(AddCommandTest, self).setUp() super(AddCommandTest, self).setUp()
self.todolist = TodoList.TodoList([]) self.todolist = TodoList.TodoList([])
...@@ -34,48 +44,48 @@ class AddCommandTest(CommandTest.CommandTest): ...@@ -34,48 +44,48 @@ class AddCommandTest(CommandTest.CommandTest):
command = AddCommand.AddCommand(args, self.todolist, self.out, self.error) command = AddCommand.AddCommand(args, self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.todolist.todo(1).source(), self.today + " New todo") self.assertEqual(self.todolist.todo(1).source(), self.today + " New todo")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_add_multiple_args(self): def test_add_multiple_args(self):
args = ["New", "todo"] args = ["New", "todo"]
command = AddCommand.AddCommand(args, self.todolist, self.out, self.error) command = AddCommand.AddCommand(args, self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.todolist.todo(1).source(), self.today + " New todo") self.assertEqual(self.todolist.todo(1).source(), self.today + " New todo")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_add_priority1(self): def test_add_priority1(self):
command = AddCommand.AddCommand(["Foo (C)"], self.todolist, self.out, self.error) command = AddCommand.AddCommand(["Foo (C)"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.todolist.todo(1).priority(), 'C') self.assertEqual(self.todolist.todo(1).priority(), 'C')
self.assertEquals(self.todolist.todo(1).source(), "(C) " + self.today + " Foo") self.assertEqual(self.todolist.todo(1).source(), "(C) " + self.today + " Foo")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_add_priority2(self): def test_add_priority2(self):
command = AddCommand.AddCommand(["Foo (CC)"], self.todolist, self.out, self.error) command = AddCommand.AddCommand(["Foo (CC)"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.todolist.todo(1).priority(), None) self.assertEqual(self.todolist.todo(1).priority(), None)
self.assertEquals(self.todolist.todo(1).source(), self.today + " Foo (CC)") self.assertEqual(self.todolist.todo(1).source(), self.today + " Foo (CC)")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_add_priority3(self): def test_add_priority3(self):
command = AddCommand.AddCommand(["Fo(C)o"], self.todolist, self.out, self.error) command = AddCommand.AddCommand(["Fo(C)o"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.todolist.todo(1).priority(), None) self.assertEqual(self.todolist.todo(1).priority(), None)
self.assertEquals(self.todolist.todo(1).source(), self.today + " Fo(C)o" ) self.assertEqual(self.todolist.todo(1).source(), self.today + " Fo(C)o" )
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_add_priority4(self): def test_add_priority4(self):
command = AddCommand.AddCommand(["(C) Foo"], self.todolist, self.out, self.error) command = AddCommand.AddCommand(["(C) Foo"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.todolist.todo(1).priority(), 'C') self.assertEqual(self.todolist.todo(1).priority(), 'C')
self.assertEquals(self.todolist.todo(1).source(), "(C) " + self.today + " Foo") self.assertEqual(self.todolist.todo(1).source(), "(C) " + self.today + " Foo")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_add_dep1(self): def test_add_dep1(self):
command = AddCommand.AddCommand(["Foo"], self.todolist, self.out, self.error) command = AddCommand.AddCommand(["Foo"], self.todolist, self.out, self.error)
...@@ -84,9 +94,9 @@ class AddCommandTest(CommandTest.CommandTest): ...@@ -84,9 +94,9 @@ class AddCommandTest(CommandTest.CommandTest):
command = AddCommand.AddCommand(["Bar before:1"], self.todolist, self.out, self.error) command = AddCommand.AddCommand(["Bar before:1"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.todolist.todo(1).source(), self.today + " Foo id:1") self.assertEqual(self.todolist.todo(1).source(), self.today + " Foo id:1")
self.assertEquals(self.todolist.todo(2).source(), self.today + " Bar p:1") self.assertEqual(self.todolist.todo(2).source(), self.today + " Bar p:1")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_add_dep2(self): def test_add_dep2(self):
command = AddCommand.AddCommand(["Foo"], self.todolist, self.out, self.error) command = AddCommand.AddCommand(["Foo"], self.todolist, self.out, self.error)
...@@ -95,9 +105,9 @@ class AddCommandTest(CommandTest.CommandTest): ...@@ -95,9 +105,9 @@ class AddCommandTest(CommandTest.CommandTest):
command = AddCommand.AddCommand(["Bar partof:1"], self.todolist) command = AddCommand.AddCommand(["Bar partof:1"], self.todolist)
command.execute() command.execute()
self.assertEquals(self.todolist.todo(1).source(), self.today + " Foo id:1") self.assertEqual(self.todolist.todo(1).source(), self.today + " Foo id:1")
self.assertEquals(self.todolist.todo(2).source(), self.today + " Bar p:1") self.assertEqual(self.todolist.todo(2).source(), self.today + " Bar p:1")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_add_dep3(self): def test_add_dep3(self):
command = AddCommand.AddCommand(["Foo"], self.todolist) command = AddCommand.AddCommand(["Foo"], self.todolist)
...@@ -106,9 +116,9 @@ class AddCommandTest(CommandTest.CommandTest): ...@@ -106,9 +116,9 @@ class AddCommandTest(CommandTest.CommandTest):
command = AddCommand.AddCommand(["Bar after:1"], self.todolist, self.out, self.error) command = AddCommand.AddCommand(["Bar after:1"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.todolist.todo(1).source(), self.today + " Foo p:1") self.assertEqual(self.todolist.todo(1).source(), self.today + " Foo p:1")
self.assertEquals(self.todolist.todo(2).source(), self.today + " Bar id:1") self.assertEqual(self.todolist.todo(2).source(), self.today + " Bar id:1")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_add_dep4(self): def test_add_dep4(self):
""" Test for using an after: tag with non-existing value. """ """ Test for using an after: tag with non-existing value. """
...@@ -116,9 +126,9 @@ class AddCommandTest(CommandTest.CommandTest): ...@@ -116,9 +126,9 @@ class AddCommandTest(CommandTest.CommandTest):
command.execute() command.execute()
self.assertFalse(self.todolist.todo(1).has_tag("after")) self.assertFalse(self.todolist.todo(1).has_tag("after"))
self.assertEquals(self.todolist.todo(1).source(), self.today + " Foo") self.assertEqual(self.todolist.todo(1).source(), self.today + " Foo")
self.assertEquals(self.output, "| 1| " + str(self.todolist.todo(1)) + "\n") self.assertEqual(self.output, "| 1| " + str(self.todolist.todo(1)) + "\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_add_dep5(self): def test_add_dep5(self):
""" Test for using an after: tag with non-existing value. """ """ Test for using an after: tag with non-existing value. """
...@@ -126,9 +136,9 @@ class AddCommandTest(CommandTest.CommandTest): ...@@ -126,9 +136,9 @@ class AddCommandTest(CommandTest.CommandTest):
command.execute() command.execute()
self.assertFalse(self.todolist.todo(1).has_tag("after")) self.assertFalse(self.todolist.todo(1).has_tag("after"))
self.assertEquals(self.todolist.todo(1).source(), self.today + " Foo") self.assertEqual(self.todolist.todo(1).source(), self.today + " Foo")
self.assertEquals(self.output, "| 1| " + str(self.todolist.todo(1)) + "\n") self.assertEqual(self.output, "| 1| " + str(self.todolist.todo(1)) + "\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_add_dep6(self): def test_add_dep6(self):
command = AddCommand.AddCommand(["Foo"], self.todolist, self.out, self.error) command = AddCommand.AddCommand(["Foo"], self.todolist, self.out, self.error)
...@@ -140,10 +150,10 @@ class AddCommandTest(CommandTest.CommandTest): ...@@ -140,10 +150,10 @@ class AddCommandTest(CommandTest.CommandTest):
command = AddCommand.AddCommand(["Baz before:1 before:2"], self.todolist, self.out, self.error) command = AddCommand.AddCommand(["Baz before:1 before:2"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.todolist.todo(1).source(), self.today + " Foo id:1") self.assertEqual(self.todolist.todo(1).source(), self.today + " Foo id:1")
self.assertEquals(self.todolist.todo(2).source(), self.today + " Bar id:2") self.assertEqual(self.todolist.todo(2).source(), self.today + " Bar id:2")
self.assertEquals(self.todolist.todo(3).source(), self.today + " Baz p:1 p:2") self.assertEqual(self.todolist.todo(3).source(), self.today + " Baz p:1 p:2")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_add_dep7(self): def test_add_dep7(self):
command = AddCommand.AddCommand(["Foo"], self.todolist, self.out, self.error) command = AddCommand.AddCommand(["Foo"], self.todolist, self.out, self.error)
...@@ -155,10 +165,10 @@ class AddCommandTest(CommandTest.CommandTest): ...@@ -155,10 +165,10 @@ class AddCommandTest(CommandTest.CommandTest):
command = AddCommand.AddCommand(["Baz after:1 after:2"], self.todolist, self.out, self.error) command = AddCommand.AddCommand(["Baz after:1 after:2"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.todolist.todo(1).source(), self.today + " Foo p:1") self.assertEqual(self.todolist.todo(1).source(), self.today + " Foo p:1")
self.assertEquals(self.todolist.todo(2).source(), self.today + " Bar p:1") self.assertEqual(self.todolist.todo(2).source(), self.today + " Bar p:1")
self.assertEquals(self.todolist.todo(3).source(), self.today + " Baz id:1") self.assertEqual(self.todolist.todo(3).source(), self.today + " Baz id:1")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_add_dep8(self): def test_add_dep8(self):
config("test/data/todolist-uid.conf") config("test/data/todolist-uid.conf")
...@@ -166,11 +176,11 @@ class AddCommandTest(CommandTest.CommandTest): ...@@ -166,11 +176,11 @@ class AddCommandTest(CommandTest.CommandTest):
command = AddCommand.AddCommand(["Foo"], self.todolist, self.out, self.error) command = AddCommand.AddCommand(["Foo"], self.todolist, self.out, self.error)
command.execute() command.execute()
command = AddCommand.AddCommand(["Bar after:tpi"], self.todolist, self.out, self.error) command = AddCommand.AddCommand(["Bar after:7ui"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.todolist.todo('tpi').source(), "{} Foo p:1".format(self.today)) self.assertEqual(self.todolist.todo('7ui').source(), "{} Foo p:1".format(self.today))
self.assertEquals(self.todolist.todo('b0n').source(), "{} Bar id:1".format(self.today)) self.assertEqual(self.todolist.todo('8to').source(), "{} Bar id:1".format(self.today))
def test_add_dep9(self): def test_add_dep9(self):
""" """
...@@ -184,13 +194,13 @@ class AddCommandTest(CommandTest.CommandTest): ...@@ -184,13 +194,13 @@ class AddCommandTest(CommandTest.CommandTest):
command = AddCommand.AddCommand(["Foo +Project"], self.todolist, lambda t: t, self.error) command = AddCommand.AddCommand(["Foo +Project"], self.todolist, lambda t: t, self.error)
command.execute() command.execute()
command = AddCommand.AddCommand(["Bar before:eqk"], self.todolist, self.out, self.error) command = AddCommand.AddCommand(["Bar before:kh0"], self.todolist, self.out, self.error)
command.execute() command.execute()
command = ListCommand.ListCommand(["Bar"], self.todolist, self.out, self.error) command = ListCommand.ListCommand(["Bar"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.output, "|5dh| {today} Bar p:1 +Project\n|5dh| {today} Bar +Project\n".format(today=self.today)) self.assertEqual(self.output, "|kbn| {today} Bar p:1 +Project\n|kbn| {today} Bar +Project\n".format(today=self.today))
def test_add_dep10(self): def test_add_dep10(self):
""" """
...@@ -204,42 +214,64 @@ class AddCommandTest(CommandTest.CommandTest): ...@@ -204,42 +214,64 @@ class AddCommandTest(CommandTest.CommandTest):
command = AddCommand.AddCommand(["Foo @Context"], self.todolist, lambda t: t, self.error) command = AddCommand.AddCommand(["Foo @Context"], self.todolist, lambda t: t, self.error)
command.execute() command.execute()
command = AddCommand.AddCommand(["Bar before:x2k"], self.todolist, self.out, self.error) command = AddCommand.AddCommand(["Bar before:2a2"], self.todolist, self.out, self.error)
command.execute() command.execute()
command = ListCommand.ListCommand(["Bar"], self.todolist, self.out, self.error) command = ListCommand.ListCommand(["Bar"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.output, "|5dc| {today} Bar p:1 @Context\n|5dc| {today} Bar @Context\n".format(today=self.today)) self.assertEqual(self.output, "|wb3| {today} Bar p:1 @Context\n|wb3| {today} Bar @Context\n".format(today=self.today))
def test_add_reldate1(self): def test_add_reldate1(self):
command = AddCommand.AddCommand(["Foo due:today"], self.todolist, self.out, self.error) command = AddCommand.AddCommand(["Foo due:today"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.todolist.todo(1).source(), self.today + " Foo due:" + self.today) self.assertEqual(self.todolist.todo(1).source(), self.today + " Foo due:" + self.today)
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_add_reldate2(self): def test_add_reldate2(self):
command = AddCommand.AddCommand(["Foo t:today due:today"], self.todolist, self.out, self.error) command = AddCommand.AddCommand(["Foo t:today due:today"], self.todolist, self.out, self.error)
command.execute() command.execute()
result = "| 1| {} Foo t:{} due:{}\n".format(self.today, self.today, self.today) result = "| 1| {} Foo t:{} due:{}\n".format(self.today, self.today, self.today)
self.assertEquals(self.output, result) self.assertEqual(self.output, result)
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_add_empty(self): def test_add_empty(self):
command = AddCommand.AddCommand([], self.todolist, self.out, self.error) command = AddCommand.AddCommand([], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.output, "") self.assertEqual(self.output, "")
self.assertEquals(self.errors, command.usage() + "\n") self.assertEqual(self.errors, command.usage() + "\n")
def test_add_unicode(self):
command = AddCommand.AddCommand([u("Special \u25c4")], self.todolist, self.out, self.error)
command.execute()
self.assertEqual(self.output, utf8(u("| 1| {} Special \u25c4\n").format(self.today)))
self.assertEqual(self.errors, "")
@mock.patch("topydo.commands.AddCommand.stdin", StringIO(u("Fo\u00f3 due:tod id:1\nB\u0105r before:1")))
def test_add_from_stdin(self):
command = AddCommand.AddCommand(["-f", "-"], self.todolist, self.out, self.error)
command.execute()
self.assertEqual(self.output, utf8(u("| 1| {tod} Fo\u00f3 due:{tod} id:1\n| 2| {tod} B\u0105r p:1\n".format(tod=self.today))))
self.assertEqual(self.errors, "")
def test_add_from_file(self):
command = AddCommand.AddCommand(["-f", "test/data/AddCommandTest-from_file.txt"], self.todolist, self.out, self.error)
command.execute()
self.assertEqual(self.output, utf8(u("| 1| {tod} Foo @fo\u00f3b\u0105r due:{tod} id:1\n| 2| {tod} Bar +baz t:{tod} p:1\n".format(tod=self.today))))
self.assertEqual(self.errors, "")
def test_help(self): def test_help(self):
command = AddCommand.AddCommand(["help"], self.todolist, self.out, self.error) command = AddCommand.AddCommand(["help"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.output, "") self.assertEqual(self.output, "")
self.assertEquals(self.errors, command.usage() + "\n\n" + command.help() + "\n") self.assertEqual(self.errors, command.usage() + "\n\n" + command.help() + "\n")
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
...@@ -16,11 +16,11 @@ ...@@ -16,11 +16,11 @@
import unittest import unittest
from topydo.lib.AppendCommand import AppendCommand from topydo.commands.AppendCommand import AppendCommand
import CommandTest from test.CommandTest import CommandTest
from topydo.lib.TodoList import TodoList from topydo.lib.TodoList import TodoList
class AppendCommandTest(CommandTest.CommandTest): class AppendCommandTest(CommandTest):
def setUp(self): def setUp(self):
super(AppendCommandTest, self).setUp() super(AppendCommandTest, self).setUp()
self.todolist = TodoList([]) self.todolist = TodoList([])
...@@ -79,8 +79,8 @@ class AppendCommandTest(CommandTest.CommandTest): ...@@ -79,8 +79,8 @@ class AppendCommandTest(CommandTest.CommandTest):
command = AppendCommand(["help"], self.todolist, self.out, self.error) command = AppendCommand(["help"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.output, "") self.assertEqual(self.output, "")
self.assertEquals(self.errors, command.usage() + "\n\n" + command.help() + "\n") self.assertEqual(self.errors, command.usage() + "\n\n" + command.help() + "\n")
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
...@@ -16,14 +16,14 @@ ...@@ -16,14 +16,14 @@
import unittest import unittest
from topydo.lib.ArchiveCommand import ArchiveCommand from topydo.commands.ArchiveCommand import ArchiveCommand
import CommandTest from test.CommandTest import CommandTest
import TestFacilities from test.TestFacilities import load_file_to_todolist
from topydo.lib.TodoList import TodoList from topydo.lib.TodoList import TodoList
class ArchiveCommandTest(CommandTest.CommandTest): class ArchiveCommandTest(CommandTest):
def test_archive(self): def test_archive(self):
todolist = TestFacilities.load_file_to_todolist("test/data/ArchiveCommandTest.txt") todolist = load_file_to_todolist("test/data/ArchiveCommandTest.txt")
archive = TodoList([]) archive = TodoList([])
command = ArchiveCommand(todolist, archive) command = ArchiveCommand(todolist, archive)
...@@ -31,8 +31,8 @@ class ArchiveCommandTest(CommandTest.CommandTest): ...@@ -31,8 +31,8 @@ class ArchiveCommandTest(CommandTest.CommandTest):
self.assertTrue(todolist.is_dirty()) self.assertTrue(todolist.is_dirty())
self.assertTrue(archive.is_dirty()) self.assertTrue(archive.is_dirty())
self.assertEquals(str(todolist), "x Not complete\n(C) Active") self.assertEqual(str(todolist), "x Not complete\n(C) Active")
self.assertEquals(str(archive), "x 2014-10-19 Complete\nx 2014-10-20 Another one complete") self.assertEqual(str(archive), "x 2014-10-19 Complete\nx 2014-10-20 Another one complete")
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
......
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
#
# 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/>.
""" Tests for the colorscheme functionality. """
import unittest
from topydo.lib.Colors import Colors, NEUTRAL_COLOR
from topydo.lib.Config import config
from test.TopydoTest import TopydoTest
class ColorsTest(TopydoTest):
def test_project_color1(self):
config(p_overrides={('colorscheme', 'project_color'): '2'})
color = Colors().get_project_color()
self.assertEqual(color, '\033[1;38;5;2m')
def test_project_color2(self):
config(p_overrides={('colorscheme', 'project_color'): 'Foo'})
color = Colors().get_project_color()
self.assertEqual(color, NEUTRAL_COLOR)
def test_project_color3(self):
config(p_overrides={('colorscheme', 'project_color'): 'yellow'})
color = Colors().get_project_color()
self.assertEqual(color, '\033[1;33m')
def test_project_color4(self):
config(p_overrides={('colorscheme', 'project_color'): '686'})
color = Colors().get_project_color()
self.assertEqual(color, NEUTRAL_COLOR)
def test_context_color1(self):
config(p_overrides={('colorscheme', 'context_color'): '35'})
color = Colors().get_context_color()
self.assertEqual(color, '\033[1;38;5;35m')
def test_context_color2(self):
config(p_overrides={('colorscheme', 'context_color'): 'Bar'})
color = Colors().get_context_color()
self.assertEqual(color, NEUTRAL_COLOR)
def test_context_color3(self):
config(p_overrides={('colorscheme', 'context_color'): 'magenta'})
color = Colors().get_context_color()
self.assertEqual(color, '\033[1;35m')
def test_context_color4(self):
config(p_overrides={('colorscheme', 'context_color'): '392'})
color = Colors().get_context_color()
self.assertEqual(color, NEUTRAL_COLOR)
def test_metadata_color1(self):
config(p_overrides={('colorscheme', 'metadata_color'): '128'})
color = Colors().get_metadata_color()
self.assertEqual(color, '\033[1;38;5;128m')
def test_metadata_color2(self):
config(p_overrides={('colorscheme', 'metadata_color'): 'Baz'})
color = Colors().get_metadata_color()
self.assertEqual(color, NEUTRAL_COLOR)
def test_metadata_color3(self):
config(p_overrides={('colorscheme', 'metadata_color'): 'light-red'})
color = Colors().get_metadata_color()
self.assertEqual(color, '\033[1;1;31m')
def test_metadata_color4(self):
config(p_overrides={('colorscheme', 'metadata_color'): '777'})
color = Colors().get_metadata_color()
self.assertEqual(color, NEUTRAL_COLOR)
def test_link_color1(self):
config(p_overrides={('colorscheme', 'link_color'): '77'})
color = Colors().get_link_color()
self.assertEqual(color, '\033[4;38;5;77m')
def test_link_color2(self):
config(p_overrides={('colorscheme', 'link_color'): 'FooBar'})
color = Colors().get_link_color()
self.assertEqual(color, NEUTRAL_COLOR)
def test_link_color3(self):
config(p_overrides={('colorscheme', 'link_color'): 'red'})
color = Colors().get_link_color()
self.assertEqual(color, '\033[4;31m')
def test_link_color4(self):
config(p_overrides={('colorscheme', 'link_color'): '777'})
color = Colors().get_link_color()
self.assertEqual(color, NEUTRAL_COLOR)
def test_priority_color1(self):
config("test/data/ColorsTest1.conf")
color = Colors().get_priority_colors()
self.assertEqual(color['A'], '\033[0;38;5;1m')
self.assertEqual(color['B'], '\033[0;38;5;2m')
self.assertEqual(color['C'], '\033[0;38;5;3m')
def test_priority_color2(self):
config("test/data/ColorsTest2.conf")
color = Colors().get_priority_colors()
self.assertEqual(color['A'], '\033[0;35m')
self.assertEqual(color['B'], '\033[0;1;36m')
self.assertEqual(color['C'], '\033[0;37m')
def test_priority_color3(self):
config("test/data/ColorsTest3.conf")
color = Colors().get_priority_colors()
self.assertEqual(color['A'], '\033[0;35m')
self.assertEqual(color['B'], '\033[0;1;36m')
self.assertEqual(color['Z'], NEUTRAL_COLOR)
self.assertEqual(color['D'], '\033[0;31m')
self.assertEqual(color['C'], '\033[0;38;5;7m')
def test_priority_color4(self):
config("test/data/ColorsTest4.conf")
color = Colors().get_priority_colors()
self.assertEqual(color['A'], NEUTRAL_COLOR)
self.assertEqual(color['B'], NEUTRAL_COLOR)
self.assertEqual(color['C'], NEUTRAL_COLOR)
def test_empty_color_values(self):
config("test/data/ColorsTest5.conf")
pri_color = Colors().get_priority_colors()
project_color = Colors().get_project_color()
context_color = Colors().get_context_color()
link_color = Colors().get_link_color()
metadata_color = Colors().get_metadata_color()
self.assertEqual(pri_color['A'], NEUTRAL_COLOR)
self.assertEqual(pri_color['B'], NEUTRAL_COLOR)
self.assertEqual(pri_color['C'], NEUTRAL_COLOR)
self.assertEqual(project_color, '')
self.assertEqual(context_color, '')
self.assertEqual(link_color, '')
self.assertEqual(metadata_color, '')
def test_empty_colorscheme(self):
config("test/data/config1")
pri_color = Colors().get_priority_colors()
project_color = Colors().get_project_color()
context_color = Colors().get_context_color()
link_color = Colors().get_link_color()
metadata_color = Colors().get_metadata_color()
self.assertEqual(pri_color['A'], '\033[0;36m')
self.assertEqual(pri_color['B'], '\033[0;33m')
self.assertEqual(pri_color['C'], '\033[0;34m')
self.assertEqual(project_color, '\033[1;31m')
self.assertEqual(context_color, '\033[1;35m')
self.assertEqual(link_color, '\033[4;36m')
self.assertEqual(metadata_color, '\033[1;32m')
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import unittest import unittest
from six import PY2
from topydo.lib.Utils import escape_ansi from topydo.lib.Utils import escape_ansi
from test.TopydoTest import TopydoTest from test.TopydoTest import TopydoTest
...@@ -33,5 +34,13 @@ class CommandTest(TopydoTest): ...@@ -33,5 +34,13 @@ class CommandTest(TopydoTest):
if p_error: if p_error:
self.errors += escape_ansi(p_error + "\n") self.errors += escape_ansi(p_error + "\n")
# utility for several commands
def utf8(p_string):
""" Converts a Unicode string to UTF-8 in case of Python 2. """
if PY2:
p_string = p_string.encode('utf-8')
return p_string
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
...@@ -21,13 +21,21 @@ from test.TopydoTest import TopydoTest ...@@ -21,13 +21,21 @@ from test.TopydoTest import TopydoTest
class ConfigTest(TopydoTest): class ConfigTest(TopydoTest):
def test_config1(self): def test_config1(self):
self.assertEquals(config("test/data/config1").default_command(), 'do') self.assertEqual(config("test/data/config1").default_command(), 'do')
def test_config2(self): def test_config2(self):
self.assertNotEquals(config("").default_command(), 'do') self.assertNotEqual(config("").default_command(), 'do')
def test_config3(self): def test_config3(self):
self.assertTrue(config("test/data/config2").ignore_weekends()) self.assertTrue(config("test/data/config2").ignore_weekends())
def test_config4(self):
""" Test that value in file is overridden by parameter. """
overrides = {
('topydo', 'default_command'): 'edit'
}
self.assertEqual(config("test/data/config1", p_overrides=overrides).default_command(), 'edit')
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
...@@ -15,10 +15,11 @@ ...@@ -15,10 +15,11 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import unittest import unittest
from six import u
import CommandTest from test.CommandTest import CommandTest
from topydo.lib.Config import config from topydo.lib.Config import config
from topydo.lib.DeleteCommand import DeleteCommand from topydo.commands.DeleteCommand import DeleteCommand
from topydo.lib.TodoList import TodoList from topydo.lib.TodoList import TodoList
from topydo.lib.TodoListBase import InvalidTodoException from topydo.lib.TodoListBase import InvalidTodoException
...@@ -28,7 +29,7 @@ def _yes_prompt(self): ...@@ -28,7 +29,7 @@ def _yes_prompt(self):
def _no_prompt(self): def _no_prompt(self):
return "n" return "n"
class DeleteCommandTest(CommandTest.CommandTest): class DeleteCommandTest(CommandTest):
def setUp(self): def setUp(self):
super(DeleteCommandTest, self).setUp() super(DeleteCommandTest, self).setUp()
todos = [ todos = [
...@@ -43,79 +44,79 @@ class DeleteCommandTest(CommandTest.CommandTest): ...@@ -43,79 +44,79 @@ class DeleteCommandTest(CommandTest.CommandTest):
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.todolist.todo(1).source(), "Bar") self.assertEqual(self.todolist.todo(1).source(), "Bar")
self.assertEquals(self.output, "| 2| Bar p:1\nRemoved: Foo id:1\n") self.assertEqual(self.output, "| 2| Bar p:1\nRemoved: Foo id:1\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_del1_regex(self): def test_del1_regex(self):
command = DeleteCommand(["Foo"], self.todolist, self.out, self.error, _no_prompt) command = DeleteCommand(["Foo"], self.todolist, self.out, self.error, _no_prompt)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.todolist.todo(1).source(), "Bar") self.assertEqual(self.todolist.todo(1).source(), "Bar")
self.assertEquals(self.output, "| 2| Bar p:1\nRemoved: Foo id:1\n") self.assertEqual(self.output, "| 2| Bar p:1\nRemoved: Foo id:1\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_del2(self): def test_del2(self):
command = DeleteCommand(["1"], self.todolist, self.out, self.error, _yes_prompt) command = DeleteCommand(["1"], self.todolist, self.out, self.error, _yes_prompt)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.todolist.count(), 0) self.assertEqual(self.todolist.count(), 0)
self.assertEquals(self.output, "| 2| Bar p:1\nRemoved: Bar\nRemoved: Foo\n") self.assertEqual(self.output, "| 2| Bar p:1\nRemoved: Bar\nRemoved: Foo\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_del3(self): def test_del3(self):
command = DeleteCommand(["-f", "1"], self.todolist, self.out, self.error, _yes_prompt) command = DeleteCommand(["-f", "1"], self.todolist, self.out, self.error, _yes_prompt)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.todolist.count(), 1) # force won't delete subtasks self.assertEqual(self.todolist.count(), 1) # force won't delete subtasks
self.assertEquals(self.output, "| 2| Bar p:1\nRemoved: Foo id:1\n") self.assertEqual(self.output, "| 2| Bar p:1\nRemoved: Foo id:1\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_del4(self): def test_del4(self):
command = DeleteCommand(["--force", "1"], self.todolist, self.out, self.error, _yes_prompt) command = DeleteCommand(["--force", "1"], self.todolist, self.out, self.error, _yes_prompt)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.todolist.count(), 1) # force won't delete subtasks self.assertEqual(self.todolist.count(), 1) # force won't delete subtasks
self.assertEquals(self.output, "| 2| Bar p:1\nRemoved: Foo id:1\n") self.assertEqual(self.output, "| 2| Bar p:1\nRemoved: Foo id:1\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_del5(self): def test_del5(self):
command = DeleteCommand(["2"], self.todolist, self.out, self.error) command = DeleteCommand(["2"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.todolist.todo(1).source(), "Foo") self.assertEqual(self.todolist.todo(1).source(), "Foo")
self.assertEquals(self.output, "Removed: Bar p:1\nThe following todo item(s) became active:\n| 1| Foo\n") self.assertEqual(self.output, "Removed: Bar p:1\nThe following todo item(s) became active:\n| 1| Foo\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_del7(self): def test_del7(self):
command = DeleteCommand(["99"], self.todolist, self.out, self.error) command = DeleteCommand(["99"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "") self.assertEqual(self.output, "")
self.assertEquals(self.errors, "Invalid todo number given.\n") self.assertEqual(self.errors, "Invalid todo number given.\n")
def test_del8(self): def test_del8(self):
command = DeleteCommand(["A"], self.todolist, self.out, self.error) command = DeleteCommand(["A"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "") self.assertEqual(self.output, "")
self.assertEquals(self.errors, "Invalid todo number given.\n") self.assertEqual(self.errors, "Invalid todo number given.\n")
def test_del9(self): def test_del9(self):
""" Test deletion with textual IDs. """ """ Test deletion with textual IDs. """
config("test/data/todolist-uid.conf") config("test/data/todolist-uid.conf")
command = DeleteCommand(["b0n"], self.todolist, self.out, self.error) command = DeleteCommand(["8to"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(str(self.todolist), "Foo") self.assertEqual(str(self.todolist), "Foo")
self.assertRaises(InvalidTodoException, self.todolist.todo, 'b0n') self.assertRaises(InvalidTodoException, self.todolist.todo, 'b0n')
def test_multi_del1(self): def test_multi_del1(self):
...@@ -123,14 +124,14 @@ class DeleteCommandTest(CommandTest.CommandTest): ...@@ -123,14 +124,14 @@ class DeleteCommandTest(CommandTest.CommandTest):
command = DeleteCommand(["1", "2"], self.todolist, self.out, self.error, _no_prompt) command = DeleteCommand(["1", "2"], self.todolist, self.out, self.error, _no_prompt)
command.execute() command.execute()
self.assertEquals(self.todolist.count(), 0) self.assertEqual(self.todolist.count(), 0)
def test_multi_del2(self): def test_multi_del2(self):
""" Test deletion of multiple items. """ """ Test deletion of multiple items. """
command = DeleteCommand(["1", "2"], self.todolist, self.out, self.error, _yes_prompt) command = DeleteCommand(["1", "2"], self.todolist, self.out, self.error, _yes_prompt)
command.execute() command.execute()
self.assertEquals(self.todolist.count(), 0) self.assertEqual(self.todolist.count(), 0)
def test_multi_del3(self): def test_multi_del3(self):
""" Fail if any of supplied todo numbers is invalid. """ """ Fail if any of supplied todo numbers is invalid. """
...@@ -138,8 +139,8 @@ class DeleteCommandTest(CommandTest.CommandTest): ...@@ -138,8 +139,8 @@ class DeleteCommandTest(CommandTest.CommandTest):
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "") self.assertEqual(self.output, "")
self.assertEquals(self.errors, "Invalid todo number given: 99.\n") self.assertEqual(self.errors, "Invalid todo number given: 99.\n")
def test_multi_del4(self): def test_multi_del4(self):
""" Check output when all supplied todo numbers are invalid. """ """ Check output when all supplied todo numbers are invalid. """
...@@ -147,8 +148,17 @@ class DeleteCommandTest(CommandTest.CommandTest): ...@@ -147,8 +148,17 @@ class DeleteCommandTest(CommandTest.CommandTest):
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "") self.assertEqual(self.output, "")
self.assertEquals(self.errors, "Invalid todo number given: 99.\nInvalid todo number given: A.\n") self.assertEqual(self.errors, "Invalid todo number given: 99.\nInvalid todo number given: A.\n")
def test_multi_del5(self):
""" Throw an error with invalid argument containing special characters. """
command = DeleteCommand([u("Fo\u00d3B\u0105r"), "Bar"], self.todolist, self.out, self.error, None)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEqual(self.output, "")
self.assertEqual(self.errors, u("Invalid todo number given: Fo\u00d3B\u0105r.\n"))
def test_empty(self): def test_empty(self):
command = DeleteCommand([], self.todolist, self.out, self.error) command = DeleteCommand([], self.todolist, self.out, self.error)
...@@ -156,14 +166,14 @@ class DeleteCommandTest(CommandTest.CommandTest): ...@@ -156,14 +166,14 @@ class DeleteCommandTest(CommandTest.CommandTest):
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertFalse(self.output) self.assertFalse(self.output)
self.assertEquals(self.errors, command.usage() + "\n") self.assertEqual(self.errors, command.usage() + "\n")
def test_help(self): def test_help(self):
command = DeleteCommand(["help"], self.todolist, self.out, self.error) command = DeleteCommand(["help"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.output, "") self.assertEqual(self.output, "")
self.assertEquals(self.errors, command.usage() + "\n\n" + command.help() + "\n") self.assertEqual(self.errors, command.usage() + "\n\n" + command.help() + "\n")
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
...@@ -16,11 +16,11 @@ ...@@ -16,11 +16,11 @@
import unittest import unittest
import CommandTest from topydo.commands.DepCommand import DepCommand
from topydo.lib.DepCommand import DepCommand from test.CommandTest import CommandTest
from topydo.lib.TodoList import TodoList from topydo.lib.TodoList import TodoList
class DepCommandTest(CommandTest.CommandTest): class DepCommandTest(CommandTest):
def setUp(self): def setUp(self):
super(DepCommandTest, self).setUp() super(DepCommandTest, self).setUp()
todos = [ todos = [
...@@ -40,8 +40,8 @@ class DepCommandTest(CommandTest.CommandTest): ...@@ -40,8 +40,8 @@ class DepCommandTest(CommandTest.CommandTest):
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertTrue(self.todolist.todo(4).has_tag('p', '1')) self.assertTrue(self.todolist.todo(4).has_tag('p', '1'))
self.assertEquals(self.output, "") self.assertEqual(self.output, "")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_add2(self): def test_add2(self):
command = DepCommand(["add", "1", "4"], self.todolist, self.out, self.error) command = DepCommand(["add", "1", "4"], self.todolist, self.out, self.error)
...@@ -49,32 +49,32 @@ class DepCommandTest(CommandTest.CommandTest): ...@@ -49,32 +49,32 @@ class DepCommandTest(CommandTest.CommandTest):
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertTrue(self.todolist.todo(4).has_tag('p', '1')) self.assertTrue(self.todolist.todo(4).has_tag('p', '1'))
self.assertEquals(self.output, "") self.assertEqual(self.output, "")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_add3(self): def test_add3(self):
command = DepCommand(["add", "99", "3"], self.todolist, self.out, self.error) command = DepCommand(["add", "99", "3"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "") self.assertEqual(self.output, "")
self.assertEquals(self.errors, "Invalid todo number given.\n") self.assertEqual(self.errors, "Invalid todo number given.\n")
def test_add4(self): def test_add4(self):
command = DepCommand(["add", "A", "3"], self.todolist, self.out, self.error) command = DepCommand(["add", "A", "3"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "") self.assertEqual(self.output, "")
self.assertEquals(self.errors, "Invalid todo number given.\n") self.assertEqual(self.errors, "Invalid todo number given.\n")
def test_add5(self): def test_add5(self):
command = DepCommand(["add", "1"], self.todolist, self.out, self.error) command = DepCommand(["add", "1"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "") self.assertEqual(self.output, "")
self.assertEquals(self.errors, command.usage() + "\n") self.assertEqual(self.errors, command.usage() + "\n")
def test_add6(self): def test_add6(self):
command = DepCommand(["add", "1", "after", "4"], self.todolist, self.out, self.error) command = DepCommand(["add", "1", "after", "4"], self.todolist, self.out, self.error)
...@@ -82,8 +82,8 @@ class DepCommandTest(CommandTest.CommandTest): ...@@ -82,8 +82,8 @@ class DepCommandTest(CommandTest.CommandTest):
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertTrue(self.todolist.todo(4).has_tag('p', '1')) self.assertTrue(self.todolist.todo(4).has_tag('p', '1'))
self.assertEquals(self.output, "") self.assertEqual(self.output, "")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_add7(self): def test_add7(self):
command = DepCommand(["add", "1", "before", "4"], self.todolist, self.out, self.error) command = DepCommand(["add", "1", "before", "4"], self.todolist, self.out, self.error)
...@@ -91,8 +91,8 @@ class DepCommandTest(CommandTest.CommandTest): ...@@ -91,8 +91,8 @@ class DepCommandTest(CommandTest.CommandTest):
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertTrue(self.todolist.todo(1).has_tag('p', '2')) self.assertTrue(self.todolist.todo(1).has_tag('p', '2'))
self.assertEquals(self.output, "") self.assertEqual(self.output, "")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_add8(self): def test_add8(self):
command = DepCommand(["add", "1", "partof", "4"], self.todolist, self.out, self.error) command = DepCommand(["add", "1", "partof", "4"], self.todolist, self.out, self.error)
...@@ -100,8 +100,8 @@ class DepCommandTest(CommandTest.CommandTest): ...@@ -100,8 +100,8 @@ class DepCommandTest(CommandTest.CommandTest):
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertTrue(self.todolist.todo(1).has_tag('p', '2')) self.assertTrue(self.todolist.todo(1).has_tag('p', '2'))
self.assertEquals(self.output, "") self.assertEqual(self.output, "")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_add9(self): def test_add9(self):
command = DepCommand(["add", "Foo", "to", "4"], self.todolist, self.out, self.error) command = DepCommand(["add", "Foo", "to", "4"], self.todolist, self.out, self.error)
...@@ -109,8 +109,8 @@ class DepCommandTest(CommandTest.CommandTest): ...@@ -109,8 +109,8 @@ class DepCommandTest(CommandTest.CommandTest):
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertTrue(self.todolist.todo(4).has_tag('p', '1')) self.assertTrue(self.todolist.todo(4).has_tag('p', '1'))
self.assertEquals(self.output, "") self.assertEqual(self.output, "")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def rm_helper(self, p_args): def rm_helper(self, p_args):
""" """
...@@ -124,8 +124,8 @@ class DepCommandTest(CommandTest.CommandTest): ...@@ -124,8 +124,8 @@ class DepCommandTest(CommandTest.CommandTest):
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertTrue(self.todolist.todo(1).has_tag('id', '1')) self.assertTrue(self.todolist.todo(1).has_tag('id', '1'))
self.assertFalse(self.todolist.todo(3).has_tag('p', '1')) self.assertFalse(self.todolist.todo(3).has_tag('p', '1'))
self.assertEquals(self.output, "") self.assertEqual(self.output, "")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_rm1(self): def test_rm1(self):
self.rm_helper(["rm", "1", "to", "3"]) self.rm_helper(["rm", "1", "to", "3"])
...@@ -144,64 +144,64 @@ class DepCommandTest(CommandTest.CommandTest): ...@@ -144,64 +144,64 @@ class DepCommandTest(CommandTest.CommandTest):
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "") self.assertEqual(self.output, "")
self.assertEquals(self.errors, "Invalid todo number given.\n") self.assertEqual(self.errors, "Invalid todo number given.\n")
def test_rm4(self): def test_rm4(self):
command = DepCommand(["rm", "A", "3"], self.todolist, self.out, self.error) command = DepCommand(["rm", "A", "3"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "") self.assertEqual(self.output, "")
self.assertEquals(self.errors, "Invalid todo number given.\n") self.assertEqual(self.errors, "Invalid todo number given.\n")
def test_rm5(self): def test_rm5(self):
command = DepCommand(["rm", "1"], self.todolist, self.out, self.error) command = DepCommand(["rm", "1"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "") self.assertEqual(self.output, "")
self.assertEquals(self.errors, command.usage() + "\n") self.assertEqual(self.errors, command.usage() + "\n")
def test_ls1(self): def test_ls1(self):
command = DepCommand(["ls", "1", "to"], self.todolist, self.out, self.error) command = DepCommand(["ls", "1", "to"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "| 2| Bar p:1\n| 3| Baz p:1\n") self.assertEqual(self.output, "| 2| Bar p:1\n| 3| Baz p:1\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_ls2(self): def test_ls2(self):
command = DepCommand(["ls", "99", "to"], self.todolist, self.out, self.error) command = DepCommand(["ls", "99", "to"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "") self.assertEqual(self.output, "")
self.assertEquals(self.errors, "Invalid todo number given.\n") self.assertEqual(self.errors, "Invalid todo number given.\n")
def test_ls3(self): def test_ls3(self):
command = DepCommand(["ls", "to", "3"], self.todolist, self.out, self.error) command = DepCommand(["ls", "to", "3"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "| 1| Foo id:1\n") self.assertEqual(self.output, "| 1| Foo id:1\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_ls4(self): def test_ls4(self):
command = DepCommand(["ls", "to", "99"], self.todolist, self.out, self.error) command = DepCommand(["ls", "to", "99"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "") self.assertEqual(self.output, "")
self.assertEquals(self.errors, "Invalid todo number given.\n") self.assertEqual(self.errors, "Invalid todo number given.\n")
def test_ls5(self): def test_ls5(self):
command = DepCommand(["ls", "1"], self.todolist, self.out, self.error) command = DepCommand(["ls", "1"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "") self.assertEqual(self.output, "")
self.assertEquals(self.errors, command.usage() + "\n") self.assertEqual(self.errors, command.usage() + "\n")
def test_ls6(self): def test_ls6(self):
command = DepCommand(["ls"], self.todolist, self.out, self.error) command = DepCommand(["ls"], self.todolist, self.out, self.error)
...@@ -209,7 +209,7 @@ class DepCommandTest(CommandTest.CommandTest): ...@@ -209,7 +209,7 @@ class DepCommandTest(CommandTest.CommandTest):
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertFalse(self.output) self.assertFalse(self.output)
self.assertEquals(self.errors, command.usage() + "\n") self.assertEqual(self.errors, command.usage() + "\n")
def gc_helper(self, p_subcommand): def gc_helper(self, p_subcommand):
command = DepCommand([p_subcommand], self.todolist, self.out, self.error) command = DepCommand([p_subcommand], self.todolist, self.out, self.error)
...@@ -246,8 +246,8 @@ class DepCommandTest(CommandTest.CommandTest): ...@@ -246,8 +246,8 @@ class DepCommandTest(CommandTest.CommandTest):
command = DepCommand(["help"], self.todolist, self.out, self.error) command = DepCommand(["help"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.output, "") self.assertEqual(self.output, "")
self.assertEquals(self.errors, command.usage() + "\n\n" + command.help() + "\n") self.assertEqual(self.errors, command.usage() + "\n\n" + command.help() + "\n")
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
...@@ -15,12 +15,13 @@ ...@@ -15,12 +15,13 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import unittest import unittest
from six import u
import CommandTest from topydo.commands.DepriCommand import DepriCommand
from topydo.lib.DepriCommand import DepriCommand from test.CommandTest import CommandTest
from topydo.lib.TodoList import TodoList from topydo.lib.TodoList import TodoList
class DepriCommandTest(CommandTest.CommandTest): class DepriCommandTest(CommandTest):
def setUp(self): def setUp(self):
super(DepriCommandTest, self).setUp() super(DepriCommandTest, self).setUp()
todos = [ todos = [
...@@ -36,37 +37,37 @@ class DepriCommandTest(CommandTest.CommandTest): ...@@ -36,37 +37,37 @@ class DepriCommandTest(CommandTest.CommandTest):
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.todolist.todo(1).priority(), None) self.assertEqual(self.todolist.todo(1).priority(), None)
self.assertEquals(self.output, "Priority removed.\n| 1| Foo\n") self.assertEqual(self.output, "Priority removed.\n| 1| Foo\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_depri2(self): def test_depri2(self):
command = DepriCommand(["2"], self.todolist, self.out, self.error) command = DepriCommand(["2"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.todolist.todo(2).priority(), None) self.assertEqual(self.todolist.todo(2).priority(), None)
self.assertEquals(self.output, "") self.assertEqual(self.output, "")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_depri3(self): def test_depri3(self):
command = DepriCommand(["Foo"], self.todolist, self.out, self.error) command = DepriCommand(["Foo"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.todolist.todo(1).priority(), None) self.assertEqual(self.todolist.todo(1).priority(), None)
self.assertEquals(self.output, "Priority removed.\n| 1| Foo\n") self.assertEqual(self.output, "Priority removed.\n| 1| Foo\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_depri4(self): def test_depri4(self):
command = DepriCommand(["1","Baz"], self.todolist, self.out, self.error) command = DepriCommand(["1","Baz"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.todolist.todo(1).priority(), None) self.assertEqual(self.todolist.todo(1).priority(), None)
self.assertEquals(self.todolist.todo(3).priority(), None) self.assertEqual(self.todolist.todo(3).priority(), None)
self.assertEquals(self.output, "Priority removed.\n| 1| Foo\nPriority removed.\n| 3| Baz\n") self.assertEqual(self.output, "Priority removed.\n| 1| Foo\nPriority removed.\n| 3| Baz\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_invalid1(self): def test_invalid1(self):
...@@ -75,7 +76,7 @@ class DepriCommandTest(CommandTest.CommandTest): ...@@ -75,7 +76,7 @@ class DepriCommandTest(CommandTest.CommandTest):
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertFalse(self.output) self.assertFalse(self.output)
self.assertEquals(self.errors, "Invalid todo number given.\n") self.assertEqual(self.errors, "Invalid todo number given.\n")
def test_invalid2(self): def test_invalid2(self):
command = DepriCommand(["99", "1"], self.todolist, self.out, self.error) command = DepriCommand(["99", "1"], self.todolist, self.out, self.error)
...@@ -83,7 +84,7 @@ class DepriCommandTest(CommandTest.CommandTest): ...@@ -83,7 +84,7 @@ class DepriCommandTest(CommandTest.CommandTest):
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertFalse(self.output) self.assertFalse(self.output)
self.assertEquals(self.errors, "Invalid todo number given: 99.\n") self.assertEqual(self.errors, "Invalid todo number given: 99.\n")
def test_invalid3(self): def test_invalid3(self):
command = DepriCommand(["99", "FooBar"], self.todolist, self.out, self.error) command = DepriCommand(["99", "FooBar"], self.todolist, self.out, self.error)
...@@ -91,7 +92,16 @@ class DepriCommandTest(CommandTest.CommandTest): ...@@ -91,7 +92,16 @@ class DepriCommandTest(CommandTest.CommandTest):
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertFalse(self.output) self.assertFalse(self.output)
self.assertEquals(self.errors, "Invalid todo number given: 99.\nInvalid todo number given: FooBar.\n") self.assertEqual(self.errors, "Invalid todo number given: 99.\nInvalid todo number given: FooBar.\n")
def test_invalid4(self):
""" Throw an error with invalid argument containing special characters. """
command = DepriCommand([u("Fo\u00d3B\u0105r"), "Bar"], self.todolist, self.out, self.error, None)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertFalse(self.output)
self.assertEqual(self.errors, u("Invalid todo number given: Fo\u00d3B\u0105r.\n"))
def test_empty(self): def test_empty(self):
command = DepriCommand([], self.todolist, self.out, self.error) command = DepriCommand([], self.todolist, self.out, self.error)
...@@ -99,14 +109,14 @@ class DepriCommandTest(CommandTest.CommandTest): ...@@ -99,14 +109,14 @@ class DepriCommandTest(CommandTest.CommandTest):
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertFalse(self.output) self.assertFalse(self.output)
self.assertEquals(self.errors, command.usage() + "\n") self.assertEqual(self.errors, command.usage() + "\n")
def test_help(self): def test_help(self):
command = DepriCommand(["help"], self.todolist, self.out, self.error) command = DepriCommand(["help"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.output, "") self.assertEqual(self.output, "")
self.assertEquals(self.errors, command.usage() + "\n\n" + command.help() + "\n") self.assertEqual(self.errors, command.usage() + "\n\n" + command.help() + "\n")
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
...@@ -16,9 +16,10 @@ ...@@ -16,9 +16,10 @@
from datetime import date, timedelta from datetime import date, timedelta
import unittest import unittest
from six import u
import CommandTest from topydo.commands.DoCommand import DoCommand
from topydo.lib.DoCommand import DoCommand from test.CommandTest import CommandTest
from topydo.lib.TodoList import TodoList from topydo.lib.TodoList import TodoList
def _yes_prompt(self): def _yes_prompt(self):
...@@ -27,7 +28,7 @@ def _yes_prompt(self): ...@@ -27,7 +28,7 @@ def _yes_prompt(self):
def _no_prompt(self): def _no_prompt(self):
return "n" return "n"
class DoCommandTest(CommandTest.CommandTest): class DoCommandTest(CommandTest):
def setUp(self): def setUp(self):
super(DoCommandTest, self).setUp() super(DoCommandTest, self).setUp()
todos = [ todos = [
...@@ -57,9 +58,9 @@ class DoCommandTest(CommandTest.CommandTest): ...@@ -57,9 +58,9 @@ class DoCommandTest(CommandTest.CommandTest):
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertTrue(self.todolist.todo(3).is_completed()) self.assertTrue(self.todolist.todo(3).is_completed())
self.assertEquals(self.output, "Completed: x {} Baz p:1\n".format( self.assertEqual(self.output, "Completed: x {} Baz p:1\n".format(
self.today)) self.today))
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_do_subtasks1(self): def test_do_subtasks1(self):
command = DoCommand(["1"], self.todolist, self.out, self.error, _yes_prompt) command = DoCommand(["1"], self.todolist, self.out, self.error, _yes_prompt)
...@@ -72,8 +73,8 @@ class DoCommandTest(CommandTest.CommandTest): ...@@ -72,8 +73,8 @@ class DoCommandTest(CommandTest.CommandTest):
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertFalse(self.todolist.todo(4).is_completed()) self.assertFalse(self.todolist.todo(4).is_completed())
self.assertEquals(self.output, result) self.assertEqual(self.output, result)
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_do_subtasks2(self): def test_do_subtasks2(self):
command = DoCommand(["1"], self.todolist, self.out, self.error, _no_prompt) command = DoCommand(["1"], self.todolist, self.out, self.error, _no_prompt)
...@@ -85,8 +86,8 @@ class DoCommandTest(CommandTest.CommandTest): ...@@ -85,8 +86,8 @@ class DoCommandTest(CommandTest.CommandTest):
self.assertTrue(self.todolist.todo(1).is_completed()) self.assertTrue(self.todolist.todo(1).is_completed())
self.assertFalse(self.todolist.todo(2).is_completed()) self.assertFalse(self.todolist.todo(2).is_completed())
self.assertFalse(self.todolist.todo(3).is_completed()) self.assertFalse(self.todolist.todo(3).is_completed())
self.assertEquals(self.output, result) self.assertEqual(self.output, result)
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_do_subtasks_force1(self): def test_do_subtasks_force1(self):
prompt_shown = False prompt_shown = False
...@@ -99,7 +100,7 @@ class DoCommandTest(CommandTest.CommandTest): ...@@ -99,7 +100,7 @@ class DoCommandTest(CommandTest.CommandTest):
command.execute() command.execute()
self.assertFalse(prompt_shown) self.assertFalse(prompt_shown)
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
self.assertFalse(self.todolist.todo(2).is_completed()) self.assertFalse(self.todolist.todo(2).is_completed())
def test_do_subtasks_force2(self): def test_do_subtasks_force2(self):
...@@ -113,7 +114,7 @@ class DoCommandTest(CommandTest.CommandTest): ...@@ -113,7 +114,7 @@ class DoCommandTest(CommandTest.CommandTest):
command.execute() command.execute()
self.assertFalse(prompt_shown) self.assertFalse(prompt_shown)
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
self.assertFalse(self.todolist.todo(2).is_completed()) self.assertFalse(self.todolist.todo(2).is_completed())
def _recurrence_helper(self, p_flags): def _recurrence_helper(self, p_flags):
...@@ -121,8 +122,8 @@ class DoCommandTest(CommandTest.CommandTest): ...@@ -121,8 +122,8 @@ class DoCommandTest(CommandTest.CommandTest):
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
self.assertEquals(self.todolist.count(), 10) self.assertEqual(self.todolist.count(), 10)
def test_recurrence(self): def test_recurrence(self):
self.assertFalse(self.todolist.todo(4).has_tag('due')) self.assertFalse(self.todolist.todo(4).has_tag('due'))
...@@ -131,7 +132,7 @@ class DoCommandTest(CommandTest.CommandTest): ...@@ -131,7 +132,7 @@ class DoCommandTest(CommandTest.CommandTest):
self.assertTrue(self.todolist.todo(4).is_completed()) self.assertTrue(self.todolist.todo(4).is_completed())
result = "| 10| {today} Recurring! rec:1d due:{tomorrow}\nCompleted: x {today} Recurring! rec:1d\n".format(today=self.today, tomorrow=self.tomorrow) result = "| 10| {today} Recurring! rec:1d due:{tomorrow}\nCompleted: x {today} Recurring! rec:1d\n".format(today=self.today, tomorrow=self.tomorrow)
self.assertEquals(self.output, result) self.assertEqual(self.output, result)
todo = self.todolist.todo(10) todo = self.todolist.todo(10)
self.assertFalse(todo.is_completed()) self.assertFalse(todo.is_completed())
...@@ -140,13 +141,13 @@ class DoCommandTest(CommandTest.CommandTest): ...@@ -140,13 +141,13 @@ class DoCommandTest(CommandTest.CommandTest):
def test_strict_recurrence1(self): def test_strict_recurrence1(self):
self._recurrence_helper(["-s", "8"]) self._recurrence_helper(["-s", "8"])
result = "| 10| {today} Strict due:2014-01-02 rec:1d\nCompleted: x {today} Strict due:2014-01-01 rec:1d\n".format(today=self.today) result = "| 10| {today} Strict due:2014-01-02 rec:1d\nCompleted: x {today} Strict due:2014-01-01 rec:1d\n".format(today=self.today)
self.assertEquals(self.output, result) self.assertEqual(self.output, result)
def test_strict_recurrence2(self): def test_strict_recurrence2(self):
self._recurrence_helper(["--strict", "8"]) self._recurrence_helper(["--strict", "8"])
result = "| 10| {today} Strict due:2014-01-02 rec:1d\nCompleted: x {today} Strict due:2014-01-01 rec:1d\n".format(today=self.today) result = "| 10| {today} Strict due:2014-01-02 rec:1d\nCompleted: x {today} Strict due:2014-01-01 rec:1d\n".format(today=self.today)
self.assertEquals(self.output, result) self.assertEqual(self.output, result)
def test_invalid1(self): def test_invalid1(self):
command = DoCommand(["99"], self.todolist, self.out, self.error) command = DoCommand(["99"], self.todolist, self.out, self.error)
...@@ -154,7 +155,7 @@ class DoCommandTest(CommandTest.CommandTest): ...@@ -154,7 +155,7 @@ class DoCommandTest(CommandTest.CommandTest):
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertFalse(self.output) self.assertFalse(self.output)
self.assertEquals(self.errors, "Invalid todo number given.\n") self.assertEqual(self.errors, "Invalid todo number given.\n")
def test_invalid2(self): def test_invalid2(self):
command = DoCommand(["AAA"], self.todolist, self.out, self.error) command = DoCommand(["AAA"], self.todolist, self.out, self.error)
...@@ -162,7 +163,7 @@ class DoCommandTest(CommandTest.CommandTest): ...@@ -162,7 +163,7 @@ class DoCommandTest(CommandTest.CommandTest):
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertFalse(self.output) self.assertFalse(self.output)
self.assertEquals(self.errors, "Invalid todo number given.\n") self.assertEqual(self.errors, "Invalid todo number given.\n")
def test_invalid3(self): def test_invalid3(self):
command = DoCommand(["01"], self.todolist, self.out, self.error, _yes_prompt) command = DoCommand(["01"], self.todolist, self.out, self.error, _yes_prompt)
...@@ -170,7 +171,7 @@ class DoCommandTest(CommandTest.CommandTest): ...@@ -170,7 +171,7 @@ class DoCommandTest(CommandTest.CommandTest):
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertFalse(self.output) self.assertFalse(self.output)
self.assertEquals(self.errors, "Invalid todo number given.\n") self.assertEqual(self.errors, "Invalid todo number given.\n")
def test_activated_todos1(self): def test_activated_todos1(self):
command = DoCommand(["2"], self.todolist, self.out, self.error) command = DoCommand(["2"], self.todolist, self.out, self.error)
...@@ -178,30 +179,30 @@ class DoCommandTest(CommandTest.CommandTest): ...@@ -178,30 +179,30 @@ class DoCommandTest(CommandTest.CommandTest):
first_output = "Completed: x {} Bar p:1\n".format(self.today) first_output = "Completed: x {} Bar p:1\n".format(self.today)
self.assertEquals(self.output, first_output) self.assertEqual(self.output, first_output)
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
command = DoCommand(["3"], self.todolist, self.out, self.error) command = DoCommand(["3"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.output, first_output + "Completed: x {} Baz p:1\nThe following todo item(s) became active:\n| 1| Foo id:1\n".format(self.today)) self.assertEqual(self.output, first_output + "Completed: x {} Baz p:1\nThe following todo item(s) became active:\n| 1| Foo id:1\n".format(self.today))
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_activated_todos2(self): def test_activated_todos2(self):
command = DoCommand(["7"], self.todolist, self.out, self.error) command = DoCommand(["7"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.output, "Completed: x {} Subtodo of inactive p:2\n".format(self.today)) self.assertEqual(self.output, "Completed: x {} Subtodo of inactive p:2\n".format(self.today))
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_already_complete(self): def test_already_complete(self):
command = DoCommand(["5"], self.todolist, self.out, self.error) command = DoCommand(["5"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.todolist.todo(5).completion_date(), date(2014, 10, 18)) self.assertEqual(self.todolist.todo(5).completion_date(), date(2014, 10, 18))
self.assertFalse(self.output) self.assertFalse(self.output)
self.assertEquals(self.errors, "Todo has already been completed.\n") self.assertEqual(self.errors, "Todo has already been completed.\n")
def test_do_regex1(self): def test_do_regex1(self):
command = DoCommand(["baz"], self.todolist, self.out, self.error) command = DoCommand(["baz"], self.todolist, self.out, self.error)
...@@ -209,40 +210,40 @@ class DoCommandTest(CommandTest.CommandTest): ...@@ -209,40 +210,40 @@ class DoCommandTest(CommandTest.CommandTest):
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertTrue(self.todolist.todo(3).is_completed()) self.assertTrue(self.todolist.todo(3).is_completed())
self.assertEquals(self.output, "Completed: x {} Baz p:1\n".format(self.today)) self.assertEqual(self.output, "Completed: x {} Baz p:1\n".format(self.today))
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_do_custom_date1(self): def test_do_custom_date1(self):
command = DoCommand(["-d", "2014-11-18", "3"], self.todolist, self.out, self.error) command = DoCommand(["-d", "2014-11-18", "3"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, "Completed: x 2014-11-18 Baz p:1\n") self.assertEqual(self.output, "Completed: x 2014-11-18 Baz p:1\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_do_custom_date2(self): def test_do_custom_date2(self):
command = DoCommand(["-d", "2014-11-18", "1"], self.todolist, self.out, self.error, _yes_prompt) command = DoCommand(["-d", "2014-11-18", "1"], self.todolist, self.out, self.error, _yes_prompt)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, "| 2| Bar p:1\n| 3| Baz p:1\nCompleted: x 2014-11-18 Bar p:1\nCompleted: x 2014-11-18 Baz p:1\nCompleted: x 2014-11-18 Foo id:1\n") self.assertEqual(self.output, "| 2| Bar p:1\n| 3| Baz p:1\nCompleted: x 2014-11-18 Bar p:1\nCompleted: x 2014-11-18 Baz p:1\nCompleted: x 2014-11-18 Foo id:1\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_do_custom_date3(self): def test_do_custom_date3(self):
command = DoCommand(["--date=2014-11-18", "3"], self.todolist, self.out, self.error) command = DoCommand(["--date=2014-11-18", "3"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, "Completed: x 2014-11-18 Baz p:1\n") self.assertEqual(self.output, "Completed: x 2014-11-18 Baz p:1\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_do_custom_date4(self): def test_do_custom_date4(self):
command = DoCommand(["-d", "foo", "3"], self.todolist, self.out, self.error) command = DoCommand(["-d", "foo", "3"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, "Completed: x {} Baz p:1\n".format(self.today)) self.assertEqual(self.output, "Completed: x {} Baz p:1\n".format(self.today))
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_do_custom_date5(self): def test_do_custom_date5(self):
""" """
...@@ -253,8 +254,8 @@ class DoCommandTest(CommandTest.CommandTest): ...@@ -253,8 +254,8 @@ class DoCommandTest(CommandTest.CommandTest):
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, "| 10| {today} Recurring! rec:1d due:{today}\nCompleted: x {yesterday} Recurring! rec:1d\n".format(today=self.today, yesterday=self.yesterday)) self.assertEqual(self.output, "| 10| {today} Recurring! rec:1d due:{today}\nCompleted: x {yesterday} Recurring! rec:1d\n".format(today=self.today, yesterday=self.yesterday))
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_do_custom_date6(self): def test_do_custom_date6(self):
""" """
...@@ -266,8 +267,8 @@ class DoCommandTest(CommandTest.CommandTest): ...@@ -266,8 +267,8 @@ class DoCommandTest(CommandTest.CommandTest):
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, "| 10| {today} Recurring! rec:1d due:{today}\nCompleted: x {yesterday} Recurring! rec:1d\n".format(today=self.today, yesterday=self.yesterday)) self.assertEqual(self.output, "| 10| {today} Recurring! rec:1d due:{today}\nCompleted: x {yesterday} Recurring! rec:1d\n".format(today=self.today, yesterday=self.yesterday))
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_do_custom_date7(self): def test_do_custom_date7(self):
""" """
...@@ -278,8 +279,8 @@ class DoCommandTest(CommandTest.CommandTest): ...@@ -278,8 +279,8 @@ class DoCommandTest(CommandTest.CommandTest):
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, "| 10| {today} Strict due:2014-01-02 rec:1d\nCompleted: x {yesterday} Strict due:2014-01-01 rec:1d\n".format(today=self.today, yesterday=self.yesterday)) self.assertEqual(self.output, "| 10| {today} Strict due:2014-01-02 rec:1d\nCompleted: x {yesterday} Strict due:2014-01-01 rec:1d\n".format(today=self.today, yesterday=self.yesterday))
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_multi_do1(self): def test_multi_do1(self):
command = DoCommand(["1", "3"], self.todolist, self.out, self.error, _yes_prompt) command = DoCommand(["1", "3"], self.todolist, self.out, self.error, _yes_prompt)
...@@ -289,7 +290,7 @@ class DoCommandTest(CommandTest.CommandTest): ...@@ -289,7 +290,7 @@ class DoCommandTest(CommandTest.CommandTest):
self.assertTrue(self.todolist.todo(2).is_completed()) self.assertTrue(self.todolist.todo(2).is_completed())
self.assertTrue(self.todolist.todo(3).is_completed()) self.assertTrue(self.todolist.todo(3).is_completed())
self.assertEquals(self.output, "| 2| Bar p:1\n| 3| Baz p:1\nCompleted: x {today} Bar p:1\nCompleted: x {today} Baz p:1\nCompleted: x {today} Foo id:1\n".format(today=self.today)) self.assertEqual(self.output, "| 2| Bar p:1\n| 3| Baz p:1\nCompleted: x {today} Bar p:1\nCompleted: x {today} Baz p:1\nCompleted: x {today} Foo id:1\n".format(today=self.today))
def test_multi_do2(self): def test_multi_do2(self):
command = DoCommand(["1", "3"], self.todolist, self.out, self.error, _no_prompt) command = DoCommand(["1", "3"], self.todolist, self.out, self.error, _no_prompt)
...@@ -299,21 +300,21 @@ class DoCommandTest(CommandTest.CommandTest): ...@@ -299,21 +300,21 @@ class DoCommandTest(CommandTest.CommandTest):
self.assertFalse(self.todolist.todo(2).is_completed()) self.assertFalse(self.todolist.todo(2).is_completed())
self.assertTrue(self.todolist.todo(3).is_completed()) self.assertTrue(self.todolist.todo(3).is_completed())
self.assertEquals(self.output, "| 2| Bar p:1\n| 3| Baz p:1\nCompleted: x {today} Foo id:1\nCompleted: x {today} Baz p:1\n".format(today=self.today)) self.assertEqual(self.output, "| 2| Bar p:1\n| 3| Baz p:1\nCompleted: x {today} Foo id:1\nCompleted: x {today} Baz p:1\n".format(today=self.today))
def test_multi_do3(self): def test_multi_do3(self):
command = DoCommand(["3", "3"], self.todolist, self.out, self.error, _no_prompt) command = DoCommand(["3", "3"], self.todolist, self.out, self.error, _no_prompt)
command.execute() command.execute()
self.assertTrue(self.todolist.todo(3).is_completed()) self.assertTrue(self.todolist.todo(3).is_completed())
self.assertEquals(self.output, "Completed: x {} Baz p:1\n".format(self.today)) self.assertEqual(self.output, "Completed: x {} Baz p:1\n".format(self.today))
def test_multi_do4(self): def test_multi_do4(self):
command = DoCommand(["99", "3"], self.todolist, self.out, self.error, _no_prompt) command = DoCommand(["99", "3"], self.todolist, self.out, self.error, _no_prompt)
command.execute() command.execute()
self.assertFalse(self.todolist.todo(3).is_completed()) self.assertFalse(self.todolist.todo(3).is_completed())
self.assertEquals(self.errors, "Invalid todo number given: 99.\n") self.assertEqual(self.errors, "Invalid todo number given: 99.\n")
def test_multi_do5(self): def test_multi_do5(self):
""" """
...@@ -322,15 +323,23 @@ class DoCommandTest(CommandTest.CommandTest): ...@@ -322,15 +323,23 @@ class DoCommandTest(CommandTest.CommandTest):
command = DoCommand(["99", "10"], self.todolist, self.out, self.error, _no_prompt) command = DoCommand(["99", "10"], self.todolist, self.out, self.error, _no_prompt)
command.execute() command.execute()
self.assertEquals(self.errors, "Invalid todo number given: 99.\nInvalid todo number given: 10.\n") self.assertEqual(self.errors, "Invalid todo number given: 99.\nInvalid todo number given: 10.\n")
def test_multi_do6(self):
""" Throw an error with invalid argument containing special characters. """
command = DoCommand([u("Fo\u00d3B\u0105r"), "Bar"], self.todolist, self.out, self.error, None)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEqual(self.errors, u("Invalid todo number given: Fo\u00d3B\u0105r.\n"))
def test_invalid_recurrence(self): def test_invalid_recurrence(self):
""" Show error message when an item has an invalid recurrence pattern. """ """ Show error message when an item has an invalid recurrence pattern. """
command = DoCommand(["9"], self.todolist, self.out, self.error, _no_prompt) command = DoCommand(["9"], self.todolist, self.out, self.error, _no_prompt)
command.execute() command.execute()
self.assertEquals(self.output, "Completed: x {} Invalid rec:1\n".format(self.today)) self.assertEqual(self.output, "Completed: x {} Invalid rec:1\n".format(self.today))
self.assertEquals(self.errors, "Warning: todo item has an invalid recurrence pattern.\n") self.assertEqual(self.errors, "Warning: todo item has an invalid recurrence pattern.\n")
def test_empty(self): def test_empty(self):
command = DoCommand([], self.todolist, self.out, self.error) command = DoCommand([], self.todolist, self.out, self.error)
...@@ -338,14 +347,14 @@ class DoCommandTest(CommandTest.CommandTest): ...@@ -338,14 +347,14 @@ class DoCommandTest(CommandTest.CommandTest):
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertFalse(self.output) self.assertFalse(self.output)
self.assertEquals(self.errors, command.usage() + "\n") self.assertEqual(self.errors, command.usage() + "\n")
def test_help(self): def test_help(self):
command = DoCommand(["help"], self.todolist, self.out, self.error) command = DoCommand(["help"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.output, "") self.assertEqual(self.output, "")
self.assertEquals(self.errors, command.usage() + "\n\n" + command.help() + "\n") self.assertEqual(self.errors, command.usage() + "\n\n" + command.help() + "\n")
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
...@@ -15,27 +15,37 @@ ...@@ -15,27 +15,37 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import unittest import unittest
import mock
# We're searching for 'mock'
# pylint: disable=no-name-in-module
try:
from unittest import mock
except ImportError:
import mock
from six import u
import os import os
import CommandTest from topydo.commands.EditCommand import EditCommand
from topydo.lib.EditCommand import EditCommand from test.CommandTest import CommandTest, utf8
from topydo.lib.TodoList import TodoList from topydo.lib.TodoList import TodoList
from topydo.lib.Todo import Todo from topydo.lib.Todo import Todo
from topydo.lib.Config import config from topydo.lib.Config import config
class EditCommandTest(CommandTest.CommandTest): class EditCommandTest(CommandTest):
def setUp(self): def setUp(self):
super(EditCommandTest, self).setUp() super(EditCommandTest, self).setUp()
todos = [ todos = [
"Foo id:1", "Foo id:1",
"Bar p:1 @test", "Bar p:1 @test",
"Baz @test", "Baz @test",
u("Fo\u00f3B\u0105\u017a"),
] ]
self.todolist = TodoList(todos) self.todolist = TodoList(todos)
@mock.patch('topydo.lib.EditCommand.EditCommand._open_in_editor')
@mock.patch('topydo.commands.EditCommand.EditCommand._open_in_editor')
def test_edit1(self, mock_open_in_editor): def test_edit1(self, mock_open_in_editor):
""" Preserve dependencies after editing. """ """ Preserve dependencies after editing. """
mock_open_in_editor.return_value = 0 mock_open_in_editor.return_value = 0
...@@ -44,11 +54,11 @@ class EditCommandTest(CommandTest.CommandTest): ...@@ -44,11 +54,11 @@ class EditCommandTest(CommandTest.CommandTest):
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
self.assertEquals(str(self.todolist), "Bar p:1 @test\nBaz @test\nFoo id:1") self.assertEqual(str(self.todolist), utf8(u("Bar p:1 @test\nBaz @test\nFo\u00f3B\u0105\u017a\nFoo id:1")))
@mock.patch('topydo.lib.EditCommand.EditCommand._todos_from_temp') @mock.patch('topydo.commands.EditCommand.EditCommand._todos_from_temp')
@mock.patch('topydo.lib.EditCommand.EditCommand._open_in_editor') @mock.patch('topydo.commands.EditCommand.EditCommand._open_in_editor')
def test_edit2(self, mock_open_in_editor, mock_todos_from_temp): def test_edit2(self, mock_open_in_editor, mock_todos_from_temp):
""" Edit some todo. """ """ Edit some todo. """
mock_open_in_editor.return_value = 0 mock_open_in_editor.return_value = 0
...@@ -58,8 +68,8 @@ class EditCommandTest(CommandTest.CommandTest): ...@@ -58,8 +68,8 @@ class EditCommandTest(CommandTest.CommandTest):
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
self.assertEquals(str(self.todolist), "Foo id:1\nBaz @test\nLazy Cat") self.assertEqual(str(self.todolist), utf8(u("Foo id:1\nBaz @test\nFo\u00f3B\u0105\u017a\nLazy Cat")))
def test_edit3(self): def test_edit3(self):
""" Throw an error after invalid todo number given as argument. """ """ Throw an error after invalid todo number given as argument. """
...@@ -67,47 +77,70 @@ class EditCommandTest(CommandTest.CommandTest): ...@@ -67,47 +77,70 @@ class EditCommandTest(CommandTest.CommandTest):
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.errors, "Invalid todo number given.\n") self.assertEqual(self.errors, "Invalid todo number given.\n")
def test_edit4(self): def test_edit4(self):
""" Throw an error with pointing invalid argument. """ """ Throw an error with pointing invalid argument. """
command = EditCommand(["Bar","4"], self.todolist, self.out, self.error, None) command = EditCommand(["Bar", "5"], self.todolist, self.out, self.error, None)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.errors, "Invalid todo number given: 4.\n") self.assertEqual(self.errors, "Invalid todo number given: 5.\n")
@mock.patch('topydo.lib.EditCommand.EditCommand._todos_from_temp') @mock.patch('topydo.commands.EditCommand.EditCommand._todos_from_temp')
@mock.patch('topydo.lib.EditCommand.EditCommand._open_in_editor') @mock.patch('topydo.commands.EditCommand.EditCommand._open_in_editor')
def test_edit5(self, mock_open_in_editor, mock_todos_from_temp): def test_edit5(self, mock_open_in_editor, mock_todos_from_temp):
""" Don't let to delete todos acidentally while editing. """ """ Don't let to delete todos acidentally while editing. """
mock_open_in_editor.return_value = 0 mock_open_in_editor.return_value = 0
mock_todos_from_temp.return_value = [Todo('Only one line')] mock_todos_from_temp.return_value = [Todo('Only one line')]
command = EditCommand(["1","Bar"], self.todolist, self.out, self.error, None) command = EditCommand(["1", "Bar"], self.todolist, self.out, self.error, None)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEqual(self.errors, "Number of edited todos is not equal to number of supplied todo IDs.\n")
self.assertEqual(str(self.todolist), utf8(u("Foo id:1\nBar p:1 @test\nBaz @test\nFo\u00f3B\u0105\u017a")))
def test_edit6(self):
""" Throw an error with invalid argument containing special characters. """
command = EditCommand([u("Fo\u00d3B\u0105r"), "Bar"], self.todolist, self.out, self.error, None)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.errors, "Number of edited todos is not equal to number of supplied todo IDs.\n") self.assertEqual(self.errors, u("Invalid todo number given: Fo\u00d3B\u0105r.\n"))
self.assertEquals(str(self.todolist), "Foo id:1\nBar p:1 @test\nBaz @test")
@mock.patch('topydo.commands.EditCommand.EditCommand._todos_from_temp')
@mock.patch('topydo.commands.EditCommand.EditCommand._open_in_editor')
def test_edit7(self, mock_open_in_editor, mock_todos_from_temp):
""" Edit todo with special characters. """
mock_open_in_editor.return_value = 0
mock_todos_from_temp.return_value = [Todo('Lazy Cat')]
command = EditCommand([u("Fo\u00f3B\u0105\u017a")], self.todolist, self.out, self.error, None)
command.execute()
self.assertTrue(self.todolist.is_dirty())
self.assertEqual(self.errors, "")
self.assertEqual(str(self.todolist), utf8(u("Foo id:1\nBar p:1 @test\nBaz @test\nLazy Cat")))
@mock.patch('topydo.lib.EditCommand.EditCommand._todos_from_temp') @mock.patch('topydo.commands.EditCommand.EditCommand._todos_from_temp')
@mock.patch('topydo.lib.EditCommand.EditCommand._open_in_editor') @mock.patch('topydo.commands.EditCommand.EditCommand._open_in_editor')
def test_edit_expr(self, mock_open_in_editor, mock_todos_from_temp): def test_edit_expr(self, mock_open_in_editor, mock_todos_from_temp):
""" Edit todos matching expression. """ """ Edit todos matching expression. """
mock_open_in_editor.return_value = 0 mock_open_in_editor.return_value = 0
mock_todos_from_temp.return_value = [Todo('Lazy Cat'), Todo('Lazy Dog')] mock_todos_from_temp.return_value = [Todo('Lazy Cat'), Todo('Lazy Dog')]
command = EditCommand(["-e","@test"], self.todolist, self.out, self.error, None) command = EditCommand(["-e", "@test"], self.todolist, self.out, self.error, None)
command.execute() command.execute()
expected = "| 2| Lazy Cat\n| 3| Lazy Dog\n" expected = utf8(u("| 3| Lazy Cat\n| 4| Lazy Dog\n"))
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertEqual(self.errors, "") self.assertEqual(self.errors, "")
self.assertEqual(self.output, expected) self.assertEqual(self.output, expected)
self.assertEqual(str(self.todolist), utf8(u("Foo id:1\nFo\u00f3B\u0105\u017a\nLazy Cat\nLazy Dog")))
@mock.patch('topydo.lib.EditCommand.call') @mock.patch('topydo.commands.EditCommand.call')
def test_edit_archive(self, mock_call): def test_edit_archive(self, mock_call):
""" Edit archive file. """ """ Edit archive file. """
mock_call.return_value = 0 mock_call.return_value = 0
...@@ -116,7 +149,7 @@ class EditCommandTest(CommandTest.CommandTest): ...@@ -116,7 +149,7 @@ class EditCommandTest(CommandTest.CommandTest):
os.environ['EDITOR'] = editor os.environ['EDITOR'] = editor
archive = config().archive() archive = config().archive()
command = EditCommand(["-d"], self.todolist, self.out, self.error, None) command = EditCommand([u("-d")], self.todolist, self.out, self.error, None)
command.execute() command.execute()
self.assertEqual(self.errors, "") self.assertEqual(self.errors, "")
......
...@@ -30,7 +30,7 @@ class FilterTest(TopydoTest): ...@@ -30,7 +30,7 @@ class FilterTest(TopydoTest):
relevance = Filter.RelevanceFilter() relevance = Filter.RelevanceFilter()
result = relevance.filter([todo]) result = relevance.filter([todo])
self.assertEquals(result, [todo]) self.assertEqual(result, [todo])
def test_filter4(self): def test_filter4(self):
""" Test case insensitive match. """ """ Test case insensitive match. """
...@@ -40,7 +40,7 @@ class FilterTest(TopydoTest): ...@@ -40,7 +40,7 @@ class FilterTest(TopydoTest):
filtered_todos = grep.filter(todos) filtered_todos = grep.filter(todos)
reference = load_file('test/data/FilterTest1a-result.txt') reference = load_file('test/data/FilterTest1a-result.txt')
self.assertEquals(todolist_to_string(filtered_todos), \ self.assertEqual(todolist_to_string(filtered_todos), \
todolist_to_string(reference)) todolist_to_string(reference))
def test_filter5(self): def test_filter5(self):
...@@ -51,7 +51,7 @@ class FilterTest(TopydoTest): ...@@ -51,7 +51,7 @@ class FilterTest(TopydoTest):
filtered_todos = grep.filter(todos) filtered_todos = grep.filter(todos)
reference = load_file('test/data/FilterTest1b-result.txt') reference = load_file('test/data/FilterTest1b-result.txt')
self.assertEquals(todolist_to_string(filtered_todos), \ self.assertEqual(todolist_to_string(filtered_todos), \
todolist_to_string(reference)) todolist_to_string(reference))
def test_filter6(self): def test_filter6(self):
...@@ -62,7 +62,7 @@ class FilterTest(TopydoTest): ...@@ -62,7 +62,7 @@ class FilterTest(TopydoTest):
filtered_todos = grep.filter(todos) filtered_todos = grep.filter(todos)
reference = load_file('test/data/FilterTest1c-result.txt') reference = load_file('test/data/FilterTest1c-result.txt')
self.assertEquals(todolist_to_string(filtered_todos), \ self.assertEqual(todolist_to_string(filtered_todos), \
todolist_to_string(reference)) todolist_to_string(reference))
def test_filter7(self): def test_filter7(self):
...@@ -73,7 +73,7 @@ class FilterTest(TopydoTest): ...@@ -73,7 +73,7 @@ class FilterTest(TopydoTest):
filtered_todos = depfilter.filter(todolist.todos()) filtered_todos = depfilter.filter(todolist.todos())
reference = load_file('test/data/FilterTest2-result.txt') reference = load_file('test/data/FilterTest2-result.txt')
self.assertEquals(todolist_to_string(filtered_todos), \ self.assertEqual(todolist_to_string(filtered_todos), \
todolist_to_string(reference)) todolist_to_string(reference))
def test_filter8(self): def test_filter8(self):
...@@ -84,7 +84,7 @@ class FilterTest(TopydoTest): ...@@ -84,7 +84,7 @@ class FilterTest(TopydoTest):
filtered_todos = grep.filter(todos) filtered_todos = grep.filter(todos)
reference = load_file('test/data/FilterTest1a-result.txt') reference = load_file('test/data/FilterTest1a-result.txt')
self.assertEquals(todolist_to_string(filtered_todos), \ self.assertEqual(todolist_to_string(filtered_todos), \
todolist_to_string(reference)) todolist_to_string(reference))
def test_filter9(self): def test_filter9(self):
...@@ -94,7 +94,7 @@ class FilterTest(TopydoTest): ...@@ -94,7 +94,7 @@ class FilterTest(TopydoTest):
filtered_todos = instance_filter.filter(todos) filtered_todos = instance_filter.filter(todos)
self.assertEquals(todos[2:], filtered_todos) self.assertEqual(todos[2:], filtered_todos)
def test_filter10(self): def test_filter10(self):
""" Test instance filter """ """ Test instance filter """
...@@ -103,7 +103,7 @@ class FilterTest(TopydoTest): ...@@ -103,7 +103,7 @@ class FilterTest(TopydoTest):
filtered_todos = instance_filter.filter(todos) filtered_todos = instance_filter.filter(todos)
self.assertEquals([], filtered_todos) self.assertEqual([], filtered_todos)
def test_filter11(self): def test_filter11(self):
""" Test instance filter """ """ Test instance filter """
...@@ -112,7 +112,7 @@ class FilterTest(TopydoTest): ...@@ -112,7 +112,7 @@ class FilterTest(TopydoTest):
filtered_todos = instance_filter.filter([]) filtered_todos = instance_filter.filter([])
self.assertEquals([], filtered_todos) self.assertEqual([], filtered_todos)
def test_filter12(self): def test_filter12(self):
""" Test limit filter. """ """ Test limit filter. """
...@@ -121,7 +121,7 @@ class FilterTest(TopydoTest): ...@@ -121,7 +121,7 @@ class FilterTest(TopydoTest):
filtered_todos = limit_filter.filter(todos) filtered_todos = limit_filter.filter(todos)
self.assertEquals([], filtered_todos) self.assertEqual([], filtered_todos)
def test_filter13(self): def test_filter13(self):
""" Test limit filter. """ """ Test limit filter. """
...@@ -130,8 +130,8 @@ class FilterTest(TopydoTest): ...@@ -130,8 +130,8 @@ class FilterTest(TopydoTest):
filtered_todos = limit_filter.filter(todos) filtered_todos = limit_filter.filter(todos)
self.assertEquals(len(filtered_todos), 1) self.assertEqual(len(filtered_todos), 1)
self.assertEquals(filtered_todos[0].source(), '(C) This is part of some +Project') self.assertEqual(filtered_todos[0].source(), '(C) This is part of some +Project')
def test_filter14(self): def test_filter14(self):
""" Test limit filter. """ """ Test limit filter. """
...@@ -140,7 +140,7 @@ class FilterTest(TopydoTest): ...@@ -140,7 +140,7 @@ class FilterTest(TopydoTest):
filtered_todos = limit_filter.filter(todos) filtered_todos = limit_filter.filter(todos)
self.assertEquals(todos, filtered_todos) self.assertEqual(todos, filtered_todos)
def test_filter15(self): def test_filter15(self):
""" Test limit filter. """ """ Test limit filter. """
...@@ -149,7 +149,7 @@ class FilterTest(TopydoTest): ...@@ -149,7 +149,7 @@ class FilterTest(TopydoTest):
filtered_todos = limit_filter.filter(todos) filtered_todos = limit_filter.filter(todos)
self.assertEquals(len(filtered_todos), 4) self.assertEqual(len(filtered_todos), 4)
def test_filter16(self): def test_filter16(self):
todos = load_file('test/data/FilterTest1.txt') todos = load_file('test/data/FilterTest1.txt')
...@@ -158,7 +158,7 @@ class FilterTest(TopydoTest): ...@@ -158,7 +158,7 @@ class FilterTest(TopydoTest):
filtered_todos = grep.filter(todos) filtered_todos = grep.filter(todos)
reference = load_file('test/data/FilterTest3-result.txt') reference = load_file('test/data/FilterTest3-result.txt')
self.assertEquals(todolist_to_string(filtered_todos), \ self.assertEqual(todolist_to_string(filtered_todos), \
todolist_to_string(reference)) todolist_to_string(reference))
def test_filter17(self): def test_filter17(self):
...@@ -170,7 +170,7 @@ class FilterTest(TopydoTest): ...@@ -170,7 +170,7 @@ class FilterTest(TopydoTest):
filtered_todos = andfilter.filter(todos) filtered_todos = andfilter.filter(todos)
reference = load_file('test/data/FilterTest4-result.txt') reference = load_file('test/data/FilterTest4-result.txt')
self.assertEquals(todolist_to_string(filtered_todos), \ self.assertEqual(todolist_to_string(filtered_todos), \
todolist_to_string(reference)) todolist_to_string(reference))
def test_filter18(self): def test_filter18(self):
...@@ -182,7 +182,7 @@ class FilterTest(TopydoTest): ...@@ -182,7 +182,7 @@ class FilterTest(TopydoTest):
filtered_todos = grep.filter(todos) filtered_todos = grep.filter(todos)
reference = load_file('test/data/FilterTest5-result.txt') reference = load_file('test/data/FilterTest5-result.txt')
self.assertEquals(todolist_to_string(filtered_todos), \ self.assertEqual(todolist_to_string(filtered_todos), \
todolist_to_string(reference)) todolist_to_string(reference))
def test_filter19(self): def test_filter19(self):
...@@ -190,7 +190,7 @@ class FilterTest(TopydoTest): ...@@ -190,7 +190,7 @@ class FilterTest(TopydoTest):
grep = Filter.GrepFilter(1) grep = Filter.GrepFilter(1)
filtered_todos = grep.filter(todos) filtered_todos = grep.filter(todos)
self.assertEquals(filtered_todos, []) self.assertEqual(filtered_todos, [])
def test_filter20(self): def test_filter20(self):
todos = load_file('test/data/FilterTest3.txt') todos = load_file('test/data/FilterTest3.txt')
...@@ -199,7 +199,7 @@ class FilterTest(TopydoTest): ...@@ -199,7 +199,7 @@ class FilterTest(TopydoTest):
filtered_todos = otf.filter(todos) filtered_todos = otf.filter(todos)
reference = load_file('test/data/FilterTest6-result.txt') reference = load_file('test/data/FilterTest6-result.txt')
self.assertEquals(todolist_to_string(filtered_todos), \ self.assertEqual(todolist_to_string(filtered_todos), \
todolist_to_string(reference)) todolist_to_string(reference))
def test_filter21(self): def test_filter21(self):
...@@ -208,7 +208,7 @@ class FilterTest(TopydoTest): ...@@ -208,7 +208,7 @@ class FilterTest(TopydoTest):
filtered_todos = otf.filter(todos) filtered_todos = otf.filter(todos)
self.assertEquals(todolist_to_string(filtered_todos), "") self.assertEqual(todolist_to_string(filtered_todos), "")
def test_filter22(self): def test_filter22(self):
todos = load_file('test/data/FilterTest3.txt') todos = load_file('test/data/FilterTest3.txt')
...@@ -216,7 +216,7 @@ class FilterTest(TopydoTest): ...@@ -216,7 +216,7 @@ class FilterTest(TopydoTest):
filtered_todos = otf.filter(todos) filtered_todos = otf.filter(todos)
self.assertEquals(todolist_to_string(filtered_todos), "") self.assertEqual(todolist_to_string(filtered_todos), "")
def test_filter23(self): def test_filter23(self):
todos = load_file('test/data/FilterTest3.txt') todos = load_file('test/data/FilterTest3.txt')
...@@ -224,7 +224,7 @@ class FilterTest(TopydoTest): ...@@ -224,7 +224,7 @@ class FilterTest(TopydoTest):
filtered_todos = otf.filter(todos) filtered_todos = otf.filter(todos)
self.assertEquals(todolist_to_string(filtered_todos), "") self.assertEqual(todolist_to_string(filtered_todos), "")
def test_filter24(self): def test_filter24(self):
todos = load_file('test/data/FilterTest3.txt') todos = load_file('test/data/FilterTest3.txt')
...@@ -232,7 +232,7 @@ class FilterTest(TopydoTest): ...@@ -232,7 +232,7 @@ class FilterTest(TopydoTest):
filtered_todos = otf.filter(todos) filtered_todos = otf.filter(todos)
self.assertEquals(todolist_to_string(filtered_todos), "") self.assertEqual(todolist_to_string(filtered_todos), "")
def test_filter25(self): def test_filter25(self):
todos = load_file('test/data/FilterTest3.txt') todos = load_file('test/data/FilterTest3.txt')
...@@ -241,7 +241,7 @@ class FilterTest(TopydoTest): ...@@ -241,7 +241,7 @@ class FilterTest(TopydoTest):
filtered_todos = otf.filter(todos) filtered_todos = otf.filter(todos)
reference = load_file('test/data/FilterTest8-result.txt') reference = load_file('test/data/FilterTest8-result.txt')
self.assertEquals(todolist_to_string(filtered_todos), self.assertEqual(todolist_to_string(filtered_todos),
todolist_to_string(reference)) todolist_to_string(reference))
def test_filter26(self): def test_filter26(self):
...@@ -251,7 +251,7 @@ class FilterTest(TopydoTest): ...@@ -251,7 +251,7 @@ class FilterTest(TopydoTest):
filtered_todos = otf.filter(todos) filtered_todos = otf.filter(todos)
reference = load_file('test/data/FilterTest9-result.txt') reference = load_file('test/data/FilterTest9-result.txt')
self.assertEquals(todolist_to_string(filtered_todos), self.assertEqual(todolist_to_string(filtered_todos),
todolist_to_string(reference)) todolist_to_string(reference))
def test_filter27(self): def test_filter27(self):
...@@ -261,7 +261,7 @@ class FilterTest(TopydoTest): ...@@ -261,7 +261,7 @@ class FilterTest(TopydoTest):
filtered_todos = otf.filter(todos) filtered_todos = otf.filter(todos)
reference = load_file('test/data/FilterTest10-result.txt') reference = load_file('test/data/FilterTest10-result.txt')
self.assertEquals(todolist_to_string(filtered_todos), self.assertEqual(todolist_to_string(filtered_todos),
todolist_to_string(reference)) todolist_to_string(reference))
def test_filter28(self): def test_filter28(self):
...@@ -270,7 +270,7 @@ class FilterTest(TopydoTest): ...@@ -270,7 +270,7 @@ class FilterTest(TopydoTest):
filtered_todos = otf.filter(todos) filtered_todos = otf.filter(todos)
self.assertEquals(todolist_to_string(filtered_todos), "") self.assertEqual(todolist_to_string(filtered_todos), "")
def test_filter29(self): def test_filter29(self):
todos = load_file('test/data/FilterTest3.txt') todos = load_file('test/data/FilterTest3.txt')
...@@ -279,7 +279,7 @@ class FilterTest(TopydoTest): ...@@ -279,7 +279,7 @@ class FilterTest(TopydoTest):
filtered_todos = otf.filter(todos) filtered_todos = otf.filter(todos)
reference = load_file('test/data/FilterTest11-result.txt') reference = load_file('test/data/FilterTest11-result.txt')
self.assertEquals(todolist_to_string(filtered_todos), self.assertEqual(todolist_to_string(filtered_todos),
todolist_to_string(reference)) todolist_to_string(reference))
def test_filter30(self): def test_filter30(self):
...@@ -289,7 +289,7 @@ class FilterTest(TopydoTest): ...@@ -289,7 +289,7 @@ class FilterTest(TopydoTest):
filtered_todos = otf.filter(todos) filtered_todos = otf.filter(todos)
reference = load_file('test/data/FilterTest12-result.txt') reference = load_file('test/data/FilterTest12-result.txt')
self.assertEquals(todolist_to_string(filtered_todos), self.assertEqual(todolist_to_string(filtered_todos),
todolist_to_string(reference)) todolist_to_string(reference))
def test_filter31(self): def test_filter31(self):
...@@ -299,7 +299,7 @@ class FilterTest(TopydoTest): ...@@ -299,7 +299,7 @@ class FilterTest(TopydoTest):
filtered_todos = otf.filter(todos) filtered_todos = otf.filter(todos)
reference = load_file('test/data/FilterTest13-result.txt') reference = load_file('test/data/FilterTest13-result.txt')
self.assertEquals(todolist_to_string(filtered_todos), self.assertEqual(todolist_to_string(filtered_todos),
todolist_to_string(reference)) todolist_to_string(reference))
class OrdinalTagFilterTest(TopydoTest): class OrdinalTagFilterTest(TopydoTest):
...@@ -329,41 +329,41 @@ class OrdinalTagFilterTest(TopydoTest): ...@@ -329,41 +329,41 @@ class OrdinalTagFilterTest(TopydoTest):
result = otf.filter(self.todos) result = otf.filter(self.todos)
self.assertEquals(len(result), 1) self.assertEqual(len(result), 1)
self.assertEquals(str(result[0]), self.todo1) self.assertEqual(str(result[0]), self.todo1)
def test_filter2(self): def test_filter2(self):
otf = Filter.OrdinalTagFilter('due:=today') otf = Filter.OrdinalTagFilter('due:=today')
result = otf.filter(self.todos) result = otf.filter(self.todos)
self.assertEquals(len(result), 1) self.assertEqual(len(result), 1)
self.assertEquals(str(result[0]), self.todo1) self.assertEqual(str(result[0]), self.todo1)
def test_filter3(self): def test_filter3(self):
otf = Filter.OrdinalTagFilter('due:>today') otf = Filter.OrdinalTagFilter('due:>today')
result = otf.filter(self.todos) result = otf.filter(self.todos)
self.assertEquals(len(result), 1) self.assertEqual(len(result), 1)
self.assertEquals(str(result[0]), self.todo2) self.assertEqual(str(result[0]), self.todo2)
def test_filter4(self): def test_filter4(self):
otf = Filter.OrdinalTagFilter('due:<1w') otf = Filter.OrdinalTagFilter('due:<1w')
result = otf.filter(self.todos) result = otf.filter(self.todos)
self.assertEquals(len(result), 2) self.assertEqual(len(result), 2)
self.assertEquals(str(result[0]), self.todo1) self.assertEqual(str(result[0]), self.todo1)
self.assertEquals(str(result[1]), self.todo2) self.assertEqual(str(result[1]), self.todo2)
def test_filter5(self): def test_filter5(self):
otf = Filter.OrdinalTagFilter('due:!today') otf = Filter.OrdinalTagFilter('due:!today')
result = otf.filter(self.todos) result = otf.filter(self.todos)
self.assertEquals(len(result), 1) self.assertEqual(len(result), 1)
self.assertEquals(str(result[0]), self.todo2) self.assertEqual(str(result[0]), self.todo2)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
......
...@@ -51,34 +51,34 @@ class GraphTest(TopydoTest): ...@@ -51,34 +51,34 @@ class GraphTest(TopydoTest):
self.assertFalse(self.graph.has_edge_id("1")) self.assertFalse(self.graph.has_edge_id("1"))
def test_incoming_neighbors1(self): def test_incoming_neighbors1(self):
self.assertEquals(self.graph.incoming_neighbors(1), set()) self.assertEqual(self.graph.incoming_neighbors(1), set())
def test_edge_id_of_nonexistent_edge(self): def test_edge_id_of_nonexistent_edge(self):
self.assertFalse(self.graph.edge_id(1, 6)) self.assertFalse(self.graph.edge_id(1, 6))
def test_incoming_neighbors2(self): def test_incoming_neighbors2(self):
self.assertEquals(self.graph.incoming_neighbors(2), set([1, 6])) self.assertEqual(self.graph.incoming_neighbors(2), set([1, 6]))
def test_incoming_neighbors3(self): def test_incoming_neighbors3(self):
self.assertEquals(self.graph.incoming_neighbors(1, True), set()) self.assertEqual(self.graph.incoming_neighbors(1, True), set())
def test_incoming_neighbors4(self): def test_incoming_neighbors4(self):
self.assertEquals(self.graph.incoming_neighbors(5, True), set([1, 2, 3, 4, 6])) self.assertEqual(self.graph.incoming_neighbors(5, True), set([1, 2, 3, 4, 6]))
def test_outgoing_neighbors1(self): def test_outgoing_neighbors1(self):
self.assertEquals(self.graph.outgoing_neighbors(1), set([2, 3])) self.assertEqual(self.graph.outgoing_neighbors(1), set([2, 3]))
def test_outgoing_neighbors2(self): def test_outgoing_neighbors2(self):
self.assertEquals(self.graph.outgoing_neighbors(2), set([4])) self.assertEqual(self.graph.outgoing_neighbors(2), set([4]))
def test_outgoing_neighbors3(self): def test_outgoing_neighbors3(self):
self.assertEquals(self.graph.outgoing_neighbors(1, True), set([2, 3, 4, 5, 6])) self.assertEqual(self.graph.outgoing_neighbors(1, True), set([2, 3, 4, 5, 6]))
def test_outgoing_neighbors4(self): def test_outgoing_neighbors4(self):
self.assertEquals(self.graph.outgoing_neighbors(3), set([5])) self.assertEqual(self.graph.outgoing_neighbors(3), set([5]))
def test_outgoing_neighbors5(self): def test_outgoing_neighbors5(self):
self.assertEquals(self.graph.outgoing_neighbors(5), set([])) self.assertEqual(self.graph.outgoing_neighbors(5), set([]))
def test_remove_edge1(self): def test_remove_edge1(self):
self.graph.remove_edge(1, 2) self.graph.remove_edge(1, 2)
...@@ -165,11 +165,11 @@ class GraphTest(TopydoTest): ...@@ -165,11 +165,11 @@ class GraphTest(TopydoTest):
def test_str_output(self): def test_str_output(self):
out = 'digraph g {\n 1\n 1 -> 2 [label="1"]\n 1 -> 3\n 2\n 2 -> 4 [label="Test"]\n 3\n 3 -> 5\n 4\n 4 -> 3\n 4 -> 6\n 5\n 6\n 6 -> 2\n}\n' out = 'digraph g {\n 1\n 1 -> 2 [label="1"]\n 1 -> 3\n 2\n 2 -> 4 [label="Test"]\n 3\n 3 -> 5\n 4\n 4 -> 3\n 4 -> 6\n 5\n 6\n 6 -> 2\n}\n'
self.assertEquals(str(self.graph), out) self.assertEqual(str(self.graph), out)
def test_dot_output_without_labels(self): def test_dot_output_without_labels(self):
out = 'digraph g {\n 1\n 1 -> 2\n 1 -> 3\n 2\n 2 -> 4\n 3\n 3 -> 5\n 4\n 4 -> 3\n 4 -> 6\n 5\n 6\n 6 -> 2\n}\n' out = 'digraph g {\n 1\n 1 -> 2\n 1 -> 3\n 2\n 2 -> 4\n 3\n 3 -> 5\n 4\n 4 -> 3\n 4 -> 6\n 5\n 6\n 6 -> 2\n}\n'
self.assertEquals(self.graph.dot(False), out) self.assertEqual(self.graph.dot(False), out)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
...@@ -14,89 +14,93 @@ ...@@ -14,89 +14,93 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from six import u
import codecs
import re
import sys
import unittest import unittest
from topydo.lib.Config import config from topydo.lib.Config import config
import CommandTest from topydo.commands.ListCommand import ListCommand
from topydo.lib.ListCommand import ListCommand from test.CommandTest import CommandTest, utf8
import TestFacilities from test.TestFacilities import load_file_to_todolist
class ListCommandTest(CommandTest.CommandTest): class ListCommandTest(CommandTest):
def setUp(self): def setUp(self):
super(ListCommandTest, self).setUp() super(ListCommandTest, self).setUp()
self.todolist = TestFacilities.load_file_to_todolist("test/data/ListCommandTest.txt") self.todolist = load_file_to_todolist("test/data/ListCommandTest.txt")
def test_list1(self): def test_list1(self):
command = ListCommand([""], self.todolist, self.out, self.error) command = ListCommand([""], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "| 1| (C) Foo @Context2 Not@Context +Project1 Not+Project\n| 4| (C) Drink beer @ home\n| 5| (C) 13 + 29 = 42\n| 2| (D) Bar @Context1 +Project2\n") self.assertEqual(self.output, "| 1| (C) Foo @Context2 Not@Context +Project1 Not+Project\n| 4| (C) Drink beer @ home\n| 5| (C) 13 + 29 = 42\n| 2| (D) Bar @Context1 +Project2\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_list3(self): def test_list3(self):
command = ListCommand(["Context1"], self.todolist, self.out, self.error) command = ListCommand(["Context1"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "| 2| (D) Bar @Context1 +Project2\n") self.assertEqual(self.output, "| 2| (D) Bar @Context1 +Project2\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_list4(self): def test_list4(self):
command = ListCommand(["-x", "Context1"], self.todolist, self.out, self.error) command = ListCommand(["-x", "Context1"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "| 3| (C) Baz @Context1 +Project1 key:value\n| 2| (D) Bar @Context1 +Project2\n") self.assertEqual(self.output, "| 3| (C) Baz @Context1 +Project1 key:value\n| 2| (D) Bar @Context1 +Project2\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_list5(self): def test_list5(self):
command = ListCommand(["-x"], self.todolist, self.out, self.error) command = ListCommand(["-x"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "| 1| (C) Foo @Context2 Not@Context +Project1 Not+Project\n| 3| (C) Baz @Context1 +Project1 key:value\n| 4| (C) Drink beer @ home\n| 5| (C) 13 + 29 = 42\n| 2| (D) Bar @Context1 +Project2\n| 6| x 2014-12-12 Completed but with date:2014-12-12\n") self.assertEqual(self.output, "| 1| (C) Foo @Context2 Not@Context +Project1 Not+Project\n| 3| (C) Baz @Context1 +Project1 key:value\n| 4| (C) Drink beer @ home\n| 5| (C) 13 + 29 = 42\n| 2| (D) Bar @Context1 +Project2\n| 6| x 2014-12-12 Completed but with date:2014-12-12\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_list6(self): def test_list6(self):
command = ListCommand(["Project3"], self.todolist, self.out, self.error) command = ListCommand(["Project3"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "") self.assertEqual(self.output, "")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_list7(self): def test_list7(self):
command = ListCommand(["-s", "text", "-x", "Project1"], self.todolist, self.out, self.error) command = ListCommand(["-s", "text", "-x", "Project1"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "| 3| (C) Baz @Context1 +Project1 key:value\n| 1| (C) Foo @Context2 Not@Context +Project1 Not+Project\n") self.assertEqual(self.output, "| 3| (C) Baz @Context1 +Project1 key:value\n| 1| (C) Foo @Context2 Not@Context +Project1 Not+Project\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_list8(self): def test_list8(self):
command = ListCommand(["--", "-project1"], self.todolist, self.out, self.error) command = ListCommand(["--", "-project1"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "| 4| (C) Drink beer @ home\n| 5| (C) 13 + 29 = 42\n| 2| (D) Bar @Context1 +Project2\n") self.assertEqual(self.output, "| 4| (C) Drink beer @ home\n| 5| (C) 13 + 29 = 42\n| 2| (D) Bar @Context1 +Project2\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_list9(self): def test_list9(self):
command = ListCommand(["--", "-project1", "-Drink"], self.todolist, self.out, self.error) command = ListCommand(["--", "-project1", "-Drink"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "| 5| (C) 13 + 29 = 42\n| 2| (D) Bar @Context1 +Project2\n") self.assertEqual(self.output, "| 5| (C) 13 + 29 = 42\n| 2| (D) Bar @Context1 +Project2\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_list10(self): def test_list10(self):
command = ListCommand(["text1", "2"], self.todolist, self.out, self.error) command = ListCommand(["text1", "2"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "| 2| (D) Bar @Context1 +Project2\n") self.assertEqual(self.output, "| 2| (D) Bar @Context1 +Project2\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_list11(self): def test_list11(self):
config("test/data/listcommand.conf") config("test/data/listcommand.conf")
...@@ -105,8 +109,8 @@ class ListCommandTest(CommandTest.CommandTest): ...@@ -105,8 +109,8 @@ class ListCommandTest(CommandTest.CommandTest):
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "| 1| (C) Foo @Context2 Not@Context +Project1 Not+Project\n") self.assertEqual(self.output, "| 1| (C) Foo @Context2 Not@Context +Project1 Not+Project\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_list12(self): def test_list12(self):
config("test/data/listcommand.conf") config("test/data/listcommand.conf")
...@@ -115,16 +119,16 @@ class ListCommandTest(CommandTest.CommandTest): ...@@ -115,16 +119,16 @@ class ListCommandTest(CommandTest.CommandTest):
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "| 1| (C) Foo @Context2 Not@Context +Project1 Not+Project\n| 3| (C) Baz @Context1 +Project1 key:value\n| 2| (D) Bar @Context1 +Project2\n") self.assertEqual(self.output, "| 1| (C) Foo @Context2 Not@Context +Project1 Not+Project\n| 3| (C) Baz @Context1 +Project1 key:value\n| 2| (D) Bar @Context1 +Project2\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_list13(self): def test_list13(self):
command = ListCommand(["-x", "--", "-@Context1 +Project2"], self.todolist, self.out, self.error) command = ListCommand(["-x", "--", "-@Context1 +Project2"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "| 1| (C) Foo @Context2 Not@Context +Project1 Not+Project\n| 3| (C) Baz @Context1 +Project1 key:value\n| 4| (C) Drink beer @ home\n| 5| (C) 13 + 29 = 42\n| 6| x 2014-12-12 Completed but with date:2014-12-12\n") self.assertEqual(self.output, "| 1| (C) Foo @Context2 Not@Context +Project1 Not+Project\n| 3| (C) Baz @Context1 +Project1 key:value\n| 4| (C) Drink beer @ home\n| 5| (C) 13 + 29 = 42\n| 6| x 2014-12-12 Completed but with date:2014-12-12\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_list14(self): def test_list14(self):
config("test/data/listcommand2.conf") config("test/data/listcommand2.conf")
...@@ -133,16 +137,16 @@ class ListCommandTest(CommandTest.CommandTest): ...@@ -133,16 +137,16 @@ class ListCommandTest(CommandTest.CommandTest):
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, " | 1| (C) Foo @Context2 Not@Context +Project1 Not+Project\n | 4| (C) Drink beer @ home\n | 5| (C) 13 + 29 = 42\n | 2| (D) Bar @Context1 +Project2\n") self.assertEqual(self.output, " | 1| (C) Foo @Context2 Not@Context +Project1 Not+Project\n | 4| (C) Drink beer @ home\n | 5| (C) 13 + 29 = 42\n | 2| (D) Bar @Context1 +Project2\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_list15(self): def test_list15(self):
command = ListCommand(["p:<10"], self.todolist, self.out, self.error) command = ListCommand(["p:<10"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "| 2| (D) Bar @Context1 +Project2\n") self.assertEqual(self.output, "| 2| (D) Bar @Context1 +Project2\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_list16(self): def test_list16(self):
config("test/data/todolist-uid.conf") config("test/data/todolist-uid.conf")
...@@ -151,23 +155,23 @@ class ListCommandTest(CommandTest.CommandTest): ...@@ -151,23 +155,23 @@ class ListCommandTest(CommandTest.CommandTest):
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "|6iu| (C) Foo @Context2 Not@Context +Project1 Not+Project\n|til| (C) Drink beer @ home\n| c5| (C) 13 + 29 = 42\n|xvb| (D) Bar @Context1 +Project2\n") self.assertEqual(self.output, "|t5c| (C) Foo @Context2 Not@Context +Project1 Not+Project\n|wa5| (C) Drink beer @ home\n|z63| (C) 13 + 29 = 42\n|mfg| (D) Bar @Context1 +Project2\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_list17(self): def test_list17(self):
command = ListCommand(["-x", "id:"], self.todolist, self.out, self.error) command = ListCommand(["-x", "id:"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "| 3| (C) Baz @Context1 +Project1 key:value\n") self.assertEqual(self.output, "| 3| (C) Baz @Context1 +Project1 key:value\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_list18(self): def test_list18(self):
command = ListCommand(["-x", "date:2014-12-12"], self.todolist, self.out, self.error) command = ListCommand(["-x", "date:2014-12-12"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "| 6| x 2014-12-12 Completed but with date:2014-12-12\n") self.assertEqual(self.output, "| 6| x 2014-12-12 Completed but with date:2014-12-12\n")
def test_list19(self): def test_list19(self):
""" Force showing all tags. """ """ Force showing all tags. """
...@@ -177,15 +181,135 @@ class ListCommandTest(CommandTest.CommandTest): ...@@ -177,15 +181,135 @@ class ListCommandTest(CommandTest.CommandTest):
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "| 3| (C) Baz @Context1 +Project1 key:value id:1\n| 1| (C) Foo @Context2 Not@Context +Project1 Not+Project\n") self.assertEqual(self.output, "| 3| (C) Baz @Context1 +Project1 key:value id:1\n| 1| (C) Foo @Context2 Not@Context +Project1 Not+Project\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_list20(self):
command = ListCommand(["-f text"], self.todolist, self.out, self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEqual(self.output, "| 1| (C) Foo @Context2 Not@Context +Project1 Not+Project\n| 4| (C) Drink beer @ home\n| 5| (C) 13 + 29 = 42\n| 2| (D) Bar @Context1 +Project2\n")
self.assertEqual(self.errors, "")
def test_list21(self):
command = ListCommand(["-f invalid"], self.todolist, self.out, self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEqual(self.output, "| 1| (C) Foo @Context2 Not@Context +Project1 Not+Project\n| 4| (C) Drink beer @ home\n| 5| (C) 13 + 29 = 42\n| 2| (D) Bar @Context1 +Project2\n")
self.assertEqual(self.errors, "")
def test_help(self): def test_help(self):
command = ListCommand(["help"], self.todolist, self.out, self.error) command = ListCommand(["help"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.output, "") self.assertEqual(self.output, "")
self.assertEquals(self.errors, command.usage() + "\n\n" + command.help() + "\n") self.assertEqual(self.errors, command.usage() + "\n\n" + command.help() + "\n")
class ListCommandUnicodeTest(CommandTest):
def setUp(self):
super(ListCommandUnicodeTest, self).setUp()
self.todolist = load_file_to_todolist("test/data/ListCommandUnicodeTest.txt")
def test_list_unicode1(self):
""" Unicode filters """
command = ListCommand([u("\u25c4")], self.todolist, self.out, self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
expected = utf8(u("| 1| (C) And some sp\u00e9cial tag:\u25c4\n"))
self.assertEqual(self.output, expected)
class ListCommandJsonTest(CommandTest):
def test_json(self):
todolist = load_file_to_todolist("test/data/ListCommandTest.txt")
command = ListCommand(["-f", "json"], todolist, self.out, self.error)
command.execute()
self.assertFalse(todolist.is_dirty())
jsontext = ""
with codecs.open('test/data/ListCommandTest.json', 'r', encoding='utf-8') as json:
jsontext = json.read()
self.assertEqual(self.output, jsontext)
self.assertEqual(self.errors, "")
def test_json_unicode(self):
todolist = load_file_to_todolist("test/data/ListCommandUnicodeTest.txt")
command = ListCommand(["-f", "json"], todolist, self.out, self.error)
command.execute()
self.assertFalse(todolist.is_dirty())
jsontext = ""
with codecs.open('test/data/ListCommandUnicodeTest.json', 'r', encoding='utf-8') as json:
jsontext = json.read()
self.assertEqual(self.output, utf8(jsontext))
self.assertEqual(self.errors, "")
def replace_ical_tags(p_text):
# replace identifiers with dots, since they're random.
result = re.sub(r'\bical:....\b', 'ical:....', p_text)
result = re.sub(r'\bUID:....\b', 'UID:....', result)
return result
IS_PYTHON_32 = (sys.version_info.major, sys.version_info.minor) == (3, 2)
class ListCommandIcalTest(CommandTest):
@unittest.skipIf(IS_PYTHON_32, "icalendar is not supported for Python 3.2")
def test_ical(self):
todolist = load_file_to_todolist("test/data/ListCommandTest.txt")
command = ListCommand(["-f", "ical"], todolist, self.out, self.error)
command.execute()
self.assertTrue(todolist.is_dirty())
icaltext = ""
with codecs.open('test/data/ListCommandTest.ics', 'r', encoding='utf-8') as ical:
icaltext = ical.read()
self.assertEqual(replace_ical_tags(self.output), replace_ical_tags(icaltext))
self.assertEqual(self.errors, "")
@unittest.skipUnless(IS_PYTHON_32, "icalendar is not supported for Python 3.2")
def test_ical_python32(self):
"""
Test case for Python 3.2 where icalendar is not supported.
"""
todolist = load_file_to_todolist("test/data/ListCommandTest.txt")
command = ListCommand(["-f", "ical"], todolist, self.out, self.error)
command.execute()
self.assertFalse(todolist.is_dirty())
self.assertEqual(self.output, '')
self.assertEqual(self.errors, "icalendar is not supported in this Python version.\n")
@unittest.skipIf(IS_PYTHON_32, "icalendar is not supported for Python 3.2")
def test_ical_unicode(self):
todolist = load_file_to_todolist("test/data/ListCommandUnicodeTest.txt")
command = ListCommand(["-f", "ical"], todolist, self.out, self.error)
command.execute()
self.assertTrue(todolist.is_dirty())
icaltext = ""
with codecs.open('test/data/ListCommandUnicodeTest.ics', 'r', encoding='utf-8') as ical:
icaltext = ical.read()
self.assertEqual(replace_ical_tags(self.output), utf8(replace_ical_tags(icaltext)))
self.assertEqual(self.errors, "")
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
...@@ -16,33 +16,33 @@ ...@@ -16,33 +16,33 @@
import unittest import unittest
import CommandTest from topydo.commands.ListContextCommand import ListContextCommand
import TestFacilities from test.CommandTest import CommandTest
from topydo.lib.ListContextCommand import ListContextCommand from test.TestFacilities import load_file_to_todolist
class ListContextCommandTest(CommandTest.CommandTest): class ListContextCommandTest(CommandTest):
def test_contexts1(self): def test_contexts1(self):
todolist = TestFacilities.load_file_to_todolist("test/data/TodoListTest.txt") todolist = load_file_to_todolist("test/data/TodoListTest.txt")
command = ListContextCommand([""], todolist, self.out, self.error) command = ListContextCommand([""], todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.output,"Context1\nContext2\n") self.assertEqual(self.output,"Context1\nContext2\n")
self.assertFalse(self.errors) self.assertFalse(self.errors)
def test_contexts2(self): def test_contexts2(self):
todolist = TestFacilities.load_file_to_todolist("test/data/TodoListTest.txt") todolist = load_file_to_todolist("test/data/TodoListTest.txt")
command = ListContextCommand(["aaa"], todolist, self.out, self.error) command = ListContextCommand(["aaa"], todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.output,"Context1\nContext2\n") self.assertEqual(self.output,"Context1\nContext2\n")
self.assertFalse(self.errors) self.assertFalse(self.errors)
def test_help(self): def test_help(self):
command = ListContextCommand(["help"], None, self.out, self.error) command = ListContextCommand(["help"], None, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.output, "") self.assertEqual(self.output, "")
self.assertEquals(self.errors, command.usage() + "\n\n" + command.help() + "\n") self.assertEqual(self.errors, command.usage() + "\n\n" + command.help() + "\n")
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
...@@ -16,33 +16,33 @@ ...@@ -16,33 +16,33 @@
import unittest import unittest
import CommandTest from topydo.commands.ListProjectCommand import ListProjectCommand
import TestFacilities from test.CommandTest import CommandTest
from topydo.lib.ListProjectCommand import ListProjectCommand from test.TestFacilities import load_file_to_todolist
class ListProjectCommandTest(CommandTest.CommandTest): class ListProjectCommandTest(CommandTest):
def test_projects1(self): def test_projects1(self):
todolist = TestFacilities.load_file_to_todolist("test/data/TodoListTest.txt") todolist = load_file_to_todolist("test/data/TodoListTest.txt")
command = ListProjectCommand([""], todolist, self.out, self.error) command = ListProjectCommand([""], todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.output,"Project1\nProject2\n") self.assertEqual(self.output, "Project1\nProject2\n")
self.assertFalse(self.errors) self.assertFalse(self.errors)
def test_projects2(self): def test_projects2(self):
todolist = TestFacilities.load_file_to_todolist("test/data/TodoListTest.txt") todolist = load_file_to_todolist("test/data/TodoListTest.txt")
command = ListProjectCommand(["aaa"], todolist, self.out, self.error) command = ListProjectCommand(["aaa"], todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.output,"Project1\nProject2\n") self.assertEqual(self.output, "Project1\nProject2\n")
self.assertFalse(self.errors) self.assertFalse(self.errors)
def test_help(self): def test_help(self):
command = ListProjectCommand(["help"], None, self.out, self.error) command = ListProjectCommand(["help"], None, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.output, "") self.assertEqual(self.output, "")
self.assertEquals(self.errors, command.usage() + "\n\n" + command.help() + "\n") self.assertEqual(self.errors, command.usage() + "\n\n" + command.help() + "\n")
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
...@@ -16,12 +16,13 @@ ...@@ -16,12 +16,13 @@
from datetime import date, timedelta from datetime import date, timedelta
import unittest import unittest
from six import u
import CommandTest from topydo.commands.PostponeCommand import PostponeCommand
from topydo.lib.PostponeCommand import PostponeCommand from test.CommandTest import CommandTest
from topydo.lib.TodoList import TodoList from topydo.lib.TodoList import TodoList
class PostponeCommandTest(CommandTest.CommandTest): class PostponeCommandTest(CommandTest):
def setUp(self): def setUp(self):
super(PostponeCommandTest, self).setUp() super(PostponeCommandTest, self).setUp()
self.today = date.today() self.today = date.today()
...@@ -47,8 +48,8 @@ class PostponeCommandTest(CommandTest.CommandTest): ...@@ -47,8 +48,8 @@ class PostponeCommandTest(CommandTest.CommandTest):
due = self.today + timedelta(7) due = self.today + timedelta(7)
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, "| 1| Foo due:{}\n".format(due.isoformat())) self.assertEqual(self.output, "| 1| Foo due:{}\n".format(due.isoformat()))
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_postpone2(self): def test_postpone2(self):
command = PostponeCommand(["2", "1w"], self.todolist, self.out, self.error) command = PostponeCommand(["2", "1w"], self.todolist, self.out, self.error)
...@@ -57,8 +58,8 @@ class PostponeCommandTest(CommandTest.CommandTest): ...@@ -57,8 +58,8 @@ class PostponeCommandTest(CommandTest.CommandTest):
due = self.today + timedelta(7) due = self.today + timedelta(7)
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, "| 2| Bar due:{}\n".format(due.isoformat())) self.assertEqual(self.output, "| 2| Bar due:{}\n".format(due.isoformat()))
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_postpone3(self): def test_postpone3(self):
command = PostponeCommand(["-s", "2", "1w"], self.todolist, self.out, self.error) command = PostponeCommand(["-s", "2", "1w"], self.todolist, self.out, self.error)
...@@ -67,8 +68,8 @@ class PostponeCommandTest(CommandTest.CommandTest): ...@@ -67,8 +68,8 @@ class PostponeCommandTest(CommandTest.CommandTest):
due = self.today + timedelta(7) due = self.today + timedelta(7)
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, "| 2| Bar due:{}\n".format(due.isoformat())) self.assertEqual(self.output, "| 2| Bar due:{}\n".format(due.isoformat()))
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_postpone4(self): def test_postpone4(self):
command = PostponeCommand(["3", "1w"], self.todolist, self.out, self.error) command = PostponeCommand(["3", "1w"], self.todolist, self.out, self.error)
...@@ -77,8 +78,8 @@ class PostponeCommandTest(CommandTest.CommandTest): ...@@ -77,8 +78,8 @@ class PostponeCommandTest(CommandTest.CommandTest):
due = self.today + timedelta(7) due = self.today + timedelta(7)
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, "| 3| Baz due:{} t:{}\n".format(due.isoformat(), self.start.isoformat())) self.assertEqual(self.output, "| 3| Baz due:{} t:{}\n".format(due.isoformat(), self.start.isoformat()))
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_postpone5(self): def test_postpone5(self):
command = PostponeCommand(["-s", "3", "1w"], self.todolist, self.out, self.error) command = PostponeCommand(["-s", "3", "1w"], self.todolist, self.out, self.error)
...@@ -88,8 +89,9 @@ class PostponeCommandTest(CommandTest.CommandTest): ...@@ -88,8 +89,9 @@ class PostponeCommandTest(CommandTest.CommandTest):
start = self.start + timedelta(7) start = self.start + timedelta(7)
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, "| 3| Baz due:{} t:{}\n".format(due.isoformat(), start.isoformat())) # pylint: disable=E1103
self.assertEquals(self.errors, "") self.assertEqual(self.output, "| 3| Baz due:{} t:{}\n".format(due.isoformat(), start.isoformat()))
self.assertEqual(self.errors, "")
def test_postpone6(self): def test_postpone6(self):
command = PostponeCommand(["4", "1w"], self.todolist, self.out, self.error) command = PostponeCommand(["4", "1w"], self.todolist, self.out, self.error)
...@@ -98,8 +100,8 @@ class PostponeCommandTest(CommandTest.CommandTest): ...@@ -98,8 +100,8 @@ class PostponeCommandTest(CommandTest.CommandTest):
due = self.today + timedelta(7) due = self.today + timedelta(7)
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, "| 4| Past due:{}\n".format(due.isoformat())) self.assertEqual(self.output, "| 4| Past due:{}\n".format(due.isoformat()))
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_postpone7(self): def test_postpone7(self):
command = PostponeCommand(["5", "1w"], self.todolist, self.out, self.error) command = PostponeCommand(["5", "1w"], self.todolist, self.out, self.error)
...@@ -108,8 +110,9 @@ class PostponeCommandTest(CommandTest.CommandTest): ...@@ -108,8 +110,9 @@ class PostponeCommandTest(CommandTest.CommandTest):
due = self.future + timedelta(7) due = self.future + timedelta(7)
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, "| 5| Future due:{} t:{}\n".format(due.isoformat(), self.future_start.isoformat())) # pylint: disable=E1103
self.assertEquals(self.errors, "") self.assertEqual(self.output, "| 5| Future due:{} t:{}\n".format(due.isoformat(), self.future_start.isoformat()))
self.assertEqual(self.errors, "")
def test_postpone8(self): def test_postpone8(self):
command = PostponeCommand(["-s", "5", "1w"], self.todolist, self.out, self.error) command = PostponeCommand(["-s", "5", "1w"], self.todolist, self.out, self.error)
...@@ -119,40 +122,41 @@ class PostponeCommandTest(CommandTest.CommandTest): ...@@ -119,40 +122,41 @@ class PostponeCommandTest(CommandTest.CommandTest):
start = self.future_start + timedelta(7) start = self.future_start + timedelta(7)
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, "| 5| Future due:{} t:{}\n".format(due.isoformat(), start.isoformat())) # pylint: disable=E1103
self.assertEquals(self.errors, "") self.assertEqual(self.output, "| 5| Future due:{} t:{}\n".format(due.isoformat(), start.isoformat()))
self.assertEqual(self.errors, "")
def test_postpone9(self): def test_postpone9(self):
command = PostponeCommand(["1", "foo"], self.todolist, self.out, self.error) command = PostponeCommand(["1", "foo"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "") self.assertEqual(self.output, "")
self.assertEquals(self.errors, "Invalid date pattern given.\n") self.assertEqual(self.errors, "Invalid date pattern given.\n")
def test_postpone10(self): def test_postpone10(self):
command = PostponeCommand(["99", "foo"], self.todolist, self.out, self.error) command = PostponeCommand(["99", "foo"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "") self.assertEqual(self.output, "")
self.assertEquals(self.errors, "Invalid todo number given.\n") self.assertEqual(self.errors, "Invalid todo number given.\n")
def test_postpone11(self): def test_postpone11(self):
command = PostponeCommand(["A", "foo"], self.todolist, self.out, self.error) command = PostponeCommand(["A", "foo"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "") self.assertEqual(self.output, "")
self.assertEquals(self.errors, "Invalid todo number given.\n") self.assertEqual(self.errors, "Invalid todo number given.\n")
def test_postpone12(self): def test_postpone12(self):
command = PostponeCommand(["1"], self.todolist, self.out, self.error) command = PostponeCommand(["1"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "") self.assertEqual(self.output, "")
self.assertEquals(self.errors, command.usage() + "\n") self.assertEqual(self.errors, command.usage() + "\n")
def test_postpone13(self): def test_postpone13(self):
command = PostponeCommand(["Foo", "1w"], self.todolist, self.out, self.error) command = PostponeCommand(["Foo", "1w"], self.todolist, self.out, self.error)
...@@ -161,8 +165,8 @@ class PostponeCommandTest(CommandTest.CommandTest): ...@@ -161,8 +165,8 @@ class PostponeCommandTest(CommandTest.CommandTest):
due = self.today + timedelta(7) due = self.today + timedelta(7)
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, "| 1| Foo due:{}\n".format(due.isoformat())) self.assertEqual(self.output, "| 1| Foo due:{}\n".format(due.isoformat()))
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_postpone14(self): def test_postpone14(self):
command = PostponeCommand(["1", "2", "1w"], self.todolist, self.out, self.error) command = PostponeCommand(["1", "2", "1w"], self.todolist, self.out, self.error)
...@@ -171,8 +175,8 @@ class PostponeCommandTest(CommandTest.CommandTest): ...@@ -171,8 +175,8 @@ class PostponeCommandTest(CommandTest.CommandTest):
due = self.today + timedelta(7) due = self.today + timedelta(7)
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, "| 1| Foo due:{}\n| 2| Bar due:{}\n".format(due.isoformat(), due.isoformat())) self.assertEqual(self.output, "| 1| Foo due:{}\n| 2| Bar due:{}\n".format(due.isoformat(), due.isoformat()))
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_postpone15(self): def test_postpone15(self):
command = PostponeCommand(["Foo", "2", "1w"], self.todolist, self.out, self.error) command = PostponeCommand(["Foo", "2", "1w"], self.todolist, self.out, self.error)
...@@ -181,8 +185,8 @@ class PostponeCommandTest(CommandTest.CommandTest): ...@@ -181,8 +185,8 @@ class PostponeCommandTest(CommandTest.CommandTest):
due = self.today + timedelta(7) due = self.today + timedelta(7)
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, "| 1| Foo due:{}\n| 2| Bar due:{}\n".format(due.isoformat(), due.isoformat())) self.assertEqual(self.output, "| 1| Foo due:{}\n| 2| Bar due:{}\n".format(due.isoformat(), due.isoformat()))
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_postpone16(self): def test_postpone16(self):
command = PostponeCommand(["-s", "2", "3", "1w"], self.todolist, self.out, self.error) command = PostponeCommand(["-s", "2", "3", "1w"], self.todolist, self.out, self.error)
...@@ -192,39 +196,49 @@ class PostponeCommandTest(CommandTest.CommandTest): ...@@ -192,39 +196,49 @@ class PostponeCommandTest(CommandTest.CommandTest):
start = self.start + timedelta(7) start = self.start + timedelta(7)
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, "| 2| Bar due:{}\n| 3| Baz due:{} t:{}\n".format(due.isoformat(), due.isoformat(), start.isoformat())) # pylint: disable=E1103
self.assertEquals(self.errors, "") self.assertEqual(self.output, "| 2| Bar due:{}\n| 3| Baz due:{} t:{}\n".format(due.isoformat(), due.isoformat(), start.isoformat()))
self.assertEqual(self.errors, "")
def test_postpone17(self): def test_postpone17(self):
command = PostponeCommand(["1", "2", "3"], self.todolist, self.out, self.error) command = PostponeCommand(["1", "2", "3"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "") self.assertEqual(self.output, "")
self.assertEquals(self.errors, "Invalid date pattern given.\n") self.assertEqual(self.errors, "Invalid date pattern given.\n")
def test_postpone18(self): def test_postpone18(self):
command = PostponeCommand(["1", "99", "123", "1w"], self.todolist, self.out, self.error) command = PostponeCommand(["1", "99", "123", "1w"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "") self.assertEqual(self.output, "")
self.assertEquals(self.errors, "Invalid todo number given: 99.\nInvalid todo number given: 123.\n") self.assertEqual(self.errors, "Invalid todo number given: 99.\nInvalid todo number given: 123.\n")
def test_postpone19(self): def test_postpone19(self):
command = PostponeCommand(["Zoo", "99", "123", "1w"], self.todolist, self.out, self.error) command = PostponeCommand(["Zoo", "99", "123", "1w"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "") self.assertEqual(self.output, "")
self.assertEquals(self.errors, "Invalid todo number given: Zoo.\nInvalid todo number given: 99.\nInvalid todo number given: 123.\n") self.assertEqual(self.errors, "Invalid todo number given: Zoo.\nInvalid todo number given: 99.\nInvalid todo number given: 123.\n")
def test_postpone20(self):
""" Throw an error with invalid argument containing special characters. """
command = PostponeCommand([u("Fo\u00d3B\u0105r"), "Bar", "1d"], self.todolist, self.out, self.error, None)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEqual(self.output, "")
self.assertEqual(self.errors, u("Invalid todo number given: Fo\u00d3B\u0105r.\n"))
def test_help(self): def test_help(self):
command = PostponeCommand(["help"], self.todolist, self.out, self.error) command = PostponeCommand(["help"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.output, "") self.assertEqual(self.output, "")
self.assertEquals(self.errors, command.usage() + "\n\n" + command.help() + "\n") self.assertEqual(self.errors, command.usage() + "\n\n" + command.help() + "\n")
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
......
...@@ -15,12 +15,13 @@ ...@@ -15,12 +15,13 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import unittest import unittest
from six import u
import CommandTest from topydo.commands.PriorityCommand import PriorityCommand
from topydo.lib.PriorityCommand import PriorityCommand from test.CommandTest import CommandTest
from topydo.lib.TodoList import TodoList from topydo.lib.TodoList import TodoList
class PriorityCommandTest(CommandTest.CommandTest): class PriorityCommandTest(CommandTest):
def setUp(self): def setUp(self):
super(PriorityCommandTest, self).setUp() super(PriorityCommandTest, self).setUp()
todos = [ todos = [
...@@ -35,40 +36,40 @@ class PriorityCommandTest(CommandTest.CommandTest): ...@@ -35,40 +36,40 @@ class PriorityCommandTest(CommandTest.CommandTest):
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, "Priority changed from A to B\n| 1| (B) Foo\n") self.assertEqual(self.output, "Priority changed from A to B\n| 1| (B) Foo\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_set_prio2(self): def test_set_prio2(self):
command = PriorityCommand(["2", "Z"], self.todolist, self.out, self.error) command = PriorityCommand(["2", "Z"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, "Priority set to Z.\n| 2| (Z) Bar\n") self.assertEqual(self.output, "Priority set to Z.\n| 2| (Z) Bar\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_set_prio3(self): def test_set_prio3(self):
command = PriorityCommand(["Foo", "B"], self.todolist, self.out, self.error) command = PriorityCommand(["Foo", "B"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, "Priority changed from A to B\n| 1| (B) Foo\n") self.assertEqual(self.output, "Priority changed from A to B\n| 1| (B) Foo\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_set_prio4(self): def test_set_prio4(self):
command = PriorityCommand(["1", "A"], self.todolist, self.out, self.error) command = PriorityCommand(["1", "A"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "| 1| (A) Foo\n") self.assertEqual(self.output, "| 1| (A) Foo\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_set_prio5(self): def test_set_prio5(self):
command = PriorityCommand(["Foo", "2", "C"], self.todolist, self.out, self.error) command = PriorityCommand(["Foo", "2", "C"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, "Priority changed from A to C\n| 1| (C) Foo\nPriority set to C.\n| 2| (C) Bar\n") self.assertEqual(self.output, "Priority changed from A to C\n| 1| (C) Foo\nPriority set to C.\n| 2| (C) Bar\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_invalid1(self): def test_invalid1(self):
command = PriorityCommand(["99", "A"], self.todolist, self.out, self.error) command = PriorityCommand(["99", "A"], self.todolist, self.out, self.error)
...@@ -76,7 +77,7 @@ class PriorityCommandTest(CommandTest.CommandTest): ...@@ -76,7 +77,7 @@ class PriorityCommandTest(CommandTest.CommandTest):
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertFalse(self.output) self.assertFalse(self.output)
self.assertEquals(self.errors, "Invalid todo number given.\n") self.assertEqual(self.errors, "Invalid todo number given.\n")
def test_invalid2(self): def test_invalid2(self):
command = PriorityCommand(["1", "99", "A"], self.todolist, self.out, self.error) command = PriorityCommand(["1", "99", "A"], self.todolist, self.out, self.error)
...@@ -84,7 +85,7 @@ class PriorityCommandTest(CommandTest.CommandTest): ...@@ -84,7 +85,7 @@ class PriorityCommandTest(CommandTest.CommandTest):
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertFalse(self.output) self.assertFalse(self.output)
self.assertEquals(self.errors, "Invalid todo number given: 99.\n") self.assertEqual(self.errors, "Invalid todo number given: 99.\n")
def test_invalid3(self): def test_invalid3(self):
command = PriorityCommand(["98", "99", "A"], self.todolist, self.out, self.error) command = PriorityCommand(["98", "99", "A"], self.todolist, self.out, self.error)
...@@ -92,7 +93,7 @@ class PriorityCommandTest(CommandTest.CommandTest): ...@@ -92,7 +93,7 @@ class PriorityCommandTest(CommandTest.CommandTest):
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertFalse(self.output) self.assertFalse(self.output)
self.assertEquals(self.errors, "Invalid todo number given: 98.\nInvalid todo number given: 99.\n") self.assertEqual(self.errors, "Invalid todo number given: 98.\nInvalid todo number given: 99.\n")
def test_invalid4(self): def test_invalid4(self):
command = PriorityCommand(["1", "ZZ"], self.todolist, self.out, self.error) command = PriorityCommand(["1", "ZZ"], self.todolist, self.out, self.error)
...@@ -100,7 +101,7 @@ class PriorityCommandTest(CommandTest.CommandTest): ...@@ -100,7 +101,7 @@ class PriorityCommandTest(CommandTest.CommandTest):
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertFalse(self.output) self.assertFalse(self.output)
self.assertEquals(self.errors, "Invalid priority given.\n") self.assertEqual(self.errors, "Invalid priority given.\n")
def test_invalid5(self): def test_invalid5(self):
command = PriorityCommand(["A"], self.todolist, self.out, self.error) command = PriorityCommand(["A"], self.todolist, self.out, self.error)
...@@ -108,7 +109,7 @@ class PriorityCommandTest(CommandTest.CommandTest): ...@@ -108,7 +109,7 @@ class PriorityCommandTest(CommandTest.CommandTest):
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertFalse(self.output) self.assertFalse(self.output)
self.assertEquals(self.errors, command.usage() + "\n") self.assertEqual(self.errors, command.usage() + "\n")
def test_invalid6(self): def test_invalid6(self):
command = PriorityCommand(["1"], self.todolist, self.out, self.error) command = PriorityCommand(["1"], self.todolist, self.out, self.error)
...@@ -116,7 +117,16 @@ class PriorityCommandTest(CommandTest.CommandTest): ...@@ -116,7 +117,16 @@ class PriorityCommandTest(CommandTest.CommandTest):
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertFalse(self.output) self.assertFalse(self.output)
self.assertEquals(self.errors, command.usage() + "\n") self.assertEqual(self.errors, command.usage() + "\n")
def test_invalid7(self):
""" Throw an error with invalid argument containing special characters. """
command = PriorityCommand([u("Fo\u00d3B\u0105r"), "Bar", "C"], self.todolist, self.out, self.error, None)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEqual(self.output, "")
self.assertEqual(self.errors, u("Invalid todo number given: Fo\u00d3B\u0105r.\n"))
def test_empty(self): def test_empty(self):
command = PriorityCommand([], self.todolist, self.out, self.error) command = PriorityCommand([], self.todolist, self.out, self.error)
...@@ -124,14 +134,14 @@ class PriorityCommandTest(CommandTest.CommandTest): ...@@ -124,14 +134,14 @@ class PriorityCommandTest(CommandTest.CommandTest):
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertFalse(self.output) self.assertFalse(self.output)
self.assertEquals(self.errors, command.usage() + "\n") self.assertEqual(self.errors, command.usage() + "\n")
def test_help(self): def test_help(self):
command = PriorityCommand(["help"], self.todolist, self.out, self.error) command = PriorityCommand(["help"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.output, "") self.assertEqual(self.output, "")
self.assertEquals(self.errors, command.usage() + "\n\n" + command.help() + "\n") self.assertEqual(self.errors, command.usage() + "\n\n" + command.help() + "\n")
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
...@@ -35,7 +35,7 @@ class RecurrenceTest(TopydoTest): ...@@ -35,7 +35,7 @@ class RecurrenceTest(TopydoTest):
self.todo.set_tag(config().tag_due(), future.isoformat()) self.todo.set_tag(config().tag_due(), future.isoformat())
new_todo = advance_recurring_todo(self.todo) new_todo = advance_recurring_todo(self.todo)
self.assertEquals(new_todo.due_date(), new_due) self.assertEqual(new_todo.due_date(), new_due)
def test_duedate2(self): def test_duedate2(self):
""" Where due date is today. """ """ Where due date is today. """
...@@ -45,7 +45,7 @@ class RecurrenceTest(TopydoTest): ...@@ -45,7 +45,7 @@ class RecurrenceTest(TopydoTest):
self.todo.set_tag(config().tag_due(), today.isoformat()) self.todo.set_tag(config().tag_due(), today.isoformat())
new_todo = advance_recurring_todo(self.todo) new_todo = advance_recurring_todo(self.todo)
self.assertEquals(new_todo.due_date(), new_due) self.assertEqual(new_todo.due_date(), new_due)
def test_duedate3(self): def test_duedate3(self):
""" Where due date is in the past. """ """ Where due date is in the past. """
...@@ -55,7 +55,7 @@ class RecurrenceTest(TopydoTest): ...@@ -55,7 +55,7 @@ class RecurrenceTest(TopydoTest):
self.todo.set_tag(config().tag_due(), past.isoformat()) self.todo.set_tag(config().tag_due(), past.isoformat())
new_todo = advance_recurring_todo(self.todo) new_todo = advance_recurring_todo(self.todo)
self.assertEquals(new_todo.due_date(), new_due) self.assertEqual(new_todo.due_date(), new_due)
def test_duedate4(self): def test_duedate4(self):
""" Where due date is in the past. """ """ Where due date is in the past. """
...@@ -65,7 +65,7 @@ class RecurrenceTest(TopydoTest): ...@@ -65,7 +65,7 @@ class RecurrenceTest(TopydoTest):
self.todo.set_tag(config().tag_due(), past.isoformat()) self.todo.set_tag(config().tag_due(), past.isoformat())
new_todo = strict_advance_recurring_todo(self.todo) new_todo = strict_advance_recurring_todo(self.todo)
self.assertEquals(new_todo.due_date(), new_due) self.assertEqual(new_todo.due_date(), new_due)
def test_duedate5(self): def test_duedate5(self):
""" Where due date is in the future. """ """ Where due date is in the future. """
...@@ -75,7 +75,7 @@ class RecurrenceTest(TopydoTest): ...@@ -75,7 +75,7 @@ class RecurrenceTest(TopydoTest):
self.todo.set_tag(config().tag_due(), future.isoformat()) self.todo.set_tag(config().tag_due(), future.isoformat())
new_todo = strict_advance_recurring_todo(self.todo) new_todo = strict_advance_recurring_todo(self.todo)
self.assertEquals(new_todo.due_date(), new_due) self.assertEqual(new_todo.due_date(), new_due)
def test_duedate6(self): def test_duedate6(self):
""" Where due date is today. """ """ Where due date is today. """
...@@ -85,21 +85,21 @@ class RecurrenceTest(TopydoTest): ...@@ -85,21 +85,21 @@ class RecurrenceTest(TopydoTest):
self.todo.set_tag(config().tag_due(), today.isoformat()) self.todo.set_tag(config().tag_due(), today.isoformat())
new_todo = strict_advance_recurring_todo(self.todo) new_todo = strict_advance_recurring_todo(self.todo)
self.assertEquals(new_todo.due_date(), new_due) self.assertEqual(new_todo.due_date(), new_due)
def test_noduedate1(self): def test_noduedate1(self):
new_due = date.today() + timedelta(7) new_due = date.today() + timedelta(7)
new_todo = advance_recurring_todo(self.todo) new_todo = advance_recurring_todo(self.todo)
self.assertTrue(new_todo.has_tag(config().tag_due())) self.assertTrue(new_todo.has_tag(config().tag_due()))
self.assertEquals(new_todo.due_date(), new_due) self.assertEqual(new_todo.due_date(), new_due)
def test_noduedate2(self): def test_noduedate2(self):
new_due = date.today() + timedelta(7) new_due = date.today() + timedelta(7)
new_todo = strict_advance_recurring_todo(self.todo) new_todo = strict_advance_recurring_todo(self.todo)
self.assertTrue(new_todo.has_tag(config().tag_due())) self.assertTrue(new_todo.has_tag(config().tag_due()))
self.assertEquals(new_todo.due_date(), new_due) self.assertEqual(new_todo.due_date(), new_due)
def test_startdate1(self): def test_startdate1(self):
""" Start date is before due date. """ """ Start date is before due date. """
...@@ -110,19 +110,20 @@ class RecurrenceTest(TopydoTest): ...@@ -110,19 +110,20 @@ class RecurrenceTest(TopydoTest):
new_start = date.today() + timedelta(6) new_start = date.today() + timedelta(6)
new_todo = advance_recurring_todo(self.todo) new_todo = advance_recurring_todo(self.todo)
self.assertEquals(new_todo.start_date(), new_start) self.assertEqual(new_todo.start_date(), new_start)
def test_startdate2(self): def test_startdate2(self):
""" Strict recurrence. Start date is before due date. """ """ Strict recurrence. Start date is before due date. """
due = date.today() - timedelta(1) due = date.today() - timedelta(1)
self.todo.set_tag(config().tag_due(), date.today().isoformat()) self.todo.set_tag(config().tag_due(), date.today().isoformat())
yesterday = due - timedelta(1) yesterday = due - timedelta(1)
# pylint: disable=E1103
self.todo.set_tag(config().tag_start(), yesterday.isoformat()) self.todo.set_tag(config().tag_start(), yesterday.isoformat())
new_start = date.today() + timedelta(5) new_start = date.today() + timedelta(5)
new_todo = strict_advance_recurring_todo(self.todo) new_todo = strict_advance_recurring_todo(self.todo)
self.assertEquals(new_todo.start_date(), new_start) self.assertEqual(new_todo.start_date(), new_start)
def test_startdate3(self): def test_startdate3(self):
""" Start date equals due date. """ """ Start date equals due date. """
...@@ -132,7 +133,7 @@ class RecurrenceTest(TopydoTest): ...@@ -132,7 +133,7 @@ class RecurrenceTest(TopydoTest):
new_start = date.today() + timedelta(7) new_start = date.today() + timedelta(7)
new_todo = advance_recurring_todo(self.todo) new_todo = advance_recurring_todo(self.todo)
self.assertEquals(new_todo.start_date(), new_start) self.assertEqual(new_todo.start_date(), new_start)
def test_no_recurrence(self): def test_no_recurrence(self):
self.todo.remove_tag('rec') self.todo.remove_tag('rec')
......
...@@ -18,9 +18,9 @@ from datetime import date, timedelta ...@@ -18,9 +18,9 @@ from datetime import date, timedelta
import unittest import unittest
from topydo.lib.RelativeDate import relative_date_to_date from topydo.lib.RelativeDate import relative_date_to_date
import TopydoTest from test.TopydoTest import TopydoTest
class RelativeDateTester(TopydoTest.TopydoTest): class RelativeDateTester(TopydoTest):
def setUp(self): def setUp(self):
super(RelativeDateTester, self).setUp() super(RelativeDateTester, self).setUp()
self.today = date.today() self.today = date.today()
...@@ -32,20 +32,20 @@ class RelativeDateTester(TopydoTest.TopydoTest): ...@@ -32,20 +32,20 @@ class RelativeDateTester(TopydoTest.TopydoTest):
def test_zero_days(self): def test_zero_days(self):
result = relative_date_to_date('0d') result = relative_date_to_date('0d')
self.assertEquals(result, self.today) self.assertEqual(result, self.today)
def test_one_day(self): def test_one_day(self):
result = relative_date_to_date('1d') result = relative_date_to_date('1d')
self.assertEquals(result, self.tomorrow) self.assertEqual(result, self.tomorrow)
def test_one_week(self): def test_one_week(self):
result = relative_date_to_date('1w') result = relative_date_to_date('1w')
self.assertEquals(result, date.today() + timedelta(weeks=1)) self.assertEqual(result, date.today() + timedelta(weeks=1))
def test_one_month(self): def test_one_month(self):
test_date = date(2015, 1, 10) test_date = date(2015, 1, 10)
result = relative_date_to_date('1m', test_date) result = relative_date_to_date('1m', test_date)
self.assertEquals(result, date(2015, 2, 10)) self.assertEqual(result, date(2015, 2, 10))
def test_one_month_ext(self): def test_one_month_ext(self):
test_date1 = date(2015, 1, 29) test_date1 = date(2015, 1, 29)
...@@ -60,31 +60,31 @@ class RelativeDateTester(TopydoTest.TopydoTest): ...@@ -60,31 +60,31 @@ class RelativeDateTester(TopydoTest.TopydoTest):
result4 = relative_date_to_date('1m', test_date4) result4 = relative_date_to_date('1m', test_date4)
result5 = relative_date_to_date('1m', test_date5) result5 = relative_date_to_date('1m', test_date5)
self.assertEquals(result1, date(2015, 2, 28)) self.assertEqual(result1, date(2015, 2, 28))
self.assertEquals(result2, date(2016, 2, 29)) self.assertEqual(result2, date(2016, 2, 29))
self.assertEquals(result3, date(2016, 1, 31)) self.assertEqual(result3, date(2016, 1, 31))
self.assertEquals(result4, date(2015, 8, 31)) self.assertEqual(result4, date(2015, 8, 31))
self.assertEquals(result5, date(2015, 11, 30)) self.assertEqual(result5, date(2015, 11, 30))
def test_one_year(self): def test_one_year(self):
test_date = date(2015, 1, 10) test_date = date(2015, 1, 10)
result = relative_date_to_date('1y', test_date) result = relative_date_to_date('1y', test_date)
self.assertEquals(result, date(2016, 1, 10)) self.assertEqual(result, date(2016, 1, 10))
def test_leap_year(self): def test_leap_year(self):
test_date = date(2016, 2, 29) test_date = date(2016, 2, 29)
result1 = relative_date_to_date('1y', test_date) result1 = relative_date_to_date('1y', test_date)
result2 = relative_date_to_date('4y', test_date) result2 = relative_date_to_date('4y', test_date)
self.assertEquals(result1, date(2017, 2, 28)) self.assertEqual(result1, date(2017, 2, 28))
self.assertEquals(result2, date(2020, 2, 29)) self.assertEqual(result2, date(2020, 2, 29))
def test_zero_months(self): def test_zero_months(self):
result = relative_date_to_date('0m') result = relative_date_to_date('0m')
self.assertEquals(result, self.today) self.assertEqual(result, self.today)
def test_zero_years(self): def test_zero_years(self):
result = relative_date_to_date('0y') result = relative_date_to_date('0y')
self.assertEquals(result, self.today) self.assertEqual(result, self.today)
def test_garbage1(self): def test_garbage1(self):
result = relative_date_to_date('0dd') result = relative_date_to_date('0dd')
...@@ -92,40 +92,40 @@ class RelativeDateTester(TopydoTest.TopydoTest): ...@@ -92,40 +92,40 @@ class RelativeDateTester(TopydoTest.TopydoTest):
def test_one_day_capital(self): def test_one_day_capital(self):
result = relative_date_to_date('1D') result = relative_date_to_date('1D')
self.assertEquals(result, self.tomorrow) self.assertEqual(result, self.tomorrow)
def test_today1(self): def test_today1(self):
result = relative_date_to_date('today') result = relative_date_to_date('today')
self.assertEquals(result, self.today) self.assertEqual(result, self.today)
def test_today2(self): def test_today2(self):
result = relative_date_to_date('tod') result = relative_date_to_date('tod')
self.assertEquals(result, self.today) self.assertEqual(result, self.today)
def test_today3(self): def test_today3(self):
result = relative_date_to_date('today', \ result = relative_date_to_date('today', \
date.today() + timedelta(1)) date.today() + timedelta(1))
self.assertEquals(result, self.today) self.assertEqual(result, self.today)
def test_tomorrow1(self): def test_tomorrow1(self):
result = relative_date_to_date('Tomorrow') result = relative_date_to_date('Tomorrow')
self.assertEquals(result, self.tomorrow) self.assertEqual(result, self.tomorrow)
def test_tomorrow2(self): def test_tomorrow2(self):
result = relative_date_to_date('tom') result = relative_date_to_date('tom')
self.assertEquals(result, self.tomorrow) self.assertEqual(result, self.tomorrow)
def test_monday1(self): def test_monday1(self):
result = relative_date_to_date('monday') result = relative_date_to_date('monday')
self.assertEquals(result, self.monday) self.assertEqual(result, self.monday)
def test_monday2(self): def test_monday2(self):
result = relative_date_to_date('mo') result = relative_date_to_date('mo')
self.assertEquals(result, self.monday) self.assertEqual(result, self.monday)
def test_monday3(self): def test_monday3(self):
result = relative_date_to_date('mon') result = relative_date_to_date('mon')
self.assertEquals(result, self.monday) self.assertEqual(result, self.monday)
def test_monday4(self): def test_monday4(self):
result = relative_date_to_date('mondayy') result = relative_date_to_date('mondayy')
...@@ -133,11 +133,11 @@ class RelativeDateTester(TopydoTest.TopydoTest): ...@@ -133,11 +133,11 @@ class RelativeDateTester(TopydoTest.TopydoTest):
def test_offset1(self): def test_offset1(self):
result = relative_date_to_date('1d', self.tomorrow) result = relative_date_to_date('1d', self.tomorrow)
self.assertEquals(result, date.today() + timedelta(2)) self.assertEqual(result, date.today() + timedelta(2))
def test_negative_period1(self): def test_negative_period1(self):
result = relative_date_to_date('-1d') result = relative_date_to_date('-1d')
self.assertEquals(result, date.today() - timedelta(1)) self.assertEqual(result, date.today() - timedelta(1))
def test_negative_period2(self): def test_negative_period2(self):
result = relative_date_to_date('-0d') result = relative_date_to_date('-0d')
......
...@@ -16,46 +16,46 @@ ...@@ -16,46 +16,46 @@
import unittest import unittest
import CommandTest
from topydo.lib.Config import config from topydo.lib.Config import config
from topydo.lib.SortCommand import SortCommand from topydo.commands.SortCommand import SortCommand
import TestFacilities from test.CommandTest import CommandTest
from test.TestFacilities import load_file_to_todolist
class SortCommandTest(CommandTest.CommandTest): class SortCommandTest(CommandTest):
def setUp(self): def setUp(self):
super(SortCommandTest, self).setUp() super(SortCommandTest, self).setUp()
self.todolist = TestFacilities.load_file_to_todolist("test/data/SorterTest1.txt") self.todolist = load_file_to_todolist("test/data/SorterTest1.txt")
def test_sort1(self): def test_sort1(self):
""" Alphabetically sorted """ """ Alphabetically sorted """
command = SortCommand(["text"], self.todolist, self.out, self.error) command = SortCommand(["text"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(str(self.todolist), "First\n(A) Foo\n2014-06-14 Last") self.assertEqual(str(self.todolist), "First\n(A) Foo\n2014-06-14 Last")
def test_sort2(self): def test_sort2(self):
command = SortCommand([], self.todolist, self.out, self.error) command = SortCommand([], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(str(self.todolist), "(A) Foo\n2014-06-14 Last\nFirst") self.assertEqual(str(self.todolist), "(A) Foo\n2014-06-14 Last\nFirst")
def test_sort3(self): def test_sort3(self):
""" Check that order does not influence the UID of a todo. """ """ Check that order does not influence the UID of a todo. """
config("test/data/todolist-uid.conf") config("test/data/todolist-uid.conf")
todo1 = self.todolist.todo('tpi') todo1 = self.todolist.todo('7ui')
command = SortCommand(["text"], self.todolist, self.out, self.error) command = SortCommand(["text"], self.todolist, self.out, self.error)
command.execute() command.execute()
todo2 = self.todolist.todo('tpi') todo2 = self.todolist.todo('7ui')
self.assertEquals(todo1.source(), todo2.source()) self.assertEqual(todo1.source(), todo2.source())
def test_help(self): def test_help(self):
command = SortCommand(["help"], self.todolist, self.out, self.error) command = SortCommand(["help"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.output, "") self.assertEqual(self.output, "")
self.assertEquals(self.errors, command.usage() + "\n\n" + command.help() + "\n") self.assertEqual(self.errors, command.usage() + "\n\n" + command.help() + "\n")
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
...@@ -33,8 +33,8 @@ class SorterTest(TopydoTest): ...@@ -33,8 +33,8 @@ class SorterTest(TopydoTest):
todos_sorted = todolist_to_string(p_sorter.sort(todos)) todos_sorted = todolist_to_string(p_sorter.sort(todos))
todos_ref = todolist_to_string(load_file(p_filename_ref)) todos_ref = todolist_to_string(load_file(p_filename_ref))
self.assertEquals(todos_sorted, todos_ref) self.assertEqual(todos_sorted, todos_ref)
self.assertEquals(todolist_to_string(todos), text_before) self.assertEqual(todolist_to_string(todos), text_before)
def test_sort1(self): def test_sort1(self):
""" Alphabetically sorted """ """ Alphabetically sorted """
...@@ -128,7 +128,7 @@ class SorterTest(TopydoTest): ...@@ -128,7 +128,7 @@ class SorterTest(TopydoTest):
view = todolist.view(sorter, []) view = todolist.view(sorter, [])
result = load_file('test/data/SorterTest10-result.txt') result = load_file('test/data/SorterTest10-result.txt')
self.assertEquals(str(view), todolist_to_string(result)) self.assertEqual(str(view), todolist_to_string(result))
def test_sort15(self): def test_sort15(self):
""" """
...@@ -141,7 +141,7 @@ class SorterTest(TopydoTest): ...@@ -141,7 +141,7 @@ class SorterTest(TopydoTest):
view = todolist.view(sorter, []) view = todolist.view(sorter, [])
result = load_file('test/data/SorterTest11-result.txt') result = load_file('test/data/SorterTest11-result.txt')
self.assertEquals(str(view), todolist_to_string(result)) self.assertEqual(str(view), todolist_to_string(result))
def test_sort16(self): def test_sort16(self):
""" """
...@@ -153,7 +153,7 @@ class SorterTest(TopydoTest): ...@@ -153,7 +153,7 @@ class SorterTest(TopydoTest):
view = todolist.view(sorter, []) view = todolist.view(sorter, [])
result = load_file('test/data/SorterTest12-result.txt') result = load_file('test/data/SorterTest12-result.txt')
self.assertEquals(str(view), todolist_to_string(result)) self.assertEqual(str(view), todolist_to_string(result))
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
...@@ -16,11 +16,11 @@ ...@@ -16,11 +16,11 @@
import unittest import unittest
import CommandTest from topydo.commands.TagCommand import TagCommand
from topydo.lib.TagCommand import TagCommand from test.CommandTest import CommandTest
from topydo.lib.TodoList import TodoList from topydo.lib.TodoList import TodoList
class TagCommandTest(CommandTest.CommandTest): class TagCommandTest(CommandTest):
def setUp(self): def setUp(self):
super(TagCommandTest, self).setUp() super(TagCommandTest, self).setUp()
todos = [ todos = [
...@@ -36,27 +36,27 @@ class TagCommandTest(CommandTest.CommandTest): ...@@ -36,27 +36,27 @@ class TagCommandTest(CommandTest.CommandTest):
command = TagCommand(["1", "due", "2014-10-22"], self.todolist, self.out, self.error) command = TagCommand(["1", "due", "2014-10-22"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.todolist.todo(1).source(), "Foo due:2014-10-22") self.assertEqual(self.todolist.todo(1).source(), "Foo due:2014-10-22")
self.assertEquals(self.output, "| 1| Foo due:2014-10-22\n") self.assertEqual(self.output, "| 1| Foo due:2014-10-22\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
def test_add_tag2(self): def test_add_tag2(self):
command = TagCommand(["Foo", "due", "2014-10-22"], self.todolist, self.out, self.error) command = TagCommand(["Foo", "due", "2014-10-22"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.todolist.todo(1).source(), "Foo due:2014-10-22") self.assertEqual(self.todolist.todo(1).source(), "Foo due:2014-10-22")
self.assertEquals(self.output, "| 1| Foo due:2014-10-22\n") self.assertEqual(self.output, "| 1| Foo due:2014-10-22\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
def test_add_tag3(self): def test_add_tag3(self):
command = TagCommand(["-a", "2", "due", "2014-10-19"], self.todolist, self.out, self.error) command = TagCommand(["-a", "2", "due", "2014-10-19"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.todolist.todo(2).source(), "Bar due:2014-10-22 due:2014-10-19") self.assertEqual(self.todolist.todo(2).source(), "Bar due:2014-10-22 due:2014-10-19")
self.assertEquals(self.output, "| 2| Bar due:2014-10-22 due:2014-10-19\n") self.assertEqual(self.output, "| 2| Bar due:2014-10-22 due:2014-10-19\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
def test_add_tag4(self): def test_add_tag4(self):
...@@ -65,150 +65,150 @@ class TagCommandTest(CommandTest.CommandTest): ...@@ -65,150 +65,150 @@ class TagCommandTest(CommandTest.CommandTest):
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertFalse(self.output) self.assertFalse(self.output)
self.assertEquals(self.errors, "Invalid todo number.\n") self.assertEqual(self.errors, "Invalid todo number.\n")
def test_set_tag4(self): def test_set_tag4(self):
command = TagCommand(["3", "due", "2014-10-20"], self.todolist, self.out, self.error) command = TagCommand(["3", "due", "2014-10-20"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "| 3| Baz due:2014-10-20\n") self.assertEqual(self.output, "| 3| Baz due:2014-10-20\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_set_tag5(self): def test_set_tag5(self):
command = TagCommand(["4", "due", "2014-10-20"], self.todolist, self.out, self.error, lambda t: "all") command = TagCommand(["4", "due", "2014-10-20"], self.todolist, self.out, self.error, lambda t: "all")
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, " 1. 2014-10-20\n 2. 2014-10-22\n| 4| Fnord due:2014-10-20 due:2014-10-20\n") self.assertEqual(self.output, " 1. 2014-10-20\n 2. 2014-10-22\n| 4| Fnord due:2014-10-20 due:2014-10-20\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_set_tag6(self): def test_set_tag6(self):
command = TagCommand(["4", "due", "2014-10-20"], self.todolist, self.out, self.error, lambda t: "1") command = TagCommand(["4", "due", "2014-10-20"], self.todolist, self.out, self.error, lambda t: "1")
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, " 1. 2014-10-20\n 2. 2014-10-22\n| 4| Fnord due:2014-10-20 due:2014-10-22\n") self.assertEqual(self.output, " 1. 2014-10-20\n 2. 2014-10-22\n| 4| Fnord due:2014-10-20 due:2014-10-22\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_set_tag7(self): def test_set_tag7(self):
command = TagCommand(["4", "due", "2014-10-20"], self.todolist, self.out, self.error, lambda t: "2") command = TagCommand(["4", "due", "2014-10-20"], self.todolist, self.out, self.error, lambda t: "2")
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, " 1. 2014-10-20\n 2. 2014-10-22\n| 4| Fnord due:2014-10-20 due:2014-10-20\n") self.assertEqual(self.output, " 1. 2014-10-20\n 2. 2014-10-22\n| 4| Fnord due:2014-10-20 due:2014-10-20\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_set_tag8(self): def test_set_tag8(self):
command = TagCommand(["4", "due", "2014-10-20"], self.todolist, self.out, self.error, lambda t: "") command = TagCommand(["4", "due", "2014-10-20"], self.todolist, self.out, self.error, lambda t: "")
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, " 1. 2014-10-20\n 2. 2014-10-22\n| 4| Fnord due:2014-10-20 due:2014-10-22\n") self.assertEqual(self.output, " 1. 2014-10-20\n 2. 2014-10-22\n| 4| Fnord due:2014-10-20 due:2014-10-22\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_set_tag9(self): def test_set_tag9(self):
command = TagCommand(["4", "due", "2014-10-20"], self.todolist, self.out, self.error, lambda t: "99") command = TagCommand(["4", "due", "2014-10-20"], self.todolist, self.out, self.error, lambda t: "99")
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, " 1. 2014-10-20\n 2. 2014-10-22\n| 4| Fnord due:2014-10-20 due:2014-10-22\n") self.assertEqual(self.output, " 1. 2014-10-20\n 2. 2014-10-22\n| 4| Fnord due:2014-10-20 due:2014-10-22\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_set_tag10(self): def test_set_tag10(self):
command = TagCommand(["-f", "4", "due", "2014-10-20"], self.todolist, self.out, self.error, lambda t: "99") command = TagCommand(["-f", "4", "due", "2014-10-20"], self.todolist, self.out, self.error, lambda t: "99")
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, "| 4| Fnord due:2014-10-20 due:2014-10-20\n") self.assertEqual(self.output, "| 4| Fnord due:2014-10-20 due:2014-10-20\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_rm_tag1(self): def test_rm_tag1(self):
command = TagCommand(["1", "due"], self.todolist, self.out, self.error) command = TagCommand(["1", "due"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "| 1| Foo\n") self.assertEqual(self.output, "| 1| Foo\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_rm_tag2(self): def test_rm_tag2(self):
command = TagCommand(["2", "due"], self.todolist, self.out, self.error) command = TagCommand(["2", "due"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, "| 2| Bar\n") self.assertEqual(self.output, "| 2| Bar\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_rm_tag3(self): def test_rm_tag3(self):
command = TagCommand(["4", "due"], self.todolist, self.out, self.error, lambda t: "all") command = TagCommand(["4", "due"], self.todolist, self.out, self.error, lambda t: "all")
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, " 1. 2014-10-20\n 2. 2014-10-22\n| 4| Fnord\n") self.assertEqual(self.output, " 1. 2014-10-20\n 2. 2014-10-22\n| 4| Fnord\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_rm_tag4(self): def test_rm_tag4(self):
command = TagCommand(["4", "due"], self.todolist, self.out, self.error, lambda t: "1") command = TagCommand(["4", "due"], self.todolist, self.out, self.error, lambda t: "1")
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, " 1. 2014-10-20\n 2. 2014-10-22\n| 4| Fnord due:2014-10-22\n") self.assertEqual(self.output, " 1. 2014-10-20\n 2. 2014-10-22\n| 4| Fnord due:2014-10-22\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_rm_tag6(self): def test_rm_tag6(self):
command = TagCommand(["4", "due"], self.todolist, self.out, self.error, lambda t: "99") command = TagCommand(["4", "due"], self.todolist, self.out, self.error, lambda t: "99")
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, " 1. 2014-10-20\n 2. 2014-10-22\n| 4| Fnord due:2014-10-20 due:2014-10-22\n") self.assertEqual(self.output, " 1. 2014-10-20\n 2. 2014-10-22\n| 4| Fnord due:2014-10-20 due:2014-10-22\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_rm_tag7(self): def test_rm_tag7(self):
command = TagCommand(["4", "due"], self.todolist, self.out, self.error, lambda t: "A") command = TagCommand(["4", "due"], self.todolist, self.out, self.error, lambda t: "A")
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, " 1. 2014-10-20\n 2. 2014-10-22\n| 4| Fnord due:2014-10-20 due:2014-10-22\n") self.assertEqual(self.output, " 1. 2014-10-20\n 2. 2014-10-22\n| 4| Fnord due:2014-10-20 due:2014-10-22\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_rm_tag8(self): def test_rm_tag8(self):
command = TagCommand(["5", "due"], self.todolist, self.out, self.error) command = TagCommand(["5", "due"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "") self.assertEqual(self.output, "")
self.assertEquals(self.errors, "Invalid todo number.\n") self.assertEqual(self.errors, "Invalid todo number.\n")
def test_rm_tag9(self): def test_rm_tag9(self):
command = TagCommand(["A", "due"], self.todolist, self.out, self.error) command = TagCommand(["A", "due"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "") self.assertEqual(self.output, "")
self.assertEquals(self.errors, "Invalid todo number.\n") self.assertEqual(self.errors, "Invalid todo number.\n")
def test_rm_tag10(self): def test_rm_tag10(self):
command = TagCommand(["-f", "4", "due"], self.todolist, self.out, self.error, lambda t: "A") command = TagCommand(["-f", "4", "due"], self.todolist, self.out, self.error, lambda t: "A")
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, "| 4| Fnord\n") self.assertEqual(self.output, "| 4| Fnord\n")
self.assertEquals(self.errors, "") self.assertEqual(self.errors, "")
def test_no_tag(self): def test_no_tag(self):
command = TagCommand(["4"], self.todolist, self.out, self.error) command = TagCommand(["4"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "") self.assertEqual(self.output, "")
self.assertEquals(self.errors, command.usage() + "\n") self.assertEqual(self.errors, command.usage() + "\n")
def test_help(self): def test_help(self):
command = TagCommand(["help"], self.todolist, self.out, self.error) command = TagCommand(["help"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.output, "") self.assertEqual(self.output, "")
self.assertEquals(self.errors, command.usage() + "\n\n" + command.help() + "\n") self.assertEqual(self.errors, command.usage() + "\n\n" + command.help() + "\n")
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
...@@ -48,7 +48,7 @@ class TodoBaseTester(TopydoTest): ...@@ -48,7 +48,7 @@ class TodoBaseTester(TopydoTest):
todo = TodoBase("(C) Foo id:1") todo = TodoBase("(C) Foo id:1")
todo.add_tag('id', '2') todo.add_tag('id', '2')
self.assertEquals(todo.source(), '(C) Foo id:1 id:2') self.assertEqual(todo.source(), '(C) Foo id:1 id:2')
def test_set_tag1(self): def test_set_tag1(self):
todo = TodoBase("(C) Foo foo:bar") todo = TodoBase("(C) Foo foo:bar")
...@@ -146,7 +146,7 @@ class TodoBaseTester(TopydoTest): ...@@ -146,7 +146,7 @@ class TodoBaseTester(TopydoTest):
todo = TodoBase("(A) Foo") todo = TodoBase("(A) Foo")
todo.set_priority('B') todo.set_priority('B')
self.assertEquals(todo.priority(), 'B') self.assertEqual(todo.priority(), 'B')
self.assertTrue(re.match(r'^\(B\) Foo$', todo.src)) self.assertTrue(re.match(r'^\(B\) Foo$', todo.src))
def test_set_priority2(self): def test_set_priority2(self):
...@@ -154,7 +154,7 @@ class TodoBaseTester(TopydoTest): ...@@ -154,7 +154,7 @@ class TodoBaseTester(TopydoTest):
todo = TodoBase("Foo") todo = TodoBase("Foo")
todo.set_priority('B') todo.set_priority('B')
self.assertEquals(todo.priority(), 'B') self.assertEqual(todo.priority(), 'B')
self.assertTrue(re.match(r'^\(B\) Foo$', todo.src)) self.assertTrue(re.match(r'^\(B\) Foo$', todo.src))
def test_set_priority3(self): def test_set_priority3(self):
...@@ -162,7 +162,7 @@ class TodoBaseTester(TopydoTest): ...@@ -162,7 +162,7 @@ class TodoBaseTester(TopydoTest):
todo = TodoBase("(A) Foo") todo = TodoBase("(A) Foo")
todo.set_priority('AB') todo.set_priority('AB')
self.assertEquals(todo.priority(), 'A') self.assertEqual(todo.priority(), 'A')
self.assertTrue(re.match(r'^\(A\) Foo$', todo.src)) self.assertTrue(re.match(r'^\(A\) Foo$', todo.src))
def test_set_priority4(self): def test_set_priority4(self):
...@@ -173,7 +173,7 @@ class TodoBaseTester(TopydoTest): ...@@ -173,7 +173,7 @@ class TodoBaseTester(TopydoTest):
todo.set_priority('B') todo.set_priority('B')
self.assertEquals(todo.priority(), 'B') self.assertEqual(todo.priority(), 'B')
self.assertTrue(re.match(r'^\(B\) \(A\)Foo$', todo.src)) self.assertTrue(re.match(r'^\(B\) \(A\)Foo$', todo.src))
def test_set_priority5(self): def test_set_priority5(self):
...@@ -181,7 +181,7 @@ class TodoBaseTester(TopydoTest): ...@@ -181,7 +181,7 @@ class TodoBaseTester(TopydoTest):
todo = TodoBase("(A) Foo") todo = TodoBase("(A) Foo")
todo.set_priority(None) todo.set_priority(None)
self.assertEquals(todo.priority(), None) self.assertEqual(todo.priority(), None)
self.assertTrue(re.match(r'^Foo$', todo.src)) self.assertTrue(re.match(r'^Foo$', todo.src))
def test_set_priority6(self): def test_set_priority6(self):
...@@ -190,32 +190,32 @@ class TodoBaseTester(TopydoTest): ...@@ -190,32 +190,32 @@ class TodoBaseTester(TopydoTest):
todo.set_priority('A') todo.set_priority('A')
self.assertFalse(todo.priority()) self.assertFalse(todo.priority())
self.assertEquals(todo.src, "x 2014-06-13 Foo") self.assertEqual(todo.src, "x 2014-06-13 Foo")
def test_project1(self): def test_project1(self):
todo = TodoBase("(C) Foo +Bar +Baz +Bar:") todo = TodoBase("(C) Foo +Bar +Baz +Bar:")
self.assertEquals(len(todo.projects()), 2) self.assertEqual(len(todo.projects()), 2)
self.assertIn('Bar', todo.projects()) self.assertIn('Bar', todo.projects())
self.assertIn('Baz', todo.projects()) self.assertIn('Baz', todo.projects())
def test_project2(self): def test_project2(self):
todo = TodoBase("(C) Foo +Bar+Baz") todo = TodoBase("(C) Foo +Bar+Baz")
self.assertEquals(len(todo.projects()), 1) self.assertEqual(len(todo.projects()), 1)
self.assertIn('Bar+Baz', todo.projects()) self.assertIn('Bar+Baz', todo.projects())
def test_context1(self): def test_context1(self):
todo = TodoBase("(C) Foo @Bar @Baz @Bar:") todo = TodoBase("(C) Foo @Bar @Baz @Bar:")
self.assertEquals(len(todo.contexts()), 2) self.assertEqual(len(todo.contexts()), 2)
self.assertIn('Bar', todo.contexts()) self.assertIn('Bar', todo.contexts())
self.assertIn('Baz', todo.contexts()) self.assertIn('Baz', todo.contexts())
def test_context2(self): def test_context2(self):
todo = TodoBase("(C) Foo @Bar+Baz") todo = TodoBase("(C) Foo @Bar+Baz")
self.assertEquals(len(todo.contexts()), 1) self.assertEqual(len(todo.contexts()), 1)
self.assertIn('Bar+Baz', todo.contexts()) self.assertIn('Bar+Baz', todo.contexts())
def test_completion1(self): def test_completion1(self):
...@@ -248,7 +248,7 @@ class TodoBaseTester(TopydoTest): ...@@ -248,7 +248,7 @@ class TodoBaseTester(TopydoTest):
today_str = today.isoformat() today_str = today.isoformat()
self.assertFalse(todo.priority()) self.assertFalse(todo.priority())
self.assertEquals(todo.fields['completionDate'], today) self.assertEqual(todo.fields['completionDate'], today)
self.assertTrue(re.match('^x ' + today_str + ' Foo', todo.src)) self.assertTrue(re.match('^x ' + today_str + ' Foo', todo.src))
def test_set_complete2(self): def test_set_complete2(self):
...@@ -258,7 +258,7 @@ class TodoBaseTester(TopydoTest): ...@@ -258,7 +258,7 @@ class TodoBaseTester(TopydoTest):
today = date.today() today = date.today()
today_str = today.isoformat() today_str = today.isoformat()
self.assertEquals(todo.fields['completionDate'], today) self.assertEqual(todo.fields['completionDate'], today)
self.assertTrue(re.match('^x ' + today_str + ' 2014-06-12 Foo', \ self.assertTrue(re.match('^x ' + today_str + ' 2014-06-12 Foo', \
todo.src)) todo.src))
...@@ -269,7 +269,7 @@ class TodoBaseTester(TopydoTest): ...@@ -269,7 +269,7 @@ class TodoBaseTester(TopydoTest):
today = date.today() today = date.today()
today_str = today.isoformat() today_str = today.isoformat()
self.assertEquals(todo.fields['completionDate'], today) self.assertEqual(todo.fields['completionDate'], today)
self.assertTrue(re.match('^x ' + today_str + ' Foo', todo.src)) self.assertTrue(re.match('^x ' + today_str + ' Foo', todo.src))
def test_set_complete4(self): def test_set_complete4(self):
...@@ -279,21 +279,21 @@ class TodoBaseTester(TopydoTest): ...@@ -279,21 +279,21 @@ class TodoBaseTester(TopydoTest):
today = date.today() today = date.today()
today_str = today.isoformat() today_str = today.isoformat()
self.assertEquals(todo.fields['completionDate'], today) self.assertEqual(todo.fields['completionDate'], today)
self.assertTrue(re.match('^x ' + today_str + ' 2014-06-12 Foo', todo.src)) self.assertTrue(re.match('^x ' + today_str + ' 2014-06-12 Foo', todo.src))
def test_set_complete5(self): def test_set_complete5(self):
todo = TodoBase("x 2014-06-13 Foo") todo = TodoBase("x 2014-06-13 Foo")
todo.set_completed() todo.set_completed()
self.assertEquals(todo.src, "x 2014-06-13 Foo") self.assertEqual(todo.src, "x 2014-06-13 Foo")
def test_set_complete6(self): def test_set_complete6(self):
todo = TodoBase("Foo") todo = TodoBase("Foo")
yesterday = date.today() - timedelta(1) yesterday = date.today() - timedelta(1)
todo.set_completed(yesterday) todo.set_completed(yesterday)
self.assertEquals(todo.src, "x {} Foo".format(yesterday.isoformat())) self.assertEqual(todo.src, "x {} Foo".format(yesterday.isoformat()))
def test_set_source_text(self): def test_set_source_text(self):
todo = TodoBase("(B) Foo") todo = TodoBase("(B) Foo")
...@@ -301,8 +301,8 @@ class TodoBaseTester(TopydoTest): ...@@ -301,8 +301,8 @@ class TodoBaseTester(TopydoTest):
new_text = "(C) Foo" new_text = "(C) Foo"
todo.set_source_text(new_text) todo.set_source_text(new_text)
self.assertEquals(todo.src, new_text) self.assertEqual(todo.src, new_text)
self.assertEquals(todo.priority(),'C') self.assertEqual(todo.priority(),'C')
def test_set_creation_date1(self): def test_set_creation_date1(self):
todo = TodoBase("Foo") todo = TodoBase("Foo")
...@@ -310,8 +310,8 @@ class TodoBaseTester(TopydoTest): ...@@ -310,8 +310,8 @@ class TodoBaseTester(TopydoTest):
todo.set_creation_date(creation_date) todo.set_creation_date(creation_date)
self.assertEquals(todo.creation_date(), creation_date) self.assertEqual(todo.creation_date(), creation_date)
self.assertEquals(todo.src, "2014-07-24 Foo") self.assertEqual(todo.src, "2014-07-24 Foo")
def test_set_creation_date2(self): def test_set_creation_date2(self):
todo = TodoBase("(A) Foo") todo = TodoBase("(A) Foo")
...@@ -319,8 +319,8 @@ class TodoBaseTester(TopydoTest): ...@@ -319,8 +319,8 @@ class TodoBaseTester(TopydoTest):
todo.set_creation_date(creation_date) todo.set_creation_date(creation_date)
self.assertEquals(todo.creation_date(), creation_date) self.assertEqual(todo.creation_date(), creation_date)
self.assertEquals(todo.src, "(A) 2014-07-24 Foo") self.assertEqual(todo.src, "(A) 2014-07-24 Foo")
def test_set_creation_date3(self): def test_set_creation_date3(self):
todo = TodoBase("(A) 2014-07-23 Foo") todo = TodoBase("(A) 2014-07-23 Foo")
...@@ -328,8 +328,8 @@ class TodoBaseTester(TopydoTest): ...@@ -328,8 +328,8 @@ class TodoBaseTester(TopydoTest):
todo.set_creation_date(creation_date) todo.set_creation_date(creation_date)
self.assertEquals(todo.creation_date(), creation_date) self.assertEqual(todo.creation_date(), creation_date)
self.assertEquals(todo.src, "(A) 2014-07-24 Foo") self.assertEqual(todo.src, "(A) 2014-07-24 Foo")
def test_set_creation_date4(self): def test_set_creation_date4(self):
todo = TodoBase("2014-07-23 Foo") todo = TodoBase("2014-07-23 Foo")
...@@ -337,8 +337,8 @@ class TodoBaseTester(TopydoTest): ...@@ -337,8 +337,8 @@ class TodoBaseTester(TopydoTest):
todo.set_creation_date(creation_date) todo.set_creation_date(creation_date)
self.assertEquals(todo.creation_date(), creation_date) self.assertEqual(todo.creation_date(), creation_date)
self.assertEquals(todo.src, "2014-07-24 Foo") self.assertEqual(todo.src, "2014-07-24 Foo")
def test_set_creation_date5(self): def test_set_creation_date5(self):
todo = TodoBase("x 2014-07-25 2014-07-23 Foo") todo = TodoBase("x 2014-07-25 2014-07-23 Foo")
...@@ -346,8 +346,8 @@ class TodoBaseTester(TopydoTest): ...@@ -346,8 +346,8 @@ class TodoBaseTester(TopydoTest):
todo.set_creation_date(creation_date) todo.set_creation_date(creation_date)
self.assertEquals(todo.creation_date(), creation_date) self.assertEqual(todo.creation_date(), creation_date)
self.assertEquals(todo.src, "x 2014-07-25 2014-07-24 Foo") self.assertEqual(todo.src, "x 2014-07-25 2014-07-24 Foo")
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from six import u
import unittest import unittest
from test.TestFacilities import load_file from test.TestFacilities import load_file
...@@ -23,7 +24,12 @@ class TodoFileTest(TopydoTest): ...@@ -23,7 +24,12 @@ class TodoFileTest(TopydoTest):
def test_empty_file(self): def test_empty_file(self):
todofile = load_file('test/data/TodoFileTest1.txt') todofile = load_file('test/data/TodoFileTest1.txt')
self.assertEquals(len(todofile), 0) self.assertEqual(len(todofile), 0)
def test_utf_8(self):
todofile = load_file('test/data/utf-8.txt')
self.assertEqual(todofile[0].source(), u('(C) \u25ba UTF-8 test \u25c4'))
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
...@@ -37,12 +37,12 @@ class TodoListTester(TopydoTest): ...@@ -37,12 +37,12 @@ class TodoListTester(TopydoTest):
self.todolist = TodoList(lines) self.todolist = TodoList(lines)
def test_contexts(self): def test_contexts(self):
self.assertEquals(set(['Context1', 'Context2']), \ self.assertEqual(set(['Context1', 'Context2']), \
self.todolist.contexts()) self.todolist.contexts())
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
def test_projects(self): def test_projects(self):
self.assertEquals(set(['Project1', 'Project2']), \ self.assertEqual(set(['Project1', 'Project2']), \
self.todolist.projects()) self.todolist.projects())
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -51,18 +51,18 @@ class TodoListTester(TopydoTest): ...@@ -51,18 +51,18 @@ class TodoListTester(TopydoTest):
count = self.todolist.count() count = self.todolist.count()
todo = self.todolist.add(text) todo = self.todolist.add(text)
self.assertEquals(self.todolist.todo(count+1).source(), text) self.assertEqual(self.todolist.todo(count+1).source(), text)
self.assertEquals(set(['Project1', 'Project2', 'Project3']), \ self.assertEqual(set(['Project1', 'Project2', 'Project3']), \
self.todolist.projects()) self.todolist.projects())
self.assertEquals(set(['Context1', 'Context2', 'Context3']), \ self.assertEqual(set(['Context1', 'Context2', 'Context3']), \
self.todolist.contexts()) self.todolist.contexts())
self.assertEquals(self.todolist.number(todo), 6) self.assertEqual(self.todolist.number(todo), 6)
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
def test_add2(self): def test_add2(self):
text = str(self.todolist) text = str(self.todolist)
self.todolist.add('') self.todolist.add('')
self.assertEquals(str(self.todolist), text) self.assertEqual(str(self.todolist), text)
def test_add3a(self): def test_add3a(self):
count = self.todolist.count() count = self.todolist.count()
...@@ -83,21 +83,21 @@ class TodoListTester(TopydoTest): ...@@ -83,21 +83,21 @@ class TodoListTester(TopydoTest):
def test_add4(self): def test_add4(self):
text = str(self.todolist) text = str(self.todolist)
self.todolist.add(' ') self.todolist.add(' ')
self.assertEquals(str(self.todolist), text) self.assertEqual(str(self.todolist), text)
def test_add5(self): def test_add5(self):
text = str(self.todolist) text = str(self.todolist)
self.todolist.add("\n") self.todolist.add("\n")
self.assertEquals(str(self.todolist), text) self.assertEqual(str(self.todolist), text)
def test_delete1(self): def test_delete1(self):
count = self.todolist.count() count = self.todolist.count()
todo = self.todolist.todo(2) todo = self.todolist.todo(2)
self.todolist.delete(todo) self.todolist.delete(todo)
self.assertEquals(self.todolist.todo(2).source(), \ self.assertEqual(self.todolist.todo(2).source(), \
"(C) Baz @Context1 +Project1 key:value") "(C) Baz @Context1 +Project1 key:value")
self.assertEquals(self.todolist.count(), count - 1) self.assertEqual(self.todolist.count(), count - 1)
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertRaises(InvalidTodoException, self.todolist.number, todo) self.assertRaises(InvalidTodoException, self.todolist.number, todo)
...@@ -105,9 +105,9 @@ class TodoListTester(TopydoTest): ...@@ -105,9 +105,9 @@ class TodoListTester(TopydoTest):
todo = self.todolist.todo(3) todo = self.todolist.todo(3)
self.todolist.append(todo, "@Context3") self.todolist.append(todo, "@Context3")
self.assertEquals(todo.source(), \ self.assertEqual(todo.source(), \
"(C) Baz @Context1 +Project1 key:value @Context3") "(C) Baz @Context1 +Project1 key:value @Context3")
self.assertEquals(set(['Context1', 'Context2', 'Context3']), \ self.assertEqual(set(['Context1', 'Context2', 'Context3']), \
self.todolist.contexts()) self.todolist.contexts())
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -116,8 +116,8 @@ class TodoListTester(TopydoTest): ...@@ -116,8 +116,8 @@ class TodoListTester(TopydoTest):
text = todo.text() text = todo.text()
self.todolist.append(todo, "foo:bar") self.todolist.append(todo, "foo:bar")
self.assertEquals(todo.text(), text) self.assertEqual(todo.text(), text)
self.assertEquals(todo.source(), \ self.assertEqual(todo.source(), \
"(C) Baz @Context1 +Project1 key:value foo:bar") "(C) Baz @Context1 +Project1 key:value foo:bar")
def test_append3(self): def test_append3(self):
...@@ -125,7 +125,7 @@ class TodoListTester(TopydoTest): ...@@ -125,7 +125,7 @@ class TodoListTester(TopydoTest):
text = todo.text() text = todo.text()
self.todolist.append(todo, '') self.todolist.append(todo, '')
self.assertEquals(todo.text(), text) self.assertEqual(todo.text(), text)
def test_todo(self): def test_todo(self):
count = self.todolist.count() count = self.todolist.count()
...@@ -136,11 +136,11 @@ class TodoListTester(TopydoTest): ...@@ -136,11 +136,11 @@ class TodoListTester(TopydoTest):
def test_string(self): def test_string(self):
# readlines() always ends a string with \n, but join() in str(todolist) # readlines() always ends a string with \n, but join() in str(todolist)
# doesn't necessarily. # doesn't necessarily.
self.assertEquals(str(self.todolist) + '\n', self.text) self.assertEqual(str(self.todolist) + '\n', self.text)
def test_count(self): def test_count(self):
""" Test that empty lines are not counted. """ """ Test that empty lines are not counted. """
self.assertEquals(self.todolist.count(), 5) self.assertEqual(self.todolist.count(), 5)
def test_todo_by_dep_id(self): def test_todo_by_dep_id(self):
""" Tests that todos can be retrieved by their id tag. """ """ Tests that todos can be retrieved by their id tag. """
...@@ -155,7 +155,7 @@ class TodoListTester(TopydoTest): ...@@ -155,7 +155,7 @@ class TodoListTester(TopydoTest):
todo = self.todolist.todo(6) todo = self.todolist.todo(6)
self.assertIsInstance(todo, Todo) self.assertIsInstance(todo, Todo)
self.assertEquals(todo.text(), "No number") self.assertEqual(todo.text(), "No number")
def test_todo_number2(self): def test_todo_number2(self):
todo = Todo("Non-existent") todo = Todo("Non-existent")
...@@ -171,7 +171,7 @@ class TodoListTester(TopydoTest): ...@@ -171,7 +171,7 @@ class TodoListTester(TopydoTest):
todo = self.todolist.todo(1) todo = self.todolist.todo(1)
self.todolist.set_priority(todo, 'F') self.todolist.set_priority(todo, 'F')
self.assertEquals(self.todolist.todo(1).priority(), 'F') self.assertEqual(self.todolist.todo(1).priority(), 'F')
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
def test_todo_priority2(self): def test_todo_priority2(self):
...@@ -183,7 +183,7 @@ class TodoListTester(TopydoTest): ...@@ -183,7 +183,7 @@ class TodoListTester(TopydoTest):
def test_erase(self): def test_erase(self):
self.todolist.erase() self.todolist.erase()
self.assertEquals(self.todolist.count(), 0) self.assertEqual(self.todolist.count(), 0)
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
def test_regex1(self): def test_regex1(self):
...@@ -193,20 +193,20 @@ class TodoListTester(TopydoTest): ...@@ -193,20 +193,20 @@ class TodoListTester(TopydoTest):
def test_regex3(self): def test_regex3(self):
todo = self.todolist.todo("project2") todo = self.todolist.todo("project2")
self.assertTrue(todo) self.assertTrue(todo)
self.assertEquals(todo.source(), "(D) Bar @Context1 +Project2") self.assertEqual(todo.source(), "(D) Bar @Context1 +Project2")
def test_uid1(self): def test_uid1(self):
config("test/data/todolist-uid.conf") config("test/data/todolist-uid.conf")
self.assertEquals(self.todolist.todo('6iu').source(), "(C) Foo @Context2 Not@Context +Project1 Not+Project") self.assertEqual(self.todolist.todo('t5c').source(), "(C) Foo @Context2 Not@Context +Project1 Not+Project")
def test_uid2(self): def test_uid2(self):
""" Changing the priority should not change the identifier. """ """ Changing the priority should not change the identifier. """
config("test/data/todolist-uid.conf") config("test/data/todolist-uid.conf")
todo = self.todolist.todo('6iu') todo = self.todolist.todo('t5c')
self.todolist.set_priority(todo, 'B') self.todolist.set_priority(todo, 'B')
self.assertEquals(self.todolist.todo('6iu').source(), "(B) Foo @Context2 Not@Context +Project1 Not+Project") self.assertEqual(self.todolist.todo('t5c').source(), "(B) Foo @Context2 Not@Context +Project1 Not+Project")
def test_uid3(self): def test_uid3(self):
""" """
...@@ -220,10 +220,10 @@ class TodoListTester(TopydoTest): ...@@ -220,10 +220,10 @@ class TodoListTester(TopydoTest):
""" Make sure that item has new text ID after append. """ """ Make sure that item has new text ID after append. """
config("test/data/todolist-uid.conf") config("test/data/todolist-uid.conf")
todo = self.todolist.todo('6iu') todo = self.todolist.todo('t5c')
self.todolist.append(todo, "A") self.todolist.append(todo, "A")
self.assertNotEquals(self.todolist.number(todo), '6iu') self.assertNotEqual(self.todolist.number(todo), 't5c')
class TodoListDependencyTester(TopydoTest): class TodoListDependencyTester(TopydoTest):
def setUp(self): def setUp(self):
...@@ -299,7 +299,7 @@ class TodoListDependencyTester(TopydoTest): ...@@ -299,7 +299,7 @@ class TodoListDependencyTester(TopydoTest):
self.todolist.add_dependency(todo6, todo7) self.todolist.add_dependency(todo6, todo7)
self.assertEquals(projects, todo7.projects()) self.assertEqual(projects, todo7.projects())
def test_add_dep4(self): def test_add_dep4(self):
""" """
...@@ -312,7 +312,7 @@ class TodoListDependencyTester(TopydoTest): ...@@ -312,7 +312,7 @@ class TodoListDependencyTester(TopydoTest):
self.todolist.add_dependency(todo6, todo8) self.todolist.add_dependency(todo6, todo8)
self.assertEquals(set(["Project", "AnotherProject"]), todo8.projects()) self.assertEqual(set(["Project", "AnotherProject"]), todo8.projects())
def test_remove_dep1(self): def test_remove_dep1(self):
from_todo = self.todolist.todo(3) from_todo = self.todolist.todo(3)
...@@ -328,7 +328,7 @@ class TodoListDependencyTester(TopydoTest): ...@@ -328,7 +328,7 @@ class TodoListDependencyTester(TopydoTest):
to_todo = self.todolist.todo(4) to_todo = self.todolist.todo(4)
self.todolist.remove_dependency(from_todo, to_todo) self.todolist.remove_dependency(from_todo, to_todo)
self.assertEquals(str(self.todolist), old) self.assertEqual(str(self.todolist), old)
def test_remove_todo_check_children(self): def test_remove_todo_check_children(self):
todo = self.todolist.todo(2) todo = self.todolist.todo(2)
......
...@@ -34,7 +34,7 @@ class ViewTest(TopydoTest): ...@@ -34,7 +34,7 @@ class ViewTest(TopydoTest):
todofilter = Filter.GrepFilter('+Project') todofilter = Filter.GrepFilter('+Project')
view = todolist.view(sorter, [todofilter]) view = todolist.view(sorter, [todofilter])
self.assertEquals(str(view), todolist_to_string(ref)) self.assertEqual(str(view), todolist_to_string(ref))
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
......
Foo @foóbąr due:tod id:1
Bar +baz t:tod before:1
[colorscheme]
priority_colors = A:1,B:2,C:3
[colorscheme]
priority_colors = A:magenta,B:light-cyan,C:gray
[colorscheme]
priority_colors = A:magenta,B:light-cyan,C:7,D:red,Z:foobar
[colorscheme]
priority_colors = A:,B:,C:
[colorscheme]
priority_colors =
project_color =
context_color =
link_color =
metadata_color =
[{"completed": false, "completion_date": null, "contexts": ["Context2"], "creation_date": null, "priority": "C", "projects": ["Project1"], "source": "(C) Foo @Context2 Not@Context +Project1 Not+Project", "tags": [], "text": "Foo @Context2 Not@Context +Project1 Not+Project"}, {"completed": false, "completion_date": null, "contexts": [], "creation_date": null, "priority": "C", "projects": [], "source": "(C) Drink beer @ home", "tags": [], "text": "Drink beer @ home"}, {"completed": false, "completion_date": null, "contexts": [], "creation_date": null, "priority": "C", "projects": [], "source": "(C) 13 + 29 = 42", "tags": [], "text": "13 + 29 = 42"}, {"completed": false, "completion_date": null, "contexts": ["Context1"], "creation_date": null, "priority": "D", "projects": ["Project2"], "source": "(D) Bar @Context1 +Project2 p:1", "tags": [["p", "1"]], "text": "Bar @Context1 +Project2"}]
This diff was suppressed by a .gitattributes entry.
[{"completed": false, "completion_date": null, "contexts": [], "creation_date": null, "priority": "C", "projects": [], "source": "(C) And some spécial tag:◄", "tags": [["tag", "◄"]], "text": "And some spécial"}]
(C) And some spécial tag:◄
(C) ► UTF-8 test ◄
...@@ -30,3 +30,16 @@ ignore_weekends = 1 ...@@ -30,3 +30,16 @@ ignore_weekends = 1
append_parent_projects = 0 append_parent_projects = 0
; Add parent contexts when adding sub todo items ; Add parent contexts when adding sub todo items
append_parent_contexts = 0 append_parent_contexts = 0
[colorscheme]
; Configure colorscheme. Accepted values are: black, [light-]red, [light-]green,
; [light-]yellow, [light-]blue, [light-]magenta, [light-]cyan, white
; [light-]gray, darkgray or numbers from 0 to 255. When number is specified color
; is matched from Xterm color chart available here:
; http://en.wikipedia.org/wiki/File:Xterm_256color_chart.svg
; priority_colors = A:cyan,B:yellow,C:blue
; project_color = red
; context_color = magenta
; metadata_color = green
; link_color = light-cyan
...@@ -19,48 +19,36 @@ This module is aware of all supported submodules and hands out a Command ...@@ -19,48 +19,36 @@ This module is aware of all supported submodules and hands out a Command
instance based on an argument list. instance based on an argument list.
""" """
from topydo.lib.Config import config import sys
from topydo.lib.AddCommand import AddCommand from topydo.lib.Config import config
from topydo.lib.AppendCommand import AppendCommand
from topydo.lib.DeleteCommand import DeleteCommand
from topydo.lib.DepCommand import DepCommand
from topydo.lib.DepriCommand import DepriCommand
from topydo.lib.DoCommand import DoCommand
from topydo.lib.EditCommand import EditCommand
from topydo.lib.IcalCommand import IcalCommand
from topydo.lib.ListCommand import ListCommand
from topydo.lib.ListContextCommand import ListContextCommand
from topydo.lib.ListProjectCommand import ListProjectCommand
from topydo.lib.PostponeCommand import PostponeCommand
from topydo.lib.PriorityCommand import PriorityCommand
from topydo.lib.SortCommand import SortCommand
from topydo.lib.TagCommand import TagCommand
_SUBCOMMAND_MAP = { _SUBCOMMAND_MAP = {
'add': AddCommand, 'add': 'AddCommand',
'app': AppendCommand, 'app': 'AppendCommand',
'append': AppendCommand, 'append': 'AppendCommand',
'del': DeleteCommand, 'del': 'DeleteCommand',
'dep': DepCommand, 'dep': 'DepCommand',
'depri': DepriCommand, 'depri': 'DepriCommand',
'do': DoCommand, 'do': 'DoCommand',
'edit': EditCommand, 'edit': 'EditCommand',
'ical': IcalCommand, 'exit': 'ExitCommand', # used for the prompt
'ls': ListCommand, 'ical': 'IcalCommand', # deprecated
'lscon': ListContextCommand, 'ls': 'ListCommand',
'listcon': ListContextCommand, 'lscon': 'ListContextCommand',
'lsprj': ListProjectCommand, 'listcon': 'ListContextCommand',
'lsproj': ListProjectCommand, 'lsprj': 'ListProjectCommand',
'listprj': ListProjectCommand, 'lsproj': 'ListProjectCommand',
'listproj': ListProjectCommand, 'listprj': 'ListProjectCommand',
'listproject': ListProjectCommand, 'listproj': 'ListProjectCommand',
'listprojects': ListProjectCommand, 'listproject': 'ListProjectCommand',
'postpone': PostponeCommand, 'listprojects': 'ListProjectCommand',
'pri': PriorityCommand, 'postpone': 'PostponeCommand',
'rm': DeleteCommand, 'pri': 'PriorityCommand',
'sort': SortCommand, 'quit': 'ExitCommand',
'tag': TagCommand, 'rm': 'DeleteCommand',
'sort': 'SortCommand',
'tag': 'TagCommand',
} }
def get_subcommand(p_args): def get_subcommand(p_args):
...@@ -78,6 +66,18 @@ def get_subcommand(p_args): ...@@ -78,6 +66,18 @@ def get_subcommand(p_args):
If no valid command could be found, the subcommand part of the tuple If no valid command could be found, the subcommand part of the tuple
is None. is None.
""" """
def import_subcommand(p_subcommand):
"""
Returns the class of the requested subcommand. An invalid p_subcommand
will result in an ImportError, since this is a programming mistake
(most likely an error in the _SUBCOMMAND_MAP).
"""
classname = _SUBCOMMAND_MAP[p_subcommand]
modulename = 'topydo.commands.{}'.format(classname)
__import__(modulename, globals(), locals(), [classname], 0)
return getattr(sys.modules[modulename], classname)
result = None result = None
args = p_args args = p_args
...@@ -85,7 +85,7 @@ def get_subcommand(p_args): ...@@ -85,7 +85,7 @@ def get_subcommand(p_args):
subcommand = p_args[0] subcommand = p_args[0]
if subcommand in _SUBCOMMAND_MAP: if subcommand in _SUBCOMMAND_MAP:
result = _SUBCOMMAND_MAP[subcommand] result = import_subcommand(subcommand)
args = args[1:] args = args[1:]
elif subcommand == 'help': elif subcommand == 'help':
try: try:
...@@ -100,12 +100,12 @@ def get_subcommand(p_args): ...@@ -100,12 +100,12 @@ def get_subcommand(p_args):
else: else:
p_command = config().default_command() p_command = config().default_command()
if p_command in _SUBCOMMAND_MAP: if p_command in _SUBCOMMAND_MAP:
result = _SUBCOMMAND_MAP[p_command] result = import_subcommand(p_command)
# leave args unchanged # leave args unchanged
except IndexError: except IndexError:
p_command = config().default_command() p_command = config().default_command()
if p_command in _SUBCOMMAND_MAP: if p_command in _SUBCOMMAND_MAP:
result = _SUBCOMMAND_MAP[p_command] result = import_subcommand(p_command)
return (result, args) return (result, args)
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 - 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
#
# 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/>.
""" Entry file for the Python todo.txt CLI. """
import sys
from topydo.cli.CLIApplicationBase import CLIApplicationBase, error
from topydo.lib import TodoFile
from topydo.lib.Config import config, ConfigError
# First thing is to poke the configuration and check whether it's sane
# The modules below may already read in configuration upon import, so
# make sure to bail out if the configuration is invalid.
try:
config()
except ConfigError as config_error:
error(str(config_error))
sys.exit(1)
from topydo.Commands import get_subcommand
from topydo.lib import TodoList
class CLIApplication(CLIApplicationBase):
"""
Class that represents the (original) Command Line Interface of Topydo.
"""
def __init__(self):
super(CLIApplication, self).__init__()
def run(self):
""" Main entry function. """
args = self._process_flags()
self.todofile = TodoFile.TodoFile(config().todotxt())
self.todolist = TodoList.TodoList(self.todofile.read())
(subcommand, args) = get_subcommand(args)
if subcommand == None:
self._usage()
if self._execute(subcommand, args) == False:
sys.exit(1)
def main():
""" Main entry point of the CLI. """
CLIApplication().run()
if __name__ == '__main__':
main()
# Topydo - A todo.txt client written in Python. # Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 - 2015 Bram Schoenmakers <me@bramschoenmakers.nl> # Copyright (C) 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # 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 # it under the terms of the GNU General Public License as published by
...@@ -14,15 +14,22 @@ ...@@ -14,15 +14,22 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
""" Entry file for the Python todo.txt CLI. """ """
Contains a base class for a CLI implementation of topydo and functions for the
I/O on the command-line.
"""
import getopt import getopt
import sys import sys
from six import PY2
from six.moves import input
MAIN_OPTS = "c:d:ht:v"
def usage(): def usage():
""" Prints the command-line usage of topydo. """ """ Prints the command-line usage of topydo. """
print """\ print("""\
Synopsis: topydo [-c <config>] [-d <archive>] [-t <todo.txt>] subcommand [help|args] Synopsis: topydo [-c <config>] [-d <archive>] [-t <todo.txt>] subcommand [help|args]
topydo -h topydo -h
topydo -v topydo -v
...@@ -52,9 +59,7 @@ Available commands: ...@@ -52,9 +59,7 @@ Available commands:
* tag * tag
Run `topydo help <subcommand>` for command-specific help. Run `topydo help <subcommand>` for command-specific help.
""" """)
sys.exit(0)
def write(p_file, p_string): def write(p_file, p_string):
""" """
...@@ -76,8 +81,8 @@ def error(p_string): ...@@ -76,8 +81,8 @@ def error(p_string):
def version(): def version():
""" Print the current version and exit. """ """ Print the current version and exit. """
from topydo.lib.Version import VERSION, LICENSE from topydo.lib.Version import VERSION, LICENSE
print "topydo {}\n".format(VERSION) print("topydo {}\n".format(VERSION))
print LICENSE print(LICENSE)
sys.exit(0) sys.exit(0)
from topydo.lib.Config import config, ConfigError from topydo.lib.Config import config, ConfigError
...@@ -91,52 +96,59 @@ except ConfigError as config_error: ...@@ -91,52 +96,59 @@ except ConfigError as config_error:
error(str(config_error)) error(str(config_error))
sys.exit(1) sys.exit(1)
from topydo.lib.Commands import get_subcommand from topydo.commands.ArchiveCommand import ArchiveCommand
from topydo.lib.ArchiveCommand import ArchiveCommand from topydo.commands.SortCommand import SortCommand
from topydo.lib.SortCommand import SortCommand
from topydo.lib import TodoFile from topydo.lib import TodoFile
from topydo.lib import TodoList from topydo.lib import TodoList
from topydo.lib import TodoListBase from topydo.lib import TodoListBase
from topydo.lib.Utils import escape_ansi from topydo.lib.Utils import escape_ansi
class CLIApplication(object): class CLIApplicationBase(object):
""" """
Class that represents the Command Line Interface of Topydo. Base class for a Command Line Interfaces (CLI) for topydo. Examples are the
original CLI and the Prompt interface.
Handles input/output of the various subcommand. Handles input/output of the various subcommands.
""" """
def __init__(self): def __init__(self):
self.todolist = TodoList.TodoList([]) self.todolist = TodoList.TodoList([])
self.todofile = None
self.config = config() def _usage(self):
self.path = self.config.todotxt() usage()
self.archive_path = self.config.archive() sys.exit(0)
def _process_flags(self): def _process_flags(self):
args = sys.argv[1:]
if PY2:
args = [arg.decode('utf-8') for arg in args]
try: try:
opts, args = getopt.getopt(sys.argv[1:], "c:d:ht:v") opts, args = getopt.getopt(args, MAIN_OPTS)
except getopt.GetoptError as e: except getopt.GetoptError as e:
error(str(e)) error(str(e))
sys.exit(1) sys.exit(1)
alt_path = None alt_config_path = None
alt_archive = None overrides = {}
for opt, value in opts: for opt, value in opts:
if opt == "-c": if opt == "-c":
self.config = config(value) alt_config_path = value
elif opt == "-t": elif opt == "-t":
alt_path = value overrides[('topydo', 'filename')] = value
elif opt == "-d": elif opt == "-d":
alt_archive = value overrides[('topydo', 'archive_filename')] = value
elif opt == "-v": elif opt == "-v":
version() version()
else: else:
usage() self._usage()
self.path = alt_path if alt_path else self.config.todotxt() if alt_config_path:
self.archive_path = alt_archive \ config(alt_config_path, overrides)
if alt_archive else self.config.archive() elif len(overrides):
config(p_overrides=overrides)
return args return args
...@@ -147,7 +159,7 @@ class CLIApplication(object): ...@@ -147,7 +159,7 @@ class CLIApplication(object):
This means that all completed tasks are moved to the archive file This means that all completed tasks are moved to the archive file
(defaults to done.txt). (defaults to done.txt).
""" """
archive_file = TodoFile.TodoFile(self.archive_path) archive_file = TodoFile.TodoFile(config().archive())
archive = TodoListBase.TodoListBase(archive_file.read()) archive = TodoListBase.TodoListBase(archive_file.read())
if archive: if archive:
...@@ -163,6 +175,12 @@ class CLIApplication(object): ...@@ -163,6 +175,12 @@ class CLIApplication(object):
else: else:
pass # TODO pass # TODO
def _input(self):
"""
Returns a function that retrieves user input.
"""
return input
def _execute(self, p_command, p_args): def _execute(self, p_command, p_args):
""" """
Execute a subcommand with arguments. p_command is a class (not an Execute a subcommand with arguments. p_command is a class (not an
...@@ -173,36 +191,23 @@ class CLIApplication(object): ...@@ -173,36 +191,23 @@ class CLIApplication(object):
self.todolist, self.todolist,
lambda o: write(sys.stdout, o), lambda o: write(sys.stdout, o),
error, error,
raw_input) self._input())
return False if command.execute() == False else True
def run(self):
""" Main entry function. """
args = self._process_flags()
todofile = TodoFile.TodoFile(self.path) if command.execute() != False:
self.todolist = TodoList.TodoList(todofile.read()) self._post_execute()
return True
(subcommand, args) = get_subcommand(args) return False
if subcommand == None:
usage()
if self._execute(subcommand, args) == False:
sys.exit(1)
def _post_execute(self):
if self.todolist.is_dirty(): if self.todolist.is_dirty():
self._archive() self._archive()
if config().keep_sorted(): if config().keep_sorted():
self._execute(SortCommand, []) self._execute(SortCommand, [])
todofile.write(str(self.todolist)) self.todofile.write(str(self.todolist))
def main(): def run(self):
""" Main entry point of the CLI. """ raise NotImplementedError
CLIApplication().run()
if __name__ == '__main__':
main()
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
#
# 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/>.
""" Entry file for the topydo Prompt interface (CLI). """
import os.path
import sys
from topydo.cli.CLIApplicationBase import CLIApplicationBase, error, usage
from topydo.cli.TopydoCompleter import TopydoCompleter
from prompt_toolkit.shortcuts import get_input
from prompt_toolkit.history import History
from topydo.lib.Config import config, ConfigError
# First thing is to poke the configuration and check whether it's sane
# The modules below may already read in configuration upon import, so
# make sure to bail out if the configuration is invalid.
try:
config()
except ConfigError as config_error:
error(str(config_error))
sys.exit(1)
from topydo.Commands import get_subcommand
from topydo.lib import TodoFile
from topydo.lib import TodoList
def _todotxt_mtime():
"""
Returns the mtime for the configured todo.txt file.
"""
try:
return os.path.getmtime(config().todotxt())
except os.error:
# file not found
return None
class PromptApplication(CLIApplicationBase):
"""
This class implements a variant of topydo's CLI showing a shell and
offering auto-completion thanks to the prompt toolkit.
"""
def __init__(self):
super(PromptApplication, self).__init__()
self._process_flags()
self.mtime = None
self.completer = None
def _load_file(self):
"""
Reads the configured todo.txt file and loads it into the todo list
instance.
If the modification time of the todo.txt file is equal to the last time
it was checked, nothing will be done.
"""
current_mtime = _todotxt_mtime()
if not self.todofile or self.mtime != current_mtime:
self.todofile = TodoFile.TodoFile(config().todotxt())
self.todolist = TodoList.TodoList(self.todofile.read())
self.mtime = current_mtime
# suppress upstream issue with Python 2.7
# pylint: disable=no-value-for-parameter
self.completer = TopydoCompleter(self.todolist)
def run(self):
""" Main entry function. """
history = History()
while True:
# (re)load the todo.txt file (only if it has been modified)
self._load_file()
try:
user_input = get_input(u'topydo> ', history=history,
completer=self.completer).split()
except (EOFError, KeyboardInterrupt):
sys.exit(0)
mtime_after = _todotxt_mtime()
if self.mtime != mtime_after:
# refuse to perform operations such as 'del' and 'do' if the
# todo.txt file has been changed in the background.
error("WARNING: todo.txt file was modified by another application.\nTo prevent unintended changes, this operation was not executed.")
continue
(subcommand, args) = get_subcommand(user_input)
try:
if self._execute(subcommand, args) != False:
self._post_execute()
except TypeError:
usage()
def main():
""" Main entry point of the prompt interface. """
PromptApplication().run()
if __name__ == '__main__':
main()
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
#
# 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/>.
import datetime
import re
from prompt_toolkit.completion import Completer, Completion
from topydo.lib.Config import config
from topydo.Commands import _SUBCOMMAND_MAP
from topydo.lib.RelativeDate import relative_date_to_date
def _date_suggestions():
"""
Returns a list of relative date that is presented to the user as auto
complete suggestions.
"""
# don't use strftime, prevent locales to kick in
days_of_week = {
0: "Monday",
1: "Tuesday",
2: "Wednesday",
3: "Thursday",
4: "Friday",
5: "Saturday",
6: "Sunday"
}
dates = [
'today',
'tomorrow',
]
# show days of week up to next week
dow = datetime.date.today().weekday()
for i in range(dow + 2 % 7, dow + 7):
dates.append(days_of_week[i % 7])
# and some more relative days starting from next week
dates += ["1w", "2w", "1m", "2m", "3m", "1y"]
return dates
class TopydoCompleter(Completer):
def __init__(self, p_todolist):
self.todolist = p_todolist
def _subcommands(self, p_word_before_cursor):
subcommands = [sc for sc in sorted(_SUBCOMMAND_MAP.keys()) if sc.startswith(p_word_before_cursor)]
for command in subcommands:
yield Completion(command, -len(p_word_before_cursor))
def _projects(self, p_word_before_cursor):
projects = [p for p in self.todolist.projects() if p.startswith(p_word_before_cursor[1:])]
for project in projects:
yield Completion("+" + project, -len(p_word_before_cursor))
def _contexts(self, p_word_before_cursor):
contexts = [c for c in self.todolist.contexts() if c.startswith(p_word_before_cursor[1:])]
for context in contexts:
yield Completion("@" + context, -len(p_word_before_cursor))
def _dates(self, p_word_before_cursor):
to_absolute = lambda s: relative_date_to_date(s).isoformat()
start_value_pos = p_word_before_cursor.find(':') + 1
value = p_word_before_cursor[start_value_pos:]
for reldate in _date_suggestions():
if not reldate.startswith(value):
continue
yield Completion(reldate, -len(value), display_meta=to_absolute(reldate))
def get_completions(self, p_document, p_complete_event):
# include all characters except whitespaces (for + and @)
word_before_cursor = p_document.get_word_before_cursor(True)
is_first_word = not re.match(r'\s*\S+\s', p_document.current_line_before_cursor)
if is_first_word:
return self._subcommands(word_before_cursor)
elif word_before_cursor.startswith('+'):
return self._projects(word_before_cursor)
elif word_before_cursor.startswith('@'):
return self._contexts(word_before_cursor)
elif word_before_cursor.startswith(config().tag_due() + ':'):
return self._dates(word_before_cursor)
elif word_before_cursor.startswith(config().tag_start() + ':'):
return self._dates(word_before_cursor)
return []
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 - 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
#
# 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/>.
""" Entry file for the Python todo.txt CLI. """
import sys
import getopt
from topydo.cli.CLIApplicationBase import MAIN_OPTS, error
from topydo.cli.CLI import CLIApplication
def main():
""" Main entry point of the CLI. """
try:
args = sys.argv[1:]
try:
opts, args = getopt.getopt(args, MAIN_OPTS)
except getopt.GetoptError as e:
error(str(e))
sys.exit(1)
if args[0] == 'prompt':
try:
from topydo.cli.Prompt import PromptApplication
PromptApplication().run()
except ImportError:
error("You have to install prompt-toolkit to run prompt mode.")
else:
CLIApplication().run()
except IndexError:
CLIApplication().run()
if __name__ == '__main__':
main()
...@@ -18,6 +18,9 @@ ...@@ -18,6 +18,9 @@
from datetime import date from datetime import date
import re import re
from sys import stdin
import codecs
from os.path import expanduser
from topydo.lib.Config import config from topydo.lib.Config import config
from topydo.lib.Command import Command from topydo.lib.Command import Command
...@@ -33,73 +36,109 @@ class AddCommand(Command): ...@@ -33,73 +36,109 @@ class AddCommand(Command):
super(AddCommand, self).__init__( super(AddCommand, self).__init__(
p_args, p_todolist, p_out, p_err, p_prompt) p_args, p_todolist, p_out, p_err, p_prompt)
self.text = ' '.join(p_args) self.text = ' '.join(p_args)
self.todo = None self.from_file = None
def _preprocess_input_todo(self): def _process_flags(self):
""" opts, args = self.getopt('f:')
Preprocesses user input when adding a task.
It detects a priority mid-sentence and puts it at the start. for opt, value in opts:
""" if opt == '-f':
self.text = re.sub(r'^(.+) (\([A-Z]\))(.*)$', r'\2 \1\3', self.text) self.from_file = expanduser(value)
def _postprocess_input_todo(self): self.args = args
"""
Post-processes a parsed todo when adding it to the list.
* It converts relative dates to absolute ones.
* Automatically inserts a creation date if not present.
* Handles more user-friendly dependencies with before:, partof: and
after: tags
"""
def convert_date(p_tag):
value = self.todo.tag_value(p_tag)
if value: def get_todos_from_file(self):
dateobj = relative_date_to_date(value) if self.from_file == '-':
if dateobj: f = stdin
self.todo.set_tag(p_tag, dateobj.isoformat()) else:
f = codecs.open(self.from_file, 'r', encoding='utf-8')
todos = f.read().splitlines()
return todos
def _add_todo(self, p_todo_text):
def _preprocess_input_todo(p_todo_text):
"""
Preprocesses user input when adding a task.
It detects a priority mid-sentence and puts it at the start.
"""
todo_text = re.sub(r'^(.+) (\([A-Z]\))(.*)$', r'\2 \1\3', p_todo_text)
return todo_text
def _postprocess_input_todo(p_todo):
"""
Post-processes a parsed todo when adding it to the list.
def add_dependencies(p_tag): * It converts relative dates to absolute ones.
for value in self.todo.tag_values(p_tag): * Automatically inserts a creation date if not present.
try: * Handles more user-friendly dependencies with before:, partof: and
dep = self.todolist.todo(value) after: tags
"""
def convert_date(p_tag):
value = p_todo.tag_value(p_tag)
if p_tag == 'after': if value:
self.todolist.add_dependency(self.todo, dep) dateobj = relative_date_to_date(value)
elif p_tag == 'before' or p_tag == 'partof': if dateobj:
self.todolist.add_dependency(dep, self.todo) p_todo.set_tag(p_tag, dateobj.isoformat())
except InvalidTodoException:
pass
self.todo.remove_tag(p_tag, value) def add_dependencies(p_tag):
for value in p_todo.tag_values(p_tag):
try:
dep = self.todolist.todo(value)
convert_date(config().tag_start()) if p_tag == 'after':
convert_date(config().tag_due()) self.todolist.add_dependency(p_todo, dep)
elif p_tag == 'before' or p_tag == 'partof':
self.todolist.add_dependency(dep, p_todo)
except InvalidTodoException:
pass
add_dependencies('partof') p_todo.remove_tag(p_tag, value)
add_dependencies('before')
add_dependencies('after')
self.todo.set_creation_date(date.today()) convert_date(config().tag_start())
convert_date(config().tag_due())
add_dependencies('partof')
add_dependencies('before')
add_dependencies('after')
p_todo.set_creation_date(date.today())
todo_text = _preprocess_input_todo(p_todo_text)
todo = self.todolist.add(todo_text)
_postprocess_input_todo(todo)
self.out(self.printer.print_todo(todo))
def execute(self): def execute(self):
""" Adds a todo item to the list. """ """ Adds a todo item to the list. """
if not super(AddCommand, self).execute(): if not super(AddCommand, self).execute():
return False return False
if self.text: self.printer.add_filter(PrettyPrinterNumbers(self.todolist))
self._preprocess_input_todo() self._process_flags()
self.todo = self.todolist.add(self.text)
self._postprocess_input_todo() if self.from_file:
new_todos = self.get_todos_from_file()
self.printer.add_filter(PrettyPrinterNumbers(self.todolist)) for todo in new_todos:
self.out(self.printer.print_todo(self.todo)) self._add_todo(todo)
else: else:
self.error(self.usage()) if self.text:
self._add_todo(self.text)
else:
self.error(self.usage())
def usage(self): def usage(self):
return """Synopsis: add <text>""" return """Synopsis:
add <text>
add -f <file>
add -f -"""
def help(self): def help(self):
return """\ return """\
...@@ -114,4 +153,6 @@ This subcommand automatically adds the creation date to the added item. ...@@ -114,4 +153,6 @@ This subcommand automatically adds the creation date to the added item.
todo number (not the dependency number). todo number (not the dependency number).
Example: add "Subtask partof:1" Example: add "Subtask partof:1"
-f : Add todo items from specified <file> or from standard input.
""" """
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from topydo.lib.DCommand import DCommand from topydo.commands.DCommand import DCommand
class DeleteCommand(DCommand): class DeleteCommand(DCommand):
def __init__(self, p_args, p_todolist, def __init__(self, p_args, p_todolist,
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
from datetime import date from datetime import date
from topydo.lib.DCommand import DCommand from topydo.commands.DCommand import DCommand
from topydo.lib.PrettyPrinter import PrettyPrinter from topydo.lib.PrettyPrinter import PrettyPrinter
from topydo.lib.PrettyPrinterFilter import PrettyPrinterNumbers from topydo.lib.PrettyPrinterFilter import PrettyPrinterNumbers
from topydo.lib.Recurrence import advance_recurring_todo, strict_advance_recurring_todo, NoRecurrenceException from topydo.lib.Recurrence import advance_recurring_todo, strict_advance_recurring_todo, NoRecurrenceException
......
...@@ -18,14 +18,18 @@ import os ...@@ -18,14 +18,18 @@ import os
from subprocess import call, check_call, CalledProcessError from subprocess import call, check_call, CalledProcessError
import tempfile import tempfile
from six import text_type, u
from topydo.lib.ExpressionCommand import ExpressionCommand from topydo.lib.ExpressionCommand import ExpressionCommand
from topydo.lib.MultiCommand import MultiCommand from topydo.lib.MultiCommand import MultiCommand
from topydo.lib.Config import config from topydo.lib.Config import config
from topydo.lib.Todo import Todo from topydo.lib.Todo import Todo
from topydo.lib.TodoListBase import InvalidTodoException
from topydo.lib.TodoList import TodoList from topydo.lib.TodoList import TodoList
from topydo.lib.PrettyPrinterFilter import PrettyPrinterNumbers from topydo.lib.PrettyPrinterFilter import PrettyPrinterNumbers
# the true and only editor
DEFAULT_EDITOR = 'vi'
# Access the base class of the TodoList instance kept inside EditCommand. We # Access the base class of the TodoList instance kept inside EditCommand. We
# cannot use super() inside the class itself # cannot use super() inside the class itself
BASE_TODOLIST = lambda tl: super(TodoList, tl) BASE_TODOLIST = lambda tl: super(TodoList, tl)
...@@ -54,14 +58,14 @@ class EditCommand(MultiCommand, ExpressionCommand): ...@@ -54,14 +58,14 @@ class EditCommand(MultiCommand, ExpressionCommand):
def _todos_to_temp(self): def _todos_to_temp(self):
f = tempfile.NamedTemporaryFile() f = tempfile.NamedTemporaryFile()
for todo in self.todos: for todo in self.todos:
f.write("%s\n" % todo.__str__()) f.write((text_type(todo) + "\n").encode('utf-8'))
f.seek(0) f.seek(0)
return f return f
def _todos_from_temp(self, temp_file): def _todos_from_temp(self, p_temp_file):
temp_file.seek(0) p_temp_file.seek(0)
todos = temp_file.read().splitlines() todos = p_temp_file.read().decode('utf-8').splitlines()
todo_objs = [] todo_objs = []
for todo in todos: for todo in todos:
...@@ -69,10 +73,10 @@ class EditCommand(MultiCommand, ExpressionCommand): ...@@ -69,10 +73,10 @@ class EditCommand(MultiCommand, ExpressionCommand):
return todo_objs return todo_objs
def _open_in_editor(self, temp_file, editor): def _open_in_editor(self, p_temp_file, p_editor):
try: try:
return check_call([editor, temp_file.name]) return check_call([p_editor, p_temp_file.name])
except(CalledProcessError): except CalledProcessError:
self.error('Something went wrong in the editor...') self.error('Something went wrong in the editor...')
return 1 return 1
...@@ -81,7 +85,7 @@ class EditCommand(MultiCommand, ExpressionCommand): ...@@ -81,7 +85,7 @@ class EditCommand(MultiCommand, ExpressionCommand):
if len(self.invalid_numbers) > 1 or len(self.invalid_numbers) > 0 and len(self.todos) > 0: if len(self.invalid_numbers) > 1 or len(self.invalid_numbers) > 0 and len(self.todos) > 0:
for number in self.invalid_numbers: for number in self.invalid_numbers:
errors.append("Invalid todo number given: {}.".format(number)) errors.append(u("Invalid todo number given: {}.").format(number))
elif len(self.invalid_numbers) == 1 and len(self.todos) == 0: elif len(self.invalid_numbers) == 1 and len(self.todos) == 0:
errors.append("Invalid todo number given.") errors.append("Invalid todo number given.")
...@@ -96,9 +100,9 @@ class EditCommand(MultiCommand, ExpressionCommand): ...@@ -96,9 +100,9 @@ class EditCommand(MultiCommand, ExpressionCommand):
self.printer.add_filter(PrettyPrinterNumbers(self.todolist)) self.printer.add_filter(PrettyPrinterNumbers(self.todolist))
try: try:
editor = os.environ['EDITOR'] or 'vi' editor = os.environ['EDITOR'] or DEFAULT_EDITOR
except(KeyError): except(KeyError):
editor = 'vi' editor = DEFAULT_EDITOR
try: try:
if len(self.args) < 1: if len(self.args) < 1:
......
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
#
# 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/>.
import sys
from topydo.lib.Command import Command
class ExitCommand(Command):
"""
A command that exits topydo. Used for the 'exit' and 'quit' subcommands on
the prompt CLI.
"""
def __init__(self, p_args, p_todolist, p_output, p_error, p_input):
super(ExitCommand, self).__init__(p_args, p_todolist, p_output, p_error,
p_input)
def execute(self):
if not super(ExitCommand, self).execute():
return False
sys.exit(0)
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
#
# 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/>.
"""
Stub for the former 'ical' subcommand, now replaced with 'ls -f ical'.
To be removed.
"""
from topydo.lib.Command import Command
class IcalCommand(Command):
def __init__(self, p_args, p_todolist,
p_out=lambda a: None,
p_err=lambda a: None,
p_prompt=lambda a: None):
super(IcalCommand, self).__init__(
p_args, p_todolist, p_out, p_err, p_prompt)
def execute(self):
self.error("The 'ical' subcommand is deprecated, please use 'ls -f ical' instead.")
return False
def usage(self):
return """Synopsis: ical"""
def help(self):
return """\
Deprecated. Use 'ls -f ical' instead.
"""
...@@ -14,17 +14,14 @@ ...@@ -14,17 +14,14 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import re
from topydo.lib.ExpressionCommand import ExpressionCommand from topydo.lib.ExpressionCommand import ExpressionCommand
from topydo.lib.Config import config from topydo.lib.Config import config
from topydo.lib import Filter
from topydo.lib.PrettyPrinterFilter import ( from topydo.lib.PrettyPrinterFilter import (
PrettyPrinterIndentFilter, PrettyPrinterIndentFilter,
PrettyPrinterHideTagFilter PrettyPrinterHideTagFilter
) )
from topydo.lib.Sorter import Sorter from topydo.lib.IcalPrinter import IcalPrinter
from topydo.lib.View import View from topydo.lib.JsonPrinter import JsonPrinter
class ListCommand(ExpressionCommand): class ListCommand(ExpressionCommand):
def __init__(self, p_args, p_todolist, def __init__(self, p_args, p_todolist,
...@@ -34,42 +31,92 @@ class ListCommand(ExpressionCommand): ...@@ -34,42 +31,92 @@ class ListCommand(ExpressionCommand):
super(ListCommand, self).__init__( super(ListCommand, self).__init__(
p_args, p_todolist, p_out, p_err, p_prompt) p_args, p_todolist, p_out, p_err, p_prompt)
self.printer = None
self.sort_expression = config().sort_string() self.sort_expression = config().sort_string()
self.show_all = False self.show_all = False
def _poke_icalendar(self):
"""
Attempts to import the icalendar package. Returns True if it
succeeds, otherwise False.
Raises a SyntaxError when icalendar couldn't be imported (most likely
under Python 3.2.
"""
try:
import icalendar as _
except ImportError:
self.error("icalendar package is not installed.")
return False
# may also raise SyntaxError, but we'll deal with that in execute()
return True
def _process_flags(self): def _process_flags(self):
opts, args = self.getopt('s:x') opts, args = self.getopt('f:s:x')
for opt, value in opts: for opt, value in opts:
if opt == '-x': if opt == '-x':
self.show_all = True self.show_all = True
elif opt == '-s': elif opt == '-s':
self.sort_expression = value self.sort_expression = value
elif opt == '-f':
if value == 'json':
self.printer = JsonPrinter()
elif value == 'ical':
if self._poke_icalendar():
self.printer = IcalPrinter(self.todolist)
else:
self.printer = None
self.args = args self.args = args
def _print(self): def _print(self):
""" Prints the todos. """ """
indent = config().list_indent() Prints the todos in the right format.
hidden_tags = config().hidden_tags()
Defaults to normal text output (with possible colors and other pretty
filters = [] printing. If a format was specified on the commandline, this format is
filters.append(PrettyPrinterIndentFilter(indent)) sent to the output.
filters.append(PrettyPrinterHideTagFilter(hidden_tags)) """
self.out(self._view().pretty_print(filters)) def _print_text():
"""
Outputs a pretty-printed text format of the todo list.
"""
indent = config().list_indent()
hidden_tags = config().hidden_tags()
filters = []
filters.append(PrettyPrinterIndentFilter(indent))
filters.append(PrettyPrinterHideTagFilter(hidden_tags))
self.out(self._view().pretty_print(filters))
if self.printer == None:
_print_text()
else:
# we have set a special format, simply use the printer set in
# self.printer
self.out(str(self._view()))
def execute(self): def execute(self):
if not super(ListCommand, self).execute(): if not super(ListCommand, self).execute():
return False return False
self._process_flags() try:
self._print() self._process_flags()
except SyntaxError:
# importing icalendar failed, most likely due to Python 3.2
self.error("icalendar is not supported in this Python version.")
return False
self._print()
return True return True
def usage(self): def usage(self):
return """Synopsis: ls [-x] [-s <sort_expression>] [expression]""" return """ Synopsis: ls [-x] [-s <sort_expression>] [-f <format>] [expression]"""
def help(self): def help(self):
return """\ return """\
...@@ -81,6 +128,14 @@ Lists all relevant todos. A todo is relevant when: ...@@ -81,6 +128,14 @@ Lists all relevant todos. A todo is relevant when:
When an expression is given, only the todos matching that expression are shown. When an expression is given, only the todos matching that expression are shown.
-f : Specify the output format, being 'text' (default), 'ical' or 'json'.
* 'text' - Text output with colors and identation if applicable.
* 'ical' - iCalendar (RFC 2445). Is not supported in Python 3.2. Be aware
that this is not a read-only operation, todo items may obtain
an 'ical' tag with a unique ID. Completed todo items may be
archived.
* 'json' - Javascript Object Notation (JSON)
-s : Sort the list according to a sort expression. Defaults to the expression -s : Sort the list according to a sort expression. Defaults to the expression
in the configuration. in the configuration.
-x : Show all todos (i.e. do not filter on dependencies or relevance). -x : Show all todos (i.e. do not filter on dependencies or relevance).
......
...@@ -28,7 +28,7 @@ class ListContextCommand(Command): ...@@ -28,7 +28,7 @@ class ListContextCommand(Command):
if not super(ListContextCommand, self).execute(): if not super(ListContextCommand, self).execute():
return False return False
for context in sorted(self.todolist.contexts(), key=str.lower): for context in sorted(self.todolist.contexts(), key=lambda s: s.lower()):
self.out(context) self.out(context)
def usage(self): def usage(self):
......
...@@ -28,7 +28,7 @@ class ListProjectCommand(Command): ...@@ -28,7 +28,7 @@ class ListProjectCommand(Command):
if not super(ListProjectCommand, self).execute(): if not super(ListProjectCommand, self).execute():
return False return False
for project in sorted(self.todolist.projects(), key=str.lower): for project in sorted(self.todolist.projects(), key=lambda s: s.lower()):
self.out(project) self.out(project)
def usage(self): def usage(self):
......
...@@ -68,8 +68,10 @@ class PostponeCommand(MultiCommand): ...@@ -68,8 +68,10 @@ class PostponeCommand(MultiCommand):
if self.move_start_date and todo.has_tag(config().tag_start()): if self.move_start_date and todo.has_tag(config().tag_start()):
length = todo.length() length = todo.length()
new_start = new_due - timedelta(length) new_start = new_due - timedelta(length)
# pylint: disable=E1103
todo.set_tag(config().tag_start(), new_start.isoformat()) todo.set_tag(config().tag_start(), new_start.isoformat())
# pylint: disable=E1103
todo.set_tag(config().tag_due(), new_due.isoformat()) todo.set_tag(config().tag_due(), new_due.isoformat())
self.todolist.set_dirty() self.todolist.set_dirty()
......
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 - 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
#
# 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/>.
""" This module serves for managing output colors. """
from topydo.lib.Config import config
NEUTRAL_COLOR = '\033[0m'
class Colors(object):
def __init__(self):
self.priority_colors = config().priority_colors()
self.project_color = config().project_color()
self.context_color = config().context_color()
self.metadata_color = config().metadata_color()
self.link_color = config().link_color()
def _int_to_ansi(self, p_int, p_decorator='normal', p_safe=True):
"""
Returns ansi code for color based on xterm color id (0-255) and
decoration, where decoration can be one of: normal, bold, faint,
italic, or underline. When p_safe is True, resulting ansi code is
constructed in most compatible way, but with support for only base 16
colors.
"""
decoration_dict = {
'normal': '0',
'bold': '1',
'faint': '2',
'italic': '3',
'underline': '4'
}
decoration = decoration_dict[p_decorator]
try:
if p_safe:
if 8 > int(p_int) >=0:
return '\033[{};3{}m'.format(decoration, str(p_int))
elif 16 > int(p_int):
p_int = int(p_int) - 8
return '\033[{};1;3{}m'.format(decoration, str(p_int))
if 256 > int(p_int) >=0:
return '\033[{};38;5;{}m'.format(decoration, str(p_int))
else:
return NEUTRAL_COLOR
except ValueError:
return None
def _name_to_int(self, p_color_name):
""" Returns xterm color id from color name. """
color_names_dict = {
'black': 0,
'red': 1,
'green': 2,
'yellow': 3,
'blue': 4,
'magenta': 5,
'cyan': 6,
'gray': 7,
'darkgray': 8,
'light-red': 9,
'light-green': 10,
'light-yellow': 11,
'light-blue': 12,
'light-magenta': 13,
'light-cyan': 14,
'white': 15,
}
try:
return color_names_dict[p_color_name]
except KeyError:
return 404
def _name_to_ansi(self, p_color_name, p_decorator):
""" Returns ansi color code from color name. """
number = self._name_to_int(p_color_name)
return self._int_to_ansi(number, p_decorator)
def _get_ansi(self, p_color, p_decorator):
""" Returns ansi color code from color name or xterm color id. """
if p_color == '':
ansi = ''
else:
ansi = self._int_to_ansi(p_color, p_decorator, False)
if not ansi:
ansi = self._name_to_ansi(p_color, p_decorator)
return ansi
def get_priority_colors(self):
pri_ansi_colors = dict()
for pri in self.priority_colors:
color = self._get_ansi(self.priority_colors[pri], 'normal')
if color == '':
color = NEUTRAL_COLOR
pri_ansi_colors[pri] = color
return pri_ansi_colors
def get_project_color(self):
return self._get_ansi(self.project_color, 'bold')
def get_context_color(self):
return self._get_ansi(self.context_color, 'bold')
def get_metadata_color(self):
return self._get_ansi(self.metadata_color, 'bold')
def get_link_color(self):
return self._get_ansi(self.link_color, 'underline')
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
import os import os
import ConfigParser from six.moves import configparser
class ConfigError(Exception): class ConfigError(Exception):
def __init__(self, p_text): def __init__(self, p_text):
...@@ -26,14 +26,19 @@ class ConfigError(Exception): ...@@ -26,14 +26,19 @@ class ConfigError(Exception):
return self.text return self.text
class _Config: class _Config:
def __init__(self, p_path=None): def __init__(self, p_path=None, p_overrides=None):
""" """
Constructor. Constructor.
If p_path is given, that is the only configuration file that will be If p_path is given, that is the only configuration file that will be
read. read.
If p_overrides is given, some options are ultimately overridden. This
is for some command line options which override any configuration file
(such as todo.txt location passed with -t). The key is a tuple of
(section, option), the value is the option's value.
""" """
self.sections = ['topydo', 'tags', 'sort', 'ls', 'dep'] self.sections = ['topydo', 'tags', 'sort', 'ls', 'dep', 'colorscheme']
self.defaults = { self.defaults = {
# topydo # topydo
...@@ -62,17 +67,25 @@ class _Config: ...@@ -62,17 +67,25 @@ class _Config:
# dep # dep
'append_parent_projects': '0', 'append_parent_projects': '0',
'append_parent_contexts': '0', 'append_parent_contexts': '0',
# colorscheme
'project_color': 'red',
'context_color': 'magenta',
'metadata_color': 'green',
'link_color': 'cyan',
'priority_colors': 'A:cyan,B:yellow,C:blue',
} }
self.config = {} self.config = {}
self.cp = ConfigParser.SafeConfigParser(self.defaults) self.cp = configparser.ConfigParser(self.defaults)
files = [ files = [
"/etc/topydo.conf", "/etc/topydo.conf",
self._home_config_path(), self._home_config_path(),
".topydo", ".topydo",
"topydo.conf" "topydo.conf",
"topydo.ini",
] ]
# when a path is given, *only* use the values in that file, or the # when a path is given, *only* use the values in that file, or the
...@@ -84,6 +97,10 @@ class _Config: ...@@ -84,6 +97,10 @@ class _Config:
self._supplement_sections() self._supplement_sections()
if p_overrides:
for (section, option), value in p_overrides.items():
self.cp.set(section, option, value)
def _supplement_sections(self): def _supplement_sections(self):
for section in self.sections: for section in self.sections:
if not self.cp.has_section(section): if not self.cp.has_section(section):
...@@ -177,18 +194,68 @@ class _Config: ...@@ -177,18 +194,68 @@ class _Config:
hidden_tags = self.cp.get('ls', 'hide_tags') hidden_tags = self.cp.get('ls', 'hide_tags')
return [] if hidden_tags == '' else hidden_tags.split(',') return [] if hidden_tags == '' else hidden_tags.split(',')
def config(p_path=None): def priority_colors(self):
""" Returns a dict with priorities as keys and color numbers as value. """
pri_colors_str = self.cp.get('colorscheme', 'priority_colors')
def _str_to_dict(p_string):
pri_colors_dict = dict()
for pri_color in p_string.split(','):
pri, color = pri_color.split(':')
pri_colors_dict[pri] = color
return pri_colors_dict
try:
if pri_colors_str == '':
pri_colors_dict = {'A':'', 'B': '', 'C': ''}
else:
pri_colors_dict = _str_to_dict(pri_colors_str)
except ValueError:
pri_colors_dict = _str_to_dict(self.defaults['priority_colors'])
return pri_colors_dict
def project_color(self):
try:
return self.cp.get('colorscheme', 'project_color')
except ValueError:
return int(self.defaults['project_color'])
def context_color(self):
try:
return self.cp.get('colorscheme', 'context_color')
except ValueError:
return int(self.defaults['context_color'])
def metadata_color(self):
try:
return self.cp.get('colorscheme', 'metadata_color')
except ValueError:
return int(self.defaults['metadata_color'])
def link_color(self):
try:
return self.cp.get('colorscheme', 'link_color')
except ValueError:
return int(self.defaults['link_color'])
def config(p_path=None, p_overrides=None):
""" """
Retrieve the config instance. Retrieve the config instance.
If a path is given, the instance is overwritten by the one that supplies an If a path is given, the instance is overwritten by the one that supplies an
additional filename (for testability). Moreover, no other configuration additional filename (for testability). Moreover, no other configuration
files will be read when a path is given. files will be read when a path is given.
Overrides will discard a setting in any configuration file and use the
passed value instead. Structure: (section, option) => value
The previous configuration instance will be discarded.
""" """
if not config.instance or p_path != None: if not config.instance or p_path != None or p_overrides != None:
try: try:
config.instance = _Config(p_path) config.instance = _Config(p_path, p_overrides)
except ConfigParser.ParsingError as perr: except configparser.ParsingError as perr:
raise ConfigError(str(perr)) raise ConfigError(str(perr))
return config.instance return config.instance
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import re import re
from six import text_type
from topydo.lib.Config import config from topydo.lib.Config import config
from topydo.lib.RelativeDate import relative_date_to_date from topydo.lib.RelativeDate import relative_date_to_date
...@@ -63,7 +64,7 @@ class GrepFilter(Filter): ...@@ -63,7 +64,7 @@ class GrepFilter(Filter):
super(GrepFilter, self).__init__() super(GrepFilter, self).__init__()
# convert to string in case we receive integers # convert to string in case we receive integers
self.expression = str(p_expression) self.expression = text_type(p_expression)
if p_case_sensitive != None: if p_case_sensitive != None:
self.case_sensitive = p_case_sensitive self.case_sensitive = p_case_sensitive
......
...@@ -92,7 +92,7 @@ class DirectedGraph(object): ...@@ -92,7 +92,7 @@ class DirectedGraph(object):
visited.add(current) visited.add(current)
if p_reverse: if p_reverse:
parents = [node for node, neighbors in self._edges.iteritems() \ parents = [node for node, neighbors in self._edges.items() \
if current in neighbors] if current in neighbors]
stack = stack + parents stack = stack + parents
...@@ -182,7 +182,7 @@ class DirectedGraph(object): ...@@ -182,7 +182,7 @@ class DirectedGraph(object):
""" """
removals = set() removals = set()
for from_node, neighbors in self._edges.iteritems(): for from_node, neighbors in self._edges.items():
childpairs = \ childpairs = \
[(c1, c2) for c1 in neighbors for c2 in neighbors if c1 != c2] [(c1, c2) for c1 in neighbors for c2 in neighbors if c1 != c2]
...@@ -198,7 +198,7 @@ class DirectedGraph(object): ...@@ -198,7 +198,7 @@ class DirectedGraph(object):
""" Prints the graph in Dot format. """ """ Prints the graph in Dot format. """
out = 'digraph g {\n' out = 'digraph g {\n'
for from_node, neighbors in self._edges.iteritems(): for from_node, neighbors in self._edges.items():
out += " {}\n".format(from_node) out += " {}\n".format(from_node)
for neighbor in neighbors: for neighbor in neighbors:
......
...@@ -19,6 +19,8 @@ Module that calculates identifiers for each item in a list, based on the hash ...@@ -19,6 +19,8 @@ Module that calculates identifiers for each item in a list, based on the hash
value of each item. value of each item.
""" """
from hashlib import sha1
_TABLE_SIZES = { _TABLE_SIZES = {
# we choose a large table size to reduce the chance of collisions. # we choose a large table size to reduce the chance of collisions.
3: 46649, # largest prime under zzz_36 3: 46649, # largest prime under zzz_36
...@@ -41,7 +43,7 @@ def _to_base36(p_value): ...@@ -41,7 +43,7 @@ def _to_base36(p_value):
return base36 or alphabet[0] return base36 or alphabet[0]
def hash_list_values(p_list, p_hash=hash): def hash_list_values(p_list, p_key=lambda i: i):
""" """
Calculates a unique value for each item in the list, these can be used as Calculates a unique value for each item in the list, these can be used as
identifiers. identifiers.
...@@ -61,8 +63,15 @@ def hash_list_values(p_list, p_hash=hash): ...@@ -61,8 +63,15 @@ def hash_list_values(p_list, p_hash=hash):
if len(p_list) < _TABLE_SIZES[3] * 0.01 else _TABLE_SIZES[4] if len(p_list) < _TABLE_SIZES[3] * 0.01 else _TABLE_SIZES[4]
for item in p_list: for item in p_list:
hash_value = p_hash(item) % size # obtain the to-be-hashed value
raw_value = p_key(item)
# hash
hasher = sha1()
hasher.update(raw_value.encode('utf-8'))
hash_value = int(hasher.hexdigest(), 16) % size
# resolve possible collisions
while hash_value in used: while hash_value in used:
hash_value = (hash_value + 1) % size hash_value = (hash_value + 1) % size
......
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
#
# 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/>.
"""
Implements a subcommand that outputs an iCalendar file.
"""
from topydo.lib.IcalPrinter import IcalPrinter
from topydo.lib.ListCommand import ListCommand
class IcalCommand(ListCommand):
def __init__(self, p_args, p_todolist,
p_out=lambda a: None,
p_err=lambda a: None,
p_prompt=lambda a: None):
super(IcalCommand, self).__init__(
p_args, p_todolist, p_out, p_err, p_prompt)
self.printer = IcalPrinter(p_todolist)
def _print(self):
self.out(str(self._view()))
def execute(self):
try:
import icalendar as _
except ImportError:
self.error("icalendar package is not installed.")
return False
return super(IcalCommand, self).execute()
def usage(self):
return """Synopsis: ical [-x] [expression]"""
def help(self):
return """\
Similar to the 'ls' subcommand, except that the todos are printed in iCalendar
format (RFC 2445) that can be imported by other calendar applications.
By default prints the active todo items, possibly filtered by the given
expression.
For the supported options, please refer to the help text of 'ls'
(topydo help ls).
While specifying the sort order is supported (-s flag), like in 'ls', this is
not meaningful in the context of an iCalendar file.
Note: be aware that this is not necessarily a read-only operation. This
subcommand may add ical tags to the printed todo items containing a unique ID.
Completed todo items may be archived.
Note: topydo does not support reading iCal files, this is merely a dump.
Changes made with other iCalendar enabled applications will not be processed.
Suggested usage is to use the output as a read-only calendar.
"""
...@@ -19,12 +19,6 @@ Provides a printer that transforms a list of Todo items to an iCalendar ...@@ -19,12 +19,6 @@ Provides a printer that transforms a list of Todo items to an iCalendar
file according to RFC 2445. file according to RFC 2445.
""" """
try:
import icalendar as ical
ICAL_PRESENT = True
except ImportError:
ICAL_PRESENT = False
from datetime import datetime, time from datetime import datetime, time
import random import random
import string import string
...@@ -72,21 +66,30 @@ class IcalPrinter(Printer): ...@@ -72,21 +66,30 @@ class IcalPrinter(Printer):
super(IcalPrinter, self).__init__() super(IcalPrinter, self).__init__()
self.todolist = p_todolist self.todolist = p_todolist
try:
import icalendar
self.icalendar = icalendar
except (SyntaxError, ImportError):
# icalendar does not support Python 3.2 resulting in a SyntaxError. Since
# this is an optional dependency, dropping Python 3.2 support altogether is
# too much. Therefore just disable the iCalendar functionality
self.icalendar = None
def print_todo(self, p_todo): def print_todo(self, p_todo):
return self._convert_todo(p_todo).to_ical() if ICAL_PRESENT else "" return self._convert_todo(p_todo).to_ical() if self.icalendar else ""
def print_list(self, p_todos): def print_list(self, p_todos):
result = "" result = ""
if ICAL_PRESENT: if self.icalendar:
cal = ical.Calendar() cal = self.icalendar.Calendar()
cal.add('prodid', '-//bramschoenmakers.nl//topydo//') cal.add('prodid', '-//bramschoenmakers.nl//topydo//')
cal.add('version', '2.0') cal.add('version', '2.0')
for todo in p_todos: for todo in p_todos:
cal.add_component(self._convert_todo(todo)) cal.add_component(self._convert_todo(todo))
result = cal.to_ical() result = cal.to_ical().decode('utf-8')
return result return result
...@@ -105,7 +108,7 @@ class IcalPrinter(Printer): ...@@ -105,7 +108,7 @@ class IcalPrinter(Printer):
""" """
return ''.join( return ''.join(
random.choice(string.ascii_letters + string.digits) random.choice(string.ascii_letters + string.digits)
for i in xrange(p_length)) for i in range(p_length))
uid = p_todo.tag_value('ical') uid = p_todo.tag_value('ical')
if not uid: if not uid:
...@@ -115,14 +118,14 @@ class IcalPrinter(Printer): ...@@ -115,14 +118,14 @@ class IcalPrinter(Printer):
return uid return uid
result = ical.Todo() result = self.icalendar.Todo()
# this should be called first, it may set the ical: tag and therefore # this should be called first, it may set the ical: tag and therefore
# change the source() output. # change the source() output.
result['uid'] = _get_uid(p_todo) result['uid'] = _get_uid(p_todo)
result['summary'] = ical.vText(p_todo.text()) result['summary'] = self.icalendar.vText(p_todo.text())
result['description'] = ical.vText(p_todo.source()) result['description'] = self.icalendar.vText(p_todo.source())
result.add('priority', _convert_priority(p_todo.priority())) result.add('priority', _convert_priority(p_todo.priority()))
start = p_todo.start_date() start = p_todo.start_date()
......
...@@ -14,45 +14,51 @@ ...@@ -14,45 +14,51 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import re """
import unittest Provides a printer that transforms a list of Todo items to a JSON structure
such that other applications can process it.
"""
from topydo.lib.Config import config import json
import CommandTest
from topydo.lib.IcalCommand import IcalCommand
import TestFacilities
class IcalCommandTest(CommandTest.CommandTest): from topydo.lib.PrettyPrinter import Printer
def setUp(self):
super(IcalCommandTest, self).setUp()
self.todolist = TestFacilities.load_file_to_todolist("test/data/ListCommandTest.txt")
def test_ical(self): def _convert_todo(p_todo):
def replace_ical_tags(p_text): """ Converts a Todo instance to a dictionary. """
# replace identifiers with dots, since they're random. creation_date = p_todo.creation_date()
result = re.sub(r'\bical:....\b', 'ical:....', p_text) completion_date = p_todo.completion_date()
result = re.sub(r'\bUID:....\b', 'UID:....', result)
return result result = {
'source': p_todo.source(),
'text': p_todo.text(),
'priority': p_todo.priority(),
'completed': p_todo.is_completed(),
'tags': p_todo.tags(),
'projects': list(p_todo.projects()),
'contexts': list(p_todo.contexts()),
'creation_date':
creation_date.isoformat() if creation_date else None,
'completion_date':
completion_date.isoformat() if completion_date else None
}
command = IcalCommand([""], self.todolist, self.out, self.error) return result
command.execute()
self.assertTrue(self.todolist.is_dirty()) class JsonPrinter(Printer):
"""
A printer that converts a list of Todo items to a string in JSON format.
"""
def __init__(self):
super(JsonPrinter, self).__init__()
icaltext = "" def print_todo(self, p_todo):
with open('test/data/ListCommandTest.ics', 'r') as ical: return json.dumps(_convert_todo(p_todo), ensure_ascii=False,
icaltext = "".join(ical.readlines()) sort_keys=True)
self.assertEquals(replace_ical_tags(self.output), replace_ical_tags(icaltext)) def print_list(self, p_todos):
self.assertEquals(self.errors, "") result = []
def test_help(self): for todo in p_todos:
command = IcalCommand(["help"], self.todolist, self.out, self.error) result.append(_convert_todo(todo))
command.execute()
self.assertEquals(self.output, "") return json.dumps(result, ensure_ascii=False, sort_keys=True)
self.assertEquals(self.errors, command.usage() + "\n\n" + command.help() + "\n")
if __name__ == '__main__':
unittest.main()
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from six import u
from topydo.lib.Command import Command from topydo.lib.Command import Command
from topydo.lib.TodoListBase import InvalidTodoException from topydo.lib.TodoListBase import InvalidTodoException
...@@ -52,7 +54,7 @@ class MultiCommand(Command): ...@@ -52,7 +54,7 @@ class MultiCommand(Command):
if len(self.invalid_numbers) > 1 or len(self.invalid_numbers) > 0 and len(self.todos) > 0: if len(self.invalid_numbers) > 1 or len(self.invalid_numbers) > 0 and len(self.todos) > 0:
for number in self.invalid_numbers: for number in self.invalid_numbers:
errors.append("Invalid todo number given: {}.".format(number)) errors.append(u("Invalid todo number given: {}.").format(number))
elif len(self.invalid_numbers) == 1 and len(self.todos) == 0: elif len(self.invalid_numbers) == 1 and len(self.todos) == 0:
errors.append("Invalid todo number given.") errors.append("Invalid todo number given.")
elif len(self.todos) == 0 and len(self.invalid_numbers) == 0: elif len(self.todos) == 0 and len(self.invalid_numbers) == 0:
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
import re import re
from topydo.lib.Config import config from topydo.lib.Config import config
from topydo.lib.Colors import Colors, NEUTRAL_COLOR
class PrettyPrinterFilter(object): class PrettyPrinterFilter(object):
""" """
...@@ -31,15 +32,6 @@ class PrettyPrinterFilter(object): ...@@ -31,15 +32,6 @@ class PrettyPrinterFilter(object):
""" Default implementation returns an unmodified todo string. """ """ Default implementation returns an unmodified todo string. """
return p_todo_str return p_todo_str
PRIORITY_COLORS = {
'A': '\033[36m', # cyan
'B': '\033[33m', # yellow
'C': '\033[34m' # blue
}
PROJECT_COLOR = '\033[31m' # red
NEUTRAL_COLOR = '\033[0m'
class PrettyPrinterColorFilter(PrettyPrinterFilter): class PrettyPrinterColorFilter(PrettyPrinterFilter):
""" """
Adds colors to the todo string by inserting ANSI codes. Adds colors to the todo string by inserting ANSI codes.
...@@ -50,22 +42,40 @@ class PrettyPrinterColorFilter(PrettyPrinterFilter): ...@@ -50,22 +42,40 @@ class PrettyPrinterColorFilter(PrettyPrinterFilter):
def filter(self, p_todo_str, p_todo): def filter(self, p_todo_str, p_todo):
""" Applies the colors. """ """ Applies the colors. """
colorscheme = Colors()
priority_colors = colorscheme.get_priority_colors()
project_color = colorscheme.get_project_color()
context_color = colorscheme.get_context_color()
metadata_color = colorscheme.get_metadata_color()
link_color = colorscheme.get_link_color()
if config().colors(): if config().colors():
color = NEUTRAL_COLOR color = NEUTRAL_COLOR
try: try:
color = PRIORITY_COLORS[p_todo.priority()] color = priority_colors[p_todo.priority()]
except KeyError: except KeyError:
pass pass
p_todo_str = color + p_todo_str + NEUTRAL_COLOR p_todo_str = color + p_todo_str
if config().highlight_projects_contexts(): if config().highlight_projects_contexts():
p_todo_str = re.sub( p_todo_str = re.sub(
r'\B(\+|@)(\S*\w)', r'\B(\+|@)(\S*\w)',
PROJECT_COLOR + r'\g<0>' + color, lambda m: (
context_color if m.group(0)[0] == "@"
else project_color) + m.group(0) + color,
p_todo_str) p_todo_str)
p_todo_str += NEUTRAL_COLOR # tags
p_todo_str = re.sub(r'\b\S+:[^/\s]\S+\b',
metadata_color + r'\g<0>' + color,
p_todo_str)
# add link_color to any valid URL specified outside of the tag.
p_todo_str = re.sub(r'(^|\s)(\w+:){1}(//\S+)',
' ' + link_color + r'\2\3' + color,
p_todo_str)
p_todo_str += NEUTRAL_COLOR
return p_todo_str return p_todo_str
......
...@@ -47,6 +47,7 @@ def _advance_recurring_todo_helper(p_todo, p_offset): ...@@ -47,6 +47,7 @@ def _advance_recurring_todo_helper(p_todo, p_offset):
if not new_due: if not new_due:
raise NoRecurrenceException() raise NoRecurrenceException()
# pylint: disable=E1103
todo.set_tag(config().tag_due(), new_due.isoformat()) todo.set_tag(config().tag_due(), new_due.isoformat())
if todo.start_date(): if todo.start_date():
......
...@@ -29,7 +29,7 @@ def _add_months(p_sourcedate, p_months): ...@@ -29,7 +29,7 @@ def _add_months(p_sourcedate, p_months):
https://stackoverflow.com/questions/4130922/how-to-increment-datetime-month-in-python https://stackoverflow.com/questions/4130922/how-to-increment-datetime-month-in-python
""" """
month = p_sourcedate.month - 1 + p_months month = p_sourcedate.month - 1 + p_months
year = p_sourcedate.year + month / 12 year = p_sourcedate.year + month // 12
month = month % 12 + 1 month = month % 12 + 1
day = min(p_sourcedate.day, calendar.monthrange(year, month)[1]) day = min(p_sourcedate.day, calendar.monthrange(year, month)[1])
......
...@@ -100,7 +100,8 @@ class Sorter(object): ...@@ -100,7 +100,8 @@ class Sorter(object):
sorted_todos = p_todos sorted_todos = p_todos
for function, order in reversed(self.functions): for function, order in reversed(self.functions):
sorted_todos = sorted(sorted_todos, None, function, order == 'desc') sorted_todos = sorted(sorted_todos, key=function,
reverse=(order == 'desc'))
return sorted_todos return sorted_todos
......
...@@ -20,10 +20,12 @@ This module contains the class that represents a single todo item. ...@@ -20,10 +20,12 @@ This module contains the class that represents a single todo item.
from datetime import date from datetime import date
import re import re
from six import python_2_unicode_compatible, u
from topydo.lib.TodoParser import parse_line from topydo.lib.TodoParser import parse_line
from topydo.lib.Utils import is_valid_priority from topydo.lib.Utils import is_valid_priority
@python_2_unicode_compatible
class TodoBase(object): class TodoBase(object):
""" """
This class represents a single todo item in a todo.txt file. It maintains This class represents a single todo item in a todo.txt file. It maintains
...@@ -128,6 +130,13 @@ class TodoBase(object): ...@@ -128,6 +130,13 @@ class TodoBase(object):
value = p_value if p_value != "" else r'\S+' value = p_value if p_value != "" else r'\S+'
self.src = re.sub(r'\s?\b' + p_key + ':' + value + r'\b', '', self.src) self.src = re.sub(r'\s?\b' + p_key + ':' + value + r'\b', '', self.src)
def tags(self):
"""
Returns a list of tuples with key-value pairs representing tags in
this todo item.
"""
return self.fields['tags']
def set_priority(self, p_priority): def set_priority(self, p_priority):
""" """
Sets the priority of the todo. Must be a single capital letter [A-Z], Sets the priority of the todo. Must be a single capital letter [A-Z],
...@@ -211,7 +220,7 @@ class TodoBase(object): ...@@ -211,7 +220,7 @@ class TodoBase(object):
self.src = re.sub( self.src = re.sub(
r'^(x \d{4}-\d{2}-\d{2} |\([A-Z]\) )?(\d{4}-\d{2}-\d{2} )?(.*)$', r'^(x \d{4}-\d{2}-\d{2} |\([A-Z]\) )?(\d{4}-\d{2}-\d{2} )?(.*)$',
lambda m: \ lambda m: \
"{}{} {}".format(m.group(1) or '', p_date.isoformat(), m.group(3)), u("{}{} {}").format(m.group(1) or '', p_date.isoformat(), m.group(3)),
self.src) self.src)
def creation_date(self): def creation_date(self):
......
...@@ -18,6 +18,8 @@ ...@@ -18,6 +18,8 @@
This module deals with todo.txt files. This module deals with todo.txt files.
""" """
import codecs
class TodoFile(object): class TodoFile(object):
""" """
This class represents a todo.txt file, which can be read from or written This class represents a todo.txt file, which can be read from or written
...@@ -31,7 +33,7 @@ class TodoFile(object): ...@@ -31,7 +33,7 @@ class TodoFile(object):
""" Reads the todo.txt file and returns a list of todo items. """ """ Reads the todo.txt file and returns a list of todo items. """
todos = [] todos = []
try: try:
todofile = open(self.path, 'r') todofile = codecs.open(self.path, 'r', encoding="utf-8")
todos = todofile.readlines() todos = todofile.readlines()
todofile.close() todofile.close()
except IOError: except IOError:
......
...@@ -249,7 +249,7 @@ class TodoListBase(object): ...@@ -249,7 +249,7 @@ class TodoListBase(object):
self._todo_id_map = {} self._todo_id_map = {}
self._id_todo_map = {} self._id_todo_map = {}
uids = hash_list_values(self._todos, lambda t: hash(t.text())) uids = hash_list_values(self._todos, lambda t: t.text())
for (todo, uid) in uids: for (todo, uid) in uids:
self._todo_id_map[todo] = uid self._todo_id_map[todo] = uid
......
""" Version of Topydo. """ """ Version of Topydo. """
VERSION = '0.3.2' VERSION = '0.4'
LICENSE = """Copyright (C) 2014 - 2015 Bram Schoenmakers LICENSE = """Copyright (C) 2014 - 2015 Bram Schoenmakers
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
......
...@@ -16,12 +16,15 @@ ...@@ -16,12 +16,15 @@
""" A view is a list of todos, sorted and filtered. """ """ A view is a list of todos, sorted and filtered. """
from six import python_2_unicode_compatible
from topydo.lib.PrettyPrinterFilter import ( from topydo.lib.PrettyPrinterFilter import (
PrettyPrinterColorFilter, PrettyPrinterColorFilter,
PrettyPrinterNumbers PrettyPrinterNumbers
) )
from topydo.lib.PrettyPrinter import PrettyPrinter from topydo.lib.PrettyPrinter import PrettyPrinter
@python_2_unicode_compatible
class View(object): class View(object):
""" """
A view is instantiated by a todo list, usually obtained from a todo.txt A view is instantiated by a todo list, usually obtained from a todo.txt
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment