speech-text-data-aligners / tests /unit /data /test_metadata.py
pltobing's picture
chore(repo): finalize licensing and documentation
51e84d2
Raw History Blame Contribute Delete
4.99 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 os
from pathlib import Path
import pytest
from speech_text_data_aligners.core.errors import MetadataError
from speech_text_data_aligners.core.extraction import BOUNDARY_COLUMNS
from speech_text_data_aligners.data.metadata import (
MetadataTable,
read_metadata,
write_annotated_metadata,
)
def valid_annotations(count: int) -> tuple[dict[str, str | float | None], ...]:
return tuple(
{
"first_word_text": "Hello",
"first_word_start_s": 0.000001,
"first_word_end_s": 0.5,
"last_word_text": "world",
"last_word_start_s": 1.0,
"last_word_end_s": None,
}
for _ in range(count)
)
def test_read_and_write_preserve_bom_crlf_quoted_values_and_order(
tmp_path: Path,
) -> None:
source = tmp_path / "source.csv"
source.write_bytes(
b"\xef\xbb\xbfline_id,audio_id,en_transcript,ru_translation\r\n"
b'L1,a1,"Hello, world",Russian\r\n'
b'L1,a2,"multi\r\nline",Exact\r\n'
)
table = read_metadata(source)
assert table.csv_format.encoding == "utf-8-sig"
assert table.csv_format.lineterminator == "\r\n"
assert table.row_dict(0)["en_transcript"] == "Hello, world"
assert table.row_dict(1)["en_transcript"] == "multi\r\nline"
output = tmp_path / "output.csv"
write_annotated_metadata(table, output, valid_annotations(2))
reread = read_metadata(output)
assert reread.fieldnames == (*table.fieldnames, *BOUNDARY_COLUMNS)
assert reread.rows[0][:4] == table.rows[0]
assert reread.row_dict(0)["first_word_start_s"] == "0.000001"
assert reread.row_dict(0)["first_word_end_s"] == "0.5"
assert reread.row_dict(0)["last_word_end_s"] == ""
@pytest.mark.parametrize(
"content",
[
b"",
b"line_id,audio_id,en_transcript\nL,a,t\n",
b"line_id,audio_id,en_transcript,ru_translation,line_id\n",
b"line_id,audio_id,en_transcript,ru_translation\nL,a,t\n",
b'line_id,audio_id,en_transcript,ru_translation\nL,a,"unterminated,x\n',
b"\xff\xfeinvalid",
],
)
def test_read_rejects_empty_missing_duplicate_malformed_and_non_utf8(
tmp_path: Path, content: bytes
) -> None:
path = tmp_path / "bad.csv"
path.write_bytes(content)
with pytest.raises(MetadataError):
read_metadata(path)
def test_read_rejects_missing_path(tmp_path: Path) -> None:
with pytest.raises(MetadataError):
read_metadata(tmp_path / "missing.csv")
def test_write_rejects_unsafe_schema_counts_keys_and_overwrite(
metadata_fixture: tuple[Path, Path], tmp_path: Path
) -> None:
source, _ = metadata_fixture
table = read_metadata(source)
output = tmp_path / "out.csv"
output.write_text("existing", encoding="utf-8")
with pytest.raises(MetadataError, match="source metadata"):
write_annotated_metadata(table, source, valid_annotations(2))
with pytest.raises(MetadataError, match="count"):
write_annotated_metadata(table, tmp_path / "other.csv", valid_annotations(1))
with pytest.raises(MetadataError, match="six"):
write_annotated_metadata(table, tmp_path / "other.csv", ({"bad": "x"},) * 2)
with pytest.raises(MetadataError, match="overwrite"):
write_annotated_metadata(table, output, valid_annotations(2))
enriched = MetadataTable(
table.source_path,
(*table.fieldnames, BOUNDARY_COLUMNS[0]),
tuple((*row, "") for row in table.rows),
table.csv_format,
)
with pytest.raises(MetadataError, match="already"):
write_annotated_metadata(
enriched, tmp_path / "enriched.csv", valid_annotations(2)
)
def test_write_overwrites_when_authorized(
metadata_fixture: tuple[Path, Path], tmp_path: Path
) -> None:
source, _ = metadata_fixture
table = read_metadata(source)
output = tmp_path / "out.csv"
output.write_text("old", encoding="utf-8")
write_annotated_metadata(table, output, valid_annotations(2), overwrite=True)
assert read_metadata(output).row_dict(0)["first_word_text"] == "Hello"
def test_write_translates_publication_oserror(
metadata_fixture: tuple[Path, Path], tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
source, _ = metadata_fixture
table = read_metadata(source)
def fail_replace(source_path: Path, destination_path: Path) -> None:
raise OSError(source_path, destination_path)
monkeypatch.setattr(os, "replace", fail_replace)
with pytest.raises(MetadataError, match="publish"):
write_annotated_metadata(table, tmp_path / "out.csv", valid_annotations(2))
assert not list(tmp_path.glob(".out.csv.*.tmp"))