diff --git a/tests/unit/common/construct_equality.cpp b/tests/unit/common/construct_equality.cpp new file mode 100644 index 000000000..9c6763402 --- /dev/null +++ b/tests/unit/common/construct_equality.cpp @@ -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 +#include +#include + +namespace { + +using namespace mtxut; +using namespace mtxut::construct; +using namespace libmatroska; + +template +EbmlMaster * +master() { + T *master = new T; + master->RemoveAll(); + return master; +} + +TEST(ConstructAndEquality, EmptyMaster) { + auto a = ebml_master_cptr{ cons() }; + auto b = ebml_master_cptr{ master() }; + EXPECT_EQ(a->ListSize(), 0u); + EXPECT_EQ(b->ListSize(), 0u); + EXPECT_EBML_EQ(*a, *b); +} + +TEST(ConstructAndEquality, SingleLevel) { + auto a = ebml_master_cptr{ cons(new KaxVideoPixelWidth, 123, new KaxVideoPixelHeight, 456) }; + auto b = ebml_master_cptr{ master() }; + b->PushElement(*new KaxVideoPixelWidth); + b->PushElement(*new KaxVideoPixelHeight); + *dynamic_cast((*b)[0]) = 123; + *dynamic_cast((*b)[1]) = 456; + EXPECT_EBML_EQ(*a, *b); +} + +TEST(ConstructAndEquality, MultipleLevels) { + auto a = ebml_master_cptr{ cons(cons(cons())) }; + auto b = ebml_master_cptr{ master() }; + b->PushElement(*master()); + static_cast((*b)[0])->PushElement(*master()); + EXPECT_EBML_EQ(*a, *b); +} + +TEST(ConstructAndEquality, MasterAtTheFront) { + auto a = ebml_master_cptr{ cons(cons(), new KaxCodecID, std::string{"Stuff"}) }; + auto b = ebml_master_cptr{ master() }; + b->PushElement(*master()); + b->PushElement(*new KaxCodecID); + *static_cast((*b)[1]) = "Stuff"; + EXPECT_EBML_EQ(*a, *b); +} + +TEST(ConstructAndEquality, MasterInTheMiddle) { + auto a = ebml_master_cptr{ cons(new KaxTrackUID, 4711u, cons(), new KaxTrackUID, 4712u) }; + auto b = ebml_master_cptr{ master() }; + b->PushElement(*new KaxTrackUID); + b->PushElement(*master()); + b->PushElement(*new KaxTrackUID); + *static_cast((*b)[0]) = 4711; + *static_cast((*b)[2]) = 4712; + EXPECT_EBML_EQ(*a, *b); +} + +TEST(ConstructAndEquality, MasterAtTheBack) { + auto a = ebml_master_cptr{ cons(new KaxCodecID, "Stuff", cons()) }; + auto b = ebml_master_cptr{ master() }; + b->PushElement(*new KaxCodecID); + b->PushElement(*master()); + *static_cast((*b)[0]) = "Stuff"; + EXPECT_EBML_EQ(*a, *b); +} + +TEST(ConstructAndEquality, NoMaster) { + auto a = ebml_master_cptr{ cons(new KaxCodecID, "Stuff1", new KaxCodecID, "Stuff2") }; + auto b = ebml_master_cptr{ master() }; + b->PushElement(*new KaxCodecID); + b->PushElement(*new KaxCodecID); + *static_cast((*b)[0]) = "Stuff1"; + *static_cast((*b)[1]) = "Stuff2"; + EXPECT_EBML_EQ(*a, *b); +} + +TEST(ConstructAndEquality, AllTypes) { + auto a = ebml_master_cptr{ cons(cons(new KaxCodecID, "Stuff", + new KaxCodecName, L"UniStuff", + new KaxTrackNumber, 4254, + new KaxTrackOffset, -22, + new KaxDateUTC, 98273, + new KaxDuration, 47.11, + cons(new KaxVideoPixelWidth, 123, + new KaxVideoPixelHeight, 456))) + }; + + auto b = ebml_master_cptr{ master() }; + auto m1 = master(); + auto m2 = master(); + + 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((*m1)[0]) = "Stuff"; + *dynamic_cast((*m1)[1]) = L"UniStuff"; + *dynamic_cast((*m1)[2]) = 4254; + *dynamic_cast((*m1)[3]) = -22; + dynamic_cast((*m1)[4])->SetEpochDate(98273); + *dynamic_cast((*m1)[5]) = 47.11; + + *dynamic_cast((*m2)[0]) = 123; + *dynamic_cast((*m2)[1]) = 456; + + EXPECT_EBML_EQ(*a, *b); +} + +TEST(ConstructAndEquality, Binary) { + auto a = ebml_master_cptr{ cons(new KaxCodecPrivate, memory_c::clone("Stuff", 5)) }; + auto b = ebml_master_cptr{ master() }; + b->PushElement(*new KaxCodecPrivate); + static_cast((*b)[0])->CopyBuffer(reinterpret_cast("Stuff"), 5); + EXPECT_EBML_EQ(*a, *b); +} + +} diff --git a/tests/unit/construct.h b/tests/unit/construct.h index 7354d33e1..379c34254 100644 --- a/tests/unit/construct.h +++ b/tests/unit/construct.h @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -91,6 +92,16 @@ cons_impl(EbmlMaster *master, master->PushElement(*object); } +template +typename boost::enable_if< std::is_base_of >::type +cons_impl(EbmlMaster *master, + Tobject *object, + Tvalue const &value) { + static_cast(object)->CopyBuffer(static_cast(value->get_buffer()), value->get_size()); + master->PushElement(*object); +} + void cons_impl(EbmlMaster *master, EbmlMaster *sub_master) { diff --git a/tests/unit/util.cpp b/tests/unit/util.cpp index 1f8e9df18..83bf376b1 100644 --- a/tests/unit/util.cpp +++ b/tests/unit/util.cpp @@ -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(&a))) { auto val_b = uint64(*dynamic_cast(&b)); @@ -165,6 +166,10 @@ ebml_equals_c::compare_impl(EbmlElement &a, auto val_b = UTFstring(*dynamic_cast(&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(&a))) { + auto b_b = dynamic_cast(&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(&a))) { m_path.push_back(EBML_NAME(&a)); at_scope_exit_c popper{[&]() { m_path.pop_back(); }};