"""统一渲染服务纯逻辑测试 — _resolve_layer_role + 图层配置 + 数据结构.""" from __future__ import annotations from pathlib import Path import pytest from video_processing.unified_render_service import ( _LAYER_Z_INDEX, _PIP_SCALE, RenderLayer, ResolvedClip, _resolve_layer_role, ) class TestResolveLayerRole: """_resolve_layer_role 图层角色映射测试.""" def test_intro_is_main(self): """intro片段 → main层.""" assert _resolve_layer_role("intro", {}) == "main" def test_outro_is_main(self): """outro片段 → main层.""" assert _resolve_layer_role("outro", {}) == "main" def test_overlay_is_overlay(self): """overlay片段 → overlay层.""" assert _resolve_layer_role("overlay", {}) == "overlay" def test_corner_voice(self): """corner_voice片段 → corner_voice层.""" assert _resolve_layer_role("corner_voice", {}) == "corner_voice" def test_background(self): """background片段 → background层.""" assert _resolve_layer_role("background", {}) == "background" def test_b_roll(self): """b_roll片段 → broll层.""" assert _resolve_layer_role("b_roll", {}) == "broll" def test_main_default(self): """main type默认 → main层.""" assert _resolve_layer_role("main", {}) == "main" def test_main_with_broll_role(self): """main type + role=b_roll → broll层.""" assert _resolve_layer_role("main", {"role": "b_roll"}) == "broll" def test_main_with_audio_role(self): """main type + role=audio → audio层.""" assert _resolve_layer_role("main", {"role": "audio"}) == "audio" def test_unknown_type_falls_back_to_main(self): """未知类型 → main层.""" assert _resolve_layer_role("random_type", {}) == "main" def test_intro_ignores_role(self): """intro/outro忽略role配置.""" assert _resolve_layer_role("intro", {"role": "b_roll"}) == "main" assert _resolve_layer_role("outro", {"role": "overlay"}) == "main" def test_empty_config(self): """空config不影响结果.""" assert _resolve_layer_role("main", {}) == "main" def test_none_role(self): """role=None时走默认.""" assert _resolve_layer_role("main", {"role": None}) == "main" class TestLayerZIndex: """_LAYER_Z_INDEX 图层层级配置测试.""" def test_background_lowest(self): """background在最底层.""" assert _LAYER_Z_INDEX["background"] == -1 def test_main_and_broll_same_level(self): """main和broll在同一层(z=0).""" assert _LAYER_Z_INDEX["main"] == 0 assert _LAYER_Z_INDEX["broll"] == 0 def test_overlay_and_corner_voice_above(self): """overlay和corner_voice在z=1.""" assert _LAYER_Z_INDEX["overlay"] == 1 assert _LAYER_Z_INDEX["corner_voice"] == 1 def test_audio_highest(self): """audio在z=2(最高,因为音频不涉及z顺序但参与混音).""" assert _LAYER_Z_INDEX["audio"] == 2 def test_pip_scale_is_positive(self): """PiP缩放比例为正数.""" assert _PIP_SCALE > 0 assert _PIP_SCALE < 1.0 class TestResolvedClip: """ResolvedClip 数据结构测试.""" def test_default_values(self): """默认值正确.""" clip = ResolvedClip( clip_id="c1", asset_id="a1", local_path=Path("/tmp/test.mp4"), clip_type="main", order=0, ) assert clip.start_time == 0.0 assert clip.duration == 0.0 assert clip.transition_effect == "cut" assert clip.transition_duration == 0.0 assert clip.playback_speed == 1.0 assert clip.config == {} assert clip.actual_duration == 0.0 assert clip.trim_config is None def test_custom_values(self): """自定义值正确.""" clip = ResolvedClip( clip_id="c2", asset_id="a2", local_path=Path("/tmp/video.mp4"), clip_type="overlay", order=1, start_time=5.0, duration=10.0, transition_effect="fade", transition_duration=0.5, playback_speed=1.5, ) assert clip.clip_id == "c2" assert clip.asset_id == "a2" assert clip.clip_type == "overlay" assert clip.order == 1 assert clip.start_time == 5.0 assert clip.duration == 10.0 assert clip.transition_effect == "fade" assert clip.transition_duration == 0.5 assert clip.playback_speed == 1.5 class TestRenderLayer: """RenderLayer 数据结构测试.""" def test_default_values(self): """默认值正确.""" layer = RenderLayer(role="main") assert layer.clips == [] assert layer.z_index == 0 assert layer.opacity == 1.0 assert layer.position is None def test_with_clips(self): """带片段的图层.""" clip = ResolvedClip( clip_id="c1", asset_id="a1", local_path=Path("/tmp/t.mp4"), clip_type="main", order=0, ) layer = RenderLayer(role="overlay", clips=[clip], z_index=1) assert len(layer.clips) == 1 assert layer.z_index == 1 assert layer.role == "overlay" def test_background_layer(self): """background图层配置.""" layer = RenderLayer(role="background", z_index=-1, opacity=1.0) assert layer.role == "background" assert layer.z_index == -1 assert layer.opacity == 1.0