Subrecord improvement and more tests
still has a huge issue in that records *must* have side effects
This commit is contained in:
parent
cb29e77a05
commit
07f50fb6a1
@ -123,6 +123,11 @@ class ValidationError(Exception):
|
|||||||
self.record = record
|
self.record = record
|
||||||
|
|
||||||
def _dotted_get(d, path):
|
def _dotted_get(d, path):
|
||||||
|
"""
|
||||||
|
utility function for SubrecordFilter
|
||||||
|
|
||||||
|
dives into a complex nested dictionary with paths like a.b.c
|
||||||
|
"""
|
||||||
if path:
|
if path:
|
||||||
key_pieces = path.split('.', 1)
|
key_pieces = path.split('.', 1)
|
||||||
piece = d[key_pieces[0]]
|
piece = d[key_pieces[0]]
|
||||||
@ -134,15 +139,29 @@ def _dotted_get(d, path):
|
|||||||
return d
|
return d
|
||||||
|
|
||||||
class SubrecordFilter(Filter):
|
class SubrecordFilter(Filter):
|
||||||
|
""" Filter that calls another filter on subrecord(s) of a record
|
||||||
|
|
||||||
|
Takes a dotted path (eg. a.b.c) and instantiated filter and runs that
|
||||||
|
filter on all subrecords found at the path.
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self, field_path, filter_):
|
def __init__(self, field_path, filter_):
|
||||||
|
#if '.' in field_path:
|
||||||
|
# self.field_path, self.key = field_path.rsplit('.', 1)
|
||||||
|
#else:
|
||||||
|
# self.field_path = None
|
||||||
|
# self.key = field_path
|
||||||
self.field_path = field_path
|
self.field_path = field_path
|
||||||
self.filter = filter_
|
self.filter = filter_
|
||||||
|
|
||||||
def process_record(self, record):
|
def process_record(self, record):
|
||||||
|
#if self.field_path:
|
||||||
subrecord = _dotted_get(record, self.field_path)
|
subrecord = _dotted_get(record, self.field_path)
|
||||||
for p in subrecord:
|
if isinstance(subrecord, (tuple, list)):
|
||||||
p = self.filter.process_record(p)
|
for p in subrecord:
|
||||||
|
self.filter.process_record(p)
|
||||||
|
else:
|
||||||
|
self.filter.process_record(subrecord)
|
||||||
return record
|
return record
|
||||||
|
|
||||||
#####################
|
#####################
|
||||||
|
@ -100,14 +100,13 @@ class FilterTestCase(unittest.TestCase):
|
|||||||
# ensure only even numbers remain
|
# ensure only even numbers remain
|
||||||
self.assertEquals(list(result), [0,2,4,6,8])
|
self.assertEquals(list(result), [0,2,4,6,8])
|
||||||
|
|
||||||
### FILTERS FOR Subrecord
|
### Tests for Subrecord
|
||||||
|
|
||||||
def test_subrecord_filter(self):
|
def test_subrecord_filter_list(self):
|
||||||
data = [{'a': [{'b': 2}, {'b': 4}]},
|
data = [{'a': [{'b': 2}, {'b': 4}]},
|
||||||
{'a': [{'b': 5}]},
|
{'a': [{'b': 5}]},
|
||||||
{'a': [{'b': 8}, {'b':2}, {'b':1}]}]
|
{'a': [{'b': 8}, {'b':2}, {'b':1}]}]
|
||||||
|
|
||||||
|
|
||||||
expected = [{'a': [{'b': 4}, {'b': 8}]},
|
expected = [{'a': [{'b': 4}, {'b': 8}]},
|
||||||
{'a': [{'b': 10}]},
|
{'a': [{'b': 10}]},
|
||||||
{'a': [{'b': 16}, {'b':4}, {'b':2}]}]
|
{'a': [{'b': 16}, {'b':4}, {'b':2}]}]
|
||||||
@ -117,6 +116,57 @@ class FilterTestCase(unittest.TestCase):
|
|||||||
|
|
||||||
self.assertEquals(list(result), expected)
|
self.assertEquals(list(result), expected)
|
||||||
|
|
||||||
|
def test_subrecord_filter_deep(self):
|
||||||
|
data = [{'a': {'d':[{'b': 2}, {'b': 4}]}},
|
||||||
|
{'a': {'d':[{'b': 5}]}},
|
||||||
|
{'a': {'d':[{'b': 8}, {'b':2}, {'b':1}]}}]
|
||||||
|
|
||||||
|
expected = [{'a': {'d':[{'b': 4}, {'b': 8}]}},
|
||||||
|
{'a': {'d':[{'b': 10}]}},
|
||||||
|
{'a': {'d':[{'b': 16}, {'b':4}, {'b':2}]}}]
|
||||||
|
|
||||||
|
sf = SubrecordFilter('a.d', FieldDoubler('b'))
|
||||||
|
result = sf.attach(data)
|
||||||
|
|
||||||
|
self.assertEquals(list(result), expected)
|
||||||
|
|
||||||
|
def test_subrecord_filter_nonlist(self):
|
||||||
|
data = [
|
||||||
|
{'a':{'b':{'c':1}}},
|
||||||
|
{'a':{'b':{'c':2}}},
|
||||||
|
{'a':{'b':{'c':3}}},
|
||||||
|
]
|
||||||
|
|
||||||
|
expected = [
|
||||||
|
{'a':{'b':{'c':2}}},
|
||||||
|
{'a':{'b':{'c':4}}},
|
||||||
|
{'a':{'b':{'c':6}}},
|
||||||
|
]
|
||||||
|
|
||||||
|
sf = SubrecordFilter('a.b', FieldDoubler('c'))
|
||||||
|
result = sf.attach(data)
|
||||||
|
|
||||||
|
self.assertEquals(list(result), expected)
|
||||||
|
|
||||||
|
def test_subrecord_filter_list_in_path(self):
|
||||||
|
data = [
|
||||||
|
{'a': [{'b': {'c': 5}}, {'b': {'c': 6}}]},
|
||||||
|
{'a': [{'b': {'c': 1}}, {'b': {'c': 2}}, {'b': {'c': 3}}]},
|
||||||
|
{'a': [{'b': {'c': 2}} ]}
|
||||||
|
]
|
||||||
|
|
||||||
|
expected = [
|
||||||
|
{'a': [{'b': {'c': 10}}, {'b': {'c': 12}}]},
|
||||||
|
{'a': [{'b': {'c': 2}}, {'b': {'c': 4}}, {'b': {'c': 6}}]},
|
||||||
|
{'a': [{'b': {'c': 4}} ]}
|
||||||
|
]
|
||||||
|
|
||||||
|
sf = SubrecordFilter('a.b', FieldDoubler('c'))
|
||||||
|
result = sf.attach(data)
|
||||||
|
|
||||||
|
self.assertEquals(list(result), expected)
|
||||||
|
|
||||||
|
### Tests for Generic Filters
|
||||||
|
|
||||||
def test_field_modifier(self):
|
def test_field_modifier(self):
|
||||||
# another version of FieldDoubler
|
# another version of FieldDoubler
|
||||||
|
Loading…
Reference in New Issue
Block a user