/* * Project: MoleCuilder * Description: creates and alters molecular systems * Copyright (C) 2010 University of Bonn. All rights reserved. * Please see the LICENSE file or "Copyright notice" in builder.cpp for details. */ /* * ActionSequenceUnitTest.cpp * * Created on: Dec 17, 2009 * Author: crueger */ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include "ActionSequenceUnitTest.hpp" #include "Actions/Action.hpp" #include "Actions/ActionSequence.hpp" #include "Actions/MakroAction.hpp" #include "Actions/ActionHistory.hpp" #include "Actions/ActionRegistry.hpp" #include "unittests/DummyUI.hpp" #ifdef HAVE_TESTRUNNER #include "UnitTestMain.hpp" #endif /*HAVE_TESTRUNNER*/ /********************************************** Test classes **************************************/ // Registers the fixture into the 'registry' CPPUNIT_TEST_SUITE_REGISTRATION( ActionSequenceTest ); /* some neccessary stubs for tests */ class canUndoActionStub : public Action { public: canUndoActionStub(const ActionTraits &_trait): Action(_trait,false){} virtual ~canUndoActionStub(){} virtual void getParametersfromValueStorage(){ } virtual Dialog* fillDialog(Dialog *dialog){ ASSERT(dialog,"No Dialog given when filling action dialog"); return dialog; } virtual Action::state_ptr performCall(){ return Action::success; } virtual Action::state_ptr performUndo(Action::state_ptr){ return Action::success; } virtual Action::state_ptr performRedo(Action::state_ptr){ return Action::success; } virtual bool canUndo(){ return true; } virtual bool shouldUndo(){ return true; } }; class cannotUndoActionStub : public Action { public: cannotUndoActionStub(const ActionTraits &_trait) : Action(_trait,false){} virtual ~cannotUndoActionStub(){} virtual void getParametersfromValueStorage(){ } virtual Dialog* fillDialog(Dialog *dialog){ ASSERT(dialog,"No Dialog given when filling action dialog"); return dialog; } virtual Action::state_ptr performCall(){ return Action::success; } virtual Action::state_ptr performUndo(Action::state_ptr){ return Action::success; } virtual Action::state_ptr performRedo(Action::state_ptr){ return Action::success; } virtual bool canUndo(){ return false; } virtual bool shouldUndo(){ return true; } }; class wasCalledActionStub : public Action { public: wasCalledActionStub(const ActionTraits &_trait) : Action(_trait,false), called(false) {} virtual ~wasCalledActionStub(){} virtual void getParametersfromValueStorage(){ } virtual Dialog* fillDialog(Dialog *dialog){ return dialog; } virtual Action::state_ptr performCall(){ called = true; return Action::success; } virtual Action::state_ptr performUndo(Action::state_ptr){ called = false; return Action::success; } virtual Action::state_ptr performRedo(Action::state_ptr){ called = true; return Action::success; } virtual bool canUndo(){ return true; } virtual bool shouldUndo(){ return true; } bool wasCalled(){ return called; } private: bool called; }; void ActionSequenceTest::setUp(){ hasDescriptor = false; ActionHistory::init(); // TODO: find a way to really reset the factory to a clean state in tear-down if(!hasDescriptor){ UIFactory::registerFactory(new DummyUIFactory::description()); hasDescriptor = true; } UIFactory::makeUserInterface("Dummy"); // create some necessary stubs used in this test ActionTraits canUndoTrait("canUndoActionStub"); ActionTraits cannotUndoTrait("cannotUndoActionStub"); positive1 = new canUndoActionStub(canUndoTrait); positive2 = new canUndoActionStub(canUndoTrait); negative1 = new cannotUndoActionStub(cannotUndoTrait); negative2 = new cannotUndoActionStub(cannotUndoTrait); ActionTraits wasCalledTrait("wasCalledActionStub"); shouldCall1 = new wasCalledActionStub(wasCalledTrait); shouldCall2 = new wasCalledActionStub(wasCalledTrait); shouldNotCall1 = new wasCalledActionStub(wasCalledTrait); shouldNotCall2 = new wasCalledActionStub(wasCalledTrait); } void ActionSequenceTest::tearDown(){ delete positive1; delete positive2; delete negative1; delete negative2; delete shouldCall1; delete shouldCall2; delete shouldNotCall1; delete shouldNotCall2; ActionHistory::purgeInstance(); ActionRegistry::purgeInstance(); { UIFactory::purgeInstance(); hasDescriptor = false; } } void ActionSequenceTest::canUndoTest(){ // first section: { // test some combinations { ActionSequence *sequence = new ActionSequence(); sequence->addAction(positive1); sequence->addAction(positive2); CPPUNIT_ASSERT_EQUAL( true, sequence->canUndo() ); delete sequence; } { ActionSequence *sequence = new ActionSequence(); sequence->addAction(positive1); sequence->addAction(negative2); CPPUNIT_ASSERT_EQUAL( false, sequence->canUndo() ); delete sequence; } { ActionSequence *sequence = new ActionSequence(); sequence->addAction(negative1); sequence->addAction(positive2); CPPUNIT_ASSERT_EQUAL( false, sequence->canUndo() ); delete sequence; } { ActionSequence *sequence = new ActionSequence(); sequence->addAction(negative1); sequence->addAction(negative2); CPPUNIT_ASSERT_EQUAL( false, sequence->canUndo() ); delete sequence; } } // second section: { // empty sequence can be undone ActionSequence *sequence = new ActionSequence(); CPPUNIT_ASSERT_EQUAL( true, sequence->canUndo() ); // if only a positive action is contained it can be undone sequence->addAction(positive1); CPPUNIT_ASSERT_EQUAL( true, sequence->canUndo() ); // the single negative action should block the process sequence->addAction(negative1); CPPUNIT_ASSERT_EQUAL( false, sequence->canUndo() ); // after removing the negative action all is well again sequence->removeLastAction(); CPPUNIT_ASSERT_EQUAL( true, sequence->canUndo() ); delete sequence; } } void ActionSequenceTest::doesCallTest(){ ActionSequence *sequence = new ActionSequence(); sequence->addAction(shouldCall1); sequence->addAction(shouldCall2); sequence->addAction(shouldNotCall1); sequence->addAction(shouldNotCall2); sequence->removeLastAction(); sequence->removeLastAction(); sequence->callAll(); CPPUNIT_ASSERT_EQUAL(true,shouldCall1->wasCalled()); CPPUNIT_ASSERT_EQUAL(true,shouldCall2->wasCalled()); CPPUNIT_ASSERT_EQUAL(false,shouldNotCall1->wasCalled()); CPPUNIT_ASSERT_EQUAL(false,shouldNotCall2->wasCalled()); delete sequence; } void ActionSequenceTest::doesUndoTest(){ ActionSequence *sequence = new ActionSequence(); ActionTraits wasCalledTrait("wasCalledActionStub"); wasCalledActionStub *wasCalled1 = new wasCalledActionStub(wasCalledTrait); wasCalledActionStub *wasCalled2 = new wasCalledActionStub(wasCalledTrait); sequence->addAction(wasCalled1); sequence->addAction(wasCalled2); ActionTraits MakroTrait("Test MakroAction"); MakroAction act(MakroTrait,sequence,false); act.call(); CPPUNIT_ASSERT_EQUAL(true,wasCalled1->wasCalled()); CPPUNIT_ASSERT_EQUAL(true,wasCalled2->wasCalled()); ActionHistory::getInstance().undoLast(); CPPUNIT_ASSERT_EQUAL(false,wasCalled1->wasCalled()); CPPUNIT_ASSERT_EQUAL(false,wasCalled2->wasCalled()); }