fb02d60054
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 21s
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 1m11s
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 56s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 34s
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 Web Image (pull_request) Successful in 35s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 38s
CI/CD Pipeline / Validate - Code Quality (pull_request) Failing after 1m58s
Preview Deploy / Deploy Preview Environment (pull_request) Failing after 35s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 53s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 3m6s
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
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m15s
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
AI Code Review / AI Code Review (pull_request) Successful in 3m47s
CI/CD Pipeline / Integration Tests (pull_request) Successful in 1m58s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 2m10s
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 33s
- unified_render_service: _resolve_layer_role图层映射 + _LAYER_Z_INDEX层级 + ResolvedClip/RenderLayer数据结构 - render_audio: clip_effective_duration时长计算 + clip_has_audio缓存机制 + RenderContext - render_adapter: _parse_resolution解析(16种边界) + RenderAdapterResult数据结构 +53 tests 全绿
155 lines
5.0 KiB
Python
Executable File
155 lines
5.0 KiB
Python
Executable File
"""渲染适配器纯逻辑测试 — _parse_resolution 等纯函数."""
|
||
|
||
from __future__ import annotations
|
||
|
||
from pathlib import Path
|
||
|
||
import pytest
|
||
|
||
from video_processing.render_adapter import (
|
||
DEFAULT_OUTPUT_HEIGHT,
|
||
DEFAULT_OUTPUT_WIDTH,
|
||
RenderAdapterResult,
|
||
_parse_resolution,
|
||
)
|
||
|
||
|
||
class TestParseResolution:
|
||
"""_parse_resolution 分辨率字符串解析测试."""
|
||
|
||
def test_standard_format(self):
|
||
"""标准 宽x高 格式."""
|
||
w, h = _parse_resolution("1920x1080")
|
||
assert w == 1920
|
||
assert h == 1080
|
||
|
||
def test_portrait_format(self):
|
||
"""竖屏格式."""
|
||
w, h = _parse_resolution("1080x1920")
|
||
assert w == 1080
|
||
assert h == 1920
|
||
|
||
def test_lowercase_x(self):
|
||
"""小写x."""
|
||
w, h = _parse_resolution("1280x720")
|
||
assert w == 1280
|
||
assert h == 720
|
||
|
||
def test_uppercase_x_returns_default(self):
|
||
"""大写X不匹配小写x → 返回默认值(只支持小写x)."""
|
||
w, h = _parse_resolution("1280X720")
|
||
assert w == DEFAULT_OUTPUT_WIDTH
|
||
assert h == DEFAULT_OUTPUT_HEIGHT
|
||
|
||
def test_none_returns_default(self):
|
||
"""None返回默认值."""
|
||
w, h = _parse_resolution(None)
|
||
assert w == DEFAULT_OUTPUT_WIDTH
|
||
assert h == DEFAULT_OUTPUT_HEIGHT
|
||
|
||
def test_empty_string_returns_default(self):
|
||
"""空字符串返回默认值."""
|
||
w, h = _parse_resolution("")
|
||
assert w == DEFAULT_OUTPUT_WIDTH
|
||
assert h == DEFAULT_OUTPUT_HEIGHT
|
||
|
||
def test_no_x_returns_default(self):
|
||
"""没有x的字符串返回默认值."""
|
||
w, h = _parse_resolution("1080p")
|
||
assert w == DEFAULT_OUTPUT_WIDTH
|
||
assert h == DEFAULT_OUTPUT_HEIGHT
|
||
|
||
def test_invalid_width_returns_default(self):
|
||
"""宽度无效返回默认值."""
|
||
w, h = _parse_resolution("abcx1080")
|
||
assert w == DEFAULT_OUTPUT_WIDTH
|
||
assert h == DEFAULT_OUTPUT_HEIGHT
|
||
|
||
def test_invalid_height_returns_default(self):
|
||
"""高度无效返回默认值."""
|
||
w, h = _parse_resolution("1920xabc")
|
||
assert w == DEFAULT_OUTPUT_WIDTH
|
||
assert h == DEFAULT_OUTPUT_HEIGHT
|
||
|
||
def test_zero_width_returns_default(self):
|
||
"""宽度为0返回默认值."""
|
||
w, h = _parse_resolution("0x1080")
|
||
assert w == DEFAULT_OUTPUT_WIDTH
|
||
assert h == DEFAULT_OUTPUT_HEIGHT
|
||
|
||
def test_zero_height_returns_default(self):
|
||
"""高度为0返回默认值."""
|
||
w, h = _parse_resolution("1920x0")
|
||
assert w == DEFAULT_OUTPUT_WIDTH
|
||
assert h == DEFAULT_OUTPUT_HEIGHT
|
||
|
||
def test_negative_width_returns_default(self):
|
||
"""负宽度返回默认值."""
|
||
w, h = _parse_resolution("-100x1080")
|
||
assert w == DEFAULT_OUTPUT_WIDTH
|
||
assert h == DEFAULT_OUTPUT_HEIGHT
|
||
|
||
def test_with_spaces(self):
|
||
"""带空格的能正确strip."""
|
||
w, h = _parse_resolution(" 1920 x 1080 ")
|
||
assert w == 1920
|
||
assert h == 1080
|
||
|
||
def test_multiple_x_returns_default(self):
|
||
"""多个x的字符串解析失败 → 返回默认值."""
|
||
w, h = _parse_resolution("100x200x300")
|
||
# split("x", 1)后h部分是"200x300",int失败返回默认
|
||
assert w == DEFAULT_OUTPUT_WIDTH
|
||
assert h == DEFAULT_OUTPUT_HEIGHT
|
||
|
||
def test_square_resolution(self):
|
||
"""正方形分辨率."""
|
||
w, h = _parse_resolution("512x512")
|
||
assert w == 512
|
||
assert h == 512
|
||
|
||
def test_default_values_are_reasonable(self):
|
||
"""默认值合理(竖屏短视频)."""
|
||
assert DEFAULT_OUTPUT_WIDTH > 0
|
||
assert DEFAULT_OUTPUT_HEIGHT > 0
|
||
# 默认是竖屏 1080x1920
|
||
assert DEFAULT_OUTPUT_WIDTH == 1080
|
||
assert DEFAULT_OUTPUT_HEIGHT == 1920
|
||
|
||
|
||
class TestRenderAdapterResult:
|
||
"""RenderAdapterResult 数据结构测试."""
|
||
|
||
def test_failure_defaults(self):
|
||
"""失败结果默认值."""
|
||
result = RenderAdapterResult(success=False)
|
||
assert result.success is False
|
||
assert result.output_url == ""
|
||
assert result.output_path is None
|
||
assert result.thumbnail_url == ""
|
||
assert result.duration == 0.0
|
||
assert result.file_size == 0
|
||
assert result.width == 0
|
||
assert result.height == 0
|
||
|
||
def test_success_with_values(self):
|
||
"""成功结果带完整值."""
|
||
result = RenderAdapterResult(
|
||
success=True,
|
||
output_url="https://example.com/output.mp4",
|
||
output_path=Path("/tmp/output.mp4"),
|
||
thumbnail_url="https://example.com/thumb.jpg",
|
||
duration=30.5,
|
||
file_size=1024000,
|
||
width=1080,
|
||
height=1920,
|
||
)
|
||
assert result.success is True
|
||
assert result.output_url == "https://example.com/output.mp4"
|
||
assert result.output_path == Path("/tmp/output.mp4")
|
||
assert result.thumbnail_url == "https://example.com/thumb.jpg"
|
||
assert result.duration == pytest.approx(30.5)
|
||
assert result.file_size == 1024000
|
||
assert result.width == 1080
|
||
assert result.height == 1920
|