changeset 5628:9fbcd746f135

MoinMoin.widget.browser: Reverse sort enhanced. A table can be sorted by columns, where it is possible to sort one or more columns also vice versa. The result may look like this: Price Performance 100 123 100 111 100 99 200 456 200 321 200 111 widget/_tests/test_DataBrowserWidget: tests for sort_table added
author Reimar Bauer <rb.proj AT googlemail DOT com>
date Fri, 12 Mar 2010 13:52:00 +0100
parents dd04e0178c3d
children 32a0bf3c4e43
files MoinMoin/widget/_tests/test_DataBrowserWidget.py MoinMoin/widget/browser.py
diffstat 2 files changed, 129 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/widget/_tests/test_DataBrowserWidget.py	Fri Mar 12 13:52:00 2010 +0100
@@ -0,0 +1,102 @@
+# -*- coding: iso-8859-1 -*-
+"""
+    MoinMoin - MoinMoin.widget.browser Tests
+
+    @copyright: 2010 by MoinMoin:ReimarBauer
+    @license: GNU GPL, see COPYING for details.
+"""
+
+import py
+from MoinMoin.util.dataset import TupleDataset, Column
+from MoinMoin.widget.browser import DataBrowserWidget
+
+
+class Test_DataBrowserWidget_sort_table(object):
+    def setup_class(self):
+        # check if state of example changes during tests
+        example = [['L1', (u'c', u'c'), (u'1', u'1'),   (u'2', u'2'),           (u'a', u'a'),  (u'4', u'4'),   (u'5', u'5')],
+                   ['L2', (u'b', u'b'), (u'10', u'10'), (u'21', u'21'),         (u'B', u'B'),  (u'40', u'40'), (u'10', u'10')],
+                   ['L3', (u'b', u'b'), (u'2', u'2'),   (u'3.14', u'3.14'),     (u'c', u'c'),  (u'54', u'54'), (u'50', u'50')],
+                   ['L4', (u'b', u'b'), (u'90', u'90'), (u'-2.240', u'-2.240'), (u'D', u'D'),  (u'40', u'40'), (u'5', u'5')],
+                   ['L5', (u'a', u'a'), (u'95', u'95'), (u'20', u'20'),         (u'e', u'e'),  (u'40', u'40'), (u'10', u'10')],
+                  ]
+        self.example = example
+        data = TupleDataset()
+        data.columns = []
+        data.columns.extend([Column('TEST', label='TEST')])
+
+        for line in self.example:
+            data.addRow([line[0]] + line[1:])
+            data.columns.extend([Column(line[0], label=line[0])])
+
+        self.data = data
+        self.table = DataBrowserWidget(self.request)
+
+
+    def test_tablecreation(self):
+        """
+        tests input data not changed
+        """
+        self.table.setData(self.data)
+        result = self.table.data.data
+        example = self.example
+        assert result == example
+
+    def test_sort_one_column_alphas(self):
+        """
+        tests one column sorted alphabetically
+        """
+        self.table.setData(self.data, sort_columns=[4])
+        test_run = self.table.data.data
+        result = [result[0] for result in test_run]
+        assert result == ['L2', 'L4', 'L1', 'L3', 'L5']
+
+    def test_sort_one_column_integers(self):
+        """
+        tests one column sorted numerical
+        """
+        self.table.setData(self.data, sort_columns=[2])
+        test_run = self.table.data.data
+        result = [result[0] for result in test_run]
+        assert result == ['L1', 'L3', 'L2', 'L4', 'L5']
+
+    def test_sort_one_column_floats(self):
+        """
+        tests one column sorted numerical for floating point values
+        """
+        self.table.setData(self.data, sort_columns=[3])
+        test_run = self.table.data.data
+        result = [result[0] for result in test_run]
+        assert result == ['L4', 'L1', 'L3', 'L5', 'L2']
+
+    def test_n_sort(self):
+        """
+        tests n_sort
+        """
+        self.table.setData(self.data, sort_columns=[1, 2])
+        test_run = self.table.data.data
+        result = [result[0] for result in test_run]
+        assert result == ['L5', 'L3', 'L2', 'L4', 'L1']
+
+        self.table.setData(self.data, sort_columns=[5, 6, 3])
+        test_run = self.table.data.data
+        result = [result[0] for result in test_run]
+        assert result == ['L1', 'L4', 'L5', 'L2', 'L3']
+
+    def test_reverse_sort(self):
+        """
+        tests reverse sort
+        """
+        self.table.setData(self.data, sort_columns=[0], reverse=True)
+        test_run = self.table.data.data
+        result = [result[0] for result in test_run]
+        assert result == ['L5', 'L4', 'L3', 'L2', 'L1']
+
+    def test_sort_and_reverse_by_a_different_column(self):
+        """
+        tests reverse sort by a different column as the one to sort
+        """
+        self.table.setData(self.data, sort_columns=[6], reverse=[0])
+        test_run = self.table.data.data
+        result = [result[0] for result in test_run]
+        assert result == ['L4', 'L1', 'L5', 'L2', 'L3']
--- a/MoinMoin/widget/browser.py	Thu Mar 11 10:16:42 2010 +0100
+++ b/MoinMoin/widget/browser.py	Fri Mar 12 13:52:00 2010 +0100
@@ -26,19 +26,25 @@
         decimal_string = u""
     return (decimal_value, decimal_string, txt)
 
-def sort_table(rows, sort_columns=None, reverse=False):
+def sort_table(rows, sort_columns=None, reverse=None):
     """
     sorts table rows
 
     @param rows: table rows to sort
-    @param sort_columns: column to sort. By a given list it does a multiple sort
-    @param reverse: reverse sort
+    @param sort_columns: column to sort. The instance must be list or tuple of integer values.
+                         By more than one entry it does a multiple sort.
+    @param reverse: reverse sort. The instance must be list or tuple of boolean values.
+                    It must be of the same length than sort_columns.
     """
-    if not (sort_columns and isinstance(sort_columns, (list, tuple))):
-        # don't sort if no list is given
+    if not sort_columns:
         return rows
+
+    assert isinstance(sort_columns, (list, tuple))
+    assert isinstance(reverse, (list, tuple))
+    assert len(rows[0]) == len(reverse)
+
     for idx in reversed(sort_columns):
-        rows = sorted(rows, key=lambda x: _compare(idx, x), reverse=reverse)
+        rows = sorted(rows, key=lambda x: _compare(idx, x), reverse=reverse[idx])
     return rows
 
 class DataBrowserWidget(base.Widget):
@@ -71,7 +77,21 @@
         @param reverse: reverse sort
         """
         if sort_columns:
-            dataset.data = sort_table(dataset.data, sort_columns, reverse=reverse)
+            # simplification if there is no reverse list given
+            # then all sort_columns should have the same reverse order
+            if not isinstance(reverse, (list, tuple)):
+                reverse_var = [reverse] * len(dataset.data[0])
+            else:
+                reverse_var = [False] * len(dataset.data[0])
+                for idx in reverse:
+                    reverse_var[idx] = True
+
+                # force that reverse columns listed in sort_columns
+                missing_columns = list(set(reverse) - set(sort_columns))
+                if missing_columns:
+                    sort_columns = sort_columns + missing_columns
+
+            dataset.data = sort_table(dataset.data, sort_columns, reverse=reverse_var)
 
         self.data = dataset
         if dataset.data_id: