releases/tests/Paca.Tests/Core/VideoEnginesExtremeRedTests.cs
Yun Chan 8677853822
Some checks failed
release / test (push) Failing after 14m5s
release / windows (push) Has been cancelled
release / android (push) Has been cancelled
release / linux (push) Has been cancelled
release / macos (push) Has been cancelled
test(core/browser/platform): 26 extreme RED/GREEN TDD cycles and full regression hardening (3,235 PASS)
2026-09-18 23:32:32 +09:00

167 lines
6.4 KiB
C#

using System;
using Paca.Core;
using Xunit;
namespace Paca.Tests.Core;
public class VideoEnginesExtremeRedTests
{
private const string SampleInput = "C:\\Videos\\input.mp4";
private const string SampleOutput = "C:\\Videos\\output.mp4";
// ==========================================
// 1. VideoAspectAutoCropper
// ==========================================
[Fact]
public void VideoAspectAutoCropper_BuildCommandLine_SameInputAndOutput_ThrowsInvalidOperationException()
{
Assert.Throws<InvalidOperationException>(() =>
VideoAspectAutoCropper.BuildReframingCommandLine(SampleInput, SampleInput, ReframingMode.CenterCrop));
}
[Theory]
[InlineData(null, SampleOutput)]
[InlineData(SampleInput, null)]
[InlineData("", SampleOutput)]
[InlineData(SampleInput, " ")]
public void VideoAspectAutoCropper_BuildCommandLine_NullOrWhitespace_ThrowsArgumentException(string? inPath, string? outPath)
{
Assert.Throws<ArgumentException>(() =>
VideoAspectAutoCropper.BuildReframingCommandLine(inPath!, outPath!, ReframingMode.CenterCrop));
}
// ==========================================
// 2. VideoIntroOutroTrimmer
// ==========================================
[Fact]
public void VideoIntroOutroTrimmer_BuildCommandLine_SameInputAndOutput_ThrowsInvalidOperationException()
{
Assert.Throws<InvalidOperationException>(() =>
VideoIntroOutroTrimmer.BuildLosslessTrimCommandLine(SampleInput, SampleInput, 0, 10));
}
[Theory]
[InlineData(null, SampleOutput)]
[InlineData(SampleInput, null)]
public void VideoIntroOutroTrimmer_BuildCommandLine_NullOrWhitespace_ThrowsArgumentException(string? inPath, string? outPath)
{
Assert.Throws<ArgumentException>(() =>
VideoIntroOutroTrimmer.BuildLosslessTrimCommandLine(inPath!, outPath!, 0, 10));
}
[Fact]
public void VideoIntroOutroTrimmer_BuildCommandLine_NegativeStartOrDuration_ClampsToSafeBounds()
{
var cmd = VideoIntroOutroTrimmer.BuildLosslessTrimCommandLine(SampleInput, SampleOutput, -10.5, -5.0);
Assert.NotNull(cmd);
Assert.Contains("-ss 0.00", cmd);
Assert.DoesNotContain("-t -", cmd);
}
// ==========================================
// 3. VideoPosterExtractor
// ==========================================
[Fact]
public void VideoPosterExtractor_BuildCommandLine_SameInputAndOutput_ThrowsInvalidOperationException()
{
var spec = new PosterExtractionSpec(5.0, 640, 360, PosterFormat.Jpeg);
Assert.Throws<InvalidOperationException>(() =>
VideoPosterExtractor.BuildPosterCommandLine(SampleInput, SampleInput, spec));
}
[Theory]
[InlineData(null, SampleOutput)]
[InlineData(SampleInput, null)]
public void VideoPosterExtractor_BuildCommandLine_NullOrWhitespace_ThrowsArgumentException(string? inPath, string? outPath)
{
var spec = new PosterExtractionSpec(5.0, 640, 360, PosterFormat.Jpeg);
Assert.Throws<ArgumentException>(() =>
VideoPosterExtractor.BuildPosterCommandLine(inPath!, outPath!, spec));
}
// ==========================================
// 4. VideoSpriteSheetGenerator
// ==========================================
[Fact]
public void VideoSpriteSheetGenerator_BuildCommandLine_SameInputAndOutput_ThrowsInvalidOperationException()
{
var config = new SpriteSheetConfig(5, 5, 160, 90, 10);
Assert.Throws<InvalidOperationException>(() =>
VideoSpriteSheetGenerator.BuildFfmpegSpriteCommandLine(SampleInput, SampleInput, config));
}
[Theory]
[InlineData(null, SampleOutput)]
[InlineData(SampleInput, null)]
public void VideoSpriteSheetGenerator_BuildCommandLine_NullOrWhitespace_ThrowsArgumentException(string? inPath, string? outPath)
{
var config = new SpriteSheetConfig(5, 5, 160, 90, 10);
Assert.Throws<ArgumentException>(() =>
VideoSpriteSheetGenerator.BuildFfmpegSpriteCommandLine(inPath!, outPath!, config));
}
// ==========================================
// 5. VideoFrameRateConverter
// ==========================================
[Fact]
public void VideoFrameRateConverter_BuildFfmpegArgs_SameInputAndOutput_ThrowsInvalidOperationException()
{
Assert.Throws<InvalidOperationException>(() =>
VideoFrameRateConverter.BuildFfmpegArgs(SampleInput, SampleInput, 60, FrameRateConversionMode.Simple));
}
[Theory]
[InlineData(null, SampleOutput)]
[InlineData(SampleInput, null)]
public void VideoFrameRateConverter_BuildFfmpegArgs_NullOrWhitespace_ThrowsArgumentException(string? inPath, string? outPath)
{
Assert.Throws<ArgumentException>(() =>
VideoFrameRateConverter.BuildFfmpegArgs(inPath!, outPath!, 60, FrameRateConversionMode.Simple));
}
[Fact]
public void VideoFrameRateConverter_BuildFfmpegArgs_ExtremeFpsAndCrf_ClampedToValidRange()
{
var cmd = VideoFrameRateConverter.BuildFfmpegArgs(SampleInput, SampleOutput, 1000, FrameRateConversionMode.Simple, crf: 99);
Assert.NotNull(cmd);
Assert.Contains("fps=240", cmd);
Assert.Contains("-crf 51", cmd);
}
// ==========================================
// 6. VideoDenoiseEnhancer
// ==========================================
[Fact]
public void VideoDenoiseEnhancer_BuildCommandLine_SameInputAndOutput_ThrowsInvalidOperationException()
{
Assert.Throws<InvalidOperationException>(() =>
VideoDenoiseEnhancer.BuildDenoiseCommandLine(SampleInput, SampleInput, true, true));
}
[Theory]
[InlineData(null, SampleOutput)]
[InlineData(SampleInput, null)]
public void VideoDenoiseEnhancer_BuildCommandLine_NullOrWhitespace_ThrowsArgumentException(string? inPath, string? outPath)
{
Assert.Throws<ArgumentException>(() =>
VideoDenoiseEnhancer.BuildDenoiseCommandLine(inPath!, outPath!, true, true));
}
[Fact]
public void VideoEngines_PathsWithQuotes_EscapedOrStrippedSafely()
{
string maliciousIn = "C:\\test\\in\"jection.mp4";
string maliciousOut = "C:\\test\\out\"jection.mp4";
var cmd = VideoAspectAutoCropper.BuildReframingCommandLine(maliciousIn, maliciousOut, ReframingMode.CenterCrop);
Assert.NotNull(cmd);
Assert.DoesNotContain("in\"jection", cmd);
Assert.DoesNotContain("out\"jection", cmd);
}
}