Skip to content

Commit

Permalink
feat(Harvester): make min/max filters effective everywhere
Browse files Browse the repository at this point in the history
cc -j, cc --xml, mi -j all respect min/max filters.

Closes #62
  • Loading branch information
rubik committed Sep 6, 2014
1 parent 1ca7d48 commit 0c4f534
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 14 deletions.
34 changes: 26 additions & 8 deletions radon/cli/harvest.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,16 @@ def caching_iterator(it, r):
return self._results
return caching_iterator(self.run(), self._results)

@property
def filtered_results(self):
'''A proxy around :attr:`results`. Subclasses must implement correct
behavior.
'''
return self.results

def as_json(self):
'''Format the results as JSON.'''
return json.dumps(dict(self.results))
return json.dumps(dict(self.filtered_results))

def as_xml(self):
'''Format the results as XML.'''
Expand All @@ -115,11 +122,14 @@ def gobble(self, fobj):
def _to_dicts(self):
'''Format the results as a dictionary of dictionaries.'''
result = {}
for key, data in self.results:
for key, data in self.filtered_results:
if 'error' in data:
result[key] = data
continue
result[key] = list(map(cc_to_dict, data))
values = [v for v in map(cc_to_dict, data)
if self.config.min <= v['rank'] <= self.config.max]
if values:
result[key] = values
return result

def as_json(self):
Expand Down Expand Up @@ -204,21 +214,29 @@ class MIHarvester(Harvester):

def gobble(self, fobj):
'''Analyze the content of the file object.'''
return {'mi': mi_visit(fobj.read(), self.config.multi)}
mi = mi_visit(fobj.read(), self.config.multi)
rank = mi_rank(mi)
return {'mi': mi, 'rank': rank}

@property
def filtered_results(self):
'''Filter results with respect with their rank.'''
for key, value in self.results:
if ('error' in value or
self.config.min <= value['rank'] <= self.config.max):
yield (key, value)

def as_xml(self):
'''Placeholder method. Currently not implemented.'''
raise NotImplementedError('Cannot export results as XML')

def to_terminal(self):
'''Yield lines to be printed to a terminal.'''
for name, mi in self.results:
for name, mi in self.filtered_results:
if 'error' in mi:
yield name, (mi['error'],), {'error': True}
continue
rank = mi_rank(mi['mi'])
if not self.config.min <= rank <= self.config.max:
continue
rank = mi['rank']
color = MI_RANKS[rank]
to_show = ''
if self.config.show:
Expand Down
32 changes: 26 additions & 6 deletions radon/tests/test_cli_harvest.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
CC_CONFIG = Config(
order='SCORE',
no_assert=False,
min='B',
min='A',
max='F',
show_complexity=False,
average=True,
Expand Down Expand Up @@ -123,6 +123,11 @@ def test_to_dicts(self, c2d_mock):
self.assertEqual(h._to_dicts(), dict(sample_results))
self.assertEqual(c2d_mock.call_count, 2)

h.config.min = 'B'
h._results = sample_results[1:]
self.assertEqual(h._to_dicts(), dict(sample_results[1:]))
h.config.min = 'A'

@mock.patch('radon.cli.harvest.dict_to_xml')
def test_as_json_xml(self, d2x_mock):
to_dicts_mock = mock.MagicMock()
Expand Down Expand Up @@ -233,14 +238,28 @@ class TestMIHarvester(unittest.TestCase):
def test_gobble(self, mv_mock):
fobj = mock.MagicMock()
fobj.read.return_value = mock.sentinel.one
mv_mock.return_value = mock.sentinel.two
mv_mock.return_value = 23.5

h = harvest.MIHarvester([], MI_CONFIG)
result = h.gobble(fobj)

self.assertEqual(fobj.read.call_count, 1)
mv_mock.assert_called_once_with(mock.sentinel.one, MI_CONFIG.multi)
self.assertEqual(result, {'mi': mock.sentinel.two})
self.assertEqual(result, {'mi': 23.5, 'rank': 'A'})

@mock.patch('radon.cli.harvest.json.dumps')
def test_as_json(self, d_mock):
h = harvest.MIHarvester([], MI_CONFIG)
h.config.min = 'C'
h._results = [
('a', {'error': 'mystr'}),
('b', {'mi': 25, 'rank': 'A'}),
('c', {'mi': 15, 'rank': 'B'}),
('d', {'mi': 0, 'rank': 'C'}),
]

h.as_json()
d_mock.assert_called_with(dict([h._results[0], h._results[-1]]))

def test_as_xml(self):
h = harvest.MIHarvester([], MI_CONFIG)
Expand All @@ -253,11 +272,12 @@ def test_to_terminal(self, ranks_mock, reset_mock):
reset_mock.__eq__.side_effect = lambda o: o == '__R__'

h = harvest.MIHarvester([], MI_CONFIG)
h.config.min = 'B'
h._results = [
('a', {'error': 'mystr'}),
('b', {'mi': 25}),
('c', {'mi': 15}),
('d', {'mi': 0}),
('b', {'mi': 25, 'rank': 'A'}),
('c', {'mi': 15, 'rank': 'B'}),
('d', {'mi': 0, 'rank': 'C'}),
]

self.assertEqual(list(h.to_terminal()), [
Expand Down

0 comments on commit 0c4f534

Please sign in to comment.