package org.aitools.programd.test.aiml; import java.io.IOException; import java.net.URL; import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import org.aitools.programd.Core; import org.aitools.util.runtime.DeveloperError; import org.aitools.util.xml.Characters; import org.aitools.util.xml.JDOM; import org.apache.log4j.Logger; import org.jdom.Document; import org.jdom.Element; import org.jdom.Namespace; /** * A TestSuite comprises a set of TestCases. * * @author Albertas Mickensas * @author Noel Bush <noel@aitools.org> */ public class TestSuite implements Iterable<TestCase> { /** The test suite namespace URI. */ public static final String TESTSUITE_NAMESPACE_URI = "http://aitools.org/xaiml/test-suite"; private static final Namespace TESTSUITE_NAMESPACE = Namespace.getNamespace("http://aitools.org/xaiml/test-suite"); /** * Loads a test suite from the given path. * * @param path the path from which to load the test suite * @param core the core to use * @param logger * @return the loaded test suite */ @SuppressWarnings("unchecked") public static TestSuite load(URL path, Core core, Logger logger) { Document document = JDOM.getDocument(path, core.getSettings().getXmlCatalogPath(), logger); String encoding; try { encoding = Characters.getDeclaredXMLEncoding(path); } catch (IOException e) { throw new DeveloperError("Could not get encoding of test suite file.", e); } Element testSuiteElement = document.getRootElement(); TestSuite suite = new TestSuite(testSuiteElement.getAttributeValue("name"), testSuiteElement.getAttributeValue("clearInput"), core, logger); int index = 0; for (Element testCaseElement : (List<Element>) testSuiteElement.getChildren(TestCase.TAG_TESTCASE, TESTSUITE_NAMESPACE)) { TestCase testCase = new TestCase(testCaseElement, encoding, index++, suite); suite.addTestCase(testCase); } return suite; } /** * Loads a test suite from the given path. * * @param path the path from which to load the test suite * @param logger * @return the loaded test suite */ public static TestSuite load(URL path, Logger logger) { return load(path, null, logger); } /** The test cases in this suite. */ ArrayList<TestCase> _testCases = new ArrayList<TestCase>(); /** The name of the test suite. */ private String _name; /** The clearInput to use for this test suite. */ private String _clearInput; /** The Core in use. */ private Core _core; /** The Logger. */ private Logger _logger; /** The test successes accumulated by this suite. */ private LinkedList<TestResult> successes = new LinkedList<TestResult>(); /** The test failures accumulated by this suite. */ private LinkedList<TestResult> failures = new LinkedList<TestResult>(); /** The userid to use for the tester. */ private static final String TESTER_ID = "ProgramD-Tester"; /** * Creates a new TestSuite (with no clearInput). * * @param name the name to give the test suite * @param core the multiplexor to use * @param logger */ public TestSuite(String name, Core core, Logger logger) { this._name = name; this._core = core; this._logger = logger; } /** * Creates a new TestSuite (with no clearInput or Multiplexor(!)). * * @param name the name to give the test suite * @param logger */ protected TestSuite(String name, Logger logger) { this._name = name; this._logger = logger; } /** * Creates a new TestSuite. * * @param name the name to give the test suite * @param clearInput the clearInput for the test suite * @param core the core to use * @param logger */ public TestSuite(String name, String clearInput, Core core, Logger logger) { this._name = name; this._clearInput = clearInput; this._core = core; this._logger = logger; } /** * Adds a test case to this suite. * * @param testCase the test case to add. */ public void addTestCase(TestCase testCase) { this._testCases.add(testCase); } /** * @return the failures accumulated by this suite */ public LinkedList<TestResult> getFailures() { return this.failures; } /** * @return the name of this suite */ public String getName() { return this._name; } /** * @return the successes accumulated by this suite */ public LinkedList<TestResult> getSuccesses() { return this.successes; } /** * @return the test cases in this suite */ public ArrayList<TestCase> getTestCases() { return this._testCases; } /** * @return an iterator over this suite's test cases * @see java.lang.Iterable#iterator() */ @Override public Iterator<TestCase> iterator() { return this._testCases.iterator(); } /** * Runs the test cases contained in this suite. * * @param botid the botid for whom to run the test cases * @return whether the test cases all passed successfully */ public boolean run(String botid) { if (this._clearInput != null && this._clearInput.length() > 0) { this._core.getResponse(this._clearInput, TESTER_ID, botid); } this.failures.clear(); boolean suiteSuccessful = true; for (TestCase testCase : this._testCases) { boolean caseSuccessful = testCase.run(this._core, TESTER_ID, botid); String testcaseName = testCase.getName(); if (!caseSuccessful) { this._logger.warn(String.format("Test case \"%s\" failed with response \"%s\".", testcaseName, Characters.removeMarkup(testCase.getLastResponse()))); this.failures.add(new TestResult(testCase)); } else { this._logger.info(String.format("Test case \"%s\" succeeded.", testcaseName)); this.successes.add(new TestResult(testCase)); } suiteSuccessful &= caseSuccessful; } return suiteSuccessful; } }