1 //
2 // test_Observable.cc for pekwm
3 // Copyright (C) 2021 Claes Nästén <pekdon@gmail.com>
4 //
5 // This program is licensed under the GNU GPL.
6 // See the LICENSE file for more information.
7 //
8
9 #include "test.hh"
10
11 #include "Observable.hh"
12
13 class TestObservable : public Observable {
14 public:
15 virtual ~TestObservable(void);
16 };
17
18 class TestObservation : public Observation {
19 public:
20 virtual ~TestObservation(void);
21 };
22
23 class TestObserver : public Observer {
24 public:
25 virtual ~TestObserver(void);
26 virtual void notify(Observable* observable, Observation* observation);
27
28 std::vector<TestObservation*> observations;
29 };
30
31 class TestObserverMapping : public TestSuite {
32 public:
33 TestObserverMapping(void);
34 ~TestObserverMapping(void);
35
36 virtual bool run_test(TestSpec spec, bool status);
37
38 private:
39 static void testNotify(void);
40 static void testRemoveObservable(void);
41 static void testDestructObservable(void);
42 };
43
~TestObservable(void)44 TestObservable::~TestObservable(void)
45 {
46 }
47
~TestObservation(void)48 TestObservation::~TestObservation(void)
49 {
50 }
51
~TestObserver(void)52 TestObserver::~TestObserver(void)
53 {
54 }
55
56 void
notify(Observable * observable,Observation * observation)57 TestObserver::notify(Observable* observable, Observation* observation)
58 {
59 TestObservation *test_observation =
60 dynamic_cast<TestObservation*>(observation);
61 observations.push_back(test_observation);
62 }
63
TestObserverMapping(void)64 TestObserverMapping::TestObserverMapping(void)
65 : TestSuite("ObserverMapping")
66 {
67 }
68
~TestObserverMapping(void)69 TestObserverMapping::~TestObserverMapping(void)
70 {
71 }
72
73 bool
run_test(TestSpec spec,bool status)74 TestObserverMapping::run_test(TestSpec spec, bool status)
75 {
76 TEST_FN(spec, "notify", testNotify());
77 TEST_FN(spec, "removeObservable", testRemoveObservable());
78 TEST_FN(spec, "destructObservable", testDestructObservable());
79 return status;
80 }
81
82 void
testNotify(void)83 TestObserverMapping::testNotify(void)
84 {
85 ObserverMapping om;
86 TestObservable observable;
87 TestObserver observer1;
88 TestObserver observer2;
89 TestObservation observation;
90
91 // notify no observers
92 om.notifyObservers(&observable, nullptr);
93 ASSERT_EQUAL("no observer", 0, om.size());
94 ASSERT_EQUAL("no observer", 0, observer1.observations.size());
95 ASSERT_EQUAL("no observer", 0, observer2.observations.size());
96
97 // notify one observer
98 om.addObserver(&observable, &observer1);
99 ASSERT_EQUAL("one observer", 1, om.size());
100 om.notifyObservers(&observable, &observation);
101 ASSERT_EQUAL("one observer", 1, observer1.observations.size());
102 ASSERT_EQUAL("one observer", 0, observer2.observations.size());
103
104 // notify multiple observers
105 om.addObserver(&observable, &observer2);
106 ASSERT_EQUAL("two observers", 1, om.size());
107 om.notifyObservers(&observable, &observation);
108 ASSERT_EQUAL("two observers", 2, observer1.observations.size());
109 ASSERT_EQUAL("two observers", 1, observer2.observations.size());
110
111 // remove observer
112 om.removeObserver(&observable, &observer1);
113 ASSERT_EQUAL("remove observers", 1, om.size());
114 om.notifyObservers(&observable, &observation);
115 ASSERT_EQUAL("remove observers", 2, observer1.observations.size());
116 ASSERT_EQUAL("remove observers", 2, observer2.observations.size());
117
118 // no observers
119 om.removeObserver(&observable, &observer2);
120 ASSERT_EQUAL("no observers", 0, om.size());
121 om.notifyObservers(&observable, &observation);
122 ASSERT_EQUAL("no observers", 2, observer1.observations.size());
123 ASSERT_EQUAL("no observers", 2, observer2.observations.size());
124 }
125
126 void
testRemoveObservable(void)127 TestObserverMapping::testRemoveObservable(void)
128 {
129 ObserverMapping om;
130 TestObservable observable;
131 TestObserver observer1;
132 TestObserver observer2;
133 TestObservation observation;
134
135 om.addObserver(&observable, &observer1);
136 om.addObserver(&observable, &observer2);
137 // removing the observable should remove the observers from its
138 // list as well.
139 om.removeObservable(&observable);
140 om.notifyObservers(&observable, &observation);
141
142 ASSERT_EQUAL("removed observable", 0, observer1.observations.size());
143 ASSERT_EQUAL("removed observable", 0, observer2.observations.size());
144 }
145
146 void
testDestructObservable(void)147 TestObserverMapping::testDestructObservable(void)
148 {
149 TestObserver observer;
150
151 ObserverMapping *om = pekwm::observerMapping();
152 {
153 TestObservable observable;
154 om->addObserver(&observable, &observer);
155 ASSERT_EQUAL("destruct observable", 1, om->size());
156 }
157
158 ASSERT_EQUAL("destruct observable", 0, om->size());
159 }
160