Sfoglia il codice sorgente

test (19)

fix: unechecked ClassCastException
	IntCollection, CustomLookup, HashLookup, IdentLookup

fix: AHashLookup - #trim infinite loop
fix: AHashLookup - serialization
fix: AHashLookup - values#remove

fix: CustomLookup - serialization

fix: SortedLookup - entries/values/keys#remove

fix: ASortedMap - JVM-inner-class bug 

new: Fold/IntFold extends JDK8 functional interface

new: ExceptionInspector - backported from assira1
Ranides Atterwim 11 anni fa
parent
commit
b14a2adadb
23 ha cambiato i file con 1951 aggiunte e 787 eliminazioni
  1. 9 0
      assira/src/main/java/net/ranides/assira/collection/IntCollection.java
  2. 42 21
      assira/src/main/java/net/ranides/assira/collection/lookups/AHashLookup.java
  3. 25 3
      assira/src/main/java/net/ranides/assira/collection/lookups/CustomLookup.java
  4. 12 2
      assira/src/main/java/net/ranides/assira/collection/lookups/HashLookup.java
  5. 6 1
      assira/src/main/java/net/ranides/assira/collection/lookups/IdentLookup.java
  6. 22 3
      assira/src/main/java/net/ranides/assira/collection/lookups/SortedLookup.java
  7. 532 528
      assira/src/main/java/net/ranides/assira/collection/maps/ASortedMap.java
  8. 4 1
      assira/src/main/java/net/ranides/assira/functional/Fold.java
  9. 7 1
      assira/src/main/java/net/ranides/assira/functional/IntFold.java
  10. 131 0
      assira/src/main/java/net/ranides/assira/trace/ExceptionInspector.java
  11. 49 34
      assira/src/test/java/net/ranides/assira/collection/lookups/AVLTreeLookupTest.java
  12. 50 46
      assira/src/test/java/net/ranides/assira/collection/lookups/CustomLookupTest.java
  13. 107 0
      assira/src/test/java/net/ranides/assira/collection/lookups/RBTreeLookupTest.java
  14. 114 0
      assira/src/test/java/net/ranides/assira/collection/maps/AVLTreeMapTest.java
  15. 112 0
      assira/src/test/java/net/ranides/assira/collection/maps/CustomMapTest.java
  16. 114 0
      assira/src/test/java/net/ranides/assira/collection/maps/RBTreeMapTest.java
  17. 342 35
      assira/src/test/java/net/ranides/assira/collection/mockup/ALookupTester.java
  18. 132 0
      assira/src/test/java/net/ranides/assira/collection/mockup/LookupTesterSuite.java
  19. 111 99
      assira/src/test/java/net/ranides/assira/collection/mockup/TPoint.java
  20. 4 0
      assira/src/test/java/net/ranides/assira/collection/mockup/TPointEnum.java
  21. 6 0
      assira/src/test/java/net/ranides/assira/collection/mockup/TPointGenerator.java
  22. 13 13
      assira/src/test/java/net/ranides/assira/collection/mockup/TPointTester.java
  23. 7 0
      assira/src/test/java/net/ranides/assira/collection/mockup/TestGenerator.java

+ 9 - 0
assira/src/main/java/net/ranides/assira/collection/IntCollection.java

@@ -39,6 +39,9 @@ public abstract class IntCollection extends ACollection<Integer> implements Coll
     
     @Override
     public boolean contains(Object value) {
+        if(!(value instanceof Integer)) {
+            return false;
+        }
         return contains( ((Integer)value).intValue() );
     }
     
@@ -109,11 +112,17 @@ public abstract class IntCollection extends ACollection<Integer> implements Coll
     }
     
     public boolean rem(Object value) {
+        if(!(value instanceof Integer)) {
+            return false;
+        }
         return rem( ((Integer)value).intValue() );
     }
     
     @Override
     public boolean remove(Object value) {
+        if(!(value instanceof Integer)) {
+            return false;
+        }
         return rem( ((Integer) value).intValue() );
     }
 

+ 42 - 21
assira/src/main/java/net/ranides/assira/collection/lookups/AHashLookup.java

@@ -202,27 +202,7 @@ public abstract class AHashLookup<K> extends Lookup<K> implements java.io.Serial
 	@Override
     public final IntCollection values() {
         if (mvalues == null) {
-            mvalues = new IntCollection() {
-                @Override
-                public IntIterator iterator() {
-                    return new ValueIterator();
-                }
-
-                @Override
-                public int size() {
-                    return size;
-                }
-
-                @Override
-                public boolean contains(int v) {
-                    return containsValue(v);
-                }
-
-                @Override
-                public void clear() {
-                    AHashLookup.this.clear();
-                }
-            };
+            mvalues = new ValuesCollection();
         }
         return mvalues;
     }
@@ -277,6 +257,9 @@ public abstract class AHashLookup<K> extends Lookup<K> implements java.io.Serial
         if (this.n <= l) {
             return true;
         }
+        if(l<size) {
+            throw new IllegalArgumentException(String.format("n= %d is too small (L=%d size=%d)", n, l, size));
+        }
         try {
             irehash(l);
         } catch (OutOfMemoryError cantDoIt) {
@@ -425,12 +408,21 @@ public abstract class AHashLookup<K> extends Lookup<K> implements java.io.Serial
         used[segment] = false;
         keys[segment] = null;
     }
+    
+    protected void readObjectDetails(java.io.ObjectInputStream istream) throws java.io.IOException, ClassNotFoundException {
+        // do nothing
+    }
+    
+    protected void writeObjectDetails(java.io.ObjectOutputStream ostream) throws java.io.IOException {
+        // do nothing
+    }
 
     private void writeObject(java.io.ObjectOutputStream ostream) throws java.io.IOException {
         K ikeys[] = this.keys;
         int ivalues[] = this.values;
         MapIterator iterator = new MapIterator();
         ostream.defaultWriteObject();
+        writeObjectDetails(ostream);
         for (int j = size, element; j-- != 0;) {
             element = iterator.nextEntry();
             ostream.writeObject(ikeys[ element]);
@@ -444,6 +436,7 @@ public abstract class AHashLookup<K> extends Lookup<K> implements java.io.Serial
     })
     private void readObject(java.io.ObjectInputStream istream) throws java.io.IOException, ClassNotFoundException {
         istream.defaultReadObject();
+        readObjectDetails(istream);
         n = HashCollection.arraysize(size, factor);
         capacity = HashCollection.factorsize(n, factor);
         mask = n - 1;
@@ -728,6 +721,28 @@ public abstract class AHashLookup<K> extends Lookup<K> implements java.io.Serial
             AHashLookup.this.clear();
         }
     }
+    
+    private final class ValuesCollection extends IntCollection {
+        @Override
+        public IntIterator iterator() {
+            return new ValueIterator();
+        }
+
+        @Override
+        public int size() {
+            return size;
+        }
+
+        @Override
+        public boolean contains(int v) {
+            return containsValue(v);
+        }
+
+        @Override
+        public void clear() {
+            AHashLookup.this.clear();
+        }
+    }
 
     private final class ValueIterator extends IntIterator {
 
@@ -749,6 +764,12 @@ public abstract class AHashLookup<K> extends Lookup<K> implements java.io.Serial
         public boolean hasNext() {
             return delegate.hasNext();
         }
+
+        @Override
+        public void remove() {
+            delegate.remove();
+        }
+        
     }
 
 }

+ 25 - 3
assira/src/main/java/net/ranides/assira/collection/lookups/CustomLookup.java

@@ -6,6 +6,7 @@
  */
 package net.ranides.assira.collection.lookups;
 
+import java.io.IOException;
 import net.ranides.assira.collection.utils.HashUtils;
 import net.ranides.assira.collection.HashComparator;
 import java.util.Map;
@@ -19,7 +20,7 @@ public final class CustomLookup<K> extends AHashLookup<K> {
 
     private static final long serialVersionUID = 2L;
     
-    protected HashComparator<K> strategy;
+    protected transient HashComparator<K> strategy;
 
     /**
      * Creates a new hash map.
@@ -151,12 +152,33 @@ public final class CustomLookup<K> extends AHashLookup<K> {
 
     @Override
     protected int hash(K key) {
-        return HashUtils.murmurHash3(strategy.hashCode(key));
+        try {
+            return HashUtils.murmurHash3(strategy.hashCode(key));
+        } catch(ClassCastException ex) {
+            // "unchecked" generic methods could pass something strange here
+            return 0;
+        }
     }
 
     @Override
     protected boolean compare(K key1, K key2) {
-        return strategy.equals(key1, key2);
+        try {
+            return strategy.equals(key1, key2);
+        } catch(ClassCastException ex) {
+            // "unchecked" generic methods could pass something strange here
+            return false;
+        }
+    }
+    
+    @SuppressWarnings("unchecked")
+    @Override
+    protected void readObjectDetails(java.io.ObjectInputStream istream) throws IOException, ClassNotFoundException {
+        this.strategy = (HashComparator<K>)istream.readObject();
+    }
+    
+    @Override
+    protected void writeObjectDetails(java.io.ObjectOutputStream ostream) throws IOException {
+        ostream.writeObject(this.strategy);
     }
 
 }

+ 12 - 2
assira/src/main/java/net/ranides/assira/collection/lookups/HashLookup.java

@@ -128,12 +128,22 @@ public final class HashLookup<K> extends AHashLookup<K> {
     
     @Override
     protected int hash(K key) {
-        return key == null ? 0x87fcd5c : HashUtils.murmurHash3(key.hashCode());
+        try {
+            return key == null ? 0x87fcd5c : HashUtils.murmurHash3(key.hashCode());
+        } catch(ClassCastException ex) {
+            // "unchecked" generic methods could pass something strange here
+            return 0;
+        }
     }
 
     @Override
     protected boolean compare(K key1, K key2) {
-        return ValueUtils.equals(key1, key2);
+        try {
+            return ValueUtils.equals(key1, key2);
+        } catch(ClassCastException ex) {
+            // "unchecked" generic methods could pass something strange here
+            return false;
+        }
     }
     
 }

+ 6 - 1
assira/src/main/java/net/ranides/assira/collection/lookups/IdentLookup.java

@@ -130,7 +130,12 @@ public final class IdentLookup<K> extends AHashLookup<K> {
     
     @Override
     protected int hash(K key) {
-        return key == null ? 0x87fcd5c : HashUtils.murmurHash3(System.identityHashCode(key));
+        try {
+            return key == null ? 0x87fcd5c : HashUtils.murmurHash3(System.identityHashCode(key));
+        } catch(ClassCastException ex) {
+            // "unchecked" generic methods could pass something strange here
+            return 0;
+        }
     }
 
     @Override

+ 22 - 3
assira/src/main/java/net/ranides/assira/collection/lookups/SortedLookup.java

@@ -53,7 +53,12 @@ public abstract class SortedLookup<K> extends Lookup<K> implements SortedMap<K,
 	protected abstract SortedLookup<K> submap(K begin, boolean bottom, K end, boolean top);
 	
 	protected final int compare(K key1, K key2) {
-        return ValueUtils.cmp(acmp, key1, key2);
+        try {
+            return ValueUtils.cmp(acmp, key1, key2);
+        } catch(ClassCastException ex) {
+            // "unchecked" generic methods could pass something strange here
+            return -1;
+        }
     }
     
     protected final K lower(K key1, K key2) {
@@ -265,6 +270,15 @@ public abstract class SortedLookup<K> extends Lookup<K> implements SortedMap<K,
         public Iterator<K> iterator() {
             return new KeySetIterator<>(SortedLookup.this.entryIterator());
         }
+
+        @Override
+        public boolean remove(Object value) {
+            int prev = SortedLookup.this.size();
+            SortedLookup.this.remove(value);
+            return prev != SortedLookup.this.size();
+        }
+        
+        
     }
 
     /**
@@ -293,7 +307,7 @@ public abstract class SortedLookup<K> extends Lookup<K> implements SortedMap<K,
 
         @Override
         public void remove() {
-            throw new UnsupportedOperationException();
+            riv.remove();
         }
     }
     
@@ -366,6 +380,11 @@ public abstract class SortedLookup<K> extends Lookup<K> implements SortedMap<K,
         public int previousIndex() {
             return delegate.previousIndex();
         }
+
+        @Override
+        public void remove() {
+            delegate.remove();
+        }
 		
     }
 
@@ -408,7 +427,7 @@ public abstract class SortedLookup<K> extends Lookup<K> implements SortedMap<K,
 			Map.Entry<K, Integer> entry = (Map.Entry<K, Integer>) object;
 			LookupEntry<K> found = that.findEntry(entry.getKey());
 			if (found != null) {
-				that.removeInt(found.getIntValue());
+				that.removeInt(found.getKey());
 			}
 			return found != null;
 		}

File diff suppressed because it is too large
+ 532 - 528
assira/src/main/java/net/ranides/assira/collection/maps/ASortedMap.java


+ 4 - 1
assira/src/main/java/net/ranides/assira/functional/Fold.java

@@ -6,12 +6,15 @@
  */
 package net.ranides.assira.functional;
 
+import java.util.function.BinaryOperator;
+
 /**
  *
  * @author Ranides Atterwim <ranides@gmail.com>
  */
-public interface Fold<T> {
+public interface Fold<T> extends BinaryOperator<T>{
 
+    @Override
     T apply(T value1, T value2);
     
 }

+ 7 - 1
assira/src/main/java/net/ranides/assira/functional/IntFold.java

@@ -6,10 +6,16 @@
  */
 package net.ranides.assira.functional;
 
-public interface IntFold {
+import java.util.function.IntBinaryOperator;
+
+public interface IntFold extends IntBinaryOperator {
     
     int NONE = Integer.MAX_VALUE;
 
     int apply(int v1, int v2);
     
+    @Override
+    default int applyAsInt(int left, int right) {
+        return apply(left, right);
+    }
 }

+ 131 - 0
assira/src/main/java/net/ranides/assira/trace/ExceptionInspector.java

@@ -0,0 +1,131 @@
+/*
+ *  @author Ranides Atterwim <ranides@gmail.com>
+ *  @copyright Ranides Atterwim
+ *  @license WTFPL
+ *  @url http://ranides.net/projects/assira
+ */
+
+package net.ranides.assira.trace;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/**
+ *
+ * @author ranides
+ */
+public final class ExceptionInspector {
+
+    private ExceptionInspector() { }
+
+    public static List<Throwable> getCauseList(Throwable cause) {
+        List<Throwable> result = new ArrayList<>();
+        for(Throwable i=cause; null!=i; i=i.getCause() ) {
+            result.add(i);
+        }
+        return result;
+    }
+
+    public static List<String> getMessageList(Throwable cause) {
+        return map(cause, (item) -> item.getMessage());
+    }
+
+    public static List<String> getLocalizedMessageList(Throwable cause) {
+        return map(cause, (item) -> item.getLocalizedMessage());
+    }
+
+    public static List<Class<?>> getClassList(Throwable cause) {
+        return map(cause, (item) -> item.getClass());
+    }
+
+    public static List<String> getClassNameList(Throwable cause) {
+        return map(cause, (item) -> item.getClass().getSimpleName());
+    }
+
+    public static List<String> getFilesList(Throwable cause) {
+        return map(cause.getStackTrace(), (item) -> String.format("%4d : %s", item.getLineNumber(), item.getFileName()));
+    }
+    
+    public static String getStackTrace(Throwable cause) {
+        StringWriter result = new StringWriter();
+        PrintWriter writer = new PrintWriter(result);
+        cause.printStackTrace(writer);
+        writer.flush();
+        return result.toString();
+    }
+
+    public static RuntimeException rethrow(Throwable cause) {
+        new ExceptionErasure<RuntimeException>().rethrow(cause);
+        
+        // not reachable, wyjątek bez wrappowania leci linię wyżej
+        throw new RuntimeException(cause); 
+    }
+    
+    private static class ExceptionErasure<T extends Throwable> { // NOPMD
+        
+        @SuppressWarnings("unchecked")
+        private void rethrow(Throwable exception) throws T {
+            throw (T) exception;
+        }
+
+    }
+    
+    public static AssertionError assertError(String message, Throwable cause) {
+        AssertionError error = new AssertionError(message);
+        error.initCause(cause);
+        return error;
+    }
+	
+	public static void print(PrintStream stream, List<? extends Throwable> list) {
+		if(list.isEmpty()) {
+			return;
+		}
+		stream.println();
+		stream.println("CauseList: ");
+		for(int i=0, n=list.size(); i<n; i++) {
+			stream.println("\t[" + i + "] " + list.get(i));
+		}
+		stream.println();
+		for(int i=0, n=list.size(); i<n; i++) {
+			stream.print("CauseList details["+i+"]: ");
+			list.get(i).printStackTrace(stream);
+		}
+    }
+
+    public static void print(PrintWriter writer, List<? extends Throwable> list) {
+        if(list.isEmpty()) {
+			return;
+		}
+		writer.println();
+		writer.println("CauseList: ");
+		for(int i=0, n=list.size(); i<n; i++) {
+			writer.println("\t[" + i + "] " + list.get(i));
+		}
+		writer.println();
+		for(int i=0, n=list.size(); i<n; i++) {
+			writer.println("Caused by["+i+"]:");
+			list.get(i).printStackTrace(writer);
+		}
+    }
+    
+    // @todo (assira # 4) move to collection.lists
+
+    private static <T> List<T> map(Throwable cause, Function<Throwable, T> function) {
+        return getCauseList(cause).stream().map(function).collect(Collectors.toList());
+    }
+    
+    private static <S,T> List<T> map(S[] list, Function<S, T> function) {
+        return Arrays.asList(list).stream().map(function).collect(Collectors.toList());
+    }
+    
+    private static <S,T> List<T> map(List<S> list, Function<S, T> function) {
+        return list.stream().map(function).collect(Collectors.toList());
+    }
+
+}

+ 49 - 34
assira/src/test/java/net/ranides/assira/collection/lookups/AVLTreeLookupTest.java

@@ -6,21 +6,26 @@
  */
 package net.ranides.assira.collection.lookups;
 
-import java.util.Map;
-import net.ranides.assira.collection.mockup.ALookupTester;
+import net.ranides.assira.collection.mockup.LookupTesterSuite;
 import net.ranides.assira.collection.mockup.TPoint;
 import net.ranides.assira.collection.mockup.TPointGenerator;
+import net.ranides.assira.collection.mockup.TestGenerator;
 import static net.ranides.assira.junit.QAssert.*;
 import org.junit.Test;
 import static org.junit.Assert.*;
 
 /**
- * @todo (assira # 1) test: review & backport
+ * 
+ * @todo (assira # 1) test: tree
  * @author Ranides Atterwim <ranides@gmail.com>
  */
 public class AVLTreeLookupTest {
     
-    private final ALookupTester tester = new ALookupTester(new TPointGenerator());
+    private final TestGenerator<Lookup<TPoint>> maps = new TestGenerator<>(
+        () -> new AVLTreeLookup<>(TPoint.SUM)
+    );
+    
+    private final LookupTesterSuite common = new LookupTesterSuite(maps);
 
     @Test
     public void testConstruct() {
@@ -31,14 +36,6 @@ public class AVLTreeLookupTest {
     @Test
     public void testConstructCopy() {
         TPointGenerator generator = new TPointGenerator();
-        Map<TPoint, Integer> imap = generator.map(generator.ukeys(60));
-        
-//        assertEquals(120, new AVLTreeLookup<>(imap, TPoint.SUM).size());
-        
-//        assertEquals(120, new AVLTreeLookup<>(new CustomLookup<>(imap, TPoint.SUM), TPoint.SUM).size());
-//        assertEquals(120, new AVLTreeLookup<>(new CustomLookup<>(imap, TPoint.SUM), TPoint.STD).size());
-//        assertEquals(120, new AVLTreeLookup<>(new CustomLookup<>(imap, TPoint.STD), TPoint.SUM).size());
-//        assertEquals(180, new AVLTreeLookup<>(new CustomLookup<>(imap, TPoint.STD), TPoint.STD).size());
         
         assertEquals(120, new AVLTreeLookup<>(generator.ukeys(60), generator.values(180), TPoint.SUM).size());
         
@@ -49,43 +46,61 @@ public class AVLTreeLookupTest {
     
     @Test
     public void testPut() {
-        tester.basicPutInt(new AVLTreeLookup<>(TPoint.SUM));
-        tester.basicPutInt(new AVLTreeLookup<>(TPoint.SUM), 128);
-        tester.basicPutReplaceInt(new AVLTreeLookup<>(TPoint.SUM), 40);
-        
-        tester.basicPutInteger(new AVLTreeLookup<>(TPoint.SUM));
-        tester.basicPutInteger(new AVLTreeLookup<>(TPoint.SUM), 128);
-        tester.basicPutReplaceInteger(new AVLTreeLookup<>(TPoint.SUM), 40);
-        
+        common.put();
         assertTrue(true);
     }
 
     @Test
     public void testRemove() {
-        tester.basicRemoveInt(new AVLTreeLookup<>(TPoint.SUM));
-        tester.basicRemoveInt(new AVLTreeLookup<>(TPoint.SUM), 97);
-        tester.logicRemoveInt(new AVLTreeLookup<>(TPoint.SUM));
-        
-        tester.basicRemoveInteger(new AVLTreeLookup<>(TPoint.SUM));
-        tester.basicRemoveInteger(new AVLTreeLookup<>(TPoint.SUM), 97);
-        tester.logicRemoveInteger(new AVLTreeLookup<>(TPoint.SUM));
-        
+        common.remove();
         assertTrue(true);
     }
     
     @Test
     public void testGet() {
-        tester.basicGetInt( new AVLTreeLookup<>(TPoint.SUM) );
-        tester.basicGetInteger( new AVLTreeLookup<>(TPoint.SUM) );
-        
+        common.get();
         assertTrue(true);
     }
     
     @Test
     public void testContainsValue() {
-        tester.basicContainsInt( new AVLTreeLookup<>(TPoint.SUM) );
-        tester.basicContainsInteger( new AVLTreeLookup<>(TPoint.SUM) );
-        
+        common.containsValue();
+        assertTrue(true);
+    }
+	
+	@Test
+    public void testClear() {
+		common.clear();
+        assertTrue(true);
+	}
+	
+	@Test
+    public void testEntrySet() {
+		common.entrySet();
+		assertTrue(true);
+	}
+    
+    @Test
+    public void testKeySet() {
+        common.keySet();
+		assertTrue(true);
+    }
+    
+    @Test
+    public void testValues() {
+        common.values();
+		assertTrue(true);
+    }
+    
+    @Test
+    public void testEquality() {
+        common.equality();
+        assertTrue(true);
+    }
+    
+    @Test
+    public void testSerializable() {
+        common.serializable();
         assertTrue(true);
     }
     

+ 50 - 46
assira/src/test/java/net/ranides/assira/collection/lookups/CustomLookupTest.java

@@ -7,10 +7,10 @@
 package net.ranides.assira.collection.lookups;
 
 import net.ranides.assira.collection.mockup.TPointGenerator;
-import net.ranides.assira.collection.mockup.ALookupTester;
+import net.ranides.assira.collection.mockup.LookupTester;
 import java.util.Map;
+import net.ranides.assira.collection.mockup.LookupTesterSuite;
 import net.ranides.assira.collection.mockup.TPoint;
-import net.ranides.assira.collection.mockup.TPointEnum;
 import net.ranides.assira.collection.mockup.TestGenerator;
 import org.junit.Test;
 import static org.junit.Assert.*;
@@ -22,12 +22,14 @@ import static net.ranides.assira.junit.QAssert.*;
  */
 public class CustomLookupTest {
     
-    private final ALookupTester tester = new ALookupTester(new TPointGenerator());
-    
-    private final TestGenerator<Lookup<TPoint>> maps = new TestGenerator<>(
-        (i) -> new CustomLookup<>(TPoint.SUM)
+    private final TestGenerator<CustomLookup<TPoint>> maps = new TestGenerator<>(
+        () -> new CustomLookup<>(TPoint.SUM)
     );
     
+    private final LookupTester tester = new LookupTester();
+    
+    private final LookupTesterSuite common = new LookupTesterSuite(maps);
+    
     @Test
     public void testConstruct() {
         assertNotNull( new CustomLookup<>(32, 0.75f, TPoint.SUM) );
@@ -70,73 +72,75 @@ public class CustomLookupTest {
         );
     }
     
+    @Test
+    public void testTrim() {
+		tester.basicTrim( maps.create() );
+        assertThrows(IllegalArgumentException.class, () -> 
+            tester.basicTrim( maps.create(), 32, 1)
+        );
+		tester.basicTrim( maps.create(), 32, 1024);
+		
+		assertTrue(true);
+	}
+    
     @Test
     public void testPut() {
-        tester.basicPutInt(maps.create());
-        tester.basicPutInt(maps.create(), 128);
-        tester.basicPutReplaceInt(maps.create(), 40);
-        tester.basicPutRandomInt(maps.create(), 220);
-        
-        tester.basicPutInteger(maps.create());
-        tester.basicPutInteger(maps.create(), 128);
-        tester.basicPutReplaceInteger(maps.create(), 40);
-		tester.basicPutRandomInteger(maps.create(), 220);
-        
+        common.put();
         assertTrue(true);
     }
 
     @Test
     public void testRemove() {
-        tester.basicRemoveInt(maps.create());
-        tester.basicRemoveInt(maps.create(), 97);
-        tester.logicRemoveInt(maps.create());
-        
-        tester.basicRemoveInteger(maps.create());
-        tester.basicRemoveInteger(maps.create(), 97);
-        tester.logicRemoveInteger(maps.create());
-        
+        common.remove();
         assertTrue(true);
     }
     
     @Test
     public void testGet() {
-        tester.basicGetInt( maps.create() );
-        tester.basicGetInteger( maps.create() );
-        
+        common.get();
         assertTrue(true);
     }
     
     @Test
     public void testContainsValue() {
-        tester.basicContainsInt( maps.create() );
-        tester.basicContainsInteger( maps.create() );
-        
+        common.containsValue();
         assertTrue(true);
     }
 	
 	@Test
     public void testClear() {
-		tester.basicClear( maps.create() );
-		
-		assertTrue(true);
+		common.clear();
+        assertTrue(true);
 	}
 	
 	@Test
     public void testEntrySet() {
-		tester.basicEntrySet_Contains(maps.create());
-		tester.basicEntrySet_Remove(maps.create());
-        
-		tester.basicEntrySet_IteratorInt(maps.create());
-		tester.basicEntrySet_IteratorInteger(maps.create());
-		
-        tester.basicEntrySet_Iterator_SetValueInt(maps.create());
-        tester.basicEntrySet_Iterator_SetValueInteger(maps.create());
-        
-		tester.basicEntrySet_Iterator_Remove(maps.create());
-        tester.basicEntrySet_Iterator_RemoveAll(maps.create());
-		
-        // @todo (assira # 3) dorzucić tutaj kiedyś standardowy test dla Set<?>
+		common.entrySet();
 		assertTrue(true);
 	}
     
+    @Test
+    public void testKeySet() {
+        common.keySet();
+		assertTrue(true);
+    }
+    
+    @Test
+    public void testValues() {
+        common.values();
+		assertTrue(true);
+    }
+    
+    @Test
+    public void testEquality() {
+        common.equality();
+        assertTrue(true);
+    }
+    
+    @Test
+    public void testSerializable() {
+        common.serializable();
+        assertTrue(true);
+    }
+    
 }

+ 107 - 0
assira/src/test/java/net/ranides/assira/collection/lookups/RBTreeLookupTest.java

@@ -0,0 +1,107 @@
+/*
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/???
+ */
+package net.ranides.assira.collection.lookups;
+
+import net.ranides.assira.collection.mockup.LookupTesterSuite;
+import net.ranides.assira.collection.mockup.TPoint;
+import net.ranides.assira.collection.mockup.TPointGenerator;
+import net.ranides.assira.collection.mockup.TestGenerator;
+import static net.ranides.assira.junit.QAssert.*;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ * @todo (assira # 1) test: tree
+ * @author Ranides Atterwim <ranides@gmail.com>
+ */
+public class RBTreeLookupTest {
+    
+    private final TestGenerator<Lookup<TPoint>> maps = new TestGenerator<>(
+        () -> new RBTreeLookup<>(TPoint.SUM)
+    );
+    
+    private final LookupTesterSuite common = new LookupTesterSuite(maps);
+
+    @Test
+    public void testConstruct() {
+        assertNotNull( new RBTreeLookup<>() );
+        assertNotNull( new RBTreeLookup<>(TPoint.SUM) );
+    }
+    
+    @Test
+    public void testConstructCopy() {
+        TPointGenerator generator = new TPointGenerator();
+        
+        assertEquals(120, new RBTreeLookup<>(generator.ukeys(60), generator.values(180), TPoint.SUM).size());
+        
+        assertThrows(IllegalArgumentException.class, () -> 
+            new RBTreeLookup<>(generator.ukeys(60), generator.values(10), TPoint.SUM)
+        );
+    }
+    
+    @Test
+    public void testPut() {
+        common.put();
+        assertTrue(true);
+    }
+
+    @Test
+    public void testRemove() {
+        common.remove();
+        assertTrue(true);
+    }
+    
+    @Test
+    public void testGet() {
+        common.get();
+        assertTrue(true);
+    }
+    
+    @Test
+    public void testContainsValue() {
+        common.containsValue();
+        assertTrue(true);
+    }
+	
+	@Test
+    public void testClear() {
+		common.clear();
+        assertTrue(true);
+	}
+	
+	@Test
+    public void testEntrySet() {
+		common.entrySet();
+		assertTrue(true);
+	}
+    
+    @Test
+    public void testKeySet() {
+        common.keySet();
+		assertTrue(true);
+    }
+    
+    @Test
+    public void testValues() {
+        common.values();
+		assertTrue(true);
+    }
+    
+    @Test
+    public void testEquality() {
+        common.equality();
+        assertTrue(true);
+    }
+    
+    @Test
+    public void testSerializable() {
+        common.serializable();
+        assertTrue(true);
+    }
+    
+}

+ 114 - 0
assira/src/test/java/net/ranides/assira/collection/maps/AVLTreeMapTest.java

@@ -0,0 +1,114 @@
+/*
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/???
+ */
+package net.ranides.assira.collection.maps;
+
+import java.util.Map;
+import net.ranides.assira.collection.lookups.RBTreeLookup;
+import net.ranides.assira.collection.mockup.LookupTester;
+import net.ranides.assira.collection.mockup.TPoint;
+import net.ranides.assira.collection.mockup.TPointGenerator;
+import net.ranides.assira.collection.mockup.TestGenerator;
+import static net.ranides.assira.junit.QAssert.assertThrows;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ * 
+ * @todo (assira # 2) test: review & backport
+ * @author Ranides Atterwim <ranides@gmail.com>
+ */
+public class AVLTreeMapTest {
+    
+    private final LookupTester tester = new LookupTester();
+    
+    private final TestGenerator<Map<TPoint, Integer>> maps = new TestGenerator<>(
+        () -> new AVLTreeMap<>(TPoint.SUM)
+    );
+
+    @Test
+    public void testConstruct() {
+        assertNotNull( new AVLTreeMap<>() );
+        assertNotNull( new AVLTreeMap<>(TPoint.SUM) );
+    }
+    
+    @Test
+    public void testConstructCopy() {
+        TPointGenerator generator = new TPointGenerator();
+//        Map<TPoint, Integer> imap = generator.map(generator.ukeys(60));
+        
+//        assertEquals(120, new RBTreeLookup<>(imap, TPoint.SUM).size());
+        
+//        assertEquals(120, new RBTreeLookup<>(new CustomLookup<>(imap, TPoint.SUM), TPoint.SUM).size());
+//        assertEquals(120, new RBTreeLookup<>(new CustomLookup<>(imap, TPoint.SUM), TPoint.STD).size());
+//        assertEquals(120, new RBTreeLookup<>(new CustomLookup<>(imap, TPoint.STD), TPoint.SUM).size());
+//        assertEquals(180, new RBTreeLookup<>(new CustomLookup<>(imap, TPoint.STD), TPoint.STD).size());
+        
+        assertEquals(120, new AVLTreeMap<>(generator.ukeys(60), generator.objects(180), TPoint.SUM).size());
+        
+        assertThrows(IllegalArgumentException.class, () -> 
+            new RBTreeLookup<>(generator.ukeys(60), generator.values(10), TPoint.SUM)
+        );
+    }
+    
+    @Test
+    public void testPut() {
+       
+        tester.basicPutInteger(maps.create());
+        tester.basicPutInteger(maps.create(), 128);
+        tester.basicPutReplaceInteger(maps.create(), 40);
+		tester.basicPutRandomInteger(maps.create(), 220);
+        
+        assertTrue(true);
+    }
+
+    @Test
+    public void testRemove() {
+        tester.basicRemoveInteger(maps.create());
+        tester.basicRemoveInteger(maps.create(), 97);
+        tester.logicRemoveInteger(maps.create());
+        
+        assertTrue(true);
+    }
+    
+    @Test
+    public void testGet() {
+        tester.basicGetInteger( maps.create() );
+        
+        assertTrue(true);
+    }
+    
+    @Test
+    public void testContainsValue() {
+        tester.basicContainsInteger( maps.create() );
+        
+        assertTrue(true);
+    }
+    
+    @Test
+    public void testClear() {
+		tester.basicClear( maps.create() );
+		
+		assertTrue(true);
+	}
+	
+	@Test
+    public void testEntrySet() {
+		tester.basicEntrySet_Contains(maps.create());
+		tester.basicEntrySet_Remove(maps.create());
+        
+		tester.basicEntrySet_IteratorInteger(maps.create());
+		
+        tester.basicEntrySet_Iterator_SetValueInteger(maps.create());
+        
+		tester.basicEntrySet_Iterator_Remove(maps.create());
+        tester.basicEntrySet_Iterator_RemoveAll(maps.create());
+		
+        // @todo (assira # 3) test: generic set
+		assertTrue(true);
+	}
+    
+}

+ 112 - 0
assira/src/test/java/net/ranides/assira/collection/maps/CustomMapTest.java

@@ -0,0 +1,112 @@
+/*
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/???
+ */
+package net.ranides.assira.collection.maps;
+
+import java.util.Map;
+import net.ranides.assira.collection.lookups.RBTreeLookup;
+import net.ranides.assira.collection.mockup.LookupTester;
+import net.ranides.assira.collection.mockup.TPoint;
+import net.ranides.assira.collection.mockup.TPointGenerator;
+import net.ranides.assira.collection.mockup.TestGenerator;
+import static net.ranides.assira.junit.QAssert.assertThrows;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ * 
+ * @todo (assira # 2) test: review & backport
+ * @author Ranides Atterwim <ranides@gmail.com>
+ */
+public class CustomMapTest {
+    
+    private final LookupTester tester = new LookupTester();
+    
+    private final TestGenerator<Map<TPoint, Integer>> maps = new TestGenerator<>(
+        () -> new CustomMap<>(TPoint.SUM)
+    );
+
+    @Test
+    public void testConstruct() {
+        assertNotNull( new CustomMap<>(TPoint.SUM) );
+    }
+    
+    @Test
+    public void testConstructCopy() {
+        TPointGenerator generator = new TPointGenerator();
+//        Map<TPoint, Integer> imap = generator.map(generator.ukeys(60));
+        
+//        assertEquals(120, new RBTreeLookup<>(imap, TPoint.SUM).size());
+        
+//        assertEquals(120, new RBTreeLookup<>(new CustomLookup<>(imap, TPoint.SUM), TPoint.SUM).size());
+//        assertEquals(120, new RBTreeLookup<>(new CustomLookup<>(imap, TPoint.SUM), TPoint.STD).size());
+//        assertEquals(120, new RBTreeLookup<>(new CustomLookup<>(imap, TPoint.STD), TPoint.SUM).size());
+//        assertEquals(180, new RBTreeLookup<>(new CustomLookup<>(imap, TPoint.STD), TPoint.STD).size());
+        
+        assertEquals(120, new CustomMap<>(generator.ukeys(60), generator.objects(180), TPoint.SUM).size());
+        
+        assertThrows(IllegalArgumentException.class, () -> 
+            new RBTreeLookup<>(generator.ukeys(60), generator.values(10), TPoint.SUM)
+        );
+    }
+    
+    @Test
+    public void testPut() {
+       
+        tester.basicPutInteger(maps.create());
+        tester.basicPutInteger(maps.create(), 128);
+        tester.basicPutReplaceInteger(maps.create(), 40);
+		tester.basicPutRandomInteger(maps.create(), 220);
+        
+        assertTrue(true);
+    }
+
+    @Test
+    public void testRemove() {
+        tester.basicRemoveInteger(maps.create());
+        tester.basicRemoveInteger(maps.create(), 97);
+        tester.logicRemoveInteger(maps.create());
+        
+        assertTrue(true);
+    }
+    
+    @Test
+    public void testGet() {
+        tester.basicGetInteger( maps.create() );
+        
+        assertTrue(true);
+    }
+    
+    @Test
+    public void testContainsValue() {
+        tester.basicContainsInteger( maps.create() );
+        
+        assertTrue(true);
+    }
+    
+    @Test
+    public void testClear() {
+		tester.basicClear( maps.create() );
+		
+		assertTrue(true);
+	}
+	
+	@Test
+    public void testEntrySet() {
+		tester.basicEntrySet_Contains(maps.create());
+		tester.basicEntrySet_Remove(maps.create());
+        
+		tester.basicEntrySet_IteratorInteger(maps.create());
+		
+        tester.basicEntrySet_Iterator_SetValueInteger(maps.create());
+        
+		tester.basicEntrySet_Iterator_Remove(maps.create());
+        tester.basicEntrySet_Iterator_RemoveAll(maps.create());
+		
+        // @todo (assira # 3) test: generic set
+		assertTrue(true);
+	}
+}

+ 114 - 0
assira/src/test/java/net/ranides/assira/collection/maps/RBTreeMapTest.java

@@ -0,0 +1,114 @@
+/*
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/???
+ */
+package net.ranides.assira.collection.maps;
+
+import java.util.Map;
+import net.ranides.assira.collection.lookups.RBTreeLookup;
+import net.ranides.assira.collection.mockup.LookupTester;
+import net.ranides.assira.collection.mockup.TPoint;
+import net.ranides.assira.collection.mockup.TPointGenerator;
+import net.ranides.assira.collection.mockup.TestGenerator;
+import static net.ranides.assira.junit.QAssert.assertThrows;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ * 
+ * @todo (assira # 2) test: review & backport
+ * @author Ranides Atterwim <ranides@gmail.com>
+ */
+public class RBTreeMapTest {
+    
+    private final LookupTester tester = new LookupTester();
+    
+    private final TestGenerator<Map<TPoint, Integer>> maps = new TestGenerator<>(
+        () -> new RBTreeMap<>(TPoint.SUM)
+    );
+
+    @Test
+    public void testConstruct() {
+        assertNotNull( new RBTreeMap<>() );
+        assertNotNull( new RBTreeMap<>(TPoint.SUM) );
+    }
+    
+    @Test
+    public void testConstructCopy() {
+        TPointGenerator generator = new TPointGenerator();
+//        Map<TPoint, Integer> imap = generator.map(generator.ukeys(60));
+        
+//        assertEquals(120, new RBTreeMap<>(imap, TPoint.SUM).size());
+        
+//        assertEquals(120, new RBTreeMap<>(new CustomLookup<>(imap, TPoint.SUM), TPoint.SUM).size());
+//        assertEquals(120, new RBTreeMap<>(new CustomLookup<>(imap, TPoint.SUM), TPoint.STD).size());
+//        assertEquals(120, new RBTreeMap<>(new CustomLookup<>(imap, TPoint.STD), TPoint.SUM).size());
+//        assertEquals(180, new RBTreeMap<>(new CustomLookup<>(imap, TPoint.STD), TPoint.STD).size());
+        
+        assertEquals(120, new RBTreeMap<>(generator.ukeys(60), generator.objects(180), TPoint.SUM).size());
+        
+        assertThrows(IllegalArgumentException.class, () -> 
+            new RBTreeLookup<>(generator.ukeys(60), generator.values(10), TPoint.SUM)
+        );
+    }
+    
+    @Test
+    public void testPut() {
+       
+        tester.basicPutInteger(maps.create());
+        tester.basicPutInteger(maps.create(), 128);
+        tester.basicPutReplaceInteger(maps.create(), 40);
+		tester.basicPutRandomInteger(maps.create(), 220);
+        
+        assertTrue(true);
+    }
+
+    @Test
+    public void testRemove() {
+        tester.basicRemoveInteger(maps.create());
+        tester.basicRemoveInteger(maps.create(), 97);
+        tester.logicRemoveInteger(maps.create());
+        
+        assertTrue(true);
+    }
+    
+    @Test
+    public void testGet() {
+        tester.basicGetInteger( maps.create() );
+        
+        assertTrue(true);
+    }
+    
+    @Test
+    public void testContainsValue() {
+        tester.basicContainsInteger( maps.create() );
+        
+        assertTrue(true);
+    }
+    
+    @Test
+    public void testClear() {
+		tester.basicClear( maps.create() );
+		
+		assertTrue(true);
+	}
+	
+	@Test
+    public void testEntrySet() {
+		tester.basicEntrySet_Contains(maps.create());
+		tester.basicEntrySet_Remove(maps.create());
+        
+		tester.basicEntrySet_IteratorInteger(maps.create());
+		
+        tester.basicEntrySet_Iterator_SetValueInteger(maps.create());
+        
+		tester.basicEntrySet_Iterator_Remove(maps.create());
+        tester.basicEntrySet_Iterator_RemoveAll(maps.create());
+		
+        // @todo (assira # 3) test: generic set
+		assertTrue(true);
+	}
+    
+}

+ 342 - 35
assira/src/test/java/net/ranides/assira/collection/mockup/ALookupTester.java

@@ -6,38 +6,32 @@
  */
 package net.ranides.assira.collection.mockup;
 
-import java.util.AbstractMap;
+import java.util.Collection;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.NoSuchElementException;
 import java.util.Random;
 import java.util.Set;
+import net.ranides.assira.collection.IntCollection;
+import net.ranides.assira.collection.iterators.IntIterator;
+import net.ranides.assira.collection.lookups.AHashLookup;
 import net.ranides.assira.collection.lookups.Lookup;
 import static net.ranides.assira.collection.mockup.TPointEnum.*;
+import static net.ranides.assira.junit.QAssert.*;
 import static org.junit.Assert.*;
 
 /**
  *
  * @author Ranides Atterwim <ranides@gmail.com>
  */
-public class ALookupTester extends TPointTester {
+@SuppressWarnings("PMD.MethodNameRules")
+public class LookupTester extends TPointTester {
     
-    public ALookupTester(TPointGenerator generator) {
-        super(generator);
+    public LookupTester() {
+        super();
     }
     
-    public void put(Map<TPoint, Integer> target, TPointEnum... items) {
-        for(TPointEnum item : items) {
-            target.put($key(item), $value(item));
-        }
-    }
-    
-    public void put(Map<TPoint, Integer> target, TPoint... items) {
-        for (TPoint point : items) {
-            target.put(point, $value(B1));
-        }
-    }
-
     public void basicPutInt(Lookup<TPoint> target, int count) {
         int prev = target.size();
         int value = 200;
@@ -290,6 +284,20 @@ public class ALookupTester extends TPointTester {
 		assertEquals(true, target.isEmpty());
 	}
     
+    public void basicTrim(AHashLookup<TPoint> target) {
+        put(target, $ukeys(1024));
+        target.clear();
+        put(target, $ukeys(128));
+        target.trim();
+    }
+    
+    public void basicTrim(AHashLookup<TPoint> target, int keys, int n) {
+        put(target, $ukeys(5*n));
+        target.clear();
+        put(target, $ukeys(keys));
+        target.trim(n);
+    }
+    
     public void basicEntrySet_Contains(Map<TPoint, Integer> target) {
         Set<Entry<TPoint, Integer>> set = target.entrySet();
 		
@@ -330,10 +338,13 @@ public class ALookupTester extends TPointTester {
 		put(target, A1, A1_NE, B1, C1);
 		assertEquals(4, set.size());
         
-		for(Lookup.LookupEntry<TPoint> entry : set) {
-			assertEquals(target.getInt(entry.getKey()), entry.getIntValue());
-		}
+        Iterator<Lookup.LookupEntry<TPoint>> iterator = set.iterator();
+        while(iterator.hasNext()) {
+            Lookup.LookupEntry<TPoint> entry = iterator.next();
+            assertEquals(target.getInt(entry.getKey()), entry.getIntValue());
+        }
         
+        assertThrows(NoSuchElementException.class, ()-> iterator.next());
 	}
     
     public void basicEntrySet_IteratorInteger(Map<TPoint, Integer> target) {
@@ -343,9 +354,13 @@ public class ALookupTester extends TPointTester {
 		put(target, A1, A1_NE, B1, C1);
 		assertEquals(4, set.size());
 
-		for(Entry<TPoint, Integer> entry : set) {
-			assertEquals(target.get(entry.getKey()), entry.getValue());
-		}
+        Iterator<Entry<TPoint, Integer>> iterator = set.iterator();
+        while(iterator.hasNext()) {
+            Entry<TPoint, Integer> entry = iterator.next();
+            assertEquals(target.get(entry.getKey()), entry.getValue());
+        }
+        
+        assertThrows(NoSuchElementException.class, ()-> iterator.next());
 	}
     
     public void basicEntrySet_Iterator_SetValueInt(Lookup<TPoint> target) {
@@ -371,7 +386,7 @@ public class ALookupTester extends TPointTester {
 		assertContainsInt(target, C1, C1);
 	}
     
-    public void basicEntrySet_Iterator_SetValueInteger(Lookup<TPoint> target) {
+    public void basicEntrySet_Iterator_SetValueInteger(Map<TPoint, Integer> target) {
         Set<Entry<TPoint, Integer>> set = target.entrySet();
                 
 		assertEquals(0, set.size());
@@ -389,14 +404,14 @@ public class ALookupTester extends TPointTester {
                 entry.setValue($object(D2));
             }
 		}
-		assertContainsInt(target, A1, D1);
-		assertContainsInt(target, B1, D2);
-		assertContainsInt(target, A1_NE, A1_NE);
-		assertContainsInt(target, C1, C1);
+		assertContainsInteger(target, A1, D1);
+		assertContainsInteger(target, B1, D2);
+		assertContainsInteger(target, A1_NE, A1_NE);
+		assertContainsInteger(target, C1, C1);
 	}
     
     @SuppressWarnings("unchecked")
-    public void basicEntrySet_Iterator_Remove(Lookup<TPoint> target) {
+    public void basicEntrySet_Iterator_Remove(Map<TPoint, Integer> target) {
         Set<Entry<TPoint, Integer>> set = target.entrySet();
         
 		assertEquals(0, set.size());
@@ -412,18 +427,22 @@ public class ALookupTester extends TPointTester {
             }
             if($equals(key, B1)) {
                 iterator.remove();
+                assertThrows(IllegalStateException.class, ()-> iterator.remove());
             }
 		}
         
-        assertEquals(2, set.size());
-        assertNotContainsInt(target, A1);
-        assertNotContainsInt(target, B1);
-		assertContainsInt(target, A1_NE, A1_NE);
-		assertContainsInt(target, C1, C1);
+        assertEquals(2, target.size());
+        assertNotContainsInteger(target, A1);
+        assertNotContainsInteger(target, B1);
+		assertContainsInteger(target, A1_NE, A1_NE);
+		assertContainsInteger(target, C1, C1);
+        
+        set.clear();
+        assertEquals(0, target.size());
 	}
     
     @SuppressWarnings("unchecked")
-    public void basicEntrySet_Iterator_RemoveAll(Lookup<TPoint> target) {
+    public void basicEntrySet_Iterator_RemoveAll(Map<TPoint, Integer> target) {
         Set<Entry<TPoint, Integer>> set = target.entrySet();
         
 		assertEquals(0, set.size());
@@ -436,7 +455,273 @@ public class ALookupTester extends TPointTester {
 		}
         assertEquals(0, target.size());
 	}
-	
+    
+    public void basicEquals(TestGenerator<? extends Map<TPoint, Integer>> generator) {
+        Map<TPoint, Integer> map1 = generator.create();
+        Map<TPoint, Integer> map2 = generator.create();
+        Map<TPoint, Integer> map3 = generator.create();
+        Map<TPoint, Integer> map4 = generator.create();
+        Map<TPoint, Integer> map5 = generator.create();
+        Map<TPoint, Integer> map6 = generator.create();
+        
+        put(map1, E1, B1, C1);
+        put(map2, E1, B1, C1);
+        put(map3, E1_NE, B1, C1);
+        put(map4, B1, C1);
+        put(map5, B1, C1, D1);
+        put(map6, E1_NE, C1, D1);
+        
+        assertEquality(map1, map2, map3, map4);
+        assertEquality(map1, map2, map3, map6);
+    }
+    
+    public void basicEquals_Entry(Map<TPoint, Integer> target) {
+        put(target, E1, E1_EQ, E1_NE, B1);
+        
+        assertEquality(
+            find(target, E1), 
+            find(target, E1_EQ), 
+            find(target, E1_NE), 
+            find(target, B1)
+        );
+    }
+    
+    public void basicSerializable(Map<TPoint, Integer> target) {
+        put(target, A1, A1_EQ, A1_NE, B1, C1);
+        assertSerializable(target);
+    }
+    
+    public void basicKeySet_Contains(Map<TPoint, Integer> target) {
+        Set<TPoint> set = target.keySet();
+		
+        assertEquals(0, set.size());
+		
+        put(target, A1, A1_NE, B1, C1);
+		assertEquals(4, set.size());
+        assertEquals(true, set.contains($key(A1)));
+        assertEquals(true, set.contains($key(A1_NE)));
+        assertEquals(true, set.contains($key(B1)));
+        assertEquals(true, set.contains($key(C1)));
+        
+        assertEquals(false, set.contains($key(D1)));
+        assertEquals(false, set.contains(new Object()));
+	}
+    
+    public void basicKeySet_Remove(Map<TPoint, Integer> target) {
+        Set<TPoint> set = target.keySet();
+		
+        basicEntrySet_Contains(target);
+		
+        assertEquals(true, set.remove($key(A1_EQ)));
+        assertEquals(false, set.remove($key(D1)));
+        assertEquals(false, set.remove(new Object()));
+        
+        assertEquals(false, set.contains($key(A1)));
+        assertEquals(true, set.contains($key(A1_NE)));
+        assertEquals(true, set.contains($key(B1)));
+        assertEquals(true, set.contains($key(C1)));
+	}
+        
+    public void basicKeySet_Iterator(Map<TPoint, Integer> target) {
+        Set<TPoint> set = target.keySet();
+		
+        assertEquals(0, set.size());
+		put(target, A1, A1_NE, B1, C1);
+		assertEquals(4, set.size());
+
+        Iterator<TPoint> iterator = set.iterator();
+        while(iterator.hasNext()) {
+            TPoint key = iterator.next();
+            assertEquals(true, target.containsKey(key));
+        }
+        
+        assertThrows(NoSuchElementException.class, ()-> iterator.next());
+	}
+    
+    @SuppressWarnings("unchecked")
+    public void basicKeySet_Iterator_Remove(Map<TPoint, Integer> target) {
+        Set<TPoint> set = target.keySet();
+        
+		assertEquals(0, set.size());
+		put(target, A1, A1_NE, B1, C1);
+		
+		Iterator<TPoint> iterator = set.iterator();
+		while(iterator.hasNext()) {
+			TPoint key = iterator.next();
+			
+            if($equals(key, A1_EQ)) {
+                iterator.remove();
+            }
+            if($equals(key, B1)) {
+                iterator.remove();
+                assertThrows(IllegalStateException.class, ()-> iterator.remove());
+            }
+		}
+        
+        assertEquals(2, target.size());
+        assertNotContainsInteger(target, A1);
+        assertNotContainsInteger(target, B1);
+		assertContainsInteger(target, A1_NE, A1_NE);
+		assertContainsInteger(target, C1, C1);
+        
+        set.clear();
+        assertEquals(0, target.size());
+	}
+    
+    public void basicValues_ContainsInt(Lookup<TPoint> target) {
+        IntCollection set = target.values();
+		
+        assertEquals(0, set.size());
+		
+        put(target, A1, A1_NE, B1, C1);
+		assertEquals(4, set.size());
+        assertEquals(true, set.contains($value(A1)));
+        assertEquals(true, set.contains($value(A1_NE)));
+        assertEquals(true, set.contains($value(B1)));
+        assertEquals(true, set.contains($value(C1)));
+        
+        assertEquals(false, set.contains($value(D1)));
+        assertEquals(false, set.contains(new Object()));
+	}
+    
+    public void basicValues_ContainsInteger(Map<TPoint, Integer> target) {
+        Collection<Integer> set = target.values();
+		
+        assertEquals(0, set.size());
+		
+        put(target, A1, A1_NE, B1, C1);
+		assertEquals(4, set.size());
+        assertEquals(true, set.contains($object(A1)));
+        assertEquals(true, set.contains($object(A1_NE)));
+        assertEquals(true, set.contains($object(B1)));
+        assertEquals(true, set.contains($object(C1)));
+        
+        assertEquals(false, set.contains($object(D1)));
+        assertEquals(false, set.contains(new Object()));
+	}
+    
+    public void basicValues_RemoveInt(Lookup<TPoint> target) {
+        IntCollection set = target.values();
+		
+        basicValues_ContainsInt(target);
+		
+        assertEquals(true, set.remove($value(A1)));
+        assertEquals(false, set.remove($value(D1)));
+        assertEquals(false, set.remove(new Object()));
+        
+        assertEquals(false, set.contains($value(A1)));
+        assertEquals(true, set.contains($value(A1_NE)));
+        assertEquals(true, set.contains($value(B1)));
+        assertEquals(true, set.contains($value(C1)));
+	}
+    
+    public void basicValues_RemoveInteger(Map<TPoint, Integer> target) {
+        Collection<Integer> set = target.values();
+		
+        basicValues_ContainsInteger(target);
+		
+        assertEquals(true, set.remove($object(A1)));
+        assertEquals(false, set.remove($object(D1)));
+        assertEquals(false, set.remove(new Object()));
+        
+        assertEquals(false, set.contains($object(A1)));
+        assertEquals(true, set.contains($object(A1_NE)));
+        assertEquals(true, set.contains($object(B1)));
+        assertEquals(true, set.contains($object(C1)));
+	}
+        
+    public void basicValues_IteratorInt(Lookup<TPoint> target) {
+        IntCollection set = target.values();
+		
+        assertEquals(0, set.size());
+		put(target, A1, A1_NE, B1, C1);
+		assertEquals(4, set.size());
+
+        IntIterator iterator = set.iterator();
+        while(iterator.hasNext()) {
+            int var = iterator.next();
+            assertEquals(true, target.containsValue(var));
+        }
+        
+        assertThrows(NoSuchElementException.class, ()-> iterator.next());
+	}
+    
+    public void basicValues_IteratorInteger(Map<TPoint, Integer> target) {
+        Collection<Integer> set = target.values();
+		
+        assertEquals(0, set.size());
+		put(target, A1, A1_NE, B1, C1);
+		assertEquals(4, set.size());
+
+        Iterator<Integer> iterator = set.iterator();
+        while(iterator.hasNext()) {
+            Integer var = iterator.next();
+            assertEquals(true, target.containsValue(var));
+        }
+        
+        assertThrows(NoSuchElementException.class, ()-> iterator.next());
+	}
+    
+    @SuppressWarnings("unchecked")
+    public void basicValues_Iterator_RemoveInt(Lookup<TPoint> target) {
+        IntCollection set = target.values();
+        
+		assertEquals(0, set.size());
+		put(target, A1, A1_NE, B1, C1);
+		
+		IntIterator iterator = set.iterator();
+		while(iterator.hasNext()) {
+			int var = iterator.next();
+			
+            if(var == $value(A1)) {
+                iterator.remove();
+            }
+            if(var == $value(B1)) {
+                iterator.remove();
+                assertThrows(IllegalStateException.class, ()-> iterator.remove());
+            }
+		}
+        
+        assertEquals(2, target.size());
+        assertNotContainsInt(target, A1);
+        assertNotContainsInt(target, B1);
+		assertContainsInt(target, A1_NE, A1_NE);
+		assertContainsInt(target, C1, C1);
+        
+        set.clear();
+        assertEquals(0, target.size());
+	}
+    
+    @SuppressWarnings("unchecked")
+    public void basicValues_Iterator_RemoveInteger(Map<TPoint, Integer> target) {
+        Collection<Integer> set = target.values();
+        
+		assertEquals(0, set.size());
+		put(target, A1, A1_NE, B1, C1);
+		
+		Iterator<Integer> iterator = set.iterator();
+		while(iterator.hasNext()) {
+			Integer var = iterator.next();
+			
+            if(var.equals($object(A1))) {
+                iterator.remove();
+            }
+            if(var.equals($object(B1))) {
+                iterator.remove();
+                assertThrows(IllegalStateException.class, ()-> iterator.remove());
+            }
+		}
+        
+        assertEquals(2, target.size());
+        assertNotContainsInteger(target, A1);
+        assertNotContainsInteger(target, B1);
+		assertContainsInteger(target, A1_NE, A1_NE);
+		assertContainsInteger(target, C1, C1);
+        
+        set.clear();
+        assertEquals(0, target.size());
+	}
+    
     
     protected void assertRemoveInt(Lookup<TPoint> target, TPointEnum key, TPointEnum prev) {
         int size = target.size();
@@ -488,6 +773,28 @@ public class ALookupTester extends TPointTester {
 		assertEquals(size, target.keySet().size());
 		assertEquals(size, target.values().size());
 	}
+    
+    private void put(Map<TPoint, Integer> target, TPointEnum... items) {
+        for(TPointEnum item : items) {
+            target.put($key(item), $value(item));
+        }
+    }
+    
+    private void put(Map<TPoint, Integer> target, TPoint... items) {
+        for (TPoint point : items) {
+            target.put(point, $value(B1));
+        }
+    }
+    
+    private Entry<TPoint, Integer> find(Map<TPoint, Integer> target, TPointEnum key) {
+        for(Entry<TPoint, Integer> entry : target.entrySet()) {
+            if($equals(entry.getKey(), key)) {
+                return entry;
+            }
+        }
+        fail("Entry not found: " + key);
+        return null;
+    }
 	
 	private TPoint[] shuffle(TPoint[] array) {
 		int n = array.length;

+ 132 - 0
assira/src/test/java/net/ranides/assira/collection/mockup/LookupTesterSuite.java

@@ -0,0 +1,132 @@
+/*
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/???
+ */
+package net.ranides.assira.collection.mockup;
+
+import net.ranides.assira.collection.lookups.Lookup;
+import static net.ranides.assira.junit.QAssert.*;
+import static org.junit.Assert.*;
+import org.junit.Test;
+
+/**
+ *
+ * @author Ranides Atterwim <ranides@gmail.com>
+ */
+public class LookupTesterSuite {
+    
+    private final LookupTester tester;
+    
+    private final TestGenerator<? extends Lookup<TPoint>> maps;
+
+    public LookupTesterSuite(TestGenerator<? extends Lookup<TPoint>> maps) {
+        this.tester = new LookupTester();
+        this.maps = maps;
+    }
+    
+    public boolean put() {
+        tester.basicPutInt(maps.create());
+        tester.basicPutInt(maps.create(), 128);
+        tester.basicPutReplaceInt(maps.create(), 40);
+        tester.basicPutRandomInt(maps.create(), 220);
+        
+        tester.basicPutInteger(maps.create());
+        tester.basicPutInteger(maps.create(), 128);
+        tester.basicPutReplaceInteger(maps.create(), 40);
+		tester.basicPutRandomInteger(maps.create(), 220);
+        
+        return true;
+    }
+
+    public boolean remove() {
+        tester.basicRemoveInt(maps.create());
+        tester.basicRemoveInt(maps.create(), 97);
+        tester.logicRemoveInt(maps.create());
+        
+        tester.basicRemoveInteger(maps.create());
+        tester.basicRemoveInteger(maps.create(), 97);
+        tester.logicRemoveInteger(maps.create());
+        
+        return true;
+    }
+    
+    public boolean get() {
+        tester.basicGetInt( maps.create() );
+        tester.basicGetInteger( maps.create() );
+        
+        return true;
+    }
+
+    public boolean containsValue() {
+        tester.basicContainsInt( maps.create() );
+        tester.basicContainsInteger( maps.create() );
+        
+        return true;
+    }
+
+    public boolean clear() {
+		tester.basicClear( maps.create() );
+		
+		return true;
+	}
+
+    public boolean entrySet() {
+		tester.basicEntrySet_Contains(maps.create());
+		tester.basicEntrySet_Remove(maps.create());
+        
+		tester.basicEntrySet_IteratorInt(maps.create());
+		tester.basicEntrySet_IteratorInteger(maps.create());
+		
+        tester.basicEntrySet_Iterator_SetValueInt(maps.create());
+        tester.basicEntrySet_Iterator_SetValueInteger(maps.create());
+        
+		tester.basicEntrySet_Iterator_Remove(maps.create());
+        tester.basicEntrySet_Iterator_RemoveAll(maps.create());
+		
+        // @todo (assira # 3) test: generic set
+		return true;
+	}
+
+    public boolean keySet() {
+        tester.basicKeySet_Contains(maps.create());
+        tester.basicKeySet_Remove(maps.create());
+        
+        tester.basicKeySet_Iterator(maps.create());
+        tester.basicKeySet_Iterator_Remove(maps.create());
+        
+        // @todo (assira # 3) test: generic set
+		return true;
+    }
+
+    public boolean values() {
+        tester.basicValues_ContainsInt(maps.create());
+        tester.basicValues_RemoveInt(maps.create());
+        
+        tester.basicValues_IteratorInt(maps.create());
+        tester.basicValues_Iterator_RemoveInt(maps.create());
+        
+        tester.basicValues_ContainsInteger(maps.create());
+        tester.basicValues_RemoveInteger(maps.create());
+        
+        tester.basicValues_IteratorInteger(maps.create());
+        tester.basicValues_Iterator_RemoveInteger(maps.create());
+        
+        // @todo (assira # 3) test: generic set
+		return true;
+    }
+
+    public boolean equality() {
+        tester.basicEquals(maps);
+        tester.basicEquals_Entry(maps.create());
+        
+        return true;
+    }
+
+    public boolean serializable() {
+        tester.basicSerializable(maps.create());
+        return true;
+    }
+    
+}

+ 111 - 99
assira/src/test/java/net/ranides/assira/collection/mockup/TPoint.java

@@ -1,99 +1,111 @@
-/*
- * @author Ranides Atterwim <ranides@gmail.com>
- * @copyright Ranides Atterwim
- * @license WTFPL
- * @url http://ranides.net/projects/assira
- */
-package net.ranides.assira.collection.mockup;
-
-import java.util.Comparator;
-import net.ranides.assira.collection.HashComparator;
-import net.ranides.assira.collection.utils.HashUtils;
-
-/**
- *
- * @author Ranides Atterwim <ranides@gmail.com>
- */
-public class TPoint {
-
-    private final int x;
-    private final int y;
-    private final int z;
-
-    public TPoint(int x, int y, int z) {
-        this.x = x;
-        this.y = y;
-        this.z = z;
-    }
-
-    @Override
-    public int hashCode() {
-        return HashUtils.hashValues(3, 37, x, y, z);
-    }
-
-    @Override
-    public boolean equals(Object object) {
-        if (this == object) {
-            return true;
-        }
-        if (object == null) {
-            return false;
-        }
-        if (getClass() != object.getClass()) {
-            return false;
-        }
-        return STD.equals(this, (TPoint)object);
-    }
-
-    @Override
-    public String toString() {
-        return "(" + x + ":" + y + ":" + z + ")";
-    }
-    
-    public static abstract class PointComparator implements HashComparator<TPoint>, Comparator<TPoint> {
-    
-    }
-    
-    public static final PointComparator SUM = new PointComparator() {
-        @Override
-        public int hashCode(TPoint object) {
-            return object.x;
-        }
-
-        @Override
-        public boolean equals(TPoint value1, TPoint value2) {
-            return 0 == compare(value1,value2);
-        }
-
-        @Override
-        public int compare(TPoint value1, TPoint value2) {
-            int a = value1.x + value1.y + value1.z;
-            int b = value2.x + value2.y + value2.z;
-            return a-b;
-        }
-        
-        
-    };
-    
-    public static final PointComparator STD = new PointComparator() {
-        @Override
-        public int hashCode(TPoint object) {
-            return HashUtils.hashValues(1, 1199, object.x, object.y, object.z);
-        }
-
-        @Override
-        public boolean equals(TPoint value1, TPoint value2) {
-            return 0 == compare(value1,value2);
-        }
-
-        @Override
-        public int compare(TPoint value1, TPoint value2) {
-            int dx = value1.x - value2.x;
-            int dy = value1.y - value2.y;
-            int dz = value1.z - value2.z;
-            return dx!=0 ? dx : (dy!=0 ? dy : dz);
-        }
-        
-    };
-
-}
+/*
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/assira
+ */
+package net.ranides.assira.collection.mockup;
+
+import java.io.Serializable;
+import java.util.Comparator;
+import net.ranides.assira.collection.HashComparator;
+import net.ranides.assira.collection.utils.HashUtils;
+
+/**
+ *
+ * @author Ranides Atterwim <ranides@gmail.com>
+ */
+public class TPoint implements Serializable {
+    
+    private static final long serialVersionUID = 1L;
+
+    private final int x;
+    private final int y;
+    private final int z;
+
+    public TPoint(int x, int y, int z) {
+        this.x = x;
+        this.y = y;
+        this.z = z;
+    }
+
+    @Override
+    public int hashCode() {
+        return HashUtils.hashValues(3, 37, x, y);
+    }
+
+    @Override
+    public boolean equals(Object object) {
+        if (this == object) {
+            return true;
+        }
+        if (object == null) {
+            return false;
+        }
+        if (getClass() != object.getClass()) {
+            return false;
+        }
+        return STD.equals(this, (TPoint)object);
+    }
+
+    @Override
+    public String toString() {
+        return "(" + x + ":" + y + ":" + z + ")";
+    }
+    
+    public static abstract class PointComparator implements HashComparator<TPoint>, Comparator<TPoint>, Serializable {
+        
+        private static final long serialVersionUID = 1L;
+        
+    }
+    
+    public static final PointComparator SUM = new PointComparator() {
+        
+        private static final long serialVersionUID = 1L;
+        
+        @Override
+        public int hashCode(TPoint object) {
+            return object.x;
+        }
+
+        @Override
+        public boolean equals(TPoint value1, TPoint value2) {
+            return 0 == compare(value1,value2);
+        }
+
+        @Override
+        public int compare(TPoint value1, TPoint value2) {
+            int a = value1.x + value1.y + zz(value1.z);
+            int b = value2.x + value2.y + zz(value2.z);
+            return a-b;
+        }
+        
+        
+    };
+    
+    public static final PointComparator STD = new PointComparator() {
+        @Override
+        public int hashCode(TPoint object) {
+            return HashUtils.hashValues(1, 1199, object.x, object.y, object.z);
+        }
+
+        @Override
+        public boolean equals(TPoint value1, TPoint value2) {
+            return 0 == compare(value1, value2);
+        }
+
+        @Override
+        public int compare(TPoint value1, TPoint value2) {
+            int dx = value1.x - value2.x;
+            int dy = value1.y - value2.y;
+            int dz = zz(value1.z) - zz(value2.z);
+            return dx!=0 ? dx : (dy!=0 ? dy : dz);
+        }
+        
+    };
+    
+    private static int zz(int z) {
+        return z & 0xFFFF;
+    }
+
+}

+ 4 - 0
assira/src/test/java/net/ranides/assira/collection/mockup/TPointEnum.java

@@ -21,4 +21,8 @@ public enum TPointEnum {
     D2,
     D3,
     D4,
+    
+    E1,
+    E1_EQ,
+    E1_NE,
 }

+ 6 - 0
assira/src/test/java/net/ranides/assira/collection/mockup/TPointGenerator.java

@@ -30,6 +30,9 @@ public final class TPointGenerator {
         new TPoint(20, 40, 4),  // D2
         new TPoint(20, 40, 5),  // D3
         new TPoint(20, 40, 6),  // D4
+        new TPoint(33, 42, 6),  // E1
+        new TPoint(33, 42, 6+0x10000),  // E1_EQ
+        new TPoint(33, 42, 17),  // E1_NE
     };
     
     private final int[] mvalues = new int[]{
@@ -42,6 +45,9 @@ public final class TPointGenerator {
         32, // D2
         33, // D3 
         34, // D4 
+        81, // E1
+        81, // E1_EQ
+        81, // E1_NE
     };
 
     public TPoint key(TPointEnum type) {

+ 13 - 13
assira/src/test/java/net/ranides/assira/collection/mockup/TPointTester.java

@@ -16,50 +16,50 @@ import java.util.Map.Entry;
  */
 public abstract class TPointTester {
     
-    private final TPointGenerator generator;
+    private final TPointGenerator mpoints;
 
-    public TPointTester(TPointGenerator generator) {
-        this.generator = generator;
+    public TPointTester() {
+        this.mpoints = new TPointGenerator();
     }
     
     protected TPoint $key(TPointEnum type) {
-        return generator.key(type);
+        return mpoints.key(type);
     }
 
     protected TPoint[] $keys(int count) {
-        return generator.keys(count);
+        return mpoints.keys(count);
     }
 
     protected TPoint[] $ukeys(int count) {
-        return generator.ukeys(count);
+        return mpoints.ukeys(count);
     }
 
     protected int $value(TPointEnum type) {
-        return generator.value(type);
+        return mpoints.value(type);
     }
 
     protected int[] $values(int count) {
-        return generator.values(count);
+        return mpoints.values(count);
     }
 
     protected Integer $object(TPointEnum type) {
-        return generator.object(type);
+        return mpoints.object(type);
     }
 
     protected Integer[] $objects(int count) {
-        return generator.objects(count);
+        return mpoints.objects(count);
     }
 
     protected Map<TPoint, Integer> $map(TPoint[] keys) {
-        return generator.map(keys);
+        return mpoints.map(keys);
     }
 
     protected Map<TPoint, Integer> $map(TPoint[] points, int[] values) {
-        return generator.map(points, values);
+        return mpoints.map(points, values);
     }
 
     protected Map<TPoint, Integer> $map(TPoint[] points, Integer[] values) {
-        return generator.map(points, values);
+        return mpoints.map(points, values);
     }
     
     protected boolean $equals(TPoint point1, TPoint point2) {

+ 7 - 0
assira/src/test/java/net/ranides/assira/collection/mockup/TestGenerator.java

@@ -7,6 +7,7 @@
 package net.ranides.assira.collection.mockup;
 
 import java.util.function.Function;
+import java.util.function.Supplier;
 
 /**
  *
@@ -24,6 +25,12 @@ public class TestGenerator<T> {
         this.value = null;
     }
     
+    public TestGenerator(Supplier<T> generator) {
+        this.generator = (index) -> generator.get();
+        this.counter = 0;
+        this.value = null;
+    }
+    
     public T get() {
         return value;
     }