/* MultiFactSingleton(Test) - using MultiFact to manage a family of singletons Copyright (C) 2009, Hermann Vosseler   **Lumiera** 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. See the file COPYING for further details. * *****************************************************************/ /** @file multifact-singleton-test.cpp ** unit test \ref MultiFactSingleton_test */ #include "lib/test/run.hpp" #include "lib/test/test-helper.hpp" #include "lib/multifact.hpp" #include "lib/format-cout.hpp" #include "lib/util.hpp" #include #include namespace lib { namespace test{ using boost::lexical_cast; using lib::test::showSizeof; using util::isSameObject; using util::isnil; using std::ostream; using std::string; using LERR_(INVALID); namespace { // hierarchy of test dummy objects struct Interface { virtual ~Interface() {}; virtual operator string () const =0; }; enum theID { ONE = 1 , TWO , THR , FOU }; typedef factory::MultiFact TestFactory; template class Implementation : public Interface { operator string() const override { return "Impl-"+lexical_cast (ii); } }; /** Factory instance for the tests... */ TestFactory theFact; // Configure the products to be fabricated.... TestFactory::Singleton> holder1{theFact,ONE}; TestFactory::Singleton> holder2{theFact,TWO}; TestFactory::Singleton> holder3{theFact,THR}; TestFactory::Singleton> holder4{theFact,FOU}; } /******************************************************************//** * @test verify the use of the MultiFact template to access Singletons. * While generally speaking the MultiFact allows us to address * and invoke several "production lines" by ID, an obvious * use case would be to access a "family" of singletons * through this mechanism. And indeed, \c MultiFact::Singleton * is a preconfigured shortcut for this use case. The actual * singleton access factories are placed into a static context * (here in the anonymous namespace above) and their access * operation is wired as "factory function". * - we use a hierarchy of test dummy objects * - we set up a singleton factory for several subclasses * - the registration happens automatically in the ctor * - we verify that we indeed get the correct flavour. * * @see lib::MultiFact */ class MultiFactSingleton_test : public Test { void run (Arg) { cout << theFact(ONE) << endl; cout << theFact(TWO) << endl; cout << theFact(THR) << endl; cout << theFact(FOU) << endl; cout << showSizeof (theFact) << endl; Interface & o1 = theFact(ONE); Interface & o2 = theFact(ONE); CHECK (isSameObject(o1,o2)); TestFactory anotherFact; CHECK (isnil (anotherFact)); VERIFY_ERROR (INVALID, anotherFact(ONE) ); TestFactory::Singleton> anotherSingletonHolder (anotherFact,ONE); Interface & o3 = anotherFact(ONE); CHECK (isSameObject(o2,o3)); } }; /** Register this test class... */ LAUNCHER (MultiFactSingleton_test, "unit common"); }} // namespace lib::test