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

Merge branch 'master' into stable

parents 40b96592 41e534bf
language: python
python:
- "2.7"
- "3.2"
- "3.3"
- "3.4"
install:
- "pip install ."
- "pip install icalendar"
- "pip install pylint"
script: "python setup.py test && pylint --errors-only topydo test"
script: "./run-tests.sh"
notifications:
webhooks:
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
-----
......@@ -27,7 +52,7 @@
* Fix assignment of dependency IDs: in some cases two distinct todos get the
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
---
......
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
feature, make sure to make a Pull Request on the `master` branch.
* This Github page defaults to the **stable** branch which is for **bug fixes
only**. If you would like to add a new feature, make sure to make a Pull
Request on the `master` branch.
* Run tests with:
python2 setup.py test
python3 setup.py test
Obviously, I won't accept anything that makes the tests fail. When you submit a Pull Request, Travis CI will
automatically run all tests for various Python 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.
./run-tests.sh [python2|python3]
Obviously, I won't accept anything that makes the tests fail. When you submit
a Pull Request, Travis CI will automatically run all tests for various Python
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.
* Add tests for your change(s):
* Bugfixes: add a testcase that covers your bugfix, so the bug won't happen ever again.
* Features: add testcases that checks various inputs and outputs of your feature. Be creative in trying to break the
feature you've just implemented.
* Bugfixes: add a testcase that covers your bugfix, so the bug won't happen
ever again.
* 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.
### 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,
but please try to avoid them.
* 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.
* Please try to adhere to the coding style dictated by `pylint` as much
possible. I won't be very picky about long lines, but please try to avoid
them.
* 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(
name = "topydo",
packages = ["topydo", "topydo.lib", "topydo.cli"],
version = "0.3.2",
packages = find_packages(exclude=["test"]),
version = "0.4",
description = "A command-line todo list application using the todo.txt format.",
author = "Bram Schoenmakers",
author_email = "me@bramschoenmakers.nl",
url = "https://github.com/bram85/topydo",
install_requires = [
'six >= 1.9.0',
],
extras_require = {
'ical': ['icalendar'],
'prompt-toolkit': ['prompt-toolkit >= 0.37'],
'edit-cmd-tests': ['mock'],
},
entry_points= {
'console_scripts': ['topydo = topydo.cli.Main:main'],
'console_scripts': ['topydo = topydo.cli.UILoader:main'],
},
classifiers = [
"Development Status :: 4 - Beta",
......@@ -22,6 +26,9 @@ setup(
"License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)",
"Natural Language :: English",
"Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3.2",
"Programming Language :: Python :: 3.3",
"Programming Language :: Python :: 3.4",
"Topic :: Utilities",
],
long_description = """\
......
......@@ -17,13 +17,23 @@
from datetime import date
import unittest
from topydo.lib import AddCommand
from topydo.lib import ListCommand
import CommandTest
# We're searching for 'mock'
# pylint: disable=no-name-in-module
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 import TodoList
class AddCommandTest(CommandTest.CommandTest):
class AddCommandTest(CommandTest):
def setUp(self):
super(AddCommandTest, self).setUp()
self.todolist = TodoList.TodoList([])
......@@ -34,48 +44,48 @@ class AddCommandTest(CommandTest.CommandTest):
command = AddCommand.AddCommand(args, self.todolist, self.out, self.error)
command.execute()
self.assertEquals(self.todolist.todo(1).source(), self.today + " New todo")
self.assertEquals(self.errors, "")
self.assertEqual(self.todolist.todo(1).source(), self.today + " New todo")
self.assertEqual(self.errors, "")
def test_add_multiple_args(self):
args = ["New", "todo"]
command = AddCommand.AddCommand(args, self.todolist, self.out, self.error)
command.execute()
self.assertEquals(self.todolist.todo(1).source(), self.today + " New todo")
self.assertEquals(self.errors, "")
self.assertEqual(self.todolist.todo(1).source(), self.today + " New todo")
self.assertEqual(self.errors, "")
def test_add_priority1(self):
command = AddCommand.AddCommand(["Foo (C)"], self.todolist, self.out, self.error)
command.execute()
self.assertEquals(self.todolist.todo(1).priority(), 'C')
self.assertEquals(self.todolist.todo(1).source(), "(C) " + self.today + " Foo")
self.assertEquals(self.errors, "")
self.assertEqual(self.todolist.todo(1).priority(), 'C')
self.assertEqual(self.todolist.todo(1).source(), "(C) " + self.today + " Foo")
self.assertEqual(self.errors, "")
def test_add_priority2(self):
command = AddCommand.AddCommand(["Foo (CC)"], self.todolist, self.out, self.error)
command.execute()
self.assertEquals(self.todolist.todo(1).priority(), None)
self.assertEquals(self.todolist.todo(1).source(), self.today + " Foo (CC)")
self.assertEquals(self.errors, "")
self.assertEqual(self.todolist.todo(1).priority(), None)
self.assertEqual(self.todolist.todo(1).source(), self.today + " Foo (CC)")
self.assertEqual(self.errors, "")
def test_add_priority3(self):
command = AddCommand.AddCommand(["Fo(C)o"], self.todolist, self.out, self.error)
command.execute()
self.assertEquals(self.todolist.todo(1).priority(), None)
self.assertEquals(self.todolist.todo(1).source(), self.today + " Fo(C)o" )
self.assertEquals(self.errors, "")
self.assertEqual(self.todolist.todo(1).priority(), None)
self.assertEqual(self.todolist.todo(1).source(), self.today + " Fo(C)o" )
self.assertEqual(self.errors, "")
def test_add_priority4(self):
command = AddCommand.AddCommand(["(C) Foo"], self.todolist, self.out, self.error)
command.execute()
self.assertEquals(self.todolist.todo(1).priority(), 'C')
self.assertEquals(self.todolist.todo(1).source(), "(C) " + self.today + " Foo")
self.assertEquals(self.errors, "")
self.assertEqual(self.todolist.todo(1).priority(), 'C')
self.assertEqual(self.todolist.todo(1).source(), "(C) " + self.today + " Foo")
self.assertEqual(self.errors, "")
def test_add_dep1(self):
command = AddCommand.AddCommand(["Foo"], self.todolist, self.out, self.error)
......@@ -84,9 +94,9 @@ class AddCommandTest(CommandTest.CommandTest):
command = AddCommand.AddCommand(["Bar before:1"], self.todolist, self.out, self.error)
command.execute()
self.assertEquals(self.todolist.todo(1).source(), self.today + " Foo id:1")
self.assertEquals(self.todolist.todo(2).source(), self.today + " Bar p:1")
self.assertEquals(self.errors, "")
self.assertEqual(self.todolist.todo(1).source(), self.today + " Foo id:1")
self.assertEqual(self.todolist.todo(2).source(), self.today + " Bar p:1")
self.assertEqual(self.errors, "")
def test_add_dep2(self):
command = AddCommand.AddCommand(["Foo"], self.todolist, self.out, self.error)
......@@ -95,9 +105,9 @@ class AddCommandTest(CommandTest.CommandTest):
command = AddCommand.AddCommand(["Bar partof:1"], self.todolist)
command.execute()
self.assertEquals(self.todolist.todo(1).source(), self.today + " Foo id:1")
self.assertEquals(self.todolist.todo(2).source(), self.today + " Bar p:1")
self.assertEquals(self.errors, "")
self.assertEqual(self.todolist.todo(1).source(), self.today + " Foo id:1")
self.assertEqual(self.todolist.todo(2).source(), self.today + " Bar p:1")
self.assertEqual(self.errors, "")
def test_add_dep3(self):
command = AddCommand.AddCommand(["Foo"], self.todolist)
......@@ -106,9 +116,9 @@ class AddCommandTest(CommandTest.CommandTest):
command = AddCommand.AddCommand(["Bar after:1"], self.todolist, self.out, self.error)
command.execute()
self.assertEquals(self.todolist.todo(1).source(), self.today + " Foo p:1")
self.assertEquals(self.todolist.todo(2).source(), self.today + " Bar id:1")
self.assertEquals(self.errors, "")
self.assertEqual(self.todolist.todo(1).source(), self.today + " Foo p:1")
self.assertEqual(self.todolist.todo(2).source(), self.today + " Bar id:1")
self.assertEqual(self.errors, "")
def test_add_dep4(self):
""" Test for using an after: tag with non-existing value. """
......@@ -116,9 +126,9 @@ class AddCommandTest(CommandTest.CommandTest):
command.execute()
self.assertFalse(self.todolist.todo(1).has_tag("after"))
self.assertEquals(self.todolist.todo(1).source(), self.today + " Foo")
self.assertEquals(self.output, "| 1| " + str(self.todolist.todo(1)) + "\n")
self.assertEquals(self.errors, "")
self.assertEqual(self.todolist.todo(1).source(), self.today + " Foo")
self.assertEqual(self.output, "| 1| " + str(self.todolist.todo(1)) + "\n")
self.assertEqual(self.errors, "")
def test_add_dep5(self):
""" Test for using an after: tag with non-existing value. """
......@@ -126,9 +136,9 @@ class AddCommandTest(CommandTest.CommandTest):
command.execute()
self.assertFalse(self.todolist.todo(1).has_tag("after"))
self.assertEquals(self.todolist.todo(1).source(), self.today + " Foo")
self.assertEquals(self.output, "| 1| " + str(self.todolist.todo(1)) + "\n")
self.assertEquals(self.errors, "")
self.assertEqual(self.todolist.todo(1).source(), self.today + " Foo")
self.assertEqual(self.output, "| 1| " + str(self.todolist.todo(1)) + "\n")
self.assertEqual(self.errors, "")
def test_add_dep6(self):
command = AddCommand.AddCommand(["Foo"], self.todolist, self.out, self.error)
......@@ -140,10 +150,10 @@ class AddCommandTest(CommandTest.CommandTest):
command = AddCommand.AddCommand(["Baz before:1 before:2"], self.todolist, self.out, self.error)
command.execute()
self.assertEquals(self.todolist.todo(1).source(), self.today + " Foo id:1")
self.assertEquals(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.assertEquals(self.errors, "")
self.assertEqual(self.todolist.todo(1).source(), self.today + " Foo id:1")
self.assertEqual(self.todolist.todo(2).source(), self.today + " Bar id:2")
self.assertEqual(self.todolist.todo(3).source(), self.today + " Baz p:1 p:2")
self.assertEqual(self.errors, "")
def test_add_dep7(self):
command = AddCommand.AddCommand(["Foo"], self.todolist, self.out, self.error)
......@@ -155,10 +165,10 @@ class AddCommandTest(CommandTest.CommandTest):
command = AddCommand.AddCommand(["Baz after:1 after:2"], self.todolist, self.out, self.error)
command.execute()
self.assertEquals(self.todolist.todo(1).source(), self.today + " Foo p:1")
self.assertEquals(self.todolist.todo(2).source(), self.today + " Bar p:1")
self.assertEquals(self.todolist.todo(3).source(), self.today + " Baz id:1")
self.assertEquals(self.errors, "")
self.assertEqual(self.todolist.todo(1).source(), self.today + " Foo p:1")
self.assertEqual(self.todolist.todo(2).source(), self.today + " Bar p:1")
self.assertEqual(self.todolist.todo(3).source(), self.today + " Baz id:1")
self.assertEqual(self.errors, "")
def test_add_dep8(self):
config("test/data/todolist-uid.conf")
......@@ -166,11 +176,11 @@ class AddCommandTest(CommandTest.CommandTest):
command = AddCommand.AddCommand(["Foo"], self.todolist, self.out, self.error)
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()
self.assertEquals(self.todolist.todo('tpi').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('7ui').source(), "{} Foo p:1".format(self.today))
self.assertEqual(self.todolist.todo('8to').source(), "{} Bar id:1".format(self.today))
def test_add_dep9(self):
"""
......@@ -184,13 +194,13 @@ class AddCommandTest(CommandTest.CommandTest):
command = AddCommand.AddCommand(["Foo +Project"], self.todolist, lambda t: t, self.error)
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 = ListCommand.ListCommand(["Bar"], self.todolist, self.out, self.error)
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):
"""
......@@ -204,42 +214,64 @@ class AddCommandTest(CommandTest.CommandTest):
command = AddCommand.AddCommand(["Foo @Context"], self.todolist, lambda t: t, self.error)
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 = ListCommand.ListCommand(["Bar"], self.todolist, self.out, self.error)
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):
command = AddCommand.AddCommand(["Foo due:today"], self.todolist, self.out, self.error)
command.execute()
self.assertEquals(self.todolist.todo(1).source(), self.today + " Foo due:" + self.today)
self.assertEquals(self.errors, "")
self.assertEqual(self.todolist.todo(1).source(), self.today + " Foo due:" + self.today)
self.assertEqual(self.errors, "")
def test_add_reldate2(self):
command = AddCommand.AddCommand(["Foo t:today due:today"], self.todolist, self.out, self.error)
command.execute()
result = "| 1| {} Foo t:{} due:{}\n".format(self.today, self.today, self.today)
self.assertEquals(self.output, result)
self.assertEquals(self.errors, "")
self.assertEqual(self.output, result)
self.assertEqual(self.errors, "")
def test_add_empty(self):
command = AddCommand.AddCommand([], self.todolist, self.out, self.error)
command.execute()
self.assertEquals(self.output, "")
self.assertEquals(self.errors, command.usage() + "\n")
self.assertEqual(self.output, "")
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):
command = AddCommand.AddCommand(["help"], self.todolist, self.out, self.error)
command.execute()
self.assertEquals(self.output, "")
self.assertEquals(self.errors, command.usage() + "\n\n" + command.help() + "\n")
self.assertEqual(self.output, "")
self.assertEqual(self.errors, command.usage() + "\n\n" + command.help() + "\n")
if __name__ == '__main__':
unittest.main()
......@@ -16,11 +16,11 @@
import unittest
from topydo.lib.AppendCommand import AppendCommand
import CommandTest
from topydo.commands.AppendCommand import AppendCommand
from test.CommandTest import CommandTest
from topydo.lib.TodoList import TodoList
class AppendCommandTest(CommandTest.CommandTest):
class AppendCommandTest(CommandTest):
def setUp(self):
super(AppendCommandTest, self).setUp()
self.todolist = TodoList([])
......@@ -79,8 +79,8 @@ class AppendCommandTest(CommandTest.CommandTest):
command = AppendCommand(["help"], self.todolist, self.out, self.error)
command.execute()
self.assertEquals(self.output, "")
self.assertEquals(self.errors, command.usage() + "\n\n" + command.help() + "\n")
self.assertEqual(self.output, "")
self.assertEqual(self.errors, command.usage() + "\n\n" + command.help() + "\n")
if __name__ == '__main__':
unittest.main()
......@@ -16,14 +16,14 @@
import unittest
from topydo.lib.ArchiveCommand import ArchiveCommand
import CommandTest
import TestFacilities
from topydo.commands.ArchiveCommand import ArchiveCommand
from test.CommandTest import CommandTest
from test.TestFacilities import load_file_to_todolist
from topydo.lib.TodoList import TodoList
class ArchiveCommandTest(CommandTest.CommandTest):
class ArchiveCommandTest(CommandTest):
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([])
command = ArchiveCommand(todolist, archive)
......@@ -31,8 +31,8 @@ class ArchiveCommandTest(CommandTest.CommandTest):
self.assertTrue(todolist.is_dirty())
self.assertTrue(archive.is_dirty())
self.assertEquals(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(todolist), "x Not complete\n(C) Active")
self.assertEqual(str(archive), "x 2014-10-19 Complete\nx 2014-10-20 Another one complete")
if __name__ == '__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 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import unittest
from six import PY2
from topydo.lib.Utils import escape_ansi
from test.TopydoTest import TopydoTest
......@@ -33,5 +34,13 @@ class CommandTest(TopydoTest):
if p_error:
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__':
unittest.main()
......@@ -21,13 +21,21 @@ from test.TopydoTest import TopydoTest
class ConfigTest(TopydoTest):
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):
self.assertNotEquals(config("").default_command(), 'do')
self.assertNotEqual(config("").default_command(), 'do')
def test_config3(self):
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__':
unittest.main()
......@@ -15,10 +15,11 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import unittest
from six import u
import CommandTest
from test.CommandTest import CommandTest
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.TodoListBase import InvalidTodoException
......@@ -28,7 +29,7 @@ def _yes_prompt(self):
def _no_prompt(self):
return "n"
class DeleteCommandTest(CommandTest.CommandTest):
class DeleteCommandTest(CommandTest):
def setUp(self):
super(DeleteCommandTest, self).setUp()
todos = [
......@@ -43,79 +44,79 @@ class DeleteCommandTest(CommandTest.CommandTest):
command.execute()
self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.todolist.todo(1).source(), "Bar")
self.assertEquals(self.output, "| 2| Bar p:1\nRemoved: Foo id:1\n")
self.assertEquals(self.errors, "")
self.assertEqual(self.todolist.todo(1).source(), "Bar")
self.assertEqual(self.output, "| 2| Bar p:1\nRemoved: Foo id:1\n")
self.assertEqual(self.errors, "")
def test_del1_regex(self):
command = DeleteCommand(["Foo"], self.todolist, self.out, self.error, _no_prompt)
command.execute()
self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.todolist.todo(1).source(), "Bar")
self.assertEquals(self.output, "| 2| Bar p:1\nRemoved: Foo id:1\n")
self.assertEquals(self.errors, "")
self.assertEqual(self.todolist.todo(1).source(), "Bar")
self.assertEqual(self.output, "| 2| Bar p:1\nRemoved: Foo id:1\n")
self.assertEqual(self.errors, "")
def test_del2(self):
command = DeleteCommand(["1"], self.todolist, self.out, self.error, _yes_prompt)
command.execute()
self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.todolist.count(), 0)
self.assertEquals(self.output, "| 2| Bar p:1\nRemoved: Bar\nRemoved: Foo\n")
self.assertEquals(self.errors, "")
self.assertEqual(self.todolist.count(), 0)
self.assertEqual(self.output, "| 2| Bar p:1\nRemoved: Bar\nRemoved: Foo\n")
self.assertEqual(self.errors, "")
def test_del3(self):
command = DeleteCommand(["-f", "1"], self.todolist, self.out, self.error, _yes_prompt)
command.execute()
self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.todolist.count(), 1) # force won't delete subtasks
self.assertEquals(self.output, "| 2| Bar p:1\nRemoved: Foo id:1\n")
self.assertEquals(self.errors, "")
self.assertEqual(self.todolist.count(), 1) # force won't delete subtasks
self.assertEqual(self.output, "| 2| Bar p:1\nRemoved: Foo id:1\n")
self.assertEqual(self.errors, "")
def test_del4(self):
command = DeleteCommand(["--force", "1"], self.todolist, self.out, self.error, _yes_prompt)
command.execute()
self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.todolist.count(), 1) # force won't delete subtasks
self.assertEquals(self.output, "| 2| Bar p:1\nRemoved: Foo id:1\n")
self.assertEquals(self.errors, "")
self.assertEqual(self.todolist.count(), 1) # force won't delete subtasks
self.assertEqual(self.output, "| 2| Bar p:1\nRemoved: Foo id:1\n")
self.assertEqual(self.errors, "")
def test_del5(self):
command = DeleteCommand(["2"], self.todolist, self.out, self.error)
command.execute()
self.assertTrue(self.todolist.is_dirty())
self.assertEquals(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.assertEquals(self.errors, "")
self.assertEqual(self.todolist.todo(1).source(), "Foo")
self.assertEqual(self.output, "Removed: Bar p:1\nThe following todo item(s) became active:\n| 1| Foo\n")
self.assertEqual(self.errors, "")
def test_del7(self):
command = DeleteCommand(["99"], self.todolist, self.out, self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "")
self.assertEquals(self.errors, "Invalid todo number given.\n")
self.assertEqual(self.output, "")
self.assertEqual(self.errors, "Invalid todo number given.\n")
def test_del8(self):
command = DeleteCommand(["A"], self.todolist, self.out, self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "")
self.assertEquals(self.errors, "Invalid todo number given.\n")
self.assertEqual(self.output, "")
self.assertEqual(self.errors, "Invalid todo number given.\n")
def test_del9(self):
""" Test deletion with textual IDs. """
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()
self.assertEquals(str(self.todolist), "Foo")
self.assertEqual(str(self.todolist), "Foo")
self.assertRaises(InvalidTodoException, self.todolist.todo, 'b0n')
def test_multi_del1(self):
......@@ -123,14 +124,14 @@ class DeleteCommandTest(CommandTest.CommandTest):
command = DeleteCommand(["1", "2"], self.todolist, self.out, self.error, _no_prompt)
command.execute()
self.assertEquals(self.todolist.count(), 0)
self.assertEqual(self.todolist.count(), 0)
def test_multi_del2(self):
""" Test deletion of multiple items. """
command = DeleteCommand(["1", "2"], self.todolist, self.out, self.error, _yes_prompt)
command.execute()
self.assertEquals(self.todolist.count(), 0)
self.assertEqual(self.todolist.count(), 0)
def test_multi_del3(self):
""" Fail if any of supplied todo numbers is invalid. """
......@@ -138,8 +139,8 @@ class DeleteCommandTest(CommandTest.CommandTest):
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "")
self.assertEquals(self.errors, "Invalid todo number given: 99.\n")
self.assertEqual(self.output, "")
self.assertEqual(self.errors, "Invalid todo number given: 99.\n")
def test_multi_del4(self):
""" Check output when all supplied todo numbers are invalid. """
......@@ -147,8 +148,17 @@ class DeleteCommandTest(CommandTest.CommandTest):
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "")
self.assertEquals(self.errors, "Invalid todo number given: 99.\nInvalid todo number given: A.\n")
self.assertEqual(self.output, "")
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):
command = DeleteCommand([], self.todolist, self.out, self.error)
......@@ -156,14 +166,14 @@ class DeleteCommandTest(CommandTest.CommandTest):
self.assertFalse(self.todolist.is_dirty())
self.assertFalse(self.output)
self.assertEquals(self.errors, command.usage() + "\n")
self.assertEqual(self.errors, command.usage() + "\n")
def test_help(self):
command = DeleteCommand(["help"], self.todolist, self.out, self.error)
command.execute()
self.assertEquals(self.output, "")
self.assertEquals(self.errors, command.usage() + "\n\n" + command.help() + "\n")
self.assertEqual(self.output, "")
self.assertEqual(self.errors, command.usage() + "\n\n" + command.help() + "\n")
if __name__ == '__main__':
unittest.main()
......@@ -16,11 +16,11 @@
import unittest
import CommandTest
from topydo.lib.DepCommand import DepCommand
from topydo.commands.DepCommand import DepCommand
from test.CommandTest import CommandTest
from topydo.lib.TodoList import TodoList
class DepCommandTest(CommandTest.CommandTest):
class DepCommandTest(CommandTest):
def setUp(self):
super(DepCommandTest, self).setUp()
todos = [
......@@ -40,8 +40,8 @@ class DepCommandTest(CommandTest.CommandTest):
self.assertTrue(self.todolist.is_dirty())
self.assertTrue(self.todolist.todo(4).has_tag('p', '1'))
self.assertEquals(self.output, "")
self.assertEquals(self.errors, "")
self.assertEqual(self.output, "")
self.assertEqual(self.errors, "")
def test_add2(self):
command = DepCommand(["add", "1", "4"], self.todolist, self.out, self.error)
......@@ -49,32 +49,32 @@ class DepCommandTest(CommandTest.CommandTest):
self.assertTrue(self.todolist.is_dirty())
self.assertTrue(self.todolist.todo(4).has_tag('p', '1'))
self.assertEquals(self.output, "")
self.assertEquals(self.errors, "")
self.assertEqual(self.output, "")
self.assertEqual(self.errors, "")
def test_add3(self):
command = DepCommand(["add", "99", "3"], self.todolist, self.out, self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "")
self.assertEquals(self.errors, "Invalid todo number given.\n")
self.assertEqual(self.output, "")
self.assertEqual(self.errors, "Invalid todo number given.\n")
def test_add4(self):
command = DepCommand(["add", "A", "3"], self.todolist, self.out, self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "")
self.assertEquals(self.errors, "Invalid todo number given.\n")
self.assertEqual(self.output, "")
self.assertEqual(self.errors, "Invalid todo number given.\n")
def test_add5(self):
command = DepCommand(["add", "1"], self.todolist, self.out, self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "")
self.assertEquals(self.errors, command.usage() + "\n")
self.assertEqual(self.output, "")
self.assertEqual(self.errors, command.usage() + "\n")
def test_add6(self):
command = DepCommand(["add", "1", "after", "4"], self.todolist, self.out, self.error)
......@@ -82,8 +82,8 @@ class DepCommandTest(CommandTest.CommandTest):
self.assertTrue(self.todolist.is_dirty())
self.assertTrue(self.todolist.todo(4).has_tag('p', '1'))
self.assertEquals(self.output, "")
self.assertEquals(self.errors, "")
self.assertEqual(self.output, "")
self.assertEqual(self.errors, "")
def test_add7(self):
command = DepCommand(["add", "1", "before", "4"], self.todolist, self.out, self.error)
......@@ -91,8 +91,8 @@ class DepCommandTest(CommandTest.CommandTest):
self.assertTrue(self.todolist.is_dirty())
self.assertTrue(self.todolist.todo(1).has_tag('p', '2'))
self.assertEquals(self.output, "")
self.assertEquals(self.errors, "")
self.assertEqual(self.output, "")
self.assertEqual(self.errors, "")
def test_add8(self):
command = DepCommand(["add", "1", "partof", "4"], self.todolist, self.out, self.error)
......@@ -100,8 +100,8 @@ class DepCommandTest(CommandTest.CommandTest):
self.assertTrue(self.todolist.is_dirty())
self.assertTrue(self.todolist.todo(1).has_tag('p', '2'))
self.assertEquals(self.output, "")
self.assertEquals(self.errors, "")
self.assertEqual(self.output, "")
self.assertEqual(self.errors, "")
def test_add9(self):
command = DepCommand(["add", "Foo", "to", "4"], self.todolist, self.out, self.error)
......@@ -109,8 +109,8 @@ class DepCommandTest(CommandTest.CommandTest):
self.assertTrue(self.todolist.is_dirty())
self.assertTrue(self.todolist.todo(4).has_tag('p', '1'))
self.assertEquals(self.output, "")
self.assertEquals(self.errors, "")
self.assertEqual(self.output, "")
self.assertEqual(self.errors, "")
def rm_helper(self, p_args):
"""
......@@ -124,8 +124,8 @@ class DepCommandTest(CommandTest.CommandTest):
self.assertTrue(self.todolist.is_dirty())
self.assertTrue(self.todolist.todo(1).has_tag('id', '1'))
self.assertFalse(self.todolist.todo(3).has_tag('p', '1'))
self.assertEquals(self.output, "")
self.assertEquals(self.errors, "")
self.assertEqual(self.output, "")
self.assertEqual(self.errors, "")
def test_rm1(self):
self.rm_helper(["rm", "1", "to", "3"])
......@@ -144,64 +144,64 @@ class DepCommandTest(CommandTest.CommandTest):
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "")
self.assertEquals(self.errors, "Invalid todo number given.\n")
self.assertEqual(self.output, "")
self.assertEqual(self.errors, "Invalid todo number given.\n")
def test_rm4(self):
command = DepCommand(["rm", "A", "3"], self.todolist, self.out, self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "")
self.assertEquals(self.errors, "Invalid todo number given.\n")
self.assertEqual(self.output, "")
self.assertEqual(self.errors, "Invalid todo number given.\n")
def test_rm5(self):
command = DepCommand(["rm", "1"], self.todolist, self.out, self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "")
self.assertEquals(self.errors, command.usage() + "\n")
self.assertEqual(self.output, "")
self.assertEqual(self.errors, command.usage() + "\n")
def test_ls1(self):
command = DepCommand(["ls", "1", "to"], self.todolist, self.out, self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "| 2| Bar p:1\n| 3| Baz p:1\n")
self.assertEquals(self.errors, "")
self.assertEqual(self.output, "| 2| Bar p:1\n| 3| Baz p:1\n")
self.assertEqual(self.errors, "")
def test_ls2(self):
command = DepCommand(["ls", "99", "to"], self.todolist, self.out, self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "")
self.assertEquals(self.errors, "Invalid todo number given.\n")
self.assertEqual(self.output, "")
self.assertEqual(self.errors, "Invalid todo number given.\n")
def test_ls3(self):
command = DepCommand(["ls", "to", "3"], self.todolist, self.out, self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "| 1| Foo id:1\n")
self.assertEquals(self.errors, "")
self.assertEqual(self.output, "| 1| Foo id:1\n")
self.assertEqual(self.errors, "")
def test_ls4(self):
command = DepCommand(["ls", "to", "99"], self.todolist, self.out, self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "")
self.assertEquals(self.errors, "Invalid todo number given.\n")
self.assertEqual(self.output, "")
self.assertEqual(self.errors, "Invalid todo number given.\n")
def test_ls5(self):
command = DepCommand(["ls", "1"], self.todolist, self.out, self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "")
self.assertEquals(self.errors, command.usage() + "\n")
self.assertEqual(self.output, "")
self.assertEqual(self.errors, command.usage() + "\n")
def test_ls6(self):
command = DepCommand(["ls"], self.todolist, self.out, self.error)
......@@ -209,7 +209,7 @@ class DepCommandTest(CommandTest.CommandTest):
self.assertFalse(self.todolist.is_dirty())
self.assertFalse(self.output)
self.assertEquals(self.errors, command.usage() + "\n")
self.assertEqual(self.errors, command.usage() + "\n")
def gc_helper(self, p_subcommand):
command = DepCommand([p_subcommand], self.todolist, self.out, self.error)
......@@ -246,8 +246,8 @@ class DepCommandTest(CommandTest.CommandTest):
command = DepCommand(["help"], self.todolist, self.out, self.error)
command.execute()
self.assertEquals(self.output, "")
self.assertEquals(self.errors, command.usage() + "\n\n" + command.help() + "\n")
self.assertEqual(self.output, "")
self.assertEqual(self.errors, command.usage() + "\n\n" + command.help() + "\n")
if __name__ == '__main__':
unittest.main()
......@@ -15,12 +15,13 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import unittest
from six import u
import CommandTest
from topydo.lib.DepriCommand import DepriCommand
from topydo.commands.DepriCommand import DepriCommand
from test.CommandTest import CommandTest
from topydo.lib.TodoList import TodoList
class DepriCommandTest(CommandTest.CommandTest):
class DepriCommandTest(CommandTest):
def setUp(self):
super(DepriCommandTest, self).setUp()
todos = [
......@@ -36,37 +37,37 @@ class DepriCommandTest(CommandTest.CommandTest):
command.execute()
self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.todolist.todo(1).priority(), None)
self.assertEquals(self.output, "Priority removed.\n| 1| Foo\n")
self.assertEquals(self.errors, "")
self.assertEqual(self.todolist.todo(1).priority(), None)
self.assertEqual(self.output, "Priority removed.\n| 1| Foo\n")
self.assertEqual(self.errors, "")
def test_depri2(self):
command = DepriCommand(["2"], self.todolist, self.out, self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.todolist.todo(2).priority(), None)
self.assertEquals(self.output, "")
self.assertEquals(self.errors, "")
self.assertEqual(self.todolist.todo(2).priority(), None)
self.assertEqual(self.output, "")
self.assertEqual(self.errors, "")
def test_depri3(self):
command = DepriCommand(["Foo"], self.todolist, self.out, self.error)
command.execute()
self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.todolist.todo(1).priority(), None)
self.assertEquals(self.output, "Priority removed.\n| 1| Foo\n")
self.assertEquals(self.errors, "")
self.assertEqual(self.todolist.todo(1).priority(), None)
self.assertEqual(self.output, "Priority removed.\n| 1| Foo\n")
self.assertEqual(self.errors, "")
def test_depri4(self):
command = DepriCommand(["1","Baz"], self.todolist, self.out, self.error)
command.execute()
self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.todolist.todo(1).priority(), None)
self.assertEquals(self.todolist.todo(3).priority(), None)
self.assertEquals(self.output, "Priority removed.\n| 1| Foo\nPriority removed.\n| 3| Baz\n")
self.assertEquals(self.errors, "")
self.assertEqual(self.todolist.todo(1).priority(), None)
self.assertEqual(self.todolist.todo(3).priority(), None)
self.assertEqual(self.output, "Priority removed.\n| 1| Foo\nPriority removed.\n| 3| Baz\n")
self.assertEqual(self.errors, "")
def test_invalid1(self):
......@@ -75,7 +76,7 @@ class DepriCommandTest(CommandTest.CommandTest):
self.assertFalse(self.todolist.is_dirty())
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):
command = DepriCommand(["99", "1"], self.todolist, self.out, self.error)
......@@ -83,7 +84,7 @@ class DepriCommandTest(CommandTest.CommandTest):
self.assertFalse(self.todolist.is_dirty())
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):
command = DepriCommand(["99", "FooBar"], self.todolist, self.out, self.error)
......@@ -91,7 +92,16 @@ class DepriCommandTest(CommandTest.CommandTest):
self.assertFalse(self.todolist.is_dirty())
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):
command = DepriCommand([], self.todolist, self.out, self.error)
......@@ -99,14 +109,14 @@ class DepriCommandTest(CommandTest.CommandTest):
self.assertFalse(self.todolist.is_dirty())
self.assertFalse(self.output)
self.assertEquals(self.errors, command.usage() + "\n")
self.assertEqual(self.errors, command.usage() + "\n")
def test_help(self):
command = DepriCommand(["help"], self.todolist, self.out, self.error)
command.execute()
self.assertEquals(self.output, "")
self.assertEquals(self.errors, command.usage() + "\n\n" + command.help() + "\n")
self.assertEqual(self.output, "")
self.assertEqual(self.errors, command.usage() + "\n\n" + command.help() + "\n")
if __name__ == '__main__':
unittest.main()
......@@ -16,9 +16,10 @@
from datetime import date, timedelta
import unittest
from six import u
import CommandTest
from topydo.lib.DoCommand import DoCommand
from topydo.commands.DoCommand import DoCommand
from test.CommandTest import CommandTest
from topydo.lib.TodoList import TodoList
def _yes_prompt(self):
......@@ -27,7 +28,7 @@ def _yes_prompt(self):
def _no_prompt(self):
return "n"
class DoCommandTest(CommandTest.CommandTest):
class DoCommandTest(CommandTest):
def setUp(self):
super(DoCommandTest, self).setUp()
todos = [
......@@ -57,9 +58,9 @@ class DoCommandTest(CommandTest.CommandTest):
self.assertTrue(self.todolist.is_dirty())
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.assertEquals(self.errors, "")
self.assertEqual(self.errors, "")
def test_do_subtasks1(self):
command = DoCommand(["1"], self.todolist, self.out, self.error, _yes_prompt)
......@@ -72,8 +73,8 @@ class DoCommandTest(CommandTest.CommandTest):
self.assertTrue(self.todolist.is_dirty())
self.assertFalse(self.todolist.todo(4).is_completed())
self.assertEquals(self.output, result)
self.assertEquals(self.errors, "")
self.assertEqual(self.output, result)
self.assertEqual(self.errors, "")
def test_do_subtasks2(self):
command = DoCommand(["1"], self.todolist, self.out, self.error, _no_prompt)
......@@ -85,8 +86,8 @@ class DoCommandTest(CommandTest.CommandTest):
self.assertTrue(self.todolist.todo(1).is_completed())
self.assertFalse(self.todolist.todo(2).is_completed())
self.assertFalse(self.todolist.todo(3).is_completed())
self.assertEquals(self.output, result)
self.assertEquals(self.errors, "")
self.assertEqual(self.output, result)
self.assertEqual(self.errors, "")
def test_do_subtasks_force1(self):
prompt_shown = False
......@@ -99,7 +100,7 @@ class DoCommandTest(CommandTest.CommandTest):
command.execute()
self.assertFalse(prompt_shown)
self.assertEquals(self.errors, "")
self.assertEqual(self.errors, "")
self.assertFalse(self.todolist.todo(2).is_completed())
def test_do_subtasks_force2(self):
......@@ -113,7 +114,7 @@ class DoCommandTest(CommandTest.CommandTest):
command.execute()
self.assertFalse(prompt_shown)
self.assertEquals(self.errors, "")
self.assertEqual(self.errors, "")
self.assertFalse(self.todolist.todo(2).is_completed())
def _recurrence_helper(self, p_flags):
......@@ -121,8 +122,8 @@ class DoCommandTest(CommandTest.CommandTest):
command.execute()
self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.errors, "")
self.assertEquals(self.todolist.count(), 10)
self.assertEqual(self.errors, "")
self.assertEqual(self.todolist.count(), 10)
def test_recurrence(self):
self.assertFalse(self.todolist.todo(4).has_tag('due'))
......@@ -131,7 +132,7 @@ class DoCommandTest(CommandTest.CommandTest):
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)
self.assertEquals(self.output, result)
self.assertEqual(self.output, result)
todo = self.todolist.todo(10)
self.assertFalse(todo.is_completed())
......@@ -140,13 +141,13 @@ class DoCommandTest(CommandTest.CommandTest):
def test_strict_recurrence1(self):
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)
self.assertEquals(self.output, result)
self.assertEqual(self.output, result)
def test_strict_recurrence2(self):
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)
self.assertEquals(self.output, result)
self.assertEqual(self.output, result)
def test_invalid1(self):
command = DoCommand(["99"], self.todolist, self.out, self.error)
......@@ -154,7 +155,7 @@ class DoCommandTest(CommandTest.CommandTest):
self.assertFalse(self.todolist.is_dirty())
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):
command = DoCommand(["AAA"], self.todolist, self.out, self.error)
......@@ -162,7 +163,7 @@ class DoCommandTest(CommandTest.CommandTest):
self.assertFalse(self.todolist.is_dirty())
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):
command = DoCommand(["01"], self.todolist, self.out, self.error, _yes_prompt)
......@@ -170,7 +171,7 @@ class DoCommandTest(CommandTest.CommandTest):
self.assertFalse(self.todolist.is_dirty())
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):
command = DoCommand(["2"], self.todolist, self.out, self.error)
......@@ -178,30 +179,30 @@ class DoCommandTest(CommandTest.CommandTest):
first_output = "Completed: x {} Bar p:1\n".format(self.today)
self.assertEquals(self.output, first_output)
self.assertEquals(self.errors, "")
self.assertEqual(self.output, first_output)
self.assertEqual(self.errors, "")
command = DoCommand(["3"], self.todolist, self.out, self.error)
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.assertEquals(self.errors, "")
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.assertEqual(self.errors, "")
def test_activated_todos2(self):
command = DoCommand(["7"], self.todolist, self.out, self.error)
command.execute()
self.assertEquals(self.output, "Completed: x {} Subtodo of inactive p:2\n".format(self.today))
self.assertEquals(self.errors, "")
self.assertEqual(self.output, "Completed: x {} Subtodo of inactive p:2\n".format(self.today))
self.assertEqual(self.errors, "")
def test_already_complete(self):
command = DoCommand(["5"], self.todolist, self.out, self.error)
command.execute()
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.assertEquals(self.errors, "Todo has already been completed.\n")
self.assertEqual(self.errors, "Todo has already been completed.\n")
def test_do_regex1(self):
command = DoCommand(["baz"], self.todolist, self.out, self.error)
......@@ -209,40 +210,40 @@ class DoCommandTest(CommandTest.CommandTest):
self.assertTrue(self.todolist.is_dirty())
self.assertTrue(self.todolist.todo(3).is_completed())
self.assertEquals(self.output, "Completed: x {} Baz p:1\n".format(self.today))
self.assertEquals(self.errors, "")
self.assertEqual(self.output, "Completed: x {} Baz p:1\n".format(self.today))
self.assertEqual(self.errors, "")
def test_do_custom_date1(self):
command = DoCommand(["-d", "2014-11-18", "3"], self.todolist, self.out, self.error)
command.execute()
self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, "Completed: x 2014-11-18 Baz p:1\n")
self.assertEquals(self.errors, "")
self.assertEqual(self.output, "Completed: x 2014-11-18 Baz p:1\n")
self.assertEqual(self.errors, "")
def test_do_custom_date2(self):
command = DoCommand(["-d", "2014-11-18", "1"], self.todolist, self.out, self.error, _yes_prompt)
command.execute()
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.assertEquals(self.errors, "")
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.assertEqual(self.errors, "")
def test_do_custom_date3(self):
command = DoCommand(["--date=2014-11-18", "3"], self.todolist, self.out, self.error)
command.execute()
self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, "Completed: x 2014-11-18 Baz p:1\n")
self.assertEquals(self.errors, "")
self.assertEqual(self.output, "Completed: x 2014-11-18 Baz p:1\n")
self.assertEqual(self.errors, "")
def test_do_custom_date4(self):
command = DoCommand(["-d", "foo", "3"], self.todolist, self.out, self.error)
command.execute()
self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, "Completed: x {} Baz p:1\n".format(self.today))
self.assertEquals(self.errors, "")
self.assertEqual(self.output, "Completed: x {} Baz p:1\n".format(self.today))
self.assertEqual(self.errors, "")
def test_do_custom_date5(self):
"""
......@@ -253,8 +254,8 @@ class DoCommandTest(CommandTest.CommandTest):
command.execute()
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.assertEquals(self.errors, "")
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.assertEqual(self.errors, "")
def test_do_custom_date6(self):
"""
......@@ -266,8 +267,8 @@ class DoCommandTest(CommandTest.CommandTest):
command.execute()
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.assertEquals(self.errors, "")
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.assertEqual(self.errors, "")
def test_do_custom_date7(self):
"""
......@@ -278,8 +279,8 @@ class DoCommandTest(CommandTest.CommandTest):
command.execute()
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.assertEquals(self.errors, "")
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.assertEqual(self.errors, "")
def test_multi_do1(self):
command = DoCommand(["1", "3"], self.todolist, self.out, self.error, _yes_prompt)
......@@ -289,7 +290,7 @@ class DoCommandTest(CommandTest.CommandTest):
self.assertTrue(self.todolist.todo(2).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):
command = DoCommand(["1", "3"], self.todolist, self.out, self.error, _no_prompt)
......@@ -299,21 +300,21 @@ class DoCommandTest(CommandTest.CommandTest):
self.assertFalse(self.todolist.todo(2).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):
command = DoCommand(["3", "3"], self.todolist, self.out, self.error, _no_prompt)
command.execute()
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):
command = DoCommand(["99", "3"], self.todolist, self.out, self.error, _no_prompt)
command.execute()
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):
"""
......@@ -322,15 +323,23 @@ class DoCommandTest(CommandTest.CommandTest):
command = DoCommand(["99", "10"], self.todolist, self.out, self.error, _no_prompt)
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):
""" Show error message when an item has an invalid recurrence pattern. """
command = DoCommand(["9"], self.todolist, self.out, self.error, _no_prompt)
command.execute()
self.assertEquals(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.output, "Completed: x {} Invalid rec:1\n".format(self.today))
self.assertEqual(self.errors, "Warning: todo item has an invalid recurrence pattern.\n")
def test_empty(self):
command = DoCommand([], self.todolist, self.out, self.error)
......@@ -338,14 +347,14 @@ class DoCommandTest(CommandTest.CommandTest):
self.assertFalse(self.todolist.is_dirty())
self.assertFalse(self.output)
self.assertEquals(self.errors, command.usage() + "\n")
self.assertEqual(self.errors, command.usage() + "\n")
def test_help(self):
command = DoCommand(["help"], self.todolist, self.out, self.error)
command.execute()
self.assertEquals(self.output, "")
self.assertEquals(self.errors, command.usage() + "\n\n" + command.help() + "\n")
self.assertEqual(self.output, "")
self.assertEqual(self.errors, command.usage() + "\n\n" + command.help() + "\n")
if __name__ == '__main__':
unittest.main()
......@@ -15,27 +15,37 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
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 CommandTest
from topydo.lib.EditCommand import EditCommand
from topydo.commands.EditCommand import EditCommand
from test.CommandTest import CommandTest, utf8
from topydo.lib.TodoList import TodoList
from topydo.lib.Todo import Todo
from topydo.lib.Config import config
class EditCommandTest(CommandTest.CommandTest):
class EditCommandTest(CommandTest):
def setUp(self):
super(EditCommandTest, self).setUp()
todos = [
"Foo id:1",
"Bar p:1 @test",
"Baz @test",
u("Fo\u00f3B\u0105\u017a"),
]
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):
""" Preserve dependencies after editing. """
mock_open_in_editor.return_value = 0
......@@ -44,11 +54,11 @@ class EditCommandTest(CommandTest.CommandTest):
command.execute()
self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.errors, "")
self.assertEquals(str(self.todolist), "Bar p:1 @test\nBaz @test\nFoo id:1")
self.assertEqual(self.errors, "")
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.lib.EditCommand.EditCommand._open_in_editor')
@mock.patch('topydo.commands.EditCommand.EditCommand._todos_from_temp')
@mock.patch('topydo.commands.EditCommand.EditCommand._open_in_editor')
def test_edit2(self, mock_open_in_editor, mock_todos_from_temp):
""" Edit some todo. """
mock_open_in_editor.return_value = 0
......@@ -58,8 +68,8 @@ class EditCommandTest(CommandTest.CommandTest):
command.execute()
self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.errors, "")
self.assertEquals(str(self.todolist), "Foo id:1\nBaz @test\nLazy Cat")
self.assertEqual(self.errors, "")
self.assertEqual(str(self.todolist), utf8(u("Foo id:1\nBaz @test\nFo\u00f3B\u0105\u017a\nLazy Cat")))
def test_edit3(self):
""" Throw an error after invalid todo number given as argument. """
......@@ -67,47 +77,70 @@ class EditCommandTest(CommandTest.CommandTest):
command.execute()
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):
""" 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()
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.lib.EditCommand.EditCommand._open_in_editor')
@mock.patch('topydo.commands.EditCommand.EditCommand._todos_from_temp')
@mock.patch('topydo.commands.EditCommand.EditCommand._open_in_editor')
def test_edit5(self, mock_open_in_editor, mock_todos_from_temp):
""" Don't let to delete todos acidentally while editing. """
mock_open_in_editor.return_value = 0
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()
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.assertEquals(str(self.todolist), "Foo id:1\nBar p:1 @test\nBaz @test")
self.assertEqual(self.errors, u("Invalid todo number given: Fo\u00d3B\u0105r.\n"))
@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.lib.EditCommand.EditCommand._open_in_editor')
@mock.patch('topydo.commands.EditCommand.EditCommand._todos_from_temp')
@mock.patch('topydo.commands.EditCommand.EditCommand._open_in_editor')
def test_edit_expr(self, mock_open_in_editor, mock_todos_from_temp):
""" Edit todos matching expression. """
mock_open_in_editor.return_value = 0
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()
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.assertEqual(self.errors, "")
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):
""" Edit archive file. """
mock_call.return_value = 0
......@@ -116,7 +149,7 @@ class EditCommandTest(CommandTest.CommandTest):
os.environ['EDITOR'] = editor
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()
self.assertEqual(self.errors, "")
......
......@@ -30,7 +30,7 @@ class FilterTest(TopydoTest):
relevance = Filter.RelevanceFilter()
result = relevance.filter([todo])
self.assertEquals(result, [todo])
self.assertEqual(result, [todo])
def test_filter4(self):
""" Test case insensitive match. """
......@@ -40,7 +40,7 @@ class FilterTest(TopydoTest):
filtered_todos = grep.filter(todos)
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))
def test_filter5(self):
......@@ -51,7 +51,7 @@ class FilterTest(TopydoTest):
filtered_todos = grep.filter(todos)
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))
def test_filter6(self):
......@@ -62,7 +62,7 @@ class FilterTest(TopydoTest):
filtered_todos = grep.filter(todos)
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))
def test_filter7(self):
......@@ -73,7 +73,7 @@ class FilterTest(TopydoTest):
filtered_todos = depfilter.filter(todolist.todos())
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))
def test_filter8(self):
......@@ -84,7 +84,7 @@ class FilterTest(TopydoTest):
filtered_todos = grep.filter(todos)
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))
def test_filter9(self):
......@@ -94,7 +94,7 @@ class FilterTest(TopydoTest):
filtered_todos = instance_filter.filter(todos)
self.assertEquals(todos[2:], filtered_todos)
self.assertEqual(todos[2:], filtered_todos)
def test_filter10(self):
""" Test instance filter """
......@@ -103,7 +103,7 @@ class FilterTest(TopydoTest):
filtered_todos = instance_filter.filter(todos)
self.assertEquals([], filtered_todos)
self.assertEqual([], filtered_todos)
def test_filter11(self):
""" Test instance filter """
......@@ -112,7 +112,7 @@ class FilterTest(TopydoTest):
filtered_todos = instance_filter.filter([])
self.assertEquals([], filtered_todos)
self.assertEqual([], filtered_todos)
def test_filter12(self):
""" Test limit filter. """
......@@ -121,7 +121,7 @@ class FilterTest(TopydoTest):
filtered_todos = limit_filter.filter(todos)
self.assertEquals([], filtered_todos)
self.assertEqual([], filtered_todos)
def test_filter13(self):
""" Test limit filter. """
......@@ -130,8 +130,8 @@ class FilterTest(TopydoTest):
filtered_todos = limit_filter.filter(todos)
self.assertEquals(len(filtered_todos), 1)
self.assertEquals(filtered_todos[0].source(), '(C) This is part of some +Project')
self.assertEqual(len(filtered_todos), 1)
self.assertEqual(filtered_todos[0].source(), '(C) This is part of some +Project')
def test_filter14(self):
""" Test limit filter. """
......@@ -140,7 +140,7 @@ class FilterTest(TopydoTest):
filtered_todos = limit_filter.filter(todos)
self.assertEquals(todos, filtered_todos)
self.assertEqual(todos, filtered_todos)
def test_filter15(self):
""" Test limit filter. """
......@@ -149,7 +149,7 @@ class FilterTest(TopydoTest):
filtered_todos = limit_filter.filter(todos)
self.assertEquals(len(filtered_todos), 4)
self.assertEqual(len(filtered_todos), 4)
def test_filter16(self):
todos = load_file('test/data/FilterTest1.txt')
......@@ -158,7 +158,7 @@ class FilterTest(TopydoTest):
filtered_todos = grep.filter(todos)
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))
def test_filter17(self):
......@@ -170,7 +170,7 @@ class FilterTest(TopydoTest):
filtered_todos = andfilter.filter(todos)
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))
def test_filter18(self):
......@@ -182,7 +182,7 @@ class FilterTest(TopydoTest):
filtered_todos = grep.filter(todos)
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))
def test_filter19(self):
......@@ -190,7 +190,7 @@ class FilterTest(TopydoTest):
grep = Filter.GrepFilter(1)
filtered_todos = grep.filter(todos)
self.assertEquals(filtered_todos, [])
self.assertEqual(filtered_todos, [])
def test_filter20(self):
todos = load_file('test/data/FilterTest3.txt')
......@@ -199,7 +199,7 @@ class FilterTest(TopydoTest):
filtered_todos = otf.filter(todos)
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))
def test_filter21(self):
......@@ -208,7 +208,7 @@ class FilterTest(TopydoTest):
filtered_todos = otf.filter(todos)
self.assertEquals(todolist_to_string(filtered_todos), "")
self.assertEqual(todolist_to_string(filtered_todos), "")
def test_filter22(self):
todos = load_file('test/data/FilterTest3.txt')
......@@ -216,7 +216,7 @@ class FilterTest(TopydoTest):
filtered_todos = otf.filter(todos)
self.assertEquals(todolist_to_string(filtered_todos), "")
self.assertEqual(todolist_to_string(filtered_todos), "")
def test_filter23(self):
todos = load_file('test/data/FilterTest3.txt')
......@@ -224,7 +224,7 @@ class FilterTest(TopydoTest):
filtered_todos = otf.filter(todos)
self.assertEquals(todolist_to_string(filtered_todos), "")
self.assertEqual(todolist_to_string(filtered_todos), "")
def test_filter24(self):
todos = load_file('test/data/FilterTest3.txt')
......@@ -232,7 +232,7 @@ class FilterTest(TopydoTest):
filtered_todos = otf.filter(todos)
self.assertEquals(todolist_to_string(filtered_todos), "")
self.assertEqual(todolist_to_string(filtered_todos), "")
def test_filter25(self):
todos = load_file('test/data/FilterTest3.txt')
......@@ -241,7 +241,7 @@ class FilterTest(TopydoTest):
filtered_todos = otf.filter(todos)
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))
def test_filter26(self):
......@@ -251,7 +251,7 @@ class FilterTest(TopydoTest):
filtered_todos = otf.filter(todos)
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))
def test_filter27(self):
......@@ -261,7 +261,7 @@ class FilterTest(TopydoTest):
filtered_todos = otf.filter(todos)
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))
def test_filter28(self):
......@@ -270,7 +270,7 @@ class FilterTest(TopydoTest):
filtered_todos = otf.filter(todos)
self.assertEquals(todolist_to_string(filtered_todos), "")
self.assertEqual(todolist_to_string(filtered_todos), "")
def test_filter29(self):
todos = load_file('test/data/FilterTest3.txt')
......@@ -279,7 +279,7 @@ class FilterTest(TopydoTest):
filtered_todos = otf.filter(todos)
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))
def test_filter30(self):
......@@ -289,7 +289,7 @@ class FilterTest(TopydoTest):
filtered_todos = otf.filter(todos)
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))
def test_filter31(self):
......@@ -299,7 +299,7 @@ class FilterTest(TopydoTest):
filtered_todos = otf.filter(todos)
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))
class OrdinalTagFilterTest(TopydoTest):
......@@ -329,41 +329,41 @@ class OrdinalTagFilterTest(TopydoTest):
result = otf.filter(self.todos)
self.assertEquals(len(result), 1)
self.assertEquals(str(result[0]), self.todo1)
self.assertEqual(len(result), 1)
self.assertEqual(str(result[0]), self.todo1)
def test_filter2(self):
otf = Filter.OrdinalTagFilter('due:=today')
result = otf.filter(self.todos)
self.assertEquals(len(result), 1)
self.assertEquals(str(result[0]), self.todo1)
self.assertEqual(len(result), 1)
self.assertEqual(str(result[0]), self.todo1)
def test_filter3(self):
otf = Filter.OrdinalTagFilter('due:>today')
result = otf.filter(self.todos)
self.assertEquals(len(result), 1)
self.assertEquals(str(result[0]), self.todo2)
self.assertEqual(len(result), 1)
self.assertEqual(str(result[0]), self.todo2)
def test_filter4(self):
otf = Filter.OrdinalTagFilter('due:<1w')
result = otf.filter(self.todos)
self.assertEquals(len(result), 2)
self.assertEquals(str(result[0]), self.todo1)
self.assertEquals(str(result[1]), self.todo2)
self.assertEqual(len(result), 2)
self.assertEqual(str(result[0]), self.todo1)
self.assertEqual(str(result[1]), self.todo2)
def test_filter5(self):
otf = Filter.OrdinalTagFilter('due:!today')
result = otf.filter(self.todos)
self.assertEquals(len(result), 1)
self.assertEquals(str(result[0]), self.todo2)
self.assertEqual(len(result), 1)
self.assertEqual(str(result[0]), self.todo2)
if __name__ == '__main__':
unittest.main()
......
......@@ -51,34 +51,34 @@ class GraphTest(TopydoTest):
self.assertFalse(self.graph.has_edge_id("1"))
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):
self.assertFalse(self.graph.edge_id(1, 6))
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):
self.assertEquals(self.graph.incoming_neighbors(1, True), set())
self.assertEqual(self.graph.incoming_neighbors(1, True), set())
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):
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):
self.assertEquals(self.graph.outgoing_neighbors(2), set([4]))
self.assertEqual(self.graph.outgoing_neighbors(2), set([4]))
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):
self.assertEquals(self.graph.outgoing_neighbors(3), set([5]))
self.assertEqual(self.graph.outgoing_neighbors(3), set([5]))
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):
self.graph.remove_edge(1, 2)
......@@ -165,11 +165,11 @@ class GraphTest(TopydoTest):
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'
self.assertEquals(str(self.graph), out)
self.assertEqual(str(self.graph), out)
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'
self.assertEquals(self.graph.dot(False), out)
self.assertEqual(self.graph.dot(False), out)
if __name__ == '__main__':
unittest.main()
......@@ -14,89 +14,93 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from six import u
import codecs
import re
import sys
import unittest
from topydo.lib.Config import config
import CommandTest
from topydo.lib.ListCommand import ListCommand
import TestFacilities
from topydo.commands.ListCommand import ListCommand
from test.CommandTest import CommandTest, utf8
from test.TestFacilities import load_file_to_todolist
class ListCommandTest(CommandTest.CommandTest):
class ListCommandTest(CommandTest):
def setUp(self):
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):
command = ListCommand([""], self.todolist, self.out, self.error)
command.execute()
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.assertEquals(self.errors, "")
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_list3(self):
command = ListCommand(["Context1"], self.todolist, self.out, self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "| 2| (D) Bar @Context1 +Project2\n")
self.assertEquals(self.errors, "")
self.assertEqual(self.output, "| 2| (D) Bar @Context1 +Project2\n")
self.assertEqual(self.errors, "")
def test_list4(self):
command = ListCommand(["-x", "Context1"], self.todolist, self.out, self.error)
command.execute()
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.assertEquals(self.errors, "")
self.assertEqual(self.output, "| 3| (C) Baz @Context1 +Project1 key:value\n| 2| (D) Bar @Context1 +Project2\n")
self.assertEqual(self.errors, "")
def test_list5(self):
command = ListCommand(["-x"], self.todolist, self.out, self.error)
command.execute()
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.assertEquals(self.errors, "")
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.assertEqual(self.errors, "")
def test_list6(self):
command = ListCommand(["Project3"], self.todolist, self.out, self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "")
self.assertEquals(self.errors, "")
self.assertEqual(self.output, "")
self.assertEqual(self.errors, "")
def test_list7(self):
command = ListCommand(["-s", "text", "-x", "Project1"], self.todolist, self.out, self.error)
command.execute()
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.assertEquals(self.errors, "")
self.assertEqual(self.output, "| 3| (C) Baz @Context1 +Project1 key:value\n| 1| (C) Foo @Context2 Not@Context +Project1 Not+Project\n")
self.assertEqual(self.errors, "")
def test_list8(self):
command = ListCommand(["--", "-project1"], self.todolist, self.out, self.error)
command.execute()
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.assertEquals(self.errors, "")
self.assertEqual(self.output, "| 4| (C) Drink beer @ home\n| 5| (C) 13 + 29 = 42\n| 2| (D) Bar @Context1 +Project2\n")
self.assertEqual(self.errors, "")
def test_list9(self):
command = ListCommand(["--", "-project1", "-Drink"], self.todolist, self.out, self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "| 5| (C) 13 + 29 = 42\n| 2| (D) Bar @Context1 +Project2\n")
self.assertEquals(self.errors, "")
self.assertEqual(self.output, "| 5| (C) 13 + 29 = 42\n| 2| (D) Bar @Context1 +Project2\n")
self.assertEqual(self.errors, "")
def test_list10(self):
command = ListCommand(["text1", "2"], self.todolist, self.out, self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "| 2| (D) Bar @Context1 +Project2\n")
self.assertEquals(self.errors, "")
self.assertEqual(self.output, "| 2| (D) Bar @Context1 +Project2\n")
self.assertEqual(self.errors, "")
def test_list11(self):
config("test/data/listcommand.conf")
......@@ -105,8 +109,8 @@ class ListCommandTest(CommandTest.CommandTest):
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "| 1| (C) Foo @Context2 Not@Context +Project1 Not+Project\n")
self.assertEquals(self.errors, "")
self.assertEqual(self.output, "| 1| (C) Foo @Context2 Not@Context +Project1 Not+Project\n")
self.assertEqual(self.errors, "")
def test_list12(self):
config("test/data/listcommand.conf")
......@@ -115,16 +119,16 @@ class ListCommandTest(CommandTest.CommandTest):
command.execute()
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.assertEquals(self.errors, "")
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.assertEqual(self.errors, "")
def test_list13(self):
command = ListCommand(["-x", "--", "-@Context1 +Project2"], self.todolist, self.out, self.error)
command.execute()
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.assertEquals(self.errors, "")
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.assertEqual(self.errors, "")
def test_list14(self):
config("test/data/listcommand2.conf")
......@@ -133,16 +137,16 @@ class ListCommandTest(CommandTest.CommandTest):
command.execute()
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.assertEquals(self.errors, "")
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_list15(self):
command = ListCommand(["p:<10"], self.todolist, self.out, self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "| 2| (D) Bar @Context1 +Project2\n")
self.assertEquals(self.errors, "")
self.assertEqual(self.output, "| 2| (D) Bar @Context1 +Project2\n")
self.assertEqual(self.errors, "")
def test_list16(self):
config("test/data/todolist-uid.conf")
......@@ -151,23 +155,23 @@ class ListCommandTest(CommandTest.CommandTest):
command.execute()
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.assertEquals(self.errors, "")
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.assertEqual(self.errors, "")
def test_list17(self):
command = ListCommand(["-x", "id:"], self.todolist, self.out, self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "| 3| (C) Baz @Context1 +Project1 key:value\n")
self.assertEquals(self.errors, "")
self.assertEqual(self.output, "| 3| (C) Baz @Context1 +Project1 key:value\n")
self.assertEqual(self.errors, "")
def test_list18(self):
command = ListCommand(["-x", "date:2014-12-12"], self.todolist, self.out, self.error)
command.execute()
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):
""" Force showing all tags. """
......@@ -177,15 +181,135 @@ class ListCommandTest(CommandTest.CommandTest):
command.execute()
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.assertEquals(self.errors, "")
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.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):
command = ListCommand(["help"], self.todolist, self.out, self.error)
command.execute()
self.assertEquals(self.output, "")
self.assertEquals(self.errors, command.usage() + "\n\n" + command.help() + "\n")
self.assertEqual(self.output, "")
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__':
unittest.main()
......@@ -16,33 +16,33 @@
import unittest
import CommandTest
import TestFacilities
from topydo.lib.ListContextCommand import ListContextCommand
from topydo.commands.ListContextCommand import ListContextCommand
from test.CommandTest import CommandTest
from test.TestFacilities import load_file_to_todolist
class ListContextCommandTest(CommandTest.CommandTest):
class ListContextCommandTest(CommandTest):
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.execute()
self.assertEquals(self.output,"Context1\nContext2\n")
self.assertEqual(self.output,"Context1\nContext2\n")
self.assertFalse(self.errors)
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.execute()
self.assertEquals(self.output,"Context1\nContext2\n")
self.assertEqual(self.output,"Context1\nContext2\n")
self.assertFalse(self.errors)
def test_help(self):
command = ListContextCommand(["help"], None, self.out, self.error)
command.execute()
self.assertEquals(self.output, "")
self.assertEquals(self.errors, command.usage() + "\n\n" + command.help() + "\n")
self.assertEqual(self.output, "")
self.assertEqual(self.errors, command.usage() + "\n\n" + command.help() + "\n")
if __name__ == '__main__':
unittest.main()
......@@ -16,33 +16,33 @@
import unittest
import CommandTest
import TestFacilities
from topydo.lib.ListProjectCommand import ListProjectCommand
from topydo.commands.ListProjectCommand import ListProjectCommand
from test.CommandTest import CommandTest
from test.TestFacilities import load_file_to_todolist
class ListProjectCommandTest(CommandTest.CommandTest):
class ListProjectCommandTest(CommandTest):
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.execute()
self.assertEquals(self.output,"Project1\nProject2\n")
self.assertEqual(self.output, "Project1\nProject2\n")
self.assertFalse(self.errors)
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.execute()
self.assertEquals(self.output,"Project1\nProject2\n")
self.assertEqual(self.output, "Project1\nProject2\n")
self.assertFalse(self.errors)
def test_help(self):
command = ListProjectCommand(["help"], None, self.out, self.error)
command.execute()
self.assertEquals(self.output, "")
self.assertEquals(self.errors, command.usage() + "\n\n" + command.help() + "\n")
self.assertEqual(self.output, "")
self.assertEqual(self.errors, command.usage() + "\n\n" + command.help() + "\n")
if __name__ == '__main__':
unittest.main()
......@@ -16,12 +16,13 @@
from datetime import date, timedelta
import unittest
from six import u
import CommandTest
from topydo.lib.PostponeCommand import PostponeCommand
from topydo.commands.PostponeCommand import PostponeCommand
from test.CommandTest import CommandTest
from topydo.lib.TodoList import TodoList
class PostponeCommandTest(CommandTest.CommandTest):
class PostponeCommandTest(CommandTest):
def setUp(self):
super(PostponeCommandTest, self).setUp()
self.today = date.today()
......@@ -47,8 +48,8 @@ class PostponeCommandTest(CommandTest.CommandTest):
due = self.today + timedelta(7)
self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, "| 1| Foo due:{}\n".format(due.isoformat()))
self.assertEquals(self.errors, "")
self.assertEqual(self.output, "| 1| Foo due:{}\n".format(due.isoformat()))
self.assertEqual(self.errors, "")
def test_postpone2(self):
command = PostponeCommand(["2", "1w"], self.todolist, self.out, self.error)
......@@ -57,8 +58,8 @@ class PostponeCommandTest(CommandTest.CommandTest):
due = self.today + timedelta(7)
self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, "| 2| Bar due:{}\n".format(due.isoformat()))
self.assertEquals(self.errors, "")
self.assertEqual(self.output, "| 2| Bar due:{}\n".format(due.isoformat()))
self.assertEqual(self.errors, "")
def test_postpone3(self):
command = PostponeCommand(["-s", "2", "1w"], self.todolist, self.out, self.error)
......@@ -67,8 +68,8 @@ class PostponeCommandTest(CommandTest.CommandTest):
due = self.today + timedelta(7)
self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, "| 2| Bar due:{}\n".format(due.isoformat()))
self.assertEquals(self.errors, "")
self.assertEqual(self.output, "| 2| Bar due:{}\n".format(due.isoformat()))
self.assertEqual(self.errors, "")
def test_postpone4(self):
command = PostponeCommand(["3", "1w"], self.todolist, self.out, self.error)
......@@ -77,8 +78,8 @@ class PostponeCommandTest(CommandTest.CommandTest):
due = self.today + timedelta(7)
self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, "| 3| Baz due:{} t:{}\n".format(due.isoformat(), self.start.isoformat()))
self.assertEquals(self.errors, "")
self.assertEqual(self.output, "| 3| Baz due:{} t:{}\n".format(due.isoformat(), self.start.isoformat()))
self.assertEqual(self.errors, "")
def test_postpone5(self):
command = PostponeCommand(["-s", "3", "1w"], self.todolist, self.out, self.error)
......@@ -88,8 +89,9 @@ class PostponeCommandTest(CommandTest.CommandTest):
start = self.start + timedelta(7)
self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, "| 3| Baz due:{} t:{}\n".format(due.isoformat(), start.isoformat()))
self.assertEquals(self.errors, "")
# pylint: disable=E1103
self.assertEqual(self.output, "| 3| Baz due:{} t:{}\n".format(due.isoformat(), start.isoformat()))
self.assertEqual(self.errors, "")
def test_postpone6(self):
command = PostponeCommand(["4", "1w"], self.todolist, self.out, self.error)
......@@ -98,8 +100,8 @@ class PostponeCommandTest(CommandTest.CommandTest):
due = self.today + timedelta(7)
self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, "| 4| Past due:{}\n".format(due.isoformat()))
self.assertEquals(self.errors, "")
self.assertEqual(self.output, "| 4| Past due:{}\n".format(due.isoformat()))
self.assertEqual(self.errors, "")
def test_postpone7(self):
command = PostponeCommand(["5", "1w"], self.todolist, self.out, self.error)
......@@ -108,8 +110,9 @@ class PostponeCommandTest(CommandTest.CommandTest):
due = self.future + timedelta(7)
self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, "| 5| Future due:{} t:{}\n".format(due.isoformat(), self.future_start.isoformat()))
self.assertEquals(self.errors, "")
# pylint: disable=E1103
self.assertEqual(self.output, "| 5| Future due:{} t:{}\n".format(due.isoformat(), self.future_start.isoformat()))
self.assertEqual(self.errors, "")
def test_postpone8(self):
command = PostponeCommand(["-s", "5", "1w"], self.todolist, self.out, self.error)
......@@ -119,40 +122,41 @@ class PostponeCommandTest(CommandTest.CommandTest):
start = self.future_start + timedelta(7)
self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, "| 5| Future due:{} t:{}\n".format(due.isoformat(), start.isoformat()))
self.assertEquals(self.errors, "")
# pylint: disable=E1103
self.assertEqual(self.output, "| 5| Future due:{} t:{}\n".format(due.isoformat(), start.isoformat()))
self.assertEqual(self.errors, "")
def test_postpone9(self):
command = PostponeCommand(["1", "foo"], self.todolist, self.out, self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "")
self.assertEquals(self.errors, "Invalid date pattern given.\n")
self.assertEqual(self.output, "")
self.assertEqual(self.errors, "Invalid date pattern given.\n")
def test_postpone10(self):
command = PostponeCommand(["99", "foo"], self.todolist, self.out, self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "")
self.assertEquals(self.errors, "Invalid todo number given.\n")
self.assertEqual(self.output, "")
self.assertEqual(self.errors, "Invalid todo number given.\n")
def test_postpone11(self):
command = PostponeCommand(["A", "foo"], self.todolist, self.out, self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "")
self.assertEquals(self.errors, "Invalid todo number given.\n")
self.assertEqual(self.output, "")
self.assertEqual(self.errors, "Invalid todo number given.\n")
def test_postpone12(self):
command = PostponeCommand(["1"], self.todolist, self.out, self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "")
self.assertEquals(self.errors, command.usage() + "\n")
self.assertEqual(self.output, "")
self.assertEqual(self.errors, command.usage() + "\n")
def test_postpone13(self):
command = PostponeCommand(["Foo", "1w"], self.todolist, self.out, self.error)
......@@ -161,8 +165,8 @@ class PostponeCommandTest(CommandTest.CommandTest):
due = self.today + timedelta(7)
self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, "| 1| Foo due:{}\n".format(due.isoformat()))
self.assertEquals(self.errors, "")
self.assertEqual(self.output, "| 1| Foo due:{}\n".format(due.isoformat()))
self.assertEqual(self.errors, "")
def test_postpone14(self):
command = PostponeCommand(["1", "2", "1w"], self.todolist, self.out, self.error)
......@@ -171,8 +175,8 @@ class PostponeCommandTest(CommandTest.CommandTest):
due = self.today + timedelta(7)
self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, "| 1| Foo due:{}\n| 2| Bar due:{}\n".format(due.isoformat(), due.isoformat()))
self.assertEquals(self.errors, "")
self.assertEqual(self.output, "| 1| Foo due:{}\n| 2| Bar due:{}\n".format(due.isoformat(), due.isoformat()))
self.assertEqual(self.errors, "")
def test_postpone15(self):
command = PostponeCommand(["Foo", "2", "1w"], self.todolist, self.out, self.error)
......@@ -181,8 +185,8 @@ class PostponeCommandTest(CommandTest.CommandTest):
due = self.today + timedelta(7)
self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, "| 1| Foo due:{}\n| 2| Bar due:{}\n".format(due.isoformat(), due.isoformat()))
self.assertEquals(self.errors, "")
self.assertEqual(self.output, "| 1| Foo due:{}\n| 2| Bar due:{}\n".format(due.isoformat(), due.isoformat()))
self.assertEqual(self.errors, "")
def test_postpone16(self):
command = PostponeCommand(["-s", "2", "3", "1w"], self.todolist, self.out, self.error)
......@@ -192,39 +196,49 @@ class PostponeCommandTest(CommandTest.CommandTest):
start = self.start + timedelta(7)
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()))
self.assertEquals(self.errors, "")
# pylint: disable=E1103
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):
command = PostponeCommand(["1", "2", "3"], self.todolist, self.out, self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "")
self.assertEquals(self.errors, "Invalid date pattern given.\n")
self.assertEqual(self.output, "")
self.assertEqual(self.errors, "Invalid date pattern given.\n")
def test_postpone18(self):
command = PostponeCommand(["1", "99", "123", "1w"], self.todolist, self.out, self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "")
self.assertEquals(self.errors, "Invalid todo number given: 99.\nInvalid todo number given: 123.\n")
self.assertEqual(self.output, "")
self.assertEqual(self.errors, "Invalid todo number given: 99.\nInvalid todo number given: 123.\n")
def test_postpone19(self):
command = PostponeCommand(["Zoo", "99", "123", "1w"], self.todolist, self.out, self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEquals(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.output, "")
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):
command = PostponeCommand(["help"], self.todolist, self.out, self.error)
command.execute()
self.assertEquals(self.output, "")
self.assertEquals(self.errors, command.usage() + "\n\n" + command.help() + "\n")
self.assertEqual(self.output, "")
self.assertEqual(self.errors, command.usage() + "\n\n" + command.help() + "\n")
if __name__ == '__main__':
unittest.main()
......
......@@ -15,12 +15,13 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import unittest
from six import u
import CommandTest
from topydo.lib.PriorityCommand import PriorityCommand
from topydo.commands.PriorityCommand import PriorityCommand
from test.CommandTest import CommandTest
from topydo.lib.TodoList import TodoList
class PriorityCommandTest(CommandTest.CommandTest):
class PriorityCommandTest(CommandTest):
def setUp(self):
super(PriorityCommandTest, self).setUp()
todos = [
......@@ -35,40 +36,40 @@ class PriorityCommandTest(CommandTest.CommandTest):
command.execute()
self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, "Priority changed from A to B\n| 1| (B) Foo\n")
self.assertEquals(self.errors, "")
self.assertEqual(self.output, "Priority changed from A to B\n| 1| (B) Foo\n")
self.assertEqual(self.errors, "")
def test_set_prio2(self):
command = PriorityCommand(["2", "Z"], self.todolist, self.out, self.error)
command.execute()
self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, "Priority set to Z.\n| 2| (Z) Bar\n")
self.assertEquals(self.errors, "")
self.assertEqual(self.output, "Priority set to Z.\n| 2| (Z) Bar\n")
self.assertEqual(self.errors, "")
def test_set_prio3(self):
command = PriorityCommand(["Foo", "B"], self.todolist, self.out, self.error)
command.execute()
self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, "Priority changed from A to B\n| 1| (B) Foo\n")
self.assertEquals(self.errors, "")
self.assertEqual(self.output, "Priority changed from A to B\n| 1| (B) Foo\n")
self.assertEqual(self.errors, "")
def test_set_prio4(self):
command = PriorityCommand(["1", "A"], self.todolist, self.out, self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "| 1| (A) Foo\n")
self.assertEquals(self.errors, "")
self.assertEqual(self.output, "| 1| (A) Foo\n")
self.assertEqual(self.errors, "")
def test_set_prio5(self):
command = PriorityCommand(["Foo", "2", "C"], self.todolist, self.out, self.error)
command.execute()
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.assertEquals(self.errors, "")
self.assertEqual(self.output, "Priority changed from A to C\n| 1| (C) Foo\nPriority set to C.\n| 2| (C) Bar\n")
self.assertEqual(self.errors, "")
def test_invalid1(self):
command = PriorityCommand(["99", "A"], self.todolist, self.out, self.error)
......@@ -76,7 +77,7 @@ class PriorityCommandTest(CommandTest.CommandTest):
self.assertFalse(self.todolist.is_dirty())
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):
command = PriorityCommand(["1", "99", "A"], self.todolist, self.out, self.error)
......@@ -84,7 +85,7 @@ class PriorityCommandTest(CommandTest.CommandTest):
self.assertFalse(self.todolist.is_dirty())
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):
command = PriorityCommand(["98", "99", "A"], self.todolist, self.out, self.error)
......@@ -92,7 +93,7 @@ class PriorityCommandTest(CommandTest.CommandTest):
self.assertFalse(self.todolist.is_dirty())
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):
command = PriorityCommand(["1", "ZZ"], self.todolist, self.out, self.error)
......@@ -100,7 +101,7 @@ class PriorityCommandTest(CommandTest.CommandTest):
self.assertFalse(self.todolist.is_dirty())
self.assertFalse(self.output)
self.assertEquals(self.errors, "Invalid priority given.\n")
self.assertEqual(self.errors, "Invalid priority given.\n")
def test_invalid5(self):
command = PriorityCommand(["A"], self.todolist, self.out, self.error)
......@@ -108,7 +109,7 @@ class PriorityCommandTest(CommandTest.CommandTest):
self.assertFalse(self.todolist.is_dirty())
self.assertFalse(self.output)
self.assertEquals(self.errors, command.usage() + "\n")
self.assertEqual(self.errors, command.usage() + "\n")
def test_invalid6(self):
command = PriorityCommand(["1"], self.todolist, self.out, self.error)
......@@ -116,7 +117,16 @@ class PriorityCommandTest(CommandTest.CommandTest):
self.assertFalse(self.todolist.is_dirty())
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):
command = PriorityCommand([], self.todolist, self.out, self.error)
......@@ -124,14 +134,14 @@ class PriorityCommandTest(CommandTest.CommandTest):
self.assertFalse(self.todolist.is_dirty())
self.assertFalse(self.output)
self.assertEquals(self.errors, command.usage() + "\n")
self.assertEqual(self.errors, command.usage() + "\n")
def test_help(self):
command = PriorityCommand(["help"], self.todolist, self.out, self.error)
command.execute()
self.assertEquals(self.output, "")
self.assertEquals(self.errors, command.usage() + "\n\n" + command.help() + "\n")
self.assertEqual(self.output, "")
self.assertEqual(self.errors, command.usage() + "\n\n" + command.help() + "\n")
if __name__ == '__main__':
unittest.main()
......@@ -35,7 +35,7 @@ class RecurrenceTest(TopydoTest):
self.todo.set_tag(config().tag_due(), future.isoformat())
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):
""" Where due date is today. """
......@@ -45,7 +45,7 @@ class RecurrenceTest(TopydoTest):
self.todo.set_tag(config().tag_due(), today.isoformat())
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):
""" Where due date is in the past. """
......@@ -55,7 +55,7 @@ class RecurrenceTest(TopydoTest):
self.todo.set_tag(config().tag_due(), past.isoformat())
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):
""" Where due date is in the past. """
......@@ -65,7 +65,7 @@ class RecurrenceTest(TopydoTest):
self.todo.set_tag(config().tag_due(), past.isoformat())
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):
""" Where due date is in the future. """
......@@ -75,7 +75,7 @@ class RecurrenceTest(TopydoTest):
self.todo.set_tag(config().tag_due(), future.isoformat())
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):
""" Where due date is today. """
......@@ -85,21 +85,21 @@ class RecurrenceTest(TopydoTest):
self.todo.set_tag(config().tag_due(), today.isoformat())
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):
new_due = date.today() + timedelta(7)
new_todo = advance_recurring_todo(self.todo)
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):
new_due = date.today() + timedelta(7)
new_todo = strict_advance_recurring_todo(self.todo)
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):
""" Start date is before due date. """
......@@ -110,19 +110,20 @@ class RecurrenceTest(TopydoTest):
new_start = date.today() + timedelta(6)
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):
""" Strict recurrence. Start date is before due date. """
due = date.today() - timedelta(1)
self.todo.set_tag(config().tag_due(), date.today().isoformat())
yesterday = due - timedelta(1)
# pylint: disable=E1103
self.todo.set_tag(config().tag_start(), yesterday.isoformat())
new_start = date.today() + timedelta(5)
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):
""" Start date equals due date. """
......@@ -132,7 +133,7 @@ class RecurrenceTest(TopydoTest):
new_start = date.today() + timedelta(7)
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):
self.todo.remove_tag('rec')
......
......@@ -18,9 +18,9 @@ from datetime import date, timedelta
import unittest
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):
super(RelativeDateTester, self).setUp()
self.today = date.today()
......@@ -32,20 +32,20 @@ class RelativeDateTester(TopydoTest.TopydoTest):
def test_zero_days(self):
result = relative_date_to_date('0d')
self.assertEquals(result, self.today)
self.assertEqual(result, self.today)
def test_one_day(self):
result = relative_date_to_date('1d')
self.assertEquals(result, self.tomorrow)
self.assertEqual(result, self.tomorrow)
def test_one_week(self):
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):
test_date = date(2015, 1, 10)
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):
test_date1 = date(2015, 1, 29)
......@@ -60,31 +60,31 @@ class RelativeDateTester(TopydoTest.TopydoTest):
result4 = relative_date_to_date('1m', test_date4)
result5 = relative_date_to_date('1m', test_date5)
self.assertEquals(result1, date(2015, 2, 28))
self.assertEquals(result2, date(2016, 2, 29))
self.assertEquals(result3, date(2016, 1, 31))
self.assertEquals(result4, date(2015, 8, 31))
self.assertEquals(result5, date(2015, 11, 30))
self.assertEqual(result1, date(2015, 2, 28))
self.assertEqual(result2, date(2016, 2, 29))
self.assertEqual(result3, date(2016, 1, 31))
self.assertEqual(result4, date(2015, 8, 31))
self.assertEqual(result5, date(2015, 11, 30))
def test_one_year(self):
test_date = date(2015, 1, 10)
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):
test_date = date(2016, 2, 29)
result1 = relative_date_to_date('1y', test_date)
result2 = relative_date_to_date('4y', test_date)
self.assertEquals(result1, date(2017, 2, 28))
self.assertEquals(result2, date(2020, 2, 29))
self.assertEqual(result1, date(2017, 2, 28))
self.assertEqual(result2, date(2020, 2, 29))
def test_zero_months(self):
result = relative_date_to_date('0m')
self.assertEquals(result, self.today)
self.assertEqual(result, self.today)
def test_zero_years(self):
result = relative_date_to_date('0y')
self.assertEquals(result, self.today)
self.assertEqual(result, self.today)
def test_garbage1(self):
result = relative_date_to_date('0dd')
......@@ -92,40 +92,40 @@ class RelativeDateTester(TopydoTest.TopydoTest):
def test_one_day_capital(self):
result = relative_date_to_date('1D')
self.assertEquals(result, self.tomorrow)
self.assertEqual(result, self.tomorrow)
def test_today1(self):
result = relative_date_to_date('today')
self.assertEquals(result, self.today)
self.assertEqual(result, self.today)
def test_today2(self):
result = relative_date_to_date('tod')
self.assertEquals(result, self.today)
self.assertEqual(result, self.today)
def test_today3(self):
result = relative_date_to_date('today', \
date.today() + timedelta(1))
self.assertEquals(result, self.today)
self.assertEqual(result, self.today)
def test_tomorrow1(self):
result = relative_date_to_date('Tomorrow')
self.assertEquals(result, self.tomorrow)
self.assertEqual(result, self.tomorrow)
def test_tomorrow2(self):
result = relative_date_to_date('tom')
self.assertEquals(result, self.tomorrow)
self.assertEqual(result, self.tomorrow)
def test_monday1(self):
result = relative_date_to_date('monday')
self.assertEquals(result, self.monday)
self.assertEqual(result, self.monday)
def test_monday2(self):
result = relative_date_to_date('mo')
self.assertEquals(result, self.monday)
self.assertEqual(result, self.monday)
def test_monday3(self):
result = relative_date_to_date('mon')
self.assertEquals(result, self.monday)
self.assertEqual(result, self.monday)
def test_monday4(self):
result = relative_date_to_date('mondayy')
......@@ -133,11 +133,11 @@ class RelativeDateTester(TopydoTest.TopydoTest):
def test_offset1(self):
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):
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):
result = relative_date_to_date('-0d')
......
......@@ -16,46 +16,46 @@
import unittest
import CommandTest
from topydo.lib.Config import config
from topydo.lib.SortCommand import SortCommand
import TestFacilities
from topydo.commands.SortCommand import SortCommand
from test.CommandTest import CommandTest
from test.TestFacilities import load_file_to_todolist
class SortCommandTest(CommandTest.CommandTest):
class SortCommandTest(CommandTest):
def setUp(self):
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):
""" Alphabetically sorted """
command = SortCommand(["text"], self.todolist, self.out, self.error)
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):
command = SortCommand([], self.todolist, self.out, self.error)
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):
""" Check that order does not influence the UID of a todo. """
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.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):
command = SortCommand(["help"], self.todolist, self.out, self.error)
command.execute()
self.assertEquals(self.output, "")
self.assertEquals(self.errors, command.usage() + "\n\n" + command.help() + "\n")
self.assertEqual(self.output, "")
self.assertEqual(self.errors, command.usage() + "\n\n" + command.help() + "\n")
if __name__ == '__main__':
unittest.main()
......@@ -33,8 +33,8 @@ class SorterTest(TopydoTest):
todos_sorted = todolist_to_string(p_sorter.sort(todos))
todos_ref = todolist_to_string(load_file(p_filename_ref))
self.assertEquals(todos_sorted, todos_ref)
self.assertEquals(todolist_to_string(todos), text_before)
self.assertEqual(todos_sorted, todos_ref)
self.assertEqual(todolist_to_string(todos), text_before)
def test_sort1(self):
""" Alphabetically sorted """
......@@ -128,7 +128,7 @@ class SorterTest(TopydoTest):
view = todolist.view(sorter, [])
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):
"""
......@@ -141,7 +141,7 @@ class SorterTest(TopydoTest):
view = todolist.view(sorter, [])
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):
"""
......@@ -153,7 +153,7 @@ class SorterTest(TopydoTest):
view = todolist.view(sorter, [])
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__':
unittest.main()
......@@ -16,11 +16,11 @@
import unittest
import CommandTest
from topydo.lib.TagCommand import TagCommand
from topydo.commands.TagCommand import TagCommand
from test.CommandTest import CommandTest
from topydo.lib.TodoList import TodoList
class TagCommandTest(CommandTest.CommandTest):
class TagCommandTest(CommandTest):
def setUp(self):
super(TagCommandTest, self).setUp()
todos = [
......@@ -36,27 +36,27 @@ class TagCommandTest(CommandTest.CommandTest):
command = TagCommand(["1", "due", "2014-10-22"], self.todolist, self.out, self.error)
command.execute()
self.assertEquals(self.todolist.todo(1).source(), "Foo due:2014-10-22")
self.assertEquals(self.output, "| 1| Foo due:2014-10-22\n")
self.assertEquals(self.errors, "")
self.assertEqual(self.todolist.todo(1).source(), "Foo due:2014-10-22")
self.assertEqual(self.output, "| 1| Foo due:2014-10-22\n")
self.assertEqual(self.errors, "")
self.assertTrue(self.todolist.is_dirty())
def test_add_tag2(self):
command = TagCommand(["Foo", "due", "2014-10-22"], self.todolist, self.out, self.error)
command.execute()
self.assertEquals(self.todolist.todo(1).source(), "Foo due:2014-10-22")
self.assertEquals(self.output, "| 1| Foo due:2014-10-22\n")
self.assertEquals(self.errors, "")
self.assertEqual(self.todolist.todo(1).source(), "Foo due:2014-10-22")
self.assertEqual(self.output, "| 1| Foo due:2014-10-22\n")
self.assertEqual(self.errors, "")
self.assertTrue(self.todolist.is_dirty())
def test_add_tag3(self):
command = TagCommand(["-a", "2", "due", "2014-10-19"], self.todolist, self.out, self.error)
command.execute()
self.assertEquals(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.assertEquals(self.errors, "")
self.assertEqual(self.todolist.todo(2).source(), "Bar due:2014-10-22 due:2014-10-19")
self.assertEqual(self.output, "| 2| Bar due:2014-10-22 due:2014-10-19\n")
self.assertEqual(self.errors, "")
self.assertTrue(self.todolist.is_dirty())
def test_add_tag4(self):
......@@ -65,150 +65,150 @@ class TagCommandTest(CommandTest.CommandTest):
self.assertFalse(self.todolist.is_dirty())
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):
command = TagCommand(["3", "due", "2014-10-20"], self.todolist, self.out, self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "| 3| Baz due:2014-10-20\n")
self.assertEquals(self.errors, "")
self.assertEqual(self.output, "| 3| Baz due:2014-10-20\n")
self.assertEqual(self.errors, "")
def test_set_tag5(self):
command = TagCommand(["4", "due", "2014-10-20"], self.todolist, self.out, self.error, lambda t: "all")
command.execute()
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.assertEquals(self.errors, "")
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.assertEqual(self.errors, "")
def test_set_tag6(self):
command = TagCommand(["4", "due", "2014-10-20"], self.todolist, self.out, self.error, lambda t: "1")
command.execute()
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.assertEquals(self.errors, "")
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.assertEqual(self.errors, "")
def test_set_tag7(self):
command = TagCommand(["4", "due", "2014-10-20"], self.todolist, self.out, self.error, lambda t: "2")
command.execute()
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.assertEquals(self.errors, "")
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.assertEqual(self.errors, "")
def test_set_tag8(self):
command = TagCommand(["4", "due", "2014-10-20"], self.todolist, self.out, self.error, lambda t: "")
command.execute()
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.assertEquals(self.errors, "")
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.assertEqual(self.errors, "")
def test_set_tag9(self):
command = TagCommand(["4", "due", "2014-10-20"], self.todolist, self.out, self.error, lambda t: "99")
command.execute()
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.assertEquals(self.errors, "")
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.assertEqual(self.errors, "")
def test_set_tag10(self):
command = TagCommand(["-f", "4", "due", "2014-10-20"], self.todolist, self.out, self.error, lambda t: "99")
command.execute()
self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, "| 4| Fnord due:2014-10-20 due:2014-10-20\n")
self.assertEquals(self.errors, "")
self.assertEqual(self.output, "| 4| Fnord due:2014-10-20 due:2014-10-20\n")
self.assertEqual(self.errors, "")
def test_rm_tag1(self):
command = TagCommand(["1", "due"], self.todolist, self.out, self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "| 1| Foo\n")
self.assertEquals(self.errors, "")
self.assertEqual(self.output, "| 1| Foo\n")
self.assertEqual(self.errors, "")
def test_rm_tag2(self):
command = TagCommand(["2", "due"], self.todolist, self.out, self.error)
command.execute()
self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, "| 2| Bar\n")
self.assertEquals(self.errors, "")
self.assertEqual(self.output, "| 2| Bar\n")
self.assertEqual(self.errors, "")
def test_rm_tag3(self):
command = TagCommand(["4", "due"], self.todolist, self.out, self.error, lambda t: "all")
command.execute()
self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, " 1. 2014-10-20\n 2. 2014-10-22\n| 4| Fnord\n")
self.assertEquals(self.errors, "")
self.assertEqual(self.output, " 1. 2014-10-20\n 2. 2014-10-22\n| 4| Fnord\n")
self.assertEqual(self.errors, "")
def test_rm_tag4(self):
command = TagCommand(["4", "due"], self.todolist, self.out, self.error, lambda t: "1")
command.execute()
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.assertEquals(self.errors, "")
self.assertEqual(self.output, " 1. 2014-10-20\n 2. 2014-10-22\n| 4| Fnord due:2014-10-22\n")
self.assertEqual(self.errors, "")
def test_rm_tag6(self):
command = TagCommand(["4", "due"], self.todolist, self.out, self.error, lambda t: "99")
command.execute()
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.assertEquals(self.errors, "")
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.assertEqual(self.errors, "")
def test_rm_tag7(self):
command = TagCommand(["4", "due"], self.todolist, self.out, self.error, lambda t: "A")
command.execute()
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.assertEquals(self.errors, "")
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.assertEqual(self.errors, "")
def test_rm_tag8(self):
command = TagCommand(["5", "due"], self.todolist, self.out, self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "")
self.assertEquals(self.errors, "Invalid todo number.\n")
self.assertEqual(self.output, "")
self.assertEqual(self.errors, "Invalid todo number.\n")
def test_rm_tag9(self):
command = TagCommand(["A", "due"], self.todolist, self.out, self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "")
self.assertEquals(self.errors, "Invalid todo number.\n")
self.assertEqual(self.output, "")
self.assertEqual(self.errors, "Invalid todo number.\n")
def test_rm_tag10(self):
command = TagCommand(["-f", "4", "due"], self.todolist, self.out, self.error, lambda t: "A")
command.execute()
self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, "| 4| Fnord\n")
self.assertEquals(self.errors, "")
self.assertEqual(self.output, "| 4| Fnord\n")
self.assertEqual(self.errors, "")
def test_no_tag(self):
command = TagCommand(["4"], self.todolist, self.out, self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "")
self.assertEquals(self.errors, command.usage() + "\n")
self.assertEqual(self.output, "")
self.assertEqual(self.errors, command.usage() + "\n")
def test_help(self):
command = TagCommand(["help"], self.todolist, self.out, self.error)
command.execute()
self.assertEquals(self.output, "")
self.assertEquals(self.errors, command.usage() + "\n\n" + command.help() + "\n")
self.assertEqual(self.output, "")
self.assertEqual(self.errors, command.usage() + "\n\n" + command.help() + "\n")
if __name__ == '__main__':
unittest.main()
......@@ -48,7 +48,7 @@ class TodoBaseTester(TopydoTest):
todo = TodoBase("(C) Foo id:1")
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):
todo = TodoBase("(C) Foo foo:bar")
......@@ -146,7 +146,7 @@ class TodoBaseTester(TopydoTest):
todo = TodoBase("(A) Foo")
todo.set_priority('B')
self.assertEquals(todo.priority(), 'B')
self.assertEqual(todo.priority(), 'B')
self.assertTrue(re.match(r'^\(B\) Foo$', todo.src))
def test_set_priority2(self):
......@@ -154,7 +154,7 @@ class TodoBaseTester(TopydoTest):
todo = TodoBase("Foo")
todo.set_priority('B')
self.assertEquals(todo.priority(), 'B')
self.assertEqual(todo.priority(), 'B')
self.assertTrue(re.match(r'^\(B\) Foo$', todo.src))
def test_set_priority3(self):
......@@ -162,7 +162,7 @@ class TodoBaseTester(TopydoTest):
todo = TodoBase("(A) Foo")
todo.set_priority('AB')
self.assertEquals(todo.priority(), 'A')
self.assertEqual(todo.priority(), 'A')
self.assertTrue(re.match(r'^\(A\) Foo$', todo.src))
def test_set_priority4(self):
......@@ -173,7 +173,7 @@ class TodoBaseTester(TopydoTest):
todo.set_priority('B')
self.assertEquals(todo.priority(), 'B')
self.assertEqual(todo.priority(), 'B')
self.assertTrue(re.match(r'^\(B\) \(A\)Foo$', todo.src))
def test_set_priority5(self):
......@@ -181,7 +181,7 @@ class TodoBaseTester(TopydoTest):
todo = TodoBase("(A) Foo")
todo.set_priority(None)
self.assertEquals(todo.priority(), None)
self.assertEqual(todo.priority(), None)
self.assertTrue(re.match(r'^Foo$', todo.src))
def test_set_priority6(self):
......@@ -190,32 +190,32 @@ class TodoBaseTester(TopydoTest):
todo.set_priority('A')
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):
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('Baz', todo.projects())
def test_project2(self):
todo = TodoBase("(C) Foo +Bar+Baz")
self.assertEquals(len(todo.projects()), 1)
self.assertEqual(len(todo.projects()), 1)
self.assertIn('Bar+Baz', todo.projects())
def test_context1(self):
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('Baz', todo.contexts())
def test_context2(self):
todo = TodoBase("(C) Foo @Bar+Baz")
self.assertEquals(len(todo.contexts()), 1)
self.assertEqual(len(todo.contexts()), 1)
self.assertIn('Bar+Baz', todo.contexts())
def test_completion1(self):
......@@ -248,7 +248,7 @@ class TodoBaseTester(TopydoTest):
today_str = today.isoformat()
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))
def test_set_complete2(self):
......@@ -258,7 +258,7 @@ class TodoBaseTester(TopydoTest):
today = date.today()
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))
......@@ -269,7 +269,7 @@ class TodoBaseTester(TopydoTest):
today = date.today()
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))
def test_set_complete4(self):
......@@ -279,21 +279,21 @@ class TodoBaseTester(TopydoTest):
today = date.today()
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))
def test_set_complete5(self):
todo = TodoBase("x 2014-06-13 Foo")
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):
todo = TodoBase("Foo")
yesterday = date.today() - timedelta(1)
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):
todo = TodoBase("(B) Foo")
......@@ -301,8 +301,8 @@ class TodoBaseTester(TopydoTest):
new_text = "(C) Foo"
todo.set_source_text(new_text)
self.assertEquals(todo.src, new_text)
self.assertEquals(todo.priority(),'C')
self.assertEqual(todo.src, new_text)
self.assertEqual(todo.priority(),'C')
def test_set_creation_date1(self):
todo = TodoBase("Foo")
......@@ -310,8 +310,8 @@ class TodoBaseTester(TopydoTest):
todo.set_creation_date(creation_date)
self.assertEquals(todo.creation_date(), creation_date)
self.assertEquals(todo.src, "2014-07-24 Foo")
self.assertEqual(todo.creation_date(), creation_date)
self.assertEqual(todo.src, "2014-07-24 Foo")
def test_set_creation_date2(self):
todo = TodoBase("(A) Foo")
......@@ -319,8 +319,8 @@ class TodoBaseTester(TopydoTest):
todo.set_creation_date(creation_date)
self.assertEquals(todo.creation_date(), creation_date)
self.assertEquals(todo.src, "(A) 2014-07-24 Foo")
self.assertEqual(todo.creation_date(), creation_date)
self.assertEqual(todo.src, "(A) 2014-07-24 Foo")
def test_set_creation_date3(self):
todo = TodoBase("(A) 2014-07-23 Foo")
......@@ -328,8 +328,8 @@ class TodoBaseTester(TopydoTest):
todo.set_creation_date(creation_date)
self.assertEquals(todo.creation_date(), creation_date)
self.assertEquals(todo.src, "(A) 2014-07-24 Foo")
self.assertEqual(todo.creation_date(), creation_date)
self.assertEqual(todo.src, "(A) 2014-07-24 Foo")
def test_set_creation_date4(self):
todo = TodoBase("2014-07-23 Foo")
......@@ -337,8 +337,8 @@ class TodoBaseTester(TopydoTest):
todo.set_creation_date(creation_date)
self.assertEquals(todo.creation_date(), creation_date)
self.assertEquals(todo.src, "2014-07-24 Foo")
self.assertEqual(todo.creation_date(), creation_date)
self.assertEqual(todo.src, "2014-07-24 Foo")
def test_set_creation_date5(self):
todo = TodoBase("x 2014-07-25 2014-07-23 Foo")
......@@ -346,8 +346,8 @@ class TodoBaseTester(TopydoTest):
todo.set_creation_date(creation_date)
self.assertEquals(todo.creation_date(), creation_date)
self.assertEquals(todo.src, "x 2014-07-25 2014-07-24 Foo")
self.assertEqual(todo.creation_date(), creation_date)
self.assertEqual(todo.src, "x 2014-07-25 2014-07-24 Foo")
if __name__ == '__main__':
unittest.main()
......@@ -14,6 +14,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from six import u
import unittest
from test.TestFacilities import load_file
......@@ -23,7 +24,12 @@ class TodoFileTest(TopydoTest):
def test_empty_file(self):
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__':
unittest.main()
......@@ -37,12 +37,12 @@ class TodoListTester(TopydoTest):
self.todolist = TodoList(lines)
def test_contexts(self):
self.assertEquals(set(['Context1', 'Context2']), \
self.assertEqual(set(['Context1', 'Context2']), \
self.todolist.contexts())
self.assertFalse(self.todolist.is_dirty())
def test_projects(self):
self.assertEquals(set(['Project1', 'Project2']), \
self.assertEqual(set(['Project1', 'Project2']), \
self.todolist.projects())
self.assertFalse(self.todolist.is_dirty())
......@@ -51,18 +51,18 @@ class TodoListTester(TopydoTest):
count = self.todolist.count()
todo = self.todolist.add(text)
self.assertEquals(self.todolist.todo(count+1).source(), text)
self.assertEquals(set(['Project1', 'Project2', 'Project3']), \
self.assertEqual(self.todolist.todo(count+1).source(), text)
self.assertEqual(set(['Project1', 'Project2', 'Project3']), \
self.todolist.projects())
self.assertEquals(set(['Context1', 'Context2', 'Context3']), \
self.assertEqual(set(['Context1', 'Context2', 'Context3']), \
self.todolist.contexts())
self.assertEquals(self.todolist.number(todo), 6)
self.assertEqual(self.todolist.number(todo), 6)
self.assertTrue(self.todolist.is_dirty())
def test_add2(self):
text = str(self.todolist)
self.todolist.add('')
self.assertEquals(str(self.todolist), text)
self.assertEqual(str(self.todolist), text)
def test_add3a(self):
count = self.todolist.count()
......@@ -83,21 +83,21 @@ class TodoListTester(TopydoTest):
def test_add4(self):
text = str(self.todolist)
self.todolist.add(' ')
self.assertEquals(str(self.todolist), text)
self.assertEqual(str(self.todolist), text)
def test_add5(self):
text = str(self.todolist)
self.todolist.add("\n")
self.assertEquals(str(self.todolist), text)
self.assertEqual(str(self.todolist), text)
def test_delete1(self):
count = self.todolist.count()
todo = self.todolist.todo(2)
self.todolist.delete(todo)
self.assertEquals(self.todolist.todo(2).source(), \
self.assertEqual(self.todolist.todo(2).source(), \
"(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.assertRaises(InvalidTodoException, self.todolist.number, todo)
......@@ -105,9 +105,9 @@ class TodoListTester(TopydoTest):
todo = self.todolist.todo(3)
self.todolist.append(todo, "@Context3")
self.assertEquals(todo.source(), \
self.assertEqual(todo.source(), \
"(C) Baz @Context1 +Project1 key:value @Context3")
self.assertEquals(set(['Context1', 'Context2', 'Context3']), \
self.assertEqual(set(['Context1', 'Context2', 'Context3']), \
self.todolist.contexts())
self.assertTrue(self.todolist.is_dirty())
......@@ -116,8 +116,8 @@ class TodoListTester(TopydoTest):
text = todo.text()
self.todolist.append(todo, "foo:bar")
self.assertEquals(todo.text(), text)
self.assertEquals(todo.source(), \
self.assertEqual(todo.text(), text)
self.assertEqual(todo.source(), \
"(C) Baz @Context1 +Project1 key:value foo:bar")
def test_append3(self):
......@@ -125,7 +125,7 @@ class TodoListTester(TopydoTest):
text = todo.text()
self.todolist.append(todo, '')
self.assertEquals(todo.text(), text)
self.assertEqual(todo.text(), text)
def test_todo(self):
count = self.todolist.count()
......@@ -136,11 +136,11 @@ class TodoListTester(TopydoTest):
def test_string(self):
# readlines() always ends a string with \n, but join() in str(todolist)
# doesn't necessarily.
self.assertEquals(str(self.todolist) + '\n', self.text)
self.assertEqual(str(self.todolist) + '\n', self.text)
def test_count(self):
""" 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):
""" Tests that todos can be retrieved by their id tag. """
......@@ -155,7 +155,7 @@ class TodoListTester(TopydoTest):
todo = self.todolist.todo(6)
self.assertIsInstance(todo, Todo)
self.assertEquals(todo.text(), "No number")
self.assertEqual(todo.text(), "No number")
def test_todo_number2(self):
todo = Todo("Non-existent")
......@@ -171,7 +171,7 @@ class TodoListTester(TopydoTest):
todo = self.todolist.todo(1)
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())
def test_todo_priority2(self):
......@@ -183,7 +183,7 @@ class TodoListTester(TopydoTest):
def test_erase(self):
self.todolist.erase()
self.assertEquals(self.todolist.count(), 0)
self.assertEqual(self.todolist.count(), 0)
self.assertTrue(self.todolist.is_dirty())
def test_regex1(self):
......@@ -193,20 +193,20 @@ class TodoListTester(TopydoTest):
def test_regex3(self):
todo = self.todolist.todo("project2")
self.assertTrue(todo)
self.assertEquals(todo.source(), "(D) Bar @Context1 +Project2")
self.assertEqual(todo.source(), "(D) Bar @Context1 +Project2")
def test_uid1(self):
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):
""" Changing the priority should not change the identifier. """
config("test/data/todolist-uid.conf")
todo = self.todolist.todo('6iu')
todo = self.todolist.todo('t5c')
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):
"""
......@@ -220,10 +220,10 @@ class TodoListTester(TopydoTest):
""" Make sure that item has new text ID after append. """
config("test/data/todolist-uid.conf")
todo = self.todolist.todo('6iu')
todo = self.todolist.todo('t5c')
self.todolist.append(todo, "A")
self.assertNotEquals(self.todolist.number(todo), '6iu')
self.assertNotEqual(self.todolist.number(todo), 't5c')
class TodoListDependencyTester(TopydoTest):
def setUp(self):
......@@ -299,7 +299,7 @@ class TodoListDependencyTester(TopydoTest):
self.todolist.add_dependency(todo6, todo7)
self.assertEquals(projects, todo7.projects())
self.assertEqual(projects, todo7.projects())
def test_add_dep4(self):
"""
......@@ -312,7 +312,7 @@ class TodoListDependencyTester(TopydoTest):
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):
from_todo = self.todolist.todo(3)
......@@ -328,7 +328,7 @@ class TodoListDependencyTester(TopydoTest):
to_todo = self.todolist.todo(4)
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):
todo = self.todolist.todo(2)
......
......@@ -34,7 +34,7 @@ class ViewTest(TopydoTest):
todofilter = Filter.GrepFilter('+Project')
view = todolist.view(sorter, [todofilter])
self.assertEquals(str(view), todolist_to_string(ref))
self.assertEqual(str(view), todolist_to_string(ref))
if __name__ == '__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
append_parent_projects = 0
; Add parent contexts when adding sub todo items
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
instance based on an argument list.
"""
from topydo.lib.Config import config
import sys
from topydo.lib.AddCommand import AddCommand
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
from topydo.lib.Config import config
_SUBCOMMAND_MAP = {
'add': AddCommand,
'app': AppendCommand,
'append': AppendCommand,
'del': DeleteCommand,
'dep': DepCommand,
'depri': DepriCommand,
'do': DoCommand,
'edit': EditCommand,
'ical': IcalCommand,
'ls': ListCommand,
'lscon': ListContextCommand,
'listcon': ListContextCommand,
'lsprj': ListProjectCommand,
'lsproj': ListProjectCommand,
'listprj': ListProjectCommand,
'listproj': ListProjectCommand,
'listproject': ListProjectCommand,
'listprojects': ListProjectCommand,
'postpone': PostponeCommand,
'pri': PriorityCommand,
'rm': DeleteCommand,
'sort': SortCommand,
'tag': TagCommand,
'add': 'AddCommand',
'app': 'AppendCommand',
'append': 'AppendCommand',
'del': 'DeleteCommand',
'dep': 'DepCommand',
'depri': 'DepriCommand',
'do': 'DoCommand',
'edit': 'EditCommand',
'exit': 'ExitCommand', # used for the prompt
'ical': 'IcalCommand', # deprecated
'ls': 'ListCommand',
'lscon': 'ListContextCommand',
'listcon': 'ListContextCommand',
'lsprj': 'ListProjectCommand',
'lsproj': 'ListProjectCommand',
'listprj': 'ListProjectCommand',
'listproj': 'ListProjectCommand',
'listproject': 'ListProjectCommand',
'listprojects': 'ListProjectCommand',
'postpone': 'PostponeCommand',
'pri': 'PriorityCommand',
'quit': 'ExitCommand',
'rm': 'DeleteCommand',
'sort': 'SortCommand',
'tag': 'TagCommand',
}
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
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
args = p_args
......@@ -85,7 +85,7 @@ def get_subcommand(p_args):
subcommand = p_args[0]
if subcommand in _SUBCOMMAND_MAP:
result = _SUBCOMMAND_MAP[subcommand]
result = import_subcommand(subcommand)
args = args[1:]
elif subcommand == 'help':
try:
......@@ -100,12 +100,12 @@ def get_subcommand(p_args):
else:
p_command = config().default_command()
if p_command in _SUBCOMMAND_MAP:
result = _SUBCOMMAND_MAP[p_command]
result = import_subcommand(p_command)
# leave args unchanged
except IndexError:
p_command = config().default_command()
if p_command in _SUBCOMMAND_MAP:
result = _SUBCOMMAND_MAP[p_command]
result = import_subcommand(p_command)
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.
# 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
# it under the terms of the GNU General Public License as published by
......@@ -14,15 +14,22 @@
# 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. """
"""
Contains a base class for a CLI implementation of topydo and functions for the
I/O on the command-line.
"""
import getopt
import sys
from six import PY2
from six.moves import input
MAIN_OPTS = "c:d:ht:v"
def usage():
""" Prints the command-line usage of topydo. """
print """\
print("""\
Synopsis: topydo [-c <config>] [-d <archive>] [-t <todo.txt>] subcommand [help|args]
topydo -h
topydo -v
......@@ -52,9 +59,7 @@ Available commands:
* tag
Run `topydo help <subcommand>` for command-specific help.
"""
sys.exit(0)
""")
def write(p_file, p_string):
"""
......@@ -76,8 +81,8 @@ def error(p_string):
def version():
""" Print the current version and exit. """
from topydo.lib.Version import VERSION, LICENSE
print "topydo {}\n".format(VERSION)
print LICENSE
print("topydo {}\n".format(VERSION))
print(LICENSE)
sys.exit(0)
from topydo.lib.Config import config, ConfigError
......@@ -91,52 +96,59 @@ except ConfigError as config_error:
error(str(config_error))
sys.exit(1)
from topydo.lib.Commands import get_subcommand
from topydo.lib.ArchiveCommand import ArchiveCommand
from topydo.lib.SortCommand import SortCommand
from topydo.commands.ArchiveCommand import ArchiveCommand
from topydo.commands.SortCommand import SortCommand
from topydo.lib import TodoFile
from topydo.lib import TodoList
from topydo.lib import TodoListBase
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):
self.todolist = TodoList.TodoList([])
self.todofile = None
self.config = config()
self.path = self.config.todotxt()
self.archive_path = self.config.archive()
def _usage(self):
usage()
sys.exit(0)
def _process_flags(self):
args = sys.argv[1:]
if PY2:
args = [arg.decode('utf-8') for arg in args]
try:
opts, args = getopt.getopt(sys.argv[1:], "c:d:ht:v")
opts, args = getopt.getopt(args, MAIN_OPTS)
except getopt.GetoptError as e:
error(str(e))
sys.exit(1)
alt_path = None
alt_archive = None
alt_config_path = None
overrides = {}
for opt, value in opts:
if opt == "-c":
self.config = config(value)
alt_config_path = value
elif opt == "-t":
alt_path = value
overrides[('topydo', 'filename')] = value
elif opt == "-d":
alt_archive = value
overrides[('topydo', 'archive_filename')] = value
elif opt == "-v":
version()
else:
usage()
self._usage()
self.path = alt_path if alt_path else self.config.todotxt()
self.archive_path = alt_archive \
if alt_archive else self.config.archive()
if alt_config_path:
config(alt_config_path, overrides)
elif len(overrides):
config(p_overrides=overrides)
return args
......@@ -147,7 +159,7 @@ class CLIApplication(object):
This means that all completed tasks are moved to the archive file
(defaults to done.txt).
"""
archive_file = TodoFile.TodoFile(self.archive_path)
archive_file = TodoFile.TodoFile(config().archive())
archive = TodoListBase.TodoListBase(archive_file.read())
if archive:
......@@ -163,6 +175,12 @@ class CLIApplication(object):
else:
pass # TODO
def _input(self):
"""
Returns a function that retrieves user input.
"""
return input
def _execute(self, p_command, p_args):
"""
Execute a subcommand with arguments. p_command is a class (not an
......@@ -173,36 +191,23 @@ class CLIApplication(object):
self.todolist,
lambda o: write(sys.stdout, o),
error,
raw_input)
return False if command.execute() == False else True
def run(self):
""" Main entry function. """
args = self._process_flags()
self._input())
todofile = TodoFile.TodoFile(self.path)
self.todolist = TodoList.TodoList(todofile.read())
if command.execute() != False:
self._post_execute()
return True
(subcommand, args) = get_subcommand(args)
if subcommand == None:
usage()
if self._execute(subcommand, args) == False:
sys.exit(1)
return False
def _post_execute(self):
if self.todolist.is_dirty():
self._archive()
if config().keep_sorted():
self._execute(SortCommand, [])
todofile.write(str(self.todolist))
self.todofile.write(str(self.todolist))
def main():
""" Main entry point of the CLI. """
CLIApplication().run()
def run(self):
raise NotImplementedError
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 @@
from datetime import date
import re
from sys import stdin
import codecs
from os.path import expanduser
from topydo.lib.Config import config
from topydo.lib.Command import Command
......@@ -33,73 +36,109 @@ class AddCommand(Command):
super(AddCommand, self).__init__(
p_args, p_todolist, p_out, p_err, p_prompt)
self.text = ' '.join(p_args)
self.todo = None
self.from_file = None
def _preprocess_input_todo(self):
"""
Preprocesses user input when adding a task.
def _process_flags(self):
opts, args = self.getopt('f:')
It detects a priority mid-sentence and puts it at the start.
"""
self.text = re.sub(r'^(.+) (\([A-Z]\))(.*)$', r'\2 \1\3', self.text)
for opt, value in opts:
if opt == '-f':
self.from_file = expanduser(value)
def _postprocess_input_todo(self):
"""
Post-processes a parsed todo when adding it to the list.
self.args = args
* 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:
dateobj = relative_date_to_date(value)
if dateobj:
self.todo.set_tag(p_tag, dateobj.isoformat())
def get_todos_from_file(self):
if self.from_file == '-':
f = stdin
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):
for value in self.todo.tag_values(p_tag):
try:
dep = self.todolist.todo(value)
* 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 = p_todo.tag_value(p_tag)
if p_tag == 'after':
self.todolist.add_dependency(self.todo, dep)
elif p_tag == 'before' or p_tag == 'partof':
self.todolist.add_dependency(dep, self.todo)
except InvalidTodoException:
pass
if value:
dateobj = relative_date_to_date(value)
if dateobj:
p_todo.set_tag(p_tag, dateobj.isoformat())
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())
convert_date(config().tag_due())
if p_tag == 'after':
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')
add_dependencies('before')
add_dependencies('after')
p_todo.remove_tag(p_tag, value)
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):
""" Adds a todo item to the list. """
if not super(AddCommand, self).execute():
return False
if self.text:
self._preprocess_input_todo()
self.todo = self.todolist.add(self.text)
self._postprocess_input_todo()
self.printer.add_filter(PrettyPrinterNumbers(self.todolist))
self._process_flags()
if self.from_file:
new_todos = self.get_todos_from_file()
self.printer.add_filter(PrettyPrinterNumbers(self.todolist))
self.out(self.printer.print_todo(self.todo))
for todo in new_todos:
self._add_todo(todo)
else:
self.error(self.usage())
if self.text:
self._add_todo(self.text)
else:
self.error(self.usage())
def usage(self):
return """Synopsis: add <text>"""
return """Synopsis:
add <text>
add -f <file>
add -f -"""
def help(self):
return """\
......@@ -114,4 +153,6 @@ This subcommand automatically adds the creation date to the added item.
todo number (not the dependency number).
Example: add "Subtask partof:1"
-f : Add todo items from specified <file> or from standard input.
"""
......@@ -14,7 +14,7 @@
# You should have received a copy of the GNU General Public License
# 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):
def __init__(self, p_args, p_todolist,
......
......@@ -16,7 +16,7 @@
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.PrettyPrinterFilter import PrettyPrinterNumbers
from topydo.lib.Recurrence import advance_recurring_todo, strict_advance_recurring_todo, NoRecurrenceException
......
......@@ -18,14 +18,18 @@ import os
from subprocess import call, check_call, CalledProcessError
import tempfile
from six import text_type, u
from topydo.lib.ExpressionCommand import ExpressionCommand
from topydo.lib.MultiCommand import MultiCommand
from topydo.lib.Config import config
from topydo.lib.Todo import Todo
from topydo.lib.TodoListBase import InvalidTodoException
from topydo.lib.TodoList import TodoList
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
# cannot use super() inside the class itself
BASE_TODOLIST = lambda tl: super(TodoList, tl)
......@@ -54,14 +58,14 @@ class EditCommand(MultiCommand, ExpressionCommand):
def _todos_to_temp(self):
f = tempfile.NamedTemporaryFile()
for todo in self.todos:
f.write("%s\n" % todo.__str__())
f.write((text_type(todo) + "\n").encode('utf-8'))
f.seek(0)
return f
def _todos_from_temp(self, temp_file):
temp_file.seek(0)
todos = temp_file.read().splitlines()
def _todos_from_temp(self, p_temp_file):
p_temp_file.seek(0)
todos = p_temp_file.read().decode('utf-8').splitlines()
todo_objs = []
for todo in todos:
......@@ -69,10 +73,10 @@ class EditCommand(MultiCommand, ExpressionCommand):
return todo_objs
def _open_in_editor(self, temp_file, editor):
def _open_in_editor(self, p_temp_file, p_editor):
try:
return check_call([editor, temp_file.name])
except(CalledProcessError):
return check_call([p_editor, p_temp_file.name])
except CalledProcessError:
self.error('Something went wrong in the editor...')
return 1
......@@ -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:
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:
errors.append("Invalid todo number given.")
......@@ -96,9 +100,9 @@ class EditCommand(MultiCommand, ExpressionCommand):
self.printer.add_filter(PrettyPrinterNumbers(self.todolist))
try:
editor = os.environ['EDITOR'] or 'vi'
editor = os.environ['EDITOR'] or DEFAULT_EDITOR
except(KeyError):
editor = 'vi'
editor = DEFAULT_EDITOR
try:
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 @@
# 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 re
from topydo.lib.ExpressionCommand import ExpressionCommand
from topydo.lib.Config import config
from topydo.lib import Filter
from topydo.lib.PrettyPrinterFilter import (
PrettyPrinterIndentFilter,
PrettyPrinterHideTagFilter
)
from topydo.lib.Sorter import Sorter
from topydo.lib.View import View
from topydo.lib.IcalPrinter import IcalPrinter
from topydo.lib.JsonPrinter import JsonPrinter
class ListCommand(ExpressionCommand):
def __init__(self, p_args, p_todolist,
......@@ -34,42 +31,92 @@ class ListCommand(ExpressionCommand):
super(ListCommand, self).__init__(
p_args, p_todolist, p_out, p_err, p_prompt)
self.printer = None
self.sort_expression = config().sort_string()
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):
opts, args = self.getopt('s:x')
opts, args = self.getopt('f:s:x')
for opt, value in opts:
if opt == '-x':
self.show_all = True
elif opt == '-s':
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
def _print(self):
""" Prints the todos. """
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))
"""
Prints the todos in the right format.
Defaults to normal text output (with possible colors and other pretty
printing. If a format was specified on the commandline, this format is
sent to the output.
"""
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):
if not super(ListCommand, self).execute():
return False
self._process_flags()
self._print()
try:
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
def usage(self):
return """Synopsis: ls [-x] [-s <sort_expression>] [expression]"""
return """ Synopsis: ls [-x] [-s <sort_expression>] [-f <format>] [expression]"""
def help(self):
return """\
......@@ -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.
-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
in the configuration.
-x : Show all todos (i.e. do not filter on dependencies or relevance).
......
......@@ -28,7 +28,7 @@ class ListContextCommand(Command):
if not super(ListContextCommand, self).execute():
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)
def usage(self):
......
......@@ -28,7 +28,7 @@ class ListProjectCommand(Command):
if not super(ListProjectCommand, self).execute():
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)
def usage(self):
......
......@@ -68,8 +68,10 @@ class PostponeCommand(MultiCommand):
if self.move_start_date and todo.has_tag(config().tag_start()):
length = todo.length()
new_start = new_due - timedelta(length)
# pylint: disable=E1103
todo.set_tag(config().tag_start(), new_start.isoformat())
# pylint: disable=E1103
todo.set_tag(config().tag_due(), new_due.isoformat())
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 @@
import os
import ConfigParser
from six.moves import configparser
class ConfigError(Exception):
def __init__(self, p_text):
......@@ -26,14 +26,19 @@ class ConfigError(Exception):
return self.text
class _Config:
def __init__(self, p_path=None):
def __init__(self, p_path=None, p_overrides=None):
"""
Constructor.
If p_path is given, that is the only configuration file that will be
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 = {
# topydo
......@@ -62,17 +67,25 @@ class _Config:
# dep
'append_parent_projects': '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.cp = ConfigParser.SafeConfigParser(self.defaults)
self.cp = configparser.ConfigParser(self.defaults)
files = [
"/etc/topydo.conf",
self._home_config_path(),
".topydo",
"topydo.conf"
"topydo.conf",
"topydo.ini",
]
# when a path is given, *only* use the values in that file, or the
......@@ -84,6 +97,10 @@ class _Config:
self._supplement_sections()
if p_overrides:
for (section, option), value in p_overrides.items():
self.cp.set(section, option, value)
def _supplement_sections(self):
for section in self.sections:
if not self.cp.has_section(section):
......@@ -177,18 +194,68 @@ class _Config:
hidden_tags = self.cp.get('ls', 'hide_tags')
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.
If a path is given, the instance is overwritten by the one that supplies an
additional filename (for testability). Moreover, no other configuration
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:
config.instance = _Config(p_path)
except ConfigParser.ParsingError as perr:
config.instance = _Config(p_path, p_overrides)
except configparser.ParsingError as perr:
raise ConfigError(str(perr))
return config.instance
......
......@@ -15,6 +15,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import re
from six import text_type
from topydo.lib.Config import config
from topydo.lib.RelativeDate import relative_date_to_date
......@@ -63,7 +64,7 @@ class GrepFilter(Filter):
super(GrepFilter, self).__init__()
# convert to string in case we receive integers
self.expression = str(p_expression)
self.expression = text_type(p_expression)
if p_case_sensitive != None:
self.case_sensitive = p_case_sensitive
......
......@@ -92,7 +92,7 @@ class DirectedGraph(object):
visited.add(current)
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]
stack = stack + parents
......@@ -182,7 +182,7 @@ class DirectedGraph(object):
"""
removals = set()
for from_node, neighbors in self._edges.iteritems():
for from_node, neighbors in self._edges.items():
childpairs = \
[(c1, c2) for c1 in neighbors for c2 in neighbors if c1 != c2]
......@@ -198,7 +198,7 @@ class DirectedGraph(object):
""" Prints the graph in Dot format. """
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)
for neighbor in neighbors:
......
......@@ -19,6 +19,8 @@ Module that calculates identifiers for each item in a list, based on the hash
value of each item.
"""
from hashlib import sha1
_TABLE_SIZES = {
# we choose a large table size to reduce the chance of collisions.
3: 46649, # largest prime under zzz_36
......@@ -41,7 +43,7 @@ def _to_base36(p_value):
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
identifiers.
......@@ -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]
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:
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
file according to RFC 2445.
"""
try:
import icalendar as ical
ICAL_PRESENT = True
except ImportError:
ICAL_PRESENT = False
from datetime import datetime, time
import random
import string
......@@ -72,21 +66,30 @@ class IcalPrinter(Printer):
super(IcalPrinter, self).__init__()
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):
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):
result = ""
if ICAL_PRESENT:
cal = ical.Calendar()
if self.icalendar:
cal = self.icalendar.Calendar()
cal.add('prodid', '-//bramschoenmakers.nl//topydo//')
cal.add('version', '2.0')
for todo in p_todos:
cal.add_component(self._convert_todo(todo))
result = cal.to_ical()
result = cal.to_ical().decode('utf-8')
return result
......@@ -105,7 +108,7 @@ class IcalPrinter(Printer):
"""
return ''.join(
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')
if not uid:
......@@ -115,14 +118,14 @@ class IcalPrinter(Printer):
return uid
result = ical.Todo()
result = self.icalendar.Todo()
# this should be called first, it may set the ical: tag and therefore
# change the source() output.
result['uid'] = _get_uid(p_todo)
result['summary'] = ical.vText(p_todo.text())
result['description'] = ical.vText(p_todo.source())
result['summary'] = self.icalendar.vText(p_todo.text())
result['description'] = self.icalendar.vText(p_todo.source())
result.add('priority', _convert_priority(p_todo.priority()))
start = p_todo.start_date()
......
......@@ -14,45 +14,51 @@
# 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 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 CommandTest
from topydo.lib.IcalCommand import IcalCommand
import TestFacilities
import json
class IcalCommandTest(CommandTest.CommandTest):
def setUp(self):
super(IcalCommandTest, self).setUp()
self.todolist = TestFacilities.load_file_to_todolist("test/data/ListCommandTest.txt")
from topydo.lib.PrettyPrinter import Printer
def test_ical(self):
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)
def _convert_todo(p_todo):
""" Converts a Todo instance to a dictionary. """
creation_date = p_todo.creation_date()
completion_date = p_todo.completion_date()
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)
command.execute()
return result
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 = ""
with open('test/data/ListCommandTest.ics', 'r') as ical:
icaltext = "".join(ical.readlines())
def print_todo(self, p_todo):
return json.dumps(_convert_todo(p_todo), ensure_ascii=False,
sort_keys=True)
self.assertEquals(replace_ical_tags(self.output), replace_ical_tags(icaltext))
self.assertEquals(self.errors, "")
def print_list(self, p_todos):
result = []
def test_help(self):
command = IcalCommand(["help"], self.todolist, self.out, self.error)
command.execute()
for todo in p_todos:
result.append(_convert_todo(todo))
self.assertEquals(self.output, "")
self.assertEquals(self.errors, command.usage() + "\n\n" + command.help() + "\n")
if __name__ == '__main__':
unittest.main()
return json.dumps(result, ensure_ascii=False, sort_keys=True)
......@@ -14,6 +14,8 @@
# You should have received a copy of the GNU General Public License
# 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.TodoListBase import InvalidTodoException
......@@ -52,7 +54,7 @@ class MultiCommand(Command):
if len(self.invalid_numbers) > 1 or len(self.invalid_numbers) > 0 and len(self.todos) > 0:
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:
errors.append("Invalid todo number given.")
elif len(self.todos) == 0 and len(self.invalid_numbers) == 0:
......
......@@ -19,6 +19,7 @@
import re
from topydo.lib.Config import config
from topydo.lib.Colors import Colors, NEUTRAL_COLOR
class PrettyPrinterFilter(object):
"""
......@@ -31,15 +32,6 @@ class PrettyPrinterFilter(object):
""" Default implementation returns an unmodified todo string. """
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):
"""
Adds colors to the todo string by inserting ANSI codes.
......@@ -50,22 +42,40 @@ class PrettyPrinterColorFilter(PrettyPrinterFilter):
def filter(self, p_todo_str, p_todo):
""" 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():
color = NEUTRAL_COLOR
try:
color = PRIORITY_COLORS[p_todo.priority()]
color = priority_colors[p_todo.priority()]
except KeyError:
pass
p_todo_str = color + p_todo_str + NEUTRAL_COLOR
p_todo_str = color + p_todo_str
if config().highlight_projects_contexts():
p_todo_str = re.sub(
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 += 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
......
......@@ -47,6 +47,7 @@ def _advance_recurring_todo_helper(p_todo, p_offset):
if not new_due:
raise NoRecurrenceException()
# pylint: disable=E1103
todo.set_tag(config().tag_due(), new_due.isoformat())
if todo.start_date():
......
......@@ -29,7 +29,7 @@ def _add_months(p_sourcedate, p_months):
https://stackoverflow.com/questions/4130922/how-to-increment-datetime-month-in-python
"""
month = p_sourcedate.month - 1 + p_months
year = p_sourcedate.year + month / 12
year = p_sourcedate.year + month // 12
month = month % 12 + 1
day = min(p_sourcedate.day, calendar.monthrange(year, month)[1])
......
......@@ -100,7 +100,8 @@ class Sorter(object):
sorted_todos = p_todos
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
......
......@@ -20,10 +20,12 @@ This module contains the class that represents a single todo item.
from datetime import date
import re
from six import python_2_unicode_compatible, u
from topydo.lib.TodoParser import parse_line
from topydo.lib.Utils import is_valid_priority
@python_2_unicode_compatible
class TodoBase(object):
"""
This class represents a single todo item in a todo.txt file. It maintains
......@@ -128,6 +130,13 @@ class TodoBase(object):
value = p_value if p_value != "" else r'\S+'
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):
"""
Sets the priority of the todo. Must be a single capital letter [A-Z],
......@@ -211,7 +220,7 @@ class TodoBase(object):
self.src = re.sub(
r'^(x \d{4}-\d{2}-\d{2} |\([A-Z]\) )?(\d{4}-\d{2}-\d{2} )?(.*)$',
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)
def creation_date(self):
......
......@@ -18,6 +18,8 @@
This module deals with todo.txt files.
"""
import codecs
class TodoFile(object):
"""
This class represents a todo.txt file, which can be read from or written
......@@ -31,7 +33,7 @@ class TodoFile(object):
""" Reads the todo.txt file and returns a list of todo items. """
todos = []
try:
todofile = open(self.path, 'r')
todofile = codecs.open(self.path, 'r', encoding="utf-8")
todos = todofile.readlines()
todofile.close()
except IOError:
......
......@@ -249,7 +249,7 @@ class TodoListBase(object):
self._todo_id_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:
self._todo_id_map[todo] = uid
......
""" Version of Topydo. """
VERSION = '0.3.2'
VERSION = '0.4'
LICENSE = """Copyright (C) 2014 - 2015 Bram Schoenmakers
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
......
......@@ -16,12 +16,15 @@
""" A view is a list of todos, sorted and filtered. """
from six import python_2_unicode_compatible
from topydo.lib.PrettyPrinterFilter import (
PrettyPrinterColorFilter,
PrettyPrinterNumbers
)
from topydo.lib.PrettyPrinter import PrettyPrinter
@python_2_unicode_compatible
class View(object):
"""
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