Moved the current implementation to src/audita_prototype, moved current test suite to tests/audita_prototype, and started a new, more modular application skeleton in src/audita
This commit is contained in:
1
tests/__init__.py
Normal file
1
tests/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
"""Test package root."""
|
||||
1
tests/audita_prototype/__init__.py
Normal file
1
tests/audita_prototype/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
"""Archived prototype regression suite."""
|
||||
@@ -1,8 +1,8 @@
|
||||
import pytest
|
||||
|
||||
from audita.chunking import chunk_transcript
|
||||
from audita.errors import AuditaValidationError
|
||||
from audita.schemas import parse_transcript_json
|
||||
from audita_prototype.chunking import chunk_transcript
|
||||
from audita_prototype.errors import AuditaValidationError
|
||||
from audita_prototype.schemas import parse_transcript_json
|
||||
|
||||
|
||||
class CountEstimator:
|
||||
@@ -1,8 +1,8 @@
|
||||
import pytest
|
||||
|
||||
from audita.cli import main
|
||||
from audita.reporting import ProcessResult, RunReport
|
||||
from audita.schemas import parse_transcript_json
|
||||
from audita_prototype.cli import main
|
||||
from audita_prototype.reporting import ProcessResult, RunReport
|
||||
from audita_prototype.schemas import parse_transcript_json
|
||||
|
||||
|
||||
def test_cli_help_uses_audita_program_name(capsys):
|
||||
@@ -63,10 +63,10 @@ def test_cli_process_writes_report_json(monkeypatch, tmp_path):
|
||||
work_dir_retained=False,
|
||||
)
|
||||
|
||||
monkeypatch.setattr("audita.cli.AuditaConfig.from_sources", lambda overrides=None: object())
|
||||
monkeypatch.setattr("audita.cli.load_transcript", lambda path: [])
|
||||
monkeypatch.setattr("audita.cli.load_glossary", lambda path: object())
|
||||
monkeypatch.setattr("audita.cli.process_transcript_result", lambda *args, **kwargs: result)
|
||||
monkeypatch.setattr("audita_prototype.cli.AuditaConfig.from_sources", lambda overrides=None: object())
|
||||
monkeypatch.setattr("audita_prototype.cli.load_transcript", lambda path: [])
|
||||
monkeypatch.setattr("audita_prototype.cli.load_glossary", lambda path: object())
|
||||
monkeypatch.setattr("audita_prototype.cli.process_transcript_result", lambda *args, **kwargs: result)
|
||||
|
||||
output_path = tmp_path / "out.json"
|
||||
report_path = tmp_path / "report.json"
|
||||
@@ -2,8 +2,8 @@ from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from audita.config import AuditaConfig, ConfigOverrides
|
||||
from audita.config import (
|
||||
from audita_prototype.config import AuditaConfig, ConfigOverrides
|
||||
from audita_prototype.config import (
|
||||
DEFAULT_GLOSSARY_CONFIDENCE_THRESHOLD,
|
||||
DEFAULT_GLOSSARY_MAX_LLM_PASSES,
|
||||
DEFAULT_GRAMMAR_CONFIDENCE_THRESHOLD,
|
||||
@@ -20,7 +20,7 @@ from audita.config import (
|
||||
DEFAULT_WORK_DIR,
|
||||
DEFAULT_WORK_DIR_RETENTION,
|
||||
)
|
||||
from audita.errors import AuditaConfigError
|
||||
from audita_prototype.errors import AuditaConfigError
|
||||
|
||||
|
||||
def test_config_uses_defaults_with_api_key():
|
||||
@@ -1,9 +1,9 @@
|
||||
import pytest
|
||||
|
||||
from audita.corrections import apply_corrections
|
||||
from audita.errors import AuditaValidationError
|
||||
from audita.protection import ProtectedVocabulary
|
||||
from audita.schemas import CorrectionCandidate, parse_glossary_yaml, parse_transcript_json
|
||||
from audita_prototype.corrections import apply_corrections
|
||||
from audita_prototype.errors import AuditaValidationError
|
||||
from audita_prototype.protection import ProtectedVocabulary
|
||||
from audita_prototype.schemas import CorrectionCandidate, parse_glossary_yaml, parse_transcript_json
|
||||
|
||||
|
||||
def _transcript():
|
||||
33
tests/audita_prototype/test_launcher.py
Normal file
33
tests/audita_prototype/test_launcher.py
Normal file
@@ -0,0 +1,33 @@
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
|
||||
|
||||
def test_prototype_package_is_importable():
|
||||
package_root = ROOT / "src" / "audita_prototype"
|
||||
assert package_root.is_dir()
|
||||
assert (package_root / "__main__.py").is_file()
|
||||
|
||||
|
||||
def test_prototype_module_help_smoke():
|
||||
env = os.environ.copy()
|
||||
env["PYTHONPATH"] = str(ROOT / "src")
|
||||
|
||||
result = subprocess.run(
|
||||
[sys.executable, "-m", "audita_prototype", "--help"],
|
||||
cwd=ROOT,
|
||||
text=True,
|
||||
capture_output=True,
|
||||
env=env,
|
||||
check=False,
|
||||
)
|
||||
|
||||
assert result.returncode == 0
|
||||
assert result.stdout.startswith("usage: audita ")
|
||||
@@ -1,5 +1,5 @@
|
||||
from audita.normalization import normalize_transcript
|
||||
from audita.schemas import parse_source_transcript_json
|
||||
from audita_prototype.normalization import normalize_transcript
|
||||
from audita_prototype.schemas import parse_source_transcript_json
|
||||
|
||||
|
||||
class WordEstimator:
|
||||
@@ -2,11 +2,11 @@ import json
|
||||
|
||||
import pytest
|
||||
|
||||
from audita.config import AuditaConfig
|
||||
from audita.errors import AuditaError
|
||||
from audita.io import write_report
|
||||
from audita.pipeline import process_transcript, process_transcript_result
|
||||
from audita.schemas import (
|
||||
from audita_prototype.config import AuditaConfig
|
||||
from audita_prototype.errors import AuditaError
|
||||
from audita_prototype.io import write_report
|
||||
from audita_prototype.pipeline import process_transcript, process_transcript_result
|
||||
from audita_prototype.schemas import (
|
||||
CorrectionCandidate,
|
||||
GrammarSpokenFormValidationDecision,
|
||||
GrammarSpokenFormValidationSet,
|
||||
@@ -1,13 +1,13 @@
|
||||
import json
|
||||
|
||||
from audita.chunking import chunk_transcript
|
||||
from audita.prompts import (
|
||||
from audita_prototype.chunking import chunk_transcript
|
||||
from audita_prototype.prompts import (
|
||||
build_glossary_correction_messages,
|
||||
build_grammar_correction_messages,
|
||||
build_grammar_spoken_form_validation_messages,
|
||||
build_grammar_validation_messages,
|
||||
)
|
||||
from audita.schemas import parse_glossary_yaml, parse_transcript_json
|
||||
from audita_prototype.schemas import parse_glossary_yaml, parse_transcript_json
|
||||
|
||||
|
||||
def test_prompt_requires_acoustically_plausible_transcription_errors():
|
||||
@@ -1,5 +1,5 @@
|
||||
from audita.protection import ProtectedVocabulary
|
||||
from audita.schemas import parse_glossary_yaml
|
||||
from audita_prototype.protection import ProtectedVocabulary
|
||||
from audita_prototype.schemas import parse_glossary_yaml
|
||||
|
||||
|
||||
def _vocabulary():
|
||||
@@ -1,8 +1,8 @@
|
||||
import pytest
|
||||
|
||||
from audita.errors import AuditaLLMError
|
||||
from audita.protection import ProtectedVocabulary
|
||||
from audita.schemas import (
|
||||
from audita_prototype.errors import AuditaLLMError
|
||||
from audita_prototype.protection import ProtectedVocabulary
|
||||
from audita_prototype.schemas import (
|
||||
CorrectionCandidate,
|
||||
GrammarSpokenFormValidationDecision,
|
||||
GrammarSpokenFormValidationSet,
|
||||
@@ -11,7 +11,7 @@ from audita.schemas import (
|
||||
parse_glossary_yaml,
|
||||
parse_transcript_json,
|
||||
)
|
||||
from audita.semantic_validation import (
|
||||
from audita_prototype.semantic_validation import (
|
||||
filter_with_meaning_preserving_validations,
|
||||
filter_with_spoken_form_validations,
|
||||
keep_corrections_with_indexes,
|
||||
@@ -1,7 +1,7 @@
|
||||
import pytest
|
||||
|
||||
from audita.errors import AuditaValidationError
|
||||
from audita.schemas import parse_glossary_yaml, parse_source_transcript_json, parse_transcript_json
|
||||
from audita_prototype.errors import AuditaValidationError
|
||||
from audita_prototype.schemas import parse_glossary_yaml, parse_source_transcript_json, parse_transcript_json
|
||||
|
||||
|
||||
def test_valid_transcript_parses():
|
||||
27
tests/test_framework_chunking.py
Normal file
27
tests/test_framework_chunking.py
Normal file
@@ -0,0 +1,27 @@
|
||||
from audita.core.chunking import TokenEstimatorProtocol, chunk_transcript
|
||||
from audita.core.schemas import parse_transcript_json
|
||||
|
||||
|
||||
class FakeEstimator(TokenEstimatorProtocol):
|
||||
def estimate_json(self, value):
|
||||
if len(value) == 1:
|
||||
return 4
|
||||
return len(value) * 4
|
||||
|
||||
|
||||
def test_chunk_transcript_batches_sections_by_token_limit():
|
||||
transcript = parse_transcript_json(
|
||||
"""
|
||||
[
|
||||
{"id": 1, "speaker": "A", "start": 0.0, "end": 1.0, "text": "one"},
|
||||
{"id": 2, "speaker": "A", "start": 1.0, "end": 2.0, "text": "two"},
|
||||
{"id": 3, "speaker": "A", "start": 2.0, "end": 3.0, "text": "three"}
|
||||
]
|
||||
"""
|
||||
)
|
||||
|
||||
sections = chunk_transcript(transcript, max_section_tokens=8, estimator=FakeEstimator())
|
||||
|
||||
assert len(sections) == 2
|
||||
assert [segment.segment.id for segment in sections[0].segments] == [1, 2]
|
||||
assert [segment.segment.id for segment in sections[1].segments] == [3]
|
||||
173
tests/test_framework_runner.py
Normal file
173
tests/test_framework_runner.py
Normal file
@@ -0,0 +1,173 @@
|
||||
from pathlib import Path
|
||||
|
||||
from audita.core.config import AuditaConfig
|
||||
from audita.core.schemas import parse_glossary_yaml, parse_transcript_json
|
||||
from audita.framework.models import (
|
||||
CorrectionProposal,
|
||||
FilterDecision,
|
||||
ModuleContext,
|
||||
ModuleRunSpec,
|
||||
ReviewDecision,
|
||||
)
|
||||
from audita.framework.runner import PipelineRunner
|
||||
|
||||
|
||||
class AllowAllFilter:
|
||||
name = "allow_all"
|
||||
|
||||
def evaluate(self, proposal, transcript, glossary, config):
|
||||
return FilterDecision(approved=True)
|
||||
|
||||
|
||||
class RejectAllFilter:
|
||||
name = "reject_all"
|
||||
|
||||
def evaluate(self, proposal, transcript, glossary, config):
|
||||
return FilterDecision(approved=False, reason="filter rejected proposal")
|
||||
|
||||
|
||||
class AllowAllReviewStage:
|
||||
name = "allow_all_review"
|
||||
|
||||
def review(self, proposals, transcript, glossary, config, llm_client, run_dir):
|
||||
return [ReviewDecision(proposal_index=proposal.proposal_index, approved=True) for proposal in proposals]
|
||||
|
||||
|
||||
class RecordingModule:
|
||||
replacement_policy = "require_unique"
|
||||
|
||||
def __init__(self, module_key, proposals, recorder):
|
||||
self.module_key = module_key
|
||||
self._proposals = proposals
|
||||
self._recorder = recorder
|
||||
|
||||
def deterministic_filters(self):
|
||||
return [AllowAllFilter()]
|
||||
|
||||
def review_stages(self):
|
||||
return [AllowAllReviewStage()]
|
||||
|
||||
def propose(self, transcript_section, context: ModuleContext):
|
||||
self._recorder.append([segment.text for segment in transcript_section])
|
||||
return list(self._proposals)
|
||||
|
||||
|
||||
class RejectedModule:
|
||||
module_key = "rejected"
|
||||
replacement_policy = "require_unique"
|
||||
|
||||
def deterministic_filters(self):
|
||||
return [RejectAllFilter()]
|
||||
|
||||
def review_stages(self):
|
||||
return []
|
||||
|
||||
def propose(self, transcript_section, context):
|
||||
return [
|
||||
CorrectionProposal(
|
||||
proposal_index=0,
|
||||
module_instance=context.run_spec.instance_name,
|
||||
module_key=context.run_spec.module_key,
|
||||
id=1,
|
||||
original_text="Hello",
|
||||
corrected_text="Goodbye",
|
||||
confidence=0.9,
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
def test_pipeline_runner_applies_modules_sequentially(tmp_path):
|
||||
transcript = parse_transcript_json(
|
||||
"""
|
||||
[
|
||||
{"id": 1, "speaker": "A", "start": 0.0, "end": 1.0, "text": "Alpha."}
|
||||
]
|
||||
"""
|
||||
)
|
||||
glossary = parse_glossary_yaml(
|
||||
"""
|
||||
glossary:
|
||||
- name: "Alpha"
|
||||
category: noun
|
||||
summary: "Alpha."
|
||||
"""
|
||||
)
|
||||
seen = []
|
||||
first = RecordingModule(
|
||||
"first",
|
||||
[
|
||||
CorrectionProposal(
|
||||
proposal_index=0,
|
||||
module_instance="first",
|
||||
module_key="first",
|
||||
id=1,
|
||||
original_text="Alpha",
|
||||
corrected_text="Beta",
|
||||
confidence=0.9,
|
||||
)
|
||||
],
|
||||
seen,
|
||||
)
|
||||
second = RecordingModule(
|
||||
"second",
|
||||
[
|
||||
CorrectionProposal(
|
||||
proposal_index=0,
|
||||
module_instance="second",
|
||||
module_key="second",
|
||||
id=1,
|
||||
original_text="Beta",
|
||||
corrected_text="Gamma",
|
||||
confidence=0.9,
|
||||
)
|
||||
],
|
||||
seen,
|
||||
)
|
||||
|
||||
runner = PipelineRunner()
|
||||
result = runner.run(
|
||||
transcript=transcript,
|
||||
glossary=glossary,
|
||||
module_specs=[
|
||||
ModuleRunSpec(instance_name="first", module_key="first", module=first),
|
||||
ModuleRunSpec(instance_name="second", module_key="second", module=second),
|
||||
],
|
||||
config=AuditaConfig.from_sources(env={}),
|
||||
run_dir=tmp_path / "run",
|
||||
)
|
||||
|
||||
assert seen[0] == ["Alpha."]
|
||||
assert seen[1] == ["Beta."]
|
||||
assert result.transcript[0].text == "Gamma."
|
||||
assert len(result.applied_changes) == 2
|
||||
|
||||
|
||||
def test_pipeline_runner_reports_filter_rejections(tmp_path):
|
||||
transcript = parse_transcript_json(
|
||||
"""
|
||||
[
|
||||
{"id": 1, "speaker": "A", "start": 0.0, "end": 1.0, "text": "Hello."}
|
||||
]
|
||||
"""
|
||||
)
|
||||
glossary = parse_glossary_yaml(
|
||||
"""
|
||||
glossary:
|
||||
- name: "Hello"
|
||||
category: noun
|
||||
summary: "Hello."
|
||||
"""
|
||||
)
|
||||
|
||||
runner = PipelineRunner()
|
||||
result = runner.run(
|
||||
transcript=transcript,
|
||||
glossary=glossary,
|
||||
module_specs=[ModuleRunSpec(instance_name="rejected", module_key="rejected", module=RejectedModule())],
|
||||
config=AuditaConfig.from_sources(env={}),
|
||||
run_dir=tmp_path / "run",
|
||||
)
|
||||
|
||||
assert result.transcript[0].text == "Hello."
|
||||
assert result.module_reports[0].skipped_count == 1
|
||||
assert result.skipped_corrections[0].reason == "filter rejected proposal"
|
||||
83
tests/test_new_cli.py
Normal file
83
tests/test_new_cli.py
Normal file
@@ -0,0 +1,83 @@
|
||||
import pytest
|
||||
|
||||
from audita.cli import main
|
||||
from audita.core.reporting import ProcessResult, RunReport
|
||||
from audita.core.schemas import parse_transcript_json
|
||||
|
||||
|
||||
def test_cli_help_uses_audita_program_name(capsys):
|
||||
with pytest.raises(SystemExit) as exc:
|
||||
main(["--help"])
|
||||
|
||||
assert exc.value.code == 0
|
||||
assert capsys.readouterr().out.startswith("usage: audita ")
|
||||
|
||||
|
||||
def test_process_help_exposes_framework_flags(capsys):
|
||||
with pytest.raises(SystemExit) as exc:
|
||||
main(["process", "--help"])
|
||||
|
||||
assert exc.value.code == 0
|
||||
output = capsys.readouterr().out
|
||||
assert "--report-json" in output
|
||||
assert "--model" in output
|
||||
assert "--base-url" in output
|
||||
assert "--max-retries" in output
|
||||
assert "--max-section-tokens" in output
|
||||
assert "--work-dir-retention" in output
|
||||
assert "--normalize-max-segment-gap" in output
|
||||
assert "--glossary-confidence-threshold" not in output
|
||||
assert "--grammar-validation-enabled" not in output
|
||||
|
||||
|
||||
def test_cli_process_writes_report_json(monkeypatch, tmp_path):
|
||||
transcript = parse_transcript_json(
|
||||
"""
|
||||
[
|
||||
{"id": 1, "speaker": "Eric", "start": 0.0, "end": 1.0, "text": "Fixed."}
|
||||
]
|
||||
"""
|
||||
)
|
||||
report = RunReport(
|
||||
status="success",
|
||||
config={"model": "m", "base_url": "b"},
|
||||
normalization={"source_segment_count": 1, "normalized_segment_count": 1, "merge_count": 0},
|
||||
pipeline=["glossary_primary", "homophones", "glossary_secondary", "spoken_word", "grammar"],
|
||||
modules=[],
|
||||
applied_changes=[],
|
||||
skipped_corrections=[],
|
||||
totals={"output_segment_count": 1, "applied_change_count": 0, "skipped_correction_count": 0},
|
||||
work_dir_retention="auto",
|
||||
work_dir_retained=False,
|
||||
work_dir=None,
|
||||
error=None,
|
||||
)
|
||||
result = ProcessResult(
|
||||
transcript=transcript,
|
||||
report=report,
|
||||
run_dir=tmp_path / "run",
|
||||
work_dir_retained=False,
|
||||
)
|
||||
|
||||
monkeypatch.setattr("audita.cli.AuditaConfig.from_sources", lambda overrides=None: object())
|
||||
monkeypatch.setattr("audita.cli.load_transcript", lambda path: [])
|
||||
monkeypatch.setattr("audita.cli.load_glossary", lambda path: object())
|
||||
monkeypatch.setattr("audita.cli.process_transcript_result", lambda *args, **kwargs: result)
|
||||
|
||||
output_path = tmp_path / "out.json"
|
||||
report_path = tmp_path / "report.json"
|
||||
exit_code = main(
|
||||
[
|
||||
"process",
|
||||
"transcript.json",
|
||||
"--glossary",
|
||||
"glossary.yaml",
|
||||
"--output",
|
||||
str(output_path),
|
||||
"--report-json",
|
||||
str(report_path),
|
||||
]
|
||||
)
|
||||
|
||||
assert exit_code == 0
|
||||
assert report_path.exists()
|
||||
31
tests/test_new_config.py
Normal file
31
tests/test_new_config.py
Normal file
@@ -0,0 +1,31 @@
|
||||
import pytest
|
||||
|
||||
from audita.core.config import (
|
||||
AuditaConfig,
|
||||
ConfigOverrides,
|
||||
DEFAULT_NORMALIZE_MAX_SEGMENT_GAP,
|
||||
DEFAULT_WORK_DIR_RETENTION,
|
||||
)
|
||||
from audita.core.errors import AuditaConfigError
|
||||
|
||||
|
||||
def test_default_config_allows_missing_api_key():
|
||||
config = AuditaConfig.from_sources(env={})
|
||||
|
||||
assert config.api_key is None
|
||||
assert config.normalize_max_segment_gap == DEFAULT_NORMALIZE_MAX_SEGMENT_GAP
|
||||
assert config.work_dir_retention == DEFAULT_WORK_DIR_RETENTION
|
||||
|
||||
|
||||
def test_cli_overrides_take_precedence():
|
||||
config = AuditaConfig.from_sources(
|
||||
env={"AUDITA_MAX_SECTION_TOKENS": "1000"},
|
||||
overrides=ConfigOverrides(max_section_tokens=2000),
|
||||
)
|
||||
|
||||
assert config.max_section_tokens == 2000
|
||||
|
||||
|
||||
def test_invalid_work_dir_retention_is_rejected():
|
||||
with pytest.raises(AuditaConfigError):
|
||||
AuditaConfig.from_sources(env={"AUDITA_WORK_DIR_RETENTION": "sometimes"})
|
||||
86
tests/test_new_pipeline.py
Normal file
86
tests/test_new_pipeline.py
Normal file
@@ -0,0 +1,86 @@
|
||||
import json
|
||||
|
||||
from audita.core.config import AuditaConfig
|
||||
from audita.core.io import write_report
|
||||
from audita.core.schemas import parse_glossary_yaml, parse_source_transcript_json
|
||||
from audita.pipeline import process_transcript, process_transcript_result
|
||||
|
||||
|
||||
def _glossary():
|
||||
return parse_glossary_yaml(
|
||||
"""
|
||||
glossary:
|
||||
- name: "Jesters"
|
||||
category: faction
|
||||
summary: "A faction."
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def _transcript():
|
||||
return parse_source_transcript_json(
|
||||
"""
|
||||
[
|
||||
{"speaker": "Eric", "start": 0.0, "end": 1.0, "text": "Hello."},
|
||||
{"speaker": "Eric", "start": 1.5, "end": 2.0, "text": "Again."},
|
||||
{"speaker": "Mike", "start": 10.0, "end": 11.0, "text": "Done."}
|
||||
]
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def test_process_transcript_runs_noop_framework(tmp_path):
|
||||
revised = process_transcript(
|
||||
_transcript(),
|
||||
_glossary(),
|
||||
AuditaConfig.from_sources(env={}, overrides=None),
|
||||
)
|
||||
|
||||
assert [segment.id for segment in revised] == [1, 2]
|
||||
assert revised[0].text == "Hello. Again."
|
||||
assert revised[1].text == "Done."
|
||||
|
||||
|
||||
def test_process_transcript_result_writes_report_and_preserves_skips_per_policy(tmp_path):
|
||||
config = AuditaConfig.from_sources(
|
||||
env={},
|
||||
overrides=None,
|
||||
)
|
||||
config = AuditaConfig(
|
||||
api_key=config.api_key,
|
||||
model=config.model,
|
||||
base_url=config.base_url,
|
||||
max_retries=config.max_retries,
|
||||
max_section_tokens=config.max_section_tokens,
|
||||
normalize_max_segment_gap=config.normalize_max_segment_gap,
|
||||
normalize_ellipsis_gap=config.normalize_ellipsis_gap,
|
||||
normalize_max_segment_duration=config.normalize_max_segment_duration,
|
||||
normalize_max_segment_tokens=config.normalize_max_segment_tokens,
|
||||
work_dir=tmp_path / "work",
|
||||
work_dir_retention="always",
|
||||
)
|
||||
|
||||
result = process_transcript_result(_transcript(), _glossary(), config)
|
||||
|
||||
assert result.work_dir_retained is True
|
||||
assert result.report.pipeline == [
|
||||
"glossary_primary",
|
||||
"homophones",
|
||||
"glossary_secondary",
|
||||
"spoken_word",
|
||||
"grammar",
|
||||
]
|
||||
assert result.report.totals["applied_change_count"] == 0
|
||||
assert (result.run_dir / "report.json").exists()
|
||||
assert (result.run_dir / "normalization" / "summary.json").exists()
|
||||
|
||||
|
||||
def test_external_report_can_be_written(tmp_path):
|
||||
config = AuditaConfig.from_sources(env={})
|
||||
result = process_transcript_result(_transcript(), _glossary(), config)
|
||||
report_path = tmp_path / "report.json"
|
||||
write_report(report_path, result.report)
|
||||
|
||||
payload = json.loads(report_path.read_text(encoding="utf-8"))
|
||||
assert payload["pipeline"][0] == "glossary_primary"
|
||||
assert payload["totals"]["applied_change_count"] == 0
|
||||
Reference in New Issue
Block a user