/* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package freenet.support; import java.util.Arrays; import java.util.Enumeration; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Random; import junit.framework.TestCase; /** * Test case for {@link freenet.support.MultiValueTable} class. * * @author Alberto Bacchelli <sback@freenetproject.org> */ public class MultiValueTableTest extends TestCase { private static final int sampleKeyNumber = 100; private static final int sampleMaxValueNumber = 3; private static final boolean sampleIsRandom = true; private Random rnd = new Random(12345); /** * Create a Object[][] filled with increasing Integers as keys * and a List of generic Objects as values. * @param keysNumber the number of keys to create * @param valueNumber the maximum value number per key * @param isRandom if true each key could have [1,valuesNumber] values * chosen randomly, if false each key will have valuesNumber values * @return the Object[][] created */ private Object[][] createSampleKeyMultiVal(int keysNumber, int valuesNumber, boolean isRandom) { Object[][] sampleObjects = new Object[keysNumber][valuesNumber]; int methodValuesNumber = valuesNumber; for (int i=0; i<sampleObjects.length;i++) { if (isRandom) methodValuesNumber = 1+rnd.nextInt(valuesNumber); sampleObjects[i][0] = i; sampleObjects[i][1] = fillSampleValuesList(methodValuesNumber); } return sampleObjects; } /** * Create a sample List filled * with the specified number of * generic objects * @param valuesNumber number of objects to create * @return the sample List */ private List<Object> fillSampleValuesList(int valuesNumber) { List<Object> sampleValues = new LinkedList<Object>(); for(int i=0; i<valuesNumber;i++) sampleValues.add(new Object()); return sampleValues; } /** * Create a sample MultiValueTable * @param keyNumber the number of key to insert in the MultiValueTable * @param maxValueNumber the maximum number of value for each key * @param isRandom true if the maxValueNumber is an upper bound, false if it is the actual value * @return the sample MultiValueTable created */ private MultiValueTable<Object, Object> createSampleMultiValueTable(int keyNumber, int maxValueNumber, boolean isRandom) { Object[][] sampleObjects = createSampleKeyMultiVal(keyNumber,maxValueNumber,isRandom); return fillMultiValueTable(sampleObjects); } /** * Given an Enumeration it returns the number of present objects * @param anEnumeration * @return the number of present objects */ private int enumerationSize(Enumeration<Object> anEnumeration) { int counter = 0; while(anEnumeration.hasMoreElements()) { anEnumeration.nextElement(); counter++;} return counter; } /** * Fill a new MultiValueTable from a Object[][] provided. * The Object[][] must be in the same form generated by * createSampleKeyMultiVal method. * @param sampleObjects Object[][] array, with [i][0] as key and [i][1] as list of values * @return the created MultiValueTable */ @SuppressWarnings("unchecked") private MultiValueTable<Object, Object> fillMultiValueTable(Object[][] sampleObjects) { MultiValueTable<Object, Object> methodMVTable = new MultiValueTable<Object, Object>(); Iterator<Object> itr; for(int i=0;i<sampleKeyNumber;i++) { itr = ((List<Object>)(sampleObjects[i][1])).iterator(); while( itr.hasNext()) methodMVTable.put(sampleObjects[i][0], itr.next()); } return methodMVTable; } /** * Tests if there are problems when * putting values in a sample * MultiValueTable */ public void testPut() { assertNotNull( createSampleMultiValueTable(sampleKeyNumber,sampleMaxValueNumber,sampleIsRandom)); } /** * Tests get(Object) method with both * present keys and not present */ @SuppressWarnings("unchecked") public void testGet() { MultiValueTable<Object, Object> methodMVTable = new MultiValueTable<Object, Object>(); assertNull(methodMVTable.get(new Object())); Object[][] sampleObjects = createSampleKeyMultiVal(sampleKeyNumber,sampleMaxValueNumber,sampleIsRandom); methodMVTable = fillMultiValueTable(sampleObjects); for(int i=0;i<sampleObjects.length;i++) assertEquals(methodMVTable.get(sampleObjects[i][0]),((List<Object>)sampleObjects[i][1]).get(0)); } /** * Tests containsKey(Object) method verifying * if all keys inserted are correctly found. * It verifies the correct behavior with empty * MultiValueTable and not present keys, too. */ public void testContainsKey() { MultiValueTable<Object, Object> methodMVTable = new MultiValueTable<Object, Object>(); assertFalse(methodMVTable.containsKey(new Object())); Object[][] sampleObjects = createSampleKeyMultiVal(sampleKeyNumber,sampleMaxValueNumber,sampleIsRandom); methodMVTable = fillMultiValueTable(sampleObjects); for(int i=0;i<sampleObjects.length;i++) assertTrue(methodMVTable.containsKey(sampleObjects[i][0])); assertFalse(methodMVTable.containsKey(new Object())); } /** * Tests containsElement(Object,Object) method * verifying if all values inserted are correctly * found. * It verifies the correct behavior with empty * MultiValueTable and not present Elements, too. */ @SuppressWarnings("unchecked") public void testContainsElement() { MultiValueTable<Object, Object> methodMVTable = new MultiValueTable<Object, Object>(); assertFalse(methodMVTable.containsElement(new Object(),new Object())); Object[][] sampleObjects = createSampleKeyMultiVal(sampleKeyNumber,sampleMaxValueNumber,sampleIsRandom); methodMVTable = fillMultiValueTable(sampleObjects); Iterator<Object> iter; for(int i=0;i<sampleObjects.length;i++) { iter = ((List<Object>)(sampleObjects[i][1])).iterator(); assertFalse(methodMVTable.containsElement(sampleObjects[i][0],new Object())); while(iter.hasNext()) assertTrue(methodMVTable.containsElement(sampleObjects[i][0],iter.next())); } } /** * Tests getAll() method */ @SuppressWarnings("unchecked") public void testGetAll() { MultiValueTable<Object, Object> methodMVTable = new MultiValueTable<Object, Object>(); //TODO: verifies if an Exception is necessary methodMVTable.getAll(new Object()); Object[][] sampleObjects = createSampleKeyMultiVal(sampleKeyNumber,sampleMaxValueNumber,sampleIsRandom); methodMVTable = fillMultiValueTable(sampleObjects); Iterator<Object> iter; Enumeration<Object> methodEnumeration; for(int i=0;i<sampleObjects.length;i++) { iter = ((List<Object>)(sampleObjects[i][1])).iterator(); methodEnumeration = methodMVTable.getAll(sampleObjects[i][0]); while(iter.hasNext()) assertEquals(methodEnumeration.nextElement(),iter.next()); } } /** * Tests countAll() method */ @SuppressWarnings("unchecked") public void testCountAll() { MultiValueTable<Object, Object> methodMVTable = new MultiValueTable<Object, Object>(); assertEquals(methodMVTable.countAll(new Object()),0); Object[][] sampleObjects = createSampleKeyMultiVal(sampleKeyNumber,sampleMaxValueNumber,sampleIsRandom); methodMVTable = fillMultiValueTable(sampleObjects); for(int i=0;i<sampleObjects.length;i++) assertEquals(((List<Object>)(sampleObjects[i][1])).size(),methodMVTable.countAll(sampleObjects[i][0])); } /** * Tests getSync(Object) method fetching * both present and not present keys */ @SuppressWarnings({ "cast", "unchecked" }) public void testGetSync() { MultiValueTable<Object, Object> methodMVTable = new MultiValueTable<Object, Object>(); assertNull(methodMVTable.getSync(new Object())); Object[][] sampleObjects = createSampleKeyMultiVal(sampleKeyNumber,sampleMaxValueNumber,sampleIsRandom); methodMVTable = fillMultiValueTable(sampleObjects); for(int i=0;i<sampleObjects.length;i++) assertEquals(methodMVTable.getSync(sampleObjects[i][0]),((List<Object>)sampleObjects[i][1])); } /** * Tests getArray(Object) method both * with a present key and a not present key */ @SuppressWarnings("unchecked") public void testGetArray() { MultiValueTable<Object, Object> methodMVTable = new MultiValueTable<Object, Object>(); assertNull(methodMVTable.getArray(new Object())); Object[][] sampleObjects = createSampleKeyMultiVal(sampleKeyNumber,sampleMaxValueNumber,sampleIsRandom); methodMVTable = fillMultiValueTable(sampleObjects); for(int i=0;i<sampleObjects.length;i++) assertTrue(Arrays.equals(((List<Object>)(sampleObjects[i][1])).toArray(),methodMVTable.getArray(sampleObjects[i][0]))); } /** * Tests remove(Object) method trying * to remove all keys inserted in a MultiValueTable. * It verifies the behavior when removing a not present * key, too. */ public void testRemove() { MultiValueTable<Object, Object> methodMVTable = new MultiValueTable<Object, Object>(); //TODO: shouldn't it raise an exception? methodMVTable.remove(new Object()); Object[][] sampleObjects = createSampleKeyMultiVal(sampleKeyNumber,sampleMaxValueNumber,sampleIsRandom); methodMVTable = fillMultiValueTable(sampleObjects); for(int i=0;i<sampleObjects.length;i++) methodMVTable.remove(sampleObjects[i][0]); assertTrue(methodMVTable.isEmpty()); } /** * Tests isEmpty() method with an empty MultiValueTable, * after putting objects and after removing all of them. */ public void testIsEmpty() { MultiValueTable<Object, Object> methodMVTable = new MultiValueTable<Object, Object>(); assertTrue(methodMVTable.isEmpty()); Object[][] sampleObjects = createSampleKeyMultiVal(sampleKeyNumber,sampleMaxValueNumber,sampleIsRandom); methodMVTable = fillMultiValueTable(sampleObjects); assertFalse(methodMVTable.isEmpty()); for(int i=0;i<sampleObjects.length;i++) methodMVTable.remove(sampleObjects[i][0]); assertTrue(methodMVTable.isEmpty()); } /** * Tests clear() method filling a MultiValueTable * and verifying if all keys are correctly removed. * Finally it verifies the result of isEmpty() method. */ public void testClear() { Object[][] sampleObjects = createSampleKeyMultiVal(sampleKeyNumber,sampleMaxValueNumber,sampleIsRandom); MultiValueTable<Object, Object> methodMVTable = fillMultiValueTable(sampleObjects); methodMVTable.clear(); for(int i=0;i<sampleObjects.length;i++) assertFalse(methodMVTable.containsKey(sampleObjects[i][0])); assertTrue(methodMVTable.isEmpty()); } /** * Tests removeElement(Object,Object) removing all elements from * a sample MultiValueTable, and verifying if they are correctly * removed and if the result of isEmpty() method is correct. */ @SuppressWarnings("unchecked") public void testRemoveElement() { Object[][] sampleObjects = createSampleKeyMultiVal(sampleKeyNumber,sampleMaxValueNumber,sampleIsRandom); MultiValueTable<Object, Object> methodMVTable = fillMultiValueTable(sampleObjects); Object methodValue; Iterator<Object> iter; for(int i=0;i<sampleObjects.length;i++) { iter = ((List<Object>)(sampleObjects[i][1])).iterator(); assertFalse(methodMVTable.removeElement(sampleObjects[i][0],new Object())); while(iter.hasNext()) { methodValue = iter.next(); assertTrue(methodMVTable.removeElement(sampleObjects[i][0],methodValue)); assertFalse(methodMVTable.containsElement(sampleObjects[i][0],methodValue)); } } assertTrue(methodMVTable.isEmpty()); } /** * Tests keys() method verifying if all keys inserted are * correctly present in the resulting Enumeration */ public void testKeys() { Object[][] sampleObjects = createSampleKeyMultiVal(sampleKeyNumber,sampleMaxValueNumber,sampleIsRandom); MultiValueTable<Object, Object> methodMVTable = fillMultiValueTable(sampleObjects); //TODO: shouldn't it respect keys order? int j = sampleObjects.length-1; Enumeration<Object> methodEnumeration = methodMVTable.keys(); while(methodEnumeration.hasMoreElements()) { assertEquals(sampleObjects[j][0],methodEnumeration.nextElement()); j--;} } /** * Tests elements() and keys() method * verifying their behavior when putting the same * value for different keys. */ public void testDifferentKeysSameElement() { int keysNumber = 2; MultiValueTable<Object, Object> methodMVTable = new MultiValueTable<Object, Object>(); String sampleValue = "sampleValue"; //putting the same value for different keys for(int i=0;i<keysNumber;i++) methodMVTable.put(new Object(),sampleValue); assertEquals(enumerationSize(methodMVTable.elements()),1); assertEquals(enumerationSize(methodMVTable.keys()),keysNumber); } }