1   /***************************************************************************************
2    * Copyright (c) Jonas BonŽr, Alexandre Vasseur. All rights reserved.                 *
3    * http://aspectwerkz.codehaus.org                                                    *
4    * ---------------------------------------------------------------------------------- *
5    * The software in this package is published under the terms of the LGPL license      *
6    * a copy of which has been included with this distribution in the license.txt file.  *
7    **************************************************************************************/
8   package test.mixin.perclass;
9   
10  import java.io.Serializable;
11  import java.lang.reflect.Method;
12  
13  import junit.framework.TestCase;
14  
15  /***
16   * @author <a href="mailto:jboner@codehaus.org">Jonas BonŽr </a>
17   * @author <a href="mailto:alex@gnilux.com">Alexandre Vasseur </a>
18   */
19  public class IntroductionTest extends TestCase {
20      private ToBeIntroduced m_toBeIntroduced;
21      private ToBeIntroducedUsingHasMethod m_toBeIntroducedUsingHasMethod;
22      private ToBeIntroducedUsingHasField m_toBeIntroducedUsingHasField;
23  
24      public IntroductionTest(String name) {
25          super(name);
26          try {
27              m_toBeIntroduced = new ToBeIntroduced();
28          } catch (Exception e) {
29              e.printStackTrace();
30          }
31          m_toBeIntroducedUsingHasMethod = new ToBeIntroducedUsingHasMethod();
32          m_toBeIntroducedUsingHasField = new ToBeIntroducedUsingHasField();
33      }
34  
35      public void testInterfaceIntroduction() {
36          assertTrue(m_toBeIntroduced instanceof Serializable);
37      }
38  
39      public void testMixinInterfaceIntroduction() {
40          assertTrue(m_toBeIntroduced instanceof Introductions);
41          assertTrue(m_toBeIntroduced instanceof Cloneable);
42      }
43  
44      public void testIntroducedComesFromInterfaces() {
45          Class klass = m_toBeIntroduced.getClass();
46          try {
47              Method m = klass.getDeclaredMethod("NOT_IN_MIXIN_INTF", new Class[0]);
48              fail("should not have introduced : " + m);
49          } catch (NoSuchMethodException e) {
50              ;//ok
51          }
52      }
53  
54      public void testReturnVoid() {
55          try {
56              ((Introductions) m_toBeIntroduced).getVoid();
57          } catch (RuntimeException e) {
58              fail(e.getMessage());
59          }
60      }
61  
62  
63      public void testReturnLong() {
64          assertEquals(1L, ((Introductions) m_toBeIntroduced).getLong());
65      }
66  
67      public void testReturnInt() {
68          assertEquals(1, ((Introductions) m_toBeIntroduced).getInt());
69      }
70  
71      public void testReturnShort() {
72          assertEquals(1, ((Introductions) m_toBeIntroduced).getShort());
73      }
74  
75      public void testReturnDouble() {
76          assertEquals(new Double(1.1D), new Double(((Introductions) m_toBeIntroduced).getDouble()));
77      }
78  
79      public void testReturnFloat() {
80          assertEquals(new Float(1.1F), new Float(((Introductions) m_toBeIntroduced).getFloat()));
81      }
82  
83      public void testReturnByte() {
84          assertEquals(Byte.parseByte("1"), ((Introductions) m_toBeIntroduced).getByte());
85      }
86  
87      public void testReturnChar() {
88          assertEquals('A', ((Introductions) m_toBeIntroduced).getChar());
89      }
90  
91      public void testReturnBoolean() {
92          assertEquals(true, ((Introductions) m_toBeIntroduced).getBoolean());
93      }
94  
95      public void testNoArgs() {
96          try {
97              ((Introductions) m_toBeIntroduced).noArgs();
98          } catch (Exception e) {
99              fail();
100         }
101     }
102 
103     public void testIntArg() {
104         assertEquals(12, ((Introductions) m_toBeIntroduced).intArg(12));
105     }
106 
107     public void testLongArg() {
108         long result = ((Introductions) m_toBeIntroduced).longArg(12L);
109         assertEquals(12L, result);
110     }
111 
112     public void testShortArg() {
113         assertEquals((short) 3, ((Introductions) m_toBeIntroduced).shortArg((short) 3));
114     }
115 
116     public void testDoubleArg() {
117         assertEquals(
118                 new Double(2.3D), new Double(
119                         ((Introductions) m_toBeIntroduced)
120                         .doubleArg(2.3D)
121                 )
122         );
123     }
124 
125     public void testFloatArg() {
126         assertEquals(new Float(2.3F), new Float(((Introductions) m_toBeIntroduced).floatArg(2.3F)));
127     }
128 
129     public void testByteArg() {
130         assertEquals(
131                 Byte.parseByte("1"), ((Introductions) m_toBeIntroduced).byteArg(
132                         Byte
133                         .parseByte("1")
134                 )
135         );
136     }
137 
138     public void testCharArg() {
139         assertEquals('B', ((Introductions) m_toBeIntroduced).charArg('B'));
140     }
141 
142     public void testBooleanArg() {
143         assertTrue(!((Introductions) m_toBeIntroduced).booleanArg(false));
144     }
145 
146     public void testObjectArg() {
147         assertEquals("test", ((Introductions) m_toBeIntroduced).objectArg("test"));
148     }
149 
150     public void testArrayArg() {
151         String[] strings = new String[0];
152         try {
153             strings = ((Introductions) m_toBeIntroduced).arrayArg(
154                     new String[]{
155                         "test1", "test2"
156                     }
157             );
158         } catch (Throwable e) {
159             System.out.println("e = " + e);
160         }
161         assertEquals("test1", strings[0]);
162         assertEquals("test2", strings[1]);
163     }
164 
165     public void testVariousArguments1() {
166         assertEquals(
167                 "dummy".hashCode() + 1 + (int) 2.3F,
168                 this.hashCode() + (int) 34L,
169                 ((Introductions) m_toBeIntroduced).variousArguments1("dummy", 1, 2.3F, this, 34L)
170         );
171     }
172 
173     public void testVariousArguments2() {
174         assertEquals(
175                 (int) 2.3F
176                 + 1
177                 + "dummy".hashCode()
178                 + this.hashCode()
179                 + (int) 34L
180                 + "test".hashCode(), ((Introductions) m_toBeIntroduced).variousArguments2(
181                         2.3F,
182                         1,
183                         "dummy",
184                         this,
185                         34L,
186                         "test"
187                 )
188         );
189     }
190 
191     public void testThrowException() {
192         try {
193             ((Introductions) m_toBeIntroduced).exceptionThrower();
194         } catch (Throwable e) {
195             assertTrue(e instanceof UnsupportedOperationException);
196             return;
197         }
198         fail("this point should never be reached");
199     }
200 
201     public void testThrowExceptionChecked() {
202         try {
203             ((Introductions) m_toBeIntroduced).exceptionThrowerChecked();
204         } catch (Throwable e) {
205             assertTrue(e instanceof Introductions.CheckedException);
206             return;
207         }
208         fail("this point should never be reached");
209     }
210 
211     // FIXME XXX implement mixin and comment out tests
212 
213 //    public void testReplaceImplementation() {
214 //        assertEquals("test.mixin.perinstance.IntroductionTestAspect$MyImpl", SystemLoader.getCflowStack(this)
215 //                .getAspectManager("tests").getMixin("test.mixin.perinstance.IntroductionTestAspect$MyImpl")
216 //                .getImplementationClassName());
217 //        assertEquals(1, ((Introductions) m_toBeIntroduced).intArg(1));
218 //
219 //        // swap with an inner class
220 //        SystemLoader.getCflowStack(this).getAspectManager("tests").getMixin(
221 //            "test.mixin.perinstance.IntroductionTestAspect$MyImpl").swapImplementation(
222 //            "test.mixin.perinstance.IntroductionTestAspect$MyOtherImpl");
223 //        assertEquals(-1, ((Introductions) m_toBeIntroduced).intArg(1));
224 //        assertEquals("test.mixin.perinstance.IntroductionTestAspect$MyOtherImpl", SystemLoader.getCflowStack(this)
225 //                .getAspectManager("tests").getMixin("test.mixin.perinstance.IntroductionTestAspect$MyImpl")
226 //                .getImplementationClassName());
227 //    }
228 //
229 //    public void testReplaceImplementationToAutonomousOne() {
230 //        assertEquals("test.mixin.perinstance.IntroductionTestAspect$MyOtherImpl", SystemLoader.getCflowStack(this)
231 //                .getAspectManager("tests").getMixin("test.mixin.perinstance.IntroductionTestAspect$MyImpl")
232 //                .getImplementationClassName());
233 //        assertEquals(-1, ((Introductions) m_toBeIntroduced).intArg(1));
234 //
235 //        // swap with an outer class
236 //        SystemLoader.getCflowStack(this).getAspectManager("tests").getMixin(
237 //            "test.mixin.perinstance.IntroductionTestAspect$MyImpl").swapImplementation(
238 //            "test.mixin.IntroductionTestAspectMyImplReplacement");
239 //        assertEquals(-2, ((Introductions) m_toBeIntroduced).intArg(1));
240 //        assertEquals("test.mixin.IntroductionTestAspectMyImplReplacement", SystemLoader.getCflowStack(
241 //            this).getAspectManager("tests").getMixin("test.mixin.perinstance.IntroductionTestAspect$MyImpl")
242 //                .getImplementationClassName());
243 //    }
244     public void testIntroductionUsingHasMethod() {
245         assertTrue(m_toBeIntroducedUsingHasMethod instanceof Cloneable);
246         assertTrue(m_toBeIntroducedUsingHasMethod instanceof Introductions);
247     }
248 
249     public void testIntroductionUsingHasField() {
250         assertTrue(m_toBeIntroducedUsingHasField instanceof Cloneable);
251         assertTrue(m_toBeIntroducedUsingHasField instanceof Introductions);
252     }
253 
254     public static void main(String[] args) {
255         junit.textui.TestRunner.run(suite());
256     }
257 
258     public static junit.framework.Test suite() {
259         //TODO: on IBM JRE, test method order is changed, and thus mixin replacement is done first
260         // leading to some test
261         // failure.
262         return new junit.framework.TestSuite(IntroductionTest.class);
263     }
264 }