package com.cedarsoftware.util; import com.google.common.collect.Lists; import com.google.common.collect.Sets; import org.junit.Test; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import java.util.SortedMap; import java.util.SortedSet; import java.util.TreeMap; import java.util.TreeSet; import java.util.concurrent.ConcurrentSkipListMap; import static java.lang.Math.E; import static java.lang.Math.PI; import static java.lang.Math.atan; import static java.lang.Math.cos; import static java.lang.Math.log; import static java.lang.Math.pow; import static java.lang.Math.sin; import static java.lang.Math.tan; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; /** * @author John DeRegnaucourt * @author sapradhan8 * <br> * Licensed under the Apache License, Version 2.0 (the "License"); you * may not use this file except in compliance with the License. You may * obtain a copy of the License at <br> * <br> * http://www.apache.org/licenses/LICENSE-2.0 <br> * <br> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. */ public class TestDeepEquals { @Test public void testSameObjectEquals() { Date date1 = new Date(); Date date2 = date1; assertTrue(DeepEquals.deepEquals(date1, date2)); } @Test public void testEqualsWithNull() { Date date1 = new Date(); assertFalse(DeepEquals.deepEquals(null, date1)); assertFalse(DeepEquals.deepEquals(date1, null)); } @Test public void testDifferentClasses() { assertFalse(DeepEquals.deepEquals(new Date(), "test")); } @Test public void testPOJOequals() { Class1 x = new Class1(true, tan(PI / 4), 1); Class1 y = new Class1(true, 1.0, 1); assertTrue(DeepEquals.deepEquals(x, y)); assertFalse(DeepEquals.deepEquals(x, new Class1())); Class2 a = new Class2((float) atan(1.0), "hello", (short) 2, new Class1(false, sin(0.75), 5)); Class2 b = new Class2((float) PI / 4, "hello", (short) 2, new Class1(false, 2 * cos(0.75 / 2) * sin(0.75 / 2), 5) ); assertTrue(DeepEquals.deepEquals(a, b)); assertFalse(DeepEquals.deepEquals(a, new Class2())); } @Test public void testPrimitiveArrays() { int array1[] = { 2, 4, 5, 6, 3, 1, 3, 3, 5, 22 }; int array2[] = { 2, 4, 5, 6, 3, 1, 3, 3, 5, 22 }; assertTrue(DeepEquals.deepEquals(array1, array2)); int array3[] = { 3, 4, 7 }; assertFalse(DeepEquals.deepEquals(array1, array3)); float array4[] = { 3.4f, 5.5f }; assertFalse(DeepEquals.deepEquals(array1, array4)); } @Test public void testOrderedCollection() { List<String> a = Lists.newArrayList("one", "two", "three", "four", "five"); List<String> b = Lists.newLinkedList(a); assertTrue(DeepEquals.deepEquals(a, b)); List<Integer> c = Lists.newArrayList(1, 2, 3, 4, 5); assertFalse(DeepEquals.deepEquals(a, c)); List<Integer> d = Lists.newArrayList(4, 6); assertFalse(DeepEquals.deepEquals(c, d)); List<Class1> x1 = Lists.newArrayList(new Class1(true, log(pow(E, 2)), 6), new Class1(true, tan(PI / 4), 1)); List<Class1> x2 = Lists.newArrayList(new Class1(true, 2, 6), new Class1(true, 1, 1)); assertTrue(DeepEquals.deepEquals(x1, x2)); } @Test public void testUnorderedCollection() { Set<String> a = Sets.newHashSet("one", "two", "three", "four", "five"); Set<String> b = Sets.newHashSet("three", "five", "one", "four", "two"); assertTrue(DeepEquals.deepEquals(a, b)); Set<Integer> c = Sets.newHashSet(1, 2, 3, 4, 5); assertFalse(DeepEquals.deepEquals(a, c)); Set<Integer> d = Sets.newHashSet(4, 2, 6); assertFalse(DeepEquals.deepEquals(c, d)); Set<Class1> x1 = Sets.newHashSet(new Class1(true, log(pow(E, 2)), 6), new Class1(true, tan(PI / 4), 1)); Set<Class1> x2 = Sets.newHashSet(new Class1(true, 1, 1), new Class1(true, 2, 6)); assertTrue(DeepEquals.deepEquals(x1, x2)); } @Test public void testEquivalentMaps() { Map map1 = new LinkedHashMap(); fillMap(map1); Map map2 = new HashMap(); fillMap(map2); assertTrue(DeepEquals.deepEquals(map1, map2)); assertEquals(DeepEquals.deepHashCode(map1), DeepEquals.deepHashCode(map2)); map1 = new TreeMap(); fillMap(map1); map2 = new TreeMap(); map2 = Collections.synchronizedSortedMap((SortedMap) map2); fillMap(map2); assertTrue(DeepEquals.deepEquals(map1, map2)); assertEquals(DeepEquals.deepHashCode(map1), DeepEquals.deepHashCode(map2)); } @Test public void testInequivalentMaps() { Map map1 = new TreeMap(); fillMap(map1); Map map2 = new HashMap(); fillMap(map2); // Sorted versus non-sorted Map assertFalse(DeepEquals.deepEquals(map1, map2)); // Hashcodes are equals because the Maps have same elements assertEquals(DeepEquals.deepHashCode(map1), DeepEquals.deepHashCode(map2)); map2 = new TreeMap(); fillMap(map2); map2.remove("kilo"); assertFalse(DeepEquals.deepEquals(map1, map2)); // Hashcodes are different because contents of maps are different assertNotEquals(DeepEquals.deepHashCode(map1), DeepEquals.deepHashCode(map2)); // Inequality because ConcurrentSkipListMap is a SortedMap map1 = new HashMap(); fillMap(map1); map2 = new ConcurrentSkipListMap(); fillMap(map2); assertFalse(DeepEquals.deepEquals(map1, map2)); map1 = new TreeMap(); fillMap(map1); map2 = new ConcurrentSkipListMap(); fillMap(map2); assertTrue(DeepEquals.deepEquals(map1, map2)); map2.remove("papa"); assertFalse(DeepEquals.deepEquals(map1, map2)); } @Test public void testEquivalentCollections() { // ordered Collection Collection col1 = new ArrayList(); fillCollection(col1); Collection col2 = new LinkedList(); fillCollection(col2); assertTrue(DeepEquals.deepEquals(col1, col2)); assertEquals(DeepEquals.deepHashCode(col1), DeepEquals.deepHashCode(col2)); // unordered Collections (Set) col1 = new LinkedHashSet(); fillCollection(col1); col2 = new HashSet(); fillCollection(col2); assertTrue(DeepEquals.deepEquals(col1, col2)); assertEquals(DeepEquals.deepHashCode(col1), DeepEquals.deepHashCode(col2)); col1 = new TreeSet(); fillCollection(col1); col2 = new TreeSet(); Collections.synchronizedSortedSet((SortedSet) col2); fillCollection(col2); assertTrue(DeepEquals.deepEquals(col1, col2)); assertEquals(DeepEquals.deepHashCode(col1), DeepEquals.deepHashCode(col2)); } @Test public void testInequivalentCollections() { Collection col1 = new TreeSet(); fillCollection(col1); Collection col2 = new HashSet(); fillCollection(col2); assertFalse(DeepEquals.deepEquals(col1, col2)); assertEquals(DeepEquals.deepHashCode(col1), DeepEquals.deepHashCode(col2)); col2 = new TreeSet(); fillCollection(col2); col2.remove("lima"); assertFalse(DeepEquals.deepEquals(col1, col2)); assertNotEquals(DeepEquals.deepHashCode(col1), DeepEquals.deepHashCode(col2)); assertFalse(DeepEquals.deepEquals(new HashMap(), new ArrayList())); assertFalse(DeepEquals.deepEquals(new ArrayList(), new HashMap())); } @Test public void testArray() { Object[] a1 = new Object[] {"alpha", "bravo", "charlie", "delta"}; Object[] a2 = new Object[] {"alpha", "bravo", "charlie", "delta"}; assertTrue(DeepEquals.deepEquals(a1, a2)); assertEquals(DeepEquals.deepHashCode(a1), DeepEquals.deepHashCode(a2)); a2[3] = "echo"; assertFalse(DeepEquals.deepEquals(a1, a2)); assertNotEquals(DeepEquals.deepHashCode(a1), DeepEquals.deepHashCode(a2)); } @Test public void testHasCustomMethod() { assertFalse(DeepEquals.hasCustomEquals(EmptyClass.class)); assertFalse(DeepEquals.hasCustomHashCode(Class1.class)); assertTrue(DeepEquals.hasCustomEquals(EmptyClassWithEquals.class)); assertTrue(DeepEquals.hasCustomHashCode(EmptyClassWithEquals.class)); } @Test public void testSymmetry() { boolean one = DeepEquals.deepEquals(new ArrayList<String>(), new EmptyClass()); boolean two = DeepEquals.deepEquals(new EmptyClass(), new ArrayList<String>()); assert one == two; } static class EmptyClass { } static class EmptyClassWithEquals { public boolean equals(Object obj) { return obj instanceof EmptyClassWithEquals; } public int hashCode() { return 0; } } static class Class1 { private boolean b; private double d; int i; public Class1() { } public Class1(boolean b, double d, int i) { super(); this.b = b; this.d = d; this.i = i; } } static class Class2 { private Float f; String s; short ss; Class1 c; public Class2(float f, String s, short ss, Class1 c) { super(); this.f = f; this.s = s; this.ss = ss; this.c = c; } public Class2() { } } private void fillMap(Map map) { map.put("zulu", 26); map.put("alpha", 1); map.put("bravo", 2); map.put("charlie", 3); map.put("delta", 4); map.put("echo", 5); map.put("foxtrot", 6); map.put("golf", 7); map.put("hotel", 8); map.put("india", 9); map.put("juliet", 10); map.put("kilo", 11); map.put("lima", 12); map.put("mike", 13); map.put("november", 14); map.put("oscar", 15); map.put("papa", 16); map.put("quebec", 17); map.put("romeo", 18); map.put("sierra", 19); map.put("tango", 20); map.put("uniform", 21); map.put("victor", 22); map.put("whiskey", 23); map.put("xray", 24); map.put("yankee", 25); } private void fillCollection(Collection col) { col.add("zulu"); col.add("alpha"); col.add("bravo"); col.add("charlie"); col.add("delta"); col.add("echo"); col.add("foxtrot"); col.add("golf"); col.add("hotel"); col.add("india"); col.add("juliet"); col.add("kilo"); col.add("lima"); col.add("mike"); col.add("november"); col.add("oscar"); col.add("papa"); col.add("quebec"); col.add("romeo"); col.add("sierra"); col.add("tango"); col.add("uniform"); col.add("victor"); col.add("whiskey"); col.add("xray"); col.add("yankee"); } }