source: src/unittests/ObserverTest.cpp@ a7b761b

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 a7b761b was a7b761b, checked in by Tillmann Crueger <crueger@…>, 15 years ago

Merge branch 'MoleculeStartEndSwitch' into StructureRefactoring

Conflicts:

molecuilder/src/Helpers/Assert.cpp
molecuilder/src/Helpers/Assert.hpp
molecuilder/src/Legacy/oldmenu.cpp
molecuilder/src/Makefile.am
molecuilder/src/Patterns/Cacheable.hpp
molecuilder/src/Patterns/Observer.cpp
molecuilder/src/Patterns/Observer.hpp
molecuilder/src/analysis_correlation.cpp
molecuilder/src/boundary.cpp
molecuilder/src/builder.cpp
molecuilder/src/config.cpp
molecuilder/src/helpers.hpp
molecuilder/src/molecule.cpp
molecuilder/src/molecule.hpp
molecuilder/src/molecule_dynamics.cpp
molecuilder/src/molecule_fragmentation.cpp
molecuilder/src/molecule_geometry.cpp
molecuilder/src/molecule_graph.cpp
molecuilder/src/moleculelist.cpp
molecuilder/src/tesselation.cpp
molecuilder/src/unittests/AnalysisCorrelationToSurfaceUnitTest.cpp
molecuilder/src/unittests/ObserverTest.cpp
molecuilder/src/unittests/ObserverTest.hpp

  • Property mode set to 100644
File size: 9.9 KB
Line 
1/*
2 * ObserverTest.cpp
3 *
4 * Created on: Jan 19, 2010
5 * Author: crueger
6 */
7
8#include "ObserverTest.hpp"
9
10#include <cppunit/CompilerOutputter.h>
11#include <cppunit/extensions/TestFactoryRegistry.h>
12#include <cppunit/ui/text/TestRunner.h>
13#include <set>
14
15#include "Patterns/Observer.hpp"
16#include "Patterns/ObservedIterator.hpp"
17#include "Helpers/Assert.hpp"
18
19#include <iostream>
20
21using namespace std;
22
23#ifdef HAVE_TESTRUNNER
24#include "UnitTestMain.hpp"
25#endif /*HAVE_TESTRUNNER*/
26
27// Registers the fixture into the 'registry'
28CPPUNIT_TEST_SUITE_REGISTRATION( ObserverTest );
29
30/******************* Test stubs ************************/
31
32class UpdateCountObserver : public Observer {
33public:
34 UpdateCountObserver() :
35 updates(0)
36 {};
37 void update(Observable *publisher){
38 updates++;
39 }
40 void subjectKilled(Observable *publisher) {
41 }
42 int updates;
43};
44
45class SimpleObservable : public Observable {
46public:
47 void changeMethod() {
48 OBSERVE;
49 int i = 0;
50 i++;
51 }
52};
53
54class CallObservable : public Observable {
55public:
56 void changeMethod1() {
57 OBSERVE;
58 int i = 0;
59 i++;
60 }
61
62 void changeMethod2() {
63 OBSERVE;
64 int i = 0;
65 i++;
66 changeMethod1();
67 }
68};
69
70class BlockObservable : public Observable {
71public:
72 void changeMethod1(){
73 OBSERVE;
74 // test if we report correctly as blocked
75 CPPUNIT_ASSERT(isBlocked());
76 }
77
78 void changeMethod2(){
79 OBSERVE;
80 internalMethod1();
81 internalMethod2();
82 }
83
84 void internalMethod1(){
85 // we did not block, but our caller did...
86 // see if this is found
87 CPPUNIT_ASSERT(isBlocked());
88 }
89
90 void internalMethod2(){
91 OBSERVE;
92 // Both this method and the caller do block
93 // Does the reporting still work as expected?
94 CPPUNIT_ASSERT(isBlocked());
95 }
96
97 void noChangeMethod(){
98 // No Block introduced here
99 // reported correctely?
100 CPPUNIT_ASSERT(!isBlocked());
101 }
102};
103
104class SuperObservable : public Observable {
105public:
106 SuperObservable(){
107 subObservable = new SimpleObservable();
108 subObservable->signOn(this);
109 }
110 ~SuperObservable(){
111 delete subObservable;
112 }
113 void changeMethod() {
114 OBSERVE;
115 int i = 0;
116 i++;
117 subObservable->changeMethod();
118 }
119 SimpleObservable *subObservable;
120};
121
122class NotificationObservable : public Observable {
123public:
124 NotificationObservable() :
125 notification1(new Notification(this)),
126 notification2(new Notification(this))
127 {}
128
129 ~NotificationObservable(){
130 delete notification1;
131 delete notification2;
132 }
133
134 void operation1(){
135 OBSERVE;
136 NOTIFY(notification1);
137 }
138
139 void operation2(){
140 OBSERVE;
141 NOTIFY(notification2);
142 }
143
144 Notification_ptr notification1;
145 Notification_ptr notification2;
146};
147
148class NotificationObserver : public Observer {
149public:
150 NotificationObserver(Notification_ptr notification) :
151 requestedNotification(notification),
152 wasNotified(false)
153 {}
154
155 void update(Observable*){}
156 void subjectKilled(Observable*){}
157 void recieveNotification(Observable *publisher, Notification_ptr notification){
158 ASSERT(requestedNotification==notification,"Notification received that was not requested");
159 wasNotified = true;
160 }
161
162 Notification_ptr requestedNotification;
163
164 bool wasNotified;
165};
166
167class ObservableCollection : public Observable {
168public:
169 typedef std::set<SimpleObservable*> set;
170 typedef ObservedIterator<set> iterator;
171 typedef set::const_iterator const_iterator;
172
173 ObservableCollection(int _num) :
174 num(_num)
175 {
176 for(int i=0; i<num; ++i){
177 SimpleObservable *content = new SimpleObservable();
178 content->signOn(this);
179 theSet.insert(content);
180 }
181 }
182
183 ~ObservableCollection(){
184 set::iterator iter;
185 for(iter=theSet.begin(); iter!=theSet.end(); ++iter ){
186 delete (*iter);
187 }
188 }
189
190 iterator begin(){
191 return iterator(theSet.begin(),this);
192 }
193
194 iterator end(){
195 return iterator(theSet.end(),this);
196 }
197
198 const int num;
199
200private:
201 set theSet;
202};
203
204
205/******************* actuall tests ***************/
206
207void ObserverTest::setUp() {
208 ASSERT_DO(Assert::Throw);
209 simpleObservable1 = new SimpleObservable();
210 simpleObservable2 = new SimpleObservable();
211 callObservable = new CallObservable();
212 superObservable = new SuperObservable();
213 blockObservable = new BlockObservable();
214 notificationObservable = new NotificationObservable();
215 collection = new ObservableCollection(5);
216
217 observer1 = new UpdateCountObserver();
218 observer2 = new UpdateCountObserver();
219 observer3 = new UpdateCountObserver();
220 observer4 = new UpdateCountObserver();
221
222 notificationObserver1 = new NotificationObserver(notificationObservable->notification1);
223 notificationObserver2 = new NotificationObserver(notificationObservable->notification2);
224}
225
226void ObserverTest::tearDown() {
227 delete simpleObservable1;
228 delete simpleObservable2;
229 delete callObservable;
230 delete superObservable;
231 delete blockObservable;
232 delete notificationObservable;
233 delete collection;
234
235 delete observer1;
236 delete observer2;
237 delete observer3;
238 delete observer4;
239 delete notificationObserver1;
240 delete notificationObserver2;
241}
242
243void ObserverTest::doesUpdateTest()
244{
245 simpleObservable1->signOn(observer1);
246 simpleObservable1->signOn(observer2);
247 simpleObservable1->signOn(observer3);
248
249 simpleObservable2->signOn(observer2);
250 simpleObservable2->signOn(observer4);
251
252 simpleObservable1->changeMethod();
253 CPPUNIT_ASSERT_EQUAL( 1, observer1->updates );
254 CPPUNIT_ASSERT_EQUAL( 1, observer2->updates );
255 CPPUNIT_ASSERT_EQUAL( 1, observer3->updates );
256 CPPUNIT_ASSERT_EQUAL( 0, observer4->updates );
257
258 simpleObservable1->signOff(observer3);
259
260 simpleObservable1->changeMethod();
261 CPPUNIT_ASSERT_EQUAL( 2, observer1->updates );
262 CPPUNIT_ASSERT_EQUAL( 2, observer2->updates );
263 CPPUNIT_ASSERT_EQUAL( 1, observer3->updates );
264 CPPUNIT_ASSERT_EQUAL( 0, observer4->updates );
265
266 simpleObservable2->changeMethod();
267 CPPUNIT_ASSERT_EQUAL( 2, observer1->updates );
268 CPPUNIT_ASSERT_EQUAL( 3, observer2->updates );
269 CPPUNIT_ASSERT_EQUAL( 1, observer3->updates );
270 CPPUNIT_ASSERT_EQUAL( 1, observer4->updates );
271}
272
273
274void ObserverTest::doesBlockUpdateTest() {
275 callObservable->signOn(observer1);
276
277 callObservable->changeMethod1();
278 CPPUNIT_ASSERT_EQUAL( 1, observer1->updates );
279
280 callObservable->changeMethod2();
281 CPPUNIT_ASSERT_EQUAL( 2, observer1->updates );
282}
283
284void ObserverTest::doesSubObservableTest() {
285 superObservable->signOn(observer1);
286 superObservable->subObservable->signOn(observer2);
287
288 superObservable->subObservable->changeMethod();
289 CPPUNIT_ASSERT_EQUAL( 1, observer1->updates );
290 CPPUNIT_ASSERT_EQUAL( 1, observer2->updates );
291
292 superObservable->changeMethod();
293 CPPUNIT_ASSERT_EQUAL( 2, observer1->updates );
294 CPPUNIT_ASSERT_EQUAL( 2, observer2->updates );
295}
296
297void ObserverTest::doesNotifyTest(){
298 notificationObservable->signOn(notificationObserver1,
299 notificationObservable->notification1);
300 notificationObservable->signOn(notificationObserver2,
301 notificationObservable->notification2);
302
303 notificationObservable->operation1();
304 CPPUNIT_ASSERT(notificationObserver1->wasNotified);
305 CPPUNIT_ASSERT(!notificationObserver2->wasNotified);
306
307 notificationObserver1->wasNotified=false;
308
309 notificationObservable->operation2();
310 CPPUNIT_ASSERT(!notificationObserver1->wasNotified);
311 CPPUNIT_ASSERT(notificationObserver2->wasNotified);
312
313}
314
315void ObserverTest::doesReportTest(){
316 // Actual checks are in the Stub-methods for this
317 blockObservable->changeMethod1();
318 blockObservable->changeMethod2();
319 blockObservable->noChangeMethod();
320}
321
322void ObserverTest::iteratorTest(){
323 int i = 0;
324 // test the general iterator methods
325 for(ObservableCollection::iterator iter=collection->begin(); iter!=collection->end();++iter){
326 CPPUNIT_ASSERT(i< collection->num);
327 i++;
328 }
329
330 i=0;
331 for(ObservableCollection::const_iterator iter=collection->begin(); iter!=collection->end();++iter){
332 CPPUNIT_ASSERT(i<collection->num);
333 i++;
334 }
335
336 collection->signOn(observer1);
337 {
338 // we construct this out of the loop, so the iterator dies at the end of
339 // the scope and not the end of the loop (allows more testing)
340 ObservableCollection::iterator iter;
341 for(iter=collection->begin(); iter!=collection->end(); ++iter){
342 (*iter)->changeMethod();
343 }
344 // At this point no change should have been propagated
345 CPPUNIT_ASSERT_EQUAL( 0, observer1->updates);
346 }
347 // After the Iterator has died the propagation should take place
348 CPPUNIT_ASSERT_EQUAL( 1, observer1->updates);
349
350 // when using a const_iterator no changes should be propagated
351 for(ObservableCollection::const_iterator iter = collection->begin(); iter!=collection->end();++iter);
352 CPPUNIT_ASSERT_EQUAL( 1, observer1->updates);
353 collection->signOff(observer1);
354}
355
356void ObserverTest::CircleDetectionTest() {
357 cout << endl << "Warning: the next test involved methods that can produce infinite loops." << endl;
358 cout << "Errors in this methods can not be checked using the CPPUNIT_ASSERT Macros." << endl;
359 cout << "Instead tests are run on these methods to see if termination is assured" << endl << endl;
360 cout << "If this test does not complete in a few seconds, kill the test-suite and fix the Error in the circle detection mechanism" << endl;
361
362 cout << endl << endl << "The following errors displayed by the observer framework can be ignored" << endl;
363
364 // make this Observable its own subject. NEVER DO THIS IN ACTUAL CODE
365 simpleObservable1->signOn(simpleObservable1);
366 CPPUNIT_ASSERT_THROW(simpleObservable1->changeMethod(),Assert::AssertionFailure);
367
368 // more complex test
369 simpleObservable1->signOff(simpleObservable1);
370 simpleObservable1->signOn(simpleObservable2);
371 simpleObservable2->signOn(simpleObservable1);
372 CPPUNIT_ASSERT_THROW(simpleObservable1->changeMethod(),Assert::AssertionFailure);
373 simpleObservable1->signOff(simpleObservable2);
374 simpleObservable2->signOff(simpleObservable1);
375 // when we reach this line, although we broke the DAG assumption the circle check works fine
376 CPPUNIT_ASSERT(true);
377}
Note: See TracBrowser for help on using the repository browser.