mirror of
https://github.com/navidrome/navidrome.git
synced 2026-11-01 16:07:47 +01:00
test(plugins): validate plugin lyrics auto-detect across all formats
The test-lyrics WASM plugin now supports per-format modes via the "format" config key: ttml, srt, yaml, lrc, and plain, in addition to the existing default plain-text response. The plugin is rebuilt with the standard Go wasip1 compiler. lyrics_adapter_test.go gains a DescribeTable covering all five formats, asserting both Synced (the discriminator that proves correct format detection) and the exact line value. This validates the full auto-detect chain (TTML → SRT → YAML/Lyricsfile → LRC → plain) end-to-end through the real plugin → adapter → parser flow.
This commit is contained in:
parent
0ec7a818fb
commit
873c41b465
2 changed files with 52 additions and 27 deletions
|
|
@ -84,24 +84,31 @@ var _ = Describe("LyricsPlugin", Ordered, func() {
|
|||
Expect(err).To(HaveOccurred())
|
||||
})
|
||||
|
||||
It("content-sniffs TTML returned by the plugin", func() {
|
||||
manager, _ := createTestManagerWithPlugins(map[string]map[string]string{
|
||||
"test-lyrics": {"format": "ttml"},
|
||||
}, "test-lyrics"+PackageExtension)
|
||||
// Each DescribeTable entry proves that the adapter's content-sniffing routes
|
||||
// the plugin's rich payload to the right parser rather than mangling it as plain text.
|
||||
DescribeTable("content-sniffs plugin responses across all supported formats",
|
||||
func(format string, wantSynced bool, wantLine string) {
|
||||
manager, _ := createTestManagerWithPlugins(map[string]map[string]string{
|
||||
"test-lyrics": {"format": format},
|
||||
}, "test-lyrics"+PackageExtension)
|
||||
|
||||
p, ok := manager.LoadLyricsProvider("test-lyrics")
|
||||
Expect(ok).To(BeTrue())
|
||||
p, ok := manager.LoadLyricsProvider("test-lyrics")
|
||||
Expect(ok).To(BeTrue())
|
||||
|
||||
track := &model.MediaFile{ID: "track-1", Title: "Test Song", Artist: "Test Artist"}
|
||||
result, err := p.GetLyrics(GinkgoT().Context(), track)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(result).To(HaveLen(1))
|
||||
// Verify the result is parsed as TTML (synced, with the exact cue text),
|
||||
// not mangled as plain text with raw XML markup.
|
||||
Expect(result[0].Synced).To(BeTrue())
|
||||
Expect(result[0].Line).To(HaveLen(1))
|
||||
Expect(result[0].Line[0].Value).To(Equal("plugin ttml line"))
|
||||
})
|
||||
track := &model.MediaFile{ID: "track-1", Title: "Test Song", Artist: "Test Artist"}
|
||||
result, err := p.GetLyrics(GinkgoT().Context(), track)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(result).To(HaveLen(1))
|
||||
Expect(result[0].Synced).To(Equal(wantSynced), "unexpected Synced value for format %s", format)
|
||||
Expect(result[0].Line).To(HaveLen(1))
|
||||
Expect(result[0].Line[0].Value).To(Equal(wantLine))
|
||||
},
|
||||
Entry("ttml", "ttml", true, "plugin ttml line"),
|
||||
Entry("srt", "srt", true, "plugin srt line"),
|
||||
Entry("yaml", "yaml", true, "plugin yaml line"),
|
||||
Entry("lrc", "lrc", true, "plugin lrc line"),
|
||||
Entry("plain", "plain", false, "plugin plain line"),
|
||||
)
|
||||
})
|
||||
|
||||
Describe("PluginNames", func() {
|
||||
|
|
|
|||
36
plugins/testdata/test-lyrics/main.go
vendored
36
plugins/testdata/test-lyrics/main.go
vendored
|
|
@ -15,16 +15,21 @@ func init() {
|
|||
type testLyrics struct{}
|
||||
|
||||
func (t *testLyrics) GetLyrics(input lyrics.GetLyricsRequest) (lyrics.GetLyricsResponse, error) {
|
||||
// Check for configured error
|
||||
errMsg, hasErr := pdk.GetConfig("error")
|
||||
if hasErr && errMsg != "" {
|
||||
return lyrics.GetLyricsResponse{}, fmt.Errorf("%s", errMsg)
|
||||
}
|
||||
|
||||
// Return a minimal TTML document to exercise content-sniffing for rich formats.
|
||||
// Config-selected formats let integration tests prove the adapter's content-sniffing
|
||||
// detects each format; plain-text parsing would silently mangle the rich ones.
|
||||
format, hasFormat := pdk.GetConfig("format")
|
||||
if hasFormat && format == "ttml" {
|
||||
const ttml = `<?xml version="1.0" encoding="UTF-8"?>
|
||||
if hasFormat {
|
||||
var text string
|
||||
var lang string
|
||||
switch format {
|
||||
case "ttml":
|
||||
lang = "eng"
|
||||
text = `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<tt xmlns="http://www.w3.org/ns/ttml">
|
||||
<body xml:lang="eng">
|
||||
<div>
|
||||
|
|
@ -32,11 +37,24 @@ func (t *testLyrics) GetLyrics(input lyrics.GetLyricsRequest) (lyrics.GetLyricsR
|
|||
</div>
|
||||
</body>
|
||||
</tt>`
|
||||
return lyrics.GetLyricsResponse{
|
||||
Lyrics: []lyrics.LyricsText{
|
||||
{Lang: "eng", Text: ttml},
|
||||
},
|
||||
}, nil
|
||||
case "srt":
|
||||
lang = "eng"
|
||||
text = "1\n00:00:01,000 --> 00:00:02,000\nplugin srt line\n"
|
||||
case "yaml":
|
||||
lang = "eng"
|
||||
text = "version: \"1.0\"\nmetadata:\n language: eng\nlines:\n - text: \"plugin yaml line\"\n start_ms: 1000\n"
|
||||
case "lrc":
|
||||
lang = "eng"
|
||||
text = "[00:01.00]plugin lrc line"
|
||||
case "plain":
|
||||
lang = "eng"
|
||||
text = "plugin plain line"
|
||||
}
|
||||
if text != "" {
|
||||
return lyrics.GetLyricsResponse{
|
||||
Lyrics: []lyrics.LyricsText{{Lang: lang, Text: text}},
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
// Check if we should omit language (to test default language handling)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue