/* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * 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 .
*/ package lib;
/** * The class supports method based interface tests development. * * <p>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 name>()', e.g. 'public void _getText()'. * The methods will be called by MultiMethodText code using reflection API * for each method in the interface description. * * 3. to set status for a call 'tRes.tested(String method, * boolean result)' should be used. For example 'tRes.tested("getText()", * true)'. Also 'tRes.assert(String assertion, boolean result)' call can * be used. Note, that one can call the methods not necessarily from the * test for the tested method, but from other method tests too (in the * MultiMethodTest subclass). See also TestResult and MultiMethodTest.tRes * documentation. * * 4. the before() and after() methods can be overridden to perform some * actions, accordingly, before and after calling the test methods. * * 5. besides tRes, there are some fields initialized in the MultiMethodTest, * that can be used for implementing tests: * * - tEnv contains the environment tested * - tParam contains parameters of the test * - log a writer to log information about the test * * @see TestResult
*/
@SuppressWarnings("unused") publicclass MultiMethodTest
{
/** * Contains the TestEnvironment being tested, to allow for tests to access * it.
*/ protected TestEnvironment tEnv; /** * Contains the TestParameters for the tests, to allow for tests to access * it.
*/ protected TestParameters tParam; /** * Contains the Description for the test * it.
*/ protected DescEntry entry; /** * Contains a writer to log an information about the interface testing, to * allows for tests to access it.
*/ protected PrintWriter log; /** * Contains the TestResult instance for the interface test to collect * information about methods test.
*/ protected TestResult tRes; /** * Contains names of the methods have been already called
*/ privatefinal ArrayList<String> methCalled = new ArrayList<String>(10);
/** * Disposes the current test environment, which was corrupted by the test. * * @see #disposeEnvironment(TestEnvironment)
*/ publicvoid disposeEnvironment()
{
tEnv.dispose();
TestCase tCase = tEnv.getTestCase();
tCase.disposeTestEnvironment(tEnv, tParam);
}
/** * Runs the interface test: its method tests. First, it initializes some * of MultiMethodTest fields, like tRes, log, tEnv, etc. Then, it queries * the tested interface and initializes 'oObj' field (defined in a * subclass). Before calling method tests, before() method is called to allow * initialization of s stuff before testing. Then, the method tests are * called. After them, after() method is called, to allow cleaning up the * stuff initialized in before() and test methods. * * @param entry the interface test state * @param tEnv the environment to test * @param tParam the parameters of the test * * @see #before * @see #after
*/ public TestResult run(DescEntry entry, TestEnvironment tEnv, TestParameters tParam)
{
if (oObj == null)
{ if (entry.isOptional)
{
Summarizer.summarizeDown(entry, "Not supported but optional.OK");
} else
{
Summarizer.summarizeDown(entry, "queryInterface returned null.FAILED");
entry.ErrorMsg = "queryInterface returned null";
entry.hasErrorMsg = true;
}
returnnull;
}
//setting the field oObj try
{
setField("oObj", oObj);
} catch (Exception e)
{
e.printStackTrace();
setSubStates(e.toString()); return tRes;
}
// to perform some stuff before all method tests try
{
before();
} catch (Exception e)
{
e.printStackTrace();
setSubStates(e.toString()); return tRes;
}
// executing methods tests for (int i = 0; i < entry.SubEntryCount; i++)
{
DescEntry aSubEntry = entry.SubEntries[i]; try
{ final String sEntryName = aSubEntry.entryName;
executeMethod(sEntryName);
} catch (Exception e)
{
log.println("Exception while checking: " + aSubEntry.entryName + " : " + e.getMessage());
}
}
// to perform some stuff after all method tests try
{
after();
} catch (Exception e)
{
}
return tRes;
}
/** * Is called before calling method tests, but after initialization. * Subclasses may override to perform actions before method tests.
*/ protectedvoid before() throws Exception
{
}
/** * Is called after calling method tests. Subclasses may override * to perform actions after method tests.
*/ protectedvoid after()
{
}
/** * @return the name of the interface or the service tested.
*/ protected String getTestedClassName()
{
String clsName = this.getClass().getName();
int firstDot = clsName.indexOf('.'); int lastDot = clsName.lastIndexOf('.');
String append = "com.sun.star.";
if (entry.longName.indexOf("::drafts::com::") > -1)
{
append = "drafts.com.sun.star.";
}
/** * Sets a method status. * * @param methName the method name to set status * @param methStatus the status to set to the method
*/ privatevoid setStatus(String methName, Status methStatus)
{
tRes.tested(methName, methStatus);
}
/** * sets the substates
*/ privatevoid setSubStates(String msg)
{ for (int k = 0; k < entry.SubEntryCount; k++)
{
entry.SubEntries[k].hasErrorMsg = true;
entry.SubEntries[k].ErrorMsg = msg; if (entry.SubEntries[k].State.equals("UNKNOWN"))
{
entry.SubEntries[k].State = msg;
}
}
}
/** * Checks if the <code>method</code> is optional in the service.
*/ protectedboolean isOptional(String _method)
{ for (int k = 0; k < entry.SubEntryCount; k++)
{ final String sName = entry.SubEntries[k].entryName; if (sName.equals(_method))
{ finalboolean bIsOptional = entry.SubEntries[k].isOptional; return bIsOptional;
}
} returnfalse;
}
/** * Checks if the <code>method</code> test has been already called.
*/ privateboolean isCalled(String method)
{ return methCalled.contains(method);
}
/** * Calling of the method indicates that the <code>method</code> 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.
*/ protectedvoid requiredMethod(String method)
{
log.println("starting required method: " + method);
executeMethod(method);
Status mtStatus = tRes.getStatusFor(method);
/** * Checks if the <code>method</code> was called, and if not, call it. * On contrary to requiredMethod(), he method doesn't check its status.
*/ protectedvoid executeMethod(String method)
{ if (!isCalled(method))
{
log.println("Execute: " + method);
callMethod(method);
log.println(method + ": " + tRes.getStatusFor(method));
log.println();
}
}
/** * Just calls the <code>method</code> test.
*/ privatevoid 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
*/ protectedvoid 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 <code>method</code> of the interface. * * @return the testing method, if found, <tt>null</tt> otherwise
*/ private Method getMethodFor(String method)
{
String mName = "_" + method;
if (mName.endsWith("()"))
{
mName = mName.substring(0, mName.length() - 2);
}
/** * @return the name of the interface tested
*/ public String getInterfaceName()
{
String clName = this.getClass().getName(); return clName.substring(clName.lastIndexOf('.') + 1);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.