/* * Copyright 2015 - 2024 gary@drinkingtea.net * * 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 https://mozilla.org/MPL/2.0/. */ #undef NDEBUG #include #include #include #include #include #include #include union TestUnion { static constexpr auto TypeName = "TestUnion"; static constexpr auto TypeVersion = 1; bool Bool; uint32_t Int = 5; char *String; }; struct TestStructNest { static constexpr auto TypeName = "TestStructNest"; static constexpr auto TypeVersion = 1; bool Bool = false; uint32_t Int = 0; ox::IString<32> String = ""; }; struct TestStruct { static constexpr auto TypeName = "TestStruct"; static constexpr auto TypeVersion = 1; bool Bool = false; int32_t Int = 0; int32_t Int1 = 0; int32_t Int2 = 0; int32_t Int3 = 0; int32_t Int4 = 0; int32_t Int5 = 0; int32_t Int6 = 0; int32_t Int7 = 0; int32_t Int8 = 0; int unionIdx = 1; TestUnion Union; ox::IString<32> String = ""; uint32_t List[4] = {0, 0, 0, 0}; TestStructNest EmptyStruct; TestStructNest Struct; ~TestStruct() { if (unionIdx == 2) { ox::safeDelete(Union.String); } } }; template constexpr ox::Error model(T *io, ox::CommonPtrWith auto *obj) { oxReturnError(io->template setTypeInfo()); oxReturnError(io->field("Bool", &obj->Bool)); oxReturnError(io->field("Int", &obj->Int)); oxReturnError(io->fieldCString("String", &obj->String)); return OxError(0); } template constexpr ox::Error model(T *io, ox::CommonPtrWith auto *obj) { oxReturnError(io->template setTypeInfo()); oxReturnError(io->field("Bool", &obj->Bool)); oxReturnError(io->field("Int", &obj->Int)); oxReturnError(io->field("String", &obj->String)); return OxError(0); } template constexpr ox::Error model(T *io, ox::CommonPtrWith auto *obj) { oxReturnError(io->template setTypeInfo()); oxReturnError(io->field("Bool", &obj->Bool)); oxReturnError(io->field("Int", &obj->Int)); oxReturnError(io->field("Int1", &obj->Int1)); oxReturnError(io->field("Int2", &obj->Int2)); oxReturnError(io->field("Int3", &obj->Int3)); oxReturnError(io->field("Int4", &obj->Int4)); oxReturnError(io->field("Int5", &obj->Int5)); oxReturnError(io->field("Int6", &obj->Int6)); oxReturnError(io->field("Int7", &obj->Int7)); oxReturnError(io->field("Int8", &obj->Int8)); int unionIdx = 0; if constexpr(T::opType() != ox::OpType::Reflect) { unionIdx = obj->unionIdx; } oxReturnError(io->field("Union", ox::UnionView{&obj->Union, unionIdx})); oxReturnError(io->field("String", &obj->String)); oxReturnError(io->field("List", obj->List, 4)); oxReturnError(io->field("EmptyStruct", &obj->EmptyStruct)); oxReturnError(io->field("Struct", &obj->Struct)); return OxError(0); } static std::map tests = { { { "ClawHeaderReader", [] { constexpr auto hdr = ox::StringLiteral("O1;com.drinkingtea.ox.claw.test.Header;2;"); auto [ch, err] = ox::readClawHeader({hdr.c_str(), hdr.len() + 1}); oxAssert(err, "Error parsing header"); oxAssert(ch.fmt == ox::ClawFormat::Organic, "Format wrong"); oxAssert(ch.typeName == "com.drinkingtea.ox.claw.test.Header", "Type name wrong"); oxAssert(ch.typeVersion == 2, "Type version wrong"); return OxError(0); } }, { "ClawHeaderReader2", [] { constexpr auto hdr = ox::StringLiteral("M2;com.drinkingtea.ox.claw.test.Header2;3;"); auto [ch, err] = ox::readClawHeader({hdr.c_str(), hdr.len() + 1}); oxAssert(err, "Error parsing header"); oxAssert(ch.fmt == ox::ClawFormat::Metal, "Format wrong"); oxAssert(ch.typeName == "com.drinkingtea.ox.claw.test.Header2", "Type name wrong"); oxAssert(ch.typeVersion == 3, "Type version wrong"); return OxError(0); } }, { "ClawHeaderReadTypeId", [] { constexpr auto hdr = ox::StringLiteral("M2;com.drinkingtea.ox.claw.test.Header2;3;awefawf"); constexpr auto expected = ox::StringLiteral("com.drinkingtea.ox.claw.test.Header2;3"); oxRequire(actual, ox::readClawTypeId({hdr.data(), hdr.len() + 1})); oxExpect(actual, expected); return ox::Error{}; } }, { "ClawWriter", [] { // This test doesn't confirm much, but it does show that the writer // doesn't segfault TestStruct ts; oxReturnError(ox::writeClaw(ts, ox::ClawFormat::Metal)); return OxError(0); } }, { "ClawReader", [] { TestStruct testIn, testOut; testIn.Bool = true; testIn.Int = 42; testIn.Union.Int = 42; testIn.String = "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.String = "Test String 2"; const auto [buff, err] = ox::writeMC(testIn); oxAssert(err, "writeClaw failed"); oxAssert(ox::readMC(buff, testOut), "readClaw failed"); //std::cout << testIn.Union.Int << "|" << testOut.Union.Int << "|\n"; oxAssert(testIn.Bool == testOut.Bool, "Bool value mismatch"); oxAssert(testIn.Int == testOut.Int, "Int value mismatch"); oxAssert(testIn.Int1 == testOut.Int1, "Int1 value mismatch"); oxAssert(testIn.Int2 == testOut.Int2, "Int2 value mismatch"); oxAssert(testIn.Int3 == testOut.Int3, "Int3 value mismatch"); oxAssert(testIn.Int4 == testOut.Int4, "Int4 value mismatch"); oxAssert(testIn.Int5 == testOut.Int5, "Int5 value mismatch"); oxAssert(testIn.Int6 == testOut.Int6, "Int6 value mismatch"); oxAssert(testIn.Int7 == testOut.Int7, "Int7 value mismatch"); oxAssert(testIn.Int8 == testOut.Int8, "Int8 value mismatch"); oxAssert(testIn.Union.Int == testOut.Union.Int, "Union.Int value mismatch"); oxAssert(testIn.String == testOut.String, "String value mismatch"); oxAssert(testIn.List[0] == testOut.List[0], "List[0] value mismatch"); oxAssert(testIn.List[1] == testOut.List[1], "List[1] value mismatch"); oxAssert(testIn.List[2] == testOut.List[2], "List[2] value mismatch"); oxAssert(testIn.List[3] == testOut.List[3], "List[3] value mismatch"); oxAssert(testIn.EmptyStruct.Bool == testOut.EmptyStruct.Bool, "EmptyStruct.Bool value mismatch"); oxAssert(testIn.EmptyStruct.Int == testOut.EmptyStruct.Int, "EmptyStruct.Int value mismatch"); oxAssert(testIn.EmptyStruct.String == testOut.EmptyStruct.String, "EmptyStruct.String value mismatch"); oxAssert(testIn.Struct.Int == testOut.Struct.Int, "Struct.Int value mismatch"); oxAssert(testIn.Struct.String == testOut.Struct.String, "Struct.String value mismatch"); oxAssert(testIn.Struct.Bool == testOut.Struct.Bool, "Struct.Bool value mismatch"); return OxError(0); } }, } }; int main(int argc, const char **args) { if (argc < 2) { oxError("Must specify test to run"); } auto const testName = args[1]; auto const func = tests.find(testName); if (func != tests.end()) { oxAssert(func->second(), "Test returned Error"); return 0; } return -1; }