summaryrefslogtreecommitdiffstats
path: root/tests/tabular_output/test_output_formatter.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/tabular_output/test_output_formatter.py')
-rw-r--r--tests/tabular_output/test_output_formatter.py173
1 files changed, 173 insertions, 0 deletions
diff --git a/tests/tabular_output/test_output_formatter.py b/tests/tabular_output/test_output_formatter.py
new file mode 100644
index 0000000..0509cb6
--- /dev/null
+++ b/tests/tabular_output/test_output_formatter.py
@@ -0,0 +1,173 @@
+# -*- coding: utf-8 -*-
+"""Test the generic output formatter interface."""
+
+from __future__ import unicode_literals
+from decimal import Decimal
+from textwrap import dedent
+
+import pytest
+
+from cli_helpers.tabular_output import format_output, TabularOutputFormatter
+from cli_helpers.compat import binary_type, text_type
+from cli_helpers.utils import strip_ansi
+
+
+def test_tabular_output_formatter():
+ """Test the TabularOutputFormatter class."""
+ headers = ['text', 'numeric']
+ data = [
+ ["abc", Decimal(1)],
+ ["defg", Decimal("11.1")],
+ ["hi", Decimal("1.1")],
+ ["Pablo\rß\n", 0],
+ ]
+ expected = dedent("""\
+ +------------+---------+
+ | text | numeric |
+ +------------+---------+
+ | abc | 1 |
+ | defg | 11.1 |
+ | hi | 1.1 |
+ | Pablo\\rß\\n | 0 |
+ +------------+---------+"""
+ )
+
+ print(expected)
+ print("\n".join(TabularOutputFormatter().format_output(
+ iter(data), headers, format_name='ascii')))
+ assert expected == "\n".join(TabularOutputFormatter().format_output(
+ iter(data), headers, format_name='ascii'))
+
+
+def test_tabular_format_output_wrapper():
+ """Test the format_output wrapper."""
+ data = [['1', None], ['2', 'Sam'],
+ ['3', 'Joe']]
+ headers = ['id', 'name']
+ expected = dedent('''\
+ +----+------+
+ | id | name |
+ +----+------+
+ | 1 | N/A |
+ | 2 | Sam |
+ | 3 | Joe |
+ +----+------+''')
+
+ assert expected == "\n".join(format_output(iter(data), headers, format_name='ascii',
+ missing_value='N/A'))
+
+
+def test_additional_preprocessors():
+ """Test that additional preprocessors are run."""
+ def hello_world(data, headers, **_):
+ def hello_world_data(data):
+ for row in data:
+ for i, value in enumerate(row):
+ if value == 'hello':
+ row[i] = "{}, world".format(value)
+ yield row
+ return hello_world_data(data), headers
+
+ data = [['foo', None], ['hello!', 'hello']]
+ headers = 'ab'
+
+ expected = dedent('''\
+ +--------+--------------+
+ | a | b |
+ +--------+--------------+
+ | foo | hello |
+ | hello! | hello, world |
+ +--------+--------------+''')
+
+ assert expected == "\n".join(TabularOutputFormatter().format_output(
+ iter(data), headers, format_name='ascii', preprocessors=(hello_world,),
+ missing_value='hello'))
+
+
+def test_format_name_attribute():
+ """Test the the format_name attribute be set and retrieved."""
+ formatter = TabularOutputFormatter(format_name='plain')
+ assert formatter.format_name == 'plain'
+ formatter.format_name = 'simple'
+ assert formatter.format_name == 'simple'
+
+ with pytest.raises(ValueError):
+ formatter.format_name = 'foobar'
+
+
+def test_unsupported_format():
+ """Test that TabularOutputFormatter rejects unknown formats."""
+ formatter = TabularOutputFormatter()
+
+ with pytest.raises(ValueError):
+ formatter.format_name = 'foobar'
+
+ with pytest.raises(ValueError):
+ formatter.format_output((), (), format_name='foobar')
+
+
+def test_tabulate_ansi_escape_in_default_value():
+ """Test that ANSI escape codes work with tabulate."""
+
+ data = [['1', None], ['2', 'Sam'],
+ ['3', 'Joe']]
+ headers = ['id', 'name']
+
+ styled = format_output(iter(data), headers, format_name='psql',
+ missing_value='\x1b[38;5;10mNULL\x1b[39m')
+ unstyled = format_output(iter(data), headers, format_name='psql',
+ missing_value='NULL')
+
+ stripped_styled = [strip_ansi(s) for s in styled]
+
+ assert list(unstyled) == stripped_styled
+
+
+def test_get_type():
+ """Test that _get_type returns the expected type."""
+ formatter = TabularOutputFormatter()
+
+ tests = ((1, int), (2.0, float), (b'binary', binary_type),
+ ('text', text_type), (None, type(None)), ((), text_type))
+
+ for value, data_type in tests:
+ assert data_type is formatter._get_type(value)
+
+
+def test_provide_column_types():
+ """Test that provided column types are passed to preprocessors."""
+ expected_column_types = (bool, float)
+ data = ((1, 1.0), (0, 2))
+ headers = ('a', 'b')
+
+ def preprocessor(data, headers, column_types=(), **_):
+ assert expected_column_types == column_types
+ return data, headers
+
+ format_output(data, headers, 'csv',
+ column_types=expected_column_types,
+ preprocessors=(preprocessor,))
+
+
+def test_enforce_iterable():
+ """Test that all output formatters accept iterable"""
+ formatter = TabularOutputFormatter()
+ loremipsum = 'lorem ipsum dolor sit amet consectetur adipiscing elit sed do eiusmod'.split(' ')
+
+ for format_name in formatter.supported_formats:
+ formatter.format_name = format_name
+ try:
+ formatted = next(formatter.format_output(
+ zip(loremipsum), ['lorem']))
+ except TypeError:
+ assert False, "{0} doesn't return iterable".format(format_name)
+
+
+def test_all_text_type():
+ """Test the TabularOutputFormatter class."""
+ data = [[1, u"", None, Decimal(2)]]
+ headers = ['col1', 'col2', 'col3', 'col4']
+ output_formatter = TabularOutputFormatter()
+ for format_name in output_formatter.supported_formats:
+ for row in output_formatter.format_output(iter(data), headers, format_name=format_name):
+ assert isinstance(row, text_type), "not unicode for {}".format(format_name)