/////////////////////////////////////////////////////////////////////////////// // Copyright (c) 2001-2006, Eric D. Friedman All Rights Reserved. // Copyright (c) 2009, Rob Eden All Rights Reserved. // Copyright (c) 2009, Jeff Randall All Rights Reserved. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library 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 Lesser 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 gnu.trove.set.hash; import junit.framework.TestCase; import org.omg.CORBA.portable.Streamable; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.*; /** * Created: Sat Nov 3 10:33:15 2001 * * @author Eric D. Friedman * @author Rob Eden * @author Jeff Randall * @version $Id: THashSetTest.java,v 1.1.2.3 2010/03/02 04:09:50 robeden Exp $ */ public class TLinkedHashSetTest extends TestCase { public TLinkedHashSetTest(String name) { super( name ); } public void setUp() throws Exception { super.setUp(); } public void tearDown() throws Exception { super.tearDown(); } public void testConstructors() throws Exception { Set<String> set = new TLinkedHashSet<String>(); assertNotNull( set ); String[] strings = {"a", "b", "c", "d"}; set.addAll( Arrays.asList( strings ) ); Set<String> copy = new TLinkedHashSet<String>( set ); assertTrue( "set not a copy: " + set + ", " + copy, set.equals( copy ) ); Set<String> another = new TLinkedHashSet<String>( 20 ); another.addAll( Arrays.asList( strings ) ); assertTrue( "set not equal: " + set + ", " + copy, set.equals( another ) ); another = new TLinkedHashSet<String>( 2, 1.0f ); another.addAll( Arrays.asList( strings ) ); assertTrue( "set not equal: " + set + ", " + copy, set.equals( another ) ); } public void testIsEmpty() throws Exception { Set<String> s = new TLinkedHashSet<String>(); assertTrue( "new set wasn't empty", s.isEmpty() ); s.add( "One" ); assertTrue( "set with element reports empty", !s.isEmpty() ); s.clear(); assertTrue( "cleared set reports not-empty", s.isEmpty() ); } public void testContains() throws Exception { Set<String> s = new TLinkedHashSet<String>(); String o = "testContains"; s.add( o ); assertTrue( "contains failed", s.contains( o ) ); } @SuppressWarnings({"ForLoopReplaceableByForEach"}) public void testContainsAll() throws Exception { Set<String> s = new TLinkedHashSet<String>(); String[] o = {"Hello World", "Goodbye World", "Hello Goodbye"}; s.addAll( Arrays.asList( o ) ); for ( int i = 0; i < o.length; i++ ) { assertTrue( o[i], s.contains( o[i] ) ); } assertTrue( "containsAll failed: " + s, s.containsAll( Arrays.asList( o ) ) ); String[] more = {"Hello World", "Goodbye World", "Hello Goodbye", "Not There"}; assertFalse( "containsAll failed: " + s, s.containsAll( Arrays.asList( more ) ) ); } public void testRetainAll() throws Exception { Set<String> set = new TLinkedHashSet<String>(); String[] strings = {"Hello World", "Goodbye World", "Hello Goodbye", "Remove Me"}; set.addAll( Arrays.asList( strings ) ); for ( String string : strings ) { assertTrue( string, set.contains( string ) ); } String[] retain = {"Hello World", "Goodbye World", "Hello Goodbye"}; assertTrue( "retainAll failed: " + set, set.retainAll( Arrays.asList( retain ) ) ); assertTrue( "containsAll failed: " + set, set.containsAll( Arrays.asList( retain ) ) ); } public void testRemoveAll() throws Exception { Set<String> set = new TLinkedHashSet<String>(); String[] strings = {"Hello World", "Goodbye World", "Hello Goodbye", "Keep Me"}; set.addAll( Arrays.asList( strings ) ); for ( String string : strings ) { assertTrue( string, set.contains( string ) ); } String[] remove = {"Hello World", "Goodbye World", "Hello Goodbye"}; assertTrue( "removeAll failed: " + set, set.removeAll( Arrays.asList( remove ) ) ); assertTrue( "removeAll failed: " + set, set.containsAll( Arrays.asList( "Keep Me" ) ) ); for ( String element : remove ) { assertFalse( element + " still in set: " + set, set.contains( element ) ); } assertEquals( 1, set.size() ); } public void testAdd() throws Exception { Set<String> s = new TLinkedHashSet<String>(); assertTrue( "add failed", s.add( "One" ) ); assertTrue( "duplicated add succeded", !s.add( "One" ) ); } public void testRemove() throws Exception { Set<String> s = new TLinkedHashSet<String>(); s.add( "One" ); s.add( "Two" ); assertTrue( "One was not added", s.contains( "One" ) ); assertTrue( "One was not removed", s.remove( "One" ) ); assertTrue( "One was not removed", !s.contains( "One" ) ); assertTrue( "Two was removed", s.contains( "Two" ) ); assertEquals( 1, s.size() ); } public void testRemoveObjectNotInSet() throws Exception { Set<String> set = new TLinkedHashSet<String>(); set.add( "One" ); set.add( "Two" ); assertTrue( "One was not added", set.contains( "One" ) ); assertTrue( "One was not removed", set.remove( "One" ) ); assertTrue( "One was not removed", !set.contains( "One" ) ); assertTrue( "Two was removed", set.contains( "Two" ) ); assertFalse( "Three was removed (non-existant)", set.remove( "Three" ) ); assertEquals( 1, set.size() ); } public void testSize() throws Exception { Set<Object> o = new TLinkedHashSet<Object>(); assertEquals( "initial size was not 0", 0, o.size() ); for ( int i = 0; i < 99; i++ ) { o.add( new Object() ); assertEquals( "size did not increase after add", i + 1, o.size() ); } } public void testClear() throws Exception { Set<String> s = new TLinkedHashSet<String>(); s.addAll( Arrays.asList( "one", "two", "three" ) ); assertEquals( "size was not 3", 3, s.size() ); s.clear(); assertEquals( "initial size was not 0", 0, s.size() ); } public void testIterationOrder() throws Exception { TLinkedHashSet<String> lhs = new TLinkedHashSet<String>(); Set<String> s = lhs; s.add("a"); s.add("b"); s.add("c"); // Iterator<String> it = s.iterator(); // assertEquals("a", it.next()); assertEquals("b", it.next()); assertEquals("c", it.next()); // s.add("a"); it = s.iterator(); // assertEquals("a", it.next()); assertEquals("b", it.next()); assertEquals("c", it.next()); // s.remove("a"); s.add("a"); // it = s.iterator(); assertEquals("b", it.next()); assertEquals("c", it.next()); assertEquals("a", it.next()); // lhs.compact(); it = s.iterator(); assertEquals("b", it.next()); assertEquals("c", it.next()); assertEquals("a", it.next()); } public void testIteratorRemove() throws Exception { Set<String> s = new TLinkedHashSet<String>(); s.add("a"); s.add("b"); s.add("c"); // Iterator<String> it = s.iterator(); // assertEquals("a", it.next()); assertEquals("b", it.next()); assertEquals("c", it.next()); it = s.iterator(); // assertEquals("a", it.next()); it.remove(); assertEquals("b", it.next()); assertEquals("c", it.next()); it = s.iterator(); // assertEquals("b", it.next()); it.remove(); assertEquals("c", it.next()); it = s.iterator(); // assertEquals("c", it.next()); it.remove(); assertTrue(s.isEmpty()); } public void testSerialize() throws Exception { Set<String> s = new TLinkedHashSet<String>(); s.addAll( Arrays.asList( "one", "two", "three" ) ); assertEquals(s, s); ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream( baos ); oos.writeObject( s ); ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() ); ObjectInputStream ois = new ObjectInputStream( bais ); TLinkedHashSet s2 = (TLinkedHashSet) ois.readObject(); assertEquals( s, s2 ); } public void testToArray() { Set<String> s = new TLinkedHashSet<String>(); String[] str = {"hi", "bye", "hello", "goodbye"}; s.addAll( Arrays.asList( str ) ); Object[] res = s.toArray(); Arrays.sort( str ); Arrays.sort( res ); assertTrue( Arrays.equals( str, res ) ); } public void testToArrayWithParams() { Set<String> s = new TLinkedHashSet<String>(); String[] str = {"hi", "bye", "hello", "goodbye"}; s.addAll( Arrays.asList( str ) ); String[] sink = new String[str.length + 2]; sink[sink.length - 1] = "residue"; sink[sink.length - 2] = "will be cleared"; String[] res = s.toArray( sink ); Set<String> copy = new HashSet<String>(); copy.addAll( Arrays.asList( res ) ); Set<String> bogey = new HashSet<String>(); bogey.addAll( Arrays.asList( str ) ); bogey.add( "residue" ); bogey.add( null ); assertEquals( bogey, copy ); } @SuppressWarnings({"ToArrayCallWithZeroLengthArrayArgument", "SuspiciousToArrayCall"}) public void testToArrayAnotherType() throws Exception { Set<Number> set = new TLinkedHashSet<Number>(); Number[] nums = {1138, 42, 86, 99, 101}; set.addAll( Arrays.asList( nums ) ); Integer[] to_int_array_zero = set.toArray( new Integer[0] ); assertTrue( "set and array mismatch: " + set + ", " + Arrays.asList( to_int_array_zero ), set.containsAll( Arrays.asList( to_int_array_zero ) ) ); Integer[] to_int_array_size = set.toArray( new Integer[set.size()] ); assertTrue( "set and array mismatch: " + set + ", " + Arrays.asList( to_int_array_size ), set.containsAll( Arrays.asList( to_int_array_size ) ) ); Number[] to_num_array_zero = set.toArray( new Number[0] ); assertTrue( "set and array mismatch: " + set + ", " + Arrays.asList( to_num_array_zero ), set.containsAll( Arrays.asList( to_num_array_zero ) ) ); Number[] to_num_array_size = set.toArray( new Number[set.size()] ); assertTrue( "set and array mismatch: " + set + ", " + Arrays.asList( to_num_array_size ), set.containsAll( Arrays.asList( to_num_array_size ) ) ); } @SuppressWarnings({"MismatchedQueryAndUpdateOfCollection"}) public void testRehashing() throws Exception { Set<Integer> s = new TLinkedHashSet<Integer>(); for ( int i = 0; i < 10000; i++ ) { s.add( new Integer( i ) ); } } /** * this tests that we throw when people violate the * general contract for hashcode on java.lang.Object */ @SuppressWarnings({"MismatchedQueryAndUpdateOfCollection"}) public void testSomeBadlyWrittenObject() { Set<Object> s = new TLinkedHashSet<Object>(); boolean didThrow = false; int i = 0; try { for (; i < 101; i++ ) { s.add( new Crap() ); } } catch ( IllegalArgumentException e ) { didThrow = true; } assertTrue( "expected TLinkedHashSet to throw an IllegalArgumentException", didThrow ); } public void testIterable() { Set<String> set = new TLinkedHashSet<String>(); set.add( "One" ); set.add( "Two" ); for ( String s : set ) { assertTrue( s.equals( "One" ) || s.equals( "Two" ) ); } } public void testToString() { Set<String> set = new TLinkedHashSet<String>(); set.add( "One" ); set.add( "Two" ); String to_string = set.toString(); assertTrue( to_string, to_string.equals( "{One, Two}" ) || to_string.equals( "{Two, One}" ) ); } public void testEquals() { String[] strings = {"hi", "bye", "hello", "goodbye"}; Set<String> set = new TLinkedHashSet<String>(); set.addAll( Arrays.asList( strings ) ); Set<String> other = new TLinkedHashSet<String>(); other.addAll( Arrays.asList( strings ) ); assertTrue( "sets incorrectly not equal: " + set + ", " + other, set.equals( other ) ); String[] mismatched = {"heyya", "whassup", "seeya", "blargh"}; Set<String> unequal = new TLinkedHashSet<String>(); unequal.addAll( Arrays.asList( mismatched ) ); assertFalse( "sets incorrectly equal: " + set + ", " + unequal, set.equals( unequal ) ); // Change length, different code branch unequal.add( "whee!" ); assertFalse( "sets incorrectly equal: " + set + ", " + unequal, set.equals( unequal ) ); } public void testEqualsNonSet() { String[] strings = {"hi", "bye", "hello", "goodbye"}; Set<String> set = new TLinkedHashSet<String>(); set.addAll( Arrays.asList( strings ) ); List<String> other = new ArrayList<String>(); other.addAll( Arrays.asList( strings ) ); assertFalse( "sets incorrectly equals list: " + set + ", " + other, set.equals( other ) ); Map<String, String> map = new HashMap<String, String>(); for ( String string : strings ) { map.put( string, string ); } assertFalse( "sets incorrectly equals map: " + set + ", " + map, set.equals( map ) ); } public void testHashcode() { String[] strings = {"hi", "bye", "hello", "goodbye"}; Set<String> set = new TLinkedHashSet<String>(); set.addAll( Arrays.asList( strings ) ); Set<String> other = new TLinkedHashSet<String>(); other.addAll( Arrays.asList( strings ) ); assertTrue( "hashcodes incorrectly not equal: " + set + ", " + other, set.hashCode() == other.hashCode() ); String[] mismatched = {"heyya", "whassup", "seeya", "blargh"}; Set<String> unequal = new TLinkedHashSet<String>(); unequal.addAll( Arrays.asList( mismatched ) ); assertFalse( "hashcodes unlikely equal: " + set + ", " + unequal, set.hashCode() == unequal.hashCode() ); } public void testCompact() { int max_size = 10000; int reduced_size = 100; TLinkedHashSet<Integer> set = new TLinkedHashSet<Integer>( max_size, 1.0f ); for ( int index = 1; index <= max_size; index++ ) { set.add( Integer.valueOf( index ) ); } assertEquals( max_size, set.size() ); int max_length = set._set.length; for ( int index = max_size; index > reduced_size; index-- ) { set.remove( Integer.valueOf( index ) ); } assertEquals( reduced_size, set.size() ); set.compact(); int compacted_length = set._set.length; assertFalse( max_length + " should != " + compacted_length, max_length == compacted_length ); } public void testDisabledAutoCompact() { int max_size = 10000; int reduced_size = 100; TLinkedHashSet<Integer> set = new TLinkedHashSet<Integer>( max_size, 1.0f ); set.setAutoCompactionFactor( 0.0f ); // Disable for ( int index = 1; index <= max_size; index++ ) { set.add( Integer.valueOf( index ) ); } assertEquals( max_size, set.size() ); int max_length = set._set.length; for ( int index = max_size; index > reduced_size; index-- ) { set.remove( Integer.valueOf( index ) ); } assertEquals( reduced_size, set.size() ); int uncompacted_length = set._set.length; assertEquals( max_length, uncompacted_length ); set.compact(); int compacted_length = set._set.length; assertFalse( uncompacted_length + " should != " + compacted_length, uncompacted_length == compacted_length ); } // in this junk class, all instances hash to the same // address, but some objects claim to be equal where // others do not. public static class Crap { public boolean equals( Object other ) { return other instanceof Crap; } public int hashCode() { return System.identityHashCode( this ); } } public static void main( String[] args ) throws Exception { junit.textui.TestRunner.run( new TLinkedHashSetTest( "testBadlyWrittenObject" ) ); } } // TLinkedHashSetTests