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

Merge pull request #55 from MinchinWeb/style

Style Changes
parents 1cd3a094 8ade0c20
*.pyc *.py[cod]
*.sw? *.sw?
install install
.coverage .coverage
...@@ -19,6 +19,7 @@ var/ ...@@ -19,6 +19,7 @@ var/
*.egg-info/ *.egg-info/
.installed.cfg .installed.cfg
*.egg *.egg
.eggs/
# Sublime Text # Sublime Text
*.sublime-* *.sublime-*
......
...@@ -2,8 +2,17 @@ sudo: false # run on new infrastructure ...@@ -2,8 +2,17 @@ sudo: false # run on new infrastructure
language: python language: python
python: python:
- "2.7" - "2.7"
- "3.2"
- "3.3" - "3.3"
- "3.4" - "3.4"
- "3.5"
- "pypy"
- "pypy3"
matrix:
allow_failures:
- python: "3.2"
- python: "pypy"
- python: "pypy3"
install: install:
- "pip install ." - "pip install ."
- "pip install icalendar" - "pip install icalendar"
......
# 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 - 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
...@@ -14,10 +14,9 @@ ...@@ -14,10 +14,9 @@
# 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 from test.TopydoTestCase import TopydoTest
from topydo.lib.Utils import escape_ansi from topydo.lib.Utils import escape_ansi
from test.TopydoTest import TopydoTest
class CommandTest(TopydoTest): class CommandTest(TopydoTest):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
...@@ -32,6 +31,3 @@ class CommandTest(TopydoTest): ...@@ -32,6 +31,3 @@ class CommandTest(TopydoTest):
def error(self, p_error): def error(self, p_error):
if p_error: if p_error:
self.errors += escape_ansi(p_error + "\n") self.errors += escape_ansi(p_error + "\n")
if __name__ == '__main__':
unittest.main()
# 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 - 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
...@@ -19,6 +19,7 @@ from topydo.lib.Todo import Todo ...@@ -19,6 +19,7 @@ from topydo.lib.Todo import Todo
from topydo.lib.TodoFile import TodoFile from topydo.lib.TodoFile import TodoFile
from topydo.lib.TodoList 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.
...@@ -26,6 +27,7 @@ def load_file(p_filename): ...@@ -26,6 +27,7 @@ def load_file(p_filename):
todolist = load_file_to_raw_list(p_filename) todolist = load_file_to_raw_list(p_filename)
return [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
...@@ -34,6 +36,7 @@ def load_file_to_raw_list(p_filename): ...@@ -34,6 +36,7 @@ def load_file_to_raw_list(p_filename):
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):
""" """
Loads a todo file to a TodoList instance. Loads a todo file to a TodoList instance.
...@@ -41,10 +44,12 @@ def load_file_to_todolist(p_filename): ...@@ -41,10 +44,12 @@ def load_file_to_todolist(p_filename):
todolist = load_file_to_raw_list(p_filename) todolist = load_file_to_raw_list(p_filename)
return 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. """
return '\n'.join([t.source() for t in p_list]) return '\n'.join([t.source() for t in p_list])
def print_view(p_view): def print_view(p_view):
printer = PrettyPrinter() printer = PrettyPrinter()
return printer.print_list(p_view.todos) return printer.print_list(p_view.todos)
# 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 - 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
...@@ -16,10 +16,11 @@ ...@@ -16,10 +16,11 @@
import unittest import unittest
from test.CommandTestCase import CommandTest
from topydo.commands.AppendCommand import AppendCommand from topydo.commands.AppendCommand import AppendCommand
from test.CommandTest import CommandTest
from topydo.lib.TodoList import TodoList from topydo.lib.TodoList import TodoList
class AppendCommandTest(CommandTest): class AppendCommandTest(CommandTest):
def setUp(self): def setUp(self):
super(AppendCommandTest, self).setUp() super(AppendCommandTest, self).setUp()
...@@ -27,14 +28,16 @@ class AppendCommandTest(CommandTest): ...@@ -27,14 +28,16 @@ class AppendCommandTest(CommandTest):
self.todolist.add("Foo") self.todolist.add("Foo")
def test_append1(self): def test_append1(self):
command = AppendCommand([1, "Bar"], self.todolist, self.out, self.error) command = AppendCommand([1, "Bar"], self.todolist, self.out,
self.error)
command.execute() 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([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, "")
...@@ -55,7 +58,8 @@ class AppendCommandTest(CommandTest): ...@@ -55,7 +58,8 @@ class AppendCommandTest(CommandTest):
self.assertEqual(self.errors, command.usage() + "\n") self.assertEqual(self.errors, command.usage() + "\n")
def test_append5(self): def test_append5(self):
command = AppendCommand([1, "Bar", "Baz"], self.todolist, self.out, self.error) command = AppendCommand([1, "Bar", "Baz"], self.todolist, self.out,
self.error)
command.execute() command.execute()
self.assertEqual(self.output, "| 1| Foo Bar Baz\n") self.assertEqual(self.output, "| 1| Foo Bar Baz\n")
...@@ -80,7 +84,8 @@ class AppendCommandTest(CommandTest): ...@@ -80,7 +84,8 @@ class AppendCommandTest(CommandTest):
command.execute() command.execute()
self.assertEqual(self.output, "") self.assertEqual(self.output, "")
self.assertEqual(self.errors, command.usage() + "\n\n" + command.help() + "\n") self.assertEqual(self.errors,
command.usage() + "\n\n" + command.help() + "\n")
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
# 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 - 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
...@@ -16,11 +16,12 @@ ...@@ -16,11 +16,12 @@
import unittest import unittest
from test.CommandTestCase import CommandTest
from test.Facilities import load_file_to_todolist
from topydo.commands.ArchiveCommand import ArchiveCommand from topydo.commands.ArchiveCommand import ArchiveCommand
from test.CommandTest import CommandTest
from test.TestFacilities import load_file_to_todolist
from topydo.lib.TodoList import TodoList from topydo.lib.TodoList import TodoList
class ArchiveCommandTest(CommandTest): class ArchiveCommandTest(CommandTest):
def test_archive(self): def test_archive(self):
todolist = load_file_to_todolist("test/data/ArchiveCommandTest.txt") todolist = load_file_to_todolist("test/data/ArchiveCommandTest.txt")
...@@ -36,4 +37,3 @@ class ArchiveCommandTest(CommandTest): ...@@ -36,4 +37,3 @@ class ArchiveCommandTest(CommandTest):
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
# 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 - 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
...@@ -17,9 +17,11 @@ ...@@ -17,9 +17,11 @@
""" Tests for the colorscheme functionality. """ """ Tests for the colorscheme functionality. """
import unittest import unittest
from topydo.lib.Colors import Colors, NEUTRAL_COLOR
from test.TopydoTestCase import TopydoTest
from topydo.lib.Colors import NEUTRAL_COLOR, Colors
from topydo.lib.Config import config from topydo.lib.Config import config
from test.TopydoTest import TopydoTest
class ColorsTest(TopydoTest): class ColorsTest(TopydoTest):
def test_project_color1(self): def test_project_color1(self):
...@@ -183,3 +185,6 @@ class ColorsTest(TopydoTest): ...@@ -183,3 +185,6 @@ class ColorsTest(TopydoTest):
self.assertEqual(context_color, '\033[1;35m') self.assertEqual(context_color, '\033[1;35m')
self.assertEqual(link_color, '\033[4;36m') self.assertEqual(link_color, '\033[4;36m')
self.assertEqual(metadata_color, '\033[1;32m') self.assertEqual(metadata_color, '\033[1;32m')
if __name__ == '__main__':
unittest.main()
# 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 - 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
...@@ -16,8 +16,9 @@ ...@@ -16,8 +16,9 @@
import unittest import unittest
from test.TopydoTestCase import TopydoTest
from topydo.lib.Config import config from topydo.lib.Config import config
from test.TopydoTest import TopydoTest
class ConfigTest(TopydoTest): class ConfigTest(TopydoTest):
def test_config1(self): def test_config1(self):
......
...@@ -15,20 +15,24 @@ ...@@ -15,20 +15,24 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import unittest import unittest
from six import u from six import u
from test.CommandTest import CommandTest from test.CommandTestCase import CommandTest
from topydo.lib.Config import config
from topydo.commands.DeleteCommand import DeleteCommand from topydo.commands.DeleteCommand import DeleteCommand
from topydo.lib.Config import config
from topydo.lib.TodoList import TodoList from topydo.lib.TodoList import TodoList
from topydo.lib.TodoListBase import InvalidTodoException from topydo.lib.TodoListBase import InvalidTodoException
def _yes_prompt(self): def _yes_prompt(self):
return "y" return "y"
def _no_prompt(self): def _no_prompt(self):
return "n" return "n"
class DeleteCommandTest(CommandTest): class DeleteCommandTest(CommandTest):
def setUp(self): def setUp(self):
super(DeleteCommandTest, self).setUp() super(DeleteCommandTest, self).setUp()
...@@ -42,7 +46,8 @@ class DeleteCommandTest(CommandTest): ...@@ -42,7 +46,8 @@ class DeleteCommandTest(CommandTest):
self.todolist = TodoList(todos) self.todolist = TodoList(todos)
def test_del1(self): def test_del1(self):
command = DeleteCommand(["1"], self.todolist, self.out, self.error, _no_prompt) command = DeleteCommand(["1"], self.todolist, self.out, self.error,
_no_prompt)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -51,7 +56,8 @@ class DeleteCommandTest(CommandTest): ...@@ -51,7 +56,8 @@ class DeleteCommandTest(CommandTest):
self.assertEqual(self.errors, "") self.assertEqual(self.errors, "")
def test_del1_regex(self): def test_del1_regex(self):
command = DeleteCommand(["Foo"], self.todolist, self.out, self.error, _no_prompt) command = DeleteCommand(["Foo"], self.todolist, self.out, self.error,
_no_prompt)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -60,16 +66,19 @@ class DeleteCommandTest(CommandTest): ...@@ -60,16 +66,19 @@ class DeleteCommandTest(CommandTest):
self.assertEqual(self.errors, "") self.assertEqual(self.errors, "")
def test_del2(self): def test_del2(self):
command = DeleteCommand(["1"], self.todolist, self.out, self.error, _yes_prompt) command = DeleteCommand(["1"], self.todolist, self.out, self.error,
_yes_prompt)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertEqual(self.todolist.count(), 2) self.assertEqual(self.todolist.count(), 2)
self.assertEqual(self.output, "| 2| Bar p:1\nRemoved: Bar\nRemoved: Foo\n") self.assertEqual(self.output,
"| 2| Bar p:1\nRemoved: Bar\nRemoved: Foo\n")
self.assertEqual(self.errors, "") self.assertEqual(self.errors, "")
def test_del3(self): def test_del3(self):
command = DeleteCommand(["-f", "1"], self.todolist, self.out, self.error, _yes_prompt) command = DeleteCommand(["-f", "1"], self.todolist, self.out,
self.error, _yes_prompt)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -78,7 +87,8 @@ class DeleteCommandTest(CommandTest): ...@@ -78,7 +87,8 @@ class DeleteCommandTest(CommandTest):
self.assertEqual(self.errors, "") self.assertEqual(self.errors, "")
def test_del4(self): def test_del4(self):
command = DeleteCommand(["--force", "1"], self.todolist, self.out, self.error, _yes_prompt) command = DeleteCommand(["--force", "1"], self.todolist, self.out,
self.error, _yes_prompt)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -125,7 +135,8 @@ class DeleteCommandTest(CommandTest): ...@@ -125,7 +135,8 @@ class DeleteCommandTest(CommandTest):
def test_multi_del1(self): def test_multi_del1(self):
""" Test deletion of multiple items. """ """ Test deletion of multiple items. """
command = DeleteCommand(["1", "2"], self.todolist, self.out, self.error, _no_prompt) command = DeleteCommand(["1", "2"], self.todolist, self.out,
self.error, _no_prompt)
command.execute() command.execute()
result = "a @test with due:2015-06-03\na @test with +project" result = "a @test with due:2015-06-03\na @test with +project"
...@@ -135,7 +146,8 @@ class DeleteCommandTest(CommandTest): ...@@ -135,7 +146,8 @@ class DeleteCommandTest(CommandTest):
def test_multi_del2(self): def test_multi_del2(self):
""" Test deletion of multiple items. """ """ Test deletion of multiple items. """
command = DeleteCommand(["1", "2"], self.todolist, self.out, self.error, _yes_prompt) command = DeleteCommand(["1", "2"], self.todolist, self.out,
self.error, _yes_prompt)
command.execute() command.execute()
result = "a @test with due:2015-06-03\na @test with +project" result = "a @test with due:2015-06-03\na @test with +project"
...@@ -145,7 +157,8 @@ class DeleteCommandTest(CommandTest): ...@@ -145,7 +157,8 @@ class DeleteCommandTest(CommandTest):
def test_multi_del3(self): def test_multi_del3(self):
""" Fail if any of supplied todo numbers is invalid. """ """ Fail if any of supplied todo numbers is invalid. """
command = DeleteCommand(["99", "2"], self.todolist, self.out, self.error, _yes_prompt) command = DeleteCommand(["99", "2"], self.todolist, self.out,
self.error, _yes_prompt)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -154,7 +167,8 @@ class DeleteCommandTest(CommandTest): ...@@ -154,7 +167,8 @@ class DeleteCommandTest(CommandTest):
def test_multi_del4(self): def test_multi_del4(self):
""" Check output when all supplied todo numbers are invalid. """ """ Check output when all supplied todo numbers are invalid. """
command = DeleteCommand(["99", "A"], self.todolist, self.out, self.error, _yes_prompt) command = DeleteCommand(["99", "A"], self.todolist, self.out,
self.error, _yes_prompt)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -162,16 +176,21 @@ class DeleteCommandTest(CommandTest): ...@@ -162,16 +176,21 @@ class DeleteCommandTest(CommandTest):
self.assertEqual(self.errors, "Invalid todo number given: 99.\nInvalid todo number given: A.\n") self.assertEqual(self.errors, "Invalid todo number given: 99.\nInvalid todo number given: A.\n")
def test_multi_del5(self): def test_multi_del5(self):
""" Throw an error with invalid argument containing special characters. """ """
command = DeleteCommand([u("Fo\u00d3B\u0105r"), "Bar"], self.todolist, self.out, self.error, None) Throw an error with invalid argument containing special characters.
"""
command = DeleteCommand([u("Fo\u00d3B\u0105r"), "Bar"], self.todolist,
self.out, self.error, None)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEqual(self.output, "") self.assertEqual(self.output, "")
self.assertEqual(self.errors, u("Invalid todo number given: Fo\u00d3B\u0105r.\n")) self.assertEqual(self.errors,
u("Invalid todo number given: Fo\u00d3B\u0105r.\n"))
def test_expr_del1(self): def test_expr_del1(self):
command = DeleteCommand(["-e", "@test"], self.todolist, self.out, self.error, None) command = DeleteCommand(["-e", "@test"], self.todolist, self.out,
self.error, None)
command.execute() command.execute()
result = "Removed: a @test with due:2015-06-03\nRemoved: a @test with +project\n" result = "Removed: a @test with due:2015-06-03\nRemoved: a @test with +project\n"
...@@ -182,7 +201,8 @@ class DeleteCommandTest(CommandTest): ...@@ -182,7 +201,8 @@ class DeleteCommandTest(CommandTest):
self.assertEqual(self.errors, "") self.assertEqual(self.errors, "")
def test_expr_del2(self): def test_expr_del2(self):
command = DeleteCommand(["-e", "@test", "due:2015-06-03"], self.todolist, self.out, self.error, None) command = DeleteCommand(["-e", "@test", "due:2015-06-03"],
self.todolist, self.out, self.error, None)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -190,14 +210,16 @@ class DeleteCommandTest(CommandTest): ...@@ -190,14 +210,16 @@ class DeleteCommandTest(CommandTest):
self.assertEqual(self.errors, "") self.assertEqual(self.errors, "")
def test_expr_del3(self): def test_expr_del3(self):
command = DeleteCommand(["-e", "@test", "due:2015-06-03", "+project"], self.todolist, self.out, self.error, None) command = DeleteCommand(["-e", "@test", "due:2015-06-03", "+project"],
self.todolist, self.out, self.error, None)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
def test_expr_del4(self): def test_expr_del4(self):
""" Remove only relevant todo items. """ """ Remove only relevant todo items. """
command = DeleteCommand(["-e", ""], self.todolist, self.out, self.error, None) command = DeleteCommand(["-e", ""], self.todolist, self.out,
self.error, None)
command.execute() command.execute()
result = "Foo" result = "Foo"
...@@ -208,7 +230,8 @@ class DeleteCommandTest(CommandTest): ...@@ -208,7 +230,8 @@ class DeleteCommandTest(CommandTest):
def test_expr_del5(self): def test_expr_del5(self):
""" Force deleting unrelevant items with additional -x flag. """ """ Force deleting unrelevant items with additional -x flag. """
command = DeleteCommand(["-xe", ""], self.todolist, self.out, self.error, _yes_prompt) command = DeleteCommand(["-xe", ""], self.todolist, self.out,
self.error, _yes_prompt)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -227,7 +250,8 @@ class DeleteCommandTest(CommandTest): ...@@ -227,7 +250,8 @@ class DeleteCommandTest(CommandTest):
command.execute() command.execute()
self.assertEqual(self.output, "") self.assertEqual(self.output, "")
self.assertEqual(self.errors, command.usage() + "\n\n" + command.help() + "\n") self.assertEqual(self.errors,
command.usage() + "\n\n" + command.help() + "\n")
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
# 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 - 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
...@@ -16,10 +16,11 @@ ...@@ -16,10 +16,11 @@
import unittest import unittest
from test.CommandTestCase import CommandTest
from topydo.commands.DepCommand import DepCommand from topydo.commands.DepCommand import DepCommand
from test.CommandTest import CommandTest
from topydo.lib.TodoList import TodoList from topydo.lib.TodoList import TodoList
class DepCommandTest(CommandTest): class DepCommandTest(CommandTest):
def setUp(self): def setUp(self):
super(DepCommandTest, self).setUp() super(DepCommandTest, self).setUp()
...@@ -35,7 +36,8 @@ class DepCommandTest(CommandTest): ...@@ -35,7 +36,8 @@ class DepCommandTest(CommandTest):
self.todolist = TodoList(todos) self.todolist = TodoList(todos)
def test_add1(self): def test_add1(self):
command = DepCommand(["add", "1", "to", "4"], self.todolist, self.out, self.error) command = DepCommand(["add", "1", "to", "4"], self.todolist, self.out,
self.error)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -44,7 +46,8 @@ class DepCommandTest(CommandTest): ...@@ -44,7 +46,8 @@ class DepCommandTest(CommandTest):
self.assertEqual(self.errors, "") self.assertEqual(self.errors, "")
def test_add2(self): def test_add2(self):
command = DepCommand(["add", "1", "4"], self.todolist, self.out, self.error) command = DepCommand(["add", "1", "4"], self.todolist, self.out,
self.error)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -53,7 +56,8 @@ class DepCommandTest(CommandTest): ...@@ -53,7 +56,8 @@ class DepCommandTest(CommandTest):
self.assertEqual(self.errors, "") self.assertEqual(self.errors, "")
def test_add3(self): def test_add3(self):
command = DepCommand(["add", "99", "3"], self.todolist, self.out, self.error) command = DepCommand(["add", "99", "3"], self.todolist, self.out,
self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -61,7 +65,8 @@ class DepCommandTest(CommandTest): ...@@ -61,7 +65,8 @@ class DepCommandTest(CommandTest):
self.assertEqual(self.errors, "Invalid todo number given.\n") self.assertEqual(self.errors, "Invalid todo number given.\n")
def test_add4(self): def test_add4(self):
command = DepCommand(["add", "A", "3"], self.todolist, self.out, self.error) command = DepCommand(["add", "A", "3"], self.todolist, self.out,
self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -77,7 +82,8 @@ class DepCommandTest(CommandTest): ...@@ -77,7 +82,8 @@ class DepCommandTest(CommandTest):
self.assertEqual(self.errors, command.usage() + "\n") self.assertEqual(self.errors, command.usage() + "\n")
def test_add6(self): def test_add6(self):
command = DepCommand(["add", "1", "after", "4"], self.todolist, self.out, self.error) command = DepCommand(["add", "1", "after", "4"], self.todolist,
self.out, self.error)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -86,7 +92,8 @@ class DepCommandTest(CommandTest): ...@@ -86,7 +92,8 @@ class DepCommandTest(CommandTest):
self.assertEqual(self.errors, "") self.assertEqual(self.errors, "")
def test_add7(self): def test_add7(self):
command = DepCommand(["add", "1", "before", "4"], self.todolist, self.out, self.error) command = DepCommand(["add", "1", "before", "4"], self.todolist,
self.out, self.error)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -95,7 +102,8 @@ class DepCommandTest(CommandTest): ...@@ -95,7 +102,8 @@ class DepCommandTest(CommandTest):
self.assertEqual(self.errors, "") self.assertEqual(self.errors, "")
def test_add8(self): def test_add8(self):
command = DepCommand(["add", "1", "partof", "4"], self.todolist, self.out, self.error) command = DepCommand(["add", "1", "partof", "4"], self.todolist,
self.out, self.error)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -104,7 +112,8 @@ class DepCommandTest(CommandTest): ...@@ -104,7 +112,8 @@ class DepCommandTest(CommandTest):
self.assertEqual(self.errors, "") self.assertEqual(self.errors, "")
def test_add9(self): def test_add9(self):
command = DepCommand(["add", "Foo", "to", "4"], self.todolist, self.out, self.error) command = DepCommand(["add", "Foo", "to", "4"], self.todolist,
self.out, self.error)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -117,7 +126,6 @@ class DepCommandTest(CommandTest): ...@@ -117,7 +126,6 @@ class DepCommandTest(CommandTest):
Helper function that checks the removal of the dependency from todo 1 Helper function that checks the removal of the dependency from todo 1
to todo 3. to todo 3.
""" """
command = DepCommand(p_args, self.todolist, self.out, self.error) command = DepCommand(p_args, self.todolist, self.out, self.error)
command.execute() command.execute()
...@@ -140,7 +148,8 @@ class DepCommandTest(CommandTest): ...@@ -140,7 +148,8 @@ class DepCommandTest(CommandTest):
self.rm_helper(["del", "1", "3"]) self.rm_helper(["del", "1", "3"])
def test_rm3(self): def test_rm3(self):
command = DepCommand(["rm", "99", "3"], self.todolist, self.out, self.error) command = DepCommand(["rm", "99", "3"], self.todolist, self.out,
self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -148,7 +157,8 @@ class DepCommandTest(CommandTest): ...@@ -148,7 +157,8 @@ class DepCommandTest(CommandTest):
self.assertEqual(self.errors, "Invalid todo number given.\n") self.assertEqual(self.errors, "Invalid todo number given.\n")
def test_rm4(self): def test_rm4(self):
command = DepCommand(["rm", "A", "3"], self.todolist, self.out, self.error) command = DepCommand(["rm", "A", "3"], self.todolist, self.out,
self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -164,7 +174,8 @@ class DepCommandTest(CommandTest): ...@@ -164,7 +174,8 @@ class DepCommandTest(CommandTest):
self.assertEqual(self.errors, command.usage() + "\n") self.assertEqual(self.errors, command.usage() + "\n")
def test_ls1(self): def test_ls1(self):
command = DepCommand(["ls", "1", "to"], self.todolist, self.out, self.error) command = DepCommand(["ls", "1", "to"], self.todolist, self.out,
self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -172,7 +183,8 @@ class DepCommandTest(CommandTest): ...@@ -172,7 +183,8 @@ class DepCommandTest(CommandTest):
self.assertEqual(self.errors, "") self.assertEqual(self.errors, "")
def test_ls2(self): def test_ls2(self):
command = DepCommand(["ls", "99", "to"], self.todolist, self.out, self.error) command = DepCommand(["ls", "99", "to"], self.todolist, self.out,
self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -180,7 +192,8 @@ class DepCommandTest(CommandTest): ...@@ -180,7 +192,8 @@ class DepCommandTest(CommandTest):
self.assertEqual(self.errors, "Invalid todo number given.\n") self.assertEqual(self.errors, "Invalid todo number given.\n")
def test_ls3(self): def test_ls3(self):
command = DepCommand(["ls", "to", "3"], self.todolist, self.out, self.error) command = DepCommand(["ls", "to", "3"], self.todolist, self.out,
self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -188,7 +201,8 @@ class DepCommandTest(CommandTest): ...@@ -188,7 +201,8 @@ class DepCommandTest(CommandTest):
self.assertEqual(self.errors, "") self.assertEqual(self.errors, "")
def test_ls4(self): def test_ls4(self):
command = DepCommand(["ls", "to", "99"], self.todolist, self.out, self.error) command = DepCommand(["ls", "to", "99"], self.todolist, self.out,
self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -212,7 +226,8 @@ class DepCommandTest(CommandTest): ...@@ -212,7 +226,8 @@ class DepCommandTest(CommandTest):
self.assertEqual(self.errors, command.usage() + "\n") self.assertEqual(self.errors, command.usage() + "\n")
def test_ls7(self): def test_ls7(self):
command = DepCommand(["ls", "top", "99"], self.todolist, self.out, self.error) command = DepCommand(["ls", "top", "99"], self.todolist, self.out,
self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -220,7 +235,8 @@ class DepCommandTest(CommandTest): ...@@ -220,7 +235,8 @@ class DepCommandTest(CommandTest):
self.assertEqual(self.errors, command.usage() + "\n") self.assertEqual(self.errors, command.usage() + "\n")
def gc_helper(self, p_subcommand): def gc_helper(self, p_subcommand):
command = DepCommand([p_subcommand], self.todolist, self.out, self.error) command = DepCommand([p_subcommand], self.todolist, self.out,
self.error)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -255,7 +271,8 @@ class DepCommandTest(CommandTest): ...@@ -255,7 +271,8 @@ class DepCommandTest(CommandTest):
command.execute() command.execute()
self.assertEqual(self.output, "") self.assertEqual(self.output, "")
self.assertEqual(self.errors, command.usage() + "\n\n" + command.help() + "\n") self.assertEqual(self.errors,
command.usage() + "\n\n" + command.help() + "\n")
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
# 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 - 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
...@@ -15,12 +15,14 @@ ...@@ -15,12 +15,14 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import unittest import unittest
from six import u from six import u
from test.CommandTestCase import CommandTest
from topydo.commands.DepriCommand import DepriCommand from topydo.commands.DepriCommand import DepriCommand
from test.CommandTest import CommandTest
from topydo.lib.TodoList import TodoList from topydo.lib.TodoList import TodoList
class DepriCommandTest(CommandTest): class DepriCommandTest(CommandTest):
def setUp(self): def setUp(self):
super(DepriCommandTest, self).setUp() super(DepriCommandTest, self).setUp()
...@@ -63,7 +65,8 @@ class DepriCommandTest(CommandTest): ...@@ -63,7 +65,8 @@ class DepriCommandTest(CommandTest):
self.assertEqual(self.errors, "") self.assertEqual(self.errors, "")
def test_depri4(self): def test_depri4(self):
command = DepriCommand(["1","Baz"], self.todolist, self.out, self.error) command = DepriCommand(["1", "Baz"], self.todolist, self.out,
self.error)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -73,10 +76,10 @@ class DepriCommandTest(CommandTest): ...@@ -73,10 +76,10 @@ class DepriCommandTest(CommandTest):
self.assertEqual(self.errors, "") self.assertEqual(self.errors, "")
def test_expr_depri1(self): def test_expr_depri1(self):
command = DepriCommand(["-e", "@test"], self.todolist, self.out, self.error, None) command = DepriCommand(["-e", "@test"], self.todolist, self.out,
self.error, None)
command.execute() command.execute()
result = "Priority removed.\n| 4| a @test with due:2015-06-03\nPriority removed.\n| 5| a @test with +project p:1\n" result = "Priority removed.\n| 4| a @test with due:2015-06-03\nPriority removed.\n| 5| a @test with +project p:1\n"
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -84,7 +87,8 @@ class DepriCommandTest(CommandTest): ...@@ -84,7 +87,8 @@ class DepriCommandTest(CommandTest):
self.assertEqual(self.errors, "") self.assertEqual(self.errors, "")
def test_expr_depri2(self): def test_expr_depri2(self):
command = DepriCommand(["-e", "@test", "due:2015-06-03"], self.todolist, self.out, self.error, None) command = DepriCommand(["-e", "@test", "due:2015-06-03"],
self.todolist, self.out, self.error, None)
command.execute() command.execute()
result = "Priority removed.\n| 4| a @test with due:2015-06-03\n" result = "Priority removed.\n| 4| a @test with due:2015-06-03\n"
...@@ -94,29 +98,30 @@ class DepriCommandTest(CommandTest): ...@@ -94,29 +98,30 @@ class DepriCommandTest(CommandTest):
self.assertEqual(self.errors, "") self.assertEqual(self.errors, "")
def test_expr_depri3(self): def test_expr_depri3(self):
command = DepriCommand(["-e", "@test", "due:2015-06-03", "+project"], self.todolist, self.out, self.error, None) command = DepriCommand(["-e", "@test", "due:2015-06-03", "+project"],
self.todolist, self.out, self.error, None)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
def test_expr_depri4(self): def test_expr_depri4(self):
""" Don't remove priority from unrelevant todo items. """ """ Don't remove priority from unrelevant todo items. """
command = DepriCommand(["-e", "Bax"], self.todolist, self.out, self.error, None) command = DepriCommand(["-e", "Bax"], self.todolist, self.out,
self.error, None)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
def test_expr_depri5(self): def test_expr_depri5(self):
""" Force unprioritizing unrelevant items with additional -x flag. """ """ Force unprioritizing unrelevant items with additional -x flag. """
command = DepriCommand(["-xe", "Bax"], self.todolist, self.out, self.error, None) command = DepriCommand(["-xe", "Bax"], self.todolist, self.out,
self.error, None)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertEqual(self.output, "Priority removed.\n| 6| Bax id:1\n") self.assertEqual(self.output, "Priority removed.\n| 6| Bax id:1\n")
self.assertEqual(self.errors, "") self.assertEqual(self.errors, "")
def test_invalid1(self): def test_invalid1(self):
command = DepriCommand(["99"], self.todolist, self.out, self.error) command = DepriCommand(["99"], self.todolist, self.out, self.error)
command.execute() command.execute()
...@@ -126,7 +131,8 @@ class DepriCommandTest(CommandTest): ...@@ -126,7 +131,8 @@ class DepriCommandTest(CommandTest):
self.assertEqual(self.errors, "Invalid todo number given.\n") self.assertEqual(self.errors, "Invalid todo number given.\n")
def test_invalid2(self): def test_invalid2(self):
command = DepriCommand(["99", "1"], self.todolist, self.out, self.error) command = DepriCommand(["99", "1"], self.todolist, self.out,
self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -134,7 +140,8 @@ class DepriCommandTest(CommandTest): ...@@ -134,7 +140,8 @@ class DepriCommandTest(CommandTest):
self.assertEqual(self.errors, "Invalid todo number given: 99.\n") self.assertEqual(self.errors, "Invalid todo number given: 99.\n")
def test_invalid3(self): def test_invalid3(self):
command = DepriCommand(["99", "FooBar"], self.todolist, self.out, self.error) command = DepriCommand(["99", "FooBar"], self.todolist, self.out,
self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -142,13 +149,17 @@ class DepriCommandTest(CommandTest): ...@@ -142,13 +149,17 @@ class DepriCommandTest(CommandTest):
self.assertEqual(self.errors, "Invalid todo number given: 99.\nInvalid todo number given: FooBar.\n") self.assertEqual(self.errors, "Invalid todo number given: 99.\nInvalid todo number given: FooBar.\n")
def test_invalid4(self): def test_invalid4(self):
""" Throw an error with invalid argument containing special characters. """ """
command = DepriCommand([u("Fo\u00d3B\u0105r"), "Bar"], self.todolist, self.out, self.error, None) Throw an error with invalid argument containing special characters.
"""
command = DepriCommand([u("Fo\u00d3B\u0105r"), "Bar"], self.todolist,
self.out, self.error, None)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertFalse(self.output) self.assertFalse(self.output)
self.assertEqual(self.errors, u("Invalid todo number given: Fo\u00d3B\u0105r.\n")) self.assertEqual(self.errors,
u("Invalid todo number given: Fo\u00d3B\u0105r.\n"))
def test_empty(self): def test_empty(self):
command = DepriCommand([], self.todolist, self.out, self.error) command = DepriCommand([], self.todolist, self.out, self.error)
...@@ -163,7 +174,8 @@ class DepriCommandTest(CommandTest): ...@@ -163,7 +174,8 @@ class DepriCommandTest(CommandTest):
command.execute() command.execute()
self.assertEqual(self.output, "") self.assertEqual(self.output, "")
self.assertEqual(self.errors, command.usage() + "\n\n" + command.help() + "\n") self.assertEqual(self.errors,
command.usage() + "\n\n" + command.help() + "\n")
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
...@@ -14,8 +14,17 @@ ...@@ -14,8 +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/>.
import os
import unittest import unittest
from six import u
from test.CommandTestCase import CommandTest
from topydo.commands.EditCommand import EditCommand
from topydo.lib.Config import config
from topydo.lib.Todo import Todo
from topydo.lib.TodoList import TodoList
# We're searching for 'mock' # We're searching for 'mock'
# pylint: disable=no-name-in-module # pylint: disable=no-name-in-module
try: try:
...@@ -23,14 +32,6 @@ try: ...@@ -23,14 +32,6 @@ try:
except ImportError: except ImportError:
import mock import mock
from six import u
import os
from topydo.commands.EditCommand import EditCommand
from test.CommandTest import CommandTest
from topydo.lib.TodoList import TodoList
from topydo.lib.Todo import Todo
from topydo.lib.Config import config
class EditCommandTest(CommandTest): class EditCommandTest(CommandTest):
def setUp(self): def setUp(self):
...@@ -63,7 +64,8 @@ class EditCommandTest(CommandTest): ...@@ -63,7 +64,8 @@ class EditCommandTest(CommandTest):
mock_open_in_editor.return_value = 0 mock_open_in_editor.return_value = 0
mock_todos_from_temp.return_value = [Todo('Lazy Cat')] mock_todos_from_temp.return_value = [Todo('Lazy Cat')]
command = EditCommand(["Bar"], self.todolist, self.out, self.error, None) command = EditCommand(["Bar"], self.todolist, self.out, self.error,
None)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -72,7 +74,8 @@ class EditCommandTest(CommandTest): ...@@ -72,7 +74,8 @@ class EditCommandTest(CommandTest):
def test_edit3(self): def test_edit3(self):
""" Throw an error after invalid todo number given as argument. """ """ Throw an error after invalid todo number given as argument. """
command = EditCommand(["FooBar"], self.todolist, self.out, self.error, None) command = EditCommand(["FooBar"], self.todolist, self.out, self.error,
None)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -80,7 +83,8 @@ class EditCommandTest(CommandTest): ...@@ -80,7 +83,8 @@ class EditCommandTest(CommandTest):
def test_edit4(self): def test_edit4(self):
""" Throw an error with pointing invalid argument. """ """ Throw an error with pointing invalid argument. """
command = EditCommand(["Bar", "5"], self.todolist, self.out, self.error, None) command = EditCommand(["Bar", "5"], self.todolist, self.out,
self.error, None)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -93,7 +97,8 @@ class EditCommandTest(CommandTest): ...@@ -93,7 +97,8 @@ class EditCommandTest(CommandTest):
mock_open_in_editor.return_value = 0 mock_open_in_editor.return_value = 0
mock_todos_from_temp.return_value = [Todo('Only one line')] mock_todos_from_temp.return_value = [Todo('Only one line')]
command = EditCommand(["1", "Bar"], self.todolist, self.out, self.error, None) command = EditCommand(["1", "Bar"], self.todolist, self.out,
self.error, None)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -101,12 +106,16 @@ class EditCommandTest(CommandTest): ...@@ -101,12 +106,16 @@ class EditCommandTest(CommandTest):
self.assertEqual(self.todolist.print_todos(), u("Foo id:1\nBar p:1 @test\nBaz @test\nFo\u00f3B\u0105\u017a")) self.assertEqual(self.todolist.print_todos(), u("Foo id:1\nBar p:1 @test\nBaz @test\nFo\u00f3B\u0105\u017a"))
def test_edit6(self): def test_edit6(self):
""" Throw an error with invalid argument containing special characters. """ """
command = EditCommand([u("Fo\u00d3B\u0105r"), "Bar"], self.todolist, self.out, self.error, None) Throw an error with invalid argument containing special characters.
"""
command = EditCommand([u("Fo\u00d3B\u0105r"), "Bar"], self.todolist,
self.out, self.error, None)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
self.assertEqual(self.errors, u("Invalid todo number given: Fo\u00d3B\u0105r.\n")) self.assertEqual(self.errors,
u("Invalid todo number given: Fo\u00d3B\u0105r.\n"))
@mock.patch('topydo.commands.EditCommand.EditCommand._todos_from_temp') @mock.patch('topydo.commands.EditCommand.EditCommand._todos_from_temp')
@mock.patch('topydo.commands.EditCommand.EditCommand._open_in_editor') @mock.patch('topydo.commands.EditCommand.EditCommand._open_in_editor')
...@@ -115,21 +124,25 @@ class EditCommandTest(CommandTest): ...@@ -115,21 +124,25 @@ class EditCommandTest(CommandTest):
mock_open_in_editor.return_value = 0 mock_open_in_editor.return_value = 0
mock_todos_from_temp.return_value = [Todo('Lazy Cat')] mock_todos_from_temp.return_value = [Todo('Lazy Cat')]
command = EditCommand([u("Fo\u00f3B\u0105\u017a")], self.todolist, self.out, self.error, None) command = EditCommand([u("Fo\u00f3B\u0105\u017a")], self.todolist,
self.out, self.error, None)
command.execute() command.execute()
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
self.assertEqual(self.errors, "") self.assertEqual(self.errors, "")
self.assertEqual(self.todolist.print_todos(), u("Foo id:1\nBar p:1 @test\nBaz @test\nLazy Cat")) self.assertEqual(self.todolist.print_todos(),
u("Foo id:1\nBar p:1 @test\nBaz @test\nLazy Cat"))
@mock.patch('topydo.commands.EditCommand.EditCommand._todos_from_temp') @mock.patch('topydo.commands.EditCommand.EditCommand._todos_from_temp')
@mock.patch('topydo.commands.EditCommand.EditCommand._open_in_editor') @mock.patch('topydo.commands.EditCommand.EditCommand._open_in_editor')
def test_edit_expr(self, mock_open_in_editor, mock_todos_from_temp): def test_edit_expr(self, mock_open_in_editor, mock_todos_from_temp):
""" Edit todos matching expression. """ """ Edit todos matching expression. """
mock_open_in_editor.return_value = 0 mock_open_in_editor.return_value = 0
mock_todos_from_temp.return_value = [Todo('Lazy Cat'), Todo('Lazy Dog')] mock_todos_from_temp.return_value = [Todo('Lazy Cat'),
Todo('Lazy Dog')]
command = EditCommand(["-e", "@test"], self.todolist, self.out, self.error, None) command = EditCommand(["-e", "@test"], self.todolist, self.out,
self.error, None)
command.execute() command.execute()
expected = u("| 3| Lazy Cat\n| 4| Lazy Dog\n") expected = u("| 3| Lazy Cat\n| 4| Lazy Dog\n")
...@@ -148,7 +161,8 @@ class EditCommandTest(CommandTest): ...@@ -148,7 +161,8 @@ class EditCommandTest(CommandTest):
os.environ['EDITOR'] = editor os.environ['EDITOR'] = editor
archive = config().archive() archive = config().archive()
command = EditCommand(["-d"], self.todolist, self.out, self.error, None) command = EditCommand(["-d"], self.todolist, self.out, self.error,
None)
command.execute() command.execute()
self.assertEqual(self.errors, "") self.assertEqual(self.errors, "")
......
# 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 - 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
...@@ -16,23 +16,25 @@ ...@@ -16,23 +16,25 @@
""" Tests for the filter functionality. """ """ Tests for the filter functionality. """
from datetime import date, timedelta
import unittest import unittest
from datetime import date, timedelta
from test.Facilities import (load_file, load_file_to_todolist,
todolist_to_string)
from test.TopydoTestCase import TopydoTest
from topydo.lib import Filter from topydo.lib import Filter
from test.TestFacilities import load_file, todolist_to_string, load_file_to_todolist
from topydo.lib.Todo import Todo from topydo.lib.Todo import Todo
from test.TopydoTest import TopydoTest
class FilterTest(TopydoTest): class FilterTest(TopydoTest):
def test_filter3(self): def test_filter03(self):
todo = Todo("(C) Relevant") todo = Todo("(C) Relevant")
relevance = Filter.RelevanceFilter() relevance = Filter.RelevanceFilter()
result = relevance.filter([todo]) result = relevance.filter([todo])
self.assertEqual(result, [todo]) self.assertEqual(result, [todo])
def test_filter4(self): def test_filter04(self):
""" Test case insensitive match. """ """ Test case insensitive match. """
todos = load_file('test/data/FilterTest1.txt') todos = load_file('test/data/FilterTest1.txt')
grep = Filter.GrepFilter('+project') grep = Filter.GrepFilter('+project')
...@@ -40,10 +42,10 @@ class FilterTest(TopydoTest): ...@@ -40,10 +42,10 @@ class FilterTest(TopydoTest):
filtered_todos = grep.filter(todos) filtered_todos = grep.filter(todos)
reference = load_file('test/data/FilterTest1a-result.txt') reference = load_file('test/data/FilterTest1a-result.txt')
self.assertEqual(todolist_to_string(filtered_todos), \ self.assertEqual(todolist_to_string(filtered_todos),
todolist_to_string(reference)) todolist_to_string(reference))
def test_filter5(self): def test_filter05(self):
""" Test case sensitive match. """ """ Test case sensitive match. """
todos = load_file('test/data/FilterTest1.txt') todos = load_file('test/data/FilterTest1.txt')
grep = Filter.GrepFilter('+Project') grep = Filter.GrepFilter('+Project')
...@@ -51,10 +53,10 @@ class FilterTest(TopydoTest): ...@@ -51,10 +53,10 @@ class FilterTest(TopydoTest):
filtered_todos = grep.filter(todos) filtered_todos = grep.filter(todos)
reference = load_file('test/data/FilterTest1b-result.txt') reference = load_file('test/data/FilterTest1b-result.txt')
self.assertEqual(todolist_to_string(filtered_todos), \ self.assertEqual(todolist_to_string(filtered_todos),
todolist_to_string(reference)) todolist_to_string(reference))
def test_filter6(self): def test_filter06(self):
""" Test case sensitive match (forced, with lowercase). """ """ Test case sensitive match (forced, with lowercase). """
todos = load_file('test/data/FilterTest1.txt') todos = load_file('test/data/FilterTest1.txt')
grep = Filter.GrepFilter('+project', True) grep = Filter.GrepFilter('+project', True)
...@@ -62,10 +64,10 @@ class FilterTest(TopydoTest): ...@@ -62,10 +64,10 @@ class FilterTest(TopydoTest):
filtered_todos = grep.filter(todos) filtered_todos = grep.filter(todos)
reference = load_file('test/data/FilterTest1c-result.txt') reference = load_file('test/data/FilterTest1c-result.txt')
self.assertEqual(todolist_to_string(filtered_todos), \ self.assertEqual(todolist_to_string(filtered_todos),
todolist_to_string(reference)) todolist_to_string(reference))
def test_filter7(self): def test_filter07(self):
""" Tests the dependency filter. """ """ Tests the dependency filter. """
todolist = load_file_to_todolist('test/data/FilterTest2.txt') todolist = load_file_to_todolist('test/data/FilterTest2.txt')
depfilter = Filter.DependencyFilter(todolist) depfilter = Filter.DependencyFilter(todolist)
...@@ -73,10 +75,10 @@ class FilterTest(TopydoTest): ...@@ -73,10 +75,10 @@ class FilterTest(TopydoTest):
filtered_todos = depfilter.filter(todolist.todos()) filtered_todos = depfilter.filter(todolist.todos())
reference = load_file('test/data/FilterTest2-result.txt') reference = load_file('test/data/FilterTest2-result.txt')
self.assertEqual(todolist_to_string(filtered_todos), \ self.assertEqual(todolist_to_string(filtered_todos),
todolist_to_string(reference)) todolist_to_string(reference))
def test_filter8(self): def test_filter08(self):
""" Test case sensitive match (forced, with lowercase). """ """ Test case sensitive match (forced, with lowercase). """
todos = load_file('test/data/FilterTest1.txt') todos = load_file('test/data/FilterTest1.txt')
grep = Filter.GrepFilter('+Project', False) grep = Filter.GrepFilter('+Project', False)
...@@ -84,11 +86,11 @@ class FilterTest(TopydoTest): ...@@ -84,11 +86,11 @@ class FilterTest(TopydoTest):
filtered_todos = grep.filter(todos) filtered_todos = grep.filter(todos)
reference = load_file('test/data/FilterTest1a-result.txt') reference = load_file('test/data/FilterTest1a-result.txt')
self.assertEqual(todolist_to_string(filtered_todos), \ self.assertEqual(todolist_to_string(filtered_todos),
todolist_to_string(reference)) todolist_to_string(reference))
def test_filter9(self): def test_filter09(self):
""" Test instance filter """ """ Test instance filter. """
todos = load_file('test/data/FilterTest1.txt') todos = load_file('test/data/FilterTest1.txt')
instance_filter = Filter.InstanceFilter(todos[2:]) instance_filter = Filter.InstanceFilter(todos[2:])
...@@ -97,7 +99,7 @@ class FilterTest(TopydoTest): ...@@ -97,7 +99,7 @@ class FilterTest(TopydoTest):
self.assertEqual(todos[2:], filtered_todos) self.assertEqual(todos[2:], filtered_todos)
def test_filter10(self): def test_filter10(self):
""" Test instance filter """ """ Test instance filter. """
todos = load_file('test/data/FilterTest1.txt') todos = load_file('test/data/FilterTest1.txt')
instance_filter = Filter.InstanceFilter([]) instance_filter = Filter.InstanceFilter([])
...@@ -106,7 +108,7 @@ class FilterTest(TopydoTest): ...@@ -106,7 +108,7 @@ class FilterTest(TopydoTest):
self.assertEqual([], filtered_todos) self.assertEqual([], filtered_todos)
def test_filter11(self): def test_filter11(self):
""" Test instance filter """ """ Test instance filter. """
todos = load_file('test/data/FilterTest1.txt') todos = load_file('test/data/FilterTest1.txt')
instance_filter = Filter.InstanceFilter(todos[2:]) instance_filter = Filter.InstanceFilter(todos[2:])
...@@ -131,7 +133,8 @@ class FilterTest(TopydoTest): ...@@ -131,7 +133,8 @@ class FilterTest(TopydoTest):
filtered_todos = limit_filter.filter(todos) filtered_todos = limit_filter.filter(todos)
self.assertEqual(len(filtered_todos), 1) self.assertEqual(len(filtered_todos), 1)
self.assertEqual(filtered_todos[0].source(), '(C) This is part of some +Project') self.assertEqual(filtered_todos[0].source(),
'(C) This is part of some +Project')
def test_filter14(self): def test_filter14(self):
""" Test limit filter. """ """ Test limit filter. """
...@@ -158,7 +161,7 @@ class FilterTest(TopydoTest): ...@@ -158,7 +161,7 @@ class FilterTest(TopydoTest):
filtered_todos = grep.filter(todos) filtered_todos = grep.filter(todos)
reference = load_file('test/data/FilterTest3-result.txt') reference = load_file('test/data/FilterTest3-result.txt')
self.assertEqual(todolist_to_string(filtered_todos), \ self.assertEqual(todolist_to_string(filtered_todos),
todolist_to_string(reference)) todolist_to_string(reference))
def test_filter17(self): def test_filter17(self):
...@@ -170,7 +173,7 @@ class FilterTest(TopydoTest): ...@@ -170,7 +173,7 @@ class FilterTest(TopydoTest):
filtered_todos = andfilter.filter(todos) filtered_todos = andfilter.filter(todos)
reference = load_file('test/data/FilterTest4-result.txt') reference = load_file('test/data/FilterTest4-result.txt')
self.assertEqual(todolist_to_string(filtered_todos), \ self.assertEqual(todolist_to_string(filtered_todos),
todolist_to_string(reference)) todolist_to_string(reference))
def test_filter18(self): def test_filter18(self):
...@@ -182,7 +185,7 @@ class FilterTest(TopydoTest): ...@@ -182,7 +185,7 @@ class FilterTest(TopydoTest):
filtered_todos = grep.filter(todos) filtered_todos = grep.filter(todos)
reference = load_file('test/data/FilterTest5-result.txt') reference = load_file('test/data/FilterTest5-result.txt')
self.assertEqual(todolist_to_string(filtered_todos), \ self.assertEqual(todolist_to_string(filtered_todos),
todolist_to_string(reference)) todolist_to_string(reference))
def test_filter20(self): def test_filter20(self):
...@@ -192,7 +195,7 @@ class FilterTest(TopydoTest): ...@@ -192,7 +195,7 @@ class FilterTest(TopydoTest):
filtered_todos = otf.filter(todos) filtered_todos = otf.filter(todos)
reference = load_file('test/data/FilterTest6-result.txt') reference = load_file('test/data/FilterTest6-result.txt')
self.assertEqual(todolist_to_string(filtered_todos), \ self.assertEqual(todolist_to_string(filtered_todos),
todolist_to_string(reference)) todolist_to_string(reference))
def test_filter21(self): def test_filter21(self):
...@@ -295,6 +298,7 @@ class FilterTest(TopydoTest): ...@@ -295,6 +298,7 @@ class FilterTest(TopydoTest):
self.assertEqual(todolist_to_string(filtered_todos), self.assertEqual(todolist_to_string(filtered_todos),
todolist_to_string(reference)) todolist_to_string(reference))
class OrdinalTagFilterTest(TopydoTest): class OrdinalTagFilterTest(TopydoTest):
def setUp(self): def setUp(self):
super(OrdinalTagFilterTest, self).setUp() super(OrdinalTagFilterTest, self).setUp()
...@@ -374,6 +378,7 @@ class OrdinalTagFilterTest(TopydoTest): ...@@ -374,6 +378,7 @@ class OrdinalTagFilterTest(TopydoTest):
self.assertEqual(len(result), 1) self.assertEqual(len(result), 1)
self.assertEqual(result[0].source(), self.todo3) self.assertEqual(result[0].source(), self.todo3)
class PriorityFilterTest(TopydoTest): class PriorityFilterTest(TopydoTest):
def setUp(self): def setUp(self):
super(PriorityFilterTest, self).setUp() super(PriorityFilterTest, self).setUp()
...@@ -475,4 +480,3 @@ class PriorityFilterTest(TopydoTest): ...@@ -475,4 +480,3 @@ class PriorityFilterTest(TopydoTest):
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
# 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 - 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
...@@ -16,8 +16,9 @@ ...@@ -16,8 +16,9 @@
import unittest import unittest
from test.TopydoTestCase import TopydoTest
from topydo.lib.Graph import DirectedGraph from topydo.lib.Graph import DirectedGraph
from test.TopydoTest import TopydoTest
class GraphTest(TopydoTest): class GraphTest(TopydoTest):
def setUp(self): def setUp(self):
...@@ -63,7 +64,8 @@ class GraphTest(TopydoTest): ...@@ -63,7 +64,8 @@ class GraphTest(TopydoTest):
self.assertEqual(self.graph.incoming_neighbors(1, True), set()) self.assertEqual(self.graph.incoming_neighbors(1, True), set())
def test_incoming_neighbors4(self): def test_incoming_neighbors4(self):
self.assertEqual(self.graph.incoming_neighbors(5, True), set([1, 2, 3, 4, 6])) self.assertEqual(self.graph.incoming_neighbors(5, True),
set([1, 2, 3, 4, 6]))
def test_outgoing_neighbors1(self): def test_outgoing_neighbors1(self):
self.assertEqual(self.graph.outgoing_neighbors(1), set([2, 3])) self.assertEqual(self.graph.outgoing_neighbors(1), set([2, 3]))
...@@ -72,7 +74,8 @@ class GraphTest(TopydoTest): ...@@ -72,7 +74,8 @@ class GraphTest(TopydoTest):
self.assertEqual(self.graph.outgoing_neighbors(2), set([4])) self.assertEqual(self.graph.outgoing_neighbors(2), set([4]))
def test_outgoing_neighbors3(self): def test_outgoing_neighbors3(self):
self.assertEqual(self.graph.outgoing_neighbors(1, True), set([2, 3, 4, 5, 6])) self.assertEqual(self.graph.outgoing_neighbors(1, True),
set([2, 3, 4, 5, 6]))
def test_outgoing_neighbors4(self): def test_outgoing_neighbors4(self):
self.assertEqual(self.graph.outgoing_neighbors(3), set([5])) self.assertEqual(self.graph.outgoing_neighbors(3), set([5]))
......
# 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 - 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
...@@ -14,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 datetime import date
import unittest import unittest
from datetime import date
from test.TopydoTestCase import TopydoTest
from topydo.lib.Config import config from topydo.lib.Config import config
from topydo.lib.Importance import importance from topydo.lib.Importance import importance
from topydo.lib.Todo import Todo from topydo.lib.Todo import Todo
from test.TopydoTest import TopydoTest
class ImportanceTest(TopydoTest): class ImportanceTest(TopydoTest):
def test_importance1(self): def test_importance1(self):
......
...@@ -14,15 +14,19 @@ ...@@ -14,15 +14,19 @@
# 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
from test.TopydoTestCase import TopydoTest
from topydo.lib.JsonPrinter import JsonPrinter from topydo.lib.JsonPrinter import JsonPrinter
from topydo.lib.Todo import Todo from topydo.lib.Todo import Todo
from test.TopydoTest import TopydoTest
class JsonPrinterTest(TopydoTest): class JsonPrinterTest(TopydoTest):
""" """
Tests the functionality of printing a single todo item. Printing a list is Tests the functionality of printing a single todo item. Printing a list is
already covered by the ListCommand tests. already covered by the ListCommand tests.
""" """
def test_json(self): def test_json(self):
""" Print a single todo item. """ """ Print a single todo item. """
printer = JsonPrinter() printer = JsonPrinter()
...@@ -31,3 +35,6 @@ class JsonPrinterTest(TopydoTest): ...@@ -31,3 +35,6 @@ class JsonPrinterTest(TopydoTest):
result = printer.print_todo(todo) result = printer.print_todo(todo)
self.assertEqual(result, '{"completed": false, "completion_date": null, "contexts": [], "creation_date": "2015-06-06", "priority": null, "projects": [], "source": "2015-06-06 Foo due:2015-05-32", "tags": [["due", "2015-05-32"]], "text": "Foo"}') self.assertEqual(result, '{"completed": false, "completion_date": null, "contexts": [], "creation_date": "2015-06-06", "priority": null, "projects": [], "source": "2015-06-06 Foo due:2015-05-32", "tags": [["due", "2015-05-32"]], "text": "Foo"}')
if __name__ == '__main__':
unittest.main()
# Topydo - A todo.txt client written in Python. # Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl> # Copyright (C) 2014 - 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # 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
...@@ -16,9 +16,10 @@ ...@@ -16,9 +16,10 @@
import unittest import unittest
from test.CommandTestCase import CommandTest
from test.Facilities import load_file_to_todolist
from topydo.commands.ListContextCommand import ListContextCommand from topydo.commands.ListContextCommand import ListContextCommand
from test.CommandTest import CommandTest
from test.TestFacilities import load_file_to_todolist
class ListContextCommandTest(CommandTest): class ListContextCommandTest(CommandTest):
def test_contexts1(self): def test_contexts1(self):
...@@ -26,7 +27,7 @@ class ListContextCommandTest(CommandTest): ...@@ -26,7 +27,7 @@ class ListContextCommandTest(CommandTest):
command = ListContextCommand([""], todolist, self.out, self.error) command = ListContextCommand([""], todolist, self.out, self.error)
command.execute() command.execute()
self.assertEqual(self.output,"Context1\nContext2\n") self.assertEqual(self.output, "Context1\nContext2\n")
self.assertFalse(self.errors) self.assertFalse(self.errors)
def test_contexts2(self): def test_contexts2(self):
...@@ -34,7 +35,7 @@ class ListContextCommandTest(CommandTest): ...@@ -34,7 +35,7 @@ class ListContextCommandTest(CommandTest):
command = ListContextCommand(["aaa"], todolist, self.out, self.error) command = ListContextCommand(["aaa"], todolist, self.out, self.error)
command.execute() command.execute()
self.assertEqual(self.output,"Context1\nContext2\n") self.assertEqual(self.output, "Context1\nContext2\n")
self.assertFalse(self.errors) self.assertFalse(self.errors)
def test_help(self): def test_help(self):
...@@ -42,7 +43,8 @@ class ListContextCommandTest(CommandTest): ...@@ -42,7 +43,8 @@ class ListContextCommandTest(CommandTest):
command.execute() command.execute()
self.assertEqual(self.output, "") self.assertEqual(self.output, "")
self.assertEqual(self.errors, command.usage() + "\n\n" + command.help() + "\n") self.assertEqual(self.errors,
command.usage() + "\n\n" + command.help() + "\n")
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
# 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 - 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
...@@ -16,9 +16,10 @@ ...@@ -16,9 +16,10 @@
import unittest import unittest
from test.CommandTestCase import CommandTest
from test.Facilities import load_file_to_todolist
from topydo.commands.ListProjectCommand import ListProjectCommand from topydo.commands.ListProjectCommand import ListProjectCommand
from test.CommandTest import CommandTest
from test.TestFacilities import load_file_to_todolist
class ListProjectCommandTest(CommandTest): class ListProjectCommandTest(CommandTest):
def test_projects1(self): def test_projects1(self):
...@@ -42,7 +43,8 @@ class ListProjectCommandTest(CommandTest): ...@@ -42,7 +43,8 @@ class ListProjectCommandTest(CommandTest):
command.execute() command.execute()
self.assertEqual(self.output, "") self.assertEqual(self.output, "")
self.assertEqual(self.errors, command.usage() + "\n\n" + command.help() + "\n") self.assertEqual(self.errors,
command.usage() + "\n\n" + command.help() + "\n")
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
# 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 - 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
...@@ -14,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 datetime import date, timedelta
import unittest import unittest
from datetime import date, timedelta
from test.TopydoTestCase import TopydoTest
from topydo.lib.Config import config from topydo.lib.Config import config
from topydo.lib.Recurrence import advance_recurring_todo, NoRecurrenceException from topydo.lib.Recurrence import NoRecurrenceException, advance_recurring_todo
from topydo.lib.Todo import Todo from topydo.lib.Todo import Todo
from test.TopydoTest import TopydoTest
class RecurrenceTest(TopydoTest): class RecurrenceTest(TopydoTest):
def setUp(self): def setUp(self):
...@@ -164,12 +165,14 @@ class RecurrenceTest(TopydoTest): ...@@ -164,12 +165,14 @@ class RecurrenceTest(TopydoTest):
def test_no_recurrence(self): def test_no_recurrence(self):
self.todo.remove_tag('rec') self.todo.remove_tag('rec')
self.assertRaises(NoRecurrenceException, advance_recurring_todo, self.todo) self.assertRaises(NoRecurrenceException, advance_recurring_todo,
self.todo)
def test_invalid_recurrence(self): def test_invalid_recurrence(self):
""" Throw exception when 'rec' tag has an invalid value. """ """ Throw exception when 'rec' tag has an invalid value. """
self.todo.set_tag('rec', '1') self.todo.set_tag('rec', '1')
self.assertRaises(NoRecurrenceException, advance_recurring_todo, self.todo) self.assertRaises(NoRecurrenceException, advance_recurring_todo,
self.todo)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
# 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 - 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
...@@ -14,11 +14,12 @@ ...@@ -14,11 +14,12 @@
# 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
import unittest import unittest
from datetime import date, timedelta
from test.TopydoTestCase import TopydoTest
from topydo.lib.RelativeDate import relative_date_to_date from topydo.lib.RelativeDate import relative_date_to_date
from test.TopydoTest import TopydoTest
class RelativeDateTester(TopydoTest): class RelativeDateTester(TopydoTest):
def setUp(self): def setUp(self):
...@@ -103,8 +104,7 @@ class RelativeDateTester(TopydoTest): ...@@ -103,8 +104,7 @@ class RelativeDateTester(TopydoTest):
self.assertEqual(result, self.today) self.assertEqual(result, self.today)
def test_today3(self): def test_today3(self):
result = relative_date_to_date('today', \ result = relative_date_to_date('today', date.today() + timedelta(1))
date.today() + timedelta(1))
self.assertEqual(result, self.today) self.assertEqual(result, self.today)
def test_tomorrow1(self): def test_tomorrow1(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 - 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
...@@ -16,10 +16,11 @@ ...@@ -16,10 +16,11 @@
import unittest import unittest
from topydo.lib.Config import config from test.CommandTestCase import CommandTest
from test.Facilities import load_file_to_todolist
from topydo.commands.SortCommand import SortCommand from topydo.commands.SortCommand import SortCommand
from test.CommandTest import CommandTest from topydo.lib.Config import config
from test.TestFacilities import load_file_to_todolist
class SortCommandTest(CommandTest): class SortCommandTest(CommandTest):
def setUp(self): def setUp(self):
...@@ -27,17 +28,19 @@ class SortCommandTest(CommandTest): ...@@ -27,17 +28,19 @@ class SortCommandTest(CommandTest):
self.todolist = load_file_to_todolist("test/data/SorterTest1.txt") self.todolist = load_file_to_todolist("test/data/SorterTest1.txt")
def test_sort1(self): def test_sort1(self):
""" Alphabetically sorted """ """ Alphabetically sorted. """
command = SortCommand(["text"], self.todolist, self.out, self.error) command = SortCommand(["text"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEqual(self.todolist.print_todos(), "First\n(A) Foo\n2014-06-14 Last") self.assertEqual(self.todolist.print_todos(),
"First\n(A) Foo\n2014-06-14 Last")
def test_sort2(self): def test_sort2(self):
command = SortCommand([], self.todolist, self.out, self.error) command = SortCommand([], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertEqual(self.todolist.print_todos(), "(A) Foo\n2014-06-14 Last\nFirst") self.assertEqual(self.todolist.print_todos(),
"(A) Foo\n2014-06-14 Last\nFirst")
def test_sort3(self): def test_sort3(self):
""" Check that order does not influence the UID of a todo. """ """ Check that order does not influence the UID of a todo. """
...@@ -55,7 +58,8 @@ class SortCommandTest(CommandTest): ...@@ -55,7 +58,8 @@ class SortCommandTest(CommandTest):
command.execute() command.execute()
self.assertEqual(self.output, "") self.assertEqual(self.output, "")
self.assertEqual(self.errors, command.usage() + "\n\n" + command.help() + "\n") self.assertEqual(self.errors,
command.usage() + "\n\n" + command.help() + "\n")
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
# 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 - 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
...@@ -16,11 +16,12 @@ ...@@ -16,11 +16,12 @@
import unittest import unittest
from test.Facilities import (load_file, load_file_to_todolist, print_view,
todolist_to_string)
from test.TopydoTestCase import TopydoTest
from topydo.lib.Config import config from topydo.lib.Config import config
from topydo.lib.Sorter import Sorter from topydo.lib.Sorter import Sorter
from test.TestFacilities import load_file, todolist_to_string, load_file_to_todolist, print_view
from test.TopydoTest import TopydoTest
class SorterTest(TopydoTest): class SorterTest(TopydoTest):
def sort_file(self, p_filename, p_filename_ref, p_sorter): def sort_file(self, p_filename, p_filename_ref, p_sorter):
...@@ -36,80 +37,93 @@ class SorterTest(TopydoTest): ...@@ -36,80 +37,93 @@ class SorterTest(TopydoTest):
self.assertEqual(todos_sorted, todos_ref) self.assertEqual(todos_sorted, todos_ref)
self.assertEqual(todolist_to_string(todos), text_before) self.assertEqual(todolist_to_string(todos), text_before)
def test_sort1(self): def test_sort01(self):
""" Alphabetically sorted """ """ Alphabetically sorted. """
sorter = Sorter('text') sorter = Sorter('text')
self.sort_file('test/data/SorterTest1.txt', 'test/data/SorterTest1-result.txt', sorter) self.sort_file('test/data/SorterTest1.txt',
'test/data/SorterTest1-result.txt', sorter)
def test_sort2a(self): def test_sort02a(self):
""" """
Ascendingly sorted by priority. Also checks stableness of the sort. Ascendingly sorted by priority. Also checks stableness of the sort.
""" """
sorter = Sorter('prio') sorter = Sorter('prio')
self.sort_file('test/data/SorterTest2.txt', 'test/data/SorterTest2-result.txt', sorter) self.sort_file('test/data/SorterTest2.txt',
'test/data/SorterTest2-result.txt', sorter)
def test_sort2b(self): def test_sort02b(self):
""" """
Ascendingly sorted by priority. Also checks stableness of the sort. Ascendingly sorted by priority. Also checks stableness of the sort.
""" """
sorter = Sorter('asc:prio') sorter = Sorter('asc:prio')
self.sort_file('test/data/SorterTest2.txt', 'test/data/SorterTest2-result.txt', sorter) self.sort_file('test/data/SorterTest2.txt',
'test/data/SorterTest2-result.txt', sorter)
def test_sort3(self): def test_sort03(self):
""" """
Descendingly sorted by priority. Also checks stableness of the Descendingly sorted by priority. Also checks stableness of the
sort. sort.
""" """
sorter = Sorter('desc:prio') sorter = Sorter('desc:prio')
self.sort_file('test/data/SorterTest3.txt', 'test/data/SorterTest3-result.txt', sorter) self.sort_file('test/data/SorterTest3.txt',
'test/data/SorterTest3-result.txt', sorter)
def test_sort4(self): def test_sort04(self):
""" Ascendingly sorted by due date """ """ Ascendingly sorted by due date. """
sorter = Sorter(config().tag_due()) sorter = Sorter(config().tag_due())
self.sort_file('test/data/SorterTest4.txt', 'test/data/SorterTest4-result.txt', sorter) self.sort_file('test/data/SorterTest4.txt',
'test/data/SorterTest4-result.txt', sorter)
def test_sort5(self): def test_sort05(self):
""" Descendingly sorted by due date """ """ Descendingly sorted by due date. """
sorter = Sorter('desc:due') sorter = Sorter('desc:due')
self.sort_file('test/data/SorterTest5.txt', 'test/data/SorterTest5-result.txt', sorter) self.sort_file('test/data/SorterTest5.txt',
'test/data/SorterTest5-result.txt', sorter)
def test_sort6(self): def test_sort06(self):
""" Ascendingly sorted by creation date """ """ Ascendingly sorted by creation date. """
sorter = Sorter('creation') sorter = Sorter('creation')
self.sort_file('test/data/SorterTest6.txt', 'test/data/SorterTest6-result.txt', sorter) self.sort_file('test/data/SorterTest6.txt',
'test/data/SorterTest6-result.txt', sorter)
def test_sort7(self): def test_sort07(self):
""" Ascendingly sorted by completion date. """ """ Ascendingly sorted by completion date. """
sorter = Sorter('completion') sorter = Sorter('completion')
self.sort_file('test/data/SorterTest7.txt', 'test/data/SorterTest7-result.txt', sorter) self.sort_file('test/data/SorterTest7.txt',
'test/data/SorterTest7-result.txt', sorter)
def test_sort8(self): def test_sort08(self):
""" Descendingly sorted by importance """ """ Descendingly sorted by importance. """
sorter = Sorter('desc:importance') sorter = Sorter('desc:importance')
self.sort_file('test/data/SorterTest8.txt', 'test/data/SorterTest8-result.txt', sorter) self.sort_file('test/data/SorterTest8.txt',
'test/data/SorterTest8-result.txt', sorter)
def test_sort9(self): def test_sort09(self):
""" """
Sort on multiple levels: first descending importance, then Sort on multiple levels: first descending importance, then
ascending priority. ascending priority.
""" """
sorter = Sorter('desc:importance,priority') sorter = Sorter('desc:importance,priority')
self.sort_file('test/data/SorterTest9.txt', 'test/data/SorterTest9-result.txt', sorter) self.sort_file('test/data/SorterTest9.txt',
'test/data/SorterTest9-result.txt', sorter)
def test_sort10(self): def test_sort10(self):
""" Deal with garbage input. """ """ Deal with garbage input. """
sorter = Sorter('') sorter = Sorter('')
self.sort_file('test/data/SorterTest9.txt', 'test/data/SorterTest9.txt', sorter) self.sort_file('test/data/SorterTest9.txt',
'test/data/SorterTest9.txt', sorter)
def test_sort11(self): def test_sort11(self):
""" Deal with garbage input. """ """ Deal with garbage input. """
sorter = Sorter('fnord') sorter = Sorter('fnord')
self.sort_file('test/data/SorterTest9.txt', 'test/data/SorterTest9.txt', sorter) self.sort_file('test/data/SorterTest9.txt',
'test/data/SorterTest9.txt', sorter)
def test_sort12(self): def test_sort12(self):
""" Deal with garbage input. """ """ Deal with garbage input. """
sorter = Sorter('desc:importance,,priority') sorter = Sorter('desc:importance,,priority')
self.sort_file('test/data/SorterTest9.txt', 'test/data/SorterTest9-result.txt', sorter) self.sort_file('test/data/SorterTest9.txt',
'test/data/SorterTest9-result.txt', sorter)
def test_sort13(self): def test_sort13(self):
""" """
...@@ -119,7 +133,8 @@ class SorterTest(TopydoTest): ...@@ -119,7 +133,8 @@ class SorterTest(TopydoTest):
dependencies the average importance should be equal. dependencies the average importance should be equal.
""" """
sorter = Sorter('desc:importance-avg') sorter = Sorter('desc:importance-avg')
self.sort_file('test/data/SorterTest9.txt', 'test/data/SorterTest9-result.txt', sorter) self.sort_file('test/data/SorterTest9.txt',
'test/data/SorterTest9-result.txt', sorter)
def test_sort14(self): def test_sort14(self):
sorter = Sorter('desc:importance-average') sorter = Sorter('desc:importance-average')
......
# 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 - 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
...@@ -14,20 +14,23 @@ ...@@ -14,20 +14,23 @@
# 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
import unittest import unittest
from datetime import date, timedelta
from test.TopydoTestCase import TopydoTest
from topydo.lib.Todo import Todo from topydo.lib.Todo import Todo
from test.TopydoTest import TopydoTest
def today_date(): def today_date():
today = date.today() today = date.today()
return today.isoformat() return today.isoformat()
def tomorrow_date(): def tomorrow_date():
tomorrow = date.today() + timedelta(days=1) tomorrow = date.today() + timedelta(days=1)
return tomorrow.isoformat() return tomorrow.isoformat()
class TodoTest(TopydoTest): class TodoTest(TopydoTest):
def test_due_date1(self): def test_due_date1(self):
todo = Todo("(C) Foo due:2014-06-09") todo = Todo("(C) Foo due:2014-06-09")
...@@ -37,7 +40,7 @@ class TodoTest(TopydoTest): ...@@ -37,7 +40,7 @@ class TodoTest(TopydoTest):
def test_false_date(self): def test_false_date(self):
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("(C) Foo due:2014-01-01") todo = Todo("(C) Foo due:2014-01-01")
......
# 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 - 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
...@@ -16,12 +16,13 @@ ...@@ -16,12 +16,13 @@
""" Tests for the TodoBase class. """ """ Tests for the TodoBase class. """
from datetime import date, timedelta
import re import re
import unittest import unittest
from datetime import date, timedelta
from test.TopydoTestCase import TopydoTest
from topydo.lib.TodoBase import TodoBase from topydo.lib.TodoBase import TodoBase
from test.TopydoTest import TopydoTest
class TodoBaseTester(TopydoTest): class TodoBaseTester(TopydoTest):
def test_parse_tag(self): def test_parse_tag(self):
...@@ -85,7 +86,7 @@ class TodoBaseTester(TopydoTest): ...@@ -85,7 +86,7 @@ class TodoBaseTester(TopydoTest):
def test_set_tag_double_value(self): def test_set_tag_double_value(self):
todo = 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'))
self.assertTrue(todo.tag_value('foo'), 'blah') self.assertTrue(todo.tag_value('foo'), 'blah')
...@@ -97,7 +98,8 @@ class TodoBaseTester(TopydoTest): ...@@ -97,7 +98,8 @@ class TodoBaseTester(TopydoTest):
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("(C) Foo foo:bar foo:baz") todo = TodoBase("(C) Foo foo:bar foo:baz")
...@@ -108,14 +110,12 @@ class TodoBaseTester(TopydoTest): ...@@ -108,14 +110,12 @@ class TodoBaseTester(TopydoTest):
def test_tag_empty_value(self): def test_tag_empty_value(self):
""" Tag should not be recorded when there is no value. """ """ Tag should not be recorded when there is no value. """
todo = TodoBase("(C) Foo foo:") todo = TodoBase("(C) Foo foo:")
self.assertFalse(todo.has_tag('foo')) self.assertFalse(todo.has_tag('foo'))
def test_tag_empty_key(self): def test_tag_empty_key(self):
""" Tag should not be recorded when there is no key. """ """ Tag should not be recorded when there is no key. """
todo = TodoBase("(C) Foo :bar") todo = TodoBase("(C) Foo :bar")
self.assertFalse(todo.has_tag('')) self.assertFalse(todo.has_tag(''))
...@@ -259,7 +259,7 @@ class TodoBaseTester(TopydoTest): ...@@ -259,7 +259,7 @@ class TodoBaseTester(TopydoTest):
today_str = today.isoformat() today_str = today.isoformat()
self.assertEqual(todo.fields['completionDate'], today) self.assertEqual(todo.fields['completionDate'], today)
self.assertTrue(re.match('^x ' + today_str + ' 2014-06-12 Foo', \ self.assertTrue(re.match('^x ' + today_str + ' 2014-06-12 Foo',
todo.src)) todo.src))
def test_set_complete3(self): def test_set_complete3(self):
...@@ -280,7 +280,8 @@ class TodoBaseTester(TopydoTest): ...@@ -280,7 +280,8 @@ class TodoBaseTester(TopydoTest):
today_str = today.isoformat() today_str = today.isoformat()
self.assertEqual(todo.fields['completionDate'], today) self.assertEqual(todo.fields['completionDate'], today)
self.assertTrue(re.match('^x ' + today_str + ' 2014-06-12 Foo', todo.src)) self.assertTrue(re.match('^x ' + today_str + ' 2014-06-12 Foo',
todo.src))
def test_set_complete5(self): def test_set_complete5(self):
todo = TodoBase("x 2014-06-13 Foo") todo = TodoBase("x 2014-06-13 Foo")
...@@ -302,7 +303,7 @@ class TodoBaseTester(TopydoTest): ...@@ -302,7 +303,7 @@ class TodoBaseTester(TopydoTest):
todo.set_source_text(new_text) todo.set_source_text(new_text)
self.assertEqual(todo.src, new_text) self.assertEqual(todo.src, new_text)
self.assertEqual(todo.priority(),'C') self.assertEqual(todo.priority(), 'C')
def test_set_creation_date1(self): def test_set_creation_date1(self):
todo = TodoBase("Foo") todo = TodoBase("Foo")
......
# 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 - 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
...@@ -14,11 +14,13 @@ ...@@ -14,11 +14,13 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from six import u
import unittest import unittest
from test.TestFacilities import load_file from six import u
from test.TopydoTest import TopydoTest
from test.Facilities import load_file
from test.TopydoTestCase import TopydoTest
class TodoFileTest(TopydoTest): class TodoFileTest(TopydoTest):
def test_empty_file(self): def test_empty_file(self):
...@@ -29,7 +31,8 @@ class TodoFileTest(TopydoTest): ...@@ -29,7 +31,8 @@ class TodoFileTest(TopydoTest):
def test_utf_8(self): def test_utf_8(self):
todofile = load_file('test/data/utf-8.txt') todofile = load_file('test/data/utf-8.txt')
self.assertEqual(todofile[0].source(), u('(C) \u25ba UTF-8 test \u25c4')) self.assertEqual(todofile[0].source(),
u('(C) \u25ba UTF-8 test \u25c4'))
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
# 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 - 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
...@@ -19,31 +19,31 @@ ...@@ -19,31 +19,31 @@
import re import re
import unittest import unittest
from test.TopydoTestCase import TopydoTest
from topydo.lib.Config import config from topydo.lib.Config import config
from topydo.lib.Todo import Todo from topydo.lib.Todo import Todo
from topydo.lib.TodoFile import TodoFile from topydo.lib.TodoFile import TodoFile
from topydo.lib.TodoListBase import InvalidTodoException
from topydo.lib.TodoList import TodoList from topydo.lib.TodoList import TodoList
from topydo.lib.TodoListBase import TodoListBase from topydo.lib.TodoListBase import InvalidTodoException, TodoListBase
from test.TopydoTest import TopydoTest
class TodoListTester(TopydoTest): class TodoListTester(TopydoTest):
def setUp(self): def setUp(self):
super(TodoListTester, self).setUp() super(TodoListTester, self).setUp()
self.todofile = TodoFile('test/data/TodoListTest.txt') self.todofile = TodoFile('test/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 = TodoListBase(lines) self.todolist = TodoListBase(lines)
def test_contexts(self): def test_contexts(self):
self.assertEqual(set(['Context1', 'Context2']), \ self.assertEqual(set(['Context1', 'Context2']),
self.todolist.contexts()) self.todolist.contexts())
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
def test_projects(self): def test_projects(self):
self.assertEqual(set(['Project1', 'Project2']), \ self.assertEqual(set(['Project1', 'Project2']),
self.todolist.projects()) self.todolist.projects())
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -53,9 +53,9 @@ class TodoListTester(TopydoTest): ...@@ -53,9 +53,9 @@ class TodoListTester(TopydoTest):
todo = self.todolist.add(text) todo = self.todolist.add(text)
self.assertEqual(self.todolist.todo(count+1).source(), text) self.assertEqual(self.todolist.todo(count+1).source(), text)
self.assertEqual(set(['Project1', 'Project2', 'Project3']), \ self.assertEqual(set(['Project1', 'Project2', 'Project3']),
self.todolist.projects()) self.todolist.projects())
self.assertEqual(set(['Context1', 'Context2', 'Context3']), \ self.assertEqual(set(['Context1', 'Context2', 'Context3']),
self.todolist.contexts()) self.todolist.contexts())
self.assertEqual(self.todolist.number(todo), 6) self.assertEqual(self.todolist.number(todo), 6)
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -70,7 +70,8 @@ class TodoListTester(TopydoTest): ...@@ -70,7 +70,8 @@ class TodoListTester(TopydoTest):
self.todolist.add('\n(C) New task') self.todolist.add('\n(C) New task')
self.assertEqual(self.todolist.count(), count + 1) self.assertEqual(self.todolist.count(), count + 1)
self.assertEqual(self.todolist.todo(count + 1).source(), '(C) New task') self.assertEqual(self.todolist.todo(count + 1).source(),
'(C) New task')
self.assertEqual(self.todolist.todo(count + 1).priority(), 'C') self.assertEqual(self.todolist.todo(count + 1).priority(), 'C')
def test_add3b(self): def test_add3b(self):
...@@ -78,7 +79,8 @@ class TodoListTester(TopydoTest): ...@@ -78,7 +79,8 @@ class TodoListTester(TopydoTest):
self.todolist.add('(C) New task\n') self.todolist.add('(C) New task\n')
self.assertEqual(self.todolist.count(), count + 1) self.assertEqual(self.todolist.count(), count + 1)
self.assertEqual(self.todolist.todo(count + 1).source(), '(C) New task') self.assertEqual(self.todolist.todo(count + 1).source(),
'(C) New task')
self.assertEqual(self.todolist.todo(count + 1).priority(), 'C') self.assertEqual(self.todolist.todo(count + 1).priority(), 'C')
def test_add4(self): def test_add4(self):
...@@ -96,7 +98,7 @@ class TodoListTester(TopydoTest): ...@@ -96,7 +98,7 @@ class TodoListTester(TopydoTest):
todo = self.todolist.todo(2) todo = self.todolist.todo(2)
self.todolist.delete(todo) self.todolist.delete(todo)
self.assertEqual(self.todolist.todo(2).source(), \ self.assertEqual(self.todolist.todo(2).source(),
"(C) Baz @Context1 +Project1 key:value") "(C) Baz @Context1 +Project1 key:value")
self.assertEqual(self.todolist.count(), count - 1) self.assertEqual(self.todolist.count(), count - 1)
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -116,9 +118,9 @@ class TodoListTester(TopydoTest): ...@@ -116,9 +118,9 @@ class TodoListTester(TopydoTest):
todo = self.todolist.todo(3) todo = self.todolist.todo(3)
self.todolist.append(todo, "@Context3") self.todolist.append(todo, "@Context3")
self.assertEqual(todo.source(), \ self.assertEqual(todo.source(),
"(C) Baz @Context1 +Project1 key:value @Context3") "(C) Baz @Context1 +Project1 key:value @Context3")
self.assertEqual(set(['Context1', 'Context2', 'Context3']), \ self.assertEqual(set(['Context1', 'Context2', 'Context3']),
self.todolist.contexts()) self.todolist.contexts())
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
...@@ -128,7 +130,7 @@ class TodoListTester(TopydoTest): ...@@ -128,7 +130,7 @@ class TodoListTester(TopydoTest):
self.todolist.append(todo, "foo:bar") self.todolist.append(todo, "foo:bar")
self.assertEqual(todo.text(), text) self.assertEqual(todo.text(), text)
self.assertEqual(todo.source(), \ self.assertEqual(todo.source(),
"(C) Baz @Context1 +Project1 key:value foo:bar") "(C) Baz @Context1 +Project1 key:value foo:bar")
def test_append3(self): def test_append3(self):
...@@ -141,7 +143,8 @@ class TodoListTester(TopydoTest): ...@@ -141,7 +143,8 @@ class TodoListTester(TopydoTest):
def test_todo(self): def test_todo(self):
count = self.todolist.count() count = self.todolist.count()
self.assertRaises(InvalidTodoException, self.todolist.todo, count + 100) self.assertRaises(InvalidTodoException, self.todolist.todo,
count + 100)
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
def test_count(self): def test_count(self):
...@@ -197,7 +200,8 @@ class TodoListTester(TopydoTest): ...@@ -197,7 +200,8 @@ class TodoListTester(TopydoTest):
def test_uid1(self): def test_uid1(self):
config("test/data/todolist-uid.conf") config("test/data/todolist-uid.conf")
self.assertEqual(self.todolist.todo('t5c').source(), "(C) Foo @Context2 Not@Context +Project1 Not+Project") self.assertEqual(self.todolist.todo('t5c').source(),
"(C) Foo @Context2 Not@Context +Project1 Not+Project")
def test_uid2(self): def test_uid2(self):
""" Changing the priority should not change the identifier. """ """ Changing the priority should not change the identifier. """
...@@ -205,25 +209,25 @@ class TodoListTester(TopydoTest): ...@@ -205,25 +209,25 @@ class TodoListTester(TopydoTest):
todo = self.todolist.todo('t5c') todo = self.todolist.todo('t5c')
self.todolist.set_priority(todo, 'B') self.todolist.set_priority(todo, 'B')
self.assertEqual(self.todolist.todo('t5c').source(), "(B) Foo @Context2 Not@Context +Project1 Not+Project") self.assertEqual(self.todolist.todo('t5c').source(),
"(B) Foo @Context2 Not@Context +Project1 Not+Project")
def test_uid3(self): def test_uid3(self):
""" """
Must be able to handle integers when text identifiers are enabled. Must be able to handle integers when text identifiers are enabled.
""" """
config("test/data/todolist-uid.conf") config("test/data/todolist-uid.conf")
self.assertRaises(InvalidTodoException, self.todolist.todo, 1) self.assertRaises(InvalidTodoException, self.todolist.todo, 1)
def test_new_uid(self): def test_new_uid(self):
""" Make sure that item has new text ID after append. """ """ Make sure that item has new text ID after append. """
config("test/data/todolist-uid.conf") config("test/data/todolist-uid.conf")
todo = self.todolist.todo('t5c') todo = self.todolist.todo('t5c')
self.todolist.append(todo, "A") self.todolist.append(todo, "A")
self.assertNotEqual(self.todolist.number(todo), 't5c') self.assertNotEqual(self.todolist.number(todo), 't5c')
class TodoListDependencyTester(TopydoTest): class TodoListDependencyTester(TopydoTest):
def setUp(self): def setUp(self):
super(TodoListDependencyTester, self).setUp() super(TodoListDependencyTester, self).setUp()
...@@ -241,23 +245,23 @@ class TodoListDependencyTester(TopydoTest): ...@@ -241,23 +245,23 @@ class TodoListDependencyTester(TopydoTest):
def test_check_dep(self): def test_check_dep(self):
children = self.todolist.children(self.todolist.todo(1)) children = self.todolist.children(self.todolist.todo(1))
self.assertEqual(sorted([todo.source() for todo in children]), \ self.assertEqual(sorted([todo.source() for todo in children]),
sorted(['Bar p:1', 'Baz p:1 id:2', 'Buzz p:2'])) sorted(['Bar p:1', 'Baz p:1 id:2', 'Buzz p:2']))
children = self.todolist.children(self.todolist.todo(1), True) children = self.todolist.children(self.todolist.todo(1), True)
self.assertEqual(sorted([todo.source() for todo in children]), \ self.assertEqual(sorted([todo.source() for todo in children]),
sorted(['Bar p:1', 'Baz p:1 id:2'])) sorted(['Bar p:1', 'Baz p:1 id:2']))
children = self.todolist.children(self.todolist.todo(3)) children = self.todolist.children(self.todolist.todo(3))
self.assertEqual(sorted([todo.source() for todo in children]), \ self.assertEqual(sorted([todo.source() for todo in children]),
['Buzz p:2']) ['Buzz p:2'])
parents = self.todolist.parents(self.todolist.todo(4)) parents = self.todolist.parents(self.todolist.todo(4))
self.assertEqual(sorted([todo.source() for todo in parents]), \ self.assertEqual(sorted([todo.source() for todo in parents]),
sorted(['Foo id:1', 'Baz p:1 id:2'])) sorted(['Foo id:1', 'Baz p:1 id:2']))
parents = self.todolist.parents(self.todolist.todo(4), True) parents = self.todolist.parents(self.todolist.todo(4), True)
self.assertEqual(sorted([todo.source() for todo in parents]), \ self.assertEqual(sorted([todo.source() for todo in parents]),
['Baz p:1 id:2']) ['Baz p:1 id:2'])
self.assertEqual(self.todolist.children(self.todolist.todo(2)), []) self.assertEqual(self.todolist.children(self.todolist.todo(2)), [])
...@@ -276,7 +280,6 @@ class TodoListDependencyTester(TopydoTest): ...@@ -276,7 +280,6 @@ class TodoListDependencyTester(TopydoTest):
Make sure that previous add_dependency invocation stored the Make sure that previous add_dependency invocation stored the
edge_id properly. edge_id properly.
""" """
todo1 = self.todolist.todo(1) todo1 = self.todolist.todo(1)
todo4 = self.todolist.todo(4) todo4 = self.todolist.todo(4)
todo5 = self.todolist.todo(5) todo5 = self.todolist.todo(5)
...@@ -291,7 +294,6 @@ class TodoListDependencyTester(TopydoTest): ...@@ -291,7 +294,6 @@ class TodoListDependencyTester(TopydoTest):
""" """
Test that projects are not added double. Test that projects are not added double.
""" """
todo6 = self.todolist.todo(6) todo6 = self.todolist.todo(6)
todo7 = self.todolist.todo(7) todo7 = self.todolist.todo(7)
projects = todo7.projects().copy() projects = todo7.projects().copy()
...@@ -361,6 +363,7 @@ class TodoListDependencyTester(TopydoTest): ...@@ -361,6 +363,7 @@ class TodoListDependencyTester(TopydoTest):
self.assertTrue(todolist.todo_by_dep_id('1')) self.assertTrue(todolist.todo_by_dep_id('1'))
self.assertFalse(todolist.todo_by_dep_id('2')) self.assertFalse(todolist.todo_by_dep_id('2'))
class TodoListCleanDependencyTester(TopydoTest): class TodoListCleanDependencyTester(TopydoTest):
def setUp(self): def setUp(self):
super(TodoListCleanDependencyTester, self).setUp() super(TodoListCleanDependencyTester, self).setUp()
......
# 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 - 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
...@@ -16,12 +16,13 @@ ...@@ -16,12 +16,13 @@
import unittest import unittest
from test.Facilities import load_file, print_view, todolist_to_string
from test.TopydoTestCase import TopydoTest
from topydo.lib import Filter from topydo.lib import Filter
from topydo.lib.Sorter import Sorter from topydo.lib.Sorter import Sorter
from test.TestFacilities import load_file, todolist_to_string, print_view
from topydo.lib.TodoFile import TodoFile from topydo.lib.TodoFile import TodoFile
from topydo.lib.TodoList import TodoList from topydo.lib.TodoList import TodoList
from test.TopydoTest import TopydoTest
class ViewTest(TopydoTest): class ViewTest(TopydoTest):
def test_view(self): def test_view(self):
...@@ -38,4 +39,3 @@ class ViewTest(TopydoTest): ...@@ -38,4 +39,3 @@ class ViewTest(TopydoTest):
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
# 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 - 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
...@@ -18,10 +18,10 @@ import unittest ...@@ -18,10 +18,10 @@ import unittest
from topydo.lib.Config import config from topydo.lib.Config import config
class TopydoTest(unittest.TestCase): class TopydoTest(unittest.TestCase):
def tearDown(self): def tearDown(self):
""" """
Make sure that every test case leaves a clean configuration. Make sure that every test case leaves a clean configuration.
""" """
config("") config("")
...@@ -52,10 +52,10 @@ _SUBCOMMAND_MAP = { ...@@ -52,10 +52,10 @@ _SUBCOMMAND_MAP = {
'tag': 'TagCommand', 'tag': 'TagCommand',
} }
def get_subcommand(p_args): def get_subcommand(p_args):
""" """
Retrieves the to-be executed Command and returns a tuple Retrieves the to-be executed Command and returns a tuple (Command, args).
(Command, args).
If args is an empty list, then the Command that corresponds with the If args is an empty list, then the Command that corresponds with the
default command specified in the configuration will be returned. default command specified in the configuration will be returned.
...@@ -109,4 +109,3 @@ def get_subcommand(p_args): ...@@ -109,4 +109,3 @@ def get_subcommand(p_args):
result = import_subcommand(p_command) result = import_subcommand(p_command)
return (result, args) return (result, args)
...@@ -34,10 +34,12 @@ except ConfigError as config_error: ...@@ -34,10 +34,12 @@ except ConfigError as config_error:
from topydo.Commands import get_subcommand from topydo.Commands import get_subcommand
from topydo.lib import TodoList from topydo.lib import TodoList
class CLIApplication(CLIApplicationBase): class CLIApplication(CLIApplicationBase):
""" """
Class that represents the (original) Command Line Interface of Topydo. Class that represents the (original) Command Line Interface of Topydo.
""" """
def __init__(self): def __init__(self):
super(CLIApplication, self).__init__() super(CLIApplication, self).__init__()
...@@ -50,7 +52,7 @@ class CLIApplication(CLIApplicationBase): ...@@ -50,7 +52,7 @@ class CLIApplication(CLIApplicationBase):
(subcommand, args) = get_subcommand(args) (subcommand, args) = get_subcommand(args)
if subcommand == None: if subcommand is None:
self._usage() self._usage()
if self._execute(subcommand, args) == False: if self._execute(subcommand, args) == False:
...@@ -58,6 +60,7 @@ class CLIApplication(CLIApplicationBase): ...@@ -58,6 +60,7 @@ class CLIApplication(CLIApplicationBase):
else: else:
self._post_execute() self._post_execute()
def main(): def main():
""" Main entry point of the CLI. """ """ Main entry point of the CLI. """
CLIApplication().run() CLIApplication().run()
......
...@@ -26,6 +26,7 @@ from six.moves import input ...@@ -26,6 +26,7 @@ from six.moves import input
MAIN_OPTS = "ac:d:ht:v" MAIN_OPTS = "ac:d:ht:v"
def usage(): def usage():
""" Prints the command-line usage of topydo. """ """ Prints the command-line usage of topydo. """
...@@ -61,6 +62,7 @@ Available commands: ...@@ -61,6 +62,7 @@ Available commands:
Run `topydo help <subcommand>` for command-specific help. Run `topydo help <subcommand>` for command-specific help.
""") """)
def write(p_file, p_string): def write(p_file, p_string):
""" """
Write p_string to file p_file, trailed by a newline character. Write p_string to file p_file, trailed by a newline character.
...@@ -73,11 +75,12 @@ def write(p_file, p_string): ...@@ -73,11 +75,12 @@ def write(p_file, p_string):
if p_string: if p_string:
p_file.write(p_string + "\n") p_file.write(p_string + "\n")
def error(p_string): def error(p_string):
""" Writes an error on the standard error. """ """ Writes an error on the standard error. """
write(sys.stderr, p_string) write(sys.stderr, p_string)
def version(): def version():
""" Print the current version and exit. """ """ Print the current version and exit. """
from topydo.lib.Version import VERSION, LICENSE from topydo.lib.Version import VERSION, LICENSE
...@@ -103,6 +106,7 @@ from topydo.lib import TodoList ...@@ -103,6 +106,7 @@ from topydo.lib import TodoList
from topydo.lib import TodoListBase from topydo.lib import TodoListBase
from topydo.lib.Utils import escape_ansi from topydo.lib.Utils import escape_ansi
class CLIApplicationBase(object): class CLIApplicationBase(object):
""" """
Base class for a Command Line Interfaces (CLI) for topydo. Examples are the Base class for a Command Line Interfaces (CLI) for topydo. Examples are the
...@@ -110,6 +114,7 @@ class CLIApplicationBase(object): ...@@ -110,6 +114,7 @@ class CLIApplicationBase(object):
Handles input/output of the various subcommands. Handles input/output of the various subcommands.
""" """
def __init__(self): def __init__(self):
self.todolist = TodoList.TodoList([]) self.todolist = TodoList.TodoList([])
self.todofile = None self.todofile = None
...@@ -173,7 +178,7 @@ class CLIApplicationBase(object): ...@@ -173,7 +178,7 @@ class CLIApplicationBase(object):
archive_file.write(archive.print_todos()) archive_file.write(archive.print_todos())
def _help(self, args): def _help(self, args):
if args == None: if args is None:
pass # TODO pass # TODO
else: else:
pass # TODO pass # TODO
...@@ -221,4 +226,3 @@ class CLIApplicationBase(object): ...@@ -221,4 +226,3 @@ class CLIApplicationBase(object):
def run(self): def run(self):
raise NotImplementedError raise NotImplementedError
...@@ -39,6 +39,7 @@ from topydo.Commands import get_subcommand ...@@ -39,6 +39,7 @@ from topydo.Commands import get_subcommand
from topydo.lib import TodoFile from topydo.lib import TodoFile
from topydo.lib import TodoList from topydo.lib import TodoList
def _todotxt_mtime(): def _todotxt_mtime():
""" """
Returns the mtime for the configured todo.txt file. Returns the mtime for the configured todo.txt file.
...@@ -49,11 +50,13 @@ def _todotxt_mtime(): ...@@ -49,11 +50,13 @@ def _todotxt_mtime():
# file not found # file not found
return None return None
class PromptApplication(CLIApplicationBase): class PromptApplication(CLIApplicationBase):
""" """
This class implements a variant of topydo's CLI showing a shell and This class implements a variant of topydo's CLI showing a shell and
offering auto-completion thanks to the prompt toolkit. offering auto-completion thanks to the prompt toolkit.
""" """
def __init__(self): def __init__(self):
super(PromptApplication, self).__init__() super(PromptApplication, self).__init__()
...@@ -69,7 +72,6 @@ class PromptApplication(CLIApplicationBase): ...@@ -69,7 +72,6 @@ class PromptApplication(CLIApplicationBase):
If the modification time of the todo.txt file is equal to the last time If the modification time of the todo.txt file is equal to the last time
it was checked, nothing will be done. it was checked, nothing will be done.
""" """
current_mtime = _todotxt_mtime() current_mtime = _todotxt_mtime()
if not self.todofile or self.mtime != current_mtime: if not self.todofile or self.mtime != current_mtime:
...@@ -112,10 +114,10 @@ class PromptApplication(CLIApplicationBase): ...@@ -112,10 +114,10 @@ class PromptApplication(CLIApplicationBase):
except TypeError: except TypeError:
usage() usage()
def main(): def main():
""" Main entry point of the prompt interface. """ """ Main entry point of the prompt interface. """
PromptApplication().run() PromptApplication().run()
if __name__ == '__main__': if __name__ == '__main__':
main() main()
...@@ -23,11 +23,11 @@ import datetime ...@@ -23,11 +23,11 @@ import datetime
import re import re
from prompt_toolkit.completion import Completer, Completion from prompt_toolkit.completion import Completer, Completion
from topydo.lib.Config import config
from topydo.Commands import _SUBCOMMAND_MAP from topydo.Commands import _SUBCOMMAND_MAP
from topydo.lib.Config import config
from topydo.lib.RelativeDate import relative_date_to_date from topydo.lib.RelativeDate import relative_date_to_date
def _subcommands(p_word_before_cursor): def _subcommands(p_word_before_cursor):
""" Generator for subcommand name completion. """ """ Generator for subcommand name completion. """
subcommands = [sc for sc in sorted(_SUBCOMMAND_MAP.keys()) if subcommands = [sc for sc in sorted(_SUBCOMMAND_MAP.keys()) if
...@@ -35,6 +35,7 @@ def _subcommands(p_word_before_cursor): ...@@ -35,6 +35,7 @@ def _subcommands(p_word_before_cursor):
for command in subcommands: for command in subcommands:
yield Completion(command, -len(p_word_before_cursor)) yield Completion(command, -len(p_word_before_cursor))
def _dates(p_word_before_cursor): def _dates(p_word_before_cursor):
""" Generator for date completion. """ """ Generator for date completion. """
def _date_suggestions(): def _date_suggestions():
...@@ -79,11 +80,13 @@ def _dates(p_word_before_cursor): ...@@ -79,11 +80,13 @@ def _dates(p_word_before_cursor):
yield Completion(reldate, -len(value), display_meta=to_absolute(reldate)) yield Completion(reldate, -len(value), display_meta=to_absolute(reldate))
class TopydoCompleter(Completer): class TopydoCompleter(Completer):
""" """
Completer class that completes projects, contexts, dates and Completer class that completes projects, contexts, dates and
subcommands. subcommands.
""" """
def __init__(self, p_todolist): def __init__(self, p_todolist):
self.todolist = p_todolist self.todolist = p_todolist
...@@ -106,7 +109,8 @@ class TopydoCompleter(Completer): ...@@ -106,7 +109,8 @@ class TopydoCompleter(Completer):
def get_completions(self, p_document, _): def get_completions(self, p_document, _):
# include all characters except whitespaces (for + and @) # include all characters except whitespaces (for + and @)
word_before_cursor = p_document.get_word_before_cursor(True) word_before_cursor = p_document.get_word_before_cursor(True)
is_first_word = not re.match(r'\s*\S+\s', p_document.current_line_before_cursor) is_first_word = not re.match(r'\s*\S+\s',
p_document.current_line_before_cursor)
if is_first_word: if is_first_word:
return _subcommands(word_before_cursor) return _subcommands(word_before_cursor)
......
...@@ -16,15 +16,18 @@ ...@@ -16,15 +16,18 @@
""" Entry file for the Python todo.txt CLI. """ """ Entry file for the Python todo.txt CLI. """
import sys
import getopt import getopt
from topydo.cli.CLIApplicationBase import MAIN_OPTS, error import sys
from topydo.cli.CLI import CLIApplication from topydo.cli.CLI import CLIApplication
from topydo.cli.CLIApplicationBase import MAIN_OPTS, error
# enable color on windows CMD # enable color on windows CMD
if "win32" in sys.platform: if "win32" in sys.platform:
import colorama import colorama
colorama.init() colorama.init()
def main(): def main():
""" Main entry point of the CLI. """ """ Main entry point of the CLI. """
try: try:
......
...@@ -16,18 +16,19 @@ ...@@ -16,18 +16,19 @@
""" Provides the AddCommand class that implements the 'add' subcommand. """ """ Provides the AddCommand class that implements the 'add' subcommand. """
from datetime import date
import re
from sys import stdin
import codecs import codecs
import re
from datetime import date
from os.path import expanduser from os.path import expanduser
from sys import stdin
from topydo.lib.Config import config
from topydo.lib.Command import Command from topydo.lib.Command import Command
from topydo.lib.Config import config
from topydo.lib.PrettyPrinterFilter import PrettyPrinterNumbers from topydo.lib.PrettyPrinterFilter import PrettyPrinterNumbers
from topydo.lib.RelativeDate import relative_date_to_date from topydo.lib.RelativeDate import relative_date_to_date
from topydo.lib.TodoListBase import InvalidTodoException from topydo.lib.TodoListBase import InvalidTodoException
class AddCommand(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,
...@@ -60,11 +61,12 @@ class AddCommand(Command): ...@@ -60,11 +61,12 @@ class AddCommand(Command):
def _add_todo(self, p_todo_text): def _add_todo(self, p_todo_text):
def _preprocess_input_todo(p_todo_text): def _preprocess_input_todo(p_todo_text):
""" """
Preprocesses user input when adding a task. Pre-processes user input when adding a task.
It detects a priority mid-sentence and puts it at the start. It detects a priority mid-sentence and puts it at the start.
""" """
todo_text = re.sub(r'^(.+) (\([A-Z]\))(.*)$', r'\2 \1\3', p_todo_text) todo_text = re.sub(r'^(.+) (\([A-Z]\))(.*)$', r'\2 \1\3',
p_todo_text)
return todo_text return todo_text
......
...@@ -18,6 +18,7 @@ from topydo.lib.Command import Command, InvalidCommandArgument ...@@ -18,6 +18,7 @@ from topydo.lib.Command import Command, InvalidCommandArgument
from topydo.lib.PrettyPrinterFilter import PrettyPrinterNumbers from topydo.lib.PrettyPrinterFilter import PrettyPrinterNumbers
from topydo.lib.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,
......
# 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 - 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
from topydo.lib.Command import Command from topydo.lib.Command import Command
class ArchiveCommand(Command): class ArchiveCommand(Command):
def __init__(self, p_todolist, p_archive_list): def __init__(self, p_todolist, p_archive_list):
""" """
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
from topydo.lib.DCommand import DCommand from topydo.lib.DCommand import DCommand
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,
......
# 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 - 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
...@@ -14,14 +14,15 @@ ...@@ -14,14 +14,15 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from topydo.lib import Filter
from topydo.lib.Command import Command, InvalidCommandArgument from topydo.lib.Command import Command, InvalidCommandArgument
from topydo.lib.Config import config from topydo.lib.Config import config
from topydo.lib import Filter
from topydo.lib.PrettyPrinter import pretty_printer_factory from topydo.lib.PrettyPrinter import pretty_printer_factory
from topydo.lib.Sorter import Sorter from topydo.lib.Sorter import Sorter
from topydo.lib.TodoListBase import InvalidTodoException from topydo.lib.TodoListBase import InvalidTodoException
from topydo.lib.View 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,
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
from topydo.lib.MultiCommand import MultiCommand from topydo.lib.MultiCommand import MultiCommand
from topydo.lib.PrettyPrinterFilter import PrettyPrinterNumbers from topydo.lib.PrettyPrinterFilter import PrettyPrinterNumbers
class DepriCommand(MultiCommand): class DepriCommand(MultiCommand):
def __init__(self, p_args, p_todolist, def __init__(self, p_args, p_todolist,
p_out=lambda a: None, p_out=lambda a: None,
......
...@@ -19,9 +19,10 @@ from datetime import date ...@@ -19,9 +19,10 @@ from datetime import date
from topydo.lib.DCommand import DCommand from topydo.lib.DCommand import DCommand
from topydo.lib.PrettyPrinter import PrettyPrinter from topydo.lib.PrettyPrinter import PrettyPrinter
from topydo.lib.PrettyPrinterFilter import PrettyPrinterNumbers from topydo.lib.PrettyPrinterFilter import PrettyPrinterNumbers
from topydo.lib.Recurrence import advance_recurring_todo, NoRecurrenceException from topydo.lib.Recurrence import NoRecurrenceException, advance_recurring_todo
from topydo.lib.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,
p_out=lambda a: None, p_out=lambda a: None,
......
# 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 - 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
...@@ -15,17 +15,16 @@ ...@@ -15,17 +15,16 @@
# 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 os import os
from subprocess import call, check_call, CalledProcessError
import tempfile import tempfile
from subprocess import CalledProcessError, check_call
from six import u from six import u
from topydo.lib.ExpressionCommand import ExpressionCommand
from topydo.lib.MultiCommand import MultiCommand
from topydo.lib.Config import config from topydo.lib.Config import config
from topydo.lib.MultiCommand import MultiCommand
from topydo.lib.PrettyPrinterFilter import PrettyPrinterNumbers
from topydo.lib.Todo import Todo from topydo.lib.Todo import Todo
from topydo.lib.TodoList import TodoList from topydo.lib.TodoList import TodoList
from topydo.lib.PrettyPrinterFilter import PrettyPrinterNumbers
# the true and only editor # the true and only editor
DEFAULT_EDITOR = 'vi' DEFAULT_EDITOR = 'vi'
...@@ -34,6 +33,7 @@ DEFAULT_EDITOR = 'vi' ...@@ -34,6 +33,7 @@ DEFAULT_EDITOR = 'vi'
# cannot use super() inside the class itself # cannot use super() inside the class itself
BASE_TODOLIST = lambda tl: super(TodoList, tl) BASE_TODOLIST = lambda tl: super(TodoList, tl)
class EditCommand(MultiCommand): class EditCommand(MultiCommand):
def __init__(self, p_args, p_todolist, p_output, p_error, p_input): def __init__(self, p_args, p_todolist, p_output, p_error, p_input):
super(EditCommand, self).__init__(p_args, p_todolist, p_output, super(EditCommand, self).__init__(p_args, p_todolist, p_output,
......
...@@ -18,11 +18,13 @@ import sys ...@@ -18,11 +18,13 @@ import sys
from topydo.lib.Command import Command from topydo.lib.Command import Command
class ExitCommand(Command): class ExitCommand(Command):
""" """
A command that exits topydo. Used for the 'exit' and 'quit' subcommands on A command that exits topydo. Used for the 'exit' and 'quit' subcommands on
the prompt CLI. the prompt CLI.
""" """
def __init__(self, p_args, p_todolist, p_output, p_error, p_input): def __init__(self, p_args, p_todolist, p_output, p_error, p_input):
super(ExitCommand, self).__init__(p_args, p_todolist, p_output, p_error, super(ExitCommand, self).__init__(p_args, p_todolist, p_output, p_error,
p_input) p_input)
...@@ -32,4 +34,3 @@ class ExitCommand(Command): ...@@ -32,4 +34,3 @@ class ExitCommand(Command):
return False return False
sys.exit(0) sys.exit(0)
...@@ -14,15 +14,14 @@ ...@@ -14,15 +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 topydo.lib.ExpressionCommand import ExpressionCommand
from topydo.lib.Config import config from topydo.lib.Config import config
from topydo.lib.PrettyPrinter import pretty_printer_factory from topydo.lib.ExpressionCommand import ExpressionCommand
from topydo.lib.PrettyPrinterFilter import (
PrettyPrinterIndentFilter,
PrettyPrinterHideTagFilter
)
from topydo.lib.IcalPrinter import IcalPrinter from topydo.lib.IcalPrinter import IcalPrinter
from topydo.lib.JsonPrinter import JsonPrinter from topydo.lib.JsonPrinter import JsonPrinter
from topydo.lib.PrettyPrinter import pretty_printer_factory
from topydo.lib.PrettyPrinterFilter import (PrettyPrinterHideTagFilter,
PrettyPrinterIndentFilter)
class ListCommand(ExpressionCommand): class ListCommand(ExpressionCommand):
def __init__(self, p_args, p_todolist, def __init__(self, p_args, p_todolist,
...@@ -76,8 +75,7 @@ class ListCommand(ExpressionCommand): ...@@ -76,8 +75,7 @@ class ListCommand(ExpressionCommand):
printing). If a format was specified on the commandline, this format is printing). If a format was specified on the commandline, this format is
sent to the output. sent to the output.
""" """
if self.printer is None:
if self.printer == None:
# create a standard printer with some filters # create a standard printer with some filters
indent = config().list_indent() indent = config().list_indent()
hidden_tags = config().hidden_tags() hidden_tags = config().hidden_tags()
...@@ -119,7 +117,7 @@ When an expression is given, only the todos matching that expression are shown. ...@@ -119,7 +117,7 @@ When an expression is given, only the todos matching that expression are shown.
-f : Specify the output format, being 'text' (default), 'ical' or 'json'. -f : Specify the output format, being 'text' (default), 'ical' or 'json'.
* 'text' - Text output with colors and identation if applicable. * 'text' - Text output with colors and indentation if applicable.
* 'ical' - iCalendar (RFC 2445). Is not supported in Python 3.2. Be aware * 'ical' - iCalendar (RFC 2445). Is not supported in Python 3.2. Be aware
that this is not a read-only operation, todo items may obtain that this is not a read-only operation, todo items may obtain
an 'ical' tag with a unique ID. Completed todo items may be an 'ical' tag with a unique ID. Completed todo items may be
......
# 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 - 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
from topydo.lib.Command import Command from topydo.lib.Command import Command
class ListContextCommand(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,
......
# 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 - 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
from topydo.lib.Command import Command from topydo.lib.Command import Command
class ListProjectCommand(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,
......
...@@ -16,12 +16,13 @@ ...@@ -16,12 +16,13 @@
from datetime import date, timedelta from datetime import date, timedelta
from topydo.lib.MultiCommand import MultiCommand
from topydo.lib.Config import config from topydo.lib.Config import config
from topydo.lib.MultiCommand import MultiCommand
from topydo.lib.PrettyPrinterFilter import PrettyPrinterNumbers from topydo.lib.PrettyPrinterFilter import PrettyPrinterNumbers
from topydo.lib.RelativeDate import relative_date_to_date from topydo.lib.RelativeDate import relative_date_to_date
from topydo.lib.Utils import date_string_to_date from topydo.lib.Utils import date_string_to_date
class PostponeCommand(MultiCommand): class PostponeCommand(MultiCommand):
def __init__(self, p_args, p_todolist, def __init__(self, p_args, p_todolist,
p_out=lambda a: None, p_out=lambda a: None,
...@@ -84,8 +85,8 @@ Synopsis: postpone [-s] <NUMBER> [<NUMBER2> ...] <PATTERN>" ...@@ -84,8 +85,8 @@ Synopsis: postpone [-s] <NUMBER> [<NUMBER2> ...] <PATTERN>"
return """\ return """\
Postpone the todo item(s) with the given number(s) and the given pattern. Postpone the todo item(s) with the given number(s) and the given pattern.
Postponing is done by adjusting the due date(s) of the todo(s), and if the -s flag is Postponing is done by adjusting the due date(s) of the todo(s), and if the -s
given, the start date accordingly. flag is given, the start date accordingly.
It is also possible to postpone items as complete with an expression using It is also possible to postpone items as complete with an expression using
the -e flag. Use -x to also process todo items that are normally invisible the -e flag. Use -x to also process todo items that are normally invisible
......
...@@ -20,6 +20,7 @@ from topydo.lib.MultiCommand import MultiCommand ...@@ -20,6 +20,7 @@ from topydo.lib.MultiCommand import MultiCommand
from topydo.lib.PrettyPrinterFilter import PrettyPrinterNumbers from topydo.lib.PrettyPrinterFilter import PrettyPrinterNumbers
from topydo.lib.Utils import is_valid_priority from topydo.lib.Utils import is_valid_priority
class PriorityCommand(MultiCommand): class PriorityCommand(MultiCommand):
def __init__(self, p_args, p_todolist, def __init__(self, p_args, p_todolist,
p_out=lambda a: None, p_out=lambda a: None,
......
# 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 - 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
...@@ -18,6 +18,7 @@ from topydo.lib.Command import Command, InvalidCommandArgument ...@@ -18,6 +18,7 @@ from topydo.lib.Command import Command, InvalidCommandArgument
from topydo.lib.Config import config from topydo.lib.Config import config
from topydo.lib.Sorter import Sorter from topydo.lib.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,
......
...@@ -18,6 +18,7 @@ from topydo.lib.Command import Command, InvalidCommandArgument ...@@ -18,6 +18,7 @@ from topydo.lib.Command import Command, InvalidCommandArgument
from topydo.lib.PrettyPrinterFilter import PrettyPrinterNumbers from topydo.lib.PrettyPrinterFilter import PrettyPrinterNumbers
from topydo.lib.TodoListBase import InvalidTodoException from topydo.lib.TodoListBase import InvalidTodoException
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,
...@@ -67,7 +68,7 @@ class TagCommand(Command): ...@@ -67,7 +68,7 @@ class TagCommand(Command):
def _choose(self): def _choose(self):
""" """
Returns the chosen number of the tag value to process (or "all") Returns the chosen number of the tag value to process (or "all").
""" """
answer = "all" answer = "all"
...@@ -103,7 +104,7 @@ class TagCommand(Command): ...@@ -103,7 +104,7 @@ class TagCommand(Command):
if answer == "all": if answer == "all":
for value in self.current_values: for value in self.current_values:
self._set_helper(value) self._set_helper(value)
elif answer != None and self.value != self.current_values[answer]: elif answer is not None and self.value != self.current_values[answer]:
self._set_helper(self.current_values[answer]) self._set_helper(self.current_values[answer])
else: else:
...@@ -130,6 +131,6 @@ is omitted, the tag is removed from the todo item. ...@@ -130,6 +131,6 @@ is omitted, the tag is removed from the todo item.
-a : Do not change the current value of the tag if it exists, but add a new -a : Do not change the current value of the tag if it exists, but add a new
value. value.
-f : Force setting/removing all values of the tag. Prevents interaction with the -f : Force setting/removing all values of the tag. Prevents interaction with
user. the user.
""" """
...@@ -20,6 +20,7 @@ from topydo.lib.Config import config ...@@ -20,6 +20,7 @@ from topydo.lib.Config import config
NEUTRAL_COLOR = '\033[0m' NEUTRAL_COLOR = '\033[0m'
class Colors(object): class Colors(object):
def __init__(self): def __init__(self):
self.priority_colors = config().priority_colors() self.priority_colors = config().priority_colors()
...@@ -48,13 +49,13 @@ class Colors(object): ...@@ -48,13 +49,13 @@ class Colors(object):
try: try:
if p_safe: if p_safe:
if 8 > int(p_int) >=0: if 8 > int(p_int) >= 0:
return '\033[{};3{}m'.format(decoration, str(p_int)) return '\033[{};3{}m'.format(decoration, str(p_int))
elif 16 > int(p_int): elif 16 > int(p_int):
p_int = int(p_int) - 8 p_int = int(p_int) - 8
return '\033[{};1;3{}m'.format(decoration, str(p_int)) return '\033[{};1;3{}m'.format(decoration, str(p_int))
if 256 > int(p_int) >=0: if 256 > int(p_int) >= 0:
return '\033[{};38;5;{}m'.format(decoration, str(p_int)) return '\033[{};38;5;{}m'.format(decoration, str(p_int))
else: else:
return NEUTRAL_COLOR return NEUTRAL_COLOR
......
...@@ -18,9 +18,11 @@ import getopt ...@@ -18,9 +18,11 @@ import getopt
from topydo.lib.PrettyPrinter import PrettyPrinter from topydo.lib.PrettyPrinter import PrettyPrinter
class InvalidCommandArgument(Exception): class InvalidCommandArgument(Exception):
pass pass
class Command(object): class Command(object):
def __init__(self, p_args, p_todolist, def __init__(self, p_args, p_todolist,
p_out=lambda a: None, p_out=lambda a: None,
...@@ -90,4 +92,3 @@ class Command(object): ...@@ -90,4 +92,3 @@ class Command(object):
def help(self): def help(self):
""" Returns the help text for this command. """ """ Returns the help text for this command. """
raise NotImplementedError raise NotImplementedError
...@@ -18,6 +18,7 @@ import os ...@@ -18,6 +18,7 @@ import os
from six.moves import configparser from six.moves import configparser
class ConfigError(Exception): class ConfigError(Exception):
def __init__(self, p_text): def __init__(self, p_text):
self.text = p_text self.text = p_text
...@@ -25,6 +26,7 @@ class ConfigError(Exception): ...@@ -25,6 +26,7 @@ class ConfigError(Exception):
def __str__(self): def __str__(self):
return self.text return self.text
class _Config: class _Config:
def __init__(self, p_path=None, p_overrides=None): def __init__(self, p_path=None, p_overrides=None):
""" """
...@@ -52,8 +54,8 @@ class _Config: ...@@ -52,8 +54,8 @@ class _Config:
# topydo # topydo
'default_command': 'ls', 'default_command': 'ls',
'colors': '1', 'colors': '1',
'filename' : 'todo.txt', 'filename': 'todo.txt',
'archive_filename' : 'done.txt', 'archive_filename': 'done.txt',
'identifiers': 'linenumber', 'identifiers': 'linenumber',
# add # add
...@@ -100,7 +102,7 @@ class _Config: ...@@ -100,7 +102,7 @@ class _Config:
# when a path is given, *only* use the values in that file, or the # when a path is given, *only* use the values in that file, or the
# defaults listed above. # defaults listed above.
if p_path != None: if p_path is not None:
files = [p_path] files = [p_path]
self.cp.read(files) self.cp.read(files)
...@@ -201,7 +203,9 @@ class _Config: ...@@ -201,7 +203,9 @@ class _Config:
hidden_tags.split(',')] hidden_tags.split(',')]
def priority_colors(self): def priority_colors(self):
""" Returns a dict with priorities as keys and color numbers as value. """ """
Returns a dict with priorities as keys and color numbers as value.
"""
pri_colors_str = self.cp.get('colorscheme', 'priority_colors') pri_colors_str = self.cp.get('colorscheme', 'priority_colors')
def _str_to_dict(p_string): def _str_to_dict(p_string):
...@@ -214,7 +218,7 @@ class _Config: ...@@ -214,7 +218,7 @@ class _Config:
try: try:
if pri_colors_str == '': if pri_colors_str == '':
pri_colors_dict = {'A':'', 'B': '', 'C': ''} pri_colors_dict = {'A': '', 'B': '', 'C': ''}
else: else:
pri_colors_dict = _str_to_dict(pri_colors_str) pri_colors_dict = _str_to_dict(pri_colors_str)
except ValueError: except ValueError:
...@@ -252,6 +256,7 @@ class _Config: ...@@ -252,6 +256,7 @@ class _Config:
except ValueError: except ValueError:
return self.defaults['auto_creation_date'] == '1' return self.defaults['auto_creation_date'] == '1'
def config(p_path=None, p_overrides=None): def config(p_path=None, p_overrides=None):
""" """
Retrieve the config instance. Retrieve the config instance.
...@@ -264,7 +269,7 @@ def config(p_path=None, p_overrides=None): ...@@ -264,7 +269,7 @@ def config(p_path=None, p_overrides=None):
passed value instead. Structure: (section, option) => value passed value instead. Structure: (section, option) => value
The previous configuration instance will be discarded. The previous configuration instance will be discarded.
""" """
if not config.instance or p_path != None or p_overrides != None: if not config.instance or p_path is not None or p_overrides is not None:
try: try:
config.instance = _Config(p_path, p_overrides) config.instance = _Config(p_path, p_overrides)
except configparser.ParsingError as perr: except configparser.ParsingError as perr:
......
...@@ -20,6 +20,7 @@ from topydo.lib.MultiCommand import MultiCommand ...@@ -20,6 +20,7 @@ from topydo.lib.MultiCommand import MultiCommand
from topydo.lib.PrettyPrinter import PrettyPrinter from topydo.lib.PrettyPrinter import PrettyPrinter
from topydo.lib.PrettyPrinterFilter import PrettyPrinterNumbers from topydo.lib.PrettyPrinterFilter import PrettyPrinterNumbers
class DCommand(MultiCommand): class DCommand(MultiCommand):
""" """
A common class for the 'do' and 'del' operations, because they're quite A common class for the 'do' and 'del' operations, because they're quite
...@@ -35,7 +36,8 @@ class DCommand(MultiCommand): ...@@ -35,7 +36,8 @@ class DCommand(MultiCommand):
self.force = False self.force = False
self.length = len(self.todolist.todos()) # to determine newly activated todos # to determine newly activated todos
self.length = len(self.todolist.todos())
def get_flags(self): def get_flags(self):
return ("f", ["force"]) return ("f", ["force"])
......
...@@ -16,16 +16,18 @@ ...@@ -16,16 +16,18 @@
import re import re
from topydo.lib import Filter
from topydo.lib.Command import Command from topydo.lib.Command import Command
from topydo.lib.Config import config from topydo.lib.Config import config
from topydo.lib import Filter
from topydo.lib.Sorter import Sorter from topydo.lib.Sorter import Sorter
from topydo.lib.View import View from topydo.lib.View import View
class ExpressionCommand(Command): class ExpressionCommand(Command):
""" """
A common class for commands operating on todos selected by expressions. A common class for commands operating on todos selected by expressions.
""" """
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,
......
# 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 - 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
...@@ -19,18 +19,19 @@ import re ...@@ -19,18 +19,19 @@ import re
from topydo.lib.RelativeDate import relative_date_to_date from topydo.lib.RelativeDate import relative_date_to_date
from topydo.lib.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):
""" """
Filters a list of todos. Truncates the list after p_limit todo Filters a list of todos. Truncates the list after p_limit todo
items (or no maximum limit if omitted). items (or no maximum limit if omitted).
""" """
return [t for t in p_todos if self.match(t)] return [t for t in p_todos if self.match(t)]
def match(self, _): def match(self, _):
raise NotImplementedError raise NotImplementedError
class NegationFilter(Filter): class NegationFilter(Filter):
def __init__(self, p_filter): def __init__(self, p_filter):
self._filter = p_filter self._filter = p_filter
...@@ -38,6 +39,7 @@ class NegationFilter(Filter): ...@@ -38,6 +39,7 @@ class NegationFilter(Filter):
def match(self, p_todo): def match(self, p_todo):
return not self._filter.match(p_todo) return not self._filter.match(p_todo)
class AndFilter(Filter): class AndFilter(Filter):
def __init__(self, p_filter1, p_filter2): def __init__(self, p_filter1, p_filter2):
self._filter1 = p_filter1 self._filter1 = p_filter1
...@@ -46,6 +48,7 @@ class AndFilter(Filter): ...@@ -46,6 +48,7 @@ class AndFilter(Filter):
def match(self, p_todo): def match(self, p_todo):
return self._filter1.match(p_todo) and self._filter2.match(p_todo) return self._filter1.match(p_todo) and self._filter2.match(p_todo)
class OrFilter(Filter): class OrFilter(Filter):
def __init__(self, p_filter1, p_filter2): def __init__(self, p_filter1, p_filter2):
self._filter1 = p_filter1 self._filter1 = p_filter1
...@@ -54,6 +57,7 @@ class OrFilter(Filter): ...@@ -54,6 +57,7 @@ class OrFilter(Filter):
def match(self, p_todo): def match(self, p_todo):
return self._filter1.match(p_todo) or self._filter2.match(p_todo) return self._filter1.match(p_todo) or self._filter2.match(p_todo)
class GrepFilter(Filter): class GrepFilter(Filter):
""" Matches when the todo text contains a text. """ """ Matches when the todo text contains a text. """
...@@ -63,7 +67,7 @@ class GrepFilter(Filter): ...@@ -63,7 +67,7 @@ class GrepFilter(Filter):
# convert to string in case we receive integers # convert to string in case we receive integers
self.expression = p_expression self.expression = p_expression
if p_case_sensitive != None: if p_case_sensitive is not None:
self.case_sensitive = p_case_sensitive self.case_sensitive = p_case_sensitive
else: else:
# only be case sensitive when the expression contains at least one # only be case sensitive when the expression contains at least one
...@@ -80,6 +84,7 @@ class GrepFilter(Filter): ...@@ -80,6 +84,7 @@ class GrepFilter(Filter):
return string.find(expr) != -1 return string.find(expr) != -1
class RelevanceFilter(Filter): class RelevanceFilter(Filter):
""" """
Matches when the todo is relevant, i.e.: Matches when the todo is relevant, i.e.:
...@@ -99,8 +104,10 @@ class RelevanceFilter(Filter): ...@@ -99,8 +104,10 @@ class RelevanceFilter(Filter):
return p_todo.is_active() and is_due return p_todo.is_active() and is_due
class DependencyFilter(Filter): class DependencyFilter(Filter):
""" Matches when a todo has no unfinished child tasks. """ """ Matches when a todo has no unfinished child tasks. """
def __init__(self, p_todolist): def __init__(self, p_todolist):
""" """
Constructor. Constructor.
...@@ -120,6 +127,7 @@ class DependencyFilter(Filter): ...@@ -120,6 +127,7 @@ class DependencyFilter(Filter):
return not uncompleted return not uncompleted
class InstanceFilter(Filter): class InstanceFilter(Filter):
def __init__(self, p_todos): def __init__(self, p_todos):
""" """
...@@ -143,6 +151,7 @@ class InstanceFilter(Filter): ...@@ -143,6 +151,7 @@ class InstanceFilter(Filter):
except ValueError: except ValueError:
return False return False
class LimitFilter(Filter): class LimitFilter(Filter):
def __init__(self, p_limit): def __init__(self, p_limit):
super(LimitFilter, self).__init__() super(LimitFilter, self).__init__()
...@@ -153,10 +162,10 @@ class LimitFilter(Filter): ...@@ -153,10 +162,10 @@ class LimitFilter(Filter):
OPERATOR_MATCH = r"(?P<operator><=?|=|>=?|!)?" OPERATOR_MATCH = r"(?P<operator><=?|=|>=?|!)?"
class OrdinalFilter(Filter): class OrdinalFilter(Filter):
""" """ Base class for ordinal filters. """
Base class for ordinal filters.
"""
def __init__(self, p_expression, p_pattern): def __init__(self, p_expression, p_pattern):
super(OrdinalFilter, self).__init__() super(OrdinalFilter, self).__init__()
...@@ -193,6 +202,7 @@ class OrdinalFilter(Filter): ...@@ -193,6 +202,7 @@ class OrdinalFilter(Filter):
ORDINAL_TAG_MATCH = r"(?P<key>[^:]*):" + OPERATOR_MATCH + r"(?P<value>\S+)" ORDINAL_TAG_MATCH = r"(?P<key>[^:]*):" + OPERATOR_MATCH + r"(?P<value>\S+)"
class OrdinalTagFilter(OrdinalFilter): class OrdinalTagFilter(OrdinalFilter):
def __init__(self, p_expression): def __init__(self, p_expression):
super(OrdinalTagFilter, self).__init__(p_expression, ORDINAL_TAG_MATCH) super(OrdinalTagFilter, self).__init__(p_expression, ORDINAL_TAG_MATCH)
...@@ -235,6 +245,7 @@ class OrdinalTagFilter(OrdinalFilter): ...@@ -235,6 +245,7 @@ class OrdinalTagFilter(OrdinalFilter):
PRIORITY_MATCH = r"\(" + OPERATOR_MATCH + r"(?P<value>[A-Z]{1})\)" PRIORITY_MATCH = r"\(" + OPERATOR_MATCH + r"(?P<value>[A-Z]{1})\)"
class PriorityFilter(OrdinalFilter): class PriorityFilter(OrdinalFilter):
def __init__(self, p_expression): def __init__(self, p_expression):
super(PriorityFilter, self).__init__(p_expression, PRIORITY_MATCH) super(PriorityFilter, self).__init__(p_expression, PRIORITY_MATCH)
......
# 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 - 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
...@@ -16,11 +16,13 @@ ...@@ -16,11 +16,13 @@
""" Contains the class for a directed graph. """ """ Contains the class for a directed graph. """
class DirectedGraph(object): class DirectedGraph(object):
""" """
Represents a simple directed graph, used for tracking todo Represents a simple directed graph, used for tracking todo
dependencies. The nodes are very simple: just integers. dependencies. The nodes are very simple: just integers.
""" """
def __init__(self): def __init__(self):
self._edges = {} self._edges = {}
self._edge_numbers = {} self._edge_numbers = {}
...@@ -36,8 +38,7 @@ class DirectedGraph(object): ...@@ -36,8 +38,7 @@ class DirectedGraph(object):
def add_edge(self, p_from, p_to, p_id=None): def add_edge(self, p_from, p_to, p_id=None):
""" """
Adds an edge to the graph. The nodes will be added if they don't Adds an edge to the graph. The nodes will be added if they don't exist.
exist.
The p_id is the id of the edge, if the client wishes to maintain this. The p_id is the id of the edge, if the client wishes to maintain this.
""" """
...@@ -59,15 +60,13 @@ class DirectedGraph(object): ...@@ -59,15 +60,13 @@ class DirectedGraph(object):
def incoming_neighbors(self, p_id, p_recursive=False): def incoming_neighbors(self, p_id, p_recursive=False):
""" """
Returns a set of the direct neighbors that can reach the given Returns a set of the direct neighbors that can reach the given node.
node.
""" """
return self.reachable_nodes_reverse(p_id, p_recursive) return self.reachable_nodes_reverse(p_id, p_recursive)
def outgoing_neighbors(self, p_id, p_recursive=False): def outgoing_neighbors(self, p_id, p_recursive=False):
""" """
Returns the set of the direct neighbors that the given node can Returns the set of the direct neighbors that the given node can reach.
reach.
""" """
return self.reachable_nodes(p_id, p_recursive) return self.reachable_nodes(p_id, p_recursive)
...@@ -92,7 +91,7 @@ class DirectedGraph(object): ...@@ -92,7 +91,7 @@ class DirectedGraph(object):
visited.add(current) visited.add(current)
if p_reverse: if p_reverse:
parents = [node for node, neighbors in self._edges.items() \ parents = [node for node, neighbors in self._edges.items()
if current in neighbors] if current in neighbors]
stack = stack + parents stack = stack + parents
...@@ -130,8 +129,8 @@ class DirectedGraph(object): ...@@ -130,8 +129,8 @@ class DirectedGraph(object):
""" """
Returns True iff the given node has no incoming or outgoing edges. Returns True iff the given node has no incoming or outgoing edges.
""" """
return len(self.incoming_neighbors(p_id)) == 0 \ return(len(self.incoming_neighbors(p_id)) == 0
and len(self.outgoing_neighbors(p_id)) == 0 and len(self.outgoing_neighbors(p_id)) == 0)
def has_edge(self, p_from, p_to): def has_edge(self, p_from, p_to):
""" Returns True when the graph has the given edge. """ """ Returns True when the graph has the given edge. """
......
# 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 - 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
...@@ -27,6 +27,7 @@ _TABLE_SIZES = { ...@@ -27,6 +27,7 @@ _TABLE_SIZES = {
4: 1679609 # largest prime under zzzz_36 4: 1679609 # largest prime under zzzz_36
} }
def _to_base36(p_value): def _to_base36(p_value):
""" """
Converts integer to base36 string. Converts integer to base36 string.
...@@ -43,6 +44,7 @@ def _to_base36(p_value): ...@@ -43,6 +44,7 @@ def _to_base36(p_value):
return base36 or alphabet[0] return base36 or alphabet[0]
def hash_list_values(p_list, p_key=lambda i: i): def hash_list_values(p_list, p_key=lambda i: i):
""" """
Calculates a unique value for each item in the list, these can be used as Calculates a unique value for each item in the list, these can be used as
...@@ -79,4 +81,3 @@ def hash_list_values(p_list, p_key=lambda i: i): ...@@ -79,4 +81,3 @@ def hash_list_values(p_list, p_key=lambda i: i):
result.append((item, _to_base36(hash_value))) result.append((item, _to_base36(hash_value)))
return result return result
...@@ -19,12 +19,13 @@ Provides a printer that transforms a list of Todo items to an iCalendar ...@@ -19,12 +19,13 @@ Provides a printer that transforms a list of Todo items to an iCalendar
file according to RFC 2445. file according to RFC 2445.
""" """
from datetime import datetime, time
import random import random
import string import string
from datetime import datetime, time
from topydo.lib.PrettyPrinter import Printer from topydo.lib.PrettyPrinter import Printer
def _convert_priority(p_priority): def _convert_priority(p_priority):
""" """
Converts todo.txt priority to an iCalendar priority (RFC 2445). Converts todo.txt priority to an iCalendar priority (RFC 2445).
...@@ -55,6 +56,7 @@ def _convert_priority(p_priority): ...@@ -55,6 +56,7 @@ def _convert_priority(p_priority):
return result return result
class IcalPrinter(Printer): class IcalPrinter(Printer):
""" """
A printer that converts a list of Todo items to a string in iCalendar A printer that converts a list of Todo items to a string in iCalendar
...@@ -62,6 +64,7 @@ class IcalPrinter(Printer): ...@@ -62,6 +64,7 @@ class IcalPrinter(Printer):
https://www.rfc-editor.org/rfc/rfc2445.txt https://www.rfc-editor.org/rfc/rfc2445.txt
""" """
def __init__(self, p_todolist): def __init__(self, p_todolist):
super(IcalPrinter, self).__init__() super(IcalPrinter, self).__init__()
self.todolist = p_todolist self.todolist = p_todolist
...@@ -95,6 +98,7 @@ class IcalPrinter(Printer): ...@@ -95,6 +98,7 @@ class IcalPrinter(Printer):
Gets a unique ID from a todo item, stored by the ical tag. If the Gets a unique ID from a todo item, stored by the ical tag. If the
tag is not present, a random value is assigned to it and returned. tag is not present, a random value is assigned to it and returned.
""" """
def generate_uid(p_length=4): def generate_uid(p_length=4):
""" """
Generates a random string of the given length, used as Generates a random string of the given length, used as
......
# 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 - 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
...@@ -29,6 +29,7 @@ from topydo.lib.Config import config ...@@ -29,6 +29,7 @@ from topydo.lib.Config import config
IMPORTANCE_VALUE = {'A': 3, 'B': 2, 'C': 1} IMPORTANCE_VALUE = {'A': 3, 'B': 2, 'C': 1}
def is_due_next_monday(p_todo): def is_due_next_monday(p_todo):
""" Returns True when the given task is due next Monday. """ """ Returns True when the given task is due next Monday. """
today = date.today() today = date.today()
...@@ -37,6 +38,7 @@ def is_due_next_monday(p_todo): ...@@ -37,6 +38,7 @@ def is_due_next_monday(p_todo):
return due and due.weekday() == 0 and today.weekday() >= 4 and \ return due and due.weekday() == 0 and today.weekday() >= 4 and \
p_todo.days_till_due() p_todo.days_till_due()
def importance(p_todo, p_ignore_weekend=config().ignore_weekends()): def importance(p_todo, p_ignore_weekend=config().ignore_weekends()):
""" """
Calculates the importance of the given task. Calculates the importance of the given task.
...@@ -74,6 +76,7 @@ def importance(p_todo, p_ignore_weekend=config().ignore_weekends()): ...@@ -74,6 +76,7 @@ def importance(p_todo, p_ignore_weekend=config().ignore_weekends()):
return result if not p_todo.is_completed() else 0 return result if not p_todo.is_completed() else 0
def average_importance(p_todo, p_ignore_weekend=config().ignore_weekends()): def average_importance(p_todo, p_ignore_weekend=config().ignore_weekends()):
own_importance = importance(p_todo, p_ignore_weekend) own_importance = importance(p_todo, p_ignore_weekend)
......
...@@ -23,6 +23,7 @@ import json ...@@ -23,6 +23,7 @@ import json
from topydo.lib.PrettyPrinter import Printer from topydo.lib.PrettyPrinter import Printer
def _convert_todo(p_todo): def _convert_todo(p_todo):
""" Converts a Todo instance to a dictionary. """ """ Converts a Todo instance to a dictionary. """
creation_date = p_todo.creation_date() creation_date = p_todo.creation_date()
...@@ -44,10 +45,12 @@ def _convert_todo(p_todo): ...@@ -44,10 +45,12 @@ def _convert_todo(p_todo):
return result return result
class JsonPrinter(Printer): class JsonPrinter(Printer):
""" """
A printer that converts a list of Todo items to a string in JSON format. A printer that converts a list of Todo items to a string in JSON format.
""" """
def __init__(self): def __init__(self):
super(JsonPrinter, self).__init__() super(JsonPrinter, self).__init__()
......
...@@ -19,6 +19,7 @@ from six import u ...@@ -19,6 +19,7 @@ from six import u
from topydo.lib.ExpressionCommand import ExpressionCommand from topydo.lib.ExpressionCommand import ExpressionCommand
from topydo.lib.TodoListBase import InvalidTodoException from topydo.lib.TodoListBase import InvalidTodoException
class MultiCommand(ExpressionCommand): class MultiCommand(ExpressionCommand):
""" """
A common class for operations that can work with multiple todo IDs. A common class for operations that can work with multiple todo IDs.
...@@ -62,7 +63,7 @@ class MultiCommand(ExpressionCommand): ...@@ -62,7 +63,7 @@ class MultiCommand(ExpressionCommand):
self.todos = self._view().todos self.todos = self._view().todos
def get_todos(self): def get_todos(self):
""" Gets todo objects from supplied todo IDs """ """ Gets todo objects from supplied todo IDs. """
if self.is_expression: if self.is_expression:
self.get_todos_from_expr() self.get_todos_from_expr()
else: else:
...@@ -79,11 +80,11 @@ class MultiCommand(ExpressionCommand): ...@@ -79,11 +80,11 @@ class MultiCommand(ExpressionCommand):
def _catch_todo_errors(self): def _catch_todo_errors(self):
""" """
Returns None or list of error messages depending on number of valid todo Returns None or list of error messages depending on number of valid
objects and number of invalid todo IDs. todo objects and number of invalid todo IDs.
In case of multiple invalid todo IDs we generate separate error message for each In case of multiple invalid todo IDs we generate separate error message
one of them with information about supplied ID. for each one of them with information about supplied ID.
""" """
errors = [] errors = []
......
...@@ -14,10 +14,9 @@ ...@@ -14,10 +14,9 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from topydo.lib.PrettyPrinterFilter import ( from topydo.lib.PrettyPrinterFilter import (PrettyPrinterColorFilter,
PrettyPrinterColorFilter, PrettyPrinterNumbers)
PrettyPrinterNumbers
)
class Printer(object): class Printer(object):
""" """
...@@ -25,6 +24,7 @@ class Printer(object): ...@@ -25,6 +24,7 @@ class Printer(object):
Subclasses must at least implement the print_todo method. Subclasses must at least implement the print_todo method.
""" """
def print_todo(self, p_todo): def print_todo(self, p_todo):
raise NotImplementedError raise NotImplementedError
...@@ -35,6 +35,7 @@ class Printer(object): ...@@ -35,6 +35,7 @@ class Printer(object):
""" """
return "\n".join([self.print_todo(todo) for todo in p_todos]) return "\n".join([self.print_todo(todo) for todo in p_todos])
class PrettyPrinter(Printer): class PrettyPrinter(Printer):
""" """
Prints todo items on a single line, decorated by the filters passed by Prints todo items on a single line, decorated by the filters passed by
...@@ -44,6 +45,7 @@ class PrettyPrinter(Printer): ...@@ -44,6 +45,7 @@ class PrettyPrinter(Printer):
add colors, indentation, etc. These filters are found in the add colors, indentation, etc. These filters are found in the
PrettyPrinterFilter module. PrettyPrinterFilter module.
""" """
def __init__(self): def __init__(self):
""" """
Constructor. Constructor.
...@@ -68,9 +70,9 @@ class PrettyPrinter(Printer): ...@@ -68,9 +70,9 @@ class PrettyPrinter(Printer):
return todo_str return todo_str
def pretty_printer_factory(p_todolist, p_additional_filters=None): def pretty_printer_factory(p_todolist, p_additional_filters=None):
""" Returns a pretty printer suitable for the ls and dep subcommands. """ """ Returns a pretty printer suitable for the ls and dep subcommands. """
p_additional_filters = p_additional_filters or [] p_additional_filters = p_additional_filters or []
printer = PrettyPrinter() printer = PrettyPrinter()
......
...@@ -17,16 +17,18 @@ ...@@ -17,16 +17,18 @@
""" Provides filters used for pretty printing. """ """ Provides filters used for pretty printing. """
import re import re
from six import u from six import u
from topydo.lib.Colors import NEUTRAL_COLOR, Colors
from topydo.lib.Config import config from topydo.lib.Config import config
from topydo.lib.Colors import Colors, NEUTRAL_COLOR
class PrettyPrinterFilter(object): class PrettyPrinterFilter(object):
""" """
Base class for a pretty printer filter. Base class for a pretty printer filter.
Subclasses must reimplement the filter method. Subclasses must re-implement the filter method.
""" """
def filter(self, p_todo_str, _): def filter(self, p_todo_str, _):
...@@ -35,6 +37,7 @@ class PrettyPrinterFilter(object): ...@@ -35,6 +37,7 @@ class PrettyPrinterFilter(object):
""" """
raise NotImplementedError raise NotImplementedError
class PrettyPrinterColorFilter(PrettyPrinterFilter): class PrettyPrinterColorFilter(PrettyPrinterFilter):
""" """
Adds colors to the todo string by inserting ANSI codes. Adds colors to the todo string by inserting ANSI codes.
...@@ -44,7 +47,6 @@ class PrettyPrinterColorFilter(PrettyPrinterFilter): ...@@ -44,7 +47,6 @@ class PrettyPrinterColorFilter(PrettyPrinterFilter):
def filter(self, p_todo_str, p_todo): def filter(self, p_todo_str, p_todo):
""" Applies the colors. """ """ Applies the colors. """
colorscheme = Colors() colorscheme = Colors()
priority_colors = colorscheme.get_priority_colors() priority_colors = colorscheme.get_priority_colors()
project_color = colorscheme.get_project_color() project_color = colorscheme.get_project_color()
...@@ -84,8 +86,10 @@ class PrettyPrinterColorFilter(PrettyPrinterFilter): ...@@ -84,8 +86,10 @@ class PrettyPrinterColorFilter(PrettyPrinterFilter):
return p_todo_str return p_todo_str
class PrettyPrinterIndentFilter(PrettyPrinterFilter): class PrettyPrinterIndentFilter(PrettyPrinterFilter):
""" Adds indentation to the todo item. """ """ Adds indentation to the todo item. """
def __init__(self, p_indent=0): def __init__(self, p_indent=0):
super(PrettyPrinterIndentFilter, self).__init__() super(PrettyPrinterIndentFilter, self).__init__()
self.indent = p_indent self.indent = p_indent
...@@ -94,8 +98,10 @@ class PrettyPrinterIndentFilter(PrettyPrinterFilter): ...@@ -94,8 +98,10 @@ class PrettyPrinterIndentFilter(PrettyPrinterFilter):
""" Applies the indentation. """ """ Applies the indentation. """
return ' ' * self.indent + p_todo_str return ' ' * self.indent + p_todo_str
class PrettyPrinterNumbers(PrettyPrinterFilter): class PrettyPrinterNumbers(PrettyPrinterFilter):
""" Prepends the todo's number, retrieved from the todolist. """ """ Prepends the todo's number, retrieved from the todolist. """
def __init__(self, p_todolist): def __init__(self, p_todolist):
super(PrettyPrinterNumbers, self).__init__() super(PrettyPrinterNumbers, self).__init__()
self.todolist = p_todolist self.todolist = p_todolist
...@@ -104,8 +110,10 @@ class PrettyPrinterNumbers(PrettyPrinterFilter): ...@@ -104,8 +110,10 @@ class PrettyPrinterNumbers(PrettyPrinterFilter):
""" Prepends the number to the todo string. """ """ Prepends the number to the todo string. """
return u("|{:>3}| {}").format(self.todolist.number(p_todo), p_todo_str) return u("|{:>3}| {}").format(self.todolist.number(p_todo), p_todo_str)
class PrettyPrinterHideTagFilter(PrettyPrinterFilter): class PrettyPrinterHideTagFilter(PrettyPrinterFilter):
""" Removes all occurences of the given tags from the text. """ """ Removes all occurrences of the given tags from the text. """
def __init__(self, p_hidden_tags): def __init__(self, p_hidden_tags):
super(PrettyPrinterHideTagFilter, self).__init__() super(PrettyPrinterHideTagFilter, self).__init__()
self.hidden_tags = p_hidden_tags self.hidden_tags = p_hidden_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 - 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
...@@ -22,9 +22,11 @@ from topydo.lib.Config import config ...@@ -22,9 +22,11 @@ from topydo.lib.Config import config
from topydo.lib.RelativeDate import relative_date_to_date from topydo.lib.RelativeDate import relative_date_to_date
from topydo.lib.Todo import Todo from topydo.lib.Todo import Todo
class NoRecurrenceException(Exception): class NoRecurrenceException(Exception):
pass pass
def advance_recurring_todo(p_todo, p_offset=None, p_strict=False): def advance_recurring_todo(p_todo, p_offset=None, p_strict=False):
""" """
Given a Todo item, return a new instance of a Todo item with the dates Given a Todo item, return a new instance of a Todo item with the dates
......
# 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 - 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
...@@ -16,9 +16,10 @@ ...@@ -16,9 +16,10 @@
""" This module deals with relative dates (2d, 5y, Monday, today, etc.) """ """ This module deals with relative dates (2d, 5y, Monday, today, etc.) """
from datetime import date, timedelta
import calendar import calendar
import re import re
from datetime import date, timedelta
def _add_months(p_sourcedate, p_months): def _add_months(p_sourcedate, p_months):
""" """
...@@ -35,6 +36,7 @@ def _add_months(p_sourcedate, p_months): ...@@ -35,6 +36,7 @@ def _add_months(p_sourcedate, p_months):
return date(year, month, day) return date(year, month, day)
def _convert_pattern(p_length, p_periodunit, p_offset=None): def _convert_pattern(p_length, p_periodunit, p_offset=None):
""" """
Converts a pattern in the form [0-9][dwmy] and returns a date from the Converts a pattern in the form [0-9][dwmy] and returns a date from the
...@@ -56,6 +58,7 @@ def _convert_pattern(p_length, p_periodunit, p_offset=None): ...@@ -56,6 +58,7 @@ def _convert_pattern(p_length, p_periodunit, p_offset=None):
return result return result
def _convert_weekday_pattern(p_weekday): def _convert_weekday_pattern(p_weekday):
""" """
Converts a weekday name to an absolute date. Converts a weekday name to an absolute date.
...@@ -81,6 +84,7 @@ def _convert_weekday_pattern(p_weekday): ...@@ -81,6 +84,7 @@ def _convert_weekday_pattern(p_weekday):
shift = (target_day - day) % 7 shift = (target_day - day) % 7
return date.today() + timedelta(shift) return date.today() + timedelta(shift)
def relative_date_to_date(p_date, p_offset=None): def relative_date_to_date(p_date, p_offset=None):
""" """
Transforms a relative date into a date object. Transforms a relative date into a date object.
...@@ -91,7 +95,6 @@ def relative_date_to_date(p_date, p_offset=None): ...@@ -91,7 +95,6 @@ def relative_date_to_date(p_date, p_offset=None):
* 'today' or 'tomorrow' * 'today' or 'tomorrow'
* days of the week (in full or abbreviated) * days of the week (in full or abbreviated)
""" """
result = None result = None
p_date = p_date.lower() p_date = p_date.lower()
p_offset = p_offset or date.today() p_offset = p_offset or date.today()
......
# 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 - 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
...@@ -16,15 +16,17 @@ ...@@ -16,15 +16,17 @@
""" This module provides functionality to sort lists with todo items. """ """ This module provides functionality to sort lists with todo items. """
from datetime import date
import re import re
from datetime import date
from topydo.lib.Importance import average_importance, importance
from topydo.lib.Importance import importance, average_importance
def is_priority_field(p_field): def is_priority_field(p_field):
""" Returns True when the field name denotes the priority. """ """ Returns True when the field name denotes the priority. """
return p_field.startswith('prio') return p_field.startswith('prio')
def get_field_function(p_field): def get_field_function(p_field):
""" """
Given a property (string) of a todo, return a function that attempts to Given a property (string) of a todo, return a function that attempts to
...@@ -39,10 +41,10 @@ def get_field_function(p_field): ...@@ -39,10 +41,10 @@ def get_field_function(p_field):
elif p_field == 'creationdate' or p_field == 'creation': elif p_field == 'creationdate' or p_field == 'creation':
# when a task has no creation date, push it to the end by assigning it # when a task has no creation date, push it to the end by assigning it
# the maximum possible date. # the maximum possible date.
result = (lambda a: a.creation_date() if a.creation_date() \ result = (lambda a: a.creation_date() if a.creation_date()
else date.max) else date.max)
elif p_field == 'done' or p_field == 'completed' or p_field == 'completion': elif p_field == 'done' or p_field == 'completed' or p_field == 'completion':
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 = importance result = importance
...@@ -54,11 +56,12 @@ def get_field_function(p_field): ...@@ -54,11 +56,12 @@ def get_field_function(p_field):
# try to find the corresponding tag # try to find the corresponding tag
# when a tag is not present, push it to the end of the list by giving # when a tag is not present, push it to the end of the list by giving
# it an artificially higher value # it an artificially higher value
result = (lambda a: "0" + a.tag_value(p_field) if a.has_tag(p_field) \ result = (lambda a: "0" + a.tag_value(p_field) if a.has_tag(p_field)
else "1") else "1")
return result return result
class Sorter(object): class Sorter(object):
""" """
This class sorts a todo list. This class sorts a todo list.
...@@ -83,6 +86,7 @@ class Sorter(object): ...@@ -83,6 +86,7 @@ class Sorter(object):
specific search is done first. This relies on the fact that sorting is specific search is done first. This relies on the fact that sorting is
stable. stable.
""" """
def __init__(self, p_sortstring="desc:priority"): def __init__(self, p_sortstring="desc:priority"):
self.sortstring = p_sortstring self.sortstring = p_sortstring
self.functions = [] self.functions = []
...@@ -97,7 +101,6 @@ class Sorter(object): ...@@ -97,7 +101,6 @@ class Sorter(object):
sort operation is done first, relying on the stability of the sorted() sort operation is done first, relying on the stability of the sorted()
function. function.
""" """
sorted_todos = p_todos sorted_todos = p_todos
for function, order in reversed(self.functions): for function, order in reversed(self.functions):
sorted_todos = sorted(sorted_todos, key=function, sorted_todos = sorted(sorted_todos, key=function,
...@@ -113,8 +116,8 @@ class Sorter(object): ...@@ -113,8 +116,8 @@ class Sorter(object):
fields = self.sortstring.lower().split(',') fields = self.sortstring.lower().split(',')
for field in fields: for field in fields:
parsed_field = re.match( \ parsed_field = re.match(
r'(?P<order>(asc|desc)(ending)?:)?(?P<field>\S+)', \ r'(?P<order>(asc|desc)(ending)?:)?(?P<field>\S+)',
field) field)
if not parsed_field: if not parsed_field:
......
# 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 - 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
...@@ -24,6 +24,7 @@ from topydo.lib.Config import config ...@@ -24,6 +24,7 @@ from topydo.lib.Config import config
from topydo.lib.TodoBase import TodoBase from topydo.lib.TodoBase import TodoBase
from topydo.lib.Utils import date_string_to_date from topydo.lib.Utils import date_string_to_date
class Todo(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
...@@ -94,4 +95,3 @@ class Todo(TodoBase): ...@@ -94,4 +95,3 @@ class Todo(TodoBase):
return diff.days return diff.days
else: else:
return 0 return 0
# 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 - 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
...@@ -18,13 +18,15 @@ ...@@ -18,13 +18,15 @@
This module contains the class that represents a single todo item. This module contains the class that represents a single todo item.
""" """
from datetime import date
import re import re
from datetime import date
from six import u from six import u
from topydo.lib.TodoParser import parse_line from topydo.lib.TodoParser import parse_line
from topydo.lib.Utils import is_valid_priority from topydo.lib.Utils import is_valid_priority
class TodoBase(object): class TodoBase(object):
""" """
This class represents a single todo item in a todo.txt file. It maintains This class represents a single todo item in a todo.txt file. It maintains
...@@ -56,7 +58,6 @@ class TodoBase(object): ...@@ -56,7 +58,6 @@ class TodoBase(object):
Returns a list of all tag values associated with p_key. Returns Returns a list of all tag values associated with p_key. Returns
empty list if p_key does not exist. empty list if p_key does not exist.
""" """
tags = self.fields['tags'] tags = self.fields['tags']
matches = [tag[1] for tag in tags if tag[0] == p_key] matches = [tag[1] for tag in tags if tag[0] == p_key]
return matches if len(matches) else [] return matches if len(matches) else []
...@@ -67,8 +68,7 @@ class TodoBase(object): ...@@ -67,8 +68,7 @@ class TodoBase(object):
value is passed, it will only return true when there exists a tag with value is passed, it will only return true when there exists a tag with
the given key-value combination. the given key-value combination.
""" """
result = [t for t in self.tag_values(p_key)
result = [t for t in self.tag_values(p_key) \
if p_value == "" or t == p_value] if p_value == "" or t == p_value]
return len(result) > 0 return len(result) > 0
...@@ -90,7 +90,6 @@ class TodoBase(object): ...@@ -90,7 +90,6 @@ class TodoBase(object):
When p_old_value is set, all tags having this value will be set to the When p_old_value is set, all tags having this value will be set to the
new value. new value.
""" """
if p_value == "": if p_value == "":
self.remove_tag(p_key, p_old_value) self.remove_tag(p_key, p_old_value)
return return
...@@ -99,7 +98,7 @@ class TodoBase(object): ...@@ -99,7 +98,7 @@ class TodoBase(object):
if not p_force_add and value: if not p_force_add and value:
# remove old value from the tags # remove old value from the tags
self.fields['tags'] = [t for t in self.fields['tags'] \ self.fields['tags'] = [t for t in self.fields['tags']
if not (t[0] == p_key and t[1] == value)] if not (t[0] == p_key and t[1] == value)]
self.src = re.sub( self.src = re.sub(
...@@ -122,8 +121,9 @@ class TodoBase(object): ...@@ -122,8 +121,9 @@ class TodoBase(object):
# Build a new list that excludes the specified tag, match by value when # Build a new list that excludes the specified tag, match by value when
# p_value is given. # p_value is given.
self.fields['tags'] = [t for t in self.fields['tags'] \ self.fields['tags'] = [t for t in self.fields['tags']
if not (t[0] == p_key and (p_value == "" or t[1] == p_value))] if not (t[0] == p_key and (p_value == "" or
t[1] == p_value))]
# when value == "", match any value having key p_key # when value == "", match any value having key p_key
value = p_value if p_value != "" else r'\S+' value = p_value if p_value != "" else r'\S+'
...@@ -143,13 +143,11 @@ class TodoBase(object): ...@@ -143,13 +143,11 @@ class TodoBase(object):
Priority remains unchanged when an invalid priority is given, or when Priority remains unchanged when an invalid priority is given, or when
the task was completed. the task was completed.
""" """
if not self.is_completed() and (p_priority is None or
if not self.is_completed() and \ is_valid_priority(p_priority)):
(p_priority == None or is_valid_priority(p_priority)):
self.fields['priority'] = p_priority self.fields['priority'] = p_priority
priority_str = '' if p_priority == None else '(' + p_priority + ') ' priority_str = '' if p_priority is None else '(' + p_priority + ') '
self.src = re.sub(r'^(\([A-Z]\) )?', priority_str, self.src) self.src = re.sub(r'^(\([A-Z]\) )?', priority_str, self.src)
def priority(self): def priority(self):
...@@ -204,8 +202,9 @@ class TodoBase(object): ...@@ -204,8 +202,9 @@ class TodoBase(object):
self.fields['completed'] = True self.fields['completed'] = True
self.fields['completionDate'] = p_completion_date self.fields['completionDate'] = p_completion_date
self.src = re.sub(r'^(\([A-Z]\) )?', \ self.src = re.sub(r'^(\([A-Z]\) )?',
'x ' + p_completion_date.isoformat() + ' ', self.src) 'x ' + p_completion_date.isoformat() + ' ',
self.src)
def set_creation_date(self, p_date=date.today()): def set_creation_date(self, p_date=date.today()):
""" """
...@@ -213,16 +212,15 @@ class TodoBase(object): ...@@ -213,16 +212,15 @@ class TodoBase(object):
""" """
self.fields['creationDate'] = p_date self.fields['creationDate'] = p_date
# not particulary pretty, but inspired by # not particularly pretty, but inspired by
# http://bugs.python.org/issue1519638 non-existent matches trigger # http://bugs.python.org/issue1519638 non-existent matches trigger
# exceptions, hence the lambda # exceptions, hence the lambda
self.src = re.sub( self.src = re.sub(
r'^(x \d{4}-\d{2}-\d{2} |\([A-Z]\) )?(\d{4}-\d{2}-\d{2} )?(.*)$', r'^(x \d{4}-\d{2}-\d{2} |\([A-Z]\) )?(\d{4}-\d{2}-\d{2} )?(.*)$',
lambda m: \ lambda m:
u("{}{} {}").format(m.group(1) or '', p_date.isoformat(), m.group(3)), u("{}{} {}").format(m.group(1) or '', p_date.isoformat(),
self.src) m.group(3)), self.src)
def creation_date(self): def creation_date(self):
""" Returns the creation date of a todo. """ """ Returns the creation date of a todo. """
return self.fields['creationDate'] return self.fields['creationDate']
# 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 - 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
...@@ -20,6 +20,7 @@ This module deals with todo.txt files. ...@@ -20,6 +20,7 @@ This module deals with todo.txt files.
import codecs import codecs
class TodoFile(object): class TodoFile(object):
""" """
This class represents a todo.txt file, which can be read from or written This class represents a todo.txt file, which can be read from or written
...@@ -48,7 +49,6 @@ class TodoFile(object): ...@@ -48,7 +49,6 @@ class TodoFile(object):
p_todos can be a list of todo items, or a string that is just written p_todos can be a list of todo items, or a string that is just written
to the file. to the file.
""" """
todofile = codecs.open(self.path, 'w', encoding="utf-8") todofile = codecs.open(self.path, 'w', encoding="utf-8")
if p_todos is list: if p_todos is list:
......
...@@ -22,6 +22,7 @@ from topydo.lib.Config import config ...@@ -22,6 +22,7 @@ from topydo.lib.Config import config
from topydo.lib.Graph import DirectedGraph from topydo.lib.Graph import DirectedGraph
from topydo.lib.TodoListBase import TodoListBase from topydo.lib.TodoListBase import TodoListBase
class TodoList(TodoListBase): class TodoList(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,
...@@ -57,7 +58,6 @@ class TodoList(TodoListBase): ...@@ -57,7 +58,6 @@ class TodoList(TodoListBase):
Makes sure that the dependency graph is consistent according to the Makes sure that the dependency graph is consistent according to the
given todo. given todo.
""" """
dep_id = p_todo.tag_value('id') dep_id = p_todo.tag_value('id')
# maintain dependency graph # maintain dependency graph
if dep_id: if dep_id:
...@@ -114,8 +114,7 @@ class TodoList(TodoListBase): ...@@ -114,8 +114,7 @@ class TodoList(TodoListBase):
""" """
def id_exists(p_id): def id_exists(p_id):
""" """
Returns True if there exists a todo with the given parent Returns True if there exists a todo with the given parent ID.
ID.
""" """
for todo in self._todos: for todo in self._todos:
if todo.has_tag('id', str(p_id)): if todo.has_tag('id', str(p_id)):
...@@ -225,6 +224,5 @@ class TodoList(TodoListBase): ...@@ -225,6 +224,5 @@ class TodoList(TodoListBase):
This is used for calculating the average importance, that requires This is used for calculating the average importance, that requires
access to a todo's parents. access to a todo's parents.
""" """
for todo in self._todos: for todo in self._todos:
todo.attributes['parents'] = self.parents(todo) todo.attributes['parents'] = self.parents(todo)
...@@ -18,20 +18,23 @@ ...@@ -18,20 +18,23 @@
A list of todo items. A list of todo items.
""" """
from datetime import date
import re import re
from datetime import date
from six import text_type from six import text_type
from topydo.lib.Config import config
from topydo.lib import Filter from topydo.lib import Filter
from topydo.lib.Config import config
from topydo.lib.HashListValues import hash_list_values from topydo.lib.HashListValues import hash_list_values
from topydo.lib.PrettyPrinter import PrettyPrinter from topydo.lib.PrettyPrinter import PrettyPrinter
from topydo.lib.Todo import Todo from topydo.lib.Todo import Todo
from topydo.lib.View import View from topydo.lib.View import View
class InvalidTodoException(Exception): class InvalidTodoException(Exception):
pass pass
class TodoListBase(object): class TodoListBase(object):
""" """
Provides operations for a todo list, such as adding items, removing them, Provides operations for a todo list, such as adding items, removing them,
...@@ -83,10 +86,9 @@ class TodoListBase(object): ...@@ -83,10 +86,9 @@ class TodoListBase(object):
""" """
Attempts to find the todo on the given line number. Attempts to find the todo on the given line number.
When the identifier is a number but has leading zeroes, the result When the identifier is a number but has leading zeros, the result
will be None. will be None.
""" """
result = None result = None
if config().identifiers() != 'text': if config().identifiers() != 'text':
...@@ -131,7 +133,9 @@ class TodoListBase(object): ...@@ -131,7 +133,9 @@ class TodoListBase(object):
return result return result
def add(self, p_src): def add(self, p_src):
""" Given a todo string, parse it and put it to the end of the list. """ """
Given a todo string, parse it and put it to the end of the list.
"""
todos = self.add_list([p_src]) todos = self.add_list([p_src])
return todos[0] if len(todos) else None return todos[0] if len(todos) else None
...@@ -246,8 +250,8 @@ class TodoListBase(object): ...@@ -246,8 +250,8 @@ class TodoListBase(object):
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
# todo. Use the text (without tags) of the todo to keep the id as stable # todo. Use the text (without tags) of the todo to keep the id as
# as possible (not influenced by priorities or due dates, etc.) # stable as possible (not influenced by priorities or due dates, etc.)
self._todo_id_map = {} self._todo_id_map = {}
self._id_todo_map = {} self._id_todo_map = {}
......
# 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 - 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
...@@ -37,13 +37,14 @@ _TAG_MATCH = re.compile('(?P<key>[^:]+):(?P<value>.+)') ...@@ -37,13 +37,14 @@ _TAG_MATCH = re.compile('(?P<key>[^:]+):(?P<value>.+)')
_PROJECT_MATCH = re.compile(r'\+(\S*\w)') _PROJECT_MATCH = re.compile(r'\+(\S*\w)')
_CONTEXT_MATCH = re.compile(r'@(\S*\w)') _CONTEXT_MATCH = re.compile(r'@(\S*\w)')
def parse_line(p_string): def parse_line(p_string):
""" """
Parses a single line as can be encountered in a todo.txt file. Parses a single line as can be encountered in a todo.txt file.
First checks whether the standard elements are present, such as priority, First checks whether the standard elements are present, such as priority,
creation date, completeness check and the completion date. creation date, completeness check and the completion date.
Then the rest of the analyzed for any occurences of contexts, projects or Then the rest of the analyzed for any occurrences of contexts, projects or
tags. tags.
Returns an dictionary with the default values as shown below. Returns an dictionary with the default values as shown below.
...@@ -102,4 +103,3 @@ def parse_line(p_string): ...@@ -102,4 +103,3 @@ def parse_line(p_string):
result['text'] = result['text'][:-1] result['text'] = result['text'][:-1]
return result return result
This diff is collapsed.
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
VERSION = '0.6' VERSION = '0.6'
LICENSE = """Copyright (C) 2014 Bram Schoenmakers LICENSE = """Copyright (C) 2014-2015 Bram Schoenmakers
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>. 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. This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.""" There is NO WARRANTY, to the extent permitted by law."""
This diff is collapsed.
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