Skip to content

Commit 324bb0b

Browse files
committed
Tests for Link expressions
.. and fixes for anydbm backend, this now passes all the new tests.
1 parent 346b24c commit 324bb0b

File tree

4 files changed

+41
-15
lines changed

4 files changed

+41
-15
lines changed

roundup/backends/back_anydbm.py

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1701,13 +1701,7 @@ def _filter(self, search_matches, filterspec, proptree,
17011701
if isinstance(propclass, hyperdb.Link):
17021702
if type(v) is not type([]):
17031703
v = [v]
1704-
u = []
1705-
for entry in v:
1706-
# the value -1 is a special "not set" sentinel
1707-
if entry == '-1':
1708-
entry = None
1709-
u.append(entry)
1710-
l.append((LINK, k, u))
1704+
l.append((LINK, k, v))
17111705
elif isinstance(propclass, hyperdb.Multilink):
17121706
# If it's a reverse multilink, we've already
17131707
# computed the ids of our own class.
@@ -1814,7 +1808,9 @@ def _filter(self, search_matches, filterspec, proptree,
18141808
if t == LINK:
18151809
# link - if this node's property doesn't appear in the
18161810
# filterspec's nodeid list, skip it
1817-
match = nv in v
1811+
expr = Expression(v, is_link=True)
1812+
if expr.evaluate(nv):
1813+
match = 1
18181814
elif t == MULTILINK:
18191815
# multilink - if any of the nodeids required by the
18201816
# filterspec aren't in this node's property, then skip

roundup/hyperdb.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -585,7 +585,8 @@ def search(self, search_matches=None, sort=True, retired=False):
585585
exact_match_spec = {}
586586
for p in self.children:
587587
if 'search' in p.need_for:
588-
if p.children:
588+
x = [c for c in p.children if 'search' in c.need_for]
589+
if x:
589590
p.search(sort=False)
590591
if getattr(p.propclass,'rev_property',None):
591592
pn = p.propclass.rev_property.name
@@ -2122,4 +2123,3 @@ def Choice(name, db, *options):
21222123
cl.create(name=options[i], order=i)
21232124
return Link(name)
21242125

2125-
# vim: set filetype=python sts=4 sw=4 et si :

roundup/mlink_expr.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,16 +87,23 @@ def compile_expression(opcodes):
8787

8888
class Expression:
8989

90-
def __init__(self, v):
90+
def __init__(self, v, is_link=False):
9191
try:
9292
opcodes = [int(x) for x in v]
9393
if min(opcodes) >= -1:
9494
raise ValueError()
9595

9696
compiled = compile_expression(opcodes)
97-
self.evaluate = lambda x: compiled.evaluate([int(y) for y in x])
97+
if is_link:
98+
self.evaluate = lambda x: compiled.evaluate(
99+
x and [int(x)] or [])
100+
else:
101+
self.evaluate = lambda x: compiled.evaluate([int(y) for y in x])
98102
except:
99-
if '-1' in v:
103+
if is_link:
104+
v = [None if x == '-1' else x for x in v]
105+
self.evaluate = lambda x: x in v
106+
elif '-1' in v:
100107
v = [x for x in v if int(x) > 0]
101108
self.evaluate = lambda x: bool(set(x) & set(v)) or not x
102109
else:

test/db_test_base.py

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1854,13 +1854,36 @@ def testFilteringLink(self):
18541854
ae(filt(None, {'status': '1'}, ('+','id'), grp), ['2','3'])
18551855
ae(filt(None, {'status': [], 'status.name': 'unread'}), [])
18561856
ae(filt(None, {a: '-1'}, ('+','id'), grp), ['3','4'])
1857-
# Currently works only for non-sql backends:
1858-
#ae(filt(None, {a: []}, ('+','id'), grp), ['3','4'])
18591857
ae(filt(None, {a: None}, ('+','id'), grp), ['3','4'])
18601858
ae(filt(None, {a: [None]}, ('+','id'), grp), ['3','4'])
18611859
ae(filt(None, {a: ['-1', None]}, ('+','id'), grp), ['3','4'])
18621860
ae(filt(None, {a: ['1', None]}, ('+','id'), grp), ['1', '3','4'])
18631861

1862+
@pytest.mark.xfail
1863+
def testFilteringLinkExpression(self):
1864+
ae, iiter = self.filteringSetup()
1865+
a = 'assignedto'
1866+
for filt in iiter():
1867+
ae(filt(None, {}, ('+',a)), ['3','4','1','2'])
1868+
ae(filt(None, {a: '1'}, ('+',a)), ['1'])
1869+
ae(filt(None, {a: '2'}, ('+',a)), ['2'])
1870+
ae(filt(None, {a: '-1'}, ('+','status')), ['4','3'])
1871+
ae(filt(None, {a: []}, ('+','id')), ['3','4'])
1872+
ae(filt(None, {a: ['-1']}, ('+',a)), ['3','4'])
1873+
ae(filt(None, {a: []}, ('+',a)), ['3','4'])
1874+
ae(filt(None, {a: '-1'}, ('+',a)), ['3','4'])
1875+
ae(filt(None, {a: ['1','-1']}), ['1','3','4'])
1876+
ae(filt(None, {a: ['1','-1']}, ('+',a)), ['3','4','1'])
1877+
ae(filt(None, {a: ['2','-1']}, ('+',a)), ['3','4','2'])
1878+
ae(filt(None, {a: ['1','-2']}), ['2','3','4'])
1879+
ae(filt(None, {a: ['1','-2']}, ('+',a)), ['3','4','2'])
1880+
ae(filt(None, {a: ['-1','-2']}, ('+',a)), ['1','2'])
1881+
ae(filt(None, {a: ['1','2','-3']}, ('+',a)), [])
1882+
ae(filt(None, {a: ['1','2','-4']}, ('+',a)), ['1','2'])
1883+
ae(filt(None, {a: ['1','-2','2','-2','-3']}, ('+',a)), ['3','4'])
1884+
ae(filt(None, {a: ['1','-2','2','-2','-4']}, ('+',a)),
1885+
['3','4','1','2'])
1886+
18641887
def testFilteringRevLink(self):
18651888
ae, iiter = self.filteringSetupTransitiveSearch('user')
18661889
# We have

0 commit comments

Comments
 (0)