test: add unit test for playlist_check_translate_song()

This commit is contained in:
Max Kellermann 2014-01-20 21:31:40 +01:00
parent c727c86245
commit dd20a3ce7e
2 changed files with 306 additions and 0 deletions

View File

@ -1154,6 +1154,7 @@ C_TESTS = \
test/test_byte_reverse \
test/test_mixramp \
test/test_pcm \
test/test_translate_song \
test/test_queue_priority
if ENABLE_ARCHIVE
@ -1625,6 +1626,21 @@ test_test_archive_LDADD = \
$(GLIB_LIBS) \
$(CPPUNIT_LIBS)
test_test_translate_song_SOURCES = \
src/PlaylistSong.cxx \
src/DetachedSong.cxx \
src/Log.cxx \
test/test_translate_song.cxx
test_test_translate_song_CPPFLAGS = $(AM_CPPFLAGS) $(CPPUNIT_CFLAGS) -DCPPUNIT_HAVE_RTTI=0
test_test_translate_song_CXXFLAGS = $(AM_CXXFLAGS) -Wno-error=deprecated-declarations
test_test_translate_song_LDADD = \
libtag.a \
libfs.a \
libsystem.a \
libutil.a \
$(GLIB_LIBS) \
$(CPPUNIT_LIBS)
test_test_queue_priority_SOURCES = \
src/Queue.cxx \
test/test_queue_priority.cxx

View File

@ -0,0 +1,290 @@
/*
* Unit tests for playlist_check_translate_song().
*/
#include "config.h"
#include "PlaylistSong.hxx"
#include "DetachedSong.hxx"
#include "tag/TagBuilder.hxx"
#include "tag/Tag.hxx"
#include "util/Domain.hxx"
#include "fs/AllocatedPath.hxx"
#include "ls.hxx"
#include "Log.hxx"
#include "DatabaseSong.hxx"
#include "Mapper.hxx"
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <cppunit/ui/text/TestRunner.h>
#include <cppunit/extensions/HelperMacros.h>
#include <string.h>
#include <stdio.h>
void
Log(const Domain &domain, gcc_unused LogLevel level, const char *msg)
{
fprintf(stderr, "[%s] %s\n", domain.GetName(), msg);
}
bool
uri_supported_scheme(const char *uri)
{
return memcmp(uri, "http://", 7) == 0;
}
const char *const music_directory = "/music";
const char *
map_to_relative_path(const char *path_utf8)
{
size_t length = strlen(music_directory);
if (memcmp(path_utf8, music_directory, length) == 0 &&
path_utf8[length] == '/')
path_utf8 += length + 1;
return path_utf8;
}
static void
BuildTag(gcc_unused TagBuilder &tag)
{
}
template<typename... Args>
static void
BuildTag(TagBuilder &tag, TagType type, const char *value, Args&&... args)
{
tag.AddItem(type, value);
BuildTag(tag, std::forward<Args>(args)...);
}
template<typename... Args>
static Tag
MakeTag(Args&&... args)
{
TagBuilder tag;
BuildTag(tag, std::forward<Args>(args)...);
return tag.Commit();
}
static Tag
MakeTag1a()
{
return MakeTag(TAG_ARTIST, "artist_a1", TAG_TITLE, "title_a1",
TAG_ALBUM, "album_a1");
}
static Tag
MakeTag1b()
{
return MakeTag(TAG_ARTIST, "artist_b1", TAG_TITLE, "title_b1",
TAG_COMMENT, "comment_b1");
}
static Tag
MakeTag1c()
{
return MakeTag(TAG_ARTIST, "artist_b1", TAG_TITLE, "title_b1",
TAG_COMMENT, "comment_b1", TAG_ALBUM, "album_a1");
}
static Tag
MakeTag2a()
{
return MakeTag(TAG_ARTIST, "artist_a2", TAG_TITLE, "title_a2",
TAG_ALBUM, "album_a2");
}
static Tag
MakeTag2b()
{
return MakeTag(TAG_ARTIST, "artist_b2", TAG_TITLE, "title_b2",
TAG_COMMENT, "comment_b2");
}
static Tag
MakeTag2c()
{
return MakeTag(TAG_ARTIST, "artist_b2", TAG_TITLE, "title_b2",
TAG_COMMENT, "comment_b2", TAG_ALBUM, "album_a2");
}
static const char *uri1 = "/foo/bar.ogg";
static const char *uri2 = "foo/bar.ogg";
DetachedSong *
DatabaseDetachSong(const char *uri, gcc_unused Error &error)
{
if (strcmp(uri, uri2) == 0)
return new DetachedSong(uri, MakeTag2a());
return nullptr;
}
bool
DetachedSong::Update()
{
if (strcmp(GetURI(), uri1) == 0) {
SetTag(MakeTag1a());
return true;
}
return false;
}
static std::string
ToString(const Tag &tag)
{
char buffer[64];
sprintf(buffer, "%d", tag.time);
std::string result = buffer;
for (unsigned i = 0, n = tag.num_items; i != n; ++i) {
const TagItem &item = *tag.items[i];
result.push_back('|');
result.append(tag_item_names[item.type]);
result.push_back('=');
result.append(item.value);
}
return result;
}
static std::string
ToString(const DetachedSong &song)
{
std::string result = song.GetURI();
result.push_back('|');
char buffer[64];
if (song.GetLastModified() > 0) {
sprintf(buffer, "%lu", (unsigned long)song.GetLastModified());
result.append(buffer);
}
result.push_back('|');
if (song.GetStartMS() > 0) {
sprintf(buffer, "%u", song.GetStartMS());
result.append(buffer);
}
result.push_back('-');
if (song.GetEndMS() > 0) {
sprintf(buffer, "%u", song.GetEndMS());
result.append(buffer);
}
result.push_back('|');
result.append(ToString(song.GetTag()));
return result;
}
static std::string
ToString(const DetachedSong *song)
{
if (song == nullptr)
return "nullptr";
return ToString(*song);
}
class TranslateSongTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(TranslateSongTest);
CPPUNIT_TEST(TestAbsoluteURI);
CPPUNIT_TEST(TestInsecure);
CPPUNIT_TEST(TestSecure);
CPPUNIT_TEST(TestInDatabase);
CPPUNIT_TEST(TestRelative);
CPPUNIT_TEST_SUITE_END();
void TestAbsoluteURI() {
auto song1 = new DetachedSong("http://example.com/foo.ogg");
auto song2 = playlist_check_translate_song(song1, "/ignored", false);
CPPUNIT_ASSERT_EQUAL(song1, song2);
}
void TestInsecure() {
/* illegal because secure=false */
auto song1 = new DetachedSong(uri1);
auto song2 = playlist_check_translate_song(song1, nullptr, false);
CPPUNIT_ASSERT_EQUAL((DetachedSong *)nullptr, song2);
}
void TestSecure() {
auto song1 = new DetachedSong(uri1, MakeTag1b());
auto s1 = ToString(song1);
auto se = ToString(DetachedSong(uri1, MakeTag1c()));
auto song2 = playlist_check_translate_song(song1, "/ignored", true);
CPPUNIT_ASSERT_EQUAL(se, ToString(song2));
delete song2;
}
void TestInDatabase() {
auto song1 = new DetachedSong("doesntexist");
auto song2 = playlist_check_translate_song(song1, nullptr, false);
CPPUNIT_ASSERT_EQUAL((DetachedSong *)nullptr, song2);
song1 = new DetachedSong(uri2, MakeTag2b());
auto s1 = ToString(song1);
auto se = ToString(DetachedSong(uri2, MakeTag2c()));
song2 = playlist_check_translate_song(song1, nullptr, false);
CPPUNIT_ASSERT_EQUAL(se, ToString(song2));
delete song2;
song1 = new DetachedSong("/music/foo/bar.ogg", MakeTag2b());
s1 = ToString(song1);
se = ToString(DetachedSong(uri2, MakeTag2c()));
song2 = playlist_check_translate_song(song1, nullptr, false);
CPPUNIT_ASSERT_EQUAL(se, ToString(song2));
delete song2;
}
void TestRelative() {
/* map to music_directory */
auto song1 = new DetachedSong("bar.ogg", MakeTag2b());
auto s1 = ToString(song1);
auto se = ToString(DetachedSong(uri2, MakeTag2c()));
auto song2 = playlist_check_translate_song(song1, "/music/foo", false);
CPPUNIT_ASSERT_EQUAL(se, ToString(song2));
delete song2;
/* illegal because secure=false */
song1 = new DetachedSong("bar.ogg", MakeTag2b());
song2 = playlist_check_translate_song(song1, "/foo", false);
CPPUNIT_ASSERT_EQUAL((DetachedSong *)nullptr, song2);
/* legal because secure=true */
song1 = new DetachedSong("bar.ogg", MakeTag1b());
s1 = ToString(song2);
se = ToString(DetachedSong(uri1, MakeTag1c()));
song2 = playlist_check_translate_song(song1, "/foo", true);
CPPUNIT_ASSERT_EQUAL(se, ToString(song2));
delete song2;
/* relative to http:// */
song1 = new DetachedSong("bar.ogg", MakeTag2a());
s1 = ToString(song1);
se = ToString(DetachedSong("http://example.com/foo/bar.ogg", MakeTag2a()));
song2 = playlist_check_translate_song(song1, "http://example.com/foo", false);
CPPUNIT_ASSERT_EQUAL(se, ToString(song2));
delete song2;
}
};
CPPUNIT_TEST_SUITE_REGISTRATION(TranslateSongTest);
int
main(gcc_unused int argc, gcc_unused char **argv)
{
CppUnit::TextUi::TestRunner runner;
auto &registry = CppUnit::TestFactoryRegistry::getRegistry();
runner.addTest(registry.makeTest());
return runner.run() ? EXIT_SUCCESS : EXIT_FAILURE;
}