Commit f60572d2 authored by Bram Schoenmakers's avatar Bram Schoenmakers

Merge branch 'coverage'

Conflicts:
	topydo/lib/DCommand.py
parents 8dbbbbfb c547b850
[run]
source = topydo
[report]
exclude_lines =
pragma: no cover
def __repr__
raise AssertionError
raise NotImplementedError
if 0:
if __name__ == .__main__.:
omit =
topydo/lib/ExitCommand.py
topydo/lib/Version.py
......@@ -3,3 +3,4 @@
build
dist
install
.coverage
......@@ -211,6 +211,14 @@ class DepCommandTest(CommandTest):
self.assertFalse(self.output)
self.assertEqual(self.errors, command.usage() + "\n")
def test_ls7(self):
command = DepCommand(["ls", "top", "99"], self.todolist, self.out, self.error)
command.execute()
self.assertFalse(self.todolist.is_dirty())
self.assertEqual(self.output, "")
self.assertEqual(self.errors, command.usage() + "\n")
def gc_helper(self, p_subcommand):
command = DepCommand([p_subcommand], self.todolist, self.out, self.error)
command.execute()
......
# Topydo - A todo.txt client written in Python.
# Copyright (C) 2015 Bram Schoenmakers <me@bramschoenmakers.nl>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from topydo.lib.JsonPrinter import JsonPrinter
from topydo.lib.Todo import Todo
from test.TopydoTest import TopydoTest
class JsonPrinterTest(TopydoTest):
"""
Tests the functionality of printing a single todo item. Printing a list is
already covered by the ListCommand tests.
"""
def test_json(self):
""" Print a single todo item. """
printer = JsonPrinter()
todo = Todo('2015-06-06 Foo due:2015-05-32')
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"}')
......@@ -224,7 +224,6 @@ class ListCommandUnicodeTest(CommandTest):
self.assertEqual(self.output, expected)
class ListCommandJsonTest(CommandTest):
def test_json(self):
todolist = load_file_to_todolist("test/data/ListCommandTest.txt")
......@@ -265,11 +264,14 @@ def replace_ical_tags(p_text):
IS_PYTHON_32 = (sys.version_info.major, sys.version_info.minor) == (3, 2)
class ListCommandIcalTest(CommandTest):
def setUp(self):
self.maxDiff = None
@unittest.skipIf(IS_PYTHON_32, "icalendar is not supported for Python 3.2")
def test_ical(self):
todolist = load_file_to_todolist("test/data/ListCommandTest.txt")
todolist = load_file_to_todolist("test/data/ListCommandIcalTest.txt")
command = ListCommand(["-f", "ical"], todolist, self.out, self.error)
command = ListCommand(["-x", "-f", "ical"], todolist, self.out, self.error)
command.execute()
self.assertTrue(todolist.is_dirty())
......
......@@ -24,6 +24,7 @@ from topydo.lib.Todo import Todo
from topydo.lib.TodoFile import TodoFile
from topydo.lib.TodoListBase import InvalidTodoException
from topydo.lib.TodoList import TodoList
from topydo.lib.TodoListBase import TodoListBase
from test.TopydoTest import TopydoTest
class TodoListTester(TopydoTest):
......@@ -34,7 +35,7 @@ class TodoListTester(TopydoTest):
lines = [line for line in self.todofile.read() \
if re.search(r'\S', line)]
self.text = ''.join(lines)
self.todolist = TodoList(lines)
self.todolist = TodoListBase(lines)
def test_contexts(self):
self.assertEqual(set(['Context1', 'Context2']), \
......@@ -101,6 +102,16 @@ class TodoListTester(TopydoTest):
self.assertTrue(self.todolist.is_dirty())
self.assertRaises(InvalidTodoException, self.todolist.number, todo)
def test_delete2(self):
""" Try to remove a todo item that does not exist. """
count = self.todolist.count()
todo = Todo('Not in the list')
self.todolist.delete(todo)
self.assertEqual(self.todolist.count(), count)
self.assertFalse(self.todolist.is_dirty())
def test_append1(self):
todo = self.todolist.todo(3)
self.todolist.append(todo, "@Context3")
......@@ -137,13 +148,6 @@ class TodoListTester(TopydoTest):
""" Test that empty lines are not counted. """
self.assertEqual(self.todolist.count(), 5)
def test_todo_by_dep_id(self):
""" Tests that todos can be retrieved by their id tag. """
self.todolist.add("(C) Foo id:1")
self.assertTrue(self.todolist.todo_by_dep_id('1'))
self.assertFalse(self.todolist.todo_by_dep_id('2'))
def test_todo_number1(self):
todo = Todo("No number")
self.todolist.add_todo(todo)
......@@ -349,6 +353,14 @@ class TodoListDependencyTester(TopydoTest):
self.assertEqual(todo1.source(), 'Foo id:1')
self.assertEqual(todo2.source(), 'Bar p:1')
def test_todo_by_dep_id(self):
""" Tests that todos can be retrieved by their id tag. """
todolist = TodoList([])
todolist.add("(C) Foo id:1")
self.assertTrue(todolist.todo_by_dep_id('1'))
self.assertFalse(todolist.todo_by_dep_id('2'))
class TodoListCleanDependencyTester(TopydoTest):
def setUp(self):
super(TodoListCleanDependencyTester, self).setUp()
......
(C) Foo @Context2 Not@Context +Project1 Not+Project
(D) Bar @Context1 +Project2 p:1 due:2015-06-06
(C) Baz @Context1 +Project1 key:value id:1
(C) 2015-06-06 Drink beer @ home
(G) 13 + 29 = 42
(C) Only a start date t:2015-06-06
x 2015-06-06 A completed item due:2015-05-05
This diff was suppressed by a .gitattributes entry.
......@@ -46,7 +46,7 @@ class ListCommand(ExpressionCommand):
"""
try:
import icalendar as _
except ImportError:
except ImportError: # pragma: no cover
self.error("icalendar package is not installed.")
return False
......@@ -101,7 +101,7 @@ class ListCommand(ExpressionCommand):
try:
self._process_flags()
except SyntaxError:
except SyntaxError: # pragma: no cover
# importing icalendar failed, most likely due to Python 3.2
self.error("icalendar is not supported in this Python version.")
return False
......
......@@ -84,8 +84,10 @@ class Command(object):
return result
def usage(self):
return "No usage text available for this command."
""" Returns a one-line synopsis for this command. """
raise NotImplementedError
def help(self):
return "No help text available for this command."
""" Returns the help text for this command. """
raise NotImplementedError
......@@ -56,11 +56,10 @@ class DCommand(MultiCommand):
self.out(printer.print_list(p_todos))
def prompt_text(self):
return "Yes or no? [y/N] "
raise NotImplementedError
def prefix(self):
""" Prefix to use when printing a todo. """
return ""
raise NotImplementedError
def _process_subtasks(self, p_todo):
children = self._uncompleted_children(p_todo)
......@@ -101,17 +100,17 @@ class DCommand(MultiCommand):
return True
def condition_failed_text(self):
return ""
raise NotImplementedError
def execute_specific(self, _):
pass
raise NotImplementedError
def execute_specific_core(self, p_todo):
"""
The core operation on the todo itself. Also used to operate on
child/parent tasks.
"""
pass
raise NotImplementedError
def _execute_multi_specific(self):
old_active = self._active_todos()
......
......@@ -29,8 +29,7 @@ class Filter(object):
return [t for t in p_todos if self.match(t)]
def match(self, _):
""" Default match value. """
return True
raise NotImplementedError
class NegationFilter(Filter):
def __init__(self, p_filter):
......
......@@ -69,15 +69,12 @@ class IcalPrinter(Printer):
try:
import icalendar
self.icalendar = icalendar
except (SyntaxError, ImportError):
except (SyntaxError, ImportError): # pragma: no cover
# icalendar does not support Python 3.2 resulting in a SyntaxError. Since
# this is an optional dependency, dropping Python 3.2 support altogether is
# too much. Therefore just disable the iCalendar functionality
self.icalendar = None
def print_todo(self, p_todo):
return self._convert_todo(p_todo).to_ical() if self.icalendar else ""
def print_list(self, p_todos):
result = ""
......
......@@ -26,8 +26,7 @@ class Printer(object):
Subclasses must at least implement the print_todo method.
"""
def print_todo(self, p_todo):
""" Base implementation."""
return p_todo.source()
raise NotImplementedError
def print_list(self, p_todos):
"""
......
......@@ -30,8 +30,10 @@ class PrettyPrinterFilter(object):
"""
def filter(self, p_todo_str, _):
""" Default implementation returns an unmodified todo string. """
return p_todo_str
"""
Applies a filter to p_todo_str and returns a modified version of it.
"""
raise NotImplementedError
class PrettyPrinterColorFilter(PrettyPrinterFilter):
"""
......
......@@ -36,14 +36,11 @@ class TodoList(TodoListBase):
Should be given a list of strings, each element a single todo string.
The string will be parsed.
"""
self._todos = []
# initialize these first because the constructor calls add_list
self._tododict = {} # hash(todo) to todo lookup
self._depgraph = DirectedGraph()
self._todo_id_map = {}
self._id_todo_map = {}
self.add_list(p_todostrings)
self.dirty = False
super(TodoList, self).__init__(p_todostrings)
def todo_by_dep_id(self, p_dep_id):
"""
......
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