package lrc import ( "os" "path/filepath" "strings" "testing" "sub-cli/internal/model" ) func TestConvertToSubtitle(t *testing.T) { // Create a temporary test file content := `[ti:Test LRC File] [ar:Test Artist] [00:01.00]This is the first line. [00:05.00]This is the second line. ` tempDir := t.TempDir() testFile := filepath.Join(tempDir, "test.lrc") 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 != "lrc" { t.Errorf("Expected format 'lrc', 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].StartTime.Hours != 0 || subtitle.Entries[0].StartTime.Minutes != 0 || subtitle.Entries[0].StartTime.Seconds != 1 || subtitle.Entries[0].StartTime.Milliseconds != 0 { t.Errorf("First entry start time: expected 00:01.00, got %+v", subtitle.Entries[0].StartTime) } 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) } // Check metadata conversion if subtitle.Title != "Test LRC File" { t.Errorf("Expected title 'Test LRC File', got '%s'", subtitle.Title) } if subtitle.Metadata["ar"] != "Test Artist" { t.Errorf("Expected artist metadata 'Test Artist', got '%s'", subtitle.Metadata["ar"]) } } func TestConvertFromSubtitle(t *testing.T) { // Create a subtitle subtitle := model.NewSubtitle() subtitle.Format = "lrc" subtitle.Title = "Test LRC File" subtitle.Metadata["ar"] = "Test Artist" 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 LRC tempDir := t.TempDir() outputFile := filepath.Join(tempDir, "output.lrc") 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 contentStr := string(content) // Check metadata if !strings.Contains(contentStr, "[ti:Test LRC File]") { t.Errorf("Expected title metadata in output, not found") } if !strings.Contains(contentStr, "[ar:Test Artist]") { t.Errorf("Expected artist metadata in output, not found") } // Check timeline entries if !strings.Contains(contentStr, "[00:01.000]This is the first line.") { t.Errorf("Expected first timeline entry in output, not found") } if !strings.Contains(contentStr, "[00:05.000]This is the second line.") { t.Errorf("Expected second timeline entry in output, not found") } } func TestConvertToSubtitle_FileError(t *testing.T) { // Test with non-existent file _, err := ConvertToSubtitle("/nonexistent/file.lrc") if err == nil { t.Error("Expected error when converting non-existent file, got nil") } } func TestConvertToSubtitle_EdgeCases(t *testing.T) { // Test with empty lyrics (no content/timeline) tempDir := t.TempDir() emptyLyricsFile := filepath.Join(tempDir, "empty_lyrics.lrc") content := `[ti:Test LRC File] [ar:Test Artist] ` if err := os.WriteFile(emptyLyricsFile, []byte(content), 0644); err != nil { t.Fatalf("Failed to create empty lyrics test file: %v", err) } subtitle, err := ConvertToSubtitle(emptyLyricsFile) if err != nil { t.Fatalf("ConvertToSubtitle failed on empty lyrics: %v", err) } if len(subtitle.Entries) != 0 { t.Errorf("Expected 0 entries for empty lyrics, got %d", len(subtitle.Entries)) } if subtitle.Title != "Test LRC File" { t.Errorf("Expected title 'Test LRC File', got '%s'", subtitle.Title) } // Test with more content than timeline entries moreContentFile := filepath.Join(tempDir, "more_content.lrc") content = `[ti:Test LRC File] [00:01.00]This has a timestamp. This doesn't have a timestamp but is content. ` if err := os.WriteFile(moreContentFile, []byte(content), 0644); err != nil { t.Fatalf("Failed to create more content test file: %v", err) } subtitle, err = ConvertToSubtitle(moreContentFile) if err != nil { t.Fatalf("ConvertToSubtitle failed on file with more content than timestamps: %v", err) } if len(subtitle.Entries) != 1 { t.Errorf("Expected 1 entry (only the one with timestamp), got %d", len(subtitle.Entries)) } } 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.lrc") if err == nil { t.Error("Expected error when converting to invalid path, got nil") } }