Commit 30c961bf authored by Bram Schoenmakers's avatar Bram Schoenmakers

Add ability to identify todos by a regex.

Works for delete and do subcommands.
parent b8cd5ae1
...@@ -36,6 +36,15 @@ class DeleteCommandTest(CommandTest.CommandTest): ...@@ -36,6 +36,15 @@ class DeleteCommandTest(CommandTest.CommandTest):
self.assertEquals(self.output, " 2 Bar p:1\nRemoved: Foo id:1\n") self.assertEquals(self.output, " 2 Bar p:1\nRemoved: Foo id:1\n")
self.assertEquals(self.errors, "") self.assertEquals(self.errors, "")
def test_del1_regex(self):
command = DeleteCommand.DeleteCommand(["Foo"], self.todolist, self.out, self.error, lambda p: "n")
command.execute()
self.assertTrue(self.todolist.is_dirty())
self.assertEquals(self.todolist.todo(1).source(), "Bar")
self.assertEquals(self.output, " 2 Bar p:1\nRemoved: Foo id:1\n")
self.assertEquals(self.errors, "")
def test_del2(self): def test_del2(self):
command = DeleteCommand.DeleteCommand(["1"], self.todolist, self.out, self.error, lambda p: "y") command = DeleteCommand.DeleteCommand(["1"], self.todolist, self.out, self.error, lambda p: "y")
command.execute() command.execute()
......
...@@ -133,7 +133,7 @@ class DoCommandTest(CommandTest.CommandTest): ...@@ -133,7 +133,7 @@ class DoCommandTest(CommandTest.CommandTest):
self.assertEquals(self.errors, "Invalid todo number given.\n") self.assertEquals(self.errors, "Invalid todo number given.\n")
def test_invalid2(self): def test_invalid2(self):
command = DoCommand.DoCommand(["A"], self.todolist, self.out, self.error) command = DoCommand.DoCommand(["AAA"], self.todolist, self.out, self.error)
command.execute() command.execute()
self.assertFalse(self.todolist.is_dirty()) self.assertFalse(self.todolist.is_dirty())
...@@ -171,6 +171,15 @@ class DoCommandTest(CommandTest.CommandTest): ...@@ -171,6 +171,15 @@ class DoCommandTest(CommandTest.CommandTest):
self.assertFalse(self.output) self.assertFalse(self.output)
self.assertEquals(self.errors, "Todo has already been completed.\n") self.assertEquals(self.errors, "Todo has already been completed.\n")
def test_do_regex1(self):
command = DoCommand.DoCommand(["baz"], self.todolist, self.out, self.error)
command.execute()
self.assertTrue(self.todolist.is_dirty())
self.assertTrue(self.todolist.todo(3).is_completed())
self.assertEquals(self.output, "Completed: x %s Baz p:1\n" % self.today)
self.assertEquals(self.errors, "")
def test_empty(self): def test_empty(self):
command = DoCommand.DoCommand([], self.todolist, self.out, self.error) command = DoCommand.DoCommand([], self.todolist, self.out, self.error)
command.execute() command.execute()
......
...@@ -181,6 +181,18 @@ class TodoListTester(unittest.TestCase): ...@@ -181,6 +181,18 @@ class TodoListTester(unittest.TestCase):
self.assertEquals(self.todolist.count(), 0) self.assertEquals(self.todolist.count(), 0)
self.assertTrue(self.todolist.is_dirty()) self.assertTrue(self.todolist.is_dirty())
def test_regex1(self):
self.assertFalse(self.todolist.todo("1"))
def test_regex2(self):
""" Multiple hits should result in None. """
self.assertFalse(self.todolist.todo("Project1"))
def test_regex3(self):
todo = self.todolist.todo("project2")
self.assertTrue(todo)
self.assertEquals(todo.source(), "(D) Bar @Context1 +Project2")
class TodoListDependencyTester(unittest.TestCase): class TodoListDependencyTester(unittest.TestCase):
def setUp(self): def setUp(self):
self.todolist = TodoList.TodoList([]) self.todolist = TodoList.TodoList([])
......
...@@ -38,8 +38,12 @@ class DCommand(Command): ...@@ -38,8 +38,12 @@ class DCommand(Command):
try: try:
self.number = convert_todo_number(self.argument(0)) self.number = convert_todo_number(self.argument(0))
self.todo = self.todolist.todo(self.number) self.todo = self.todolist.todo(self.number)
except (InvalidCommandArgument, InvalidTodoNumberException, InvalidTodoException): except (InvalidCommandArgument, InvalidTodoException):
self.todo = None self.todo = None
except InvalidTodoNumberException:
self.todo = self.todolist.todo(self.argument(0))
if self.todo:
self.number = self.todolist.number(self.todo)
def _uncompleted_children(self, p_todo): def _uncompleted_children(self, p_todo):
return sorted([t for t in self.todolist.children(p_todo) if not t.is_completed()]) return sorted([t for t in self.todolist.children(p_todo) if not t.is_completed()])
......
# Topydo - A todo.txt client written in Python. # Topydo - A todo.txt client written in Python.
# Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl> # Copyright (C) 2014 Bram Schoenmakers <me@bramschoenmakers.nl>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
...@@ -20,6 +20,7 @@ A list of todo items. ...@@ -20,6 +20,7 @@ A list of todo items.
import re import re
import Filter
import Graph import Graph
from PrettyPrinter import pretty_print_list from PrettyPrinter import pretty_print_list
import Todo import Todo
...@@ -50,7 +51,7 @@ class TodoList(object): ...@@ -50,7 +51,7 @@ class TodoList(object):
self.dirty = False self.dirty = False
def todo(self, p_number): def todo(self, p_identifier):
""" """
The _todos list has the same order as in the backend store (usually The _todos list has the same order as in the backend store (usually
a todo.txt file. The user refers to the first task as number 1, so use a todo.txt file. The user refers to the first task as number 1, so use
...@@ -58,15 +59,31 @@ class TodoList(object): ...@@ -58,15 +59,31 @@ class TodoList(object):
""" """
result = None result = None
try: try:
result = self._todos[p_number - 1] result = self._todos[p_identifier - 1]
except IndexError: except IndexError:
raise InvalidTodoException raise InvalidTodoException
except TypeError:
result = self.todo_by_regexp(p_identifier)
return result
def todo_by_regexp(self, p_identifier):
"""
Returns the todo that is (uniquely) identified by the given regexp.
If the regexp matches more than one item, no result is returned.
"""
result = None
candidates = Filter.GrepFilter(p_identifier).filter(self._todos)
if len(candidates) == 1:
result = candidates[0]
return result return result
def todo_by_hash(self, p_hash): def todo_by_hash(self, p_hash):
""" """
Given the hash value of a todo, return the corresponding hash instance. Given the hash value of a todo, return the corresponding instance.
""" """
result = None result = None
......
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