Log in Help
Print
Homegatesrctestgateutil 〉 TestTools.java
 
package gate.util;

import java.lang.reflect.Constructor;

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

/**
 * Test cases for {@link Tools#getMostSpecificConstructor}.
 */
public class TestTools extends TestCase {

  public TestTools(String name) {
    super(name);
  }

  // A small hierarchy of interfaces and classes to test
  // getMostSpecificConstructor
  private static interface InterfaceA {
  }

  private static interface InterfaceB {
  }

  private static interface SubInterfaceB extends InterfaceB {
  }

  @SuppressWarnings("unused")
  private static class ClassA implements InterfaceA {
  }

  private static class ClassB implements InterfaceB {
  }

  private static class ClassSubB implements SubInterfaceB {
  }

  private static class ClassAB implements InterfaceA, InterfaceB {
  }

  private static class SubClassOfAB extends ClassAB {
  }

  private static class DifferentClassAB implements InterfaceA, InterfaceB {
  }

  @SuppressWarnings("unused")
  private static class ConstructorTest {
    
    public ConstructorTest(InterfaceA a) {
      // applicable to InterfaceA, ClassA, ClassAB, SubClassOfAB
      // and DifferentClassAB
    }

    public ConstructorTest(InterfaceB b) {
      // applicable to InterfaceB, ClassB, SubInterfaceB, ClassSubB,
      // ClassAB, SubClassOfAB and DifferentClassAB
    }

    public ConstructorTest(SubInterfaceB sb) {
      // applicable to SubInterfaceB and ClassSubB only
    }

    public ConstructorTest(ClassAB ab) {
      // applicable to ClassAB and SubClassOfAB only
    }
  }

  public void testGetMostSpecificConstructor1() throws Exception {
    // simple case - there is only one constructor of
    // ConstructorTest that is applicable to an argument of type ClassB
    // - the one taking an InterfaceB
    Constructor<?> expected =
            ConstructorTest.class.getConstructor(InterfaceB.class);

    Constructor<?> result =
            Tools.getMostSpecificConstructor(ConstructorTest.class,
                    ClassB.class);
    assertEquals("Most specific constructor for ConstructorTest taking a "
            + "ClassB should be ConstructorTest(InterfaceB)", expected, result);
  }

  public void testGetMostSpecificConstructor2() throws Exception {
    // more complex case - there are two applicable constructors taking
    // a ClassSubB - InterfaceB and SubInterfaceB - but the latter is
    // more specific than the former
    Constructor<?> expected =
            ConstructorTest.class.getConstructor(SubInterfaceB.class);

    Constructor<?> result =
            Tools.getMostSpecificConstructor(ConstructorTest.class,
                    ClassSubB.class);
    assertEquals("Most specific constructor for ConstructorTest taking a "
            + "ClassSubB should be ConstructorTest(SubInterfaceB)", expected,
            result);
  }

  public void testGetMostSpecificConstructor3() throws Exception {
    // more complex again - there are three applicable constructors
    // taking a SubClassOfAB - InterfaceA, InterfaceB and ClassAB - but
    // the last is more specific than both the others, so should
    // be chosen
    Constructor<?> expected = ConstructorTest.class.getConstructor(ClassAB.class);

    Constructor<?> result =
            Tools.getMostSpecificConstructor(ConstructorTest.class,
                    SubClassOfAB.class);
    assertEquals("Most specific constructor for ConstructorTest taking a "
            + "SubClassOfAB should be ConstructorTest(ClassAB)", expected,
            result);
  }

  public void testGetMostSpecificConstructor4() throws Exception {
    // ambiguous case - there are two applicable constructors for
    // a DifferentClassAB - InterfaceA and InterfaceB - and neither
    // is more specific than the other. We expect an "ambiguous"
    // exception

    try {
      Tools.getMostSpecificConstructor(ConstructorTest.class,
                      DifferentClassAB.class);
    }
    catch(NoSuchMethodException e) {
      assertTrue("Expected \"ambiguous\" exception", e.getMessage().startsWith(
              "Ambiguous"));
      return;
    }

    fail("getMostSpecificConstructor(ConstructorTest, "
            + "DifferentClassAB) "
            + "should have thrown an exception");
  }

  public static Test suite() {
    return new TestSuite(TestTools.class);
  }

  public static void main(String[] argv) throws Exception {
    TestTools app = new TestTools("TestTools");
    app.testGetMostSpecificConstructor1();
    app.testGetMostSpecificConstructor2();
    app.testGetMostSpecificConstructor3();
    app.testGetMostSpecificConstructor4();
  }
}