from ..utils import TranspileTestCase


class TryExceptTests(TranspileTestCase):

    def test_try_except(self):
        # No exception
        self.assertCodeExecution("""
            try:
                obj = 3
                print('OK')
            except:
                print("Got an error")
            print('Done.')
            """)

        # Caught exception
        self.assertCodeExecution("""
            try:
                obj.no_such_attribute
                print('OK')
            except:
                print("Got an error")
            print('Done.')
            """)

    def test_try_except_unnamed(self):
        # No exception
        self.assertCodeExecution("""
            try:
                obj = 3
                print('OK')
            except NameError:
                print("Got an error")
            print('Done.')
            """)

        # Caught exception
        self.assertCodeExecution("""
            try:
                obj.no_such_attribute
                print('OK')
            except NameError:
                print("Got an error")
            print('Done.')
            """)

        # Uncaught exception
        self.assertCodeExecution("""
            try:
                obj = int('asdf')
                print('OK')
            except NameError:
                print("Got an error")
            print('Done.')
            """)

    def test_try_except_named(self):
        # No exception
        self.assertCodeExecution("""
            try:
                obj = 3
                print('OK')
            except NameError as e:
                print("Got a NameError")
            print('Done.')
            """)

        # Caught exception
        self.assertCodeExecution("""
            try:
                obj.no_such_attribute
                print('OK')
            except NameError as e:
                print("Got a NameError")
            print('Done.')
            """)

        # Uncaught exception
        self.assertCodeExecution("""
            try:
                obj = int('asdf')
                print('OK')
            except NameError as e:
                print("Got a NameError")
            print('Done.')
            """)

    def test_try_multiple_except(self):
        # No exception
        self.assertCodeExecution("""
            try:
                obj = 3
                print('OK')
            except NameError:
                print("Got a NameError")
            except AttributeError:
                print("Got an AttributeError")
            print('Done.')
            """)

        # Caught first exception
        self.assertCodeExecution("""
            try:
                obj.no_such_attribute
                print('OK')
            except NameError:
                print("Got a NameError")
            except AttributeError:
                print("Got an AttributeError")
            print('Done.')
            """)

        # Caught second exception
        self.assertCodeExecution("""
            try:
                obj.no_such_attribute
                print('OK')
            except AttributeError:
                print("Got an AttributeError")
            except NameError:
                print("Got a NameError")
            print('Done.')
            """)

        # Uncaught exception
        self.assertCodeExecution("""
            try:
                obj = int('asdf')
                print('OK')
            except NameError:
                print("Got a NameError")
            except AttributeError:
                print("Got an AttributeError")
            print('Done.')
            """)

    def test_try_multiple_except_named(self):
        # No exception
        self.assertCodeExecution("""
            try:
                obj = 3
                print('OK')
            except NameError:
                print("Got a NameError")
            except AttributeError:
                print("Got an AttributeError")
            print('Done.')
            """)

        # Caught first exception
        self.assertCodeExecution("""
            try:
                obj.no_such_attribute
                print('OK')
            except NameError as e:
                print("Got a NameError")
            except AttributeError as e:
                print("Got an AttributeError")
            print('Done.')
            """)

        # Caught second exception
        self.assertCodeExecution("""
            try:
                obj.no_such_attribute
                print('OK')
            except AttributeError as e:
                print("Got an AttributeError")
            except NameError as e:
                print("Got a NameError")
            print('Done.')
            """)

        # Uncaught exception
        self.assertCodeExecution("""
            try:
                obj = int('asdf')
                print('OK')
            except NameError as e:
                print("Got a NameError")
            except AttributeError as e:
                print("Got an AttributeError")
            print('Done.')
            """)

    def test_try_multiple_match_except_unnamed(self):
        # No exception
        self.assertCodeExecution("""
            try:
                obj = 3
                print('OK')
            except (NameError, TypeError):
                print("Got a NameError")
            except AttributeError:
                print("Got an AttributeError")
            print('Done.')
            """)

        # Caught first exception, first handler
        self.assertCodeExecution("""
            try:
                obj.no_such_attribute
                print('OK')
            except (NameError, TypeError):
                print("Got a NameError")
            except AttributeError:
                print("Got an AttributeError")
            print('Done.')
            """)

        # Caught second exception, first handler
        self.assertCodeExecution("""
            try:
                obj.no_such_attribute
                print('OK')
            except (TypeError, NameError):
                print("Got a NameError")
            except AttributeError:
                print("Got an AttributeError")
            print('Done.')
            """)

        # Caught first exception, second handler
        self.assertCodeExecution("""
            try:
                obj.no_such_attribute
                print('OK')
            except AttributeError:
                print("Got an AttributeError")
            except (NameError, TypeError):
                print("Got a NameError")
            print('Done.')
            """)

        # Caught second exception, second handler
        self.assertCodeExecution("""
            try:
                obj.no_such_attribute
                print('OK')
            except AttributeError:
                print("Got an AttributeError")
            except (TypeError, NameError):
                print("Got a NameError")
            print('Done.')
            """)

        # Uncaught exception
        self.assertCodeExecution("""
            try:
                obj = int('asdf')
                print('OK')
            except (NameError, TypeError):
                print("Got a TypeError")
            except AttributeError:
                print("Got an AttributeError")
            print('Done.')
            """)

    def test_try_multiple_match_except_named(self):
        # No exception
        self.assertCodeExecution("""
            try:
                obj = 3
                print('OK')
            except (NameError, TypeError) as e:
                print("Got a NameError")
            except AttributeError as e:
                print("Got an AttributeError")
            print('Done.')
            """)

        # Caught first exception, first handler
        self.assertCodeExecution("""
            try:
                obj.no_such_attribute
                print('OK')
            except (NameError, TypeError) as e:
                print("Got a NameError")
            except AttributeError as e:
                print("Got an AttributeError")
            print('Done.')
            """)

        # Caught second exception, first handler
        self.assertCodeExecution("""
            try:
                obj.no_such_attribute
                print('OK')
            except (TypeError, NameError) as e:
                print("Got a NameError")
            except AttributeError as e:
                print("Got an AttributeError")
            print('Done.')
            """)

        # Caught first exception, second handler
        self.assertCodeExecution("""
            try:
                obj.no_such_attribute
                print('OK')
            except AttributeError as e:
                print("Got an AttributeError")
            except (NameError, TypeError) as e:
                print("Got a NameError")
            print('Done.')
            """)

        # Caught second exception, second handler
        self.assertCodeExecution("""
            try:
                obj.no_such_attribute
                print('OK')
            except AttributeError as e:
                print("Got an AttributeError")
            except (TypeError, NameError) as e:
                print("Got a NameError")
            print('Done.')
            """)

        # Uncaught exception
        self.assertCodeExecution("""
            try:
                obj = int('asdf')
                print('OK')
            except (NameError, TypeError) as e:
                print("Got a TypeError")
            except AttributeError as e:
                print("Got an AttributeError")
            print('Done.')
            """)

    def test_try_multiple_except_mixed1(self):
        # No exception
        self.assertCodeExecution("""
            try:
                obj = 3
                print('OK')
            except NameError:
                print("Got a NameError")
            except AttributeError as e:
                print("Got an AttributeError")
            print('Done.')
            """)

        # Caught exception
        self.assertCodeExecution("""
            try:
                obj.no_such_attribute
                print('OK')
            except NameError:
                print("Got a NameError")
            except AttributeError as e:
                print("Got an AttributeError")
            print('Done.')
            """)

        # Uncaught exception
        self.assertCodeExecution("""
            try:
                obj = int('asdf')
                print('OK')
            except NameError:
                print("Got a NameError")