-
Notifications
You must be signed in to change notification settings - Fork 17
Expand file tree
/
Copy pathparser_test.py
More file actions
329 lines (262 loc) · 11.5 KB
/
parser_test.py
File metadata and controls
329 lines (262 loc) · 11.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
from __future__ import annotations
import pythonbible as bible
def test_get_references(text_with_reference: str) -> None:
# Given a text string with at least one scripture reference
# When parsing that text
references: list[bible.NormalizedReference] = bible.get_references(
text_with_reference,
)
# Then the references are found and returned in a list of normalized reference
# tuples
assert len(references) == 2
assert references[0] == bible.NormalizedReference(
bible.Book.MATTHEW,
18,
12,
18,
14,
)
assert references[1] == bible.NormalizedReference(bible.Book.LUKE, 15, 3, 15, 7)
def test_get_references_complex(
text_with_reference_complex: str,
normalized_references_complex: list[bible.NormalizedReference],
) -> None:
# Given a text string with multiple complex references
# When parsing that text
references: list[bible.NormalizedReference] = bible.get_references(
text_with_reference_complex,
)
# Then the references are found and returned in a list of normalized reference
# tuples
assert references == normalized_references_complex
def test_normalize_reference(non_normalized_reference: str) -> None:
# Given a non-normalized reference (just a string)
# When we normalize that reference
normalized_references: list[bible.NormalizedReference] = bible.normalize_reference(
non_normalized_reference,
)
# Then the reference is returned as a list of tuples with the book enum,
# start chapter, start verse, end chapter, and end verse
assert len(normalized_references) == 1
assert normalized_references[0] == bible.NormalizedReference(
bible.Book.MATTHEW,
18,
12,
18,
14,
)
def test_normalize_reference_without_verse_numbers(
reference_without_verse_numbers: str,
) -> None:
# Given a non-normalized reference that does not contain verse numbers (just book
# and chapters)
# When we normalize that reference
normalized_references: list[bible.NormalizedReference] = bible.normalize_reference(
reference_without_verse_numbers,
)
# Then the resulting normalized references contain the proper verse numbers
assert len(normalized_references) == 1
assert normalized_references[0] == bible.NormalizedReference(
bible.Book.EXODUS,
20,
1,
20,
26,
)
def test_normalize_reference_range_without_verse_numbers(
reference_range_without_verse_numbers: str,
) -> None:
# Given a non-normalized reference that does not contain verse numbers (just book
# and chapters)
# When we normalize that reference
normalized_references: list[bible.NormalizedReference] = bible.normalize_reference(
reference_range_without_verse_numbers,
)
# Then the resulting normalized references contain the proper verse numbers
assert len(normalized_references) == 1
assert normalized_references[0] == bible.NormalizedReference(
bible.Book.GENESIS,
1,
1,
4,
26,
)
def test_get_references_roman_numerals(
roman_numeral_references: str,
normalized_references_complex: list[bible.NormalizedReference],
) -> None:
# Given a text string with multiple references with roman numerals
# When parsing that text
references: list[bible.NormalizedReference] = bible.get_references(
roman_numeral_references,
)
# Then the references are found and returned in a list of normalized reference
# tuples
assert references == normalized_references_complex
def test_philemon_vs_philippians() -> None:
"""Test for https://github.com/avendesora/pythonbible/issues/2."""
# Given a text string with a reference in the book of Philemon
text: str = "Philemon 1:9"
# When we parse the references from that text
references: list[bible.NormalizedReference] = bible.get_references(text)
# Then the parser does not raise an error and returns the appropriate reference
assert references == [bible.NormalizedReference(bible.Book.PHILEMON, 1, 9, 1, 9)]
def test_book_alternative_names(
book_alternative_names: dict[bible.Book, list[str]],
) -> None:
# Given the books of the Bible with their alternative names/abbreviations
for book, alternative_names in book_alternative_names.items():
references = bible.get_references(f"{book.title} 1:1-2")
for alternative_name in alternative_names:
# When we parse the references with the alternative name
alternative_references = bible.get_references(f"{alternative_name} 1:1-2")
# Then the alternative references match the baseline references
assert references == alternative_references
def test_cross_book_reference_just_books() -> None:
# Given a text string with a reference that ranges over multiple books of the Bible
text: str = "Genesis - Deuteronomy"
# When we parse the references from that text
references: list[bible.NormalizedReference] = bible.get_references(text)
# Then the parser does not raise an error and returns the appropriate reference
deuteronomy: bible.Book = bible.Book.DEUTERONOMY
max_chapter: int = bible.get_number_of_chapters(deuteronomy)
max_verse: int = bible.get_number_of_verses(deuteronomy, max_chapter)
assert references == [
bible.NormalizedReference(
bible.Book.GENESIS,
1,
1,
max_chapter,
max_verse,
deuteronomy,
),
]
def test_cross_book_reference_complex() -> None:
# Given a text string with a complex reference that ranges over multiple books of
# the Bible
text: str = "Genesis 1:1-5, 50:3 - Exodus 1:14, 2:3-20:5"
# When we parse the references from that text
references: list[bible.NormalizedReference] = bible.get_references(text)
# Then the parser does not raise an error and returns the appropriate reference
assert references == [
bible.NormalizedReference(bible.Book.GENESIS, 1, 1, 1, 5, None),
bible.NormalizedReference(bible.Book.GENESIS, 50, 3, 1, 14, bible.Book.EXODUS),
bible.NormalizedReference(bible.Book.EXODUS, 2, 3, 20, 5, None),
]
def test_book_group_reference() -> None:
# Given a text string with a book group reference
text: str = "This class is a survey of the Old Testament of the Bible."
# When we parse the references from that text using the optional book_groups
# parameter
references: list[bible.NormalizedReference] = bible.get_references(
text,
book_groups=bible.BOOK_GROUPS,
)
# Then the parser returns the appropriate book group reference
malachi: bible.Book = bible.Book.MALACHI
max_chapter: int = bible.get_number_of_chapters(malachi)
max_verse: int = bible.get_number_of_verses(malachi, max_chapter)
assert references == [
bible.NormalizedReference(
bible.Book.GENESIS,
1,
1,
max_chapter,
max_verse,
malachi,
),
]
def test_book_group_reference_custom() -> None:
# Given a custom dictionary of book group regular expressions
book_groups: dict[str, tuple[bible.Book, ...]] = {
"my custom book group": (
bible.Book.GENESIS,
bible.Book.EXODUS,
bible.Book.MATTHEW,
bible.Book.MARK,
bible.Book.JUDE,
),
}
# and a text string containing a custom book group reference
text: str = "Can you find my custom book group?"
# When we parse the references from that text
references: list[bible.NormalizedReference] = bible.get_references(
text,
book_groups=book_groups,
)
# Then the parser returns the appropriate book group references
assert references == [
bible.NormalizedReference(bible.Book.GENESIS, 1, 1, 40, 38, bible.Book.EXODUS),
bible.NormalizedReference(bible.Book.MATTHEW, 1, 1, 16, 20, bible.Book.MARK),
bible.NormalizedReference(bible.Book.JUDE, 1, 1, 1, 25, bible.Book.JUDE),
]
def test_single_chapter_book_without_chapter_number() -> None:
# Given a reference string that does not include the chapter number for a book that
# only has one chapter
text: str = "Obadiah 3-6"
# When we parse the references from that text
references: list[bible.NormalizedReference] = bible.get_references(text)
# Then the parser returns the appropriate normalized reference with chapter and
# verse numbers
assert references == [
bible.NormalizedReference(bible.Book.OBADIAH, 1, 3, 1, 6, None),
]
def test_book_alternative_names_verbum(
book_alternative_names_verbum: dict[bible.Book, list[str]],
) -> None:
# Given the books of the Bible with their alternative names/abbreviations
for book, alternative_names in book_alternative_names_verbum.items():
references = bible.get_references(f"{book.title} 1:1-2")
for alternative_name in alternative_names:
if len(alternative_name.replace(" ", "")) < 3:
continue
# When we parse the references with the alternative name
alternative_references = bible.get_references(f"{alternative_name} 1:1-2")
# Then the alternative references match the baseline references
assert alternative_references == references
# https://github.com/avendesora/pythonbible/issues/77
# https://github.com/avendesora/pythonbible/issues/78
def test_compound_references() -> None:
for book in bible.Book:
title = book.title
end_chapter = bible.get_number_of_chapters(book)
end_verse = bible.get_number_of_verses(book, end_chapter)
reference_string = f"{title} 1:1-{title} {end_chapter}:{end_verse}"
compound_results = bible.get_references(reference_string)
expected_result = bible.NormalizedReference(
book=book,
start_chapter=1,
start_verse=1,
end_chapter=end_chapter,
end_verse=end_verse,
end_book=book,
)
assert len(compound_results) == 1
assert compound_results[0] == expected_result
def test_book_abbreviations() -> None:
# Given the books of the Bible and their abbreviations
for book in bible.Book:
book_number = f"{book.name[-1]} " if book.name[-1].isdigit() else ""
baseline_reference = f"{book_number}{book.title} 1:1-2"
expected = bible.get_references(baseline_reference)
for abbreviation in book.abbreviations:
# When we parse the references with the abbreviated title
abbreviated_reference = f"{book_number}{abbreviation} 1:1-2"
abbreviated_reference_period = f"{book_number}{abbreviation}. 1:1-2"
actual = bible.get_references(abbreviated_reference)
actual_period = bible.get_references(abbreviated_reference_period)
# Then the abbreviated references match the baseline references
assert expected == actual
if book != book.SONG_OF_SONGS:
assert expected == actual_period
def test_multiple_references_with_prefixes() -> None:
# Given an input string containing multiple references with prefixes,
# separated by commas
input_string = "1 Corinthians 1:1, 2 Corinthians 1:1"
# When we parse the references from that string
references = bible.get_references(input_string)
# Then we get the expected references
assert references == [
bible.NormalizedReference(bible.Book.CORINTHIANS_1, 1, 1, 1, 1),
bible.NormalizedReference(bible.Book.CORINTHIANS_2, 1, 1, 1, 1),
]