# Path: string_utils/errors.py
# class InvalidInputError(TypeError):
#     """
#     Custom error raised when received object is not a string as expected.
#     """
# 
#     def __init__(self, input_data: Any):
#         """
#         :param input_data: Any received object
#         """
#         type_name = type(input_data).__name__
#         msg = 'Expected "str", received "{}"'.format(type_name)
#         super().__init__(msg)
# 
# Path: string_utils/validation.py
# def is_isbn_13(self) -> bool:
#     if len(self.input_string) == 13:
#         product = 0
# 
#         try:
#             for index, digit in enumerate(self.input_string):
#                 weight = 1 if (index % 2 == 0) else 3
#                 product += int(digit) * weight
# 
#             return product % 10 == 0
# 
#         except ValueError:
#             pass
# 
#     return False


from unittest import TestCase
from string_utils.errors import InvalidInputError
from string_utils.validation import is_isbn_13
    def test_requires_valid_string(self):
        # noinspection PyTypeChecker
        self.assertRaises(InvalidInputError, lambda: is_isbn_13(None))

        # noinspection PyTypeChecker
        self.assertRaises(InvalidInputError, lambda: is_isbn_13(True))

        # noinspection PyTypeChecker
        self.assertRaises(InvalidInputError, lambda: is_isbn_13(9780312498580))

        # noinspection PyTypeChecker
        self.assertRaises(InvalidInputError, lambda: is_isbn_13([9780312498580]))

    def test_returns_true_for_valid_isbn_13(self):
        # isbn numbers have been taken from actual books on amazon
        self.assertTrue(is_isbn_13('9780312498580'))
        self.assertTrue(is_isbn_13('9781941325827'))
        self.assertTrue(is_isbn_13('9780062853851'))
        self.assertTrue(is_isbn_13('9781250107817'))
        self.assertTrue(is_isbn_13('9788891229243'))

    def test_dashes_are_not_considered_by_default(self):
        # isbn numbers have been taken from actual books on amazon
        self.assertTrue(is_isbn_13('978-0312498580'))
        self.assertTrue(is_isbn_13('978-194-132-582-7'))
        self.assertTrue(is_isbn_13('978-0-0-6-2-8-5-3-8-5-1'))

    def test_isbn_not_recognized_if_normalization_is_disabled(self):
        # isbn numbers have been taken from actual books on amazon
        self.assertFalse(is_isbn_13('978-0312498580', normalize=False))

# Path: string_utils/errors.py
# class InvalidInputError(TypeError):
#     """
#     Custom error raised when received object is not a string as expected.
#     """
# 
#     def __init__(self, input_data: Any):
#         """
#         :param input_data: Any received object
#         """
#         type_name = type(input_data).__name__
#         msg = 'Expected "str", received "{}"'.format(type_name)
#         super().__init__(msg)
# 
# Path: string_utils/validation.py
# def is_isbn_13(self) -> bool:
#     if len(self.input_string) == 13:
#         product = 0
# 
#         try:
#             for index, digit in enumerate(self.input_string):
#                 weight = 1 if (index % 2 == 0) else 3
#                 product += int(digit) * weight
# 
#             return product % 10 == 0
# 
#         except ValueError:
#             pass
# 
#     return False


# Path: tests/test_is_isbn_13.py
from unittest import TestCase
from string_utils.errors import InvalidInputError
from string_utils.validation import is_isbn_13

    def test_requires_valid_string(self):
        # noinspection PyTypeChecker
        self.assertRaises(InvalidInputError, lambda: is_isbn_13(None))

        # noinspection PyTypeChecker
        self.assertRaises(InvalidInputError, lambda: is_isbn_13(True))

        # noinspection PyTypeChecker
        self.assertRaises(InvalidInputError, lambda: is_isbn_13(9780312498580))

        # noinspection PyTypeChecker
        self.assertRaises(InvalidInputError, lambda: is_isbn_13([9780312498580]))

    def test_returns_true_for_valid_isbn_13(self):
        # isbn numbers have been taken from actual books on amazon
        self.assertTrue(is_isbn_13('9780312498580'))
        self.assertTrue(is_isbn_13('9781941325827'))
        self.assertTrue(is_isbn_13('9780062853851'))
        self.assertTrue(is_isbn_13('9781250107817'))
        self.assertTrue(is_isbn_13('9788891229243'))

    def test_dashes_are_not_considered_by_default(self):
        # isbn numbers have been taken from actual books on amazon
        self.assertTrue(is_isbn_13('978-0312498580'))
        self.assertTrue(is_isbn_13('978-194-132-582-7'))
        self.assertTrue(is_isbn_13('978-0-0-6-2-8-5-3-8-5-1'))

    def test_isbn_not_recognized_if_normalization_is_disabled(self):
        # isbn numbers have been taken from actual books on amazon
        self.assertFalse(is_isbn_13('978-0312498580', normalize=False))

        self.assertFalse(is_isbn_13('978-194-132-582-7', normalize=False))