using System; using Paca.Mobile.Core; using Xunit; namespace Paca.Tests.Core; public class SubtitleSyncDrifterGateTests { [Fact] public void Gate433_SubtitleSyncDrifter_ShiftsConstantOffset_Accurately() { var srt = @"1 00:01:20,000 --> 00:01:25,500 Hello World"; var shifted = SubtitleSyncDrifter.ShiftOffsetSrt(srt, shiftSeconds: 2.5); Assert.Contains("00:01:22,500 --> 00:01:28,000", shifted); Assert.Contains("Hello World", shifted); } [Fact] public void Gate434_SubtitleSyncDrifter_PreventsNegativeTimestamps() { var srt = @"1 00:00:05,000 --> 00:00:08,000 Early cue"; var shifted = SubtitleSyncDrifter.ShiftOffsetSrt(srt, shiftSeconds: -10.0); Assert.Contains("00:00:00,000 --> 00:00:00,000", shifted); } [Fact] public void Gate435_SubtitleSyncDrifter_RescalesTimeByFpsRatio() { var srt = @"1 00:01:40,000 --> 00:01:50,000 Pacing test"; // 100s to 110s // Speedup by 10% (speed factor 1.10 -> duration scales by 1/1.10 = 0.90909) var rescaled = SubtitleSyncDrifter.RescaleTimeSrt(srt, speedFactor: 1.10); // 100 / 1.10 = 90.909s = 00:01:30,909 Assert.Contains("00:01:30,909", rescaled); } [Fact] public void Gate436_SubtitleSyncDrifter_ResyncsByTwoAnchorPoints() { // Anchor 1: at 100s, video speech is at 105s (+5s) // Anchor 2: at 1000s, video speech is at 1050s (+50s) // m = (1050 - 105) / (1000 - 100) = 945 / 900 = 1.05 // b = 105 - (1.05 * 100) = 0 var srt = @"1 00:08:20,000 --> 00:08:25,000 Middle dialogue"; // 500s -> 500 * 1.05 = 525s = 00:08:45,000 var resynced = SubtitleSyncDrifter.ResyncByAnchorsSrt(srt, orig1: 100.0, target1: 105.0, orig2: 1000.0, target2: 1050.0); Assert.Contains("00:08:45,000", resynced); Assert.Contains("Middle dialogue", resynced); } }