Chromium Code Reviews| 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); |
| + } |
| +} |