diff options
author | acolyer <acolyer> | 2004-08-04 12:02:07 +0000 |
---|---|---|
committer | acolyer <acolyer> | 2004-08-04 12:02:07 +0000 |
commit | 9a051d348a240095e56ead5485c2dba8cf6ad4a7 (patch) | |
tree | 5e8a37e15aa2a568737ca162707e2bcfede749dc /testing | |
parent | ef909dddd6b8728aba25dec9aee04d5e180d8662 (diff) | |
download | aspectj-9a051d348a240095e56ead5485c2dba8cf6ad4a7.tar.gz aspectj-9a051d348a240095e56ead5485c2dba8cf6ad4a7.zip |
XMLBasedAjcTestCase class and accompanying support. Drives a
junit test suite based on an ajcTests.xml format test specification.
Diffstat (limited to 'testing')
-rw-r--r-- | testing/.classpath | 38 | ||||
-rw-r--r-- | testing/newsrc/org/aspectj/testing/AjcTest.java | 120 | ||||
-rw-r--r-- | testing/newsrc/org/aspectj/testing/CompileSpec.java | 291 | ||||
-rw-r--r-- | testing/newsrc/org/aspectj/testing/ExpectedMessageSpec.java | 94 | ||||
-rw-r--r-- | testing/newsrc/org/aspectj/testing/ITestStep.java | 31 | ||||
-rw-r--r-- | testing/newsrc/org/aspectj/testing/MakeTestClass.java | 122 | ||||
-rw-r--r-- | testing/newsrc/org/aspectj/testing/RunSpec.java | 89 | ||||
-rw-r--r-- | testing/newsrc/org/aspectj/testing/XMLBasedAjcTestCase.java | 163 |
8 files changed, 930 insertions, 18 deletions
diff --git a/testing/.classpath b/testing/.classpath index 4d82f83dc..1eb23f6d6 100644 --- a/testing/.classpath +++ b/testing/.classpath @@ -1,21 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> <classpath> - <classpathentry kind="src" path="src"/> - <classpathentry kind="src" path="testsrc"/> - <classpathentry kind="var" path="JRE_LIB" sourcepath="JRE_SRC"/> - <classpathentry kind="lib" path="/lib/ant/lib/ant.jar" sourcepath="/lib/ant/ant-src.zip"/> - <classpathentry kind="lib" path="/lib/junit/junit.jar" sourcepath="/lib/junit/junit-src.jar"/> - <classpathentry kind="lib" path="/lib/jdiff/jdiff.jar"/> - <classpathentry kind="lib" path="/lib/regexp/jakarta-regexp-1.2.jar"/> - <classpathentry kind="src" path="/bridge"/> - <classpathentry kind="src" path="/util"/> - <classpathentry kind="src" path="/testing-client"/> - <classpathentry kind="lib" path="/lib/ant/lib/xercesImpl.jar"/> - <classpathentry kind="lib" path="/lib/ant/lib/xml-apis.jar"/> - <classpathentry kind="lib" path="/lib/commons/commons.jar" sourcepath="/lib/commons/commons-src.zip"/> - <classpathentry kind="src" path="/testing-util"/> - <classpathentry kind="src" path="/ajde"/> - <classpathentry kind="src" path="/asm"/> - <classpathentry kind="src" path="/taskdefs"/> - <classpathentry kind="output" path="bin"/> + <classpathentry kind="src" path="src"/> + <classpathentry kind="src" path="testsrc"/> + <classpathentry sourcepath="JRE_SRC" kind="var" path="JRE_LIB"/> + <classpathentry sourcepath="/lib/ant/ant-src.zip" kind="lib" path="/lib/ant/lib/ant.jar"/> + <classpathentry sourcepath="/lib/junit/junit-src.jar" kind="lib" path="/lib/junit/junit.jar"/> + <classpathentry kind="lib" path="/lib/jdiff/jdiff.jar"/> + <classpathentry kind="lib" path="/lib/regexp/jakarta-regexp-1.2.jar"/> + <classpathentry kind="src" path="/bridge"/> + <classpathentry kind="src" path="/util"/> + <classpathentry kind="src" path="/testing-client"/> + <classpathentry kind="lib" path="/lib/ant/lib/xercesImpl.jar"/> + <classpathentry kind="lib" path="/lib/ant/lib/xml-apis.jar"/> + <classpathentry sourcepath="/lib/commons/commons-src.zip" kind="lib" path="/lib/commons/commons.jar"/> + <classpathentry kind="src" path="/testing-util"/> + <classpathentry kind="src" path="/ajde"/> + <classpathentry kind="src" path="/asm"/> + <classpathentry kind="src" path="/taskdefs"/> + <classpathentry kind="src" path="newsrc"/> + <classpathentry kind="src" path="/org.aspectj.ajdt.core"/> + <classpathentry kind="output" path="bin"/> </classpath> diff --git a/testing/newsrc/org/aspectj/testing/AjcTest.java b/testing/newsrc/org/aspectj/testing/AjcTest.java new file mode 100644 index 000000000..923505fa2 --- /dev/null +++ b/testing/newsrc/org/aspectj/testing/AjcTest.java @@ -0,0 +1,120 @@ +/* ******************************************************************* + * Copyright (c) 2004 IBM Corporation + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Adrian Colyer, + * ******************************************************************/ +package org.aspectj.testing; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.aspectj.tools.ajc.AjcTestCase; + +/** + * @author colyer + * + * TODO To change the template for this generated type comment go to + * Window - Preferences - Java - Code Style - Code Templates + */ +public class AjcTest { + + private List testSteps = new ArrayList(); + + private String dir; + private String pr; + private String title; + private String keywords; + private String comment; + + public AjcTest() { + } + + public void addTestStep(ITestStep step) { + testSteps.add(step); + step.setTest(this); + } + + public void runTest(AjcTestCase testCase) { + try { + System.out.print("TEST: " + getTitle() + "\t"); + for (Iterator iter = testSteps.iterator(); iter.hasNext();) { + ITestStep step = (ITestStep) iter.next(); + step.setBaseDir(getDir()); + System.out.print("."); + step.execute(testCase); + } + } finally { + System.out.println("DONE"); + } + } + + /** + * @return Returns the comment. + */ + public String getComment() { + return comment; + } + /** + * @param comment The comment to set. + */ + public void setComment(String comment) { + this.comment = comment; + } + /** + * @return Returns the dir. + */ + public String getDir() { + return dir; + } + /** + * @param dir The dir to set. + */ + public void setDir(String dir) { + dir = "../tests/" + dir; + this.dir = dir; + } + /** + * @return Returns the keywords. + */ + public String getKeywords() { + return keywords; + } + /** + * @param keywords The keywords to set. + */ + public void setKeywords(String keywords) { + this.keywords = keywords; + } + /** + * @return Returns the pr. + */ + public String getPr() { + return pr; + } + /** + * @param pr The pr to set. + */ + public void setPr(String pr) { + this.pr = pr; + } + /** + * @return Returns the title. + */ + public String getTitle() { + return title; + } + /** + * @param title The title to set. + */ + public void setTitle(String title) { + this.title = title; + } + +} diff --git a/testing/newsrc/org/aspectj/testing/CompileSpec.java b/testing/newsrc/org/aspectj/testing/CompileSpec.java new file mode 100644 index 000000000..1dd29f412 --- /dev/null +++ b/testing/newsrc/org/aspectj/testing/CompileSpec.java @@ -0,0 +1,291 @@ +/* ******************************************************************* + * Copyright (c) 2004 IBM Corporation + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Adrian Colyer, + * ******************************************************************/ +package org.aspectj.testing; + +import java.io.File; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.StringTokenizer; + +import org.aspectj.tools.ajc.AjcTestCase; +import org.aspectj.tools.ajc.CompilationResult; + +/** + * @author colyer + * + * TODO To change the template for this generated type comment go to + * Window - Preferences - Java - Code Style - Code Templates + */ +public class CompileSpec implements ITestStep { + + private List expected = new ArrayList(); + + private String files; + private boolean includeClassesDir; + private String aspectpath; + private String classpath; + private String inpath; + private String sourceroots; + private String outjar; + private String xlintfile; + private String options; + private String baseDir; + private String extdirs; + private AjcTest myTest; + + public CompileSpec() { + } + + public void execute(AjcTestCase inTestCase) { + File base = new File(baseDir); + String[] args = buildArgs(); + CompilationResult result = inTestCase.ajc(base,args); + AjcTestCase.MessageSpec messageSpec = buildMessageSpec(); + String failMessage = "test \"" + myTest.getTitle() + "\" failed"; + inTestCase.assertMessages(result,failMessage,messageSpec); + inTestCase.setShouldEmptySandbox(false); // so subsequent steps in same test see my results + } + + public void addExpectedMessage(ExpectedMessageSpec message) { + expected.add(message); + } + + public void setBaseDir(String dir) { + this.baseDir = dir; + } + + public void setTest(AjcTest t) { + this.myTest = t; + } + + /** + * @return Returns the aspectpath. + */ + public String getAspectpath() { + return aspectpath; + } + /** + * @param aspectpath The aspectpath to set. + */ + public void setAspectpath(String aspectpath) { + this.aspectpath = aspectpath.replace(',',File.pathSeparatorChar); + } + /** + * @return Returns the classpath. + */ + public String getClasspath() { + return classpath; + } + /** + * @param classpath The classpath to set. + */ + public void setClasspath(String classpath) { + this.classpath = classpath.replace(',',File.pathSeparatorChar); + } + /** + * @return Returns the files. + */ + public String getFiles() { + return files; + } + /** + * @param files The files to set. + */ + public void setFiles(String files) { + this.files = files; + } + /** + * @return Returns the includeClassesDir. + */ + public boolean isIncludeClassesDir() { + return includeClassesDir; + } + /** + * @param includeClassesDir The includeClassesDir to set. + */ + public void setIncludeClassesDir(boolean includeClassesDir) { + this.includeClassesDir = includeClassesDir; + } + /** + * @return Returns the inpath. + */ + public String getInpath() { + return inpath; + } + /** + * @param inpath The inpath to set. + */ + public void setInpath(String inpath) { + this.inpath = inpath.replace(',',File.pathSeparatorChar); + } + /** + * @return Returns the options. + */ + public String getOptions() { + return options; + } + /** + * @param options The options to set. + */ + public void setOptions(String options) { + int i = options.indexOf("!eclipse"); + if (i != -1) { + this.options = options.substring(0,i); + this.options += options.substring(i + "!eclipse".length()); + } else { + this.options = options; + } + } + /** + * @return Returns the outjar. + */ + public String getOutjar() { + return outjar; + } + /** + * @param outjar The outjar to set. + */ + public void setOutjar(String outjar) { + this.outjar = outjar; + } + /** + * @return Returns the sourceroots. + */ + public String getSourceroots() { + return sourceroots; + } + /** + * @param sourceroots The sourceroots to set. + */ + public void setSourceroots(String sourceroots) { + this.sourceroots = sourceroots; + } + /** + * @return Returns the xlintfile. + */ + public String getXlintfile() { + return xlintfile; + } + /** + * @param xlintfile The xlintfile to set. + */ + public void setXlintfile(String xlintfile) { + this.xlintfile = xlintfile; + } + + public String getExtdirs() { return extdirs;} + public void setExtdirs(String extdirs) { this.extdirs = extdirs; } + + private String[] buildArgs() { + StringBuffer args = new StringBuffer(); + // add any set options, and then files to compile at the end + if (getAspectpath() != null) { + args.append("-aspectpath "); + args.append(getAspectpath()); + args.append(" "); + } + if (getSourceroots() != null) { + args.append("-sourceroots "); + args.append(getSourceroots()); + args.append(" "); + } + if (getOutjar() != null) { + args.append("-outjar "); + args.append(getOutjar()); + args.append(" "); + } + if (getOptions() != null) { + StringTokenizer strTok = new StringTokenizer(getOptions(),","); + while (strTok.hasMoreTokens()) { + args.append(strTok.nextToken()); + args.append(" "); + } + } + if (getClasspath() != null) { + args.append("-classpath "); + args.append(getClasspath()); + args.append(" "); + } + if (getXlintfile() != null) { + args.append("-Xlintfile "); + args.append(getXlintfile()); + args.append(" "); + } + if (getExtdirs() != null) { + args.append("-extdirs "); + args.append(getExtdirs()); + args.append(" "); + } + List fileList = new ArrayList(); + List jarList = new ArrayList(); + // convention that any jar on file list should be added to inpath + String files = getFiles(); + if (files == null) files = ""; + StringTokenizer strTok = new StringTokenizer(files,","); + while (strTok.hasMoreTokens()) { + String file = strTok.nextToken(); + if (file.endsWith(".jar")) { + jarList.add(file); + } else { + fileList.add(file); + } + } + if ((getInpath() != null) || !jarList.isEmpty()) { + args.append("-inpath "); + if (getInpath() != null) args.append(getInpath()); + for (Iterator iter = jarList.iterator(); iter.hasNext();) { + String jar = (String) iter.next(); + args.append(File.pathSeparator); + args.append(jar); + } + args.append(" "); + } + for (Iterator iter = fileList.iterator(); iter.hasNext();) { + String file = (String) iter.next(); + args.append(file); + args.append(" "); + } + String argumentString = args.toString(); + strTok = new StringTokenizer(argumentString," "); + String[] ret = new String[strTok.countTokens()]; + for (int i = 0; i < ret.length; i++) { + ret[i] = strTok.nextToken(); + } + return ret; + } + + private AjcTestCase.MessageSpec buildMessageSpec() { + List infos = null; + List warnings = new ArrayList(); + List errors = new ArrayList(); + List fails = new ArrayList(); + for (Iterator iter = expected.iterator(); iter.hasNext();) { + ExpectedMessageSpec exMsg = (ExpectedMessageSpec) iter.next(); + String kind = exMsg.getKind(); + if (kind.equals("info")) { + if (infos == null) infos = new ArrayList(); + infos.add(exMsg.toMessage()); + } else if (kind.equals("warning")) { + warnings.add(exMsg.toMessage()); + } else if (kind.equals("error")) { + errors.add(exMsg.toMessage()); + } else if (kind.equals("fail")) { + fails.add(exMsg.toMessage()); + } else if (kind.equals("abort")) { + fails.add(exMsg.toMessage()); + } + } + return new AjcTestCase.MessageSpec(infos,warnings,errors,fails); + } + +} diff --git a/testing/newsrc/org/aspectj/testing/ExpectedMessageSpec.java b/testing/newsrc/org/aspectj/testing/ExpectedMessageSpec.java new file mode 100644 index 000000000..f1561a38b --- /dev/null +++ b/testing/newsrc/org/aspectj/testing/ExpectedMessageSpec.java @@ -0,0 +1,94 @@ +/* ******************************************************************* + * Copyright (c) 2004 IBM Corporation + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Adrian Colyer, + * ******************************************************************/ +package org.aspectj.testing; + +import org.aspectj.tools.ajc.AjcTestCase; + +/** + * @author colyer + * + * TODO To change the template for this generated type comment go to + * Window - Preferences - Java - Code Style - Code Templates + */ +public class ExpectedMessageSpec { + + private String kind = "error"; + private int line = -1; + private String text; + private String file; + private String details; + + public AjcTestCase.Message toMessage() { + return new AjcTestCase.Message(line,file,text,null); + } + + /** + * @return Returns the details. + */ + public String getDetails() { + return details; + } + /** + * @param details The details to set. + */ + public void setDetails(String details) { + this.details = details; + } + /** + * @return Returns the file. + */ + public String getFile() { + return file; + } + /** + * @param file The file to set. + */ + public void setFile(String file) { + this.file = file; + } + /** + * @return Returns the kind. + */ + public String getKind() { + return kind; + } + /** + * @param kind The kind to set. + */ + public void setKind(String kind) { + this.kind = kind; + } + /** + * @return Returns the line. + */ + public int getLine() { + return line; + } + /** + * @param line The line to set. + */ + public void setLine(int line) { + this.line = line; + } + /** + * @return Returns the text. + */ + public String getText() { + return text; + } + /** + * @param text The text to set. + */ + public void setText(String text) { + this.text = text; + } +} diff --git a/testing/newsrc/org/aspectj/testing/ITestStep.java b/testing/newsrc/org/aspectj/testing/ITestStep.java new file mode 100644 index 000000000..babda87d5 --- /dev/null +++ b/testing/newsrc/org/aspectj/testing/ITestStep.java @@ -0,0 +1,31 @@ +/* ******************************************************************* + * Copyright (c) 2004 IBM Corporation + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Adrian Colyer, + * ******************************************************************/ +package org.aspectj.testing; + +import org.aspectj.tools.ajc.AjcTestCase; + +/** + * @author colyer + * + * TODO To change the template for this generated type comment go to + * Window - Preferences - Java - Code Style - Code Templates + */ +public interface ITestStep { + + void execute(AjcTestCase inTestCase); + + void addExpectedMessage(ExpectedMessageSpec message); + + void setBaseDir(String dir); + + void setTest(AjcTest test); +} diff --git a/testing/newsrc/org/aspectj/testing/MakeTestClass.java b/testing/newsrc/org/aspectj/testing/MakeTestClass.java new file mode 100644 index 000000000..06667c9b9 --- /dev/null +++ b/testing/newsrc/org/aspectj/testing/MakeTestClass.java @@ -0,0 +1,122 @@ +/* + * Created on 02-Aug-2004 + * + * TODO To change the template for this generated file go to + * Window - Preferences - Java - Code Style - Code Templates + */ +package org.aspectj.testing; + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStreamReader; +import java.io.PrintStream; +import java.text.NumberFormat; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.apache.commons.digester.Digester; + +/** + * @author colyer + * + * TODO To change the template for this generated type comment go to + * Window - Preferences - Java - Code Style - Code Templates + */ +public class MakeTestClass { + + private static final String HEADER = + "/* *******************************************************************\n" + + " * Copyright (c) 2004 IBM Corporation\n" + + " * All rights reserved.\n" + + " * This program and the accompanying materials are made available\n" + + " * under the terms of the Common Public License v1.0\n" + + " * which accompanies this distribution and is available at\n" + + " * http://www.eclipse.org/legal/cpl-v10.html \n" + + " * \n" + + " * ******************************************************************/\n" + + "package org.aspectj.systemtest.XXX;\n" + + "\n" + + "import java.io.File;\n" + + "import junit.framework.Test;\n" + + "import org.aspectj.testing.XMLBasedAjcTestCase;\n" + + "\n" + + "public class "; + + private static final String BODY_1 = + " extends org.aspectj.testing.XMLBasedAjcTestCase {\n" + + "\n" + + " public static Test suite() {\n" + + " return XMLBasedAjcTestCase.loadSuite("; + + private static final String BODY_2 = + ".class);\n" + + " }\n" + + "\n" + + " protected File getSpecFile() {\n" + + " return new File(\""; + + private static final String BODY_3 = + "\");\n" + + " }\n"; + + private static final String FOOTER = + "}\n"; + + private List tests = new ArrayList(); + private String className; + private String suiteFile; + + public static void main(String[] args) throws Exception { + new MakeTestClass(args[0],args[1]).makeTestClass(); + } + + public MakeTestClass(String className, String suiteFile)throws Exception { + this.className = className; + this.suiteFile = suiteFile; + Digester d = getDigester(); + InputStreamReader isr = new InputStreamReader(new FileInputStream(suiteFile)); + d.parse(isr); + } + + public void addTest(AjcTest test) { + tests.add(test); + } + + public void makeTestClass() throws Exception { + FileOutputStream fos = new FileOutputStream(className + ".java"); + PrintStream out = new PrintStream(fos); + out.print(HEADER); + out.print(className); + out.print(BODY_1); + out.print(className); + out.print(BODY_2); + out.print(suiteFile); + out.print(BODY_3); + out.println(); + int testNo = 1; + NumberFormat nf = NumberFormat.getInstance(); + nf.setMinimumIntegerDigits(3); + for (Iterator iter = tests.iterator(); iter.hasNext();) { + AjcTest test = (AjcTest) iter.next(); + out.println(); + out.print(" public void test"); + out.print(nf.format(testNo++)); + out.println("(){"); + out.println(" runTest(\"" + test.getTitle() + "\");"); + out.println(" }"); + } + out.println(); + out.println(FOOTER); + out.close(); + } + + private Digester getDigester() { + Digester digester = new Digester(); + digester.push(this); + digester.addObjectCreate("suite/ajc-test",AjcTest.class); + digester.addSetProperties("suite/ajc-test"); + digester.addSetNext("suite/ajc-test","addTest","org.aspectj.testing.AjcTest"); + return digester; + } +} diff --git a/testing/newsrc/org/aspectj/testing/RunSpec.java b/testing/newsrc/org/aspectj/testing/RunSpec.java new file mode 100644 index 000000000..431e5b094 --- /dev/null +++ b/testing/newsrc/org/aspectj/testing/RunSpec.java @@ -0,0 +1,89 @@ +/* ******************************************************************* + * Copyright (c) 2004 IBM Corporation + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Adrian Colyer, + * ******************************************************************/ +package org.aspectj.testing; + +import java.util.ArrayList; +import java.util.List; +import java.util.StringTokenizer; + +import org.aspectj.tools.ajc.AjcTestCase; + +/** + * @author colyer + * + * TODO To change the template for this generated type comment go to + * Window - Preferences - Java - Code Style - Code Templates + */ +public class RunSpec implements ITestStep { + + private List expected = new ArrayList(); + private String classToRun; + private String baseDir; + private String options; + private AjcTest myTest; + + public RunSpec() { + } + + /* (non-Javadoc) + * @see org.aspectj.testing.ITestStep#execute(org.aspectj.tools.ajc.AjcTestCase) + */ + public void execute(AjcTestCase inTestCase) { + if (!expected.isEmpty()) { + System.err.println("Warning, message spec for run command is currently ignored (org.aspectj.testing.RunSpec)"); + } + String[] args = buildArgs(); + AjcTestCase.RunResult rr = inTestCase.run(getClassToRun(),args,null); + } + + public void addExpectedMessage(ExpectedMessageSpec message) { + expected.add(message); + } + + public void setBaseDir(String dir) { + this.baseDir = dir; + } + + public void setTest(AjcTest test) { + this.myTest = test; + } + + public String getOptions() { + return options; + } + + public void setOptions(String options) { + this.options = options; + } + /** + * @return Returns the classToRun. + */ + public String getClassToRun() { + return classToRun; + } + /** + * @param classToRun The classToRun to set. + */ + public void setClassToRun(String classToRun) { + this.classToRun = classToRun; + } + + private String[] buildArgs() { + if (options == null) return new String[0]; + StringTokenizer strTok = new StringTokenizer(options,","); + String[] ret = new String[strTok.countTokens()]; + for (int i = 0; i < ret.length; i++) { + ret[i] = strTok.nextToken(); + } + return ret; + } +} diff --git a/testing/newsrc/org/aspectj/testing/XMLBasedAjcTestCase.java b/testing/newsrc/org/aspectj/testing/XMLBasedAjcTestCase.java new file mode 100644 index 000000000..6097570b2 --- /dev/null +++ b/testing/newsrc/org/aspectj/testing/XMLBasedAjcTestCase.java @@ -0,0 +1,163 @@ +/* ******************************************************************* + * Copyright (c) 2004 IBM Corporation + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Adrian Colyer, + * ******************************************************************/ +package org.aspectj.testing; + +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStreamReader; +import java.util.HashMap; +import java.util.Map; + +import junit.extensions.TestSetup; +import junit.framework.Test; +import junit.framework.TestSuite; + +import org.apache.commons.digester.Digester; +import org.aspectj.tools.ajc.AjcTestCase; + +/** + * Root class for all Test suites that are based on an AspectJ XML test suite + * file. Extends AjcTestCase allowing a mix of programmatic and spec-file + * driven testing. See org.aspectj.systemtest.incremental.IncrementalTests for + * an example of this mixed style. + * <p>The class org.aspectj.testing.MakeTestClass will generate a subclass of + * this class for you, given a suite spec. file as input...</p> + */ +public abstract class XMLBasedAjcTestCase extends AjcTestCase { + + private static Map testMap = new HashMap(); + private static boolean suiteLoaded = false; + private AjcTest currentTest = null; + + public XMLBasedAjcTestCase() { + } + + /** + * You must define a suite() method in subclasses, and return + * the result of calling this method. (Don't you hate static + * methods in programming models). For example: + * <pre> + * public static Test suite() { + * return XMLBasedAjcTestCase.loadSuite(MyTestCaseClass.class); + * } + * </pre> + * @param testCaseClass + * @return + */ + public static Test loadSuite(Class testCaseClass) { + TestSuite suite = new TestSuite(testCaseClass.getName()); + suite.addTestSuite(testCaseClass); + TestSetup wrapper = new TestSetup(suite) { + /* (non-Javadoc) + * @see junit.extensions.TestSetup#setUp() + */ + protected void setUp() throws Exception { + super.setUp(); + suiteLoaded = false; + } + /* (non-Javadoc) + * @see junit.extensions.TestSetup#tearDown() + */ + protected void tearDown() throws Exception { + super.tearDown(); + suiteLoaded = false; + } + }; + return wrapper; + } + + /** + * The file containing the XML specification for the tests. + */ + protected abstract File getSpecFile(); + + /* + * Return a map from (String) test title -> AjcTest + */ + private Map getSuiteTests() { + return testMap; + } + + /** + * This helper method runs the test with the given title in the + * suite spec file. All tests steps in given ajc-test execute + * in the same sandbox. + */ + protected void runTest(String title) { + currentTest = (AjcTest) testMap.get(title); + if (currentTest == null) { + fail("No test '" + title + "' in suite."); + } + ajc.setShouldEmptySandbox(true); + currentTest.runTest(this); + } + + /** + * Get the currently executing test. Useful for access to e.g. + * AjcTest.getTitle() etc.. + */ + protected AjcTest getCurrentTest() { + return currentTest; + } + + /** + * For use by the Digester. As the XML document is parsed, it creates instances + * of AjcTest objects, which are added to this TestCase by the Digester by + * calling this method. + */ + public void addTest(AjcTest test) { + testMap.put(test.getTitle(),test); + } + + /* + * The rules for parsing a suite spec file. The Digester using bean properties to match attributes + * in the XML document to properties in the associated classes, so this simple implementation should + * be very easy to maintain and extend should you ever need to. + */ + private Digester getDigester() { + Digester digester = new Digester(); + digester.push(this); + digester.addObjectCreate("suite/ajc-test",AjcTest.class); + digester.addSetProperties("suite/ajc-test"); + digester.addSetNext("suite/ajc-test","addTest","org.aspectj.testing.AjcTest"); + digester.addObjectCreate("suite/ajc-test/compile",CompileSpec.class); + digester.addSetProperties("suite/ajc-test/compile"); + digester.addSetNext("suite/ajc-test/compile","addTestStep","org.aspectj.testing.ITestStep"); + digester.addObjectCreate("suite/ajc-test/run",RunSpec.class); + digester.addSetProperties("suite/ajc-test/run","class","classToRun"); + digester.addSetNext("suite/ajc-test/run","addTestStep","org.aspectj.testing.ITestStep"); + digester.addObjectCreate("*/message",ExpectedMessageSpec.class); + digester.addSetProperties("*/message"); + digester.addSetNext("*/message","addExpectedMessage","org.aspectj.testing.ExpectedMessageSpec"); + return digester; + } + + /* (non-Javadoc) + * @see org.aspectj.tools.ajc.AjcTestCase#setUp() + */ + protected void setUp() throws Exception { + super.setUp(); + if (!suiteLoaded) { + testMap = new HashMap(); + System.out.println("LOADING SUITE: " + getSpecFile().getPath()); + Digester d = getDigester(); + try { + InputStreamReader isr = new InputStreamReader(new FileInputStream(getSpecFile())); + d.parse(isr); + } catch (Exception ex) { + fail("Unable to load suite " + getSpecFile().getPath() + " : " + ex); + } + suiteLoaded = true; + } + } +} + |