TestTools.java
001 package gate.util;
002 
003 import java.lang.reflect.Constructor;
004 
005 import junit.framework.Test;
006 import junit.framework.TestCase;
007 import junit.framework.TestSuite;
008 
009 /**
010  * Test cases for {@link Tools#getMostSpecificConstructor}.
011  */
012 public class TestTools extends TestCase {
013 
014   public TestTools(String name) {
015     super(name);
016   }
017 
018   // A small hierarchy of interfaces and classes to test
019   // getMostSpecificConstructor
020   private static interface InterfaceA {
021   }
022 
023   private static interface InterfaceB {
024   }
025 
026   private static interface SubInterfaceB extends InterfaceB {
027   }
028 
029   private static class ClassA implements InterfaceA {
030   }
031 
032   private static class ClassB implements InterfaceB {
033   }
034 
035   private static class ClassSubB implements SubInterfaceB {
036   }
037 
038   private static class ClassAB implements InterfaceA, InterfaceB {
039   }
040 
041   private static class SubClassOfAB extends ClassAB {
042   }
043 
044   private static class DifferentClassAB implements InterfaceA, InterfaceB {
045   }
046 
047   private static class ConstructorTest {
048     public ConstructorTest(InterfaceA a) {
049       // applicable to InterfaceA, ClassA, ClassAB, SubClassOfAB
050       // and DifferentClassAB
051     }
052 
053     public ConstructorTest(InterfaceB b) {
054       // applicable to InterfaceB, ClassB, SubInterfaceB, ClassSubB,
055       // ClassAB, SubClassOfAB and DifferentClassAB
056     }
057 
058     public ConstructorTest(SubInterfaceB sb) {
059       // applicable to SubInterfaceB and ClassSubB only
060     }
061 
062     public ConstructorTest(ClassAB ab) {
063       // applicable to ClassAB and SubClassOfAB only
064     }
065   }
066 
067   public void testGetMostSpecificConstructor1() throws Exception {
068     // simple case - there is only one constructor of
069     // ConstructorTest that is applicable to an argument of type ClassB
070     // - the one taking an InterfaceB
071     Constructor expected =
072             ConstructorTest.class.getConstructor(InterfaceB.class);
073 
074     Constructor result =
075             Tools.getMostSpecificConstructor(ConstructorTest.class,
076                     ClassB.class);
077     assertEquals("Most specific constructor for ConstructorTest taking a "
078             "ClassB should be ConstructorTest(InterfaceB)", expected, result);
079   }
080 
081   public void testGetMostSpecificConstructor2() throws Exception {
082     // more complex case - there are two applicable constructors taking
083     // a ClassSubB - InterfaceB and SubInterfaceB - but the latter is
084     // more specific than the former
085     Constructor expected =
086             ConstructorTest.class.getConstructor(SubInterfaceB.class);
087 
088     Constructor result =
089             Tools.getMostSpecificConstructor(ConstructorTest.class,
090                     ClassSubB.class);
091     assertEquals("Most specific constructor for ConstructorTest taking a "
092             "ClassSubB should be ConstructorTest(SubInterfaceB)", expected,
093             result);
094   }
095 
096   public void testGetMostSpecificConstructor3() throws Exception {
097     // more complex again - there are three applicable constructors
098     // taking a SubClassOfAB - InterfaceA, InterfaceB and ClassAB - but
099     // the last is more specific than both the others, so should
100     // be chosen
101     Constructor expected = ConstructorTest.class.getConstructor(ClassAB.class);
102 
103     Constructor result =
104             Tools.getMostSpecificConstructor(ConstructorTest.class,
105                     SubClassOfAB.class);
106     assertEquals("Most specific constructor for ConstructorTest taking a "
107             "SubClassOfAB should be ConstructorTest(ClassAB)", expected,
108             result);
109   }
110 
111   public void testGetMostSpecificConstructor4() throws Exception {
112     // ambiguous case - there are two applicable constructors for
113     // a DifferentClassAB - InterfaceA and InterfaceB - and neither
114     // is more specific than the other. We expect an "ambiguous"
115     // exception
116 
117     try {
118       Tools.getMostSpecificConstructor(ConstructorTest.class,
119                       DifferentClassAB.class);
120     }
121     catch(NoSuchMethodException e) {
122       assertTrue("Expected \"ambiguous\" exception", e.getMessage().startsWith(
123               "Ambiguous"));
124       return;
125     }
126 
127     fail("getMostSpecificConstructor(ConstructorTest, "
128             "DifferentClassAB) "
129             "should have thrown an exception");
130   }
131 
132   public static Test suite() {
133     return new TestSuite(TestTools.class);
134   }
135 
136   public static void main(String[] argvthrows Exception {
137     TestTools app = new TestTools("TestTools");
138     app.testGetMostSpecificConstructor1();
139     app.testGetMostSpecificConstructor2();
140     app.testGetMostSpecificConstructor3();
141     app.testGetMostSpecificConstructor4();
142   }
143 }