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