releases/tests/Paca.Tests/Platform/PlatformMediaToolsExtremeRedTests.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

110 lines
3.6 KiB
C#

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Paca.Core.Platform;
using Xunit;
namespace Paca.Tests.Platform;
public class PlatformMediaToolsExtremeRedTests
{
// ==========================================
// 1. ChapterSplitter
// ==========================================
[Fact]
public void ChapterSplitter_GenerateFfmetadata_NullChapters_ReturnsValidHeaderWithoutCrashing()
{
var meta = ChapterSplitter.GenerateFfmetadata(null!);
Assert.NotNull(meta);
Assert.Contains(";FFMETADATA1", meta);
}
[Fact]
public void ChapterSplitter_GenerateFfmetadata_ListContainingNullChapter_SkipsNullChapter()
{
var chapters = new List<ChapterInfo>
{
null!,
new(1, "Intro", 0.0, 30.0),
null!
};
var meta = ChapterSplitter.GenerateFfmetadata(chapters);
Assert.NotNull(meta);
Assert.Contains("title=Intro", meta);
}
[Fact]
public void ChapterSplitter_GetChapterFileName_NullTitle_ReturnsSafeDefault()
{
var name = ChapterSplitter.GetChapterFileName(1, null!, "mp4");
Assert.NotNull(name);
Assert.StartsWith("01_", name);
Assert.EndsWith(".mp4", name);
}
// ==========================================
// 2. LosslessSmartTrimmer
// ==========================================
[Theory]
[InlineData(double.NaN)]
[InlineData(double.NegativeInfinity)]
[InlineData(double.PositiveInfinity)]
public void LosslessSmartTrimmer_FindNearestKeyframe_InvalidTargetSec_ReturnsDefault(double target)
{
var keyframes = new[] { 0.0, 5.0, 10.0, 15.0 };
var nearest = LosslessSmartTrimmer.FindNearestKeyframe(keyframes, target);
Assert.False(double.IsNaN(nearest));
Assert.False(double.IsInfinity(nearest));
}
[Fact]
public void LosslessSmartTrimmer_FindNearestKeyframe_KeyframesWithNaNOrNegatives_FiltersCorrectly()
{
var keyframes = new[] { double.NaN, -10.0, 5.0, 10.0 };
var nearest = LosslessSmartTrimmer.FindNearestKeyframe(keyframes, 6.0);
Assert.Equal(5.0, nearest);
}
[Fact]
public async Task LosslessSmartTrimmer_TrimLosslessAsync_NaNTimestamps_ThrowsArgumentException()
{
var trimmer = new LosslessSmartTrimmer(DesktopProcessRunner.Default);
await Assert.ThrowsAsync<ArgumentException>(() =>
trimmer.TrimLosslessAsync("ffmpeg.exe", "in.mp4", "out.mp4", double.NaN, 10.0, CancellationToken.None));
}
// ==========================================
// 3. VideoWatermarkBurner
// ==========================================
[Fact]
public void VideoWatermarkBurner_BuildDrawTextFilter_NullText_DoesNotThrow()
{
var filter = VideoWatermarkBurner.BuildDrawTextFilter(null!);
Assert.NotNull(filter);
Assert.Contains("drawtext=", filter);
}
[Fact]
public void VideoWatermarkBurner_BuildDrawTextFilter_TextWithNewlines_EscapedOrStripped()
{
var filter = VideoWatermarkBurner.BuildDrawTextFilter("Line 1\r\nLine 2\nLine 3");
Assert.NotNull(filter);
Assert.DoesNotContain("\r", filter);
Assert.DoesNotContain("\n", filter);
}
[Theory]
[InlineData(-0.1)]
[InlineData(1.1)]
[InlineData(double.NaN)]
public void VideoWatermarkBurner_BuildOverlayFilter_InvalidOpacity_ThrowsArgumentOutOfRangeException(double opacity)
{
Assert.Throws<ArgumentOutOfRangeException>(() =>
VideoWatermarkBurner.BuildOverlayFilter(WatermarkPosition.Center, opacity: opacity));
}
}