1 /************************************************************************* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * Copyright 2000, 2010 Oracle and/or its affiliates. 5 * 6 * OpenOffice.org - a multi-platform office productivity suite 7 * 8 * This file is part of OpenOffice.org. 9 * 10 * OpenOffice.org is free software: you can redistribute it and/or modify 11 * it under the terms of the GNU Lesser General Public License version 3 12 * only, as published by the Free Software Foundation. 13 * 14 * OpenOffice.org is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU Lesser General Public License version 3 for more details 18 * (a copy is included in the LICENSE file that accompanied this code). 19 * 20 * You should have received a copy of the GNU Lesser General Public License 21 * version 3 along with OpenOffice.org. If not, see 22 * <http://www.openoffice.org/license.html> 23 * for a copy of the LGPLv3 License. 24 * 25 *************************************************************************/ 26 27 package complex.toolkit; 28 29 import java.lang.reflect.InvocationTargetException; 30 import java.lang.reflect.Method; 31 import com.sun.star.uno.UnoRuntime; 32 import static org.junit.Assert.*; 33 34 /** 35 * provides assertion capabilities not found in {@link org.junit.Assert} 36 * @author frank.schoenheit@oracle.com 37 */ 38 public class Assert 39 { 40 // -------------------------------------------------------------------------------------------------------- 41 /** invokes a given method on a given object, and assures a certain exception is caught 42 * @param i_message 43 * is the message to print when the check fails 44 * @param i_object 45 * is the object to invoke the method on 46 * @param i_methodName 47 * is the name of the method to invoke 48 * @param i_methodArgs 49 * are the arguments to pass to the method. 50 * @param i_argClasses 51 * are the classes to assume for the arguments of the methods 52 * @param i_expectedExceptionClass 53 * is the class of the exception to be caught. If this is null, 54 * it means that <em>no</em> exception must be throw by invoking the method. 55 */ 56 public static void assertException( final String i_message, final Object i_object, final String i_methodName, 57 final Class[] i_argClasses, final Object[] i_methodArgs, final Class i_expectedExceptionClass ) 58 { 59 Class objectClass = i_object.getClass(); 60 61 boolean noExceptionAllowed = ( i_expectedExceptionClass == null ); 62 63 boolean caughtExpected = noExceptionAllowed ? true : false; 64 try 65 { 66 Method method = impl_getMethod( objectClass, i_methodName, i_argClasses ); 67 method.invoke(i_object, i_methodArgs ); 68 } 69 catch ( NoSuchMethodException e ) 70 { 71 StringBuilder message = new StringBuilder(); 72 message.append( "no such method: " ).append( objectClass.getName() ).append( "." ).append( i_methodName ).append( "( " ); 73 for ( int i=0; i<i_argClasses.length; ++i ) 74 { 75 message.append( i_argClasses[i].getName() ); 76 if ( i<i_argClasses.length - 1 ) 77 message.append( ", " ); 78 } 79 message.append( " )" ); 80 fail( message.toString() ); 81 } 82 catch ( InvocationTargetException e ) 83 { 84 caughtExpected = noExceptionAllowed 85 ? false 86 : ( e.getTargetException().getClass().equals( i_expectedExceptionClass ) ); 87 } 88 catch( Exception e ) 89 { 90 caughtExpected = false; 91 } 92 93 assertTrue( i_message, caughtExpected ); 94 } 95 96 /** 97 * retrieves a method, given by name and parameter signature, from the given class 98 * 99 * The method does somewhat more than simply calling {@link Class.getMethod}. In particular, it recognizes 100 * primitiive parameter types, and attempts to find a method taking the given primitive type, instead of the 101 * type represented by the parameter class. 102 * 103 * For instance, if you have a method <code>foo( int )</code>, {@link Class.getMethod} would not return this 104 * method when you pass <code>Integer.class</code>. <code>impl_getMethod</code> will recognize this, and 105 * properly retrieve the method. 106 * 107 * Note: <code>impl_getMethod</code> is limited in that it will not try all possible combinations of primitive 108 * and non-primitive types. That is, a method like <code>foo( int, Integer, int )</code> is likely to not be 109 * found. 110 * 111 * @param i_obbjectClass 112 * @param i_methodName 113 * @param i_argClasses 114 * @return 115 */ 116 private static Method impl_getMethod( final Class i_objectClass, final String i_methodName, final Class[] i_argClasses ) throws NoSuchMethodException 117 { 118 try 119 { 120 return i_objectClass.getMethod( i_methodName, i_argClasses ); 121 } 122 catch ( NoSuchMethodException ex ) 123 { 124 } 125 126 int substitutedTypes = 0; 127 int substitutedTypesLastRound = 0; 128 final Class[][] substitutionTable = new Class[][] { 129 new Class[] { Long.class, long.class }, 130 new Class[] { Integer.class, int.class }, 131 new Class[] { Short.class, short.class }, 132 new Class[] { Byte.class, byte.class }, 133 new Class[] { Double.class, double.class }, 134 new Class[] { Float.class, float.class }, 135 new Class[] { Character.class, char.class } 136 }; 137 do 138 { 139 substitutedTypes = 0; 140 final Class[] argClasses = new Class[ i_argClasses.length ]; 141 for ( int i=0; i < argClasses.length; ++i ) 142 { 143 argClasses[i] = i_argClasses[i]; 144 if ( substitutedTypes > substitutedTypesLastRound ) 145 continue; 146 147 for ( int c=0; c<substitutionTable.length; ++c ) 148 { 149 if ( i_argClasses[i].equals( substitutionTable[c][0] ) ) 150 { 151 argClasses[i] = substitutionTable[c][1]; 152 ++substitutedTypes; 153 break; 154 } 155 } 156 } 157 if ( substitutedTypes == substitutedTypesLastRound ) 158 throw new NoSuchMethodException(); 159 substitutedTypesLastRound = substitutedTypes; 160 161 try 162 { 163 return i_objectClass.getMethod( i_methodName, argClasses ); 164 } 165 catch ( NoSuchMethodException e ) 166 { 167 } 168 } 169 while ( substitutedTypes > 0 ); 170 throw new NoSuchMethodException(); 171 } 172 173 /** invokes a given method on a given object, and assures a certain exception is caught 174 * @param i_message is the message to print when the check fails 175 * @param i_object is the object to invoke the method on 176 * @param i_methodName is the name of the method to invoke 177 * @param i_methodArgs are the arguments to pass to the method. Those implicitly define 178 * the classes of the arguments of the method which is called. 179 * @param i_expectedExceptionClass is the class of the exception to be caught. If this is null, 180 * it means that <em>no</em> exception must be throw by invoking the method. 181 */ 182 public static void assertException( final String i_message, final Object i_object, final String i_methodName, 183 final Object[] i_methodArgs, final Class i_expectedExceptionClass ) 184 { 185 Class[] argClasses = new Class[ i_methodArgs.length ]; 186 for ( int i=0; i<i_methodArgs.length; ++i ) 187 argClasses[i] = i_methodArgs[i].getClass(); 188 assertException( i_message, i_object, i_methodName, argClasses, i_methodArgs, i_expectedExceptionClass ); 189 } 190 191 /** invokes a given method on a given object, and assures a certain exception is caught 192 * @param i_object is the object to invoke the method on 193 * @param i_methodName is the name of the method to invoke 194 * @param i_methodArgs are the arguments to pass to the method. Those implicitly define 195 * the classes of the arguments of the method which is called. 196 * @param i_expectedExceptionClass is the class of the exception to be caught. If this is null, 197 * it means that <em>no</em> exception must be throw by invoking the method. 198 */ 199 public static void assertException( final Object i_object, final String i_methodName, final Object[] i_methodArgs, 200 final Class i_expectedExceptionClass ) 201 { 202 assertException( 203 "did not catch the expected exception (" + 204 ( ( i_expectedExceptionClass == null ) ? "none" : i_expectedExceptionClass.getName() ) + 205 ") while calling " + i_object.getClass().getName() + "." + i_methodName, 206 i_object, i_methodName, i_methodArgs, i_expectedExceptionClass ); 207 } 208 209 /** invokes a given method on a given object, and assures a certain exception is caught 210 * @param i_object is the object to invoke the method on 211 * @param i_methodName is the name of the method to invoke 212 * @param i_methodArgs are the arguments to pass to the method 213 * @param i_argClasses are the classes to assume for the arguments of the methods 214 * @param i_expectedExceptionClass is the class of the exception to be caught. If this is null, 215 * it means that <em>no</em> exception must be throw by invoking the method. 216 */ 217 public static void assertException( final Object i_object, final String i_methodName, final Class[] i_argClasses, 218 final Object[] i_methodArgs, final Class i_expectedExceptionClass ) 219 { 220 assertException( 221 "did not catch the expected exception (" + 222 ( ( i_expectedExceptionClass == null ) ? "none" : i_expectedExceptionClass.getName() ) + 223 ") while calling " + i_object.getClass().getName() + "." + i_methodName, 224 i_object, i_methodName, i_argClasses, i_methodArgs, i_expectedExceptionClass ); 225 } 226 227 // -------------------------------------------------------------------------------------------------------- 228 public static void assertException( Object i_object, Class _unoInterfaceClass, String i_methodName, Object[] i_methodArgs, 229 Class i_expectedExceptionClass ) 230 { 231 assertException( UnoRuntime.queryInterface( _unoInterfaceClass, i_object ), i_methodName, 232 i_methodArgs, i_expectedExceptionClass ); 233 } 234 } 235