From 5269827c4f5ef6c07bef4719cff818b19ebde853 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 24 Sep 2023 13:28:09 +0100 Subject: Test coverage and fix error handling of invalid types --- slicer/slicer/common.ice | 5 +++++ slicer/slicer/modelPartsTypes.cpp | 6 ++++++ slicer/slicer/modelPartsTypes.h | 1 + slicer/slicer/modelPartsTypes.impl.h | 9 ++++---- slicer/slicer/slicer.cpp | 8 +++++++ slicer/test/initial/inherit-base.xml | 4 ++++ slicer/test/initial/inherit-nosuchtype.xml | 5 +++++ slicer/test/initial/inherit-same.xml | 4 ++++ slicer/test/initial/inherit-wronghier.xml | 5 +++++ slicer/test/serializers.cpp | 34 +++++++++++++++++++++++++++++- 10 files changed, 76 insertions(+), 5 deletions(-) create mode 100644 slicer/test/initial/inherit-base.xml create mode 100644 slicer/test/initial/inherit-nosuchtype.xml create mode 100644 slicer/test/initial/inherit-same.xml create mode 100644 slicer/test/initial/inherit-wronghier.xml diff --git a/slicer/slicer/common.ice b/slicer/slicer/common.ice index 60a4f92..ad3ff1f 100644 --- a/slicer/slicer/common.ice +++ b/slicer/slicer/common.ice @@ -29,6 +29,11 @@ module Slicer { string type; }; ["cpp:ice_print"] + exception IncorrectType extends DeserializerError { + string type; + string target; + }; + ["cpp:ice_print"] exception InvalidEnumerationValue extends SerializerError { int value; string type; diff --git a/slicer/slicer/modelPartsTypes.cpp b/slicer/slicer/modelPartsTypes.cpp index c57d987..ffaec04 100644 --- a/slicer/slicer/modelPartsTypes.cpp +++ b/slicer/slicer/modelPartsTypes.cpp @@ -74,6 +74,12 @@ namespace Slicer { return name; } + [[noreturn]] void + ModelPartForComplexBase::throwIncorrectType(const std::string & name, const std::type_info & target) + { + throw IncorrectType(name, demangle(target.name())); + } + #define Roots(Type, Name, NameLen) \ template<> CONSTSTR(NameLen) Slicer::ModelPartForRoot::rootName {#Name}; \ template<> \ diff --git a/slicer/slicer/modelPartsTypes.h b/slicer/slicer/modelPartsTypes.h index 6b6f852..f581c49 100644 --- a/slicer/slicer/modelPartsTypes.h +++ b/slicer/slicer/modelPartsTypes.h @@ -147,6 +147,7 @@ namespace Slicer { static const std::string & ToExchangeTypeName(const std::string &); static std::string_view ToModelTypeName(const std::string &); + [[noreturn]] static void throwIncorrectType(const std::string & name, const std::type_info & target); }; template class Hooks; diff --git a/slicer/slicer/modelPartsTypes.impl.h b/slicer/slicer/modelPartsTypes.impl.h index 3d1d2be..60f221d 100644 --- a/slicer/slicer/modelPartsTypes.impl.h +++ b/slicer/slicer/modelPartsTypes.impl.h @@ -448,12 +448,13 @@ namespace Slicer { ModelPartForClass::OnSubclass(const ModelPartHandler & h, const std::string & name) { BOOST_ASSERT(this->Model); - const ClassRefBase * refbase = ModelPartForComplexBase::getSubclassRef(name); - BOOST_ASSERT(refbase); - BOOST_ASSERT(dynamic_cast *>(refbase)); - if (auto ref = dynamic_cast *>(refbase)) { + if (const ClassRefBase * refbase = ModelPartForComplexBase::getSubclassRef(name); + auto ref = dynamic_cast *>(refbase)) [[likely]] { ref->onSubClass(*this->Model, h); } + else { + ModelPartForComplexBase::throwIncorrectType(name, typeid(T)); + } } template diff --git a/slicer/slicer/slicer.cpp b/slicer/slicer/slicer.cpp index ff9a948..5a253b0 100644 --- a/slicer/slicer/slicer.cpp +++ b/slicer/slicer/slicer.cpp @@ -13,6 +13,14 @@ namespace Slicer { InvalidEnumerationSymbolMsg::write(s, symbol, type); } + AdHocFormatter(IncorrectTypeMsg, "Type [%?] cannot be used as a [%?]"); + + void + IncorrectType::ice_print(std::ostream & s) const + { + IncorrectTypeMsg::write(s, type, target); + } + AdHocFormatter(InvalidEnumerationValueMsg, "Invalid enumeration symbol [%?] for type [%?]"); void diff --git a/slicer/test/initial/inherit-base.xml b/slicer/test/initial/inherit-base.xml new file mode 100644 index 0000000..45456e2 --- /dev/null +++ b/slicer/test/initial/inherit-base.xml @@ -0,0 +1,4 @@ + + + 3 + diff --git a/slicer/test/initial/inherit-nosuchtype.xml b/slicer/test/initial/inherit-nosuchtype.xml new file mode 100644 index 0000000..057bea5 --- /dev/null +++ b/slicer/test/initial/inherit-nosuchtype.xml @@ -0,0 +1,5 @@ + + + 3 + 3 + diff --git a/slicer/test/initial/inherit-same.xml b/slicer/test/initial/inherit-same.xml new file mode 100644 index 0000000..77a22ec --- /dev/null +++ b/slicer/test/initial/inherit-same.xml @@ -0,0 +1,4 @@ + + + 3 + diff --git a/slicer/test/initial/inherit-wronghier.xml b/slicer/test/initial/inherit-wronghier.xml new file mode 100644 index 0000000..d1ce693 --- /dev/null +++ b/slicer/test/initial/inherit-wronghier.xml @@ -0,0 +1,5 @@ + + + 3 + 3 + diff --git a/slicer/test/serializers.cpp b/slicer/test/serializers.cpp index 57779be..ae9a30e 100644 --- a/slicer/test/serializers.cpp +++ b/slicer/test/serializers.cpp @@ -1,4 +1,5 @@ #define BOOST_TEST_MODULE execute_serializers +#include #include #include "classes.h" @@ -36,7 +37,6 @@ #include #include #include -#include #include #include // IWYU pragma: no_forward_declare Slicer::InvalidEnumerationSymbol @@ -677,3 +677,35 @@ BOOST_AUTO_TEST_CASE(sequence_element_in_same_slice_link_bug) BOOST_CHECK_NO_THROW( Slicer::ModelPart::Make>(nullptr, [](auto &&) {})); } + +BOOST_AUTO_TEST_CASE(typeid_specifies_same) +{ + std::ifstream in {rootDir / "initial/inherit-same.xml"}; + auto d1 = Slicer::DeserializeAny(in); + BOOST_REQUIRE(d1); + BOOST_CHECK_EQUAL(d1->a, 3); + BOOST_CHECK_EQUAL(typeid(*d1).name(), typeid(TestModule::D1).name()); +} + +BOOST_DATA_TEST_CASE(typeid_specifies_bad, + boost::unit_test::data::make({ + "inherit-base.xml", + "inherit-wronghier.xml", + }), + path) +{ + std::ifstream in {rootDir / "initial" / path}; + BOOST_CHECK_THROW(std::ignore = (Slicer::DeserializeAny(in)), + Slicer::IncorrectType); +} + +BOOST_DATA_TEST_CASE(typeid_specifies_no_such_type, + boost::unit_test::data::make({ + "inherit-nosuchtype.xml", + }), + path) +{ + std::ifstream in {rootDir / "initial" / path}; + BOOST_CHECK_THROW(std::ignore = (Slicer::DeserializeAny(in)), + Slicer::UnknownType); +} -- cgit v1.2.3