# -*- coding: utf-8 -*-

"""Test support of the various forms of tabular data."""

from __future__ import print_function
from __future__ import unicode_literals
from tabulate import tabulate
from common import assert_equal, assert_in, assert_raises, SkipTest


def test_iterable_of_iterables():
    "Input: an interable of iterables."
    ii = iter(map(lambda x: iter(x), [range(5), range(5,0,-1)]))
    expected = "\n".join(
        ['-  -  -  -  -',
         '0  1  2  3  4',
         '5  4  3  2  1',
         '-  -  -  -  -'])
    result   = tabulate(ii)
    assert_equal(expected, result)


def test_iterable_of_iterables_headers():
    "Input: an interable of iterables with headers."
    ii = iter(map(lambda x: iter(x), [range(5), range(5,0,-1)]))
    expected = "\n".join(
        ['  a    b    c    d    e',
         '---  ---  ---  ---  ---',
         '  0    1    2    3    4',
         '  5    4    3    2    1'])
    result   = tabulate(ii, "abcde")
    assert_equal(expected, result)


def test_iterable_of_iterables_firstrow():
    "Input: an interable of iterables with the first row as headers"
    ii = iter(map(lambda x: iter(x), ["abcde", range(5), range(5,0,-1)]))
    expected = "\n".join(
        ['  a    b    c    d    e',
         '---  ---  ---  ---  ---',
         '  0    1    2    3    4',
         '  5    4    3    2    1'])
    result   = tabulate(ii, "firstrow")
    assert_equal(expected, result)


def test_list_of_lists():
    "Input: a list of lists with headers."
    ll = [["a","one",1],["b","two",None]]
    expected = "\n".join([
        '    string      number',
        '--  --------  --------',
        'a   one              1',
        'b   two'])
    result   = tabulate(ll, headers=["string","number"])
    assert_equal(expected, result)


def test_list_of_lists_firstrow():
    "Input: a list of lists with the first row as headers."
    ll = [["string","number"],["a","one",1],["b","two",None]]
    expected = "\n".join([
        '    string      number',
        '--  --------  --------',
        'a   one              1',
        'b   two'])
    result   = tabulate(ll, headers="firstrow")
    assert_equal(expected, result)


def test_list_of_lists_keys():
    "Input: a list of lists with column indices as headers."
    ll = [["a","one",1],["b","two",None]]
    expected = "\n".join([
        '0    1      2',
        '---  ---  ---',
        'a    one    1',
        'b    two'])
    result   = tabulate(ll, headers="keys")
    assert_equal(expected, result)


def test_dict_like():
    "Input: a dict of iterables with keys as headers."
    # columns should be padded with None, keys should be used as headers
    dd = {"a": range(3), "b": range(101,105)}
    # keys' order (hence columns' order) is not deterministic in Python 3
    # => we have to consider both possible results as valid
    expected1 = "\n".join([
        '  a    b',
        '---  ---',
        '  0  101',
        '  1  102',
        '  2  103',
        '     104'])
    expected2 = "\n".join([
        '  b    a',
        '---  ---',
        '101    0',
        '102    1',
        '103    2',
        '104'])
    result    = tabulate(dd, "keys")
    print("Keys' order: %s" % dd.keys())
    assert_in(result, [expected1, expected2])


def test_numpy_2d():
    "Input: a 2D NumPy array with headers."
    try:
        import numpy
        na = (numpy.arange(1,10, dtype=numpy.float32).reshape((3,3))**3)*0.5
        expected = "\n".join([
            '    a      b      c',
            '-----  -----  -----',
            '  0.5    4     13.5',
            ' 32     62.5  108',
            '171.5  256    364.5'])
        result   = tabulate(na, ["a", "b", "c"])
        assert_equal(expected, result)
    except ImportError:
        print("test_numpy_2d is skipped")
        raise SkipTest()   # this test is optional


def test_numpy_2d_firstrow():
    "Input: a 2D NumPy array with the first row as headers."
    try:
        import numpy
        na = (numpy.arange(1,10, dtype=numpy.int32).reshape((3,3))**3)
        expected = "\n".join([
            '  1    8    27',
            '---  ---  ----',
            ' 64  125   216',
            '343  512   729'])
        result   = tabulate(na, headers="firstrow")
        assert_equal(expected, result)
    except ImportError:
        print("test_numpy_2d_firstrow is skipped")
        raise SkipTest()   # this test is optional



def test_numpy_2d_keys():
    "Input: a 2D NumPy array with column indices as headers."
    try:
        import numpy
        na = (numpy.arange(1,10, dtype=numpy.float32).reshape((3,3))**3)*0.5
        expected = "\n".join([
            '    0      1      2',
            '-----  -----  -----',
            '  0.5    4     13.5',
            ' 32     62.5  108',
            '171.5  256    364.5'])
        result   = tabulate(na, headers="keys")
        assert_equal(expected, result)
    except ImportError:
        print("test_numpy_2d_keys is skipped")
        raise SkipTest()   # this test is optional


def test_numpy_record_array():
    "Input: a 2D NumPy record array without header."
    try:
        import numpy
        na = numpy.asarray([("Alice", 23, 169.5),
                            ("Bob", 27, 175.0)],
                           dtype={"names":["name","age","height"],
                                  "formats":["a32","uint8","float32"]})