Index: src/unittests/Makefile.am
===================================================================
--- src/unittests/Makefile.am	(revision 04b6f9c4cd8d885f794fa20c327103eb776d9cb1)
+++ src/unittests/Makefile.am	(revision 63c1f67df77cc8176b6c0383d0c9e95cea19ac9f)
@@ -26,9 +26,11 @@
   Tesselation_BoundaryTriangleUnitTest \
   Tesselation_InOutsideUnitTest \
-  VectorUnitTest
+  VectorUnitTest \
+  ObserverTest \
+  ${MENUTESTS}  
     
   
-check_PROGRAMS = $(TESTS) ${MENUTESTS}
-noinst_PROGRAMS = $(TESTS) ${MENUTESTS}
+check_PROGRAMS = $(TESTS) 
+noinst_PROGRAMS = $(TESTS)
 
 ActOnAllUnitTest_SOURCES = ../test/ActOnAllTest.hpp ActOnAllUnitTest.cpp ActOnAllUnitTest.hpp
@@ -95,4 +97,7 @@
 ActionSequenceTest_LDADD = ../libmolecuilder.a
 
+ObserverTest_SOURCES = ObserverTest.cpp ObserverTest.hpp
+ObserverTest_LDADD = ../libmolecuilder.a
+
 #AUTOMAKE_OPTIONS = parallel-tests
 
Index: src/unittests/ObserverTest.cpp
===================================================================
--- src/unittests/ObserverTest.cpp	(revision 63c1f67df77cc8176b6c0383d0c9e95cea19ac9f)
+++ src/unittests/ObserverTest.cpp	(revision 63c1f67df77cc8176b6c0383d0c9e95cea19ac9f)
@@ -0,0 +1,185 @@
+/*
+ * ObserverTest.cpp
+ *
+ *  Created on: Jan 19, 2010
+ *      Author: crueger
+ */
+
+#include "ObserverTest.hpp"
+
+#include <cppunit/CompilerOutputter.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/ui/text/TestRunner.h>
+
+#include "Patterns/Observer.hpp"
+
+#include <iostream>
+
+using namespace std;
+
+// Registers the fixture into the 'registry'
+CPPUNIT_TEST_SUITE_REGISTRATION( ObserverTest );
+
+/******************* Test stubs ************************/
+
+class UpdateCountObserver : public Observer {
+public:
+  UpdateCountObserver() :
+    updates(0)
+  {};
+  void update(Observable *publisher){
+    updates++;
+  }
+  void subjectKilled(Observable *publisher) {
+  }
+  int updates;
+};
+
+class SimpleObservable : public Observable {
+public:
+  void changeMethod() {
+    START_OBSERVER;
+    int i;
+    i++;
+    FINISH_OBSERVER;
+  }
+};
+
+class CallObservable : public Observable {
+public:
+  void changeMethod1() {
+    START_OBSERVER;
+    int i;
+    i++;
+    FINISH_OBSERVER;
+  }
+
+  void changeMethod2() {
+    START_OBSERVER;
+    int i;
+    i++;
+    changeMethod1();
+    FINISH_OBSERVER;
+  }
+};
+
+class SuperObservable : public Observable {
+public:
+  SuperObservable(){
+    subObservable = new SimpleObservable();
+    subObservable->signOn(this);
+  }
+  ~SuperObservable(){
+    delete subObservable;
+  }
+  void changeMethod() {
+    START_OBSERVER;
+    int i;
+    i++;
+    subObservable->changeMethod();
+    FINISH_OBSERVER;
+  }
+  SimpleObservable *subObservable;
+};
+
+/******************* actuall tests ***************/
+
+void ObserverTest::setUp() {
+  simpleObservable = new  SimpleObservable();
+  callObservable = new CallObservable();
+  superObservable = new SuperObservable();
+
+  observer1 = new UpdateCountObserver();
+  observer2 = new UpdateCountObserver();
+  observer3 = new UpdateCountObserver();
+}
+
+void ObserverTest::tearDown() {
+  delete simpleObservable;
+  delete callObservable;
+  delete superObservable;
+
+  delete observer1;
+  delete observer2;
+  delete observer3;
+}
+
+void ObserverTest::doesUpdateTest()
+{
+  simpleObservable->signOn(observer1);
+  simpleObservable->signOn(observer2);
+  simpleObservable->signOn(observer3);
+
+  simpleObservable->changeMethod();
+  CPPUNIT_ASSERT_EQUAL( 1, observer1->updates );
+  CPPUNIT_ASSERT_EQUAL( 1, observer2->updates );
+  CPPUNIT_ASSERT_EQUAL( 1, observer3->updates );
+
+  simpleObservable->signOff(observer3);
+
+  simpleObservable->changeMethod();
+  CPPUNIT_ASSERT_EQUAL( 2, observer1->updates );
+  CPPUNIT_ASSERT_EQUAL( 2, observer2->updates );
+  CPPUNIT_ASSERT_EQUAL( 1, observer3->updates );
+}
+
+
+void ObserverTest::doesBlockUpdateTest() {
+  callObservable->signOn(observer1);
+
+  callObservable->changeMethod1();
+  CPPUNIT_ASSERT_EQUAL( 1, observer1->updates );
+
+  callObservable->changeMethod2();
+  CPPUNIT_ASSERT_EQUAL( 2, observer1->updates );
+}
+
+void ObserverTest::doesSubObservableTest() {
+  superObservable->signOn(observer1);
+  superObservable->subObservable->signOn(observer2);
+
+  superObservable->subObservable->changeMethod();
+  CPPUNIT_ASSERT_EQUAL( 1, observer1->updates );
+  CPPUNIT_ASSERT_EQUAL( 1, observer2->updates );
+
+  superObservable->changeMethod();
+  CPPUNIT_ASSERT_EQUAL( 2, observer1->updates );
+  CPPUNIT_ASSERT_EQUAL( 2, observer2->updates );
+}
+
+
+void ObserverTest::CircleDetectionTest() {
+  cout << endl << "Warning: the next test involved methods that can produce infinite loops." << endl;
+  cout << "Errors in this methods can not be checked using the CPPUNIT_ASSERT Macros." << endl;
+  cout << "Instead tests are run on these methods to see if termination is assured" << endl << endl;
+  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;
+
+  cout << endl << endl << "The following error displayed by the observer framwork can be ignored" << endl;
+
+  // make this Observable its own subject. NEVER DO THIS IN ACTUAL CODE
+  simpleObservable->signOn(simpleObservable);
+  simpleObservable->changeMethod();
+  // when we reach this line, although we broke the DAG assumption the circle check works fine
+  CPPUNIT_ASSERT(true);
+}
+
+/********************************************** Main routine **************************************/
+
+int main(int argc, char **argv)
+{
+  // Get the top level suite from the registry
+  CppUnit::Test *suite = CppUnit::TestFactoryRegistry::getRegistry().makeTest();
+
+  // Adds the test to the list of test to run
+  CppUnit::TextUi::TestRunner runner;
+  runner.addTest( suite );
+
+  // Change the default outputter to a compiler error format outputter
+  runner.setOutputter( new CppUnit::CompilerOutputter( &runner.result(),
+                                                       std::cerr ) );
+  // Run the tests.
+  bool wasSucessful = runner.run();
+
+  // Return error code 1 if the one of test failed.
+  return wasSucessful ? 0 : 1;
+};
Index: src/unittests/ObserverTest.hpp
===================================================================
--- src/unittests/ObserverTest.hpp	(revision 63c1f67df77cc8176b6c0383d0c9e95cea19ac9f)
+++ src/unittests/ObserverTest.hpp	(revision 63c1f67df77cc8176b6c0383d0c9e95cea19ac9f)
@@ -0,0 +1,48 @@
+/*
+ * ObserverTest.hpp
+ *
+ *  Created on: Jan 19, 2010
+ *      Author: crueger
+ */
+
+#ifndef OBSERVERTEST_HPP_
+#define OBSERVERTEST_HPP_
+
+#include <cppunit/extensions/HelperMacros.h>
+
+// forward declaration for test stubs
+class UpdateCountObserver;
+class SimpleObservable;
+class CallObservable;
+class SuperObservable;
+
+
+class ObserverTest :  public CppUnit::TestFixture
+{
+  CPPUNIT_TEST_SUITE( ObserverTest ) ;
+  CPPUNIT_TEST ( doesUpdateTest );
+  CPPUNIT_TEST ( doesBlockUpdateTest );
+  CPPUNIT_TEST ( doesSubObservableTest );
+  CPPUNIT_TEST ( CircleDetectionTest );
+  CPPUNIT_TEST_SUITE_END();
+
+public:
+  void setUp();
+  void tearDown();
+
+  void doesUpdateTest();
+  void doesBlockUpdateTest();
+  void doesSubObservableTest();
+  void CircleDetectionTest();
+
+private:
+  UpdateCountObserver *observer1;
+  UpdateCountObserver *observer2;
+  UpdateCountObserver *observer3;
+
+  SimpleObservable *simpleObservable;
+  CallObservable *callObservable;
+  SuperObservable *superObservable;
+};
+
+#endif /* OBSERVERTEST_HPP_ */
