source: src/unittests/ObserverTest.cpp@ 9848ba

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

Improved Observer Framework to include methods to report the state

  • bool Observable::isBlocked() will tell if the Observer is currently updating itself
  • The Circle detection test now uses ASSERT to report when a circle was detected (can be caught by CPPUNIT)
  • Property mode set to 100644
File size: 5.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
120/******************* actuall tests ***************/
121
122void ObserverTest::setUp() {
123 ASSERT_DO(Assert::Throw);
124 simpleObservable1 = new SimpleObservable();
125 simpleObservable2 = new SimpleObservable();
126 callObservable = new CallObservable();
127 superObservable = new SuperObservable();
128 blockObservable = new BlockObservable();
129
130 observer1 = new UpdateCountObserver();
131 observer2 = new UpdateCountObserver();
132 observer3 = new UpdateCountObserver();
133 observer4 = new UpdateCountObserver();
134}
135
136void ObserverTest::tearDown() {
137 delete simpleObservable1;
138 delete simpleObservable2;
139 delete callObservable;
140 delete superObservable;
141
142 delete observer1;
143 delete observer2;
144 delete observer3;
145 delete observer4;
146}
147
148void ObserverTest::doesUpdateTest()
149{
150 simpleObservable1->signOn(observer1);
151 simpleObservable1->signOn(observer2);
152 simpleObservable1->signOn(observer3);
153
154 simpleObservable2->signOn(observer2);
155 simpleObservable2->signOn(observer4);
156
157 simpleObservable1->changeMethod();
158 CPPUNIT_ASSERT_EQUAL( 1, observer1->updates );
159 CPPUNIT_ASSERT_EQUAL( 1, observer2->updates );
160 CPPUNIT_ASSERT_EQUAL( 1, observer3->updates );
161 CPPUNIT_ASSERT_EQUAL( 0, observer4->updates );
162
163 simpleObservable1->signOff(observer3);
164
165 simpleObservable1->changeMethod();
166 CPPUNIT_ASSERT_EQUAL( 2, observer1->updates );
167 CPPUNIT_ASSERT_EQUAL( 2, observer2->updates );
168 CPPUNIT_ASSERT_EQUAL( 1, observer3->updates );
169 CPPUNIT_ASSERT_EQUAL( 0, observer4->updates );
170
171 simpleObservable2->changeMethod();
172 CPPUNIT_ASSERT_EQUAL( 2, observer1->updates );
173 CPPUNIT_ASSERT_EQUAL( 3, observer2->updates );
174 CPPUNIT_ASSERT_EQUAL( 1, observer3->updates );
175 CPPUNIT_ASSERT_EQUAL( 1, observer4->updates );
176}
177
178
179void ObserverTest::doesBlockUpdateTest() {
180 callObservable->signOn(observer1);
181
182 callObservable->changeMethod1();
183 CPPUNIT_ASSERT_EQUAL( 1, observer1->updates );
184
185 callObservable->changeMethod2();
186 CPPUNIT_ASSERT_EQUAL( 2, observer1->updates );
187}
188
189void ObserverTest::doesSubObservableTest() {
190 superObservable->signOn(observer1);
191 superObservable->subObservable->signOn(observer2);
192
193 superObservable->subObservable->changeMethod();
194 CPPUNIT_ASSERT_EQUAL( 1, observer1->updates );
195 CPPUNIT_ASSERT_EQUAL( 1, observer2->updates );
196
197 superObservable->changeMethod();
198 CPPUNIT_ASSERT_EQUAL( 2, observer1->updates );
199 CPPUNIT_ASSERT_EQUAL( 2, observer2->updates );
200}
201
202void ObserverTest::doesReportTest(){
203 // Actual checks are in the Stub-methods for this
204 blockObservable->changeMethod1();
205 blockObservable->changeMethod2();
206 blockObservable->noChangeMethod();
207}
208
209void ObserverTest::CircleDetectionTest() {
210 cout << endl << "Warning: the next test involved methods that can produce infinite loops." << endl;
211 cout << "Errors in this methods can not be checked using the CPPUNIT_ASSERT Macros." << endl;
212 cout << "Instead tests are run on these methods to see if termination is assured" << endl << endl;
213 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;
214
215 cout << endl << endl << "The following errors displayed by the observer framework can be ignored" << endl;
216
217 // make this Observable its own subject. NEVER DO THIS IN ACTUAL CODE
218 simpleObservable1->signOn(simpleObservable1);
219 CPPUNIT_ASSERT_THROW(simpleObservable1->changeMethod(),Assert::AssertionFailure);
220
221 // more complex test
222 simpleObservable1->signOff(simpleObservable1);
223 simpleObservable1->signOn(simpleObservable2);
224 simpleObservable2->signOn(simpleObservable1);
225 CPPUNIT_ASSERT_THROW(simpleObservable1->changeMethod(),Assert::AssertionFailure);
226 simpleObservable1->signOff(simpleObservable2);
227 simpleObservable2->signOff(simpleObservable1);
228 // when we reach this line, although we broke the DAG assumption the circle check works fine
229 CPPUNIT_ASSERT(true);
230}
Note: See TracBrowser for help on using the repository browser.