File size: 2,289 Bytes
ccf5848
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
"""Shared fixtures and the deployed-Space plumbing for the whole Phase 1 suite."""

from __future__ import annotations

import json
import wave
from pathlib import Path

import pytest

FIXTURES = Path(__file__).parent / "fixtures"


def pytest_addoption(parser):
    parser.addoption(
        "--space-url",
        action="store",
        default=None,
        help="Base URL of the deployed Space, e.g. https://wolfdavid-japanese-learning-avatar.hf.space",
    )


def pytest_collection_modifyitems(config, items):
    if config.getoption("--space-url"):
        return
    skip = pytest.mark.skip(reason="needs --space-url (deployed Space)")
    for item in items:
        if "deployed" in item.keywords:
            item.add_marker(skip)


@pytest.fixture(scope="session")
def space_url(request) -> str:
    url = request.config.getoption("--space-url")
    if not url:
        pytest.skip("needs --space-url")
    return url.rstrip("/")


@pytest.fixture(scope="session")
def fixtures_dir() -> Path:
    return FIXTURES


@pytest.fixture(scope="session")
def silence_wav() -> Path:
    return FIXTURES / "silence_30s.wav"


@pytest.fixture(scope="session")
def cafe_noise_wav() -> Path:
    return FIXTURES / "cafe_noise_30s.wav"


@pytest.fixture(scope="session")
def speech_wav() -> Path:
    """Japanese speech fixture. Produced by plan 01-04 from real VOICEVOX synthesis."""
    p = FIXTURES / "speech_ja.wav"
    if not p.exists():
        pytest.skip("speech_ja.wav not generated yet (plan 01-04)")
    return p


@pytest.fixture(scope="session")
def synth_meta() -> dict:
    """Recorded synthesis metadata written by plan 01-04.

    Shape: {"cases": {"<case>": {"query": "<file>.json", "wav": "<file>.wav",
                                 "text": "...", "speed_scale": 1.0,
                                 "duration_seconds": <float from the WAV header>,
                                 "mora_count": <int>, "vowel_symbols": [...]}}}
    """
    p = FIXTURES / "synth_meta.json"
    if not p.exists():
        pytest.skip("synth_meta.json not generated yet (plan 01-04)")
    return json.loads(p.read_text(encoding="utf-8"))


def wav_duration_seconds(path: Path) -> float:
    with wave.open(str(path), "rb") as w:
        return w.getnframes() / float(w.getframerate())