--- a/selectors.py Fri Sep 24 15:00:08 2010 +0200
+++ b/selectors.py Fri Sep 24 13:41:13 2010 +0200
@@ -194,6 +194,7 @@
import logging
from warnings import warn
+from operator import eq
from logilab.common.deprecation import class_renamed
from logilab.common.compat import all, any
@@ -530,17 +531,26 @@
class multi_lines_rset(Selector):
- """If `nb` is specified, return 1 if the result set has exactly `nb` row of
- result. Else (`nb` is None), return 1 if the result set contains *at least*
+ """Return 1 if the operator expression matches between `num` elements
+ in the result set and the `expected` value if defined.
+
+ By default, multi_lines_rset(expected) matches equality expression:
+ `nb` row(s) in result set equals to expected value
+ But, you can perform richer comparisons by overriding default operator:
+ multi_lines_rset(expected, operator.gt)
+
+ If `expected` is None, return 1 if the result set contains *at least*
two rows.
+ If rset is None, return 0.
"""
- def __init__(self, nb=None):
- self.expected = nb
+ def __init__(self, expected=None, operator=eq):
+ self.expected = expected
+ self.operator = operator
def match_expected(self, num):
if self.expected is None:
return num > 1
- return num == self.expected
+ return self.operator(num, self.expected)
@lltrace
def __call__(self, cls, req, rset=None, **kwargs):
--- a/test/unittest_selectors.py Fri Sep 24 15:00:08 2010 +0200
+++ b/test/unittest_selectors.py Fri Sep 24 13:41:13 2010 +0200
@@ -17,12 +17,14 @@
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
"""unit tests for selectors mechanism"""
+from operator import eq, lt, le, gt
from logilab.common.testlib import TestCase, unittest_main
from cubicweb import Binary
from cubicweb.devtools.testlib import CubicWebTC
from cubicweb.appobject import Selector, AndSelector, OrSelector
-from cubicweb.selectors import is_instance, adaptable, match_user_groups
+from cubicweb.selectors import (is_instance, adaptable, match_user_groups,
+ multi_lines_rset)
from cubicweb.interfaces import IDownloadable
from cubicweb.web import action
@@ -190,6 +192,59 @@
finally:
del self.vreg[SomeAction.__registry__][SomeAction.__regid__]
+
+class MultiLinesRsetSelectorTC(CubicWebTC):
+ def setUp(self):
+ super(MultiLinesRsetSelectorTC, self).setUp()
+ self.req = self.request()
+ self.req.execute('INSERT CWGroup G: G name "group1"')
+ self.req.execute('INSERT CWGroup G: G name "group2"')
+ self.commit()
+ self.rset = self.req.execute('Any G WHERE G is CWGroup')
+
+ def test_default_op_in_selector(self):
+ expected = len(self.rset)
+ selector = multi_lines_rset(expected)
+ self.assertEqual(selector(None, self.req, self.rset), 1)
+ self.assertEqual(selector(None, self.req, None), 0)
+ selector = multi_lines_rset(expected + 1)
+ self.assertEqual(selector(None, self.req, self.rset), 0)
+ self.assertEqual(selector(None, self.req, None), 0)
+ selector = multi_lines_rset(expected - 1)
+ self.assertEqual(selector(None, self.req, self.rset), 0)
+ self.assertEqual(selector(None, self.req, None), 0)
+
+ def test_without_rset(self):
+ expected = len(self.rset)
+ selector = multi_lines_rset(expected)
+ self.assertEqual(selector(None, self.req, None), 0)
+ selector = multi_lines_rset(expected + 1)
+ self.assertEqual(selector(None, self.req, None), 0)
+ selector = multi_lines_rset(expected - 1)
+ self.assertEqual(selector(None, self.req, None), 0)
+
+ def test_with_operators(self):
+ expected = len(self.rset)
+
+ # Format 'expected', 'operator', 'assert'
+ testdata = (( expected, eq, 1),
+ ( expected+1, eq, 0),
+ ( expected-1, eq, 0),
+ ( expected, le, 1),
+ ( expected+1, le, 1),
+ ( expected-1, le, 0),
+ ( expected-1, gt, 1),
+ ( expected, gt, 0),
+ ( expected+1, gt, 0),
+ ( expected+1, lt, 1),
+ ( expected, lt, 0),
+ ( expected-1, lt, 0))
+
+ for (expected, operator, assertion) in testdata:
+ selector = multi_lines_rset(expected, operator)
+ yield self.assertEqual, selector(None, self.req, self.rset), assertion
+
+
if __name__ == '__main__':
unittest_main()