210 lines
6.4 KiB
Go
210 lines
6.4 KiB
Go
package ass
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
|
|
"sub-cli/internal/model"
|
|
)
|
|
|
|
func TestConvertToSubtitle(t *testing.T) {
|
|
// Create test ASS file
|
|
content := `[Script Info]
|
|
ScriptType: v4.00+
|
|
Title: Test ASS File
|
|
PlayResX: 640
|
|
PlayResY: 480
|
|
|
|
[V4+ Styles]
|
|
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
|
|
Style: Default,Arial,20,&H00FFFFFF,&H000000FF,&H00000000,&H00000000,0,0,0,0,100,100,0,0,1,2,2,2,10,10,10,1
|
|
Style: Bold,Arial,20,&H00FFFFFF,&H000000FF,&H00000000,&H00000000,1,0,0,0,100,100,0,0,1,2,2,2,10,10,10,1
|
|
|
|
[Events]
|
|
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
|
|
Dialogue: 0,0:00:01.00,0:00:04.00,Default,Character,10,20,30,Fade,This is the first subtitle line.
|
|
Dialogue: 1,0:00:05.00,0:00:08.00,Bold,Character,15,25,35,,This is the second subtitle line with bold style.
|
|
Comment: 0,0:00:09.00,0:00:12.00,Default,,0,0,0,,This is a comment.
|
|
`
|
|
tempDir := t.TempDir()
|
|
testFile := filepath.Join(tempDir, "convert_test.ass")
|
|
if err := os.WriteFile(testFile, []byte(content), 0644); err != nil {
|
|
t.Fatalf("Failed to create test file: %v", err)
|
|
}
|
|
|
|
// Test conversion to Subtitle
|
|
subtitle, err := ConvertToSubtitle(testFile)
|
|
if err != nil {
|
|
t.Fatalf("ConvertToSubtitle failed: %v", err)
|
|
}
|
|
|
|
// Verify results
|
|
if subtitle.Format != "ass" {
|
|
t.Errorf("Format should be 'ass', got '%s'", subtitle.Format)
|
|
}
|
|
|
|
if subtitle.Title != "Test ASS File" {
|
|
t.Errorf("Title should be 'Test ASS File', got '%s'", subtitle.Title)
|
|
}
|
|
|
|
// Only dialogue events should be converted
|
|
if len(subtitle.Entries) != 2 {
|
|
t.Errorf("Expected 2 subtitle entries, got %d", len(subtitle.Entries))
|
|
} else {
|
|
// Check first entry
|
|
if subtitle.Entries[0].Text != "This is the first subtitle line." {
|
|
t.Errorf("First entry text mismatch: got '%s'", subtitle.Entries[0].Text)
|
|
}
|
|
|
|
if subtitle.Entries[0].StartTime.Seconds != 1 || subtitle.Entries[0].EndTime.Seconds != 4 {
|
|
t.Errorf("First entry timing mismatch: got %+v - %+v",
|
|
subtitle.Entries[0].StartTime, subtitle.Entries[0].EndTime)
|
|
}
|
|
|
|
// Check style conversion
|
|
if subtitle.Entries[0].Styles["style"] != "Default" {
|
|
t.Errorf("First entry style mismatch: got '%s'", subtitle.Entries[0].Styles["style"])
|
|
}
|
|
|
|
// Check metadata conversion
|
|
if subtitle.Entries[0].Metadata["Layer"] != "0" {
|
|
t.Errorf("First entry layer mismatch: got '%s'", subtitle.Entries[0].Metadata["Layer"])
|
|
}
|
|
|
|
if subtitle.Entries[0].Metadata["Name"] != "Character" {
|
|
t.Errorf("First entry name mismatch: got '%s'", subtitle.Entries[0].Metadata["Name"])
|
|
}
|
|
|
|
if subtitle.Entries[0].Metadata["MarginL"] != "10" ||
|
|
subtitle.Entries[0].Metadata["MarginR"] != "20" ||
|
|
subtitle.Entries[0].Metadata["MarginV"] != "30" {
|
|
t.Errorf("First entry margins mismatch: got L=%s, R=%s, V=%s",
|
|
subtitle.Entries[0].Metadata["MarginL"],
|
|
subtitle.Entries[0].Metadata["MarginR"],
|
|
subtitle.Entries[0].Metadata["MarginV"])
|
|
}
|
|
|
|
if subtitle.Entries[0].Metadata["Effect"] != "Fade" {
|
|
t.Errorf("First entry effect mismatch: got '%s'", subtitle.Entries[0].Metadata["Effect"])
|
|
}
|
|
|
|
// Check second entry (Bold style)
|
|
if subtitle.Entries[1].Styles["style"] != "Bold" {
|
|
t.Errorf("Second entry style mismatch: got '%s'", subtitle.Entries[1].Styles["style"])
|
|
}
|
|
|
|
if subtitle.Entries[1].Metadata["Layer"] != "1" {
|
|
t.Errorf("Second entry layer mismatch: got '%s'", subtitle.Entries[1].Metadata["Layer"])
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestConvertFromSubtitle(t *testing.T) {
|
|
// Create test subtitle
|
|
subtitle := model.NewSubtitle()
|
|
subtitle.Format = "ass"
|
|
subtitle.Title = "Test Conversion"
|
|
|
|
// Create entries
|
|
entry1 := model.SubtitleEntry{
|
|
Index: 1,
|
|
StartTime: model.Timestamp{Seconds: 1},
|
|
EndTime: model.Timestamp{Seconds: 4},
|
|
Text: "This is the first subtitle line.",
|
|
Styles: map[string]string{"style": "Default"},
|
|
Metadata: map[string]string{
|
|
"Layer": "0",
|
|
"Name": "Character",
|
|
"MarginL": "10",
|
|
"MarginR": "20",
|
|
"MarginV": "30",
|
|
"Effect": "Fade",
|
|
},
|
|
}
|
|
|
|
entry2 := model.SubtitleEntry{
|
|
Index: 2,
|
|
StartTime: model.Timestamp{Seconds: 5},
|
|
EndTime: model.Timestamp{Seconds: 8},
|
|
Text: "This is the second subtitle line.",
|
|
Styles: map[string]string{"bold": "1"},
|
|
}
|
|
|
|
subtitle.Entries = append(subtitle.Entries, entry1, entry2)
|
|
|
|
// Convert back to ASS
|
|
tempDir := t.TempDir()
|
|
outputFile := filepath.Join(tempDir, "convert_back.ass")
|
|
err := ConvertFromSubtitle(subtitle, outputFile)
|
|
if err != nil {
|
|
t.Fatalf("ConvertFromSubtitle failed: %v", err)
|
|
}
|
|
|
|
// Read the generated file
|
|
content, err := os.ReadFile(outputFile)
|
|
if err != nil {
|
|
t.Fatalf("Failed to read generated file: %v", err)
|
|
}
|
|
contentStr := string(content)
|
|
|
|
// Verify file content
|
|
if !strings.Contains(contentStr, "Title: Test Conversion") {
|
|
t.Errorf("Missing or incorrect title in generated file")
|
|
}
|
|
|
|
// Check that both entries were converted correctly
|
|
if !strings.Contains(contentStr, "Dialogue: 0,0:00:01.00,0:00:04.00,Default,Character,10,20,30,Fade,This is the first subtitle line.") {
|
|
t.Errorf("First entry not converted correctly")
|
|
}
|
|
|
|
// Check that bold style was created and applied
|
|
if !strings.Contains(contentStr, "Style: Bold") {
|
|
t.Errorf("Bold style not created")
|
|
}
|
|
|
|
if !strings.Contains(contentStr, "Dialogue: 0,0:00:05.00,0:00:08.00,Bold") {
|
|
t.Errorf("Second entry not converted with Bold style")
|
|
}
|
|
|
|
// Parse the file again to check structure
|
|
assFile, err := Parse(outputFile)
|
|
if err != nil {
|
|
t.Fatalf("Failed to parse the generated file: %v", err)
|
|
}
|
|
|
|
if len(assFile.Events) != 2 {
|
|
t.Errorf("Expected 2 events, got %d", len(assFile.Events))
|
|
}
|
|
|
|
// Check style conversion
|
|
var boldStyleFound bool
|
|
for _, style := range assFile.Styles {
|
|
if style.Name == "Bold" {
|
|
boldStyleFound = true
|
|
break
|
|
}
|
|
}
|
|
|
|
if !boldStyleFound {
|
|
t.Errorf("Bold style not found in generated file")
|
|
}
|
|
}
|
|
|
|
func TestConvertToSubtitle_FileError(t *testing.T) {
|
|
// Test non-existent file
|
|
_, err := ConvertToSubtitle("/nonexistent/file.ass")
|
|
if err == nil {
|
|
t.Error("Converting non-existent file should return an error")
|
|
}
|
|
}
|
|
|
|
func TestConvertFromSubtitle_FileError(t *testing.T) {
|
|
// Test invalid path
|
|
subtitle := model.NewSubtitle()
|
|
err := ConvertFromSubtitle(subtitle, "/nonexistent/directory/file.ass")
|
|
if err == nil {
|
|
t.Error("Converting to invalid path should return an error")
|
|
}
|
|
}
|