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
31package com.google.protobuf;
32
33import static java.util.Arrays.asList;
34
35import junit.framework.TestCase;
36
37import java.util.Collections;
38import java.util.ConcurrentModificationException;
39import java.util.Iterator;
40
41/**
42 * Tests for {@link LongArrayList}.
43 *
44 * @author dweis@google.com (Daniel Weis)
45 */
46public class LongArrayListTest extends TestCase {
47
48  private static final LongArrayList UNARY_LIST = newImmutableLongArrayList(1);
49  private static final LongArrayList TERTIARY_LIST =
50      newImmutableLongArrayList(1, 2, 3);
51
52  private LongArrayList list;
53
54  @Override
55  protected void setUp() throws Exception {
56    list = new LongArrayList();
57  }
58
59  public void testEmptyListReturnsSameInstance() {
60    assertSame(LongArrayList.emptyList(), LongArrayList.emptyList());
61  }
62
63  public void testEmptyListIsImmutable() {
64    assertImmutable(LongArrayList.emptyList());
65  }
66
67  public void testMakeImmutable() {
68    list.addLong(2);
69    list.addLong(4);
70    list.addLong(6);
71    list.addLong(8);
72    list.makeImmutable();
73    assertImmutable(list);
74  }
75
76  public void testModificationWithIteration() {
77    list.addAll(asList(1L, 2L, 3L, 4L));
78    Iterator<Long> iterator = list.iterator();
79    assertEquals(4, list.size());
80    assertEquals(1, (long) list.get(0));
81    assertEquals(1, (long) iterator.next());
82    list.set(0, 1L);
83    assertEquals(2, (long) iterator.next());
84
85    list.remove(0);
86    try {
87      iterator.next();
88      fail();
89    } catch (ConcurrentModificationException e) {
90      // expected
91    }
92
93    iterator = list.iterator();
94    list.add(0, 0L);
95    try {
96      iterator.next();
97      fail();
98    } catch (ConcurrentModificationException e) {
99      // expected
100    }
101  }
102
103  public void testGet() {
104    assertEquals(1, (long) TERTIARY_LIST.get(0));
105    assertEquals(2, (long) TERTIARY_LIST.get(1));
106    assertEquals(3, (long) TERTIARY_LIST.get(2));
107
108    try {
109      TERTIARY_LIST.get(-1);
110      fail();
111    } catch (IndexOutOfBoundsException e) {
112      // expected
113    }
114
115    try {
116      TERTIARY_LIST.get(3);
117      fail();
118    } catch (IndexOutOfBoundsException e) {
119      // expected
120    }
121  }
122
123  public void testGetLong() {
124    assertEquals(1, TERTIARY_LIST.getLong(0));
125    assertEquals(2, TERTIARY_LIST.getLong(1));
126    assertEquals(3, TERTIARY_LIST.getLong(2));
127
128    try {
129      TERTIARY_LIST.get(-1);
130      fail();
131    } catch (IndexOutOfBoundsException e) {
132      // expected
133    }
134
135    try {
136      TERTIARY_LIST.get(3);
137      fail();
138    } catch (IndexOutOfBoundsException e) {
139      // expected
140    }
141  }
142
143  public void testSize() {
144    assertEquals(0, LongArrayList.emptyList().size());
145    assertEquals(1, UNARY_LIST.size());
146    assertEquals(3, TERTIARY_LIST.size());
147
148    list.addLong(2);
149    list.addLong(4);
150    list.addLong(6);
151    list.addLong(8);
152    assertEquals(4, list.size());
153
154    list.remove(0);
155    assertEquals(3, list.size());
156
157    list.add(16L);
158    assertEquals(4, list.size());
159  }
160
161  public void testSet() {
162    list.addLong(2);
163    list.addLong(4);
164
165    assertEquals(2, (long) list.set(0, 0L));
166    assertEquals(0, list.getLong(0));
167
168    assertEquals(4, (long) list.set(1, 0L));
169    assertEquals(0, list.getLong(1));
170
171    try {
172      list.set(-1, 0L);
173      fail();
174    } catch (IndexOutOfBoundsException e) {
175      // expected
176    }
177
178    try {
179      list.set(2, 0L);
180      fail();
181    } catch (IndexOutOfBoundsException e) {
182      // expected
183    }
184  }
185
186  public void testSetLong() {
187    list.addLong(2);
188    list.addLong(4);
189
190    assertEquals(2, list.setLong(0, 0));
191    assertEquals(0, list.getLong(0));
192
193    assertEquals(4, list.setLong(1, 0));
194    assertEquals(0, list.getLong(1));
195
196    try {
197      list.setLong(-1, 0);
198      fail();
199    } catch (IndexOutOfBoundsException e) {
200      // expected
201    }
202
203    try {
204      list.setLong(2, 0);
205      fail();
206    } catch (IndexOutOfBoundsException e) {
207      // expected
208    }
209  }
210
211  public void testAdd() {
212    assertEquals(0, list.size());
213
214    assertTrue(list.add(2L));
215    assertEquals(asList(2L), list);
216
217    assertTrue(list.add(3L));
218    list.add(0, 4L);
219    assertEquals(asList(4L, 2L, 3L), list);
220
221    list.add(0, 1L);
222    list.add(0, 0L);
223    // Force a resize by getting up to 11 elements.
224    for (int i = 0; i < 6; i++) {
225      list.add(Long.valueOf(5 + i));
226    }
227    assertEquals(asList(0L, 1L, 4L, 2L, 3L, 5L, 6L, 7L, 8L, 9L, 10L), list);
228
229    try {
230      list.add(-1, 5L);
231    } catch (IndexOutOfBoundsException e) {
232      // expected
233    }
234
235    try {
236      list.add(4, 5L);
237    } catch (IndexOutOfBoundsException e) {
238      // expected
239    }
240  }
241
242  public void testAddLong() {
243    assertEquals(0, list.size());
244
245    list.addLong(2);
246    assertEquals(asList(2L), list);
247
248    list.addLong(3);
249    assertEquals(asList(2L, 3L), list);
250  }
251
252  public void testAddAll() {
253    assertEquals(0, list.size());
254
255    assertTrue(list.addAll(Collections.singleton(1L)));
256    assertEquals(1, list.size());
257    assertEquals(1, (long) list.get(0));
258    assertEquals(1, list.getLong(0));
259
260    assertTrue(list.addAll(asList(2L, 3L, 4L, 5L, 6L)));
261    assertEquals(asList(1L, 2L, 3L, 4L, 5L, 6L), list);
262
263    assertTrue(list.addAll(TERTIARY_LIST));
264    assertEquals(asList(1L, 2L, 3L, 4L, 5L, 6L, 1L, 2L, 3L), list);
265
266    assertFalse(list.addAll(Collections.<Long>emptyList()));
267    assertFalse(list.addAll(LongArrayList.emptyList()));
268  }
269
270  public void testRemove() {
271    list.addAll(TERTIARY_LIST);
272    assertEquals(1, (long) list.remove(0));
273    assertEquals(asList(2L, 3L), list);
274
275    assertTrue(list.remove(3L));
276    assertEquals(asList(2L), list);
277
278    assertFalse(list.remove(3L));
279    assertEquals(asList(2L), list);
280
281    assertEquals(2, (long) list.remove(0));
282    assertEquals(asList(), list);
283
284    try {
285      list.remove(-1);
286      fail();
287    } catch (IndexOutOfBoundsException e) {
288      // expected
289    }
290
291    try {
292      list.remove(0);
293    } catch (IndexOutOfBoundsException e) {
294      // expected
295    }
296  }
297
298  private void assertImmutable(LongArrayList list) {
299    if (list.contains(1L)) {
300      throw new RuntimeException("Cannot test the immutability of lists that contain 1.");
301    }
302
303    try {
304      list.add(1L);
305      fail();
306    } catch (UnsupportedOperationException e) {
307      // expected
308    }
309
310    try {
311      list.add(0, 1L);
312      fail();
313    } catch (UnsupportedOperationException e) {
314      // expected
315    }
316
317    try {
318      list.addAll(Collections.<Long>emptyList());
319      fail();
320    } catch (UnsupportedOperationException e) {
321      // expected
322    }
323
324    try {
325      list.addAll(Collections.singletonList(1L));
326      fail();
327    } catch (UnsupportedOperationException e) {
328      // expected
329    }
330
331    try {
332      list.addAll(new LongArrayList());
333      fail();
334    } catch (UnsupportedOperationException e) {
335      // expected
336    }
337
338    try {
339      list.addAll(UNARY_LIST);
340      fail();
341    } catch (UnsupportedOperationException e) {
342      // expected
343    }
344
345    try {
346      list.addAll(0, Collections.singleton(1L));
347      fail();
348    } catch (UnsupportedOperationException e) {
349      // expected
350    }
351
352    try {
353      list.addAll(0, UNARY_LIST);
354      fail();
355    } catch (UnsupportedOperationException e) {
356      // expected
357    }
358
359    try {
360      list.addAll(0, Collections.<Long>emptyList());
361      fail();
362    } catch (UnsupportedOperationException e) {
363      // expected
364    }
365
366    try {
367      list.addLong(0);
368      fail();
369    } catch (UnsupportedOperationException e) {
370      // expected
371    }
372
373    try {
374      list.clear();
375      fail();
376    } catch (UnsupportedOperationException e) {
377      // expected
378    }
379
380    try {
381      list.remove(1);
382      fail();
383    } catch (UnsupportedOperationException e) {
384      // expected
385    }
386
387    try {
388      list.remove(new Object());
389      fail();
390    } catch (UnsupportedOperationException e) {
391      // expected
392    }
393
394    try {
395      list.removeAll(Collections.<Long>emptyList());
396      fail();
397    } catch (UnsupportedOperationException e) {
398      // expected
399    }
400
401    try {
402      list.removeAll(Collections.singleton(1L));
403      fail();
404    } catch (UnsupportedOperationException e) {
405      // expected
406    }
407
408    try {
409      list.removeAll(UNARY_LIST);
410      fail();
411    } catch (UnsupportedOperationException e) {
412      // expected
413    }
414
415    try {
416      list.retainAll(Collections.<Long>emptyList());
417      fail();
418    } catch (UnsupportedOperationException e) {
419      // expected
420    }
421
422    try {
423      list.retainAll(Collections.singleton(1L));
424      fail();
425    } catch (UnsupportedOperationException e) {
426      // expected
427    }
428
429    try {
430      list.retainAll(UNARY_LIST);
431      fail();
432    } catch (UnsupportedOperationException e) {
433      // expected
434    }
435
436    try {
437      list.set(0, 0L);
438      fail();
439    } catch (UnsupportedOperationException e) {
440      // expected
441    }
442
443    try {
444      list.setLong(0, 0);
445      fail();
446    } catch (UnsupportedOperationException e) {
447      // expected
448    }
449  }
450
451  private static LongArrayList newImmutableLongArrayList(long... elements) {
452    LongArrayList list = new LongArrayList();
453    for (long element : elements) {
454      list.addLong(element);
455    }
456    list.makeImmutable();
457    return list;
458  }
459}
460