diff --git a/CMakeLists.txt b/CMakeLists.txt index 6d6b693..de7e9f9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -156,6 +156,7 @@ set(TEST_SRC_FILES tests/overallogg.cpp tests/overallflac.cpp tests/tagvalue.cpp + tests/mediafileinfo.cpp ) set(DOC_FILES diff --git a/testfiles/unsupported.bin b/testfiles/unsupported.bin new file mode 100644 index 0000000..2dc7b56 Binary files /dev/null and b/testfiles/unsupported.bin differ diff --git a/tests/helper.h b/tests/helper.h index bf3f809..1399a76 100644 --- a/tests/helper.h +++ b/tests/helper.h @@ -19,13 +19,21 @@ inline std::ostream &operator <<(std::ostream &os, const Media::TagValue &tagVal } /*! - * \brief Prints a PositionInSet to enable CPPUNIT_ASSERT_EQUAL for tag values. + * \brief Prints a PositionInSet to enable using it in CPPUNIT_ASSERT_EQUAL. */ inline std::ostream &operator <<(std::ostream &os, const Media::PositionInSet &pos) { return os << pos.toString(); } +/*! + * \brief Prints a Notification to enable using it in CPPUNIT_ASSERT_EQUAL. + */ +inline std::ostream &operator <<(std::ostream &os, const Media::Notification &n) +{ + return os << n.typeName() << ':' << ' ' << n.message() << ' ' << '(' << n.context() << ')'; +} + } #endif // TAGPARSER_TEST_HELPER diff --git a/tests/mediafileinfo.cpp b/tests/mediafileinfo.cpp new file mode 100644 index 0000000..ee5b729 --- /dev/null +++ b/tests/mediafileinfo.cpp @@ -0,0 +1,204 @@ +#include "./helper.h" + +#include "../mediafileinfo.h" +#include "../abstracttrack.h" +#include "../tag.h" + +#include +#include +using namespace TestUtilities; + +#include +#include + +#include + +using namespace std; +using namespace Media; +using namespace IoUtilities; +using namespace TestUtilities::Literals; + +using namespace CPPUNIT_NS; + +/*! + * \brief The MediaFileInfoTests tests convenience methods provided by MediaFileInfo. + * \remarks It only tests parsing a simple Mkv/Mp4. Parsing different formats with different settings is tested in OverallTests. + */ +class MediaFileInfoTests : public TestFixture { + CPPUNIT_TEST_SUITE(MediaFileInfoTests); + CPPUNIT_TEST(testInitialStatus); + CPPUNIT_TEST(testFileSystemMethods); + CPPUNIT_TEST(testParsingUnsupportedFile); + CPPUNIT_TEST(testFullParseAndFurtherProperties); + CPPUNIT_TEST_SUITE_END(); + +public: + void setUp(); + void tearDown(); + + void testInitialStatus(); + void testFileSystemMethods(); + void testParsingUnsupportedFile(); + void testPartialParsingAndTagCreationOfMp4File(); + + void testFullParseAndFurtherProperties(); +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(MediaFileInfoTests); + +void MediaFileInfoTests::setUp() +{ +} + +void MediaFileInfoTests::tearDown() +{ +} + +void MediaFileInfoTests::testInitialStatus() +{ + const MediaFileInfo file; + CPPUNIT_ASSERT(!file.areTagsSupported()); + CPPUNIT_ASSERT(!file.areTracksSupported()); + CPPUNIT_ASSERT(!file.areChaptersSupported()); + CPPUNIT_ASSERT(!file.areAttachmentsSupported()); + CPPUNIT_ASSERT_EQUAL(ParsingStatus::NotParsedYet, file.containerParsingStatus()); + CPPUNIT_ASSERT_EQUAL(ParsingStatus::NotParsedYet, file.tagsParsingStatus()); + CPPUNIT_ASSERT_EQUAL(ParsingStatus::NotParsedYet, file.tracksParsingStatus()); + CPPUNIT_ASSERT_EQUAL(ParsingStatus::NotParsedYet, file.chaptersParsingStatus()); + CPPUNIT_ASSERT_EQUAL(ParsingStatus::NotParsedYet, file.attachmentsParsingStatus()); + CPPUNIT_ASSERT_EQUAL(ContainerFormat::Unknown, file.containerFormat()); +} + +void MediaFileInfoTests::testFileSystemMethods() +{ + MediaFileInfo file("/usr/bin/unsupported.bin"); + CPPUNIT_ASSERT_EQUAL("/usr/bin"s, file.containingDirectory()); + CPPUNIT_ASSERT_EQUAL("unsupported.bin"s, file.fileName()); + CPPUNIT_ASSERT_EQUAL("unsupported"s, file.fileName(true)); + CPPUNIT_ASSERT_EQUAL("/usr/bin/unsupported"s, file.pathWithoutExtension()); + CPPUNIT_ASSERT_EQUAL(".bin"s, file.extension()); + CPPUNIT_ASSERT_EQUAL(static_cast(0), file.size()); + file.reportPathChanged(testFilePath("unsupported.bin")); + file.open(true); + CPPUNIT_ASSERT(file.isOpen()); + CPPUNIT_ASSERT(file.isReadOnly()); + CPPUNIT_ASSERT_EQUAL(static_cast(41), file.size()); +} + +void MediaFileInfoTests::testParsingUnsupportedFile() +{ + MediaFileInfo file(testFilePath("unsupported.bin")); + file.parseContainerFormat(); + file.parseTags(); + CPPUNIT_ASSERT_EQUAL(ParsingStatus::NotSupported, file.containerParsingStatus()); + // NOTE: parsing tags of unsupported container is actually supported: there is nothing to do + // but maybe not what one would expect? + CPPUNIT_ASSERT_EQUAL(ParsingStatus::Ok, file.tagsParsingStatus()); + CPPUNIT_ASSERT_EQUAL(ParsingStatus::NotParsedYet, file.tracksParsingStatus()); + CPPUNIT_ASSERT_EQUAL(ParsingStatus::NotParsedYet, file.chaptersParsingStatus()); + CPPUNIT_ASSERT_EQUAL(ParsingStatus::NotParsedYet, file.attachmentsParsingStatus()); + CPPUNIT_ASSERT_EQUAL(ContainerFormat::Unknown, file.containerFormat()); + file.invalidate(); +} + +void MediaFileInfoTests::testPartialParsingAndTagCreationOfMp4File() +{ + MediaFileInfo file(testFilePath("mtx-test-data/aac/he-aacv2-ps.m4a")); + file.open(true); + file.parseContainerFormat(); + file.parseTags(); + file.parseAttachments(); + file.close(); + try { + file.parseTracks(); + CPPUNIT_FAIL("expected std::ios_base::failure because file has been closed"); + } catch(...) { + catchIoFailure(); + } + CPPUNIT_ASSERT(file.areTagsSupported()); + CPPUNIT_ASSERT(file.areTracksSupported()); + CPPUNIT_ASSERT(!file.areChaptersSupported()); + CPPUNIT_ASSERT(!file.areAttachmentsSupported()); + CPPUNIT_ASSERT_EQUAL(ParsingStatus::Ok, file.containerParsingStatus()); + CPPUNIT_ASSERT_EQUAL(ParsingStatus::Ok, file.tagsParsingStatus()); + CPPUNIT_ASSERT_EQUAL(ParsingStatus::NotParsedYet, file.tracksParsingStatus()); + CPPUNIT_ASSERT_EQUAL(ParsingStatus::NotParsedYet, file.chaptersParsingStatus()); + CPPUNIT_ASSERT_EQUAL(ParsingStatus::NotSupported, file.attachmentsParsingStatus()); + CPPUNIT_ASSERT_EQUAL(0_st, file.trackCount()); + CPPUNIT_ASSERT_EQUAL(ContainerFormat::Mp4, file.containerFormat()); + CPPUNIT_ASSERT_EQUAL(NotificationList({ + Notification(NotificationType::Information, + "Parsing attachments is not implemented for the container format of the file.", + "parsing attachments") + }), file.gatherRelatedNotifications()); + CPPUNIT_ASSERT_EQUAL(NotificationType::Information, file.worstNotificationTypeIncludingRelatedObjects()); + + // create/remove tag + CPPUNIT_ASSERT_EQUAL(0_st, file.matroskaTags().size()); + CPPUNIT_ASSERT(!file.id3v1Tag()); + CPPUNIT_ASSERT_EQUAL(0_st, file.id3v2Tags().size()); + CPPUNIT_ASSERT(!file.vorbisComment()); + CPPUNIT_ASSERT(!file.mp4Tag()); + // NOTE: Maybe it should not be possible to create ID3 tags for MP4 file? It will be ignored anyways. + CPPUNIT_ASSERT(file.createId3v1Tag()); + CPPUNIT_ASSERT(file.id3v1Tag()); + CPPUNIT_ASSERT(file.createId3v2Tag()); + CPPUNIT_ASSERT_EQUAL(1_st, file.id3v2Tags().size()); + CPPUNIT_ASSERT(!file.createVorbisComment()); + CPPUNIT_ASSERT(!file.vorbisComment()); + CPPUNIT_ASSERT(!file.removeVorbisComment()); + file.createAppropriateTags(); + CPPUNIT_ASSERT(file.mp4Tag()); +} + +void MediaFileInfoTests::testFullParseAndFurtherProperties() +{ + MediaFileInfo file(testFilePath("matroska_wave1/test1.mkv")); + file.open(true); + file.parseEverything(); + // calling parse methods twice should not do anything (and hence can not fail anymore because the file has already been closed) + file.close(); + file.parseEverything(); + CPPUNIT_ASSERT_EQUAL(ParsingStatus::Ok, file.containerParsingStatus()); + CPPUNIT_ASSERT_EQUAL(ParsingStatus::Ok, file.tagsParsingStatus()); + CPPUNIT_ASSERT_EQUAL(ParsingStatus::Ok, file.tracksParsingStatus()); + CPPUNIT_ASSERT_EQUAL(ParsingStatus::Ok, file.chaptersParsingStatus()); + CPPUNIT_ASSERT_EQUAL(ParsingStatus::Ok, file.attachmentsParsingStatus()); + CPPUNIT_ASSERT_EQUAL(ContainerFormat::Matroska, file.containerFormat()); + + // general info + CPPUNIT_ASSERT(file.container()); + CPPUNIT_ASSERT(file.areTagsSupported()); + CPPUNIT_ASSERT(file.hasAnyTag()); + CPPUNIT_ASSERT_EQUAL(1_st, file.tags().size()); + CPPUNIT_ASSERT_EQUAL(1_st, file.matroskaTags().size()); + CPPUNIT_ASSERT(!file.mp4Tag()); + CPPUNIT_ASSERT(!file.vorbisComment()); + CPPUNIT_ASSERT(file.areTracksSupported()); + CPPUNIT_ASSERT_EQUAL(2_st, file.trackCount()); + CPPUNIT_ASSERT(file.areChaptersSupported()); + CPPUNIT_ASSERT_EQUAL(0_st, file.chapters().size()); + CPPUNIT_ASSERT(file.areAttachmentsSupported()); + CPPUNIT_ASSERT_EQUAL(0_st, file.attachments().size()); + + // notifications + CPPUNIT_ASSERT(!file.hasNotifications()); + CPPUNIT_ASSERT(!file.haveRelatedObjectsNotifications()); + CPPUNIT_ASSERT_EQUAL(NotificationList(), file.gatherRelatedNotifications()); + CPPUNIT_ASSERT_EQUAL(NotificationType::None, file.worstNotificationTypeIncludingRelatedObjects()); + file.container()->addNotification(NotificationType::Warning, "warning", "test"); + CPPUNIT_ASSERT(file.haveRelatedObjectsNotifications()); + CPPUNIT_ASSERT_EQUAL(NotificationType::Warning, file.worstNotificationTypeIncludingRelatedObjects()); + file.tags().back()->addNotification(NotificationType::Critical, "error", "test"); + CPPUNIT_ASSERT_EQUAL(NotificationType::Critical, file.worstNotificationTypeIncludingRelatedObjects()); + CPPUNIT_ASSERT(file.haveRelatedObjectsNotifications()); + CPPUNIT_ASSERT_EQUAL(2_st, file.gatherRelatedNotifications().size()); + + // track info / available languages + file.tracks().back()->setLanguage("eng"); + CPPUNIT_ASSERT_EQUAL(unordered_set({"eng"}), file.availableLanguages()); + CPPUNIT_ASSERT_EQUAL(unordered_set({}), file.availableLanguages(MediaType::Text)); + CPPUNIT_ASSERT_EQUAL("ID: 2422994868, type: Video"s, file.tracks()[0]->label()); + CPPUNIT_ASSERT_EQUAL("ID: 3653291187, type: Audio, language: \"eng\""s, file.tracks()[1]->label()); + CPPUNIT_ASSERT_EQUAL("MS-MPEG-4-480p / MP3-2ch-eng"s, file.technicalSummary()); +} diff --git a/tests/overallogg.cpp b/tests/overallogg.cpp index 56f2a6a..dc3e26c 100644 --- a/tests/overallogg.cpp +++ b/tests/overallogg.cpp @@ -33,8 +33,9 @@ void OverallTests::checkOggTestfile1() const auto tags = m_fileInfo.tags(); switch(m_tagStatus) { case TagStatus::Original: - CPPUNIT_ASSERT(tags.size() == 1); - CPPUNIT_ASSERT(tags.front()->value(KnownField::Encoder).toString() == "ffmpeg2theora 0.13"); + CPPUNIT_ASSERT(m_fileInfo.hasAnyTag()); + CPPUNIT_ASSERT_EQUAL(1_st, tags.size()); + CPPUNIT_ASSERT_EQUAL("ffmpeg2theora 0.13"s, tags.front()->value(KnownField::Encoder).toString()); // Theora tags are currently not supported and hence only the Vorbis comment is // taken into account here break; @@ -70,8 +71,9 @@ void OverallTests::checkOggTestfile2() const auto tags = m_fileInfo.tags(); switch(m_tagStatus) { case TagStatus::Original: - CPPUNIT_ASSERT(tags.size() == 1); - CPPUNIT_ASSERT(tags.front()->value(KnownField::Encoder).toString() == "opusenc from opus-tools 0.1.6"); + CPPUNIT_ASSERT(m_fileInfo.hasAnyTag()); + CPPUNIT_ASSERT_EQUAL(1_st, tags.size()); + CPPUNIT_ASSERT_EQUAL("opusenc from opus-tools 0.1.6"s, tags.front()->value(KnownField::Encoder).toString()); break; case TagStatus::TestMetaDataPresent: checkOggTestMetaData();