def test_search_multiple_manual_delimiter(self):
     bible = WebExtractor()
     text1 = '\n'.join(
         [bible.search('Ecclesiastes 1:17'),
          bible.search('Philemon 1:1')])
     text2 = bible.search_multiple(['Ecclesiastes 1:17;Philemon 1:1', ''])
     # While unconventional, this still resolves to a valid search URL
     self.assertEqual(text1, text2, 'Passage is incorrect')
 def test_get_passage_lowercase_translation(self):
     bible = WebExtractor(translation='NLT')
     passage = 'Ecclesiastes 1:17'
     text1 = bible.search(passage)
     bible.translation = 'nlt'
     text2 = bible.search(passage)
     # Translations should be case insensitive under the hood
     self.assertEqual(text1, text2, 'Passages do not match')
 def test_get_online_chapters_with_excessive_values(self):
     bible = WebExtractor()
     text1 = bible.search('Ecclesiastes 1')
     text2 = bible.get_chapters('Ecclesiastes', -1, -1)
     self.assertEqual(text1, text2, 'Passage is incorrect')
     # This should scale down to the last chapter number of the book
     text1 = bible.search('Ecclesiastes 12')
     text2 = bible.get_chapters('Ecclesiastes', 1000, 1000)
     self.assertEqual(text1, text2, 'Passage is incorrect')
 def test_get_online_passage_range_with_excessive_values(self):
     bible = WebExtractor()
     text1 = bible.search('Ecclesiastes 1:1')
     text2 = bible.get_passage_range('Ecclesiastes', -1, -1, -1, -1)
     self.assertEqual(text1, text2, 'Passage is incorrect')
     # Starting passage is not valid
     self.assertRaises(InvalidSearchError, bible.get_passage_range,
                       'Ecclesiastes', 1000, 1000, 1000, 1000)
     # Starting passage is valid again
     text1 = bible.search('Ecclesiastes 12')
     text2 = bible.get_passage_range('Ecclesiastes', 1000, -1, 1000, 1000)
     self.assertEqual(text1, text2, 'Passage is incorrect')
 def test_search_multiple_duplicate_entries(self):
     bible = WebExtractor()
     expected_passage = bible.search('Ecclesiastes 1:17')
     text1 = '\n'.join([expected_passage, expected_passage])
     text2 = bible.search_multiple(
         ['Ecclesiastes 1:17', 'Ecclesiastes 1:17'])
     self.assertEqual(text1, text2, 'Passage is incorrect')
 def test_get_passage(self):
     bible = WebExtractor()
     text = bible.search('Ecclesiastes 1:17')
     self.assertEqual(
         '\u00b9\u2077 Then I applied myself to the understanding of wisdom, and also of '
         'madness and folly, but I learned that this, too, is a chasing after the wind.',
         text, 'Passage is incorrect')
 def test_get_passage_with_dual_unicode_quotation_marks(self):
     bible = WebExtractor()
     text = bible.search('Leviticus 15:12')
     lev15_12 = '\u00b9\u00b2 \u201c\u2018A clay pot that the man touches must be broken,' \
                ' and any wooden article is to be rinsed with water.'
     # Preserve both sets of Unicode quotation marks
     self.assertEqual(lev15_12, text, 'Passage is incorrect')
 def test_get_empty_passage(self):
     bible = WebExtractor()
     text = bible.search('Luke 17:36')
     luke17_36 = '\u00b3\u2076'
     # In rare cases, the passage can be empty/non-existent depending on the particular translation used.
     # For NIV, this passage is left empty, but ESV outright omits the passage.
     self.assertEqual(luke17_36, text, 'Passage is incorrect')
 def test_get_passage_esv_translation_note(self):
     bible = WebExtractor(translation='ESV')
     text = bible.search('John 7:53')
     john7_53 = '\u2075\u00b3 They went each to his own house,'
     # Translation notes can vary between translations in both content and tag representation.
     # This could be problematic depending on how many form variations are present on the Bible Gateway site.
     self.assertEqual(john7_53, text, 'Passage is incorrect')
 def test_get_passage_web_multiple_inline_references(self):
     bible = WebExtractor(translation='WEB')
     text = bible.search('Mark 13:25')
     mark13_25 = '\u00b2\u2075 the stars will be falling from the sky, ' \
                 'and the powers that are in the heavens will be shaken.'
     # Multiple in-line references are separated by a semi-solon, which should also be omitted
     self.assertEqual(mark13_25, text, 'Passage is incorrect')
 def test_get_passage_with_spaced_out_passage_details(self):
     bible = WebExtractor()
     text = bible.search(
         '  Titus                       2                 :                     1  '
     )
     titus2_1 = 'You, however, must teach what is appropriate to sound doctrine.'
     # The Bible Gateway search engine currently removes superfluous spaces in the passage string
     self.assertEqual(titus2_1, text, 'Passage is incorrect')
 def test_get_passage_with_italics_and_unicode_quotation_marks(self):
     bible = WebExtractor()
     text = bible.search('Matthew 27:46')
     # Preserve Unicode quotation marks, and don't bother trying to carry over the italics styling.
     self.assertEqual(
         '\u2074\u2076 About three in the afternoon Jesus cried out in a loud voice, '
         '\u201cEli, Eli, lema sabachthani?\u201d (which means \u201cMy God, my God, '
         'why have you forsaken me?\u201d).', text, 'Passage is incorrect')
 def test_get_passage_with_footnotes(self):
     bible = WebExtractor()
     text = bible.search('Nehemiah 7:71')
     # Footnotes are to be ignored
     self.assertEqual(
         '\u2077\u00b9 Some of the heads of the families gave to the treasury '
         'for the work 20,000 darics of gold and 2,200 minas of silver.',
         text, 'Passage is incorrect')
 def test_get_passage_list_from_string_without_passage_numbers(self):
     bible = WebExtractor(output_as_list=True, show_passage_numbers=False)
     text = bible.search('Haggai 1:3 - 4')
     haggai1 = [
         'Then the word of the Lord came through the prophet Haggai: ',
         '\u201cIs it a time for you yourselves to be living in your paneled houses, '
         'while this house remains a ruin?\u201d'
     ]
     self.assertEqual(haggai1, text, 'Passage is incorrect')
 def test_get_passage_nrsv_double_spaces(self):
     bible = WebExtractor(translation='NRSV')
     text = bible.search('Matthew 1:2 - 3')
     matt = '\u00b2 Abraham was the father of Isaac, and Isaac the father of Jacob, ' \
            'and Jacob the father of Judah and his brothers, ' \
            '\u00b3 and Judah the father of Perez and Zerah by Tamar, and Perez the father of Hezron, ' \
            'and Hezron the father of Aram,'
     # Trailing double space at the end of verse 2 should just shorten to a single space
     self.assertEqual(matt, text, 'Passage is incorrect')
 def test_get_passage_list_from_string_nlt(self):
     bible = WebExtractor(output_as_list=True, translation='NLT')
     text = bible.search('1 John 1:8 - 9')
     john = [
         '\u2078 If we claim we have no sin, we are only fooling ourselves and not living in the truth. ',
         '\u2079 But if we confess our sins to him, he is faithful and just to forgive us our sins and '
         'to cleanse us from all wickedness.'
     ]
     self.assertEqual(john, text, 'Passage is incorrect')
 def test_get_empty_passage_midway(self):
     bible = WebExtractor()
     text = bible.search('Luke 23:16 - 18')
     luke17 = [
         '\u00b9\u2076 Therefore, I will punish him and then release him.\u201d \u00b9\u2077 ',
         '\u00b9\u2078 But the whole crowd shouted, \u201cAway with this man! Release Barabbas to us!\u201d'
     ]
     # An empty passage in the middle of two other passages preserves its spaces
     self.assertEqual('\n'.join(luke17), text, 'Passage is incorrect')
 def test_get_passage_nkjv_interlude(self):
     bible = WebExtractor(translation='NKJV')
     text = bible.search('Psalm 32:4')
     psalm32_4 = [
         '\u2074 For day and night Your hand was heavy upon me;',
         'My vitality was turned into the drought of summer. Selah'
     ]
     # Explicit interludes should be omitted, and usually show as italicised text in the Psalm.
     self.assertEqual('\n'.join(psalm32_4), text, 'Passage is incorrect')
 def test_get_passage_list_from_string(self):
     bible = WebExtractor(output_as_list=True)
     text = bible.search('1 John 1:8 - 9')
     john = [
         '\u2078 If we claim to be without sin, we deceive ourselves and the truth is not in us. ',
         '\u2079 If we confess our sins, he is faithful and just and will forgive us our sins and purify '
         'us from all unrighteousness.'
     ]
     self.assertEqual(john, text, 'Passage is incorrect')
 def test_get_passage_with_indentations(self):
     bible = WebExtractor()
     text = bible.search('Ecclesiastes 1:3')
     ecc1_3 = [
         '\u00b3 What do people gain from all their labors',
         '    at which they toil under the sun?'
     ]
     # Preserve leading spaces in the second line of the passage
     self.assertEqual('\n'.join(ecc1_3), text, 'Passage is incorrect')
 def test_get_passage_with_headings(self):
     bible = WebExtractor()
     text = bible.search('Exodus 22:31-23:1')
     ex22 = '\u00b3\u00b9 \u201cYou are to be my holy people. So do not eat the meat of an animal ' \
            'torn by wild beasts; throw it to the dogs. '
     ex23 = '\u201cDo not spread false reports. Do not help a guilty person by being a malicious witness.'
     # Use a multi-line string to account for the chapter transition
     self.assertEqual('''{0}\n\n{1}'''.format(ex22, ex23), text,
                      'Passage is incorrect')
 def test_get_passage_with_subheadings(self):
     bible = WebExtractor()
     text = bible.search('Ezekiel 40:19-20')
     ez40_19 = '\u00b9\u2079 Then he measured the distance from the inside of the lower gateway to ' \
               'the outside of the inner court; it was a hundred cubits on the east side as well as on the north. '
     ez40_20 = '\u00b2\u2070 Then he measured the length and width of the north gate, ' \
               'leading into the outer court.'
     # Ignore the subheading, but start its paragraph contents on a new line
     self.assertEqual('''{0}\n{1}'''.format(ez40_19, ez40_20), text,
                      'Passage is incorrect')
 def test_get_passage_with_poetry_indentation(self):
     bible = WebExtractor()
     text = bible.search('Deuteronomy 7:10')
     deut7_10 = [
         '\u00b9\u2070 But',
         'those who hate him he will repay to their face by destruction;',
         '    he will not be slow to repay to their face those who hate him.'
     ]
     # In some cases, passage sections are nested within another <div> tag, presumably to apply CSS indentation
     self.assertEqual('\n'.join(deut7_10), text, 'Passage is incorrect')
    def check_baseline_passages(self, translation):
        """
        Checks that a translation can return the correct results for a basic set of passages

        :param translation: Translation code for the tests. For example, 'NIV', 'ESV', 'NLT'
        :type translation: str
        """
        bible = WebExtractor(translation=translation)
        actual_passage_results = [
            bible.search('Revelation 21:25'),
            bible.search('Matthew 1:1 - 3'),
            bible.search('Nehemiah 7:40 - 42'),
            bible.search('Psalm 32:4'),
            bible.search('John 7:53')
        ]
        for expected_passage_index in range(0, len(actual_passage_results)):
            self.check_with_static_passage_contents(translation, str(expected_passage_index),
                                                    actual_result=actual_passage_results[expected_passage_index],
                                                    is_baseline=True)
 def test_get_passage_nlt_interlude(self):
     bible = WebExtractor(translation='NLT')
     text = bible.search('Psalm 32:4')
     psalm32_4 = [
         '\u2074 Day and night your hand of discipline was heavy on me.',
         '    My strength evaporated like water in the summer heat. Interlude'
     ]
     # Explicit interludes should be omitted, and usually show as italicised text in the Psalm.
     # Implicit interludes are embedded within the passage itself, so not much can be done about it (e.g. YLT)
     self.assertEqual('\n'.join(psalm32_4), text, 'Passage is incorrect')
    def test_get_online_passage(self):
        bible = WebExtractor()
        options = self.get_alternative_interface_options()
        for option in options:
            bible.translation = option['translation']
            bible.show_passage_numbers = option['show_passage_numbers']

            text1 = bible.search('Ecclesiastes 1:17')
            text2 = bible.get_passage('Ecclesiastes', 1, 17)
            self.assertEqual(text1, text2, 'Passage is incorrect')
    def test_get_online_passages(self):
        bible = WebExtractor()
        options = self.get_alternative_interface_options()
        for option in options:
            bible.translation = option['translation']
            bible.show_passage_numbers = option['show_passage_numbers']

            text1 = bible.search('Ezekiel 40:19-20')
            text2 = bible.get_passages('Ezekiel', 40, 19, 20)
            self.assertEqual(text1, text2, 'Passage is incorrect')
    def test_get_online_chapter(self):
        bible = WebExtractor()
        options = self.get_alternative_interface_options()
        for option in options:
            bible.translation = option['translation']
            bible.show_passage_numbers = option['show_passage_numbers']

            text1 = bible.search('Daniel 5')
            text2 = bible.get_chapter('Daniel', 5)
            self.assertEqual(text1, text2, 'Passage is incorrect')
 def test_get_passage_with_extended_dash(self):
     bible = WebExtractor()
     text = bible.search('Psalms 42:6')
     psalm_6 = [
         '\u2076 My soul is downcast within me;',
         '    therefore I will remember you',
         'from the land of the Jordan,',
         '    the heights of Hermon\u2014from Mount Mizar.'
     ]
     # The extended dash is a Unicode character, and should be preserved
     self.assertEqual('\n'.join(psalm_6), text, 'Passage is incorrect')
 def test_get_passage_with_max_passage_limitation(self):
     bible = WebExtractor()
     text = bible.search('Genesis 1:1 - 40:38')
     gen10_15 = [
         '\u00b9\u2075 Canaan was the father of',
         'Sidon his firstborn, and of the Hittites,'
     ]
     # The Bible Gateway search engine has a certain limit on the number of passages that can be requested at once.
     # Not much is currently known about this limitation, but users should be aware of this during use.
     # In this particular case, the last verse to return should be Genesis 10:15
     self.assertTrue(text.endswith('\n'.join(gen10_15)),
                     'Passage is incorrect')