source: src/unittests/ObserverTest.cpp@ c6efc1

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

Small improvements to Observer code

  • Property mode set to 100644
File size: 7.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
14#include "Patterns/Observer.hpp"
15#include "Helpers/Assert.hpp"
16
17#include <iostream>
18
19using namespace std;
20
21#ifdef HAVE_TESTRUNNER
22#include "UnitTestMain.hpp"
23#endif /*HAVE_TESTRUNNER*/
24
25// Registers the fixture into the 'registry'
26CPPUNIT_TEST_SUITE_REGISTRATION( ObserverTest );
27
28/******************* Test stubs ************************/
29
30class UpdateCountObserver : public Observer {
31public:
32 UpdateCountObserver() :
33 updates(0)
34 {};
35 void update(Observable *publisher){
36 updates++;
37 }
38 void subjectKilled(Observable *publisher) {
39 }
40 int updates;
41};
42
43class SimpleObservable : public Observable {
44public:
45 void changeMethod() {
46 OBSERVE;
47 int i = 0;
48 i++;
49 }
50};
51
52class CallObservable : public Observable {
53public:
54 void changeMethod1() {
55 OBSERVE;
56 int i = 0;
57 i++;
58 }
59
60 void changeMethod2() {
61 OBSERVE;
62 int i = 0;
63 i++;
64 changeMethod1();
65 }
66};
67
68class BlockObservable : public Observable {
69public:
70 void changeMethod1(){
71 OBSERVE;
72 // test if we report correctly as blocked
73 CPPUNIT_ASSERT(isBlocked());
74 }
75
76 void changeMethod2(){
77 OBSERVE;
78 internalMethod1();
79 internalMethod2();
80 }
81
82 void internalMethod1(){
83 // we did not block, but our caller did...
84 // see if this is found
85 CPPUNIT_ASSERT(isBlocked());
86 }
87
88 void internalMethod2(){
89 OBSERVE;
90 // Both this method and the caller do block
91 // Does the reporting still work as expected?
92 CPPUNIT_ASSERT(isBlocked());
93 }
94
95 void noChangeMethod(){
96 // No Block introduced here
97 // reported correctely?
98 CPPUNIT_ASSERT(!isBlocked());
99 }
100};
101
102class SuperObservable : public Observable {
103public:
104 SuperObservable(){
105 subObservable = new SimpleObservable();
106 subObservable->signOn(this);
107 }
108 ~SuperObservable(){
109 delete subObservable;
110 }
111 void changeMethod() {
112 OBSERVE;
113 int i = 0;
114 i++;
115 subObservable->changeMethod();
116 }
117 SimpleObservable *subObservable;
118};
119
120class NotificationObservable : public Observable {
121public:
122 NotificationObservable() :
123 notification1(new Notification(this)),
124 notification2(new Notification(this))
125 {}
126
127 ~NotificationObservable(){
128 delete notification1;
129 delete notification2;
130 }
131
132 void operation1(){
133 OBSERVE;
134 NOTIFY(notification1);
135 }
136
137 void operation2(){
138 OBSERVE;
139 NOTIFY(notification2);
140 }
141
142 Notification_ptr notification1;
143 Notification_ptr notification2;
144};
145
146class NotificationObserver : public Observer {
147public:
148 NotificationObserver(Notification_ptr notification) :
149 requestedNotification(notification),
150 wasNotified(false)
151 {}
152
153 void update(Observable*){}
154 void subjectKilled(Observable*){}
155 void recieveNotification(Observable *publisher, Notification_ptr notification){
156 ASSERT(requestedNotification==notification,"Notification received that was not requested");
157 wasNotified = true;
158 }
159
160 Notification_ptr requestedNotification;
161
162 bool wasNotified;
163};
164
165/******************* actuall tests ***************/
166
167void ObserverTest::setUp() {
168 ASSERT_DO(Assert::Throw);
169 simpleObservable1 = new SimpleObservable();
170 simpleObservable2 = new SimpleObservable();
171 callObservable = new CallObservable();
172 superObservable = new SuperObservable();
173 blockObservable = new BlockObservable();
174 notificationObservable = new NotificationObservable();
175
176 observer1 = new UpdateCountObserver();
177 observer2 = new UpdateCountObserver();
178 observer3 = new UpdateCountObserver();
179 observer4 = new UpdateCountObserver();
180
181 notificationObserver1 = new NotificationObserver(notificationObservable->notification1);
182 notificationObserver2 = new NotificationObserver(notificationObservable->notification2);
183
184}
185
186void ObserverTest::tearDown() {
187 delete simpleObservable1;
188 delete simpleObservable2;
189 delete callObservable;
190 delete superObservable;
191 delete blockObservable;
192 delete notificationObservable;
193
194 delete observer1;
195 delete observer2;
196 delete observer3;
197 delete observer4;
198 delete notificationObserver1;
199 delete notificationObserver2;
200}
201
202void ObserverTest::doesUpdateTest()
203{
204 simpleObservable1->signOn(observer1);
205 simpleObservable1->signOn(observer2);
206 simpleObservable1->signOn(observer3);
207
208 simpleObservable2->signOn(observer2);
209 simpleObservable2->signOn(observer4);
210
211 simpleObservable1->changeMethod();
212 CPPUNIT_ASSERT_EQUAL( 1, observer1->updates );
213 CPPUNIT_ASSERT_EQUAL( 1, observer2->updates );
214 CPPUNIT_ASSERT_EQUAL( 1, observer3->updates );
215 CPPUNIT_ASSERT_EQUAL( 0, observer4->updates );
216
217 simpleObservable1->signOff(observer3);
218
219 simpleObservable1->changeMethod();
220 CPPUNIT_ASSERT_EQUAL( 2, observer1->updates );
221 CPPUNIT_ASSERT_EQUAL( 2, observer2->updates );
222 CPPUNIT_ASSERT_EQUAL( 1, observer3->updates );
223 CPPUNIT_ASSERT_EQUAL( 0, observer4->updates );
224
225 simpleObservable2->changeMethod();
226 CPPUNIT_ASSERT_EQUAL( 2, observer1->updates );
227 CPPUNIT_ASSERT_EQUAL( 3, observer2->updates );
228 CPPUNIT_ASSERT_EQUAL( 1, observer3->updates );
229 CPPUNIT_ASSERT_EQUAL( 1, observer4->updates );
230}
231
232
233void ObserverTest::doesBlockUpdateTest() {
234 callObservable->signOn(observer1);
235
236 callObservable->changeMethod1();
237 CPPUNIT_ASSERT_EQUAL( 1, observer1->updates );
238
239 callObservable->changeMethod2();
240 CPPUNIT_ASSERT_EQUAL( 2, observer1->updates );
241}
242
243void ObserverTest::doesSubObservableTest() {
244 superObservable->signOn(observer1);
245 superObservable->subObservable->signOn(observer2);
246
247 superObservable->subObservable->changeMethod();
248 CPPUNIT_ASSERT_EQUAL( 1, observer1->updates );
249 CPPUNIT_ASSERT_EQUAL( 1, observer2->updates );
250
251 superObservable->changeMethod();
252 CPPUNIT_ASSERT_EQUAL( 2, observer1->updates );
253 CPPUNIT_ASSERT_EQUAL( 2, observer2->updates );
254}
255
256void ObserverTest::doesNotifyTest(){
257 notificationObservable->signOn(notificationObserver1,
258 notificationObservable->notification1);
259 notificationObservable->signOn(notificationObserver2,
260 notificationObservable->notification2);
261
262 notificationObservable->operation1();
263 CPPUNIT_ASSERT(notificationObserver1->wasNotified);
264 CPPUNIT_ASSERT(!notificationObserver2->wasNotified);
265
266 notificationObserver1->wasNotified=false;
267
268 notificationObservable->operation2();
269 CPPUNIT_ASSERT(!notificationObserver1->wasNotified);
270 CPPUNIT_ASSERT(notificationObserver2->wasNotified);
271
272}
273
274void ObserverTest::doesReportTest(){
275 // Actual checks are in the Stub-methods for this
276 blockObservable->changeMethod1();
277 blockObservable->changeMethod2();
278 blockObservable->noChangeMethod();
279}
280
281void ObserverTest::CircleDetectionTest() {
282 cout << endl << "Warning: the next test involved methods that can produce infinite loops." << endl;
283 cout << "Errors in this methods can not be checked using the CPPUNIT_ASSERT Macros." << endl;
284 cout << "Instead tests are run on these methods to see if termination is assured" << endl << endl;
285 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;
286
287 cout << endl << endl << "The following errors displayed by the observer framework can be ignored" << endl;
288
289 // make this Observable its own subject. NEVER DO THIS IN ACTUAL CODE
290 simpleObservable1->signOn(simpleObservable1);
291 CPPUNIT_ASSERT_THROW(simpleObservable1->changeMethod(),Assert::AssertionFailure);
292
293 // more complex test
294 simpleObservable1->signOff(simpleObservable1);
295 simpleObservable1->signOn(simpleObservable2);
296 simpleObservable2->signOn(simpleObservable1);
297 CPPUNIT_ASSERT_THROW(simpleObservable1->changeMethod(),Assert::AssertionFailure);
298 simpleObservable1->signOff(simpleObservable2);
299 simpleObservable2->signOff(simpleObservable1);
300 // when we reach this line, although we broke the DAG assumption the circle check works fine
301 CPPUNIT_ASSERT(true);
302}
Note: See TracBrowser for help on using the repository browser.