All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.evasion.framework.test.AbstractEqualsTester Maven / Gradle / Ivy

There is a newer version: 2.0.0.2
Show newest version
/*
 * Document confidentiel - Diffusion interdite 
 */
package com.evasion.framework.test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

import org.junit.Assert;

/**
 * Classe d'utilitaire de test pour les Euqlas et Hashcode.
 * 
 */
public abstract class AbstractEqualsTester {

    /**
     * Verifies that equals() and hashCode() methods conforms to
     * java.lang.Object contract.
     *
     * @param a
     *            L'objet de base
     * @param b
     *            Un objet tel que a.equals(b) == true
     * @param c
     *            Un objet tel que a.equals(c) == false
     * @param d
     *            Un objet d�rivant de a.
     */
    public void testEqualsAndHashCode(final Object a, final Object b,
            final Object c, final Object d) {
        Assert.assertNotNull("A must not be null.", a);
        Assert.assertNotNull("B must not be null.", b);

        Assert.assertEquals("B must be of same class as A", a.getClass(), b.getClass());

        if (c == null) {
            this.assertNotMutable(a.getClass());
        } else {
            Assert.assertEquals("C must be of same class as A", a.getClass(), c.getClass());
        }

        if (isFinalClass(a.getClass())) {
            Assert.assertNull(d);
        } else {
            Assert.assertFalse("D must be of a different class than A", a.getClass().equals(d.getClass()));
        }

        this.assertNotEqualsNull(a);
        this.assertIsReflexive(a);
        this.assertIsSymmetric(a, b);

        if (c != null) {
            this.assertNotEquals(a, c);
        }

        if (d != null) {
            this.assertEqualsSubClass(a, d);
        }
    }

    /**
     * Verifie EqualsSubClass().
     *
     * @param a
     *            objet A
     * @param d
     *            objet D
     */
    protected abstract void assertEqualsSubClass(final Object a, final Object d);

    /**
     * Verifie that a.equals(c) == true and that c.equals(a) == true.
     *
     * @param a
     *            objet A
     * @param c
     *            objet C
     */
    private void assertNotEquals(final Object a, final Object c) {
        Assert.assertFalse("a.equals(c) returned true", a.equals(c));
        Assert.assertFalse("c.equals(a) returned true", c.equals(a));
    }

    /**
     * Assert that a.equals(null) == false.
     *
     * @param a
     *            objet A
     */
    @edu.umd.cs.findbugs.annotations.SuppressWarnings("NP_LOAD_OF_KNOWN_NULL_VALUE")
    private void assertNotEqualsNull(final Object a) {
        // Creation d'un objet pour tester que a.equals(null) renvoi faux
        // Si on ecrit a.equals(null) directement il s'agit d'une violation
        Object nullObject = null;
        Assert.assertFalse("a.equals(null) returned true", a.equals(nullObject));
    }

    /**
     * Verifies that a.equals(a).
     *
     * @param a
     *            objet A
     */
    private void assertIsReflexive(final Object a) {
        Assert.assertTrue(a.equals(a));
        Assert.assertEquals(a.hashCode(), a.hashCode());
    }

    /**
     * Verifies that the equals method is symmetric.
     *
     * Assert that a.equals(b) and b.equals(a) and that a.hashCode() ==
     * b.hashCode().
     *
     * @param a
     *            objet A
     * @param b
     *            objet B
     */
    private void assertIsSymmetric(final Object a, final Object b) {
        Assert.assertTrue(a.equals(b));
        Assert.assertTrue(b.equals(a));
        Assert.assertEquals(a.hashCode(), b.hashCode());
    }

    /**
     * Tests if the given class is final.
     *
     * @param clazz
     *            the class to test.
     * @return true if the class is final, false otherwise.
     */
    @SuppressWarnings("unchecked")
    private boolean isFinalClass(final Class clazz) {
        return Modifier.isFinal(clazz.getModifiers());
    }

    /**
     * Verify that the given class is not mutable.
     *
     * @param clazz
     *            la class de l'objet � tester
     */
    @SuppressWarnings("unchecked")
    private void assertNotMutable(final Class clazz) {
        final Constructor[] constructors = clazz.getConstructors();

        for (int i = 0; i < constructors.length; i++) {
            if (constructors[i].getParameterTypes().length != 0) {
                if (!(constructors[i].getParameterTypes().length == 1 && (clazz.isAnonymousClass() || clazz.isMemberClass()))) {
                    Assert.fail("Class is mutable, it has non-default public constructor "
                            + constructors[i]);
                }
            }
        }

        final Method[] methods = clazz.getMethods();

        for (int i = 0; i < methods.length; i++) {
            if (methods[i].getName().startsWith("set")) {
                Assert.fail("Class has setter method " + methods[i].getName());
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy