001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.commons.functor;
018    
019    import static org.junit.Assert.assertEquals;
020    import static org.junit.Assert.assertNotNull;
021    import static org.junit.Assert.assertTrue;
022    
023    import java.io.ByteArrayInputStream;
024    import java.io.ByteArrayOutputStream;
025    import java.io.ObjectInputStream;
026    import java.io.ObjectOutputStream;
027    import java.io.Serializable;
028    
029    import org.junit.Test;
030    
031    /**
032     * @version $Revision: 1171255 $ $Date: 2011-09-15 22:27:39 +0200 (Thu, 15 Sep 2011) $
033     * @author Rodney Waldhoff
034     */
035    public abstract class BaseFunctorTest {
036    
037        // Framework
038        // ------------------------------------------------------------------------
039    
040        protected abstract Object makeFunctor() throws Exception;
041    
042        // Tests
043        // ------------------------------------------------------------------------
044    
045        @Test
046        public final void testObjectEquals() throws Exception {
047            Object obj = makeFunctor();
048            assertEquals("equals must be reflexive",obj,obj);
049            assertEquals("hashCode must be reflexive",obj.hashCode(),obj.hashCode());
050            assertTrue(! obj.equals(null) ); // should be able to compare to null
051    
052            Object obj2 = makeFunctor();
053            if (obj.equals(obj2)) {
054                assertEquals("equals implies hash equals",obj.hashCode(),obj2.hashCode());
055                assertEquals("equals must be symmetric",obj2,obj);
056            } else {
057                assertTrue("equals must be symmetric",! obj2.equals(obj));
058            }
059        }
060    
061        @Test
062        public final void testSerializeDeserializeThenCompare() throws Exception {
063            Object obj = makeFunctor();
064            if (obj instanceof Serializable) {
065                ByteArrayOutputStream buffer = new ByteArrayOutputStream();
066                ObjectOutputStream out = new ObjectOutputStream(buffer);
067                out.writeObject(obj);
068                out.close();
069    
070                ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(buffer.toByteArray()));
071                Object dest = in.readObject();
072                in.close();
073                assertEquals("obj != deserialize(serialize(obj))",obj,dest);
074                assertEquals("obj.hash != deserialize(serialize(obj.hash))",obj.hashCode(),dest.hashCode());
075            }
076        }
077    
078        @Test
079        public void testToStringIsOverridden() throws Exception {
080            Object obj = makeFunctor();
081            assertNotNull("toString should never return null",obj.toString());
082            assertTrue(
083                obj.getClass().getName()  + " should override toString(), found \"" + obj.toString() + "\"",
084                !obj.toString().equals(objectToString(obj)));
085        }
086    
087        // protected utils
088        // ------------------------------------------------------------------------
089    
090        public static void assertObjectsAreEqual(Object a, Object b) {
091            assertEquals(a,b);
092            assertEquals(b,a);
093            assertEquals(a.hashCode(),b.hashCode());
094            assertEquals(a.toString(),b.toString()); // not strictly required
095        }
096    
097        public static void assertObjectsAreNotEqual(Object a, Object b) {
098            assertTrue(!a.equals(b));
099            assertTrue(!b.equals(a));
100            assertTrue(a.hashCode() != b.hashCode()); // not strictly required
101            assertTrue(!a.toString().equals(b.toString())); // not strictly required
102        }
103    
104        // private utils
105        // ------------------------------------------------------------------------
106        private String objectToString(Object obj) {
107            return obj.getClass().getName() + "@" + Integer.toHexString(obj.hashCode());
108        }
109    }