source: src/Actions/unittests/ActionSequenceUnitTest.cpp@ 5e17bf

Action_Thermostats Add_AtomRandomPerturbation Add_RotateAroundBondAction Add_SelectAtomByNameAction Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_StructOpt_integration_tests AutomationFragmentation_failures Candidate_v1.6.1 ChangeBugEmailaddress ChemicalSpaceEvaluator Docu_Python_wait EmpiricalPotential_contain_HomologyGraph_documentation Enhance_userguide Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns ForceAnnealing_oldresults ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion Gui_displays_atomic_force_velocity IndependentFragmentGrids_IntegrationTest JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks RotateToPrincipalAxisSystem_UndoRedo StoppableMakroAction TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps
Last change on this file since 5e17bf was 10aee4, checked in by Frederik Heber <heber@…>, 9 years ago

Cleaned up ActionQueue's interface: Actions are always cloned.

  • Action's dstor needs to be public as we have a clone() function.
  • ActionRegistrys' (and AQ's) getActionByName now returns const ref. We must not return a ptr as it may not get deleted elsewhere. We are handing out prototypes.
  • queueAction(action*,...) is private to prevent leakage, queueAction(string, ...) is the public interface.
  • some other small functions are now private, too.
  • MakroActions now need to clone() the prototype on prepare() and delete them on unprepare().
  • ActionSequence deletes contained actions.
  • FIX: ActionSequenceUnitTest cannot check on not-called property of removed actions anymore as these are gone now (they are deleted on removal and they are cloned on insertion).
  • DOCU: Updated documentation on Actions.
  • Property mode set to 100644
File size: 9.6 KB
RevLine 
[bcf653]1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
[0aa122]4 * Copyright (C) 2010-2012 University of Bonn. All rights reserved.
[5aaa43]5 * Copyright (C) 2013 Frederik Heber. All rights reserved.
[94d5ac6]6 *
7 *
8 * This file is part of MoleCuilder.
9 *
10 * MoleCuilder is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation, either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * MoleCuilder is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with MoleCuilder. If not, see <http://www.gnu.org/licenses/>.
[bcf653]22 */
23
[147339]24/*
[f7c0c4]25 * ActionSequenceUnitTest.cpp
[147339]26 *
27 * Created on: Dec 17, 2009
28 * Author: crueger
29 */
30
[bf3817]31// include config.h
32#ifdef HAVE_CONFIG_H
33#include <config.h>
34#endif
35
[147339]36#include <cppunit/CompilerOutputter.h>
37#include <cppunit/extensions/TestFactoryRegistry.h>
38#include <cppunit/ui/text/TestRunner.h>
39
[f7c0c4]40#include "ActionSequenceUnitTest.hpp"
[147339]41#include "Actions/Action.hpp"
[628577]42#include "Actions/ActionQueue.hpp"
[147339]43#include "Actions/ActionSequence.hpp"
[2efa90]44#include "Actions/MakroAction.hpp"
[147339]45
[fdcd1b]46#include "stubs/DummyUI.hpp"
[112f90]47
[ce7fdc]48using namespace MoleCuilder;
49
[9b6b2f]50#ifdef HAVE_TESTRUNNER
51#include "UnitTestMain.hpp"
52#endif /*HAVE_TESTRUNNER*/
53
54/********************************************** Test classes **************************************/
55
[147339]56// Registers the fixture into the 'registry'
57CPPUNIT_TEST_SUITE_REGISTRATION( ActionSequenceTest );
58
59/* some neccessary stubs for tests */
60class canUndoActionStub : public Action
61{
62public:
[3139b2]63 canUndoActionStub(const ActionTrait &_trait):
[126867]64 Action(_trait){}
[147339]65 virtual ~canUndoActionStub(){}
66
[047878]67 virtual Dialog* fillDialog(Dialog *dialog){
68 ASSERT(dialog,"No Dialog given when filling action dialog");
69 return dialog;
[80951de]70 }
71
[b5b01e]72 virtual ActionState::ptr performCall(){
[67e2b3]73 return Action::success;
74 }
[b5b01e]75 virtual ActionState::ptr performUndo(ActionState::ptr){
[67e2b3]76 return Action::success;
77 }
[b5b01e]78 virtual ActionState::ptr performRedo(ActionState::ptr){
[67e2b3]79 return Action::success;
80 }
[147339]81 virtual bool canUndo(){
82 return true;
83 }
[67e2b3]84 virtual bool shouldUndo(){
85 return true;
86 }
[af5384]87 Action* clone(enum QueryOptions flag = Interactive) const
88 {
89 return new canUndoActionStub(Traits);
90 }
91 void prepare(enum QueryOptions flag = Interactive)
92 {}
[46b181]93 void outputAsCLI(std::ostream &ost) const
94 {}
[477012]95 void outputAsPython(std::ostream &ost, const std::string &prefix) const
96 {}
[a82f61]97 void setOptionValue(const std::string &_token, const std::string &_value)
98 {}
[147339]99};
100
101class cannotUndoActionStub : public Action
102{
103public:
[3139b2]104 cannotUndoActionStub(const ActionTrait &_trait) :
[126867]105 Action(_trait){}
[147339]106 virtual ~cannotUndoActionStub(){}
107
[047878]108 virtual Dialog* fillDialog(Dialog *dialog){
109 ASSERT(dialog,"No Dialog given when filling action dialog");
110 return dialog;
[80951de]111 }
112
[b5b01e]113 virtual ActionState::ptr performCall(){
[67e2b3]114 return Action::success;
115 }
[b5b01e]116 virtual ActionState::ptr performUndo(ActionState::ptr){
[67e2b3]117 return Action::success;
118 }
[b5b01e]119 virtual ActionState::ptr performRedo(ActionState::ptr){
[67e2b3]120 return Action::success;
121 }
[147339]122 virtual bool canUndo(){
123 return false;
124 }
[67e2b3]125 virtual bool shouldUndo(){
126 return true;
127 }
[af5384]128 Action* clone(enum QueryOptions flag = Interactive) const
129 {
130 return new cannotUndoActionStub(Traits);
131 }
132 void prepare(enum QueryOptions flag = Interactive)
133 {}
[46b181]134 void outputAsCLI(std::ostream &ost) const
135 {}
[477012]136 void outputAsPython(std::ostream &ost, const std::string &prefix) const
137 {}
[a82f61]138 void setOptionValue(const std::string &_token, const std::string &_value)
139 {}
[147339]140};
141
[0229f9]142class wasCalledActionStub : public Action
143{
144public:
[3139b2]145 wasCalledActionStub(const ActionTrait &_trait) :
[126867]146 Action(_trait),
[0229f9]147 called(false)
148 {}
149 virtual ~wasCalledActionStub(){}
[147339]150
[047878]151 virtual Dialog* fillDialog(Dialog *dialog){
152 return dialog;
[80951de]153 }
[b5b01e]154 virtual ActionState::ptr performCall(){
[0229f9]155 called = true;
[67e2b3]156 return Action::success;
[0229f9]157 }
[b5b01e]158 virtual ActionState::ptr performUndo(ActionState::ptr){
[0229f9]159 called = false;
[67e2b3]160 return Action::success;
161 }
[b5b01e]162 virtual ActionState::ptr performRedo(ActionState::ptr){
[67e2b3]163 called = true;
164 return Action::success;
[0229f9]165 }
166 virtual bool canUndo(){
167 return true;
168 }
[67e2b3]169 virtual bool shouldUndo(){
170 return true;
171 }
[af5384]172 Action* clone(enum QueryOptions flag = Interactive) const
173 {
174 return new wasCalledActionStub(Traits);
175 }
176 void prepare(enum QueryOptions flag = Interactive)
177 {}
[46b181]178 void outputAsCLI(std::ostream &ost) const
179 {}
[477012]180 void outputAsPython(std::ostream &ost, const std::string &prefix) const
181 {}
[a82f61]182 void setOptionValue(const std::string &_token, const std::string &_value)
183 {}
[0229f9]184 bool wasCalled(){
185 return called;
186 }
187private:
188 bool called;
189};
[147339]190
[0229f9]191void ActionSequenceTest::setUp(){
[694d84]192 hasDescriptor = false;
[6367dd]193 // setup ActionHistory
194 ActionQueue::getInstance();
[112f90]195 // TODO: find a way to really reset the factory to a clean state in tear-down
196 if(!hasDescriptor){
197 UIFactory::registerFactory(new DummyUIFactory::description());
198 hasDescriptor = true;
199 }
200 UIFactory::makeUserInterface("Dummy");
[147339]201 // create some necessary stubs used in this test
[3139b2]202 ActionTrait canUndoTrait("canUndoActionStub");
203 ActionTrait cannotUndoTrait("cannotUndoActionStub");
[e4afb4]204 positive1 = new canUndoActionStub(canUndoTrait);
205 positive2 = new canUndoActionStub(canUndoTrait);
206 negative1 = new cannotUndoActionStub(cannotUndoTrait);
207 negative2 = new cannotUndoActionStub(cannotUndoTrait);
208
[3139b2]209 ActionTrait wasCalledTrait("wasCalledActionStub");
[e4afb4]210 shouldCall1 = new wasCalledActionStub(wasCalledTrait);
211 shouldCall2 = new wasCalledActionStub(wasCalledTrait);
212 shouldNotCall1 = new wasCalledActionStub(wasCalledTrait);
213 shouldNotCall2 = new wasCalledActionStub(wasCalledTrait);
[0229f9]214
215}
216
217void ActionSequenceTest::tearDown(){
218 delete positive1;
219 delete positive2;
220 delete negative1;
221 delete negative2;
[147339]222
[0229f9]223 delete shouldCall1;
224 delete shouldCall2;
225 delete shouldNotCall1;
226 delete shouldNotCall2;
227
[628577]228 ActionQueue::purgeInstance();
[694d84]229 {
230 UIFactory::purgeInstance();
231 hasDescriptor = false;
232 }
[0229f9]233}
234
235void ActionSequenceTest::canUndoTest(){
[147339]236 // first section:
237 {
238 // test some combinations
239 {
240 ActionSequence *sequence = new ActionSequence();
[10aee4]241 sequence->addAction(positive1->clone());
242 sequence->addAction(positive2->clone());
[147339]243 CPPUNIT_ASSERT_EQUAL( true, sequence->canUndo() );
244 delete sequence;
245 }
246 {
247 ActionSequence *sequence = new ActionSequence();
[10aee4]248 sequence->addAction(positive1->clone());
249 sequence->addAction(negative2->clone());
[147339]250 CPPUNIT_ASSERT_EQUAL( false, sequence->canUndo() );
251 delete sequence;
252 }
253 {
254 ActionSequence *sequence = new ActionSequence();
[10aee4]255 sequence->addAction(negative1->clone());
256 sequence->addAction(positive2->clone());
[147339]257 CPPUNIT_ASSERT_EQUAL( false, sequence->canUndo() );
258 delete sequence;
259 }
260 {
261 ActionSequence *sequence = new ActionSequence();
[10aee4]262 sequence->addAction(negative1->clone());
263 sequence->addAction(negative2->clone());
[147339]264 CPPUNIT_ASSERT_EQUAL( false, sequence->canUndo() );
265 delete sequence;
266 }
267 }
268
269 // second section:
270 {
271 // empty sequence can be undone
272 ActionSequence *sequence = new ActionSequence();
273 CPPUNIT_ASSERT_EQUAL( true, sequence->canUndo() );
274 // if only a positive action is contained it can be undone
[10aee4]275 sequence->addAction(positive1->clone());
[147339]276 CPPUNIT_ASSERT_EQUAL( true, sequence->canUndo() );
277 // the single negative action should block the process
[10aee4]278 sequence->addAction(negative1->clone());
[147339]279 CPPUNIT_ASSERT_EQUAL( false, sequence->canUndo() );
280 // after removing the negative action all is well again
[10aee4]281 delete sequence->removeLastAction();
[147339]282 CPPUNIT_ASSERT_EQUAL( true, sequence->canUndo() );
283 delete sequence;
284 }
[0229f9]285}
[147339]286
[0229f9]287void ActionSequenceTest::doesCallTest(){
288 ActionSequence *sequence = new ActionSequence();
[10aee4]289 sequence->addAction(shouldCall1->clone());
290 sequence->addAction(shouldCall2->clone());
291 sequence->addAction(shouldNotCall1->clone());
292 sequence->addAction(shouldNotCall2->clone());
293 delete sequence->removeLastAction();
294 delete sequence->removeLastAction();
[0229f9]295
296 sequence->callAll();
297
[10aee4]298 ActionSequence::actionSet::const_iterator iter = sequence->actions.begin();
299 CPPUNIT_ASSERT_EQUAL(true,dynamic_cast<wasCalledActionStub *>(*iter++)->wasCalled());
300 CPPUNIT_ASSERT_EQUAL(true,dynamic_cast<wasCalledActionStub *>(*iter++)->wasCalled());
301 CPPUNIT_ASSERT( iter == sequence->actions.end() );
[0229f9]302
[f59d81]303 delete sequence;
[0229f9]304}
305
306void ActionSequenceTest::doesUndoTest(){
307 ActionSequence *sequence = new ActionSequence();
[3139b2]308 ActionTrait wasCalledTrait("wasCalledActionStub");
[c1d837]309 sequence->addAction(new wasCalledActionStub(wasCalledTrait));
310 sequence->addAction(new wasCalledActionStub(wasCalledTrait));
[0229f9]311
[3139b2]312 ActionTrait MakroTrait("Test MakroAction");
[126867]313 MakroAction act(MakroTrait,*sequence);
[a58c16]314// wasCalledActionStub *wasCalled1 =
315// static_cast<wasCalledActionStub *>(act.actions.actions.front());
316// wasCalledActionStub *wasCalled2 =
317// static_cast<wasCalledActionStub *>(act.actions.actions.back());
[0229f9]318
[2efa90]319 act.call();
[0229f9]320
[c17aa8]321 CPPUNIT_ASSERT_EQUAL(true,
322 static_cast<wasCalledActionStub *>(act.actions.actions.front())->wasCalled());
323 CPPUNIT_ASSERT_EQUAL(true,
324 static_cast<wasCalledActionStub *>(act.actions.actions.back())->wasCalled());
[0229f9]325
[6367dd]326 ActionQueue::getInstance().undoLast();
[2efa90]327
[c17aa8]328 CPPUNIT_ASSERT_EQUAL(false,
329 static_cast<wasCalledActionStub *>(act.actions.actions.front())->wasCalled());
330 CPPUNIT_ASSERT_EQUAL(false,
331 static_cast<wasCalledActionStub *>(act.actions.actions.back())->wasCalled());
[147339]332
[22b786]333 delete sequence;
[147339]334}
335
336
Note: See TracBrowser for help on using the repository browser.