source: src/Patterns/unittests/ObserverUnitTest.cpp@ 8e24ef

Last change on this file since 8e24ef was d3926b5, checked in by Frederik Heber <heber@…>, 15 years ago

BUGFIX: ObservedContainer::reverse_iterator was wrong way implemnted.

  • Library version is now 4:0:4, API version is still 1.0.9.
  • reverse_iterator had begin(), end() messed in cstor.
  • added unit test on ObservedContainer.
  • Property mode set to 100644
File size: 8.2 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2010 University of Bonn. All rights reserved.
5 * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
6 */
7
8/*
9 * ObserverTest.cpp
10 *
11 * Created on: Jan 19, 2010
12 * Author: crueger
13 */
14
15// include config.h
16#ifdef HAVE_CONFIG_H
17#include <config.h>
18#endif
19
20#include <cppunit/CompilerOutputter.h>
21#include <cppunit/extensions/TestFactoryRegistry.h>
22#include <cppunit/ui/text/TestRunner.h>
23#include <set>
24
25#include "Assert.hpp"
26
27#include <iostream>
28
29#include "stubs/ObserverStub.hpp"
30#include "ObservedContainer.hpp"
31#include "ObservedContainer_impl.hpp"
32
33#include "ObserverUnitTest.hpp"
34
35#ifdef HAVE_TESTRUNNER
36#include "UnitTestMain.hpp"
37#endif /*HAVE_TESTRUNNER*/
38
39// Registers the fixture into the 'registry'
40CPPUNIT_TEST_SUITE_REGISTRATION( ObserverTest );
41
42/******************* Test stubs ************************/
43
44
45/******************* actuall tests ***************/
46
47void ObserverTest::setUp() {
48 ASSERT_DO(Assert::Throw);
49 simpleObservable1 = new SimpleObservable();
50 simpleObservable2 = new SimpleObservable();
51 callObservable = new CallObservable();
52 superObservable = new SuperObservable();
53 blockObservable = new BlockObservable();
54 notificationObservable = new NotificationObservable();
55 obsset = new ObservableSet(5);
56 obsmap = new ObservableMap(5);
57
58 observer1 = new UpdateCountObserver();
59 observer2 = new UpdateCountObserver();
60 observer3 = new UpdateCountObserver();
61 observer4 = new UpdateCountObserver();
62
63 notificationObserver1 = new NotificationObserver(notificationObservable->notification1);
64 notificationObserver2 = new NotificationObserver(notificationObservable->notification2);
65}
66
67void ObserverTest::tearDown() {
68 delete simpleObservable1;
69 delete simpleObservable2;
70 delete callObservable;
71 delete superObservable;
72 delete blockObservable;
73 delete notificationObservable;
74 delete obsset;
75 delete obsmap;
76
77 delete observer1;
78 delete observer2;
79 delete observer3;
80 delete observer4;
81 delete notificationObserver1;
82 delete notificationObserver2;
83}
84
85void ObserverTest::doesUpdateTest()
86{
87 simpleObservable1->signOn(observer1);
88 simpleObservable1->signOn(observer2);
89 simpleObservable1->signOn(observer3);
90
91 simpleObservable2->signOn(observer2);
92 simpleObservable2->signOn(observer4);
93
94 CPPUNIT_ASSERT_EQUAL( 0, observer1->updates );
95 CPPUNIT_ASSERT_EQUAL( 0, observer2->updates );
96 CPPUNIT_ASSERT_EQUAL( 0, observer3->updates );
97 CPPUNIT_ASSERT_EQUAL( 0, observer4->updates );
98
99
100 simpleObservable1->changeMethod();
101 CPPUNIT_ASSERT_EQUAL( 1, observer1->updates );
102 CPPUNIT_ASSERT_EQUAL( 1, observer2->updates );
103 CPPUNIT_ASSERT_EQUAL( 1, observer3->updates );
104 CPPUNIT_ASSERT_EQUAL( 0, observer4->updates );
105
106 simpleObservable1->signOff(observer3);
107
108 simpleObservable1->changeMethod();
109 CPPUNIT_ASSERT_EQUAL( 2, observer1->updates );
110 CPPUNIT_ASSERT_EQUAL( 2, observer2->updates );
111 CPPUNIT_ASSERT_EQUAL( 1, observer3->updates );
112 CPPUNIT_ASSERT_EQUAL( 0, observer4->updates );
113
114 simpleObservable2->changeMethod();
115 CPPUNIT_ASSERT_EQUAL( 2, observer1->updates );
116 CPPUNIT_ASSERT_EQUAL( 3, observer2->updates );
117 CPPUNIT_ASSERT_EQUAL( 1, observer3->updates );
118 CPPUNIT_ASSERT_EQUAL( 1, observer4->updates );
119}
120
121
122void ObserverTest::doesBlockUpdateTest() {
123 callObservable->signOn(observer1);
124 CPPUNIT_ASSERT_EQUAL( 0, observer1->updates );
125
126 callObservable->changeMethod1();
127 CPPUNIT_ASSERT_EQUAL( 1, observer1->updates );
128
129 callObservable->changeMethod2();
130 CPPUNIT_ASSERT_EQUAL( 2, observer1->updates );
131}
132
133void ObserverTest::doesSubObservableTest() {
134 superObservable->signOn(observer1);
135 superObservable->subObservable->signOn(observer2);
136
137 superObservable->subObservable->changeMethod();
138 CPPUNIT_ASSERT_EQUAL( 1, observer1->updates );
139 CPPUNIT_ASSERT_EQUAL( 1, observer2->updates );
140
141 superObservable->changeMethod();
142 CPPUNIT_ASSERT_EQUAL( 2, observer1->updates );
143 CPPUNIT_ASSERT_EQUAL( 2, observer2->updates );
144}
145
146void ObserverTest::outsideLockTest(){
147 callObservable->signOn(observer1);
148 CPPUNIT_ASSERT_EQUAL( 0, observer1->updates );
149
150 {
151 LOCK_OBSERVABLE(*callObservable);
152 CPPUNIT_ASSERT_EQUAL( 0, observer1->updates );
153 }
154 // lock is gone now, observer should have notified
155 CPPUNIT_ASSERT_EQUAL( 1, observer1->updates );
156}
157
158void ObserverTest::doesNotifyTest(){
159 notificationObservable->signOn(notificationObserver1,
160 notificationObservable->notification1);
161 notificationObservable->signOn(notificationObserver2,
162 notificationObservable->notification2);
163
164 notificationObservable->operation1();
165 CPPUNIT_ASSERT(notificationObserver1->wasNotified);
166 CPPUNIT_ASSERT(!notificationObserver2->wasNotified);
167
168 notificationObserver1->wasNotified=false;
169
170 notificationObservable->operation2();
171 CPPUNIT_ASSERT(!notificationObserver1->wasNotified);
172 CPPUNIT_ASSERT(notificationObserver2->wasNotified);
173
174}
175
176void ObserverTest::doesReportTest(){
177 // Actual checks are in the Stub-methods for this
178 blockObservable->changeMethod1();
179 blockObservable->changeMethod2();
180 blockObservable->noChangeMethod();
181}
182
183void ObserverTest::iteratorTest(){
184 int i = 0;
185 // test the general iterator methods
186 for(ObservableSet::iterator iter=obsset->begin(); iter!=obsset->end();++iter){
187 CPPUNIT_ASSERT(i< obsset->num);
188 i++;
189 }
190
191 i=0;
192 for(ObservableSet::const_iterator iter=obsset->begin(); iter!=obsset->end();++iter){
193 CPPUNIT_ASSERT(i<obsset->num);
194 i++;
195 }
196
197 obsset->signOn(observer1);
198 {
199 // we construct this out of the loop, so the iterator dies at the end of
200 // the scope and not the end of the loop (allows more testing)
201 ObservableSet::iterator iter;
202 for(iter=obsset->begin(); iter!=obsset->end(); ++iter){
203 (*iter)->changeMethod();
204 }
205 // At this point no change should have been propagated
206 CPPUNIT_ASSERT_EQUAL( 0, observer1->updates);
207 }
208 // After the Iterator has died the propagation should take place
209 CPPUNIT_ASSERT_EQUAL( 1, observer1->updates);
210
211 // when using a const_iterator no changes should be propagated
212 for(ObservableSet::const_iterator iter = obsset->begin(); iter!=obsset->end();++iter);
213 CPPUNIT_ASSERT_EQUAL( 1, observer1->updates);
214
215 // we need to test the operator-> as well
216 obsmap->signOn(observer2);
217 {
218 // we construct this out of the loop, so the iterator dies at the end of
219 // the scope and not the end of the loop (allows more testing)
220 ObservableMap::iterator iter;
221 for(iter=obsmap->begin(); iter!=obsmap->end(); ++iter){
222 iter->second->changeMethod();
223 }
224 // At this point no change should have been propagated
225 CPPUNIT_ASSERT_EQUAL( 0, observer2->updates);
226 }
227 // After the Iterator has died the propagation should take place
228 CPPUNIT_ASSERT_EQUAL( 1, observer2->updates);
229
230
231 obsset->signOff(observer1);
232 obsmap->signOff(observer2);
233}
234
235void ObserverTest::CircleDetectionTest() {
236 std::cout << std::endl << "Warning: the next test involved methods that can produce infinite loops." << std::endl;
237 std::cout << "Errors in this methods can not be checked using the CPPUNIT_ASSERT Macros." << std::endl;
238 std::cout << "Instead tests are run on these methods to see if termination is assured" << std::endl << std::endl;
239 std::cout << "If this test does not complete in a few seconds, kill the test-suite and fix the Error in the circle detection mechanism" << std::endl;
240
241 std::cout << std::endl << std::endl << "The following errors displayed by the observer framework can be ignored" << std::endl;
242
243 // make this Observable its own subject. NEVER DO THIS IN ACTUAL CODE
244 simpleObservable1->signOn(simpleObservable1);
245#ifndef NDEBUG
246 CPPUNIT_ASSERT_THROW(simpleObservable1->changeMethod(),Assert::AssertionFailure);
247#else
248 simpleObservable1->changeMethod();
249#endif
250
251 // more complex test
252 simpleObservable1->signOff(simpleObservable1);
253 simpleObservable1->signOn(simpleObservable2);
254 simpleObservable2->signOn(simpleObservable1);
255#ifndef NDEBUG
256 CPPUNIT_ASSERT_THROW(simpleObservable1->changeMethod(),Assert::AssertionFailure);
257#else
258 simpleObservable1->changeMethod();
259#endif
260
261
262 simpleObservable1->signOff(simpleObservable2);
263 simpleObservable2->signOff(simpleObservable1);
264 // when we reach this line, although we broke the DAG assumption the circle check works fine
265 CPPUNIT_ASSERT(true);
266}
Note: See TracBrowser for help on using the repository browser.