1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 //     * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 //     * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 //     * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 package com.google.protobuf;
32 
33 import static java.util.Arrays.asList;
34 
35 import java.util.Collections;
36 import java.util.ConcurrentModificationException;
37 import java.util.Iterator;
38 import java.util.List;
39 import junit.framework.TestCase;
40 
41 /** Tests for {@link ProtobufArrayList}. */
42 public class ProtobufArrayListTest extends TestCase {
43 
44   private static final ProtobufArrayList<Integer> UNARY_LIST = newImmutableProtoArrayList(1);
45   private static final ProtobufArrayList<Integer> TERTIARY_LIST =
46       newImmutableProtoArrayList(1, 2, 3);
47 
48   private ProtobufArrayList<Integer> list;
49 
50   @Override
setUp()51   protected void setUp() throws Exception {
52     list = new ProtobufArrayList<Integer>();
53   }
54 
testEmptyListReturnsSameInstance()55   public void testEmptyListReturnsSameInstance() {
56     assertSame(ProtobufArrayList.emptyList(), ProtobufArrayList.emptyList());
57   }
58 
testEmptyListIsImmutable()59   public void testEmptyListIsImmutable() {
60     assertImmutable(ProtobufArrayList.<Integer>emptyList());
61   }
62 
testModificationWithIteration()63   public void testModificationWithIteration() {
64     list.addAll(asList(1, 2, 3, 4));
65     Iterator<Integer> iterator = list.iterator();
66     assertEquals(4, list.size());
67     assertEquals(1, (int) list.get(0));
68     assertEquals(1, (int) iterator.next());
69 
70     list.remove(0);
71     try {
72       iterator.next();
73       fail();
74     } catch (ConcurrentModificationException e) {
75       // expected
76     }
77 
78     iterator = list.iterator();
79     list.set(0, 1);
80     try {
81       iterator.next();
82       fail();
83     } catch (ConcurrentModificationException e) {
84       // expected
85     }
86 
87     iterator = list.iterator();
88     list.add(0, 0);
89     try {
90       iterator.next();
91       fail();
92     } catch (ConcurrentModificationException e) {
93       // expected
94     }
95   }
96 
testMakeImmutable()97   public void testMakeImmutable() {
98     list.add(2);
99     list.add(4);
100     list.add(6);
101     list.add(8);
102     list.makeImmutable();
103     assertImmutable(list);
104   }
105 
testRemove()106   public void testRemove() {
107     list.addAll(TERTIARY_LIST);
108     assertEquals(1, (int) list.remove(0));
109     assertEquals(asList(2, 3), list);
110 
111     assertTrue(list.remove(Integer.valueOf(3)));
112     assertEquals(asList(2), list);
113 
114     assertFalse(list.remove(Integer.valueOf(3)));
115     assertEquals(asList(2), list);
116 
117     assertEquals(2, (int) list.remove(0));
118     assertEquals(asList(), list);
119 
120     try {
121       list.remove(-1);
122       fail();
123     } catch (IndexOutOfBoundsException e) {
124       // expected
125     }
126 
127     try {
128       list.remove(0);
129     } catch (IndexOutOfBoundsException e) {
130       // expected
131     }
132   }
133 
testGet()134   public void testGet() {
135     assertEquals(1, (int) TERTIARY_LIST.get(0));
136     assertEquals(2, (int) TERTIARY_LIST.get(1));
137     assertEquals(3, (int) TERTIARY_LIST.get(2));
138 
139     try {
140       TERTIARY_LIST.get(-1);
141       fail();
142     } catch (IndexOutOfBoundsException e) {
143       // expected
144     }
145 
146     try {
147       TERTIARY_LIST.get(3);
148       fail();
149     } catch (IndexOutOfBoundsException e) {
150       // expected
151     }
152   }
153 
testSet()154   public void testSet() {
155     list.add(2);
156     list.add(4);
157 
158     assertEquals(2, (int) list.set(0, 3));
159     assertEquals(3, (int) list.get(0));
160 
161     assertEquals(4, (int) list.set(1, 0));
162     assertEquals(0, (int) list.get(1));
163 
164     try {
165       list.set(-1, 0);
166       fail();
167     } catch (IndexOutOfBoundsException e) {
168       // expected
169     }
170 
171     try {
172       list.set(2, 0);
173       fail();
174     } catch (IndexOutOfBoundsException e) {
175       // expected
176     }
177   }
178 
testAdd()179   public void testAdd() {
180     assertEquals(0, list.size());
181 
182     assertTrue(list.add(2));
183     assertEquals(asList(2), list);
184 
185     assertTrue(list.add(3));
186     list.add(0, 4);
187     assertEquals(asList(4, 2, 3), list);
188 
189     list.add(0, 1);
190     list.add(0, 0);
191     // Force a resize by getting up to 11 elements.
192     for (int i = 0; i < 6; i++) {
193       list.add(Integer.valueOf(5 + i));
194     }
195     assertEquals(asList(0, 1, 4, 2, 3, 5, 6, 7, 8, 9, 10), list);
196 
197     try {
198       list.add(-1, 5);
199     } catch (IndexOutOfBoundsException e) {
200       // expected
201     }
202 
203     try {
204       list.add(4, 5);
205     } catch (IndexOutOfBoundsException e) {
206       // expected
207     }
208   }
209 
testAddAll()210   public void testAddAll() {
211     assertEquals(0, list.size());
212 
213     assertTrue(list.addAll(Collections.singleton(1)));
214     assertEquals(1, list.size());
215     assertEquals(1, (int) list.get(0));
216 
217     assertTrue(list.addAll(asList(2, 3, 4, 5, 6)));
218     assertEquals(asList(1, 2, 3, 4, 5, 6), list);
219 
220     assertTrue(list.addAll(TERTIARY_LIST));
221     assertEquals(asList(1, 2, 3, 4, 5, 6, 1, 2, 3), list);
222 
223     assertFalse(list.addAll(Collections.<Integer>emptyList()));
224     assertFalse(list.addAll(IntArrayList.emptyList()));
225   }
226 
testSize()227   public void testSize() {
228     assertEquals(0, ProtobufArrayList.emptyList().size());
229     assertEquals(1, UNARY_LIST.size());
230     assertEquals(3, TERTIARY_LIST.size());
231 
232     list.add(3);
233     list.add(4);
234     list.add(6);
235     list.add(8);
236     assertEquals(4, list.size());
237 
238     list.remove(0);
239     assertEquals(3, list.size());
240 
241     list.add(17);
242     assertEquals(4, list.size());
243   }
244 
assertImmutable(List<Integer> list)245   private void assertImmutable(List<Integer> list) {
246     if (list.contains(1)) {
247       throw new RuntimeException("Cannot test the immutability of lists that contain 1.");
248     }
249 
250     try {
251       list.add(1);
252       fail();
253     } catch (UnsupportedOperationException e) {
254       // expected
255     }
256 
257     try {
258       list.add(0, 1);
259       fail();
260     } catch (UnsupportedOperationException e) {
261       // expected
262     }
263 
264     try {
265       list.addAll(Collections.<Integer>emptyList());
266       fail();
267     } catch (UnsupportedOperationException e) {
268       // expected
269     }
270 
271     try {
272       list.addAll(Collections.singletonList(1));
273       fail();
274     } catch (UnsupportedOperationException e) {
275       // expected
276     }
277 
278     try {
279       list.addAll(new ProtobufArrayList<Integer>());
280       fail();
281     } catch (UnsupportedOperationException e) {
282       // expected
283     }
284 
285     try {
286       list.addAll(UNARY_LIST);
287       fail();
288     } catch (UnsupportedOperationException e) {
289       // expected
290     }
291 
292     try {
293       list.addAll(0, Collections.singleton(1));
294       fail();
295     } catch (UnsupportedOperationException e) {
296       // expected
297     }
298 
299     try {
300       list.addAll(0, UNARY_LIST);
301       fail();
302     } catch (UnsupportedOperationException e) {
303       // expected
304     }
305 
306     try {
307       list.addAll(0, Collections.<Integer>emptyList());
308       fail();
309     } catch (UnsupportedOperationException e) {
310       // expected
311     }
312 
313     try {
314       list.clear();
315       fail();
316     } catch (UnsupportedOperationException e) {
317       // expected
318     }
319 
320     try {
321       list.remove(1);
322       fail();
323     } catch (UnsupportedOperationException e) {
324       // expected
325     }
326 
327     try {
328       list.remove(new Object());
329       fail();
330     } catch (UnsupportedOperationException e) {
331       // expected
332     }
333 
334     try {
335       list.removeAll(Collections.emptyList());
336       fail();
337     } catch (UnsupportedOperationException e) {
338       // expected
339     }
340 
341     try {
342       list.removeAll(Collections.singleton(1));
343       fail();
344     } catch (UnsupportedOperationException e) {
345       // expected
346     }
347 
348     try {
349       list.removeAll(UNARY_LIST);
350       fail();
351     } catch (UnsupportedOperationException e) {
352       // expected
353     }
354 
355     try {
356       list.retainAll(Collections.emptyList());
357       fail();
358     } catch (UnsupportedOperationException e) {
359       // expected
360     }
361 
362     try {
363       list.retainAll(Collections.singleton(1));
364       fail();
365     } catch (UnsupportedOperationException e) {
366       // expected
367     }
368 
369     try {
370       list.retainAll(UNARY_LIST);
371       fail();
372     } catch (UnsupportedOperationException e) {
373       // expected
374     }
375 
376     try {
377       list.set(0, 0);
378       fail();
379     } catch (UnsupportedOperationException e) {
380       // expected
381     }
382   }
383 
newImmutableProtoArrayList(int... elements)384   private static ProtobufArrayList<Integer> newImmutableProtoArrayList(int... elements) {
385     ProtobufArrayList<Integer> list = new ProtobufArrayList<Integer>();
386     for (int element : elements) {
387       list.add(element);
388     }
389     list.makeImmutable();
390     return list;
391   }
392 }
393