diff --git a/setup.py b/setup.py index d160fa2..42360f6 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setup( name="getbible", - version="1.0.3", + version="1.1.0", author="Llewellyn van der Merwe", author_email="getbible@vdm.io", description="A Python package to retrieving Bible references with ease.", diff --git a/src/getbible/getbible.py b/src/getbible/getbible.py index 58cc3c5..daf5a0b 100644 --- a/src/getbible/getbible.py +++ b/src/getbible/getbible.py @@ -7,6 +7,7 @@ from datetime import datetime, timedelta from typing import Dict, Optional, Union from getbible import GetBibleReference +from getbible import BookReference class GetBible: @@ -26,6 +27,7 @@ def __init__(self, repo_path: str = "https://api.getbible.net", version: str = ' self.__books_cache = {} self.__chapters_cache = {} self.__start_cache_reset_thread() + # Pattern to check valid translations names self.__pattern = re.compile(r'^[a-zA-Z0-9]{1,30}$') # Determine if the repository path is a URL self.__repo_path_url = self.__repo_path.startswith("http://") or self.__repo_path.startswith("https://") @@ -43,11 +45,11 @@ def select(self, reference: str, abbreviation: Optional[str] = 'kjv') -> Dict[st references = reference.split(';') for ref in references: try: - reference = self.__get.ref(ref, abbreviation) + book_reference = self.__get.ref(ref, abbreviation) except ValueError: raise ValueError(f"Invalid reference '{ref}'.") - self.__set_verse(abbreviation, reference.book, reference.chapter, reference.verses, result) + self.__set_verse(abbreviation, book_reference, result) return result @@ -127,18 +129,16 @@ def __calculate_time_until_next_month(self) -> float: first_of_next_month = (now.replace(day=1) + timedelta(days=32)).replace(day=1) return (first_of_next_month - now).total_seconds() - def __set_verse(self, abbreviation: str, book: int, chapter: int, verses: list, result: Dict) -> None: + def __set_verse(self, abbreviation: str, book_ref: BookReference, result: Dict) -> None: """ Set verse information into the result JSON. :param abbreviation: Bible translation abbreviation. - :param book: The book of the Bible. - :param chapter: The chapter number. - :param verses: List of verse numbers. + :param book_ref: The book reference class. :param result: The dictionary to store verse information. """ - cache_key = f"{abbreviation}_{book}_{chapter}" + cache_key = f"{abbreviation}_{book_ref.book}_{book_ref.chapter}" if cache_key not in self.__chapters_cache: - chapter_data = self.__retrieve_chapter_data(abbreviation, book, chapter) + chapter_data = self.__retrieve_chapter_data(abbreviation, book_ref.book, book_ref.chapter) # Convert verses list to dictionary for faster lookup verse_dict = {str(v["verse"]): v for v in chapter_data.get("verses", [])} chapter_data["verses"] = verse_dict @@ -146,18 +146,22 @@ def __set_verse(self, abbreviation: str, book: int, chapter: int, verses: list, else: chapter_data = self.__chapters_cache[cache_key] - for verse in verses: + for verse in book_ref.verses: verse_info = chapter_data["verses"].get(str(verse)) if not verse_info: - raise ValueError(f"Verse {verse} not found in book {book}, chapter {chapter}.") + raise ValueError(f"Verse {verse} not found in book {book_ref.book}, chapter {book_ref.chapter}.") if cache_key in result: existing_verses = {str(v["verse"]) for v in result[cache_key].get("verses", [])} if str(verse) not in existing_verses: result[cache_key]["verses"].append(verse_info) + existing_ref = result[cache_key].get("ref", []) + if str(book_ref.reference) not in existing_ref: + result[cache_key]["ref"].append(book_ref.reference) else: # Include all other relevant elements of your JSON structure result[cache_key] = {key: chapter_data[key] for key in chapter_data if key != "verses"} + result[cache_key]["ref"] = [book_ref.reference] result[cache_key]["verses"] = [verse_info] def __check_translation(self, abbreviation: str) -> None: @@ -169,7 +173,7 @@ def __check_translation(self, abbreviation: str) -> None: """ # Use valid_translation to check if the translation is available if not self.valid_translation(abbreviation): - raise FileNotFoundError(f"Translation ({abbreviation}) not found in this API.") + raise FileNotFoundError(f"Translation ({abbreviation}) not found.") def __generate_path(self, abbreviation: str, file_name: str) -> str: """ @@ -210,7 +214,7 @@ def __retrieve_chapter_data(self, abbreviation: str, book: int, chapter: int) -> :param abbreviation: Bible translation abbreviation. :param book: The book of the Bible. - :param chapter: The chapter number. + :param chapter: The chapter. :return: Chapter data. :raises FileNotFoundError: If the chapter data is not found. """ @@ -218,5 +222,5 @@ def __retrieve_chapter_data(self, abbreviation: str, book: int, chapter: int) -> f"{chapter}.json") chapter_data = self.__fetch_data(self.__generate_path(abbreviation, chapter_file)) if chapter_data is None: - raise FileNotFoundError(f"File {abbreviation}/{book}/{chapter}.json does not exist.") + raise FileNotFoundError(f"Chapter:{chapter} in book:{book} for {abbreviation} not found.") return chapter_data diff --git a/src/getbible/getbible_book_number.py b/src/getbible/getbible_book_number.py index 7dfae17..016752e 100644 --- a/src/getbible/getbible_book_number.py +++ b/src/getbible/getbible_book_number.py @@ -10,8 +10,8 @@ def __init__(self) -> None: Sets up the class by loading all translation tries from the data directory. """ - self._tries = {} - self._data_path = os.path.join(os.path.dirname(__file__), 'data') + self.__tries = {} + self.__data_path = os.path.join(os.path.dirname(__file__), 'data') self.__load_all_translations() def __load_translation(self, filename: str) -> None: @@ -24,19 +24,33 @@ def __load_translation(self, filename: str) -> None: trie = GetBibleReferenceTrie() translation_code = filename.split('.')[0] try: - trie.load(os.path.join(self._data_path, filename)) + trie.load(os.path.join(self.__data_path, filename)) except IOError as e: raise IOError(f"Error loading translation {translation_code}: {e}") - self._tries[translation_code] = trie + self.__tries[translation_code] = trie def __load_all_translations(self) -> None: """ Load all translation tries from the data directory. """ - for filename in os.listdir(self._data_path): + for filename in os.listdir(self.__data_path): if filename.endswith('.json'): self.__load_translation(filename) + def __valid_book_number(self, number: str) -> Optional[int]: + """ + Check if the number is a valid book number. + """ + try: + num = int(number) + if 1 <= num <= 83: + return num + else: + return None + except ValueError: + # Handle the case where the number cannot be converted to an integer + return None + def number(self, reference: str, translation_code: Optional[str] = None, fallback_translations: Optional[List[str]] = None) -> Optional[int]: """ @@ -47,27 +61,30 @@ def number(self, reference: str, translation_code: Optional[str] = None, :param fallback_translations: A list of fallback translations to use if necessary. :return: The book number as an integer if found, None otherwise. """ - if not translation_code or translation_code not in self._tries: + if reference.isdigit(): + return self.__valid_book_number(reference) + + if not translation_code or translation_code not in self.__tries: translation_code = 'kjv' - translation = self._tries.get(translation_code) + translation = self.__tries.get(translation_code) result = translation.search(reference) if translation else None if result and result.isdigit(): return int(result) # If 'kjv' is not the original choice, try it next if translation_code != 'kjv': - translation = self._tries.get('kjv') + translation = self.__tries.get('kjv') result = translation.search(reference) if translation else None if result and result.isdigit(): return int(result) # Fallback to other translations if fallback_translations is None: - fallback_translations = [code for code in self._tries if code != translation_code] + fallback_translations = [code for code in self.__tries if code != translation_code] for code in fallback_translations: - translation = self._tries.get(code) + translation = self.__tries.get(code) result = translation.search(reference) if translation else None if result and result.isdigit(): return int(result) @@ -82,7 +99,7 @@ def dump(self, translation_code: str, filename: str) -> None: :param filename: The name of the file to dump to. :raises ValueError: If no data is available for the specified translation. """ - if translation_code in self._tries: - self._tries[translation_code].dump(filename) + if translation_code in self.__tries: + self.__tries[translation_code].dump(filename) else: raise ValueError(f"No data available for translation: {translation_code}") diff --git a/src/getbible/getbible_reference.py b/src/getbible/getbible_reference.py index 7cc316a..15929fd 100644 --- a/src/getbible/getbible_reference.py +++ b/src/getbible/getbible_reference.py @@ -9,14 +9,15 @@ class BookReference: book: int chapter: int verses: list + reference: str class GetBibleReference: def __init__(self): self.__get_book = GetBibleBookNumber() self.__pattern = re.compile(r'^[\w\s,:-]{1,50}$', re.UNICODE) - self.cache = {} - self.cache_limit = 5000 + self.__cache = {} + self.__cache_limit = 5000 def ref(self, reference: str, translation_code: Optional[str] = None) -> BookReference: """ @@ -30,12 +31,12 @@ def ref(self, reference: str, translation_code: Optional[str] = None) -> BookRef sanitized_ref = self.__sanitize(reference) if not sanitized_ref: raise ValueError(f"Invalid reference '{reference}'.") - if sanitized_ref not in self.cache: + if sanitized_ref not in self.__cache: book_ref = self.__book_reference(reference, translation_code) if book_ref is None: raise ValueError(f"Invalid reference '{reference}'.") self.__manage_local_cache(sanitized_ref, book_ref) - return self.cache[sanitized_ref] + return self.__cache[sanitized_ref] def valid(self, reference: str, translation_code: Optional[str] = None) -> bool: """ @@ -48,10 +49,10 @@ def valid(self, reference: str, translation_code: Optional[str] = None) -> bool: sanitized_ref = self.__sanitize(reference) if sanitized_ref is None: return False - if sanitized_ref not in self.cache: + if sanitized_ref not in self.__cache: book_ref = self.__book_reference(reference, translation_code) self.__manage_local_cache(sanitized_ref, book_ref) - return self.cache[sanitized_ref] is not None + return self.__cache[sanitized_ref] is not None def __sanitize(self, reference: str) -> Optional[str]: """ @@ -80,7 +81,7 @@ def __book_reference(self, reference: str, translation_code: Optional[str] = Non return None verses_arr = self.__get_verses_numbers(verses_portion) chapter_number = self.__extract_chapter(book_chapter) - return BookReference(book=int(book_number), chapter=chapter_number, verses=verses_arr) + return BookReference(book=int(book_number), chapter=chapter_number, verses=verses_arr, reference=reference) except Exception: return None @@ -112,7 +113,7 @@ def __extract_book_name(self, book_chapter: str) -> str: """ if book_chapter.isdigit(): # If the entire string is numeric, return it as is - return book_chapter + return book_chapter.strip() chapter_match = re.search(r'\d+$', book_chapter) return book_chapter[:chapter_match.start()].strip() if chapter_match else book_chapter.strip() @@ -150,10 +151,7 @@ def __get_book_number(self, book_name: str, abbreviation: Optional[str]) -> Opti :param abbreviation: Translation abbreviation. :return: Book number or None if not found. """ - if book_name.isdigit(): - return int(book_name) - book_number = self.__get_book.number(book_name, abbreviation) - return int(book_number) if book_number is not None else None + return self.__get_book.number(book_name, abbreviation) def __manage_local_cache(self, key: str, value: Optional[BookReference]): """ @@ -162,6 +160,6 @@ def __manage_local_cache(self, key: str, value: Optional[BookReference]): :param key: The key to insert into the cache. :param value: The value to associate with the key. """ - if len(self.cache) >= self.cache_limit: - self.cache.pop(next(iter(self.cache))) # Evict the oldest cache item - self.cache[key] = value + if len(self.__cache) >= self.__cache_limit: + self.__cache.pop(next(iter(self.__cache))) # Evict the oldest cache item + self.__cache[key] = value diff --git a/src/getbible/getbible_reference_trie.py b/src/getbible/getbible_reference_trie.py index 323a962..f8e5035 100644 --- a/src/getbible/getbible_reference_trie.py +++ b/src/getbible/getbible_reference_trie.py @@ -11,8 +11,8 @@ def __init__(self) -> None: Sets up the Trie data structure for storing and searching book names. """ - self.root = TrieNode() - self.space_removal_regex = re.compile(r'(\d)\s+(\w)', re.UNICODE) + self.__root = TrieNode() + self.__space_removal_regex = re.compile(r'(\d)\s+(\w)', re.UNICODE) def __preprocess(self, name: str) -> str: """ @@ -22,7 +22,7 @@ def __preprocess(self, name: str) -> str: :return: The processed name in lowercase. """ processed_name = name.replace('.', '') - processed_name = self.space_removal_regex.sub(r'\1\2', processed_name) + processed_name = self.__space_removal_regex.sub(r'\1\2', processed_name) return processed_name.lower() def __insert(self, book_number: str, names: [str]) -> None: @@ -34,7 +34,7 @@ def __insert(self, book_number: str, names: [str]) -> None: """ for name in names: processed_name = self.__preprocess(name) - node = self.root + node = self.__root for char in processed_name: node = node.children.setdefault(char, TrieNode()) node.book_number = book_number @@ -47,7 +47,7 @@ def search(self, book_name: str) -> Optional[str]: :return: The book number if found, None otherwise. """ processed_name = self.__preprocess(book_name) - node = self.root + node = self.__root for char in processed_name: node = node.children.get(char) if node is None: @@ -63,7 +63,7 @@ def __dump_to_dict(self, node: Optional[TrieNode] = None, key: str = '') -> Dict :return: Dictionary representation of the Trie. """ if node is None: - node = self.root + node = self.__root result = {} if node.book_number is not None: diff --git a/tests/test_getbible.py b/tests/test_getbible.py index d8349c7..735cd80 100644 --- a/tests/test_getbible.py +++ b/tests/test_getbible.py @@ -13,7 +13,7 @@ def test_valid_reference(self): expected_result = { "kjv_1_1": {"translation": "King James Version", "abbreviation": "kjv", "lang": "en", "language": "English", "direction": "LTR", "encoding": "UTF-8", "book_nr": 1, "book_name": "Genesis", "chapter": 1, - "name": "Genesis 1", "verses": [{"chapter": 1, "verse": 2, "name": "Genesis 1:2", + "name": "Genesis 1", "ref": ["Gen 1:2-7"], "verses": [{"chapter": 1, "verse": 2, "name": "Genesis 1:2", "text": "And the earth was without form and void; and darkness was upon the face of the deep. And the Spirit of God moved upon the face of the waters."}, {"chapter": 1, "verse": 3, "name": "Genesis 1:3", "text": "And God said, Let there be light: and there was light."}, @@ -33,7 +33,7 @@ def test_valid_reference_cns(self): "cns_1_1": {"translation": "NCV Simplified", "abbreviation": "cns", "lang": "zh-Hans", "language": "Chinese", "direction": "LTR", "encoding": "UTF-8", "book_nr": 1, "book_name": "\ufeff\u521b\u4e16\u8bb0", - "chapter": 1, "name": "\ufeff\u521b\u4e16\u8bb0 1", "verses": [ + "chapter": 1, "name": "\ufeff\u521b\u4e16\u8bb0 1", "ref": ["创世记1:2-7"], "verses": [ {"chapter": 1, "verse": 2, "name": "\ufeff\u521b\u4e16\u8bb0 1:2", "text": "\u5730\u662f\u7a7a\u865a\u6df7\u6c8c\uff1b\u6df1\u6e0a\u4e0a\u4e00\u7247\u9ed1\u6697\uff1b\u3000\u795e\u7684\u7075\u8fd0\u884c\u5728\u6c34\u9762\u4e0a\u3002 "}, {"chapter": 1, "verse": 3, "name": "\ufeff\u521b\u4e16\u8bb0 1:3", @@ -53,15 +53,15 @@ def test_valid_multiple_reference_aov(self): expected_result = { "aov_1_1": {"translation": "Ou Vertaling", "abbreviation": "aov", "lang": "af", "language": "Afrikaans", "direction": "LTR", "encoding": "UTF-8", "book_nr": 1, "book_name": "Genesis", "chapter": 1, - "name": "Genesis 1", "verses": [{"chapter": 1, "verse": 1, "name": "Genesis 1:1", + "name": "Genesis 1", "ref": ['Ge1:1'], "verses": [{"chapter": 1, "verse": 1, "name": "Genesis 1:1", "text": "In die begin het God die hemel en die aarde geskape. "}]}, "aov_43_1": {"translation": "Ou Vertaling", "abbreviation": "aov", "lang": "af", "language": "Afrikaans", "direction": "LTR", "encoding": "UTF-8", "book_nr": 43, "book_name": "Johannes", "chapter": 1, - "name": "Johannes 1", "verses": [{"chapter": 1, "verse": 1, "name": "Johannes 1:1", + "name": "Johannes 1", "ref": ['Jn1:1'], "verses": [{"chapter": 1, "verse": 1, "name": "Johannes 1:1", "text": "In die begin was die Woord, en die Woord was by God, en die Woord was God. "}]}, "aov_62_1": {"translation": "Ou Vertaling", "abbreviation": "aov", "lang": "af", "language": "Afrikaans", "direction": "LTR", "encoding": "UTF-8", "book_nr": 62, "book_name": "1 Johannes", - "chapter": 1, "name": "1 Johannes 1", "verses": [ + "chapter": 1, "name": "1 Johannes 1", "ref": ["1Jn1:1"], "verses": [ {"chapter": 1, "verse": 1, "name": "1 Johannes 1:1", "text": "Wat van die begin af was, wat ons gehoor het, wat ons met ons o\u00eb gesien het, wat ons aanskou het en ons hande getas het aangaande die Woord van die lewe \u2014 "}]}} self.assertEqual(actual_result, expected_result, "Failed to find 'Ge1:1;Jn1:1;1Jn1:1' scripture.") @@ -79,6 +79,7 @@ def test_valid_multiple_reference_select_aleppo(self): 'language': 'Hebrew', 'name': 'תְּהִלִּים 1', 'translation': 'Aleppo Codex', + 'ref': ['Ps1:1', 'ps1:1-2'], 'verses': [{'chapter': 1, 'name': 'תְּהִלִּים 1:1', 'text': '\xa0\xa0אשרי האיש— \xa0\xa0 אשר לא הלך ' @@ -100,6 +101,7 @@ def test_valid_multiple_reference_select_aleppo(self): 'language': 'Hebrew', 'name': 'בְּרֵאשִׁית 1', 'translation': 'Aleppo Codex', + 'ref': ['Ge1:1-3', 'Ge1:6-7,10'], 'verses': [{'chapter': 1, 'name': 'בְּרֵאשִׁית 1:1', 'text': 'בראשית ברא אלהים את השמים ואת הארץ ', @@ -134,6 +136,35 @@ def test_valid_multiple_reference_select_aleppo(self): self.assertEqual(actual_result, expected_result, "Failed to find 'Ge1:1-3;Ps1:1;ps1:1-2;Ge1:6-7,1' scripture.") + def test_invalid_reference_select_aleppo(self): + expected_exception = "Chapter:111 in book:1 for aleppo not found." + with self.assertRaises(FileNotFoundError) as actual: + self.getbible.select('Ge111', 'aleppo') + self.assertEqual(str(actual.exception), expected_exception) + + def test_invalid_reference_select_kjv(self): + expected_exception = "Verse 111 not found in book 1, chapter 1." + with self.assertRaises(ValueError) as actual: + self.getbible.select('Ge 1:111', 'kjv') + self.assertEqual(str(actual.exception), expected_exception) + + def test_invalid_double_dash_reference_select_kjv(self): + expected_exception = "Invalid reference 'Ge 1:1-7-11'." + with self.assertRaises(ValueError) as actual: + self.getbible.select('Ge 1:1-7-11', 'kjv') + self.assertEqual(str(actual.exception), expected_exception) + + def test_invalid_verse_reference_select_kjv(self): + expected_exception = "Verse 32 not found in book 1, chapter 1." + with self.assertRaises(ValueError) as actual: + self.getbible.select('1 1:1-80', 'kjv') + self.assertEqual(str(actual.exception), expected_exception) + + def test_invalid_book_reference_select_kjv(self): + expected_exception = "Invalid reference '112 1:1-80'." + with self.assertRaises(ValueError) as actual: + self.getbible.select('112 1:1-80', 'kjv') + self.assertEqual(str(actual.exception), expected_exception) if __name__ == '__main__': unittest.main() diff --git a/tests/test_getbible_book_number.py b/tests/test_getbible_book_number.py index 83e8808..03a7043 100644 --- a/tests/test_getbible_book_number.py +++ b/tests/test_getbible_book_number.py @@ -47,6 +47,23 @@ def test_valid_first_john(self): actual_result = self.get_book.number('First John', 'kjv') self.assertEqual(actual_result, expected_result, "Failed to find 'First John' in 'kjv' translation") + def test_valid_1_john(self): + expected_result = 62 + actual_result = self.get_book.number('62', 'kjv') + self.assertEqual(actual_result, expected_result, "Failed to find '62' in 'kjv' translation") + + def test_wrong_book_number(self): + actual_result = self.get_book.number('84', 'kjv') + self.assertIsNone(actual_result, "Failed to limit the books in 'kjv' translation to 1-83") + + def test_wrong_book_number_zero(self): + actual_result = self.get_book.number('0', 'kjv') + self.assertIsNone(actual_result, "Failed to limit the books in 'kjv' translation to 1-83") + + def test_wrong_book_number_minus(self): + actual_result = self.get_book.number('-19', 'kjv') + self.assertIsNone(actual_result, "Failed to limit the books in 'kjv' translation to 1-83") + def test_valid_mismatch_nospace_call(self): expected_result = 62 actual_result = self.get_book.number('1Jn', 'aov') diff --git a/tests/test_getbible_reference.py b/tests/test_getbible_reference.py index 330d812..dba5e5d 100644 --- a/tests/test_getbible_reference.py +++ b/tests/test_getbible_reference.py @@ -8,57 +8,57 @@ def setUp(self): self.get = GetBibleReference() def test_valid_reference(self): - expected_result = BookReference(book=1, chapter=1, verses=[2, 3, 4, 5, 6, 7]) + expected_result = BookReference(book=1, chapter=1, verses=[2, 3, 4, 5, 6, 7], reference='Gen 1:2-7') actual_result = self.get.ref('Gen 1:2-7', 'kjv') self.assertEqual(actual_result, expected_result, "Failed to find 'Gen 1:2-7' book reference.") def test_valid_reference_ch(self): - expected_result = BookReference(book=1, chapter=1, verses=[2, 3, 4, 5, 6, 7]) + expected_result = BookReference(book=1, chapter=1, verses=[2, 3, 4, 5, 6, 7], reference='创世记1:2-7') actual_result = self.get.ref('创世记1:2-7', 'cns') self.assertEqual(actual_result, expected_result, "Failed to find '创世记1:2-7' book reference") def test_valid_reference_missing_verse_ch(self): - expected_result = BookReference(book=1, chapter=1, verses=[2]) + expected_result = BookReference(book=1, chapter=1, verses=[2], reference='创记 1:2-') actual_result = self.get.ref('创记 1:2-', 'cus') self.assertEqual(actual_result, expected_result, "Failed to find '创记 1:2-' book reference") def test_valid_reference_missing_verse__ch(self): - expected_result = BookReference(book=1, chapter=1, verses=[5]) + expected_result = BookReference(book=1, chapter=1, verses=[5], reference='创记 1:-5') actual_result = self.get.ref('创记 1:-5', 'cus') self.assertEqual(actual_result, expected_result, "Failed to find '创记 1:-5' book reference") def test_valid_reference_ch_no_trans(self): actual_result = self.get.ref('创世记') - expected_result = BookReference(book=1, chapter=1, verses=[1]) + expected_result = BookReference(book=1, chapter=1, verses=[1], reference='创世记') self.assertEqual(actual_result, expected_result, "Failed to find '创世记 1:1' book reference") def test_valid_reference_ch_no__trans(self): - expected_result = BookReference(book=1, chapter=1, verses=[1]) + expected_result = BookReference(book=1, chapter=1, verses=[1], reference='创记') actual_result = self.get.ref('创记') self.assertEqual(actual_result, expected_result, "Failed to find '创记 1:1' book reference") def test_valid_1_john(self): - expected_result = BookReference(book=62, chapter=1, verses=[1]) + expected_result = BookReference(book=62, chapter=1, verses=[1], reference='1 John') actual_result = self.get.ref('1 John', 'kjv') self.assertEqual(actual_result, expected_result, "Failed to find '1 John 1:1' book reference") def test_valid_1_peter_ch(self): actual_result = self.get.ref('彼得前书', 'cns') - expected_result = BookReference(book=60, chapter=1, verses=[1]) + expected_result = BookReference(book=60, chapter=1, verses=[1], reference='彼得前书') self.assertEqual(actual_result, expected_result, "Failed to find '彼得前书 1:1' book reference") def test_valid_first_john(self): - expected_result = BookReference(book=62, chapter=3, verses=[16, 19, 20, 21]) + expected_result = BookReference(book=62, chapter=3, verses=[16, 19, 20, 21], reference='First John 3:16,19-21') actual_result = self.get.ref('First John 3:16,19-21', 'kjv') self.assertEqual(actual_result, expected_result, "Failed to find 'First John 1:2-7' book reference.") def test_valid_mismatch_nospace_call(self): - expected_result = BookReference(book=62, chapter=1, verses=[1]) + expected_result = BookReference(book=62, chapter=1, verses=[1], reference='1Jn') actual_result = self.get.ref('1Jn', 'aov') self.assertEqual(actual_result, expected_result, "Failed to find '1Jn 1:1' book reference.") def test_valid_mismatch_call(self): - expected_result = BookReference(book=62, chapter=5, verses=[1]) + expected_result = BookReference(book=62, chapter=5, verses=[1], reference='1 John 5') actual_result = self.get.ref('1 John 5', 'aov') self.assertEqual(actual_result, expected_result, "Failed to find '1 John 5:1' book reference.") @@ -69,7 +69,7 @@ def test_invalid_reference(self): self.assertEqual(str(actual.exception), expected_exception) def test_nonexistent_translation(self): - expected_result = BookReference(book=1, chapter=1, verses=[1]) + expected_result = BookReference(book=1, chapter=1, verses=[1], reference='Gen') actual_result = self.get.ref('Gen', 'nonexistent') self.assertEqual(actual_result, expected_result, "Failed to find 'Gen 1:1' book reference.")