1import eyed3
2import unittest
3import pytest
4from pathlib import Path
5from eyed3.id3 import *
6from .. import DATA_D
7
8ID3_VERSIONS = [(ID3_V1, (1, None, None), "v1.x"),
9                (ID3_V1_0, (1, 0, 0), "v1.0"),
10                (ID3_V1_1, (1, 1, 0), "v1.1"),
11                (ID3_V2, (2, None, None), "v2.x"),
12                (ID3_V2_2, (2, 2, 0), "v2.2"),
13                (ID3_V2_3, (2, 3, 0), "v2.3"),
14                (ID3_V2_4, (2, 4, 0), "v2.4"),
15                (ID3_DEFAULT_VERSION, (2, 4, 0), "v2.4"),
16                (ID3_ANY_VERSION, (1|2, None, None), "v1.x/v2.x"),
17                ]
18
19with pytest.raises(TypeError):
20    versionToString(666)
21
22with pytest.raises(ValueError):
23    versionToString((3, 1, 0))
24
25
26def testEmptyGenre():
27    g = Genre()
28    assert g.id is None
29    assert g.name is None
30
31
32def testValidGenres():
33    # Create with id
34    for i in range(genres.GENRE_MAX):
35        g = Genre()
36        g.id = i
37        assert g.id == i
38        assert g.name == genres[i]
39
40        g = Genre(id=i)
41        assert g.id == i
42        assert g.name == genres[i]
43
44    # Create with name
45    for name in [n for n in genres if n is not None and type(n) is not int]:
46        g = Genre()
47        g.name = name
48        assert g.id == genres[name]
49        assert g.name == genres[g.id]
50        assert g.name.lower() == name
51
52        g = Genre(name=name)
53        assert g.id == genres[name]
54        assert g.name.lower() == name
55
56
57def test255Padding():
58    for i in range(GenreMap.GENRE_MAX + 1, 256):
59        assert genres[i] is None
60    with pytest.raises(KeyError):
61        genres.__getitem__(256)
62
63
64def testCustomGenres():
65    # Genres can be created for any name, their ID is None
66    g = Genre(name="Grindcore")
67    assert g.name == "Grindcore"
68    assert g.id is None
69
70    # But when constructing with IDs they must map.
71    with pytest.raises(ValueError):
72        Genre.__call__(id=1024)
73
74
75def testRemappedNames():
76    g = Genre(id=3, name="dance stuff")
77    assert g.id == 3
78    assert g.name == "Dance"
79
80    g = Genre(id=666, name="Funky")
81    assert g.id is None
82    assert g.name == "Funky"
83
84
85def testGenreEq():
86    for s in ["Hardcore", "(129)Hardcore",
87              "(129)", "(0129)",
88              "129", "0129"]:
89        assert Genre.parse(s) == Genre.parse(s)
90        assert Genre.parse(s) != Genre.parse("Blues")
91
92
93def testParseGenre():
94    test_list = ["Hardcore", "(129)Hardcore",
95                 "(129)", "(0129)",
96                 "129", "0129"]
97
98    # This is typically what will happen when parsing tags, a blob of text
99    # is parsed into Genre
100    for s in test_list:
101        g = Genre.parse(s)
102        assert g.name == "Hardcore"
103        assert g.id == 129
104
105    g = Genre.parse("")
106    assert g is None
107
108    g = Genre.parse("1")
109    assert g.id == 1
110    assert g.name == "Classic Rock"
111
112    g = Genre.parse("1", id3_std=False)
113    assert g.id is None
114    assert g.name == "1"
115
116
117def testToSting():
118    assert str(Genre("Hardcore")) == "(129)Hardcore"
119    assert str(Genre("Grindcore")) == "Grindcore"
120
121
122def testId3Versions():
123    for v in [ID3_V1, ID3_V1_0, ID3_V1_1]:
124        assert (v[0] == 1)
125
126    assert (ID3_V1_0[1] == 0)
127    assert (ID3_V1_0[2] == 0)
128    assert (ID3_V1_1[1] == 1)
129    assert (ID3_V1_1[2] == 0)
130
131    for v in [ID3_V2, ID3_V2_2, ID3_V2_3, ID3_V2_4]:
132        assert (v[0] == 2)
133
134    assert (ID3_V2_2[1] == 2)
135    assert (ID3_V2_3[1] == 3)
136    assert (ID3_V2_4[1] == 4)
137
138    assert (ID3_ANY_VERSION == (ID3_V1[0] | ID3_V2[0], None, None))
139    assert (ID3_DEFAULT_VERSION == ID3_V2_4)
140
141
142def test_versionToString():
143    for const, tple, string in ID3_VERSIONS:
144        assert versionToString(const) == string
145
146
147def test_isValidVersion():
148    for v, _, _ in ID3_VERSIONS:
149        assert isValidVersion(v)
150
151    for _, v, _ in ID3_VERSIONS:
152        if None in v:
153            assert not isValidVersion(v, True)
154        else:
155            assert isValidVersion(v, True)
156
157    assert not isValidVersion((3, 1, 1))
158
159
160def testNormalizeVersion():
161    assert normalizeVersion(ID3_V1) == ID3_V1_1
162    assert normalizeVersion(ID3_V2) == ID3_V2_4
163    assert normalizeVersion(ID3_DEFAULT_VERSION) == ID3_V2_4
164    assert normalizeVersion(ID3_ANY_VERSION) == ID3_DEFAULT_VERSION
165    # Correcting the bogus
166    assert normalizeVersion((2, 2, 1)) == ID3_V2_2
167
168
169# ID3 v2.2
170@unittest.skipIf(not Path(DATA_D).exists(), "test requires data files")
171def test_id3v22():
172    data_file = Path(DATA_D) / "sample-ID3v2.2.0.tag"
173    audio_file = eyed3.load(data_file)
174    assert audio_file.tag.version == (2, 2, 0)
175    assert audio_file.tag.title == "11.Portfolio Diaz.mp3"
176    assert audio_file.tag.album == "Acrobatic Tenement"
177    assert audio_file.tag.artist == "At the Drive-In"
178