4 #include "../abstracttrack.h"
5 #include "../id3/id3v1tag.h"
6 #include "../id3/id3v2tag.h"
7 #include "../mpegaudio/mpegaudioframe.h"
25 void OverallTests::checkMp3Testfile1()
28 const auto tracks = m_fileInfo.
tracks();
29 CPPUNIT_ASSERT_EQUAL(1_st, tracks.size());
30 for (
const auto &track : tracks) {
34 CPPUNIT_ASSERT_EQUAL(
static_cast<std::uint16_t
>(2), track->channelCount());
35 CPPUNIT_ASSERT_EQUAL(
static_cast<std::uint8_t
>(MpegChannelMode::JointStereo), track->channelConfig());
36 CPPUNIT_ASSERT_EQUAL(44100u, track->samplingFrequency());
37 CPPUNIT_ASSERT_EQUAL(3, track->duration().seconds());
39 const auto tags = m_fileInfo.
tags();
40 switch (m_tagStatus) {
42 CPPUNIT_ASSERT(m_fileInfo.
id3v1Tag());
43 CPPUNIT_ASSERT_EQUAL(1_st, m_fileInfo.
id3v2Tags().size());
44 CPPUNIT_ASSERT_EQUAL(2_st, tags.size());
45 for (
const auto &tag : tags) {
48 switch (tag->type()) {
49 case TagType::Id3v1Tag:
52 CPPUNIT_ASSERT_EQUAL(
"Double Nickels On The Dime"s, tag->value(
KnownField::Album).toString());
54 CPPUNIT_ASSERT_EQUAL(
"ExactAudioCopy v0.95b4"s, tag->value(
KnownField::Comment).toString());
56 case TagType::Id3v2Tag:
57 CPPUNIT_ASSERT_EQUAL(TagTextEncoding::Utf16LittleEndian, tag->value(
KnownField::Title).dataEncoding());
62 CPPUNIT_ASSERT_EQUAL(u
"Double Nickels On The Dime"s, tag->value(
KnownField::Album).toWString());
66 CPPUNIT_ASSERT_EQUAL(u
"ExactAudioCopy v0.95b4"s, tag->value(
KnownField::Comment).toWString());
69 CPPUNIT_ASSERT(tag->value(KnownField::Length).toTimeSpan().isNull());
77 checkMp3TestMetaData();
80 CPPUNIT_ASSERT_EQUAL(0_st, tracks.size());
83 auto warningAboutEncoding =
false;
84 for (
auto &msg : m_diag) {
85 if (msg.message() ==
"The used encoding is unlikely to be supported by other software.") {
86 CPPUNIT_ASSERT_EQUAL(DiagLevel::Warning, msg.level());
87 warningAboutEncoding =
true;
88 msg =
DiagMessage(DiagLevel::Information,
string(),
string());
91 const auto encodingWarningExpected
93 CPPUNIT_ASSERT_EQUAL(encodingWarningExpected, warningAboutEncoding);
94 CPPUNIT_ASSERT(m_diag.level() <= DiagLevel::Information);
100 void OverallTests::checkMp3Testfile2()
103 const auto tracks = m_fileInfo.
tracks();
104 CPPUNIT_ASSERT_EQUAL(1_st, tracks.size());
105 for (
const auto &track : tracks) {
109 CPPUNIT_ASSERT_EQUAL(
static_cast<std::uint16_t
>(2), track->channelCount());
110 CPPUNIT_ASSERT_EQUAL(
static_cast<std::uint8_t
>(MpegChannelMode::Stereo), track->channelConfig());
111 CPPUNIT_ASSERT_EQUAL(44100u, track->samplingFrequency());
112 CPPUNIT_ASSERT_EQUAL(20, track->duration().seconds());
114 const auto tags = m_fileInfo.
tags();
116 switch (m_tagStatus) {
119 CPPUNIT_ASSERT(!m_fileInfo.
id3v1Tag());
120 CPPUNIT_ASSERT_EQUAL(1_st, m_fileInfo.
id3v2Tags().size());
121 CPPUNIT_ASSERT_EQUAL(1_st, tags.size());
122 for (
const auto &tag : tags) {
123 if (tag->type() != TagType::Id3v2Tag) {
124 CPPUNIT_FAIL(argsToString(
"no ", tag->typeName(),
" tag expected"));
126 const auto *
const id3v2Tag =
static_cast<const Id3v2Tag *
>(tag);
129 CPPUNIT_ASSERT_EQUAL(expectId3v24 ? 4 : 3,
static_cast<int>(id3v2Tag->majorVersion()));
130 CPPUNIT_ASSERT_EQUAL(
137 CPPUNIT_ASSERT_EQUAL(
"Lavf57.83.100"s, tag->value(KnownField::EncoderSettings).toString(
TagTextEncoding::Utf8));
141 CPPUNIT_ASSERT(tag->value(KnownField::Length).toTimeSpan().isNull());
145 const auto &fields = id3v2Tag->fields();
147 CPPUNIT_ASSERT_MESSAGE(
"genre field present"s, genreFields.first != genreFields.second);
148 const auto &genreField = genreFields.first->second;
149 const auto &additionalValues = genreField.additionalValues();
152 CPPUNIT_ASSERT_EQUAL(1_st, additionalValues.size());
156 CPPUNIT_ASSERT_EQUAL(3_st, additionalValues.size());
161 CPPUNIT_ASSERT_MESSAGE(
"exactly one genre field present"s, ++genreFields.first == genreFields.second);
174 CPPUNIT_ASSERT_EQUAL(2_st, genres.size());
178 CPPUNIT_ASSERT_EQUAL(4_st, genres.size());
187 CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
191 CPPUNIT_ASSERT(m_diag.level() <= DiagLevel::Information);
195 CPPUNIT_ASSERT(m_diag.level() <= DiagLevel::Warning);
196 int warningCount = 0;
197 for (
const auto &msg : m_diag) {
198 if (msg.level() != DiagLevel::Warning) {
202 TESTUTILS_ASSERT_LIKE(
"context",
"(parsing|making) (TPE1|TCON)( frame)?", msg.context());
203 TESTUTILS_ASSERT_LIKE(
"message",
204 "Multiple strings (found|assigned) .*"
205 "Additional (values \"Second Artist Example\" and \"3rd Artist Example\" are|"
206 "value \"Example\" is) "
207 "supposed to be ignored.",
210 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"exactly 4 warnings present", 4, warningCount);
216 void OverallTests::checkMp3TestMetaData()
224 CPPUNIT_ASSERT(id3v1Tag = m_fileInfo.id3v1Tag());
225 CPPUNIT_ASSERT(id3v2Tag = m_fileInfo.id3v2Tags().at(0).get());
227 CPPUNIT_ASSERT(id3v1Tag = m_fileInfo.id3v1Tag());
228 CPPUNIT_ASSERT(m_fileInfo.id3v2Tags().empty());
230 CPPUNIT_ASSERT(!m_fileInfo.id3v1Tag());
231 CPPUNIT_ASSERT(id3v2Tag = m_fileInfo.id3v2Tags().at(0).get());
241 m_preservedMetaData.pop();
249 CPPUNIT_ASSERT_EQUAL(m_testTitle, titleValue);
250 CPPUNIT_ASSERT_EQUAL(m_testComment, commentValue);
255 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"not attempted to use UTF-8 in ID3v2.3", TagTextEncoding::Utf16LittleEndian, titleValue.
dataEncoding());
256 CPPUNIT_ASSERT_EQUAL(m_testTitle, titleValue);
257 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"not attempted to use UTF-8 in ID3v2.3", TagTextEncoding::Utf16LittleEndian, commentValue.
dataEncoding());
258 CPPUNIT_ASSERT_EQUAL_MESSAGE(
259 "not attempted to use UTF-8 in ID3v2.3", TagTextEncoding::Utf16LittleEndian, commentValue.
descriptionEncoding());
260 CPPUNIT_ASSERT_EQUAL(m_testComment, commentValue);
261 CPPUNIT_ASSERT_EQUAL_MESSAGE(
262 "description is also converted to UTF-16",
"s\0o\0m\0e\0 \0d\0e\0s\0c\0r\0i\0p\0t\0i\0\xf3\0n\0"s, commentValue.
description());
268 m_preservedMetaData.pop();
285 void OverallTests::checkMp3PaddingConstraints()
292 CPPUNIT_ASSERT_EQUAL(
static_cast<std::uint64_t
>(4096), m_fileInfo.paddingSize());
294 CPPUNIT_ASSERT(m_fileInfo.paddingSize() >= 1024);
295 CPPUNIT_ASSERT(m_fileInfo.paddingSize() <= (4096 + 1024));
307 void OverallTests::setMp3TestMetaData1()
315 id3v1Tag = m_fileInfo.createId3v1Tag();
316 id3v2Tag = m_fileInfo.createId3v2Tag();
318 id3v1Tag = m_fileInfo.createId3v1Tag();
319 m_fileInfo.removeAllId3v2Tags();
321 m_fileInfo.removeId3v1Tag();
322 id3v2Tag = m_fileInfo.createId3v2Tag();
329 for (
Tag *
const tag : initializer_list<Tag *>{ id3v1Tag, id3v2Tag }) {
349 void OverallTests::setMp3TestMetaData2()
353 CPPUNIT_ASSERT_EQUAL(1_st, m_fileInfo.id3v2Tags().size());
354 auto &id3v2Tag(m_fileInfo.id3v2Tags().front());
357 CPPUNIT_ASSERT_EQUAL(2_st, artists.size());
367 cerr << endl <<
"MP3 parser" << endl;
370 parseFile(testFilePath(
"mtx-test-data/mp3/id3-tag-and-xing-header.mp3"), &OverallTests::checkMp3Testfile1);
371 parseFile(testFilePath(
"misc/multiple_id3v2_4_values.mp3"), &OverallTests::checkMp3Testfile2);
384 for (m_mode = 0; m_mode != 0x20; ++m_mode) {
394 m_fileInfo.setTagPosition(ElementPosition::Keep);
395 m_fileInfo.setIndexPosition(ElementPosition::Keep);
398 m_fileInfo.setMaxPadding(m_mode &
PaddingConstraints ? (4096 + 1024) : numeric_limits<size_t>::max());
399 m_fileInfo.setForceTagPosition(
false);
400 m_fileInfo.setForceIndexPosition(
false);
403 list<string> testConditions;
405 testConditions.emplace_back(
"forcing rewrite");
409 testConditions.emplace_back(
"removing tag");
411 testConditions.emplace_back(
"ID3v1 and ID3v2");
414 testConditions.emplace_back(
"ID3v1 only");
416 testConditions.emplace_back(
"ID3v2 only");
419 testConditions.emplace_back(
"padding constraints");
422 testConditions.emplace_back(
"use ID3v2.4");
424 cerr << endl <<
"MP3 maker - testmode " << m_mode <<
": " << joinStrings(testConditions,
", ") << endl;
428 makeFile(workingCopyPath(
"mtx-test-data/mp3/id3-tag-and-xing-header.mp3"),
429 (m_mode &
RemoveTag) ? &OverallTests::removeAllTags : &OverallTests::setMp3TestMetaData1, &OverallTests::checkMp3Testfile1);
430 makeFile(workingCopyPath(
"misc/multiple_id3v2_4_values.mp3"),
431 (m_mode &
RemoveTag) ? &OverallTests::removeAllTags : &OverallTests::setMp3TestMetaData2, &OverallTests::checkMp3Testfile2);