/* * Copyright 2010-2012 VMware and contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springsource.loaded.ri.test; import static org.springsource.loaded.ri.test.AbstractReflectionTests.newInstance; import static org.springsource.loaded.test.SpringLoadedTests.runOnInstance; import java.lang.reflect.Constructor; import org.junit.runner.RunWith; import org.springsource.loaded.test.infra.Result; import org.springsource.loaded.test.infra.ResultException; import org.springsource.loaded.testgen.ExploreAllChoicesRunner; import org.springsource.loaded.testgen.GenerativeSpringLoadedTest; import org.springsource.loaded.testgen.RejectedChoice; /** * Tests the following methods: * * Constructor.newInstance * * @author kdvolder */ @RunWith(ExploreAllChoicesRunner.class) public class ConstructorNewInstanceTest extends GenerativeSpringLoadedTest { // Needed to run the tests (non-changing parameters) private Class<?> callerClazz; private Object callerInstance; private Class<?> targetClass; //One class chosen to focus test on // Parameters that change for different test runs private boolean doSetAccess; //Should we call 'setAccessible'? private Constructor<?> member; //A constructor declared on this class private Object[] args; //List of arguments that should be passed to constructor private String testedMethodCaller; @Override protected String getTargetPackage() { return "reflection.constructors"; } @Override protected void chooseTestParameters() throws RejectedChoice, Exception { //We can test all of these methods, they have the same kinds of parameters. doSetAccess = choice(); if (doSetAccess) { toStringValue.append("setAccess "); } testedMethodCaller = "callNewInstance"; // toStringValue.append(testedMethodCaller+": "); targetClass = targetClass("ClassForNewInstance", choice("", "002")); member = targetConstructorFrom(targetClass); if (choice()) { // A regular kind of invoker callerClazz = loadClassVersion("reflection.ConstructorInvoker", ""); } else { // Also try an invoker that has special priviliges because... callerClazz = targetClass; // The caller is the class itself //TODO: other cases (subclass of the class, same package as the class). } toStringValue.append(" from " + callerClazz.getSimpleName()); if (generative) { callerInstance = callerClazz.newInstance(); // makes it easier to debug specific test case // because avoids driving "test generation" thorugh the ReflectiveInterceptor } else { callerInstance = newInstance(callerClazz); } args = chooseArgs(member.getParameterTypes()); } /** * Choose a number of arguments, to be passed to the selected constructor, based on that constructor's formal * parameters. * * @throws RejectedChoice */ private Object[] chooseArgs(Class<?>[] parameterTypes) throws RejectedChoice { if (parameterTypes.length == 0) { Object[] result = choice() ? null : new Object[0]; toStringValue.append(result == null ? "null" : "[]"); return result; } toStringValue.append("("); Object[] args = new Object[parameterTypes.length]; for (int i = 0; i < args.length; i++) { if (i > 0) { toStringValue.append(", "); } args[i] = chooseArg(parameterTypes[i]); toStringValue.append("" + args[i]); } toStringValue.append(")"); return args; } private Object chooseArg(Class<?> param) throws RejectedChoice { if (int.class == param) { return (int) (choice() ? 0 : 15); } else if (boolean.class == param) { return choice(); } else if (String.class == param) { return choice(null, "someString"); } else if (double.class == param) { return (double) 3.14; } else if (float.class == param) { return (float) 3.14; } else if (char.class == param) { return (char) 'A'; } throw new Error("Don't know how to provide parameter value for: " + param); } @Override public Result test() throws ResultException, Exception { if (doSetAccess) { member.setAccessible(true); } Result r = runOnInstance(callerClazz, callerInstance, testedMethodCaller, member, args); return r; } }