diff --git a/src/playlist/Item.hpp b/src/playlist/Item.hpp index bf79125a2..04040e441 100644 --- a/src/playlist/Item.hpp +++ b/src/playlist/Item.hpp @@ -18,7 +18,6 @@ public: */ auto Filename() const -> std::string; - /** * @brief Filename comparator. * @param other The preset filename to compare. diff --git a/src/playlist/Playlist.cpp b/src/playlist/Playlist.cpp index 0f43f6b6d..3436c73bd 100644 --- a/src/playlist/Playlist.cpp +++ b/src/playlist/Playlist.cpp @@ -26,6 +26,12 @@ uint32_t Playlist::Size() const } +bool Playlist::Empty() const +{ + return m_items.empty(); +} + + void Playlist::Clear() { m_items.clear(); @@ -124,7 +130,7 @@ auto Playlist::RemoveItem(uint32_t index) -> bool } -void Playlist::Shuffle(bool enabled) +void Playlist::SetShuffle(bool enabled) { m_shuffle = enabled; } diff --git a/src/playlist/Playlist.hpp b/src/playlist/Playlist.hpp index 138116835..56ae93b0f 100644 --- a/src/playlist/Playlist.hpp +++ b/src/playlist/Playlist.hpp @@ -73,6 +73,14 @@ public: */ virtual uint32_t Size() const; + /** + * @brief Returns if the playlist is empty. + * Calling this is a bit more performant than comparing Size() to 0. + * Don't confuse with Clear(), this method does not clear the playlist. + * @return True if the playlist is empty, false if it contains at least one item. + */ + virtual bool Empty() const; + /** * @brief Clears the current playlist. */ @@ -131,7 +139,7 @@ public: * @brief Enables or disabled shuffle mode. * @param enabled True to enable shuffle mode, false to disable. */ - virtual void Shuffle(bool enabled); + virtual void SetShuffle(bool enabled); /** * @brief Returns the enable state of shuffle mode. @@ -162,14 +170,14 @@ public: * @throws PlaylistEmptyException Thrown if the playlist is currently empty. * @return The index of the next playlist item to be played. */ - auto NextPresetIndex() -> size_t; + virtual auto NextPresetIndex() -> size_t; /** * @brief Returns the current playlist/preset index without changing the position. * @throws PlaylistEmptyException Thrown if the playlist is currently empty. * @return The current preset index being played. */ - auto PresetIndex() const -> size_t; + virtual auto PresetIndex() const -> size_t; /** * @brief Sets the playlist/preset index to the given value and returns the new index. @@ -181,7 +189,7 @@ public: * @param presetIndex The new preset index to switch to. * @return The newly set preset index, either presetIndex or 0 if out of bounds. */ - auto SetPresetIndex(size_t presetIndex) -> size_t; + virtual auto SetPresetIndex(size_t presetIndex) -> size_t; private: std::vector m_items; //!< Items in the current playlist. diff --git a/src/playlist/PlaylistCWrapper.cpp b/src/playlist/PlaylistCWrapper.cpp index 2c5daa347..b868c8d95 100644 --- a/src/playlist/PlaylistCWrapper.cpp +++ b/src/playlist/PlaylistCWrapper.cpp @@ -82,7 +82,13 @@ void PlaylistCWrapper::SetRetryCount(uint32_t retryCount) } -void PlaylistCWrapper::SetPresetWitchFailedCallback(projectm_playlist_preset_switch_failed_event callback, void* userData) +auto PlaylistCWrapper::RetryCount() -> uint32_t +{ + return m_presetSwitchRetryCount; +} + + +void PlaylistCWrapper::SetPresetSwitchFailedCallback(projectm_playlist_preset_switch_failed_event callback, void* userData) { m_presetSwitchFailedEventCallback = callback; m_presetSwitchFailedEventUserData = userData; @@ -116,6 +122,12 @@ auto playlist_handle_to_instance(projectm_playlist_handle instance) -> PlaylistC } +void projectm_playlist_free_string(char* string) +{ + delete[] string; +} + + void projectm_playlist_free_string_array(char** array) { int index{0}; @@ -155,7 +167,7 @@ void projectm_playlist_set_preset_switch_failed_event_callback(projectm_playlist void* user_data) { auto* playlist = playlist_handle_to_instance(instance); - playlist->SetPresetWitchFailedCallback(callback, user_data); + playlist->SetPresetSwitchFailedCallback(callback, user_data); } @@ -201,6 +213,23 @@ auto projectm_playlist_items(projectm_playlist_handle instance) -> char** } +char* projectm_playlist_item(projectm_playlist_handle instance, uint32_t index) +{ + auto* playlist = playlist_handle_to_instance(instance); + + if (playlist->Empty() || index >= playlist->Size()) + { + return nullptr; + } + + auto filename = playlist->Items().at(index).Filename(); + auto buffer = new char[filename.length() + 1]{}; + filename.copy(buffer, filename.length()); + + return buffer; +} + + auto projectm_playlist_add_path(projectm_playlist_handle instance, const char* path, bool recurse_subdirs, bool allow_duplicates) -> uint32_t { @@ -328,7 +357,7 @@ uint32_t projectm_playlist_remove_presets(projectm_playlist_handle instance, uin void projectm_playlist_set_shuffle(projectm_playlist_handle instance, bool shuffle) { auto* playlist = playlist_handle_to_instance(instance); - playlist->Shuffle(shuffle); + playlist->SetShuffle(shuffle); } @@ -354,6 +383,13 @@ void projectm_playlist_sort(projectm_playlist_handle instance, uint32_t start_in } +uint32_t projectm_playlist_get_retry_count(projectm_playlist_handle instance) +{ + auto* playlist = playlist_handle_to_instance(instance); + return playlist->RetryCount(); +} + + void projectm_playlist_set_retry_count(projectm_playlist_handle instance, uint32_t retry_count) { auto* playlist = playlist_handle_to_instance(instance); diff --git a/src/playlist/PlaylistCWrapper.h b/src/playlist/PlaylistCWrapper.h index 0567418e9..3d655a85f 100644 --- a/src/playlist/PlaylistCWrapper.h +++ b/src/playlist/PlaylistCWrapper.h @@ -24,7 +24,7 @@ public: */ virtual void Connect(projectm_handle projectMInstance); - void PlayPresetIndex(size_t index, bool hardCut, bool resetFailureCount); + virtual void PlayPresetIndex(size_t index, bool hardCut, bool resetFailureCount); /** * @brief Callback executed by projectM if a preset switch should be done. @@ -46,9 +46,15 @@ public: * @brief Sets the retry count for preset switches before giving up. * @param retryCount The number of retries. */ - void SetRetryCount(uint32_t retryCount); + virtual void SetRetryCount(uint32_t retryCount); - void SetPresetWitchFailedCallback(projectm_playlist_preset_switch_failed_event callback, + /** + * @brief Sets the retry count for preset switches before giving up. + * @param retryCount The number of retries. + */ + virtual auto RetryCount() -> uint32_t; + + virtual void SetPresetSwitchFailedCallback(projectm_playlist_preset_switch_failed_event callback, void* userData); private: diff --git a/src/playlist/playlist.h b/src/playlist/playlist.h index 05e0d527d..e48a0aecb 100644 --- a/src/playlist/playlist.h +++ b/src/playlist/playlist.h @@ -29,6 +29,16 @@ typedef enum } projectm_playlist_sort_order; +/** + * @brief Frees a char pointer returned by any of the playlist API functions. + * + * Please only use this function with char pointers returned by the playlist library, and don't use + * other projectM memory management functions with pointers returned by the playlist library. + * + * @param string A pointer to a string that should be freed. + */ +void projectm_playlist_free_string(char* string); + /** * @brief Frees a string array returned by any of the playlist API functions. * @@ -144,6 +154,18 @@ void projectm_playlist_clear(projectm_playlist_handle instance); */ char** projectm_playlist_items(projectm_playlist_handle instance); +/** + * @brief Returns the name of a preset at the given index in the current playlist. + * @note Call projectm_playlist_free_string() when you're done using the return value. + * @note If you need to retrieve a major part of playlist filenames, use projectm_playlist_items() + * instead. + * @param instance The playlist manager instance. + * @param index The index to retrieve the filename for. + * @return The filename of the requested preset, or NULL if the index was out of bounds or the + * playlist is empty. + */ +char* projectm_playlist_item(projectm_playlist_handle instance, uint32_t index); + /** * @brief Appends presets from the given path to the end of the current playlist. * @@ -311,6 +333,13 @@ void projectm_playlist_set_shuffle(projectm_playlist_handle instance, bool shuff void projectm_playlist_sort(projectm_playlist_handle instance, uint32_t start_index, uint32_t count, projectm_playlist_sort_predicate predicate, projectm_playlist_sort_order order); +/** + * @brief Returns the number of retries after failed preset switches. + * @param instance The playlist manager instance. + * @return The number of retries after failed preset switches. + */ +uint32_t projectm_playlist_get_retry_count(projectm_playlist_handle instance); + /** * @brief Sets the number of retries after failed preset switches. * @note Don't set this value too high, as each retry is done recursively. diff --git a/tests/playlist/APITest.cpp b/tests/playlist/APITest.cpp index e28dbc135..14b4b9d02 100644 --- a/tests/playlist/APITest.cpp +++ b/tests/playlist/APITest.cpp @@ -6,6 +6,7 @@ using ::testing::Return; using ::testing::ReturnRef; +using ::testing::Throw; /** * This suite only tests the API forwarding to the wrapper, not the actual playlist functionality! @@ -15,7 +16,7 @@ using ::testing::ReturnRef; * functions to access the functionality. The extreme use of reinterpret_cast<>() in this test suite * should make that quite obvious. */ -TEST(projectMPlaylist, APICreate) +TEST(projectMPlaylistAPI, Create) { auto* playlistHandle = projectm_playlist_create(nullptr); @@ -25,7 +26,7 @@ TEST(projectMPlaylist, APICreate) } -TEST(projectMPlaylist, APIConnect) +TEST(projectMPlaylistAPI, Connect) { PlaylistCWrapperMock mockPlaylist; @@ -41,7 +42,7 @@ TEST(projectMPlaylist, APIConnect) } -TEST(projectMPlaylist, APISize) +TEST(projectMPlaylistAPI, Size) { PlaylistCWrapperMock mockPlaylist; @@ -53,7 +54,7 @@ TEST(projectMPlaylist, APISize) } -TEST(projectMPlaylist, APIClear) +TEST(projectMPlaylistAPI, Clear) { PlaylistCWrapperMock mockPlaylist; @@ -64,7 +65,7 @@ TEST(projectMPlaylist, APIClear) } -TEST(projectMPlaylist, APIItems) +TEST(projectMPlaylistAPI, Items) { PlaylistCWrapperMock mockPlaylist; @@ -88,7 +89,68 @@ TEST(projectMPlaylist, APIItems) } -TEST(projectMPlaylist, APIAddPath) +TEST(projectMPlaylistAPI, Item) +{ + PlaylistCWrapperMock mockPlaylist; + + std::vector items{ + ProjectM::Playlist::Item("/some/file"), + ProjectM::Playlist::Item("/another/file")}; + + EXPECT_CALL(mockPlaylist, Empty()) + .Times(1) + .WillOnce(Return(false)); + EXPECT_CALL(mockPlaylist, Size()) + .Times(1) + .WillOnce(Return(2)); + EXPECT_CALL(mockPlaylist, Items()) + .Times(1) + .WillOnce(ReturnRef(items)); + + auto* returnedItem = projectm_playlist_item(reinterpret_cast(&mockPlaylist), 1); + ASSERT_NE(returnedItem, nullptr); + EXPECT_STREQ(returnedItem, items.at(1).Filename().c_str()); + + projectm_playlist_free_string(returnedItem); +} + + +TEST(projectMPlaylistAPI, ItemEmptyPlaylist) +{ + PlaylistCWrapperMock mockPlaylist; + + std::vector items{ + ProjectM::Playlist::Item("/some/file"), + ProjectM::Playlist::Item("/another/file")}; + + EXPECT_CALL(mockPlaylist, Empty()) + .Times(1) + .WillOnce(Return(true)); + + EXPECT_EQ(projectm_playlist_item(reinterpret_cast(&mockPlaylist), 1), nullptr); +} + + +TEST(projectMPlaylistAPI, ItemIndexOutOfBounds) +{ + PlaylistCWrapperMock mockPlaylist; + + std::vector items{ + ProjectM::Playlist::Item("/some/file"), + ProjectM::Playlist::Item("/another/file")}; + + EXPECT_CALL(mockPlaylist, Empty()) + .Times(1) + .WillOnce(Return(false)); + EXPECT_CALL(mockPlaylist, Size()) + .Times(1) + .WillOnce(Return(2)); + + EXPECT_EQ(projectm_playlist_item(reinterpret_cast(&mockPlaylist), 5), nullptr); +} + + +TEST(projectMPlaylistAPI, AddPath) { PlaylistCWrapperMock mockPlaylist; @@ -100,7 +162,7 @@ TEST(projectMPlaylist, APIAddPath) } -TEST(projectMPlaylist, APIInsertPath) +TEST(projectMPlaylistAPI, InsertPath) { PlaylistCWrapperMock mockPlaylist; @@ -112,7 +174,7 @@ TEST(projectMPlaylist, APIInsertPath) } -TEST(projectMPlaylist, APIAddPreset) +TEST(projectMPlaylistAPI, AddPreset) { PlaylistCWrapperMock mockPlaylist; @@ -124,7 +186,7 @@ TEST(projectMPlaylist, APIAddPreset) } -TEST(projectMPlaylist, APIInsertPreset) +TEST(projectMPlaylistAPI, InsertPreset) { PlaylistCWrapperMock mockPlaylist; @@ -136,7 +198,7 @@ TEST(projectMPlaylist, APIInsertPreset) } -TEST(projectMPlaylist, APIAddPresets) +TEST(projectMPlaylistAPI, AddPresets) { PlaylistCWrapperMock mockPlaylist; @@ -157,7 +219,7 @@ TEST(projectMPlaylist, APIAddPresets) } -TEST(projectMPlaylist, APIInsertPresets) +TEST(projectMPlaylistAPI, InsertPresets) { PlaylistCWrapperMock mockPlaylist; @@ -180,7 +242,7 @@ TEST(projectMPlaylist, APIInsertPresets) } -TEST(projectMPlaylist, APIRemovePreset) +TEST(projectMPlaylistAPI, RemovePreset) { PlaylistCWrapperMock mockPlaylist; @@ -194,7 +256,7 @@ TEST(projectMPlaylist, APIRemovePreset) } -TEST(projectMPlaylist, APIRemovePresets) +TEST(projectMPlaylistAPI, RemovePresets) { PlaylistCWrapperMock mockPlaylist; @@ -208,13 +270,13 @@ TEST(projectMPlaylist, APIRemovePresets) } -TEST(projectMPlaylist, APISetShuffle) +TEST(projectMPlaylistAPI, SetShuffle) { PlaylistCWrapperMock mockPlaylist; - EXPECT_CALL(mockPlaylist, Shuffle(true)) + EXPECT_CALL(mockPlaylist, SetShuffle(true)) .Times(1); - EXPECT_CALL(mockPlaylist, Shuffle(false)) + EXPECT_CALL(mockPlaylist, SetShuffle(false)) .Times(1); projectm_playlist_set_shuffle(reinterpret_cast(&mockPlaylist), true); @@ -222,7 +284,7 @@ TEST(projectMPlaylist, APISetShuffle) } -TEST(projectMPlaylist, APISort) +TEST(projectMPlaylistAPI, Sort) { using ProjectM::Playlist::Playlist; @@ -250,3 +312,80 @@ TEST(projectMPlaylist, APISort) projectm_playlist_sort(reinterpret_cast(&mockPlaylist), 0, 5000, SORT_PREDICATE_FULL_PATH, static_cast(200)); } + + +TEST(projectMPlaylistAPI, GetRetryCount) +{ + PlaylistCWrapperMock mockPlaylist; + + EXPECT_CALL(mockPlaylist, RetryCount()) + .Times(1) + .WillOnce(Return(5)); + + EXPECT_EQ(projectm_playlist_get_retry_count(reinterpret_cast(&mockPlaylist)), 5); +} + + +TEST(projectMPlaylistAPI, SetRetryCount) +{ + PlaylistCWrapperMock mockPlaylist; + + EXPECT_CALL(mockPlaylist, SetRetryCount(5)) + .Times(1); + + projectm_playlist_set_retry_count(reinterpret_cast(&mockPlaylist), 5); +} + + +TEST(projectMPlaylistAPI, GetPosition) +{ + PlaylistCWrapperMock mockPlaylist; + + EXPECT_CALL(mockPlaylist, PresetIndex()) + .Times(1) + .WillOnce(Return(512)); + + EXPECT_EQ(projectm_playlist_get_position(reinterpret_cast(&mockPlaylist)), 512); +} + + +TEST(projectMPlaylistAPI, GetPositionException) +{ + PlaylistCWrapperMock mockPlaylist; + + EXPECT_CALL(mockPlaylist, PresetIndex()) + .Times(1) + .WillOnce(Throw(ProjectM::Playlist::PlaylistEmptyException())); + + EXPECT_EQ(projectm_playlist_get_position(reinterpret_cast(&mockPlaylist)), 0); +} + + +TEST(projectMPlaylistAPI, SetPosition) +{ + PlaylistCWrapperMock mockPlaylist; + + EXPECT_CALL(mockPlaylist, SetPresetIndex(256)) + .Times(2) + .WillRepeatedly(Return(512)); + EXPECT_CALL(mockPlaylist, PlayPresetIndex(512, true, true)) + .Times(1); + EXPECT_CALL(mockPlaylist, PlayPresetIndex(512, false, true)) + .Times(1); + + EXPECT_EQ(projectm_playlist_set_position(reinterpret_cast(&mockPlaylist), 256, true), 512); + EXPECT_EQ(projectm_playlist_set_position(reinterpret_cast(&mockPlaylist), 256, false), 512); +} + + +TEST(projectMPlaylistAPI, SetPositionException) +{ + PlaylistCWrapperMock mockPlaylist; + + EXPECT_CALL(mockPlaylist, SetPresetIndex(256)) + .Times(2) + .WillRepeatedly(Throw(ProjectM::Playlist::PlaylistEmptyException())); + + EXPECT_EQ(projectm_playlist_set_position(reinterpret_cast(&mockPlaylist), 256, true), 0); + EXPECT_EQ(projectm_playlist_set_position(reinterpret_cast(&mockPlaylist), 256, false), 0); +} diff --git a/tests/playlist/ItemTest.cpp b/tests/playlist/ItemTest.cpp index 4226b3845..20fac16f9 100644 --- a/tests/playlist/ItemTest.cpp +++ b/tests/playlist/ItemTest.cpp @@ -2,13 +2,13 @@ #include -TEST(projectMPlaylist, ItemCreate) +TEST(projectMPlaylistItem, Create) { ASSERT_NO_THROW(ProjectM::Playlist::Item item("/some/file")); } -TEST(projectMPlaylist, ItemGetFilename) +TEST(projectMPlaylistItem, GetFilename) { ProjectM::Playlist::Item item("/some/file"); @@ -16,7 +16,7 @@ TEST(projectMPlaylist, ItemGetFilename) } -TEST(projectMPlaylist, ItemFilenameEquality) +TEST(projectMPlaylistItem, FilenameEquality) { ProjectM::Playlist::Item item("/some/file"); diff --git a/tests/playlist/PlaylistCWrapperMock.h b/tests/playlist/PlaylistCWrapperMock.h index 36beff880..1c9083166 100644 --- a/tests/playlist/PlaylistCWrapperMock.h +++ b/tests/playlist/PlaylistCWrapperMock.h @@ -14,11 +14,17 @@ public: // Playlist members MOCK_METHOD(uint32_t, Size, (), (const)); + MOCK_METHOD(bool, Empty, (), (const)); MOCK_METHOD(void, Clear, ()); MOCK_METHOD(const std::vector&, Items, (), (const)); MOCK_METHOD(bool, AddItem, (const std::string&, uint32_t, bool)); MOCK_METHOD(uint32_t, AddPath, (const std::string&, uint32_t, bool, bool)); MOCK_METHOD(bool, RemoveItem, (uint32_t)); - MOCK_METHOD(void, Shuffle, (bool)); + MOCK_METHOD(void, SetShuffle, (bool)); MOCK_METHOD(void, Sort, (uint32_t, uint32_t, SortPredicate, SortOrder)); + MOCK_METHOD(uint32_t, RetryCount, ()); + MOCK_METHOD(void, SetRetryCount, (uint32_t)); + MOCK_METHOD(size_t, PresetIndex, (), (const)); + MOCK_METHOD(size_t, SetPresetIndex, (size_t)); + MOCK_METHOD(void, PlayPresetIndex, (size_t, bool, bool)); }; diff --git a/tests/playlist/PlaylistTest.cpp b/tests/playlist/PlaylistTest.cpp index ae4d5c5b5..f6b7bd110 100644 --- a/tests/playlist/PlaylistTest.cpp +++ b/tests/playlist/PlaylistTest.cpp @@ -6,13 +6,13 @@ using ProjectM::Playlist::Playlist; -TEST(projectMPlaylist, PlaylistCreate) +TEST(projectMPlaylistPlaylist, Create) { ASSERT_NO_THROW(Playlist playlist); } -TEST(projectMPlaylist, PlaylistSize) +TEST(projectMPlaylistPlaylist, Size) { Playlist playlist; @@ -24,7 +24,19 @@ TEST(projectMPlaylist, PlaylistSize) } -TEST(projectMPlaylist, PlaylistClear) +TEST(projectMPlaylistPlaylist, Empty) +{ + Playlist playlist; + + EXPECT_TRUE(playlist.Empty()); + + EXPECT_TRUE(playlist.AddItem("/some/file", Playlist::InsertAtEnd, false)); + + EXPECT_FALSE(playlist.Empty()); +} + + +TEST(projectMPlaylistPlaylist, Clear) { Playlist playlist; EXPECT_TRUE(playlist.AddItem("/some/file", Playlist::InsertAtEnd, false)); @@ -37,7 +49,7 @@ TEST(projectMPlaylist, PlaylistClear) } -TEST(projectMPlaylist, PlaylistItems) +TEST(projectMPlaylistPlaylist, Items) { Playlist playlist; EXPECT_TRUE(playlist.AddItem("/some/file", Playlist::InsertAtEnd, false)); @@ -52,7 +64,7 @@ TEST(projectMPlaylist, PlaylistItems) } -TEST(projectMPlaylist, PlaylistAddItemEmptyFilename) +TEST(projectMPlaylistPlaylist, AddItemEmptyFilename) { Playlist playlist; EXPECT_FALSE(playlist.AddItem("", Playlist::InsertAtEnd, false)); @@ -61,7 +73,7 @@ TEST(projectMPlaylist, PlaylistAddItemEmptyFilename) } -TEST(projectMPlaylist, PlaylistAddItemAtEnd) +TEST(projectMPlaylistPlaylist, AddItemAtEnd) { Playlist playlist; EXPECT_TRUE(playlist.AddItem("/some/file", Playlist::InsertAtEnd, false)); @@ -76,7 +88,7 @@ TEST(projectMPlaylist, PlaylistAddItemAtEnd) } -TEST(projectMPlaylist, PlaylistAddItemAtFront) +TEST(projectMPlaylistPlaylist, AddItemAtFront) { Playlist playlist; EXPECT_TRUE(playlist.AddItem("/some/file", 0, false)); @@ -93,7 +105,7 @@ TEST(projectMPlaylist, PlaylistAddItemAtFront) } -TEST(projectMPlaylist, PlaylistAddItemInMiddle) +TEST(projectMPlaylistPlaylist, AddItemInMiddle) { Playlist playlist; EXPECT_TRUE(playlist.AddItem("/some/file", 0, false)); @@ -110,7 +122,7 @@ TEST(projectMPlaylist, PlaylistAddItemInMiddle) } -TEST(projectMPlaylist, PlaylistAddItemDuplicates) +TEST(projectMPlaylistPlaylist, AddItemDuplicates) { Playlist playlist; EXPECT_TRUE(playlist.AddItem("/some/file", Playlist::InsertAtEnd, true)); @@ -125,7 +137,7 @@ TEST(projectMPlaylist, PlaylistAddItemDuplicates) } -TEST(projectMPlaylist, PlaylistAddItemNoDuplicates) +TEST(projectMPlaylistPlaylist, AddItemNoDuplicates) { Playlist playlist; EXPECT_TRUE(playlist.AddItem("/some/file", Playlist::InsertAtEnd, false)); @@ -140,7 +152,7 @@ TEST(projectMPlaylist, PlaylistAddItemNoDuplicates) } -TEST(projectMPlaylist, PlaylistAddPathRecursively) +TEST(projectMPlaylistPlaylist, AddPathRecursively) { Playlist playlist; @@ -164,7 +176,7 @@ TEST(projectMPlaylist, PlaylistAddPathRecursively) } -TEST(projectMPlaylist, PlaylistAddPathRecursivelyNoDuplicates) +TEST(projectMPlaylistPlaylist, AddPathRecursivelyNoDuplicates) { Playlist playlist; @@ -175,7 +187,7 @@ TEST(projectMPlaylist, PlaylistAddPathRecursivelyNoDuplicates) } -TEST(projectMPlaylist, PlaylistAddPathNonRecursively) +TEST(projectMPlaylistPlaylist, AddPathNonRecursively) { Playlist playlist; @@ -205,7 +217,7 @@ TEST(projectMPlaylist, PlaylistAddPathNonRecursively) } -TEST(projectMPlaylist, PlaylistAddPathnonRecursivelyNoDuplicates) +TEST(projectMPlaylistPlaylist, AddPathnonRecursivelyNoDuplicates) { Playlist playlist; @@ -216,7 +228,7 @@ TEST(projectMPlaylist, PlaylistAddPathnonRecursivelyNoDuplicates) } -TEST(projectMPlaylist, PlaylistRemoveItemFromEnd) +TEST(projectMPlaylistPlaylist, RemoveItemFromEnd) { Playlist playlist; EXPECT_TRUE(playlist.AddItem("/some/file", Playlist::InsertAtEnd, false)); @@ -236,7 +248,7 @@ TEST(projectMPlaylist, PlaylistRemoveItemFromEnd) } -TEST(projectMPlaylist, PlaylistRemoveItemFromFront) +TEST(projectMPlaylistPlaylist, RemoveItemFromFront) { Playlist playlist; EXPECT_TRUE(playlist.AddItem("/some/file", Playlist::InsertAtEnd, false)); @@ -256,7 +268,7 @@ TEST(projectMPlaylist, PlaylistRemoveItemFromFront) } -TEST(projectMPlaylist, PlaylistRemoveItemFromMiddle) +TEST(projectMPlaylistPlaylist, RemoveItemFromMiddle) { Playlist playlist; EXPECT_TRUE(playlist.AddItem("/some/file", Playlist::InsertAtEnd, false)); @@ -276,7 +288,7 @@ TEST(projectMPlaylist, PlaylistRemoveItemFromMiddle) } -TEST(projectMPlaylist, PlaylistRemoveItemIndexOutOfBounds) +TEST(projectMPlaylistPlaylist, RemoveItemIndexOutOfBounds) { Playlist playlist; EXPECT_TRUE(playlist.AddItem("/some/file", Playlist::InsertAtEnd, false)); @@ -291,23 +303,23 @@ TEST(projectMPlaylist, PlaylistRemoveItemIndexOutOfBounds) } -TEST(projectMPlaylist, PlaylistShuffleEnableDisable) +TEST(projectMPlaylistPlaylist, ShuffleEnableDisable) { Playlist playlist; EXPECT_FALSE(playlist.Shuffle()); - playlist.Shuffle(true); + playlist.SetShuffle(true); EXPECT_TRUE(playlist.Shuffle()); - playlist.Shuffle(false); + playlist.SetShuffle(false); EXPECT_FALSE(playlist.Shuffle()); } -TEST(projectMPlaylist, PlaylistSortFullPathAscending) +TEST(projectMPlaylistPlaylist, SortFullPathAscending) { Playlist playlist; EXPECT_TRUE(playlist.AddItem("/some/PresetZ.milk", Playlist::InsertAtEnd, false)); @@ -327,11 +339,10 @@ TEST(projectMPlaylist, PlaylistSortFullPathAscending) EXPECT_EQ(items.at(1).Filename(), "/some/PresetZ.milk"); EXPECT_EQ(items.at(2).Filename(), "/some/other/PresetC.milk"); EXPECT_EQ(items.at(3).Filename(), "/yet/another/PresetD.milk"); - } -TEST(projectMPlaylist, PlaylistSortFullPathDescending) +TEST(projectMPlaylistPlaylist, SortFullPathDescending) { Playlist playlist; EXPECT_TRUE(playlist.AddItem("/some/PresetZ.milk", Playlist::InsertAtEnd, false)); @@ -354,7 +365,7 @@ TEST(projectMPlaylist, PlaylistSortFullPathDescending) } -TEST(projectMPlaylist, PlaylistSortFilenameOnlyAscending) +TEST(projectMPlaylistPlaylist, SortFilenameOnlyAscending) { Playlist playlist; EXPECT_TRUE(playlist.AddItem("/some/PresetZ.milk", Playlist::InsertAtEnd, false)); @@ -374,11 +385,10 @@ TEST(projectMPlaylist, PlaylistSortFilenameOnlyAscending) EXPECT_EQ(items.at(1).Filename(), "/some/other/PresetC.milk"); EXPECT_EQ(items.at(2).Filename(), "/yet/another/PresetD.milk"); EXPECT_EQ(items.at(3).Filename(), "/some/PresetZ.milk"); - } -TEST(projectMPlaylist, PlaylistSortFilenameOnlyDescending) +TEST(projectMPlaylistPlaylist, SortFilenameOnlyDescending) { Playlist playlist; EXPECT_TRUE(playlist.AddItem("/some/PresetZ.milk", Playlist::InsertAtEnd, false)); @@ -399,3 +409,107 @@ TEST(projectMPlaylist, PlaylistSortFilenameOnlyDescending) EXPECT_EQ(items.at(2).Filename(), "/some/other/PresetC.milk"); EXPECT_EQ(items.at(3).Filename(), "/some/PresetA.milk"); } + + +TEST(projectMPlaylistPlaylist, NextPresetIndexEmptyPlaylist) +{ + Playlist playlist; + + EXPECT_THROW(playlist.NextPresetIndex(), ProjectM::Playlist::PlaylistEmptyException); +} + + +TEST(projectMPlaylistPlaylist, NextPresetIndexShuffle) +{ + Playlist playlist; + + playlist.SetShuffle(true); + + EXPECT_TRUE(playlist.AddItem("/some/PresetZ.milk", Playlist::InsertAtEnd, false)); + EXPECT_TRUE(playlist.AddItem("/some/PresetA.milk", Playlist::InsertAtEnd, false)); + + // Shuffle 100 times, this will have an (almost) 100% chance that both presets were played. + std::set playlistIndices; + for (int i = 0; i < 100; i++) + { + EXPECT_NO_THROW(playlistIndices.insert(playlist.NextPresetIndex())); + } + + EXPECT_TRUE(playlistIndices.find(0) != playlistIndices.end()); + EXPECT_TRUE(playlistIndices.find(1) != playlistIndices.end()); +} + + +TEST(projectMPlaylistPlaylist, NextPresetIndexSequential) +{ + Playlist playlist; + + playlist.SetShuffle(false); + + EXPECT_TRUE(playlist.AddItem("/some/PresetZ.milk", Playlist::InsertAtEnd, false)); + EXPECT_TRUE(playlist.AddItem("/some/PresetA.milk", Playlist::InsertAtEnd, false)); + EXPECT_TRUE(playlist.AddItem("/some/other/PresetC.milk", Playlist::InsertAtEnd, false)); + + EXPECT_EQ(playlist.NextPresetIndex(), 1); + EXPECT_EQ(playlist.NextPresetIndex(), 2); + + // Also test wrap to 0 + EXPECT_EQ(playlist.NextPresetIndex(), 0); + EXPECT_EQ(playlist.NextPresetIndex(), 1); +} + + +TEST(projectMPlaylistPlaylist, SetPresetIndex) +{ + Playlist playlist; + + EXPECT_TRUE(playlist.AddItem("/some/PresetZ.milk", Playlist::InsertAtEnd, false)); + EXPECT_TRUE(playlist.AddItem("/some/PresetA.milk", Playlist::InsertAtEnd, false)); + EXPECT_TRUE(playlist.AddItem("/some/other/PresetC.milk", Playlist::InsertAtEnd, false)); + + EXPECT_EQ(playlist.SetPresetIndex(1), 1); + EXPECT_EQ(playlist.SetPresetIndex(2), 2); + EXPECT_EQ(playlist.SetPresetIndex(0), 0); +} + + +TEST(projectMPlaylistPlaylist, SetPresetIndexOutOfBounds) +{ + Playlist playlist; + + EXPECT_TRUE(playlist.AddItem("/some/PresetZ.milk", Playlist::InsertAtEnd, false)); + EXPECT_TRUE(playlist.AddItem("/some/PresetA.milk", Playlist::InsertAtEnd, false)); + EXPECT_TRUE(playlist.AddItem("/some/other/PresetC.milk", Playlist::InsertAtEnd, false)); + + EXPECT_EQ(playlist.SetPresetIndex(5), 0); +} + + +TEST(projectMPlaylistPlaylist, SetPresetIndexException) +{ + Playlist playlist; + + EXPECT_THROW(playlist.SetPresetIndex(0), ProjectM::Playlist::PlaylistEmptyException);; +} + + +TEST(projectMPlaylistPlaylist, PresetIndex) +{ + Playlist playlist; + + EXPECT_TRUE(playlist.AddItem("/some/PresetZ.milk", Playlist::InsertAtEnd, false)); + EXPECT_TRUE(playlist.AddItem("/some/PresetA.milk", Playlist::InsertAtEnd, false)); + EXPECT_TRUE(playlist.AddItem("/some/other/PresetC.milk", Playlist::InsertAtEnd, false)); + + EXPECT_EQ(playlist.PresetIndex(), 0); + EXPECT_NO_THROW(playlist.SetPresetIndex(2)); + EXPECT_EQ(playlist.PresetIndex(), 2); +} + + +TEST(projectMPlaylistPlaylist, PresetIndexException) +{ + Playlist playlist; + + EXPECT_THROW(playlist.PresetIndex(), ProjectM::Playlist::PlaylistEmptyException);; +}