1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package android.databinding; 17 18 import org.junit.Test; 19 20 import java.util.ArrayList; 21 22 import static org.junit.Assert.assertEquals; 23 import static org.junit.Assert.assertFalse; 24 import static org.junit.Assert.assertNotNull; 25 import static org.junit.Assert.assertTrue; 26 27 public class CallbackRegistryTest { 28 29 final Integer callback1 = 1; 30 final Integer callback2 = 2; 31 final Integer callback3 = 3; 32 CallbackRegistry<Integer, CallbackRegistryTest, Integer> registry; 33 int notify1; 34 int notify2; 35 int notify3; 36 int[] deepNotifyCount = new int[300]; 37 Integer argValue; 38 39 private void addNotifyCount(Integer callback) { 40 if (callback == callback1) { 41 notify1++; 42 } else if (callback == callback2) { 43 notify2++; 44 } else if (callback == callback3) { 45 notify3++; 46 } 47 deepNotifyCount[callback]++; 48 } 49 50 @Test 51 public void testAddListener() { 52 CallbackRegistry.NotifierCallback<Integer, CallbackRegistryTest, Integer> notifier = 53 new CallbackRegistry.NotifierCallback<Integer, CallbackRegistryTest, Integer>() { 54 @Override 55 public void onNotifyCallback(Integer callback, CallbackRegistryTest sender, 56 int arg, Integer arg2) { 57 } 58 }; 59 registry = new CallbackRegistry<Integer, CallbackRegistryTest, Integer>(notifier); 60 Integer callback = 0; 61 62 assertNotNull(registry.copyCallbacks()); 63 assertEquals(0, registry.copyCallbacks().size()); 64 65 registry.add(callback); 66 ArrayList<Integer> callbacks = registry.copyCallbacks(); 67 assertEquals(1, callbacks.size()); 68 assertEquals(callback, callbacks.get(0)); 69 70 registry.add(callback); 71 callbacks = registry.copyCallbacks(); 72 assertEquals(1, callbacks.size()); 73 assertEquals(callback, callbacks.get(0)); 74 75 Integer otherListener = 1; 76 registry.add(otherListener); 77 callbacks = registry.copyCallbacks(); 78 assertEquals(2, callbacks.size()); 79 assertEquals(callback, callbacks.get(0)); 80 assertEquals(otherListener, callbacks.get(1)); 81 82 registry.remove(callback); 83 registry.add(callback); 84 callbacks = registry.copyCallbacks(); 85 assertEquals(2, callbacks.size()); 86 assertEquals(callback, callbacks.get(1)); 87 assertEquals(otherListener, callbacks.get(0)); 88 } 89 90 @Test 91 public void testSimpleNotify() { 92 CallbackRegistry.NotifierCallback<Integer, CallbackRegistryTest, Integer> notifier = 93 new CallbackRegistry.NotifierCallback<Integer, CallbackRegistryTest, Integer>() { 94 @Override 95 public void onNotifyCallback(Integer callback, CallbackRegistryTest sender, 96 int arg1, Integer arg) { 97 assertEquals(arg1, (int) arg); 98 addNotifyCount(callback); 99 argValue = arg; 100 } 101 }; 102 registry = new CallbackRegistry<Integer, CallbackRegistryTest, Integer>(notifier); 103 registry.add(callback2); 104 Integer arg = 1; 105 registry.notifyCallbacks(this, arg, arg); 106 assertEquals(arg, argValue); 107 assertEquals(1, notify2); 108 } 109 110 @Test 111 public void testRemoveWhileNotifying() { 112 CallbackRegistry.NotifierCallback<Integer, CallbackRegistryTest, Integer> notifier = 113 new CallbackRegistry.NotifierCallback<Integer, CallbackRegistryTest, Integer>() { 114 @Override 115 public void onNotifyCallback(Integer callback, CallbackRegistryTest sender, 116 int arg1, Integer arg) { 117 addNotifyCount(callback); 118 if (callback == callback1) { 119 registry.remove(callback1); 120 registry.remove(callback2); 121 } 122 } 123 }; 124 registry = new CallbackRegistry<Integer, CallbackRegistryTest, Integer>(notifier); 125 registry.add(callback1); 126 registry.add(callback2); 127 registry.add(callback3); 128 registry.notifyCallbacks(this, 0, null); 129 assertEquals(1, notify1); 130 assertEquals(1, notify2); 131 assertEquals(1, notify3); 132 133 ArrayList<Integer> callbacks = registry.copyCallbacks(); 134 assertEquals(1, callbacks.size()); 135 assertEquals(callback3, callbacks.get(0)); 136 } 137 138 @Test 139 public void testDeepRemoveWhileNotifying() { 140 CallbackRegistry.NotifierCallback<Integer, CallbackRegistryTest, Integer> notifier = 141 new CallbackRegistry.NotifierCallback<Integer, CallbackRegistryTest, Integer>() { 142 @Override 143 public void onNotifyCallback(Integer callback, CallbackRegistryTest sender, 144 int arg1, Integer arg) { 145 addNotifyCount(callback); 146 registry.remove(callback); 147 registry.notifyCallbacks(CallbackRegistryTest.this, arg1, null); 148 } 149 }; 150 registry = new CallbackRegistry<Integer, CallbackRegistryTest, Integer>(notifier); 151 registry.add(callback1); 152 registry.add(callback2); 153 registry.add(callback3); 154 registry.notifyCallbacks(this, 0, null); 155 assertEquals(1, notify1); 156 assertEquals(2, notify2); 157 assertEquals(3, notify3); 158 159 ArrayList<Integer> callbacks = registry.copyCallbacks(); 160 assertEquals(0, callbacks.size()); 161 } 162 163 @Test 164 public void testAddRemovedListener() { 165 166 CallbackRegistry.NotifierCallback<Integer, CallbackRegistryTest, Integer> notifier = 167 new CallbackRegistry.NotifierCallback<Integer, CallbackRegistryTest, Integer>() { 168 @Override 169 public void onNotifyCallback(Integer callback, CallbackRegistryTest sender, 170 int arg1, Integer arg) { 171 addNotifyCount(callback); 172 if (callback == callback1) { 173 registry.remove(callback2); 174 } else if (callback == callback3) { 175 registry.add(callback2); 176 } 177 } 178 }; 179 registry = new CallbackRegistry<Integer, CallbackRegistryTest, Integer>(notifier); 180 181 registry.add(callback1); 182 registry.add(callback2); 183 registry.add(callback3); 184 registry.notifyCallbacks(this, 0, null); 185 186 ArrayList<Integer> callbacks = registry.copyCallbacks(); 187 assertEquals(3, callbacks.size()); 188 assertEquals(callback1, callbacks.get(0)); 189 assertEquals(callback3, callbacks.get(1)); 190 assertEquals(callback2, callbacks.get(2)); 191 assertEquals(1, notify1); 192 assertEquals(1, notify2); 193 assertEquals(1, notify3); 194 } 195 196 @Test 197 public void testVeryDeepRemoveWhileNotifying() { 198 final Integer[] callbacks = new Integer[deepNotifyCount.length]; 199 for (int i = 0; i < callbacks.length; i++) { 200 callbacks[i] = i; 201 } 202 CallbackRegistry.NotifierCallback<Integer, CallbackRegistryTest, Integer> notifier = 203 new CallbackRegistry.NotifierCallback<Integer, CallbackRegistryTest, Integer>() { 204 @Override 205 public void onNotifyCallback(Integer callback, CallbackRegistryTest sender, 206 int arg1, Integer arg) { 207 addNotifyCount(callback); 208 registry.remove(callback); 209 registry.remove(callbacks[callbacks.length - callback - 1]); 210 registry.notifyCallbacks(CallbackRegistryTest.this, arg1, null); 211 } 212 }; 213 registry = new CallbackRegistry<Integer, CallbackRegistryTest, Integer>(notifier); 214 for (int i = 0; i < callbacks.length; i++) { 215 registry.add(callbacks[i]); 216 } 217 registry.notifyCallbacks(this, 0, null); 218 for (int i = 0; i < deepNotifyCount.length; i++) { 219 int expectedCount = Math.min(i + 1, deepNotifyCount.length - i); 220 assertEquals(expectedCount, deepNotifyCount[i]); 221 } 222 223 ArrayList<Integer> callbackList = registry.copyCallbacks(); 224 assertEquals(0, callbackList.size()); 225 } 226 227 @Test 228 public void testClear() { 229 CallbackRegistry.NotifierCallback<Integer, CallbackRegistryTest, Integer> notifier = 230 new CallbackRegistry.NotifierCallback<Integer, CallbackRegistryTest, Integer>() { 231 @Override 232 public void onNotifyCallback(Integer callback, CallbackRegistryTest sender, 233 int arg1, Integer arg) { 234 addNotifyCount(callback); 235 } 236 }; 237 registry = new CallbackRegistry<Integer, CallbackRegistryTest, Integer>(notifier); 238 for (int i = 0; i < deepNotifyCount.length; i++) { 239 registry.add(i); 240 } 241 registry.clear(); 242 243 ArrayList<Integer> callbackList = registry.copyCallbacks(); 244 assertEquals(0, callbackList.size()); 245 246 registry.notifyCallbacks(this, 0, null); 247 for (int i = 0; i < deepNotifyCount.length; i++) { 248 assertEquals(0, deepNotifyCount[i]); 249 } 250 } 251 252 @Test 253 public void testNestedClear() { 254 CallbackRegistry.NotifierCallback<Integer, CallbackRegistryTest, Integer> notifier = 255 new CallbackRegistry.NotifierCallback<Integer, CallbackRegistryTest, Integer>() { 256 @Override 257 public void onNotifyCallback(Integer callback, CallbackRegistryTest sender, 258 int arg1, Integer arg) { 259 addNotifyCount(callback); 260 registry.clear(); 261 } 262 }; 263 registry = new CallbackRegistry<Integer, CallbackRegistryTest, Integer>(notifier); 264 for (int i = 0; i < deepNotifyCount.length; i++) { 265 registry.add(i); 266 } 267 registry.notifyCallbacks(this, 0, null); 268 for (int i = 0; i < deepNotifyCount.length; i++) { 269 assertEquals(1, deepNotifyCount[i]); 270 } 271 272 ArrayList<Integer> callbackList = registry.copyCallbacks(); 273 assertEquals(0, callbackList.size()); 274 } 275 276 @Test 277 public void testIsEmpty() throws Exception { 278 CallbackRegistry.NotifierCallback<Integer, CallbackRegistryTest, Integer> notifier = 279 new CallbackRegistry.NotifierCallback<Integer, CallbackRegistryTest, Integer>() { 280 @Override 281 public void onNotifyCallback(Integer callback, CallbackRegistryTest sender, 282 int arg, Integer arg2) { 283 } 284 }; 285 registry = new CallbackRegistry<Integer, CallbackRegistryTest, Integer>(notifier); 286 Integer callback = 0; 287 288 assertTrue(registry.isEmpty()); 289 registry.add(callback); 290 assertFalse(registry.isEmpty()); 291 } 292 293 @Test 294 public void testClone() throws Exception { 295 CallbackRegistry.NotifierCallback<Integer, CallbackRegistryTest, Integer> notifier = 296 new CallbackRegistry.NotifierCallback<Integer, CallbackRegistryTest, Integer>() { 297 @Override 298 public void onNotifyCallback(Integer callback, CallbackRegistryTest sender, 299 int arg, Integer arg2) { 300 } 301 }; 302 registry = new CallbackRegistry<Integer, CallbackRegistryTest, Integer>(notifier); 303 304 assertTrue(registry.isEmpty()); 305 CallbackRegistry<Integer, CallbackRegistryTest, Integer> registry2 = registry.clone(); 306 Integer callback = 0; 307 registry.add(callback); 308 assertFalse(registry.isEmpty()); 309 assertTrue(registry2.isEmpty()); 310 registry2 = registry.clone(); 311 assertFalse(registry2.isEmpty()); 312 } 313 } 314