LUMIERA.clone/tests/core/proc/mobject/session/query-resolver-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

227 lines
5.9 KiB
C++

/*
QueryResolver(Test) - issuing typed queries over a generic interface
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 query-resolver-test.cpp
** unit test §§TODO§§
*/
#include "lib/test/run.hpp"
#include "lib/test/test-helper.hpp"
#include "lib/format-cout.hpp"
#include "lib/depend.hpp"
#include "common/query/query-resolver.hpp"
#include <string>
namespace lumiera {
namespace test{
using lib::test::showSizeof;
using std::string;
namespace { // providing a test query resolving facility...
typedef Goal::QueryID const& QID;
/** an sequence of "solutions" to be "found" */
template<typename TY>
class DummySolutions;
template<>
class DummySolutions<int>
{
int resNr_;
public:
DummySolutions() : resNr_(7) {}
int* next () { --resNr_; return &resNr_; }
bool exhausted() { return !bool(resNr_); }
};
template<>
class DummySolutions<string>
: public DummySolutions<int>
{
string currentText_;
public:
string*
next ()
{
static const char* lumi ="Lumiera";
currentText_ = string (lumi + *DummySolutions<int>::next());
return &currentText_;
}
};
/**
* a concrete "resolution" of the query
* is a set of "solutions", which can be
* explored by iteration. Thus, the result set
* has to implement the iteration control API
* as required by IterAdapter
*/
template<typename TY>
struct DummyResultSet
: Resolution
{
DummySolutions<TY> solutions_;
typedef typename Query<TY>::Cursor Cursor;
Result
prepareResolution()
{
Cursor cursor;
cursor.point_at (solutions_.next());
return cursor;
}
void
nextResult(Result& pos)
{
Cursor& cursor = static_cast<Cursor&> (pos);
if (solutions_.exhausted())
cursor.point_at (0);
else
cursor.point_at (solutions_.next());
}
};
/**
* a (dummy) concrete query resolution facility.
* It is hard-wired to accept queries on int and string,
* generating a sequence of results for both cases
*/
class DummyTypedSolutionProducer
: public QueryResolver
{
bool
canHandleQuery (QID qID) const
{
return Goal::GENERIC == qID.kind
&& (wantResultType<int> (qID)
||wantResultType<string>(qID));
}
template<typename TY>
bool
wantResultType (QID qID) const
{
return qID.type == getResultTypeID<TY>();
}
template<typename TY>
static Resolution*
resolutionFunction (Goal const& goal)
{
QID qID = goal.getQID();
REQUIRE (qID.kind == Goal::GENERIC
&& qID.type == getResultTypeID<TY>());
return new DummyResultSet<TY>();
}
operator string() const { return "Test-DummyQueryResolver"; }
public:
DummyTypedSolutionProducer()
: QueryResolver()
{
Goal::QueryID case1(Goal::GENERIC, getResultTypeID<int>());
Goal::QueryID case2(Goal::GENERIC, getResultTypeID<string>());
installResolutionCase(case1, &resolutionFunction<int> );
installResolutionCase(case2, &resolutionFunction<string> );
}
};
lib::Depend<DummyTypedSolutionProducer> testResolver;
QueryResolver&
buildTestQueryResolver ()
{
return testResolver();
}
} // (END) implementation of a test query resolving facility
/*******************************************************************************//**
* @test verify the mechanism for issuing typed queries through a generic interface,
* without disclosing the facility actually answering those queries.
* Results are to be retrieved through a Lumiera Forward Iterator.
*
* @see mobject::session::QueryResolver
* @see mobject::session::ScopeLocate usage example
* @see mobject::session::ContentsQuery typed query example
* @see contents-query-test.cpp
*/
class QueryResolver_test : public Test
{
virtual void
run (Arg)
{
QueryResolver& resolver = buildTestQueryResolver();
Query<int> firstQuery("");
explore (firstQuery.resolveBy (resolver));
Query<string> secondQuery("");
explore (secondQuery.resolveBy(resolver));
}
template<typename ITER>
static void
explore (ITER ii)
{
cout << "Query-Results: " << showSizeof(ii) << endl;
for ( ; ii; ++ii )
cout << *ii << endl;
}
};
/** Register this test class... */
LAUNCHER (QueryResolver_test, "unit session");
}} // namespace lumiera::test