using System; using Paca.Mobile.Core; using Xunit; namespace Paca.Tests.Core; public class PlaybackSleepTimerEngineGateTests { [Fact] public void Gate445_PlaybackSleepTimerEngine_CalculatesVolume_BeforeFade() { var total = TimeSpan.FromMinutes(30); var fade = TimeSpan.FromMinutes(5); var elapsed = TimeSpan.FromMinutes(10); var status = PlaybackSleepTimerEngine.Evaluate(elapsed, total, fade, FadeVolumeCurve.Linear); Assert.False(status.IsExpired); Assert.False(status.IsFading); Assert.Equal(1.0, status.VolumeFactor, 2); } [Fact] public void Gate446_PlaybackSleepTimerEngine_CalculatesVolume_DuringFade() { var total = TimeSpan.FromMinutes(30); var fade = TimeSpan.FromMinutes(10); // fade starts at 20m var elapsed = TimeSpan.FromMinutes(25); // halfway through 10m fade var statusLinear = PlaybackSleepTimerEngine.Evaluate(elapsed, total, fade, FadeVolumeCurve.Linear); Assert.True(statusLinear.IsFading); Assert.False(statusLinear.IsExpired); Assert.Equal(0.5, statusLinear.VolumeFactor, 2); var statusExp = PlaybackSleepTimerEngine.Evaluate(elapsed, total, fade, FadeVolumeCurve.Exponential); Assert.True(statusExp.VolumeFactor < 0.5); // exponential falls faster } [Fact] public void Gate447_PlaybackSleepTimerEngine_TriggersExpiry_AtOrPastTotal() { var total = TimeSpan.FromMinutes(30); var fade = TimeSpan.FromMinutes(5); var statusExact = PlaybackSleepTimerEngine.Evaluate(TimeSpan.FromMinutes(30), total, fade, FadeVolumeCurve.Linear); Assert.True(statusExact.IsExpired); Assert.Equal(0.0, statusExact.VolumeFactor); var statusPast = PlaybackSleepTimerEngine.Evaluate(TimeSpan.FromMinutes(35), total, fade, FadeVolumeCurve.Linear); Assert.True(statusPast.IsExpired); Assert.Equal(0.0, statusPast.VolumeFactor); } [Fact] public void Gate448_PlaybackSleepTimerEngine_BuildsFfmpegAfadeFilter() { var filter = PlaybackSleepTimerEngine.BuildFfmpegFadeOutFilter(totalSec: 1800, fadeDurationSec: 60); Assert.Equal("afade=t=out:st=1740:d=60", filter); } }