style: auto-format with black + isort + prettier
CI/CD Pipeline / Validate - Migration (alembic) (push) Successful in 1m42s
CI/CD Pipeline / Validate - Type Check (mypy) (push) Successful in 1m44s
CI/CD Pipeline / Build Staging Web Image (push) Successful in 1m42s
CI/CD Pipeline / Frontend Unit Tests (push) Successful in 1m26s
CI/CD Pipeline / Validate - Code Quality (push) Failing after 3m13s
CI/CD Pipeline / Build Staging Worker Image (push) Successful in 2m22s
CI/CD Pipeline / Frontend Lint (push) Successful in 4m29s
CI/CD Pipeline / Integration Tests (push) Successful in 2m16s
CI/CD Pipeline / Unit Tests (push) Failing after 5m46s
CI/CD Pipeline / Build Staging API Image (push) Successful in 11m28s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Successful in 3m18s
CI/CD Pipeline / ACR Image Cleanup (push) Successful in 30s
CI/CD Pipeline / Staging E2E Tests (push) Failing after 2m13s
CI/CD Pipeline / Staging API Integration Tests (push) Successful in 5m58s
CI/CD Pipeline / Production Browser E2E (push) Failing after 1289h2m32s
CI/CD Pipeline / Build Production Worker Image (push) Failing after 1289h5m6s
CI/CD Pipeline / Build Production Web Image (push) Failing after 1289h5m7s
CI/CD Pipeline / PR Build Worker Image (push) Failing after 1289h6m49s
CI/CD Pipeline / PR Build Web Image (push) Failing after 1289h6m50s
CI/CD Pipeline / Check if frontend-only change (push) Failing after 1289h6m52s
CI/CD Pipeline / Deploy Production (push) Failing after 1289h35m22s
CI/CD Pipeline / Build Production API Image (push) Failing after 1289h37m37s
CI/CD Pipeline / PR Build API Image (push) Failing after 1289h39m20s
CI/CD Pipeline / Validate - Migration (alembic) (push) Successful in 1m42s
CI/CD Pipeline / Validate - Type Check (mypy) (push) Successful in 1m44s
CI/CD Pipeline / Build Staging Web Image (push) Successful in 1m42s
CI/CD Pipeline / Frontend Unit Tests (push) Successful in 1m26s
CI/CD Pipeline / Validate - Code Quality (push) Failing after 3m13s
CI/CD Pipeline / Build Staging Worker Image (push) Successful in 2m22s
CI/CD Pipeline / Frontend Lint (push) Successful in 4m29s
CI/CD Pipeline / Integration Tests (push) Successful in 2m16s
CI/CD Pipeline / Unit Tests (push) Failing after 5m46s
CI/CD Pipeline / Build Staging API Image (push) Successful in 11m28s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Successful in 3m18s
CI/CD Pipeline / ACR Image Cleanup (push) Successful in 30s
CI/CD Pipeline / Staging E2E Tests (push) Failing after 2m13s
CI/CD Pipeline / Staging API Integration Tests (push) Successful in 5m58s
CI/CD Pipeline / Production Browser E2E (push) Failing after 1289h2m32s
CI/CD Pipeline / Build Production Worker Image (push) Failing after 1289h5m6s
CI/CD Pipeline / Build Production Web Image (push) Failing after 1289h5m7s
CI/CD Pipeline / PR Build Worker Image (push) Failing after 1289h6m49s
CI/CD Pipeline / PR Build Web Image (push) Failing after 1289h6m50s
CI/CD Pipeline / Check if frontend-only change (push) Failing after 1289h6m52s
CI/CD Pipeline / Deploy Production (push) Failing after 1289h35m22s
CI/CD Pipeline / Build Production API Image (push) Failing after 1289h37m37s
CI/CD Pipeline / PR Build API Image (push) Failing after 1289h39m20s
This commit is contained in:
@@ -1,11 +1,10 @@
|
||||
"""ReverseEngine 单测 — 倒放引擎配置解析 + 滤镜构建."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
from video_processing.reverse_engine import ReverseConfig, ReverseEngine
|
||||
|
||||
|
||||
# ── ReverseConfig.from_dict ────────────────────────────────────────────────
|
||||
|
||||
|
||||
@@ -34,31 +33,37 @@ class TestReverseConfigFromDict:
|
||||
assert config.reverse_audio is True
|
||||
|
||||
def test_disable_video_only(self):
|
||||
config = ReverseConfig.from_dict({
|
||||
"enabled": True,
|
||||
"reverse_video": False,
|
||||
"reverse_audio": True,
|
||||
})
|
||||
config = ReverseConfig.from_dict(
|
||||
{
|
||||
"enabled": True,
|
||||
"reverse_video": False,
|
||||
"reverse_audio": True,
|
||||
}
|
||||
)
|
||||
assert config.enabled is True
|
||||
assert config.reverse_video is False
|
||||
assert config.reverse_audio is True
|
||||
|
||||
def test_disable_audio_only(self):
|
||||
config = ReverseConfig.from_dict({
|
||||
"enabled": True,
|
||||
"reverse_video": True,
|
||||
"reverse_audio": False,
|
||||
})
|
||||
config = ReverseConfig.from_dict(
|
||||
{
|
||||
"enabled": True,
|
||||
"reverse_video": True,
|
||||
"reverse_audio": False,
|
||||
}
|
||||
)
|
||||
assert config.enabled is True
|
||||
assert config.reverse_video is True
|
||||
assert config.reverse_audio is False
|
||||
|
||||
def test_both_disabled(self):
|
||||
config = ReverseConfig.from_dict({
|
||||
"enabled": True,
|
||||
"reverse_video": False,
|
||||
"reverse_audio": False,
|
||||
})
|
||||
config = ReverseConfig.from_dict(
|
||||
{
|
||||
"enabled": True,
|
||||
"reverse_video": False,
|
||||
"reverse_audio": False,
|
||||
}
|
||||
)
|
||||
assert config.enabled is True
|
||||
assert config.reverse_video is False
|
||||
assert config.reverse_audio is False
|
||||
@@ -75,22 +80,26 @@ class TestReverseConfigFromDict:
|
||||
|
||||
def test_truthy_values(self):
|
||||
"""非布尔真值也能被 bool() 转换."""
|
||||
config = ReverseConfig.from_dict({
|
||||
"enabled": 1,
|
||||
"reverse_video": 1,
|
||||
"reverse_audio": "yes",
|
||||
})
|
||||
config = ReverseConfig.from_dict(
|
||||
{
|
||||
"enabled": 1,
|
||||
"reverse_video": 1,
|
||||
"reverse_audio": "yes",
|
||||
}
|
||||
)
|
||||
assert config.enabled is True
|
||||
assert config.reverse_video is True
|
||||
assert config.reverse_audio is True
|
||||
|
||||
def test_falsy_values(self):
|
||||
"""非布尔假值也能被 bool() 转换."""
|
||||
config = ReverseConfig.from_dict({
|
||||
"enabled": True,
|
||||
"reverse_video": 0,
|
||||
"reverse_audio": "",
|
||||
})
|
||||
config = ReverseConfig.from_dict(
|
||||
{
|
||||
"enabled": True,
|
||||
"reverse_video": 0,
|
||||
"reverse_audio": "",
|
||||
}
|
||||
)
|
||||
assert config.enabled is True
|
||||
assert config.reverse_video is False
|
||||
assert config.reverse_audio is False
|
||||
@@ -125,17 +134,13 @@ class TestBuildVideoFilter:
|
||||
def test_exactly_max_safe_duration(self):
|
||||
"""刚好等于上限,允许."""
|
||||
config = ReverseConfig(enabled=True)
|
||||
result = ReverseEngine.build_video_filter(
|
||||
config, duration=ReverseEngine.MAX_SAFE_DURATION
|
||||
)
|
||||
result = ReverseEngine.build_video_filter(config, duration=ReverseEngine.MAX_SAFE_DURATION)
|
||||
assert result == "reverse"
|
||||
|
||||
def test_exceeds_max_safe_duration_skips(self):
|
||||
"""超过上限,跳过倒放,返回空字符串."""
|
||||
config = ReverseConfig(enabled=True)
|
||||
result = ReverseEngine.build_video_filter(
|
||||
config, duration=ReverseEngine.MAX_SAFE_DURATION + 1
|
||||
)
|
||||
result = ReverseEngine.build_video_filter(config, duration=ReverseEngine.MAX_SAFE_DURATION + 1)
|
||||
assert result == ""
|
||||
|
||||
def test_negative_duration(self):
|
||||
@@ -173,22 +178,16 @@ class TestBuildAudioFilter:
|
||||
|
||||
def test_exactly_max_safe_duration(self):
|
||||
config = ReverseConfig(enabled=True)
|
||||
result = ReverseEngine.build_audio_filter(
|
||||
config, duration=ReverseEngine.MAX_SAFE_DURATION
|
||||
)
|
||||
result = ReverseEngine.build_audio_filter(config, duration=ReverseEngine.MAX_SAFE_DURATION)
|
||||
assert result == "areverse"
|
||||
|
||||
def test_exceeds_max_safe_duration_skips(self):
|
||||
config = ReverseConfig(enabled=True)
|
||||
result = ReverseEngine.build_audio_filter(
|
||||
config, duration=ReverseEngine.MAX_SAFE_DURATION + 1
|
||||
)
|
||||
result = ReverseEngine.build_audio_filter(config, duration=ReverseEngine.MAX_SAFE_DURATION + 1)
|
||||
assert result == ""
|
||||
|
||||
def test_both_video_and_audio_disabled(self):
|
||||
"""两个都关,两个滤镜都为空."""
|
||||
config = ReverseConfig(
|
||||
enabled=True, reverse_video=False, reverse_audio=False
|
||||
)
|
||||
config = ReverseConfig(enabled=True, reverse_video=False, reverse_audio=False)
|
||||
assert ReverseEngine.build_video_filter(config, 10) == ""
|
||||
assert ReverseEngine.build_audio_filter(config, 10) == ""
|
||||
|
||||
Reference in New Issue
Block a user