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