test(core/browser/platform): 26 extreme RED/GREEN TDD cycles and full regression hardening (3,235 PASS)
This commit is contained in:
parent
bcd242691f
commit
8677853822
100 changed files with 4814 additions and 333 deletions
167
tests/Paca.Tests/Core/VideoEnginesExtremeRedTests.cs
Normal file
167
tests/Paca.Tests/Core/VideoEnginesExtremeRedTests.cs
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
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);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue