Commit d0342c58 authored by Bram Schoenmakers's avatar Bram Schoenmakers

Apply LimitFilter after HiddenTagFilter

The LimitFilter should be performed at the very last step. Instead of
complicating ExpressionCommand and ListCommand to cough up a well
ordered set of filters, order the filters when updating the view. Each
filter is assigned an order number, where filters with a higher order
are applied later.

This fixes the output when using the ls -n flag, where the truncation
appears before the hide tag filter. This results in possibly less items
to be printed than specified (or worse: nothing is printed).
parent 9e13f20b
......@@ -26,6 +26,7 @@ from test.command_testcase import CommandTest
from test.facilities import load_file_to_todolist
from topydo.commands.ListCommand import ListCommand
from topydo.lib.Config import config
from topydo.lib.TodoList import TodoList
# We're searching for 'mock'
# 'mock' was added as 'unittest.mock' in Python 3.3, but PyPy 3 is based on Python 3.2
......@@ -420,6 +421,19 @@ class ListCommandTest(CommandTest):
self.assertEqual(self.output, "| 1| (C) 2015-11-05 Foo @Context2 Not@Context +Project1 Not+Project\n")
self.assertEqual(self.errors, "")
def test_list49(self):
""" Only show the top todo. """
todolist = TodoList([
"This item is hidden h:1",
"This item is visible",
])
command = ListCommand(["-n", "1"], todolist, self.out, self.error)
command.execute()
self.assertEqual(self.output, '| 2| This item is visible\n')
self.assertEqual(self.errors, "")
def test_list_name(self):
name = ListCommand.name()
......
......@@ -32,6 +32,10 @@ class Filter(object):
def match(self, _):
raise NotImplementedError
@property
def order(self):
return 50
class NegationFilter(Filter):
def __init__(self, p_filter):
......@@ -107,6 +111,13 @@ class RelevanceFilter(Filter):
return active and is_due
@property
def order(self):
"""
Perform just after the DependencyFilter, but before any other filters.
"""
return 20
class DependencyFilter(Filter):
""" Matches when a todo has no unfinished child tasks. """
......@@ -130,6 +141,14 @@ class DependencyFilter(Filter):
return not uncompleted
@property
def order(self):
"""
Perform early before any other items are filtered out, possibly
breaking the dependency chain.
"""
return 10
class InstanceFilter(Filter):
def __init__(self, p_todos):
......@@ -185,6 +204,11 @@ class LimitFilter(Filter):
def filter(self, p_todos):
return p_todos[:self.limit] if self.limit >= 0 else p_todos
@property
def order(self):
# should be performed at the very last step
return 100
_OPERATOR_MATCH = r"(?P<operator><=?|=|>=?|!)?"
......
......@@ -33,7 +33,7 @@ class View(object):
""" Applies the filters to the list of todo items. """
result = p_todos
for _filter in self._filters:
for _filter in sorted(self._filters, key=lambda f: f.order):
result = _filter.filter(result)
return result
......
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