Commit 5e13411a authored by Bram Schoenmakers's avatar Bram Schoenmakers

Do not apply ordinal filtering when a tag appears more than once

Suppose we have the todo item:

    (C) Some item key:value1 key:value2

And then I do an ls:

    topydo ls -x key:value2

Before, this would yield an empty result, which is undesired. Therefore,
only apply ordinal tag filtering when a tag appears exactly once in the
todo item. This is a simple approach, and special operators >, >= etc
will not be applicable:

    topydo ls -x key:>value1

will no longer work. The result could be ambiguous: filter out when none of
the tags match, or only some of them?
parent 51ff4a66
......@@ -313,12 +313,14 @@ class OrdinalTagFilterTest(TopydoTest):
self.todo2 = "Bar due:{}".format(self.tomorrow)
self.todo3 = "Baz due:Nonsense"
self.todo4 = "Fnord due:2014-10-32"
self.todo5 = "Double tags key:value1 key:value2"
self.todos = [
Todo(self.todo1),
Todo(self.todo2),
Todo(self.todo3),
Todo(self.todo4),
Todo(self.todo5),
]
def test_filter1(self):
......@@ -378,6 +380,18 @@ class OrdinalTagFilterTest(TopydoTest):
self.assertEqual(len(result), 1)
self.assertEqual(result[0].source(), self.todo3)
def test_filter8(self):
"""
OrdinalTagFilter should resort to a simple GrepFilter when a tag
appears more than once.
"""
otf = Filter.OrdinalTagFilter('key:value2')
result = otf.filter(self.todos)
self.assertEqual(len(result), 1)
self.assertEqual(result[0].source(), self.todo5)
class CreationFilterTest(TopydoTest):
def setUp(self):
......
......@@ -246,9 +246,18 @@ class OrdinalTagFilter(OrdinalFilter):
As a last resort, it falls back to using a Grep filter to see if the
user given expression is contained in the todo text.
"""
def resort_to_grep_filter():
grep = GrepFilter(self.expression)
return grep.match(p_todo)
if not self.key or not p_todo.has_tag(self.key):
return False
if len(p_todo.tag_values(self.key)) > 1:
# we cannot apply an ordening on a tag that appears more than once
# in this todo item, therefore use a simple value match
return resort_to_grep_filter()
try:
operand1 = date_string_to_date(p_todo.tag_value(self.key))
operand2 = relative_date_to_date(self.value)
......@@ -264,8 +273,7 @@ class OrdinalTagFilter(OrdinalFilter):
operand1 = int(operand1)
operand2 = int(operand2)
except ValueError:
grep = GrepFilter(self.expression)
return grep.match(p_todo)
return resort_to_grep_filter()
return self.compare_operands(operand1, operand2)
......
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