From 5f290ea3ddb9f8e4df2fbbcc4a3314d48f6b10c8 Mon Sep 17 00:00:00 2001 From: wisberg Date: Thu, 27 Jan 2005 06:05:13 +0000 Subject: [PATCH] refactoring, reformatting; support for generated test classes (latter not checked in) --- .../testsrc/TestingDriversModuleTests.java | 3 + .../testing/drivers/AjctestsAdapter.java | 270 ++++++++++++++---- .../testing/drivers/HarnessJUnitUtil.java | 58 +++- 3 files changed, 263 insertions(+), 68 deletions(-) diff --git a/testing-drivers/testsrc/TestingDriversModuleTests.java b/testing-drivers/testsrc/TestingDriversModuleTests.java index 55254beb2..f834a2b8f 100644 --- a/testing-drivers/testsrc/TestingDriversModuleTests.java +++ b/testing-drivers/testsrc/TestingDriversModuleTests.java @@ -19,6 +19,9 @@ import org.aspectj.testing.drivers.DriversTests; import junit.framework.*; import junit.framework.Test; +/** + * TODO weaver dumping ajcore files when using this interface + */ public class TestingDriversModuleTests extends TestCase { public static Test suite() { diff --git a/testing-drivers/testsrc/org/aspectj/testing/drivers/AjctestsAdapter.java b/testing-drivers/testsrc/org/aspectj/testing/drivers/AjctestsAdapter.java index dca57adf3..af326dbfa 100644 --- a/testing-drivers/testsrc/org/aspectj/testing/drivers/AjctestsAdapter.java +++ b/testing-drivers/testsrc/org/aspectj/testing/drivers/AjctestsAdapter.java @@ -12,42 +12,51 @@ package org.aspectj.testing.drivers; -import java.io.*; -import java.util.*; +import java.io.File; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; -import junit.framework.*; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestResult; +import junit.framework.TestSuite; -import org.aspectj.bridge.*; -import org.aspectj.testing.harness.bridge.*; -import org.aspectj.testing.run.*; -//import org.aspectj.testing.util.RunUtils; -//import org.aspectj.testing.xml.AjcSpecXmlReader; +import org.aspectj.bridge.IMessage; +import org.aspectj.bridge.IMessageHolder; +import org.aspectj.bridge.MessageHandler; +import org.aspectj.bridge.MessageUtil; +import org.aspectj.testing.harness.bridge.AjcTest; +import org.aspectj.testing.harness.bridge.RunSpecIterator; +import org.aspectj.testing.harness.bridge.Sandbox; +import org.aspectj.testing.harness.bridge.Validator; +import org.aspectj.testing.run.IRunIterator; +import org.aspectj.testing.run.RunStatus; +import org.aspectj.testing.run.Runner; /* - * Adapt Harness tests to JUnit driver. - * This renders suite files as TestSuite - * and AjcTest as TestCase. - * When run, aborts are reported as error - * and fails as failures, with all messages stuffed - * into the one JUnit exception message. - * Test options are supported, but no harness options. - * The TestSuite implementation prevents us - * from re-running tests. - * In the Eclipse JUnit test runner, - * the tests display hierarchically and with annotations - * and with messages. You can stop the tests, but not - * traverse to the source or re-run the test. + * Adapt Harness tests to JUnit driver. This renders suite files as TestSuite + * and AjcTest as TestCase. When run, aborts are reported as error and fails as + * failures, with all messages stuffed into the one JUnit exception message. + * Test options are supported, but no harness options. The TestSuite + * implementation prevents us from re-running tests. In the Eclipse JUnit test + * runner, the tests display hierarchically and with annotations and with + * messages. You can stop the tests, but not traverse to the source or re-run + * the test. */ public class AjctestsAdapter extends TestSuite { - public static final String VERBOSE_NAME = - AjctestsAdapter.class.getName() + ".VERBOSE"; - - private static final boolean VERBOSE - = HarnessJUnitUtil.readBooleanSystemProperty(VERBOSE_NAME); - + public static final String VERBOSE_NAME = AjctestsAdapter.class.getName() + + ".VERBOSE"; + + private static final boolean VERBOSE = HarnessJUnitUtil + .readBooleanSystemProperty(VERBOSE_NAME); + /** * Factory to make and populate suite without options. - * @param suitePath the String path to a harness suite file + * + * @param suitePath + * the String path to a harness suite file * @return AjctestJUnitSuite populated with tests */ public static AjctestsAdapter make(String suitePath) { @@ -56,8 +65,11 @@ public class AjctestsAdapter extends TestSuite { /** * Factory to make and populate suite - * @param suitePath the String path to a harness suite file - * @param options the String[] options to use when creating tests + * + * @param suitePath + * the String path to a harness suite file + * @param options + * the String[] options to use when creating tests * @return AjctestJUnitSuite populated with tests */ public static AjctestsAdapter make(String suitePath, String[] options) { @@ -79,16 +91,24 @@ public class AjctestsAdapter extends TestSuite { } private final String suitePath; + private final String[] options; + private AjcTest.Suite.Spec spec; + private Runner runner; + private Validator validator; + private IMessageHolder holder; + private Sandbox sandbox; + private File suiteDir; + private String name; - private AjctestsAdapter(String suitePath, String[] options) { + private AjctestsAdapter(String suitePath, String[] options) { this.suitePath = suitePath; String[] opts = new String[0]; if (!HarnessJUnitUtil.isEmpty(options)) { @@ -99,11 +119,10 @@ public class AjctestsAdapter extends TestSuite { } public void addTest(Test test) { - if (! (test instanceof AjcTestSpecAsTest)) { + if (!(test instanceof AjcTestSpecAsTest)) { String m = "expecting AjcTestSpecAsTest, got " - + (null == test - ? "null test" - : test.getClass().getName() + ": " + test); + + (null == test ? "null test" : test.getClass().getName() + + ": " + test); throw new IllegalArgumentException(m); } super.addTest(test); @@ -112,20 +131,23 @@ public class AjctestsAdapter extends TestSuite { public void addTestSuite(Class testClass) { throw new Error("unimplemented"); } - + public String getName() { if (null == name) { - name = HarnessJUnitUtil.cleanTestName(suitePath + Arrays.asList(options)); + name = HarnessJUnitUtil.cleanTestName(suitePath + + Arrays.asList(options)); } return name; } - + /** - * Callback from test to run it using suite-wide holder, etc. - * The caller is responsible for calling - * result.startTest(test) and result.endTest(test); - * @param test the AjcTestSpecAsTest to run - * @param result the TestResult for any result messages + * Callback from test to run it using suite-wide holder, etc. The caller is + * responsible for calling result.startTest(test) and result.endTest(test); + * + * @param test + * the AjcTestSpecAsTest to run + * @param result + * the TestResult for any result messages (may be null) */ protected void runTest(AjcTestSpecAsTest test, TestResult result) { final Runner runner = getRunner(); @@ -139,7 +161,8 @@ public class AjctestsAdapter extends TestSuite { holder.clearMessages(); IRunIterator steps = test.spec.makeRunIterator(sandbox, validator); if (0 < holder.numMessages(IMessage.ERROR, true)) { - MessageUtil.handleAll(status, holder, IMessage.INFO, true, false); + MessageUtil.handleAll(status, holder, IMessage.INFO, true, + false); } else { runner.runIterator(steps, status, null); } @@ -147,8 +170,13 @@ public class AjctestsAdapter extends TestSuite { numIncomplete = ((RunSpecIterator) steps).getNumIncomplete(); } } finally { - HarnessJUnitUtil.reportResult(result, status, test, numIncomplete); - validator.deleteTempFiles(true); + try { + // reportResult handles null TestResult + HarnessJUnitUtil + .reportResult(null, status, test, numIncomplete); + } finally { + validator.deleteTempFiles(true); + } } } @@ -189,16 +217,17 @@ public class AjctestsAdapter extends TestSuite { private AjcTest.Suite.Spec getSpec() { if (null == spec) { IMessageHolder holder = getHolder(); - spec = HarnessJUnitUtil.getSuiteSpec(suitePath, options, getHolder()); + spec = HarnessJUnitUtil.getSuiteSpec(suitePath, options, + getHolder()); if (VERBOSE && holder.hasAnyMessage(null, true)) { - MessageUtil.print(System.err, holder, "skip ", - MessageUtil.MESSAGE_MOST); + MessageUtil.print(System.err, holder, "skip ", + MessageUtil.MESSAGE_MOST); } holder.clearMessages(); } - return spec; + return spec; } - + private Sandbox getSandbox() { if (null == sandbox) { sandbox = new Sandbox(spec.getSuiteDirFile(), getValidator()); @@ -206,13 +235,138 @@ public class AjctestsAdapter extends TestSuite { return sandbox; } + /** + * Wrap AjcTest.Spec for lookup by description + * + * @author wes + */ + public static class SpecTests { + private static final HashMap TESTS = new HashMap(); + + private static void putSpecTestsFor(String id, SpecTests tests) { + TESTS.put(id, tests); + } + + private static SpecTests getSpecTestsFor(String id) { + SpecTests result = (SpecTests) TESTS.get(id); + if (null == result) { + throw new Error("no tests found for " + id); + } + return result; + } + + private static String safeName(String name) { + return HarnessJUnitUtil.cleanTestName(name); + } + + private static String filename(String path) { + if (null == path) { + throw new IllegalArgumentException("null path"); + } + int loc = path.lastIndexOf(File.pathSeparator); + if (-1 != loc) { + path = path.substring(loc+1); + } + loc = path.lastIndexOf('/'); + if (-1 != loc) { + path = path.substring(loc+1); + } + loc = path.lastIndexOf("."); + if (-1 != loc) { + path = path.substring(0, loc); + } + return path; + } + + private static String classnameToPath(String classname) { + return classname.replace('.', File.separatorChar) + ".class"; + } + + + // ------------------------------------ + final AjctestsAdapter mAjctestsAdapter; + + private final Map mDescriptionToAjcTestSpec; + + // ------------------------------------ + private SpecTests(AjctestsAdapter ajctestsAdapter, AjcTest.Spec[] tests) { + mAjctestsAdapter = ajctestsAdapter; + Map map = new HashMap(); + for (int i = 0; i < tests.length; i++) { + map.put(tests[i].getDescription(), tests[i]); + } + ; + mDescriptionToAjcTestSpec = Collections.unmodifiableMap(map); + } + + /** + * @param description + * the String description of the test + * @throws IllegalArgumentException + * if testName is not found + */ + protected void runTest(String description) { + AjcTest.Spec spec = getSpec(description); + AjctestsAdapter.AjcTestSpecAsTest ajcTestAsSpec = new AjctestsAdapter.AjcTestSpecAsTest( + spec, mAjctestsAdapter); + // runTest handles null TestResult + mAjctestsAdapter.runTest(ajcTestAsSpec, null); + } + + /** + * @param description + * the String description of the test + * @throws IllegalArgumentException + * if testName is not found + */ + private AjcTest.Spec getSpec(String description) { + AjcTest.Spec spec = (AjcTest.Spec) mDescriptionToAjcTestSpec + .get(description); + if (null == spec) { + throw new IllegalArgumentException("no test for " + description); + } + return spec; + } + + /** + * makeUsingTestClass(..) extends this to create TestCase with + * test_{name} for each test case. + */ + public static class TestClass extends TestCase { + public TestClass() { + } + private SpecTests mTests; + + /** + * Called by code generated in makeUsingTestClass(..) + * + * @param description + * the String identifier of the test stored in SpecTests + * mTests. + * @throws Error + * on first and later uses if getTestsFor() returns + * null. + */ + public final void runTest(String description) { + if (null == mTests) { + String classname = getClass().getName(); + mTests = getSpecTestsFor(classname); + } + mTests.runTest(description); + } + } + } + /** Wrap AjcTest.Spec as a TestCase. Run by delegation to suite */ - private static class AjcTestSpecAsTest extends TestCase - implements HarnessJUnitUtil.IHasAjcSpec { - // this could implement Test, but Ant batchtest fails to pull name + private static class AjcTestSpecAsTest extends TestCase implements + HarnessJUnitUtil.IHasAjcSpec { + // this could implement Test, but Ant batchtest fails to pull name final String name; + final AjcTest.Spec spec; + AjctestsAdapter suite; + AjcTestSpecAsTest(AjcTest.Spec spec, AjctestsAdapter suite) { super(HarnessJUnitUtil.cleanTestName(spec.getDescription())); this.name = HarnessJUnitUtil.cleanTestName(spec.getDescription()); @@ -220,19 +374,22 @@ public class AjctestsAdapter extends TestSuite { this.spec = spec; spec.setSuiteDir(suite.getSuiteDir()); } + public int countTestCases() { return 1; } + public AjcTest.Spec getAjcTestSpec() { return spec; } + public void run(TestResult result) { if (null == suite) { throw new Error("need to re-init"); } try { result.startTest(this); - suite.runTest(this, result); + suite.runTest(this, result); } finally { result.endTest(this); suite = null; @@ -242,8 +399,9 @@ public class AjctestsAdapter extends TestSuite { public String getName() { return name; } + public String toString() { return name; } } -} +} \ No newline at end of file diff --git a/testing-drivers/testsrc/org/aspectj/testing/drivers/HarnessJUnitUtil.java b/testing-drivers/testsrc/org/aspectj/testing/drivers/HarnessJUnitUtil.java index 84e9d7d91..dded8196a 100644 --- a/testing-drivers/testsrc/org/aspectj/testing/drivers/HarnessJUnitUtil.java +++ b/testing-drivers/testsrc/org/aspectj/testing/drivers/HarnessJUnitUtil.java @@ -112,24 +112,50 @@ public class HarnessJUnitUtil { if (status.runResult()) { if (expectFail) { String m = "did not fail as expected per expect-fail keyword"; - AssertionFailedError failure = new AssertionFailedError(m); - result.addFailure(test, failure); + reportResultToJUnit(m, false, true, test, result); } } else if (!expectFail) { final boolean includeChildren = true; if (status.hasAnyMessage(IMessage.FAIL, false, includeChildren)) { String m = render(status, null); - AssertionFailedError failure = new AssertionFailedError(m); - result.addFailure(test, failure); + reportResultToJUnit(m, false, true, test, result); } else if (status.hasAnyMessage(IMessage.ERROR, true, includeChildren)) { String m = render(status, null); - AssertionFailedError failure = new AssertionFailedError(m); - result.addError(test, failure); + reportResultToJUnit(m, true, false, test, result); } // /XXX skip INFO, DEBUG } return 0; // XXX not doing incomplete } + /** + * Report results as error, failure, or success (ignored), + * differently if result is null + * @param description the String description of the result + * @param isError if true, report as failure + * @param isFailure if true and not isError, report as failure + * @param test the Test case + * @param result the TestResult sink - ignored if null + * @return 0 + */ + private static int reportResultToJUnit(String description, boolean isError, boolean isFailure, Test test, TestResult result) { + if (null != result) { + if (isError) { + result.addError(test, new AssertionFailedError(description)); + } else if (isFailure) { + result.addFailure(test, new AssertionFailedError(description)); + } // no need to log success + } else { // have to throw failure + if (isError) { + String m = safeTestName(test) + " " + description; + throw new Error(m); + } else if (isFailure) { + String m = safeTestName(test) + " " + description; + throw new AssertionFailedError(description); + } // no need to log success + } + return 0; + } + // public static int reportResultComplex( // TestResult result, // IRunStatus status, @@ -186,6 +212,19 @@ public class HarnessJUnitUtil { // return errs; // } + /** + * @return TestCase.getName() or Test.toString() or "nullTest" + */ + public static String safeTestName(Test test) { + if (test instanceof TestCase) { + return ((TestCase) test).getName(); + } else if (null != test) { + return test.toString(); + } else { + return "nullTest"; + } + } + /** * Fix up test names for JUnit. * (i.e., workaround eclipse JUnit bugs) @@ -203,12 +242,7 @@ public class HarnessJUnitUtil { public static boolean readBooleanSystemProperty(String name) { boolean result = false; try { - String value = System.getProperty(name); - if (null != value) { - // XXX convert using Boolean? - value = value.toLowerCase(); - result = ("true".equals(value) || "on".equals(value)); - } + result = Boolean.getBoolean(name); } catch (Throwable t) { // ignore } -- 2.39.5