1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package org.apache.harmony.tests.java.util; 19 20 import java.util.Observable; 21 import java.util.Observer; 22 import java.util.Vector; 23 import java.util.concurrent.atomic.AtomicReference; 24 25 public class ObservableTest extends junit.framework.TestCase { 26 27 static class TestObserver implements Observer { 28 public Vector objv = new Vector(); 29 30 int updateCount = 0; 31 32 public void update(Observable observed, Object arg) { 33 ++updateCount; 34 objv.add(arg); 35 } 36 37 public int updateCount() { 38 return updateCount; 39 } 40 41 } 42 43 static class DeleteTestObserver implements Observer { 44 int updateCount = 0; 45 46 boolean deleteAll = false; 47 48 public DeleteTestObserver(boolean all) { 49 deleteAll = all; 50 } 51 52 public void update(Observable observed, Object arg) { 53 ++updateCount; 54 if (deleteAll) 55 observed.deleteObservers(); 56 else 57 observed.deleteObserver(this); 58 } 59 60 public int updateCount() { 61 return updateCount; 62 } 63 64 } 65 66 static class TestObservable extends Observable { 67 public void doChange() { 68 setChanged(); 69 } 70 71 public void clearChange() { 72 clearChanged(); 73 } 74 } 75 76 Observer observer; 77 78 TestObservable observable; 79 80 /** 81 * java.util.Observable#Observable() 82 */ 83 public void test_Constructor() { 84 // Test for method java.util.Observable() 85 try { 86 Observable ov = new Observable(); 87 assertTrue("Wrong initial values.", !ov.hasChanged()); 88 assertEquals("Wrong initial values.", 0, ov.countObservers()); 89 } catch (Exception e) { 90 fail("Exception during test : " + e.getMessage()); 91 } 92 } 93 94 /** 95 * java.util.Observable#addObserver(java.util.Observer) 96 */ 97 public void test_addObserverLjava_util_Observer() { 98 // Test for method void 99 // java.util.Observable.addObserver(java.util.Observer) 100 TestObserver test = new TestObserver(); 101 observable.addObserver(test); 102 assertEquals("Failed to add observer", 1, observable.countObservers()); 103 observable.addObserver(test); 104 assertEquals("Duplicate observer", 1, observable.countObservers()); 105 106 Observable o = new Observable(); 107 try { 108 o.addObserver(null); 109 fail("Expected adding a null observer to throw a NPE."); 110 } catch (NullPointerException ex) { 111 // expected; 112 } catch (Throwable ex) { 113 fail("Did not expect adding a new observer to throw a " 114 + ex.getClass().getName()); 115 } 116 } 117 118 /** 119 * java.util.Observable#countObservers() 120 */ 121 public void test_countObservers() { 122 // Test for method int java.util.Observable.countObservers() 123 assertEquals("New observable had > 0 observers", 0, observable 124 .countObservers()); 125 observable.addObserver(new TestObserver()); 126 assertEquals("Observable with observer returned other than 1", 1, observable 127 .countObservers()); 128 } 129 130 /** 131 * java.util.Observable#deleteObserver(java.util.Observer) 132 */ 133 public void test_deleteObserverLjava_util_Observer() { 134 // Test for method void 135 // java.util.Observable.deleteObserver(java.util.Observer) 136 observable.addObserver(observer = new TestObserver()); 137 observable.deleteObserver(observer); 138 assertEquals("Failed to delete observer", 139 0, observable.countObservers()); 140 observable.deleteObserver(observer); 141 observable.deleteObserver(null); 142 } 143 144 /** 145 * java.util.Observable#deleteObservers() 146 */ 147 public void test_deleteObservers() { 148 // Test for method void java.util.Observable.deleteObservers() 149 observable.addObserver(new TestObserver()); 150 observable.addObserver(new TestObserver()); 151 observable.addObserver(new TestObserver()); 152 observable.addObserver(new TestObserver()); 153 observable.addObserver(new TestObserver()); 154 observable.addObserver(new TestObserver()); 155 observable.addObserver(new TestObserver()); 156 observable.addObserver(new TestObserver()); 157 observable.deleteObservers(); 158 assertEquals("Failed to delete observers", 159 0, observable.countObservers()); 160 } 161 162 /** 163 * java.util.Observable#hasChanged() 164 */ 165 public void test_hasChanged() { 166 assertFalse(observable.hasChanged()); 167 observable.addObserver(observer = new TestObserver()); 168 observable.doChange(); 169 assertTrue(observable.hasChanged()); 170 } 171 172 public void test_clearChanged() { 173 assertFalse(observable.hasChanged()); 174 observable.addObserver(observer = new TestObserver()); 175 observable.doChange(); 176 assertTrue(observable.hasChanged()); 177 observable.clearChange(); 178 assertFalse(observable.hasChanged()); 179 } 180 181 /** 182 * java.util.Observable#notifyObservers() 183 */ 184 public void test_notifyObservers() { 185 // Test for method void java.util.Observable.notifyObservers() 186 observable.addObserver(observer = new TestObserver()); 187 observable.notifyObservers(); 188 assertEquals("Notified when unchnaged", 0, ((TestObserver) observer) 189 .updateCount()); 190 ((TestObservable) observable).doChange(); 191 observable.notifyObservers(); 192 assertEquals("Failed to notify", 193 1, ((TestObserver) observer).updateCount()); 194 195 DeleteTestObserver observer1, observer2; 196 observable.deleteObservers(); 197 observable.addObserver(observer1 = new DeleteTestObserver(false)); 198 observable.addObserver(observer2 = new DeleteTestObserver(false)); 199 observable.doChange(); 200 observable.notifyObservers(); 201 assertTrue("Failed to notify all", observer1.updateCount() == 1 202 && observer2.updateCount() == 1); 203 assertEquals("Failed to delete all", 0, observable.countObservers()); 204 205 observable.addObserver(observer1 = new DeleteTestObserver(false)); 206 observable.addObserver(observer2 = new DeleteTestObserver(false)); 207 observable.doChange(); 208 observable.notifyObservers(); 209 assertTrue("Failed to notify all 2", observer1.updateCount() == 1 210 && observer2.updateCount() == 1); 211 assertEquals("Failed to delete all 2", 0, observable.countObservers()); 212 } 213 214 /** 215 * java.util.Observable#notifyObservers(java.lang.Object) 216 */ 217 public void test_notifyObserversLjava_lang_Object() { 218 // Test for method void 219 // java.util.Observable.notifyObservers(java.lang.Object) 220 Object obj; 221 observable.addObserver(observer = new TestObserver()); 222 observable.notifyObservers(); 223 assertEquals("Notified when unchanged", 0, ((TestObserver) observer) 224 .updateCount()); 225 ((TestObservable) observable).doChange(); 226 observable.notifyObservers(obj = new Object()); 227 assertEquals("Failed to notify", 228 1, ((TestObserver) observer).updateCount()); 229 assertTrue("Failed to pass Object arg", ((TestObserver) observer).objv 230 .elementAt(0).equals(obj)); 231 } 232 233 static final class AlwaysChangedObservable extends Observable { 234 @Override 235 public boolean hasChanged() { 236 return true; 237 } 238 } 239 240 // http://b/28797950 241 public void test_observableWithOverridenHasChanged() throws Exception { 242 final AtomicReference<Observable> updated = new AtomicReference<>(); 243 final Observer observer = (observable1, data) -> updated.set(observable1); 244 245 Observable alwaysChanging = new AlwaysChangedObservable(); 246 alwaysChanging.addObserver(observer); 247 alwaysChanging.notifyObservers(null); 248 assertSame(alwaysChanging, updated.get()); 249 } 250 251 /** 252 * Sets up the fixture, for example, open a network connection. This method 253 * is called before a test is executed. 254 */ 255 protected void setUp() { 256 observable = new TestObservable(); 257 } 258 259 /** 260 * Tears down the fixture, for example, close a network connection. This 261 * method is called after a test is executed. 262 */ 263 protected void tearDown() { 264 } 265 } 266