#include "base/strings/string_number_conversions.h"
#include "media/formats/hls/media_playlist_test_builder.h"
#include "media/formats/hls/multivariant_playlist_test_builder.h"
#include "media/formats/hls/parse_status.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace media::hls {
namespace {
template <typename BuilderT>
class HlsCommonPlaylistTest : public testing::Test {
public:
using Builder = BuilderT;
};
using Implementations =
testing::Types<MultivariantPlaylistTestBuilder, MediaPlaylistTestBuilder>;
TYPED_TEST_SUITE(HlsCommonPlaylistTest, Implementations);
void AddRequiredTags(MultivariantPlaylistTestBuilder&) {
}
void AddRequiredTags(MediaPlaylistTestBuilder& builder) {
builder.AppendLine("#EXT-X-TARGETDURATION:10");
}
}
TYPED_TEST(HlsCommonPlaylistTest, BadLineEndings) {
TypeParam builder;
builder.AppendLine("#EXTM3U");
AddRequiredTags(builder);
{
auto fork = builder;
fork.Append("\r\r\n");
fork.ExpectError(ParseStatusCode::kInvalidEOL);
}
{
auto fork = builder;
fork.Append("#EXT-X-VERSION:5\r");
fork.ExpectError(ParseStatusCode::kInvalidEOL);
}
builder.Append("\r\n");
builder.ExpectOk();
}
TYPED_TEST(HlsCommonPlaylistTest, MissingM3u) {
TypeParam builder;
builder.AppendLine("");
builder.AppendLine("#EXTM3U");
builder.ExpectError(ParseStatusCode::kPlaylistMissingM3uTag);
builder = TypeParam();
builder.AppendLine("#EXT-X-VERSION:5");
builder.AppendLine("#EXTM3U");
builder.ExpectError(ParseStatusCode::kPlaylistMissingM3uTag);
builder = TypeParam();
builder.AppendLine("#EXTM3U:");
builder.ExpectError(ParseStatusCode::kPlaylistMissingM3uTag);
builder = TypeParam();
builder.AppendLine("#EXTM3U:1");
builder.ExpectError(ParseStatusCode::kPlaylistMissingM3uTag);
builder = TypeParam();
builder.AppendLine("#EXTM3U");
builder.AppendLine("#EXTM3U");
AddRequiredTags(builder);
builder.ExpectOk();
}
TYPED_TEST(HlsCommonPlaylistTest, UnknownTag) {
TypeParam builder;
builder.AppendLine("#EXTM3U");
AddRequiredTags(builder);
builder.AppendLine("#EXT-UNKNOWN-TAG");
builder.ExpectOk();
}
TYPED_TEST(HlsCommonPlaylistTest, VersionChecks) {
TypeParam builder;
builder.AppendLine("#EXTM3U");
AddRequiredTags(builder);
{
auto fork = builder;
fork.ExpectOk();
}
{
auto fork = builder;
fork.AppendLine("#EXT-X-VERSION:-1");
fork.ExpectError(ParseStatusCode::kFailedToParseDecimalInteger);
}
{
auto fork = builder;
fork.AppendLine("#EXT-X-VERSION:0");
fork.ExpectError(ParseStatusCode::kInvalidPlaylistVersion);
}
for (int i = 1; i <= 10; ++i) {
auto fork = builder;
fork.AppendLine("#EXT-X-VERSION:" + base::NumberToString(i));
fork.SetVersion(i);
fork.ExpectOk();
}
for (int i : {11, 12, 100, 999}) {
auto fork = builder;
fork.AppendLine("#EXT-X-VERSION:" + base::NumberToString(i));
fork.SetVersion(i);
fork.ExpectError(ParseStatusCode::kPlaylistHasUnsupportedVersion);
}
builder.SetVersion(5);
builder.ExpectError(ParseStatusCode::kPlaylistHasVersionMismatch);
builder.AppendLine("#EXT-X-VESION:3");
builder.ExpectError(ParseStatusCode::kPlaylistHasVersionMismatch);
}
TYPED_TEST(HlsCommonPlaylistTest, XIndependentSegmentsTag) {
TypeParam builder;
builder.AppendLine("#EXTM3U");
AddRequiredTags(builder);
{
auto fork = builder;
fork.ExpectPlaylist(HasIndependentSegments, false);
fork.ExpectOk();
}
builder.AppendLine("#EXT-X-INDEPENDENT-SEGMENTS");
builder.ExpectPlaylist(HasIndependentSegments, true);
builder.ExpectOk();
builder.AppendLine("#EXT-X-INDEPENDENT-SEGMENTS");
builder.ExpectError(ParseStatusCode::kPlaylistHasDuplicateTags);
}
}