lumiera_documentation/tests/lib/multifact-singleton-test.cpp
Ichthyostega 3caa5cfb03 Tests: reorganise test folders
This resolves a long-standing issue:
we could not use proper include paths for test-helper code that was defined alongside the tests.

Since some test-helper code must now be relocated into the »Vault«-Layer,
I took the opportunity to finally resolve this annoyance. The solution is two-fold
 * introduce a dedicated test-support library
 * remove the quirks that were necessary to support some plain-C tests
Together, this allows to raise the include-directory by one level,
and then to adjust all folder names so that they match the namespace
2026-03-07 00:56:19 +01:00

134 lines
3.8 KiB
C++
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
MultiFactSingleton(Test) - using MultiFact to manage a family of singletons
Copyright (C)
2009, Hermann Vosseler <Ichthyostega@web.de>
  **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 "test/run.hpp"
#include "test/test-helper.hpp"
#include "lib/multifact.hpp"
#include "lib/format-cout.hpp"
#include "lib/util.hpp"
#include <boost/lexical_cast.hpp>
#include <string>
namespace lib {
namespace test{
using boost::lexical_cast;
using ::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<Interface&, theID> TestFactory;
template<theID ii>
class Implementation
: public Interface
{
operator string() const override
{
return "Impl-"+lexical_cast<string> (ii);
}
};
/** Factory instance for the tests... */
TestFactory theFact;
// Configure the products to be fabricated....
TestFactory::Singleton<Implementation<ONE>> holder1{theFact,ONE};
TestFactory::Singleton<Implementation<TWO>> holder2{theFact,TWO};
TestFactory::Singleton<Implementation<THR>> holder3{theFact,THR};
TestFactory::Singleton<Implementation<FOU>> 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<Implementation<ONE>> anotherSingletonHolder (anotherFact,ONE);
Interface & o3 = anotherFact(ONE);
CHECK (isSameObject(o2,o3));
}
};
/** Register this test class... */
LAUNCHER (MultiFactSingleton_test, "unit common");
}} // namespace lib::test