test/playlist: unit tests for the playlist plugins

Only "pls" for now.
This commit is contained in:
Max Kellermann 2025-03-10 14:13:52 +01:00
parent 2d3271859f
commit 898e0a2bc4
6 changed files with 189 additions and 0 deletions

@ -0,0 +1,27 @@
// SPDX-License-Identifier: BSD-2-Clause
// author: Max Kellermann <max.kellermann@gmail.com>
#pragma once
#include "OutputStream.hxx"
#include "util/SpanCast.hxx"
#include <string>
class StringOutputStream final : public OutputStream {
std::string value;
public:
const std::string &GetValue() const & noexcept {
return value;
}
std::string &&GetValue() && noexcept {
return std::move(value);
}
/* virtual methods from class OutputStream */
void Write(std::span<const std::byte> src) override {
value.append(ToStringView(src));
}
};

@ -6,6 +6,7 @@ subdir('util')
subdir('net')
subdir('time')
subdir('tag')
subdir('playlist')
executable(
'read_conf',

@ -0,0 +1,39 @@
// SPDX-License-Identifier: GPL-2.0-or-later
// Copyright The Music Player Daemon Project
#include "PlaylistUtil.hxx"
#include "playlist/PlaylistRegistry.hxx"
#include "playlist/SongEnumerator.hxx"
#include "song/DetachedSong.hxx"
#include "input/MemoryInputStream.hxx"
#include "input/Ptr.hxx"
#include "thread/Mutex.hxx"
#include "io/BufferedOutputStream.hxx"
#include "io/StringOutputStream.hxx"
#include "util/SpanCast.hxx"
#include "SongSave.hxx"
std::unique_ptr<SongEnumerator>
ParsePlaylist(const char *uri, std::string_view contents)
{
Mutex mutex;
InputStreamPtr input{new MemoryInputStream{uri, mutex, AsBytes(contents)}};
return playlist_list_open_stream(std::move(input), uri);
}
std::string
ToString(SongEnumerator &e)
{
StringOutputStream sos;
WithBufferedOutputStream(sos, [&e](auto &bos){
while (const auto song = e.NextSong()) {
bos.Write('\n');
song_save(bos, *song);
}
bos.Write('\n');
});
return std::move(sos).GetValue();
}

@ -0,0 +1,15 @@
// SPDX-License-Identifier: GPL-2.0-or-later
// Copyright The Music Player Daemon Project
#pragma once
#include <memory>
#include <string>
class SongEnumerator;
std::unique_ptr<SongEnumerator>
ParsePlaylist(const char *uri, std::string_view contents);
std::string
ToString(SongEnumerator &e);

@ -0,0 +1,88 @@
// SPDX-License-Identifier: GPL-2.0-or-later
// Copyright The Music Player Daemon Project
#include "PlaylistUtil.hxx"
#include "playlist/PlaylistRegistry.hxx"
#include "playlist/SongEnumerator.hxx"
#include "config/Data.hxx"
#include <gtest/gtest.h>
using std::string_view_literals::operator""sv;
// from https://en.wikipedia.org/wiki/PLS_(file_format)
static constexpr auto pls1 = R"(
[playlist]
File1=https://e20.yesstreaming.net:8279/
Title1=Here enter name of the station
NumberOfEntries=1
)"sv;
static constexpr auto expect1 = R"(
song_begin: https://e20.yesstreaming.net:8279/
Title: Here enter name of the station
song_end
)"sv;
// from https://en.wikipedia.org/wiki/PLS_(file_format)
static constexpr auto pls2 = R"pls(
[playlist]
File1=https://e20.yesstreaming.net:8279/
Length1=-1
File2=example2.mp3
Title2=Just some local audio that is 2mins long
Length2=120
File3=F:\Music\whatever.m4a
Title3=absolute path on Windows
File4=%UserProfile%\Music\short.ogg
Title4=example for an Environment variable
Length4=5
NumberOfEntries=4
Version=2
)pls"sv;
static constexpr auto expect2 = R"(
song_begin: https://e20.yesstreaming.net:8279/
song_end
song_begin: example2.mp3
Time: 120
Title: Just some local audio that is 2mins long
song_end
song_begin: F:\Music\whatever.m4a
Title: absolute path on Windows
song_end
song_begin: %UserProfile%\Music\short.ogg
Time: 5
Title: example for an Environment variable
song_end
)"sv;
TEST(PlaylistPlugins, Pls)
{
const ConfigData config;
ScopePlaylistPluginsInit playlist_plugins_init{config};
const char *uri = "dummy.pls";
{
const auto p = ParsePlaylist(uri, pls1);
ASSERT_TRUE(p);
EXPECT_EQ(ToString(*p), expect1);
}
{
const auto p = ParsePlaylist(uri, pls2);
ASSERT_TRUE(p);
EXPECT_EQ(ToString(*p), expect2);
}
}

19
test/playlist/meson.build Normal file

@ -0,0 +1,19 @@
test(
'TestPlaylistPlugins',
executable(
'TestPlaylistPlugins',
'PlaylistUtil.cxx',
'TestPlsPlaylistPlugin.cxx',
'../../src/SongSave.cxx',
'../../src/TagSave.cxx',
'../../src/TagFile.cxx',
include_directories: inc,
dependencies: [
gtest_dep,
playlist_glue_dep,
archive_glue_dep,
input_glue_dep,
decoder_glue_dep,
],
),
)