]> source.dussan.org Git - aspectj.git/commitdiff
XMLBasedAjcTestCase class and accompanying support. Drives a
authoracolyer <acolyer>
Wed, 4 Aug 2004 12:02:07 +0000 (12:02 +0000)
committeracolyer <acolyer>
Wed, 4 Aug 2004 12:02:07 +0000 (12:02 +0000)
junit test suite based on an ajcTests.xml format test specification.

testing/.classpath
testing/newsrc/org/aspectj/testing/AjcTest.java [new file with mode: 0644]
testing/newsrc/org/aspectj/testing/CompileSpec.java [new file with mode: 0644]
testing/newsrc/org/aspectj/testing/ExpectedMessageSpec.java [new file with mode: 0644]
testing/newsrc/org/aspectj/testing/ITestStep.java [new file with mode: 0644]
testing/newsrc/org/aspectj/testing/MakeTestClass.java [new file with mode: 0644]
testing/newsrc/org/aspectj/testing/RunSpec.java [new file with mode: 0644]
testing/newsrc/org/aspectj/testing/XMLBasedAjcTestCase.java [new file with mode: 0644]

index 4d82f83dcfbca3ff18219f444e9bba4914e5ed50..1eb23f6d694c6a477ce31d1111aa782cb0b3e531 100644 (file)
@@ -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 (file)
index 0000000..923505f
--- /dev/null
@@ -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 (file)
index 0000000..1dd29f4
--- /dev/null
@@ -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 (file)
index 0000000..f1561a3
--- /dev/null
@@ -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 (file)
index 0000000..babda87
--- /dev/null
@@ -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 (file)
index 0000000..06667c9
--- /dev/null
@@ -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 (file)
index 0000000..431e5b0
--- /dev/null
@@ -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 (file)
index 0000000..6097570
--- /dev/null
@@ -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;
+               }
+       }
+}
+