Ver Fonte

test (89)

fix: IntArrayAllocator#ensureCapacity - NPE
fix: AIntArray#SubList - extends AIntArray instead of IntArrayList
fix: IntArrayList#getInt - range check
Ranides Atterwim há 10 anos atrás
pai
commit
18c196d207

+ 160 - 158
assira/src/main/java/net/ranides/assira/collection/arrays/IntArrayAllocator.java

@@ -1,158 +1,160 @@
-/*
- *  @author Ranides Atterwim <ranides@gmail.com>
- *  @copyright Ranides Atterwim
- *  @license WTFPL
- *  @url http://ranides.net/projects/assira
- */
-package net.ranides.assira.collection.arrays;
-
-public final class IntArrayAllocator {
-
-    /**
-     * A static, final, empty array.
-     */
-    public final static int[] EMPTY_ARRAY = {};
-    
-    private IntArrayAllocator() {
-        // utility class
-    }
-    
-    /**
-     * Ensures that an array can contain the given number of entries.
-     *
-     * <P>If you cannot foresee whether this array will need again to be
-     * enlarged, you should probably use
-     * <code>grow()</code> instead.
-     *
-     * @param array an array.
-     * @param length the new minimum length for this array.
-     * @return <code>array</code>, if it contains <code>length</code> entries or
-     * more; otherwise, an array with <code>length</code> entries whose * *
-     * first <code>array.length</code> entries are the same as those * *
-     * of <code>array</code>.
-     */
-    public static int[] ensureCapacity(int[] array, int length) {
-        return ensureCapacity(array, length, IntArrayUtils.size(array));
-    }
-    
-    /**
-     * Ensures that an array can contain the given number of entries, preserving
-     * just a part of the array.
-     *
-     * @param array an array.
-     * @param length the new minimum length for this array.
-     * @param preserve the number of elements of the array that must be
-     * preserved in case a new allocation is necessary.
-     * @return <code>array</code>, if it can contain <code>length</code> entries
-     * or more; otherwise, an array with <code>length</code> entries whose *
-     * first <code>preserve</code> entries are the same as those * *
-     * of <code>array</code>.
-     */
-    public static int[] ensureCapacity(int[] array, int length, int preserve) {
-        if (length > IntArrayUtils.size(array)) {
-            int t[] = new int[length];
-            System.arraycopy(array, 0, t, 0, preserve);
-            return t;
-        }
-        return array;
-    }
-
-    
-    /**
-     * Ensures that a range given by an offset and a length fits an array.
-     *
-     * <P>This method may be used whenever an array range check is needed.
-     *
-     * @param array an array.
-     * @param offset a start index.
-     * @param length a length (the number of elements in the range).
-     * @throws IllegalArgumentException if <code>length</code> is negative.
-     * @throws ArrayIndexOutOfBoundsException if <code>offset</code> is negative
-     * or <code>offset</code>+<code>length</code> is greater than the array
-     * length.
-     */
-    public static void ensureOffsetLength(int[] array, int offset, int length) {
-        ArrayAllocator.ensureOffsetLength(IntArrayUtils.size(array), offset, length);
-    }
-    
-    /**
-     * Ensures that a range given by its first (inclusive) and last (exclusive)
-     * elements fits an array.
-     *
-     * <P>This method may be used whenever an array range check is needed.
-     *
-     * @param array an array.
-     * @param begin a start index (inclusive).
-     * @param end an end index (exclusive).
-     * @throws IllegalArgumentException if <code>from</code> is greater * *
-     * than <code>to</code>.
-     * @throws ArrayIndexOutOfBoundsException if <code>from</code> * *
-     * or <code>to</code> are greater than the array length or negative.
-     */
-    public static void ensureFromTo(int[] array, int begin, int end) {
-        ArrayAllocator.ensureFromTo(IntArrayUtils.size(array), begin, end);
-    }
-    
-    /**
-     * Grows the given array to the maximum between the given length and the
-     * current length multiplied by two, provided that the given length is
-     * larger than the current length.
-     *
-     * <P>If you want complete control on the array growth, you should probably
-     * use
-     * <code>ensureCapacity()</code> instead.
-     *
-     * @param array an array.
-     * @param length the new minimum length for this array.
-     * @return <code>array</code>, if it can contain <code>length</code>
-     * entries; otherwise, an array with
-     * max(<code>length</code>,<code>array.length</code>/&phi;) entries whose
-     * first <code>array.length</code> entries are the same as those * *
-     * of <code>array</code>.
-     *
-     */
-    public static int[] grow(int[] array, int length) {
-        return grow(array, length, IntArrayUtils.size(array));
-    }
-
-    /**
-     * Grows the given array to the maximum between the given length and the
-     * current length multiplied by two, provided that the given length is
-     * larger than the current length, preserving just a part of the array.
-     *
-     * <P>If you want complete control on the array growth, you should probably
-     * use
-     * <code>ensureCapacity()</code> instead.
-     *
-     * @param array an array.
-     * @param length the new minimum length for this array.
-     * @param preserve the number of elements of the array that must be
-     * preserved in case a new allocation is necessary.
-     * @return <code>array</code>, if it can contain <code>length</code>
-     * entries; otherwise, an array with
-     * max(<code>length</code>,<code>array.length</code>/&phi;) entries whose
-     * first <code>preserve</code> entries are the same as those * *
-     * of <code>array</code>.
-     *
-     */
-    public static int[] grow(int[] array, int length, int preserve) {
-        int n = IntArrayUtils.size(array);
-        if (length > n) {
-            int newLength = (int) Math.min(Math.max(2L * n, length), ArrayAllocator.MAX_SIZE);
-            int t[] = new int[newLength];
-            System.arraycopy(array, 0, t, 0, preserve);
-            return t;
-        }
-        return array;
-    }
-    
-    public static int[] trim(int[] array, int length) {
-        if (length >= IntArrayUtils.size(array)) {
-            return array;
-        }
-        int target[] = new int[length];
-        System.arraycopy(array, 0, target, 0, length);
-        return target;
-    }
-
-}
+/*
+ *  @author Ranides Atterwim <ranides@gmail.com>
+ *  @copyright Ranides Atterwim
+ *  @license WTFPL
+ *  @url http://ranides.net/projects/assira
+ */
+package net.ranides.assira.collection.arrays;
+
+public final class IntArrayAllocator {
+
+    /**
+     * A static, final, empty array.
+     */
+    public final static int[] EMPTY_ARRAY = {};
+    
+    private IntArrayAllocator() {
+        // utility class
+    }
+    
+    /**
+     * Ensures that an array can contain the given number of entries.
+     *
+     * <P>If you cannot foresee whether this array will need again to be
+     * enlarged, you should probably use
+     * <code>grow()</code> instead.
+     *
+     * @param array an array.
+     * @param length the new minimum length for this array.
+     * @return <code>array</code>, if it contains <code>length</code> entries or
+     * more; otherwise, an array with <code>length</code> entries whose * *
+     * first <code>array.length</code> entries are the same as those * *
+     * of <code>array</code>.
+     */
+    public static int[] ensureCapacity(int[] array, int length) {
+        return ensureCapacity(array, length, IntArrayUtils.size(array));
+    }
+    
+    /**
+     * Ensures that an array can contain the given number of entries, preserving
+     * just a part of the array.
+     *
+     * @param array an array.
+     * @param length the new minimum length for this array.
+     * @param preserve the number of elements of the array that must be
+     * preserved in case a new allocation is necessary.
+     * @return <code>array</code>, if it can contain <code>length</code> entries
+     * or more; otherwise, an array with <code>length</code> entries whose *
+     * first <code>preserve</code> entries are the same as those * *
+     * of <code>array</code>.
+     */
+    public static int[] ensureCapacity(int[] array, int length, int preserve) {
+        if (length > IntArrayUtils.size(array)) {
+            int t[] = new int[length];
+            if(array != null && preserve>0) {
+                System.arraycopy(array, 0, t, 0, preserve);
+            }
+            return t;
+        }
+        return array;
+    }
+
+    
+    /**
+     * Ensures that a range given by an offset and a length fits an array.
+     *
+     * <P>This method may be used whenever an array range check is needed.
+     *
+     * @param array an array.
+     * @param offset a start index.
+     * @param length a length (the number of elements in the range).
+     * @throws IllegalArgumentException if <code>length</code> is negative.
+     * @throws ArrayIndexOutOfBoundsException if <code>offset</code> is negative
+     * or <code>offset</code>+<code>length</code> is greater than the array
+     * length.
+     */
+    public static void ensureOffsetLength(int[] array, int offset, int length) {
+        ArrayAllocator.ensureOffsetLength(IntArrayUtils.size(array), offset, length);
+    }
+    
+    /**
+     * Ensures that a range given by its first (inclusive) and last (exclusive)
+     * elements fits an array.
+     *
+     * <P>This method may be used whenever an array range check is needed.
+     *
+     * @param array an array.
+     * @param begin a start index (inclusive).
+     * @param end an end index (exclusive).
+     * @throws IllegalArgumentException if <code>from</code> is greater * *
+     * than <code>to</code>.
+     * @throws ArrayIndexOutOfBoundsException if <code>from</code> * *
+     * or <code>to</code> are greater than the array length or negative.
+     */
+    public static void ensureFromTo(int[] array, int begin, int end) {
+        ArrayAllocator.ensureFromTo(IntArrayUtils.size(array), begin, end);
+    }
+    
+    /**
+     * Grows the given array to the maximum between the given length and the
+     * current length multiplied by two, provided that the given length is
+     * larger than the current length.
+     *
+     * <P>If you want complete control on the array growth, you should probably
+     * use
+     * <code>ensureCapacity()</code> instead.
+     *
+     * @param array an array.
+     * @param length the new minimum length for this array.
+     * @return <code>array</code>, if it can contain <code>length</code>
+     * entries; otherwise, an array with
+     * max(<code>length</code>,<code>array.length</code>/&phi;) entries whose
+     * first <code>array.length</code> entries are the same as those * *
+     * of <code>array</code>.
+     *
+     */
+    public static int[] grow(int[] array, int length) {
+        return grow(array, length, IntArrayUtils.size(array));
+    }
+
+    /**
+     * Grows the given array to the maximum between the given length and the
+     * current length multiplied by two, provided that the given length is
+     * larger than the current length, preserving just a part of the array.
+     *
+     * <P>If you want complete control on the array growth, you should probably
+     * use
+     * <code>ensureCapacity()</code> instead.
+     *
+     * @param array an array.
+     * @param length the new minimum length for this array.
+     * @param preserve the number of elements of the array that must be
+     * preserved in case a new allocation is necessary.
+     * @return <code>array</code>, if it can contain <code>length</code>
+     * entries; otherwise, an array with
+     * max(<code>length</code>,<code>array.length</code>/&phi;) entries whose
+     * first <code>preserve</code> entries are the same as those * *
+     * of <code>array</code>.
+     *
+     */
+    public static int[] grow(int[] array, int length, int preserve) {
+        int n = IntArrayUtils.size(array);
+        if (length > n) {
+            int newLength = (int) Math.min(Math.max(2L * n, length), ArrayAllocator.MAX_SIZE);
+            int t[] = new int[newLength];
+            System.arraycopy(array, 0, t, 0, preserve);
+            return t;
+        }
+        return array;
+    }
+    
+    public static int[] trim(int[] array, int length) {
+        if (length >= IntArrayUtils.size(array)) {
+            return array;
+        }
+        int target[] = new int[length];
+        System.arraycopy(array, 0, target, 0, length);
+        return target;
+    }
+
+}

+ 2 - 17
assira/src/main/java/net/ranides/assira/collection/lists/AIntList.java

@@ -369,12 +369,12 @@ public abstract class AIntList extends AIntCollection implements IntList, Compar
         checkIndex(from);
         checkIndex(to);
         if (from > to) {
-            throw new IndexOutOfBoundsException("Start index (" + from + ") is greater than end index (" + to + ")");
+            throw new IllegalArgumentException("Start index (" + from + ") is greater than end index (" + to + ")");
         }
         return new SubList(this, from, to);
     }
     
-    protected static class SubList extends IntArrayList implements Serializable {
+    protected static class SubList extends AIntList implements Serializable {
 
         private static final long serialVersionUID = 2;
 
@@ -414,21 +414,6 @@ public abstract class AIntList extends AIntCollection implements IntList, Compar
             return -1;
         }
 
-        @Override
-        public void resize(int size) {
-            int i = size();
-            if (size > i) {
-                while (i++ < size) {
-                    add(0);
-                }
-            } else {
-                while (i-- != size) {
-                    remove(i);
-                }
-            }
-        }
-
-
         @Override
         public boolean add(int k) {
             idata.add(end, k);

+ 1 - 1
assira/src/main/java/net/ranides/assira/collection/lists/IntArrayList.java

@@ -242,7 +242,7 @@ public class IntArrayList extends AIntList implements BlockCollection<Integer>,
 
     @Override
     public int getInt(int index) {
-        checkIndex(index);
+        checkIndexElement(index);
         return data[ index];
     }
 

+ 6 - 1
assira/src/test/java/net/ranides/assira/collection/lists/IntArrayListTest.java

@@ -30,6 +30,7 @@ public class IntArrayListTest {
         CollectionSuite.SUITE
 			.param("set!", $list)
 			.param("list!", $list)
+			.param("nest!", true)
 			.run(() -> new IntArrayList());
     }
 
@@ -123,18 +124,20 @@ public class IntArrayListTest {
     public void testCompare_List() {
         IntArrayList list0 = new IntArrayList(new int[]{1,3,5,7});
         
-        List<Integer> ilist0 = new IntArrayList(new int[]{1,3,5,7});
+        List<Integer> ilist0 = list0;
         List<Integer> ilist1 = new IntArrayList(new int[]{1,3,5,7});
         List<Integer> ilist2 = new IntArrayList(new int[]{1,3,5,7});
         List<Integer> ilist3 = new IntArrayList(new int[]{1,3,5});
         List<Integer> ilist4 = new IntArrayList(new int[]{1,2,5,7});
         List<Integer> ilist5 = new IntArrayList(new int[]{1,4,5,7});
+        List<Integer> ilist6 = new IntArrayList(new int[]{1,4,5,7,9});
         
         List<Integer> list1 = Arrays.asList(1,3,5,7);
         List<Integer> list2 = Arrays.asList(1,3,5,7);
         List<Integer> list3 = Arrays.asList(1,3,5);
         List<Integer> list4 = Arrays.asList(1,2,5,7);
         List<Integer> list5 = Arrays.asList(1,4,5,7);
+        List<Integer> list6 = Arrays.asList(1,4,5,7,9);
         
         assertTrue( list0.compareTo(ilist0) == 0 );
         
@@ -143,12 +146,14 @@ public class IntArrayListTest {
         assertTrue( list0.compareTo(ilist3) > 0 );
         assertTrue( list0.compareTo(ilist4) > 0 );
         assertTrue( list0.compareTo(ilist5) < 0 );
+        assertTrue( list0.compareTo(ilist6) < 0 );
         
         assertTrue( list0.compareTo(list1) == 0 );
         assertTrue( list0.compareTo(list2) == 0 );
         assertTrue( list0.compareTo(list3) > 0 );
         assertTrue( list0.compareTo(list4) > 0 );
         assertTrue( list0.compareTo(list5) < 0 );
+        assertTrue( list0.compareTo(list6) < 0 );
     }
 	
     

+ 35 - 17
assira/src/test/java/net/ranides/assira/collection/suite/lists/IntListTester.java

@@ -7,6 +7,7 @@
 package net.ranides.assira.collection.suite.lists;
 
 import java.util.ArrayList;
+import java.util.List;
 import javax.annotation.Resource;
 import net.ranides.assira.collection.IntCollection;
 import net.ranides.assira.collection.lists.IntArrayList;
@@ -22,6 +23,13 @@ import static net.ranides.assira.junit.NewAssert.*;
  */
 public class IntListTester {
     
+    private static final int[] ITEMS_ADD_0 = new int[]{1,3,5,7,9};
+    private static final int[] ITEMS_ADD_1 = new int[]{1,11,12,13,3,5,7,9};
+    private static final int[] ITEMS_ADD_2 = new int[]{21,22,1,11,12,13,3,5,7,9};
+    private static final int[] ITEMS_ADD_3 = new int[]{21,22,1,11,12,13,3,5,7,31,32,33,9};
+    private static final int[] ITEMS_ADD_4 = new int[]{21,22,1,11,12,13,3,5,7,31,32,33,9,41,42,43};
+    private static final int[] ITEMS_ADD_5 = new int[]{21,22,1,11,12,13,3,5,7,31,32,33,9,41,42,43,51,52,53};
+    
     @Resource(name = "list!")
     private TCollection<?> $list;
     
@@ -43,16 +51,20 @@ public class IntListTester {
         
         assertEquals($list.list(1,3,5,7,9,11).into(new ArrayList<>()), target);
         
-        assertThrows(IllegalArgumentException.class, ()->{
+        // IllegalArgumentException | IndexOutOfBoundsException | ArrayIndexOutOfBoundsException
+        assertThrows(Exception.class, ()->{
             target.removeElements(0, -1);
         });
-        assertThrows(IllegalArgumentException.class, ()->{
+        // IllegalArgumentException | IndexOutOfBoundsException | ArrayIndexOutOfBoundsException
+        assertThrows(Exception.class, ()->{
             target.removeElements(3, 2);
         });
-        assertThrows(ArrayIndexOutOfBoundsException.class, ()->{
+        // IllegalArgumentException | IndexOutOfBoundsException | ArrayIndexOutOfBoundsException
+        assertThrows(Exception.class, ()->{
             target.removeElements(-1, 1);
         });
-        assertThrows(ArrayIndexOutOfBoundsException.class, ()->{
+        // IllegalArgumentException | IndexOutOfBoundsException | ArrayIndexOutOfBoundsException
+        assertThrows(Exception.class, ()->{
             target.removeElements(2, 8);
         });
         
@@ -79,42 +91,48 @@ public class IntListTester {
     
     @InterfaceTest
     public void basicAddAll_Collection(IntList target) {
-        $list.list(1,3,5,7,9).intoInt(target);
+        $list.list(ITEMS_ADD_0).intoInt(target);
         
         target.addAll(1, icollection(11,12,13));
-        assertEquals($list.list(1,11,12,13,3,5,7,9).into(new ArrayList<>()), target);
+        assertEquals($list.list(ITEMS_ADD_1).into(new ArrayList<>()), target);
         
         target.addAll(0,icollection(21,22));
-        assertEquals($list.list(21,22,1,11,12,13,3,5,7,9).into(new ArrayList<>()), target);
+        assertEquals($list.list(ITEMS_ADD_2).into(new ArrayList<>()), target);
         
         target.addAll(target.size()-1, icollection(31,32,33));
-        assertEquals($list.list(21,22,1,11,12,13,3,5,7,31,32,33,9).into(new ArrayList<>()), target);
+        assertEquals($list.list(ITEMS_ADD_3).into(new ArrayList<>()), target);
         
         target.addAll(target.size(),icollection(41,42,43));
-        assertEquals($list.list(21,22,1,11,12,13,3,5,7,31,32,33,9,41,42,43).into(new ArrayList<>()), target);
+        assertEquals($list.list(ITEMS_ADD_4).into(new ArrayList<>()), target);
         
         target.addAll(target.size(),icollection());
-        assertEquals($list.list(21,22,1,11,12,13,3,5,7,31,32,33,9,41,42,43).into(new ArrayList<>()), target);
+        assertEquals($list.list(ITEMS_ADD_4).into(new ArrayList<>()), target);
+        
+        target.addAll(icollection(51,52,53));
+        assertEquals($list.list(ITEMS_ADD_5).into(new ArrayList<>()), target);
     }
-    
+        
     @InterfaceTest
     public void basicAddAll_List(IntList target) {
-        $list.list(1,3,5,7,9).intoInt(target);
+        $list.list(ITEMS_ADD_0).intoInt(target);
         
         target.addAll(1, ilist(11,12,13));
-        assertEquals($list.list(1,11,12,13,3,5,7,9).into(new ArrayList<>()), target);
+        assertEquals($list.list(ITEMS_ADD_1).into(new ArrayList<>()), target);
         
         target.addAll(0,ilist(21,22));
-        assertEquals($list.list(21,22,1,11,12,13,3,5,7,9).into(new ArrayList<>()), target);
+        assertEquals($list.list(ITEMS_ADD_2).into(new ArrayList<>()), target);
         
         target.addAll(target.size()-1, ilist(31,32,33));
-        assertEquals($list.list(21,22,1,11,12,13,3,5,7,31,32,33,9).into(new ArrayList<>()), target);
+        assertEquals($list.list(ITEMS_ADD_3).into(new ArrayList<>()), target);
         
         target.addAll(target.size(),ilist(41,42,43));
-        assertEquals($list.list(21,22,1,11,12,13,3,5,7,31,32,33,9,41,42,43).into(new ArrayList<>()), target);
+        assertEquals($list.list(ITEMS_ADD_4).into(new ArrayList<>()), target);
         
         target.addAll(target.size(),ilist());
-        assertEquals($list.list(21,22,1,11,12,13,3,5,7,31,32,33,9,41,42,43).into(new ArrayList<>()), target);
+        assertEquals($list.list(ITEMS_ADD_4).into(new ArrayList<>()), target);
+        
+        target.addAll(ilist(51,52,53));
+        assertEquals($list.list(ITEMS_ADD_5).into(new ArrayList<>()), target);
     }
     
     private IntCollection icollection(int... values) {

+ 176 - 1
assira/src/test/java/net/ranides/assira/collection/suite/lists/ListTester.java

@@ -7,9 +7,11 @@
 package net.ranides.assira.collection.suite.lists;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
-import java.util.Map;
+import java.util.function.Supplier;
 import javax.annotation.Resource;
+import net.ranides.assira.junit.InterfaceSuite;
 import net.ranides.assira.junit.InterfaceTest;
 import net.ranides.assira.test.TCollection;
 import static net.ranides.assira.junit.NewAssert.*;
@@ -22,6 +24,9 @@ public class ListTester<T> {
     
     @Resource(name = "list!")
     private TCollection<T> $list;
+
+    @Resource(name = "nest!")
+    private boolean $nest = false;
     
     @InterfaceTest
     public void basicAdd(List<T> target) {
@@ -69,6 +74,27 @@ public class ListTester<T> {
         assertEquals(16, target.size());
         assertEquals($list.list(0,1,2,3,10,11,12,13,14,15,16,17,4,5,6,7).into(new ArrayList<>()), target);
     }
+    
+    @InterfaceTest
+    public void basicGet(List<T> target) {
+        assertEquals(0, target.size());
+        $list.range(0,8).into(target);
+        
+        assertEquals(8, target.size());
+        
+		assertEquals($list.item(3).value(), target.get(3));
+		assertEquals($list.item(5).value(), target.get(5));
+		assertEquals($list.item(7).value(), target.get(7));
+        assertThrows(IndexOutOfBoundsException.class, ()->{
+            target.get(-1);
+        });
+        assertThrows(IndexOutOfBoundsException.class, ()->{
+            target.get(20);
+        });
+        assertThrows(IndexOutOfBoundsException.class, ()->{
+            target.get(8);
+        });
+    }
 	
 	@InterfaceTest
     public void basicSet(List<T> target) {
@@ -156,9 +182,158 @@ public class ListTester<T> {
 		});
 	}
     
+    @InterfaceTest
+    public void basicClear(List<T> target) {
+		$list.list(1,3,5,7,9,11).into(target);
+        assertEquals(6, target.size());
+        assertFalse(target.isEmpty());
+        
+        target.clear();
+        assertEquals(0, target.size());
+        assertTrue(target.isEmpty());
+        
+        $list.list(21,22).into(target);
+        assertEquals(2, target.size());
+        assertFalse(target.isEmpty());
+    }
+        
+    
     @InterfaceTest
     public void basicSerializable(List<T> target) {
         $list.list(1,2,3,4).into(target);
         assertSerializable(target);
     }
+    
+    @InterfaceTest
+    public void basicEquals(Supplier<List<T>> generator) {
+        List<T> list1 = $list.list(1,2,3,4).into(generator.get());
+        List<T> list2 = $list.list(1,2,3,4).into(generator.get());
+        List<T> list3 = $list.list(1,5,6,8).into(generator.get());
+        List<T> list4 = $list.list(1,2,3).into(generator.get());
+        List<T> list5 = $list.list(1,2,4,3).into(generator.get());
+        
+        assertEquality(list1, list2, list3);
+        assertEquality(list1, list2, list4);
+        assertEquality(list1, list2, list5);
+    }
+    
+    @InterfaceTest
+    public void basicSublist(List<T> target) {
+        $list.list(1,3,5,7,9).into(target);
+        
+        assertEquals($values(3,5,7,9), target.subList(1, 5));
+        assertEquals($values(3,5,7), target.subList(1, 4));
+        assertEquals($values(1,3,5,7,9), target.subList(0, 5));
+        
+        assertThrows(IndexOutOfBoundsException.class, ()->{
+            target.subList(-1, 3);
+        });
+        assertThrows(IndexOutOfBoundsException.class, ()->{
+            target.subList(1, 30);
+        });
+        assertThrows(IndexOutOfBoundsException.class, ()->{
+            target.subList(0, 6);
+        });
+        assertThrows(IllegalArgumentException.class, ()->{
+            target.subList(4, 1);
+        });
+    }
+    
+    @InterfaceTest
+    public void basicSublist_indexOf(List<T> target) {
+        $list.list(1,3,5,7,9).into(target);
+        
+        assertEquals(-1, target.subList(1, 3).indexOf($list.item(9).value()));
+        assertEquals(-1, target.subList(1, 3).indexOf($list.item(1).value()));
+        assertEquals(1, target.subList(1, 3).indexOf($list.item(5).value()));
+    }
+    
+    @InterfaceTest
+    public void basicSublist_lastIndexOf(List<T> target) {
+        $list.list(1,3,5,7,9).into(target);
+        
+        assertEquals(-1, target.subList(1, 3).lastIndexOf($list.item(9).value()));
+        assertEquals(-1, target.subList(1, 3).lastIndexOf($list.item(1).value()));
+        assertEquals(1, target.subList(1, 3).lastIndexOf($list.item(5).value()));
+    }
+    
+    @InterfaceTest
+    public void basicSublist_add(List<T> target) {
+        $list.list(1,3,5,7,9).into(target);
+        List<T> sub = target.subList(1, 3);
+        
+        assertEquals($values(3,5), sub);
+        assertEquals($values(1,3,5,7,9), target);
+        
+        sub.add(1, $list.item(21).value());
+        assertEquals($values(3,21,5), sub);
+        assertEquals($values(1,3,21,5,7,9), target);
+        
+        sub.add($list.item(31).value());
+        assertEquals($values(3,21,5,31), sub);
+        assertEquals($values(1,3,21,5,31,7,9), target);
+    }
+    
+    @InterfaceTest
+    public void basicSublist_addAll(List<T> target) {
+        $list.list(1,3,5,7,9).into(target);
+        List<T> sub = target.subList(1, 3);
+        
+        assertEquals($values(3,5), sub);
+        assertEquals($values(1,3,5,7,9), target);
+        
+        sub.addAll(1, $values(21,22));
+        assertEquals($values(3,21,22,5), sub);
+        assertEquals($values(1,3,21,22,5,7,9), target);
+        
+        sub.addAll($values(31,32));
+        assertEquals($values(3,21,22,5,31,32), sub);
+        assertEquals($values(1,3,21,22,5,31,32,7,9), target);
+    }
+    
+    @InterfaceTest
+    public void basicSublist_clear(List<T> target) {
+        $list.list(1,3,5,7,9).into(target);
+        List<T> sub = target.subList(1, 3);
+        
+        sub.clear();
+        assertEquals(Collections.emptyList(), sub);
+        assertEquals($values(1,7,9), target);
+        
+        sub.addAll($values(31,32));
+        assertEquals($values(31,32), sub);
+        assertEquals($values(1,31,32,7,9), target);
+    }
+    
+    @InterfaceTest
+    public void basicSublist_set(List<T> target) {
+        $list.list(1,3,5,7,9).into(target);
+        List<T> sub = target.subList(1, 3);
+        
+        assertEquals($list.item(3).value(), sub.set(0, $list.item(21).value()));
+        assertEquals($list.item(5).value(), sub.set(1, $list.item(22).value()));
+        
+        assertEquals($list.item(21).value(), sub.get(0));
+        assertEquals($list.item(22).value(), sub.get(1));
+        
+        assertEquals($values(21,22), sub);
+        assertEquals($values(1,21,22,7,9), target);
+    }
+    
+    @InterfaceTest
+    public void nestedSublistTest(Supplier<List<T>> target) {
+        if(!$nest) {
+            throw new UnsupportedOperationException("TEST.SILENT");
+        }
+        new InterfaceSuite(System.err)
+            .append(new ListTester<>())
+            .append(new IntListTester())
+            .param("list!", $list)
+            .run(()->target.get().subList(0, 0));
+        
+    }
+    
+    private List<T> $values(int... values) {
+        return $list.list(values).into(new ArrayList<>());
+    }
 }