package sync import ( "testing" "sub-cli/internal/model" ) func TestSyncSRTTimeline(t *testing.T) { testCases := []struct { name string sourceEntries []model.SRTEntry targetEntries []model.SRTEntry verify func(t *testing.T, result []model.SRTEntry) }{ { name: "Equal entry counts", sourceEntries: []model.SRTEntry{ { Number: 1, StartTime: model.Timestamp{Seconds: 1}, EndTime: model.Timestamp{Seconds: 4}, Content: "Source line one.", }, { Number: 2, StartTime: model.Timestamp{Seconds: 5}, EndTime: model.Timestamp{Seconds: 8}, Content: "Source line two.", }, { Number: 3, StartTime: model.Timestamp{Seconds: 9}, EndTime: model.Timestamp{Seconds: 12}, Content: "Source line three.", }, }, targetEntries: []model.SRTEntry{ { Number: 1, StartTime: model.Timestamp{Minutes: 1, Seconds: 0}, EndTime: model.Timestamp{Minutes: 1, Seconds: 3}, Content: "Target line one.", }, { Number: 2, StartTime: model.Timestamp{Minutes: 1, Seconds: 5}, EndTime: model.Timestamp{Minutes: 1, Seconds: 8}, Content: "Target line two.", }, { Number: 3, StartTime: model.Timestamp{Minutes: 1, Seconds: 10}, EndTime: model.Timestamp{Minutes: 1, Seconds: 13}, Content: "Target line three.", }, }, verify: func(t *testing.T, result []model.SRTEntry) { if len(result) != 3 { t.Errorf("Expected 3 entries, got %d", len(result)) return } // Check that source timings are applied to target entries if result[0].StartTime.Seconds != 1 || result[0].EndTime.Seconds != 4 { t.Errorf("First entry timing mismatch: got %+v", result[0]) } if result[1].StartTime.Seconds != 5 || result[1].EndTime.Seconds != 8 { t.Errorf("Second entry timing mismatch: got %+v", result[1]) } if result[2].StartTime.Seconds != 9 || result[2].EndTime.Seconds != 12 { t.Errorf("Third entry timing mismatch: got %+v", result[2]) } // Check that target content is preserved if result[0].Content != "Target line one." { t.Errorf("Content should be preserved, got: %s", result[0].Content) } // Check that numbering is correct if result[0].Number != 1 || result[1].Number != 2 || result[2].Number != 3 { t.Errorf("Entry numbers should be sequential: %+v", result) } }, }, { name: "More target entries than source", sourceEntries: []model.SRTEntry{ { Number: 1, StartTime: model.Timestamp{Seconds: 1}, EndTime: model.Timestamp{Seconds: 4}, Content: "Source line one.", }, { Number: 2, StartTime: model.Timestamp{Seconds: 5}, EndTime: model.Timestamp{Seconds: 8}, Content: "Source line two.", }, }, targetEntries: []model.SRTEntry{ { Number: 1, StartTime: model.Timestamp{Minutes: 1, Seconds: 0}, EndTime: model.Timestamp{Minutes: 1, Seconds: 3}, Content: "Target line one.", }, { Number: 2, StartTime: model.Timestamp{Minutes: 1, Seconds: 5}, EndTime: model.Timestamp{Minutes: 1, Seconds: 8}, Content: "Target line two.", }, { Number: 3, StartTime: model.Timestamp{Minutes: 1, Seconds: 10}, EndTime: model.Timestamp{Minutes: 1, Seconds: 13}, Content: "Target line three.", }, }, verify: func(t *testing.T, result []model.SRTEntry) { if len(result) != 3 { t.Errorf("Expected 3 entries, got %d", len(result)) return } // Check that source timings are scaled appropriately if result[0].StartTime.Seconds != 1 { t.Errorf("First entry should have first source start time, got: %+v", result[0].StartTime) } if result[2].StartTime.Seconds != 5 { t.Errorf("Last entry should have last source start time, got: %+v", result[2].StartTime) } // Check that content is preserved if result[2].Content != "Target line three." { t.Errorf("Content should be preserved, got: %s", result[2].Content) } // Check that numbering is correct if result[0].Number != 1 || result[1].Number != 2 || result[2].Number != 3 { t.Errorf("Entry numbers should be sequential: %+v", result) } }, }, { name: "More source entries than target", sourceEntries: []model.SRTEntry{ { Number: 1, StartTime: model.Timestamp{Seconds: 1}, EndTime: model.Timestamp{Seconds: 3}, Content: "Source line one.", }, { Number: 2, StartTime: model.Timestamp{Seconds: 4}, EndTime: model.Timestamp{Seconds: 6}, Content: "Source line two.", }, { Number: 3, StartTime: model.Timestamp{Seconds: 7}, EndTime: model.Timestamp{Seconds: 9}, Content: "Source line three.", }, { Number: 4, StartTime: model.Timestamp{Seconds: 10}, EndTime: model.Timestamp{Seconds: 12}, Content: "Source line four.", }, }, targetEntries: []model.SRTEntry{ { Number: 1, StartTime: model.Timestamp{Minutes: 1, Seconds: 0}, EndTime: model.Timestamp{Minutes: 1, Seconds: 3}, Content: "Target line one.", }, { Number: 2, StartTime: model.Timestamp{Minutes: 1, Seconds: 5}, EndTime: model.Timestamp{Minutes: 1, Seconds: 8}, Content: "Target line two.", }, }, verify: func(t *testing.T, result []model.SRTEntry) { if len(result) != 2 { t.Errorf("Expected 2 entries, got %d", len(result)) return } // Check that source timings are scaled appropriately if result[0].StartTime.Seconds != 1 { t.Errorf("First entry should have first source timing, got: %+v", result[0].StartTime) } if result[1].StartTime.Seconds != 10 { t.Errorf("Last entry should have last source timing, got: %+v", result[1].StartTime) } // Check that content is preserved if result[0].Content != "Target line one." || result[1].Content != "Target line two." { t.Errorf("Content should be preserved, got: %+v", result) } // Check that numbering is correct if result[0].Number != 1 || result[1].Number != 2 { t.Errorf("Entry numbers should be sequential: %+v", result) } }, }, { name: "Empty target entries", sourceEntries: []model.SRTEntry{ { Number: 1, StartTime: model.Timestamp{Seconds: 1}, EndTime: model.Timestamp{Seconds: 4}, Content: "Source line one.", }, }, targetEntries: []model.SRTEntry{}, verify: func(t *testing.T, result []model.SRTEntry) { if len(result) != 0 { t.Errorf("Expected 0 entries, got %d", len(result)) } }, }, { name: "Empty source entries", sourceEntries: []model.SRTEntry{}, targetEntries: []model.SRTEntry{ { Number: 1, StartTime: model.Timestamp{Seconds: 1}, EndTime: model.Timestamp{Seconds: 4}, Content: "Target line one.", }, }, verify: func(t *testing.T, result []model.SRTEntry) { if len(result) != 1 { t.Errorf("Expected 1 entry, got %d", len(result)) return } // Check that numbering is correct even with empty source if result[0].Number != 1 { t.Errorf("Entry number should be 1, got: %d", result[0].Number) } // Content should be preserved if result[0].Content != "Target line one." { t.Errorf("Content should be preserved, got: %s", result[0].Content) } }, }, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { result := syncSRTTimeline(tc.sourceEntries, tc.targetEntries) if tc.verify != nil { tc.verify(t, result) } }) } }