1 /*
   2  * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package javafx.collections;
  27 
  28 import org.junit.Before;
  29 import org.junit.Test;
  30 
  31 import java.util.Arrays;
  32 import java.util.Collection;
  33 import java.util.Collections;
  34 import java.util.List;
  35 import javafx.beans.InvalidationListener;
  36 
  37 import static org.junit.Assert.*;
  38 import org.junit.Ignore;
  39 import org.junit.runner.RunWith;
  40 import org.junit.runners.Parameterized;
  41 
  42 /**
  43  * Tests for ObservableArray.
  44  */
  45 @RunWith(Parameterized.class)
  46 public class ObservableArrayTest  {
  47     public static final int INITIAL_SIZE = 6;
  48 
  49     /**
  50      * @param <T> ObservableArray subclass
  51      * @param <A> corresponding primitive array
  52      * @param <P> corresponding class for boxed elements
  53      */
  54     public static abstract class ArrayWrapper<T extends ObservableArray<T>, A, P> {
  55 
  56         T array;
  57         final T array() {
  58             return array;
  59         }
  60 
  61         abstract T createEmptyArray();
  62         abstract T createNotEmptyArray(A src);
  63         abstract ArrayWrapper<T, A, P> newInstance();
  64         abstract P getNextValue();
  65         abstract void set(int index, P value);
  66         abstract void setAllA(A src);
  67         abstract void setAllT(T src);
  68         abstract void setAllA(A src, int srcIndex, int length);
  69         abstract void setAllT(T src, int srcIndex, int length);
  70         abstract void addAllA(A src);
  71         abstract void addAllT(T src);
  72         abstract void addAllA(A src, int srcIndex, int length);
  73         abstract void addAllT(T src, int srcIndex, int length);
  74         abstract void setA(int destIndex, A src, int srcIndex, int length);
  75         abstract void setT(int destIndex, T src, int srcIndex, int length);
  76         abstract void copyToA(int srcIndex, A dest, int destIndex, int length);
  77         abstract void copyToT(int srcIndex, T dest, int destIndex, int length);
  78         abstract P get(int index);
  79         abstract A toArray(A dest);
  80         abstract A toArray(int srcIndex, A dest, int length);
  81 
  82         A createPrimitiveArray(int size) {
  83             return createPrimitiveArray(size, true);
  84         }
  85         abstract A createPrimitiveArray(int size, boolean fillWithData);
  86         abstract A clonePrimitiveArray(A array);
  87         abstract int arrayLength(A array);
  88         abstract P get(A array, int index);
  89         abstract void assertElementsEqual(A actual, int from, int to, A expected, int expFrom);
  90         abstract String primitiveArrayToString(A array);
  91     }
  92 
  93     private static class IntegerArrayWrapper extends ArrayWrapper<ObservableIntegerArray, int[], Integer> {
  94 
  95         int nextValue = 0;
  96 
  97         @Override IntegerArrayWrapper newInstance() {
  98             return new IntegerArrayWrapper();
  99         }
 100 
 101         @Override ObservableIntegerArray createEmptyArray() {
 102             return array = FXCollections.observableIntegerArray();
 103         }
 104 
 105         @Override ObservableIntegerArray createNotEmptyArray(int[] src) {
 106             return array = FXCollections.observableIntegerArray(src);
 107         }
 108 
 109         @Override Integer getNextValue() {
 110             return nextValue++;
 111         }
 112 
 113         @Override void set(int index, Integer value) {
 114             array.set(index, value);
 115         }
 116 
 117         @Override int[] createPrimitiveArray(int size, boolean fillWithData) {
 118             int[] res = new int[size];
 119             if (fillWithData) {
 120                 for (int i = 0; i < size; i++) {
 121                     res[i] = nextValue++;
 122                 }
 123             }
 124             return res;
 125         }
 126 
 127         @Override void setAllA(int[] src) {
 128             array.setAll(src);
 129         }
 130 
 131         @Override void setAllA(int[] src, int srcIndex, int length) {
 132             array.setAll(src, srcIndex, length);
 133         }
 134 
 135         @Override void setAllT(ObservableIntegerArray src) {
 136             array.setAll(src);
 137         }
 138 
 139         @Override void setAllT(ObservableIntegerArray src, int srcIndex, int length) {
 140             array.setAll(src, srcIndex, length);
 141         }
 142 
 143         @Override void addAllA(int[] src) {
 144             array.addAll(src);
 145         }
 146 
 147         @Override void addAllA(int[] src, int srcIndex, int length) {
 148             array.addAll(src, srcIndex, length);
 149         }
 150 
 151         @Override void addAllT(ObservableIntegerArray src) {
 152             array.addAll(src);
 153         }
 154 
 155         @Override void addAllT(ObservableIntegerArray src, int srcIndex, int length) {
 156             array.addAll(src, srcIndex, length);
 157         }
 158 
 159         @Override void copyToA(int srcIndex, int[] dest, int destIndex, int length) {
 160             array.copyTo(srcIndex, dest, destIndex, length);
 161         }
 162 
 163         @Override void copyToT(int srcIndex, ObservableIntegerArray dest, int destIndex, int length) {
 164             array.copyTo(srcIndex, dest, destIndex, length);
 165         }
 166 
 167         @Override Integer get(int index) {
 168             return array.get(index);
 169         }
 170 
 171         @Override int[] toArray(int[] src) {
 172             return array.toArray(src);
 173         }
 174 
 175         @Override int[] toArray(int srcIndex, int[] dest, int length) {
 176             return array.toArray(srcIndex, dest, length);
 177         }
 178 
 179         @Override void setA(int destIndex, int[] src, int srcIndex, int length) {
 180             array.set(destIndex, src, srcIndex, length);
 181         }
 182 
 183         @Override void setT(int destIndex, ObservableIntegerArray src, int srcIndex, int length) {
 184             array.set(destIndex, src, srcIndex, length);
 185         }
 186 
 187         @Override int arrayLength(int[] array) {
 188             return array.length;
 189         }
 190 
 191         @Override
 192         Integer get(int[] array, int index) {
 193             return array[index];
 194         }
 195 
 196         @Override
 197         void assertElementsEqual(int[] actual, int from, int to, int[] expected, int expFrom) {
 198             for(int i = from, j = expFrom; i < to; i++, j++) {
 199                 assertEquals(actual[i], expected[j]);
 200             }
 201         }
 202 
 203         @Override int[] clonePrimitiveArray(int[] array) {
 204             return Arrays.copyOf(array, array.length);
 205         }
 206 
 207         @Override
 208         String primitiveArrayToString(int[] array) {
 209             return Arrays.toString(array);
 210         }
 211     }
 212 
 213     private static class FloatArrayWrapper extends ArrayWrapper<ObservableFloatArray, float[], Float> {
 214 
 215         float nextValue = 0;
 216 
 217         @Override FloatArrayWrapper newInstance() {
 218             return new FloatArrayWrapper();
 219         }
 220 
 221         @Override ObservableFloatArray createEmptyArray() {
 222             return array = FXCollections.observableFloatArray();
 223         }
 224 
 225         @Override ObservableFloatArray createNotEmptyArray(float[] elements) {
 226             return array = FXCollections.observableFloatArray(elements);
 227         }
 228 
 229         @Override
 230         Float getNextValue() {
 231             return nextValue++;
 232         }
 233 
 234         @Override void set(int index, Float value) {
 235             array.set(index, value);
 236         }
 237 
 238         @Override float[] createPrimitiveArray(int size, boolean fillWithData) {
 239             float[] res = new float[size];
 240             if (fillWithData) {
 241                 for (int i = 0; i < size; i++) {
 242                     res[i] = nextValue++;
 243                 }
 244             }
 245             return res;
 246         }
 247 
 248         @Override void setAllA(float[] src) {
 249             array.setAll(src);
 250         }
 251 
 252         @Override void copyToA(int srcIndex, float[] dest, int destIndex, int length) {
 253             array.copyTo(srcIndex, dest, destIndex, length);
 254         }
 255 
 256         @Override void copyToT(int srcIndex, ObservableFloatArray dest, int destIndex, int length) {
 257             array.copyTo(srcIndex, dest, destIndex, length);
 258         }
 259 
 260         @Override Float get(int index) {
 261             return array.get(index);
 262         }
 263 
 264         @Override float[] toArray(float[] dest) {
 265             return array.toArray(dest);
 266         }
 267 
 268         @Override float[] toArray(int srcIndex, float[] dest, int length) {
 269             return array.toArray(srcIndex, dest, length);
 270         }
 271 
 272         @Override void setA(int destIndex, float[] src, int srcIndex, int length) {
 273             array.set(destIndex, src, srcIndex, length);
 274         }
 275 
 276         @Override int arrayLength(float[] array) {
 277             return array.length;
 278         }
 279 
 280         @Override
 281         Float get(float[] array, int index) {
 282             return array[index];
 283         }
 284 
 285         @Override
 286         void assertElementsEqual(float[] actual, int from, int to, float[] expected, int expFrom) {
 287             for(int i = from, j = expFrom; i < to; i++, j++) {
 288                 assertEquals("expected float = " + expected[j] + ", actual float = " + actual[i],
 289                         Float.floatToRawIntBits(expected[j]),
 290                         Float.floatToRawIntBits(actual[i]));
 291             }
 292         }
 293 
 294         @Override float[] clonePrimitiveArray(float[] array) {
 295             return Arrays.copyOf(array, array.length);
 296         }
 297 
 298         @Override void setAllT(ObservableFloatArray src) {
 299             array.setAll(src);
 300         }
 301 
 302         @Override void setAllA(float[] src, int srcIndex, int length) {
 303             array.setAll(src, srcIndex, length);
 304         }
 305 
 306         @Override void setAllT(ObservableFloatArray src, int srcIndex, int length) {
 307             array.setAll(src, srcIndex, length);
 308         }
 309 
 310         @Override void addAllA(float[] src) {
 311             array.addAll(src);
 312         }
 313 
 314         @Override void addAllT(ObservableFloatArray src) {
 315             array.addAll(src);
 316         }
 317 
 318         @Override void addAllA(float[] src, int srcIndex, int length) {
 319             array.addAll(src, srcIndex, length);
 320         }
 321 
 322         @Override void addAllT(ObservableFloatArray src, int srcIndex, int length) {
 323             array.addAll(src, srcIndex, length);
 324         }
 325 
 326         @Override void setT(int destIndex, ObservableFloatArray src, int srcIndex, int length) {
 327             array.set(destIndex, src, srcIndex, length);
 328         }
 329 
 330         @Override
 331         String primitiveArrayToString(float[] array) {
 332             return Arrays.toString(array);
 333         }
 334     }
 335 
 336     static final List<String> EMPTY = Collections.emptyList();
 337     final ArrayWrapper wrapper;
 338     private int initialSize;
 339     private Object initialElements;
 340     private ObservableArray array;
 341     private MockArrayObserver mao;
 342 
 343     public ObservableArrayTest(final ArrayWrapper arrayWrapper) {
 344         this.wrapper = arrayWrapper;
 345     }
 346 
 347     @Parameterized.Parameters
 348     public static Collection createParameters() {
 349         Object[][] data = new Object[][] {
 350             { new FloatArrayWrapper() },
 351             { new IntegerArrayWrapper() },
 352          };
 353         return Arrays.asList(data);
 354     }
 355 
 356     @Before
 357     public void setUp() throws Exception {
 358         initialSize = INITIAL_SIZE;
 359         initialElements = wrapper.createPrimitiveArray(initialSize);
 360         array = wrapper.createNotEmptyArray(initialElements);
 361         mao = new MockArrayObserver();
 362         array.addListener(mao);
 363     }
 364 
 365     private void makeEmpty() {
 366         initialSize = 0;
 367         initialElements = wrapper.createPrimitiveArray(initialSize);
 368         array.clear();
 369         mao.reset();
 370     }
 371 
 372     private void assertUnchanged() {
 373         mao.check0();
 374         assertEquals(initialSize, array.size());
 375         Object actual = wrapper.toArray(null);
 376         assertEquals(initialSize, wrapper.arrayLength(actual));
 377         wrapper.assertElementsEqual(actual, 0, array.size(), initialElements, 0);
 378     }
 379 
 380     // ========== pre-condition tests ================
 381 
 382     @Test public void testSize() {
 383         mao.check0();
 384         assertEquals(INITIAL_SIZE, array.size());
 385     }
 386 
 387     @Test public void testClear() {
 388         array.clear();
 389         mao.checkOnlySizeChanged(array);
 390         assertEquals(0, array.size());
 391     }
 392 
 393     @Test public void testGet() {
 394         for (int i = 0; i < array.size(); i++) {
 395             Object expected = wrapper.get(initialElements, i);
 396             Object actural = wrapper.get(i);
 397             assertEquals(expected, actural);
 398         }
 399         assertUnchanged();
 400     }
 401 
 402     @Test public void testToArray() {
 403         Object expected = initialElements;
 404         Object actual = wrapper.toArray(null);
 405         assertEquals(INITIAL_SIZE, wrapper.arrayLength(actual));
 406         wrapper.assertElementsEqual(actual, 0, array.size(), expected, 0);
 407         assertUnchanged();
 408     }
 409 
 410     // ========== add/remove listener tests ==========
 411 
 412     @Test public void testAddRemoveListener() {
 413         MockArrayObserver mao2 = new MockArrayObserver();
 414         array.addListener(mao2);
 415         array.removeListener(mao);
 416         wrapper.set(0, wrapper.getNextValue());
 417         mao.check0();
 418         mao2.check(array, false, 0, 1);
 419     }
 420 
 421     @Test public void testAddTwoListenersElementChange() {
 422         MockArrayObserver mao2 = new MockArrayObserver();
 423         array.addListener(mao2);
 424         wrapper.set(0, wrapper.getNextValue());
 425         mao.check(array, false, 0, 1);
 426         mao2.check(array, false, 0, 1);
 427     }
 428 
 429     @Test public void testAddTwoListenersSizeChange() {
 430         MockArrayObserver mao2 = new MockArrayObserver();
 431         array.addListener(mao2);
 432         array.resize(3);
 433         mao.checkOnlySizeChanged(array);
 434         mao2.checkOnlySizeChanged(array);
 435     }
 436 
 437     @Test public void testAddThreeListeners() {
 438         MockArrayObserver mao2 = new MockArrayObserver();
 439         MockArrayObserver mao3 = new MockArrayObserver();
 440         array.addListener(mao2);
 441         array.addListener(mao3);
 442         wrapper.set(0, wrapper.getNextValue());
 443         mao.check(array, false, 0, 1);
 444         mao2.check(array, false, 0, 1);
 445         mao3.check(array, false, 0, 1);
 446     }
 447 
 448     @Test public void testAddThreeListenersSizeChange() {
 449         MockArrayObserver mao2 = new MockArrayObserver();
 450         MockArrayObserver mao3 = new MockArrayObserver();
 451         array.addListener(mao2);
 452         array.addListener(mao3);
 453         array.resize(10);
 454         mao.checkOnlySizeChanged(array);
 455         mao2.checkOnlySizeChanged(array);
 456         mao3.checkOnlySizeChanged(array);
 457     }
 458 
 459     @Test @Ignore
 460     public void testAddListenerTwice() {
 461         array.addListener(mao); // add it a second time
 462         wrapper.set(1, wrapper.getNextValue());
 463         mao.check(array, false, 1, 2);
 464     }
 465 
 466     @Test public void testRemoveListenerTwice() {
 467         array.removeListener(mao);
 468         array.removeListener(mao);
 469         wrapper.set(1, wrapper.getNextValue());
 470         mao.check0();
 471     }
 472 
 473     @Test (expected = NullPointerException.class)
 474     public void testAddNullArrayChangeListener() {
 475         try {
 476             array.addListener((ArrayChangeListener) null);
 477         } finally {
 478             mao.check0();
 479             array.resize(1);
 480             mao.check1();
 481         }
 482     }
 483 
 484     @Test (expected = NullPointerException.class)
 485     public void testAddNullInvalidationListener() {
 486         try {
 487             array.addListener((InvalidationListener) null);
 488         } finally {
 489             mao.check0();
 490             array.resize(1);
 491             mao.check1();
 492         }
 493     }
 494 
 495     @Test (expected = NullPointerException.class)
 496     public void testRemoveNullArrayChangeListener() {
 497         try {
 498             array.removeListener((ArrayChangeListener) null);
 499         } finally {
 500             mao.check0();
 501             array.resize(1);
 502             mao.check1();
 503         }
 504     }
 505 
 506     @Test (expected = NullPointerException.class)
 507     public void testRemoveNullInvalidationListener() {
 508         try {
 509             array.removeListener((InvalidationListener) null);
 510         } finally {
 511             mao.check0();
 512             array.resize(1);
 513             mao.check1();
 514         }
 515     }
 516 
 517     // ========== resize tests ==========
 518 
 519     private void testResize(boolean noChange, int newSize, int matchingElements) {
 520         Object expected = wrapper.toArray(null);
 521         array.resize(newSize);
 522         if (noChange) {
 523             assertUnchanged();
 524         } else {
 525             mao.checkOnlySizeChanged(array);
 526         }
 527         Object actual = wrapper.toArray(null);
 528         assertEquals(newSize, array.size());
 529         assertEquals(newSize, wrapper.arrayLength(actual));
 530         wrapper.assertElementsEqual(actual, 0, matchingElements, expected, 0);
 531         wrapper.assertElementsEqual(actual, matchingElements, newSize,
 532                 wrapper.createPrimitiveArray(Math.max(0, newSize - matchingElements), false), 0);
 533     }
 534 
 535     @Test public void testResizeTo0() {
 536         testResize(false, 0, 0);
 537     }
 538 
 539     @Test public void testResizeToSmaller() {
 540         testResize(false, 3, 3);
 541     }
 542 
 543     @Test public void testResizeToSameSize() {
 544         testResize(true, array.size(), array.size());
 545     }
 546 
 547     @Test public void testResizeToBigger() {
 548         testResize(false, 10, array.size());
 549     }
 550 
 551     @Test public void testResizeOnEmpty() {
 552         makeEmpty();
 553         testResize(false, 10, 0);
 554     }
 555 
 556     @Test public void testResizeOnEmptyToEmpty() {
 557         makeEmpty();
 558         testResize(true, 0, 0);
 559     }
 560 
 561     @Test (expected = NegativeArraySizeException.class)
 562     public void testResizeToNegative() {
 563         try {
 564             array.resize(-5);
 565         } finally {
 566             assertUnchanged();
 567         }
 568     }
 569 
 570     // ========== setAll(primitive array) tests ==========
 571 
 572     private void testSetAllA(boolean sizeChanged, int newSize) {
 573         Object expected = wrapper.createPrimitiveArray(newSize);
 574 
 575         wrapper.setAllA(expected);
 576 
 577         mao.check(array, sizeChanged, 0, newSize);
 578         Object actual = wrapper.toArray(null);
 579         assertEquals(wrapper.arrayLength(expected), array.size());
 580         assertEquals(wrapper.arrayLength(expected), wrapper.arrayLength(actual));
 581         wrapper.assertElementsEqual(actual, 0, wrapper.arrayLength(expected), expected, 0);
 582     }
 583 
 584     @Test public void testSetAllASmaller() {
 585         testSetAllA(true, 3);
 586     }
 587 
 588     @Test public void testSetAllABigger() {
 589         testSetAllA(true, 10);
 590     }
 591 
 592     @Test public void testSetAllAOnSameSize() {
 593         testSetAllA(false, INITIAL_SIZE);
 594     }
 595 
 596     @Test public void testSetAllAOnEmpty() {
 597         makeEmpty();
 598         testSetAllA(true, 3);
 599     }
 600 
 601     @Test public void testSetAllAOnEmptyToEmpty() {
 602         makeEmpty();
 603         wrapper.setAllA(wrapper.createPrimitiveArray(0));
 604         assertUnchanged();
 605         assertEquals(0, array.size());
 606     }
 607 
 608     @Test (expected = NullPointerException.class)
 609     public void testSetAllAToNull() {
 610         try {
 611             wrapper.setAllA(null);
 612         } finally {
 613             assertUnchanged();
 614         }
 615     }
 616 
 617     // ========== setAll(ObservableArray) tests ==========
 618 
 619     private void testSetAllT(boolean sizeChanged, int newSize) {
 620         ArrayWrapper wrapper2 = wrapper.newInstance();
 621         Object expected = wrapper.createPrimitiveArray(newSize);
 622         ObservableArray src = wrapper2.createNotEmptyArray(expected);
 623 
 624         wrapper.setAllT(src);
 625 
 626         mao.check(array, sizeChanged, 0, newSize);
 627         Object actual = wrapper.toArray(null);
 628         assertEquals(wrapper.arrayLength(expected), array.size());
 629         assertEquals(wrapper.arrayLength(expected), wrapper.arrayLength(actual));
 630         wrapper.assertElementsEqual(actual, 0, wrapper.arrayLength(expected), expected, 0);
 631     }
 632 
 633     @Test public void testSetAllTSmaller() {
 634         testSetAllT(true, 3);
 635     }
 636 
 637     @Test public void testSetAllTBigger() {
 638         testSetAllT(true, 10);
 639     }
 640 
 641     @Test public void testSetAllTOnSameSize() {
 642         testSetAllT(false, INITIAL_SIZE);
 643     }
 644 
 645     @Test public void testSetAllTOnEmpty() {
 646         makeEmpty();
 647         testSetAllT(true, 3);
 648     }
 649 
 650     @Test public void testSetAllTOnEmptyToEmpty() {
 651         makeEmpty();
 652         wrapper.setAllT(wrapper.newInstance().createEmptyArray());
 653         assertUnchanged();
 654         assertEquals(0, array.size());
 655     }
 656 
 657     @Test (expected = NullPointerException.class)
 658     public void testSetAllTToNull() {
 659         try {
 660             wrapper.setAllT(null);
 661         } finally {
 662             assertUnchanged();
 663         }
 664     }
 665 
 666     @Test public void testSetAllTSelf() {
 667 
 668         wrapper.setAllT(array);
 669 
 670         mao.check0();
 671         Object actual = wrapper.toArray(null);
 672         assertEquals(initialSize, array.size());
 673         assertEquals(initialSize, wrapper.arrayLength(actual));
 674         wrapper.assertElementsEqual(actual, 0, initialSize, initialElements, 0);
 675     }
 676 
 677     @Test public void testSetAllTSelfEmpty() {
 678         makeEmpty();
 679 
 680         wrapper.setAllT(array);
 681 
 682         mao.check0();
 683         Object actual = wrapper.toArray(null);
 684         assertEquals(0, array.size());
 685         assertEquals(0, wrapper.arrayLength(actual));
 686     }
 687 
 688     // ========== setAll(primitive array, range) tests ==========
 689 
 690     private void testSetAllARange(boolean sizeChanged, int newSize, int srcIndex, int length) {
 691         Object expected = wrapper.createPrimitiveArray(newSize);
 692 
 693         wrapper.setAllA(expected, srcIndex, length);
 694 
 695         mao.check(array, sizeChanged, 0, length);
 696         Object actual = wrapper.toArray(null);
 697         assertEquals(length, array.size());
 698         assertEquals(length, wrapper.arrayLength(actual));
 699         wrapper.assertElementsEqual(actual, 0, length, expected, srcIndex);
 700     }
 701 
 702     @Test public void testSetAllARange1() {
 703         testSetAllARange(false, INITIAL_SIZE, 0, INITIAL_SIZE);
 704     }
 705 
 706     @Test public void testSetAllARange2() {
 707         testSetAllARange(false, INITIAL_SIZE + 10, 0, INITIAL_SIZE);
 708     }
 709 
 710     @Test public void testSetAllARange3() {
 711         testSetAllARange(false, INITIAL_SIZE + 10, 10, INITIAL_SIZE);
 712     }
 713 
 714     @Test public void testSetAllARange4() {
 715         testSetAllARange(false, INITIAL_SIZE + 10, 2, INITIAL_SIZE);
 716     }
 717 
 718     @Test public void testSetAllARange5() {
 719         testSetAllARange(true, INITIAL_SIZE, 0, INITIAL_SIZE / 2);
 720     }
 721 
 722     @Test public void testSetAllARange6() {
 723         testSetAllARange(true, INITIAL_SIZE + 10, 0, INITIAL_SIZE + 10);
 724     }
 725 
 726     @Test public void testSetAllARange7() {
 727         testSetAllARange(true, INITIAL_SIZE + 20, 10, INITIAL_SIZE + 10);
 728     }
 729 
 730     @Test public void testSetAllARange8() {
 731         testSetAllARange(true, INITIAL_SIZE + 10, 2, INITIAL_SIZE - 3);
 732     }
 733 
 734     @Test public void testSetAllARangeOnEmpty() {
 735         makeEmpty();
 736         testSetAllARange(true, INITIAL_SIZE, 1, 3);
 737     }
 738 
 739     @Test public void testSetAllARangeOnEmptyToEmpty() {
 740         makeEmpty();
 741         wrapper.setAllA(wrapper.createPrimitiveArray(INITIAL_SIZE), 1, 0);
 742         assertUnchanged();
 743     }
 744 
 745     @Test (expected = NullPointerException.class)
 746     public void testSetAllARangeToNull() {
 747         try {
 748             wrapper.setAllA(null, 0, 0);
 749         } finally {
 750             assertUnchanged();
 751         }
 752     }
 753 
 754     @Test (expected = ArrayIndexOutOfBoundsException.class)
 755     public void testSetAllARangeNegative1() {
 756         try {
 757             testSetAllARange(true, INITIAL_SIZE, -1, INITIAL_SIZE);
 758         } finally {
 759             assertUnchanged();
 760         }
 761     }
 762 
 763     @Test (expected = ArrayIndexOutOfBoundsException.class)
 764     public void testSetAllARangeNegative2() {
 765         try {
 766             testSetAllARange(true, INITIAL_SIZE, 0, INITIAL_SIZE + 1);
 767         } finally {
 768             assertUnchanged();
 769         }
 770     }
 771 
 772     @Test (expected = ArrayIndexOutOfBoundsException.class)
 773     public void testSetAllARangeNegative3() {
 774         try {
 775             testSetAllARange(true, INITIAL_SIZE, 1, -1);
 776         } finally {
 777             assertUnchanged();
 778         }
 779     }
 780 
 781     @Test (expected = ArrayIndexOutOfBoundsException.class)
 782     public void testSetAllARangeNegative4() {
 783         try {
 784             testSetAllARange(true, INITIAL_SIZE, INITIAL_SIZE, 1);
 785         } finally {
 786             assertUnchanged();
 787         }
 788     }
 789 
 790     // ========== setAll(observable array, range) tests ==========
 791 
 792     private void testSetAllTRange(boolean sizeChanged, int srcSize, int srcIndex, int length) {
 793         Object expected = wrapper.createPrimitiveArray(srcSize);
 794         ObservableArray src = wrapper.newInstance().createNotEmptyArray(expected);
 795 
 796         wrapper.setAllT(src, srcIndex, length);
 797 
 798         mao.check(array, sizeChanged, 0, length);
 799         Object actual = wrapper.toArray(null);
 800         assertEquals(length, array.size());
 801         assertEquals(length, wrapper.arrayLength(actual));
 802         wrapper.assertElementsEqual(actual, 0, length, expected, srcIndex);
 803     }
 804 
 805     @Test public void testSetAllTRange1() {
 806         testSetAllTRange(false, INITIAL_SIZE, 0, INITIAL_SIZE);
 807     }
 808 
 809     @Test public void testSetAllTRange2() {
 810         testSetAllTRange(false, INITIAL_SIZE + 10, 0, INITIAL_SIZE);
 811     }
 812 
 813     @Test public void testSetAllTRange3() {
 814         testSetAllTRange(false, INITIAL_SIZE + 10, 10, INITIAL_SIZE);
 815     }
 816 
 817     @Test public void testSetAllTRange4() {
 818         testSetAllTRange(false, INITIAL_SIZE + 10, 2, INITIAL_SIZE);
 819     }
 820 
 821     @Test public void testSetAllTRange5() {
 822         testSetAllTRange(true, INITIAL_SIZE, 0, INITIAL_SIZE / 2);
 823     }
 824 
 825     @Test public void testSetAllTRange6() {
 826         testSetAllTRange(true, INITIAL_SIZE + 10, 0, INITIAL_SIZE + 10);
 827     }
 828 
 829     @Test public void testSetAllTRange7() {
 830         testSetAllTRange(true, INITIAL_SIZE + 20, 10, INITIAL_SIZE + 10);
 831     }
 832 
 833     @Test public void testSetAllTRange8() {
 834         testSetAllTRange(true, INITIAL_SIZE + 10, 2, INITIAL_SIZE - 3);
 835     }
 836 
 837     @Test public void testSetAllTRangeOnEmpty() {
 838         makeEmpty();
 839         testSetAllTRange(true, INITIAL_SIZE, 1, 3);
 840     }
 841 
 842     @Test public void testSetAllTRangeOnEmptyToEmpty() {
 843         makeEmpty();
 844         wrapper.setAllT(wrapper.newInstance().createNotEmptyArray(wrapper.createPrimitiveArray(INITIAL_SIZE)), 1, 0);
 845         assertUnchanged();
 846     }
 847 
 848     @Test (expected = NullPointerException.class)
 849     public void testSetAllTRangeToNull() {
 850         try {
 851             wrapper.setAllT(null, 0, 0);
 852         } finally {
 853             assertUnchanged();
 854         }
 855     }
 856 
 857     @Test (expected = ArrayIndexOutOfBoundsException.class)
 858     public void testSetAllTRangeNegative1() {
 859         try {
 860             testSetAllTRange(true, INITIAL_SIZE, -1, INITIAL_SIZE);
 861         } finally {
 862             assertUnchanged();
 863         }
 864     }
 865 
 866     @Test (expected = ArrayIndexOutOfBoundsException.class)
 867     public void testSetAllTRangeNegative2() {
 868         try {
 869             testSetAllTRange(true, INITIAL_SIZE, 0, INITIAL_SIZE + 1);
 870         } finally {
 871             assertUnchanged();
 872         }
 873     }
 874 
 875     @Test (expected = ArrayIndexOutOfBoundsException.class)
 876     public void testSetAllTRangeNegative3() {
 877         try {
 878             testSetAllTRange(true, INITIAL_SIZE, 1, -1);
 879         } finally {
 880             assertUnchanged();
 881         }
 882     }
 883 
 884     @Test (expected = ArrayIndexOutOfBoundsException.class)
 885     public void testSetAllTRangeNegative4() {
 886         try {
 887             testSetAllTRange(true, INITIAL_SIZE, INITIAL_SIZE, 1);
 888         } finally {
 889             assertUnchanged();
 890         }
 891     }
 892 
 893     @Test (expected = ArrayIndexOutOfBoundsException.class)
 894     public void testSetAllTRangeNegativeAfterSrcEnsureCapacity() {
 895         Object expected = wrapper.createPrimitiveArray(INITIAL_SIZE);
 896         ObservableArray src = wrapper.newInstance().createNotEmptyArray(expected);
 897         src.ensureCapacity(INITIAL_SIZE * 2);
 898         try {
 899             wrapper.setAllT(src, INITIAL_SIZE, 1);
 900         } finally {
 901             assertUnchanged();
 902         }
 903     }
 904 
 905     @Test (expected = ArrayIndexOutOfBoundsException.class)
 906     public void testSetAllTRangeNegativeAfterSrcClear() {
 907         Object expected = wrapper.createPrimitiveArray(INITIAL_SIZE);
 908         ObservableArray src = wrapper.newInstance().createNotEmptyArray(expected);
 909         src.clear();
 910         try {
 911             wrapper.setAllT(src, 0, 1);
 912         } finally {
 913             assertUnchanged();
 914         }
 915     }
 916 
 917     private void testSetAllTRangeSelf(boolean sizeChanged, int srcIndex, int length) {
 918 
 919         wrapper.setAllT(array, srcIndex, length);
 920 
 921         if (srcIndex == 0) {
 922             if (length == initialSize) {
 923                 mao.check0();
 924             } else {
 925                 mao.checkOnlySizeChanged(array);
 926             }
 927         } else {
 928             mao.check(array, sizeChanged, 0, length);
 929         }
 930         Object actual = wrapper.toArray(null);
 931         assertEquals(length, array.size());
 932         assertEquals(length, wrapper.arrayLength(actual));
 933         wrapper.assertElementsEqual(actual, 0, length, initialElements, srcIndex);
 934     }
 935 
 936     @Test public void testSetAllTRangeSelf() {
 937         testSetAllTRangeSelf(true, 0, INITIAL_SIZE);
 938     }
 939 
 940     @Test public void testSetAllTRangeSelfBeginning() {
 941         testSetAllTRangeSelf(true, 0, INITIAL_SIZE / 2);
 942     }
 943 
 944     @Test public void testSetAllTRangeSelfTrailing() {
 945         testSetAllTRangeSelf(true, INITIAL_SIZE / 2, INITIAL_SIZE / 2);
 946     }
 947 
 948     @Test public void testSetAllTRangeSelfMiddle() {
 949         testSetAllTRangeSelf(true, 3, 2);
 950     }
 951 
 952     @Test public void testSetAllTRangeSelfEmpty() {
 953         makeEmpty();
 954         testSetAllTRangeSelf(false, 0, 0);
 955     }
 956 
 957     @Test (expected = ArrayIndexOutOfBoundsException.class)
 958     public void testSetAllTRangeSelfNegative1() {
 959         try {
 960             wrapper.setAllT(array, -1, INITIAL_SIZE);
 961         } finally {
 962             assertUnchanged();
 963         }
 964     }
 965 
 966     @Test (expected = ArrayIndexOutOfBoundsException.class)
 967     public void testSetAllTRangeSelfNegative2() {
 968         try {
 969             wrapper.setAllT(array, INITIAL_SIZE, 1);
 970         } finally {
 971             assertUnchanged();
 972         }
 973     }
 974 
 975     @Test (expected = ArrayIndexOutOfBoundsException.class)
 976     public void testSetAllTRangeSelfNegative3() {
 977         try {
 978             wrapper.setAllT(array, 0, -1);
 979         } finally {
 980             assertUnchanged();
 981         }
 982     }
 983 
 984     @Test (expected = ArrayIndexOutOfBoundsException.class)
 985     public void testSetAllTRangeSelfNegative4() {
 986         try {
 987             wrapper.setAllT(array, 0, INITIAL_SIZE + 1);
 988         } finally {
 989             assertUnchanged();
 990         }
 991     }
 992 
 993     @Test (expected = ArrayIndexOutOfBoundsException.class)
 994     public void testSetAllTRangeSelfNegativeAfterEnsureCapacity() {
 995         array.ensureCapacity(INITIAL_SIZE * 2);
 996         try {
 997             wrapper.setAllT(array, INITIAL_SIZE, 1);
 998         } finally {
 999             assertUnchanged();
1000         }
1001     }
1002 
1003     @Test (expected = ArrayIndexOutOfBoundsException.class)
1004     public void testSetAllTRangeSelfNegativeAfterClear() {
1005         makeEmpty();
1006         try {
1007             wrapper.setAllT(array, 0, 1);
1008         } finally {
1009             assertUnchanged();
1010         }
1011     }
1012 
1013     // ========== addAll(primitive array) tests ==========
1014 
1015     private void testAddAllA(int srcSize) {
1016         Object src = wrapper.createPrimitiveArray(srcSize);
1017         int oldSize = array.size();
1018 
1019         wrapper.addAllA(src);
1020 
1021         int newSize = oldSize + srcSize;
1022         boolean sizeChanged = newSize != oldSize;
1023         mao.check(array, sizeChanged, oldSize, newSize);
1024         Object actual = wrapper.toArray(null);
1025         assertEquals(newSize, array.size());
1026         assertEquals(newSize, wrapper.arrayLength(actual));
1027         wrapper.assertElementsEqual(actual, 0, oldSize, initialElements, 0);
1028         wrapper.assertElementsEqual(actual, oldSize, newSize, src, 0);
1029     }
1030 
1031     @Test public void testAddAllA0() {
1032         wrapper.addAllA(wrapper.createPrimitiveArray(0));
1033         assertUnchanged();
1034     }
1035 
1036     @Test public void testAddAllA1() {
1037         testAddAllA(1);
1038     }
1039 
1040     @Test public void testAddAllA3() {
1041         testAddAllA(3);
1042     }
1043 
1044     @Test public void testAddAllABig() {
1045         testAddAllA(INITIAL_SIZE * 2);
1046     }
1047 
1048     @Test public void testAddAllASameSize() {
1049         testAddAllA(INITIAL_SIZE);
1050     }
1051 
1052     @Test public void testAddAllAOnEmpty1() {
1053         makeEmpty();
1054         testAddAllA(1);
1055     }
1056 
1057     @Test public void testAddAllAOnEmptySameSize() {
1058         makeEmpty();
1059         testAddAllA(INITIAL_SIZE);
1060     }
1061 
1062     @Test public void testAddAllAOnEmptyBig() {
1063         makeEmpty();
1064         testAddAllA(INITIAL_SIZE * 3);
1065     }
1066 
1067     @Test public void testAddAllAOnEmpty0() {
1068         makeEmpty();
1069         wrapper.addAllA(wrapper.createPrimitiveArray(0));
1070         assertUnchanged();
1071     }
1072 
1073     @Test (expected = NullPointerException.class)
1074     public void testAddAllANull() {
1075         try {
1076             wrapper.addAllA(null);
1077         } finally {
1078             assertUnchanged();
1079         }
1080     }
1081 
1082     @Test public void testAddAllAManyPoints() {
1083         for (int i = 0; i < 65_000; i++) {
1084             wrapper.addAllA(wrapper.createPrimitiveArray(3));
1085         }
1086     }
1087 
1088     // ========== addAll(ObservableArray) tests ==========
1089 
1090     private void testAddAllT(int srcSize) {
1091         Object src = wrapper.createPrimitiveArray(srcSize);
1092         int oldSize = array.size();
1093 
1094         wrapper.addAllT(wrapper.newInstance().createNotEmptyArray(src));
1095 
1096         int newSize = oldSize + srcSize;
1097         boolean sizeChanged = newSize != oldSize;
1098         mao.check(array, sizeChanged, oldSize, newSize);
1099         Object actual = wrapper.toArray(null);
1100         assertEquals(newSize, array.size());
1101         assertEquals(newSize, wrapper.arrayLength(actual));
1102         wrapper.assertElementsEqual(actual, 0, oldSize, initialElements, 0);
1103         wrapper.assertElementsEqual(actual, oldSize, newSize, src, 0);
1104     }
1105 
1106     @Test public void testAddAllT0() {
1107         wrapper.addAllT(wrapper.newInstance().createEmptyArray());
1108         assertUnchanged();
1109     }
1110 
1111     @Test public void testAddAllT1() {
1112         testAddAllT(1);
1113     }
1114 
1115     @Test public void testAddAllT3() {
1116         testAddAllT(3);
1117     }
1118 
1119     @Test public void testAddAllTBig() {
1120         testAddAllT(INITIAL_SIZE * 2);
1121     }
1122 
1123     @Test public void testAddAllTSameSize() {
1124         testAddAllT(INITIAL_SIZE);
1125     }
1126 
1127     @Test public void testAddAllTOnEmpty1() {
1128         makeEmpty();
1129         testAddAllT(1);
1130     }
1131 
1132     @Test public void testAddAllTOnEmptySameSize() {
1133         makeEmpty();
1134         testAddAllT(INITIAL_SIZE);
1135     }
1136 
1137     @Test public void testAddAllTOnEmptyBig() {
1138         makeEmpty();
1139         testAddAllT(INITIAL_SIZE * 3);
1140     }
1141 
1142     @Test public void testAddAllTOnEmpty0() {
1143         makeEmpty();
1144         wrapper.addAllT(wrapper.newInstance().createEmptyArray());
1145         assertUnchanged();
1146     }
1147 
1148     @Test (expected = NullPointerException.class)
1149     public void testAddAllTNull() {
1150         try {
1151             wrapper.addAllT(null);
1152         } finally {
1153             assertUnchanged();
1154         }
1155     }
1156 
1157     @Test public void testAddAllTSelf() {
1158         wrapper.addAllT(array);
1159 
1160         mao.check(array, true, initialSize, initialSize * 2);
1161         assertEquals(initialSize * 2, array.size());
1162         Object actual = wrapper.toArray(null);
1163         wrapper.assertElementsEqual(actual, 0, initialSize, initialElements, 0);
1164         wrapper.assertElementsEqual(actual, initialSize, initialSize * 2, initialElements, 0);
1165     }
1166 
1167     @Test public void testAddAllTSelfEmpty() {
1168         makeEmpty();
1169 
1170         wrapper.addAllT(array);
1171 
1172         mao.check0();
1173         Object actual = wrapper.toArray(null);
1174         assertEquals(0, array.size());
1175         assertEquals(0, wrapper.arrayLength(actual));
1176     }
1177 
1178     @Test public void testAddAllTManyPoints() {
1179         for (int i = 0; i < 65_000; i++) {
1180             wrapper.addAllT(wrapper.createNotEmptyArray(wrapper.createPrimitiveArray(3)));
1181         }
1182     }
1183 
1184     // ========== addAll(primitive array, range) tests ==========
1185 
1186     private void testAddAllARange(int srcSize, int srcIndex, int length) {
1187         Object src = wrapper.createPrimitiveArray(srcSize);
1188         int oldSize = array.size();
1189 
1190         wrapper.addAllA(src, srcIndex, length);
1191 
1192         int newSize = oldSize + length;
1193         boolean sizeChanged = newSize != oldSize;
1194 
1195         mao.check(array, sizeChanged, oldSize, newSize);
1196         Object actual = wrapper.toArray(null);
1197         assertEquals(newSize, array.size());
1198         assertEquals(newSize, wrapper.arrayLength(actual));
1199         wrapper.assertElementsEqual(actual, 0, oldSize, initialElements, 0);
1200         wrapper.assertElementsEqual(actual, oldSize, newSize, src, srcIndex);
1201     }
1202 
1203     @Test public void testAddAllARange1() {
1204         testAddAllARange(INITIAL_SIZE, 0, INITIAL_SIZE);
1205     }
1206 
1207     @Test public void testAddAllARange2() {
1208         testAddAllARange(INITIAL_SIZE + 10, 0, INITIAL_SIZE);
1209     }
1210 
1211     @Test public void testAddAllARange3() {
1212         testAddAllARange(INITIAL_SIZE + 10, 10, INITIAL_SIZE);
1213     }
1214 
1215     @Test public void testAddAllARange4() {
1216         testAddAllARange(INITIAL_SIZE + 10, 2, INITIAL_SIZE);
1217     }
1218 
1219     @Test public void testAddAllARange5() {
1220         testAddAllARange(INITIAL_SIZE, 0, INITIAL_SIZE / 2);
1221     }
1222 
1223     @Test public void testAddAllARange6() {
1224         testAddAllARange(INITIAL_SIZE + 10, 0, INITIAL_SIZE + 10);
1225     }
1226 
1227     @Test public void testAddAllARange7() {
1228         testAddAllARange(INITIAL_SIZE + 20, 10, INITIAL_SIZE + 10);
1229     }
1230 
1231     @Test public void testAddAllARange8() {
1232         testAddAllARange(INITIAL_SIZE + 10, 2, INITIAL_SIZE - 3);
1233     }
1234 
1235     @Test public void testAddAllARangeOnEmpty1() {
1236         makeEmpty();
1237         testAddAllARange(INITIAL_SIZE, 1, 3);
1238     }
1239 
1240     @Test public void testAddAllARangeOnEmpty2() {
1241         makeEmpty();
1242         testAddAllARange(INITIAL_SIZE * 3, INITIAL_SIZE, INITIAL_SIZE * 2);
1243     }
1244 
1245     @Test public void testAddAllARangeOnEmpty3() {
1246         makeEmpty();
1247         wrapper.addAllA(wrapper.createPrimitiveArray(INITIAL_SIZE), 1, 0);
1248         assertUnchanged();
1249     }
1250 
1251     @Test (expected = NullPointerException.class)
1252     public void testAddAllARangeNull() {
1253         try {
1254             wrapper.addAllA(null, 0, 0);
1255         } finally {
1256             assertUnchanged();
1257         }
1258     }
1259 
1260     @Test (expected = ArrayIndexOutOfBoundsException.class)
1261     public void testAddAllARangeNegative1() {
1262         try {
1263             testAddAllARange(INITIAL_SIZE, -1, INITIAL_SIZE);
1264         } finally {
1265             assertUnchanged();
1266         }
1267     }
1268 
1269     @Test (expected = ArrayIndexOutOfBoundsException.class)
1270     public void testAddAllARangeNegative2() {
1271         try {
1272             testAddAllARange(INITIAL_SIZE, 0, INITIAL_SIZE + 1);
1273         } finally {
1274             assertUnchanged();
1275         }
1276     }
1277 
1278     @Test (expected = ArrayIndexOutOfBoundsException.class)
1279     public void testAddAllARangeNegative3() {
1280         try {
1281             testAddAllARange(INITIAL_SIZE, 1, -1);
1282         } finally {
1283             assertUnchanged();
1284         }
1285     }
1286 
1287     @Test (expected = ArrayIndexOutOfBoundsException.class)
1288     public void testAddAllARangeNegative4() {
1289         try {
1290             testAddAllARange(INITIAL_SIZE, INITIAL_SIZE, 1);
1291         } finally {
1292             assertUnchanged();
1293         }
1294     }
1295 
1296     // ========== addAll(observable array, range) tests ==========
1297 
1298     private void testAddAllTRange(int srcSize, int srcIndex, int length) {
1299         Object src = wrapper.createPrimitiveArray(srcSize);
1300         int oldSize = array.size();
1301 
1302         wrapper.addAllT(wrapper.newInstance().createNotEmptyArray(src), srcIndex, length);
1303 
1304         int newSize = oldSize + length;
1305         boolean sizeChanged = newSize != oldSize;
1306 
1307         mao.check(array, sizeChanged, oldSize, newSize);
1308         Object actual = wrapper.toArray(null);
1309         assertEquals(newSize, array.size());
1310         assertEquals(newSize, wrapper.arrayLength(actual));
1311         wrapper.assertElementsEqual(actual, 0, oldSize, initialElements, 0);
1312         wrapper.assertElementsEqual(actual, oldSize, newSize, src, srcIndex);
1313     }
1314 
1315     @Test public void testAddAllTRange1() {
1316         testAddAllTRange(INITIAL_SIZE, 0, INITIAL_SIZE);
1317     }
1318 
1319     @Test public void testAddAllTRange2() {
1320         testAddAllTRange(INITIAL_SIZE + 10, 0, INITIAL_SIZE);
1321     }
1322 
1323     @Test public void testAddAllTRange3() {
1324         testAddAllTRange(INITIAL_SIZE + 10, 10, INITIAL_SIZE);
1325     }
1326 
1327     @Test public void testAddAllTRange4() {
1328         testAddAllTRange(INITIAL_SIZE + 10, 2, INITIAL_SIZE);
1329     }
1330 
1331     @Test public void testAddAllTRange5() {
1332         testAddAllTRange(INITIAL_SIZE, 0, INITIAL_SIZE / 2);
1333     }
1334 
1335     @Test public void testAddAllTRange6() {
1336         testAddAllTRange(INITIAL_SIZE + 10, 0, INITIAL_SIZE + 10);
1337     }
1338 
1339     @Test public void testAddAllTRange7() {
1340         testAddAllTRange(INITIAL_SIZE + 20, 10, INITIAL_SIZE + 10);
1341     }
1342 
1343     @Test public void testAddAllTRange8() {
1344         testAddAllTRange(INITIAL_SIZE + 10, 2, INITIAL_SIZE - 3);
1345     }
1346 
1347     @Test public void testAddAllTRangeOnEmpty1() {
1348         makeEmpty();
1349         testAddAllTRange(INITIAL_SIZE, 1, 3);
1350     }
1351 
1352     @Test public void testAddAllTRangeOnEmpty2() {
1353         makeEmpty();
1354         testAddAllTRange(INITIAL_SIZE * 3, INITIAL_SIZE, INITIAL_SIZE * 2);
1355     }
1356 
1357     @Test public void testAddAllTRangeOnEmpty3() {
1358         makeEmpty();
1359         wrapper.addAllT(wrapper.newInstance().createNotEmptyArray(wrapper.createPrimitiveArray(INITIAL_SIZE)), 1, 0);
1360         assertUnchanged();
1361     }
1362 
1363     @Test (expected = NullPointerException.class)
1364     public void testAddAllTRangeNull() {
1365         try {
1366             wrapper.addAllT(null, 0, 0);
1367         } finally {
1368             assertUnchanged();
1369         }
1370     }
1371 
1372     @Test (expected = ArrayIndexOutOfBoundsException.class)
1373     public void testAddAllTRangeNegative1() {
1374         try {
1375             testAddAllTRange(INITIAL_SIZE, -1, INITIAL_SIZE);
1376         } finally {
1377             assertUnchanged();
1378         }
1379     }
1380 
1381     @Test (expected = ArrayIndexOutOfBoundsException.class)
1382     public void testAddAllTRangeNegative2() {
1383         try {
1384             testAddAllTRange(INITIAL_SIZE, 0, INITIAL_SIZE + 1);
1385         } finally {
1386             assertUnchanged();
1387         }
1388     }
1389 
1390     @Test (expected = ArrayIndexOutOfBoundsException.class)
1391     public void testAddAllTRangeNegative3() {
1392         try {
1393             testAddAllTRange(INITIAL_SIZE, 1, -1);
1394         } finally {
1395             assertUnchanged();
1396         }
1397     }
1398 
1399     @Test (expected = ArrayIndexOutOfBoundsException.class)
1400     public void testAddAllTRangeNegative4() {
1401         try {
1402             testAddAllTRange(INITIAL_SIZE, INITIAL_SIZE, 1);
1403         } finally {
1404             assertUnchanged();
1405         }
1406     }
1407 
1408     @Test (expected = ArrayIndexOutOfBoundsException.class)
1409     public void testAddAllTRangeNegativeAfterSrcEnsureCapacity() {
1410         Object srcA = wrapper.createPrimitiveArray(INITIAL_SIZE);
1411         ObservableArray src = wrapper.newInstance().createNotEmptyArray(srcA);
1412         src.ensureCapacity(INITIAL_SIZE * 2);
1413         try {
1414             wrapper.addAllT(src, INITIAL_SIZE, 1);
1415         } finally {
1416             assertUnchanged();
1417         }
1418     }
1419 
1420     @Test (expected = ArrayIndexOutOfBoundsException.class)
1421     public void testAddAllTRangeNegativeAfterSrcClear() {
1422         Object srcA = wrapper.createPrimitiveArray(INITIAL_SIZE);
1423         ObservableArray src = wrapper.newInstance().createNotEmptyArray(srcA);
1424         src.clear();
1425         try {
1426             wrapper.addAllT(src, 0, 1);
1427         } finally {
1428             assertUnchanged();
1429         }
1430     }
1431 
1432     private void testAddAllTRangeSelf(int srcIndex, int length) {
1433         wrapper.addAllT(array, srcIndex, length);
1434 
1435         int expSize = initialSize + length;
1436         mao.check(array, true, initialSize, expSize);
1437         Object actual = wrapper.toArray(null);
1438         assertEquals(expSize, array.size());
1439         assertEquals(expSize, wrapper.arrayLength(actual));
1440         wrapper.assertElementsEqual(actual, 0, initialSize, initialElements, 0);
1441         wrapper.assertElementsEqual(actual, initialSize, expSize, initialElements, srcIndex);
1442     }
1443 
1444     @Test public void testAddAllTRangeSelf() {
1445         testAddAllTRangeSelf(0, INITIAL_SIZE);
1446     }
1447 
1448     @Test public void testAddAllTRangeSelfBeginning() {
1449         testAddAllTRangeSelf(0, INITIAL_SIZE / 2);
1450     }
1451 
1452     @Test public void testAddAllTRangeSelfTrailing() {
1453         testAddAllTRangeSelf(INITIAL_SIZE / 2, INITIAL_SIZE / 2);
1454     }
1455 
1456     @Test public void testAddAllTRangeSelfMiddle() {
1457         testAddAllTRangeSelf(2, 2);
1458     }
1459 
1460     @Test (expected = ArrayIndexOutOfBoundsException.class)
1461     public void testAddAllTRangeSelfNegative1() {
1462         try {
1463             testAddAllTRangeSelf(-1, INITIAL_SIZE);
1464         } finally {
1465             assertUnchanged();
1466         }
1467     }
1468 
1469     @Test (expected = ArrayIndexOutOfBoundsException.class)
1470     public void testAddAllTRangeSelfNegative2() {
1471         try {
1472             testAddAllTRangeSelf(0, INITIAL_SIZE + 1);
1473         } finally {
1474             assertUnchanged();
1475         }
1476     }
1477 
1478     @Test (expected = ArrayIndexOutOfBoundsException.class)
1479     public void testAddAllTRangeSelfNegative3() {
1480         try {
1481             testAddAllTRangeSelf(1, -1);
1482         } finally {
1483             assertUnchanged();
1484         }
1485     }
1486 
1487     @Test (expected = ArrayIndexOutOfBoundsException.class)
1488     public void testAddAllTRangeSelfNegative4() {
1489         try {
1490             testAddAllTRangeSelf(INITIAL_SIZE, 1);
1491         } finally {
1492             assertUnchanged();
1493         }
1494     }
1495 
1496     @Test (expected = ArrayIndexOutOfBoundsException.class)
1497     public void testAddAllTRangeSelfNegativeAfterEnsureCapacity() {
1498         array.ensureCapacity(INITIAL_SIZE * 2);
1499         try {
1500             wrapper.addAllT(array, INITIAL_SIZE, 1);
1501         } finally {
1502             assertUnchanged();
1503         }
1504     }
1505 
1506     @Test (expected = ArrayIndexOutOfBoundsException.class)
1507     public void testAddAllTRangeSelfNegativeAfterClear() {
1508         makeEmpty();
1509         try {
1510             wrapper.addAllT(array, 0, 1);
1511         } finally {
1512             assertUnchanged();
1513         }
1514     }
1515 
1516     // ========== set(primitive array, range) tests ==========
1517 
1518     private void testSetARange(int srcLength, int destIndex, int srcIndex, int length) {
1519         Object expected = wrapper.createPrimitiveArray(srcLength);
1520 
1521         wrapper.setA(destIndex, expected, srcIndex, length);
1522 
1523         mao.checkOnlyElementsChanged(array, destIndex, destIndex + length);
1524         Object actual = wrapper.toArray(null);
1525         assertEquals(INITIAL_SIZE, array.size());
1526         assertEquals(INITIAL_SIZE, wrapper.arrayLength(actual));
1527         wrapper.assertElementsEqual(actual, 0, destIndex, initialElements, 0);
1528         wrapper.assertElementsEqual(actual, destIndex, destIndex + length, expected, srcIndex);
1529         wrapper.assertElementsEqual(actual, destIndex + length, INITIAL_SIZE, initialElements, destIndex + length);
1530     }
1531 
1532     @Test public void testSetARange1() {
1533         testSetARange(5, 0, 0, 5);
1534     }
1535 
1536     @Test public void testSetARange2() {
1537         testSetARange(3, 2, 0, 3);
1538     }
1539 
1540     @Test public void testSetARange3() {
1541         testSetARange(5, 0, 2, 3);
1542     }
1543 
1544     @Test public void testSetARange4() {
1545         testSetARange(5, 0, 0, 3);
1546     }
1547 
1548     @Test public void testSetARange5() {
1549         testSetARange(10, 3, 5, 3);
1550     }
1551 
1552     @Test (expected = ArrayIndexOutOfBoundsException.class)
1553     public void testSetARangeNegative1() {
1554         try {
1555             testSetARange(10, -1, 0, 3);
1556         } finally {
1557             assertUnchanged();
1558         }
1559     }
1560 
1561     @Test (expected = ArrayIndexOutOfBoundsException.class)
1562     public void testSetARangeNegative2() {
1563         try {
1564             testSetARange(10, 0, -1, 3);
1565         } finally {
1566             assertUnchanged();
1567         }
1568     }
1569 
1570     @Test (expected = ArrayIndexOutOfBoundsException.class)
1571     public void testSetARangeNegative3() {
1572         try {
1573             testSetARange(10, 1, 1, -1);
1574         } finally {
1575             assertUnchanged();
1576         }
1577     }
1578 
1579     @Test (expected = ArrayIndexOutOfBoundsException.class)
1580     public void testSetARangeNegative4() {
1581         try {
1582             testSetARange(10, INITIAL_SIZE, 0, 3);
1583         } finally {
1584             assertUnchanged();
1585         }
1586     }
1587 
1588     @Test (expected = ArrayIndexOutOfBoundsException.class)
1589     public void testSetARangeNegative5() {
1590         try {
1591             testSetARange(10, 0, 10, 1);
1592         } finally {
1593             assertUnchanged();
1594         }
1595     }
1596 
1597     @Test (expected = ArrayIndexOutOfBoundsException.class)
1598     public void testSetARangeNegative6() {
1599         try {
1600             testSetARange(3, 0, 1, 4);
1601         } finally {
1602             assertUnchanged();
1603         }
1604     }
1605 
1606     @Test (expected = ArrayIndexOutOfBoundsException.class)
1607     public void testSetARangeNegative7() {
1608         try {
1609             testSetARange(10, INITIAL_SIZE - 3, 0, 4);
1610         } finally {
1611             assertUnchanged();
1612         }
1613     }
1614 
1615     @Test (expected = ArrayIndexOutOfBoundsException.class)
1616     public void testSetARangeNegativeAfterEnsureCapacity() {
1617         array.ensureCapacity(INITIAL_SIZE * 2);
1618         try {
1619             testSetARange(1, INITIAL_SIZE, 0, 1);
1620         } finally {
1621             assertUnchanged();
1622         }
1623     }
1624 
1625     @Test (expected = ArrayIndexOutOfBoundsException.class)
1626     public void testSetARangeNegativeAfterClear() {
1627         makeEmpty();
1628         try {
1629             testSetARange(1, 0, 0, 1);
1630         } finally {
1631             assertUnchanged();
1632         }
1633     }
1634 
1635     // ========== set(ObservableArray, range) tests ==========
1636 
1637     private void testSetTRange(int srcLength, int destIndex, int srcIndex, int length) {
1638         Object expected = wrapper.createPrimitiveArray(srcLength);
1639         ObservableArray src = wrapper.newInstance().createNotEmptyArray(expected);
1640 
1641         wrapper.setT(destIndex, src, srcIndex, length);
1642 
1643         mao.checkOnlyElementsChanged(array, destIndex, destIndex + length);
1644         Object actual = wrapper.toArray(null);
1645         assertEquals(INITIAL_SIZE, array.size());
1646         assertEquals(INITIAL_SIZE, wrapper.arrayLength(actual));
1647         wrapper.assertElementsEqual(actual, 0, destIndex, initialElements, 0);
1648         wrapper.assertElementsEqual(actual, destIndex, destIndex + length, expected, srcIndex);
1649         wrapper.assertElementsEqual(actual, destIndex + length, initialSize, initialElements, destIndex + length);
1650     }
1651 
1652     @Test public void testSetTRange1() {
1653         testSetTRange(5, 0, 0, 5);
1654     }
1655 
1656     @Test public void testSetTRange2() {
1657         testSetTRange(3, 2, 0, 3);
1658     }
1659 
1660     @Test public void testSetTRange3() {
1661         testSetTRange(5, 0, 2, 3);
1662     }
1663 
1664     @Test public void testSetTRange4() {
1665         testSetTRange(5, 0, 0, 3);
1666     }
1667 
1668     @Test public void testSetTRange5() {
1669         testSetTRange(10, 3, 5, 3);
1670     }
1671 
1672     @Test (expected = ArrayIndexOutOfBoundsException.class)
1673     public void testSetTRangeNegative1() {
1674         try {
1675             testSetTRange(10, -1, 0, 3);
1676         } finally {
1677             assertUnchanged();
1678         }
1679     }
1680 
1681     @Test (expected = ArrayIndexOutOfBoundsException.class)
1682     public void testSetTRangeNegative2() {
1683         try {
1684             testSetTRange(10, 0, -1, 3);
1685         } finally {
1686             assertUnchanged();
1687         }
1688     }
1689 
1690     @Test (expected = ArrayIndexOutOfBoundsException.class)
1691     public void testSetTRangeNegative3() {
1692         try {
1693             testSetTRange(10, 1, 1, -1);
1694         } finally {
1695             assertUnchanged();
1696         }
1697     }
1698 
1699     @Test (expected = ArrayIndexOutOfBoundsException.class)
1700     public void testSetTRangeNegative4() {
1701         try {
1702             testSetTRange(10, INITIAL_SIZE, 0, 3);
1703         } finally {
1704             assertUnchanged();
1705         }
1706     }
1707 
1708     @Test (expected = ArrayIndexOutOfBoundsException.class)
1709     public void testSetTRangeNegative5() {
1710         try {
1711             testSetTRange(10, 0, 10, 1);
1712         } finally {
1713             assertUnchanged();
1714         }
1715     }
1716 
1717     @Test (expected = ArrayIndexOutOfBoundsException.class)
1718     public void testSetTRangeNegative6() {
1719         try {
1720             testSetTRange(3, 0, 1, 4);
1721         } finally {
1722             assertUnchanged();
1723         }
1724     }
1725 
1726     @Test (expected = ArrayIndexOutOfBoundsException.class)
1727     public void testSetTRangeNegative7() {
1728         try {
1729             testSetTRange(10, INITIAL_SIZE - 3, 0, 4);
1730         } finally {
1731             assertUnchanged();
1732         }
1733     }
1734 
1735     @Test (expected = ArrayIndexOutOfBoundsException.class)
1736     public void testSetTRangeNegativeAfterEnsureCapacity() {
1737         array.ensureCapacity(INITIAL_SIZE * 2);
1738         try {
1739             testSetTRange(1, INITIAL_SIZE, 0, 1);
1740         } finally {
1741             assertUnchanged();
1742         }
1743     }
1744 
1745     @Test (expected = ArrayIndexOutOfBoundsException.class)
1746     public void testSetTRangeNegativeAfterClear() {
1747         makeEmpty();
1748         try {
1749             testSetTRange(1, 0, 0, 1);
1750         } finally {
1751             assertUnchanged();
1752         }
1753     }
1754 
1755     @Test (expected = ArrayIndexOutOfBoundsException.class)
1756     public void testSetTRangeNegativeAfterSrcEnsureCapacity() {
1757         try {
1758             Object srcA = wrapper.createPrimitiveArray(1);
1759             ObservableArray src = wrapper.newInstance().createNotEmptyArray(srcA);
1760             src.ensureCapacity(2);
1761 
1762             wrapper.setT(0, src, 1, 1);
1763         } finally {
1764             assertUnchanged();
1765         }
1766     }
1767 
1768     @Test (expected = ArrayIndexOutOfBoundsException.class)
1769     public void testSetTRangeNegativeAfterSrcClear() {
1770         try {
1771             Object srcA = wrapper.createPrimitiveArray(1);
1772             ObservableArray src = wrapper.newInstance().createNotEmptyArray(srcA);
1773             src.clear();
1774 
1775             wrapper.setT(0, src, 0, 1);
1776         } finally {
1777             assertUnchanged();
1778         }
1779     }
1780 
1781     private void testSetTRangeSelf(int destIndex, int srcIndex, int length) {
1782 
1783         wrapper.setT(destIndex, array, srcIndex, length);
1784 
1785         mao.checkOnlyElementsChanged(array, destIndex, destIndex + length);
1786         Object actual = wrapper.toArray(null);
1787         assertEquals(INITIAL_SIZE, array.size());
1788         assertEquals(INITIAL_SIZE, wrapper.arrayLength(actual));
1789         wrapper.assertElementsEqual(actual, 0, destIndex, initialElements, 0);
1790         wrapper.assertElementsEqual(actual, destIndex, destIndex + length, initialElements, srcIndex);
1791         wrapper.assertElementsEqual(actual, destIndex + length, initialSize, initialElements, destIndex + length);
1792     }
1793 
1794     @Test public void testSetTRangeSelf() {
1795         testSetTRangeSelf(0, 0, INITIAL_SIZE);
1796     }
1797 
1798     @Test public void testSetTRangeSelfLeft() {
1799         testSetTRangeSelf(0, 1, INITIAL_SIZE - 1);
1800     }
1801 
1802     @Test public void testSetTRangeSelfRight() {
1803         testSetTRangeSelf(1, 0, INITIAL_SIZE - 1);
1804     }
1805 
1806     @Test public void testSetTRangeSelfRightDifferentParts() {
1807         testSetTRangeSelf(0, INITIAL_SIZE / 2, INITIAL_SIZE / 2);
1808     }
1809 
1810     @Test public void testSetTRangeSelfLeftDifferentParts() {
1811         testSetTRangeSelf(INITIAL_SIZE / 2, 0, INITIAL_SIZE / 2);
1812     }
1813 
1814     @Test (expected = ArrayIndexOutOfBoundsException.class)
1815     public void testSetTRangeSelfNegative1() {
1816         try {
1817             wrapper.setT(-1, array, 0, INITIAL_SIZE);
1818         } finally {
1819             assertUnchanged();
1820         }
1821     }
1822 
1823     @Test (expected = ArrayIndexOutOfBoundsException.class)
1824     public void testSetTRangeSelfNegative2() {
1825         try {
1826             wrapper.setT(0, array, -1, INITIAL_SIZE);
1827         } finally {
1828             assertUnchanged();
1829         }
1830     }
1831 
1832     @Test (expected = ArrayIndexOutOfBoundsException.class)
1833     public void testSetTRangeSelfNegative3() {
1834         try {
1835             wrapper.setT(0, array, 0, INITIAL_SIZE + 1);
1836         } finally {
1837             assertUnchanged();
1838         }
1839     }
1840 
1841     @Test (expected = ArrayIndexOutOfBoundsException.class)
1842     public void testSetTRangeSelfNegative4() {
1843         try {
1844             wrapper.setT(0, array, 1, -1);
1845         } finally {
1846             assertUnchanged();
1847         }
1848     }
1849 
1850     @Test (expected = ArrayIndexOutOfBoundsException.class)
1851     public void testSetTRangeSelfNegative5() {
1852         try {
1853             wrapper.setT(INITIAL_SIZE, array, 0, 1);
1854         } finally {
1855             assertUnchanged();
1856         }
1857     }
1858 
1859     @Test (expected = ArrayIndexOutOfBoundsException.class)
1860     public void testSetTRangeSelfNegative6() {
1861         try {
1862             wrapper.setT(0, array, INITIAL_SIZE, 1);
1863         } finally {
1864             assertUnchanged();
1865         }
1866     }
1867 
1868     @Test (expected = ArrayIndexOutOfBoundsException.class)
1869     public void testSetTRangeSelfNegativeAfterEnsureCapacity() {
1870         try {
1871             array.ensureCapacity(INITIAL_SIZE * 2);
1872 
1873             wrapper.setT(0, array, INITIAL_SIZE, 1);
1874         } finally {
1875             assertUnchanged();
1876         }
1877     }
1878 
1879     @Test (expected = ArrayIndexOutOfBoundsException.class)
1880     public void testSetTRangeSelfNegativeAfterClear() {
1881         makeEmpty();
1882         try {
1883             wrapper.setT(0, array, 0, 1);
1884         } finally {
1885             assertUnchanged();
1886         }
1887     }
1888 
1889 
1890     // ========== negative get(index) tests ==========
1891 
1892     @Test (expected = ArrayIndexOutOfBoundsException.class)
1893     public void testGetNegative() {
1894         try {
1895             wrapper.get(-1);
1896         } finally {
1897             assertUnchanged();
1898         }
1899     }
1900 
1901     @Test (expected = ArrayIndexOutOfBoundsException.class)
1902     public void testGetOutOfBounds() {
1903         try {
1904             wrapper.get(array.size());
1905         } finally {
1906             assertUnchanged();
1907         }
1908     }
1909 
1910     @Test (expected = ArrayIndexOutOfBoundsException.class)
1911     public void testGetAfterEnsureCapacity() {
1912         try {
1913             array.ensureCapacity(INITIAL_SIZE * 2);
1914             wrapper.get(INITIAL_SIZE);
1915         } finally {
1916             assertUnchanged();
1917         }
1918     }
1919 
1920     @Test (expected = ArrayIndexOutOfBoundsException.class)
1921     public void testGetAfterClear() {
1922         makeEmpty();
1923         try {
1924             wrapper.get(0);
1925         } finally {
1926             assertUnchanged();
1927         }
1928     }
1929 
1930     // ================== set(index) tests ===============
1931 
1932     @Test public void testSetValue() {
1933         for (int i = 0; i < INITIAL_SIZE; i++) {
1934             Object expected = wrapper.getNextValue();
1935 
1936             wrapper.set(i, expected);
1937 
1938             mao.check(array, false, i, i + 1);
1939             mao.reset();
1940             assertEquals(expected, wrapper.get(i));
1941             assertEquals(INITIAL_SIZE, array.size());
1942         }
1943     }
1944 
1945     @Test (expected = ArrayIndexOutOfBoundsException.class)
1946     public void testSetValueNegative() {
1947         try {
1948             wrapper.set(-1, wrapper.getNextValue());
1949         } finally {
1950             assertUnchanged();
1951         }
1952     }
1953 
1954     @Test (expected = ArrayIndexOutOfBoundsException.class)
1955     public void testSetValueOutOfBounds() {
1956         try {
1957             wrapper.set(INITIAL_SIZE, wrapper.getNextValue());
1958         } finally {
1959             assertUnchanged();
1960         }
1961     }
1962 
1963     @Test (expected = ArrayIndexOutOfBoundsException.class)
1964     public void testSetValueNegativeAfterClear() {
1965         makeEmpty();
1966         try {
1967             wrapper.set(0, wrapper.getNextValue());
1968         } finally {
1969             assertUnchanged();
1970         }
1971     }
1972 
1973     @Test (expected = ArrayIndexOutOfBoundsException.class)
1974     public void testSetValueNegativeAfterEnsureCapacity() {
1975         array.ensureCapacity(INITIAL_SIZE * 2);
1976         try {
1977             wrapper.set(INITIAL_SIZE, wrapper.getNextValue());
1978         } finally {
1979             assertUnchanged();
1980         }
1981     }
1982 
1983     // ================= toArray(array) tests ======================
1984 
1985     private void testToArray(int arraySize, boolean same) {
1986         Object param = wrapper.createPrimitiveArray(arraySize);
1987         Object actual = wrapper.toArray(param);
1988         assertUnchanged();
1989         if (same) {
1990             assertSame(param, actual);
1991         } else {
1992             assertNotSame(param, actual);
1993             assertEquals(array.size(), wrapper.arrayLength(actual));
1994         }
1995         wrapper.assertElementsEqual(actual, 0, array.size(), wrapper.toArray(null), 0);
1996     }
1997 
1998     @Test public void testToArraySameSize() {
1999         testToArray(array.size(), true);
2000     }
2001 
2002     @Test public void testToArraySmaller() {
2003         testToArray(3, false);
2004     }
2005 
2006     @Test public void testToArrayBigger() {
2007         testToArray(10, true);
2008     }
2009 
2010     @Test public void testToArrayEmpty() {
2011         makeEmpty();
2012         testToArray(10, true);
2013     }
2014 
2015     @Test public void testToArrayEmptyToEmpty() {
2016         makeEmpty();
2017         testToArray(0, true);
2018     }
2019 
2020     // ============ toArray range tests =========================
2021 
2022     private void testToArrayRange(int srcIndex, int destSize, int length) {
2023         Object dest = wrapper.createPrimitiveArray(destSize);
2024         Object initial = wrapper.clonePrimitiveArray(dest);
2025         Object actual = wrapper.toArray(srcIndex, dest, length);
2026         assertUnchanged();
2027         Object expected = wrapper.toArray(null);
2028         wrapper.assertElementsEqual(actual, 0, length, expected, srcIndex);
2029         wrapper.assertElementsEqual(actual, length, wrapper.arrayLength(actual), initial, length);
2030     }
2031 
2032     @Test public void testToArrayRange0() {
2033         testToArrayRange(0, array.size(), array.size());
2034     }
2035 
2036     @Test public void testToArrayRange1() {
2037         testToArrayRange(3, array.size(), array.size() - 3);
2038     }
2039 
2040     @Test public void testToArrayRange2() {
2041         testToArrayRange(0, array.size(), array.size() - 3);
2042     }
2043 
2044     @Test public void testToArrayRange3() {
2045         testToArrayRange(2, array.size(), 2);
2046     }
2047 
2048     @Test public void testToArrayRange4() {
2049         testToArrayRange(2, 0, 0);
2050     }
2051 
2052     @Test public void testToArrayRange5() {
2053         makeEmpty();
2054         testToArrayRange(0, 0, 0);
2055     }
2056 
2057     @Test public void testToArrayRange6() {
2058         testToArrayRange(3, 2, 2);
2059     }
2060 
2061     @Test public void testToArrayRange7() {
2062         testToArrayRange(5, 1, 1);
2063     }
2064 
2065     @Test public void testToArrayRange8() {
2066         testToArrayRange(0, array.size() * 2, array.size());
2067     }
2068 
2069     @Test public void testToArrayRange9() {
2070         testToArrayRange(0, array.size() - 1, array.size());
2071     }
2072 
2073     @Test (expected = ArrayIndexOutOfBoundsException.class)
2074     public void testToArrayRangeNegative1() {
2075         try {
2076             testToArrayRange(-1, array.size(), 2);
2077         } finally {
2078             assertUnchanged();
2079         }
2080     }
2081 
2082     @Test (expected = ArrayIndexOutOfBoundsException.class)
2083     public void testToArrayRangeNegative2() {
2084         try {
2085             testToArrayRange(array.size(), array.size(), 2);
2086         } finally {
2087             assertUnchanged();
2088         }
2089     }
2090 
2091     @Test (expected = ArrayIndexOutOfBoundsException.class)
2092     public void testToArrayRangeNegative3() {
2093         try {
2094             testToArrayRange(5, array.size(), array.size() + 1);
2095         } finally {
2096             assertUnchanged();
2097         }
2098     }
2099 
2100     @Test (expected = ArrayIndexOutOfBoundsException.class)
2101     public void testToArrayRangeNegative5() {
2102         makeEmpty();
2103         try {
2104             testToArrayRange(2, 0, 0);
2105         } finally {
2106             assertUnchanged();
2107         }
2108     }
2109 
2110     @Test (expected = ArrayIndexOutOfBoundsException.class)
2111     public void testToArrayRangeNegativeAfterEnsureCapacity() {
2112         array.ensureCapacity(INITIAL_SIZE * 2);
2113         try {
2114             testToArrayRange(INITIAL_SIZE, 1, 1);
2115         } finally {
2116             assertUnchanged();
2117         }
2118     }
2119 
2120     @Test (expected = ArrayIndexOutOfBoundsException.class)
2121     public void testToArrayRangeNegativeAfterClear() {
2122         makeEmpty();
2123         try {
2124             testToArrayRange(0, 1, 1);
2125         } finally {
2126             assertUnchanged();
2127         }
2128     }
2129 
2130     // ============ copyTo(primitive array) tests =========================
2131 
2132     private void testCopyToA(int srcIndex, int destSize, int destIndex, int length) {
2133         Object actual = wrapper.createPrimitiveArray(destSize);
2134         Object initial = wrapper.clonePrimitiveArray(actual);
2135         wrapper.copyToA(srcIndex, actual, destIndex, length);
2136         assertUnchanged();
2137         Object expected = wrapper.toArray(null);
2138         wrapper.assertElementsEqual(actual, 0, destIndex, initial, 0);
2139         wrapper.assertElementsEqual(actual, destIndex, destIndex + length, expected, srcIndex);
2140         wrapper.assertElementsEqual(actual, destIndex + length, wrapper.arrayLength(actual), initial, destIndex + length);
2141     }
2142 
2143     @Test public void testCopyToA0() {
2144         testCopyToA(0, array.size(), 0, array.size());
2145     }
2146 
2147     @Test public void testCopyToA1() {
2148         testCopyToA(1, array.size(), 2, 3);
2149     }
2150 
2151     @Test public void testCopyToA2() {
2152         testCopyToA(2, array.size(), 2, 2);
2153     }
2154 
2155     @Test public void testCopyToA3() {
2156         testCopyToA(0, array.size(), 2, 2);
2157     }
2158 
2159     @Test public void testCopyToA4() {
2160         testCopyToA(0, 3, 1, 2);
2161     }
2162 
2163     @Test public void testCopyToA5() {
2164         testCopyToA(0, array.size() * 3, array.size() * 2, array.size());
2165     }
2166 
2167     @Test public void testCopyToA6() {
2168         testCopyToA(3, array.size(), 0, array.size() - 3);
2169     }
2170 
2171     @Test public void testCopyToA7() {
2172         testCopyToA(0, 10, 7, 3);
2173     }
2174 
2175     @Test public void testCopyToA8() {
2176         testCopyToA(1, 0, 0, 0);
2177     }
2178 
2179     @Test public void testCopyToA9() {
2180         makeEmpty();
2181         testCopyToA(0, 0, 0, 0);
2182     }
2183 
2184     @Test (expected = ArrayIndexOutOfBoundsException.class)
2185     public void testCopyToANegative1() {
2186         try {
2187             testCopyToA(-1, array.size(), 0, array.size());
2188         } finally {
2189             assertUnchanged();
2190         }
2191     }
2192 
2193     @Test (expected = ArrayIndexOutOfBoundsException.class)
2194     public void testCopyToANegative2() {
2195         try {
2196             testCopyToA(0, array.size() / 2, 0, array.size());
2197         } finally {
2198             assertUnchanged();
2199         }
2200     }
2201 
2202     @Test (expected = ArrayIndexOutOfBoundsException.class)
2203     public void testCopyToANegative3() {
2204         try {
2205             testCopyToA(array.size(), array.size(), 0, array.size());
2206         } finally {
2207             assertUnchanged();
2208         }
2209 
2210     }
2211 
2212     @Test (expected = ArrayIndexOutOfBoundsException.class)
2213     public void testCopyToANegative4() {
2214         try {
2215             testCopyToA(0, array.size(), -1, array.size());
2216         } finally {
2217             assertUnchanged();
2218         }
2219 
2220     }
2221 
2222     @Test (expected = ArrayIndexOutOfBoundsException.class)
2223     public void testCopyToANegative5() {
2224         try {
2225             testCopyToA(0, array.size(), array.size(), array.size());
2226         } finally {
2227             assertUnchanged();
2228         }
2229     }
2230 
2231     @Test (expected = ArrayIndexOutOfBoundsException.class)
2232     public void testCopyToANegative6() {
2233         try {
2234             testCopyToA(0, array.size(), 0, array.size() * 2);
2235         } finally {
2236             assertUnchanged();
2237         }
2238     }
2239 
2240     @Test (expected = ArrayIndexOutOfBoundsException.class)
2241     public void testCopyToANegative7() {
2242         makeEmpty();
2243         try {
2244             testCopyToA(1, 0, 0, 0);
2245         } finally {
2246             assertUnchanged();
2247         }
2248     }
2249 
2250     @Test (expected = ArrayIndexOutOfBoundsException.class)
2251     public void testCopyToANegative8() {
2252         try {
2253             testCopyToA(0, 0, 1, 0);
2254         } finally {
2255             assertUnchanged();
2256         }
2257     }
2258 
2259     @Test (expected = ArrayIndexOutOfBoundsException.class)
2260     public void testCopyToANegativeAfterEnsureCapacity() {
2261         array.ensureCapacity(INITIAL_SIZE * 2);
2262         try {
2263             testCopyToA(INITIAL_SIZE, 1, 0, 1);
2264         } finally {
2265             assertUnchanged();
2266         }
2267     }
2268 
2269     @Test (expected = ArrayIndexOutOfBoundsException.class)
2270     public void testCopyToANegativeAfterClear() {
2271         makeEmpty();
2272         try {
2273             testCopyToA(0, 1, 0, 1);
2274         } finally {
2275             assertUnchanged();
2276         }
2277     }
2278 
2279     // ============ copyTo(ObservableArray) tests =========================
2280 
2281     private void testCopyToT(int srcIndex, int destSize, int destIndex, int length) {
2282         ArrayWrapper wrapper2 = wrapper.newInstance();
2283         Object initial = wrapper2.createPrimitiveArray(destSize);
2284         ObservableArray dest = wrapper2.createNotEmptyArray(initial);
2285 
2286         wrapper.copyToT(srcIndex, dest, destIndex, length);
2287 
2288         assertUnchanged();
2289         Object expected = wrapper.toArray(null);
2290         Object actual = wrapper2.toArray(null);
2291         wrapper.assertElementsEqual(actual, 0, destIndex, initial, 0);
2292         wrapper.assertElementsEqual(actual, destIndex, destIndex + length, expected, srcIndex);
2293         wrapper.assertElementsEqual(actual, destIndex + length, wrapper.arrayLength(actual), initial, destIndex + length);
2294     }
2295 
2296     @Test public void testCopyToT0() {
2297         testCopyToT(0, array.size(), 0, array.size());
2298     }
2299 
2300     @Test public void testCopyToT1() {
2301         testCopyToT(1, array.size(), 2, 3);
2302     }
2303 
2304     @Test public void testCopyToT2() {
2305         testCopyToT(2, array.size(), 2, 2);
2306     }
2307 
2308     @Test public void testCopyToT3() {
2309         testCopyToT(0, array.size(), 2, 2);
2310     }
2311 
2312     @Test public void testCopyToT4() {
2313         testCopyToT(0, 3, 1, 2);
2314     }
2315 
2316     @Test public void testCopyToT5() {
2317         testCopyToT(0, array.size() * 3, array.size() * 2, array.size());
2318     }
2319 
2320     @Test public void testCopyToT6() {
2321         testCopyToT(3, array.size(), 0, array.size() - 3);
2322     }
2323 
2324     @Test public void testCopyToT7() {
2325         testCopyToT(0, 10, 7, 3);
2326     }
2327 
2328     @Test public void testCopyToT8() {
2329         testCopyToT(1, 0, 0, 0);
2330     }
2331 
2332     @Test public void testCopyToT9() {
2333         makeEmpty();
2334         testCopyToT(0, 0, 0, 0);
2335     }
2336 
2337     @Test (expected = ArrayIndexOutOfBoundsException.class)
2338     public void testCopyToTNegative1() {
2339         try {
2340             testCopyToT(-1, array.size(), 0, array.size());
2341         } finally {
2342             assertUnchanged();
2343         }
2344     }
2345 
2346     @Test (expected = ArrayIndexOutOfBoundsException.class)
2347     public void testCopyToTNegative2() {
2348         try {
2349             testCopyToT(0, array.size() / 2, 0, array.size());
2350         } finally {
2351             assertUnchanged();
2352         }
2353     }
2354 
2355     @Test (expected = ArrayIndexOutOfBoundsException.class)
2356     public void testCopyToTNegative3() {
2357         try {
2358             testCopyToT(array.size(), array.size(), 0, array.size());
2359         } finally {
2360             assertUnchanged();
2361         }
2362 
2363     }
2364 
2365     @Test (expected = ArrayIndexOutOfBoundsException.class)
2366     public void testCopyToTNegative4() {
2367         try {
2368             testCopyToT(0, array.size(), -1, array.size());
2369         } finally {
2370             assertUnchanged();
2371         }
2372 
2373     }
2374 
2375     @Test (expected = ArrayIndexOutOfBoundsException.class)
2376     public void testCopyToTNegative5() {
2377         try {
2378             testCopyToT(0, array.size(), array.size(), array.size());
2379         } finally {
2380             assertUnchanged();
2381         }
2382     }
2383 
2384     @Test (expected = ArrayIndexOutOfBoundsException.class)
2385     public void testCopyToTNegative6() {
2386         try {
2387             testCopyToT(0, array.size(), 0, array.size() * 2);
2388         } finally {
2389             assertUnchanged();
2390         }
2391     }
2392 
2393     @Test (expected = ArrayIndexOutOfBoundsException.class)
2394     public void testCopyToTNegative7() {
2395         makeEmpty();
2396         try {
2397             testCopyToT(1, 0, 0, 0);
2398         } finally {
2399             assertUnchanged();
2400         }
2401     }
2402 
2403     @Test (expected = ArrayIndexOutOfBoundsException.class)
2404     public void testCopyToTNegative8() {
2405         try {
2406             testCopyToT(0, 0, 1, 0);
2407         } finally {
2408             assertUnchanged();
2409         }
2410     }
2411 
2412     @Test (expected = ArrayIndexOutOfBoundsException.class)
2413     public void testCopyToTNegativeAfterEnsureCapacity() {
2414         array.ensureCapacity(INITIAL_SIZE * 2);
2415         try {
2416             testCopyToT(INITIAL_SIZE, 1, 0, 1);
2417         } finally {
2418             assertUnchanged();
2419         }
2420     }
2421 
2422     @Test (expected = ArrayIndexOutOfBoundsException.class)
2423     public void testCopyToTNegativeAfterClear() {
2424         makeEmpty();
2425         try {
2426             testCopyToT(0, 1, 0, 1);
2427         } finally {
2428             assertUnchanged();
2429         }
2430     }
2431 
2432     @Test (expected = ArrayIndexOutOfBoundsException.class)
2433     public void testCopyToTNegativeAfterDestEnsureCapacity() {
2434         try {
2435             ArrayWrapper wrapper2 = wrapper.newInstance();
2436             Object destA = wrapper2.createPrimitiveArray(1);
2437             ObservableArray dest = wrapper2.createNotEmptyArray(destA);
2438             dest.ensureCapacity(2);
2439 
2440             wrapper.copyToT(0, dest, 1, 1);
2441         } finally {
2442             assertUnchanged();
2443         }
2444     }
2445 
2446     @Test (expected = ArrayIndexOutOfBoundsException.class)
2447     public void testCopyToTNegativeAfterDestClear() {
2448         try {
2449             ArrayWrapper wrapper2 = wrapper.newInstance();
2450             Object destA = wrapper2.createPrimitiveArray(1);
2451             ObservableArray dest = wrapper2.createNotEmptyArray(destA);
2452             dest.clear();
2453 
2454             wrapper.copyToT(0, dest, 0, 1);
2455         } finally {
2456             assertUnchanged();
2457         }
2458     }
2459 
2460     private void testCopyToTSelf(int srcIndex, int destIndex, int length) {
2461 
2462         wrapper.copyToT(srcIndex, array, destIndex, length);
2463 
2464         mao.checkOnlyElementsChanged(array, destIndex, destIndex + length);
2465         Object actual = wrapper.toArray(null);
2466         wrapper.assertElementsEqual(actual, 0, destIndex, initialElements, 0);
2467         wrapper.assertElementsEqual(actual, destIndex, destIndex + length, initialElements, srcIndex);
2468         wrapper.assertElementsEqual(actual, destIndex + length, initialSize, initialElements, destIndex + length);
2469     }
2470 
2471     @Test public void testCopyToTSelf() {
2472         testCopyToTSelf(0, 0, INITIAL_SIZE);
2473     }
2474 
2475     @Test public void testCopyToTSelfRight() {
2476         testCopyToTSelf(0, 1, INITIAL_SIZE - 1);
2477     }
2478 
2479     @Test public void testCopyToTSelfLeft() {
2480         testCopyToTSelf(1, 0, INITIAL_SIZE - 1);
2481     }
2482 
2483     @Test public void testCopyToTSelfRightDifferentParts() {
2484         testCopyToTSelf(0, INITIAL_SIZE / 2, INITIAL_SIZE / 2);
2485     }
2486 
2487     @Test public void testCopyToTSelfLeftDifferentParts() {
2488         testCopyToTSelf(INITIAL_SIZE / 2, 0, INITIAL_SIZE / 2);
2489     }
2490 
2491     @Test (expected = ArrayIndexOutOfBoundsException.class)
2492     public void testCopyToTSelfNegative1() {
2493         try {
2494             testCopyToTSelf(-1, 0, INITIAL_SIZE);
2495         } finally {
2496             assertUnchanged();
2497         }
2498     }
2499 
2500     @Test (expected = ArrayIndexOutOfBoundsException.class)
2501     public void testCopyToTSelfNegative2() {
2502         try {
2503             testCopyToTSelf(INITIAL_SIZE, 0, 1);
2504         } finally {
2505             assertUnchanged();
2506         }
2507     }
2508 
2509     @Test (expected = ArrayIndexOutOfBoundsException.class)
2510     public void testCopyToTSelfNegative3() {
2511         try {
2512             testCopyToTSelf(0, -1, INITIAL_SIZE);
2513         } finally {
2514             assertUnchanged();
2515         }
2516     }
2517 
2518     @Test (expected = ArrayIndexOutOfBoundsException.class)
2519     public void testCopyToTSelfNegative4() {
2520         try {
2521             testCopyToTSelf(0, INITIAL_SIZE, 1);
2522         } finally {
2523             assertUnchanged();
2524         }
2525     }
2526 
2527     @Test (expected = ArrayIndexOutOfBoundsException.class)
2528     public void testCopyToTSelfNegative5() {
2529         try {
2530             testCopyToTSelf(1, 1, -1);
2531         } finally {
2532             assertUnchanged();
2533         }
2534     }
2535 
2536     @Test (expected = ArrayIndexOutOfBoundsException.class)
2537     public void testCopyToTSelfNegative6() {
2538         try {
2539             testCopyToTSelf(0, 1, INITIAL_SIZE);
2540         } finally {
2541             assertUnchanged();
2542         }
2543     }
2544 
2545     @Test (expected = ArrayIndexOutOfBoundsException.class)
2546     public void testCopyToTSelfNegative7() {
2547         try {
2548             testCopyToTSelf(1, 0, INITIAL_SIZE);
2549         } finally {
2550             assertUnchanged();
2551         }
2552     }
2553 
2554     @Test (expected = ArrayIndexOutOfBoundsException.class)
2555     public void testCopyToTSelfNegativeAfterEnsureCapacity() {
2556         array.ensureCapacity(INITIAL_SIZE * 2);
2557         try {
2558             testCopyToTSelf(0, INITIAL_SIZE, 1);
2559         } finally {
2560             assertUnchanged();
2561         }
2562     }
2563 
2564     @Test (expected = ArrayIndexOutOfBoundsException.class)
2565     public void testCopyToTSelfNegativeAfterClear() {
2566         makeEmpty();
2567         try {
2568             testCopyToTSelf(0, 0, 1);
2569         } finally {
2570             assertUnchanged();
2571         }
2572     }
2573 
2574     // ============ ensureCapacity() and trimToSize() tests ====================
2575 
2576     @Test public void testTrimToSize() {
2577         array.trimToSize();
2578         assertUnchanged();
2579     }
2580 
2581     @Test public void testTrimToSizeEmpty() {
2582         makeEmpty();
2583         array.trimToSize();
2584         assertUnchanged();
2585     }
2586 
2587     @Test public void testTrimToSizeResize() {
2588         array.resize(3);
2589         initialSize = 3;
2590         mao.reset();
2591 
2592         array.trimToSize();
2593 
2594         assertUnchanged();
2595     }
2596 
2597     @Test public void testTrimToSizeAddRemove() {
2598         array.resize(1000);
2599         array.resize(INITIAL_SIZE);
2600         mao.reset();
2601 
2602         array.trimToSize();
2603 
2604         assertUnchanged();
2605     }
2606 
2607     @Test public void testEnsureCapacity0() {
2608         array.ensureCapacity(0);
2609         assertUnchanged();
2610     }
2611 
2612     @Test public void testEnsureCapacityBy1() {
2613         array.ensureCapacity(INITIAL_SIZE + 1);
2614         assertUnchanged();
2615     }
2616 
2617     @Test public void testEnsureCapacity1000() {
2618         array.ensureCapacity(1000);
2619         assertUnchanged();
2620     }
2621 
2622     @Test public void testEnsureCapacitySmaller() {
2623         array.ensureCapacity(INITIAL_SIZE / 2);
2624         assertUnchanged();
2625     }
2626 
2627     @Test public void testEnsureCapacityNegative() {
2628         array.ensureCapacity(-1000);
2629         assertUnchanged();
2630     }
2631 
2632     @Test public void testEnsureCapacityOnEmpty() {
2633         makeEmpty();
2634         array.ensureCapacity(100);
2635         assertUnchanged();
2636     }
2637 
2638     @Test public void testEnsureCapacityOnEmpty0() {
2639         makeEmpty();
2640         array.ensureCapacity(0);
2641         assertUnchanged();
2642     }
2643 
2644     @Test public void testEnsureCapacityOnEmptyNegative() {
2645         makeEmpty();
2646         array.ensureCapacity(-1);
2647         assertUnchanged();
2648     }
2649 
2650     @Test public void testTrimToSizeEnsureCapacity() {
2651         array.ensureCapacity(1000);
2652         array.trimToSize();
2653         assertUnchanged();
2654     }
2655 
2656     // ================= clear() tests ====================
2657 
2658     @Test public void testClearEmpty() {
2659         makeEmpty();
2660         array.clear();
2661         mao.check0();
2662         assertEquals(0, array.size());
2663     }
2664 
2665     @Test public void testClear1000() {
2666         array.resize(1000);
2667         mao.reset();
2668 
2669         array.clear();
2670 
2671         mao.checkOnlySizeChanged(array);
2672         assertEquals(0, array.size());
2673     }
2674 
2675     // ================= toString() tests ===================
2676 
2677     @Test public void testToString() {
2678         String actual = array.toString();
2679         String expected = wrapper.primitiveArrayToString(wrapper.toArray(null));
2680         assertEquals(expected, actual);
2681         String regex = "\\[[0-9]+(\\.[0-9]+){0,1}(\\, [0-9]+(.[0-9]+){0,1}){" + (initialSize - 1) + "}\\]";
2682         assertTrue("toString() output matches to regex '" + regex + "'. Actual = '" + actual + "'",
2683                 actual.matches(regex));
2684     }
2685 
2686     @Test public void testToStringAfterResize() {
2687         array.resize(initialSize / 2);
2688         String actual = array.toString();
2689         String expected = wrapper.primitiveArrayToString(wrapper.toArray(null));
2690         assertEquals(expected, actual);
2691         String regex = "\\[[0-9]+(\\.[0-9]+){0,1}(\\, [0-9]+(.[0-9]+){0,1}){" + (array.size() - 1) + "}\\]";
2692         assertTrue("toString() output matches to regex '" + regex + "'. Actual = '" + actual + "'",
2693                 actual.matches(regex));
2694     }
2695 
2696     @Test public void testToStringAfterClear() {
2697         array.clear();
2698         String actual = array.toString();
2699         assertEquals("[]", actual);
2700     }
2701 }