- add sources.
[platform/framework/web/crosswalk.git] / src / base / android / javatests / src / org / chromium / base / ObserverListTest.java
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package org.chromium.base;
6
7 import android.test.InstrumentationTestCase;
8 import android.test.suitebuilder.annotation.SmallTest;
9
10 import org.chromium.base.ObserverList;
11 import org.chromium.base.test.util.Feature;
12
13 import java.lang.Iterable;
14 import java.util.Iterator;
15 import java.util.NoSuchElementException;
16
17 /**
18  * Tests for (@link ObserverList}.
19  */
20 public class ObserverListTest extends InstrumentationTestCase {
21     interface Observer {
22         void observe(int x);
23     }
24
25     private static class Foo implements Observer {
26         private final int mScalar;
27         private int mTotal = 0;
28
29         Foo(int scalar) {
30             mScalar = scalar;
31         }
32
33         @Override
34         public void observe(int x) {
35             mTotal += x * mScalar;
36         }
37     }
38
39     /**
40      * An observer which add a given Observer object to the list when observe is called.
41      */
42     private static class FooAdder implements Observer {
43         private final ObserverList<Observer> mList;
44         private final Observer mLucky;
45
46         FooAdder(ObserverList<Observer> list, Observer oblivious) {
47             mList = list;
48             mLucky = oblivious;
49         }
50
51         @Override
52         public void observe(int x) {
53             mList.addObserver(mLucky);
54         }
55     }
56
57     /**
58      * An observer which removes a given Observer object from the list when observe is called.
59      */
60     private static class FooRemover implements Observer {
61         private final ObserverList<Observer> mList;
62         private final Observer mDoomed;
63
64         FooRemover(ObserverList<Observer> list, Observer innocent) {
65             mList = list;
66             mDoomed = innocent;
67         }
68
69         @Override
70         public void observe(int x) {
71             mList.removeObserver(mDoomed);
72         }
73     }
74
75     private static <T> int getSizeOfIterable(Iterable<T> iterable) {
76         int num = 0;
77         for (T el : iterable)
78             num++;
79         return num;
80     }
81
82     @SmallTest
83     @Feature({"Android-AppBase"})
84     public void testRemoveWhileIteration() {
85         ObserverList<Observer> observerList = new ObserverList<Observer>();
86         Foo a = new Foo(1);
87         Foo b = new Foo(-1);
88         Foo c = new Foo(1);
89         Foo d = new Foo(-1);
90         Foo e = new Foo(-1);
91         FooRemover evil = new FooRemover(observerList, c);
92
93         observerList.addObserver(a);
94         observerList.addObserver(b);
95
96         for (Observer obs : observerList)
97             obs.observe(10);
98
99         // Removing an observer not in the list should do nothing.
100         observerList.removeObserver(e);
101
102         observerList.addObserver(evil);
103         observerList.addObserver(c);
104         observerList.addObserver(d);
105
106         for (Observer obs : observerList)
107             obs.observe(10);
108
109         // observe should be called twice on a.
110         assertEquals(20, a.mTotal);
111         // observe should be called twice on b.
112         assertEquals(-20, b.mTotal);
113         // evil removed c from the observerList before it got any callbacks.
114         assertEquals(0, c.mTotal);
115         // observe should be called once on d.
116         assertEquals(-10, d.mTotal);
117         // e was never added to the list, observe should not be called.
118         assertEquals(0, e.mTotal);
119     }
120
121     @SmallTest
122     @Feature({"Android-AppBase"})
123     public void testAddWhileIteration() {
124         ObserverList<Observer> observerList = new ObserverList<Observer>();
125         Foo a = new Foo(1);
126         Foo b = new Foo(-1);
127         Foo c = new Foo(1);
128         FooAdder evil = new FooAdder(observerList, c);
129
130         observerList.addObserver(evil);
131         observerList.addObserver(a);
132         observerList.addObserver(b);
133
134         for (Observer obs : observerList)
135             obs.observe(10);
136
137         assertTrue(observerList.hasObserver(c));
138         assertEquals(10, a.mTotal);
139         assertEquals(-10, b.mTotal);
140         assertEquals(0, c.mTotal);
141     }
142
143     @SmallTest
144     @Feature({"Android-AppBase"})
145     public void testIterator() {
146         ObserverList<Integer> observerList = new ObserverList<Integer>();
147         observerList.addObserver(5);
148         observerList.addObserver(10);
149         observerList.addObserver(15);
150         assertEquals(3, getSizeOfIterable(observerList));
151
152         observerList.removeObserver(10);
153         assertEquals(2, getSizeOfIterable(observerList));
154
155         Iterator<Integer> it = observerList.iterator();
156         assertTrue(it.hasNext());
157         assertTrue(5 == it.next());
158         assertTrue(it.hasNext());
159         assertTrue(15 == it.next());
160         assertFalse(it.hasNext());
161
162         boolean removeExceptionThrown = false;
163         try {
164             it.remove();
165             fail("Expecting UnsupportedOperationException to be thrown here.");
166         } catch (UnsupportedOperationException e) {
167             removeExceptionThrown = true;
168         }
169         assertTrue(removeExceptionThrown);
170         assertEquals(2, getSizeOfIterable(observerList));
171
172         boolean noElementExceptionThrown = false;
173         try {
174             it.next();
175             fail("Expecting NoSuchElementException to be thrown here.");
176         } catch (NoSuchElementException e) {
177             noElementExceptionThrown = true;
178         }
179         assertTrue(noElementExceptionThrown);
180     }
181
182     @SmallTest
183     @Feature({"Android-AppBase"})
184     public void testRewindableIterator() {
185         ObserverList<Integer> observerList = new ObserverList<Integer>();
186         observerList.addObserver(5);
187         observerList.addObserver(10);
188         observerList.addObserver(15);
189         assertEquals(3, getSizeOfIterable(observerList));
190
191         ObserverList.RewindableIterator<Integer> it = observerList.rewindableIterator();
192         assertTrue(it.hasNext());
193         assertTrue(5 == it.next());
194         assertTrue(it.hasNext());
195         assertTrue(10 == it.next());
196         assertTrue(it.hasNext());
197         assertTrue(15 == it.next());
198         assertFalse(it.hasNext());
199
200         it.rewind();
201
202         assertTrue(it.hasNext());
203         assertTrue(5 == it.next());
204         assertTrue(it.hasNext());
205         assertTrue(10 == it.next());
206         assertTrue(it.hasNext());
207         assertTrue(15 == it.next());
208         assertEquals(5, (int) observerList.mObservers.get(0));
209         observerList.removeObserver(5);
210         assertEquals(null, observerList.mObservers.get(0));
211
212         it.rewind();
213
214         assertEquals(10, (int) observerList.mObservers.get(0));
215         assertTrue(it.hasNext());
216         assertTrue(10 == it.next());
217         assertTrue(it.hasNext());
218         assertTrue(15 == it.next());
219     }
220 }