pltobing's picture
chore(repo): finalize licensing and documentation
51e84d2
Raw History Blame Contribute Delete
6.39 kB
# License: Apache-2.0 License
# Created by: Patrick Lumbantobing, VertoX-AI
# Copyright (c) 2026 VertoX-AI. All rights reserved.
#
# This work is licensed under the Apache-2.0 License.
# To view a copy of this license, visit
# https://www.apache.org/licenses/LICENSE-2.0
from __future__ import annotations
import csv
from pathlib import Path
import pytest
from speech_text_data_aligners.application.benchmark import (
BenchmarkOptions,
benchmark_backend,
benchmark_backends,
)
from speech_text_data_aligners.core.errors import BenchmarkError, SpeechTextAlignerError
from tests.fakes import FakeBackend
def write_reference(path: Path, rows: list[tuple[str, str, str, str]]) -> Path:
with path.open("w", encoding="utf-8", newline="") as stream:
writer = csv.writer(stream, lineterminator="\n")
writer.writerow(
(
"line_id",
"audio_id",
"en_transcript",
"ru_translation",
"first_word_text",
"first_word_end_s",
)
)
for line_id, audio_id, first_word, end in rows:
writer.writerow((line_id, audio_id, "ignored", "ignored", first_word, end))
return path
def test_benchmark_runs_identical_requests_and_builds_gold_and_pairwise_report(
metadata_fixture: tuple[Path, Path], tmp_path: Path
) -> None:
metadata, audio_dir = metadata_fixture
reference = write_reference(
tmp_path / "gold.csv",
[("L1", "a1", "Hello", "0.2"), ("L1", "a2", "Can't", "0.2")],
)
left = FakeBackend(offset=0.0)
right = FakeBackend(offset=0.1)
report = benchmark_backends(
backends={"left": left, "right": right},
metadata_csv=metadata,
reference_csv=reference,
audio_dir=audio_dir,
)
assert left.batches[0] == right.batches[0]
assert [request.transcript for request in left.batches[0]] == [
"Hello world.",
"Can't stop",
]
assert report.backend_reports[0].gold_metrics.exact_text_match_count == 2
assert report.backend_reports[0].gold_metrics.first_end_errors.mae == 0.0
assert report.backend_reports[0].observations[0].native_artifacts == ()
assert report.pairwise_metrics[0].first_end.mae == pytest.approx(0.1)
def test_benchmark_single_wrapper_and_sparse_missing_reference(
metadata_fixture: tuple[Path, Path], tmp_path: Path
) -> None:
metadata, audio_dir = metadata_fixture
reference = write_reference(tmp_path / "gold.csv", [("L1", "a1", "", "")])
backend = FakeBackend()
report = benchmark_backend(
backend=backend,
metadata_csv=metadata,
reference_csv=reference,
audio_dir=audio_dir,
)
metrics = report.backend_reports[0].gold_metrics
assert metrics.referenced_rows == 1
assert metrics.missing_reference_rows == 1
assert metrics.exact_text_match_rate is None
assert report.pairwise_metrics == ()
@pytest.mark.parametrize("bad_end", ["bad", "nan", "-0.1", "inf"])
def test_benchmark_rejects_invalid_reference_timestamp(
metadata_fixture: tuple[Path, Path], tmp_path: Path, bad_end: str
) -> None:
metadata, audio_dir = metadata_fixture
reference = write_reference(tmp_path / "gold.csv", [("L1", "a1", "Hello", bad_end)])
with pytest.raises(BenchmarkError, match="invalid"):
benchmark_backend(
backend=FakeBackend(),
metadata_csv=metadata,
reference_csv=reference,
audio_dir=audio_dir,
)
def test_benchmark_rejects_duplicate_and_extra_reference_rows(
metadata_fixture: tuple[Path, Path], tmp_path: Path
) -> None:
metadata, audio_dir = metadata_fixture
duplicate = write_reference(
tmp_path / "duplicate.csv",
[("L1", "a1", "Hello", "0.2"), ("L1", "a1", "Hello", "0.2")],
)
with pytest.raises(BenchmarkError, match="duplicate"):
benchmark_backend(
backend=FakeBackend(),
metadata_csv=metadata,
reference_csv=duplicate,
audio_dir=audio_dir,
)
extra = write_reference(tmp_path / "extra.csv", [("X", "other", "A", "0.2")])
with pytest.raises(BenchmarkError, match="absent"):
benchmark_backend(
backend=FakeBackend(),
metadata_csv=metadata,
reference_csv=extra,
audio_dir=audio_dir,
)
def test_benchmark_rejects_missing_reference_fields_and_backend_mapping(
metadata_fixture: tuple[Path, Path], tmp_path: Path
) -> None:
metadata, audio_dir = metadata_fixture
bad_reference = tmp_path / "bad.csv"
bad_reference.write_text(
"line_id,audio_id,en_transcript,ru_translation\nL1,a1,x,y\n",
encoding="utf-8",
)
with pytest.raises(BenchmarkError, match="lacks"):
benchmark_backend(
backend=FakeBackend(),
metadata_csv=metadata,
reference_csv=bad_reference,
audio_dir=audio_dir,
)
valid = write_reference(tmp_path / "valid.csv", [])
with pytest.raises(BenchmarkError, match="at least"):
benchmark_backends(
backends={}, metadata_csv=metadata, reference_csv=valid, audio_dir=audio_dir
)
with pytest.raises(BenchmarkError, match="cannot be empty"):
benchmark_backends(
backends={"": FakeBackend()},
metadata_csv=metadata,
reference_csv=valid,
audio_dir=audio_dir,
)
def test_benchmark_continue_mode_records_failures_and_strict_mode_aborts(
metadata_fixture: tuple[Path, Path], tmp_path: Path
) -> None:
metadata, audio_dir = metadata_fixture
reference = write_reference(tmp_path / "gold.csv", [("L1", "a1", "Hello", "0.2")])
report = benchmark_backend(
backend=FakeBackend(fail_ids={"000000"}),
metadata_csv=metadata,
reference_csv=reference,
audio_dir=audio_dir,
)
assert report.backend_reports[0].gold_metrics.failure_count == 1
assert report.backend_reports[0].observations[0].failure_code == "fake_failure"
with pytest.raises(SpeechTextAlignerError):
benchmark_backend(
backend=FakeBackend(fail_ids={"000000"}),
metadata_csv=metadata,
reference_csv=reference,
audio_dir=audio_dir,
options=BenchmarkOptions(strict=True),
)