From 0aaa010350799e7b764bf6609a7be734c226ccd6 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Wed, 20 Apr 2011 19:11:08 +0200 Subject: [PATCH] WIP draft how polymorphic value objects are expected to behave --- tests/lib/polymorphic-value-test.cpp | 208 +++++++++++++++++++++++++++ 1 file changed, 208 insertions(+) create mode 100644 tests/lib/polymorphic-value-test.cpp diff --git a/tests/lib/polymorphic-value-test.cpp b/tests/lib/polymorphic-value-test.cpp new file mode 100644 index 000000000..d56e2a122 --- /dev/null +++ b/tests/lib/polymorphic-value-test.cpp @@ -0,0 +1,208 @@ +/* + PolymorphicValue(Test) - verify handling of opaque polymorphic values + + Copyright (C) Lumiera.org + 2011, Hermann Vosseler + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +* *****************************************************/ + + + +#include "lib/test/run.hpp" +#include "lib/test/test-helper.hpp" +#include "lib/util.hpp" +#include "lib/util-foreach.hpp" + +#include "lib/opaque-holder.hpp" +//#include "lib/bool-checkable.hpp" + +#include +//#include +#include + + +namespace lib { +namespace test{ + + using ::Test; +// using util::isnil; + using util::for_each; + using util::isSameObject; +// using lumiera::error::LUMIERA_ERROR_INVALID; + using lumiera::error::LUMIERA_ERROR_ASSERTION; + + using std::vector; +// using std::cout; +// using std::endl; + + namespace { // test dummy hierarchy + // Note: largely varying space requirements + // correct function depending on concrete class + + + struct Interface + { + virtual ~Interface() {} + virtual long apiFunc() =0; + + virtual long& localSum() =0; + + bool + operator== (Interface const& o) + { + return localSum() == o.localSum(); + } + }; + + + const uint MAX_RAND = 1000; + const uint MAX_SIZ = sizeof(long[111]); + + long _checkSum = 0; + long _callSum = 0; + uint _created = 0; + + + template + struct Imp : Interface + { + long localData_[ii]; + + Imp() + { + REQUIRE (0 < ii); + localSum() = 0; + note(ii); + ++ _created; + } + + ~Imp() + { + note (-1 * localSum()); + CHECK (0 == localSum()); + } + + + long + apiFunc() + { + long rr = ii * (rand() % MAX_RAND); + note (rr); + _callSum += rr; + return rr; + } + + long& + localSum() + { + return localData[ii-1]; + } + + void + note (long markerValue) + { + localSum() += markerValue; + _checkSum += markerValue; + } + }; + + + /** maximum additional storage maybe wasted + * due to alignment of the contained object + * within the embedded Holder/Buffer + */ + const size_t _ALIGN_ = sizeof(size_t); + + } + + typedef PolymorphicValue PolyVal; + typedef vector TestList; + + + + /********************************************************************************** + * @test build a bunch of PolymorphicValue objects. Handle them like copyable + * value objects, without knowing the exact implementation type; moreover + * execute implementation internals only disclosed to the concrete subtype. + * Verify correctness through checksums. + */ + class PolymorphicValue_test : public Test + { + + virtual void + run (Arg) + { + _checkSum = 0; + _callSum = 0; + _created = 0; + + { + TestList objs = createOpaqueValues (); + for_each (objs, operate); + } + CHECK (0 == _checksum); // all dead + + verifyOverrunProtection(); + } + + + TestList + createOpaqueValues () + { + TestList list; + list.push_back (PolyVal::build > () ); + list.push_back (PolyVal::build > () ); + list.push_back (PolyVal::build >() ); + list.push_back (PolyVal::build > () ); + list.push_back (PolyVal::build > () ); + return list; + } //note: copy + + + static void + operate (PolyVal& elm) + { + PolyVal myLocalVal(elm); + CHECK (elm == myLocalVal); + + long prevSum = _callSum; + long randVal = myLocalVal.apiFunc(); + CHECK (prevSum + randVal == _callSum); + CHECK (elm != myLocalVal); + + elm = myLocalVal; + CHECK (elm == myLocalVal); + CHECK (!isSameObject (elm, myLocalVal)); + + CHECK (sizeof(myLocalVal) <= MAX_SIZ + _ALIGN_); + } + + + void + verifyOverrunProtection() + { +#if false ///////////////////////////////////////////////////////////////////////////////////////////////TICKET #537 : restore throwing ASSERT + VERIFY_ERROR (ASSERTION, PolyVal::build >() ); +#endif ///////////////////////////////////////////////////////////////////////////////////////////////TICKET #537 : restore throwing ASSERT + } + }; + + + LAUNCHER (PolymorphicValue_test, "unit common"); + + +}} // namespace lib::test