Commit a736ccda authored by Bram Schoenmakers's avatar Bram Schoenmakers

Merge branch 'ordinal-tag-filter'

parents d764811f d3dc0eff
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
""" Tests for the filter functionality. """ """ Tests for the filter functionality. """
from datetime import date, timedelta
import unittest import unittest
import Filter import Filter
...@@ -183,3 +184,152 @@ class FilterTest(unittest.TestCase): ...@@ -183,3 +184,152 @@ class FilterTest(unittest.TestCase):
self.assertEquals(todolist_to_string(filtered_todos), \ self.assertEquals(todolist_to_string(filtered_todos), \
todolist_to_string(reference)) todolist_to_string(reference))
def test_filter19(self):
todos = load_file('data/FilterTest3.txt')
otf = Filter.OrdinalTagFilter('due:<2014-11-10')
filtered_todos = otf.filter(todos)
reference = load_file('data/FilterTest6-result.txt')
self.assertEquals(todolist_to_string(filtered_todos), \
todolist_to_string(reference))
def test_filter20(self):
todos = load_file('data/FilterTest3.txt')
otf = Filter.OrdinalTagFilter('due:=2014-11-10')
filtered_todos = otf.filter(todos)
reference = load_file('data/FilterTest6-result.txt')
self.assertEquals(todolist_to_string(filtered_todos), "")
def test_filter21(self):
todos = load_file('data/FilterTest3.txt')
otf = Filter.OrdinalTagFilter('due:=2014-11-10')
filtered_todos = otf.filter(todos)
self.assertEquals(todolist_to_string(filtered_todos), "")
def test_filter22(self):
todos = load_file('data/FilterTest3.txt')
otf = Filter.OrdinalTagFilter('due:=2014-11-99')
filtered_todos = otf.filter(todos)
self.assertEquals(todolist_to_string(filtered_todos), "")
def test_filter23(self):
todos = load_file('data/FilterTest3.txt')
otf = Filter.OrdinalTagFilter('due:=garbage')
filtered_todos = otf.filter(todos)
self.assertEquals(todolist_to_string(filtered_todos), "")
def test_filter24(self):
todos = load_file('data/FilterTest3.txt')
otf = Filter.OrdinalTagFilter('value:<10')
filtered_todos = otf.filter(todos)
reference = load_file('data/FilterTest8-result.txt')
self.assertEquals(todolist_to_string(filtered_todos),
todolist_to_string(reference))
def test_filter25(self):
todos = load_file('data/FilterTest3.txt')
otf = Filter.OrdinalTagFilter('value:<=16')
filtered_todos = otf.filter(todos)
reference = load_file('data/FilterTest9-result.txt')
self.assertEquals(todolist_to_string(filtered_todos),
todolist_to_string(reference))
def test_filter26(self):
todos = load_file('data/FilterTest3.txt')
otf = Filter.OrdinalTagFilter('value:<16')
filtered_todos = otf.filter(todos)
reference = load_file('data/FilterTest10-result.txt')
self.assertEquals(todolist_to_string(filtered_todos),
todolist_to_string(reference))
def test_filter27(self):
todos = load_file('data/FilterTest3.txt')
otf = Filter.OrdinalTagFilter('value:<16a')
filtered_todos = otf.filter(todos)
self.assertEquals(todolist_to_string(filtered_todos), "")
def test_filter28(self):
todos = load_file('data/FilterTest3.txt')
otf = Filter.OrdinalTagFilter('value:>8')
filtered_todos = otf.filter(todos)
reference = load_file('data/FilterTest11-result.txt')
self.assertEquals(todolist_to_string(filtered_todos),
todolist_to_string(reference))
def test_filter29(self):
todos = load_file('data/FilterTest3.txt')
otf = Filter.OrdinalTagFilter('value:>=8')
filtered_todos = otf.filter(todos)
reference = load_file('data/FilterTest12-result.txt')
self.assertEquals(todolist_to_string(filtered_todos),
todolist_to_string(reference))
class OrdinalTagFilterTest(unittest.TestCase):
def setUp(self):
today = date.today()
tomorrow = today + timedelta(1)
self.today = today.isoformat()
self.tomorrow = tomorrow.isoformat()
self.todos = [
Todo.Todo("Foo due:%s" % self.today),
Todo.Todo("Bar due:%s" % self.tomorrow),
Todo.Todo("Baz due:nonsense"),
Todo.Todo("Fnord due:2014-10-32")
]
def test_filter1(self):
otf = Filter.OrdinalTagFilter('due:today')
result = otf.filter(self.todos)
self.assertEquals(len(result), 1)
self.assertEquals(str(result[0]), "Foo due:%s" % self.today)
def test_filter2(self):
otf = Filter.OrdinalTagFilter('due:=today')
result = otf.filter(self.todos)
self.assertEquals(len(result), 1)
self.assertEquals(str(result[0]), "Foo due:%s" % self.today)
def test_filter3(self):
otf = Filter.OrdinalTagFilter('due:>today')
result = otf.filter(self.todos)
self.assertEquals(len(result), 1)
self.assertEquals(str(result[0]), "Bar due:%s" % self.tomorrow)
def test_filter4(self):
otf = Filter.OrdinalTagFilter('due:<1w')
result = otf.filter(self.todos)
self.assertEquals(len(result), 2)
self.assertEquals(str(result[0]), "Foo due:%s" % self.today)
self.assertEquals(str(result[1]), "Bar due:%s" % self.tomorrow)
Tag with some other value:16
Tag with some value:8
Tag with some other value:16
Tag with past due date due:2014-01-01
Tag with future due date due:2030-01-01
Tag with some value:8
Tag with some other value:16
Tag with nonsense value:nonsense
Tag with past due date due:2014-01-01
Tag with future due date due:2030-01-01
Tag with some value:8
Tag with some other value:16
...@@ -14,6 +14,13 @@ ...@@ -14,6 +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 datetime import date
import re
from Config import config
from RelativeDate import relative_date_to_date
from Utils import date_string_to_date
class Filter(object): class Filter(object):
def filter(self, p_todos): def filter(self, p_todos):
""" """
...@@ -140,3 +147,46 @@ class LimitFilter(Filter): ...@@ -140,3 +147,46 @@ class LimitFilter(Filter):
def filter(self, p_todos): def filter(self, p_todos):
return p_todos[:self.limit] if self.limit >= 0 else p_todos return p_todos[:self.limit] if self.limit >= 0 else p_todos
ORDINAL_TAG_MATCH = r"(?P<key>[^:]*):(?P<operator><=?|=|>=?)?(?P<value>\S*)"
class OrdinalTagFilter(Filter):
def __init__(self, p_expression):
match = re.match(ORDINAL_TAG_MATCH, p_expression)
if match:
self.key = match.group('key')
self.operator = match.group('operator') or '='
self.value = match.group('value')
def match(self, p_todo):
if not self.key or not p_todo.has_tag(self.key):
return False
if self.key == config().tag_due() or self.key == config().tag_start():
operand1 = date_string_to_date(p_todo.tag_value(self.key))
operand2 = relative_date_to_date(self.value)
if not operand2:
operand2 = date_string_to_date(self.value)
if not operand1 or not operand2:
return False
else:
try:
operand1 = int(p_todo.tag_value(self.key))
operand2 = int(self.value)
except ValueError:
return False
if self.operator == '<':
return operand1 < operand2
elif self.operator == '<=':
return operand1 <= operand2
elif self.operator == '=':
return operand1 == operand2
elif self.operator == '>=':
return operand1 >= operand2
elif self.operator == '>':
return operand1 > operand2
return False
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