OPEN SOURCE
software/tests/test_pericope_generator.py
このサイトで読み、必要なファイルを保存できます。
日常訳はAIを用いて作成された翻訳です。人間の聖書学・原語の専門家による全訳の検証は確認されていません。既存の翻訳や原語資料と照らし合わせてお読みください。
1"""Tests for pericope auto-generation."""23import json4import pytest5from pathlib import Path6from tempfile import TemporaryDirectory78from src.context.pericope_generator import (9MAX_PERICOPE_SIZE,10MIN_PERICOPE_SIZE,11PARAGRAPH_MARKER,12PericopeGenerator,13merge_pericope_indexes,14)15from src.models.pericope import Pericope, PericopeIndex161718class TestPericopeGenerator:19"""Tests for PericopeGenerator."""2021@pytest.fixture22def sample_greek_data(self):23"""Create sample Greek data with paragraph markers."""24return {25"1:1": {"text": "¶ Ἐν ἀρχῇ ἦν ὁ λόγος"},26"1:2": {"text": "οὗτος ἦν ἐν ἀρχῇ"},27"1:3": {"text": "πάντα δι᾽ αὐτοῦ ἐγένετο"},28"1:4": {"text": "ἐν αὐτῷ ζωὴ ἦν"},29"1:5": {"text": "¶ καὶ τὸ φῶς ἐν τῇ σκοτίᾳ"},30"1:6": {"text": "ἐγένετο ἄνθρωπος"},31"1:7": {"text": "οὗτος ἦλθεν εἰς μαρτυρίαν"},32"1:8": {"text": "¶ οὐκ ἦν ἐκεῖνος τὸ φῶς"},33"1:9": {"text": "ἦν τὸ φῶς τὸ ἀληθινόν"},34"1:10": {"text": "ἐν τῷ κόσμῳ ἦν"},35}3637@pytest.fixture38def temp_data_dir(self, sample_greek_data):39"""Create temporary data directory with Greek data."""40with TemporaryDirectory() as tmpdir:41data_dir = Path(tmpdir)42greek_dir = data_dir / "sources" / "greek"43greek_dir.mkdir(parents=True)4445with (greek_dir / "john.json").open("w") as f:46json.dump(sample_greek_data, f)4748yield data_dir4950def test_init(self, temp_data_dir):51"""Test generator initialization."""52generator = PericopeGenerator(temp_data_dir)53assert generator._data_dir == temp_data_dir5455def test_find_paragraph_markers(self, temp_data_dir, sample_greek_data):56"""Test finding paragraph markers."""57generator = PericopeGenerator(temp_data_dir)58markers = generator._find_paragraph_markers(sample_greek_data)5960assert "1:1" in markers # Has ¶61assert "1:5" in markers # Has ¶62assert "1:8" in markers # Has ¶63assert "1:2" not in markers # No ¶6465def test_get_all_verses(self, temp_data_dir, sample_greek_data):66"""Test getting all verses in order."""67generator = PericopeGenerator(temp_data_dir)68verses = generator._get_all_verses(sample_greek_data)6970assert verses == ["1:1", "1:2", "1:3", "1:4", "1:5", "1:6", "1:7", "1:8", "1:9", "1:10"]7172def test_ref_sort_key(self, temp_data_dir):73"""Test reference sort key."""74generator = PericopeGenerator(temp_data_dir)7576assert generator._ref_sort_key("1:1") == (1, 1)77assert generator._ref_sort_key("2:15") == (2, 15)78assert generator._ref_sort_key("10:5") == (10, 5)79assert generator._ref_sort_key("invalid") == (0, 0)8081def test_split_large_pericope(self, temp_data_dir):82"""Test splitting large pericopes."""83generator = PericopeGenerator(temp_data_dir)8485# Small list should not be split86small = ["1:1", "1:2", "1:3"]87result = generator._split_large_pericope(small, max_size=10)88assert len(result) == 189assert result[0] == small9091# Large list should be split92large = [f"1:{i}" for i in range(1, 31)] # 30 verses93result = generator._split_large_pericope(large, max_size=10)94assert len(result) == 395assert all(len(part) <= 10 for part in result)9697def test_generate_pericopes(self, temp_data_dir):98"""Test generating pericopes from paragraph markers."""99generator = PericopeGenerator(temp_data_dir)100index = generator.generate_pericopes("john", min_size=2)101102assert index.book == "john"103assert len(index.pericopes) > 0104105# All pericopes should be auto-generated106for p in index.pericopes:107assert p.auto_generated is True108assert p.id.startswith("john-auto-")109110def test_generate_pericopes_respects_min_size(self, temp_data_dir):111"""Test that small pericopes are merged."""112generator = PericopeGenerator(temp_data_dir)113index = generator.generate_pericopes("john", min_size=5)114115# Should have fewer pericopes due to merging116for p in index.pericopes:117assert len(p.verses) >= 5 or p == index.pericopes[-1] # Last may be smaller118119def test_generate_pericopes_empty_book(self, temp_data_dir):120"""Test generating pericopes for non-existent book."""121generator = PericopeGenerator(temp_data_dir)122index = generator.generate_pericopes("nonexistent")123124assert index.book == "nonexistent"125assert len(index.pericopes) == 0126127def test_create_pericope(self, temp_data_dir):128"""Test creating a single pericope."""129generator = PericopeGenerator(temp_data_dir)130verses = ["1:1", "1:2", "1:3"]131pericope = generator._create_pericope("john", verses, 1)132133assert pericope.id == "john-auto-001"134assert pericope.start_chapter == 1135assert pericope.start_verse == 1136assert pericope.end_chapter == 1137assert pericope.end_verse == 3138assert pericope.verses == verses139assert pericope.auto_generated is True140141def test_generate_and_save(self, temp_data_dir):142"""Test generating and saving pericopes."""143generator = PericopeGenerator(temp_data_dir)144index = generator.generate_and_save("john")145146# Check file was created147output_path = temp_data_dir / "metadata" / "pericopes_generated.json"148assert output_path.exists()149150# Check content151with output_path.open() as f:152data = json.load(f)153assert "john" in data154assert data["john"]["auto_generated"] is True155156def test_generate_all_books(self, temp_data_dir):157"""Test generating pericopes for multiple books."""158generator = PericopeGenerator(temp_data_dir)159160# Only john.json exists in our fixture161result = generator.generate_all_books()162163assert "john" in result164assert len(result["john"].pericopes) > 0165166167class TestMergePericopeIndexes:168"""Tests for merge_pericope_indexes function."""169170def test_both_none(self):171"""Test merging two None values."""172result = merge_pericope_indexes(None, None)173assert result is None174175def test_manual_only(self):176"""Test when only manual exists."""177manual = PericopeIndex(178book="john",179name="John",180pericopes=[181Pericope(182id="john-prologue",183start_chapter=1,184start_verse=1,185end_chapter=1,186end_verse=18,187verses=["1:1", "1:2"],188)189],190)191result = merge_pericope_indexes(manual, None)192assert result == manual193194def test_generated_only(self):195"""Test when only generated exists."""196generated = PericopeIndex(197book="john",198name="John",199pericopes=[200Pericope(201id="john-auto-001",202start_chapter=1,203start_verse=1,204end_chapter=1,205end_verse=4,206verses=["1:1", "1:2", "1:3", "1:4"],207auto_generated=True,208)209],210)211result = merge_pericope_indexes(None, generated)212assert result == generated213214def test_manual_takes_precedence(self):215"""Test that manual pericopes take precedence."""216manual = PericopeIndex(217book="john",218name="John",219pericopes=[220Pericope(221id="john-prologue",222start_chapter=1,223start_verse=1,224end_chapter=1,225end_verse=18,226verses=["1:1"],227)228],229)230generated = PericopeIndex(231book="john",232name="John",233pericopes=[234Pericope(235id="john-auto-001",236start_chapter=1,237start_verse=1,238end_chapter=1,239end_verse=4,240verses=["1:1", "1:2", "1:3", "1:4"],241auto_generated=True,242)243],244)245result = merge_pericope_indexes(manual, generated)246assert result == manual247248def test_empty_manual_uses_generated(self):249"""Test that empty manual index falls back to generated."""250manual = PericopeIndex(book="john", name="John", pericopes=[])251generated = PericopeIndex(252book="john",253name="John",254pericopes=[255Pericope(256id="john-auto-001",257start_chapter=1,258start_verse=1,259end_chapter=1,260end_verse=4,261verses=["1:1", "1:2", "1:3", "1:4"],262auto_generated=True,263)264],265)266result = merge_pericope_indexes(manual, generated)267assert result == generated268269270class TestConstants:271"""Tests for module constants."""272273def test_paragraph_marker(self):274"""Test paragraph marker constant."""275assert PARAGRAPH_MARKER == "¶"276277def test_min_pericope_size(self):278"""Test minimum pericope size."""279assert MIN_PERICOPE_SIZE >= 1280281def test_max_pericope_size(self):282"""Test maximum pericope size."""283assert MAX_PERICOPE_SIZE > MIN_PERICOPE_SIZE284assert MAX_PERICOPE_SIZE <= 50 # Reasonable upper bound285