Commit 66de5976 authored by Bram Schoenmakers's avatar Bram Schoenmakers

Merge branch 'stable'

Conflicts:
	test/DoCommandTest.py
	test/SortCommandTest.py
	test/TodoListTest.py
	topydo/lib/TodoList.py
	topydo/lib/TodoListBase.py
parents ed53670d 8e32cf75
...@@ -2,7 +2,7 @@ topydo ...@@ -2,7 +2,7 @@ topydo
====== ======
topydo is a todo list application using the [todo.txt format][1]. It is heavily topydo is a todo list application using the [todo.txt format][1]. It is heavily
inspired by the [todo.txt CLI][1] by Gina Trapani. This tool is actually a inspired by the [todo.txt CLI][2] by Gina Trapani. This tool is actually a
merge between the todo.txt CLI and a [number of extensions][3] that I wrote merge between the todo.txt CLI and a [number of extensions][3] that I wrote
on top of the CLI, hereafter refered to as todo.txt-tools. These extensions on top of the CLI, hereafter refered to as todo.txt-tools. These extensions
are: are:
...@@ -16,33 +16,7 @@ are: ...@@ -16,33 +16,7 @@ are:
**relative dates**); **relative dates**);
Consult the [wiki][4] for more information about the features and on how to Consult the [wiki][4] for more information about the features and on how to
use Topydo. use topydo.
Motivation
----------
I rewrote the CLI from scratch for multiple reasons.
First, in the long term I'd like to write the perfect todo client. The perfect
todo client is free, open source, flexible and available wherever I am.
todo.txt is the perfect format, since it's simple and plain text and not bound
to a particular tool.
Second, the current (CLI) interface is handy, but has its limits when dealing
with large swaths of todo items. The CLI and a GUI should complement each
other.
Third, the original todo.txt CLI is a huge Bash script. In my opinion it's the
wrong language to write a serious application with it. It may behave
differently on other operating systems (or sometimes it's plain broken). The
todo.txt-tools that extend the CLI were (quickly) written in Perl. It doesn't
have a proper test suite and it sometimes doesn't play very well when a user
inputs something funny.
In order to achieve the long term vision of a perfect todo list, I need a solid
foundation in a solid language. Hence the rewrite in Python, sprinkeled with
unit tests.
[1]: https://github.com/ginatrapani/todo.txt-cli/wiki/The-Todo.txt-Format [1]: https://github.com/ginatrapani/todo.txt-cli/wiki/The-Todo.txt-Format
......
; See https://github.com/bram85/topydo/wiki/How-to-use for more info ; See https://github.com/bram85/topydo/wiki/Configuration for more info
[topydo] [topydo]
default_command = ls default_command = ls
......
from distutils.core import setup from setuptools import setup
setup( setup(
name = "Topydo", name = "topydo",
packages = ["topydo", "topydo.lib", "topydo.cli"], packages = ["topydo", "topydo.lib", "topydo.cli"],
version = "0.1", version = "0.1",
description = "A todo list application using the todo.txt format.", description = "A todo list application using the todo.txt format.",
author = "Bram Schoenmakers", author = "Bram Schoenmakers",
author_email = "me@bramschoenmakers.nl", author_email = "me@bramschoenmakers.nl",
url = "https://github.com/bram85/topydo", url = "https://github.com/bram85/topydo",
download_url = "https://github.com/bram85/topydo/archive/master.zip",
scripts = ["bin/topydo"], scripts = ["bin/topydo"],
classifiers = [ classifiers = [
"Development Status :: 4 - Beta", "Development Status :: 4 - Beta",
"Environment :: Console", "Environment :: Console",
"Intended Audience :: End Users/Desktop", "Intended Audience :: End Users/Desktop",
"License :: OSI Approved :: GNU Lesser General Public License v3 or later (LGPLv3+)", "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)",
"Natural Language :: English", "Natural Language :: English",
"Programming Language :: Python :: 2", "Programming Language :: Python :: 2",
"Topic :: Utilities", "Topic :: Utilities",
], ],
long_description = """\ long_description = """\
Topydo is a todo list application using the todo.txt format. It is heavily inspired by the todo.txt CLI by Gina Trapani. This tool is actually a merge between the todo.txt CLI and a number of extensions that I wrote on top of the CLI. These extensions are: topydo is a todo list application using the todo.txt format. It is heavily inspired by the todo.txt CLI by Gina Trapani. This tool is actually a merge between the todo.txt CLI and a number of extensions that I wrote on top of the CLI. These extensions are:
* Set due and start dates; * Set due and start dates;
* Custom sorting; * Custom sorting;
......
...@@ -16,12 +16,13 @@ ...@@ -16,12 +16,13 @@
from datetime import date from datetime import date
import AddCommand from topydo.lib import AddCommand
import CommandTest import CommandTest
import TodoList from topydo.lib import TodoList
class AddCommandTest(CommandTest.CommandTest): class AddCommandTest(CommandTest.CommandTest):
def setUp(self): def setUp(self):
super(AddCommandTest, self).setUp()
self.todolist = TodoList.TodoList([]) self.todolist = TodoList.TodoList([])
self.today = date.today().isoformat() self.today = date.today().isoformat()
...@@ -116,7 +117,7 @@ class AddCommandTest(CommandTest.CommandTest): ...@@ -116,7 +117,7 @@ class AddCommandTest(CommandTest.CommandTest):
self.assertEquals(self.output, "| 1| " + str(self.todolist.todo(1)) + "\n") self.assertEquals(self.output, "| 1| " + str(self.todolist.todo(1)) + "\n")
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_add_dep4(self): def test_add_dep5(self):
""" Test for using an after: tag with non-existing value. """ """ Test for using an after: tag with non-existing value. """
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() command.execute()
...@@ -126,7 +127,7 @@ class AddCommandTest(CommandTest.CommandTest): ...@@ -126,7 +127,7 @@ class AddCommandTest(CommandTest.CommandTest):
self.assertEquals(self.output, "| 1| " + str(self.todolist.todo(1)) + "\n") self.assertEquals(self.output, "| 1| " + str(self.todolist.todo(1)) + "\n")
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_add_dep5(self): def test_add_dep6(self):
command = AddCommand.AddCommand(["Foo"], self.todolist, self.out, self.error) command = AddCommand.AddCommand(["Foo"], self.todolist, self.out, self.error)
command.execute() command.execute()
...@@ -141,7 +142,7 @@ class AddCommandTest(CommandTest.CommandTest): ...@@ -141,7 +142,7 @@ class AddCommandTest(CommandTest.CommandTest):
self.assertEquals(self.todolist.todo(3).source(), self.today + " Baz p:1 p:2") self.assertEquals(self.todolist.todo(3).source(), self.today + " Baz p:1 p:2")
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_add_dep6(self): def test_add_dep7(self):
command = AddCommand.AddCommand(["Foo"], self.todolist, self.out, self.error) command = AddCommand.AddCommand(["Foo"], self.todolist, self.out, self.error)
command.execute() command.execute()
......
...@@ -14,66 +14,67 @@ ...@@ -14,66 +14,67 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import AppendCommand from topydo.lib.AppendCommand import AppendCommand
import CommandTest import CommandTest
import TodoList from topydo.lib.TodoList import TodoList
class AppendCommandTest(CommandTest.CommandTest): class AppendCommandTest(CommandTest.CommandTest):
def setUp(self): def setUp(self):
self.todolist = TodoList.TodoList([]) super(AppendCommandTest, self).setUp()
self.todolist = TodoList([])
self.todolist.add("Foo") self.todolist.add("Foo")
def test_append1(self): def test_append1(self):
command = AppendCommand.AppendCommand([1, "Bar"], self.todolist, self.out, self.error) command = AppendCommand([1, "Bar"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEqual(self.output, "| 1| Foo Bar\n") self.assertEqual(self.output, "| 1| Foo Bar\n")
self.assertEqual(self.errors, "") self.assertEqual(self.errors, "")
def test_append2(self): def test_append2(self):
command = AppendCommand.AppendCommand([2, "Bar"], self.todolist, self.out, self.error) command = AppendCommand([2, "Bar"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEqual(self.output, "") self.assertEqual(self.output, "")
self.assertEqual(self.errors, "Invalid todo number given.\n") self.assertEqual(self.errors, "Invalid todo number given.\n")
def test_append3(self): def test_append3(self):
command = AppendCommand.AppendCommand([1, ""], self.todolist, self.out, self.error) command = AppendCommand([1, ""], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEqual(self.output, "") self.assertEqual(self.output, "")
self.assertEqual(self.output, "") self.assertEqual(self.output, "")
def test_append4(self): def test_append4(self):
command = AppendCommand.AppendCommand([1], self.todolist, self.out, self.error) command = AppendCommand([1], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEqual(self.output, "") self.assertEqual(self.output, "")
self.assertEqual(self.errors, command.usage() + "\n") self.assertEqual(self.errors, command.usage() + "\n")
def test_append5(self): def test_append5(self):
command = AppendCommand.AppendCommand([1, "Bar", "Baz"], self.todolist, self.out, self.error) command = AppendCommand([1, "Bar", "Baz"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEqual(self.output, "| 1| Foo Bar Baz\n") self.assertEqual(self.output, "| 1| Foo Bar Baz\n")
self.assertEqual(self.errors, "") self.assertEqual(self.errors, "")
def test_append6(self): def test_append6(self):
command = AppendCommand.AppendCommand([], self.todolist, self.out, self.error) command = AppendCommand([], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEqual(self.output, "") self.assertEqual(self.output, "")
self.assertEqual(self.errors, command.usage() + "\n") self.assertEqual(self.errors, command.usage() + "\n")
def test_append7(self): def test_append7(self):
command = AppendCommand.AppendCommand(["Bar"], self.todolist, self.out, self.error) command = AppendCommand(["Bar"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEqual(self.output, "") self.assertEqual(self.output, "")
self.assertEqual(self.errors, command.usage() + "\n") self.assertEqual(self.errors, command.usage() + "\n")
def test_help(self): def test_help(self):
command = AppendCommand.AppendCommand(["help"], self.todolist, self.out, self.error) command = AppendCommand(["help"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.output, "") self.assertEquals(self.output, "")
......
# Topydo - A todo.txt client written in Python. # Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl> # Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import ArchiveCommand from topydo.lib.ArchiveCommand import ArchiveCommand
import CommandTest import CommandTest
import TestFacilities import TestFacilities
import TodoList from topydo.lib.TodoList import TodoList
class ArchiveCommandTest(CommandTest.CommandTest): class ArchiveCommandTest(CommandTest.CommandTest):
def test_archive(self): def test_archive(self):
todolist = TestFacilities.load_file_to_todolist("data/ArchiveCommandTest.txt") todolist = TestFacilities.load_file_to_todolist("data/ArchiveCommandTest.txt")
archive = TodoList.TodoList([]) archive = TodoList([])
command = ArchiveCommand.ArchiveCommand(todolist, archive) command = ArchiveCommand(todolist, archive)
command.execute() command.execute()
self.assertTrue(todolist.is_dirty()) self.assertTrue(todolist.is_dirty())
......
# Topydo - A todo.txt client written in Python. # Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl> # Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import unittest import unittest
from Utils import escape_ansi from topydo.lib.Config import config
from topydo.lib.Utils import escape_ansi
class CommandTest(unittest.TestCase): class CommandTest(unittest.TestCase):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
...@@ -24,6 +25,9 @@ class CommandTest(unittest.TestCase): ...@@ -24,6 +25,9 @@ class CommandTest(unittest.TestCase):
self.output = "" self.output = ""
self.errors = "" self.errors = ""
def setUp(self):
config("")
def out(self, p_output): def out(self, p_output):
if p_output: if p_output:
self.output += escape_ansi(p_output + "\n") self.output += escape_ansi(p_output + "\n")
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
import unittest import unittest
from Config import config from topydo.lib.Config import config
class ConfigTest(unittest.TestCase): class ConfigTest(unittest.TestCase):
def test_config1(self): def test_config1(self):
......
...@@ -15,20 +15,21 @@ ...@@ -15,20 +15,21 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import CommandTest import CommandTest
import DeleteCommand from topydo.lib.DeleteCommand import DeleteCommand
import TodoList from topydo.lib.TodoList import TodoList
class DeleteCommandTest(CommandTest.CommandTest): class DeleteCommandTest(CommandTest.CommandTest):
def setUp(self): def setUp(self):
super(DeleteCommandTest, self).setUp()
todos = [ todos = [
"Foo id:1", "Foo id:1",
"Bar p:1", "Bar p:1",
] ]
self.todolist = TodoList.TodoList(todos) self.todolist = TodoList(todos)
def test_del1(self): def test_del1(self):
command = DeleteCommand.DeleteCommand(["1"], self.todolist, self.out, self.error, lambda p: "n") command = DeleteCommand(["1"], self.todolist, self.out, self.error, lambda p: "n")
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -37,7 +38,7 @@ class DeleteCommandTest(CommandTest.CommandTest): ...@@ -37,7 +38,7 @@ class DeleteCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_del1_regex(self): def test_del1_regex(self):
command = DeleteCommand.DeleteCommand(["Foo"], self.todolist, self.out, self.error, lambda p: "n") command = DeleteCommand(["Foo"], self.todolist, self.out, self.error, lambda p: "n")
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -46,7 +47,7 @@ class DeleteCommandTest(CommandTest.CommandTest): ...@@ -46,7 +47,7 @@ class DeleteCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_del2(self): def test_del2(self):
command = DeleteCommand.DeleteCommand(["1"], self.todolist, self.out, self.error, lambda p: "y") command = DeleteCommand(["1"], self.todolist, self.out, self.error, lambda p: "y")
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -55,7 +56,7 @@ class DeleteCommandTest(CommandTest.CommandTest): ...@@ -55,7 +56,7 @@ class DeleteCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_del3(self): def test_del3(self):
command = DeleteCommand.DeleteCommand(["-f", "1"], self.todolist, self.out, self.error, lambda p: "y") command = DeleteCommand(["-f", "1"], self.todolist, self.out, self.error, lambda p: "y")
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -64,7 +65,7 @@ class DeleteCommandTest(CommandTest.CommandTest): ...@@ -64,7 +65,7 @@ class DeleteCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_del4(self): def test_del4(self):
command = DeleteCommand.DeleteCommand(["--force", "1"], self.todolist, self.out, self.error, lambda p: "y") command = DeleteCommand(["--force", "1"], self.todolist, self.out, self.error, lambda p: "y")
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -73,7 +74,7 @@ class DeleteCommandTest(CommandTest.CommandTest): ...@@ -73,7 +74,7 @@ class DeleteCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_del5(self): def test_del5(self):
command = DeleteCommand.DeleteCommand(["2"], self.todolist, self.out, self.error) command = DeleteCommand(["2"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -82,7 +83,7 @@ class DeleteCommandTest(CommandTest.CommandTest): ...@@ -82,7 +83,7 @@ class DeleteCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_del7(self): def test_del7(self):
command = DeleteCommand.DeleteCommand(["99"], self.todolist, self.out, self.error) command = DeleteCommand(["99"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -90,7 +91,7 @@ class DeleteCommandTest(CommandTest.CommandTest): ...@@ -90,7 +91,7 @@ class DeleteCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "Invalid todo number given.\n") self.assertEquals(self.errors, "Invalid todo number given.\n")
def test_del8(self): def test_del8(self):
command = DeleteCommand.DeleteCommand(["A"], self.todolist, self.out, self.error) command = DeleteCommand(["A"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -98,7 +99,7 @@ class DeleteCommandTest(CommandTest.CommandTest): ...@@ -98,7 +99,7 @@ class DeleteCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "Invalid todo number given.\n") self.assertEquals(self.errors, "Invalid todo number given.\n")
def test_empty(self): def test_empty(self):
command = DeleteCommand.DeleteCommand([], self.todolist, self.out, self.error) command = DeleteCommand([], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -106,7 +107,7 @@ class DeleteCommandTest(CommandTest.CommandTest): ...@@ -106,7 +107,7 @@ class DeleteCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, command.usage() + "\n") self.assertEquals(self.errors, command.usage() + "\n")
def test_help(self): def test_help(self):
command = DeleteCommand.DeleteCommand(["help"], self.todolist, self.out, self.error) command = DeleteCommand(["help"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.output, "") self.assertEquals(self.output, "")
......
...@@ -15,11 +15,12 @@ ...@@ -15,11 +15,12 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import CommandTest import CommandTest
import DepCommand from topydo.lib.DepCommand import DepCommand
import TodoList from topydo.lib.TodoList import TodoList
class DepCommandTest(CommandTest.CommandTest): class DepCommandTest(CommandTest.CommandTest):
def setUp(self): def setUp(self):
super(DepCommandTest, self).setUp()
todos = [ todos = [
"Foo id:1", "Foo id:1",
"Bar p:1", "Bar p:1",
...@@ -29,10 +30,10 @@ class DepCommandTest(CommandTest.CommandTest): ...@@ -29,10 +30,10 @@ class DepCommandTest(CommandTest.CommandTest):
"Fart p:2", "Fart p:2",
] ]
self.todolist = TodoList.TodoList(todos) self.todolist = TodoList(todos)
def test_add1(self): def test_add1(self):
command = DepCommand.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() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -41,7 +42,7 @@ class DepCommandTest(CommandTest.CommandTest): ...@@ -41,7 +42,7 @@ class DepCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_add2(self): def test_add2(self):
command = DepCommand.DepCommand(["add", "1", "4"], self.todolist, self.out, self.error) command = DepCommand(["add", "1", "4"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -50,7 +51,7 @@ class DepCommandTest(CommandTest.CommandTest): ...@@ -50,7 +51,7 @@ class DepCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_add3(self): def test_add3(self):
command = DepCommand.DepCommand(["add", "99", "3"], self.todolist, self.out, self.error) command = DepCommand(["add", "99", "3"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -58,7 +59,7 @@ class DepCommandTest(CommandTest.CommandTest): ...@@ -58,7 +59,7 @@ class DepCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "Invalid todo number given.\n") self.assertEquals(self.errors, "Invalid todo number given.\n")
def test_add4(self): def test_add4(self):
command = DepCommand.DepCommand(["add", "A", "3"], self.todolist, self.out, self.error) command = DepCommand(["add", "A", "3"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -66,7 +67,7 @@ class DepCommandTest(CommandTest.CommandTest): ...@@ -66,7 +67,7 @@ class DepCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "Invalid todo number given.\n") self.assertEquals(self.errors, "Invalid todo number given.\n")
def test_add5(self): def test_add5(self):
command = DepCommand.DepCommand(["add", "1"], self.todolist, self.out, self.error) command = DepCommand(["add", "1"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -74,7 +75,7 @@ class DepCommandTest(CommandTest.CommandTest): ...@@ -74,7 +75,7 @@ class DepCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, command.usage() + "\n") self.assertEquals(self.errors, command.usage() + "\n")
def test_add6(self): def test_add6(self):
command = DepCommand.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() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -83,7 +84,7 @@ class DepCommandTest(CommandTest.CommandTest): ...@@ -83,7 +84,7 @@ class DepCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_add7(self): def test_add7(self):
command = DepCommand.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() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -92,7 +93,7 @@ class DepCommandTest(CommandTest.CommandTest): ...@@ -92,7 +93,7 @@ class DepCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_add8(self): def test_add8(self):
command = DepCommand.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() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -101,7 +102,7 @@ class DepCommandTest(CommandTest.CommandTest): ...@@ -101,7 +102,7 @@ class DepCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_add9(self): def test_add9(self):
command = DepCommand.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() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -115,7 +116,7 @@ class DepCommandTest(CommandTest.CommandTest): ...@@ -115,7 +116,7 @@ class DepCommandTest(CommandTest.CommandTest):
to todo 3. to todo 3.
""" """
command = DepCommand.DepCommand(p_args, self.todolist, self.out, self.error) command = DepCommand(p_args, self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -137,7 +138,7 @@ class DepCommandTest(CommandTest.CommandTest): ...@@ -137,7 +138,7 @@ class DepCommandTest(CommandTest.CommandTest):
self.rm_helper(["del", "1", "3"]) self.rm_helper(["del", "1", "3"])
def test_rm3(self): def test_rm3(self):
command = DepCommand.DepCommand(["rm", "99", "3"], self.todolist, self.out, self.error) command = DepCommand(["rm", "99", "3"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -145,7 +146,7 @@ class DepCommandTest(CommandTest.CommandTest): ...@@ -145,7 +146,7 @@ class DepCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "Invalid todo number given.\n") self.assertEquals(self.errors, "Invalid todo number given.\n")
def test_rm4(self): def test_rm4(self):
command = DepCommand.DepCommand(["rm", "A", "3"], self.todolist, self.out, self.error) command = DepCommand(["rm", "A", "3"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -153,7 +154,7 @@ class DepCommandTest(CommandTest.CommandTest): ...@@ -153,7 +154,7 @@ class DepCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "Invalid todo number given.\n") self.assertEquals(self.errors, "Invalid todo number given.\n")
def test_rm5(self): def test_rm5(self):
command = DepCommand.DepCommand(["rm", "1"], self.todolist, self.out, self.error) command = DepCommand(["rm", "1"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -161,7 +162,7 @@ class DepCommandTest(CommandTest.CommandTest): ...@@ -161,7 +162,7 @@ class DepCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, command.usage() + "\n") self.assertEquals(self.errors, command.usage() + "\n")
def test_ls1(self): def test_ls1(self):
command = DepCommand.DepCommand(["ls", "1", "to"], self.todolist, self.out, self.error) command = DepCommand(["ls", "1", "to"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -169,7 +170,7 @@ class DepCommandTest(CommandTest.CommandTest): ...@@ -169,7 +170,7 @@ class DepCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_ls2(self): def test_ls2(self):
command = DepCommand.DepCommand(["ls", "99", "to"], self.todolist, self.out, self.error) command = DepCommand(["ls", "99", "to"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -177,7 +178,7 @@ class DepCommandTest(CommandTest.CommandTest): ...@@ -177,7 +178,7 @@ class DepCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "Invalid todo number given.\n") self.assertEquals(self.errors, "Invalid todo number given.\n")
def test_ls3(self): def test_ls3(self):
command = DepCommand.DepCommand(["ls", "to", "3"], self.todolist, self.out, self.error) command = DepCommand(["ls", "to", "3"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -185,7 +186,7 @@ class DepCommandTest(CommandTest.CommandTest): ...@@ -185,7 +186,7 @@ class DepCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_ls4(self): def test_ls4(self):
command = DepCommand.DepCommand(["ls", "to", "99"], self.todolist, self.out, self.error) command = DepCommand(["ls", "to", "99"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -193,7 +194,7 @@ class DepCommandTest(CommandTest.CommandTest): ...@@ -193,7 +194,7 @@ class DepCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "Invalid todo number given.\n") self.assertEquals(self.errors, "Invalid todo number given.\n")
def test_ls5(self): def test_ls5(self):
command = DepCommand.DepCommand(["ls", "1"], self.todolist, self.out, self.error) command = DepCommand(["ls", "1"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -201,7 +202,7 @@ class DepCommandTest(CommandTest.CommandTest): ...@@ -201,7 +202,7 @@ class DepCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, command.usage() + "\n") self.assertEquals(self.errors, command.usage() + "\n")
def test_ls6(self): def test_ls6(self):
command = DepCommand.DepCommand(["ls"], self.todolist, self.out, self.error) command = DepCommand(["ls"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -209,7 +210,7 @@ class DepCommandTest(CommandTest.CommandTest): ...@@ -209,7 +210,7 @@ class DepCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, command.usage() + "\n") self.assertEquals(self.errors, command.usage() + "\n")
def gc_helper(self, p_subcommand): def gc_helper(self, p_subcommand):
command = DepCommand.DepCommand([p_subcommand], self.todolist, self.out, self.error) command = DepCommand([p_subcommand], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -224,7 +225,7 @@ class DepCommandTest(CommandTest.CommandTest): ...@@ -224,7 +225,7 @@ class DepCommandTest(CommandTest.CommandTest):
self.gc_helper("gc") self.gc_helper("gc")
def test_invalid_subsubcommand(self): def test_invalid_subsubcommand(self):
command = DepCommand.DepCommand(["foo"], self.todolist, self.out, self.error) command = DepCommand(["foo"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.output) self.assertFalse(self.output)
...@@ -232,7 +233,7 @@ class DepCommandTest(CommandTest.CommandTest): ...@@ -232,7 +233,7 @@ class DepCommandTest(CommandTest.CommandTest):
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
def test_no_subsubcommand(self): def test_no_subsubcommand(self):
command = DepCommand.DepCommand([], self.todolist, self.out, self.error) command = DepCommand([], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.output) self.assertFalse(self.output)
...@@ -240,7 +241,7 @@ class DepCommandTest(CommandTest.CommandTest): ...@@ -240,7 +241,7 @@ class DepCommandTest(CommandTest.CommandTest):
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
def test_help(self): def test_help(self):
command = DepCommand.DepCommand(["help"], self.todolist, self.out, self.error) command = DepCommand(["help"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.output, "") self.assertEquals(self.output, "")
......
# Topydo - A todo.txt client written in Python. # Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl> # Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import CommandTest import CommandTest
import DepriCommand from topydo.lib.DepriCommand import DepriCommand
import TodoList from topydo.lib.TodoList import TodoList
class DepriCommandTest(CommandTest.CommandTest): class DepriCommandTest(CommandTest.CommandTest):
def setUp(self): def setUp(self):
super(DepriCommandTest, self).setUp()
todos = [ todos = [
"(A) Foo", "(A) Foo",
"Bar", "Bar",
] ]
self.todolist = TodoList.TodoList(todos) self.todolist = TodoList(todos)
def test_set_prio1(self): def test_set_prio1(self):
command = DepriCommand.DepriCommand(["1"], self.todolist, self.out, self.error) command = DepriCommand(["1"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -37,7 +38,7 @@ class DepriCommandTest(CommandTest.CommandTest): ...@@ -37,7 +38,7 @@ class DepriCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_set_prio2(self): def test_set_prio2(self):
command = DepriCommand.DepriCommand(["2"], self.todolist, self.out, self.error) command = DepriCommand(["2"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -46,7 +47,7 @@ class DepriCommandTest(CommandTest.CommandTest): ...@@ -46,7 +47,7 @@ class DepriCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_set_prio3(self): def test_set_prio3(self):
command = DepriCommand.DepriCommand(["Foo"], self.todolist, self.out, self.error) command = DepriCommand(["Foo"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -55,7 +56,7 @@ class DepriCommandTest(CommandTest.CommandTest): ...@@ -55,7 +56,7 @@ class DepriCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_invalid1(self): def test_invalid1(self):
command = DepriCommand.DepriCommand(["99"], self.todolist, self.out, self.error) command = DepriCommand(["99"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -63,7 +64,7 @@ class DepriCommandTest(CommandTest.CommandTest): ...@@ -63,7 +64,7 @@ class DepriCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "Invalid todo number given.\n") self.assertEquals(self.errors, "Invalid todo number given.\n")
def test_empty(self): def test_empty(self):
command = DepriCommand.DepriCommand([], self.todolist, self.out, self.error) command = DepriCommand([], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -71,7 +72,7 @@ class DepriCommandTest(CommandTest.CommandTest): ...@@ -71,7 +72,7 @@ class DepriCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, command.usage() + "\n") self.assertEquals(self.errors, command.usage() + "\n")
def test_help(self): def test_help(self):
command = DepriCommand.DepriCommand(["help"], self.todolist, self.out, self.error) command = DepriCommand(["help"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.output, "") self.assertEquals(self.output, "")
......
...@@ -17,8 +17,8 @@ ...@@ -17,8 +17,8 @@
from datetime import date, timedelta from datetime import date, timedelta
import CommandTest import CommandTest
import DoCommand from topydo.lib.DoCommand import DoCommand
import TodoList from topydo.lib.TodoList import TodoList
def _yes_prompt(self): def _yes_prompt(self):
return "y" return "y"
...@@ -28,6 +28,7 @@ def _no_prompt(self): ...@@ -28,6 +28,7 @@ def _no_prompt(self):
class DoCommandTest(CommandTest.CommandTest): class DoCommandTest(CommandTest.CommandTest):
def setUp(self): def setUp(self):
super(DoCommandTest, self).setUp()
todos = [ todos = [
"Foo id:1", "Foo id:1",
"Bar p:1", "Bar p:1",
...@@ -39,14 +40,14 @@ class DoCommandTest(CommandTest.CommandTest): ...@@ -39,14 +40,14 @@ class DoCommandTest(CommandTest.CommandTest):
"Strict due:2014-01-01 rec:1d", "Strict due:2014-01-01 rec:1d",
] ]
self.todolist = TodoList.TodoList(todos) self.todolist = TodoList(todos)
self.today = date.today() self.today = date.today()
self.tomorrow = self.today + timedelta(1) self.tomorrow = self.today + timedelta(1)
self.today = self.today.isoformat() self.today = self.today.isoformat()
self.tomorrow = self.tomorrow.isoformat() self.tomorrow = self.tomorrow.isoformat()
def test_do1(self): def test_do1(self):
command = DoCommand.DoCommand(["3"], self.todolist, self.out, self.error, _no_prompt) command = DoCommand(["3"], self.todolist, self.out, self.error, _no_prompt)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -55,7 +56,7 @@ class DoCommandTest(CommandTest.CommandTest): ...@@ -55,7 +56,7 @@ class DoCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_do_subtasks1(self): def test_do_subtasks1(self):
command = DoCommand.DoCommand(["1"], self.todolist, self.out, self.error, _yes_prompt) command = DoCommand(["1"], self.todolist, self.out, self.error, _yes_prompt)
command.execute() command.execute()
result = "| 2| Bar p:1\n| 3| Baz p:1\nCompleted: x %s Bar p:1\nCompleted: x %s Baz p:1\nCompleted: x %s Foo id:1\n" % (self.today, self.today, self.today) result = "| 2| Bar p:1\n| 3| Baz p:1\nCompleted: x %s Bar p:1\nCompleted: x %s Baz p:1\nCompleted: x %s Foo id:1\n" % (self.today, self.today, self.today)
...@@ -69,7 +70,7 @@ class DoCommandTest(CommandTest.CommandTest): ...@@ -69,7 +70,7 @@ class DoCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_do_subtasks2(self): def test_do_subtasks2(self):
command = DoCommand.DoCommand(["1"], self.todolist, self.out, self.error, _no_prompt) command = DoCommand(["1"], self.todolist, self.out, self.error, _no_prompt)
command.execute() command.execute()
result = "| 2| Bar p:1\n| 3| Baz p:1\nCompleted: x %s Foo id:1\n" % self.today result = "| 2| Bar p:1\n| 3| Baz p:1\nCompleted: x %s Foo id:1\n" % self.today
...@@ -85,9 +86,10 @@ class DoCommandTest(CommandTest.CommandTest): ...@@ -85,9 +86,10 @@ class DoCommandTest(CommandTest.CommandTest):
prompt_shown = False prompt_shown = False
def prompt(p_prompt): def prompt(p_prompt):
global prompt_shown
prompt_shown = True prompt_shown = True
command = DoCommand.DoCommand(["-f", "1"], self.todolist, self.out, self.error, prompt) command = DoCommand(["-f", "1"], self.todolist, self.out, self.error, prompt)
command.execute() command.execute()
self.assertFalse(prompt_shown) self.assertFalse(prompt_shown)
...@@ -98,9 +100,10 @@ class DoCommandTest(CommandTest.CommandTest): ...@@ -98,9 +100,10 @@ class DoCommandTest(CommandTest.CommandTest):
prompt_shown = False prompt_shown = False
def prompt(p_prompt): def prompt(p_prompt):
global prompt_shown
prompt_shown = True prompt_shown = True
command = DoCommand.DoCommand(["--force", "1"], self.todolist, self.out, self.error, prompt) command = DoCommand(["--force", "1"], self.todolist, self.out, self.error, prompt)
command.execute() command.execute()
self.assertFalse(prompt_shown) self.assertFalse(prompt_shown)
...@@ -108,7 +111,7 @@ class DoCommandTest(CommandTest.CommandTest): ...@@ -108,7 +111,7 @@ class DoCommandTest(CommandTest.CommandTest):
self.assertFalse(self.todolist.todo(2).is_completed()) self.assertFalse(self.todolist.todo(2).is_completed())
def _recurrence_helper(self, p_flags): def _recurrence_helper(self, p_flags):
command = DoCommand.DoCommand(p_flags, self.todolist, self.out, self.error) command = DoCommand(p_flags, self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -130,17 +133,17 @@ class DoCommandTest(CommandTest.CommandTest): ...@@ -130,17 +133,17 @@ class DoCommandTest(CommandTest.CommandTest):
def test_strict_recurrence1(self): def test_strict_recurrence1(self):
self._recurrence_helper(["-s", "8"]) self._recurrence_helper(["-s", "8"])
result = "| 9| 2014-11-19 Strict due:2014-01-02 rec:1d\nCompleted: x 2014-11-19 Strict due:2014-01-01 rec:1d\n" result = "| 9| %s Strict due:2014-01-02 rec:1d\nCompleted: x %s Strict due:2014-01-01 rec:1d\n" % (self.today, self.today)
self.assertEquals(self.output, result) self.assertEquals(self.output, result)
def test_strict_recurrence2(self): def test_strict_recurrence2(self):
self._recurrence_helper(["--strict", "8"]) self._recurrence_helper(["--strict", "8"])
result = "| 9| 2014-11-19 Strict due:2014-01-02 rec:1d\nCompleted: x 2014-11-19 Strict due:2014-01-01 rec:1d\n" result = "| 9| %s Strict due:2014-01-02 rec:1d\nCompleted: x %s Strict due:2014-01-01 rec:1d\n" % (self.today, self.today)
self.assertEquals(self.output, result) self.assertEquals(self.output, result)
def test_invalid1(self): def test_invalid1(self):
command = DoCommand.DoCommand(["99"], self.todolist, self.out, self.error) command = DoCommand(["99"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -148,7 +151,15 @@ class DoCommandTest(CommandTest.CommandTest): ...@@ -148,7 +151,15 @@ class DoCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "Invalid todo number given.\n") self.assertEquals(self.errors, "Invalid todo number given.\n")
def test_invalid2(self): def test_invalid2(self):
command = DoCommand.DoCommand(["AAA"], self.todolist, self.out, self.error) command = DoCommand(["AAA"], self.todolist, self.out, self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertFalse(self.output)
self.assertEquals(self.errors, "Invalid todo number given.\n")
def test_invalid3(self):
command = DoCommand(["01"], self.todolist, self.out, self.error, _yes_prompt)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -156,7 +167,7 @@ class DoCommandTest(CommandTest.CommandTest): ...@@ -156,7 +167,7 @@ class DoCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "Invalid todo number given.\n") self.assertEquals(self.errors, "Invalid todo number given.\n")
def test_activated_todos1(self): def test_activated_todos1(self):
command = DoCommand.DoCommand(["2"], self.todolist, self.out, self.error) command = DoCommand(["2"], self.todolist, self.out, self.error)
command.execute() command.execute()
first_output = "Completed: x %s Bar p:1\n" % self.today first_output = "Completed: x %s Bar p:1\n" % self.today
...@@ -164,21 +175,21 @@ class DoCommandTest(CommandTest.CommandTest): ...@@ -164,21 +175,21 @@ class DoCommandTest(CommandTest.CommandTest):
self.assertEquals(self.output, first_output) self.assertEquals(self.output, first_output)
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
command = DoCommand.DoCommand(["3"], self.todolist, self.out, self.error) command = DoCommand(["3"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.output, first_output + "Completed: x %s Baz p:1\nThe following todo item(s) became active:\n| 1| Foo id:1\n" % self.today) self.assertEquals(self.output, first_output + "Completed: x %s Baz p:1\nThe following todo item(s) became active:\n| 1| Foo id:1\n" % self.today)
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_activated_todos2(self): def test_activated_todos2(self):
command = DoCommand.DoCommand(["7"], self.todolist, self.out, self.error) command = DoCommand(["7"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.output, "Completed: x %s Subtodo of inactive p:2\n" % self.today) self.assertEquals(self.output, "Completed: x %s Subtodo of inactive p:2\n" % self.today)
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_already_complete(self): def test_already_complete(self):
command = DoCommand.DoCommand(["5"], self.todolist, self.out, self.error) command = DoCommand(["5"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -187,7 +198,7 @@ class DoCommandTest(CommandTest.CommandTest): ...@@ -187,7 +198,7 @@ class DoCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "Todo has already been completed.\n") self.assertEquals(self.errors, "Todo has already been completed.\n")
def test_do_regex1(self): def test_do_regex1(self):
command = DoCommand.DoCommand(["baz"], self.todolist, self.out, self.error) command = DoCommand(["baz"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -196,7 +207,7 @@ class DoCommandTest(CommandTest.CommandTest): ...@@ -196,7 +207,7 @@ class DoCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_do_custom_date1(self): def test_do_custom_date1(self):
command = DoCommand.DoCommand(["-d", "2014-11-18", "3"], self.todolist, self.out, self.error) command = DoCommand(["-d", "2014-11-18", "3"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -204,7 +215,7 @@ class DoCommandTest(CommandTest.CommandTest): ...@@ -204,7 +215,7 @@ class DoCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_do_custom_date2(self): def test_do_custom_date2(self):
command = DoCommand.DoCommand(["-d", "2014-11-18", "1"], self.todolist, self.out, self.error, _yes_prompt) command = DoCommand(["-d", "2014-11-18", "1"], self.todolist, self.out, self.error, _yes_prompt)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -212,7 +223,7 @@ class DoCommandTest(CommandTest.CommandTest): ...@@ -212,7 +223,7 @@ class DoCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_do_custom_date3(self): def test_do_custom_date3(self):
command = DoCommand.DoCommand(["--date=2014-11-18", "3"], self.todolist, self.out, self.error) command = DoCommand(["--date=2014-11-18", "3"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -220,15 +231,15 @@ class DoCommandTest(CommandTest.CommandTest): ...@@ -220,15 +231,15 @@ class DoCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_do_custom_date4(self): def test_do_custom_date4(self):
command = DoCommand.DoCommand(["-d", "foo", "3"], self.todolist, self.out, self.error) command = DoCommand(["-d", "foo", "3"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.output, "Completed: x 2014-11-19 Baz p:1\n") self.assertEquals(self.output, "Completed: x %s Baz p:1\n" % self.today)
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_empty(self): def test_empty(self):
command = DoCommand.DoCommand([], self.todolist, self.out, self.error) command = DoCommand([], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -236,7 +247,7 @@ class DoCommandTest(CommandTest.CommandTest): ...@@ -236,7 +247,7 @@ class DoCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, command.usage() + "\n") self.assertEquals(self.errors, command.usage() + "\n")
def test_help(self): def test_help(self):
command = DoCommand.DoCommand(["help"], self.todolist, self.out, self.error) command = DoCommand(["help"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.output, "") self.assertEquals(self.output, "")
......
# Topydo - A todo.txt client written in Python. # Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl> # Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
...@@ -19,14 +19,13 @@ ...@@ -19,14 +19,13 @@
from datetime import date, timedelta from datetime import date, timedelta
import unittest import unittest
import Filter from topydo.lib import Filter
from TestFacilities import * from TestFacilities import load_file, todolist_to_string, load_file_to_todolist
import Todo from topydo.lib.Todo import Todo
import TodoList
class FilterTest(unittest.TestCase): class FilterTest(unittest.TestCase):
def test_filter3(self): def test_filter3(self):
todo = Todo.Todo("(C) Relevant") todo = Todo("(C) Relevant")
relevance = Filter.RelevanceFilter() relevance = Filter.RelevanceFilter()
result = relevance.filter([todo]) result = relevance.filter([todo])
...@@ -194,16 +193,15 @@ class FilterTest(unittest.TestCase): ...@@ -194,16 +193,15 @@ class FilterTest(unittest.TestCase):
self.assertEquals(todolist_to_string(filtered_todos), \ self.assertEquals(todolist_to_string(filtered_todos), \
todolist_to_string(reference)) todolist_to_string(reference))
def test_filter20(self): def test_filter20(self):
todos = load_file('data/FilterTest3.txt') todos = load_file('data/FilterTest3.txt')
otf = Filter.OrdinalTagFilter('due:=2014-11-10') otf = Filter.OrdinalTagFilter('due:=2014-11-10')
filtered_todos = otf.filter(todos) filtered_todos = otf.filter(todos)
reference = load_file('data/FilterTest6-result.txt')
self.assertEquals(todolist_to_string(filtered_todos), "") self.assertEquals(todolist_to_string(filtered_todos), "")
def test_filter21(self): def test_filter21(self):
todos = load_file('data/FilterTest3.txt') todos = load_file('data/FilterTest3.txt')
otf = Filter.OrdinalTagFilter('due:=2014-11-10') otf = Filter.OrdinalTagFilter('due:=2014-11-10')
...@@ -211,7 +209,7 @@ class FilterTest(unittest.TestCase): ...@@ -211,7 +209,7 @@ class FilterTest(unittest.TestCase):
filtered_todos = otf.filter(todos) filtered_todos = otf.filter(todos)
self.assertEquals(todolist_to_string(filtered_todos), "") self.assertEquals(todolist_to_string(filtered_todos), "")
def test_filter22(self): def test_filter22(self):
todos = load_file('data/FilterTest3.txt') todos = load_file('data/FilterTest3.txt')
otf = Filter.OrdinalTagFilter('due:=2014-11-99') otf = Filter.OrdinalTagFilter('due:=2014-11-99')
...@@ -305,10 +303,10 @@ class OrdinalTagFilterTest(unittest.TestCase): ...@@ -305,10 +303,10 @@ class OrdinalTagFilterTest(unittest.TestCase):
self.tomorrow = tomorrow.isoformat() self.tomorrow = tomorrow.isoformat()
self.todos = [ self.todos = [
Todo.Todo("Foo due:%s" % self.today), Todo("Foo due:%s" % self.today),
Todo.Todo("Bar due:%s" % self.tomorrow), Todo("Bar due:%s" % self.tomorrow),
Todo.Todo("Baz due:nonsense"), Todo("Baz due:nonsense"),
Todo.Todo("Fnord due:2014-10-32") Todo("Fnord due:2014-10-32")
] ]
def test_filter1(self): def test_filter1(self):
......
# Topydo - A todo.txt client written in Python. # Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl> # Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import unittest import unittest
import Graph from topydo.lib.Graph import DirectedGraph
class GraphTest(unittest.TestCase): class GraphTest(unittest.TestCase):
def setUp(self): def setUp(self):
self.graph = Graph.DirectedGraph() self.graph = DirectedGraph()
self.graph.add_edge(1, 2, 1) self.graph.add_edge(1, 2, 1)
self.graph.add_edge(2, 4, "Test") self.graph.add_edge(2, 4, "Test")
......
# Topydo - A todo.txt client written in Python. # Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl> # Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from datetime import date from datetime import date
import unittest import unittest
from Config import config from topydo.lib.Config import config
from Importance import importance from topydo.lib.Importance import importance
import Todo from topydo.lib.Todo import Todo
class ImportanceTest(unittest.TestCase): class ImportanceTest(unittest.TestCase):
def test_importance1(self): def test_importance1(self):
todo = Todo.Todo("Foo") todo = Todo("Foo")
self.assertEqual(importance(todo), 2) self.assertEqual(importance(todo), 2)
def test_importance2(self): def test_importance2(self):
todo = Todo.Todo("(A) Foo") todo = Todo("(A) Foo")
self.assertEqual(importance(todo), 5) self.assertEqual(importance(todo), 5)
def test_importance3(self): def test_importance3(self):
todo = Todo.Todo("(A) Foo " + config().tag_star() + ":1") todo = Todo("(A) Foo " + config().tag_star() + ":1")
self.assertEqual(importance(todo), 6) self.assertEqual(importance(todo), 6)
def test_importance4(self): def test_importance4(self):
today_str = date.today().isoformat() today_str = date.today().isoformat()
todo = Todo.Todo("(C) Foo " + config().tag_due() + ":" + today_str) todo = Todo("(C) Foo " + config().tag_due() + ":" + today_str)
self.assertEqual(importance(todo), 8) self.assertEqual(importance(todo), 8)
...@@ -14,13 +14,14 @@ ...@@ -14,13 +14,14 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from Config import config, _Config from topydo.lib.Config import config
import CommandTest import CommandTest
import ListCommand from topydo.lib.ListCommand import ListCommand
import TestFacilities import TestFacilities
class ListCommandTest(CommandTest.CommandTest): class ListCommandTest(CommandTest.CommandTest):
def setUp(self): def setUp(self):
super(ListCommandTest, self).setUp()
self.todolist = TestFacilities.load_file_to_todolist("data/ListCommandTest.txt") self.todolist = TestFacilities.load_file_to_todolist("data/ListCommandTest.txt")
def tearDown(self): def tearDown(self):
...@@ -28,7 +29,7 @@ class ListCommandTest(CommandTest.CommandTest): ...@@ -28,7 +29,7 @@ class ListCommandTest(CommandTest.CommandTest):
config("") config("")
def test_list1(self): def test_list1(self):
command = ListCommand.ListCommand([""], self.todolist, self.out, self.error) command = ListCommand([""], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -36,7 +37,7 @@ class ListCommandTest(CommandTest.CommandTest): ...@@ -36,7 +37,7 @@ class ListCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_list3(self): def test_list3(self):
command = ListCommand.ListCommand(["Context1"], self.todolist, self.out, self.error) command = ListCommand(["Context1"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -44,7 +45,7 @@ class ListCommandTest(CommandTest.CommandTest): ...@@ -44,7 +45,7 @@ class ListCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_list4(self): def test_list4(self):
command = ListCommand.ListCommand(["-x", "Context1"], self.todolist, self.out, self.error) command = ListCommand(["-x", "Context1"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -52,7 +53,7 @@ class ListCommandTest(CommandTest.CommandTest): ...@@ -52,7 +53,7 @@ class ListCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_list5(self): def test_list5(self):
command = ListCommand.ListCommand(["-x"], self.todolist, self.out, self.error) command = ListCommand(["-x"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -60,7 +61,7 @@ class ListCommandTest(CommandTest.CommandTest): ...@@ -60,7 +61,7 @@ class ListCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_list6(self): def test_list6(self):
command = ListCommand.ListCommand(["Project3"], self.todolist, self.out, self.error) command = ListCommand(["Project3"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -68,7 +69,7 @@ class ListCommandTest(CommandTest.CommandTest): ...@@ -68,7 +69,7 @@ class ListCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_list7(self): def test_list7(self):
command = ListCommand.ListCommand(["-s", "text", "-x", "Project1"], self.todolist, self.out, self.error) command = ListCommand(["-s", "text", "-x", "Project1"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -76,7 +77,7 @@ class ListCommandTest(CommandTest.CommandTest): ...@@ -76,7 +77,7 @@ class ListCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_list8(self): def test_list8(self):
command = ListCommand.ListCommand(["--", "-project1"], self.todolist, self.out, self.error) command = ListCommand(["--", "-project1"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -84,7 +85,7 @@ class ListCommandTest(CommandTest.CommandTest): ...@@ -84,7 +85,7 @@ class ListCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_list9(self): def test_list9(self):
command = ListCommand.ListCommand(["--", "-project1", "-Drink"], self.todolist, self.out, self.error) command = ListCommand(["--", "-project1", "-Drink"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -92,7 +93,7 @@ class ListCommandTest(CommandTest.CommandTest): ...@@ -92,7 +93,7 @@ class ListCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_list10(self): def test_list10(self):
command = ListCommand.ListCommand(["text1", "2"], self.todolist, self.out, self.error) command = ListCommand(["text1", "2"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -102,7 +103,7 @@ class ListCommandTest(CommandTest.CommandTest): ...@@ -102,7 +103,7 @@ class ListCommandTest(CommandTest.CommandTest):
def test_list11(self): def test_list11(self):
config("data/listcommand.conf") config("data/listcommand.conf")
command = ListCommand.ListCommand(["project"], self.todolist, self.out, self.error) command = ListCommand(["project"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -112,7 +113,7 @@ class ListCommandTest(CommandTest.CommandTest): ...@@ -112,7 +113,7 @@ class ListCommandTest(CommandTest.CommandTest):
def test_list12(self): def test_list12(self):
config("data/listcommand.conf") config("data/listcommand.conf")
command = ListCommand.ListCommand(["-x", "project"], self.todolist, self.out, self.error) command = ListCommand(["-x", "project"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -120,7 +121,7 @@ class ListCommandTest(CommandTest.CommandTest): ...@@ -120,7 +121,7 @@ class ListCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_list13(self): def test_list13(self):
command = ListCommand.ListCommand(["-x", "--", "-@Context1 +Project2"], self.todolist, self.out, self.error) command = ListCommand(["-x", "--", "-@Context1 +Project2"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -130,7 +131,7 @@ class ListCommandTest(CommandTest.CommandTest): ...@@ -130,7 +131,7 @@ class ListCommandTest(CommandTest.CommandTest):
def test_list14(self): def test_list14(self):
config("data/listcommand2.conf") config("data/listcommand2.conf")
command = ListCommand.ListCommand([], self.todolist, self.out, self.error) command = ListCommand([], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -138,7 +139,7 @@ class ListCommandTest(CommandTest.CommandTest): ...@@ -138,7 +139,7 @@ class ListCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_list15(self): def test_list15(self):
command = ListCommand.ListCommand(["p:<10"], self.todolist, self.out, self.error) command = ListCommand(["p:<10"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -148,15 +149,23 @@ class ListCommandTest(CommandTest.CommandTest): ...@@ -148,15 +149,23 @@ class ListCommandTest(CommandTest.CommandTest):
def test_list16(self): def test_list16(self):
config("data/todolist-uid.conf") config("data/todolist-uid.conf")
command = ListCommand.ListCommand([], self.todolist, self.out, self.error) command = ListCommand([], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "|6iu| (C) Foo @Context2 Not@Context +Project1 Not+Project\n|til| (C) Drink beer @ home\n| c5| (C) 13 + 29 = 42\n|xvb| (D) Bar @Context1 +Project2 p:1\n") self.assertEquals(self.output, "|6iu| (C) Foo @Context2 Not@Context +Project1 Not+Project\n|til| (C) Drink beer @ home\n| c5| (C) 13 + 29 = 42\n|xvb| (D) Bar @Context1 +Project2 p:1\n")
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_list17(self):
command = ListCommand(["-x", "id:"], self.todolist, self.out, self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEquals(self.output, "| 3| (C) Baz @Context1 +Project1 key:value id:1\n")
self.assertEquals(self.errors, "")
def test_help(self): def test_help(self):
command = ListCommand.ListCommand(["help"], self.todolist, self.out, self.error) command = ListCommand(["help"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.output, "") self.assertEquals(self.output, "")
......
# Topydo - A todo.txt client written in Python. # Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl> # Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import CommandTest import CommandTest
import TestFacilities import TestFacilities
import ListContextCommand from topydo.lib.ListContextCommand import ListContextCommand
class ListContextCommandTest(CommandTest.CommandTest): class ListContextCommandTest(CommandTest.CommandTest):
def test_contexts1(self): def test_contexts1(self):
todolist = TestFacilities.load_file_to_todolist("data/TodoListTest.txt") todolist = TestFacilities.load_file_to_todolist("data/TodoListTest.txt")
command = ListContextCommand.ListContextCommand([""], todolist, self.out, self.error) command = ListContextCommand([""], todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.output,"Context1\nContext2\n") self.assertEquals(self.output,"Context1\nContext2\n")
...@@ -29,14 +29,14 @@ class ListContextCommandTest(CommandTest.CommandTest): ...@@ -29,14 +29,14 @@ class ListContextCommandTest(CommandTest.CommandTest):
def test_contexts2(self): def test_contexts2(self):
todolist = TestFacilities.load_file_to_todolist("data/TodoListTest.txt") todolist = TestFacilities.load_file_to_todolist("data/TodoListTest.txt")
command = ListContextCommand.ListContextCommand(["aaa"], todolist, self.out, self.error) command = ListContextCommand(["aaa"], todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.output,"Context1\nContext2\n") self.assertEquals(self.output,"Context1\nContext2\n")
self.assertFalse(self.errors) self.assertFalse(self.errors)
def test_help(self): def test_help(self):
command = ListContextCommand.ListContextCommand(["help"], None, self.out, self.error) command = ListContextCommand(["help"], None, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.output, "") self.assertEquals(self.output, "")
......
# Topydo - A todo.txt client written in Python. # Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl> # Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import CommandTest import CommandTest
import TestFacilities import TestFacilities
import ListProjectCommand from topydo.lib.ListProjectCommand import ListProjectCommand
class ListProjectCommandTest(CommandTest.CommandTest): class ListProjectCommandTest(CommandTest.CommandTest):
def test_projects1(self): def test_projects1(self):
todolist = TestFacilities.load_file_to_todolist("data/TodoListTest.txt") todolist = TestFacilities.load_file_to_todolist("data/TodoListTest.txt")
command = ListProjectCommand.ListProjectCommand([""], todolist, self.out, self.error) command = ListProjectCommand([""], todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.output,"Project1\nProject2\n") self.assertEquals(self.output,"Project1\nProject2\n")
...@@ -29,14 +29,14 @@ class ListProjectCommandTest(CommandTest.CommandTest): ...@@ -29,14 +29,14 @@ class ListProjectCommandTest(CommandTest.CommandTest):
def test_projects2(self): def test_projects2(self):
todolist = TestFacilities.load_file_to_todolist("data/TodoListTest.txt") todolist = TestFacilities.load_file_to_todolist("data/TodoListTest.txt")
command = ListProjectCommand.ListProjectCommand(["aaa"], todolist, self.out, self.error) command = ListProjectCommand(["aaa"], todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.output,"Project1\nProject2\n") self.assertEquals(self.output,"Project1\nProject2\n")
self.assertFalse(self.errors) self.assertFalse(self.errors)
def test_help(self): def test_help(self):
command = ListProjectCommand.ListProjectCommand(["help"], None, self.out, self.error) command = ListProjectCommand(["help"], None, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.output, "") self.assertEquals(self.output, "")
......
...@@ -17,11 +17,12 @@ ...@@ -17,11 +17,12 @@
from datetime import date, timedelta from datetime import date, timedelta
import CommandTest import CommandTest
import PostponeCommand from topydo.lib.PostponeCommand import PostponeCommand
import TodoList from topydo.lib.TodoList import TodoList
class PostponeCommandTest(CommandTest.CommandTest): class PostponeCommandTest(CommandTest.CommandTest):
def setUp(self): def setUp(self):
super(PostponeCommandTest, self).setUp()
self.today = date.today() self.today = date.today()
self.past = date.today() - timedelta(1) self.past = date.today() - timedelta(1)
self.future = date.today() + timedelta(1) self.future = date.today() + timedelta(1)
...@@ -36,10 +37,10 @@ class PostponeCommandTest(CommandTest.CommandTest): ...@@ -36,10 +37,10 @@ class PostponeCommandTest(CommandTest.CommandTest):
"Future due:%s t:%s" % (self.future.isoformat(), self.future_start.isoformat()), "Future due:%s t:%s" % (self.future.isoformat(), self.future_start.isoformat()),
] ]
self.todolist = TodoList.TodoList(todos) self.todolist = TodoList(todos)
def test_postpone1(self): def test_postpone1(self):
command = PostponeCommand.PostponeCommand(["1", "1w"], self.todolist, self.out, self.error) command = PostponeCommand(["1", "1w"], self.todolist, self.out, self.error)
command.execute() command.execute()
due = self.today + timedelta(7) due = self.today + timedelta(7)
...@@ -49,7 +50,7 @@ class PostponeCommandTest(CommandTest.CommandTest): ...@@ -49,7 +50,7 @@ class PostponeCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_postpone2(self): def test_postpone2(self):
command = PostponeCommand.PostponeCommand(["2", "1w"], self.todolist, self.out, self.error) command = PostponeCommand(["2", "1w"], self.todolist, self.out, self.error)
command.execute() command.execute()
due = self.today + timedelta(7) due = self.today + timedelta(7)
...@@ -59,7 +60,7 @@ class PostponeCommandTest(CommandTest.CommandTest): ...@@ -59,7 +60,7 @@ class PostponeCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_postpone3(self): def test_postpone3(self):
command = PostponeCommand.PostponeCommand(["-s", "2", "1w"], self.todolist, self.out, self.error) command = PostponeCommand(["-s", "2", "1w"], self.todolist, self.out, self.error)
command.execute() command.execute()
due = self.today + timedelta(7) due = self.today + timedelta(7)
...@@ -69,7 +70,7 @@ class PostponeCommandTest(CommandTest.CommandTest): ...@@ -69,7 +70,7 @@ class PostponeCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_postpone4(self): def test_postpone4(self):
command = PostponeCommand.PostponeCommand(["3", "1w"], self.todolist, self.out, self.error) command = PostponeCommand(["3", "1w"], self.todolist, self.out, self.error)
command.execute() command.execute()
due = self.today + timedelta(7) due = self.today + timedelta(7)
...@@ -79,7 +80,7 @@ class PostponeCommandTest(CommandTest.CommandTest): ...@@ -79,7 +80,7 @@ class PostponeCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_postpone5(self): def test_postpone5(self):
command = PostponeCommand.PostponeCommand(["-s", "3", "1w"], self.todolist, self.out, self.error) command = PostponeCommand(["-s", "3", "1w"], self.todolist, self.out, self.error)
command.execute() command.execute()
due = self.today + timedelta(7) due = self.today + timedelta(7)
...@@ -90,7 +91,7 @@ class PostponeCommandTest(CommandTest.CommandTest): ...@@ -90,7 +91,7 @@ class PostponeCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_postpone6(self): def test_postpone6(self):
command = PostponeCommand.PostponeCommand(["4", "1w"], self.todolist, self.out, self.error) command = PostponeCommand(["4", "1w"], self.todolist, self.out, self.error)
command.execute() command.execute()
due = self.today + timedelta(7) due = self.today + timedelta(7)
...@@ -100,7 +101,7 @@ class PostponeCommandTest(CommandTest.CommandTest): ...@@ -100,7 +101,7 @@ class PostponeCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_postpone7(self): def test_postpone7(self):
command = PostponeCommand.PostponeCommand(["5", "1w"], self.todolist, self.out, self.error) command = PostponeCommand(["5", "1w"], self.todolist, self.out, self.error)
command.execute() command.execute()
due = self.future + timedelta(7) due = self.future + timedelta(7)
...@@ -110,7 +111,7 @@ class PostponeCommandTest(CommandTest.CommandTest): ...@@ -110,7 +111,7 @@ class PostponeCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_postpone8(self): def test_postpone8(self):
command = PostponeCommand.PostponeCommand(["-s", "5", "1w"], self.todolist, self.out, self.error) command = PostponeCommand(["-s", "5", "1w"], self.todolist, self.out, self.error)
command.execute() command.execute()
due = self.future + timedelta(7) due = self.future + timedelta(7)
...@@ -121,7 +122,7 @@ class PostponeCommandTest(CommandTest.CommandTest): ...@@ -121,7 +122,7 @@ class PostponeCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_postpone9(self): def test_postpone9(self):
command = PostponeCommand.PostponeCommand(["1", "foo"], self.todolist, self.out, self.error) command = PostponeCommand(["1", "foo"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -129,7 +130,7 @@ class PostponeCommandTest(CommandTest.CommandTest): ...@@ -129,7 +130,7 @@ class PostponeCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "Invalid date pattern given.\n") self.assertEquals(self.errors, "Invalid date pattern given.\n")
def test_postpone10(self): def test_postpone10(self):
command = PostponeCommand.PostponeCommand(["99", "foo"], self.todolist, self.out, self.error) command = PostponeCommand(["99", "foo"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -137,7 +138,7 @@ class PostponeCommandTest(CommandTest.CommandTest): ...@@ -137,7 +138,7 @@ class PostponeCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "Invalid todo number given.\n") self.assertEquals(self.errors, "Invalid todo number given.\n")
def test_postpone11(self): def test_postpone11(self):
command = PostponeCommand.PostponeCommand(["A", "foo"], self.todolist, self.out, self.error) command = PostponeCommand(["A", "foo"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -145,7 +146,7 @@ class PostponeCommandTest(CommandTest.CommandTest): ...@@ -145,7 +146,7 @@ class PostponeCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "Invalid todo number given.\n") self.assertEquals(self.errors, "Invalid todo number given.\n")
def test_postpone12(self): def test_postpone12(self):
command = PostponeCommand.PostponeCommand(["1"], self.todolist, self.out, self.error) command = PostponeCommand(["1"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -153,7 +154,7 @@ class PostponeCommandTest(CommandTest.CommandTest): ...@@ -153,7 +154,7 @@ class PostponeCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, command.usage() + "\n") self.assertEquals(self.errors, command.usage() + "\n")
def test_postpone13(self): def test_postpone13(self):
command = PostponeCommand.PostponeCommand(["Foo", "1w"], self.todolist, self.out, self.error) command = PostponeCommand(["Foo", "1w"], self.todolist, self.out, self.error)
command.execute() command.execute()
due = self.today + timedelta(7) due = self.today + timedelta(7)
...@@ -163,7 +164,7 @@ class PostponeCommandTest(CommandTest.CommandTest): ...@@ -163,7 +164,7 @@ class PostponeCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_help(self): def test_help(self):
command = PostponeCommand.PostponeCommand(["help"], self.todolist, self.out, self.error) command = PostponeCommand(["help"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.output, "") self.assertEquals(self.output, "")
......
...@@ -15,20 +15,21 @@ ...@@ -15,20 +15,21 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import CommandTest import CommandTest
import PriorityCommand from topydo.lib.PriorityCommand import PriorityCommand
import TodoList from topydo.lib.TodoList import TodoList
class PriorityCommandTest(CommandTest.CommandTest): class PriorityCommandTest(CommandTest.CommandTest):
def setUp(self): def setUp(self):
super(PriorityCommandTest, self).setUp()
todos = [ todos = [
"(A) Foo", "(A) Foo",
"Bar", "Bar",
] ]
self.todolist = TodoList.TodoList(todos) self.todolist = TodoList(todos)
def test_set_prio1(self): def test_set_prio1(self):
command = PriorityCommand.PriorityCommand(["1", "B"], self.todolist, self.out, self.error) command = PriorityCommand(["1", "B"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -36,7 +37,7 @@ class PriorityCommandTest(CommandTest.CommandTest): ...@@ -36,7 +37,7 @@ class PriorityCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_set_prio2(self): def test_set_prio2(self):
command = PriorityCommand.PriorityCommand(["2", "Z"], self.todolist, self.out, self.error) command = PriorityCommand(["2", "Z"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -44,7 +45,7 @@ class PriorityCommandTest(CommandTest.CommandTest): ...@@ -44,7 +45,7 @@ class PriorityCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_set_prio3(self): def test_set_prio3(self):
command = PriorityCommand.PriorityCommand(["Foo", "B"], self.todolist, self.out, self.error) command = PriorityCommand(["Foo", "B"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -52,7 +53,7 @@ class PriorityCommandTest(CommandTest.CommandTest): ...@@ -52,7 +53,7 @@ class PriorityCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_set_prio4(self): def test_set_prio4(self):
command = PriorityCommand.PriorityCommand(["1", "A"], self.todolist, self.out, self.error) command = PriorityCommand(["1", "A"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -60,7 +61,7 @@ class PriorityCommandTest(CommandTest.CommandTest): ...@@ -60,7 +61,7 @@ class PriorityCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_invalid1(self): def test_invalid1(self):
command = PriorityCommand.PriorityCommand(["99", "A"], self.todolist, self.out, self.error) command = PriorityCommand(["99", "A"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -68,7 +69,7 @@ class PriorityCommandTest(CommandTest.CommandTest): ...@@ -68,7 +69,7 @@ class PriorityCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "Invalid todo number given.\n") self.assertEquals(self.errors, "Invalid todo number given.\n")
def test_invalid2(self): def test_invalid2(self):
command = PriorityCommand.PriorityCommand(["1", "ZZ"], self.todolist, self.out, self.error) command = PriorityCommand(["1", "ZZ"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -76,7 +77,7 @@ class PriorityCommandTest(CommandTest.CommandTest): ...@@ -76,7 +77,7 @@ class PriorityCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "Invalid priority given.\n") self.assertEquals(self.errors, "Invalid priority given.\n")
def test_invalid3(self): def test_invalid3(self):
command = PriorityCommand.PriorityCommand(["A"], self.todolist, self.out, self.error) command = PriorityCommand(["A"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -84,7 +85,7 @@ class PriorityCommandTest(CommandTest.CommandTest): ...@@ -84,7 +85,7 @@ class PriorityCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, command.usage() + "\n") self.assertEquals(self.errors, command.usage() + "\n")
def test_invalid4(self): def test_invalid4(self):
command = PriorityCommand.PriorityCommand(["1"], self.todolist, self.out, self.error) command = PriorityCommand(["1"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -92,7 +93,7 @@ class PriorityCommandTest(CommandTest.CommandTest): ...@@ -92,7 +93,7 @@ class PriorityCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, command.usage() + "\n") self.assertEquals(self.errors, command.usage() + "\n")
def test_empty(self): def test_empty(self):
command = PriorityCommand.PriorityCommand([], self.todolist, self.out, self.error) command = PriorityCommand([], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -100,7 +101,7 @@ class PriorityCommandTest(CommandTest.CommandTest): ...@@ -100,7 +101,7 @@ class PriorityCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, command.usage() + "\n") self.assertEquals(self.errors, command.usage() + "\n")
def test_help(self): def test_help(self):
command = PriorityCommand.PriorityCommand(["help"], self.todolist, self.out, self.error) command = PriorityCommand(["help"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.output, "") self.assertEquals(self.output, "")
......
# Topydo - A todo.txt client written in Python. # Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl> # Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from datetime import date, timedelta from datetime import date, timedelta
import unittest import unittest
from Config import config from topydo.lib.Config import config
from Recurrence import advance_recurring_todo, strict_advance_recurring_todo, NoRecurrenceException from topydo.lib.Recurrence import advance_recurring_todo, strict_advance_recurring_todo, NoRecurrenceException
import Todo from topydo.lib.Todo import Todo
class RecurrenceTest(unittest.TestCase): class RecurrenceTest(unittest.TestCase):
def setUp(self): def setUp(self):
self.todo = Todo.Todo("Test rec:1w") self.todo = Todo("Test rec:1w")
def test_duedate1(self): def test_duedate1(self):
""" Where due date is in the future. """ """ Where due date is in the future. """
...@@ -99,7 +99,7 @@ class RecurrenceTest(unittest.TestCase): ...@@ -99,7 +99,7 @@ class RecurrenceTest(unittest.TestCase):
self.assertTrue(new_todo.has_tag(config().tag_due())) self.assertTrue(new_todo.has_tag(config().tag_due()))
self.assertEquals(new_todo.due_date(), new_due) self.assertEquals(new_todo.due_date(), new_due)
def test_startdate(self): def test_startdate1(self):
""" Start date is before due date. """ """ Start date is before due date. """
self.todo.set_tag(config().tag_due(), date.today().isoformat()) self.todo.set_tag(config().tag_due(), date.today().isoformat())
yesterday = date.today() - timedelta(1) yesterday = date.today() - timedelta(1)
...@@ -110,7 +110,7 @@ class RecurrenceTest(unittest.TestCase): ...@@ -110,7 +110,7 @@ class RecurrenceTest(unittest.TestCase):
self.assertEquals(new_todo.start_date(), new_start) self.assertEquals(new_todo.start_date(), new_start)
def test_startdate(self): def test_startdate2(self):
""" Strict recurrence. Start date is before due date. """ """ Strict recurrence. Start date is before due date. """
due = date.today() - timedelta(1) due = date.today() - timedelta(1)
self.todo.set_tag(config().tag_due(), date.today().isoformat()) self.todo.set_tag(config().tag_due(), date.today().isoformat())
...@@ -122,7 +122,7 @@ class RecurrenceTest(unittest.TestCase): ...@@ -122,7 +122,7 @@ class RecurrenceTest(unittest.TestCase):
self.assertEquals(new_todo.start_date(), new_start) self.assertEquals(new_todo.start_date(), new_start)
def test_startdate2(self): def test_startdate3(self):
""" Start date equals due date. """ """ Start date equals due date. """
self.todo.set_tag(config().tag_due(), date.today().isoformat()) self.todo.set_tag(config().tag_due(), date.today().isoformat())
self.todo.set_tag(config().tag_start(), date.today().isoformat()) self.todo.set_tag(config().tag_start(), date.today().isoformat())
......
# Topydo - A todo.txt client written in Python. # Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl> # Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from datetime import date, timedelta from datetime import date, timedelta
import unittest import unittest
import RelativeDate from topydo.lib.RelativeDate import relative_date_to_date
class RelativeDateTester(unittest.TestCase): class RelativeDateTester(unittest.TestCase):
def setUp(self): def setUp(self):
...@@ -29,82 +29,82 @@ class RelativeDateTester(unittest.TestCase): ...@@ -29,82 +29,82 @@ class RelativeDateTester(unittest.TestCase):
self.monday += timedelta(7 - self.today.weekday() % 7) self.monday += timedelta(7 - self.today.weekday() % 7)
def test_zero_days(self): def test_zero_days(self):
result = RelativeDate.relative_date_to_date('0d') result = relative_date_to_date('0d')
self.assertEquals(result, self.today) self.assertEquals(result, self.today)
def test_one_day(self): def test_one_day(self):
result = RelativeDate.relative_date_to_date('1d') result = relative_date_to_date('1d')
self.assertEquals(result, self.tomorrow) self.assertEquals(result, self.tomorrow)
def test_one_week(self): def test_one_week(self):
result = RelativeDate.relative_date_to_date('1w') result = relative_date_to_date('1w')
self.assertEquals(result, date.today() + timedelta(weeks=1)) self.assertEquals(result, date.today() + timedelta(weeks=1))
def test_one_month(self): def test_one_month(self):
result = RelativeDate.relative_date_to_date('1m') result = relative_date_to_date('1m')
self.assertEquals(result, date.today() + timedelta(30)) self.assertEquals(result, date.today() + timedelta(30))
def test_one_year(self): def test_one_year(self):
result = RelativeDate.relative_date_to_date('1y') result = relative_date_to_date('1y')
self.assertEquals(result, date.today() + timedelta(365)) self.assertEquals(result, date.today() + timedelta(365))
def test_zero_months(self): def test_zero_months(self):
result = RelativeDate.relative_date_to_date('0m') result = relative_date_to_date('0m')
self.assertEquals(result, self.today) self.assertEquals(result, self.today)
def test_zero_years(self): def test_zero_years(self):
result = RelativeDate.relative_date_to_date('0y') result = relative_date_to_date('0y')
self.assertEquals(result, self.today) self.assertEquals(result, self.today)
def test_garbage1(self): def test_garbage1(self):
result = RelativeDate.relative_date_to_date('0dd') result = relative_date_to_date('0dd')
self.assertFalse(result) self.assertFalse(result)
def test_garbage2(self): def test_garbage2(self):
result = RelativeDate.relative_date_to_date('-0d') result = relative_date_to_date('-0d')
self.assertFalse(result) self.assertFalse(result)
def test_one_day_capital(self): def test_one_day_capital(self):
result = RelativeDate.relative_date_to_date('1D') result = relative_date_to_date('1D')
self.assertEquals(result, self.tomorrow) self.assertEquals(result, self.tomorrow)
def test_today1(self): def test_today1(self):
result = RelativeDate.relative_date_to_date('today') result = relative_date_to_date('today')
self.assertEquals(result, self.today) self.assertEquals(result, self.today)
def test_today2(self): def test_today2(self):
result = RelativeDate.relative_date_to_date('tod') result = relative_date_to_date('tod')
self.assertEquals(result, self.today) self.assertEquals(result, self.today)
def test_today3(self): def test_today3(self):
result = RelativeDate.relative_date_to_date('today', \ result = relative_date_to_date('today', \
date.today() + timedelta(1)) date.today() + timedelta(1))
self.assertEquals(result, self.today) self.assertEquals(result, self.today)
def test_tomorrow1(self): def test_tomorrow1(self):
result = RelativeDate.relative_date_to_date('Tomorrow') result = relative_date_to_date('Tomorrow')
self.assertEquals(result, self.tomorrow) self.assertEquals(result, self.tomorrow)
def test_tomorrow2(self): def test_tomorrow2(self):
result = RelativeDate.relative_date_to_date('tom') result = relative_date_to_date('tom')
self.assertEquals(result, self.tomorrow) self.assertEquals(result, self.tomorrow)
def test_monday1(self): def test_monday1(self):
result = RelativeDate.relative_date_to_date('monday') result = relative_date_to_date('monday')
self.assertEquals(result, self.monday) self.assertEquals(result, self.monday)
def test_monday2(self): def test_monday2(self):
result = RelativeDate.relative_date_to_date('mo') result = relative_date_to_date('mo')
self.assertEquals(result, self.monday) self.assertEquals(result, self.monday)
def test_monday3(self): def test_monday3(self):
result = RelativeDate.relative_date_to_date('mon') result = relative_date_to_date('mon')
self.assertEquals(result, self.monday) self.assertEquals(result, self.monday)
def test_monday4(self): def test_monday4(self):
result = RelativeDate.relative_date_to_date('mondayy') result = relative_date_to_date('mondayy')
self.assertFalse(result) self.assertFalse(result)
def test_offset1(self): def test_offset1(self):
result = RelativeDate.relative_date_to_date('1d', self.tomorrow) result = relative_date_to_date('1d', self.tomorrow)
self.assertEquals(result, date.today() + timedelta(2)) self.assertEquals(result, date.today() + timedelta(2))
...@@ -15,12 +15,13 @@ ...@@ -15,12 +15,13 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import CommandTest import CommandTest
from Config import config from topydo.lib.Config import config
import SortCommand from topydo.lib.SortCommand import SortCommand
import TestFacilities import TestFacilities
class SortCommandTest(CommandTest.CommandTest): class SortCommandTest(CommandTest.CommandTest):
def setUp(self): def setUp(self):
super(SortCommandTest, self).setUp()
self.todolist = TestFacilities.load_file_to_todolist("data/SorterTest1.txt") self.todolist = TestFacilities.load_file_to_todolist("data/SorterTest1.txt")
def tearDown(self): def tearDown(self):
...@@ -29,13 +30,13 @@ class SortCommandTest(CommandTest.CommandTest): ...@@ -29,13 +30,13 @@ class SortCommandTest(CommandTest.CommandTest):
def test_sort1(self): def test_sort1(self):
""" Alphabetically sorted """ """ Alphabetically sorted """
command = SortCommand.SortCommand(["text"], self.todolist, self.out, self.error) command = SortCommand(["text"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(str(self.todolist), "First\n(A) Foo\n2014-06-14 Last") self.assertEquals(str(self.todolist), "First\n(A) Foo\n2014-06-14 Last")
def test_sort2(self): def test_sort2(self):
command = SortCommand.SortCommand([], self.todolist, self.out, self.error) command = SortCommand([], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(str(self.todolist), "(A) Foo\n2014-06-14 Last\nFirst") self.assertEquals(str(self.todolist), "(A) Foo\n2014-06-14 Last\nFirst")
...@@ -45,14 +46,14 @@ class SortCommandTest(CommandTest.CommandTest): ...@@ -45,14 +46,14 @@ class SortCommandTest(CommandTest.CommandTest):
config("data/todolist-uid.conf") config("data/todolist-uid.conf")
todo1 = self.todolist.todo('tpi') todo1 = self.todolist.todo('tpi')
command = SortCommand.SortCommand(["text"], self.todolist, self.out, self.error) command = SortCommand(["text"], self.todolist, self.out, self.error)
command.execute() command.execute()
todo2 = self.todolist.todo('tpi') todo2 = self.todolist.todo('tpi')
self.assertEquals(todo1.source(), todo2.source()) self.assertEquals(todo1.source(), todo2.source())
def test_help(self): def test_help(self):
command = SortCommand.SortCommand(["help"], self.todolist, self.out, self.error) command = SortCommand(["help"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.output, "") self.assertEquals(self.output, "")
......
...@@ -16,10 +16,8 @@ ...@@ -16,10 +16,8 @@
import unittest import unittest
from Config import config from topydo.lib.Config import config
import Sorter from topydo.lib.Sorter import Sorter
import TodoList
import View
from TestFacilities import load_file, todolist_to_string, load_file_to_todolist from TestFacilities import load_file, todolist_to_string, load_file_to_todolist
...@@ -39,21 +37,21 @@ class SorterTest(unittest.TestCase): ...@@ -39,21 +37,21 @@ class SorterTest(unittest.TestCase):
def test_sort1(self): def test_sort1(self):
""" Alphabetically sorted """ """ Alphabetically sorted """
sorter = Sorter.Sorter('text') sorter = Sorter('text')
self.sort_file('data/SorterTest1.txt', 'data/SorterTest1-result.txt', sorter) self.sort_file('data/SorterTest1.txt', 'data/SorterTest1-result.txt', sorter)
def test_sort2a(self): def test_sort2a(self):
""" """
Ascendingly sorted by priority. Also checks stableness of the sort. Ascendingly sorted by priority. Also checks stableness of the sort.
""" """
sorter = Sorter.Sorter('prio') sorter = Sorter('prio')
self.sort_file('data/SorterTest2.txt', 'data/SorterTest2-result.txt', sorter) self.sort_file('data/SorterTest2.txt', 'data/SorterTest2-result.txt', sorter)
def test_sort2b(self): def test_sort2b(self):
""" """
Ascendingly sorted by priority. Also checks stableness of the sort. Ascendingly sorted by priority. Also checks stableness of the sort.
""" """
sorter = Sorter.Sorter('asc:prio') sorter = Sorter('asc:prio')
self.sort_file('data/SorterTest2.txt', 'data/SorterTest2-result.txt', sorter) self.sort_file('data/SorterTest2.txt', 'data/SorterTest2-result.txt', sorter)
def test_sort3(self): def test_sort3(self):
...@@ -61,32 +59,32 @@ class SorterTest(unittest.TestCase): ...@@ -61,32 +59,32 @@ class SorterTest(unittest.TestCase):
Descendingly sorted by priority. Also checks stableness of the Descendingly sorted by priority. Also checks stableness of the
sort. sort.
""" """
sorter = Sorter.Sorter('desc:prio') sorter = Sorter('desc:prio')
self.sort_file('data/SorterTest3.txt', 'data/SorterTest3-result.txt', sorter) self.sort_file('data/SorterTest3.txt', 'data/SorterTest3-result.txt', sorter)
def test_sort4(self): def test_sort4(self):
""" Ascendingly sorted by due date """ """ Ascendingly sorted by due date """
sorter = Sorter.Sorter(config().tag_due()) sorter = Sorter(config().tag_due())
self.sort_file('data/SorterTest4.txt', 'data/SorterTest4-result.txt', sorter) self.sort_file('data/SorterTest4.txt', 'data/SorterTest4-result.txt', sorter)
def test_sort5(self): def test_sort5(self):
""" Descendingly sorted by due date """ """ Descendingly sorted by due date """
sorter = Sorter.Sorter('desc:due') sorter = Sorter('desc:due')
self.sort_file('data/SorterTest5.txt', 'data/SorterTest5-result.txt', sorter) self.sort_file('data/SorterTest5.txt', 'data/SorterTest5-result.txt', sorter)
def test_sort6(self): def test_sort6(self):
""" Ascendingly sorted by creation date """ """ Ascendingly sorted by creation date """
sorter = Sorter.Sorter('creation') sorter = Sorter('creation')
self.sort_file('data/SorterTest6.txt', 'data/SorterTest6-result.txt', sorter) self.sort_file('data/SorterTest6.txt', 'data/SorterTest6-result.txt', sorter)
def test_sort7(self): def test_sort7(self):
""" Ascendingly sorted by completion date. """ """ Ascendingly sorted by completion date. """
sorter = Sorter.Sorter('completion') sorter = Sorter('completion')
self.sort_file('data/SorterTest7.txt', 'data/SorterTest7-result.txt', sorter) self.sort_file('data/SorterTest7.txt', 'data/SorterTest7-result.txt', sorter)
def test_sort8(self): def test_sort8(self):
""" Descendingly sorted by importance """ """ Descendingly sorted by importance """
sorter = Sorter.Sorter('desc:importance') sorter = Sorter('desc:importance')
self.sort_file('data/SorterTest8.txt', 'data/SorterTest8-result.txt', sorter) self.sort_file('data/SorterTest8.txt', 'data/SorterTest8-result.txt', sorter)
def test_sort9(self): def test_sort9(self):
...@@ -94,22 +92,22 @@ class SorterTest(unittest.TestCase): ...@@ -94,22 +92,22 @@ class SorterTest(unittest.TestCase):
Sort on multiple levels: first descending importance, then Sort on multiple levels: first descending importance, then
ascending priority. ascending priority.
""" """
sorter = Sorter.Sorter('desc:importance,priority') sorter = Sorter('desc:importance,priority')
self.sort_file('data/SorterTest9.txt', 'data/SorterTest9-result.txt', sorter) self.sort_file('data/SorterTest9.txt', 'data/SorterTest9-result.txt', sorter)
def test_sort10(self): def test_sort10(self):
""" Deal with garbage input. """ """ Deal with garbage input. """
sorter = Sorter.Sorter('') sorter = Sorter('')
self.sort_file('data/SorterTest9.txt', 'data/SorterTest9.txt', sorter) self.sort_file('data/SorterTest9.txt', 'data/SorterTest9.txt', sorter)
def test_sort11(self): def test_sort11(self):
""" Deal with garbage input. """ """ Deal with garbage input. """
sorter = Sorter.Sorter('fnord') sorter = Sorter('fnord')
self.sort_file('data/SorterTest9.txt', 'data/SorterTest9.txt', sorter) self.sort_file('data/SorterTest9.txt', 'data/SorterTest9.txt', sorter)
def test_sort12(self): def test_sort12(self):
""" Deal with garbage input. """ """ Deal with garbage input. """
sorter = Sorter.Sorter('desc:importance,,priority') sorter = Sorter('desc:importance,,priority')
self.sort_file('data/SorterTest9.txt', 'data/SorterTest9-result.txt', sorter) self.sort_file('data/SorterTest9.txt', 'data/SorterTest9-result.txt', sorter)
def test_sort13(self): def test_sort13(self):
...@@ -119,11 +117,11 @@ class SorterTest(unittest.TestCase): ...@@ -119,11 +117,11 @@ class SorterTest(unittest.TestCase):
Reusing input and output for normal importance test, since without Reusing input and output for normal importance test, since without
dependencies the average importance should be equal. dependencies the average importance should be equal.
""" """
sorter = Sorter.Sorter('desc:importance-avg') sorter = Sorter('desc:importance-avg')
self.sort_file('data/SorterTest9.txt', 'data/SorterTest9-result.txt', sorter) self.sort_file('data/SorterTest9.txt', 'data/SorterTest9-result.txt', sorter)
def test_sort14(self): def test_sort14(self):
sorter = Sorter.Sorter('desc:importance-average') sorter = Sorter('desc:importance-average')
todolist = load_file_to_todolist('data/SorterTest10.txt') todolist = load_file_to_todolist('data/SorterTest10.txt')
view = todolist.view(sorter, []) view = todolist.view(sorter, [])
...@@ -136,7 +134,7 @@ class SorterTest(unittest.TestCase): ...@@ -136,7 +134,7 @@ class SorterTest(unittest.TestCase):
Test that own importance is used when average turns out to be Test that own importance is used when average turns out to be
lower. lower.
""" """
sorter = Sorter.Sorter('desc:importance-average') sorter = Sorter('desc:importance-average')
todolist = load_file_to_todolist('data/SorterTest11.txt') todolist = load_file_to_todolist('data/SorterTest11.txt')
view = todolist.view(sorter, []) view = todolist.view(sorter, [])
...@@ -148,7 +146,7 @@ class SorterTest(unittest.TestCase): ...@@ -148,7 +146,7 @@ class SorterTest(unittest.TestCase):
""" """
Check sort of low priority tasks (D or lower) with non-priority tasks. Check sort of low priority tasks (D or lower) with non-priority tasks.
""" """
sorter = Sorter.Sorter('desc:importance,desc:prio') sorter = Sorter('desc:importance,desc:prio')
todolist = load_file_to_todolist('data/SorterTest12.txt') todolist = load_file_to_todolist('data/SorterTest12.txt')
view = todolist.view(sorter, []) view = todolist.view(sorter, [])
......
...@@ -15,11 +15,12 @@ ...@@ -15,11 +15,12 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import CommandTest import CommandTest
import TagCommand from topydo.lib.TagCommand import TagCommand
import TodoList from topydo.lib.TodoList import TodoList
class TagCommandTest(CommandTest.CommandTest): class TagCommandTest(CommandTest.CommandTest):
def setUp(self): def setUp(self):
super(TagCommandTest, self).setUp()
todos = [ todos = [
"Foo", "Foo",
"Bar due:2014-10-22", "Bar due:2014-10-22",
...@@ -27,10 +28,10 @@ class TagCommandTest(CommandTest.CommandTest): ...@@ -27,10 +28,10 @@ class TagCommandTest(CommandTest.CommandTest):
"Fnord due:2014-10-20 due:2014-10-22", "Fnord due:2014-10-20 due:2014-10-22",
] ]
self.todolist = TodoList.TodoList(todos) self.todolist = TodoList(todos)
def test_add_tag1(self): def test_add_tag1(self):
command = TagCommand.TagCommand(["1", "due", "2014-10-22"], self.todolist, self.out, self.error) command = TagCommand(["1", "due", "2014-10-22"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.todolist.todo(1).source(), "Foo due:2014-10-22") self.assertEquals(self.todolist.todo(1).source(), "Foo due:2014-10-22")
...@@ -39,7 +40,7 @@ class TagCommandTest(CommandTest.CommandTest): ...@@ -39,7 +40,7 @@ class TagCommandTest(CommandTest.CommandTest):
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
def test_add_tag2(self): def test_add_tag2(self):
command = TagCommand.TagCommand(["Foo", "due", "2014-10-22"], self.todolist, self.out, self.error) command = TagCommand(["Foo", "due", "2014-10-22"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.todolist.todo(1).source(), "Foo due:2014-10-22") self.assertEquals(self.todolist.todo(1).source(), "Foo due:2014-10-22")
...@@ -48,7 +49,7 @@ class TagCommandTest(CommandTest.CommandTest): ...@@ -48,7 +49,7 @@ class TagCommandTest(CommandTest.CommandTest):
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
def test_add_tag3(self): def test_add_tag3(self):
command = TagCommand.TagCommand(["-a", "2", "due", "2014-10-19"], self.todolist, self.out, self.error) command = TagCommand(["-a", "2", "due", "2014-10-19"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.todolist.todo(2).source(), "Bar due:2014-10-22 due:2014-10-19") self.assertEquals(self.todolist.todo(2).source(), "Bar due:2014-10-22 due:2014-10-19")
...@@ -57,7 +58,7 @@ class TagCommandTest(CommandTest.CommandTest): ...@@ -57,7 +58,7 @@ class TagCommandTest(CommandTest.CommandTest):
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
def test_add_tag4(self): def test_add_tag4(self):
command = TagCommand.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() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -65,7 +66,7 @@ class TagCommandTest(CommandTest.CommandTest): ...@@ -65,7 +66,7 @@ class TagCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "Invalid todo number.\n") self.assertEquals(self.errors, "Invalid todo number.\n")
def test_set_tag4(self): def test_set_tag4(self):
command = TagCommand.TagCommand(["3", "due", "2014-10-20"], self.todolist, self.out, self.error) command = TagCommand(["3", "due", "2014-10-20"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -73,7 +74,7 @@ class TagCommandTest(CommandTest.CommandTest): ...@@ -73,7 +74,7 @@ class TagCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_set_tag5(self): def test_set_tag5(self):
command = TagCommand.TagCommand(["4", "due", "2014-10-20"], self.todolist, self.out, self.error, lambda t: "all") command = TagCommand(["4", "due", "2014-10-20"], self.todolist, self.out, self.error, lambda t: "all")
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -81,7 +82,7 @@ class TagCommandTest(CommandTest.CommandTest): ...@@ -81,7 +82,7 @@ class TagCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_set_tag6(self): def test_set_tag6(self):
command = TagCommand.TagCommand(["4", "due", "2014-10-20"], self.todolist, self.out, self.error, lambda t: "1") command = TagCommand(["4", "due", "2014-10-20"], self.todolist, self.out, self.error, lambda t: "1")
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -89,7 +90,7 @@ class TagCommandTest(CommandTest.CommandTest): ...@@ -89,7 +90,7 @@ class TagCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_set_tag7(self): def test_set_tag7(self):
command = TagCommand.TagCommand(["4", "due", "2014-10-20"], self.todolist, self.out, self.error, lambda t: "2") command = TagCommand(["4", "due", "2014-10-20"], self.todolist, self.out, self.error, lambda t: "2")
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -97,7 +98,7 @@ class TagCommandTest(CommandTest.CommandTest): ...@@ -97,7 +98,7 @@ class TagCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_set_tag8(self): def test_set_tag8(self):
command = TagCommand.TagCommand(["4", "due", "2014-10-20"], self.todolist, self.out, self.error, lambda t: "") command = TagCommand(["4", "due", "2014-10-20"], self.todolist, self.out, self.error, lambda t: "")
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -105,7 +106,7 @@ class TagCommandTest(CommandTest.CommandTest): ...@@ -105,7 +106,7 @@ class TagCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_set_tag9(self): def test_set_tag9(self):
command = TagCommand.TagCommand(["4", "due", "2014-10-20"], self.todolist, self.out, self.error, lambda t: "99") command = TagCommand(["4", "due", "2014-10-20"], self.todolist, self.out, self.error, lambda t: "99")
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -113,7 +114,7 @@ class TagCommandTest(CommandTest.CommandTest): ...@@ -113,7 +114,7 @@ class TagCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_set_tag10(self): def test_set_tag10(self):
command = TagCommand.TagCommand(["-f", "4", "due", "2014-10-20"], self.todolist, self.out, self.error, lambda t: "99") command = TagCommand(["-f", "4", "due", "2014-10-20"], self.todolist, self.out, self.error, lambda t: "99")
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -121,7 +122,7 @@ class TagCommandTest(CommandTest.CommandTest): ...@@ -121,7 +122,7 @@ class TagCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_rm_tag1(self): def test_rm_tag1(self):
command = TagCommand.TagCommand(["1", "due"], self.todolist, self.out, self.error) command = TagCommand(["1", "due"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -129,7 +130,7 @@ class TagCommandTest(CommandTest.CommandTest): ...@@ -129,7 +130,7 @@ class TagCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_rm_tag2(self): def test_rm_tag2(self):
command = TagCommand.TagCommand(["2", "due"], self.todolist, self.out, self.error) command = TagCommand(["2", "due"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -137,7 +138,7 @@ class TagCommandTest(CommandTest.CommandTest): ...@@ -137,7 +138,7 @@ class TagCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_rm_tag3(self): def test_rm_tag3(self):
command = TagCommand.TagCommand(["4", "due"], self.todolist, self.out, self.error, lambda t: "all") command = TagCommand(["4", "due"], self.todolist, self.out, self.error, lambda t: "all")
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -145,7 +146,7 @@ class TagCommandTest(CommandTest.CommandTest): ...@@ -145,7 +146,7 @@ class TagCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_rm_tag4(self): def test_rm_tag4(self):
command = TagCommand.TagCommand(["4", "due"], self.todolist, self.out, self.error, lambda t: "1") command = TagCommand(["4", "due"], self.todolist, self.out, self.error, lambda t: "1")
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -153,7 +154,7 @@ class TagCommandTest(CommandTest.CommandTest): ...@@ -153,7 +154,7 @@ class TagCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_rm_tag6(self): def test_rm_tag6(self):
command = TagCommand.TagCommand(["4", "due"], self.todolist, self.out, self.error, lambda t: "99") command = TagCommand(["4", "due"], self.todolist, self.out, self.error, lambda t: "99")
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -161,7 +162,7 @@ class TagCommandTest(CommandTest.CommandTest): ...@@ -161,7 +162,7 @@ class TagCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_rm_tag7(self): def test_rm_tag7(self):
command = TagCommand.TagCommand(["4", "due"], self.todolist, self.out, self.error, lambda t: "A") command = TagCommand(["4", "due"], self.todolist, self.out, self.error, lambda t: "A")
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -169,7 +170,7 @@ class TagCommandTest(CommandTest.CommandTest): ...@@ -169,7 +170,7 @@ class TagCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_rm_tag8(self): def test_rm_tag8(self):
command = TagCommand.TagCommand(["5", "due"], self.todolist, self.out, self.error) command = TagCommand(["5", "due"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -177,7 +178,7 @@ class TagCommandTest(CommandTest.CommandTest): ...@@ -177,7 +178,7 @@ class TagCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "Invalid todo number.\n") self.assertEquals(self.errors, "Invalid todo number.\n")
def test_rm_tag9(self): def test_rm_tag9(self):
command = TagCommand.TagCommand(["A", "due"], self.todolist, self.out, self.error) command = TagCommand(["A", "due"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -185,7 +186,7 @@ class TagCommandTest(CommandTest.CommandTest): ...@@ -185,7 +186,7 @@ class TagCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "Invalid todo number.\n") self.assertEquals(self.errors, "Invalid todo number.\n")
def test_rm_tag10(self): def test_rm_tag10(self):
command = TagCommand.TagCommand(["-f", "4", "due"], self.todolist, self.out, self.error, lambda t: "A") command = TagCommand(["-f", "4", "due"], self.todolist, self.out, self.error, lambda t: "A")
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -193,7 +194,7 @@ class TagCommandTest(CommandTest.CommandTest): ...@@ -193,7 +194,7 @@ class TagCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_help(self): def test_help(self):
command = TagCommand.TagCommand(["help"], self.todolist, self.out, self.error) command = TagCommand(["help"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEquals(self.output, "") self.assertEquals(self.output, "")
......
# Topydo - A todo.txt client written in Python. # Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl> # Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import Todo from topydo.lib.Todo import Todo
import TodoFile from topydo.lib.TodoFile import TodoFile
import TodoList from topydo.lib.TodoList import TodoList
def load_file(p_filename): def load_file(p_filename):
""" """
Loads a todo file from the given filename and returns a list of todos. Loads a todo file from the given filename and returns a list of todos.
""" """
todolist = load_file_to_raw_list(p_filename) todolist = load_file_to_raw_list(p_filename)
return [Todo.Todo(src) for src in todolist] return [Todo(src) for src in todolist]
def load_file_to_raw_list(p_filename): def load_file_to_raw_list(p_filename):
""" """
Loads a todo file from the given filename and returns a list of todo Loads a todo file from the given filename and returns a list of todo
strings (unparsed). strings (unparsed).
""" """
todofile = TodoFile.TodoFile(p_filename) todofile = TodoFile(p_filename)
return todofile.read() return todofile.read()
def load_file_to_todolist(p_filename): def load_file_to_todolist(p_filename):
...@@ -38,7 +38,7 @@ def load_file_to_todolist(p_filename): ...@@ -38,7 +38,7 @@ def load_file_to_todolist(p_filename):
Loads a todo file to a TodoList instance. Loads a todo file to a TodoList instance.
""" """
todolist = load_file_to_raw_list(p_filename) todolist = load_file_to_raw_list(p_filename)
return TodoList.TodoList(todolist) return TodoList(todolist)
def todolist_to_string(p_list): def todolist_to_string(p_list):
""" Converts a todo list to a single string. """ """ Converts a todo list to a single string. """
......
# Topydo - A todo.txt client written in Python. # Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl> # Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
...@@ -20,11 +20,11 @@ from datetime import date, timedelta ...@@ -20,11 +20,11 @@ from datetime import date, timedelta
import re import re
import unittest import unittest
import TodoBase from topydo.lib.TodoBase import TodoBase
class TodoBaseTester(unittest.TestCase): class TodoBaseTester(unittest.TestCase):
def test_parse_tag(self): def test_parse_tag(self):
todo = TodoBase.TodoBase("(C) Test foo:bar foo:baz foo_:baz_ blah:zah:haz") todo = TodoBase("(C) Test foo:bar foo:baz foo_:baz_ blah:zah:haz")
self.assertTrue(todo.has_tag('foo')) self.assertTrue(todo.has_tag('foo'))
self.assertTrue(todo.has_tag('foo_')) self.assertTrue(todo.has_tag('foo_'))
...@@ -34,7 +34,7 @@ class TodoBaseTester(unittest.TestCase): ...@@ -34,7 +34,7 @@ class TodoBaseTester(unittest.TestCase):
self.assertTrue(todo.has_tag('blah', 'zah:haz')) self.assertTrue(todo.has_tag('blah', 'zah:haz'))
def test_add_tag1(self): def test_add_tag1(self):
todo = TodoBase.TodoBase("(C) Foo") todo = TodoBase("(C) Foo")
todo.set_tag('foo', 'bar') todo.set_tag('foo', 'bar')
self.assertTrue(todo.has_tag('foo')) self.assertTrue(todo.has_tag('foo'))
...@@ -44,13 +44,13 @@ class TodoBaseTester(unittest.TestCase): ...@@ -44,13 +44,13 @@ class TodoBaseTester(unittest.TestCase):
self.assertTrue(re.search(r'\bfoo:bar\b', todo.src)) self.assertTrue(re.search(r'\bfoo:bar\b', todo.src))
def test_add_tag2(self): def test_add_tag2(self):
todo = TodoBase.TodoBase("(C) Foo id:1") todo = TodoBase("(C) Foo id:1")
todo.add_tag('id', '2') todo.add_tag('id', '2')
self.assertEquals(todo.source(), '(C) Foo id:1 id:2') self.assertEquals(todo.source(), '(C) Foo id:1 id:2')
def test_set_tag1(self): def test_set_tag1(self):
todo = TodoBase.TodoBase("(C) Foo foo:bar") todo = TodoBase("(C) Foo foo:bar")
todo.set_tag('foo', 'baz') todo.set_tag('foo', 'baz')
self.assertTrue(todo.has_tag('foo')) self.assertTrue(todo.has_tag('foo'))
...@@ -61,7 +61,7 @@ class TodoBaseTester(unittest.TestCase): ...@@ -61,7 +61,7 @@ class TodoBaseTester(unittest.TestCase):
self.assertFalse(re.search(r'\bfoo:bar\b', todo.src)) self.assertFalse(re.search(r'\bfoo:bar\b', todo.src))
def test_set_tag2(self): def test_set_tag2(self):
todo = TodoBase.TodoBase("(C) Foo foo:bar foo:baz") todo = TodoBase("(C) Foo foo:bar foo:baz")
todo.set_tag('foo', 'bang', False, 'baz') todo.set_tag('foo', 'bang', False, 'baz')
self.assertTrue(todo.has_tag('foo')) self.assertTrue(todo.has_tag('foo'))
...@@ -73,7 +73,7 @@ class TodoBaseTester(unittest.TestCase): ...@@ -73,7 +73,7 @@ class TodoBaseTester(unittest.TestCase):
self.assertFalse(re.search(r'\bfoo:baz\b', todo.src)) self.assertFalse(re.search(r'\bfoo:baz\b', todo.src))
def test_set_tag3(self): def test_set_tag3(self):
todo = TodoBase.TodoBase("(C) Foo foo:bar foo:bar") todo = TodoBase("(C) Foo foo:bar foo:bar")
todo.set_tag('foo', 'bang', False, 'bar') todo.set_tag('foo', 'bang', False, 'bar')
self.assertTrue(todo.has_tag('foo')) self.assertTrue(todo.has_tag('foo'))
...@@ -83,7 +83,7 @@ class TodoBaseTester(unittest.TestCase): ...@@ -83,7 +83,7 @@ class TodoBaseTester(unittest.TestCase):
self.assertTrue(re.search(r'\bfoo:bang foo:bang\b', todo.src)) self.assertTrue(re.search(r'\bfoo:bang foo:bang\b', todo.src))
def test_set_tag_double_value(self): def test_set_tag_double_value(self):
todo = TodoBase.TodoBase("(C) Foo foo:bar baz:bar") 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.has_tag('foo'))
...@@ -92,21 +92,21 @@ class TodoBaseTester(unittest.TestCase): ...@@ -92,21 +92,21 @@ class TodoBaseTester(unittest.TestCase):
self.assertTrue(todo.tag_value('baz'), 'bar') self.assertTrue(todo.tag_value('baz'), 'bar')
def test_set_tag_double_tag(self): def test_set_tag_double_tag(self):
todo = TodoBase.TodoBase("(C) Foo foo:bar foo:baz") todo = TodoBase("(C) Foo foo:bar foo:baz")
todo.set_tag('foo', 'blah') todo.set_tag('foo', 'blah')
self.assertTrue(todo.has_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): def test_set_tag_empty_value(self):
todo = TodoBase.TodoBase("(C) Foo foo:bar foo:baz") todo = TodoBase("(C) Foo foo:bar foo:baz")
todo.set_tag('foo') todo.set_tag('foo')
self.assertFalse(todo.has_tag('foo')) self.assertFalse(todo.has_tag('foo'))
self.assertFalse(re.search(r'\bfoo:', todo.src)) self.assertFalse(re.search(r'\bfoo:', todo.src))
def test_remove_all(self): def test_remove_all(self):
todo = TodoBase.TodoBase("(C) Foo foo:bar foo:baz foo:") todo = TodoBase("(C) Foo foo:bar foo:baz foo:")
todo.remove_tag('foo') todo.remove_tag('foo')
self.assertFalse(todo.has_tag('foo')) self.assertFalse(todo.has_tag('foo'))
...@@ -114,7 +114,7 @@ class TodoBaseTester(unittest.TestCase): ...@@ -114,7 +114,7 @@ class TodoBaseTester(unittest.TestCase):
self.assertTrue(re.search(r'foo:', todo.src)) self.assertTrue(re.search(r'foo:', todo.src))
def test_remove_specific_tag_value(self): def test_remove_specific_tag_value(self):
todo = TodoBase.TodoBase("(C) Foo kungfoo:bar foo:bar foo:barz") todo = TodoBase("(C) Foo kungfoo:bar foo:bar foo:barz")
todo.remove_tag('foo', 'bar') todo.remove_tag('foo', 'bar')
self.assertTrue(todo.has_tag('foo')) self.assertTrue(todo.has_tag('foo'))
...@@ -128,7 +128,7 @@ class TodoBaseTester(unittest.TestCase): ...@@ -128,7 +128,7 @@ class TodoBaseTester(unittest.TestCase):
def test_set_priority1(self): def test_set_priority1(self):
""" Change priority. """ """ Change priority. """
todo = TodoBase.TodoBase("(A) Foo") todo = TodoBase("(A) Foo")
todo.set_priority('B') todo.set_priority('B')
self.assertEquals(todo.priority(), 'B') self.assertEquals(todo.priority(), 'B')
...@@ -136,7 +136,7 @@ class TodoBaseTester(unittest.TestCase): ...@@ -136,7 +136,7 @@ class TodoBaseTester(unittest.TestCase):
def test_set_priority2(self): def test_set_priority2(self):
""" Set priority to task without priority. """ """ Set priority to task without priority. """
todo = TodoBase.TodoBase("Foo") todo = TodoBase("Foo")
todo.set_priority('B') todo.set_priority('B')
self.assertEquals(todo.priority(), 'B') self.assertEquals(todo.priority(), 'B')
...@@ -144,7 +144,7 @@ class TodoBaseTester(unittest.TestCase): ...@@ -144,7 +144,7 @@ class TodoBaseTester(unittest.TestCase):
def test_set_priority3(self): def test_set_priority3(self):
""" Test invalid priority input. """ """ Test invalid priority input. """
todo = TodoBase.TodoBase("(A) Foo") todo = TodoBase("(A) Foo")
todo.set_priority('AB') todo.set_priority('AB')
self.assertEquals(todo.priority(), 'A') self.assertEquals(todo.priority(), 'A')
...@@ -152,7 +152,7 @@ class TodoBaseTester(unittest.TestCase): ...@@ -152,7 +152,7 @@ class TodoBaseTester(unittest.TestCase):
def test_set_priority4(self): def test_set_priority4(self):
""" Add priority, while not be mistaken about todo string. """ """ Add priority, while not be mistaken about todo string. """
todo = TodoBase.TodoBase("(A)Foo") todo = TodoBase("(A)Foo")
self.assertNotEqual(todo.priority(), 'A') self.assertNotEqual(todo.priority(), 'A')
...@@ -163,7 +163,7 @@ class TodoBaseTester(unittest.TestCase): ...@@ -163,7 +163,7 @@ class TodoBaseTester(unittest.TestCase):
def test_set_priority5(self): def test_set_priority5(self):
""" Unset priority. """ """ Unset priority. """
todo = TodoBase.TodoBase("(A) Foo") todo = TodoBase("(A) Foo")
todo.set_priority(None) todo.set_priority(None)
self.assertEquals(todo.priority(), None) self.assertEquals(todo.priority(), None)
...@@ -171,62 +171,62 @@ class TodoBaseTester(unittest.TestCase): ...@@ -171,62 +171,62 @@ class TodoBaseTester(unittest.TestCase):
def test_set_priority6(self): def test_set_priority6(self):
""" Do not set priorities on completed tasks. """ """ Do not set priorities on completed tasks. """
todo = TodoBase.TodoBase("x 2014-06-13 Foo") todo = TodoBase("x 2014-06-13 Foo")
todo.set_priority('A') todo.set_priority('A')
self.assertFalse(todo.priority()) self.assertFalse(todo.priority())
self.assertEquals(todo.src, "x 2014-06-13 Foo") self.assertEquals(todo.src, "x 2014-06-13 Foo")
def test_project1(self): def test_project1(self):
todo = TodoBase.TodoBase("(C) Foo +Bar +Baz +Bar:") todo = TodoBase("(C) Foo +Bar +Baz +Bar:")
self.assertEquals(len(todo.projects()), 2) self.assertEquals(len(todo.projects()), 2)
self.assertIn('Bar', todo.projects()) self.assertIn('Bar', todo.projects())
self.assertIn('Baz', todo.projects()) self.assertIn('Baz', todo.projects())
def test_project2(self): def test_project2(self):
todo = TodoBase.TodoBase("(C) Foo +Bar+Baz") todo = TodoBase("(C) Foo +Bar+Baz")
self.assertEquals(len(todo.projects()), 1) self.assertEquals(len(todo.projects()), 1)
self.assertIn('Bar+Baz', todo.projects()) self.assertIn('Bar+Baz', todo.projects())
def test_context1(self): def test_context1(self):
todo = TodoBase.TodoBase("(C) Foo @Bar @Baz @Bar:") todo = TodoBase("(C) Foo @Bar @Baz @Bar:")
self.assertEquals(len(todo.contexts()), 2) self.assertEquals(len(todo.contexts()), 2)
self.assertIn('Bar', todo.contexts()) self.assertIn('Bar', todo.contexts())
self.assertIn('Baz', todo.contexts()) self.assertIn('Baz', todo.contexts())
def test_context2(self): def test_context2(self):
todo = TodoBase.TodoBase("(C) Foo @Bar+Baz") todo = TodoBase("(C) Foo @Bar+Baz")
self.assertEquals(len(todo.contexts()), 1) self.assertEquals(len(todo.contexts()), 1)
self.assertIn('Bar+Baz', todo.contexts()) self.assertIn('Bar+Baz', todo.contexts())
def test_completion1(self): def test_completion1(self):
todo = TodoBase.TodoBase("x 2014-06-09 Foo") todo = TodoBase("x 2014-06-09 Foo")
self.assertTrue(todo.is_completed()) self.assertTrue(todo.is_completed())
def test_completion2(self): def test_completion2(self):
todo = TodoBase.TodoBase("xx Important xx") todo = TodoBase("xx Important xx")
self.assertFalse(todo.is_completed()) self.assertFalse(todo.is_completed())
def test_completion3(self): def test_completion3(self):
""" A completed todo must start with an x followed by a date. """ """ A completed todo must start with an x followed by a date. """
todo = TodoBase.TodoBase("x Not complete") todo = TodoBase("x Not complete")
self.assertFalse(todo.is_completed()) self.assertFalse(todo.is_completed())
def test_completion4(self): def test_completion4(self):
""" A completed todo must start with an x followed by a date. """ """ A completed todo must start with an x followed by a date. """
todo = TodoBase.TodoBase("X 2014-06-14 Not complete") todo = TodoBase("X 2014-06-14 Not complete")
self.assertFalse(todo.is_completed()) self.assertFalse(todo.is_completed())
def test_set_complete1(self): def test_set_complete1(self):
todo = TodoBase.TodoBase("(A) Foo") todo = TodoBase("(A) Foo")
todo.set_completed() todo.set_completed()
today = date.today() today = date.today()
...@@ -237,7 +237,7 @@ class TodoBaseTester(unittest.TestCase): ...@@ -237,7 +237,7 @@ class TodoBaseTester(unittest.TestCase):
self.assertTrue(re.match('^x ' + today_str + ' Foo', todo.src)) self.assertTrue(re.match('^x ' + today_str + ' Foo', todo.src))
def test_set_complete2(self): def test_set_complete2(self):
todo = TodoBase.TodoBase("2014-06-12 Foo") todo = TodoBase("2014-06-12 Foo")
todo.set_completed() todo.set_completed()
today = date.today() today = date.today()
...@@ -248,7 +248,7 @@ class TodoBaseTester(unittest.TestCase): ...@@ -248,7 +248,7 @@ class TodoBaseTester(unittest.TestCase):
todo.src)) todo.src))
def test_set_complete3(self): def test_set_complete3(self):
todo = TodoBase.TodoBase("Foo") todo = TodoBase("Foo")
todo.set_completed() todo.set_completed()
today = date.today() today = date.today()
...@@ -258,7 +258,7 @@ class TodoBaseTester(unittest.TestCase): ...@@ -258,7 +258,7 @@ class TodoBaseTester(unittest.TestCase):
self.assertTrue(re.match('^x ' + today_str + ' Foo', todo.src)) self.assertTrue(re.match('^x ' + today_str + ' Foo', todo.src))
def test_set_complete4(self): def test_set_complete4(self):
todo = TodoBase.TodoBase("(A) 2014-06-12 Foo") todo = TodoBase("(A) 2014-06-12 Foo")
todo.set_completed() todo.set_completed()
today = date.today() today = date.today()
...@@ -268,20 +268,20 @@ class TodoBaseTester(unittest.TestCase): ...@@ -268,20 +268,20 @@ class TodoBaseTester(unittest.TestCase):
self.assertTrue(re.match('^x ' + today_str + ' 2014-06-12 Foo', todo.src)) self.assertTrue(re.match('^x ' + today_str + ' 2014-06-12 Foo', todo.src))
def test_set_complete5(self): def test_set_complete5(self):
todo = TodoBase.TodoBase("x 2014-06-13 Foo") todo = TodoBase("x 2014-06-13 Foo")
todo.set_completed() todo.set_completed()
self.assertEquals(todo.src, "x 2014-06-13 Foo") self.assertEquals(todo.src, "x 2014-06-13 Foo")
def test_set_complete6(self): def test_set_complete6(self):
todo = TodoBase.TodoBase("Foo") todo = TodoBase("Foo")
yesterday = date.today() - timedelta(1) yesterday = date.today() - timedelta(1)
todo.set_completed(yesterday) todo.set_completed(yesterday)
self.assertEquals(todo.src, "x %s Foo" % yesterday.isoformat()) self.assertEquals(todo.src, "x %s Foo" % yesterday.isoformat())
def test_set_source_text(self): def test_set_source_text(self):
todo = TodoBase.TodoBase("(B) Foo") todo = TodoBase("(B) Foo")
new_text = "(C) Foo" new_text = "(C) Foo"
todo.set_source_text(new_text) todo.set_source_text(new_text)
...@@ -290,7 +290,7 @@ class TodoBaseTester(unittest.TestCase): ...@@ -290,7 +290,7 @@ class TodoBaseTester(unittest.TestCase):
self.assertEquals(todo.priority(),'C') self.assertEquals(todo.priority(),'C')
def test_set_creation_date1(self): def test_set_creation_date1(self):
todo = TodoBase.TodoBase("Foo") todo = TodoBase("Foo")
creation_date = date(2014, 7, 24) creation_date = date(2014, 7, 24)
todo.set_creation_date(creation_date) todo.set_creation_date(creation_date)
...@@ -299,7 +299,7 @@ class TodoBaseTester(unittest.TestCase): ...@@ -299,7 +299,7 @@ class TodoBaseTester(unittest.TestCase):
self.assertEquals(todo.src, "2014-07-24 Foo") self.assertEquals(todo.src, "2014-07-24 Foo")
def test_set_creation_date2(self): def test_set_creation_date2(self):
todo = TodoBase.TodoBase("(A) Foo") todo = TodoBase("(A) Foo")
creation_date = date(2014, 7, 24) creation_date = date(2014, 7, 24)
todo.set_creation_date(creation_date) todo.set_creation_date(creation_date)
...@@ -308,7 +308,7 @@ class TodoBaseTester(unittest.TestCase): ...@@ -308,7 +308,7 @@ class TodoBaseTester(unittest.TestCase):
self.assertEquals(todo.src, "(A) 2014-07-24 Foo") self.assertEquals(todo.src, "(A) 2014-07-24 Foo")
def test_set_creation_date3(self): def test_set_creation_date3(self):
todo = TodoBase.TodoBase("(A) 2014-07-23 Foo") todo = TodoBase("(A) 2014-07-23 Foo")
creation_date = date(2014, 7, 24) creation_date = date(2014, 7, 24)
todo.set_creation_date(creation_date) todo.set_creation_date(creation_date)
...@@ -317,7 +317,7 @@ class TodoBaseTester(unittest.TestCase): ...@@ -317,7 +317,7 @@ class TodoBaseTester(unittest.TestCase):
self.assertEquals(todo.src, "(A) 2014-07-24 Foo") self.assertEquals(todo.src, "(A) 2014-07-24 Foo")
def test_set_creation_date4(self): def test_set_creation_date4(self):
todo = TodoBase.TodoBase("2014-07-23 Foo") todo = TodoBase("2014-07-23 Foo")
creation_date = date(2014, 7, 24) creation_date = date(2014, 7, 24)
todo.set_creation_date(creation_date) todo.set_creation_date(creation_date)
...@@ -326,7 +326,7 @@ class TodoBaseTester(unittest.TestCase): ...@@ -326,7 +326,7 @@ class TodoBaseTester(unittest.TestCase):
self.assertEquals(todo.src, "2014-07-24 Foo") self.assertEquals(todo.src, "2014-07-24 Foo")
def test_set_creation_date5(self): def test_set_creation_date5(self):
todo = TodoBase.TodoBase("x 2014-07-25 2014-07-23 Foo") todo = TodoBase("x 2014-07-25 2014-07-23 Foo")
creation_date = date(2014, 7, 24) creation_date = date(2014, 7, 24)
todo.set_creation_date(creation_date) todo.set_creation_date(creation_date)
......
# Topydo - A todo.txt client written in Python. # Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl> # Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
......
...@@ -19,19 +19,19 @@ ...@@ -19,19 +19,19 @@
import re import re
import unittest import unittest
from Config import config from topydo.lib.Config import config
import Todo from topydo.lib.Todo import Todo
import TodoFile from topydo.lib.TodoFile import TodoFile
from TodoListBase import InvalidTodoException from topydo.lib.TodoListBase import InvalidTodoException
import TodoList from topydo.lib.TodoList import TodoList
class TodoListTester(unittest.TestCase): class TodoListTester(unittest.TestCase):
def setUp(self): def setUp(self):
self.todofile = TodoFile.TodoFile('data/TodoListTest.txt') self.todofile = TodoFile('data/TodoListTest.txt')
lines = [line for line in self.todofile.read() \ lines = [line for line in self.todofile.read() \
if re.search(r'\S', line)] if re.search(r'\S', line)]
self.text = ''.join(lines) self.text = ''.join(lines)
self.todolist = TodoList.TodoList(lines) self.todolist = TodoList(lines)
def tearDown(self): def tearDown(self):
# restore to the default configuration in case a custom one was set # restore to the default configuration in case a custom one was set
...@@ -151,15 +151,15 @@ class TodoListTester(unittest.TestCase): ...@@ -151,15 +151,15 @@ class TodoListTester(unittest.TestCase):
self.assertFalse(self.todolist.todo_by_dep_id('2')) self.assertFalse(self.todolist.todo_by_dep_id('2'))
def test_todo_number1(self): def test_todo_number1(self):
todo = Todo.Todo("No number") todo = Todo("No number")
self.todolist.add_todo(todo) self.todolist.add_todo(todo)
todo = self.todolist.todo(6) todo = self.todolist.todo(6)
self.assertIsInstance(todo, Todo.Todo) self.assertIsInstance(todo, Todo)
self.assertEquals(todo.text(), "No number") self.assertEquals(todo.text(), "No number")
def test_todo_number2(self): def test_todo_number2(self):
todo = Todo.Todo("Non-existent") todo = Todo("Non-existent")
self.assertRaises(InvalidTodoException, self.todolist.number, todo) self.assertRaises(InvalidTodoException, self.todolist.number, todo)
def test_todo_complete(self): def test_todo_complete(self):
...@@ -211,7 +211,7 @@ class TodoListTester(unittest.TestCase): ...@@ -211,7 +211,7 @@ class TodoListTester(unittest.TestCase):
class TodoListDependencyTester(unittest.TestCase): class TodoListDependencyTester(unittest.TestCase):
def setUp(self): def setUp(self):
self.todolist = TodoList.TodoList([]) self.todolist = TodoList([])
self.todolist.add("Foo id:1") self.todolist.add("Foo id:1")
self.todolist.add("Bar p:1") self.todolist.add("Bar p:1")
self.todolist.add("Baz p:1 id:2") self.todolist.add("Baz p:1 id:2")
...@@ -308,7 +308,7 @@ class TodoListDependencyTester(unittest.TestCase): ...@@ -308,7 +308,7 @@ class TodoListDependencyTester(unittest.TestCase):
class TodoListCleanDependencyTester(unittest.TestCase): class TodoListCleanDependencyTester(unittest.TestCase):
def setUp(self): def setUp(self):
self.todolist = TodoList.TodoList([]) self.todolist = TodoList([])
self.todolist.add("Bar p:1") self.todolist.add("Bar p:1")
self.todolist.add("Baz p:1 id:2") self.todolist.add("Baz p:1 id:2")
self.todolist.add("Buzz p:2") self.todolist.add("Buzz p:2")
......
# Topydo - A todo.txt client written in Python. # Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl> # Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from datetime import date, timedelta from datetime import date, timedelta
import unittest import unittest
import Todo from topydo.lib.Todo import Todo
def today_date(): def today_date():
today = date.today() today = date.today()
...@@ -29,59 +29,59 @@ def tomorrow_date(): ...@@ -29,59 +29,59 @@ def tomorrow_date():
class TodoTest(unittest.TestCase): class TodoTest(unittest.TestCase):
def test_due_date1(self): def test_due_date1(self):
todo = Todo.Todo("(C) Foo due:2014-06-09") todo = Todo("(C) Foo due:2014-06-09")
due = date(2014, 6, 9) due = date(2014, 6, 9)
self.assertEqual(todo.due_date(), due) self.assertEqual(todo.due_date(), due)
def test_false_date(self): def test_false_date(self):
todo = Todo.Todo("(C) Foo due:2014-04-31") todo = Todo("(C) Foo due:2014-04-31")
self.assertEqual( todo.due_date(), None ) self.assertEqual( todo.due_date(), None )
def test_active1(self): def test_active1(self):
todo = Todo.Todo("(C) Foo due:2014-01-01") todo = Todo("(C) Foo due:2014-01-01")
self.assertTrue(todo.is_active()) self.assertTrue(todo.is_active())
def test_active2(self): def test_active2(self):
todo = Todo.Todo("(C) Foo t:" + tomorrow_date()) todo = Todo("(C) Foo t:" + tomorrow_date())
self.assertFalse(todo.is_active()) self.assertFalse(todo.is_active())
def test_active3(self): def test_active3(self):
todo = Todo.Todo("x 2014-06-09 Foo t:2014-01-01") todo = Todo("x 2014-06-09 Foo t:2014-01-01")
self.assertFalse(todo.is_active()) self.assertFalse(todo.is_active())
def test_active4(self): def test_active4(self):
todo = Todo.Todo("(C) Foo t:" + today_date()) todo = Todo("(C) Foo t:" + today_date())
self.assertTrue(todo.is_active()) self.assertTrue(todo.is_active())
def test_active5(self): def test_active5(self):
todo = Todo.Todo("(C) Foo t:2014-02-29") todo = Todo("(C) Foo t:2014-02-29")
self.assertTrue(todo.is_active()) self.assertTrue(todo.is_active())
def test_overdue1(self): def test_overdue1(self):
todo = Todo.Todo("(C) Foo due:2014-01-01") todo = Todo("(C) Foo due:2014-01-01")
self.assertTrue(todo.is_overdue()) self.assertTrue(todo.is_overdue())
def test_overdue2(self): def test_overdue2(self):
todo = Todo.Todo("(C) Foo due:" + tomorrow_date()) todo = Todo("(C) Foo due:" + tomorrow_date())
self.assertFalse(todo.is_overdue()) self.assertFalse(todo.is_overdue())
def test_overdue3(self): def test_overdue3(self):
todo = Todo.Todo("(C) Foo due:" + today_date()) todo = Todo("(C) Foo due:" + today_date())
self.assertFalse(todo.is_overdue()) self.assertFalse(todo.is_overdue())
def days_till_due(self): def days_till_due(self):
todo = Todo.Todo("(C) due:" + tomorrow_date()) todo = Todo("(C) due:" + tomorrow_date())
self.assertEqual(todo.days_till_due(), 1) self.assertEqual(todo.days_till_due(), 1)
def test_length1(self): def test_length1(self):
todo = Todo.Todo("(C) Foo t:2014-01-01 due:2013-12-31") todo = Todo("(C) Foo t:2014-01-01 due:2013-12-31")
self.assertEqual(todo.length(), 0) self.assertEqual(todo.length(), 0)
def test_length2(self): def test_length2(self):
todo = Todo.Todo("(C) Foo t:2014-01-01 due:2014-01-01") todo = Todo("(C) Foo t:2014-01-01 due:2014-01-01")
self.assertEqual(todo.length(), 0) self.assertEqual(todo.length(), 0)
def test_length3(self): def test_length3(self):
todo = Todo.Todo("(C) Foo t:2014-01-01 due:2014-01-02") todo = Todo("(C) Foo t:2014-01-01 due:2014-01-02")
self.assertEqual(todo.length(), 1) self.assertEqual(todo.length(), 1)
# Topydo - A todo.txt client written in Python. # Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl> # Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import unittest import unittest
import Filter from topydo.lib import Filter
import Sorter from topydo.lib.Sorter import Sorter
from TestFacilities import load_file, todolist_to_string from TestFacilities import load_file, todolist_to_string
import TodoFile from topydo.lib.TodoFile import TodoFile
import TodoList from topydo.lib.TodoList import TodoList
class ViewTest(unittest.TestCase): class ViewTest(unittest.TestCase):
def test_view(self): def test_view(self):
""" Check filters and printer for views. """ """ Check filters and printer for views. """
todofile = TodoFile.TodoFile('data/FilterTest1.txt') todofile = TodoFile('data/FilterTest1.txt')
ref = load_file('data/ViewTest1-result.txt') ref = load_file('data/ViewTest1-result.txt')
todolist = TodoList.TodoList(todofile.read()) todolist = TodoList(todofile.read())
sorter = Sorter.Sorter('text') sorter = Sorter('text')
todofilter = Filter.GrepFilter('+Project') todofilter = Filter.GrepFilter('+Project')
view = todolist.view(sorter, [todofilter]) view = todolist.view(sorter, [todofilter])
......
#!/bin/bash #!/bin/bash
export PYTHONPATH=../topydo/lib export PYTHONPATH=..
if [ -n "$1" ]; then if [ -n "$1" ]; then
TESTS=$1 TESTS=$1
......
...@@ -16,26 +16,21 @@ ...@@ -16,26 +16,21 @@
""" Entry file for the Python todo.txt CLI. """ """ Entry file for the Python todo.txt CLI. """
import getopt
import sys import sys
def usage(): def usage():
""" Prints the usage of the todo.txt CLI """ """ Prints the usage of the todo.txt CLI """
exit(1)
def arguments(p_start=2):
"""
Retrieves all values from the argument list starting from the given
position.
This is a parameter, because argv has a different structure when no print """\
subcommand was given and it fallbacks to the default subcommand. -c : Specify an alternative configuration file.
""" -d : Specify an alternative archive file (done.txt)
try: -h : This help text
values = sys.argv[p_start:] -t : Specify an alternative todo file
except IndexError: -v : Print version and exit
usage() """
return values exit(0)
def write(p_file, p_string): def write(p_file, p_string):
""" """
...@@ -54,6 +49,13 @@ def error(p_string): ...@@ -54,6 +49,13 @@ def error(p_string):
write(sys.stderr, p_string) write(sys.stderr, p_string)
def version():
""" Print the current version and exit. """
from topydo.lib.Version import VERSION, LICENSE
print "topydo %s\n" % (VERSION)
print LICENSE
exit(0)
from topydo.lib.Config import config, ConfigError from topydo.lib.Config import config, ConfigError
# First thing is to poke the configuration and check whether it's sane # First thing is to poke the configuration and check whether it's sane
...@@ -61,8 +63,8 @@ from topydo.lib.Config import config, ConfigError ...@@ -61,8 +63,8 @@ from topydo.lib.Config import config, ConfigError
# make sure to bail out if the configuration is invalid. # make sure to bail out if the configuration is invalid.
try: try:
config() config()
except ConfigError as e: except ConfigError as config_error:
error(str(e)) error(str(config_error))
exit(1) exit(1)
from topydo.lib.AddCommand import AddCommand from topydo.lib.AddCommand import AddCommand
...@@ -76,7 +78,6 @@ from topydo.lib.ListCommand import ListCommand ...@@ -76,7 +78,6 @@ from topydo.lib.ListCommand import ListCommand
from topydo.lib.ListContextCommand import ListContextCommand from topydo.lib.ListContextCommand import ListContextCommand
from topydo.lib.ListProjectCommand import ListProjectCommand from topydo.lib.ListProjectCommand import ListProjectCommand
from topydo.lib.PostponeCommand import PostponeCommand from topydo.lib.PostponeCommand import PostponeCommand
from topydo.lib.PrettyPrinter import *
from topydo.lib.PriorityCommand import PriorityCommand from topydo.lib.PriorityCommand import PriorityCommand
from topydo.lib.SortCommand import SortCommand from topydo.lib.SortCommand import SortCommand
from topydo.lib.TagCommand import TagCommand from topydo.lib.TagCommand import TagCommand
...@@ -86,9 +87,46 @@ from topydo.lib import TodoListBase ...@@ -86,9 +87,46 @@ from topydo.lib import TodoListBase
from topydo.lib.Utils import escape_ansi from topydo.lib.Utils import escape_ansi
class CLIApplication(object): class CLIApplication(object):
"""
Class that represents the Command Line Interface of Topydo.
Handles input/output of the various subcommand.
"""
def __init__(self): def __init__(self):
self.todolist = TodoList.TodoList([]) self.todolist = TodoList.TodoList([])
self.config = config()
self.path = self.config.todotxt()
self.archive_path = self.config.archive()
def _process_flags(self):
try:
opts, args = getopt.getopt(sys.argv[1:], "c:d:ht:v")
except getopt.GetoptError as e:
error(str(e))
exit(1)
alt_path = None
alt_archive = None
for opt, value in opts:
if opt == "-c":
self.config = config(value)
elif opt == "-t":
alt_path = value
elif opt == "-d":
alt_archive = value
elif opt == "-v":
version()
else:
usage()
self.path = alt_path if alt_path else self.config.todotxt()
self.archive_path = alt_archive \
if alt_archive else self.config.archive()
return args
def archive(self): def archive(self):
""" """
Performs an archive action on the todolist. Performs an archive action on the todolist.
...@@ -96,7 +134,7 @@ class CLIApplication(object): ...@@ -96,7 +134,7 @@ class CLIApplication(object):
This means that all completed tasks are moved to the archive file This means that all completed tasks are moved to the archive file
(defaults to done.txt). (defaults to done.txt).
""" """
archive_file = TodoFile.TodoFile(config().archive()) archive_file = TodoFile.TodoFile(self.archive_path)
archive = TodoListBase.TodoListBase(archive_file.read()) archive = TodoListBase.TodoListBase(archive_file.read())
if archive: if archive:
...@@ -107,18 +145,25 @@ class CLIApplication(object): ...@@ -107,18 +145,25 @@ class CLIApplication(object):
archive_file.write(str(archive)) archive_file.write(str(archive))
def execute(self, p_command, p_args): def execute(self, p_command, p_args):
command = p_command(p_args, self.todolist, lambda o: write(sys.stdout, o), error, raw_input) """
Execute a subcommand with arguments. p_command is a class (not an
object).
"""
command = p_command(
p_args,
self.todolist,
lambda o: write(sys.stdout, o),
error,
raw_input)
return False if command.execute() == False else True return False if command.execute() == False else True
def run(self): def run(self):
""" Main entry function. """ """ Main entry function. """
todofile = TodoFile.TodoFile(config().todotxt()) args = self._process_flags()
self.todolist = TodoList.TodoList(todofile.read())
try: todofile = TodoFile.TodoFile(self.path)
subcommand = sys.argv[1] self.todolist = TodoList.TodoList(todofile.read())
except IndexError:
subcommand = config().default_command()
subcommand_map = { subcommand_map = {
'add': AddCommand, 'add': AddCommand,
...@@ -144,12 +189,27 @@ class CLIApplication(object): ...@@ -144,12 +189,27 @@ class CLIApplication(object):
'tag': TagCommand, 'tag': TagCommand,
} }
args = arguments() try:
if not subcommand in subcommand_map: subcommand = args[0]
subcommand = config().default_command()
args = arguments(1) if subcommand in subcommand_map:
subcommand = subcommand_map[subcommand]
args = args[1:]
else:
subcommand = self.config.default_command()
if subcommand in subcommand_map:
subcommand = subcommand_map[subcommand]
# leave args unchanged
else:
usage()
except IndexError:
subcommand = self.config.default_command()
if subcommand in subcommand_map:
subcommand = subcommand_map[subcommand]
else:
usage()
if self.execute(subcommand_map[subcommand], args) == False: if self.execute(subcommand, args) == False:
exit(1) exit(1)
if self.todolist.is_dirty(): if self.todolist.is_dirty():
......
# Topydo - A todo.txt client written in Python. # Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl> # Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
...@@ -19,20 +19,21 @@ ...@@ -19,20 +19,21 @@
from datetime import date from datetime import date
import re import re
from Config import config from topydo.lib.Config import config
import Command from topydo.lib.Command import Command
from PrettyPrinter import pretty_print from topydo.lib.PrettyPrinter import pretty_print
from RelativeDate import relative_date_to_date from topydo.lib.RelativeDate import relative_date_to_date
from TodoListBase import InvalidTodoException from topydo.lib.TodoListBase import InvalidTodoException
import TodoList
class AddCommand(Command.Command): class AddCommand(Command):
def __init__(self, p_args, p_todolist, def __init__(self, p_args, p_todolist,
p_out=lambda a: None, p_out=lambda a: None,
p_err=lambda a: None, p_err=lambda a: None,
p_prompt=lambda a: None): p_prompt=lambda a: None):
super(AddCommand, self).__init__(p_args, p_todolist, p_out, p_err, p_prompt) super(AddCommand, self).__init__(
p_args, p_todolist, p_out, p_err, p_prompt)
self.text = ' '.join(p_args) self.text = ' '.join(p_args)
self.todo = None
def _preprocess_input_todo(self): def _preprocess_input_todo(self):
""" """
...@@ -103,7 +104,8 @@ class AddCommand(Command.Command): ...@@ -103,7 +104,8 @@ class AddCommand(Command.Command):
return """Synopsis: add <text>""" return """Synopsis: add <text>"""
def help(self): def help(self):
return """This subcommand automatically adds the creation date to the added item. return """\
This subcommand automatically adds the creation date to the added item.
<text> may contain: <text> may contain:
......
# Topydo - A todo.txt client written in Python. # Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl> # Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from Command import * from topydo.lib.Command import Command, InvalidCommandArgument
from PrettyPrinter import pretty_print from topydo.lib.PrettyPrinter import pretty_print
from TodoListBase import InvalidTodoException from topydo.lib.TodoListBase import InvalidTodoException
class AppendCommand(Command): class AppendCommand(Command):
def __init__(self, p_args, p_todolist, def __init__(self, p_args, p_todolist,
p_out=lambda a: None, p_out=lambda a: None,
p_err=lambda a: None, p_err=lambda a: None,
p_prompt=lambda a: None): p_prompt=lambda a: None):
super(AppendCommand, self).__init__(p_args, p_todolist, p_out, p_err, p_prompt=lambda a: None) super(AppendCommand, self).__init__(
p_args, p_todolist, p_out, p_err, p_prompt=lambda a: None)
def execute(self): def execute(self):
if not super(AppendCommand, self).execute(): if not super(AppendCommand, self).execute():
...@@ -48,4 +49,6 @@ class AppendCommand(Command): ...@@ -48,4 +49,6 @@ class AppendCommand(Command):
return """Synopsis: append <number> <text>""" return """Synopsis: append <number> <text>"""
def help(self): def help(self):
return """Adds the given <text> to the end of the todo indicated by <number>.""" return """\
Adds the given <text> to the end of the todo indicated by <number>.
"""
# Topydo - A todo.txt client written in Python. # Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl> # Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import Command from topydo.lib.Command import Command
class ArchiveCommand(Command.Command): class ArchiveCommand(Command):
def __init__(self, p_todolist, p_archive_list): def __init__(self, p_todolist, p_archive_list):
""" """
Constructor. Constructor.
......
...@@ -70,12 +70,14 @@ class Command(object): ...@@ -70,12 +70,14 @@ class Command(object):
return value return value
def getopt(self, p_flags, p_long=[]): def getopt(self, p_flags, p_long=None):
p_long = p_long or []
try: try:
result = getopt.getopt(self.args, p_flags, p_long) result = getopt.getopt(self.args, p_flags, p_long)
except getopt.GetoptError as e: except getopt.GetoptError as goe:
self.error(str(e)) self.error(str(goe))
result = ([],self.args) result = ([], self.args)
return result return result
......
...@@ -27,6 +27,12 @@ class ConfigError(Exception): ...@@ -27,6 +27,12 @@ class ConfigError(Exception):
class _Config: class _Config:
def __init__(self, p_path=None): def __init__(self, p_path=None):
"""
Constructor.
If p_path is given, that is the only configuration file that will be
read.
"""
self.sections = ['topydo', 'tags', 'sort', 'ls'] self.sections = ['topydo', 'tags', 'sort', 'ls']
self.defaults = { self.defaults = {
...@@ -57,9 +63,17 @@ class _Config: ...@@ -57,9 +63,17 @@ class _Config:
self.cp = ConfigParser.SafeConfigParser(self.defaults) self.cp = ConfigParser.SafeConfigParser(self.defaults)
files = ["/etc/topydo.conf", self._home_config_path(), ".topydo", "topydo.conf"] files = [
"/etc/topydo.conf",
self._home_config_path(),
".topydo",
"topydo.conf"
]
# when a path is given, *only* use the values in that file, or the
# defaults listed above.
if p_path != None: if p_path != None:
files.append(p_path) files = [p_path]
self.cp.read(files) self.cp.read(files)
...@@ -144,14 +158,16 @@ class _Config: ...@@ -144,14 +158,16 @@ class _Config:
def config(p_path=None): def config(p_path=None):
""" """
Retrieve the config instance. Retrieve the config instance.
If a path is given, the instance is overwritten by the one that supplies an If a path is given, the instance is overwritten by the one that supplies an
additional filename (for testability). additional filename (for testability). Moreover, no other configuration
files will be read when a path is given.
""" """
if not config.instance or p_path != None: if not config.instance or p_path != None:
try: try:
config.instance = _Config(p_path) config.instance = _Config(p_path)
except ConfigParser.ParsingError as e: except ConfigParser.ParsingError as perr:
raise ConfigError(str(e)) raise ConfigError(str(perr))
return config.instance return config.instance
......
...@@ -14,9 +14,11 @@ ...@@ -14,9 +14,11 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from Command import * import re
from PrettyPrinter import *
from TodoListBase import InvalidTodoException from topydo.lib.Command import Command, InvalidCommandArgument
from topydo.lib.PrettyPrinter import pretty_print, pretty_print_list
from topydo.lib.TodoListBase import InvalidTodoException
class DCommand(Command): class DCommand(Command):
""" """
...@@ -28,7 +30,8 @@ class DCommand(Command): ...@@ -28,7 +30,8 @@ class DCommand(Command):
p_out=lambda a: None, p_out=lambda a: None,
p_err=lambda a: None, p_err=lambda a: None,
p_prompt=lambda a: None): p_prompt=lambda a: None):
super(DCommand, self).__init__(p_args, p_todolist, p_out, p_err, p_prompt) super(DCommand, self).__init__(
p_args, p_todolist, p_out, p_err, p_prompt)
self.force = False self.force = False
...@@ -44,7 +47,7 @@ class DCommand(Command): ...@@ -44,7 +47,7 @@ class DCommand(Command):
""" Default implementation of getting specific flags. """ """ Default implementation of getting specific flags. """
return ("", []) return ("", [])
def process_flag(self): def process_flag(self, p_option, p_value):
""" Default implementation of processing specific flags. """ """ Default implementation of processing specific flags. """
pass pass
...@@ -61,7 +64,9 @@ class DCommand(Command): ...@@ -61,7 +64,9 @@ class DCommand(Command):
self.args = args self.args = args
def _uncompleted_children(self, p_todo): def _uncompleted_children(self, p_todo):
return sorted([t for t in self.todolist.children(p_todo) if not t.is_completed()]) return sorted(
[t for t in self.todolist.children(p_todo) if not t.is_completed()]
)
def _print_list(self, p_todos): def _print_list(self, p_todos):
filters = [self.todolist.pp_number()] filters = [self.todolist.pp_number()]
...@@ -75,17 +80,17 @@ class DCommand(Command): ...@@ -75,17 +80,17 @@ class DCommand(Command):
return "" return ""
def _process_subtasks(self): def _process_subtasks(self):
children = self._uncompleted_children(self.todo) children = self._uncompleted_children(self.todo)
if children: if children:
self._print_list(children) self._print_list(children)
if not self.force: if not self.force:
confirmation = self.prompt(self.prompt_text()) confirmation = self.prompt(self.prompt_text())
if not self.force and re.match('^y(es)?$', confirmation, re.I): if not self.force and re.match('^y(es)?$', confirmation, re.I):
for child in children: for child in children:
self.execute_specific_core(child) self.execute_specific_core(child)
self.out(self.prefix() + pretty_print(child)) self.out(self.prefix() + pretty_print(child))
def _print_unlocked_todos(self, p_old, p_new): def _print_unlocked_todos(self, p_old, p_new):
delta = [todo for todo in p_new if todo not in p_old] delta = [todo for todo in p_new if todo not in p_old]
...@@ -103,10 +108,13 @@ class DCommand(Command): ...@@ -103,10 +108,13 @@ class DCommand(Command):
Since these todos pop up at the end of the list, we cut off the list Since these todos pop up at the end of the list, we cut off the list
just before that point. just before that point.
""" """
return [todo for todo in self.todolist.todos()[:self.length] if not self._uncompleted_children(todo) and todo.is_active()] return [todo for todo in self.todolist.todos()[:self.length]
if not self._uncompleted_children(todo) and todo.is_active()]
def condition(self): def condition(self):
""" An additional condition whether execute_specific should be executed. """ """
An additional condition whether execute_specific should be executed.
"""
return True return True
def condition_failed_text(self): def condition_failed_text(self):
......
...@@ -14,15 +14,16 @@ ...@@ -14,15 +14,16 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from DCommand import DCommand from topydo.lib.DCommand import DCommand
from PrettyPrinter import pretty_print from topydo.lib.PrettyPrinter import pretty_print
class DeleteCommand(DCommand): class DeleteCommand(DCommand):
def __init__(self, p_args, p_todolist, def __init__(self, p_args, p_todolist,
p_out=lambda a: None, p_out=lambda a: None,
p_err=lambda a: None, p_err=lambda a: None,
p_prompt=lambda a: None): p_prompt=lambda a: None):
super(DeleteCommand, self).__init__(p_args, p_todolist, p_out, p_err, p_prompt) super(DeleteCommand, self).__init__(
p_args, p_todolist, p_out, p_err, p_prompt)
def prompt_text(self): def prompt_text(self):
return "Also remove subtasks? [y/N] " return "Also remove subtasks? [y/N] "
......
# Topydo - A todo.txt client written in Python. # Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl> # Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from Command import * from topydo.lib.Command import Command, InvalidCommandArgument
from Config import config from topydo.lib.Config import config
import Filter from topydo.lib import Filter
import Sorter from topydo.lib.Sorter import Sorter
from TodoListBase import InvalidTodoException from topydo.lib.TodoListBase import InvalidTodoException
import View from topydo.lib.View import View
class DepCommand(Command): class DepCommand(Command):
def __init__(self, p_args, p_todolist, def __init__(self, p_args, p_todolist,
p_out=lambda a: None, p_out=lambda a: None,
p_err=lambda a: None, p_err=lambda a: None,
p_prompt=lambda a: None): p_prompt=lambda a: None):
super(DepCommand, self).__init__(p_args, p_todolist, p_out, p_err, p_prompt) super(DepCommand, self).__init__(
p_args, p_todolist, p_out, p_err, p_prompt)
try: try:
self.subsubcommand = self.argument(0) self.subsubcommand = self.argument(0)
...@@ -94,9 +95,9 @@ class DepCommand(Command): ...@@ -94,9 +95,9 @@ class DepCommand(Command):
self.error(self.usage()) self.error(self.usage())
if todos: if todos:
sorter = Sorter.Sorter(config().sort_string()) sorter = Sorter(config().sort_string())
instance_filter = Filter.InstanceFilter(todos) instance_filter = Filter.InstanceFilter(todos)
view = View.View(sorter, [instance_filter], self.todolist) view = View(sorter, [instance_filter], self.todolist)
self.out(view.pretty_print()) self.out(view.pretty_print())
except InvalidTodoException: except InvalidTodoException:
self.error("Invalid todo number given.") self.error("Invalid todo number given.")
...@@ -130,7 +131,10 @@ class DepCommand(Command): ...@@ -130,7 +131,10 @@ class DepCommand(Command):
dep clean""" dep clean"""
def help(self): def help(self):
return """* add: Adds a dependency. Using 1 before 2 creates a dependency from todo item 2 to 1. return """\
* rm (alias: del): Removes a dependency. * add : Adds a dependency. Using 1 before 2 creates a dependency
* ls: Lists all dependencies to or from a certain todo. from todo item 2 to 1.
* clean (alias: gc): Removes redundant id or p tags.""" * rm (alias: del) : Removes a dependency.
* ls : Lists all dependencies to or from a certain todo.
* clean (alias: gc): Removes redundant id or p tags.
"""
# Topydo - A todo.txt client written in Python. # Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl> # Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from Command import * from topydo.lib.Command import Command, InvalidCommandArgument
from PrettyPrinter import pretty_print from topydo.lib.PrettyPrinter import pretty_print
from TodoListBase import InvalidTodoException from topydo.lib.TodoListBase import InvalidTodoException
class DepriCommand(Command): class DepriCommand(Command):
def __init__(self, p_args, p_todolist, def __init__(self, p_args, p_todolist,
p_out=lambda a: None, p_out=lambda a: None,
p_err=lambda a: None, p_err=lambda a: None,
p_prompt=lambda a: None): p_prompt=lambda a: None):
super(DepriCommand, self).__init__(p_args, p_todolist, p_out, p_err, p_prompt) super(DepriCommand, self).__init__(
p_args, p_todolist, p_out, p_err, p_prompt)
def execute(self): def execute(self):
if not super(DepriCommand, self).execute(): if not super(DepriCommand, self).execute():
......
...@@ -15,12 +15,11 @@ ...@@ -15,12 +15,11 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from datetime import date from datetime import date
import re
from DCommand import DCommand from topydo.lib.DCommand import DCommand
from PrettyPrinter import pretty_print from topydo.lib.PrettyPrinter import pretty_print
from Recurrence import advance_recurring_todo, strict_advance_recurring_todo from topydo.lib.Recurrence import advance_recurring_todo, strict_advance_recurring_todo
from Utils import date_string_to_date from topydo.lib.Utils import date_string_to_date
class DoCommand(DCommand): class DoCommand(DCommand):
def __init__(self, p_args, p_todolist, def __init__(self, p_args, p_todolist,
...@@ -31,7 +30,8 @@ class DoCommand(DCommand): ...@@ -31,7 +30,8 @@ class DoCommand(DCommand):
self.strict_recurrence = False self.strict_recurrence = False
self.completion_date = date.today() self.completion_date = date.today()
super(DoCommand, self).__init__(p_args, p_todolist, p_out, p_err, p_prompt) super(DoCommand, self).__init__(
p_args, p_todolist, p_out, p_err, p_prompt)
def get_flags(self): def get_flags(self):
""" Additional flags. """ """ Additional flags. """
...@@ -60,7 +60,9 @@ class DoCommand(DCommand): ...@@ -60,7 +60,9 @@ class DoCommand(DCommand):
return "Completed: " return "Completed: "
def condition(self): def condition(self):
""" An additional condition whether execute_specific should be executed. """ """
An additional condition whether execute_specific should be executed.
"""
return not self.todo.is_completed() return not self.todo.is_completed()
def condition_failed_text(self): def condition_failed_text(self):
......
# Topydo - A todo.txt client written in Python. # Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl> # Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from datetime import date
import re import re
from Config import config from topydo.lib.Config import config
from RelativeDate import relative_date_to_date from topydo.lib.RelativeDate import relative_date_to_date
from Utils import date_string_to_date from topydo.lib.Utils import date_string_to_date
class Filter(object): class Filter(object):
def filter(self, p_todos): def filter(self, p_todos):
...@@ -61,6 +60,8 @@ class GrepFilter(Filter): ...@@ -61,6 +60,8 @@ class GrepFilter(Filter):
""" Matches when the todo text contains a text. """ """ Matches when the todo text contains a text. """
def __init__(self, p_expression, p_case_sensitive=None): def __init__(self, p_expression, p_case_sensitive=None):
super(GrepFilter, self).__init__()
self.expression = p_expression self.expression = p_expression
if p_case_sensitive != None: if p_case_sensitive != None:
...@@ -108,6 +109,7 @@ class DependencyFilter(Filter): ...@@ -108,6 +109,7 @@ class DependencyFilter(Filter):
Pass on a TodoList instance such that the dependencies can be Pass on a TodoList instance such that the dependencies can be
looked up. looked up.
""" """
super(DependencyFilter, self).__init__()
self.todolist = p_todolist self.todolist = p_todolist
def match(self, p_todo): def match(self, p_todo):
...@@ -129,6 +131,7 @@ class InstanceFilter(Filter): ...@@ -129,6 +131,7 @@ class InstanceFilter(Filter):
This is handy for constructing a view given a plain list of Todo items. This is handy for constructing a view given a plain list of Todo items.
""" """
super(InstanceFilter, self).__init__()
self.todos = p_todos self.todos = p_todos
def match(self, p_todo): def match(self, p_todo):
...@@ -143,15 +146,17 @@ class InstanceFilter(Filter): ...@@ -143,15 +146,17 @@ class InstanceFilter(Filter):
class LimitFilter(Filter): class LimitFilter(Filter):
def __init__(self, p_limit): def __init__(self, p_limit):
super(LimitFilter, self).__init__()
self.limit = p_limit self.limit = p_limit
def filter(self, p_todos): def filter(self, p_todos):
return p_todos[:self.limit] if self.limit >= 0 else p_todos return p_todos[:self.limit] if self.limit >= 0 else p_todos
ORDINAL_TAG_MATCH = r"(?P<key>[^:]*):(?P<operator><=?|=|>=?|!)?(?P<value>\S*)" ORDINAL_TAG_MATCH = r"(?P<key>[^:]*):(?P<operator><=?|=|>=?|!)?(?P<value>\S+)"
class OrdinalTagFilter(Filter): class OrdinalTagFilter(Filter):
def __init__(self, p_expression): def __init__(self, p_expression):
super(OrdinalTagFilter, self).__init__()
match = re.match(ORDINAL_TAG_MATCH, p_expression) match = re.match(ORDINAL_TAG_MATCH, p_expression)
if match: if match:
self.key = match.group('key') self.key = match.group('key')
......
# Topydo - A todo.txt client written in Python. # Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl> # Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
...@@ -141,8 +141,7 @@ class DirectedGraph(object): ...@@ -141,8 +141,7 @@ class DirectedGraph(object):
""" """
Returns True if the client registered an edge with the given id. Returns True if the client registered an edge with the given id.
""" """
l = [e for e in self._edge_numbers.itervalues() if e == p_id] return p_id in self._edge_numbers.values()
return len(l) > 0
def edge_id(self, p_from, p_to): def edge_id(self, p_from, p_to):
""" """
......
# Topydo - A todo.txt client written in Python. # Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl> # Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
...@@ -25,7 +25,7 @@ future. ...@@ -25,7 +25,7 @@ future.
from datetime import date from datetime import date
from Config import config from topydo.lib.Config import config
IMPORTANCE_VALUE = {'A': 3, 'B': 2, 'C': 1} IMPORTANCE_VALUE = {'A': 3, 'B': 2, 'C': 1}
......
# Topydo - A todo.txt client written in Python. # Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl> # Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import re import re
import Command from topydo.lib.Command import Command
from Config import config from topydo.lib.Config import config
import Filter from topydo.lib import Filter
from PrettyPrinter import pp_indent from topydo.lib.PrettyPrinter import pp_indent
import Sorter from topydo.lib.Sorter import Sorter
class ListCommand(Command.Command): class ListCommand(Command):
def __init__(self, p_args, p_todolist, def __init__(self, p_args, p_todolist,
p_out=lambda a: None, p_out=lambda a: None,
p_err=lambda a: None, p_err=lambda a: None,
p_prompt=lambda a: None): p_prompt=lambda a: None):
super(ListCommand, self).__init__(p_args, p_todolist, p_out, p_err, p_prompt) super(ListCommand, self).__init__(
p_args, p_todolist, p_out, p_err, p_prompt)
self.sort_expression = config().sort_string() self.sort_expression = config().sort_string()
self.show_all = False self.show_all = False
...@@ -35,11 +36,11 @@ class ListCommand(Command.Command): ...@@ -35,11 +36,11 @@ class ListCommand(Command.Command):
def _process_flags(self): def _process_flags(self):
opts, args = self.getopt('s:x') opts, args = self.getopt('s:x')
for o, a in opts: for opt, value in opts:
if o == '-x': if opt == '-x':
self.show_all = True self.show_all = True
elif o == '-s': elif opt == '-s':
self.sort_expression = a self.sort_expression = value
self.args = args self.args = args
...@@ -53,7 +54,8 @@ class ListCommand(Command.Command): ...@@ -53,7 +54,8 @@ class ListCommand(Command.Command):
argfilter = Filter.OrdinalTagFilter(arg) argfilter = Filter.OrdinalTagFilter(arg)
elif len(arg) > 1 and arg[0] == '-': elif len(arg) > 1 and arg[0] == '-':
# when a word starts with -, exclude it # when a word starts with -, exclude it
argfilter = Filter.NegationFilter(Filter.GrepFilter(arg[1:])) argfilter = Filter.GrepFilter(arg[1:])
argfilter = Filter.NegationFilter(argfilter)
else: else:
argfilter = Filter.GrepFilter(arg) argfilter = Filter.GrepFilter(arg)
...@@ -78,7 +80,7 @@ class ListCommand(Command.Command): ...@@ -78,7 +80,7 @@ class ListCommand(Command.Command):
self._process_flags() self._process_flags()
sorter = Sorter.Sorter(self.sort_expression) sorter = Sorter(self.sort_expression)
filters = self._filters() filters = self._filters()
pp_filters = [pp_indent(config().list_indent())] pp_filters = [pp_indent(config().list_indent())]
...@@ -88,7 +90,8 @@ class ListCommand(Command.Command): ...@@ -88,7 +90,8 @@ class ListCommand(Command.Command):
return """Synopsis: ls [-x] [-s <sort_expression>] [expression]""" return """Synopsis: ls [-x] [-s <sort_expression>] [expression]"""
def help(self): def help(self):
return """Lists all relevant todos. A todo is relevant when: return """\
Lists all relevant todos. A todo is relevant when:
* has not been completed yet; * has not been completed yet;
* the start date (if present) has passed; * the start date (if present) has passed;
...@@ -98,4 +101,5 @@ When an expression is given, only the todos matching that expression are shown. ...@@ -98,4 +101,5 @@ When an expression is given, only the todos matching that expression are shown.
-s : Sort the list according to a sort expression. Defaults to the expression -s : Sort the list according to a sort expression. Defaults to the expression
in the configuration. in the configuration.
-x : Show all todos (i.e. do not filter on dependencies or relevance).""" -x : Show all todos (i.e. do not filter on dependencies or relevance).
"""
# Topydo - A todo.txt client written in Python. # Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl> # Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import Command from topydo.lib.Command import Command
class ListContextCommand(Command.Command): class ListContextCommand(Command):
def __init__(self, p_args, p_todolist, def __init__(self, p_args, p_todolist,
p_out=lambda a: None, p_out=lambda a: None,
p_err=lambda a: None, p_err=lambda a: None,
p_prompt=lambda a: None): p_prompt=lambda a: None):
super(ListContextCommand, self).__init__(p_args, p_todolist, p_out, p_err, p_prompt) super(ListContextCommand, self).__init__(
p_args, p_todolist, p_out, p_err, p_prompt)
def execute(self): def execute(self):
if not super(ListContextCommand, self).execute(): if not super(ListContextCommand, self).execute():
...@@ -31,7 +32,7 @@ class ListContextCommand(Command.Command): ...@@ -31,7 +32,7 @@ class ListContextCommand(Command.Command):
self.out(context) self.out(context)
def usage(self): def usage(self):
return """Synopsis: lscon""" return """Synopsis: lscon"""
def help(self): def help(self):
return """Lists all contexts in the todo list.""" return """Lists all contexts in the todo list."""
# Topydo - A todo.txt client written in Python. # Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl> # Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import Command from topydo.lib.Command import Command
class ListProjectCommand(Command.Command): class ListProjectCommand(Command):
def __init__(self, p_args, p_todolist, def __init__(self, p_args, p_todolist,
p_out=lambda a: None, p_out=lambda a: None,
p_err=lambda a: None, p_err=lambda a: None,
p_prompt=lambda a: None): p_prompt=lambda a: None):
super(ListProjectCommand, self).__init__(p_args, p_todolist, p_out, p_err, p_prompt) super(ListProjectCommand, self).__init__(
p_args, p_todolist, p_out, p_err, p_prompt)
def execute(self): def execute(self):
if not super(ListProjectCommand, self).execute(): if not super(ListProjectCommand, self).execute():
...@@ -31,7 +32,7 @@ class ListProjectCommand(Command.Command): ...@@ -31,7 +32,7 @@ class ListProjectCommand(Command.Command):
self.out(project) self.out(project)
def usage(self): def usage(self):
return """Synopsis: lscon""" return """Synopsis: lscon"""
def help(self): def help(self):
return """Lists all projects in the todo list.""" return """Lists all projects in the todo list."""
# Topydo - A todo.txt client written in Python. # Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl> # Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from datetime import date, timedelta from datetime import date, timedelta
from Command import * from topydo.lib.Command import Command, InvalidCommandArgument
from Config import config from topydo.lib.Config import config
from PrettyPrinter import * from topydo.lib.PrettyPrinter import pretty_print
from RelativeDate import relative_date_to_date from topydo.lib.RelativeDate import relative_date_to_date
from TodoListBase import InvalidTodoException from topydo.lib.TodoListBase import InvalidTodoException
from Utils import date_string_to_date from topydo.lib.Utils import date_string_to_date
class PostponeCommand(Command): class PostponeCommand(Command):
def __init__(self, p_args, p_todolist, def __init__(self, p_args, p_todolist,
p_out=lambda a: None, p_out=lambda a: None,
p_err=lambda a: None, p_err=lambda a: None,
p_prompt=lambda a: None): p_prompt=lambda a: None):
super(PostponeCommand, self).__init__(p_args, p_todolist, p_out, p_err, p_prompt) super(PostponeCommand, self).__init__(
p_args, p_todolist, p_out, p_err, p_prompt)
self.move_start_date = False self.move_start_date = False
def _process_flags(self): def _process_flags(self):
opts, args = self.getopt('s') opts, args = self.getopt('s')
for o, a in opts: for opt, _ in opts:
if o == '-s': if opt == '-s':
self.move_start_date = True self.move_start_date = True
self.args = args self.args = args
...@@ -86,7 +87,8 @@ class PostponeCommand(Command): ...@@ -86,7 +87,8 @@ class PostponeCommand(Command):
return "Synopsis: postpone [-s] <NUMBER> <PATTERN>" return "Synopsis: postpone [-s] <NUMBER> <PATTERN>"
def help(self): def help(self):
return """Postpone a todo item with the given number and the given pattern. return """\
Postpone a todo item with the given number and the given pattern.
Postponing is done by adjusting the due date of the todo, and if the -s flag is Postponing is done by adjusting the due date of the todo, and if the -s flag is
given, the start date accordingly. given, the start date accordingly.
...@@ -94,4 +96,5 @@ given, the start date accordingly. ...@@ -94,4 +96,5 @@ given, the start date accordingly.
The pattern is a relative date, written in the format <COUNT><PERIOD> where The pattern is a relative date, written in the format <COUNT><PERIOD> where
count is a number and <PERIOD> is either 'd', 'w', 'm' or 'y', which stands for count is a number and <PERIOD> is either 'd', 'w', 'm' or 'y', which stands for
days, weeks, months and years respectively. Example: 'postpone 1 1w' postpones days, weeks, months and years respectively. Example: 'postpone 1 1w' postpones
todo number 1 for 1 week.""" todo number 1 for 1 week.
"""
# Topydo - A todo.txt client written in Python. # Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl> # Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
import re import re
from Config import config from topydo.lib.Config import config
PRIORITY_COLORS = { PRIORITY_COLORS = {
'A': '\033[36m', # cyan 'A': '\033[36m', # cyan
...@@ -46,7 +46,9 @@ def pp_color(p_todo_str, p_todo): ...@@ -46,7 +46,9 @@ def pp_color(p_todo_str, p_todo):
p_todo_str = '%s%s%s' % (color, p_todo_str, NEUTRAL_COLOR) p_todo_str = '%s%s%s' % (color, p_todo_str, NEUTRAL_COLOR)
if config().highlight_projects_contexts(): if config().highlight_projects_contexts():
p_todo_str = re.sub(r'\B(\+|@)(\S*\w)', PROJECT_COLOR + r'\g<0>' + color, \ p_todo_str = re.sub(
r'\B(\+|@)(\S*\w)',
PROJECT_COLOR + r'\g<0>' + color,
p_todo_str) p_todo_str)
p_todo_str += NEUTRAL_COLOR p_todo_str += NEUTRAL_COLOR
...@@ -56,7 +58,7 @@ def pp_color(p_todo_str, p_todo): ...@@ -56,7 +58,7 @@ def pp_color(p_todo_str, p_todo):
def pp_indent(p_indent=0): def pp_indent(p_indent=0):
return lambda s, t: ' ' * p_indent + s return lambda s, t: ' ' * p_indent + s
def pretty_print(p_todo, p_filters=[]): def pretty_print(p_todo, p_filters=None):
""" """
Given a todo item, pretty print it and return a list of formatted strings. Given a todo item, pretty print it and return a list of formatted strings.
...@@ -68,6 +70,7 @@ def pretty_print(p_todo, p_filters=[]): ...@@ -68,6 +70,7 @@ def pretty_print(p_todo, p_filters=[]):
Example is pp_color in this fle. Example is pp_color in this fle.
""" """
p_filters = p_filters or []
todo_str = str(p_todo) todo_str = str(p_todo)
...@@ -76,9 +79,10 @@ def pretty_print(p_todo, p_filters=[]): ...@@ -76,9 +79,10 @@ def pretty_print(p_todo, p_filters=[]):
return todo_str return todo_str
def pretty_print_list(p_todos, p_filters=[]): def pretty_print_list(p_todos, p_filters=None):
""" """
Given a list of todo items, pretty print it and return a list of Given a list of todo items, pretty print it and return a list of
formatted strings. formatted strings.
""" """
p_filters = p_filters or []
return [pretty_print(todo, p_filters) for todo in p_todos] return [pretty_print(todo, p_filters) for todo in p_todos]
...@@ -14,17 +14,18 @@ ...@@ -14,17 +14,18 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from Command import * from topydo.lib.Command import Command, InvalidCommandArgument
from PrettyPrinter import pretty_print from topydo.lib.PrettyPrinter import pretty_print
from TodoListBase import InvalidTodoException from topydo.lib.TodoListBase import InvalidTodoException
from Utils import is_valid_priority from topydo.lib.Utils import is_valid_priority
class PriorityCommand(Command): class PriorityCommand(Command):
def __init__(self, p_args, p_todolist, def __init__(self, p_args, p_todolist,
p_out=lambda a: None, p_out=lambda a: None,
p_err=lambda a: None, p_err=lambda a: None,
p_prompt=lambda a: None): p_prompt=lambda a: None):
super(PriorityCommand, self).__init__(p_args, p_todolist, p_out, p_err, p_prompt) super(PriorityCommand, self).__init__(
p_args, p_todolist, p_out, p_err, p_prompt)
def execute(self): def execute(self):
if not super(PriorityCommand, self).execute(): if not super(PriorityCommand, self).execute():
...@@ -61,4 +62,6 @@ class PriorityCommand(Command): ...@@ -61,4 +62,6 @@ class PriorityCommand(Command):
return """Synopsis: pri <NUMBER> <PRIORITY>""" return """Synopsis: pri <NUMBER> <PRIORITY>"""
def help(self): def help(self):
return """Sets the priority of todo the given number to the given priority.""" return """\
Sets the priority of todo the given number to the given priority.
"""
# Topydo - A todo.txt client written in Python. # Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl> # Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
...@@ -18,9 +18,9 @@ ...@@ -18,9 +18,9 @@
from datetime import date, timedelta from datetime import date, timedelta
from Config import config from topydo.lib.Config import config
from RelativeDate import relative_date_to_date from topydo.lib.RelativeDate import relative_date_to_date
import Todo from topydo.lib.Todo import Todo
class NoRecurrenceException(Exception): class NoRecurrenceException(Exception):
pass pass
...@@ -33,7 +33,7 @@ def _advance_recurring_todo_helper(p_todo, p_offset): ...@@ -33,7 +33,7 @@ def _advance_recurring_todo_helper(p_todo, p_offset):
When no recurrence tag is present, an exception is raised. When no recurrence tag is present, an exception is raised.
""" """
todo = Todo.Todo(p_todo.source()) todo = Todo(p_todo.source())
pattern = todo.tag_value('rec') pattern = todo.tag_value('rec')
if not pattern: if not pattern:
......
# Topydo - A todo.txt client written in Python. # Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl> # Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
...@@ -81,7 +81,18 @@ def relative_date_to_date(p_date, p_offset=date.today()): ...@@ -81,7 +81,18 @@ def relative_date_to_date(p_date, p_offset=date.today()):
p_date = p_date.lower() p_date = p_date.lower()
relative = re.match('(?P<length>[0-9]+)(?P<period>[dwmy])$', p_date, re.I) relative = re.match('(?P<length>[0-9]+)(?P<period>[dwmy])$', p_date, re.I)
weekday = re.match('mo(n(day)?)?$|tu(e(sday)?)?$|we(d(nesday)?)?$|th(u(rsday)?)?$|fr(i(day)?)?$|sa(t(urday)?)?$|su(n(day)?)?$', p_date)
monday = 'mo(n(day)?)?$'
tuesday = 'tu(e(sday)?)?$'
wednesday = 'we(d(nesday)?)?$'
thursday = 'th(u(rsday)?)?$'
friday = 'fr(i(day)?)?$'
saturday = 'sa(t(urday)?)?$'
sunday = 'su(n(day)?)?$'
weekday = re.match('|'.join(
[monday, tuesday, wednesday, thursday, friday, saturday, sunday]),
p_date)
if relative: if relative:
length = relative.group('length') length = relative.group('length')
......
...@@ -14,17 +14,17 @@ ...@@ -14,17 +14,17 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from Command import * from topydo.lib.Command import Command, InvalidCommandArgument
from Config import config from topydo.lib.Config import config
import Filter from topydo.lib.Sorter import Sorter
import Sorter
class SortCommand(Command): class SortCommand(Command):
def __init__(self, p_args, p_todolist, def __init__(self, p_args, p_todolist,
p_out=lambda a: None, p_out=lambda a: None,
p_err=lambda a: None, p_err=lambda a: None,
p_prompt=lambda a: None): p_prompt=lambda a: None):
super(SortCommand, self).__init__(p_args, p_todolist, p_out, p_err, p_prompt) super(SortCommand, self).__init__(
p_args, p_todolist, p_out, p_err, p_prompt)
def execute(self): def execute(self):
if not super(SortCommand, self).execute(): if not super(SortCommand, self).execute():
...@@ -35,7 +35,7 @@ class SortCommand(Command): ...@@ -35,7 +35,7 @@ class SortCommand(Command):
except InvalidCommandArgument: except InvalidCommandArgument:
expression = config().sort_string() expression = config().sort_string()
sorter = Sorter.Sorter(expression) # TODO: validate sorter = Sorter(expression) # TODO: validate
sorted_todos = sorter.sort(self.todolist.todos()) sorted_todos = sorter.sort(self.todolist.todos())
self.todolist.erase() self.todolist.erase()
...@@ -47,8 +47,9 @@ class SortCommand(Command): ...@@ -47,8 +47,9 @@ class SortCommand(Command):
return """Synopsis: sort [expression]""" return """Synopsis: sort [expression]"""
def help(self): def help(self):
return """Sorts the file according to the expression. If no expression is given, return """\
the expression in the configuration is used. Sorts the file according to the expression. If no expression is given, the
expression in the configuration is used.
The following sort properties are supported: The following sort properties are supported:
......
# Topydo - A todo.txt client written in Python. # Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl> # Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
from datetime import date from datetime import date
import re import re
from Importance import importance, average_importance from topydo.lib.Importance import importance, average_importance
def is_priority_field(p_field): def is_priority_field(p_field):
""" Returns True when the field name denotes the priority. """ """ Returns True when the field name denotes the priority. """
...@@ -45,9 +45,9 @@ def get_field_function(p_field): ...@@ -45,9 +45,9 @@ def get_field_function(p_field):
result = (lambda a: a.completion_date() if a.completion_date() \ result = (lambda a: a.completion_date() if a.completion_date() \
else date.max) else date.max)
elif p_field == 'importance': elif p_field == 'importance':
result = lambda a: importance(a) result = importance
elif p_field == 'importance-avg' or p_field == 'importance-average': elif p_field == 'importance-avg' or p_field == 'importance-average':
result = lambda a: average_importance(a) result = average_importance
elif p_field == 'text': elif p_field == 'text':
result = lambda a: a.text() result = lambda a: a.text()
else: else:
......
# Topydo - A todo.txt client written in Python. # Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl> # Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from Command import * from topydo.lib.Command import Command, InvalidCommandArgument
from TodoListBase import InvalidTodoException from topydo.lib.TodoListBase import InvalidTodoException
from PrettyPrinter import pretty_print from topydo.lib.PrettyPrinter import pretty_print
class TagCommand(Command): class TagCommand(Command):
def __init__(self, p_args, p_todolist, def __init__(self, p_args, p_todolist,
p_out=lambda a: None, p_out=lambda a: None,
p_err=lambda a: None, p_err=lambda a: None,
p_prompt=lambda a: None): p_prompt=lambda a: None):
super(TagCommand, self).__init__(p_args, p_todolist, p_out, p_err, p_prompt) super(TagCommand, self).__init__(
p_args, p_todolist, p_out, p_err, p_prompt)
self.force = False self.force = False
self.force_add = False self.force_add = False
...@@ -31,10 +32,11 @@ class TagCommand(Command): ...@@ -31,10 +32,11 @@ class TagCommand(Command):
self.tag = None self.tag = None
self.value = None self.value = None
self.values = [] self.values = []
self.current_values = []
def _process_flags(self): def _process_flags(self):
flags, args = self.getopt("af") flags, args = self.getopt("af")
for flag, value in flags: for flag, _ in flags:
if flag == "-a": if flag == "-a":
self.force_add = True self.force_add = True
elif flag == "-f": elif flag == "-f":
...@@ -70,7 +72,8 @@ class TagCommand(Command): ...@@ -70,7 +72,8 @@ class TagCommand(Command):
for i, value in enumerate(self.current_values): for i, value in enumerate(self.current_values):
self.out("%2d. %s" % (i + 1, value)) self.out("%2d. %s" % (i + 1, value))
answer = self.prompt('Which value to remove? Enter number or "all": ') answer = self.prompt(
'Which value to remove? Enter number or "all": ')
if answer != "all": if answer != "all":
try: try:
...@@ -118,9 +121,12 @@ class TagCommand(Command): ...@@ -118,9 +121,12 @@ class TagCommand(Command):
return """Synopsis: tag [-a] [-f] <NUMBER> <tag> [<value>]""" return """Synopsis: tag [-a] [-f] <NUMBER> <tag> [<value>]"""
def help(self): def help(self):
return """Sets the given tag to the given todo number with the given value. If return """\
the value is omitted, the tag is removed from the todo item. Sets the given tag to the given todo number with the given value. If the value
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. -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.
"""
# Topydo - A todo.txt client written in Python. # Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl> # Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
...@@ -20,24 +20,24 @@ This module provides the Todo class. ...@@ -20,24 +20,24 @@ This module provides the Todo class.
from datetime import date from datetime import date
from Config import config from topydo.lib.Config import config
import Utils from topydo.lib.TodoBase import TodoBase
import TodoBase from topydo.lib.Utils import date_string_to_date
class Todo(TodoBase.TodoBase): class Todo(TodoBase):
""" """
This class adds common functionality with respect to dates to the Todo This class adds common functionality with respect to dates to the Todo
base class, mainly by interpreting the start and due dates of task. base class, mainly by interpreting the start and due dates of task.
""" """
def __init__(self, p_str): def __init__(self, p_str):
TodoBase.TodoBase.__init__(self, p_str) TodoBase.__init__(self, p_str)
self.attributes = {} self.attributes = {}
def get_date(self, p_tag): def get_date(self, p_tag):
""" Given a date tag, return a date object. """ """ Given a date tag, return a date object. """
string = self.tag_value(p_tag) string = self.tag_value(p_tag)
return Utils.date_string_to_date(string) if string else None return date_string_to_date(string) if string else None
def start_date(self): def start_date(self):
""" Returns a date object of the todo's start date. """ """ Returns a date object of the todo's start date. """
......
# Topydo - A todo.txt client written in Python. # Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl> # Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
...@@ -21,8 +21,8 @@ This module contains the class that represents a single todo item. ...@@ -21,8 +21,8 @@ This module contains the class that represents a single todo item.
from datetime import date from datetime import date
import re import re
import TodoParser from topydo.lib.TodoParser import parse_line
from Utils import is_valid_priority from topydo.lib.Utils import is_valid_priority
class TodoBase(object): class TodoBase(object):
""" """
...@@ -164,7 +164,7 @@ class TodoBase(object): ...@@ -164,7 +164,7 @@ class TodoBase(object):
def set_source_text(self, p_text): def set_source_text(self, p_text):
""" Sets the todo source text. The text will be parsed again. """ """ Sets the todo source text. The text will be parsed again. """
self.src = p_text.strip() self.src = p_text.strip()
self.fields = TodoParser.parse_line(self.src) self.fields = parse_line(self.src)
def projects(self): def projects(self):
""" Returns a set of projects associated with this todo item. """ """ Returns a set of projects associated with this todo item. """
......
# Topydo - A todo.txt client written in Python. # Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl> # Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
......
...@@ -18,16 +18,10 @@ ...@@ -18,16 +18,10 @@
A list of todo items. A list of todo items.
""" """
import re from topydo.lib.Graph import DirectedGraph
from topydo.lib.TodoListBase import TodoListBase
import Filter class TodoList(TodoListBase):
import Graph
from PrettyPrinter import pretty_print_list
import Todo
import TodoListBase
import View
class TodoList(TodoListBase.TodoListBase):
""" """
Provides operations for a todo list, such as adding items, removing them, Provides operations for a todo list, such as adding items, removing them,
etc. etc.
...@@ -43,7 +37,7 @@ class TodoList(TodoListBase.TodoListBase): ...@@ -43,7 +37,7 @@ class TodoList(TodoListBase.TodoListBase):
""" """
self._todos = [] self._todos = []
self._tododict = {} # hash(todo) to todo lookup self._tododict = {} # hash(todo) to todo lookup
self._depgraph = Graph.DirectedGraph() self._depgraph = DirectedGraph()
self._todo_id_map = {} self._todo_id_map = {}
self._id_todo_map = {} self._id_todo_map = {}
...@@ -154,7 +148,8 @@ class TodoList(TodoListBase.TodoListBase): ...@@ -154,7 +148,8 @@ class TodoList(TodoListBase.TodoListBase):
Returns a list of parent todos that (in)directly depend on the Returns a list of parent todos that (in)directly depend on the
given todo. given todo.
""" """
parents = self._depgraph.incoming_neighbors(hash(p_todo), not p_only_direct) parents = self._depgraph.incoming_neighbors(
hash(p_todo), not p_only_direct)
return [self._tododict[parent] for parent in parents] return [self._tododict[parent] for parent in parents]
def children(self, p_todo, p_only_direct=False): def children(self, p_todo, p_only_direct=False):
...@@ -176,7 +171,9 @@ class TodoList(TodoListBase.TodoListBase): ...@@ -176,7 +171,9 @@ class TodoList(TodoListBase.TodoListBase):
""" """
def clean_by_tag(tag_name): def clean_by_tag(tag_name):
""" Generic function to handle 'p' and 'id' tags. """ """ Generic function to handle 'p' and 'id' tags. """
for todo in [todo for todo in self._todos if todo.has_tag(tag_name)]: for todo in [todo for todo in self._todos
if todo.has_tag(tag_name)]:
value = todo.tag_value(tag_name) value = todo.tag_value(tag_name)
if not self._depgraph.has_edge_id(value): if not self._depgraph.has_edge_id(value):
todo.remove_tag(tag_name, value) todo.remove_tag(tag_name, value)
......
...@@ -21,12 +21,12 @@ A list of todo items. ...@@ -21,12 +21,12 @@ A list of todo items.
from datetime import date from datetime import date
import re import re
from Config import config from topydo.lib.Config import config
import Filter from topydo.lib import Filter
from HashListValues import hash_list_values from topydo.lib.HashListValues import hash_list_values
from PrettyPrinter import pretty_print_list from topydo.lib.PrettyPrinter import pretty_print_list
import Todo from topydo.lib.Todo import Todo
import View from topydo.lib.View import View
class InvalidTodoException(Exception): class InvalidTodoException(Exception):
pass pass
...@@ -70,6 +70,13 @@ class TodoListBase(object): ...@@ -70,6 +70,13 @@ class TodoListBase(object):
if config().identifiers() == 'text': if config().identifiers() == 'text':
result = self._id_todo_map[p_identifier] result = self._id_todo_map[p_identifier]
else: else:
try:
if not re.match('[1-9]\d*', p_identifier):
raise ValueError # leading zeros, pass to regexp
except TypeError:
# we're dealing with an integer
pass
result = self._todos[int(p_identifier) - 1] result = self._todos[int(p_identifier) - 1]
except IndexError: except IndexError:
raise InvalidTodoException raise InvalidTodoException
...@@ -101,7 +108,7 @@ class TodoListBase(object): ...@@ -101,7 +108,7 @@ class TodoListBase(object):
return todos[0] if len(todos) else None return todos[0] if len(todos) else None
def add_list(self, p_srcs): def add_list(self, p_srcs):
todos = [Todo.Todo(src) for src in p_srcs if re.search(r'\S', src)] todos = [Todo(src) for src in p_srcs if re.search(r'\S', src)]
self.add_todos(todos) self.add_todos(todos)
return todos return todos
...@@ -169,7 +176,7 @@ class TodoListBase(object): ...@@ -169,7 +176,7 @@ class TodoListBase(object):
defined by the end user. Todos is this list should not be modified, defined by the end user. Todos is this list should not be modified,
modifications should occur through this class. modifications should occur through this class.
""" """
return View.View(p_sorter, p_filters, self) return View(p_sorter, p_filters, self)
def is_dirty(self): def is_dirty(self):
return self.dirty return self.dirty
...@@ -201,9 +208,11 @@ class TodoListBase(object): ...@@ -201,9 +208,11 @@ class TodoListBase(object):
printed todo. printed todo.
""" """
if config().identifiers() == 'text': if config().identifiers() == 'text':
return lambda p_todo_str, p_todo: "|%3s| %s" % (self._todo_id_map[p_todo], p_todo_str) return lambda p_todo_str, p_todo: \
"|%3s| %s" % (self._todo_id_map[p_todo], p_todo_str)
else: else:
return lambda p_todo_str, p_todo: "|%3d| %s" % (self.number(p_todo), p_todo_str) return lambda p_todo_str, p_todo: \
"|%3d| %s" % (self.number(p_todo), p_todo_str)
def _update_todo_ids(self): def _update_todo_ids(self):
# the idea is to have a hash that is independent of the position of the # the idea is to have a hash that is independent of the position of the
......
# Topydo - A todo.txt client written in Python. # Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl> # Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
...@@ -21,14 +21,21 @@ todo.txt file. ...@@ -21,14 +21,21 @@ todo.txt file.
import re import re
import Utils from topydo.lib.Utils import date_string_to_date
_date_match = r'\d{4}-\d{2}-\d{2}' _DATE_MATCH = r'\d{4}-\d{2}-\d{2}'
_completed_head_match = re.compile(r'x ((?P<completionDate>' + _date_match + ') )' + '((?P<creationDate>' + _date_match + ') )?(?P<rest>.*)')
_normal_head_match = re.compile(r'(\((?P<priority>[A-Z])\) )?' + '((?P<creationDate>' + _date_match + ') )?(?P<rest>.*)') _COMPLETED_HEAD_MATCH = re.compile(
_tag_match = re.compile('(?P<key>[^:]*):(?P<value>.*)') r'x ((?P<completionDate>' + _DATE_MATCH + ') )' + '((?P<creationDate>' +
_project_match = re.compile(r'\+(\S*\w)') _DATE_MATCH + ') )?(?P<rest>.*)')
_context_match = re.compile(r'@(\S*\w)')
_NORMAL_HEAD_MATCH = re.compile(
r'(\((?P<priority>[A-Z])\) )?' + '((?P<creationDate>' + _DATE_MATCH +
') )?(?P<rest>.*)')
_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): def parse_line(p_string):
""" """
...@@ -52,8 +59,8 @@ def parse_line(p_string): ...@@ -52,8 +59,8 @@ def parse_line(p_string):
'tags': [] 'tags': []
} }
completed_head = _completed_head_match.match(p_string) completed_head = _COMPLETED_HEAD_MATCH.match(p_string)
normal_head = _normal_head_match.match(p_string) normal_head = _NORMAL_HEAD_MATCH.match(p_string)
rest = p_string rest = p_string
...@@ -61,30 +68,30 @@ def parse_line(p_string): ...@@ -61,30 +68,30 @@ def parse_line(p_string):
result['completed'] = True result['completed'] = True
completion_date = completed_head.group('completionDate') completion_date = completed_head.group('completionDate')
result['completionDate'] = Utils.date_string_to_date(completion_date) result['completionDate'] = date_string_to_date(completion_date)
creation_date = completed_head.group('creationDate') creation_date = completed_head.group('creationDate')
result['creationDate'] = Utils.date_string_to_date(creation_date) result['creationDate'] = date_string_to_date(creation_date)
rest = completed_head.group('rest') rest = completed_head.group('rest')
elif normal_head: elif normal_head:
result['priority'] = normal_head.group('priority') result['priority'] = normal_head.group('priority')
creation_date = normal_head.group('creationDate') creation_date = normal_head.group('creationDate')
result['creationDate'] = Utils.date_string_to_date(creation_date) result['creationDate'] = date_string_to_date(creation_date)
rest = normal_head.group('rest') rest = normal_head.group('rest')
for word in rest.split(): for word in rest.split():
project = _project_match.match(word) project = _PROJECT_MATCH.match(word)
if project: if project:
result['projects'].append(project.group(1)) result['projects'].append(project.group(1))
context = _context_match.match(word) context = _CONTEXT_MATCH.match(word)
if context: if context:
result['contexts'].append(context.group(1)) result['contexts'].append(context.group(1))
tag = _tag_match.match(word) tag = _TAG_MATCH.match(word)
if tag: if tag:
result['tags'].append((tag.group('key'), tag.group('value'))) result['tags'].append((tag.group('key'), tag.group('value')))
continue continue
......
# Topydo - A todo.txt client written in Python. # Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl> # Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
......
""" Version of Topydo. """
VERSION = 0.1
LICENSE = """Copyright (C) 2014 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."""
# Topydo - A todo.txt client written in Python. # Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl> # Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
""" A view is a list of todos, sorted and filtered. """ """ A view is a list of todos, sorted and filtered. """
from PrettyPrinter import pretty_print_list, pp_color from topydo.lib.PrettyPrinter import pretty_print_list, pp_color
class View(object): class View(object):
""" """
...@@ -42,9 +42,10 @@ class View(object): ...@@ -42,9 +42,10 @@ class View(object):
for _filter in self._filters: for _filter in self._filters:
self._viewdata = _filter.filter(self._viewdata) self._viewdata = _filter.filter(self._viewdata)
def pretty_print(self, p_pp_filters=[]): def pretty_print(self, p_pp_filters=None):
""" Pretty prints the view. """ """ Pretty prints the view. """
pp_filters = [self._todolist.pp_number(), pp_color] + p_pp_filters; p_pp_filters = p_pp_filters or []
pp_filters = [self._todolist.pp_number(), pp_color] + p_pp_filters
return '\n'.join(pretty_print_list(self._viewdata, pp_filters)) return '\n'.join(pretty_print_list(self._viewdata, pp_filters))
def __str__(self): def __str__(self):
......
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