Index: base/android/javatests/src/org/chromium/base/ObserverListTest.java |
diff --git a/base/android/javatests/src/org/chromium/base/ObserverListTest.java b/base/android/javatests/src/org/chromium/base/ObserverListTest.java |
new file mode 100644 |
index 0000000000000000000000000000000000000000..e201c803c340c896e1a10d9609d9bd86e2563dab |
--- /dev/null |
+++ b/base/android/javatests/src/org/chromium/base/ObserverListTest.java |
@@ -0,0 +1,141 @@ |
+// Copyright 2013 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+package org.chromium.base; |
+ |
+import android.test.InstrumentationTestCase; |
+import android.test.suitebuilder.annotation.SmallTest; |
+ |
+import org.chromium.base.test.util.Feature; |
+ |
+import java.lang.Iterable; |
+import java.util.Iterator; |
+import java.util.NoSuchElementException; |
+ |
+/** |
+ * Tests for (@link ObserverList}. |
+ */ |
+public class ObserverListTest extends InstrumentationTestCase { |
+ interface Observer { |
+ void observe(int x); |
+ } |
+ |
+ private static class Foo implements Observer { |
+ private final int mScalar; |
+ private int mTotal = 0; |
+ |
+ Foo(int scalar) { |
+ mScalar = scalar; |
+ } |
+ |
+ @Override |
+ public void observe(int x) { |
+ mTotal += x * mScalar; |
+ } |
+ } |
+ |
+ /** |
+ * An observer which removes a given Observer object from the list when observe is called. |
+ */ |
+ private static class FooRemover implements Observer { |
+ private final ObserverList<Observer> mList; |
+ private final Observer mDoomed; |
+ |
+ FooRemover(ObserverList<Observer> list, Observer innocent) { |
+ mList = list; |
+ mDoomed = innocent; |
+ } |
+ |
+ @Override |
+ public void observe(int x) { |
+ mList.removeObserver(mDoomed); |
+ } |
+ } |
+ |
+ private static <T> int getSizeOfIterable(Iterable<T> iterable) { |
+ int num = 0; |
+ for (T el : iterable) |
+ num++; |
+ return num; |
+ } |
+ |
+ @SmallTest |
+ @Feature({"Android-AppBase"}) |
+ public void testRemoveWhileIteration() { |
bulach
2013/02/28 12:39:12
it'd be nice to add a "testAddWhileIterating" and
nilesh
2013/02/28 19:35:36
Makes sense, add a test for addWhileIterating.
|
+ ObserverList<Observer> observerList = new ObserverList<Observer>(); |
+ Foo a, b, c, d, e; |
bulach
2013/02/28 12:39:12
nit: I don't think this is strictly forbidden, but
nilesh
2013/02/28 19:35:36
Done.
|
+ a = new Foo(1); |
+ b = new Foo(-1); |
+ c = new Foo(1); |
+ d = new Foo(-1); |
+ e = new Foo(-1); |
+ FooRemover evil = new FooRemover(observerList, c); |
+ |
+ observerList.addObserver(a); |
+ observerList.addObserver(b); |
+ |
+ for (Observer obs : observerList) |
+ obs.observe(10); |
+ |
+ // Removing an observer not in the list should do nothing. |
+ observerList.removeObserver(e); |
+ |
+ observerList.addObserver(evil); |
+ observerList.addObserver(c); |
+ observerList.addObserver(d); |
+ |
+ for (Observer obs : observerList) |
+ obs.observe(10); |
+ |
+ // observe should be called twice on a. |
+ assertEquals(20, a.mTotal); |
+ // observe should be called twice on b. |
+ assertEquals(-20, b.mTotal); |
+ // evil removed c from the observerList before it got any callbacks. |
+ assertEquals(0, c.mTotal); |
+ // observe should be called once on d. |
+ assertEquals(-10, d.mTotal); |
+ // e was never added to the list, observe should not be called. |
+ assertEquals(0, e.mTotal); |
+ } |
+ |
+ @SmallTest |
+ @Feature({"Android-AppBase"}) |
+ public void testIterator() { |
+ ObserverList<Integer> observerList = new ObserverList<Integer>(); |
+ observerList.addObserver(5); |
+ observerList.addObserver(10); |
+ observerList.addObserver(15); |
+ assertEquals(3, getSizeOfIterable(observerList)); |
+ |
+ observerList.removeObserver(10); |
+ assertEquals(2, getSizeOfIterable(observerList)); |
+ |
+ Iterator<Integer> it = observerList.iterator(); |
+ assertTrue(it.hasNext()); |
+ assertTrue(5 == it.next()); |
+ assertTrue(it.hasNext()); |
+ assertTrue(15 == it.next()); |
+ assertFalse(it.hasNext()); |
+ |
+ boolean removeExceptionThrown = false; |
+ try { |
+ it.remove(); |
+ fail("Expecting UnsupportedOperationException to be thrown here."); |
+ } catch (UnsupportedOperationException e) { |
+ removeExceptionThrown = true; |
+ } |
+ assertTrue(removeExceptionThrown); |
+ assertEquals(2, getSizeOfIterable(observerList)); |
+ |
+ boolean noElementExceptionThrown = false; |
+ try { |
+ it.next(); |
+ fail("Expecting NoSuchElementException to be thrown here."); |
+ } catch (NoSuchElementException e) { |
+ noElementExceptionThrown = true; |
+ } |
+ assertTrue(noElementExceptionThrown); |
+ } |
+} |