Tag Parser  10.0.0
C++ library for reading and writing MP4 (iTunes), ID3, Vorbis, Opus, FLAC and Matroska tags
overallflac.cpp
Go to the documentation of this file.
1 #include "./overall.h"
2 
3 #include "../abstracttrack.h"
4 #include "../tag.h"
5 
6 #include <regex>
7 
12 void OverallTests::checkFlacTestfile1()
13 {
14  CPPUNIT_ASSERT_EQUAL(ContainerFormat::Flac, m_fileInfo.containerFormat());
15  const auto tracks = m_fileInfo.tracks();
16  CPPUNIT_ASSERT_EQUAL(1_st, tracks.size());
17  for (const auto &track : tracks) {
18  CPPUNIT_ASSERT_EQUAL(MediaType::Audio, track->mediaType());
19  CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Flac, track->format().general);
20  CPPUNIT_ASSERT_EQUAL(static_cast<std::uint16_t>(2), track->channelCount());
21  CPPUNIT_ASSERT_EQUAL(44100u, track->samplingFrequency());
22  CPPUNIT_ASSERT_EQUAL(static_cast<std::uint16_t>(16), track->bitsPerSample());
23  CPPUNIT_ASSERT_EQUAL(4, track->duration().minutes());
24  }
25  const auto tags = m_fileInfo.tags();
26  switch (m_tagStatus) {
28  // ffmpeg is able to set some tags from the original file (mtx-test-data/alac/othertest-itunes.m4a)
29  CPPUNIT_ASSERT_EQUAL(1_st, tags.size());
30  CPPUNIT_ASSERT_EQUAL("Sad Song"s, tags.front()->value(KnownField::Title).toString());
31  CPPUNIT_ASSERT_EQUAL("Oasis"s, tags.front()->value(KnownField::Artist).toString());
32  CPPUNIT_ASSERT_EQUAL("Don't Go Away (Apple Lossless)"s, tags.front()->value(KnownField::Album).toString());
33  CPPUNIT_ASSERT_EQUAL("Alternative & Punk"s, tags.front()->value(KnownField::Genre).toString());
34  TESTUTILS_ASSERT_LIKE("encoder", "Lavf.*", tags.front()->value(KnownField::Encoder).toString());
35  CPPUNIT_ASSERT_EQUAL("1998"s, tags.front()->value(KnownField::RecordDate).toString());
36  CPPUNIT_ASSERT(tags.front()->value(KnownField::Comment).isEmpty());
37  //CPPUNIT_ASSERT(tags.front()->value(KnownField::Cover).dataSize() == 0x58f3);
38  //CPPUNIT_ASSERT(BE::toUInt64(tags.front()->value(KnownField::Cover).dataPointer()) == 0xFFD8FFE000104A46);
39  CPPUNIT_ASSERT_EQUAL(PositionInSet(3, 4), tags.front()->value(KnownField::TrackPosition).toPositionInSet());
40  CPPUNIT_ASSERT_EQUAL(PositionInSet(1, 1), tags.front()->value(KnownField::DiskPosition).toPositionInSet());
41  break;
43  checkOggTestMetaData();
44  break;
45  case TagStatus::Removed:
46  CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
47  }
48 
49  CPPUNIT_ASSERT(m_diag.level() <= DiagLevel::Information);
50 }
51 
56 void OverallTests::checkFlacTestfile2()
57 {
58  CPPUNIT_ASSERT_EQUAL(ContainerFormat::Ogg, m_fileInfo.containerFormat());
59  const auto tracks = m_fileInfo.tracks();
60  CPPUNIT_ASSERT_EQUAL(1_st, tracks.size());
61  for (const auto &track : tracks) {
62  CPPUNIT_ASSERT_EQUAL(MediaType::Audio, track->mediaType());
63  CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Flac, track->format().general);
64  CPPUNIT_ASSERT_EQUAL(static_cast<std::uint16_t>(2), track->channelCount());
65  CPPUNIT_ASSERT_EQUAL(44100u, track->samplingFrequency());
66  CPPUNIT_ASSERT_EQUAL(static_cast<std::uint16_t>(16), track->bitsPerSample());
67  CPPUNIT_ASSERT_EQUAL(4, track->duration().minutes());
68  }
69  const auto tags = m_fileInfo.tags();
70  switch (m_tagStatus) {
72  CPPUNIT_ASSERT_EQUAL(1_st, tags.size());
73  break;
75  checkOggTestMetaData();
76  break;
77  case TagStatus::Removed:
78  CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
79  }
80 
81  // check for unexpected critical notifications or warnings
82  if (m_tagStatus == TagStatus::Removed) {
83  bool gotMessageAboutMissingVorbisComment = false;
84  for (const auto &msg : m_diag) {
85  if (msg.level() == DiagLevel::Critical) {
86  CPPUNIT_ASSERT_EQUAL("OGG page after FLAC-to-Ogg mapping header doesn't contain Vorbis comment."s, msg.message());
87  gotMessageAboutMissingVorbisComment = true;
88  continue;
89  }
90  CPPUNIT_ASSERT(msg.level() <= DiagLevel::Information);
91  }
92  CPPUNIT_ASSERT(gotMessageAboutMissingVorbisComment);
93  } else {
94  CPPUNIT_ASSERT(m_diag.level() <= DiagLevel::Information);
95  }
96 }
97 
102 {
103  cerr << endl << "FLAC parser" << endl;
104  m_fileInfo.setForceFullParse(false);
105  m_tagStatus = TagStatus::Original;
106  parseFile(testFilePath("flac/test.flac"), &OverallTests::checkFlacTestfile1);
107  parseFile(testFilePath("flac/test.ogg"), &OverallTests::checkFlacTestfile2);
108 }
109 
115 {
116  // full parse is required to determine padding
117  m_fileInfo.setForceFullParse(true);
118 
119  // do the test under different conditions
120  for (m_mode = 0; m_mode != 0x2; ++m_mode) {
121  using namespace SimpleTestFlags;
122 
123  // TODO: setup test conditions
124 
125  // print test conditions
126  list<string> testConditions;
127  if (m_mode & RemoveTag) {
128  testConditions.emplace_back("removing tag");
129  } else {
130  testConditions.emplace_back("modifying tag");
131  }
132  cerr << endl << "FLAC maker - testmode " << m_mode << ": " << joinStrings(testConditions, ", ") << endl;
133 
134  // do actual tests
135  m_tagStatus = (m_mode & RemoveTag) ? TagStatus::Removed : TagStatus::TestMetaDataPresent;
136  void (OverallTests::*modifyRoutine)(void) = (m_mode & RemoveTag) ? &OverallTests::removeAllTags : &OverallTests::setOggTestMetaData;
137  makeFile(workingCopyPath("flac/test.flac"), modifyRoutine, &OverallTests::checkFlacTestfile1);
138  makeFile(workingCopyPath("flac/test.ogg"), modifyRoutine, &OverallTests::checkFlacTestfile2);
139  }
140 }
The OverallTests class tests reading and writing tags and parsing technical information for all suppo...
Definition: overall.h:40
void testFlacParsing()
Tests the FLAC parser via MediaFileInfo.
void testFlacMaking()
Tests the FLAC maker via MediaFileInfo.
DiagLevel level() const
Returns the worst diag level present in the container.
Definition: diagnostics.cpp:55
std::vector< AbstractTrack * > tracks() const
Returns the tracks for the current file.
void setForceFullParse(bool forceFullParse)
Sets whether forcing a full parse is enabled.
void tags(std::vector< Tag * > &tags) const
Stores all tags assigned to the current file in the specified vector.
ContainerFormat containerFormat() const
Returns the container format of the current file.
The PositionInSet class describes the position of an element in a set which consists of a certain num...
Definition: positioninset.h:21
@ TestMetaDataPresent