package ass import ( "os" "path/filepath" "strings" "testing" "sub-cli/internal/model" ) func TestGenerate(t *testing.T) { // Create test ASS file structure assFile := model.NewASSFile() assFile.ScriptInfo["Title"] = "Generation Test" // Add a custom style boldStyle := model.ASSStyle{ Name: "Bold", Properties: map[string]string{ "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": "Bold,Arial,20,&H00FFFFFF,&H000000FF,&H00000000,&H00000000,1,0,0,0,100,100,0,0,1,2,2,2,10,10,10,1", "Bold": "1", }, } assFile.Styles = append(assFile.Styles, boldStyle) // Add dialogue events event1 := model.NewASSEvent() event1.Type = "Dialogue" event1.StartTime = model.Timestamp{Seconds: 1} event1.EndTime = model.Timestamp{Seconds: 4} event1.Style = "Default" event1.Text = "This is a test subtitle." event2 := model.NewASSEvent() event2.Type = "Dialogue" event2.StartTime = model.Timestamp{Seconds: 5} event2.EndTime = model.Timestamp{Seconds: 8} event2.Style = "Bold" event2.Text = "This is a bold subtitle." assFile.Events = append(assFile.Events, event1, event2) // Generate ASS file tempDir := t.TempDir() outputFile := filepath.Join(tempDir, "output.ass") err := Generate(assFile, outputFile) if err != nil { t.Fatalf("Generate 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 structure and content // Check Script Info section if !strings.Contains(contentStr, "[Script Info]") { t.Errorf("Missing [Script Info] section") } if !strings.Contains(contentStr, "Title: Generation Test") { t.Errorf("Missing Title in Script Info") } // Check Styles section if !strings.Contains(contentStr, "[V4+ Styles]") { t.Errorf("Missing [V4+ Styles] section") } if !strings.Contains(contentStr, "Style: Bold,Arial,20") { t.Errorf("Missing Bold style definition") } // Check Events section if !strings.Contains(contentStr, "[Events]") { t.Errorf("Missing [Events] section") } if !strings.Contains(contentStr, "Format: Layer, Start, End, Style,") { t.Errorf("Missing Format line in Events section") } if !strings.Contains(contentStr, "Dialogue: 0,0:00:01.00,0:00:04.00,Default,,0,0,0,,This is a test subtitle.") { t.Errorf("Missing first dialogue event") } if !strings.Contains(contentStr, "Dialogue: 0,0:00:05.00,0:00:08.00,Bold,,0,0,0,,This is a bold subtitle.") { t.Errorf("Missing second dialogue event") } } func TestGenerate_FileError(t *testing.T) { // Test invalid path assFile := model.NewASSFile() err := Generate(assFile, "/nonexistent/directory/file.ass") if err == nil { t.Error("Generating to invalid path should return an error") } } func TestFormatEventLine(t *testing.T) { event := model.ASSEvent{ Type: "Dialogue", Layer: 0, StartTime: model.Timestamp{Seconds: 1}, EndTime: model.Timestamp{Seconds: 4}, Style: "Default", Name: "Character", MarginL: 10, MarginR: 10, MarginV: 10, Effect: "Fade", Text: "Test text", } expected := "Dialogue: 0,0:00:01.00,0:00:04.00,Default,Character,10,10,10,Fade,Test text" result := formatEventLine(event) if result != expected { t.Errorf("Expected: '%s', got: '%s'", expected, result) } // Test Comment type event.Type = "Comment" expected = "Comment: 0,0:00:01.00,0:00:04.00,Default,Character,10,10,10,Fade,Test text" result = formatEventLine(event) if result != expected { t.Errorf("Expected: '%s', got: '%s'", expected, result) } }