test/playlist: unit tests for the playlist plugins
Only "pls" for now.
This commit is contained in:
parent
2d3271859f
commit
898e0a2bc4
27
src/io/StringOutputStream.hxx
Normal file
27
src/io/StringOutputStream.hxx
Normal file
@ -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',
|
||||
|
39
test/playlist/PlaylistUtil.cxx
Normal file
39
test/playlist/PlaylistUtil.cxx
Normal file
@ -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();
|
||||
}
|
15
test/playlist/PlaylistUtil.hxx
Normal file
15
test/playlist/PlaylistUtil.hxx
Normal file
@ -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);
|
88
test/playlist/TestPlsPlaylistPlugin.cxx
Normal file
88
test/playlist/TestPlsPlaylistPlugin.cxx
Normal file
@ -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
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,
|
||||
],
|
||||
),
|
||||
)
|
Loading…
x
Reference in New Issue
Block a user