2009-07-23 03:47:57 +02:00
|
|
|
/*
|
2009-07-24 05:24:39 +02:00
|
|
|
CommandUse1(Test) - usage aspects I
|
2009-07-23 03:47:57 +02:00
|
|
|
|
|
|
|
|
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.
|
|
|
|
|
|
|
|
|
|
* *****************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "lib/test/run.hpp"
|
2009-07-24 05:24:39 +02:00
|
|
|
#include "lib/test/test-helper.hpp"
|
2009-07-23 03:47:57 +02:00
|
|
|
//#include "proc/asset/media.hpp"
|
|
|
|
|
//#include "proc/mobject/session.hpp"
|
|
|
|
|
//#include "proc/mobject/session/edl.hpp"
|
|
|
|
|
//#include "proc/mobject/session/testclip.hpp"
|
|
|
|
|
//#include "proc/mobject/test-dummy-mobject.hpp"
|
|
|
|
|
//#include "lib/p.hpp"
|
|
|
|
|
//#include "proc/mobject/placement.hpp"
|
|
|
|
|
//#include "proc/mobject/placement-index.hpp"
|
|
|
|
|
//#include "proc/mobject/explicitplacement.hpp"
|
2009-07-25 19:21:50 +02:00
|
|
|
#include "proc/control/command.hpp"
|
2009-07-23 03:47:57 +02:00
|
|
|
#include "proc/control/command-def.hpp"
|
|
|
|
|
//#include "lib/lumitime.hpp"
|
|
|
|
|
#include "lib/util.hpp"
|
|
|
|
|
|
|
|
|
|
#include "proc/control/test-dummy-commands.hpp"
|
|
|
|
|
|
|
|
|
|
//#include <boost/format.hpp>
|
|
|
|
|
//#include <iostream>
|
|
|
|
|
//#include <cstdlib>
|
|
|
|
|
//#include <string>
|
|
|
|
|
|
|
|
|
|
//using boost::format;
|
|
|
|
|
//using lumiera::Time;
|
|
|
|
|
//using util::contains;
|
|
|
|
|
//using std::string;
|
|
|
|
|
//using std::rand;
|
|
|
|
|
//using std::cout;
|
|
|
|
|
//using std::endl;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace control {
|
|
|
|
|
namespace test {
|
|
|
|
|
|
|
|
|
|
// using lib::test::showSizeof;
|
|
|
|
|
using util::isSameObject;
|
2009-08-01 17:14:27 +02:00
|
|
|
using util::contains;
|
2009-07-23 03:47:57 +02:00
|
|
|
|
|
|
|
|
// using session::test::TestClip;
|
|
|
|
|
// using lumiera::P;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//using lumiera::typelist::BuildTupleAccessor;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/***************************************************************************
|
2009-07-24 05:24:39 +02:00
|
|
|
* @test command usage aspects I: defining commands in various ways,
|
|
|
|
|
* then re-accessing those definitions, create instances,
|
|
|
|
|
* invoke them and undo the effect. Clean up finally.
|
2009-07-23 03:47:57 +02:00
|
|
|
*
|
2009-07-24 05:24:39 +02:00
|
|
|
* @see Command
|
|
|
|
|
* @see command-basic-test.cpp (simple usage example)
|
2009-07-23 03:47:57 +02:00
|
|
|
*/
|
|
|
|
|
class CommandUse1_test : public Test
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
int randVal;
|
2009-07-24 05:24:39 +02:00
|
|
|
int random() { return randVal = 10 + (rand() % 40); }
|
2009-07-23 03:47:57 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
virtual void
|
|
|
|
|
run (Arg)
|
|
|
|
|
{
|
2009-07-24 17:50:14 +02:00
|
|
|
command1::check_ = 0;
|
2009-07-24 05:24:39 +02:00
|
|
|
uint cnt_defs = Command::definition_count();
|
|
|
|
|
uint cnt_inst = Command::instance_count();
|
|
|
|
|
|
2009-07-23 03:47:57 +02:00
|
|
|
allInOneStep();
|
2009-07-24 05:24:39 +02:00
|
|
|
standardUse();
|
2009-07-23 03:47:57 +02:00
|
|
|
definePrototype();
|
|
|
|
|
usePrototype();
|
2009-08-01 17:14:27 +02:00
|
|
|
preventDuplicates();
|
2009-07-24 05:24:39 +02:00
|
|
|
undef();
|
2009-07-23 03:47:57 +02:00
|
|
|
|
2009-07-24 05:24:39 +02:00
|
|
|
ASSERT (0 == command1::check_);
|
|
|
|
|
ASSERT (cnt_defs == Command::definition_count());
|
|
|
|
|
ASSERT (cnt_inst == Command::instance_count());
|
2009-07-23 03:47:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
allInOneStep()
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
CommandDef ("test.command1.1")
|
|
|
|
|
.operation (command1::operate)
|
|
|
|
|
.captureUndo (command1::capture)
|
|
|
|
|
.undoOperation (command1::undoIt)
|
2009-07-24 05:24:39 +02:00
|
|
|
.bind (random())
|
|
|
|
|
.execSync()
|
2009-07-23 03:47:57 +02:00
|
|
|
;
|
|
|
|
|
|
2009-07-24 17:50:14 +02:00
|
|
|
ASSERT (randVal == command1::check_);
|
2009-07-23 03:47:57 +02:00
|
|
|
|
|
|
|
|
Command::get("test.command1.1").undo();
|
2009-07-24 05:24:39 +02:00
|
|
|
ASSERT ( 0 == command1::check_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
standardUse()
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
CommandDef ("test.command1.2")
|
|
|
|
|
.operation (command1::operate)
|
|
|
|
|
.captureUndo (command1::capture)
|
|
|
|
|
.undoOperation (command1::undoIt)
|
|
|
|
|
;
|
|
|
|
|
}
|
|
|
|
|
ASSERT ( CommandDef("test.command1.2"));
|
|
|
|
|
ASSERT (!Command::get("test.command1.2"));
|
|
|
|
|
|
|
|
|
|
Command com = Command::get("test.command1.2");
|
2009-08-01 17:14:27 +02:00
|
|
|
ASSERT (contains (str(com), "test.command1.2"));
|
|
|
|
|
ASSERT (contains (str(com), "{def}"));
|
|
|
|
|
ASSERT (!com); ////////////////////TODO: mismatch: shall bool() < canExec() ????
|
2009-07-24 05:24:39 +02:00
|
|
|
ASSERT (!com.canUndo());
|
|
|
|
|
VERIFY_ERROR (UNBOUND_ARGUMENTS, com() );
|
|
|
|
|
|
|
|
|
|
ASSERT ( 0 == command1::check_);
|
|
|
|
|
VERIFY_ERROR (INVALID_ARGUMENTS, com.bind ("foo") );
|
|
|
|
|
com.bind (random()); // note: run-time type check only
|
|
|
|
|
com();
|
|
|
|
|
ASSERT (randVal == command1::check_);
|
|
|
|
|
com.undo();
|
|
|
|
|
ASSERT ( 0 == command1::check_);
|
|
|
|
|
|
|
|
|
|
// the following shortcut does the same:
|
|
|
|
|
Command::invoke ("test.command1.2", 1234);
|
|
|
|
|
ASSERT ( 1234 == command1::check_);
|
|
|
|
|
|
|
|
|
|
// another shortcut, with static type check:
|
|
|
|
|
invoke (command1::operate, 5678);
|
|
|
|
|
ASSERT ( 1234+5678 == command1::check_);
|
|
|
|
|
|
|
|
|
|
com.undo();
|
|
|
|
|
ASSERT ( 0 == command1::check_);
|
2009-07-23 03:47:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
definePrototype()
|
|
|
|
|
{
|
2009-07-24 05:24:39 +02:00
|
|
|
CommandDef ("test.command1.3")
|
2009-07-23 03:47:57 +02:00
|
|
|
.operation (command1::operate)
|
|
|
|
|
.captureUndo (command1::capture)
|
|
|
|
|
.undoOperation (command1::undoIt)
|
2009-07-24 05:24:39 +02:00
|
|
|
.bind (random())
|
2009-07-23 03:47:57 +02:00
|
|
|
;
|
|
|
|
|
|
|
|
|
|
|
2009-07-24 05:24:39 +02:00
|
|
|
ASSERT (Command::get("test.command1.3").canExec());
|
2009-07-23 03:47:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
usePrototype()
|
|
|
|
|
{
|
2009-07-24 05:24:39 +02:00
|
|
|
Command c1 = Command::get("test.command1.3");
|
2009-07-23 03:47:57 +02:00
|
|
|
ASSERT (c1);
|
|
|
|
|
ASSERT (c1.canExec());
|
|
|
|
|
ASSERT (!c1.canUndo());
|
|
|
|
|
|
2009-07-24 05:24:39 +02:00
|
|
|
Command c2 = Command::get("test.command1.3");
|
2009-07-23 03:47:57 +02:00
|
|
|
ASSERT (c1);
|
|
|
|
|
ASSERT (c1.canExec());
|
|
|
|
|
ASSERT (!c1.canUndo());
|
|
|
|
|
|
|
|
|
|
ASSERT (c1 == c2);
|
|
|
|
|
ASSERT (!isSameObject(c1, c2));
|
|
|
|
|
|
2009-07-24 05:24:39 +02:00
|
|
|
ASSERT (0 == command1::check_);
|
2009-07-23 03:47:57 +02:00
|
|
|
|
|
|
|
|
c1();
|
|
|
|
|
|
2009-07-24 05:24:39 +02:00
|
|
|
ASSERT (randVal == command1::check_);
|
2009-07-23 03:47:57 +02:00
|
|
|
ASSERT (c1.canUndo());
|
|
|
|
|
ASSERT (c1 != c2);
|
|
|
|
|
ASSERT (!c2.canUndo());
|
|
|
|
|
|
|
|
|
|
c2();
|
2009-07-24 05:24:39 +02:00
|
|
|
ASSERT (randVal + randVal == command1::check_);
|
2009-07-23 03:47:57 +02:00
|
|
|
ASSERT (c2.canUndo());
|
|
|
|
|
ASSERT (c1 != c2);
|
|
|
|
|
|
|
|
|
|
c1.undo();
|
2009-07-24 05:24:39 +02:00
|
|
|
ASSERT (0 == command1::check_);
|
2009-07-23 03:47:57 +02:00
|
|
|
c2.undo();
|
2009-07-24 05:24:39 +02:00
|
|
|
ASSERT (randVal == command1::check_);
|
2009-07-23 03:47:57 +02:00
|
|
|
|
|
|
|
|
c2.bind(23);
|
|
|
|
|
c2();
|
2009-07-24 05:24:39 +02:00
|
|
|
ASSERT (randVal + 23 == command1::check_);
|
2009-07-23 03:47:57 +02:00
|
|
|
|
|
|
|
|
// you should not use a command more than once (but it works...)
|
|
|
|
|
c1();
|
2009-07-24 05:24:39 +02:00
|
|
|
ASSERT (randVal + 23 + randVal == command1::check_);
|
2009-07-23 03:47:57 +02:00
|
|
|
c1.undo();
|
2009-07-24 05:24:39 +02:00
|
|
|
ASSERT (randVal + 23 == command1::check_);
|
2009-07-23 03:47:57 +02:00
|
|
|
// note we've overwritten the previous undo state
|
|
|
|
|
// and get the sate captured on the second invocation
|
|
|
|
|
|
2009-07-25 19:21:50 +02:00
|
|
|
c2.undo();
|
2009-07-24 05:24:39 +02:00
|
|
|
ASSERT (randVal == command1::check_);
|
2009-07-23 03:47:57 +02:00
|
|
|
c1.undo();
|
2009-07-24 05:24:39 +02:00
|
|
|
ASSERT (randVal + 23 == command1::check_);
|
|
|
|
|
|
|
|
|
|
// use the current sate of c2 as Prototype for new command definition
|
|
|
|
|
c2.storeDef ("test.command1.4");
|
|
|
|
|
Command c3 = Command::get("test.command1.4");
|
|
|
|
|
ASSERT (c3);
|
|
|
|
|
ASSERT (!c3.canUndo());
|
|
|
|
|
c3();
|
|
|
|
|
ASSERT (randVal + 2*23 == command1::check_);
|
|
|
|
|
|
|
|
|
|
c3.bind(-command1::check_);
|
|
|
|
|
c3();
|
|
|
|
|
ASSERT (0 == command1::check_);
|
|
|
|
|
c2();
|
|
|
|
|
ASSERT (23 == command1::check_);
|
|
|
|
|
c2.undo();
|
|
|
|
|
ASSERT (0 == command1::check_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2009-08-01 17:14:27 +02:00
|
|
|
void
|
|
|
|
|
preventDuplicates()
|
|
|
|
|
{
|
|
|
|
|
ASSERT (CommandDef ("test.command1.1"));
|
|
|
|
|
VERIFY_ERROR (DUPLICATE_COMMAND, CommandDef ("test.command1.1").operation (command1::operate) );
|
|
|
|
|
ASSERT (CommandDef ("test.command1.2"));
|
|
|
|
|
VERIFY_ERROR (DUPLICATE_COMMAND, CommandDef ("test.command1.2").operation (command1::operate) );
|
|
|
|
|
ASSERT (CommandDef ("test.command1.3"));
|
|
|
|
|
VERIFY_ERROR (DUPLICATE_COMMAND, CommandDef ("test.command1.3").operation (command1::operate) );
|
|
|
|
|
ASSERT (CommandDef ("test.command1.4"));
|
|
|
|
|
VERIFY_ERROR (DUPLICATE_COMMAND, CommandDef ("test.command1.4").operation (command1::operate) );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2009-07-24 05:24:39 +02:00
|
|
|
void
|
|
|
|
|
undef()
|
|
|
|
|
{
|
2009-07-24 17:50:14 +02:00
|
|
|
ASSERT (CommandDef ("test.command1.1"));
|
|
|
|
|
ASSERT (CommandDef ("test.command1.2"));
|
|
|
|
|
ASSERT (CommandDef ("test.command1.3"));
|
|
|
|
|
ASSERT (CommandDef ("test.command1.4"));
|
2009-07-24 05:24:39 +02:00
|
|
|
|
|
|
|
|
ASSERT (Command::get("test.command1.1"));
|
|
|
|
|
ASSERT (Command::get("test.command1.2"));
|
|
|
|
|
ASSERT (Command::get("test.command1.3"));
|
|
|
|
|
ASSERT (Command::get("test.command1.4"));
|
|
|
|
|
|
|
|
|
|
VERIFY_ERROR (INVALID_COMMAND, Command::get("miracle"));
|
|
|
|
|
|
|
|
|
|
CommandDef unbelievable ("miracle");
|
|
|
|
|
ASSERT (!unbelievable);
|
|
|
|
|
|
2009-08-01 17:14:27 +02:00
|
|
|
Command miracle;
|
2009-07-24 05:24:39 +02:00
|
|
|
// but because the miracle isn't yet defined, any use throws
|
2009-08-01 17:14:27 +02:00
|
|
|
VERIFY_ERROR (INVALID_COMMAND, miracle.bind("abracadabra"));
|
|
|
|
|
VERIFY_ERROR (INVALID_COMMAND, miracle.execSync());
|
|
|
|
|
VERIFY_ERROR (INVALID_COMMAND, miracle.undo());
|
|
|
|
|
VERIFY_ERROR (INVALID_COMMAND, miracle());
|
|
|
|
|
ASSERT (!miracle.canExec());
|
|
|
|
|
ASSERT (!miracle.canUndo());
|
|
|
|
|
ASSERT (!miracle);
|
2009-07-24 05:24:39 +02:00
|
|
|
|
|
|
|
|
ASSERT (Command::remove("test.command1.1"));
|
|
|
|
|
ASSERT (Command::remove("test.command1.2"));
|
|
|
|
|
ASSERT (Command::remove("test.command1.3"));
|
|
|
|
|
|
|
|
|
|
ASSERT (!Command::remove("miracle")); // there is no such thing...
|
|
|
|
|
|
|
|
|
|
// note, we didn't remove the *definitions*
|
|
|
|
|
// thus we're free to create new instances...
|
|
|
|
|
Command xxx = Command::get("test.command1.1");
|
|
|
|
|
VERIFY_ERROR (UNBOUND_ARGUMENTS, xxx() );
|
|
|
|
|
|
|
|
|
|
// but this one is still there (we didn't remove it)
|
|
|
|
|
ASSERT (Command::get("test.command1.4"));
|
|
|
|
|
|
|
|
|
|
// now kill the definitions too...
|
|
|
|
|
ASSERT (Command::undef ("test.command1.1"));
|
|
|
|
|
ASSERT (Command::undef ("test.command1.2"));
|
|
|
|
|
ASSERT (Command::undef ("test.command1.3"));
|
|
|
|
|
ASSERT (Command::undef ("test.command1.4"));
|
|
|
|
|
ASSERT (Command::undef ("miracle"));
|
|
|
|
|
|
|
|
|
|
VERIFY_ERROR (INVALID_COMMAND, Command::get("test.command1.1"));
|
|
|
|
|
VERIFY_ERROR (INVALID_COMMAND, Command::get("test.command1.2"));
|
|
|
|
|
VERIFY_ERROR (INVALID_COMMAND, Command::get("test.command1.3"));
|
|
|
|
|
VERIFY_ERROR (INVALID_COMMAND, Command::get("miracle"));
|
|
|
|
|
|
|
|
|
|
// note: removing the definition automatically killed the remaining instance:
|
|
|
|
|
VERIFY_ERROR (INVALID_COMMAND, Command::get("test.command1.4"));
|
2009-07-23 03:47:57 +02:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** Register this test class... */
|
|
|
|
|
LAUNCHER (CommandUse1_test, "function controller");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}} // namespace control::test
|