[ox] Overhaul serialization/model system and add ModelValue/ModelObject/ModelUnion variant system
This commit is contained in:
106
deps/ox/src/ox/mc/test/tests.cpp
vendored
106
deps/ox/src/ox/mc/test/tests.cpp
vendored
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#undef NDEBUG
|
||||
@ -19,7 +19,7 @@ union TestUnion {
|
||||
static constexpr auto TypeVersion = 1;
|
||||
bool Bool;
|
||||
uint32_t Int = 5;
|
||||
char CString[32];
|
||||
char *CString;
|
||||
};
|
||||
|
||||
struct TestStructNest {
|
||||
@ -43,6 +43,7 @@ struct TestStruct {
|
||||
int32_t Int6 = 0;
|
||||
int32_t Int7 = 0;
|
||||
int32_t Int8 = 0;
|
||||
int unionIdx = 1;
|
||||
TestUnion Union;
|
||||
ox::String String = "";
|
||||
ox::BString<32> BString = "";
|
||||
@ -50,14 +51,19 @@ struct TestStruct {
|
||||
ox::HashMap<ox::String, int> Map;
|
||||
TestStructNest EmptyStruct;
|
||||
TestStructNest Struct;
|
||||
constexpr ~TestStruct() noexcept {
|
||||
if (unionIdx == 2) {
|
||||
ox::safeDelete(Union.CString);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
constexpr ox::Error model(T *io, TestUnion *obj) noexcept {
|
||||
constexpr ox::Error model(T *io, ox::CommonPtrWith<TestUnion> auto *obj) noexcept {
|
||||
io->template setTypeInfo<TestUnion>();
|
||||
oxReturnError(io->field("Bool", &obj->Bool));
|
||||
oxReturnError(io->field("Int", &obj->Int));
|
||||
oxReturnError(io->field("CString", ox::SerStr(obj->CString)));
|
||||
oxReturnError(io->fieldCString("CString", &obj->CString));
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
@ -68,7 +74,7 @@ oxModelBegin(TestStructNest)
|
||||
oxModelEnd()
|
||||
|
||||
template<typename T>
|
||||
constexpr ox::Error model(T *io, TestStruct *obj) noexcept {
|
||||
constexpr ox::Error model(T *io, ox::CommonPtrWith<TestStruct> auto *obj) noexcept {
|
||||
io->template setTypeInfo<TestStruct>();
|
||||
oxReturnError(io->field("Bool", &obj->Bool));
|
||||
oxReturnError(io->field("Int", &obj->Int));
|
||||
@ -80,7 +86,12 @@ constexpr ox::Error model(T *io, TestStruct *obj) noexcept {
|
||||
oxReturnError(io->field("Int6", &obj->Int6));
|
||||
oxReturnError(io->field("Int7", &obj->Int7));
|
||||
oxReturnError(io->field("Int8", &obj->Int8));
|
||||
oxReturnError(io->field("Union", ox::UnionView{&obj->Union, 1}));
|
||||
oxReturnError(io->field("unionIdx", &obj->unionIdx));
|
||||
if (ox_strcmp(io->opType(), ox::OpType::Reflect) == 0) {
|
||||
oxReturnError(io->field("Union", ox::UnionView{&obj->Union, 0}));
|
||||
} else {
|
||||
oxReturnError(io->field("Union", ox::UnionView{&obj->Union, obj->unionIdx}));
|
||||
}
|
||||
oxReturnError(io->field("String", &obj->String));
|
||||
oxReturnError(io->field("BString", &obj->BString));
|
||||
oxReturnError(io->field("List", obj->List, 4));
|
||||
@ -165,14 +176,15 @@ std::map<ox::String, ox::Error(*)()> tests = {
|
||||
using ox::MaxValue;
|
||||
using ox::mc::McInt;
|
||||
using ox::mc::encodeInteger;
|
||||
static constexpr auto check = [](McInt val, ox::Vector<uint8_t, 9> &&expected) {
|
||||
static constexpr auto check = [](McInt val, const ox::Vector<uint8_t, 9> &expected) {
|
||||
if (val.length != expected.size()) {
|
||||
std::cout << "val.length: " << val.length << ", expected: " << expected.size() << '\n';
|
||||
return OxError(1);
|
||||
}
|
||||
for (std::size_t i = 0; i < expected.size(); i++) {
|
||||
if (expected[i] != val.data[i]) {
|
||||
std::cout << i << ": " << static_cast<uint32_t>(val.data[i]) << '\n';
|
||||
std::cout << "decoded: " << static_cast<uint32_t>(val.data[i]) << ", expected: " << static_cast<uint32_t>(expected[i]) << '\n';
|
||||
std::cout << "decoded: " << i << ": " << static_cast<uint32_t>(val.data[i]) << '\n';
|
||||
return OxError(1);
|
||||
}
|
||||
}
|
||||
@ -195,6 +207,7 @@ std::map<ox::String, ox::Error(*)()> tests = {
|
||||
oxAssert(check(encodeInteger(int64_t(2)), {0b000'0010'0}), "Encode 2 fail");
|
||||
oxAssert(check(encodeInteger(int64_t(3)), {0b000'0011'0}), "Encode 3 fail");
|
||||
oxAssert(check(encodeInteger(int64_t(4)), {0b000'0100'0}), "Encode 4 fail");
|
||||
oxAssert(check(encodeInteger(int64_t(64)), {0b00'0000'01, 0b1}), "Encode 64 fail");
|
||||
oxAssert(check(encodeInteger(int64_t(128)), {0b00'0000'01, 0b10}), "Encode 128 fail");
|
||||
oxAssert(check(encodeInteger(int64_t(129)), {0b00'0001'01, 0b10}), "Encode 129 fail");
|
||||
oxAssert(check(encodeInteger(int64_t(130)), {0b00'0010'01, 0b10}), "Encode 130 fail");
|
||||
@ -204,6 +217,7 @@ std::map<ox::String, ox::Error(*)()> tests = {
|
||||
oxAssert(check(encodeInteger( int64_t(-2)), {0b111'1110'0}), "Encode -2 fail");
|
||||
oxAssert(check(encodeInteger( int64_t(-3)), {0b111'1101'0}), "Encode -3 fail");
|
||||
oxAssert(check(encodeInteger( int64_t(-4)), {0b111'1100'0}), "Encode -4 fail");
|
||||
oxAssert(check(encodeInteger( int64_t(-64)), {0b100'0000'0}), "Encode -64 fail");
|
||||
oxAssert(check(encodeInteger(int64_t(-128)), {0b00'0000'01, 0b11'1111'10}), "Encode -128 fail");
|
||||
oxAssert(check(encodeInteger(int64_t(-129)), {0b11'1111'01, 0b11'1111'01}), "Encode -129 fail");
|
||||
oxAssert(check(encodeInteger(int64_t(-130)), {0b11'1110'01, 0b11'1111'01}), "Encode -130 fail");
|
||||
@ -214,6 +228,7 @@ std::map<ox::String, ox::Error(*)()> tests = {
|
||||
oxAssert(check(encodeInteger(uint64_t(2)), {0b0100}), "Encode 2 fail");
|
||||
oxAssert(check(encodeInteger(uint64_t(3)), {0b0110}), "Encode 3 fail");
|
||||
oxAssert(check(encodeInteger(uint64_t(4)), {0b1000}), "Encode 4 fail");
|
||||
oxAssert(check(encodeInteger(uint64_t(64)), {0b1000'000'0}), "Encode 4 fail");
|
||||
oxAssert(check(encodeInteger(uint64_t(128)), {0b0001, 0b10}), "Encode 128 fail");
|
||||
oxAssert(check(encodeInteger(uint64_t(129)), {0b0101, 0b10}), "Encode 129 fail");
|
||||
oxAssert(check(encodeInteger(uint64_t(130)), {0b1001, 0b10}), "Encode 130 fail");
|
||||
@ -267,14 +282,13 @@ std::map<ox::String, ox::Error(*)()> tests = {
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
"MetalClawDef",
|
||||
"MetalClawModelValue",
|
||||
[] {
|
||||
//constexpr size_t descBuffLen = 1024;
|
||||
//uint8_t descBuff[descBuffLen];
|
||||
static constexpr size_t dataBuffLen = ox::units::MB;
|
||||
char dataBuff[dataBuffLen];
|
||||
TestStruct testIn, testOut;
|
||||
ox::Buffer dataBuff(dataBuffLen);
|
||||
TestStruct testIn;
|
||||
testIn.Bool = true;
|
||||
testIn.Int = 42;
|
||||
testIn.BString = "Test String 1";
|
||||
@ -285,18 +299,71 @@ std::map<ox::String, ox::Error(*)()> tests = {
|
||||
testIn.Struct.Bool = false;
|
||||
testIn.Struct.Int = 300;
|
||||
testIn.Struct.BString = "Test String 2";
|
||||
oxAssert(ox::writeMC(dataBuff, dataBuffLen, &testIn), "Data generation failed");
|
||||
testIn.unionIdx = 1;
|
||||
testIn.Union.Int = 93;
|
||||
oxAssert(ox::writeMC(dataBuff.data(), dataBuff.size(), &testIn), "Data generation failed");
|
||||
ox::TypeStore typeStore;
|
||||
auto type = ox::buildTypeDef(&typeStore, &testIn);
|
||||
oxAssert(type.error, "Descriptor write failed");
|
||||
oxReturnError(ox::walkModel<ox::MetalClawReader>(type.value, dataBuff, dataBuffLen,
|
||||
ox::ModelObject testOut;
|
||||
oxReturnError(testOut.setType(type.value));
|
||||
oxAssert(ox::readMC(dataBuff.data(), dataBuff.size(), &testOut), "Data read failed");
|
||||
oxAssert(testOut["Int"].get<int>() == testIn.Int, "testOut.Int failed");
|
||||
oxAssert(testOut["Bool"].get<bool>() == testIn.Bool, "testOut.Bool failed");
|
||||
oxAssert(testOut["String"].get<ox::String>() == testIn.String, "testOut.String failed");
|
||||
auto &testOutStruct = testOut["Struct"].get<ox::ModelObject>();
|
||||
auto &testOutUnion = testOut["Union"].get<ox::ModelUnion>();
|
||||
auto &testOutList = testOut["List"].get<ox::ModelValueVector>();
|
||||
auto testOutStructCopy = testOut["Struct"].get<ox::ModelObject>();
|
||||
auto testOutUnionCopy = testOut["Union"].get<ox::ModelUnion>();
|
||||
auto testOutListCopy = testOut["List"].get<ox::ModelValueVector>();
|
||||
oxAssert(testOutStruct.typeName() == TestStructNest::TypeName, "ModelObject TypeName failed");
|
||||
oxAssert(testOutStruct.typeVersion() == TestStructNest::TypeVersion, "ModelObject TypeVersion failed");
|
||||
oxAssert(testOutStruct["Bool"].get<bool>() == testIn.Struct.Bool, "testOut.Struct.Bool failed");
|
||||
oxAssert(testOutStruct["BString"].get<ox::String>() == testIn.Struct.BString.c_str(), "testOut.Struct.BString failed");
|
||||
oxAssert(testOut["unionIdx"].get<int>() == testIn.unionIdx, "testOut.unionIdx failed");
|
||||
oxAssert(testOutUnion.unionIdx() == testIn.unionIdx, "testOut.Union idx wrong");
|
||||
oxAssert(testOutUnion["Int"].get<uint32_t>() == testIn.Union.Int, "testOut.Union.Int failed");
|
||||
oxAssert(testOutList[0].get<uint32_t>() == testIn.List[0], "testOut.List[0] failed");
|
||||
oxAssert(testOutList[1].get<uint32_t>() == testIn.List[1], "testOut.Struct.List[1] failed");
|
||||
oxAssert(testOutStructCopy["Bool"].get<bool>() == testIn.Struct.Bool, "testOut.Struct.Bool (copy) failed");
|
||||
oxAssert(testOutStructCopy["BString"].get<ox::String>() == testIn.Struct.BString.c_str(), "testOut.Struct.BString (copy) failed");
|
||||
oxAssert(testOutListCopy[0].get<uint32_t>() == testIn.List[0], "testOut.Struct.List[0] (copy) failed");
|
||||
oxAssert(testOutListCopy[1].get<uint32_t>() == testIn.List[1], "testOut.Struct.List[1] (copy) failed");
|
||||
return OxError(0);
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"MetalClawDef",
|
||||
[] {
|
||||
//constexpr size_t descBuffLen = 1024;
|
||||
//uint8_t descBuff[descBuffLen];
|
||||
static constexpr size_t dataBuffLen = ox::units::MB;
|
||||
char dataBuff[dataBuffLen];
|
||||
TestStruct testIn, testOut;
|
||||
testIn.Bool = true;
|
||||
testIn.Int = 42;
|
||||
testIn.BString = "Test String 1";
|
||||
testIn.List[0] = 1;
|
||||
testIn.List[1] = 2;
|
||||
testIn.List[2] = 3;
|
||||
testIn.List[3] = 4;
|
||||
testIn.Struct.Bool = false;
|
||||
testIn.Struct.Int = 300;
|
||||
testIn.Struct.BString = "Test String 2";
|
||||
oxAssert(ox::writeMC(dataBuff, dataBuffLen, &testIn), "Data generation failed");
|
||||
ox::TypeStore typeStore;
|
||||
auto type = ox::buildTypeDef(&typeStore, &testIn);
|
||||
oxAssert(type.error, "Descriptor write failed");
|
||||
oxReturnError(ox::walkModel<ox::MetalClawReader>(type.value, dataBuff, dataBuffLen,
|
||||
[](const ox::Vector<ox::FieldName>&, const ox::Vector<ox::String>&, const ox::DescriptorField &f, ox::MetalClawReader *rdr) -> ox::Error {
|
||||
//std::cout << f.fieldName.c_str() << '\n';
|
||||
auto fieldName = f.fieldName.c_str();
|
||||
switch (f.type->primitiveType) {
|
||||
case ox::PrimitiveType::UnsignedInteger:
|
||||
std::cout << fieldName << ":\tuint" << f.type->length * 8 << "_t:\t";
|
||||
switch (f.type->length) {
|
||||
std::cout << fieldName << ":\tuint" << f.type->length * 8 << "_t:\t";
|
||||
switch (f.type->length) {
|
||||
case 1: {
|
||||
uint8_t i = {};
|
||||
oxAssert(rdr->field(fieldName, &i), "Walking model failed.");
|
||||
@ -382,12 +449,11 @@ std::map<ox::String, ox::Error(*)()> tests = {
|
||||
};
|
||||
|
||||
int main(int argc, const char **args) {
|
||||
int retval = -1;
|
||||
if (argc > 0) {
|
||||
auto testName = args[1];
|
||||
if (tests.find(testName) != tests.end()) {
|
||||
retval = tests[testName]();
|
||||
oxAssert(tests[testName](), "Test failed...");
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
return 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user