179 lines
5.1 KiB
Go
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")
|
|
}
|
|
}
|