package normalize
import "testing"
func TestName(t *testing.T) {
cases := []struct{ in, want string }{
{"The Method to Love", "the-method-to-love"},
{"Prophecy At 1420 MHz", "prophecy-at-1420-mhz"},
{"Don't Stop", "dont-stop"},
{"Don\u2019t Stop", "dont-stop"},
{"Caf\u00e9 M\u00fcnster", "cafe-munster"},
{"MIXED Case TiTlE", "mixed-case-title"},
{" leading and trailing ", "leading-and-trailing"},
{"trailing dots...", "trailing-dots"},
{"\u591c\u660e\u3051", ""},
{"\u2605\u2605\u2605\u2605\u2605", ""},
{"", ""},
{"---", ""},
{"1", "1"},
// Symbols that every filesystem accepts are kept, so a title stays
// readable instead of collapsing into a run of dashes.
{"Track (feat. Someone) [Remix]", "track-(feat-someone)-[remix]"},
{"Bj\u00f6rk & Sigur R\u00f3s", "bjork-&-sigur-ros"},
{"while(1<2), Part 1", "while(1_2)-part-1"},
// A symbol that is illegal somewhere becomes an underscore inside a
// word, so the two characters it sat between stay separated rather than
// turning into two words.
{"a<b", "a_b"},
{"Foo*Bar", "foo_bar"},
{"Path/With/Slashes", "path_with_slashes"},
// Next to a space it is just a separator, or the words either side run
// together as album_the.
{"\u00c1lbum: The (Deluxe) Edition!", "album-the-(deluxe)-edition"},
{"Foo: Bar", "foo-bar"},
{"Foo < Bar", "foo-bar"},
// Nothing is left dangling at either end.
{"Foo<", "foo"},
{"<Foo", "foo"},
{"()", ""},
}
for _, c := range cases {
if got := Name(c.in); got != c.want {
t.Errorf("Name(%q) = %q, want %q", c.in, got, c.want)
}
}
}
func TestPadWidth(t *testing.T) {
cases := []struct {
max, want int
}{
{1, 2}, {9, 2}, {99, 2}, {100, 3}, {120, 3}, {999, 3}, {1000, 4},
}
for _, c := range cases {
if got := PadWidth(c.max); got != c.want {
t.Errorf("PadWidth(%d) = %d, want %d", c.max, got, c.want)
}
}
}
func TestTrackFile(t *testing.T) {
if got := TrackFile(1, 1, 2, "The Method to Love", ".flac", true); got != "1-01_the-method-to-love.flac" {
t.Errorf("2-digit: got %q", got)
}
if got := TrackFile(1, 7, 3, "Long Player Track 7", ".flac", true); got != "1-007_long-player-track-7.flac" {
t.Errorf("3-digit: got %q", got)
}
if got := TrackFile(2, 10, 2, "X", "flac", true); got != "2-10_x.flac" {
t.Errorf("ext: got %q", got)
}
}
func TestDetectCollisions(t *testing.T) {
items := [][2]string{
{"First", "1-01_same.flac"},
{"Second", "1-02_same.flac"},
{"Other", "1-03_other.flac"},
}
got := DetectCollisions(items)
if len(got) != 1 {
t.Fatalf("want 1 collision, got %d (%v)", len(got), got)
}
if got[0].Target != "same" || len(got[0].Causes) != 2 {
t.Errorf("unexpected collision: %+v", got[0])
}
dup := [][2]string{{"Same", "1-01_same.flac"}, {"Same", "1-01_same.flac"}}
if c := DetectCollisions(dup); len(c) != 0 {
t.Errorf("identical sources should not collide, got %v", c)
}
}
func TestTruncate(t *testing.T) {
long := "1-01_" + string(make([]byte, 0)) + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.flac"
got, cut := Truncate(long, 200)
if !cut {
t.Fatal("expected truncation")
}
if len(got) > 200 {
t.Errorf("truncated name is %d bytes, want <= 200", len(got))
}
if ext := got[len(got)-5:]; ext != ".flac" {
t.Errorf("extension not preserved: %q", got)
}
if s, cut := Truncate("short.flac", 200); cut || s != "short.flac" {
t.Errorf("short name should be untouched, got %q cut=%v", s, cut)
}
}