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.py271
1 files changed, 271 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..8e1fa92
--- /dev/null
+++ b/tests/tabular_output/test_output_formatter.py
@@ -0,0 +1,271 @@
+# -*- 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 | 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_output_escaped():
+ """Test the ascii_escaped output format."""
+ 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_escaped"
+ )
+ )
+ )
+ assert expected == "\n".join(
+ TabularOutputFormatter().format_output(
+ iter(data), headers, format_name="ascii_escaped"
+ )
+ )
+
+
+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_headless_tabulate_format():
+ """Test that a headless formatter doesn't display headers"""
+ formatter = TabularOutputFormatter(format_name="minimal")
+ headers = ["text", "numeric"]
+ data = [["a"], ["b"], ["c"]]
+ expected = "a\nb\nc"
+ assert expected == "\n".join(
+ TabularOutputFormatter().format_output(
+ iter(data),
+ headers,
+ format_name="minimal",
+ )
+ )
+
+
+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)
+
+
+@pytest.mark.parametrize(
+ "extra_kwargs",
+ [
+ {},
+ {"style": "default"},
+ {"style": "colorful"},
+ ],
+)
+def test_all_text_type(extra_kwargs):
+ """Test the TabularOutputFormatter class."""
+ data = [[1, "", 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, **extra_kwargs
+ ):
+ assert isinstance(row, text_type), "not unicode for {}".format(format_name)