/* * This file is part of Web-CAT Eclipse Plugins. * * Web-CAT is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Web-CAT is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Web-CAT; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package net.sf.webcat.eclipse.cxxtest.wizards; import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.IFunctionDeclaration; import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.model.IWorkingCopy; import org.eclipse.cdt.internal.ui.wizards.classwizard.NewClassWizardMessages; import org.eclipse.cdt.internal.ui.wizards.filewizard.NewSourceFileGenerator; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.SubProgressMonitor; /** * Generates a CxxTest suite header file based on information chose in the * wizard by the user. * * @author Tony Allevato (Virginia Tech Computer Science) */ @SuppressWarnings("restriction") public class CxxTestSuiteGenerator { private String suiteName; private IPath suitePath; private IPath headerUnderTestPath; private String superClass; private boolean createSetUp; private boolean createTearDown; private IFunctionDeclaration[] functionStubs; private String[] stubNames; private IFile suiteFile; private ITranslationUnit createdSuite; public CxxTestSuiteGenerator(String suiteName, IPath suitePath, IPath headerUnderTestPath, String superClass, boolean createSetUp, boolean createTearDown, IFunctionDeclaration[] methodStubs) { this.suiteName = suiteName; this.suitePath = suitePath; this.headerUnderTestPath = headerUnderTestPath; this.superClass = superClass; this.createSetUp = createSetUp; this.createTearDown = createTearDown; this.functionStubs = methodStubs; populateStubNameMap(); } private void populateStubNameMap() { int stubCount = functionStubs.length; stubNames = new String[stubCount]; ICElement[] stubElements = new ICElement[stubCount]; for(int i = 0; i < stubCount; i++) { stubNames[i] = functionStubs[i].getElementName(); stubElements[i] = functionStubs[i]; } boolean anotherPass, fixIthName; do { anotherPass = false; fixIthName = false; for(int i = 0; i < stubCount; i++) { for(int j = 0; j < stubCount; j++) { if(i != j && stubNames[i].equals(stubNames[j])) { // The names of the stubs are equal, so go up a step and // try to further qualify them. if(!(stubElements[j] instanceof ITranslationUnit)) { stubElements[j] = stubElements[j].getParent(); String jPrefix; if(!(stubElements[j] instanceof ITranslationUnit)) jPrefix = stubElements[j].getElementName(); else jPrefix = "_global"; //$NON-NLS-1$ stubNames[j] = jPrefix + "_" + stubNames[j]; //$NON-NLS-1$ anotherPass = true; fixIthName = true; } } } if(fixIthName) { if(!(stubElements[i] instanceof ITranslationUnit)) { stubElements[i] = stubElements[i].getParent(); String iPrefix; if(!(stubElements[i] instanceof ITranslationUnit)) iPrefix = stubElements[i].getElementName(); else iPrefix = "_global"; //$NON-NLS-1$ stubNames[i] = iPrefix + "_" + stubNames[i]; //$NON-NLS-1$ } fixIthName = false; } } } while(anotherPass); } public void generate(IProgressMonitor monitor) throws CoreException, InterruptedException { suiteFile = NewSourceFileGenerator.createHeaderFile( suitePath, true, new SubProgressMonitor(monitor, 50)); if(suiteFile != null) createdSuite = (ITranslationUnit) CoreModel.getDefault().create(suiteFile); // create a working copy with a new owner IWorkingCopy suiteWorkingCopy = createdSuite.getWorkingCopy(); String suiteContent = constructHeaderFileContent(createdSuite, "", //suiteWorkingCopy.getBuffer().getContents(), //$NON-NLS-1$ new SubProgressMonitor(monitor, 100)); suiteWorkingCopy.getBuffer().setContents(suiteContent); if (monitor.isCanceled()) { throw new InterruptedException(); } suiteWorkingCopy.reconcile(); suiteWorkingCopy.commit(true, monitor); monitor.worked(50); } public IFile getCreatedSuiteFile() { return suiteFile; } private String constructHeaderFileContent(ITranslationUnit headerTU, String oldContents, IProgressMonitor monitor) { monitor.beginTask( NewClassWizardMessages.NewClassCodeGeneration_createType_task_header, 100); //$NON-NLS-1$ if (oldContents != null && oldContents.length() == 0) oldContents = null; StringBuffer text = new StringBuffer(); appendFilePrologue(text); appendClassPrologue(text); if(createSetUp) appendSetUp(text); if(createTearDown) appendTearDown(text); if(functionStubs != null) appendFunctionStubs(text); appendClassEpilogue(text); appendFileEpilogue(text); String newContents = text.toString(); monitor.done(); return newContents; } private void appendFilePrologue(StringBuffer text) { String guardSymbol = suiteName.toUpperCase() + "_H_"; //$NON-NLS-1$ text.append("#ifndef " + guardSymbol + "\n"); //$NON-NLS-1$ //$NON-NLS-2$ text.append("#define " + guardSymbol + "\n\n"); //$NON-NLS-1$ //$NON-NLS-2$ text.append("#include <cxxtest/TestSuite.h>\n\n"); //$NON-NLS-1$ if(headerUnderTestPath != null) { IPath headerAbsPath = headerUnderTestPath.makeAbsolute(); IPath suiteAbsPath = suitePath.makeAbsolute(); int matchingSegs = headerAbsPath.matchingFirstSegments(suiteAbsPath); IPath includePath = headerAbsPath.removeFirstSegments(matchingSegs); text.append("#include \"" + includePath.toOSString() + "\"\n\n"); //$NON-NLS-1$ //$NON-NLS-2$ } } private void appendClassPrologue(StringBuffer text) { text.append("class " + suiteName + " : public " + superClass + "\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ text.append("{\n"); //$NON-NLS-1$ text.append("public:\n"); //$NON-NLS-1$ } private void appendSetUp(StringBuffer text) { text.append("\tvoid setUp()\n"); //$NON-NLS-1$ text.append("\t{\n"); //$NON-NLS-1$ text.append("\t\t// TODO: Implement setUp() function.\n"); //$NON-NLS-1$ text.append("\t}\n\n"); //$NON-NLS-1$ } private void appendTearDown(StringBuffer text) { text.append("\tvoid tearDown()\n"); //$NON-NLS-1$ text.append("\t{\n"); //$NON-NLS-1$ text.append("\t\t// TODO: Implement tearDown() function.\n"); //$NON-NLS-1$ text.append("\t}\n\n"); //$NON-NLS-1$ } private void appendFunctionStubs(StringBuffer text) { for(int i = 0; i < functionStubs.length; i++) { String name = stubNames[i]; name = "test" + Character.toUpperCase(name.charAt(0)) + //$NON-NLS-1$ name.substring(1); text.append("\tvoid " + name + "()\n"); //$NON-NLS-1$ //$NON-NLS-2$ text.append("\t{\n"); //$NON-NLS-1$ text.append("\t\t// TODO: Implement " + name + "() function.\n"); //$NON-NLS-1$ //$NON-NLS-2$ text.append("\t}\n\n"); //$NON-NLS-1$ } } private void appendClassEpilogue(StringBuffer text) { text.append("};\n\n"); //$NON-NLS-1$ } private void appendFileEpilogue(StringBuffer text) { String guardSymbol = suiteName.toUpperCase() + "_H_"; //$NON-NLS-1$ text.append("#endif /*" + guardSymbol + "*/\n"); //$NON-NLS-1$ //$NON-NLS-2$ } }