/* * jPOS Project [http://jpos.org] * Copyright (C) 2000-2017 jPOS Software SRL * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.jpos.testhelpers; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import junit.framework.AssertionFailedError; import org.junit.Assert; import org.junit.Before; import org.junit.Test; /** * Extend me in order to test a class's functional compliance with the * {@link java.lang.Comparable Comparable} interface. * <p> * Override my {@link #createLessInstance() createLessInstance}, * {@link #createEqualInstance() createEqualInstance}, and * {@link #createGreaterInstance() createGreaterInstance} methods to provide me * with objects to test against. These methods should return objects that are of * the same class. * * @see java.lang.Comparable */ @SuppressWarnings("javadoc") public abstract class ComparabilityTestCase<T extends Comparable<T>> { private T less; private T equal1; private T equal2; private T greater; /** * Creates and returns an instance of the class under test. * * @return a new instance of the class under test; each object returned from * this method should compare less than the objects returned from * {@link #createEqualInstance() createEqualInstance()} * @throws Exception */ protected abstract T createLessInstance() throws Exception; /** * Creates and returns an instance of the class under test. * * @return a new instance of the class under test; each object returned from * this method should compare equal to each other * @throws Exception */ protected abstract T createEqualInstance() throws Exception; /** * Creates and returns an instance of the class under test. * * @return a new instance of the class under test; each object returned from * this method should compare greater than the objects returned from * {@link #createEqualInstance() createEqualInstance()} * @throws Exception */ protected abstract T createGreaterInstance() throws Exception; /** * Sets up the test fixture. * * @throws Exception */ @Before public void setUp() throws Exception { less = createLessInstance(); equal1 = createEqualInstance(); equal2 = createEqualInstance(); greater = createGreaterInstance(); // We want these assertions to yield errors, not failures. try { assertNotNull("createLessInstance() returned null", less); assertNotNull("createEqualInstance() returned null", equal1); assertNotNull("2nd createEqualInstance() returned null", equal2); assertNotNull("createGreaterInstance() returned null", greater); assertEquals("less and equal1 of different classes", less.getClass(), equal1.getClass()); assertEquals("less and equal2 of different classes", less.getClass(), equal2.getClass()); assertEquals("less and greater of different classes", less.getClass(), greater.getClass()); checkForEquality(equal1, equal2); } catch (AssertionFailedError ex) { throw new IllegalArgumentException(ex.getMessage()); } } /** * Override as a no-op if you do not require that * {@link #createEqualInstance() createEqualInstance()} return distinct but * equivalent objects. */ protected void checkForEquality(T c1, T c2) { Assert.assertNotSame("1st equal instance same as 2nd", c1, c2); assertEquals("1st equal not equal to 2nd", equal1, equal2); } /** * Tests whether <code>sgn(x.compareTo(y)) == -sgn(y.compareTo(x))</code> * for all <code>x</code> and <code>y</code> given to this test. */ @Test public final void testForReverseSigns() { assertEquals("less vs. equal1", sgn(less.compareTo(equal1)), -sgn(equal1.compareTo(less))); assertEquals("less vs. equal2", sgn(less.compareTo(equal2)), -sgn(equal2.compareTo(less))); assertEquals("less vs. greater", sgn(less.compareTo(greater)), -sgn(greater.compareTo(less))); assertEquals("equal1 vs. equal2", sgn(equal1.compareTo(equal2)), -sgn(equal2.compareTo(equal1))); assertEquals("equal1 vs. greater", sgn(equal1.compareTo(greater)), -sgn(greater.compareTo(equal1))); assertEquals("equal2 vs. greater", sgn(equal2.compareTo(greater)), -sgn(greater.compareTo(equal2))); } /** * Tests whether <code>sgn(x.compareTo(z)) == sgn(y.compareTo(z))</code> for * all <code>z</code> when <code>x.compareTo(y) == 0</code>. */ @Test public final void testForSameSigns() { assertEquals("equal vs. less", sgn(equal1.compareTo(less)), sgn(equal2.compareTo(less))); assertEquals("equal vs. greater", sgn(equal1.compareTo(greater)), sgn(equal2.compareTo(greater))); } /** * Tests for sensible return values from the class under test's * <code>compareTo</code> method. Doing so effectively tests the * transitivity of <code>compareTo</code> also-- * <code>(x.compareTo(y)>0 && y.compareTo(z)>0)</code> implies * <code>x.compareTo(z)>0</code>. */ @Test public final void testReturnValues() { ComparableAssert.assertLesser(equal1, less); ComparableAssert.assertLesser(equal2, less); ComparableAssert.assertGreater(less, greater); ComparableAssert.assertEquals(equal1, equal2); ComparableAssert.assertGreater(equal1, greater); ComparableAssert.assertGreater(equal2, greater); } // /** // * Tests whether <code>compareTo</code> throws a ClassCastException when // appropriate. // */ // @Test // public final void testForClassCastException() throws Exception { // try { // less.compareTo(new Object()); // } catch (ClassCastException success) { // return; // } // fail("should have thrown ClassCastException"); // } private int sgn(int x) { return x == 0 ? 0 : x / Math.abs(x); } }