OPEN SOURCE
software/tests/test_widgets_extended.py
Read on this site and download the files you need.
Nichijoyaku was created using AI. A complete review by human biblical-language and biblical-studies specialists has not been established. Read alongside established translations and original-language resources.
← Back to the open-source guide
1"""Extended tests for TUI widgets to improve coverage."""23import json4from datetime import datetime5from io import StringIO6from pathlib import Path78import pytest9from rich.console import Console10from rich.text import Text1112from src.models.evaluation import (13EvaluationScore,14VerseEvaluation,15)16from src.tui.data_provider import TUIDataProvider, VerseData17from src.tui.widgets import (18ChapterQualitySummary,19DetailPanel,20EvaluationSummaryTable,21)222324@pytest.fixture25def temp_data_dir(tmp_path: Path) -> Path:26"""Create a temporary data directory with test data."""27# Create source directories28sources_dir = tmp_path / "sources"29(sources_dir / "greek").mkdir(parents=True)30(sources_dir / "english" / "kjv").mkdir(parents=True)3132# Create Greek source33greek_data = {"1:1": {"text": "Ἐν ἀρχῇ", "translit": "En archē"}}34with (sources_dir / "greek" / "john.json").open("w") as f:35json.dump(greek_data, f)3637# Create KJV source38kjv_data = {"1:1": "In the beginning was the Word"}39with (sources_dir / "english" / "kjv" / "john.json").open("w") as f:40json.dump(kjv_data, f)4142# Create output directory with translations43output_dir = tmp_path / "output" / "john"44output_dir.mkdir(parents=True)4546chapter_data = {47"book": "john",48"chapter": 1,49"verses": {50"1": {51"text": "初めに言葉があった。",52"model": "claude-sonnet-4",53"timestamp": "2026-01-13T00:00:00Z",54"glossary_terms_applied": [],55},56},57}58with (output_dir / "chapter_01.json").open("w") as f:59json.dump(chapter_data, f)6061# Create evaluation file with all score levels62eval_data = {63"book": "john",64"chapter": 1,65"evaluator_model": "claude-opus-4-5",66"evaluated_at": "2026-01-13T00:00:00Z",67"verses": {68"1": {69"scores": {70"theological_accuracy": {71"score": 95,72"confidence": 90,73"reasoning": "Excellent",74},75"source_fidelity": {76"score": 75,77"confidence": 85,78"reasoning": "Good but could improve",79},80"naturalness": {81"score": 65,82"confidence": 80,83"reasoning": "Below threshold",84},85},86"overall_score": 78.3,87"flags": ["naturalness_concern"],88"notes": "Consider improving naturalness",89"timestamp": "2026-01-13T00:00:00Z",90},91},92"aggregate": {93"scores": {94"theological_accuracy": 95.0,95"source_fidelity": 75.0,96"naturalness": 65.0,97},98"overall": 78.3,99"flagged_count": 1,100"flagged_verses": [1],101},102}103with (output_dir / "chapter_01_eval.json").open("w") as f:104json.dump(eval_data, f)105106# Create metadata directory107metadata_dir = tmp_path / "metadata"108metadata_dir.mkdir(parents=True)109110return tmp_path111112113def _render_to_string(renderable) -> str:114"""Render content to a string for testing."""115console = Console(file=StringIO(), force_terminal=True, width=120)116console.print(renderable)117return console.file.getvalue()118119120class TestDetailPanelScoreColors:121"""Tests for DetailPanel score color coding."""122123def test_render_with_excellent_score(self, temp_data_dir: Path) -> None:124"""Test rendering with excellent score (>= 90)."""125provider = TUIDataProvider(temp_data_dir)126panel = DetailPanel(provider, id="detail")127128# Create verse data with excellent score129panel.current_verse = VerseData(130book="john",131chapter=1,132verse=1,133greek_text="Ἐν ἀρχῇ",134kjv_text="In the beginning",135japanese_reference=None,136glossary_terms=[],137translation_text="初めに言葉があった。",138translation_model="claude-sonnet-4",139translation_timestamp="2026-01-13",140evaluation=VerseEvaluation(141verse_number=1,142evaluator_model="test",143timestamp=datetime.utcnow(),144scores={145"theological_accuracy": EvaluationScore(146dimension="theological_accuracy",147score=95.0,148confidence=90.0,149reasoning="Excellent",150),151},152flags=[],153notes=None,154),155)156157rendered_str = _render_to_string(panel.render())158# Should show excellent score indicator159assert "95" in rendered_str160161def test_render_with_concern_score(self, temp_data_dir: Path) -> None:162"""Test rendering with concerning score (< 70)."""163provider = TUIDataProvider(temp_data_dir)164panel = DetailPanel(provider, id="detail")165166# Create verse data with low score167panel.current_verse = VerseData(168book="john",169chapter=1,170verse=1,171greek_text="Ἐν ἀρχῇ",172kjv_text="In the beginning",173japanese_reference=None,174glossary_terms=[],175translation_text="初めに言葉があった。",176translation_model="claude-sonnet-4",177translation_timestamp="2026-01-13",178evaluation=VerseEvaluation(179verse_number=1,180evaluator_model="test",181timestamp=datetime.utcnow(),182scores={183"naturalness": EvaluationScore(184dimension="naturalness",185score=55.0,186confidence=80.0,187reasoning="Needs work",188),189},190flags=["naturalness_concern"],191notes="Needs improvement",192),193)194195rendered_str = _render_to_string(panel.render())196assert "55" in rendered_str197198def test_render_with_multiple_flags(self, temp_data_dir: Path) -> None:199"""Test rendering verse with multiple flags."""200provider = TUIDataProvider(temp_data_dir)201panel = DetailPanel(provider, id="detail")202203panel.current_verse = VerseData(204book="john",205chapter=1,206verse=1,207greek_text="Ἐν ἀρχῇ",208kjv_text="In the beginning",209japanese_reference=None,210glossary_terms=[],211translation_text="初めに言葉があった。",212translation_model="claude-sonnet-4",213translation_timestamp="2026-01-13",214evaluation=VerseEvaluation(215verse_number=1,216evaluator_model="test",217timestamp=datetime.utcnow(),218scores={219"theological_accuracy": EvaluationScore(220dimension="theological_accuracy",221score=60.0,222confidence=70.0,223reasoning="Concern",224),225"source_fidelity": EvaluationScore(226dimension="source_fidelity",227score=55.0,228confidence=65.0,229reasoning="Issue",230),231},232flags=["theological_concern", "source_fidelity_concern"],233notes="Multiple issues",234),235)236237rendered_str = _render_to_string(panel.render())238# Should contain flag indicators239assert "concern" in rendered_str.lower() or "flag" in rendered_str.lower()240241242class TestEvaluationSummaryTableScoreBars:243"""Tests for EvaluationSummaryTable visual bars."""244245def test_render_with_varied_scores(self) -> None:246"""Test rendering with various score levels."""247table = EvaluationSummaryTable(id="eval-table")248table.set_scores({249"theological_accuracy": (95.0, 90.0), # Excellent250"source_fidelity": (75.0, 85.0), # Good251"naturalness": (55.0, 80.0), # Concern252"readability": (85.0, 90.0), # Good253"glossary_consistency": (100.0, 100.0), # Perfect254"literary_quality": (65.0, 75.0), # Below threshold255})256257rendered_str = _render_to_string(table.render())258259# Should contain all dimension scores260assert "95" in rendered_str261assert "75" in rendered_str262assert "55" in rendered_str263264def test_render_with_scores_uses_bars(self) -> None:265"""Test rendering includes visual bars."""266table = EvaluationSummaryTable(id="eval-table")267table.set_scores({"theological_accuracy": (90.0, 95.0)})268269rendered_str = _render_to_string(table.render())270# Should contain bar characters271assert "█" in rendered_str or "░" in rendered_str272273274class TestChapterQualitySummary:275"""Tests for ChapterQualitySummary widget."""276277def test_render_empty(self, temp_data_dir: Path) -> None:278"""Test rendering with no chapter selected."""279provider = TUIDataProvider(temp_data_dir)280widget = ChapterQualitySummary(provider, id="quality-summary")281rendered = widget.render()282rendered_str = _render_to_string(rendered)283assert "Select a chapter" in rendered_str or "Chapter" in rendered_str284285def test_render_with_chapter_data(self, temp_data_dir: Path) -> None:286"""Test rendering with chapter selected."""287provider = TUIDataProvider(temp_data_dir)288widget = ChapterQualitySummary(provider, id="quality-summary")289widget.update_chapter("john", 1)290291rendered_str = _render_to_string(widget.render())292# Should show chapter info293assert "JOHN" in rendered_str or "john" in rendered_str.lower()294295def test_render_with_no_eval_data(self, temp_data_dir: Path) -> None:296"""Test rendering chapter with no evaluation."""297provider = TUIDataProvider(temp_data_dir)298widget = ChapterQualitySummary(provider, id="quality-summary")299# Select a chapter that doesn't have evaluation300widget.update_chapter("john", 99)301302rendered_str = _render_to_string(widget.render())303assert "No evaluation" in rendered_str or "--evaluate" in rendered_str304305306class TestDimensionNameFormatting:307"""Tests for dimension name formatting in widgets."""308309def test_format_dimension_names_table(self) -> None:310"""Test dimension name formatting in EvaluationSummaryTable."""311table = EvaluationSummaryTable(id="eval-table")312313# Test that dimension names are formatted314formatted = table._format_dimension_name("theological_accuracy")315assert "Theolog" in formatted or "theological" in formatted.lower()316317formatted = table._format_dimension_name("source_fidelity")318assert "Fidelity" in formatted or "source" in formatted.lower()319320formatted = table._format_dimension_name("glossary_consistency")321assert "Glossary" in formatted or "consistency" in formatted.lower()322323def test_format_dimension_names_panel(self, temp_data_dir: Path) -> None:324"""Test dimension name formatting in DetailPanel."""325provider = TUIDataProvider(temp_data_dir)326panel = DetailPanel(provider, id="detail")327328formatted = panel._format_dimension_name("theological_accuracy")329assert "Theolog" in formatted330331formatted = panel._format_dimension_name("unknown_dimension")332# Unknown dimensions should be title-cased333assert "Unknown" in formatted or "Dimension" in formatted334335336class TestScoreColorHelpers:337"""Tests for score color helper methods."""338339def test_get_score_color_excellent(self) -> None:340"""Test color for excellent scores."""341table = EvaluationSummaryTable(id="eval-table")342color = table._get_score_color(95.0)343assert color == "green"344345def test_get_score_color_good(self) -> None:346"""Test color for good scores."""347table = EvaluationSummaryTable(id="eval-table")348color = table._get_score_color(80.0)349assert color == "yellow"350351def test_get_score_color_concern(self) -> None:352"""Test color for concerning scores."""353table = EvaluationSummaryTable(id="eval-table")354color = table._get_score_color(65.0)355assert color == "orange1"356357def test_get_score_color_poor(self) -> None:358"""Test color for poor scores."""359table = EvaluationSummaryTable(id="eval-table")360color = table._get_score_color(50.0)361assert color == "red"362363364class TestDetailPanelHelpers:365"""Tests for DetailPanel helper methods."""366367def test_get_quality_indicator_excellent(self, temp_data_dir: Path) -> None:368"""Test indicator for excellent quality."""369provider = TUIDataProvider(temp_data_dir)370panel = DetailPanel(provider, id="detail")371indicator = panel._get_quality_indicator(95.0)372assert indicator == "●"373374def test_get_quality_indicator_good(self, temp_data_dir: Path) -> None:375"""Test indicator for good quality."""376provider = TUIDataProvider(temp_data_dir)377panel = DetailPanel(provider, id="detail")378indicator = panel._get_quality_indicator(80.0)379assert indicator == "◐"380381def test_get_quality_indicator_concern(self, temp_data_dir: Path) -> None:382"""Test indicator for concerning quality."""383provider = TUIDataProvider(temp_data_dir)384panel = DetailPanel(provider, id="detail")385indicator = panel._get_quality_indicator(65.0)386assert indicator == "○"387388def test_get_quality_indicator_poor(self, temp_data_dir: Path) -> None:389"""Test indicator for poor quality."""390provider = TUIDataProvider(temp_data_dir)391panel = DetailPanel(provider, id="detail")392indicator = panel._get_quality_indicator(50.0)393assert indicator == "✗"394395396class TestFlagFormatting:397"""Tests for flag formatting in DetailPanel."""398399def test_format_flag_theological(self, temp_data_dir: Path) -> None:400"""Test formatting theological flag."""401provider = TUIDataProvider(temp_data_dir)402panel = DetailPanel(provider, id="detail")403formatted = panel._format_flag("theological_concern")404assert "theological" in formatted or "concern" in formatted405406def test_format_flag_source(self, temp_data_dir: Path) -> None:407"""Test formatting source fidelity flag."""408provider = TUIDataProvider(temp_data_dir)409panel = DetailPanel(provider, id="detail")410formatted = panel._format_flag("source_fidelity_concern")411assert "source" in formatted or "fidelity" in formatted412413def test_format_flag_with_low(self, temp_data_dir: Path) -> None:414"""Test formatting flag with 'low' keyword."""415provider = TUIDataProvider(temp_data_dir)416panel = DetailPanel(provider, id="detail")417formatted = panel._format_flag("low_confidence")418# 'low' should be replaced with arrow419assert "↓" in formatted or "confidence" in formatted420