package srt import ( "os" "path/filepath" "strings" "testing" "sub-cli/internal/model" ) func TestConvertToSubtitle(t *testing.T) { // Create a temporary test file content := `1 00:00:01,000 --> 00:00:04,000 This is the first line. 2 00:00:05,000 --> 00:00:08,000 This is the second line. ` tempDir := t.TempDir() testFile := filepath.Join(tempDir, "test.srt") if err := os.WriteFile(testFile, []byte(content), 0644); err != nil { t.Fatalf("Failed to create test file: %v", err) } // Convert to subtitle subtitle, err := ConvertToSubtitle(testFile) if err != nil { t.Fatalf("ConvertToSubtitle failed: %v", err) } // Check result if subtitle.Format != "srt" { t.Errorf("Expected format 'srt', got '%s'", subtitle.Format) } if len(subtitle.Entries) != 2 { t.Errorf("Expected 2 entries, got %d", len(subtitle.Entries)) } // Check first entry if subtitle.Entries[0].Index != 1 { t.Errorf("First entry index: expected 1, got %d", subtitle.Entries[0].Index) } if subtitle.Entries[0].Text != "This is the first line." { t.Errorf("First entry text: expected 'This is the first line.', got '%s'", subtitle.Entries[0].Text) } } func TestConvertFromSubtitle(t *testing.T) { // Create a subtitle subtitle := model.NewSubtitle() subtitle.Format = "srt" entry1 := model.NewSubtitleEntry() entry1.Index = 1 entry1.StartTime = model.Timestamp{Hours: 0, Minutes: 0, Seconds: 1, Milliseconds: 0} entry1.EndTime = model.Timestamp{Hours: 0, Minutes: 0, Seconds: 4, Milliseconds: 0} entry1.Text = "This is the first line." entry2 := model.NewSubtitleEntry() entry2.Index = 2 entry2.StartTime = model.Timestamp{Hours: 0, Minutes: 0, Seconds: 5, Milliseconds: 0} entry2.EndTime = model.Timestamp{Hours: 0, Minutes: 0, Seconds: 8, Milliseconds: 0} entry2.Text = "This is the second line." subtitle.Entries = append(subtitle.Entries, entry1, entry2) // Convert to SRT tempDir := t.TempDir() outputFile := filepath.Join(tempDir, "output.srt") err := ConvertFromSubtitle(subtitle, outputFile) if err != nil { t.Fatalf("ConvertFromSubtitle failed: %v", err) } // Verify by reading the file directly content, err := os.ReadFile(outputFile) if err != nil { t.Fatalf("Failed to read output file: %v", err) } // Check content lines := strings.Split(string(content), "\n") if len(lines) < 7 { t.Fatalf("Expected at least 7 lines, got %d", len(lines)) } // Check that the SRT entries were created correctly if lines[0] != "1" { t.Errorf("Expected first entry number to be '1', got '%s'", lines[0]) } if !strings.Contains(lines[1], "00:00:01,000 --> 00:00:04,000") { t.Errorf("Expected first entry time range to match, got '%s'", lines[1]) } if lines[2] != "This is the first line." { t.Errorf("Expected first entry content to match, got '%s'", lines[2]) } } func TestConvertToSubtitle_WithHTMLTags(t *testing.T) { // Create a temporary test file with HTML styling tags content := `1 00:00:01,000 --> 00:00:04,000 This is italic. 2 00:00:05,000 --> 00:00:08,000 This is bold. 3 00:00:09,000 --> 00:00:12,000 This is underlined. ` tempDir := t.TempDir() testFile := filepath.Join(tempDir, "styled.srt") if err := os.WriteFile(testFile, []byte(content), 0644); err != nil { t.Fatalf("Failed to create test file: %v", err) } // Convert to subtitle subtitle, err := ConvertToSubtitle(testFile) if err != nil { t.Fatalf("ConvertToSubtitle failed: %v", err) } // Check style detection if value, ok := subtitle.Entries[0].Styles["italic"]; !ok || value != "true" { t.Errorf("Expected Styles to contain italic=true for entry with tag") } if value, ok := subtitle.Entries[1].Styles["bold"]; !ok || value != "true" { t.Errorf("Expected Styles to contain bold=true for entry with tag") } if value, ok := subtitle.Entries[2].Styles["underline"]; !ok || value != "true" { t.Errorf("Expected Styles to contain underline=true for entry with tag") } } func TestConvertToSubtitle_FileError(t *testing.T) { // Test with non-existent file _, err := ConvertToSubtitle("/nonexistent/file.srt") if err == nil { t.Error("Expected error when converting non-existent file, got nil") } } func TestConvertFromSubtitle_WithStyling(t *testing.T) { // Create a subtitle with style attributes subtitle := model.NewSubtitle() subtitle.Format = "srt" // Create an entry with italics entry1 := model.NewSubtitleEntry() entry1.Index = 1 entry1.StartTime = model.Timestamp{Hours: 0, Minutes: 0, Seconds: 1, Milliseconds: 0} entry1.EndTime = model.Timestamp{Hours: 0, Minutes: 0, Seconds: 4, Milliseconds: 0} entry1.Text = "This should be italic." entry1.Styles["italic"] = "true" // Create an entry with bold entry2 := model.NewSubtitleEntry() entry2.Index = 2 entry2.StartTime = model.Timestamp{Hours: 0, Minutes: 0, Seconds: 5, Milliseconds: 0} entry2.EndTime = model.Timestamp{Hours: 0, Minutes: 0, Seconds: 8, Milliseconds: 0} entry2.Text = "This should be bold." entry2.Styles["bold"] = "true" // Create an entry with underline entry3 := model.NewSubtitleEntry() entry3.Index = 3 entry3.StartTime = model.Timestamp{Hours: 0, Minutes: 0, Seconds: 9, Milliseconds: 0} entry3.EndTime = model.Timestamp{Hours: 0, Minutes: 0, Seconds: 12, Milliseconds: 0} entry3.Text = "This should be underlined." entry3.Styles["underline"] = "true" subtitle.Entries = append(subtitle.Entries, entry1, entry2, entry3) // Convert from subtitle to SRT tempDir := t.TempDir() outputFile := filepath.Join(tempDir, "styled.srt") err := ConvertFromSubtitle(subtitle, outputFile) if err != nil { t.Fatalf("ConvertFromSubtitle failed: %v", err) } // Verify by reading the file directly content, err := os.ReadFile(outputFile) if err != nil { t.Fatalf("Failed to read output file: %v", err) } // Check that HTML tags were applied contentStr := string(content) if !strings.Contains(contentStr, "This should be italic.") { t.Errorf("Expected italic HTML tags to be applied") } if !strings.Contains(contentStr, "This should be bold.") { t.Errorf("Expected bold HTML tags to be applied") } if !strings.Contains(contentStr, "This should be underlined.") { t.Errorf("Expected underline HTML tags to be applied") } } func TestConvertFromSubtitle_FileError(t *testing.T) { // Create simple subtitle subtitle := model.NewSubtitle() subtitle.Entries = append(subtitle.Entries, model.NewSubtitleEntry()) // Test with invalid path err := ConvertFromSubtitle(subtitle, "/nonexistent/directory/file.srt") if err == nil { t.Error("Expected error when converting to invalid path, got nil") } } func TestConvertFromSubtitle_WithExistingHTMLTags(t *testing.T) { // Create a subtitle with text that already contains HTML tags subtitle := model.NewSubtitle() subtitle.Format = "srt" // Create an entry with existing italic tags but also style attribute entry := model.NewSubtitleEntry() entry.Index = 1 entry.StartTime = model.Timestamp{Hours: 0, Minutes: 0, Seconds: 1, Milliseconds: 0} entry.EndTime = model.Timestamp{Hours: 0, Minutes: 0, Seconds: 4, Milliseconds: 0} entry.Text = "Already italic text." entry.Styles["italic"] = "true" // Should not double-wrap with tags subtitle.Entries = append(subtitle.Entries, entry) // Convert from subtitle to SRT tempDir := t.TempDir() outputFile := filepath.Join(tempDir, "existing_tags.srt") err := ConvertFromSubtitle(subtitle, outputFile) if err != nil { t.Fatalf("ConvertFromSubtitle failed: %v", err) } // Verify by reading the file directly content, err := os.ReadFile(outputFile) if err != nil { t.Fatalf("Failed to read output file: %v", err) } // Should not have double tags contentStr := string(content) if strings.Contains(contentStr, "") { t.Errorf("Expected no duplicate italic tags, but found them") } }