source: src/unittests/ObserverTest.cpp@ bd58fb

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

Added an iterator pattern for observed Data structures

  • Property mode set to 100644
File size: 6.0 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
18#include <iostream>
19
20using namespace std;
21
22#ifdef HAVE_TESTRUNNER
23#include "UnitTestMain.hpp"
24#endif /*HAVE_TESTRUNNER*/
25
26// Registers the fixture into the 'registry'
27CPPUNIT_TEST_SUITE_REGISTRATION( ObserverTest );
28
29/******************* Test stubs ************************/
30
31class UpdateCountObserver : public Observer {
32public:
33 UpdateCountObserver() :
34 updates(0)
35 {};
36 void update(Observable *publisher){
37 updates++;
38 }
39 void subjectKilled(Observable *publisher) {
40 }
41 int updates;
42};
43
44class SimpleObservable : public Observable {
45public:
46 void changeMethod() {
47 OBSERVE;
48 int i = 0;
49 i++;
50 }
51};
52
53class CallObservable : public Observable {
54public:
55 void changeMethod1() {
56 OBSERVE;
57 int i = 0;
58 i++;
59 }
60
61 void changeMethod2() {
62 OBSERVE;
63 int i = 0;
64 i++;
65 changeMethod1();
66 }
67};
68
69class SuperObservable : public Observable {
70public:
71 SuperObservable(){
72 subObservable = new SimpleObservable();
73 subObservable->signOn(this);
74 }
75 ~SuperObservable(){
76 delete subObservable;
77 }
78 void changeMethod() {
79 OBSERVE;
80 int i = 0;
81 i++;
82 subObservable->changeMethod();
83 }
84 SimpleObservable *subObservable;
85};
86
87class ObservableCollection : public Observable {
88public:
89 typedef std::set<SimpleObservable*> set;
90 typedef ObservedIterator<set> iterator;
91
92 ObservableCollection(int num){
93 for(int i=0; i<num; ++i){
94 SimpleObservable *content = new SimpleObservable();
95 content->signOn(this);
96 theSet.insert(content);
97 }
98 }
99
100 ~ObservableCollection(){
101 set::iterator iter;
102 for(iter=theSet.begin(); iter!=theSet.end(); ++iter ){
103 delete (*iter);
104 }
105 }
106
107 iterator begin(){
108 return iterator(theSet.begin(),this);
109 }
110
111 iterator end(){
112 return iterator(theSet.end(),this);
113 }
114
115private:
116 set theSet;
117};
118
119/******************* actuall tests ***************/
120
121void ObserverTest::setUp() {
122 simpleObservable1 = new SimpleObservable();
123 simpleObservable2 = new SimpleObservable();
124 callObservable = new CallObservable();
125 superObservable = new SuperObservable();
126
127 observer1 = new UpdateCountObserver();
128 observer2 = new UpdateCountObserver();
129 observer3 = new UpdateCountObserver();
130 observer4 = new UpdateCountObserver();
131
132 collection = new ObservableCollection(5);
133}
134
135void ObserverTest::tearDown() {
136 delete simpleObservable1;
137 delete simpleObservable2;
138 delete callObservable;
139 delete superObservable;
140
141 delete observer1;
142 delete observer2;
143 delete observer3;
144 delete observer4;
145
146 delete collection;
147}
148
149void ObserverTest::doesUpdateTest()
150{
151 simpleObservable1->signOn(observer1);
152 simpleObservable1->signOn(observer2);
153 simpleObservable1->signOn(observer3);
154
155 simpleObservable2->signOn(observer2);
156 simpleObservable2->signOn(observer4);
157
158 simpleObservable1->changeMethod();
159 CPPUNIT_ASSERT_EQUAL( 1, observer1->updates );
160 CPPUNIT_ASSERT_EQUAL( 1, observer2->updates );
161 CPPUNIT_ASSERT_EQUAL( 1, observer3->updates );
162 CPPUNIT_ASSERT_EQUAL( 0, observer4->updates );
163
164 simpleObservable1->signOff(observer3);
165
166 simpleObservable1->changeMethod();
167 CPPUNIT_ASSERT_EQUAL( 2, observer1->updates );
168 CPPUNIT_ASSERT_EQUAL( 2, observer2->updates );
169 CPPUNIT_ASSERT_EQUAL( 1, observer3->updates );
170 CPPUNIT_ASSERT_EQUAL( 0, observer4->updates );
171
172 simpleObservable2->changeMethod();
173 CPPUNIT_ASSERT_EQUAL( 2, observer1->updates );
174 CPPUNIT_ASSERT_EQUAL( 3, observer2->updates );
175 CPPUNIT_ASSERT_EQUAL( 1, observer3->updates );
176 CPPUNIT_ASSERT_EQUAL( 1, observer4->updates );
177}
178
179
180void ObserverTest::doesBlockUpdateTest() {
181 callObservable->signOn(observer1);
182
183 callObservable->changeMethod1();
184 CPPUNIT_ASSERT_EQUAL( 1, observer1->updates );
185
186 callObservable->changeMethod2();
187 CPPUNIT_ASSERT_EQUAL( 2, observer1->updates );
188}
189
190void ObserverTest::doesSubObservableTest() {
191 superObservable->signOn(observer1);
192 superObservable->subObservable->signOn(observer2);
193
194 superObservable->subObservable->changeMethod();
195 CPPUNIT_ASSERT_EQUAL( 1, observer1->updates );
196 CPPUNIT_ASSERT_EQUAL( 1, observer2->updates );
197
198 superObservable->changeMethod();
199 CPPUNIT_ASSERT_EQUAL( 2, observer1->updates );
200 CPPUNIT_ASSERT_EQUAL( 2, observer2->updates );
201}
202
203void ObserverTest::iteratorTest(){
204 collection->signOn(observer1);
205 {
206 ObservableCollection::iterator iter;
207 for(iter=collection->begin(); iter!=collection->end(); ++iter){
208 (*iter)->changeMethod();
209 }
210 // At this point no change should have been propagated
211 CPPUNIT_ASSERT_EQUAL( 0, observer1->updates);
212 }
213 // After the Iterator has died the propagation should take place
214 CPPUNIT_ASSERT_EQUAL( 1, observer1->updates);
215 collection->signOff(observer1);
216}
217
218
219void ObserverTest::CircleDetectionTest() {
220 cout << endl << "Warning: the next test involved methods that can produce infinite loops." << endl;
221 cout << "Errors in this methods can not be checked using the CPPUNIT_ASSERT Macros." << endl;
222 cout << "Instead tests are run on these methods to see if termination is assured" << endl << endl;
223 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;
224
225 cout << endl << endl << "The following errors displayed by the observer framework can be ignored" << endl;
226
227 // make this Observable its own subject. NEVER DO THIS IN ACTUAL CODE
228 simpleObservable1->signOn(simpleObservable1);
229 simpleObservable1->changeMethod();
230
231 // more complex test
232 simpleObservable1->signOff(simpleObservable1);
233 simpleObservable1->signOn(simpleObservable2);
234 simpleObservable2->signOn(simpleObservable1);
235 simpleObservable1->changeMethod();
236 simpleObservable1->signOff(simpleObservable2);
237 simpleObservable2->signOff(simpleObservable1);
238 // when we reach this line, although we broke the DAG assumption the circle check works fine
239 CPPUNIT_ASSERT(true);
240}
Note: See TracBrowser for help on using the repository browser.