Test kamaki.cli.utils up to print_items
authorStavros Sachtouris <saxtouri@admin.grnet.gr>
Fri, 9 Aug 2013 14:22:01 +0000 (17:22 +0300)
committerStavros Sachtouris <saxtouri@admin.grnet.gr>
Fri, 9 Aug 2013 14:22:01 +0000 (17:22 +0300)
Refs: #4058

kamaki/cli/utils/__init__.py
kamaki/cli/utils/test.py

index 57b526c..29f933b 100644 (file)
@@ -62,6 +62,11 @@ def _print(w):
     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)
@@ -229,22 +234,17 @@ def print_list(
 
 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
 
 
@@ -266,36 +266,32 @@ def print_items(
     :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))
 
 
index 0aec8c2..6701cfb 100644 (file)
@@ -201,6 +201,91 @@ class UtilsMethods(TestCase):
                     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