In the Lumiera code base, we use C-String constants as unique error-IDs. Basically this allows to create new unique error IDs anywhere in the code. However, definition of such IDs in arbitrary namespaces tends to create slight confusion and ambiguities, while maintaining the proper use statements requires some manual work. Thus I introduce a new **standard scheme** * Error-IDs for widespread use shall be defined _exclusively_ into `namespace lumiera::error` * The shorthand-Macro `LERR_()` can now be used to simplify inclusion and referral * (for local or single-usage errors, a local or even hidden definition is OK)
142 lines
4.4 KiB
C++
142 lines
4.4 KiB
C++
/*
|
|
MementoTie(Test) - check the mechanism for capturing and providing undo-state
|
|
|
|
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 memento-tie-test.cpp
|
|
** unit test \ref MementoTie_test
|
|
*/
|
|
|
|
|
|
#include "lib/test/run.hpp"
|
|
#include "lib/test/test-helper.hpp"
|
|
#include "steam/control/memento-tie.hpp"
|
|
|
|
#include <functional>
|
|
#include <cstdlib>
|
|
|
|
using std::function;
|
|
using std::bind;
|
|
using std::rand;
|
|
|
|
|
|
namespace steam {
|
|
namespace control {
|
|
namespace test {
|
|
|
|
namespace {
|
|
|
|
int testVal=0; ///< used to verify the effect of testFunc
|
|
|
|
void
|
|
undo (short param, int memento) ///< simulates "Undo" of the command operation
|
|
{
|
|
testVal += param-memento;
|
|
}
|
|
|
|
int
|
|
capture (short param) ///< simulates capturing the undo state
|
|
{
|
|
return testVal+param;
|
|
}
|
|
|
|
|
|
/** maximum additional storage maybe wasted due
|
|
* to alignment of the memento value within MementoTie
|
|
*/
|
|
const size_t ALIGNMENT = sizeof(size_t);
|
|
}
|
|
|
|
using LERR_(MISSING_MEMENTO);
|
|
|
|
|
|
|
|
/*************************************************************************************//**
|
|
* @test Verify the state capturing mechanism (memento), which is used to implement
|
|
* the Undo() functionality for Steam-Layer commands. Bind an undo function and a state
|
|
* capturing function and wire up both to store and retrieve a memento value.
|
|
* Verify that after closing the functions, actually state is captured by each invocation.
|
|
*
|
|
* @see control::Command
|
|
* @see control::CmdClosure
|
|
* @see control::UndoMutation
|
|
* @see command-mutation-test.hpp
|
|
*/
|
|
class MementoTie_test : public Test
|
|
{
|
|
|
|
virtual void
|
|
run (Arg)
|
|
{
|
|
checkStateCapturingMechanism();
|
|
}
|
|
|
|
|
|
/// assumed signature of the Command "Operation"
|
|
typedef void OpSIG(short);
|
|
typedef MementoTie<OpSIG,int> MemHolder;
|
|
|
|
|
|
void
|
|
checkStateCapturingMechanism ()
|
|
{
|
|
function<void(short,int)> undo_func = undo;
|
|
function< int(short)> cap_func = capture;
|
|
|
|
MemHolder mementoHolder (undo_func,cap_func);
|
|
|
|
CHECK (sizeof(MemHolder) <= sizeof(int) // storage for the memento
|
|
+ 2 * sizeof(function<void()>) // storage for the 2 undecorated functors
|
|
+ ALIGNMENT);
|
|
|
|
function<OpSIG> bound_undo_func = mementoHolder.tieUndoFunc();
|
|
function<OpSIG> bound_cap_func = mementoHolder.tieCaptureFunc();
|
|
|
|
VERIFY_ERROR (MISSING_MEMENTO, bound_undo_func(123) );
|
|
VERIFY_ERROR (MISSING_MEMENTO, mementoHolder.getState() );
|
|
|
|
short rr (rand() %100);
|
|
testVal = 0;
|
|
bound_cap_func(rr); // invoke state capturing
|
|
|
|
CHECK (rr == mementoHolder.getState());
|
|
|
|
testVal = 10; // meanwhile "somehow" mutate the state
|
|
bound_undo_func(0); // invoking the undo() feeds back the memento
|
|
CHECK (testVal == 10-rr);
|
|
|
|
// this cycle can be repeated with different state values
|
|
rr = (rand() %100);
|
|
testVal = rr;
|
|
bound_cap_func(5); // capture new state
|
|
CHECK (5+rr == mementoHolder.getState());
|
|
|
|
testVal = -20;
|
|
bound_undo_func(3*rr);
|
|
CHECK (testVal == -20 + 3*rr - (5+rr));
|
|
}
|
|
};
|
|
|
|
|
|
/** Register this test class... */
|
|
LAUNCHER (MementoTie_test, "unit controller");
|
|
|
|
|
|
}}} // namespace steam::control::test
|