/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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 lib; import java.io.PrintWriter; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Vector; import com.sun.star.uno.UnoRuntime; import com.sun.star.uno.XInterface; import share.DescEntry; import lib.TestParameters; import stats.Summarizer; /** * The class supports method based interface tests development. * *
There are some points that should be fulfilled in a subclass to work
* correctly in the multi-method framework:
*
* 1. each subclass should define a public field named oObj of type tested
* by the subclass, e.g. 'public XText oObj;'. That field will be initialized
* by the MultiMethodTest code with the instance of the interface to test.
* In a case of service testing the field type should be XPropertySet.
*
* 2. for the test of each method of the tested interface(or a property in the
* case of service testing) should be method with the following signature
* provided: 'public void _method
is optional in the service.
*/
protected boolean isOptional(String _method)
{
for (int k = 0; k < entry.SubEntryCount; k++)
{
final String sName = entry.SubEntries[k].entryName;
if (sName.equals(_method))
{
final boolean bIsOptional = entry.SubEntries[k].isOptional;
return bIsOptional;
}
}
return false;
}
/**
* Checks if the method
test has been already called.
*/
protected boolean isCalled(String method)
{
return methCalled.contains(method);
}
/**
* Calling of the method indicates that the method
test should
* be called. The method checks this and if it is not called, calls it.
* If the method is failed or skipped, it throws StatusException.
*/
protected void requiredMethod(String method)
{
log.println("starting required method: " + method);
executeMethod(method);
Status mtStatus = tRes.getStatusFor(method);
if (mtStatus != null && (!mtStatus.isPassed() || mtStatus.isFailed()))
{
log.println("! Required method " + method + " failed");
throw new StatusException(mtStatus);
}
}
/**
* Checks if the method
was called, and if not, call it.
* On contrary to requiredMethod(), he method doesn't check its status.
*/
protected void executeMethod(String method)
{
if (!isCalled(method))
{
log.println("Execute: " + method);
callMethod(method);
log.println(method + ": " + tRes.getStatusFor(method));
log.println();
}
}
/**
* Just calls the method
test.
*/
protected void callMethod(String method)
{
methCalled.add(method);
invokeTestMethod(getMethodFor(method), method);
}
/**
* Invokes a test method of the subclass using reflection API. Handles
* the method results and sets its status.
*
* @param meth the subclass' method to invoke
* @param methName the name of the method
*/
protected void invokeTestMethod(Method meth, String methName)
{
if (meth == null)
{
setStatus(methName, Status.skipped(false));
}
else
{
Status stat;
try
{
meth.invoke(this, new Object[0]);
return;
}
catch (InvocationTargetException itE)
{
Throwable t = itE.getTargetException();
if (t instanceof StatusException)
{
stat = ((StatusException) t).getStatus();
}
else
{
t.printStackTrace(log);
stat = Status.exception(t);
}
}
catch (IllegalAccessException iaE)
{
iaE.printStackTrace(log);
stat = Status.exception(iaE);
}
catch (IllegalArgumentException iaE)
{
iaE.printStackTrace(log);
stat = Status.exception(iaE);
}
catch (ClassCastException ccE)
{
ccE.printStackTrace(log);
stat = Status.exception(ccE);
}
setStatus(methName, stat);
}
}
/**
* Finds a testing method for the method
of the interface.
*
* @return the testing method, if found, null otherwise
*/
protected Method getMethodFor(String method)
{
String mName = "_" + method;
if (mName.endsWith("()"))
{
mName = mName.substring(0, mName.length() - 2);
}
final Class[] paramTypes = new Class[0];
try
{
return this.getClass().getDeclaredMethod(mName, paramTypes);
}
catch (NoSuchMethodException nsmE)
{
return null;
}
}
/**
* @return the name of the interface tested
*/
public String getInterfaceName()
{
String clName = this.getClass().getName();
return clName.substring(clName.lastIndexOf('.') + 1);
}
/**
* Initializes fieldName
of the subclass with
* value
.
*
* @return Status describing the result of the operation.
*/
protected Status setField(String fieldName, Object value)
{
Field objField;
try
{
objField = this.getClass().getField(fieldName);
}
catch (NoSuchFieldException nsfE)
{
return Status.exception(nsfE);
}
try
{
objField.set(this, value);
return Status.passed(true);
}
catch (IllegalArgumentException iaE)
{
return Status.exception(iaE);
}
catch (IllegalAccessException iaE)
{
return Status.exception(iaE);
}
}
}