print w
+def _write(w):
+ """stdout.write wrapper is used to help unittests check what is printed"""
+ stdout.write(w)
+
+
def suggest_missing(miss=None, exclude=[]):
global suggest
sgs = dict(suggest)
def page_hold(index, limit, maxlen):
"""Check if there are results to show, and hold the page when needed
- :param index: (int) > 0
+ :param index: (int) > 0, index of current element
:param limit: (int) 0 < limit <= max, page hold if limit mod index == 0
:param maxlen: (int) Don't hold if index reaches maxlen
:returns: True if there are more to show, False if all results are shown
"""
- if index >= limit and index % limit == 0:
- if index >= maxlen:
- return False
- else:
- print('(%s listed - %s more - "enter" to continue)' % (
- index,
- maxlen - index))
- c = ' '
- while c != '\n':
- c = stdin.read(1)
+ if index >= maxlen:
+ return False
+ if index and index % limit == 0:
+ raw_input('(%s listed - %s more - "enter" to continue)' % (
+ index, maxlen - index))
return True
:param page_size: (int) show results in pages of page_size items, enter to
continue
"""
- if not items:
- return
- elif not (
- isinstance(items, dict) or isinstance(
- items, list) or isinstance(items, dict)):
- print '%s' % items
+ if not (isinstance(items, dict) or isinstance(items, list) or isinstance(
+ items, tuple)):
+ _print('%s' % items if items is not None else '')
return
+ page_size = int(page_size)
try:
- page_size = int(page_size) if int(page_size) > 0 else len(items)
+ page_size = page_size if page_size > 0 else len(items)
except:
page_size = len(items)
num_of_pages = len(items) // page_size
num_of_pages += 1 if len(items) % page_size else 0
for i, item in enumerate(items):
if with_enumeration:
- stdout.write('%s. ' % (i + 1))
- if isinstance(item, dict):
- title = sorted(set(title).intersection(item.keys()))
- if with_redundancy:
- header = ' '.join('%s' % item[key] for key in title)
- else:
- header = ' '.join('%s' % item.pop(key) for key in title)
- print(bold(header))
+ _write('%s. ' % (i + 1))
if isinstance(item, dict):
+ item = dict(item)
+ title = sorted(set(title).intersection(item))
+ pick = item.get if with_redundancy else item.pop
+ header = ' '.join('%s' % pick(key) for key in title)
+ _print(bold(header))
print_dict(item, indent=INDENT_TAB)
- elif isinstance(item, list):
+ elif isinstance(item, list) or isinstance(item, tuple):
print_list(item, indent=INDENT_TAB)
else:
- print(' %s' % item)
+ _print(' %s' % item)
page_hold(i + 1, page_size, len(items))
call_counter = len(PR.mock_calls)
self.assertEqual(sorted(real_calls), sorted(exp_calls))
+ @patch('__builtin__.raw_input')
+ def test_page_hold(self, RI):
+ from kamaki.cli.utils import page_hold
+ ri_counter = 0
+ for args, expected in (
+ ((0, 0, 0), False),
+ ((1, 3, 10), True),
+ ((3, 3, 10), True),
+ ((5, 3, 10), True),
+ ((6, 3, 10), True),
+ ((10, 3, 10), False),
+ ((11, 3, 10), False)):
+ self.assertEqual(page_hold(*args), expected)
+ index, limit, maxlen = args
+ if index and index < maxlen and index % limit == 0:
+ self.assertEqual(ri_counter + 1, len(RI.mock_calls))
+ self.assertEqual(RI.mock_calls[-1], call(
+ '(%s listed - %s more - "enter" to continue)' % (
+ index, maxlen - index)))
+ else:
+ self.assertEqual(ri_counter, len(RI.mock_calls))
+ ri_counter = len(RI.mock_calls)
+
+ @patch('kamaki.cli.utils._print')
+ @patch('kamaki.cli.utils._write')
+ @patch('kamaki.cli.utils.print_dict')
+ @patch('kamaki.cli.utils.print_list')
+ @patch('kamaki.cli.utils.page_hold')
+ @patch('kamaki.cli.utils.bold', return_value='bold')
+ def test_print_items(self, bold, PH, PL, PD, WR, PR):
+ from kamaki.cli.utils import print_items, INDENT_TAB
+ for args in product(
+ (
+ 42, None, 'simple outputs',
+ [1, 2, 3], {1: 1, 2: 2}, (3, 4),
+ ({'k': 1, 'id': 2}, [5, 6, 7], (8, 9), '10')),
+ (('id', 'name'), ('something', 2), ('lala', )),
+ (False, True),
+ (False, True),
+ (0, 1, 2, 10)):
+ items, title, with_enumeration, with_redundancy, page_size = args
+ wr_counter, pr_counter = len(WR.mock_calls), len(PR.mock_calls)
+ pl_counter, pd_counter = len(PL.mock_calls), len(PD.mock_calls)
+ bold_counter, ph_counter = len(bold.mock_calls), len(PH.mock_calls)
+ print_items(*args)
+ if not (isinstance(items, dict) or isinstance(
+ items, list) or isinstance(items, tuple)):
+ self.assertEqual(PR.mock_calls[-1], call(
+ '%s' % items if items is not None else ''))
+ else:
+ for i, item in enumerate(items):
+ if with_enumeration:
+ self.assertEqual(
+ WR.mock_calls[wr_counter],
+ call('%s. ' % (i + 1)))
+ wr_counter += 1
+ if isinstance(item, dict):
+ title = sorted(set(title).intersection(item))
+ pick = item.get if with_redundancy else item.pop
+ header = ' '.join('%s' % pick(key) for key in title)
+ self.assertEqual(
+ bold.mock_calls[bold_counter], call(header))
+ self.assertEqual(
+ PR.mock_calls[pr_counter], call('bold'))
+ self.assertEqual(
+ PD.mock_calls[pd_counter],
+ call(item, indent=INDENT_TAB))
+ pr_counter += 1
+ pd_counter += 1
+ bold_counter += 1
+ elif isinstance(item, list) or isinstance(item, tuple):
+ self.assertEqual(
+ PL.mock_calls[pl_counter],
+ call(item, indent=INDENT_TAB))
+ pl_counter += 1
+ else:
+ self.assertEqual(
+ PR.mock_calls[pr_counter], call(' %s' % item))
+ pr_counter += 1
+ page_size = page_size if page_size > 0 else len(items)
+ self.assertEqual(
+ PH.mock_calls[ph_counter],
+ call(i + 1, page_size, len(items)))
+ ph_counter += 1
+
if __name__ == '__main__':
from sys import argv