Commit 0079d622 authored by Bram Schoenmakers's avatar Bram Schoenmakers

Add support for filtering todos.

At this point there are two filters:

* A grep filter that finds a pattern in a todo text
* A relevance filter, which selects todos that are relevant at this
  moment.
parent 823fe7a1
class Filter(object):
# def __init__(self):
# pass
def filter(self, p_todos, p_limit=None):
"""
Filters a list of todos. Truncates the list after p_limit todo
items (or no maximum limit if omitted).
"""
result = [t for t in p_todos if self.match(t)]
return result[:p_limit]
def match(self, p_todo):
""" Default match value. """
return True
class GrepFilter(Filter):
""" Matches when the todo text contains a text. """
def __init__(self, p_expression, p_case_sensitive=None):
self.expression = p_expression
if p_case_sensitive:
self.case_sensitive = p_case_sensitive
else:
# only be case sensitive when the expression contains at least one
# capital character.
self.case_sensitive = \
len([c for c in p_expression if c.isupper()]) > 0
def match(self, p_todo):
expr = self.expression
string = p_todo.source()
if not self.case_sensitive:
expr = expr.lower()
string = string.lower()
return string.find(expr) != -1
class RelevanceFilter(Filter):
"""
Matches when the todo is relevant, i.e.:
The item has not been completed AND
The start date is blank, today or in the past, AND
The priority is 'A' or the priority is B with due date within 30 days or
the priority is C with due date within 14 days.
"""
def match(self, p_todo):
is_due = p_todo.is_active()
is_due |= p_todo.due_date() == None
is_due |= p_todo.priority() == 'A'
is_due |= p_todo.priority() == 'B' and p_todo.days_till_due() <= 30
is_due |= p_todo.priority() == 'C' and p_todo.days_till_due() <= 14
return p_todo.is_active() and is_due
""" Tests for the filter functionality. """
import pdb
import datetime
import unittest
import Filter
from TestFacilities import load_file, todolist_to_string
import Todo
class FilterTest(unittest.TestCase):
def setUp(self):
# self.today = datetime.date.today()
pass
def test_filter1(self):
todo = Todo.Todo("(C) Relevant")
relevance = Filter.RelevanceFilter()
result = relevance.filter([todo], 0)
self.assertEquals(result, [])
def test_filter2(self):
todo = Todo.Todo("(C) Relevant")
relevance = Filter.RelevanceFilter()
result = relevance.filter([todo], 100)
self.assertEquals(result, [todo])
def test_filter3(self):
todo = Todo.Todo("(C) Relevant")
relevance = Filter.RelevanceFilter()
result = relevance.filter([todo])
self.assertEquals(result, [todo])
def test_filter4(self):
""" Test case insensitive match. """
todos = load_file('data/FilterTest1.txt')
grep = Filter.GrepFilter('+project')
filtered_todos = grep.filter(todos)
reference = load_file('data/FilterTest1a-result.txt')
self.assertEquals(todolist_to_string(filtered_todos), \
todolist_to_string(reference))
def test_filter5(self):
""" Test case sensitive match. """
todos = load_file('data/FilterTest1.txt')
grep = Filter.GrepFilter('+Project')
filtered_todos = grep.filter(todos)
reference = load_file('data/FilterTest1b-result.txt')
self.assertEquals(todolist_to_string(filtered_todos), \
todolist_to_string(reference))
def test_filter6(self):
""" Test case sensitive match (forced, with lowercase). """
todos = load_file('data/FilterTest1.txt')
grep = Filter.GrepFilter('+project', True)
filtered_todos = grep.filter(todos)
reference = load_file('data/FilterTest1c-result.txt')
self.assertEquals(todolist_to_string(filtered_todos), \
todolist_to_string(reference))
(C) This is part of some +Project
(D) Just an arbitrary task
(C) Another mildly important task for the +Project
(C) And here's one with a lowercase +project
(C) This is part of some +Project
(C) Another mildly important task for the +Project
(C) And here's one with a lowercase +project
(C) This is part of some +Project
(C) Another mildly important task for the +Project
(C) And here's one with a lowercase +project
......@@ -5,7 +5,7 @@ PYTHONPATH=..
if [ -n "$1" ]; then
TESTS=$1
else
TESTS="SorterTest TodoBaseTest TodoFileTest TodoTest TodoListTest"
TESTS="FilterTest SorterTest TodoBaseTest TodoFileTest TodoTest TodoListTest"
fi
for TEST in $TESTS; do
......
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