LUMIERA.clone/tests/library/multifact-argument-test.cpp
Ichthyostega 24b3bec4be Doxygen: prepare all unit tests for inclusion in the documentation
Doxygen will only process files with a @file documentation comment.
Up to now, none of our test code has such a comment, preventing the
cross-links to unit tests from working.

This is unfortunate, since unit tests, and even the code comments there,
can be considered as the most useful form of technical documentation.
Thus I'll start an initiative to fill in those missing comments automatically
2017-02-22 01:54:20 +01:00

126 lines
3.9 KiB
C++

/*
MultiFactArgument(Test) - passing additional invocation arguments to registered factory functions
Copyright (C) Lumiera.org
2009, Hermann Vosseler <Ichthyostega@web.de>
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.
* *****************************************************/
/** @file multifact-argument-test.cpp
** unit test §§TODO§§
*/
#include "lib/test/run.hpp"
#include "lib/test/test-helper.hpp"
#include "lib/format-cout.hpp"
#include "lib/multifact.hpp"
#include <functional>
namespace lib {
namespace test{
using std::bind;
using std::function;
using std::placeholders::_1;
using lib::test::showSizeof;
namespace { // dummy fabrication function, creating wrapped numbers, controlled by an additional argument
enum prodID
{ ONE = 1
, TWO
};
struct Num { int n_; };
/** dummy "factory" function to be invoked
* @return pointer to heap allocated product object
* @note this function needs to deliver the product in a form
* which can be accepted by the concrete wrapper, which
* is going to be configured into the factory.
*/
Num*
fabricateNumberz (int base, int offset)
{
cout << "fabricate("<<base<<", "<<offset<<")" << endl;
Num* product = new Num;
product->n_ = base*offset;
return product;
}
/** the factory instantiation used for this test */
typedef factory::MultiFact< Num(int) // nominal signature of fabrication
, prodID // select factory function by prodID
, factory::BuildRefcountPtr // wrapper: manage product by smart-ptr
> TestFactory;
// for reference: type of an equivalent dispatcher table...
typedef std::map<prodID, function<Num(int)> > DispatcherMap;
}
/***************************************************************//**
* @test define a MultiFact (factory with dynamic registration),
* which accepts additional arguments and passes them
* through to the registered factory function(s).
* @note we set up fabrication functions by binding the functions
* in such a way as to match the function signature declared
* in the factory; thereby one argument remains unclosed,
* which is the argument to be supplied on each
* factory invocation by the client code.
*
* @see lib::MultiFact
* @see query-resolver.cpp
*/
class MultiFactArgument_test : public Test
{
void
run (Arg)
{
TestFactory theFact;
theFact.defineProduction (ONE, bind (&fabricateNumberz, 1, _1 ));
theFact.defineProduction (TWO, bind (&fabricateNumberz, 2, _1 ));
cout << showSizeof (theFact) << endl;
CHECK (sizeof(theFact) == sizeof(DispatcherMap));
typedef TestFactory::Product PP;
PP p1 = theFact(ONE, 2);
PP p2 = theFact(TWO, 3);
CHECK (1*2 == p1->n_);
CHECK (2*3 == p2->n_);
}
};
/** Register this test class... */
LAUNCHER (MultiFactArgument_test, "unit common");
}} // namespace lib::test