From ee15e08dd99c76f2529a7951b320e872fa987cc4 Mon Sep 17 00:00:00 2001 From: Martchus Date: Fri, 19 May 2017 00:05:57 +0200 Subject: [PATCH] Test parsing and rewriting nested Mkv tags --- matroska/matroskatags.dtd | 29 ++++++++ testfiles/mkv/nested-tags.xml | 46 +++++++++++++ tests/overall.cpp | 122 ++++++++++++++++++++++++++++++++-- tests/testfilecheck.cpp | 2 + 4 files changed, 195 insertions(+), 4 deletions(-) create mode 100644 matroska/matroskatags.dtd create mode 100644 testfiles/mkv/nested-tags.xml diff --git a/matroska/matroskatags.dtd b/matroska/matroskatags.dtd new file mode 100644 index 0000000..4b36958 --- /dev/null +++ b/matroska/matroskatags.dtd @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + diff --git a/testfiles/mkv/nested-tags.xml b/testfiles/mkv/nested-tags.xml new file mode 100644 index 0000000..66b1e5a --- /dev/null +++ b/testfiles/mkv/nested-tags.xml @@ -0,0 +1,46 @@ + + + + + + TITLE + Vanilla Sky + und + + + ARTIST + Test artist + und + + ADDRESS + Test address + und + + + + 50 + + + + + TITLE + Main video track + und + + + 3164620769 + 50 + + + + + TITLE + English audio track + und + + + 3571773145 + 50 + + + diff --git a/tests/overall.cpp b/tests/overall.cpp index 3923ce2..285fe8c 100644 --- a/tests/overall.cpp +++ b/tests/overall.cpp @@ -25,6 +25,7 @@ using namespace std; using namespace ConversionUtilities; +using namespace TestUtilities; using namespace Media; using namespace CPPUNIT_NS; @@ -53,7 +54,8 @@ class OverallTests : public TestFixture CPPUNIT_TEST(testMp3Making); CPPUNIT_TEST(testOggMaking); CPPUNIT_TEST(testFlacMaking); - CPPUNIT_TEST(testMkvMaking); + CPPUNIT_TEST(testMkvMakingWithDifferentSettings); + CPPUNIT_TEST(testMkvMakingNestedTags); #endif CPPUNIT_TEST_SUITE_END(); @@ -61,6 +63,7 @@ public: void setUp(); void tearDown(); +private: void parseFile(const string &path, void (OverallTests::* checkRoutine)(void)); void makeFile(const string &path, void (OverallTests::* modifyRoutine)(void), void (OverallTests::* checkRoutine)(void)); @@ -73,6 +76,7 @@ public: void checkMkvTestfile7(); void checkMkvTestfile8(); void checkMkvTestfileHandbrakeChapters(); + void checkMkvTestfileNestedTags(); void checkMkvTestMetaData(); void checkMkvPaddingConstraints(); @@ -100,14 +104,18 @@ public: void setMp3TestMetaData(); void setOggTestMetaData(); void removeAllTags(); + void noop(); + void createMkvWithNestedTags(); +public: void testMkvParsing(); void testMp4Parsing(); void testMp3Parsing(); void testOggParsing(); void testFlacParsing(); #ifdef PLATFORM_UNIX - void testMkvMaking(); + void testMkvMakingWithDifferentSettings(); + void testMkvMakingNestedTags(); void testMp4Making(); void testMp3Making(); void testOggMaking(); @@ -123,6 +131,7 @@ private: TagValue m_testTotalParts; TagValue m_testPosition; queue m_preservedMetaData; + string m_nestedTagsMkvPath; TagStatus m_tagStatus; uint16 m_mode; }; @@ -143,7 +152,11 @@ void OverallTests::setUp() } void OverallTests::tearDown() -{} +{ + if(!m_nestedTagsMkvPath.empty()) { + remove(m_nestedTagsMkvPath.data()); + } +} /*! * \brief Parses the specified file and tests the results using the specified check routine. @@ -595,6 +608,42 @@ void OverallTests::checkMkvTestfileHandbrakeChapters() } } +/*! + * \brief Checks "mtx-test-data/mkv/nested-tags.mkv" ("mtx-test-data/mkv/tags.mkv" where "mkv/nested-tags.xml" has been applied). + */ +void OverallTests::checkMkvTestfileNestedTags() +{ + CPPUNIT_ASSERT(m_fileInfo.containerFormat() == ContainerFormat::Matroska); + const auto tags = m_fileInfo.tags(); + bool generalTagFound = false; + switch(m_tagStatus) { + case TagStatus::Original: + case TagStatus::TestMetaDataPresent: + CPPUNIT_ASSERT_EQUAL(5ul, tags.size()); + for(const Tag *tag : tags) { + CPPUNIT_ASSERT(tag->type() == TagType::MatroskaTag); + const auto *mkvTag = static_cast(tag); + const auto &target = mkvTag->target(); + if(target.level() == 50 && target.tracks().empty()) { + generalTagFound = true; + CPPUNIT_ASSERT_EQUAL("Vanilla Sky"s, tag->value(KnownField::Title).toString()); + const auto &fields = mkvTag->fields(); + const auto &artistField = fields.find(mkvTag->fieldId(KnownField::Artist)); + CPPUNIT_ASSERT(artistField != fields.end()); + CPPUNIT_ASSERT_EQUAL("Test artist"s, artistField->second.value().toString()); + const auto &nestedFields = artistField->second.nestedFields(); + CPPUNIT_ASSERT_EQUAL(1ul, nestedFields.size()); + CPPUNIT_ASSERT_EQUAL("ADDRESS"s, nestedFields[0].idToString()); + CPPUNIT_ASSERT_EQUAL("Test address"s, nestedFields[0].value().toString()); + } + } + CPPUNIT_ASSERT(generalTagFound); + break; + case TagStatus::Removed: + CPPUNIT_ASSERT(tags.size() == 0); + } +} + /*! * \brief Checks whether test meta data for Matroska files has been applied correctly. */ @@ -1298,6 +1347,47 @@ void OverallTests::removeAllTags() m_fileInfo.removeAllTags(); } +/*! + * \brief Does nothing. + * \remarks Used to just resave the file. + */ +void OverallTests::noop() +{ +} + +/*! + * \brief Creates a Matroska test file with nested tags from "mtx-test-data/mkv/nested-tags.mkv" using "mkv/nested-tags.xml". + * \remarks Requires mkvmerge. + * \todo Make mkvmerge path variable. + */ +void OverallTests::createMkvWithNestedTags() +{ +#ifdef PLATFORM_UNIX + m_nestedTagsMkvPath = workingCopyPathMode("mtx-test-data/mkv/nested-tags.mkv", WorkingCopyMode::NoCopy); + remove(m_nestedTagsMkvPath.data()); + + cerr << "\n\ncreating testfile \"" << m_nestedTagsMkvPath << "\" with mkvmerge" << endl; + const string tagsMkvPath(testFilePath("mtx-test-data/mkv/tags.mkv")); + const string tagsXmlPath(testFilePath("mkv/nested-tags.xml")); + const char *const mkvmergeArgs[] = { + "--ui-language en_US", + "--output", m_nestedTagsMkvPath.data(), + "--no-global-tags", "--language", "0:und", "--default-track", "0:yes", "--language", "1:und", "--default-track", "1:yes", + "(", tagsMkvPath.data(), ")", + "--global-tags", tagsXmlPath.data(), "--track-order", "0:0,0:1", nullptr + }; + string mkvmergeOutput, mkvmergeErrors; + int res = execHelperApp("/bin/mkvmerge", mkvmergeArgs, mkvmergeOutput, mkvmergeErrors); + cout << mkvmergeOutput << endl; + cerr << mkvmergeErrors << endl; + if(res) { + cerr << "Failure (exit code " << res << "); unable to test nested tags" << endl; + remove(m_nestedTagsMkvPath.data()); + m_nestedTagsMkvPath.clear(); + } +#endif +} + /*! * \brief Tests the Matroska parser via MediaFileInfo. */ @@ -1315,14 +1405,21 @@ void OverallTests::testMkvParsing() parseFile(TestUtilities::testFilePath("matroska_wave1/test7.mkv"), &OverallTests::checkMkvTestfile7); parseFile(TestUtilities::testFilePath("matroska_wave1/test8.mkv"), &OverallTests::checkMkvTestfile8); parseFile(TestUtilities::testFilePath("mtx-test-data/mkv/handbrake-chapters-2.mkv"), &OverallTests::checkMkvTestfileHandbrakeChapters); + createMkvWithNestedTags(); + if(!m_nestedTagsMkvPath.empty()) { + parseFile(m_nestedTagsMkvPath, &OverallTests::checkMkvTestfileNestedTags); + } } #ifdef PLATFORM_UNIX /*! * \brief Tests the Matroska maker via MediaFileInfo. + * + * This method tests various combinations of the possible settings. + * * \remarks Relies on the parser to check results. */ -void OverallTests::testMkvMaking() +void OverallTests::testMkvMakingWithDifferentSettings() { // full parse is required to determine padding m_fileInfo.setForceFullParse(true); @@ -1399,6 +1496,23 @@ void OverallTests::testMkvMaking() makeFile(TestUtilities::workingCopyPath("mtx-test-data/mkv/handbrake-chapters-2.mkv"), modifyRoutine, &OverallTests::checkMkvTestfileHandbrakeChapters); } } + +/*! + * \brief Tests making a Matroska file with nested tags via MediaFileInfo. + * \remarks Relies on the parser to check results. + */ +void OverallTests::testMkvMakingNestedTags() +{ + createMkvWithNestedTags(); + if(!m_nestedTagsMkvPath.empty()) { + cerr << endl << "Matroska maker - rewrite file with nested tags" << endl; + m_fileInfo.setMinPadding(0); + m_fileInfo.setMaxPadding(0); + m_fileInfo.setTagPosition(ElementPosition::BeforeData); + m_fileInfo.setIndexPosition(ElementPosition::BeforeData); + makeFile(m_nestedTagsMkvPath, &OverallTests::noop, &OverallTests::checkMkvTestfileNestedTags); + } +} #endif /*! diff --git a/tests/testfilecheck.cpp b/tests/testfilecheck.cpp index 27c14c4..de63259 100644 --- a/tests/testfilecheck.cpp +++ b/tests/testfilecheck.cpp @@ -70,6 +70,8 @@ struct TestFile {"matroska_wave1/test7.mkv", {"95b21c92ad5a4fe00914ff5009e2a64f12fd4c5fb9cb1c3c888ab50bf0ffe483"}}, {"matroska_wave1/test8.mkv", {"9dddcd1550b814dae44d62e2b9f27c0eca31d5e190df2220cbf7492e3d6c63da"}}, {"mtx-test-data/mkv/handbrake-chapters-2.mkv", {"eccc55f3b59a77086b3ffb914525d312c7886eae34e3933352dea2f6f6a1974c"}}, + {"mtx-test-data/mkv/tags.mkv", {"4330019afc3d846600c1ded38158fcac081297f4e56c749251c236f4871e0287"}}, + {"mkv/nested-tags.xml", {"85cfcc94920f114e52fd1aa3df24706cd2710626e065a2c8c55dd209ec8dc8ce"}}, {"mp4/test1.m4a", {"4f16e0a22525bd13ba859431406d7f5991e0b4f155c51e10e5f32b0c97034b36"}}, {"mtx-test-data/aac/he-aacv2-ps.m4a", {"be54be0ae45b0184583ced8a84a881a1652a449feb7f6a917e11f60efabb68ac"}}, {"mtx-test-data/alac/othertest-itunes.m4a", {"5e9c64cde00902211533fbe38aaa67ef5f79a945e1d717951b78b4bbf9ff84e8"}},