Files
xiaoxia-saas/tests/unit/test_render_audio_utils.py
T
CI Bot b16fbb636d
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 14s
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 53s
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 47s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 32s
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 29s
CI/CD Pipeline / Validate - Code Quality (pull_request) Successful in 3m21s
CI/CD Pipeline / PR Build Web Image (pull_request) Successful in 1m45s
Preview Deploy / Deploy Preview Environment (pull_request) Failing after 14s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 3m38s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m41s
AI Code Review / AI Code Review (pull_request) Successful in 5m17s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Integration Tests (pull_request) Successful in 2m6s
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 48m5s
CI/CD Pipeline / Unit Tests (pull_request) Failing after 1h10m2s
style: isort修复5个测试文件导入排序,修复Code Quality门禁
2026-07-25 00:44:14 +08:00

108 lines
4.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
render_audio 纯工具函数测试.
覆盖 clip_effective_duration / RenderContext 等纯逻辑.
核心混音逻辑依赖 FFmpeg,由集成测试覆盖.
"""
from __future__ import annotations
from pathlib import Path
from types import SimpleNamespace
from unittest.mock import MagicMock
import pytest
from video_processing.render_audio import RenderContext, clip_effective_duration
class TestClipEffectiveDuration:
"""clip_effective_duration 有效时长计算."""
def test_duration_specified_and_actual_longer(self):
"""指定了 duration,且实际时长更长 → 取 duration"""
clip = SimpleNamespace(duration=5.0, actual_duration=10.0)
assert clip_effective_duration(clip) == 5.0
def test_duration_specified_and_actual_shorter(self):
"""指定了 duration,但实际时长更短 → 取实际时长"""
clip = SimpleNamespace(duration=10.0, actual_duration=5.0)
assert clip_effective_duration(clip) == 5.0
def test_duration_specified_actual_zero(self):
"""指定了 duration,但实际时长为 0 → 取 duration"""
clip = SimpleNamespace(duration=5.0, actual_duration=0.0)
assert clip_effective_duration(clip) == 5.0
def test_duration_specified_actual_negative(self):
"""指定了 duration,但实际时长为负 → 取 duration"""
clip = SimpleNamespace(duration=5.0, actual_duration=-1.0)
assert clip_effective_duration(clip) == 5.0
def test_no_duration_use_actual(self):
"""未指定 duration0),用实际时长"""
clip = SimpleNamespace(duration=0.0, actual_duration=8.0)
assert clip_effective_duration(clip) == 8.0
def test_no_duration_negative_actual(self):
"""未指定 duration,实际时长也为负 → 返回 0"""
clip = SimpleNamespace(duration=0.0, actual_duration=-5.0)
assert clip_effective_duration(clip) == 0.0
def test_no_duration_zero_actual(self):
"""都为 0 → 返回 0"""
clip = SimpleNamespace(duration=0.0, actual_duration=0.0)
assert clip_effective_duration(clip) == 0.0
def test_negative_duration_use_actual(self):
"""duration 为负(视为未指定),用实际时长"""
clip = SimpleNamespace(duration=-1.0, actual_duration=5.0)
assert clip_effective_duration(clip) == 5.0
def test_both_negative_returns_zero(self):
"""两者都为负 → 返回 0"""
clip = SimpleNamespace(duration=-2.0, actual_duration=-3.0)
assert clip_effective_duration(clip) == 0.0
def test_exact_match(self):
"""duration 与实际时长相等"""
clip = SimpleNamespace(duration=7.5, actual_duration=7.5)
assert clip_effective_duration(clip) == 7.5
def test_very_short_duration(self):
"""很短的时长"""
clip = SimpleNamespace(duration=0.1, actual_duration=0.2)
assert clip_effective_duration(clip) == 0.1
class TestRenderContext:
"""RenderContext 渲染上下文."""
def test_create_with_work_dir_and_plan_id(self, tmp_path):
ctx = RenderContext(work_dir=tmp_path, plan_id="plan_123")
assert ctx.work_dir == tmp_path
assert ctx.plan_id == "plan_123"
assert ctx.noise_reduction_config is None
assert ctx._audio_cache == {}
def test_noise_reduction_config(self, tmp_path):
config = {"enabled": True, "strength": 0.5}
ctx = RenderContext(
work_dir=tmp_path,
plan_id="plan_123",
noise_reduction_config=config,
)
assert ctx.noise_reduction_config == config
assert ctx.noise_reduction_config["enabled"] is True
def test_audio_cache_isolation(self, tmp_path):
"""每个实例有独立的缓存字典."""
ctx1 = RenderContext(work_dir=tmp_path, plan_id="p1")
ctx2 = RenderContext(work_dir=tmp_path, plan_id="p2")
ctx1._audio_cache["key1"] = True
assert "key1" not in ctx2._audio_cache
assert len(ctx2._audio_cache) == 0
def test_work_dir_path_type(self, tmp_path):
ctx = RenderContext(work_dir=tmp_path, plan_id="test")
assert isinstance(ctx.work_dir, Path)