#!/usr/bin/env python3

from __future__ import division
from __future__ import print_function

import unittest

from conway import look_and_say


class LookAndSayTests(unittest.TestCase):
    """
    Tests for look_and_say.
    """

    def test_simple(self):
        self.assertEqual(list(look_and_say(1)), ["1", "1"])
        self.assertEqual(list(look_and_say(11)), ["2", "1"])
        self.assertEqual(list(look_and_say(21)), ["1", "2", "1", "1"])

    def test_works_with_string(self):
        self.assertEqual(list(look_and_say("1")), ["1", "1"])
        self.assertEqual(list(look_and_say("11")), ["2", "1"])
        self.assertEqual(list(look_and_say("21")), ["1", "2", "1", "1"])

    def test_empty(self):
        self.assertEqual(list(look_and_say("")), [])

    def test_works_with_generators(self):
        self.assertEqual(list(look_and_say(range(2))), ["1", "0", "1", "1"])
        self.assertEqual(list(look_and_say(range(5))), ["1", "0", "1", "1", "1", "2", "1", "3", "1", "4"])

    def test_multiple_calls(self):
        self.assertEqual(list(look_and_say(look_and_say("1"))), ["2", "1"])
        self.assertEqual(list(look_and_say(look_and_say(look_and_say("1")))), ["1", "2", "1", "1"])

    # Comment the following line to force the check the bonus code
    @unittest.expectedFailure
    def test_bonus1_rev(self):
        from conway import look_and_say_rev
        self.assertEqual(list(look_and_say_rev(look_and_say(1))), ["1"])
        self.assertEqual(list(look_and_say_rev(look_and_say(1211))), ["1", "2", "1", "1"])

    # Comment the following line to force the check the bonus code
    @unittest.expectedFailure
    def test_bonus2_iterator(self):
        # Check look_and_say is well using generator memory-efficiently
        items = iter("123456789" * 10)
        obj = look_and_say(items)
        self.assertEqual(iter(obj), obj)
        # get one item from the next rank of the suite
        self.assertEqual(next(obj), "1")
        # Input iterator should not be fully consumed.
        self.assertEqual(next(items), '3')

        # Check look_and_say is well using generator memory-efficiently
        from conway import look_and_say_rev
        items = iter("12345678" * 10)
        obj = look_and_say_rev(items)
        self.assertEqual(iter(obj), obj)
        # get one item
        self.assertEqual(next(obj), "2")
        # Input iterator should not be fully consumed.
        self.assertEqual(next(items), '3')


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