202 lines
6.4 KiB
Go
202 lines
6.4 KiB
Go
package moonblood
|
|
|
|
import (
|
|
"bufio"
|
|
"os"
|
|
"testing"
|
|
)
|
|
|
|
func TestParseMoonblood(t *testing.T) {
|
|
file, err := os.Open("../../resources/moonblood.txt")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer file.Close()
|
|
|
|
scanner := bufio.NewScanner(file)
|
|
total, success := 0, 0
|
|
|
|
for scanner.Scan() {
|
|
line := scanner.Text()
|
|
if line == "" {
|
|
continue
|
|
}
|
|
|
|
result := Parse(line)
|
|
total++
|
|
|
|
if result.Group == "MOONBLOOD" && result.Year != 0 && result.Format == "FLAC" {
|
|
success++
|
|
}
|
|
|
|
if result.Confidence < 0.7 {
|
|
t.Logf("Low confidence: %s (%.2f)", line, result.Confidence)
|
|
}
|
|
}
|
|
|
|
t.Logf("Parsed %d releases, %d successful (%.1f%%)", total, success, float64(success)/float64(total)*100)
|
|
}
|
|
|
|
func TestParseFullTail(t *testing.T) {
|
|
r := Parse("Fane-Dragged_Through_the_Unending-24BIT-WEB-FLAC-2025-MOONBLOOD")
|
|
if r.Artist != "Fane" {
|
|
t.Errorf("Artist = %q, want %q", r.Artist, "Fane")
|
|
}
|
|
if r.Title != "Dragged_Through_the_Unending" {
|
|
t.Errorf("Title = %q, want %q", r.Title, "Dragged_Through_the_Unending")
|
|
}
|
|
if r.Year != 2025 || r.Format != "FLAC" || r.Source != "WEB" || r.BitDepth != "24BIT" {
|
|
t.Errorf("tail fields wrong: %+v", r)
|
|
}
|
|
if len(r.UnknownTokens) != 0 {
|
|
t.Errorf("UnknownTokens = %v, want empty", r.UnknownTokens)
|
|
}
|
|
if r.Confidence < 0.99 {
|
|
t.Errorf("Confidence = %.2f, want ~1.0", r.Confidence)
|
|
}
|
|
}
|
|
|
|
func TestParseEditionAndDemo(t *testing.T) {
|
|
r := Parse("Satans_Grind-Rotten_Demo-DEMO-16BIT-WEB-FLAC-2016-MOONBLOOD")
|
|
if r.Edition != "DEMO" {
|
|
t.Errorf("Edition = %q, want %q", r.Edition, "DEMO")
|
|
}
|
|
if r.Artist != "Satans_Grind" || r.Title != "Rotten_Demo" {
|
|
t.Errorf("Artist/Title = %q/%q", r.Artist, r.Title)
|
|
}
|
|
if len(r.UnknownTokens) != 0 {
|
|
t.Errorf("UnknownTokens = %v, want empty", r.UnknownTokens)
|
|
}
|
|
}
|
|
|
|
func TestParseArtistWithHyphen(t *testing.T) {
|
|
// Artist itself contains a hyphen; no part of it may leak into UnknownTokens.
|
|
r := Parse("Ultra-Violence-All_My_Life-EP-16BIT-WEB-FLAC-2026-MOONBLOOD")
|
|
if r.Artist != "Ultra" || r.Title != "Violence-All_My_Life" {
|
|
t.Errorf("Artist/Title = %q/%q, want Ultra / Violence-All_My_Life", r.Artist, r.Title)
|
|
}
|
|
if r.Edition != "EP" || r.BitDepth != "16BIT" || r.Source != "WEB" || r.Year != 2026 {
|
|
t.Errorf("tail fields wrong: %+v", r)
|
|
}
|
|
if len(r.UnknownTokens) != 0 {
|
|
t.Errorf("UnknownTokens = %v, want empty", r.UnknownTokens)
|
|
}
|
|
}
|
|
|
|
func TestParseLanguageAndCDSource(t *testing.T) {
|
|
r := Parse("Burn_Thou_in_Effigy-Memorias_Postumas_do_Imperador-BR-CD-FLAC-2026-MOONBLOOD")
|
|
if r.Language != "BR" || r.Source != "CD" || r.Year != 2026 || r.Format != "FLAC" {
|
|
t.Errorf("tail fields wrong: %+v", r)
|
|
}
|
|
if len(r.UnknownTokens) != 0 {
|
|
t.Errorf("UnknownTokens = %v, want empty", r.UnknownTokens)
|
|
}
|
|
}
|
|
|
|
func TestParseNoYear(t *testing.T) {
|
|
// Without a year the tail still parses; group stays the last token.
|
|
r := Parse("Fane-Gallant_Shroud-EP-16BIT-WEB-FLAC-MOONBLOOD")
|
|
if r.Group != "MOONBLOOD" || r.Year != 0 {
|
|
t.Errorf("Group/Year = %q/%d", r.Group, r.Year)
|
|
}
|
|
if r.Edition != "EP" || r.Source != "WEB" || r.Format != "FLAC" {
|
|
t.Errorf("tail fields wrong: %+v", r)
|
|
}
|
|
if r.Artist != "Fane" || r.Title != "Gallant_Shroud" {
|
|
t.Errorf("Artist/Title = %q/%q", r.Artist, r.Title)
|
|
}
|
|
}
|
|
|
|
func TestParseResolutionSlot(t *testing.T) {
|
|
r := Parse("Ice_Nine_Kills-Last_Chance_To_Make_Amends-REMASTERED-24BIT-44KHZ-WEB-FLAC-2024-FLACCiD")
|
|
if r.Group != "FLACCiD" {
|
|
t.Errorf("Group = %q, want FLACCiD", r.Group)
|
|
}
|
|
if r.Resolution != "44KHZ" {
|
|
t.Errorf("Resolution = %q, want 44KHZ", r.Resolution)
|
|
}
|
|
if r.BitDepth != "24BIT" || r.Edition != "REMASTERED" || r.Source != "WEB" || r.Year != 2024 {
|
|
t.Errorf("tail fields wrong: %+v", r)
|
|
}
|
|
if r.Artist != "Ice_Nine_Kills" || r.Title != "Last_Chance_To_Make_Amends" {
|
|
t.Errorf("Artist/Title = %q/%q", r.Artist, r.Title)
|
|
}
|
|
if len(r.UnknownTokens) != 0 {
|
|
t.Errorf("UnknownTokens = %v, want empty", r.UnknownTokens)
|
|
}
|
|
}
|
|
|
|
func TestParseVinylIsSource(t *testing.T) {
|
|
r := Parse("ROTH-Alles_Endet-DE-VINYL-FLAC-2026-TOTENKVLT")
|
|
if r.Language != "DE" {
|
|
t.Errorf("Language = %q, want DE", r.Language)
|
|
}
|
|
if r.Source != "VINYL" {
|
|
t.Errorf("Source = %q, want VINYL", r.Source)
|
|
}
|
|
if r.Edition != "" {
|
|
t.Errorf("Edition = %q, want empty (VINYL is source, not edition)", r.Edition)
|
|
}
|
|
if len(r.UnknownTokens) != 0 {
|
|
t.Errorf("UnknownTokens = %v, want empty", r.UnknownTokens)
|
|
}
|
|
}
|
|
|
|
func TestParseCaseInsensitiveDictionaries(t *testing.T) {
|
|
r := Parse("Artist-Some_Title-16bit-web-flac-2020-moonblood")
|
|
if r.BitDepth != "16BIT" || r.Source != "WEB" || r.Format != "FLAC" {
|
|
t.Errorf("case-insensitive lookup failed: %+v", r)
|
|
}
|
|
if r.Artist != "Artist" || r.Title != "Some_Title" {
|
|
t.Errorf("Artist/Title = %q/%q", r.Artist, r.Title)
|
|
}
|
|
}
|
|
|
|
func TestParseUnknownTailTokenReported(t *testing.T) {
|
|
// Невідомий токен між двома відомими маркерами → у UnknownTokens.
|
|
r := Parse("Artist-Some_Title-SPLIT-FOO-16BIT-WEB-FLAC-2025-MOONBLOOD")
|
|
if len(r.UnknownTokens) != 1 || r.UnknownTokens[0] != "FOO" {
|
|
t.Errorf("UnknownTokens = %v, want [FOO]", r.UnknownTokens)
|
|
}
|
|
if r.Edition != "SPLIT" || r.BitDepth != "16BIT" || r.Source != "WEB" || r.Year != 2025 {
|
|
t.Errorf("tail fields wrong: %+v", r)
|
|
}
|
|
if r.Artist != "Artist" || r.Title != "Some_Title" {
|
|
t.Errorf("Artist/Title = %q/%q", r.Artist, r.Title)
|
|
}
|
|
}
|
|
|
|
func TestParseCoreTokensNeverReported(t *testing.T) {
|
|
// Артист/тайтл ніколи не потрапляють в UnknownTokens.
|
|
r := Parse("Fane-Dragged_Through_the_Unending-24BIT-WEB-FLAC-2025-MOONBLOOD")
|
|
if len(r.UnknownTokens) != 0 {
|
|
t.Errorf("UnknownTokens = %v, want empty", r.UnknownTokens)
|
|
}
|
|
if r.Artist != "Fane" || r.Title != "Dragged_Through_the_Unending" {
|
|
t.Errorf("Artist/Title = %q/%q", r.Artist, r.Title)
|
|
}
|
|
}
|
|
|
|
func TestParseAnyGroupNoWarning(t *testing.T) {
|
|
cases := []string{
|
|
"Jetsex-Down_Down_Down-24BIT-WEB-FLAC-2025-FLACCiD",
|
|
"Sabaton-The_Last_Stand-24BIT-96KHZ-WEB-FLAC-2016-FLACCiD",
|
|
"Wind_Walkers-What_If_I_Break-16BIT-WEB-FLAC-2023-FLACCiD",
|
|
}
|
|
for _, line := range cases {
|
|
r := Parse(line)
|
|
if r.Group != "FLACCiD" {
|
|
t.Errorf("%s: Group = %q, want FLACCiD", line, r.Group)
|
|
}
|
|
if len(r.Warnings) != 0 {
|
|
t.Errorf("%s: Warnings = %v, want empty", line, r.Warnings)
|
|
}
|
|
if len(r.UnknownTokens) != 0 {
|
|
t.Errorf("%s: UnknownTokens = %v, want empty", line, r.UnknownTokens)
|
|
}
|
|
if r.Year == 0 || r.Format != "FLAC" || r.Source != "WEB" || r.BitDepth == "" {
|
|
t.Errorf("%s: tail fields wrong: %+v", line, r)
|
|
}
|
|
}
|
|
}
|