sub-cli/internal/format/vtt/converter_test.go
2025-04-23 19:22:41 +08:00

179 lines
5.1 KiB
Go

package vtt
import (
"os"
"path/filepath"
"strings"
"testing"
"sub-cli/internal/model"
)
func TestConvertToSubtitle(t *testing.T) {
// Create a temporary test file
content := `WEBVTT - Test Title
STYLE
::cue {
color: white;
}
NOTE This is a test comment
1
00:00:01.000 --> 00:00:04.000 align:start position:10%
This is <i>styled</i> text.
2
00:00:05.000 --> 00:00:08.000
This is the second line.
`
tempDir := t.TempDir()
testFile := filepath.Join(tempDir, "test.vtt")
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 != "vtt" {
t.Errorf("Expected format 'vtt', got '%s'", subtitle.Format)
}
if subtitle.Title != "Test Title" {
t.Errorf("Expected title 'Test Title', got '%s'", subtitle.Title)
}
// Check style conversion
if _, ok := subtitle.Styles["css"]; !ok {
t.Errorf("Expected CSS style to be preserved in subtitle.Styles['css'], got: %v", subtitle.Styles)
}
// Check entry count and content
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)
}
// The VTT parser does not strip HTML tags by default
if subtitle.Entries[0].Text != "This is <i>styled</i> text." {
t.Errorf("First entry text: expected 'This is <i>styled</i> text.', got '%s'", subtitle.Entries[0].Text)
}
if subtitle.Entries[0].Styles["align"] != "start" {
t.Errorf("Expected align style 'start', got '%s'", subtitle.Entries[0].Styles["align"])
}
// 检查 FormatData 中是否记录了 HTML 标签存在
if val, ok := subtitle.Entries[0].FormatData["has_html_tags"]; !ok || val != true {
t.Errorf("Expected FormatData['has_html_tags'] to be true for entry with HTML tags")
}
}
func TestConvertFromSubtitle(t *testing.T) {
// Create a subtitle
subtitle := model.NewSubtitle()
subtitle.Format = "vtt"
subtitle.Title = "Test VTT"
subtitle.Styles = map[string]string{"css": "::cue { color: white; }"}
subtitle.Comments = append(subtitle.Comments, "This is a test comment")
// Create a region
region := model.NewSubtitleRegion("region1")
region.Settings["width"] = "40%"
region.Settings["lines"] = "3"
subtitle.Regions = append(subtitle.Regions, region)
// Create entries
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."
entry1.Styles["region"] = "region1"
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 <i>italic</i> text."
subtitle.Entries = append(subtitle.Entries, entry1, entry2)
// Convert to VTT
tempDir := t.TempDir()
outputFile := filepath.Join(tempDir, "output.vtt")
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)
}
contentStr := string(content)
// Check header
if !strings.HasPrefix(contentStr, "WEBVTT - Test VTT") {
t.Errorf("Expected header with title in output")
}
// Check style section
if !strings.Contains(contentStr, "STYLE") {
t.Errorf("Expected STYLE section in output")
}
if !strings.Contains(contentStr, "::cue { color: white; }") {
t.Errorf("Expected CSS content in style section")
}
// Check comment
if !strings.Contains(contentStr, "NOTE This is a test comment") {
t.Errorf("Expected comment in output")
}
// Check region
if !strings.Contains(contentStr, "REGION") || !strings.Contains(contentStr, "region1") {
t.Errorf("Expected region definition in output")
}
// Check region applied to first entry
if !strings.Contains(contentStr, "region:region1") {
t.Errorf("Expected region style to be applied to first entry")
}
// Check HTML tags
if !strings.Contains(contentStr, "<i>") || !strings.Contains(contentStr, "</i>") {
t.Errorf("Expected HTML italic tags in second entry")
}
}
func TestConvertToSubtitle_FileError(t *testing.T) {
// Test with non-existent file
_, err := ConvertToSubtitle("/nonexistent/file.vtt")
if err == nil {
t.Error("Expected error when converting non-existent file, got nil")
}
}
func TestConvertFromSubtitle_FileError(t *testing.T) {
// Create simple subtitle
subtitle := model.NewSubtitle()
subtitle.Format = "vtt"
subtitle.Entries = append(subtitle.Entries, model.NewSubtitleEntry())
// Test with invalid path
err := ConvertFromSubtitle(subtitle, "/nonexistent/directory/file.vtt")
if err == nil {
t.Error("Expected error when converting to invalid path, got nil")
}
}