Unit tests for constructing and comparing EBML hierarchies

This commit is contained in:
Moritz Bunkus 2012-08-21 14:57:09 +02:00
parent e1634f4540
commit c1fa6f0381
3 changed files with 157 additions and 0 deletions

View File

@ -0,0 +1,141 @@
#include "common/common_pch.h"
#include "gtest/gtest.h"
#include "common/ebml.h"
#include "tests/unit/construct.h"
#include "tests/unit/util.h"
#include <matroska/KaxTracks.h>
#include <matroska/KaxTrackEntryData.h>
#include <matroska/KaxTrackVideo.h>
namespace {
using namespace mtxut;
using namespace mtxut::construct;
using namespace libmatroska;
template<typename T>
EbmlMaster *
master() {
T *master = new T;
master->RemoveAll();
return master;
}
TEST(ConstructAndEquality, EmptyMaster) {
auto a = ebml_master_cptr{ cons<KaxTracks>() };
auto b = ebml_master_cptr{ master<KaxTracks>() };
EXPECT_EQ(a->ListSize(), 0u);
EXPECT_EQ(b->ListSize(), 0u);
EXPECT_EBML_EQ(*a, *b);
}
TEST(ConstructAndEquality, SingleLevel) {
auto a = ebml_master_cptr{ cons<KaxTrackVideo>(new KaxVideoPixelWidth, 123, new KaxVideoPixelHeight, 456) };
auto b = ebml_master_cptr{ master<KaxTrackVideo>() };
b->PushElement(*new KaxVideoPixelWidth);
b->PushElement(*new KaxVideoPixelHeight);
*dynamic_cast<EbmlUInteger *>((*b)[0]) = 123;
*dynamic_cast<EbmlUInteger *>((*b)[1]) = 456;
EXPECT_EBML_EQ(*a, *b);
}
TEST(ConstructAndEquality, MultipleLevels) {
auto a = ebml_master_cptr{ cons<KaxTracks>(cons<KaxTrackEntry>(cons<KaxTrackVideo>())) };
auto b = ebml_master_cptr{ master<KaxTracks>() };
b->PushElement(*master<KaxTrackEntry>());
static_cast<EbmlMaster *>((*b)[0])->PushElement(*master<KaxTrackVideo>());
EXPECT_EBML_EQ(*a, *b);
}
TEST(ConstructAndEquality, MasterAtTheFront) {
auto a = ebml_master_cptr{ cons<KaxTracks>(cons<KaxTrackEntry>(), new KaxCodecID, std::string{"Stuff"}) };
auto b = ebml_master_cptr{ master<KaxTracks>() };
b->PushElement(*master<KaxTrackEntry>());
b->PushElement(*new KaxCodecID);
*static_cast<EbmlString *>((*b)[1]) = "Stuff";
EXPECT_EBML_EQ(*a, *b);
}
TEST(ConstructAndEquality, MasterInTheMiddle) {
auto a = ebml_master_cptr{ cons<KaxTracks>(new KaxTrackUID, 4711u, cons<KaxTrackEntry>(), new KaxTrackUID, 4712u) };
auto b = ebml_master_cptr{ master<KaxTracks>() };
b->PushElement(*new KaxTrackUID);
b->PushElement(*master<KaxTrackEntry>());
b->PushElement(*new KaxTrackUID);
*static_cast<EbmlUInteger *>((*b)[0]) = 4711;
*static_cast<EbmlUInteger *>((*b)[2]) = 4712;
EXPECT_EBML_EQ(*a, *b);
}
TEST(ConstructAndEquality, MasterAtTheBack) {
auto a = ebml_master_cptr{ cons<KaxTracks>(new KaxCodecID, "Stuff", cons<KaxTrackEntry>()) };
auto b = ebml_master_cptr{ master<KaxTracks>() };
b->PushElement(*new KaxCodecID);
b->PushElement(*master<KaxTrackEntry>());
*static_cast<EbmlString *>((*b)[0]) = "Stuff";
EXPECT_EBML_EQ(*a, *b);
}
TEST(ConstructAndEquality, NoMaster) {
auto a = ebml_master_cptr{ cons<KaxTracks>(new KaxCodecID, "Stuff1", new KaxCodecID, "Stuff2") };
auto b = ebml_master_cptr{ master<KaxTracks>() };
b->PushElement(*new KaxCodecID);
b->PushElement(*new KaxCodecID);
*static_cast<EbmlString *>((*b)[0]) = "Stuff1";
*static_cast<EbmlString *>((*b)[1]) = "Stuff2";
EXPECT_EBML_EQ(*a, *b);
}
TEST(ConstructAndEquality, AllTypes) {
auto a = ebml_master_cptr{ cons<KaxTracks>(cons<KaxTrackEntry>(new KaxCodecID, "Stuff",
new KaxCodecName, L"UniStuff",
new KaxTrackNumber, 4254,
new KaxTrackOffset, -22,
new KaxDateUTC, 98273,
new KaxDuration, 47.11,
cons<KaxTrackVideo>(new KaxVideoPixelWidth, 123,
new KaxVideoPixelHeight, 456)))
};
auto b = ebml_master_cptr{ master<KaxTracks>() };
auto m1 = master<KaxTrackEntry>();
auto m2 = master<KaxTrackVideo>();
b->PushElement(*m1);
m1->PushElement(*new KaxCodecID);
m1->PushElement(*new KaxCodecName);
m1->PushElement(*new KaxTrackNumber);
m1->PushElement(*new KaxTrackOffset);
m1->PushElement(*new KaxDateUTC);
m1->PushElement(*new KaxDuration);
m1->PushElement(*m2);
m2->PushElement(*new KaxVideoPixelWidth);
m2->PushElement(*new KaxVideoPixelHeight);
*dynamic_cast<EbmlString *>((*m1)[0]) = "Stuff";
*dynamic_cast<EbmlUnicodeString *>((*m1)[1]) = L"UniStuff";
*dynamic_cast<EbmlUInteger *>((*m1)[2]) = 4254;
*dynamic_cast<EbmlSInteger *>((*m1)[3]) = -22;
dynamic_cast<EbmlDate *>((*m1)[4])->SetEpochDate(98273);
*dynamic_cast<EbmlFloat *>((*m1)[5]) = 47.11;
*dynamic_cast<EbmlUInteger *>((*m2)[0]) = 123;
*dynamic_cast<EbmlUInteger *>((*m2)[1]) = 456;
EXPECT_EBML_EQ(*a, *b);
}
TEST(ConstructAndEquality, Binary) {
auto a = ebml_master_cptr{ cons<KaxTracks>(new KaxCodecPrivate, memory_c::clone("Stuff", 5)) };
auto b = ebml_master_cptr{ master<KaxTracks>() };
b->PushElement(*new KaxCodecPrivate);
static_cast<EbmlBinary *>((*b)[0])->CopyBuffer(reinterpret_cast<binary const *>("Stuff"), 5);
EXPECT_EBML_EQ(*a, *b);
}
}

View File

@ -19,6 +19,7 @@
#include <type_traits>
#include <boost/type_traits.hpp>
#include <ebml/EbmlBinary.h>
#include <ebml/EbmlDate.h>
#include <ebml/EbmlFloat.h>
#include <ebml/EbmlSInteger.h>
@ -91,6 +92,16 @@ cons_impl(EbmlMaster *master,
master->PushElement(*object);
}
template<typename Tobject,
typename Tvalue>
typename boost::enable_if< std::is_base_of<EbmlBinary, Tobject> >::type
cons_impl(EbmlMaster *master,
Tobject *object,
Tvalue const &value) {
static_cast<EbmlBinary *>(object)->CopyBuffer(static_cast<binary *>(value->get_buffer()), value->get_size());
master->PushElement(*object);
}
void
cons_impl(EbmlMaster *master,
EbmlMaster *sub_master) {

View File

@ -138,6 +138,7 @@ ebml_equals_c::compare_impl(EbmlElement &a,
EbmlUnicodeString *ustr_a;
EbmlMaster *m_a;
EbmlDate *d_a;
EbmlBinary *b_a;
if ((ui_a = dynamic_cast<EbmlUInteger *>(&a))) {
auto val_b = uint64(*dynamic_cast<EbmlUInteger *>(&b));
@ -165,6 +166,10 @@ ebml_equals_c::compare_impl(EbmlElement &a,
auto val_b = UTFstring(*dynamic_cast<EbmlUnicodeString *>(&b)).GetUTF8();
return val_a == val_b ? true : set_error(boost::format("UnicodeString values differ: %1% vs %2%") % val_a % val_b, &a);
} else if ((b_a = dynamic_cast<EbmlBinary *>(&a))) {
auto b_b = dynamic_cast<EbmlBinary *>(&b);
return *b_a == *b_b ? true : set_error(boost::format("Binary values differ; sizes %1% vs %2%") % b_a->GetSize() % b_b->GetSize(), &a);
} else if ((m_a = dynamic_cast<EbmlMaster *>(&a))) {
m_path.push_back(EBML_NAME(&a));
at_scope_exit_c popper{[&]() { m_path.pop_back(); }};