Commit 95861af2 authored by Bram Schoenmakers's avatar Bram Schoenmakers

Merge pull request #55 from MinchinWeb/style

Style Changes
parents 1cd3a094 8ade0c20
*.pyc
*.py[cod]
*.sw?
install
.coverage
......@@ -19,6 +19,7 @@ var/
*.egg-info/
.installed.cfg
*.egg
.eggs/
# Sublime Text
*.sublime-*
......
......@@ -2,8 +2,17 @@ sudo: false # run on new infrastructure
language: python
python:
- "2.7"
- "3.2"
- "3.3"
- "3.4"
- "3.5"
- "pypy"
- "pypy3"
matrix:
allow_failures:
- python: "3.2"
- python: "pypy"
- python: "pypy3"
install:
- "pip install ."
- "pip install icalendar"
......
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# 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
......@@ -14,10 +14,9 @@
# 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 unittest
from test.TopydoTestCase import TopydoTest
from topydo.lib.Utils import escape_ansi
from test.TopydoTest import TopydoTest
class CommandTest(TopydoTest):
def __init__(self, *args, **kwargs):
......@@ -32,6 +31,3 @@ class CommandTest(TopydoTest):
def error(self, p_error):
if p_error:
self.errors += escape_ansi(p_error + "\n")
if __name__ == '__main__':
unittest.main()
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# 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
......@@ -19,6 +19,7 @@ from topydo.lib.Todo import Todo
from topydo.lib.TodoFile import TodoFile
from topydo.lib.TodoList import TodoList
def load_file(p_filename):
"""
Loads a todo file from the given filename and returns a list of todos.
......@@ -26,6 +27,7 @@ def load_file(p_filename):
todolist = load_file_to_raw_list(p_filename)
return [Todo(src) for src in todolist]
def load_file_to_raw_list(p_filename):
"""
Loads a todo file from the given filename and returns a list of todo
......@@ -34,6 +36,7 @@ def load_file_to_raw_list(p_filename):
todofile = TodoFile(p_filename)
return todofile.read()
def load_file_to_todolist(p_filename):
"""
Loads a todo file to a TodoList instance.
......@@ -41,10 +44,12 @@ def load_file_to_todolist(p_filename):
todolist = load_file_to_raw_list(p_filename)
return TodoList(todolist)
def todolist_to_string(p_list):
""" Converts a todo list to a single string. """
return '\n'.join([t.source() for t in p_list])
def print_view(p_view):
printer = PrettyPrinter()
return printer.print_list(p_view.todos)
......@@ -14,8 +14,16 @@
# 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 datetime import date
import unittest
from datetime import date
from io import StringIO
from six import u
from test.CommandTestCase import CommandTest
from topydo.commands import AddCommand, ListCommand
from topydo.lib import TodoList
from topydo.lib.Config import config
# We're searching for 'mock'
# pylint: disable=no-name-in-module
......@@ -24,14 +32,6 @@ try:
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
from topydo.lib.Config import config
from topydo.lib import TodoList
class AddCommandTest(CommandTest):
def setUp(self):
......@@ -41,219 +41,276 @@ class AddCommandTest(CommandTest):
def test_add_task(self):
args = ["New todo"]
command = AddCommand.AddCommand(args, self.todolist, self.out, self.error)
command = AddCommand.AddCommand(args, self.todolist, self.out,
self.error)
command.execute()
self.assertEqual(self.todolist.todo(1).source(), self.today + " New todo")
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 = AddCommand.AddCommand(args, self.todolist, self.out,
self.error)
command.execute()
self.assertEqual(self.todolist.todo(1).source(), self.today + " New todo")
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 = AddCommand.AddCommand(["Foo (C)"], self.todolist, self.out,
self.error)
command.execute()
self.assertEqual(self.todolist.todo(1).priority(), 'C')
self.assertEqual(self.todolist.todo(1).source(), "(C) " + self.today + " Foo")
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 = AddCommand.AddCommand(["Foo (CC)"], self.todolist, self.out,
self.error)
command.execute()
self.assertEqual(self.todolist.todo(1).priority(), None)
self.assertEqual(self.todolist.todo(1).source(), self.today + " Foo (CC)")
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 = AddCommand.AddCommand(["Fo(C)o"], self.todolist, self.out,
self.error)
command.execute()
self.assertEqual(self.todolist.todo(1).priority(), None)
self.assertEqual(self.todolist.todo(1).source(), self.today + " Fo(C)o" )
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 = AddCommand.AddCommand(["(C) Foo"], self.todolist, self.out,
self.error)
command.execute()
self.assertEqual(self.todolist.todo(1).priority(), 'C')
self.assertEqual(self.todolist.todo(1).source(), "(C) " + self.today + " Foo")
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)
def test_add_dep01(self):
command = AddCommand.AddCommand(["Foo"], self.todolist, self.out,
self.error)
command.execute()
command = AddCommand.AddCommand(["Bar before:1"], self.todolist, self.out, self.error)
command = AddCommand.AddCommand(["Bar before:1"], self.todolist,
self.out, self.error)
command.execute()
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.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)
def test_add_dep02(self):
command = AddCommand.AddCommand(["Foo"], self.todolist, self.out,
self.error)
command.execute()
command = AddCommand.AddCommand(["Bar partof:1"], self.todolist)
command.execute()
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.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):
def test_add_dep03(self):
command = AddCommand.AddCommand(["Foo"], self.todolist)
command.execute()
command = AddCommand.AddCommand(["Bar after:1"], self.todolist, self.out, self.error)
command = AddCommand.AddCommand(["Bar after:1"], self.todolist,
self.out, self.error)
command.execute()
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.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):
def test_add_de04(self):
""" Test for using an after: tag with non-existing value. """
command = AddCommand.AddCommand(["Foo after:1"], self.todolist, self.out, self.error)
command = AddCommand.AddCommand(["Foo after:1"], self.todolist,
self.out, self.error)
command.execute()
self.assertFalse(self.todolist.todo(1).has_tag("after"))
self.assertEqual(self.todolist.todo(1).source(), self.today + " Foo")
self.assertEqual(self.output, "| 1| " + self.todolist.todo(1).source() + "\n")
self.assertEqual(self.output,
"| 1| " + self.todolist.todo(1).source() + "\n")
self.assertEqual(self.errors, "")
def test_add_dep5(self):
def test_add_dep05(self):
""" Test for using an after: tag with non-existing value. """
command = AddCommand.AddCommand(["Foo after:2"], self.todolist, self.out, self.error)
command = AddCommand.AddCommand(["Foo after:2"], self.todolist,
self.out, self.error)
command.execute()
self.assertFalse(self.todolist.todo(1).has_tag("after"))
self.assertEqual(self.todolist.todo(1).source(), self.today + " Foo")
self.assertEqual(self.output, "| 1| " + self.todolist.todo(1).source() + "\n")
self.assertEqual(self.output,
"| 1| " + self.todolist.todo(1).source() + "\n")
self.assertEqual(self.errors, "")
def test_add_dep6(self):
command = AddCommand.AddCommand(["Foo"], self.todolist, self.out, self.error)
def test_add_dep06(self):
command = AddCommand.AddCommand(["Foo"], self.todolist, self.out,
self.error)
command.execute()
command = AddCommand.AddCommand(["Bar"], self.todolist, self.out, self.error)
command = AddCommand.AddCommand(["Bar"], self.todolist, self.out,
self.error)
command.execute()
command = AddCommand.AddCommand(["Baz before:1 before:2"], self.todolist, self.out, self.error)
command = AddCommand.AddCommand(["Baz before:1 before:2"],
self.todolist, self.out, self.error)
command.execute()
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.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)
def test_add_dep07(self):
command = AddCommand.AddCommand(["Foo"], self.todolist, self.out,
self.error)
command.execute()
command = AddCommand.AddCommand(["Bar"], self.todolist, self.out, self.error)
command = AddCommand.AddCommand(["Bar"], self.todolist, self.out,
self.error)
command.execute()
command = AddCommand.AddCommand(["Baz after:1 after:2"], self.todolist, self.out, self.error)
command = AddCommand.AddCommand(["Baz after:1 after:2"], self.todolist,
self.out, self.error)
command.execute()
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.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):
def test_add_dep08(self):
config("test/data/todolist-uid.conf")
command = AddCommand.AddCommand(["Foo"], self.todolist, self.out, self.error)
command = AddCommand.AddCommand(["Foo"], self.todolist, self.out,
self.error)
command.execute()
command = AddCommand.AddCommand(["Bar after:7ui"], self.todolist, self.out, self.error)
command = AddCommand.AddCommand(["Bar after:7ui"], self.todolist,
self.out, self.error)
command.execute()
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))
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):
def test_add_dep09(self):
"""
The text ID shown after adding and after an 'ls' must be equal."
The text ID shown after adding and after an 'ls' must be equal.
By appending the parent's projects, the textual ID may change.
"""
config("test/data/todolist-uid-projects.conf")
# pass identitiy function to for writing output, we're not interested
# in this output
command = AddCommand.AddCommand(["Foo +Project"], self.todolist, lambda t: t, self.error)
command = AddCommand.AddCommand(["Foo +Project"], self.todolist,
lambda t: t, self.error)
command.execute()
command = AddCommand.AddCommand(["Bar before:kh0"], 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 = ListCommand.ListCommand(["Bar"], self.todolist, self.out,
self.error)
command.execute()
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):
"""
The text ID shown after adding and after an 'ls' must be equal."
The text ID shown after adding and after an 'ls' must be equal.
By appending the parent's contexts, the textual ID may change.
"""
config("test/data/todolist-uid-contexts.conf")
# pass identitiy function to for writing output, we're not interested
# in this output
command = AddCommand.AddCommand(["Foo @Context"], self.todolist, lambda t: t, self.error)
command = AddCommand.AddCommand(["Foo @Context"], self.todolist,
lambda t: t, self.error)
command.execute()
command = AddCommand.AddCommand(["Bar before:2a2"], 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 = ListCommand.ListCommand(["Bar"], self.todolist, self.out,
self.error)
command.execute()
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 = AddCommand.AddCommand(["Foo due:today"], self.todolist,
self.out, self.error)
command.execute()
self.assertEqual(self.todolist.todo(1).source(), self.today + " Foo due:" + self.today)
self.assertEqual(self.todolist.todo(1).source(),
self.today + " Foo due:" + self.today)
self.assertEqual(self.errors, "")
def test_add_reldate2(self):
command = AddCommand.AddCommand(["Foo t:today due:today"], self.todolist, self.out, self.error)
command = AddCommand.AddCommand(["Foo t:today due:today"],
self.todolist, self.out, self.error)
command.execute()
result = "| 1| {} Foo t:{} due:{}\n".format(self.today, self.today, self.today)
result = "| 1| {} Foo t:{} due:{}\n".format(self.today, self.today,
self.today)
self.assertEqual(self.output, result)
self.assertEqual(self.errors, "")
def test_add_empty(self):
command = AddCommand.AddCommand([], self.todolist, self.out, self.error)
command = AddCommand.AddCommand([], self.todolist, self.out,
self.error)
command.execute()
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 = AddCommand.AddCommand([u("Special \u25c4")], self.todolist,
self.out, self.error)
command.execute()
self.assertEqual(self.output, u("| 1| {} Special \u25c4\n").format(self.today))
self.assertEqual(self.output,
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")))
@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 = AddCommand.AddCommand(["-f", "-"], self.todolist, self.out,
self.error)
command.execute()
self.assertEqual(self.output, u("| 1| {tod} Fo\u00f3 due:{tod} id:1\n| 2| {tod} B\u0105r p:1\n".format(tod=self.today)))
......@@ -270,18 +327,21 @@ class AddCommandTest(CommandTest):
config(p_overrides={('add', 'auto_creation_date'): '0'})
args = ["New todo"]
command = AddCommand.AddCommand(args, self.todolist, self.out, self.error)
command = AddCommand.AddCommand(args, self.todolist, self.out,
self.error)
command.execute()
self.assertEqual(self.todolist.todo(1).source(), "New todo")
self.assertEqual(self.errors, "")
def test_help(self):
command = AddCommand.AddCommand(["help"], self.todolist, self.out, self.error)
command = AddCommand.AddCommand(["help"], self.todolist, self.out,
self.error)
command.execute()
self.assertEqual(self.output, "")
self.assertEqual(self.errors, command.usage() + "\n\n" + command.help() + "\n")
self.assertEqual(self.errors,
command.usage() + "\n\n" + command.help() + "\n")
if __name__ == '__main__':
unittest.main()
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# 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
......@@ -16,10 +16,11 @@
import unittest
from test.CommandTestCase import CommandTest
from topydo.commands.AppendCommand import AppendCommand
from test.CommandTest import CommandTest
from topydo.lib.TodoList import TodoList
class AppendCommandTest(CommandTest):
def setUp(self):
super(AppendCommandTest, self).setUp()
......@@ -27,14 +28,16 @@ class AppendCommandTest(CommandTest):
self.todolist.add("Foo")
def test_append1(self):
command = AppendCommand([1, "Bar"], self.todolist, self.out, self.error)
command = AppendCommand([1, "Bar"], self.todolist, self.out,
self.error)
command.execute()
self.assertEqual(self.output, "| 1| Foo Bar\n")
self.assertEqual(self.errors, "")
def test_append2(self):
command = AppendCommand([2, "Bar"], self.todolist, self.out, self.error)
command = AppendCommand([2, "Bar"], self.todolist, self.out,
self.error)
command.execute()
self.assertEqual(self.output, "")
......@@ -55,7 +58,8 @@ class AppendCommandTest(CommandTest):
self.assertEqual(self.errors, command.usage() + "\n")
def test_append5(self):
command = AppendCommand([1, "Bar", "Baz"], self.todolist, self.out, self.error)
command = AppendCommand([1, "Bar", "Baz"], self.todolist, self.out,
self.error)
command.execute()
self.assertEqual(self.output, "| 1| Foo Bar Baz\n")
......@@ -80,7 +84,8 @@ class AppendCommandTest(CommandTest):
command.execute()
self.assertEqual(self.output, "")
self.assertEqual(self.errors, command.usage() + "\n\n" + command.help() + "\n")
self.assertEqual(self.errors,
command.usage() + "\n\n" + command.help() + "\n")
if __name__ == '__main__':
unittest.main()
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# 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
......@@ -16,11 +16,12 @@
import unittest
from test.CommandTestCase import CommandTest
from test.Facilities import load_file_to_todolist
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):
def test_archive(self):
todolist = load_file_to_todolist("test/data/ArchiveCommandTest.txt")
......@@ -36,4 +37,3 @@ class ArchiveCommandTest(CommandTest):
if __name__ == '__main__':
unittest.main()
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# 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
......@@ -17,9 +17,11 @@
""" Tests for the colorscheme functionality. """
import unittest
from topydo.lib.Colors import Colors, NEUTRAL_COLOR
from test.TopydoTestCase import TopydoTest
from topydo.lib.Colors import NEUTRAL_COLOR, Colors
from topydo.lib.Config import config
from test.TopydoTest import TopydoTest
class ColorsTest(TopydoTest):
def test_project_color1(self):
......@@ -69,7 +71,7 @@ class ColorsTest(TopydoTest):
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()
......@@ -150,7 +152,7 @@ class ColorsTest(TopydoTest):
self.assertEqual(color['A'], NEUTRAL_COLOR)
self.assertEqual(color['B'], NEUTRAL_COLOR)
self.assertEqual(color['C'], NEUTRAL_COLOR)
self.assertEqual(color['C'], NEUTRAL_COLOR)
def test_empty_color_values(self):
config("test/data/ColorsTest5.conf")
......@@ -183,3 +185,6 @@ class ColorsTest(TopydoTest):
self.assertEqual(context_color, '\033[1;35m')
self.assertEqual(link_color, '\033[4;36m')
self.assertEqual(metadata_color, '\033[1;32m')
if __name__ == '__main__':
unittest.main()
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# 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
......@@ -16,8 +16,9 @@
import unittest
from test.TopydoTestCase import TopydoTest
from topydo.lib.Config import config
from test.TopydoTest import TopydoTest
class ConfigTest(TopydoTest):
def test_config1(self):
......
......@@ -15,20 +15,24 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import unittest
from six import u
from test.CommandTest import CommandTest
from topydo.lib.Config import config
from test.CommandTestCase import CommandTest
from topydo.commands.DeleteCommand import DeleteCommand
from topydo.lib.Config import config
from topydo.lib.TodoList import TodoList
from topydo.lib.TodoListBase import InvalidTodoException
def _yes_prompt(self):
return "y"
def _no_prompt(self):
return "n"
class DeleteCommandTest(CommandTest):
def setUp(self):
super(DeleteCommandTest, self).setUp()
......@@ -42,7 +46,8 @@ class DeleteCommandTest(CommandTest):
self.todolist = TodoList(todos)
def test_del1(self):
command = DeleteCommand(["1"], self.todolist, self.out, self.error, _no_prompt)
command = DeleteCommand(["1"], self.todolist, self.out, self.error,
_no_prompt)
command.execute()
self.assertTrue(self.todolist.is_dirty())
......@@ -51,7 +56,8 @@ class DeleteCommandTest(CommandTest):
self.assertEqual(self.errors, "")
def test_del1_regex(self):
command = DeleteCommand(["Foo"], self.todolist, self.out, self.error, _no_prompt)
command = DeleteCommand(["Foo"], self.todolist, self.out, self.error,
_no_prompt)
command.execute()
self.assertTrue(self.todolist.is_dirty())
......@@ -60,29 +66,33 @@ class DeleteCommandTest(CommandTest):
self.assertEqual(self.errors, "")
def test_del2(self):
command = DeleteCommand(["1"], self.todolist, self.out, self.error, _yes_prompt)
command = DeleteCommand(["1"], self.todolist, self.out, self.error,
_yes_prompt)
command.execute()
self.assertTrue(self.todolist.is_dirty())
self.assertEqual(self.todolist.count(), 2)
self.assertEqual(self.output, "| 2| Bar p:1\nRemoved: Bar\nRemoved: Foo\n")
self.assertEqual(self.output,
"| 2| Bar p:1\nRemoved: Bar\nRemoved: Foo\n")
self.assertEqual(self.errors, "")
def test_del3(self):
command = DeleteCommand(["-f", "1"], self.todolist, self.out, self.error, _yes_prompt)
command = DeleteCommand(["-f", "1"], self.todolist, self.out,
self.error, _yes_prompt)
command.execute()
self.assertTrue(self.todolist.is_dirty())
self.assertEqual(self.todolist.count(), 3) # force won't delete subtasks
self.assertEqual(self.todolist.count(), 3) # 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 = DeleteCommand(["--force", "1"], self.todolist, self.out,
self.error, _yes_prompt)
command.execute()
self.assertTrue(self.todolist.is_dirty())
self.assertEqual(self.todolist.count(), 3) # force won't delete subtasks
self.assertEqual(self.todolist.count(), 3) # force won't delete subtasks
self.assertEqual(self.output, "| 2| Bar p:1\nRemoved: Foo id:1\n")
self.assertEqual(self.errors, "")
......@@ -125,7 +135,8 @@ class DeleteCommandTest(CommandTest):
def test_multi_del1(self):
""" Test deletion of multiple items. """
command = DeleteCommand(["1", "2"], self.todolist, self.out, self.error, _no_prompt)
command = DeleteCommand(["1", "2"], self.todolist, self.out,
self.error, _no_prompt)
command.execute()
result = "a @test with due:2015-06-03\na @test with +project"
......@@ -135,7 +146,8 @@ class DeleteCommandTest(CommandTest):
def test_multi_del2(self):
""" Test deletion of multiple items. """
command = DeleteCommand(["1", "2"], self.todolist, self.out, self.error, _yes_prompt)
command = DeleteCommand(["1", "2"], self.todolist, self.out,
self.error, _yes_prompt)
command.execute()
result = "a @test with due:2015-06-03\na @test with +project"
......@@ -145,7 +157,8 @@ class DeleteCommandTest(CommandTest):
def test_multi_del3(self):
""" Fail if any of supplied todo numbers is invalid. """
command = DeleteCommand(["99", "2"], self.todolist, self.out, self.error, _yes_prompt)
command = DeleteCommand(["99", "2"], self.todolist, self.out,
self.error, _yes_prompt)
command.execute()
self.assertFalse(self.todolist.is_dirty())
......@@ -154,7 +167,8 @@ class DeleteCommandTest(CommandTest):
def test_multi_del4(self):
""" Check output when all supplied todo numbers are invalid. """
command = DeleteCommand(["99", "A"], self.todolist, self.out, self.error, _yes_prompt)
command = DeleteCommand(["99", "A"], self.todolist, self.out,
self.error, _yes_prompt)
command.execute()
self.assertFalse(self.todolist.is_dirty())
......@@ -162,16 +176,21 @@ class DeleteCommandTest(CommandTest):
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)
"""
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"))
self.assertEqual(self.errors,
u("Invalid todo number given: Fo\u00d3B\u0105r.\n"))
def test_expr_del1(self):
command = DeleteCommand(["-e", "@test"], self.todolist, self.out, self.error, None)
command = DeleteCommand(["-e", "@test"], self.todolist, self.out,
self.error, None)
command.execute()
result = "Removed: a @test with due:2015-06-03\nRemoved: a @test with +project\n"
......@@ -182,7 +201,8 @@ class DeleteCommandTest(CommandTest):
self.assertEqual(self.errors, "")
def test_expr_del2(self):
command = DeleteCommand(["-e", "@test", "due:2015-06-03"], self.todolist, self.out, self.error, None)
command = DeleteCommand(["-e", "@test", "due:2015-06-03"],
self.todolist, self.out, self.error, None)
command.execute()
self.assertTrue(self.todolist.is_dirty())
......@@ -190,14 +210,16 @@ class DeleteCommandTest(CommandTest):
self.assertEqual(self.errors, "")
def test_expr_del3(self):
command = DeleteCommand(["-e", "@test", "due:2015-06-03", "+project"], self.todolist, self.out, self.error, None)
command = DeleteCommand(["-e", "@test", "due:2015-06-03", "+project"],
self.todolist, self.out, self.error, None)
command.execute()
self.assertFalse(self.todolist.is_dirty())
def test_expr_del4(self):
""" Remove only relevant todo items. """
command = DeleteCommand(["-e", ""], self.todolist, self.out, self.error, None)
command = DeleteCommand(["-e", ""], self.todolist, self.out,
self.error, None)
command.execute()
result = "Foo"
......@@ -208,7 +230,8 @@ class DeleteCommandTest(CommandTest):
def test_expr_del5(self):
""" Force deleting unrelevant items with additional -x flag. """
command = DeleteCommand(["-xe", ""], self.todolist, self.out, self.error, _yes_prompt)
command = DeleteCommand(["-xe", ""], self.todolist, self.out,
self.error, _yes_prompt)
command.execute()
self.assertTrue(self.todolist.is_dirty())
......@@ -227,7 +250,8 @@ class DeleteCommandTest(CommandTest):
command.execute()
self.assertEqual(self.output, "")
self.assertEqual(self.errors, command.usage() + "\n\n" + command.help() + "\n")
self.assertEqual(self.errors,
command.usage() + "\n\n" + command.help() + "\n")
if __name__ == '__main__':
unittest.main()
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# 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
......@@ -16,10 +16,11 @@
import unittest
from test.CommandTestCase import CommandTest
from topydo.commands.DepCommand import DepCommand
from test.CommandTest import CommandTest
from topydo.lib.TodoList import TodoList
class DepCommandTest(CommandTest):
def setUp(self):
super(DepCommandTest, self).setUp()
......@@ -35,7 +36,8 @@ class DepCommandTest(CommandTest):
self.todolist = TodoList(todos)
def test_add1(self):
command = DepCommand(["add", "1", "to", "4"], self.todolist, self.out, self.error)
command = DepCommand(["add", "1", "to", "4"], self.todolist, self.out,
self.error)
command.execute()
self.assertTrue(self.todolist.is_dirty())
......@@ -44,7 +46,8 @@ class DepCommandTest(CommandTest):
self.assertEqual(self.errors, "")
def test_add2(self):
command = DepCommand(["add", "1", "4"], self.todolist, self.out, self.error)
command = DepCommand(["add", "1", "4"], self.todolist, self.out,
self.error)
command.execute()
self.assertTrue(self.todolist.is_dirty())
......@@ -53,7 +56,8 @@ class DepCommandTest(CommandTest):
self.assertEqual(self.errors, "")
def test_add3(self):
command = DepCommand(["add", "99", "3"], self.todolist, self.out, self.error)
command = DepCommand(["add", "99", "3"], self.todolist, self.out,
self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
......@@ -61,7 +65,8 @@ class DepCommandTest(CommandTest):
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 = DepCommand(["add", "A", "3"], self.todolist, self.out,
self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
......@@ -77,7 +82,8 @@ class DepCommandTest(CommandTest):
self.assertEqual(self.errors, command.usage() + "\n")
def test_add6(self):
command = DepCommand(["add", "1", "after", "4"], self.todolist, self.out, self.error)
command = DepCommand(["add", "1", "after", "4"], self.todolist,
self.out, self.error)
command.execute()
self.assertTrue(self.todolist.is_dirty())
......@@ -86,7 +92,8 @@ class DepCommandTest(CommandTest):
self.assertEqual(self.errors, "")
def test_add7(self):
command = DepCommand(["add", "1", "before", "4"], self.todolist, self.out, self.error)
command = DepCommand(["add", "1", "before", "4"], self.todolist,
self.out, self.error)
command.execute()
self.assertTrue(self.todolist.is_dirty())
......@@ -95,7 +102,8 @@ class DepCommandTest(CommandTest):
self.assertEqual(self.errors, "")
def test_add8(self):
command = DepCommand(["add", "1", "partof", "4"], self.todolist, self.out, self.error)
command = DepCommand(["add", "1", "partof", "4"], self.todolist,
self.out, self.error)
command.execute()
self.assertTrue(self.todolist.is_dirty())
......@@ -104,7 +112,8 @@ class DepCommandTest(CommandTest):
self.assertEqual(self.errors, "")
def test_add9(self):
command = DepCommand(["add", "Foo", "to", "4"], self.todolist, self.out, self.error)
command = DepCommand(["add", "Foo", "to", "4"], self.todolist,
self.out, self.error)
command.execute()
self.assertTrue(self.todolist.is_dirty())
......@@ -117,7 +126,6 @@ class DepCommandTest(CommandTest):
Helper function that checks the removal of the dependency from todo 1
to todo 3.
"""
command = DepCommand(p_args, self.todolist, self.out, self.error)
command.execute()
......@@ -131,16 +139,17 @@ class DepCommandTest(CommandTest):
self.rm_helper(["rm", "1", "to", "3"])
def test_rm2(self):
self.rm_helper(["rm", "1", "3"])
self.rm_helper(["rm", "1", "3"])
def test_del1(self):
self.rm_helper(["del", "1", "to", "3"])
def test_del2(self):
self.rm_helper(["del", "1", "3"])
self.rm_helper(["del", "1", "3"])
def test_rm3(self):
command = DepCommand(["rm", "99", "3"], self.todolist, self.out, self.error)
command = DepCommand(["rm", "99", "3"], self.todolist, self.out,
self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
......@@ -148,7 +157,8 @@ class DepCommandTest(CommandTest):
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 = DepCommand(["rm", "A", "3"], self.todolist, self.out,
self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
......@@ -164,7 +174,8 @@ class DepCommandTest(CommandTest):
self.assertEqual(self.errors, command.usage() + "\n")
def test_ls1(self):
command = DepCommand(["ls", "1", "to"], self.todolist, self.out, self.error)
command = DepCommand(["ls", "1", "to"], self.todolist, self.out,
self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
......@@ -172,7 +183,8 @@ class DepCommandTest(CommandTest):
self.assertEqual(self.errors, "")
def test_ls2(self):
command = DepCommand(["ls", "99", "to"], self.todolist, self.out, self.error)
command = DepCommand(["ls", "99", "to"], self.todolist, self.out,
self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
......@@ -180,7 +192,8 @@ class DepCommandTest(CommandTest):
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 = DepCommand(["ls", "to", "3"], self.todolist, self.out,
self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
......@@ -188,7 +201,8 @@ class DepCommandTest(CommandTest):
self.assertEqual(self.errors, "")
def test_ls4(self):
command = DepCommand(["ls", "to", "99"], self.todolist, self.out, self.error)
command = DepCommand(["ls", "to", "99"], self.todolist, self.out,
self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
......@@ -212,7 +226,8 @@ class DepCommandTest(CommandTest):
self.assertEqual(self.errors, command.usage() + "\n")
def test_ls7(self):
command = DepCommand(["ls", "top", "99"], self.todolist, self.out, self.error)
command = DepCommand(["ls", "top", "99"], self.todolist, self.out,
self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
......@@ -220,7 +235,8 @@ class DepCommandTest(CommandTest):
self.assertEqual(self.errors, command.usage() + "\n")
def gc_helper(self, p_subcommand):
command = DepCommand([p_subcommand], self.todolist, self.out, self.error)
command = DepCommand([p_subcommand], self.todolist, self.out,
self.error)
command.execute()
self.assertTrue(self.todolist.is_dirty())
......@@ -255,7 +271,8 @@ class DepCommandTest(CommandTest):
command.execute()
self.assertEqual(self.output, "")
self.assertEqual(self.errors, command.usage() + "\n\n" + command.help() + "\n")
self.assertEqual(self.errors,
command.usage() + "\n\n" + command.help() + "\n")
if __name__ == '__main__':
unittest.main()
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# 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
......@@ -15,12 +15,14 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import unittest
from six import u
from test.CommandTestCase import CommandTest
from topydo.commands.DepriCommand import DepriCommand
from test.CommandTest import CommandTest
from topydo.lib.TodoList import TodoList
class DepriCommandTest(CommandTest):
def setUp(self):
super(DepriCommandTest, self).setUp()
......@@ -63,7 +65,8 @@ class DepriCommandTest(CommandTest):
self.assertEqual(self.errors, "")
def test_depri4(self):
command = DepriCommand(["1","Baz"], self.todolist, self.out, self.error)
command = DepriCommand(["1", "Baz"], self.todolist, self.out,
self.error)
command.execute()
self.assertTrue(self.todolist.is_dirty())
......@@ -73,10 +76,10 @@ class DepriCommandTest(CommandTest):
self.assertEqual(self.errors, "")
def test_expr_depri1(self):
command = DepriCommand(["-e", "@test"], self.todolist, self.out, self.error, None)
command = DepriCommand(["-e", "@test"], self.todolist, self.out,
self.error, None)
command.execute()
result = "Priority removed.\n| 4| a @test with due:2015-06-03\nPriority removed.\n| 5| a @test with +project p:1\n"
self.assertTrue(self.todolist.is_dirty())
......@@ -84,7 +87,8 @@ class DepriCommandTest(CommandTest):
self.assertEqual(self.errors, "")
def test_expr_depri2(self):
command = DepriCommand(["-e", "@test", "due:2015-06-03"], self.todolist, self.out, self.error, None)
command = DepriCommand(["-e", "@test", "due:2015-06-03"],
self.todolist, self.out, self.error, None)
command.execute()
result = "Priority removed.\n| 4| a @test with due:2015-06-03\n"
......@@ -94,29 +98,30 @@ class DepriCommandTest(CommandTest):
self.assertEqual(self.errors, "")
def test_expr_depri3(self):
command = DepriCommand(["-e", "@test", "due:2015-06-03", "+project"], self.todolist, self.out, self.error, None)
command = DepriCommand(["-e", "@test", "due:2015-06-03", "+project"],
self.todolist, self.out, self.error, None)
command.execute()
self.assertFalse(self.todolist.is_dirty())
def test_expr_depri4(self):
""" Don't remove priority from unrelevant todo items. """
command = DepriCommand(["-e", "Bax"], self.todolist, self.out, self.error, None)
command = DepriCommand(["-e", "Bax"], self.todolist, self.out,
self.error, None)
command.execute()
self.assertFalse(self.todolist.is_dirty())
def test_expr_depri5(self):
""" Force unprioritizing unrelevant items with additional -x flag. """
command = DepriCommand(["-xe", "Bax"], self.todolist, self.out, self.error, None)
command = DepriCommand(["-xe", "Bax"], self.todolist, self.out,
self.error, None)
command.execute()
self.assertTrue(self.todolist.is_dirty())
self.assertEqual(self.output, "Priority removed.\n| 6| Bax id:1\n")
self.assertEqual(self.errors, "")
def test_invalid1(self):
command = DepriCommand(["99"], self.todolist, self.out, self.error)
command.execute()
......@@ -126,7 +131,8 @@ class DepriCommandTest(CommandTest):
self.assertEqual(self.errors, "Invalid todo number given.\n")
def test_invalid2(self):
command = DepriCommand(["99", "1"], self.todolist, self.out, self.error)
command = DepriCommand(["99", "1"], self.todolist, self.out,
self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
......@@ -134,7 +140,8 @@ class DepriCommandTest(CommandTest):
self.assertEqual(self.errors, "Invalid todo number given: 99.\n")
def test_invalid3(self):
command = DepriCommand(["99", "FooBar"], self.todolist, self.out, self.error)
command = DepriCommand(["99", "FooBar"], self.todolist, self.out,
self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
......@@ -142,13 +149,17 @@ class DepriCommandTest(CommandTest):
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)
"""
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"))
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)
......@@ -163,7 +174,8 @@ class DepriCommandTest(CommandTest):
command.execute()
self.assertEqual(self.output, "")
self.assertEqual(self.errors, command.usage() + "\n\n" + command.help() + "\n")
self.assertEqual(self.errors,
command.usage() + "\n\n" + command.help() + "\n")
if __name__ == '__main__':
unittest.main()
......@@ -14,20 +14,24 @@
# 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 datetime import date, timedelta
import unittest
from datetime import date, timedelta
from six import u
from test.CommandTestCase import CommandTest
from topydo.commands.DoCommand import DoCommand
from test.CommandTest import CommandTest
from topydo.lib.TodoList import TodoList
def _yes_prompt(self):
return "y"
def _no_prompt(self):
return "n"
class DoCommandTest(CommandTest):
def setUp(self):
super(DoCommandTest, self).setUp()
......@@ -55,17 +59,19 @@ class DoCommandTest(CommandTest):
self.tomorrow = self.tomorrow.isoformat()
def test_do1(self):
command = DoCommand(["3"], self.todolist, self.out, self.error, _no_prompt)
command = DoCommand(["3"], self.todolist, self.out, self.error,
_no_prompt)
command.execute()
self.assertTrue(self.todolist.is_dirty())
self.assertTrue(self.todolist.todo(3).is_completed())
self.assertEqual(self.output, "Completed: x {} Baz p:1\n".format(
self.today))
self.assertEqual(self.output,
"Completed: x {} Baz p:1\n".format(self.today))
self.assertEqual(self.errors, "")
def test_do_subtasks1(self):
command = DoCommand(["1"], self.todolist, self.out, self.error, _yes_prompt)
command = DoCommand(["1"], self.todolist, self.out, self.error,
_yes_prompt)
command.execute()
result = "| 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)
......@@ -79,7 +85,8 @@ class DoCommandTest(CommandTest):
self.assertEqual(self.errors, "")
def test_do_subtasks2(self):
command = DoCommand(["1"], self.todolist, self.out, self.error, _no_prompt)
command = DoCommand(["1"], self.todolist, self.out, self.error,
_no_prompt)
command.execute()
result = "| 2| Bar p:1\n| 3| Baz p:1\nCompleted: x {} Foo id:1\n".format(self.today)
......@@ -98,7 +105,8 @@ class DoCommandTest(CommandTest):
global prompt_shown
prompt_shown = True
command = DoCommand(["-f", "1"], self.todolist, self.out, self.error, prompt)
command = DoCommand(["-f", "1"], self.todolist, self.out, self.error,
prompt)
command.execute()
self.assertFalse(prompt_shown)
......@@ -112,7 +120,8 @@ class DoCommandTest(CommandTest):
global prompt_shown
prompt_shown = True
command = DoCommand(["--force", "1"], self.todolist, self.out, self.error, prompt)
command = DoCommand(["--force", "1"], self.todolist, self.out,
self.error, prompt)
command.execute()
self.assertFalse(prompt_shown)
......@@ -168,7 +177,8 @@ class DoCommandTest(CommandTest):
self.assertEqual(self.errors, "Invalid todo number given.\n")
def test_invalid3(self):
command = DoCommand(["01"], self.todolist, self.out, self.error, _yes_prompt)
command = DoCommand(["01"], self.todolist, self.out, self.error,
_yes_prompt)
command.execute()
self.assertFalse(self.todolist.is_dirty())
......@@ -202,7 +212,8 @@ class DoCommandTest(CommandTest):
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEqual(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.assertEqual(self.errors, "Todo has already been completed.\n")
......@@ -212,11 +223,13 @@ class DoCommandTest(CommandTest):
self.assertTrue(self.todolist.is_dirty())
self.assertTrue(self.todolist.todo(3).is_completed())
self.assertEqual(self.output, "Completed: x {} Baz p:1\n".format(self.today))
self.assertEqual(self.output,
"Completed: x {} Baz p:1\n".format(self.today))
self.assertEqual(self.errors, "")
def test_do_custom_date1(self):
command = DoCommand(["-d", "2014-11-18", "3"], self.todolist, self.out, self.error)
command = DoCommand(["-d", "2014-11-18", "3"], self.todolist, self.out,
self.error)
command.execute()
self.assertTrue(self.todolist.is_dirty())
......@@ -224,7 +237,8 @@ class DoCommandTest(CommandTest):
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 = DoCommand(["-d", "2014-11-18", "1"], self.todolist, self.out,
self.error, _yes_prompt)
command.execute()
self.assertTrue(self.todolist.is_dirty())
......@@ -232,7 +246,8 @@ class DoCommandTest(CommandTest):
self.assertEqual(self.errors, "")
def test_do_custom_date3(self):
command = DoCommand(["--date=2014-11-18", "3"], self.todolist, self.out, self.error)
command = DoCommand(["--date=2014-11-18", "3"], self.todolist,
self.out, self.error)
command.execute()
self.assertTrue(self.todolist.is_dirty())
......@@ -240,11 +255,13 @@ class DoCommandTest(CommandTest):
self.assertEqual(self.errors, "")
def test_do_custom_date4(self):
command = DoCommand(["-d", "foo", "3"], self.todolist, self.out, self.error)
command = DoCommand(["-d", "foo", "3"], self.todolist, self.out,
self.error)
command.execute()
self.assertTrue(self.todolist.is_dirty())
self.assertEqual(self.output, "Completed: x {} Baz p:1\n".format(self.today))
self.assertEqual(self.output,
"Completed: x {} Baz p:1\n".format(self.today))
self.assertEqual(self.errors, "")
def test_do_custom_date5(self):
......@@ -252,7 +269,8 @@ class DoCommandTest(CommandTest):
Make sure that the new recurrence date is correct when a custom
date is given.
"""
command = DoCommand(["-d", self.yesterday, "4"], self.todolist, self.out, self.error)
command = DoCommand(["-d", self.yesterday, "4"], self.todolist,
self.out, self.error)
command.execute()
self.assertTrue(self.todolist.is_dirty())
......@@ -265,7 +283,8 @@ class DoCommandTest(CommandTest):
due date as the offset. This todo item however, has no due date, then
the completion date must be used as an offset.
"""
command = DoCommand(["-s", "-d", self.yesterday, "4"], self.todolist, self.out, self.error)
command = DoCommand(["-s", "-d", self.yesterday, "4"], self.todolist,
self.out, self.error)
command.execute()
self.assertTrue(self.todolist.is_dirty())
......@@ -277,7 +296,8 @@ class DoCommandTest(CommandTest):
When a custom date is set, strict recurrence must still hold on to the
due date as the offset.
"""
command = DoCommand(["-s", "-d", self.yesterday, "8"], self.todolist, self.out, self.error)
command = DoCommand(["-s", "-d", self.yesterday, "8"], self.todolist,
self.out, self.error)
command.execute()
self.assertTrue(self.todolist.is_dirty())
......@@ -285,7 +305,8 @@ class DoCommandTest(CommandTest):
self.assertEqual(self.errors, "")
def test_multi_do1(self):
command = DoCommand(["1", "3"], self.todolist, self.out, self.error, _yes_prompt)
command = DoCommand(["1", "3"], self.todolist, self.out, self.error,
_yes_prompt)
command.execute()
self.assertTrue(self.todolist.todo(1).is_completed())
......@@ -295,7 +316,8 @@ class DoCommandTest(CommandTest):
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)
command = DoCommand(["1", "3"], self.todolist, self.out, self.error,
_no_prompt)
command.execute()
self.assertTrue(self.todolist.todo(1).is_completed())
......@@ -305,14 +327,17 @@ class DoCommandTest(CommandTest):
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 = DoCommand(["3", "3"], self.todolist, self.out, self.error,
_no_prompt)
command.execute()
self.assertTrue(self.todolist.todo(3).is_completed())
self.assertEqual(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 = DoCommand(["99", "3"], self.todolist, self.out, self.error,
_no_prompt)
command.execute()
self.assertFalse(self.todolist.todo(3).is_completed())
......@@ -322,21 +347,27 @@ class DoCommandTest(CommandTest):
"""
Check output when all supplied todo numbers are invalid.
"""
command = DoCommand(["99", "15"], self.todolist, self.out, self.error, _no_prompt)
command = DoCommand(["99", "15"], self.todolist, self.out, self.error,
_no_prompt)
command.execute()
self.assertEqual(self.errors, "Invalid todo number given: 99.\nInvalid todo number given: 15.\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)
"""
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"))
self.assertEqual(self.errors,
u("Invalid todo number given: Fo\u00d3B\u0105r.\n"))
def test_expr_do1(self):
command = DoCommand(["-e", "@test"], self.todolist, self.out, self.error, None)
command = DoCommand(["-e", "@test"], self.todolist, self.out,
self.error, None)
command.execute()
self.assertTrue(self.todolist.is_dirty())
......@@ -344,7 +375,8 @@ class DoCommandTest(CommandTest):
self.assertEqual(self.errors, "")
def test_expr_do2(self):
command = DoCommand(["-e", "@test", "due:2015-06-03"], self.todolist, self.out, self.error, None)
command = DoCommand(["-e", "@test", "due:2015-06-03"], self.todolist,
self.out, self.error, None)
command.execute()
self.assertTrue(self.todolist.is_dirty())
......@@ -352,21 +384,24 @@ class DoCommandTest(CommandTest):
self.assertEqual(self.errors, "")
def test_expr_do3(self):
command = DoCommand(["-e", "@test", "due:2015-06-03", "+project"], self.todolist, self.out, self.error, None)
command = DoCommand(["-e", "@test", "due:2015-06-03", "+project"],
self.todolist, self.out, self.error, None)
command.execute()
self.assertFalse(self.todolist.is_dirty())
def test_expr_do4(self):
""" Don't do anything with unrelevant todo items. """
command = DoCommand(["-e", "Foo"], self.todolist, self.out, self.error, None)
command = DoCommand(["-e", "Foo"], self.todolist, self.out, self.error,
None)
command.execute()
self.assertFalse(self.todolist.is_dirty())
def test_expr_do5(self):
""" Force marking unrelevant items as done with additional -x flag. """
command = DoCommand(["-xe", "Foo"], self.todolist, self.out, self.error, _yes_prompt)
command = DoCommand(["-xe", "Foo"], self.todolist, self.out,
self.error, _yes_prompt)
command.execute()
result = "| 2| Bar p:1\n| 3| Baz p:1\nCompleted: x {t} Bar p:1\nCompleted: x {t} Baz p:1\nCompleted: x {t} Foo id:1\n".format(t=self.today)
......@@ -376,11 +411,15 @@ class DoCommandTest(CommandTest):
self.assertEqual(self.errors, "")
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)
"""
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.assertEqual(self.output, "Completed: x {} Invalid rec:1\n".format(self.today))
self.assertEqual(self.output,
"Completed: x {} Invalid rec:1\n".format(self.today))
self.assertEqual(self.errors, "Warning: todo item has an invalid recurrence pattern.\n")
def test_empty(self):
......@@ -396,7 +435,8 @@ class DoCommandTest(CommandTest):
command.execute()
self.assertEqual(self.output, "")
self.assertEqual(self.errors, command.usage() + "\n\n" + command.help() + "\n")
self.assertEqual(self.errors,
command.usage() + "\n\n" + command.help() + "\n")
if __name__ == '__main__':
unittest.main()
......@@ -14,8 +14,17 @@
# 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 os
import unittest
from six import u
from test.CommandTestCase import CommandTest
from topydo.commands.EditCommand import EditCommand
from topydo.lib.Config import config
from topydo.lib.Todo import Todo
from topydo.lib.TodoList import TodoList
# We're searching for 'mock'
# pylint: disable=no-name-in-module
try:
......@@ -23,14 +32,6 @@ try:
except ImportError:
import mock
from six import u
import os
from topydo.commands.EditCommand import EditCommand
from test.CommandTest import CommandTest
from topydo.lib.TodoList import TodoList
from topydo.lib.Todo import Todo
from topydo.lib.Config import config
class EditCommandTest(CommandTest):
def setUp(self):
......@@ -63,7 +64,8 @@ class EditCommandTest(CommandTest):
mock_open_in_editor.return_value = 0
mock_todos_from_temp.return_value = [Todo('Lazy Cat')]
command = EditCommand(["Bar"], self.todolist, self.out, self.error, None)
command = EditCommand(["Bar"], self.todolist, self.out, self.error,
None)
command.execute()
self.assertTrue(self.todolist.is_dirty())
......@@ -72,7 +74,8 @@ class EditCommandTest(CommandTest):
def test_edit3(self):
""" Throw an error after invalid todo number given as argument. """
command = EditCommand(["FooBar"], self.todolist, self.out, self.error, None)
command = EditCommand(["FooBar"], self.todolist, self.out, self.error,
None)
command.execute()
self.assertFalse(self.todolist.is_dirty())
......@@ -80,7 +83,8 @@ class EditCommandTest(CommandTest):
def test_edit4(self):
""" Throw an error with pointing invalid argument. """
command = EditCommand(["Bar", "5"], 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())
......@@ -93,7 +97,8 @@ class EditCommandTest(CommandTest):
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())
......@@ -101,12 +106,16 @@ class EditCommandTest(CommandTest):
self.assertEqual(self.todolist.print_todos(), 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)
"""
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.assertEqual(self.errors, u("Invalid todo number given: Fo\u00d3B\u0105r.\n"))
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')
......@@ -115,21 +124,25 @@ class EditCommandTest(CommandTest):
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 = 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(self.todolist.print_todos(), u("Foo id:1\nBar p:1 @test\nBaz @test\nLazy Cat"))
self.assertEqual(self.todolist.print_todos(),
u("Foo id:1\nBar p:1 @test\nBaz @test\nLazy Cat"))
@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')]
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 = u("| 3| Lazy Cat\n| 4| Lazy Dog\n")
......@@ -148,7 +161,8 @@ class EditCommandTest(CommandTest):
os.environ['EDITOR'] = editor
archive = config().archive()
command = EditCommand(["-d"], self.todolist, self.out, self.error, None)
command = EditCommand(["-d"], self.todolist, self.out, self.error,
None)
command.execute()
self.assertEqual(self.errors, "")
......@@ -163,7 +177,7 @@ class EditCommandTest(CommandTest):
os.environ['EDITOR'] = editor
todotxt = config().todotxt()
result = self.todolist.print_todos() # copy TodoList content *before* executing command
result = self.todolist.print_todos() # copy TodoList content *before* executing command
command = EditCommand([], self.todolist, self.out, self.error, None)
command.execute()
......
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# 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
......@@ -16,23 +16,25 @@
""" Tests for the filter functionality. """
from datetime import date, timedelta
import unittest
from datetime import date, timedelta
from test.Facilities import (load_file, load_file_to_todolist,
todolist_to_string)
from test.TopydoTestCase import TopydoTest
from topydo.lib import Filter
from test.TestFacilities import load_file, todolist_to_string, load_file_to_todolist
from topydo.lib.Todo import Todo
from test.TopydoTest import TopydoTest
class FilterTest(TopydoTest):
def test_filter3(self):
def test_filter03(self):
todo = Todo("(C) Relevant")
relevance = Filter.RelevanceFilter()
result = relevance.filter([todo])
self.assertEqual(result, [todo])
def test_filter4(self):
def test_filter04(self):
""" Test case insensitive match. """
todos = load_file('test/data/FilterTest1.txt')
grep = Filter.GrepFilter('+project')
......@@ -40,10 +42,10 @@ class FilterTest(TopydoTest):
filtered_todos = grep.filter(todos)
reference = load_file('test/data/FilterTest1a-result.txt')
self.assertEqual(todolist_to_string(filtered_todos), \
todolist_to_string(reference))
self.assertEqual(todolist_to_string(filtered_todos),
todolist_to_string(reference))
def test_filter5(self):
def test_filter05(self):
""" Test case sensitive match. """
todos = load_file('test/data/FilterTest1.txt')
grep = Filter.GrepFilter('+Project')
......@@ -51,10 +53,10 @@ class FilterTest(TopydoTest):
filtered_todos = grep.filter(todos)
reference = load_file('test/data/FilterTest1b-result.txt')
self.assertEqual(todolist_to_string(filtered_todos), \
todolist_to_string(reference))
self.assertEqual(todolist_to_string(filtered_todos),
todolist_to_string(reference))
def test_filter6(self):
def test_filter06(self):
""" Test case sensitive match (forced, with lowercase). """
todos = load_file('test/data/FilterTest1.txt')
grep = Filter.GrepFilter('+project', True)
......@@ -62,10 +64,10 @@ class FilterTest(TopydoTest):
filtered_todos = grep.filter(todos)
reference = load_file('test/data/FilterTest1c-result.txt')
self.assertEqual(todolist_to_string(filtered_todos), \
todolist_to_string(reference))
self.assertEqual(todolist_to_string(filtered_todos),
todolist_to_string(reference))
def test_filter7(self):
def test_filter07(self):
""" Tests the dependency filter. """
todolist = load_file_to_todolist('test/data/FilterTest2.txt')
depfilter = Filter.DependencyFilter(todolist)
......@@ -73,10 +75,10 @@ class FilterTest(TopydoTest):
filtered_todos = depfilter.filter(todolist.todos())
reference = load_file('test/data/FilterTest2-result.txt')
self.assertEqual(todolist_to_string(filtered_todos), \
todolist_to_string(reference))
self.assertEqual(todolist_to_string(filtered_todos),
todolist_to_string(reference))
def test_filter8(self):
def test_filter08(self):
""" Test case sensitive match (forced, with lowercase). """
todos = load_file('test/data/FilterTest1.txt')
grep = Filter.GrepFilter('+Project', False)
......@@ -84,11 +86,11 @@ class FilterTest(TopydoTest):
filtered_todos = grep.filter(todos)
reference = load_file('test/data/FilterTest1a-result.txt')
self.assertEqual(todolist_to_string(filtered_todos), \
todolist_to_string(reference))
self.assertEqual(todolist_to_string(filtered_todos),
todolist_to_string(reference))
def test_filter9(self):
""" Test instance filter """
def test_filter09(self):
""" Test instance filter. """
todos = load_file('test/data/FilterTest1.txt')
instance_filter = Filter.InstanceFilter(todos[2:])
......@@ -97,7 +99,7 @@ class FilterTest(TopydoTest):
self.assertEqual(todos[2:], filtered_todos)
def test_filter10(self):
""" Test instance filter """
""" Test instance filter. """
todos = load_file('test/data/FilterTest1.txt')
instance_filter = Filter.InstanceFilter([])
......@@ -106,7 +108,7 @@ class FilterTest(TopydoTest):
self.assertEqual([], filtered_todos)
def test_filter11(self):
""" Test instance filter """
""" Test instance filter. """
todos = load_file('test/data/FilterTest1.txt')
instance_filter = Filter.InstanceFilter(todos[2:])
......@@ -131,7 +133,8 @@ class FilterTest(TopydoTest):
filtered_todos = limit_filter.filter(todos)
self.assertEqual(len(filtered_todos), 1)
self.assertEqual(filtered_todos[0].source(), '(C) This is part of some +Project')
self.assertEqual(filtered_todos[0].source(),
'(C) This is part of some +Project')
def test_filter14(self):
""" Test limit filter. """
......@@ -158,8 +161,8 @@ class FilterTest(TopydoTest):
filtered_todos = grep.filter(todos)
reference = load_file('test/data/FilterTest3-result.txt')
self.assertEqual(todolist_to_string(filtered_todos), \
todolist_to_string(reference))
self.assertEqual(todolist_to_string(filtered_todos),
todolist_to_string(reference))
def test_filter17(self):
todos = load_file('test/data/FilterTest1.txt')
......@@ -170,8 +173,8 @@ class FilterTest(TopydoTest):
filtered_todos = andfilter.filter(todos)
reference = load_file('test/data/FilterTest4-result.txt')
self.assertEqual(todolist_to_string(filtered_todos), \
todolist_to_string(reference))
self.assertEqual(todolist_to_string(filtered_todos),
todolist_to_string(reference))
def test_filter18(self):
todos = load_file('test/data/FilterTest1.txt')
......@@ -182,8 +185,8 @@ class FilterTest(TopydoTest):
filtered_todos = grep.filter(todos)
reference = load_file('test/data/FilterTest5-result.txt')
self.assertEqual(todolist_to_string(filtered_todos), \
todolist_to_string(reference))
self.assertEqual(todolist_to_string(filtered_todos),
todolist_to_string(reference))
def test_filter20(self):
todos = load_file('test/data/FilterTest3.txt')
......@@ -192,8 +195,8 @@ class FilterTest(TopydoTest):
filtered_todos = otf.filter(todos)
reference = load_file('test/data/FilterTest6-result.txt')
self.assertEqual(todolist_to_string(filtered_todos), \
todolist_to_string(reference))
self.assertEqual(todolist_to_string(filtered_todos),
todolist_to_string(reference))
def test_filter21(self):
todos = load_file('test/data/FilterTest3.txt')
......@@ -235,7 +238,7 @@ class FilterTest(TopydoTest):
reference = load_file('test/data/FilterTest8-result.txt')
self.assertEqual(todolist_to_string(filtered_todos),
todolist_to_string(reference))
todolist_to_string(reference))
def test_filter26(self):
todos = load_file('test/data/FilterTest3.txt')
......@@ -245,7 +248,7 @@ class FilterTest(TopydoTest):
reference = load_file('test/data/FilterTest9-result.txt')
self.assertEqual(todolist_to_string(filtered_todos),
todolist_to_string(reference))
todolist_to_string(reference))
def test_filter27(self):
todos = load_file('test/data/FilterTest3.txt')
......@@ -255,7 +258,7 @@ class FilterTest(TopydoTest):
reference = load_file('test/data/FilterTest10-result.txt')
self.assertEqual(todolist_to_string(filtered_todos),
todolist_to_string(reference))
todolist_to_string(reference))
def test_filter28(self):
todos = load_file('test/data/FilterTest3.txt')
......@@ -273,7 +276,7 @@ class FilterTest(TopydoTest):
reference = load_file('test/data/FilterTest11-result.txt')
self.assertEqual(todolist_to_string(filtered_todos),
todolist_to_string(reference))
todolist_to_string(reference))
def test_filter30(self):
todos = load_file('test/data/FilterTest3.txt')
......@@ -283,7 +286,7 @@ class FilterTest(TopydoTest):
reference = load_file('test/data/FilterTest12-result.txt')
self.assertEqual(todolist_to_string(filtered_todos),
todolist_to_string(reference))
todolist_to_string(reference))
def test_filter31(self):
todos = load_file('test/data/FilterTest3.txt')
......@@ -293,7 +296,8 @@ class FilterTest(TopydoTest):
reference = load_file('test/data/FilterTest13-result.txt')
self.assertEqual(todolist_to_string(filtered_todos),
todolist_to_string(reference))
todolist_to_string(reference))
class OrdinalTagFilterTest(TopydoTest):
def setUp(self):
......@@ -374,6 +378,7 @@ class OrdinalTagFilterTest(TopydoTest):
self.assertEqual(len(result), 1)
self.assertEqual(result[0].source(), self.todo3)
class PriorityFilterTest(TopydoTest):
def setUp(self):
super(PriorityFilterTest, self).setUp()
......@@ -475,4 +480,3 @@ class PriorityFilterTest(TopydoTest):
if __name__ == '__main__':
unittest.main()
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# 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
......@@ -16,8 +16,9 @@
import unittest
from test.TopydoTestCase import TopydoTest
from topydo.lib.Graph import DirectedGraph
from test.TopydoTest import TopydoTest
class GraphTest(TopydoTest):
def setUp(self):
......@@ -63,7 +64,8 @@ class GraphTest(TopydoTest):
self.assertEqual(self.graph.incoming_neighbors(1, True), set())
def test_incoming_neighbors4(self):
self.assertEqual(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.assertEqual(self.graph.outgoing_neighbors(1), set([2, 3]))
......@@ -72,7 +74,8 @@ class GraphTest(TopydoTest):
self.assertEqual(self.graph.outgoing_neighbors(2), set([4]))
def test_outgoing_neighbors3(self):
self.assertEqual(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.assertEqual(self.graph.outgoing_neighbors(3), set([5]))
......
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# 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
......@@ -14,13 +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/>.
from datetime import date
import unittest
from datetime import date
from test.TopydoTestCase import TopydoTest
from topydo.lib.Config import config
from topydo.lib.Importance import importance
from topydo.lib.Todo import Todo
from test.TopydoTest import TopydoTest
class ImportanceTest(TopydoTest):
def test_importance1(self):
......
......@@ -14,15 +14,19 @@
# 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 unittest
from test.TopydoTestCase import TopydoTest
from topydo.lib.JsonPrinter import JsonPrinter
from topydo.lib.Todo import Todo
from test.TopydoTest import TopydoTest
class JsonPrinterTest(TopydoTest):
"""
Tests the functionality of printing a single todo item. Printing a list is
already covered by the ListCommand tests.
"""
def test_json(self):
""" Print a single todo item. """
printer = JsonPrinter()
......@@ -31,3 +35,6 @@ class JsonPrinterTest(TopydoTest):
result = printer.print_todo(todo)
self.assertEqual(result, '{"completed": false, "completion_date": null, "contexts": [], "creation_date": "2015-06-06", "priority": null, "projects": [], "source": "2015-06-06 Foo due:2015-05-32", "tags": [["due", "2015-05-32"]], "text": "Foo"}')
if __name__ == '__main__':
unittest.main()
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# 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
......@@ -14,22 +14,24 @@
# 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 unittest
from topydo.lib.Config import config
from six import u
from test.CommandTestCase import CommandTest
from test.Facilities import load_file_to_todolist
from topydo.commands.ListCommand import ListCommand
from test.CommandTest import CommandTest
from test.TestFacilities import load_file_to_todolist
from topydo.lib.Config import config
class ListCommandTest(CommandTest):
def setUp(self):
super(ListCommandTest, self).setUp()
self.todolist = load_file_to_todolist("test/data/ListCommandTest.txt")
def test_list1(self):
def test_list01(self):
command = ListCommand([""], self.todolist, self.out, self.error)
command.execute()
......@@ -37,23 +39,25 @@ class ListCommandTest(CommandTest):
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)
def test_list03(self):
command = ListCommand(["Context1"], self.todolist, self.out,
self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
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)
def test_list04(self):
command = ListCommand(["-x", "Context1"], self.todolist, self.out,
self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
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):
def test_list05(self):
command = ListCommand(["-x"], self.todolist, self.out, self.error)
command.execute()
......@@ -61,32 +65,36 @@ class ListCommandTest(CommandTest):
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)
def test_list06(self):
command = ListCommand(["Project3"], self.todolist, self.out,
self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEqual(self.output, "")
self.assertEqual(self.errors, "")
def test_list7(self):
command = ListCommand(["-s", "text", "-x", "Project1"], self.todolist, self.out, self.error)
def test_list07(self):
command = ListCommand(["-s", "text", "-x", "Project1"], self.todolist,
self.out, self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
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)
def test_list08(self):
command = ListCommand(["--", "-project1"], self.todolist, self.out,
self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
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)
def test_list09(self):
command = ListCommand(["--", "-project1", "-Drink"], self.todolist,
self.out, self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
......@@ -94,7 +102,8 @@ class ListCommandTest(CommandTest):
self.assertEqual(self.errors, "")
def test_list10(self):
command = ListCommand(["text1", "2"], self.todolist, self.out, self.error)
command = ListCommand(["text1", "2"], self.todolist, self.out,
self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
......@@ -114,7 +123,8 @@ class ListCommandTest(CommandTest):
def test_list12(self):
config("test/data/listcommand.conf")
command = ListCommand(["-x", "project"], self.todolist, self.out, self.error)
command = ListCommand(["-x", "project"], self.todolist, self.out,
self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
......@@ -122,7 +132,8 @@ class ListCommandTest(CommandTest):
self.assertEqual(self.errors, "")
def test_list13(self):
command = ListCommand(["-x", "--", "-@Context1 +Project2"], self.todolist, self.out, self.error)
command = ListCommand(["-x", "--", "-@Context1 +Project2"],
self.todolist, self.out, self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
......@@ -158,15 +169,18 @@ class ListCommandTest(CommandTest):
self.assertEqual(self.errors, "")
def test_list17(self):
command = ListCommand(["-x", "id:"], self.todolist, self.out, self.error)
command = ListCommand(["-x", "id:"], self.todolist, self.out,
self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEqual(self.output, "| 3| (C) Baz @Context1 +Project1 key:value\n")
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 = ListCommand(["-x", "date:2014-12-12"], self.todolist,
self.out, self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
......@@ -176,7 +190,8 @@ class ListCommandTest(CommandTest):
""" Force showing all tags. """
config('test/data/listcommand-tags.conf')
command = ListCommand(["-s", "text", "-x", "Project1"], self.todolist, self.out, self.error)
command = ListCommand(["-s", "text", "-x", "Project1"], self.todolist,
self.out, self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
......@@ -192,7 +207,8 @@ class ListCommandTest(CommandTest):
self.assertEqual(self.errors, "")
def test_list21(self):
command = ListCommand(["-f invalid"], self.todolist, self.out, self.error)
command = ListCommand(["-f invalid"], self.todolist, self.out,
self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
......@@ -215,7 +231,9 @@ class ListCommandTest(CommandTest):
command.execute()
self.assertEqual(self.output, "")
self.assertEqual(self.errors, command.usage() + "\n\n" + command.help() + "\n")
self.assertEqual(self.errors,
command.usage() + "\n\n" + command.help() + "\n")
class ListCommandUnicodeTest(CommandTest):
def setUp(self):
......@@ -223,8 +241,9 @@ class ListCommandUnicodeTest(CommandTest):
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)
""" Unicode filters."""
command = ListCommand([u("\u25c4")], self.todolist, self.out,
self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
......@@ -233,6 +252,7 @@ class ListCommandUnicodeTest(CommandTest):
self.assertEqual(self.output, expected)
class ListCommandJsonTest(CommandTest):
def test_json(self):
todolist = load_file_to_todolist("test/data/ListCommandTest.txt")
......@@ -243,7 +263,8 @@ class ListCommandJsonTest(CommandTest):
self.assertFalse(todolist.is_dirty())
jsontext = ""
with codecs.open('test/data/ListCommandTest.json', 'r', encoding='utf-8') as json:
with codecs.open('test/data/ListCommandTest.json', 'r',
encoding='utf-8') as json:
jsontext = json.read()
self.assertEqual(self.output, jsontext)
......@@ -258,12 +279,14 @@ class ListCommandJsonTest(CommandTest):
self.assertFalse(todolist.is_dirty())
jsontext = ""
with codecs.open('test/data/ListCommandUnicodeTest.json', 'r', encoding='utf-8') as json:
with codecs.open('test/data/ListCommandUnicodeTest.json', 'r',
encoding='utf-8') as json:
jsontext = json.read()
self.assertEqual(self.output, 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)
......@@ -271,6 +294,7 @@ def replace_ical_tags(p_text):
return result
class ListCommandIcalTest(CommandTest):
def setUp(self):
self.maxDiff = None
......@@ -278,16 +302,19 @@ class ListCommandIcalTest(CommandTest):
def test_ical(self):
todolist = load_file_to_todolist("test/data/ListCommandIcalTest.txt")
command = ListCommand(["-x", "-f", "ical"], todolist, self.out, self.error)
command = ListCommand(["-x", "-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:
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(replace_ical_tags(self.output),
replace_ical_tags(icaltext))
self.assertEqual(self.errors, "")
def test_ical_unicode(self):
......@@ -299,10 +326,12 @@ class ListCommandIcalTest(CommandTest):
self.assertTrue(todolist.is_dirty())
icaltext = ""
with codecs.open('test/data/ListCommandUnicodeTest.ics', 'r', encoding='utf-8') as ical:
with codecs.open('test/data/ListCommandUnicodeTest.ics', 'r',
encoding='utf-8') as ical:
icaltext = ical.read()
self.assertEqual(replace_ical_tags(self.output), replace_ical_tags(icaltext))
self.assertEqual(replace_ical_tags(self.output),
replace_ical_tags(icaltext))
self.assertEqual(self.errors, "")
if __name__ == '__main__':
......
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# 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
......@@ -16,9 +16,10 @@
import unittest
from test.CommandTestCase import CommandTest
from test.Facilities import load_file_to_todolist
from topydo.commands.ListContextCommand import ListContextCommand
from test.CommandTest import CommandTest
from test.TestFacilities import load_file_to_todolist
class ListContextCommandTest(CommandTest):
def test_contexts1(self):
......@@ -26,7 +27,7 @@ class ListContextCommandTest(CommandTest):
command = ListContextCommand([""], todolist, self.out, self.error)
command.execute()
self.assertEqual(self.output,"Context1\nContext2\n")
self.assertEqual(self.output, "Context1\nContext2\n")
self.assertFalse(self.errors)
def test_contexts2(self):
......@@ -34,7 +35,7 @@ class ListContextCommandTest(CommandTest):
command = ListContextCommand(["aaa"], todolist, self.out, self.error)
command.execute()
self.assertEqual(self.output,"Context1\nContext2\n")
self.assertEqual(self.output, "Context1\nContext2\n")
self.assertFalse(self.errors)
def test_help(self):
......@@ -42,7 +43,8 @@ class ListContextCommandTest(CommandTest):
command.execute()
self.assertEqual(self.output, "")
self.assertEqual(self.errors, command.usage() + "\n\n" + command.help() + "\n")
self.assertEqual(self.errors,
command.usage() + "\n\n" + command.help() + "\n")
if __name__ == '__main__':
unittest.main()
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# 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
......@@ -16,9 +16,10 @@
import unittest
from test.CommandTestCase import CommandTest
from test.Facilities import load_file_to_todolist
from topydo.commands.ListProjectCommand import ListProjectCommand
from test.CommandTest import CommandTest
from test.TestFacilities import load_file_to_todolist
class ListProjectCommandTest(CommandTest):
def test_projects1(self):
......@@ -42,7 +43,8 @@ class ListProjectCommandTest(CommandTest):
command.execute()
self.assertEqual(self.output, "")
self.assertEqual(self.errors, command.usage() + "\n\n" + command.help() + "\n")
self.assertEqual(self.errors,
command.usage() + "\n\n" + command.help() + "\n")
if __name__ == '__main__':
unittest.main()
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# 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
......@@ -14,14 +14,16 @@
# 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 datetime import date, timedelta
import unittest
from datetime import date, timedelta
from six import u
from test.CommandTestCase import CommandTest
from topydo.commands.PostponeCommand import PostponeCommand
from test.CommandTest import CommandTest
from topydo.lib.TodoList import TodoList
class PostponeCommandTest(CommandTest):
def setUp(self):
super(PostponeCommandTest, self).setUp()
......@@ -42,38 +44,45 @@ class PostponeCommandTest(CommandTest):
self.todolist = TodoList(todos)
def test_postpone1(self):
command = PostponeCommand(["1", "1w"], self.todolist, self.out, self.error)
def test_postpone01(self):
command = PostponeCommand(["1", "1w"], self.todolist, self.out,
self.error)
command.execute()
due = self.today + timedelta(7)
self.assertTrue(self.todolist.is_dirty())
self.assertEqual(self.output, "| 1| Foo due:{}\n".format(due.isoformat()))
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)
def test_postpone02(self):
command = PostponeCommand(["2", "1w"], self.todolist, self.out,
self.error)
command.execute()
due = self.today + timedelta(7)
self.assertTrue(self.todolist.is_dirty())
self.assertEqual(self.output, "| 2| Bar due:{}\n".format(due.isoformat()))
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)
def test_postpone03(self):
command = PostponeCommand(["-s", "2", "1w"], self.todolist, self.out,
self.error)
command.execute()
due = self.today + timedelta(7)
self.assertTrue(self.todolist.is_dirty())
self.assertEqual(self.output, "| 2| Bar due:{}\n".format(due.isoformat()))
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)
def test_postpone04(self):
command = PostponeCommand(["3", "1w"], self.todolist, self.out,
self.error)
command.execute()
due = self.today + timedelta(7)
......@@ -82,8 +91,9 @@ class PostponeCommandTest(CommandTest):
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)
def test_postpone05(self):
command = PostponeCommand(["-s", "3", "1w"], self.todolist, self.out,
self.error)
command.execute()
due = self.today + timedelta(7)
......@@ -94,18 +104,21 @@ class PostponeCommandTest(CommandTest):
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)
def test_postpone06(self):
command = PostponeCommand(["4", "1w"], self.todolist, self.out,
self.error)
command.execute()
due = self.today + timedelta(7)
self.assertTrue(self.todolist.is_dirty())
self.assertEqual(self.output, "| 4| Past due:{}\n".format(due.isoformat()))
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)
def test_postpone07(self):
command = PostponeCommand(["5", "1w"], self.todolist, self.out,
self.error)
command.execute()
due = self.future + timedelta(7)
......@@ -115,8 +128,9 @@ class PostponeCommandTest(CommandTest):
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)
def test_postpone08(self):
command = PostponeCommand(["-s", "5", "1w"], self.todolist, self.out,
self.error)
command.execute()
due = self.future + timedelta(7)
......@@ -127,8 +141,9 @@ class PostponeCommandTest(CommandTest):
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)
def test_postpone09(self):
command = PostponeCommand(["1", "foo"], self.todolist, self.out,
self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
......@@ -136,7 +151,8 @@ class PostponeCommandTest(CommandTest):
self.assertEqual(self.errors, "Invalid date pattern given.\n")
def test_postpone10(self):
command = PostponeCommand(["99", "foo"], self.todolist, self.out, self.error)
command = PostponeCommand(["99", "foo"], self.todolist, self.out,
self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
......@@ -144,7 +160,8 @@ class PostponeCommandTest(CommandTest):
self.assertEqual(self.errors, "Invalid todo number given.\n")
def test_postpone11(self):
command = PostponeCommand(["A", "foo"], self.todolist, self.out, self.error)
command = PostponeCommand(["A", "foo"], self.todolist, self.out,
self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
......@@ -160,17 +177,20 @@ class PostponeCommandTest(CommandTest):
self.assertEqual(self.errors, command.usage() + "\n")
def test_postpone13(self):
command = PostponeCommand(["Foo", "1w"], self.todolist, self.out, self.error)
command = PostponeCommand(["Foo", "1w"], self.todolist, self.out,
self.error)
command.execute()
due = self.today + timedelta(7)
self.assertTrue(self.todolist.is_dirty())
self.assertEqual(self.output, "| 1| Foo due:{}\n".format(due.isoformat()))
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)
command = PostponeCommand(["1", "2", "1w"], self.todolist, self.out,
self.error)
command.execute()
due = self.today + timedelta(7)
......@@ -180,7 +200,8 @@ class PostponeCommandTest(CommandTest):
self.assertEqual(self.errors, "")
def test_postpone15(self):
command = PostponeCommand(["Foo", "2", "1w"], self.todolist, self.out, self.error)
command = PostponeCommand(["Foo", "2", "1w"], self.todolist, self.out,
self.error)
command.execute()
due = self.today + timedelta(7)
......@@ -190,7 +211,8 @@ class PostponeCommandTest(CommandTest):
self.assertEqual(self.errors, "")
def test_postpone16(self):
command = PostponeCommand(["-s", "2", "3", "1w"], self.todolist, self.out, self.error)
command = PostponeCommand(["-s", "2", "3", "1w"], self.todolist,
self.out, self.error)
command.execute()
due = self.today + timedelta(7)
......@@ -202,7 +224,8 @@ class PostponeCommandTest(CommandTest):
self.assertEqual(self.errors, "")
def test_postpone17(self):
command = PostponeCommand(["1", "2", "3"], self.todolist, self.out, self.error)
command = PostponeCommand(["1", "2", "3"], self.todolist, self.out,
self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
......@@ -210,7 +233,8 @@ class PostponeCommandTest(CommandTest):
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 = PostponeCommand(["1", "99", "123", "1w"], self.todolist,
self.out, self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
......@@ -218,7 +242,8 @@ class PostponeCommandTest(CommandTest):
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 = PostponeCommand(["Zoo", "99", "123", "1w"], self.todolist,
self.out, self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
......@@ -227,15 +252,18 @@ class PostponeCommandTest(CommandTest):
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 = 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"))
self.assertEqual(self.errors,
u("Invalid todo number given: Fo\u00d3B\u0105r.\n"))
def test_expr_postpone1(self):
command = PostponeCommand(["-e", "due:tod", "2w"], self.todolist, self.out, self.error, None)
command = PostponeCommand(["-e", "due:tod", "2w"], self.todolist,
self.out, self.error, None)
command.execute()
due = self.today + timedelta(14)
......@@ -247,33 +275,38 @@ class PostponeCommandTest(CommandTest):
def test_expr_postpone2(self):
cmd_args = ["-e", "t:{}".format(self.start.isoformat()), "due:tod", "1w"]
command = PostponeCommand(cmd_args, self.todolist, self.out, self.error, None)
command = PostponeCommand(cmd_args, self.todolist, self.out,
self.error, None)
command.execute()
due = self.today + timedelta(7)
result = "| 3| Baz due:{} t:{}\n".format(due.isoformat(), self.start.isoformat())
result = "| 3| Baz due:{} t:{}\n".format(due.isoformat(),
self.start.isoformat())
self.assertTrue(self.todolist.is_dirty())
self.assertEqual(self.output, result)
self.assertEqual(self.errors, "")
def test_expr_postpone3(self):
command = PostponeCommand(["-e", "@test", "due:tod", "+project", "C"], self.todolist, self.out, self.error, None)
command = PostponeCommand(["-e", "@test", "due:tod", "+project", "C"],
self.todolist, self.out, self.error, None)
command.execute()
self.assertFalse(self.todolist.is_dirty())
def test_expr_postpone4(self):
""" Don't postpone unrelevant todo items. """
command = PostponeCommand(["-e", "FutureStart", "1w"], self.todolist, self.out, self.error, None)
command = PostponeCommand(["-e", "FutureStart", "1w"], self.todolist,
self.out, self.error, None)
command.execute()
self.assertFalse(self.todolist.is_dirty())
def test_expr_postpone5(self):
""" Force postponing unrelevant items with additional -x flag. """
command = PostponeCommand(["-xe", "FutureStart", "1w"], self.todolist, self.out, self.error, None)
command = PostponeCommand(["-xe", "FutureStart", "1w"], self.todolist,
self.out, self.error, None)
command.execute()
due = self.today + timedelta(7)
......@@ -284,12 +317,13 @@ class PostponeCommandTest(CommandTest):
self.assertEqual(self.errors, "")
def test_help(self):
command = PostponeCommand(["help"], self.todolist, self.out, self.error)
command = PostponeCommand(["help"], self.todolist, self.out,
self.error)
command.execute()
self.assertEqual(self.output, "")
self.assertEqual(self.errors, command.usage() + "\n\n" + command.help() + "\n")
self.assertEqual(self.errors,
command.usage() + "\n\n" + command.help() + "\n")
if __name__ == '__main__':
unittest.main()
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# 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
......@@ -15,12 +15,14 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import unittest
from six import u
from test.CommandTestCase import CommandTest
from topydo.commands.PriorityCommand import PriorityCommand
from test.CommandTest import CommandTest
from topydo.lib.TodoList import TodoList
class PriorityCommandTest(CommandTest):
def setUp(self):
super(PriorityCommandTest, self).setUp()
......@@ -35,15 +37,18 @@ class PriorityCommandTest(CommandTest):
self.todolist = TodoList(todos)
def test_set_prio1(self):
command = PriorityCommand(["1", "B"], self.todolist, self.out, self.error)
command = PriorityCommand(["1", "B"], self.todolist, self.out,
self.error)
command.execute()
self.assertTrue(self.todolist.is_dirty())
self.assertEqual(self.output, "Priority changed from A to B\n| 1| (B) Foo\n")
self.assertEqual(self.output,
"Priority changed from A to B\n| 1| (B) Foo\n")
self.assertEqual(self.errors, "")
def test_set_prio2(self):
command = PriorityCommand(["2", "Z"], self.todolist, self.out, self.error)
command = PriorityCommand(["2", "Z"], self.todolist, self.out,
self.error)
command.execute()
self.assertTrue(self.todolist.is_dirty())
......@@ -51,15 +56,18 @@ class PriorityCommandTest(CommandTest):
self.assertEqual(self.errors, "")
def test_set_prio3(self):
command = PriorityCommand(["Foo", "B"], self.todolist, self.out, self.error)
command = PriorityCommand(["Foo", "B"], self.todolist, self.out,
self.error)
command.execute()
self.assertTrue(self.todolist.is_dirty())
self.assertEqual(self.output, "Priority changed from A to B\n| 1| (B) Foo\n")
self.assertEqual(self.output,
"Priority changed from A to B\n| 1| (B) Foo\n")
self.assertEqual(self.errors, "")
def test_set_prio4(self):
command = PriorityCommand(["1", "A"], self.todolist, self.out, self.error)
command = PriorityCommand(["1", "A"], self.todolist, self.out,
self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
......@@ -67,7 +75,8 @@ class PriorityCommandTest(CommandTest):
self.assertEqual(self.errors, "")
def test_set_prio5(self):
command = PriorityCommand(["Foo", "2", "C"], self.todolist, self.out, self.error)
command = PriorityCommand(["Foo", "2", "C"], self.todolist, self.out,
self.error)
command.execute()
self.assertTrue(self.todolist.is_dirty())
......@@ -76,7 +85,8 @@ class PriorityCommandTest(CommandTest):
def test_set_prio6(self):
""" Allow priority to be set including parentheses. """
command = PriorityCommand(["Foo", "2", "(C)"], self.todolist, self.out, self.error)
command = PriorityCommand(["Foo", "2", "(C)"], self.todolist, self.out,
self.error)
command.execute()
self.assertTrue(self.todolist.is_dirty())
......@@ -84,10 +94,10 @@ class PriorityCommandTest(CommandTest):
self.assertEqual(self.errors, "")
def test_expr_prio1(self):
command = PriorityCommand(["-e", "@test", "C"], self.todolist, self.out, self.error, None)
command = PriorityCommand(["-e", "@test", "C"], self.todolist,
self.out, self.error, None)
command.execute()
result = "Priority changed from B to C\n| 3| (C) a @test with due:2015-06-03\nPriority set to C.\n| 4| (C) a @test with +project p:1\n"
self.assertTrue(self.todolist.is_dirty())
......@@ -95,7 +105,8 @@ class PriorityCommandTest(CommandTest):
self.assertEqual(self.errors, "")
def test_expr_prio2(self):
command = PriorityCommand(["-e", "@test", "due:2015-06-03", "C"], self.todolist, self.out, self.error, None)
command = PriorityCommand(["-e", "@test", "due:2015-06-03", "C"],
self.todolist, self.out, self.error, None)
command.execute()
result = "Priority changed from B to C\n| 3| (C) a @test with due:2015-06-03\n"
......@@ -105,29 +116,35 @@ class PriorityCommandTest(CommandTest):
self.assertEqual(self.errors, "")
def test_expr_prio3(self):
command = PriorityCommand(["-e", "@test", "due:2015-06-03", "+project", "C"], self.todolist, self.out, self.error, None)
command = PriorityCommand(["-e", "@test", "due:2015-06-03", "+project",
"C"], self.todolist, self.out, self.error,
None)
command.execute()
self.assertFalse(self.todolist.is_dirty())
def test_expr_prio4(self):
""" Don't prioritize unrelevant todo items. """
command = PriorityCommand(["-e", "Baz", "C"], self.todolist, self.out, self.error, None)
command = PriorityCommand(["-e", "Baz", "C"], self.todolist, self.out,
self.error, None)
command.execute()
self.assertFalse(self.todolist.is_dirty())
def test_expr_prio5(self):
""" Force prioritizing unrelevant items with additional -x flag. """
command = PriorityCommand(["-xe", "Baz", "D"], self.todolist, self.out, self.error, None)
command = PriorityCommand(["-xe", "Baz", "D"], self.todolist, self.out,
self.error, None)
command.execute()
self.assertTrue(self.todolist.is_dirty())
self.assertEqual(self.output, "Priority set to D.\n| 5| (D) Baz id:1\n")
self.assertEqual(self.output,
"Priority set to D.\n| 5| (D) Baz id:1\n")
self.assertEqual(self.errors, "")
def test_invalid1(self):
command = PriorityCommand(["99", "A"], self.todolist, self.out, self.error)
command = PriorityCommand(["99", "A"], self.todolist, self.out,
self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
......@@ -135,7 +152,8 @@ class PriorityCommandTest(CommandTest):
self.assertEqual(self.errors, "Invalid todo number given.\n")
def test_invalid2(self):
command = PriorityCommand(["1", "99", "A"], self.todolist, self.out, self.error)
command = PriorityCommand(["1", "99", "A"], self.todolist, self.out,
self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
......@@ -143,7 +161,8 @@ class PriorityCommandTest(CommandTest):
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)
command = PriorityCommand(["98", "99", "A"], self.todolist, self.out,
self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
......@@ -151,7 +170,8 @@ class PriorityCommandTest(CommandTest):
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)
command = PriorityCommand(["1", "ZZ"], self.todolist, self.out,
self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
......@@ -175,20 +195,25 @@ class PriorityCommandTest(CommandTest):
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)
"""
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"))
self.assertEqual(self.errors,
u("Invalid todo number given: Fo\u00d3B\u0105r.\n"))
def test_invalid8(self):
"""
Test that there's only one capital surrounded by non-word
characters that makes up a priority.
"""
command = PriorityCommand(["2", "(Aa)"], self.todolist, self.out, self.error)
command = PriorityCommand(["2", "(Aa)"], self.todolist, self.out,
self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
......@@ -200,12 +225,14 @@ class PriorityCommandTest(CommandTest):
Test that there's only one capital surrounded by non-word
characters that makes up a priority.
"""
command = PriorityCommand(["2", "Aa"], self.todolist, self.out, self.error)
command = PriorityCommand(["2", "Aa"], self.todolist, self.out,
self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEqual(self.output, "")
self.assertEqual(self.errors, "Invalid priority given.\n")
def test_empty(self):
command = PriorityCommand([], self.todolist, self.out, self.error)
command.execute()
......@@ -215,11 +242,13 @@ class PriorityCommandTest(CommandTest):
self.assertEqual(self.errors, command.usage() + "\n")
def test_help(self):
command = PriorityCommand(["help"], self.todolist, self.out, self.error)
command = PriorityCommand(["help"], self.todolist, self.out,
self.error)
command.execute()
self.assertEqual(self.output, "")
self.assertEqual(self.errors, command.usage() + "\n\n" + command.help() + "\n")
self.assertEqual(self.errors,
command.usage() + "\n\n" + command.help() + "\n")
if __name__ == '__main__':
unittest.main()
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# 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
......@@ -14,13 +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/>.
from datetime import date, timedelta
import unittest
from datetime import date, timedelta
from test.TopydoTestCase import TopydoTest
from topydo.lib.Config import config
from topydo.lib.Recurrence import advance_recurring_todo, NoRecurrenceException
from topydo.lib.Recurrence import NoRecurrenceException, advance_recurring_todo
from topydo.lib.Todo import Todo
from test.TopydoTest import TopydoTest
class RecurrenceTest(TopydoTest):
def setUp(self):
......@@ -164,12 +165,14 @@ class RecurrenceTest(TopydoTest):
def test_no_recurrence(self):
self.todo.remove_tag('rec')
self.assertRaises(NoRecurrenceException, advance_recurring_todo, self.todo)
self.assertRaises(NoRecurrenceException, advance_recurring_todo,
self.todo)
def test_invalid_recurrence(self):
""" Throw exception when 'rec' tag has an invalid value. """
self.todo.set_tag('rec', '1')
self.assertRaises(NoRecurrenceException, advance_recurring_todo, self.todo)
self.assertRaises(NoRecurrenceException, advance_recurring_todo,
self.todo)
if __name__ == '__main__':
unittest.main()
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# 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
......@@ -14,11 +14,12 @@
# 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 datetime import date, timedelta
import unittest
from datetime import date, timedelta
from test.TopydoTestCase import TopydoTest
from topydo.lib.RelativeDate import relative_date_to_date
from test.TopydoTest import TopydoTest
class RelativeDateTester(TopydoTest):
def setUp(self):
......@@ -103,8 +104,7 @@ class RelativeDateTester(TopydoTest):
self.assertEqual(result, self.today)
def test_today3(self):
result = relative_date_to_date('today', \
date.today() + timedelta(1))
result = relative_date_to_date('today', date.today() + timedelta(1))
self.assertEqual(result, self.today)
def test_tomorrow1(self):
......
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# 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
......@@ -16,10 +16,11 @@
import unittest
from topydo.lib.Config import config
from test.CommandTestCase import CommandTest
from test.Facilities import load_file_to_todolist
from topydo.commands.SortCommand import SortCommand
from test.CommandTest import CommandTest
from test.TestFacilities import load_file_to_todolist
from topydo.lib.Config import config
class SortCommandTest(CommandTest):
def setUp(self):
......@@ -27,17 +28,19 @@ class SortCommandTest(CommandTest):
self.todolist = load_file_to_todolist("test/data/SorterTest1.txt")
def test_sort1(self):
""" Alphabetically sorted """
""" Alphabetically sorted. """
command = SortCommand(["text"], self.todolist, self.out, self.error)
command.execute()
self.assertEqual(self.todolist.print_todos(), "First\n(A) Foo\n2014-06-14 Last")
self.assertEqual(self.todolist.print_todos(),
"First\n(A) Foo\n2014-06-14 Last")
def test_sort2(self):
command = SortCommand([], self.todolist, self.out, self.error)
command.execute()
self.assertEqual(self.todolist.print_todos(), "(A) Foo\n2014-06-14 Last\nFirst")
self.assertEqual(self.todolist.print_todos(),
"(A) Foo\n2014-06-14 Last\nFirst")
def test_sort3(self):
""" Check that order does not influence the UID of a todo. """
......@@ -55,7 +58,8 @@ class SortCommandTest(CommandTest):
command.execute()
self.assertEqual(self.output, "")
self.assertEqual(self.errors, command.usage() + "\n\n" + command.help() + "\n")
self.assertEqual(self.errors,
command.usage() + "\n\n" + command.help() + "\n")
if __name__ == '__main__':
unittest.main()
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# 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
......@@ -16,11 +16,12 @@
import unittest
from test.Facilities import (load_file, load_file_to_todolist, print_view,
todolist_to_string)
from test.TopydoTestCase import TopydoTest
from topydo.lib.Config import config
from topydo.lib.Sorter import Sorter
from test.TestFacilities import load_file, todolist_to_string, load_file_to_todolist, print_view
from test.TopydoTest import TopydoTest
class SorterTest(TopydoTest):
def sort_file(self, p_filename, p_filename_ref, p_sorter):
......@@ -36,80 +37,93 @@ class SorterTest(TopydoTest):
self.assertEqual(todos_sorted, todos_ref)
self.assertEqual(todolist_to_string(todos), text_before)
def test_sort1(self):
""" Alphabetically sorted """
def test_sort01(self):
""" Alphabetically sorted. """
sorter = Sorter('text')
self.sort_file('test/data/SorterTest1.txt', 'test/data/SorterTest1-result.txt', sorter)
self.sort_file('test/data/SorterTest1.txt',
'test/data/SorterTest1-result.txt', sorter)
def test_sort2a(self):
def test_sort02a(self):
"""
Ascendingly sorted by priority. Also checks stableness of the sort.
"""
sorter = Sorter('prio')
self.sort_file('test/data/SorterTest2.txt', 'test/data/SorterTest2-result.txt', sorter)
self.sort_file('test/data/SorterTest2.txt',
'test/data/SorterTest2-result.txt', sorter)
def test_sort2b(self):
def test_sort02b(self):
"""
Ascendingly sorted by priority. Also checks stableness of the sort.
"""
sorter = Sorter('asc:prio')
self.sort_file('test/data/SorterTest2.txt', 'test/data/SorterTest2-result.txt', sorter)
self.sort_file('test/data/SorterTest2.txt',
'test/data/SorterTest2-result.txt', sorter)
def test_sort3(self):
def test_sort03(self):
"""
Descendingly sorted by priority. Also checks stableness of the
sort.
"""
sorter = Sorter('desc:prio')
self.sort_file('test/data/SorterTest3.txt', 'test/data/SorterTest3-result.txt', sorter)
self.sort_file('test/data/SorterTest3.txt',
'test/data/SorterTest3-result.txt', sorter)
def test_sort4(self):
""" Ascendingly sorted by due date """
def test_sort04(self):
""" Ascendingly sorted by due date. """
sorter = Sorter(config().tag_due())
self.sort_file('test/data/SorterTest4.txt', 'test/data/SorterTest4-result.txt', sorter)
self.sort_file('test/data/SorterTest4.txt',
'test/data/SorterTest4-result.txt', sorter)
def test_sort5(self):
""" Descendingly sorted by due date """
def test_sort05(self):
""" Descendingly sorted by due date. """
sorter = Sorter('desc:due')
self.sort_file('test/data/SorterTest5.txt', 'test/data/SorterTest5-result.txt', sorter)
self.sort_file('test/data/SorterTest5.txt',
'test/data/SorterTest5-result.txt', sorter)
def test_sort6(self):
""" Ascendingly sorted by creation date """
def test_sort06(self):
""" Ascendingly sorted by creation date. """
sorter = Sorter('creation')
self.sort_file('test/data/SorterTest6.txt', 'test/data/SorterTest6-result.txt', sorter)
self.sort_file('test/data/SorterTest6.txt',
'test/data/SorterTest6-result.txt', sorter)
def test_sort7(self):
def test_sort07(self):
""" Ascendingly sorted by completion date. """
sorter = Sorter('completion')
self.sort_file('test/data/SorterTest7.txt', 'test/data/SorterTest7-result.txt', sorter)
self.sort_file('test/data/SorterTest7.txt',
'test/data/SorterTest7-result.txt', sorter)
def test_sort8(self):
""" Descendingly sorted by importance """
def test_sort08(self):
""" Descendingly sorted by importance. """
sorter = Sorter('desc:importance')
self.sort_file('test/data/SorterTest8.txt', 'test/data/SorterTest8-result.txt', sorter)
self.sort_file('test/data/SorterTest8.txt',
'test/data/SorterTest8-result.txt', sorter)
def test_sort9(self):
def test_sort09(self):
"""
Sort on multiple levels: first descending importance, then
ascending priority.
"""
sorter = Sorter('desc:importance,priority')
self.sort_file('test/data/SorterTest9.txt', 'test/data/SorterTest9-result.txt', sorter)
self.sort_file('test/data/SorterTest9.txt',
'test/data/SorterTest9-result.txt', sorter)
def test_sort10(self):
""" Deal with garbage input. """
sorter = Sorter('')
self.sort_file('test/data/SorterTest9.txt', 'test/data/SorterTest9.txt', sorter)
self.sort_file('test/data/SorterTest9.txt',
'test/data/SorterTest9.txt', sorter)
def test_sort11(self):
""" Deal with garbage input. """
sorter = Sorter('fnord')
self.sort_file('test/data/SorterTest9.txt', 'test/data/SorterTest9.txt', sorter)
self.sort_file('test/data/SorterTest9.txt',
'test/data/SorterTest9.txt', sorter)
def test_sort12(self):
""" Deal with garbage input. """
sorter = Sorter('desc:importance,,priority')
self.sort_file('test/data/SorterTest9.txt', 'test/data/SorterTest9-result.txt', sorter)
self.sort_file('test/data/SorterTest9.txt',
'test/data/SorterTest9-result.txt', sorter)
def test_sort13(self):
"""
......@@ -119,7 +133,8 @@ class SorterTest(TopydoTest):
dependencies the average importance should be equal.
"""
sorter = Sorter('desc:importance-avg')
self.sort_file('test/data/SorterTest9.txt', 'test/data/SorterTest9-result.txt', sorter)
self.sort_file('test/data/SorterTest9.txt',
'test/data/SorterTest9-result.txt', sorter)
def test_sort14(self):
sorter = Sorter('desc:importance-average')
......
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# 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
......@@ -16,10 +16,11 @@
import unittest
from test.CommandTestCase import CommandTest
from topydo.commands.TagCommand import TagCommand
from test.CommandTest import CommandTest
from topydo.lib.TodoList import TodoList
class TagCommandTest(CommandTest):
def setUp(self):
super(TagCommandTest, self).setUp()
......@@ -33,7 +34,8 @@ class TagCommandTest(CommandTest):
self.todolist = TodoList(todos)
def test_add_tag1(self):
command = TagCommand(["1", "due", "2014-10-22"], self.todolist, self.out, self.error)
command = TagCommand(["1", "due", "2014-10-22"], self.todolist,
self.out, self.error)
command.execute()
self.assertEqual(self.todolist.todo(1).source(), "Foo due:2014-10-22")
......@@ -42,7 +44,8 @@ class TagCommandTest(CommandTest):
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 = TagCommand(["Foo", "due", "2014-10-22"], self.todolist,
self.out, self.error)
command.execute()
self.assertEqual(self.todolist.todo(1).source(), "Foo due:2014-10-22")
......@@ -51,64 +54,74 @@ class TagCommandTest(CommandTest):
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 = TagCommand(["-a", "2", "due", "2014-10-19"], self.todolist,
self.out, self.error)
command.execute()
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.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):
command = TagCommand(["Foox", "due", "2014-10-22"], self.todolist, self.out, self.error)
command = TagCommand(["Foox", "due", "2014-10-22"], self.todolist,
self.out, self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertFalse(self.output)
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)
def test_set_tag04(self):
command = TagCommand(["3", "due", "2014-10-20"], self.todolist,
self.out, self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
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")
def test_set_tag05(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.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")
def test_set_tag06(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.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")
def test_set_tag07(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.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: "")
def test_set_tag08(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.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")
def test_set_tag09(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())
......@@ -116,14 +129,16 @@ class TagCommandTest(CommandTest):
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 = 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.assertEqual(self.output, "| 4| Fnord due:2014-10-20 due:2014-10-20\n")
self.assertEqual(self.output,
"| 4| Fnord due:2014-10-20 due:2014-10-20\n")
self.assertEqual(self.errors, "")
def test_rm_tag1(self):
def test_rm_tag01(self):
command = TagCommand(["1", "due"], self.todolist, self.out, self.error)
command.execute()
......@@ -131,7 +146,7 @@ class TagCommandTest(CommandTest):
self.assertEqual(self.output, "| 1| Foo\n")
self.assertEqual(self.errors, "")
def test_rm_tag2(self):
def test_rm_tag02(self):
command = TagCommand(["2", "due"], self.todolist, self.out, self.error)
command.execute()
......@@ -139,39 +154,44 @@ class TagCommandTest(CommandTest):
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")
def test_rm_tag03(self):
command = TagCommand(["4", "due"], self.todolist, self.out,
self.error, lambda t: "all")
command.execute()
self.assertTrue(self.todolist.is_dirty())
self.assertEqual(self.output, " 1. 2014-10-20\n 2. 2014-10-22\n| 4| Fnord\n")
self.assertEqual(self.output,
" 1. 2014-10-20\n 2. 2014-10-22\n| 4| Fnord\n")
self.assertEqual(self.errors, "")
def test_rm_tag4(self):
command = TagCommand(["4", "due"], self.todolist, self.out, self.error, lambda t: "1")
def test_rm_tag04(self):
command = TagCommand(["4", "due"], self.todolist, self.out, self.error,
lambda t: "1")
command.execute()
self.assertTrue(self.todolist.is_dirty())
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")
def test_rm_tag06(self):
command = TagCommand(["4", "due"], self.todolist, self.out, self.error,
lambda t: "99")
command.execute()
self.assertFalse(self.todolist.is_dirty())
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")
def test_rm_tag07(self):
command = TagCommand(["4", "due"], self.todolist, self.out, self.error,
lambda t: "A")
command.execute()
self.assertFalse(self.todolist.is_dirty())
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):
def test_rm_tag08(self):
command = TagCommand(["5", "due"], self.todolist, self.out, self.error)
command.execute()
......@@ -179,7 +199,7 @@ class TagCommandTest(CommandTest):
self.assertEqual(self.output, "")
self.assertEqual(self.errors, "Invalid todo number.\n")
def test_rm_tag9(self):
def test_rm_tag09(self):
command = TagCommand(["A", "due"], self.todolist, self.out, self.error)
command.execute()
......@@ -188,7 +208,8 @@ class TagCommandTest(CommandTest):
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 = TagCommand(["-f", "4", "due"], self.todolist, self.out,
self.error, lambda t: "A")
command.execute()
self.assertTrue(self.todolist.is_dirty())
......@@ -208,7 +229,8 @@ class TagCommandTest(CommandTest):
command.execute()
self.assertEqual(self.output, "")
self.assertEqual(self.errors, command.usage() + "\n\n" + command.help() + "\n")
self.assertEqual(self.errors,
command.usage() + "\n\n" + command.help() + "\n")
if __name__ == '__main__':
unittest.main()
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# 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
......@@ -14,20 +14,23 @@
# 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 datetime import date, timedelta
import unittest
from datetime import date, timedelta
from test.TopydoTestCase import TopydoTest
from topydo.lib.Todo import Todo
from test.TopydoTest import TopydoTest
def today_date():
today = date.today()
return today.isoformat()
def tomorrow_date():
tomorrow = date.today() + timedelta(days=1)
return tomorrow.isoformat()
class TodoTest(TopydoTest):
def test_due_date1(self):
todo = Todo("(C) Foo due:2014-06-09")
......@@ -37,7 +40,7 @@ class TodoTest(TopydoTest):
def test_false_date(self):
todo = Todo("(C) Foo due:2014-04-31")
self.assertEqual( todo.due_date(), None )
self.assertEqual(todo.due_date(), None)
def test_active1(self):
todo = Todo("(C) Foo due:2014-01-01")
......
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# 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
......@@ -16,12 +16,13 @@
""" Tests for the TodoBase class. """
from datetime import date, timedelta
import re
import unittest
from datetime import date, timedelta
from test.TopydoTestCase import TopydoTest
from topydo.lib.TodoBase import TodoBase
from test.TopydoTest import TopydoTest
class TodoBaseTester(TopydoTest):
def test_parse_tag(self):
......@@ -85,7 +86,7 @@ class TodoBaseTester(TopydoTest):
def test_set_tag_double_value(self):
todo = TodoBase("(C) Foo foo:bar baz:bar")
todo.set_tag('foo', 'blah');
todo.set_tag('foo', 'blah')
self.assertTrue(todo.has_tag('foo'))
self.assertTrue(todo.tag_value('foo'), 'blah')
......@@ -97,7 +98,8 @@ class TodoBaseTester(TopydoTest):
todo.set_tag('foo', 'blah')
self.assertTrue(todo.has_tag('foo', 'blah'))
self.assertTrue(todo.has_tag('foo', 'bar') or todo.has_tag('foo', 'baz'))
self.assertTrue(todo.has_tag('foo', 'bar') or
todo.has_tag('foo', 'baz'))
def test_set_tag_empty_value(self):
todo = TodoBase("(C) Foo foo:bar foo:baz")
......@@ -108,14 +110,12 @@ class TodoBaseTester(TopydoTest):
def test_tag_empty_value(self):
""" Tag should not be recorded when there is no value. """
todo = TodoBase("(C) Foo foo:")
self.assertFalse(todo.has_tag('foo'))
def test_tag_empty_key(self):
""" Tag should not be recorded when there is no key. """
todo = TodoBase("(C) Foo :bar")
self.assertFalse(todo.has_tag(''))
......@@ -259,8 +259,8 @@ class TodoBaseTester(TopydoTest):
today_str = today.isoformat()
self.assertEqual(todo.fields['completionDate'], today)
self.assertTrue(re.match('^x ' + today_str + ' 2014-06-12 Foo', \
todo.src))
self.assertTrue(re.match('^x ' + today_str + ' 2014-06-12 Foo',
todo.src))
def test_set_complete3(self):
todo = TodoBase("Foo")
......@@ -280,7 +280,8 @@ class TodoBaseTester(TopydoTest):
today_str = today.isoformat()
self.assertEqual(todo.fields['completionDate'], today)
self.assertTrue(re.match('^x ' + today_str + ' 2014-06-12 Foo', todo.src))
self.assertTrue(re.match('^x ' + today_str + ' 2014-06-12 Foo',
todo.src))
def test_set_complete5(self):
todo = TodoBase("x 2014-06-13 Foo")
......@@ -302,7 +303,7 @@ class TodoBaseTester(TopydoTest):
todo.set_source_text(new_text)
self.assertEqual(todo.src, new_text)
self.assertEqual(todo.priority(),'C')
self.assertEqual(todo.priority(), 'C')
def test_set_creation_date1(self):
todo = TodoBase("Foo")
......
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# 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
......@@ -14,11 +14,13 @@
# 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
from test.TopydoTest import TopydoTest
from six import u
from test.Facilities import load_file
from test.TopydoTestCase import TopydoTest
class TodoFileTest(TopydoTest):
def test_empty_file(self):
......@@ -29,7 +31,8 @@ class TodoFileTest(TopydoTest):
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'))
self.assertEqual(todofile[0].source(),
u('(C) \u25ba UTF-8 test \u25c4'))
if __name__ == '__main__':
unittest.main()
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# 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
......@@ -19,32 +19,32 @@
import re
import unittest
from test.TopydoTestCase import TopydoTest
from topydo.lib.Config import config
from topydo.lib.Todo import Todo
from topydo.lib.TodoFile import TodoFile
from topydo.lib.TodoListBase import InvalidTodoException
from topydo.lib.TodoList import TodoList
from topydo.lib.TodoListBase import TodoListBase
from test.TopydoTest import TopydoTest
from topydo.lib.TodoListBase import InvalidTodoException, TodoListBase
class TodoListTester(TopydoTest):
def setUp(self):
super(TodoListTester, self).setUp()
self.todofile = TodoFile('test/data/TodoListTest.txt')
lines = [line for line in self.todofile.read() \
if re.search(r'\S', line)]
lines = [line for line in self.todofile.read()
if re.search(r'\S', line)]
self.text = ''.join(lines)
self.todolist = TodoListBase(lines)
def test_contexts(self):
self.assertEqual(set(['Context1', 'Context2']), \
self.todolist.contexts())
self.assertEqual(set(['Context1', 'Context2']),
self.todolist.contexts())
self.assertFalse(self.todolist.is_dirty())
def test_projects(self):
self.assertEqual(set(['Project1', 'Project2']), \
self.todolist.projects())
self.assertEqual(set(['Project1', 'Project2']),
self.todolist.projects())
self.assertFalse(self.todolist.is_dirty())
def test_add1(self):
......@@ -53,10 +53,10 @@ class TodoListTester(TopydoTest):
todo = self.todolist.add(text)
self.assertEqual(self.todolist.todo(count+1).source(), text)
self.assertEqual(set(['Project1', 'Project2', 'Project3']), \
self.todolist.projects())
self.assertEqual(set(['Context1', 'Context2', 'Context3']), \
self.todolist.contexts())
self.assertEqual(set(['Project1', 'Project2', 'Project3']),
self.todolist.projects())
self.assertEqual(set(['Context1', 'Context2', 'Context3']),
self.todolist.contexts())
self.assertEqual(self.todolist.number(todo), 6)
self.assertTrue(self.todolist.is_dirty())
......@@ -70,7 +70,8 @@ class TodoListTester(TopydoTest):
self.todolist.add('\n(C) New task')
self.assertEqual(self.todolist.count(), count + 1)
self.assertEqual(self.todolist.todo(count + 1).source(), '(C) New task')
self.assertEqual(self.todolist.todo(count + 1).source(),
'(C) New task')
self.assertEqual(self.todolist.todo(count + 1).priority(), 'C')
def test_add3b(self):
......@@ -78,7 +79,8 @@ class TodoListTester(TopydoTest):
self.todolist.add('(C) New task\n')
self.assertEqual(self.todolist.count(), count + 1)
self.assertEqual(self.todolist.todo(count + 1).source(), '(C) New task')
self.assertEqual(self.todolist.todo(count + 1).source(),
'(C) New task')
self.assertEqual(self.todolist.todo(count + 1).priority(), 'C')
def test_add4(self):
......@@ -96,8 +98,8 @@ class TodoListTester(TopydoTest):
todo = self.todolist.todo(2)
self.todolist.delete(todo)
self.assertEqual(self.todolist.todo(2).source(), \
"(C) Baz @Context1 +Project1 key:value")
self.assertEqual(self.todolist.todo(2).source(),
"(C) Baz @Context1 +Project1 key:value")
self.assertEqual(self.todolist.count(), count - 1)
self.assertTrue(self.todolist.is_dirty())
self.assertRaises(InvalidTodoException, self.todolist.number, todo)
......@@ -116,10 +118,10 @@ class TodoListTester(TopydoTest):
todo = self.todolist.todo(3)
self.todolist.append(todo, "@Context3")
self.assertEqual(todo.source(), \
"(C) Baz @Context1 +Project1 key:value @Context3")
self.assertEqual(set(['Context1', 'Context2', 'Context3']), \
self.todolist.contexts())
self.assertEqual(todo.source(),
"(C) Baz @Context1 +Project1 key:value @Context3")
self.assertEqual(set(['Context1', 'Context2', 'Context3']),
self.todolist.contexts())
self.assertTrue(self.todolist.is_dirty())
def test_append2(self):
......@@ -128,8 +130,8 @@ class TodoListTester(TopydoTest):
self.todolist.append(todo, "foo:bar")
self.assertEqual(todo.text(), text)
self.assertEqual(todo.source(), \
"(C) Baz @Context1 +Project1 key:value foo:bar")
self.assertEqual(todo.source(),
"(C) Baz @Context1 +Project1 key:value foo:bar")
def test_append3(self):
todo = self.todolist.todo(3)
......@@ -141,7 +143,8 @@ class TodoListTester(TopydoTest):
def test_todo(self):
count = self.todolist.count()
self.assertRaises(InvalidTodoException, self.todolist.todo, count + 100)
self.assertRaises(InvalidTodoException, self.todolist.todo,
count + 100)
self.assertFalse(self.todolist.is_dirty())
def test_count(self):
......@@ -197,7 +200,8 @@ class TodoListTester(TopydoTest):
def test_uid1(self):
config("test/data/todolist-uid.conf")
self.assertEqual(self.todolist.todo('t5c').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. """
......@@ -205,25 +209,25 @@ class TodoListTester(TopydoTest):
todo = self.todolist.todo('t5c')
self.todolist.set_priority(todo, 'B')
self.assertEqual(self.todolist.todo('t5c').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):
"""
Must be able to handle integers when text identifiers are enabled.
"""
config("test/data/todolist-uid.conf")
self.assertRaises(InvalidTodoException, self.todolist.todo, 1)
def test_new_uid(self):
""" Make sure that item has new text ID after append. """
config("test/data/todolist-uid.conf")
todo = self.todolist.todo('t5c')
self.todolist.append(todo, "A")
self.assertNotEqual(self.todolist.number(todo), 't5c')
class TodoListDependencyTester(TopydoTest):
def setUp(self):
super(TodoListDependencyTester, self).setUp()
......@@ -241,24 +245,24 @@ class TodoListDependencyTester(TopydoTest):
def test_check_dep(self):
children = self.todolist.children(self.todolist.todo(1))
self.assertEqual(sorted([todo.source() for todo in children]), \
sorted(['Bar p:1', 'Baz p:1 id:2', 'Buzz p:2']))
self.assertEqual(sorted([todo.source() for todo in children]),
sorted(['Bar p:1', 'Baz p:1 id:2', 'Buzz p:2']))
children = self.todolist.children(self.todolist.todo(1), True)
self.assertEqual(sorted([todo.source() for todo in children]), \
sorted(['Bar p:1', 'Baz p:1 id:2']))
self.assertEqual(sorted([todo.source() for todo in children]),
sorted(['Bar p:1', 'Baz p:1 id:2']))
children = self.todolist.children(self.todolist.todo(3))
self.assertEqual(sorted([todo.source() for todo in children]), \
['Buzz p:2'])
self.assertEqual(sorted([todo.source() for todo in children]),
['Buzz p:2'])
parents = self.todolist.parents(self.todolist.todo(4))
self.assertEqual(sorted([todo.source() for todo in parents]), \
sorted(['Foo id:1', 'Baz p:1 id:2']))
self.assertEqual(sorted([todo.source() for todo in parents]),
sorted(['Foo id:1', 'Baz p:1 id:2']))
parents = self.todolist.parents(self.todolist.todo(4), True)
self.assertEqual(sorted([todo.source() for todo in parents]), \
['Baz p:1 id:2'])
self.assertEqual(sorted([todo.source() for todo in parents]),
['Baz p:1 id:2'])
self.assertEqual(self.todolist.children(self.todolist.todo(2)), [])
self.assertEqual(self.todolist.parents(self.todolist.todo(1)), [])
......@@ -276,7 +280,6 @@ class TodoListDependencyTester(TopydoTest):
Make sure that previous add_dependency invocation stored the
edge_id properly.
"""
todo1 = self.todolist.todo(1)
todo4 = self.todolist.todo(4)
todo5 = self.todolist.todo(5)
......@@ -291,7 +294,6 @@ class TodoListDependencyTester(TopydoTest):
"""
Test that projects are not added double.
"""
todo6 = self.todolist.todo(6)
todo7 = self.todolist.todo(7)
projects = todo7.projects().copy()
......@@ -361,6 +363,7 @@ class TodoListDependencyTester(TopydoTest):
self.assertTrue(todolist.todo_by_dep_id('1'))
self.assertFalse(todolist.todo_by_dep_id('2'))
class TodoListCleanDependencyTester(TopydoTest):
def setUp(self):
super(TodoListCleanDependencyTester, self).setUp()
......
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# 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
......@@ -16,12 +16,13 @@
import unittest
from test.Facilities import load_file, print_view, todolist_to_string
from test.TopydoTestCase import TopydoTest
from topydo.lib import Filter
from topydo.lib.Sorter import Sorter
from test.TestFacilities import load_file, todolist_to_string, print_view
from topydo.lib.TodoFile import TodoFile
from topydo.lib.TodoList import TodoList
from test.TopydoTest import TopydoTest
class ViewTest(TopydoTest):
def test_view(self):
......@@ -38,4 +39,3 @@ class ViewTest(TopydoTest):
if __name__ == '__main__':
unittest.main()
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# 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
......@@ -18,10 +18,10 @@ import unittest
from topydo.lib.Config import config
class TopydoTest(unittest.TestCase):
def tearDown(self):
"""
Make sure that every test case leaves a clean configuration.
"""
config("")
......@@ -32,7 +32,7 @@ _SUBCOMMAND_MAP = {
'depri': 'DepriCommand',
'do': 'DoCommand',
'edit': 'EditCommand',
'exit': 'ExitCommand', # used for the prompt
'exit': 'ExitCommand', # used for the prompt
'ls': 'ListCommand',
'lscon': 'ListContextCommand',
'listcon': 'ListContextCommand',
......@@ -52,10 +52,10 @@ _SUBCOMMAND_MAP = {
'tag': 'TagCommand',
}
def get_subcommand(p_args):
"""
Retrieves the to-be executed Command and returns a tuple
(Command, args).
Retrieves the to-be executed Command and returns a tuple (Command, args).
If args is an empty list, then the Command that corresponds with the
default command specified in the configuration will be returned.
......@@ -109,4 +109,3 @@ def get_subcommand(p_args):
result = import_subcommand(p_command)
return (result, args)
......@@ -34,10 +34,12 @@ except ConfigError as config_error:
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__()
......@@ -50,7 +52,7 @@ class CLIApplication(CLIApplicationBase):
(subcommand, args) = get_subcommand(args)
if subcommand == None:
if subcommand is None:
self._usage()
if self._execute(subcommand, args) == False:
......@@ -58,6 +60,7 @@ class CLIApplication(CLIApplicationBase):
else:
self._post_execute()
def main():
""" Main entry point of the CLI. """
CLIApplication().run()
......
......@@ -26,6 +26,7 @@ from six.moves import input
MAIN_OPTS = "ac:d:ht:v"
def usage():
""" Prints the command-line usage of topydo. """
......@@ -61,6 +62,7 @@ Available commands:
Run `topydo help <subcommand>` for command-specific help.
""")
def write(p_file, p_string):
"""
Write p_string to file p_file, trailed by a newline character.
......@@ -73,11 +75,12 @@ def write(p_file, p_string):
if p_string:
p_file.write(p_string + "\n")
def error(p_string):
""" Writes an error on the standard error. """
write(sys.stderr, p_string)
def version():
""" Print the current version and exit. """
from topydo.lib.Version import VERSION, LICENSE
......@@ -103,6 +106,7 @@ from topydo.lib import TodoList
from topydo.lib import TodoListBase
from topydo.lib.Utils import escape_ansi
class CLIApplicationBase(object):
"""
Base class for a Command Line Interfaces (CLI) for topydo. Examples are the
......@@ -110,6 +114,7 @@ class CLIApplicationBase(object):
Handles input/output of the various subcommands.
"""
def __init__(self):
self.todolist = TodoList.TodoList([])
self.todofile = None
......@@ -173,10 +178,10 @@ class CLIApplicationBase(object):
archive_file.write(archive.print_todos())
def _help(self, args):
if args == None:
pass # TODO
if args is None:
pass # TODO
else:
pass # TODO
pass # TODO
def _input(self):
"""
......@@ -221,4 +226,3 @@ class CLIApplicationBase(object):
def run(self):
raise NotImplementedError
......@@ -39,6 +39,7 @@ 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.
......@@ -49,11 +50,13 @@ def _todotxt_mtime():
# 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__()
......@@ -69,7 +72,6 @@ class PromptApplication(CLIApplicationBase):
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:
......@@ -91,8 +93,8 @@ class PromptApplication(CLIApplicationBase):
try:
user_input = prompt(u'topydo> ', history=history,
completer=self.completer,
complete_while_typing=False).split()
completer=self.completer,
complete_while_typing=False).split()
except (EOFError, KeyboardInterrupt):
sys.exit(0)
......@@ -112,10 +114,10 @@ class PromptApplication(CLIApplicationBase):
except TypeError:
usage()
def main():
""" Main entry point of the prompt interface. """
PromptApplication().run()
if __name__ == '__main__':
main()
......@@ -23,11 +23,11 @@ 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.Config import config
from topydo.lib.RelativeDate import relative_date_to_date
def _subcommands(p_word_before_cursor):
""" Generator for subcommand name completion. """
subcommands = [sc for sc in sorted(_SUBCOMMAND_MAP.keys()) if
......@@ -35,6 +35,7 @@ def _subcommands(p_word_before_cursor):
for command in subcommands:
yield Completion(command, -len(p_word_before_cursor))
def _dates(p_word_before_cursor):
""" Generator for date completion. """
def _date_suggestions():
......@@ -79,11 +80,13 @@ def _dates(p_word_before_cursor):
yield Completion(reldate, -len(value), display_meta=to_absolute(reldate))
class TopydoCompleter(Completer):
"""
Completer class that completes projects, contexts, dates and
subcommands.
"""
def __init__(self, p_todolist):
self.todolist = p_todolist
......@@ -106,7 +109,8 @@ class TopydoCompleter(Completer):
def get_completions(self, p_document, _):
# 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)
is_first_word = not re.match(r'\s*\S+\s',
p_document.current_line_before_cursor)
if is_first_word:
return _subcommands(word_before_cursor)
......
......@@ -16,15 +16,18 @@
""" Entry file for the Python todo.txt CLI. """
import sys
import getopt
from topydo.cli.CLIApplicationBase import MAIN_OPTS, error
import sys
from topydo.cli.CLI import CLIApplication
from topydo.cli.CLIApplicationBase import MAIN_OPTS, error
# enable color on windows CMD
if "win32" in sys.platform:
import colorama
colorama.init()
def main():
""" Main entry point of the CLI. """
try:
......
......@@ -16,18 +16,19 @@
""" Provides the AddCommand class that implements the 'add' subcommand. """
from datetime import date
import re
from sys import stdin
import codecs
import re
from datetime import date
from os.path import expanduser
from sys import stdin
from topydo.lib.Config import config
from topydo.lib.Command import Command
from topydo.lib.Config import config
from topydo.lib.PrettyPrinterFilter import PrettyPrinterNumbers
from topydo.lib.RelativeDate import relative_date_to_date
from topydo.lib.TodoListBase import InvalidTodoException
class AddCommand(Command):
def __init__(self, p_args, p_todolist,
p_out=lambda a: None,
......@@ -60,11 +61,12 @@ class AddCommand(Command):
def _add_todo(self, p_todo_text):
def _preprocess_input_todo(p_todo_text):
"""
Preprocesses user input when adding a task.
Pre-processes 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)
todo_text = re.sub(r'^(.+) (\([A-Z]\))(.*)$', r'\2 \1\3',
p_todo_text)
return todo_text
......
......@@ -18,6 +18,7 @@ from topydo.lib.Command import Command, InvalidCommandArgument
from topydo.lib.PrettyPrinterFilter import PrettyPrinterNumbers
from topydo.lib.TodoListBase import InvalidTodoException
class AppendCommand(Command):
def __init__(self, p_args, p_todolist,
p_out=lambda a: None,
......
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# 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
......@@ -16,6 +16,7 @@
from topydo.lib.Command import Command
class ArchiveCommand(Command):
def __init__(self, p_todolist, p_archive_list):
"""
......
......@@ -16,6 +16,7 @@
from topydo.lib.DCommand import DCommand
class DeleteCommand(DCommand):
def __init__(self, p_args, p_todolist,
p_out=lambda a: None,
......
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# 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
......@@ -14,14 +14,15 @@
# 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 import Filter
from topydo.lib.Command import Command, InvalidCommandArgument
from topydo.lib.Config import config
from topydo.lib import Filter
from topydo.lib.PrettyPrinter import pretty_printer_factory
from topydo.lib.Sorter import Sorter
from topydo.lib.TodoListBase import InvalidTodoException
from topydo.lib.View import View
class DepCommand(Command):
def __init__(self, p_args, p_todolist,
p_out=lambda a: None,
......
......@@ -17,6 +17,7 @@
from topydo.lib.MultiCommand import MultiCommand
from topydo.lib.PrettyPrinterFilter import PrettyPrinterNumbers
class DepriCommand(MultiCommand):
def __init__(self, p_args, p_todolist,
p_out=lambda a: None,
......
......@@ -19,9 +19,10 @@ from datetime import date
from topydo.lib.DCommand import DCommand
from topydo.lib.PrettyPrinter import PrettyPrinter
from topydo.lib.PrettyPrinterFilter import PrettyPrinterNumbers
from topydo.lib.Recurrence import advance_recurring_todo, NoRecurrenceException
from topydo.lib.Recurrence import NoRecurrenceException, advance_recurring_todo
from topydo.lib.Utils import date_string_to_date
class DoCommand(DCommand):
def __init__(self, p_args, p_todolist,
p_out=lambda a: None,
......
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# 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
......@@ -15,17 +15,16 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
from subprocess import call, check_call, CalledProcessError
import tempfile
from subprocess import CalledProcessError, check_call
from six import u
from topydo.lib.ExpressionCommand import ExpressionCommand
from topydo.lib.MultiCommand import MultiCommand
from topydo.lib.Config import config
from topydo.lib.MultiCommand import MultiCommand
from topydo.lib.PrettyPrinterFilter import PrettyPrinterNumbers
from topydo.lib.Todo import Todo
from topydo.lib.TodoList import TodoList
from topydo.lib.PrettyPrinterFilter import PrettyPrinterNumbers
# the true and only editor
DEFAULT_EDITOR = 'vi'
......@@ -34,10 +33,11 @@ DEFAULT_EDITOR = 'vi'
# cannot use super() inside the class itself
BASE_TODOLIST = lambda tl: super(TodoList, tl)
class EditCommand(MultiCommand):
def __init__(self, p_args, p_todolist, p_output, p_error, p_input):
super(EditCommand, self).__init__(p_args, p_todolist, p_output,
p_error, p_input)
p_error, p_input)
if len(self.args) == 0:
self.multi_mode = False
......@@ -85,7 +85,7 @@ class EditCommand(MultiCommand):
return 1
except(OSError):
self.error('There is no such editor as: ' + editor + '. '
'Check your $EDITOR and/or $PATH')
'Check your $EDITOR and/or $PATH')
def _catch_todo_errors(self):
errors = []
......@@ -117,7 +117,7 @@ class EditCommand(MultiCommand):
self.out(self.printer.print_todo(todo))
else:
self.error('Number of edited todos is not equal to '
'number of supplied todo IDs.')
'number of supplied todo IDs.')
else:
self.error(self.usage())
......
......@@ -18,11 +18,13 @@ 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)
......@@ -32,4 +34,3 @@ class ExitCommand(Command):
return False
sys.exit(0)
......@@ -14,15 +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/>.
from topydo.lib.ExpressionCommand import ExpressionCommand
from topydo.lib.Config import config
from topydo.lib.PrettyPrinter import pretty_printer_factory
from topydo.lib.PrettyPrinterFilter import (
PrettyPrinterIndentFilter,
PrettyPrinterHideTagFilter
)
from topydo.lib.ExpressionCommand import ExpressionCommand
from topydo.lib.IcalPrinter import IcalPrinter
from topydo.lib.JsonPrinter import JsonPrinter
from topydo.lib.PrettyPrinter import pretty_printer_factory
from topydo.lib.PrettyPrinterFilter import (PrettyPrinterHideTagFilter,
PrettyPrinterIndentFilter)
class ListCommand(ExpressionCommand):
def __init__(self, p_args, p_todolist,
......@@ -43,7 +42,7 @@ class ListCommand(ExpressionCommand):
"""
try:
import icalendar as _
except ImportError: # pragma: no cover
except ImportError: # pragma: no cover
self.error("icalendar package is not installed.")
return False
......@@ -76,8 +75,7 @@ class ListCommand(ExpressionCommand):
printing). If a format was specified on the commandline, this format is
sent to the output.
"""
if self.printer == None:
if self.printer is None:
# create a standard printer with some filters
indent = config().list_indent()
hidden_tags = config().hidden_tags()
......@@ -96,7 +94,7 @@ class ListCommand(ExpressionCommand):
try:
self._process_flags()
except SyntaxError: # pragma: no cover
except SyntaxError: # pragma: no cover
# importing icalendar failed, most likely due to Python 3.2
self.error("icalendar is not supported in this Python version.")
return False
......@@ -119,7 +117,7 @@ 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.
* 'text' - Text output with colors and indentation 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
......
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# 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
......@@ -16,6 +16,7 @@
from topydo.lib.Command import Command
class ListContextCommand(Command):
def __init__(self, p_args, p_todolist,
p_out=lambda a: None,
......
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# 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
......@@ -16,6 +16,7 @@
from topydo.lib.Command import Command
class ListProjectCommand(Command):
def __init__(self, p_args, p_todolist,
p_out=lambda a: None,
......
......@@ -16,12 +16,13 @@
from datetime import date, timedelta
from topydo.lib.MultiCommand import MultiCommand
from topydo.lib.Config import config
from topydo.lib.MultiCommand import MultiCommand
from topydo.lib.PrettyPrinterFilter import PrettyPrinterNumbers
from topydo.lib.RelativeDate import relative_date_to_date
from topydo.lib.Utils import date_string_to_date
class PostponeCommand(MultiCommand):
def __init__(self, p_args, p_todolist,
p_out=lambda a: None,
......@@ -84,8 +85,8 @@ Synopsis: postpone [-s] <NUMBER> [<NUMBER2> ...] <PATTERN>"
return """\
Postpone the todo item(s) with the given number(s) and the given pattern.
Postponing is done by adjusting the due date(s) of the todo(s), and if the -s flag is
given, the start date accordingly.
Postponing is done by adjusting the due date(s) of the todo(s), and if the -s
flag is given, the start date accordingly.
It is also possible to postpone items as complete with an expression using
the -e flag. Use -x to also process todo items that are normally invisible
......
......@@ -20,6 +20,7 @@ from topydo.lib.MultiCommand import MultiCommand
from topydo.lib.PrettyPrinterFilter import PrettyPrinterNumbers
from topydo.lib.Utils import is_valid_priority
class PriorityCommand(MultiCommand):
def __init__(self, p_args, p_todolist,
p_out=lambda a: None,
......
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# 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
......@@ -18,6 +18,7 @@ from topydo.lib.Command import Command, InvalidCommandArgument
from topydo.lib.Config import config
from topydo.lib.Sorter import Sorter
class SortCommand(Command):
def __init__(self, p_args, p_todolist,
p_out=lambda a: None,
......@@ -35,7 +36,7 @@ class SortCommand(Command):
except InvalidCommandArgument:
expression = config().sort_string()
sorter = Sorter(expression) # TODO: validate
sorter = Sorter(expression) # TODO: validate
sorted_todos = sorter.sort(self.todolist.todos())
self.todolist.erase()
......
......@@ -18,6 +18,7 @@ from topydo.lib.Command import Command, InvalidCommandArgument
from topydo.lib.PrettyPrinterFilter import PrettyPrinterNumbers
from topydo.lib.TodoListBase import InvalidTodoException
class TagCommand(Command):
def __init__(self, p_args, p_todolist,
p_out=lambda a: None,
......@@ -67,7 +68,7 @@ class TagCommand(Command):
def _choose(self):
"""
Returns the chosen number of the tag value to process (or "all")
Returns the chosen number of the tag value to process (or "all").
"""
answer = "all"
......@@ -103,7 +104,7 @@ class TagCommand(Command):
if answer == "all":
for value in self.current_values:
self._set_helper(value)
elif answer != None and self.value != self.current_values[answer]:
elif answer is not None and self.value != self.current_values[answer]:
self._set_helper(self.current_values[answer])
else:
......@@ -130,6 +131,6 @@ is omitted, the tag is removed from the todo item.
-a : Do not change the current value of the tag if it exists, but add a new
value.
-f : Force setting/removing all values of the tag. Prevents interaction with the
user.
-f : Force setting/removing all values of the tag. Prevents interaction with
the user.
"""
......@@ -18,7 +18,8 @@
from topydo.lib.Config import config
NEUTRAL_COLOR = '\033[0m'
NEUTRAL_COLOR = '\033[0m'
class Colors(object):
def __init__(self):
......@@ -48,13 +49,13 @@ class Colors(object):
try:
if p_safe:
if 8 > int(p_int) >=0:
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:
if 256 > int(p_int) >= 0:
return '\033[{};38;5;{}m'.format(decoration, str(p_int))
else:
return NEUTRAL_COLOR
......
......@@ -18,9 +18,11 @@ import getopt
from topydo.lib.PrettyPrinter import PrettyPrinter
class InvalidCommandArgument(Exception):
pass
class Command(object):
def __init__(self, p_args, p_todolist,
p_out=lambda a: None,
......@@ -90,4 +92,3 @@ class Command(object):
def help(self):
""" Returns the help text for this command. """
raise NotImplementedError
......@@ -18,6 +18,7 @@ import os
from six.moves import configparser
class ConfigError(Exception):
def __init__(self, p_text):
self.text = p_text
......@@ -25,6 +26,7 @@ class ConfigError(Exception):
def __str__(self):
return self.text
class _Config:
def __init__(self, p_path=None, p_overrides=None):
"""
......@@ -52,8 +54,8 @@ class _Config:
# topydo
'default_command': 'ls',
'colors': '1',
'filename' : 'todo.txt',
'archive_filename' : 'done.txt',
'filename': 'todo.txt',
'archive_filename': 'done.txt',
'identifiers': 'linenumber',
# add
......@@ -100,7 +102,7 @@ class _Config:
# when a path is given, *only* use the values in that file, or the
# defaults listed above.
if p_path != None:
if p_path is not None:
files = [p_path]
self.cp.read(files)
......@@ -198,10 +200,12 @@ class _Config:
hidden_tags = self.cp.get('ls', 'hide_tags')
# pylint: disable=no-member
return [] if hidden_tags == '' else [tag.strip() for tag in
hidden_tags.split(',')]
hidden_tags.split(',')]
def priority_colors(self):
""" Returns a dict with priorities as keys and color numbers as value. """
"""
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):
......@@ -214,7 +218,7 @@ class _Config:
try:
if pri_colors_str == '':
pri_colors_dict = {'A':'', 'B': '', 'C': ''}
pri_colors_dict = {'A': '', 'B': '', 'C': ''}
else:
pri_colors_dict = _str_to_dict(pri_colors_str)
except ValueError:
......@@ -252,6 +256,7 @@ class _Config:
except ValueError:
return self.defaults['auto_creation_date'] == '1'
def config(p_path=None, p_overrides=None):
"""
Retrieve the config instance.
......@@ -264,7 +269,7 @@ def config(p_path=None, p_overrides=None):
passed value instead. Structure: (section, option) => value
The previous configuration instance will be discarded.
"""
if not config.instance or p_path != None or p_overrides != None:
if not config.instance or p_path is not None or p_overrides is not None:
try:
config.instance = _Config(p_path, p_overrides)
except configparser.ParsingError as perr:
......
......@@ -20,6 +20,7 @@ from topydo.lib.MultiCommand import MultiCommand
from topydo.lib.PrettyPrinter import PrettyPrinter
from topydo.lib.PrettyPrinterFilter import PrettyPrinterNumbers
class DCommand(MultiCommand):
"""
A common class for the 'do' and 'del' operations, because they're quite
......@@ -35,7 +36,8 @@ class DCommand(MultiCommand):
self.force = False
self.length = len(self.todolist.todos()) # to determine newly activated todos
# to determine newly activated todos
self.length = len(self.todolist.todos())
def get_flags(self):
return ("f", ["force"])
......@@ -91,7 +93,7 @@ class DCommand(MultiCommand):
just before that point.
"""
return [todo for todo in self.todolist.todos()[:self.length]
if not self._uncompleted_children(todo) and todo.is_active()]
if not self._uncompleted_children(todo) and todo.is_active()]
def condition(self, _):
"""
......
......@@ -16,16 +16,18 @@
import re
from topydo.lib import Filter
from topydo.lib.Command import Command
from topydo.lib.Config import config
from topydo.lib import Filter
from topydo.lib.Sorter import Sorter
from topydo.lib.View import View
class ExpressionCommand(Command):
"""
A common class for commands operating on todos selected by expressions.
"""
def __init__(self, p_args, p_todolist,
p_out=lambda a: None,
p_err=lambda a: None,
......
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# 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
......@@ -19,18 +19,19 @@ import re
from topydo.lib.RelativeDate import relative_date_to_date
from topydo.lib.Utils import date_string_to_date
class Filter(object):
def filter(self, p_todos):
"""
Filters a list of todos. Truncates the list after p_limit todo
items (or no maximum limit if omitted).
"""
return [t for t in p_todos if self.match(t)]
def match(self, _):
raise NotImplementedError
class NegationFilter(Filter):
def __init__(self, p_filter):
self._filter = p_filter
......@@ -38,6 +39,7 @@ class NegationFilter(Filter):
def match(self, p_todo):
return not self._filter.match(p_todo)
class AndFilter(Filter):
def __init__(self, p_filter1, p_filter2):
self._filter1 = p_filter1
......@@ -46,6 +48,7 @@ class AndFilter(Filter):
def match(self, p_todo):
return self._filter1.match(p_todo) and self._filter2.match(p_todo)
class OrFilter(Filter):
def __init__(self, p_filter1, p_filter2):
self._filter1 = p_filter1
......@@ -54,6 +57,7 @@ class OrFilter(Filter):
def match(self, p_todo):
return self._filter1.match(p_todo) or self._filter2.match(p_todo)
class GrepFilter(Filter):
""" Matches when the todo text contains a text. """
......@@ -63,7 +67,7 @@ class GrepFilter(Filter):
# convert to string in case we receive integers
self.expression = p_expression
if p_case_sensitive != None:
if p_case_sensitive is not None:
self.case_sensitive = p_case_sensitive
else:
# only be case sensitive when the expression contains at least one
......@@ -80,6 +84,7 @@ class GrepFilter(Filter):
return string.find(expr) != -1
class RelevanceFilter(Filter):
"""
Matches when the todo is relevant, i.e.:
......@@ -99,8 +104,10 @@ class RelevanceFilter(Filter):
return p_todo.is_active() and is_due
class DependencyFilter(Filter):
""" Matches when a todo has no unfinished child tasks. """
def __init__(self, p_todolist):
"""
Constructor.
......@@ -120,6 +127,7 @@ class DependencyFilter(Filter):
return not uncompleted
class InstanceFilter(Filter):
def __init__(self, p_todos):
"""
......@@ -143,6 +151,7 @@ class InstanceFilter(Filter):
except ValueError:
return False
class LimitFilter(Filter):
def __init__(self, p_limit):
super(LimitFilter, self).__init__()
......@@ -153,10 +162,10 @@ class LimitFilter(Filter):
OPERATOR_MATCH = r"(?P<operator><=?|=|>=?|!)?"
class OrdinalFilter(Filter):
"""
Base class for ordinal filters.
"""
""" Base class for ordinal filters. """
def __init__(self, p_expression, p_pattern):
super(OrdinalFilter, self).__init__()
......@@ -193,6 +202,7 @@ class OrdinalFilter(Filter):
ORDINAL_TAG_MATCH = r"(?P<key>[^:]*):" + OPERATOR_MATCH + r"(?P<value>\S+)"
class OrdinalTagFilter(OrdinalFilter):
def __init__(self, p_expression):
super(OrdinalTagFilter, self).__init__(p_expression, ORDINAL_TAG_MATCH)
......@@ -235,6 +245,7 @@ class OrdinalTagFilter(OrdinalFilter):
PRIORITY_MATCH = r"\(" + OPERATOR_MATCH + r"(?P<value>[A-Z]{1})\)"
class PriorityFilter(OrdinalFilter):
def __init__(self, p_expression):
super(PriorityFilter, self).__init__(p_expression, PRIORITY_MATCH)
......
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# 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
......@@ -16,11 +16,13 @@
""" Contains the class for a directed graph. """
class DirectedGraph(object):
"""
Represents a simple directed graph, used for tracking todo
dependencies. The nodes are very simple: just integers.
"""
def __init__(self):
self._edges = {}
self._edge_numbers = {}
......@@ -36,8 +38,7 @@ class DirectedGraph(object):
def add_edge(self, p_from, p_to, p_id=None):
"""
Adds an edge to the graph. The nodes will be added if they don't
exist.
Adds an edge to the graph. The nodes will be added if they don't exist.
The p_id is the id of the edge, if the client wishes to maintain this.
"""
......@@ -59,15 +60,13 @@ class DirectedGraph(object):
def incoming_neighbors(self, p_id, p_recursive=False):
"""
Returns a set of the direct neighbors that can reach the given
node.
Returns a set of the direct neighbors that can reach the given node.
"""
return self.reachable_nodes_reverse(p_id, p_recursive)
def outgoing_neighbors(self, p_id, p_recursive=False):
"""
Returns the set of the direct neighbors that the given node can
reach.
Returns the set of the direct neighbors that the given node can reach.
"""
return self.reachable_nodes(p_id, p_recursive)
......@@ -92,8 +91,8 @@ class DirectedGraph(object):
visited.add(current)
if p_reverse:
parents = [node for node, neighbors in self._edges.items() \
if current in neighbors]
parents = [node for node, neighbors in self._edges.items()
if current in neighbors]
stack = stack + parents
result = result.union(parents)
......@@ -130,8 +129,8 @@ class DirectedGraph(object):
"""
Returns True iff the given node has no incoming or outgoing edges.
"""
return len(self.incoming_neighbors(p_id)) == 0 \
and len(self.outgoing_neighbors(p_id)) == 0
return(len(self.incoming_neighbors(p_id)) == 0
and len(self.outgoing_neighbors(p_id)) == 0)
def has_edge(self, p_from, p_to):
""" Returns True when the graph has the given edge. """
......
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# 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
......@@ -23,10 +23,11 @@ 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
4: 1679609 # largest prime under zzzz_36
3: 46649, # largest prime under zzz_36
4: 1679609 # largest prime under zzzz_36
}
def _to_base36(p_value):
"""
Converts integer to base36 string.
......@@ -43,6 +44,7 @@ def _to_base36(p_value):
return base36 or alphabet[0]
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
......@@ -79,4 +81,3 @@ def hash_list_values(p_list, p_key=lambda i: i):
result.append((item, _to_base36(hash_value)))
return result
......@@ -19,12 +19,13 @@ Provides a printer that transforms a list of Todo items to an iCalendar
file according to RFC 2445.
"""
from datetime import datetime, time
import random
import string
from datetime import datetime, time
from topydo.lib.PrettyPrinter import Printer
def _convert_priority(p_priority):
"""
Converts todo.txt priority to an iCalendar priority (RFC 2445).
......@@ -55,6 +56,7 @@ def _convert_priority(p_priority):
return result
class IcalPrinter(Printer):
"""
A printer that converts a list of Todo items to a string in iCalendar
......@@ -62,6 +64,7 @@ class IcalPrinter(Printer):
https://www.rfc-editor.org/rfc/rfc2445.txt
"""
def __init__(self, p_todolist):
super(IcalPrinter, self).__init__()
self.todolist = p_todolist
......@@ -69,7 +72,7 @@ class IcalPrinter(Printer):
try:
import icalendar
self.icalendar = icalendar
except ImportError: # pragma: no cover
except ImportError: # pragma: no cover
self.icalendar = None
def print_list(self, p_todos):
......@@ -95,6 +98,7 @@ class IcalPrinter(Printer):
Gets a unique ID from a todo item, stored by the ical tag. If the
tag is not present, a random value is assigned to it and returned.
"""
def generate_uid(p_length=4):
"""
Generates a random string of the given length, used as
......
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# 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
......@@ -29,6 +29,7 @@ from topydo.lib.Config import config
IMPORTANCE_VALUE = {'A': 3, 'B': 2, 'C': 1}
def is_due_next_monday(p_todo):
""" Returns True when the given task is due next Monday. """
today = date.today()
......@@ -37,6 +38,7 @@ def is_due_next_monday(p_todo):
return due and due.weekday() == 0 and today.weekday() >= 4 and \
p_todo.days_till_due()
def importance(p_todo, p_ignore_weekend=config().ignore_weekends()):
"""
Calculates the importance of the given task.
......@@ -74,6 +76,7 @@ def importance(p_todo, p_ignore_weekend=config().ignore_weekends()):
return result if not p_todo.is_completed() else 0
def average_importance(p_todo, p_ignore_weekend=config().ignore_weekends()):
own_importance = importance(p_todo, p_ignore_weekend)
......
......@@ -23,6 +23,7 @@ import json
from topydo.lib.PrettyPrinter import Printer
def _convert_todo(p_todo):
""" Converts a Todo instance to a dictionary. """
creation_date = p_todo.creation_date()
......@@ -44,10 +45,12 @@ def _convert_todo(p_todo):
return result
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__()
......
......@@ -19,6 +19,7 @@ from six import u
from topydo.lib.ExpressionCommand import ExpressionCommand
from topydo.lib.TodoListBase import InvalidTodoException
class MultiCommand(ExpressionCommand):
"""
A common class for operations that can work with multiple todo IDs.
......@@ -62,7 +63,7 @@ class MultiCommand(ExpressionCommand):
self.todos = self._view().todos
def get_todos(self):
""" Gets todo objects from supplied todo IDs """
""" Gets todo objects from supplied todo IDs. """
if self.is_expression:
self.get_todos_from_expr()
else:
......@@ -79,11 +80,11 @@ class MultiCommand(ExpressionCommand):
def _catch_todo_errors(self):
"""
Returns None or list of error messages depending on number of valid todo
objects and number of invalid todo IDs.
Returns None or list of error messages depending on number of valid
todo objects and number of invalid todo IDs.
In case of multiple invalid todo IDs we generate separate error message for each
one of them with information about supplied ID.
In case of multiple invalid todo IDs we generate separate error message
for each one of them with information about supplied ID.
"""
errors = []
......
......@@ -14,10 +14,9 @@
# 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.PrettyPrinterFilter import (
PrettyPrinterColorFilter,
PrettyPrinterNumbers
)
from topydo.lib.PrettyPrinterFilter import (PrettyPrinterColorFilter,
PrettyPrinterNumbers)
class Printer(object):
"""
......@@ -25,6 +24,7 @@ class Printer(object):
Subclasses must at least implement the print_todo method.
"""
def print_todo(self, p_todo):
raise NotImplementedError
......@@ -35,6 +35,7 @@ class Printer(object):
"""
return "\n".join([self.print_todo(todo) for todo in p_todos])
class PrettyPrinter(Printer):
"""
Prints todo items on a single line, decorated by the filters passed by
......@@ -44,6 +45,7 @@ class PrettyPrinter(Printer):
add colors, indentation, etc. These filters are found in the
PrettyPrinterFilter module.
"""
def __init__(self):
"""
Constructor.
......@@ -68,9 +70,9 @@ class PrettyPrinter(Printer):
return todo_str
def pretty_printer_factory(p_todolist, p_additional_filters=None):
""" Returns a pretty printer suitable for the ls and dep subcommands. """
p_additional_filters = p_additional_filters or []
printer = PrettyPrinter()
......
......@@ -17,16 +17,18 @@
""" Provides filters used for pretty printing. """
import re
from six import u
from topydo.lib.Colors import NEUTRAL_COLOR, Colors
from topydo.lib.Config import config
from topydo.lib.Colors import Colors, NEUTRAL_COLOR
class PrettyPrinterFilter(object):
"""
Base class for a pretty printer filter.
Subclasses must reimplement the filter method.
Subclasses must re-implement the filter method.
"""
def filter(self, p_todo_str, _):
......@@ -35,6 +37,7 @@ class PrettyPrinterFilter(object):
"""
raise NotImplementedError
class PrettyPrinterColorFilter(PrettyPrinterFilter):
"""
Adds colors to the todo string by inserting ANSI codes.
......@@ -44,7 +47,6 @@ 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()
......@@ -84,8 +86,10 @@ class PrettyPrinterColorFilter(PrettyPrinterFilter):
return p_todo_str
class PrettyPrinterIndentFilter(PrettyPrinterFilter):
""" Adds indentation to the todo item. """
def __init__(self, p_indent=0):
super(PrettyPrinterIndentFilter, self).__init__()
self.indent = p_indent
......@@ -94,8 +98,10 @@ class PrettyPrinterIndentFilter(PrettyPrinterFilter):
""" Applies the indentation. """
return ' ' * self.indent + p_todo_str
class PrettyPrinterNumbers(PrettyPrinterFilter):
""" Prepends the todo's number, retrieved from the todolist. """
def __init__(self, p_todolist):
super(PrettyPrinterNumbers, self).__init__()
self.todolist = p_todolist
......@@ -104,8 +110,10 @@ class PrettyPrinterNumbers(PrettyPrinterFilter):
""" Prepends the number to the todo string. """
return u("|{:>3}| {}").format(self.todolist.number(p_todo), p_todo_str)
class PrettyPrinterHideTagFilter(PrettyPrinterFilter):
""" Removes all occurences of the given tags from the text. """
""" Removes all occurrences of the given tags from the text. """
def __init__(self, p_hidden_tags):
super(PrettyPrinterHideTagFilter, self).__init__()
self.hidden_tags = p_hidden_tags
......@@ -114,6 +122,6 @@ class PrettyPrinterHideTagFilter(PrettyPrinterFilter):
for hidden_tag in self.hidden_tags:
# inspired from remove_tag in TodoBase
p_todo_str = re.sub(r'\s?\b' + hidden_tag + r':\S+\b', '',
p_todo_str)
p_todo_str)
return p_todo_str
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# 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
......@@ -22,9 +22,11 @@ from topydo.lib.Config import config
from topydo.lib.RelativeDate import relative_date_to_date
from topydo.lib.Todo import Todo
class NoRecurrenceException(Exception):
pass
def advance_recurring_todo(p_todo, p_offset=None, p_strict=False):
"""
Given a Todo item, return a new instance of a Todo item with the dates
......
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# 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
......@@ -16,9 +16,10 @@
""" This module deals with relative dates (2d, 5y, Monday, today, etc.) """
from datetime import date, timedelta
import calendar
import re
from datetime import date, timedelta
def _add_months(p_sourcedate, p_months):
"""
......@@ -35,6 +36,7 @@ def _add_months(p_sourcedate, p_months):
return date(year, month, day)
def _convert_pattern(p_length, p_periodunit, p_offset=None):
"""
Converts a pattern in the form [0-9][dwmy] and returns a date from the
......@@ -56,6 +58,7 @@ def _convert_pattern(p_length, p_periodunit, p_offset=None):
return result
def _convert_weekday_pattern(p_weekday):
"""
Converts a weekday name to an absolute date.
......@@ -81,6 +84,7 @@ def _convert_weekday_pattern(p_weekday):
shift = (target_day - day) % 7
return date.today() + timedelta(shift)
def relative_date_to_date(p_date, p_offset=None):
"""
Transforms a relative date into a date object.
......@@ -91,7 +95,6 @@ def relative_date_to_date(p_date, p_offset=None):
* 'today' or 'tomorrow'
* days of the week (in full or abbreviated)
"""
result = None
p_date = p_date.lower()
p_offset = p_offset or date.today()
......
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# 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
......@@ -16,15 +16,17 @@
""" This module provides functionality to sort lists with todo items. """
from datetime import date
import re
from datetime import date
from topydo.lib.Importance import average_importance, importance
from topydo.lib.Importance import importance, average_importance
def is_priority_field(p_field):
""" Returns True when the field name denotes the priority. """
return p_field.startswith('prio')
def get_field_function(p_field):
"""
Given a property (string) of a todo, return a function that attempts to
......@@ -39,11 +41,11 @@ def get_field_function(p_field):
elif p_field == 'creationdate' or p_field == 'creation':
# when a task has no creation date, push it to the end by assigning it
# the maximum possible date.
result = (lambda a: a.creation_date() if a.creation_date() \
else date.max)
result = (lambda a: a.creation_date() if a.creation_date()
else date.max)
elif p_field == 'done' or p_field == 'completed' or p_field == 'completion':
result = (lambda a: a.completion_date() if a.completion_date() \
else date.max)
result = (lambda a: a.completion_date() if a.completion_date()
else date.max)
elif p_field == 'importance':
result = importance
elif p_field == 'importance-avg' or p_field == 'importance-average':
......@@ -54,11 +56,12 @@ def get_field_function(p_field):
# try to find the corresponding tag
# when a tag is not present, push it to the end of the list by giving
# it an artificially higher value
result = (lambda a: "0" + a.tag_value(p_field) if a.has_tag(p_field) \
else "1")
result = (lambda a: "0" + a.tag_value(p_field) if a.has_tag(p_field)
else "1")
return result
class Sorter(object):
"""
This class sorts a todo list.
......@@ -83,6 +86,7 @@ class Sorter(object):
specific search is done first. This relies on the fact that sorting is
stable.
"""
def __init__(self, p_sortstring="desc:priority"):
self.sortstring = p_sortstring
self.functions = []
......@@ -97,7 +101,6 @@ class Sorter(object):
sort operation is done first, relying on the stability of the sorted()
function.
"""
sorted_todos = p_todos
for function, order in reversed(self.functions):
sorted_todos = sorted(sorted_todos, key=function,
......@@ -113,8 +116,8 @@ class Sorter(object):
fields = self.sortstring.lower().split(',')
for field in fields:
parsed_field = re.match( \
r'(?P<order>(asc|desc)(ending)?:)?(?P<field>\S+)', \
parsed_field = re.match(
r'(?P<order>(asc|desc)(ending)?:)?(?P<field>\S+)',
field)
if not parsed_field:
......
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# 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
......@@ -24,6 +24,7 @@ from topydo.lib.Config import config
from topydo.lib.TodoBase import TodoBase
from topydo.lib.Utils import date_string_to_date
class Todo(TodoBase):
"""
This class adds common functionality with respect to dates to the Todo
......@@ -94,4 +95,3 @@ class Todo(TodoBase):
return diff.days
else:
return 0
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# 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
......@@ -18,13 +18,15 @@
This module contains the class that represents a single todo item.
"""
from datetime import date
import re
from datetime import date
from six import u
from topydo.lib.TodoParser import parse_line
from topydo.lib.Utils import is_valid_priority
class TodoBase(object):
"""
This class represents a single todo item in a todo.txt file. It maintains
......@@ -56,7 +58,6 @@ class TodoBase(object):
Returns a list of all tag values associated with p_key. Returns
empty list if p_key does not exist.
"""
tags = self.fields['tags']
matches = [tag[1] for tag in tags if tag[0] == p_key]
return matches if len(matches) else []
......@@ -67,9 +68,8 @@ class TodoBase(object):
value is passed, it will only return true when there exists a tag with
the given key-value combination.
"""
result = [t for t in self.tag_values(p_key) \
if p_value == "" or t == p_value]
result = [t for t in self.tag_values(p_key)
if p_value == "" or t == p_value]
return len(result) > 0
def add_tag(self, p_key, p_value):
......@@ -90,7 +90,6 @@ class TodoBase(object):
When p_old_value is set, all tags having this value will be set to the
new value.
"""
if p_value == "":
self.remove_tag(p_key, p_old_value)
return
......@@ -99,8 +98,8 @@ class TodoBase(object):
if not p_force_add and value:
# remove old value from the tags
self.fields['tags'] = [t for t in self.fields['tags'] \
if not (t[0] == p_key and t[1] == value)]
self.fields['tags'] = [t for t in self.fields['tags']
if not (t[0] == p_key and t[1] == value)]
self.src = re.sub(
r'\b' + p_key + ':' + value + r'\b',
......@@ -122,8 +121,9 @@ class TodoBase(object):
# Build a new list that excludes the specified tag, match by value when
# p_value is given.
self.fields['tags'] = [t for t in self.fields['tags'] \
if not (t[0] == p_key and (p_value == "" or t[1] == p_value))]
self.fields['tags'] = [t for t in self.fields['tags']
if not (t[0] == p_key and (p_value == "" or
t[1] == p_value))]
# when value == "", match any value having key p_key
value = p_value if p_value != "" else r'\S+'
......@@ -143,13 +143,11 @@ class TodoBase(object):
Priority remains unchanged when an invalid priority is given, or when
the task was completed.
"""
if not self.is_completed() and \
(p_priority == None or is_valid_priority(p_priority)):
if not self.is_completed() and (p_priority is None or
is_valid_priority(p_priority)):
self.fields['priority'] = p_priority
priority_str = '' if p_priority == None else '(' + p_priority + ') '
priority_str = '' if p_priority is None else '(' + p_priority + ') '
self.src = re.sub(r'^(\([A-Z]\) )?', priority_str, self.src)
def priority(self):
......@@ -204,8 +202,9 @@ class TodoBase(object):
self.fields['completed'] = True
self.fields['completionDate'] = p_completion_date
self.src = re.sub(r'^(\([A-Z]\) )?', \
'x ' + p_completion_date.isoformat() + ' ', self.src)
self.src = re.sub(r'^(\([A-Z]\) )?',
'x ' + p_completion_date.isoformat() + ' ',
self.src)
def set_creation_date(self, p_date=date.today()):
"""
......@@ -213,16 +212,15 @@ class TodoBase(object):
"""
self.fields['creationDate'] = p_date
# not particulary pretty, but inspired by
# not particularly pretty, but inspired by
# http://bugs.python.org/issue1519638 non-existent matches trigger
# exceptions, hence the lambda
self.src = re.sub(
r'^(x \d{4}-\d{2}-\d{2} |\([A-Z]\) )?(\d{4}-\d{2}-\d{2} )?(.*)$',
lambda m: \
u("{}{} {}").format(m.group(1) or '', p_date.isoformat(), m.group(3)),
self.src)
lambda m:
u("{}{} {}").format(m.group(1) or '', p_date.isoformat(),
m.group(3)), self.src)
def creation_date(self):
""" Returns the creation date of a todo. """
return self.fields['creationDate']
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# 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
......@@ -20,6 +20,7 @@ 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
......@@ -48,7 +49,6 @@ class TodoFile(object):
p_todos can be a list of todo items, or a string that is just written
to the file.
"""
todofile = codecs.open(self.path, 'w', encoding="utf-8")
if p_todos is list:
......
......@@ -22,6 +22,7 @@ from topydo.lib.Config import config
from topydo.lib.Graph import DirectedGraph
from topydo.lib.TodoListBase import TodoListBase
class TodoList(TodoListBase):
"""
Provides operations for a todo list, such as adding items, removing them,
......@@ -37,7 +38,7 @@ class TodoList(TodoListBase):
The string will be parsed.
"""
# initialize these first because the constructor calls add_list
self._tododict = {} # hash(todo) to todo lookup
self._tododict = {} # hash(todo) to todo lookup
self._depgraph = DirectedGraph()
super(TodoList, self).__init__(p_todostrings)
......@@ -57,7 +58,6 @@ class TodoList(TodoListBase):
Makes sure that the dependency graph is consistent according to the
given todo.
"""
dep_id = p_todo.tag_value('id')
# maintain dependency graph
if dep_id:
......@@ -66,7 +66,7 @@ class TodoList(TodoListBase):
# connect all tasks we have in memory so far that refer to this
# task
for dep in \
[dep for dep in self._todos if dep.has_tag('p', dep_id)]:
[dep for dep in self._todos if dep.has_tag('p', dep_id)]:
self._depgraph.add_edge(hash(p_todo), hash(dep), dep_id)
......@@ -114,8 +114,7 @@ class TodoList(TodoListBase):
"""
def id_exists(p_id):
"""
Returns True if there exists a todo with the given parent
ID.
Returns True if there exists a todo with the given parent ID.
"""
for todo in self._todos:
if todo.has_tag('id', str(p_id)):
......@@ -148,7 +147,7 @@ class TodoList(TodoListBase):
self.append(p_to_todo, "@{}".format(context))
if p_from_todo != p_to_todo and not self._depgraph.has_edge(
hash(p_from_todo), hash(p_to_todo)):
hash(p_from_todo), hash(p_to_todo)):
dep_id = None
if p_from_todo.has_tag('id'):
......@@ -207,7 +206,7 @@ class TodoList(TodoListBase):
def clean_by_tag(tag_name):
""" Generic function to handle 'p' and 'id' tags. """
for todo in [todo for todo in self._todos
if todo.has_tag(tag_name)]:
if todo.has_tag(tag_name)]:
value = todo.tag_value(tag_name)
if not self._depgraph.has_edge_id(value):
......@@ -225,6 +224,5 @@ class TodoList(TodoListBase):
This is used for calculating the average importance, that requires
access to a todo's parents.
"""
for todo in self._todos:
todo.attributes['parents'] = self.parents(todo)
......@@ -18,20 +18,23 @@
A list of todo items.
"""
from datetime import date
import re
from datetime import date
from six import text_type
from topydo.lib.Config import config
from topydo.lib import Filter
from topydo.lib.Config import config
from topydo.lib.HashListValues import hash_list_values
from topydo.lib.PrettyPrinter import PrettyPrinter
from topydo.lib.Todo import Todo
from topydo.lib.View import View
class InvalidTodoException(Exception):
pass
class TodoListBase(object):
"""
Provides operations for a todo list, such as adding items, removing them,
......@@ -75,7 +78,7 @@ class TodoListBase(object):
try:
result = self._id_todo_map[p_identifier]
except KeyError:
pass # we'll try something else
pass # we'll try something else
return result
......@@ -83,10 +86,9 @@ class TodoListBase(object):
"""
Attempts to find the todo on the given line number.
When the identifier is a number but has leading zeroes, the result
When the identifier is a number but has leading zeros, the result
will be None.
"""
result = None
if config().identifiers() != 'text':
......@@ -131,7 +133,9 @@ class TodoListBase(object):
return result
def add(self, p_src):
""" Given a todo string, parse it and put it to the end of the list. """
"""
Given a todo string, parse it and put it to the end of the list.
"""
todos = self.add_list([p_src])
return todos[0] if len(todos) else None
......@@ -246,8 +250,8 @@ class TodoListBase(object):
def _update_todo_ids(self):
# the idea is to have a hash that is independent of the position of the
# todo. Use the text (without tags) of the todo to keep the id as stable
# as possible (not influenced by priorities or due dates, etc.)
# todo. Use the text (without tags) of the todo to keep the id as
# stable as possible (not influenced by priorities or due dates, etc.)
self._todo_id_map = {}
self._id_todo_map = {}
......
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# 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
......@@ -37,13 +37,14 @@ _TAG_MATCH = re.compile('(?P<key>[^:]+):(?P<value>.+)')
_PROJECT_MATCH = re.compile(r'\+(\S*\w)')
_CONTEXT_MATCH = re.compile(r'@(\S*\w)')
def parse_line(p_string):
"""
Parses a single line as can be encountered in a todo.txt file.
First checks whether the standard elements are present, such as priority,
creation date, completeness check and the completion date.
Then the rest of the analyzed for any occurences of contexts, projects or
Then the rest of the analyzed for any occurrences of contexts, projects or
tags.
Returns an dictionary with the default values as shown below.
......@@ -102,4 +103,3 @@ def parse_line(p_string):
result['text'] = result['text'][:-1]
return result
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# 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
......@@ -18,8 +18,9 @@
Various utility functions.
"""
from datetime import date
import re
from datetime import date
def date_string_to_date(p_date):
"""
......@@ -32,17 +33,19 @@ def date_string_to_date(p_date):
parsed_date = re.match(r'(\d{4})-(\d{2})-(\d{2})', p_date)
if parsed_date:
result = date(
int(parsed_date.group(1)), # year
int(parsed_date.group(2)), # month
int(parsed_date.group(3)) # day
int(parsed_date.group(1)), # year
int(parsed_date.group(2)), # month
int(parsed_date.group(3)) # day
)
else:
raise ValueError
return result
def is_valid_priority(p_priority):
return p_priority != None and re.match(r'^[A-Z]$', p_priority) != None
return p_priority is not None and re.match(r'^[A-Z]$', p_priority) is not None
def escape_ansi(p_string):
return escape_ansi.pattern.sub('', p_string)
......
......@@ -2,7 +2,7 @@
VERSION = '0.6'
LICENSE = """Copyright (C) 2014 Bram Schoenmakers
LICENSE = """Copyright (C) 2014-2015 Bram Schoenmakers
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law."""
......@@ -16,12 +16,14 @@
""" A view is a list of todos, sorted and filtered. """
class View(object):
"""
A view is instantiated by a todo list, usually obtained from a todo.txt
file. Also a sorter and a list of filters should be given that is applied
to the list.
"""
def __init__(self, p_sorter, p_filters, p_todolist):
self._todolist = p_todolist
self._sorter = p_sorter
......
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