source: src/Actions/unittests/ActionSequenceUnitTest.cpp@ 7a0456

Action_Thermostats Add_AtomRandomPerturbation Add_FitFragmentPartialChargesAction Add_RotateAroundBondAction Add_SelectAtomByNameAction Added_ParseSaveFragmentResults AddingActions_SaveParseParticleParameters Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_ParticleName_to_Atom Adding_StructOpt_integration_tests AtomFragments Automaking_mpqc_open AutomationFragmentation_failures Candidate_v1.5.4 Candidate_v1.6.0 Candidate_v1.6.1 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator CombiningParticlePotentialParsing Combining_Subpackages Debian_Package_split Debian_package_split_molecuildergui_only Disabling_MemDebug Docu_Python_wait EmpiricalPotential_contain_HomologyGraph EmpiricalPotential_contain_HomologyGraph_documentation Enable_parallel_make_install Enhance_userguide Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph FitPartialCharges_GlobalError Fix_BoundInBox_CenterInBox_MoleculeActions Fix_ChargeSampling_PBC Fix_ChronosMutex Fix_FitPartialCharges Fix_FitPotential_needs_atomicnumbers Fix_ForceAnnealing Fix_IndependentFragmentGrids Fix_ParseParticles Fix_ParseParticles_split_forward_backward_Actions Fix_PopActions Fix_QtFragmentList_sorted_selection Fix_Restrictedkeyset_FragmentMolecule Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns Fix_fitting_potentials Fixes ForceAnnealing_goodresults ForceAnnealing_oldresults ForceAnnealing_tocheck ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion FragmentAction_writes_AtomFragments FragmentMolecule_checks_bonddegrees GeometryObjects Gui_Fixes Gui_displays_atomic_force_velocity ImplicitCharges IndependentFragmentGrids IndependentFragmentGrids_IndividualZeroInstances IndependentFragmentGrids_IntegrationTest IndependentFragmentGrids_Sole_NN_Calculation JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix MoreRobust_FragmentAutomation ODR_violation_mpqc_open PartialCharges_OrthogonalSummation PdbParser_setsAtomName PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks Rewrite_FitPartialCharges RotateToPrincipalAxisSystem_UndoRedo SaturateAtoms_findBestMatching SaturateAtoms_singleDegree StoppableMakroAction Subpackage_CodePatterns Subpackage_JobMarket Subpackage_LinearAlgebra Subpackage_levmar Subpackage_mpqc_open Subpackage_vmg Switchable_LogView ThirdParty_MPQC_rebuilt_buildsystem TrajectoryDependenant_MaxOrder TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps TremoloParser_setsAtomName Ubuntu_1604_changes stable
Last change on this file since 7a0456 was a82f61, checked in by Frederik Heber <heber@…>, 10 years ago

Added Action::setOptionValue() which allows setting the option via a string.

  • this is preparatory for allowing the creation of MakroActions inside the code. We need to set the options without going through dialogs in some way or another and without being completely inside the Actions as is the case for the COMMAND variants and the python function calls.
  • Property mode set to 100644
File size: 9.4 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2010-2012 University of Bonn. All rights reserved.
5 * Copyright (C) 2013 Frederik Heber. All rights reserved.
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/>.
22 */
23
24/*
25 * ActionSequenceUnitTest.cpp
26 *
27 * Created on: Dec 17, 2009
28 * Author: crueger
29 */
30
31// include config.h
32#ifdef HAVE_CONFIG_H
33#include <config.h>
34#endif
35
36#include <cppunit/CompilerOutputter.h>
37#include <cppunit/extensions/TestFactoryRegistry.h>
38#include <cppunit/ui/text/TestRunner.h>
39
40#include "ActionSequenceUnitTest.hpp"
41#include "Actions/Action.hpp"
42#include "Actions/ActionQueue.hpp"
43#include "Actions/ActionSequence.hpp"
44#include "Actions/MakroAction.hpp"
45
46#include "stubs/DummyUI.hpp"
47
48using namespace MoleCuilder;
49
50#ifdef HAVE_TESTRUNNER
51#include "UnitTestMain.hpp"
52#endif /*HAVE_TESTRUNNER*/
53
54/********************************************** Test classes **************************************/
55
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:
63 canUndoActionStub(const ActionTrait &_trait):
64 Action(_trait){}
65 virtual ~canUndoActionStub(){}
66
67 virtual Dialog* fillDialog(Dialog *dialog){
68 ASSERT(dialog,"No Dialog given when filling action dialog");
69 return dialog;
70 }
71
72 virtual ActionState::ptr performCall(){
73 return Action::success;
74 }
75 virtual ActionState::ptr performUndo(ActionState::ptr){
76 return Action::success;
77 }
78 virtual ActionState::ptr performRedo(ActionState::ptr){
79 return Action::success;
80 }
81 virtual bool canUndo(){
82 return true;
83 }
84 virtual bool shouldUndo(){
85 return true;
86 }
87 Action* clone(enum QueryOptions flag = Interactive) const
88 {
89 return new canUndoActionStub(Traits);
90 }
91 void prepare(enum QueryOptions flag = Interactive)
92 {}
93 void outputAsCLI(std::ostream &ost) const
94 {}
95 void outputAsPython(std::ostream &ost, const std::string &prefix) const
96 {}
97 void setOptionValue(const std::string &_token, const std::string &_value)
98 {}
99};
100
101class cannotUndoActionStub : public Action
102{
103public:
104 cannotUndoActionStub(const ActionTrait &_trait) :
105 Action(_trait){}
106 virtual ~cannotUndoActionStub(){}
107
108 virtual Dialog* fillDialog(Dialog *dialog){
109 ASSERT(dialog,"No Dialog given when filling action dialog");
110 return dialog;
111 }
112
113 virtual ActionState::ptr performCall(){
114 return Action::success;
115 }
116 virtual ActionState::ptr performUndo(ActionState::ptr){
117 return Action::success;
118 }
119 virtual ActionState::ptr performRedo(ActionState::ptr){
120 return Action::success;
121 }
122 virtual bool canUndo(){
123 return false;
124 }
125 virtual bool shouldUndo(){
126 return true;
127 }
128 Action* clone(enum QueryOptions flag = Interactive) const
129 {
130 return new cannotUndoActionStub(Traits);
131 }
132 void prepare(enum QueryOptions flag = Interactive)
133 {}
134 void outputAsCLI(std::ostream &ost) const
135 {}
136 void outputAsPython(std::ostream &ost, const std::string &prefix) const
137 {}
138 void setOptionValue(const std::string &_token, const std::string &_value)
139 {}
140};
141
142class wasCalledActionStub : public Action
143{
144public:
145 wasCalledActionStub(const ActionTrait &_trait) :
146 Action(_trait),
147 called(false)
148 {}
149 virtual ~wasCalledActionStub(){}
150
151 virtual Dialog* fillDialog(Dialog *dialog){
152 return dialog;
153 }
154 virtual ActionState::ptr performCall(){
155 called = true;
156 return Action::success;
157 }
158 virtual ActionState::ptr performUndo(ActionState::ptr){
159 called = false;
160 return Action::success;
161 }
162 virtual ActionState::ptr performRedo(ActionState::ptr){
163 called = true;
164 return Action::success;
165 }
166 virtual bool canUndo(){
167 return true;
168 }
169 virtual bool shouldUndo(){
170 return true;
171 }
172 Action* clone(enum QueryOptions flag = Interactive) const
173 {
174 return new wasCalledActionStub(Traits);
175 }
176 void prepare(enum QueryOptions flag = Interactive)
177 {}
178 void outputAsCLI(std::ostream &ost) const
179 {}
180 void outputAsPython(std::ostream &ost, const std::string &prefix) const
181 {}
182 void setOptionValue(const std::string &_token, const std::string &_value)
183 {}
184 bool wasCalled(){
185 return called;
186 }
187private:
188 bool called;
189};
190
191void ActionSequenceTest::setUp(){
192 hasDescriptor = false;
193 // setup ActionHistory
194 ActionQueue::getInstance();
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");
201 // create some necessary stubs used in this test
202 ActionTrait canUndoTrait("canUndoActionStub");
203 ActionTrait cannotUndoTrait("cannotUndoActionStub");
204 positive1 = new canUndoActionStub(canUndoTrait);
205 positive2 = new canUndoActionStub(canUndoTrait);
206 negative1 = new cannotUndoActionStub(cannotUndoTrait);
207 negative2 = new cannotUndoActionStub(cannotUndoTrait);
208
209 ActionTrait wasCalledTrait("wasCalledActionStub");
210 shouldCall1 = new wasCalledActionStub(wasCalledTrait);
211 shouldCall2 = new wasCalledActionStub(wasCalledTrait);
212 shouldNotCall1 = new wasCalledActionStub(wasCalledTrait);
213 shouldNotCall2 = new wasCalledActionStub(wasCalledTrait);
214
215}
216
217void ActionSequenceTest::tearDown(){
218 delete positive1;
219 delete positive2;
220 delete negative1;
221 delete negative2;
222
223 delete shouldCall1;
224 delete shouldCall2;
225 delete shouldNotCall1;
226 delete shouldNotCall2;
227
228 ActionQueue::purgeInstance();
229 {
230 UIFactory::purgeInstance();
231 hasDescriptor = false;
232 }
233}
234
235void ActionSequenceTest::canUndoTest(){
236 // first section:
237 {
238 // test some combinations
239 {
240 ActionSequence *sequence = new ActionSequence();
241 sequence->addAction(positive1);
242 sequence->addAction(positive2);
243 CPPUNIT_ASSERT_EQUAL( true, sequence->canUndo() );
244 delete sequence;
245 }
246 {
247 ActionSequence *sequence = new ActionSequence();
248 sequence->addAction(positive1);
249 sequence->addAction(negative2);
250 CPPUNIT_ASSERT_EQUAL( false, sequence->canUndo() );
251 delete sequence;
252 }
253 {
254 ActionSequence *sequence = new ActionSequence();
255 sequence->addAction(negative1);
256 sequence->addAction(positive2);
257 CPPUNIT_ASSERT_EQUAL( false, sequence->canUndo() );
258 delete sequence;
259 }
260 {
261 ActionSequence *sequence = new ActionSequence();
262 sequence->addAction(negative1);
263 sequence->addAction(negative2);
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
275 sequence->addAction(positive1);
276 CPPUNIT_ASSERT_EQUAL( true, sequence->canUndo() );
277 // the single negative action should block the process
278 sequence->addAction(negative1);
279 CPPUNIT_ASSERT_EQUAL( false, sequence->canUndo() );
280 // after removing the negative action all is well again
281 sequence->removeLastAction();
282 CPPUNIT_ASSERT_EQUAL( true, sequence->canUndo() );
283 delete sequence;
284 }
285}
286
287void ActionSequenceTest::doesCallTest(){
288 ActionSequence *sequence = new ActionSequence();
289 sequence->addAction(shouldCall1);
290 sequence->addAction(shouldCall2);
291 sequence->addAction(shouldNotCall1);
292 sequence->addAction(shouldNotCall2);
293 sequence->removeLastAction();
294 sequence->removeLastAction();
295
296 sequence->callAll();
297
298 CPPUNIT_ASSERT_EQUAL(true,shouldCall1->wasCalled());
299 CPPUNIT_ASSERT_EQUAL(true,shouldCall2->wasCalled());
300 CPPUNIT_ASSERT_EQUAL(false,shouldNotCall1->wasCalled());
301 CPPUNIT_ASSERT_EQUAL(false,shouldNotCall2->wasCalled());
302
303 delete sequence;
304}
305
306void ActionSequenceTest::doesUndoTest(){
307 ActionSequence *sequence = new ActionSequence();
308 ActionTrait wasCalledTrait("wasCalledActionStub");
309 sequence->addAction(new wasCalledActionStub(wasCalledTrait));
310 sequence->addAction(new wasCalledActionStub(wasCalledTrait));
311
312 ActionTrait MakroTrait("Test MakroAction");
313 MakroAction act(MakroTrait,*sequence);
314// wasCalledActionStub *wasCalled1 =
315// static_cast<wasCalledActionStub *>(act.actions.actions.front());
316// wasCalledActionStub *wasCalled2 =
317// static_cast<wasCalledActionStub *>(act.actions.actions.back());
318
319 act.call();
320
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());
325
326 ActionQueue::getInstance().undoLast();
327
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());
332
333 delete sequence;
334}
335
336
Note: See TracBrowser for help on using the repository browser.