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[] argv) throws Exception {
137 TestTools app = new TestTools("TestTools");
138 app.testGetMostSpecificConstructor1();
139 app.testGetMostSpecificConstructor2();
140 app.testGetMostSpecificConstructor3();
141 app.testGetMostSpecificConstructor4();
142 }
143 }
|