#!/usr/bin/env python3

from __future__ import division
from __future__ import print_function

import unittest
from textwrap import dedent

from ascii import Table


class ASCII_TableTests(unittest.TestCase):
    '''
    Tests for Table in ascii.
    '''

    def test_constructor(self):
        Table(((1, 2), (3, 4)))

    def test_string_single_char_cells(self):
        obj = Table((("1", "2"), ("3", "4")))
        result = dedent("""
        | 1 | 2 |
        | - | - |
        | 3 | 4 |
        """)[1:-1]
        self.assertEqual(str(obj), result)

    def test_string_multiple_size_cells(self):
        obj = Table(((1, 2), (3, 4)))
        result = dedent("""
        | 1 | 2 |
        | - | - |
        | 3 | 4 |
        """)[1:-1]
        self.assertEqual(str(obj), result)

    def test_string_multiple_times(self):
        obj = Table(((1, 2), (3, 4)))
        result = dedent("""
        | 1 | 2 |
        | - | - |
        | 3 | 4 |
        """)[1:-1]
        for _ in range(10):
            self.assertEqual(str(obj), result)

    def test_string_multiple_times_from_generator(self):
        obj = Table((range(3), range(3)))
        result = dedent("""
        | 0 | 1 | 2 |
        | - | - | - |
        | 0 | 1 | 2 |
        """)[1:-1]
        for _ in range(10):
            self.assertEqual(str(obj), result)

    def test_repr1(self):
        obj = Table(((1, 2), (3, 4)))
        self.assertEqual(repr(obj), "Table(rows=2, cols=2)")
        obj = Table(((1, 2, 3, 4), (5, 6, 7, 8)))
        self.assertEqual(repr(obj), "Table(rows=2, cols=4)")

    # Comment the following line to force the check the bonus code
    @unittest.expectedFailure
    def test_bonus1(self):
        obj = Table(((1111, 2), (3, 4)))
        obj2 = Table(str(obj))
        result = dedent("""
        | 1111 | 2 |
        | ---- | - |
        |    3 | 4 |
        """)[1:-1]
        self.assertEqual(str(obj2), result)

        wrong_spacing = dedent("""
        | 1111     | 2        |
        | ---- | ---- |
        | 3 |       4 |
        """)[1:-1]
        obj3 = Table(wrong_spacing)
        self.assertEqual(str(obj3), result)

    # Comment the following line to force the check the bonus code
    @unittest.expectedFailure
    def test_bonus2(self):
        obj = Table((range(3), range(3)))
        self.assertEqual(obj[(0, 0)], '0')
        self.assertEqual(obj[0][0], '0')
        self.assertEqual(obj[(1, 2)], '2')
        for row in obj:
            self.assertEqual(row[1], '1')

        result = dedent("""
        | 0 | 1 | 2 |
        | - | - | - |
        | 3 | 1 | 2 |
        """)[1:-1]
        obj[(1, 0)] = 3
        self.assertEqual(str(obj), result)

    # Comment the following line to force the check the bonus code
    @unittest.expectedFailure
    def test_bonus3(self):
        a = Table([[1, 2], [3, 4]])
        self.assertEqual(repr(a), 'Table(rows=2, cols=2)')
        a.append_row((5, 6))
        self.assertEqual(repr(a), 'Table(rows=3, cols=2)')
        a.append_col((7, 8, 9))
        result = dedent("""
        | 1 | 2 | 7 |
        | - | - | - |
        | 3 | 4 | 8 |
        | 5 | 6 | 9 |
        """)[1:-1]
        self.assertEqual(str(a), result)

        a.insert_row(1, (0, 0, 0))
        result = dedent("""
        | 1 | 2 | 7 |
        | - | - | - |
        | 0 | 0 | 0 |
        | 3 | 4 | 8 |
        | 5 | 6 | 9 |
        """)[1:-1]
        self.assertEqual(str(a), result)
        self.assertEqual(a.pop_row(1), ['0', '0', '0'])

        self.assertEqual(a.pop_row(), ['5', '6', '9'])
        self.assertEqual(a.pop_col(1), ['2', '4'])

        result = dedent("""
        | 1 | 7 |
        | - | - |
        | 3 | 8 |
        """)[1:-1]
        self.assertEqual(str(a), result)

        a.insert_col(1, (0, 0))
        result = dedent("""
        | 1 | 0 | 7 |
        | - | - | - |
        | 3 | 0 | 8 |
        """)[1:-1]
        self.assertEqual(str(a), result)

        with self.assertRaises(ValueError):
            a.append_row((1, 2, 3, 4, 5))
        with self.assertRaises(ValueError):
            a.append_col((1, 2, 3, 4, 5))


if __name__ == "__main__":
    unittest.main(verbosity=2)
