| /******************************************************************************* |
| * Copyright (c) 2007, 2020 IBM Corporation and others. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.pde.api.tools.util.tests; |
| |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertFalse; |
| import static org.junit.Assert.assertNotNull; |
| import static org.junit.Assert.assertNull; |
| import static org.junit.Assert.assertTrue; |
| |
| import java.io.IOException; |
| import java.lang.reflect.InvocationTargetException; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| import org.eclipse.core.filebuffers.FileBuffers; |
| import org.eclipse.core.filebuffers.ITextFileBuffer; |
| import org.eclipse.core.filebuffers.ITextFileBufferManager; |
| import org.eclipse.core.filebuffers.LocationKind; |
| import org.eclipse.core.resources.IContainer; |
| import org.eclipse.core.resources.IFolder; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.NullProgressMonitor; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.jdt.core.ICompilationUnit; |
| import org.eclipse.jdt.core.IJavaElement; |
| import org.eclipse.jdt.core.IJavaProject; |
| import org.eclipse.jdt.core.IPackageFragment; |
| import org.eclipse.jdt.core.IPackageFragmentRoot; |
| import org.eclipse.jdt.core.JavaCore; |
| import org.eclipse.jdt.core.JavaModelException; |
| import org.eclipse.jdt.core.dom.AST; |
| import org.eclipse.jdt.core.dom.ASTParser; |
| import org.eclipse.jdt.core.dom.ASTVisitor; |
| import org.eclipse.jdt.core.dom.BodyDeclaration; |
| import org.eclipse.jdt.core.dom.CompilationUnit; |
| import org.eclipse.jdt.core.dom.FieldDeclaration; |
| import org.eclipse.jdt.core.dom.Javadoc; |
| import org.eclipse.jdt.core.dom.MethodDeclaration; |
| import org.eclipse.jdt.core.dom.TagElement; |
| import org.eclipse.jdt.core.dom.TypeDeclaration; |
| import org.eclipse.jdt.core.dom.VariableDeclarationFragment; |
| import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; |
| import org.eclipse.jdt.core.dom.rewrite.ListRewrite; |
| import org.eclipse.jface.text.BadLocationException; |
| import org.eclipse.jface.text.IDocument; |
| import org.eclipse.pde.api.tools.internal.ApiBaselineManager; |
| import org.eclipse.pde.api.tools.internal.model.ApiModelFactory; |
| import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin; |
| import org.eclipse.pde.api.tools.internal.provisional.Factory; |
| import org.eclipse.pde.api.tools.internal.provisional.IApiAnnotations; |
| import org.eclipse.pde.api.tools.internal.provisional.IApiBaselineManager; |
| import org.eclipse.pde.api.tools.internal.provisional.IApiDescription; |
| import org.eclipse.pde.api.tools.internal.provisional.RestrictionModifiers; |
| import org.eclipse.pde.api.tools.internal.provisional.VisibilityModifiers; |
| import org.eclipse.pde.api.tools.internal.provisional.model.IApiBaseline; |
| import org.eclipse.pde.api.tools.internal.provisional.model.IApiComponent; |
| import org.eclipse.pde.api.tools.internal.util.Signatures; |
| import org.eclipse.pde.api.tools.model.tests.TestSuiteHelper; |
| import org.eclipse.pde.api.tools.tests.AbstractApiTest; |
| import org.eclipse.pde.api.tools.tests.util.FileUtils; |
| import org.eclipse.pde.api.tools.tests.util.ProjectUtils; |
| import org.eclipse.pde.core.project.IBundleClasspathEntry; |
| import org.eclipse.pde.core.project.IBundleProjectDescription; |
| import org.eclipse.pde.core.project.IBundleProjectService; |
| import org.eclipse.text.edits.MalformedTreeException; |
| import org.eclipse.text.edits.TextEdit; |
| import org.junit.After; |
| import org.junit.Before; |
| import org.junit.Test; |
| |
| /** |
| * Tests the {@link ApiBaselineManager} without the framework running |
| */ |
| @SuppressWarnings("unchecked") |
| public class ApiBaselineManagerTests extends AbstractApiTest { |
| |
| static final String THREE = "three"; //$NON-NLS-1$ |
| static final String TESTDEFAULT = "testdefault"; //$NON-NLS-1$ |
| static final String ADDTEST = "addtest"; //$NON-NLS-1$ |
| |
| class SourceChangeVisitor extends ASTVisitor { |
| String name = null; |
| String signature = null; |
| String tagname = null; |
| ASTRewrite rewrite = null; |
| boolean remove = false; |
| |
| public SourceChangeVisitor(String name, String signature, String tagname, boolean remove, ASTRewrite rewrite) { |
| this.name = name; |
| this.signature = signature; |
| this.tagname = tagname; |
| this.rewrite = rewrite; |
| this.remove = remove; |
| } |
| |
| @Override |
| public boolean visit(FieldDeclaration node) { |
| if (signature != null) { |
| return false; |
| } |
| List<VariableDeclarationFragment> fields = node.fragments(); |
| VariableDeclarationFragment fragment = null; |
| for (Iterator<VariableDeclarationFragment> iter = fields.iterator(); iter.hasNext();) { |
| fragment = iter.next(); |
| if (fragment.getName().getFullyQualifiedName().equals(name)) { |
| break; |
| } |
| } |
| if (fragment != null) { |
| updateTag(node); |
| } |
| return false; |
| } |
| |
| @Override |
| public boolean visit(MethodDeclaration node) { |
| if (name.equals(node.getName().getFullyQualifiedName())) { |
| if (signature.equals(Signatures.getMethodSignatureFromNode(node, true))) { |
| updateTag(node); |
| } |
| } |
| return false; |
| } |
| |
| @Override |
| public boolean visit(TypeDeclaration node) { |
| if (name.equals(node.getName().getFullyQualifiedName())) { |
| updateTag(node); |
| return false; |
| } |
| return true; |
| } |
| |
| /** |
| * Updates a javadoc tag, by either adding a new one or removing an |
| * existing one |
| * |
| * @param body |
| */ |
| private void updateTag(BodyDeclaration body) { |
| Javadoc docnode = body.getJavadoc(); |
| AST ast = body.getAST(); |
| if (docnode == null) { |
| docnode = ast.newJavadoc(); |
| rewrite.set(body, body.getJavadocProperty(), docnode, null); |
| } |
| ListRewrite lrewrite = rewrite.getListRewrite(docnode, Javadoc.TAGS_PROPERTY); |
| if (remove) { |
| List<TagElement> tags = (List<TagElement>) docnode.getStructuralProperty(Javadoc.TAGS_PROPERTY); |
| if (tags != null) { |
| TagElement tag = null; |
| for (TagElement tag2 : tags) { |
| tag = tag2; |
| if (tagname.equals(tag.getTagName())) { |
| lrewrite.remove(tag, null); |
| } |
| } |
| } |
| } else { |
| TagElement newtag = ast.newTagElement(); |
| newtag.setTagName(tagname); |
| lrewrite.insertLast(newtag, null); |
| } |
| } |
| } |
| |
| private IPath SRC_LOC = TestSuiteHelper.getPluginDirectoryPath().append("test-source").append("a").append("b").append("c"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ |
| private IPath PLUGIN_LOC = TestSuiteHelper.getPluginDirectoryPath().append("test-plugins"); //$NON-NLS-1$ |
| private IApiBaselineManager fPMmanager = ApiPlugin.getDefault().getApiBaselineManager(); |
| private final String TESTING_PACKAGE = "a.b.c"; //$NON-NLS-1$ |
| |
| /** |
| * @return the {@link IApiDescription} for the testing project |
| */ |
| private IApiDescription getTestProjectApiDescription() throws CoreException { |
| IApiBaseline baseline = getWorkspaceBaseline(); |
| assertNotNull("the workspace baseline must exist", baseline); //$NON-NLS-1$ |
| IApiComponent component = baseline.getApiComponent(TESTING_PLUGIN_PROJECT_NAME); |
| if (component != null) { |
| return component.getApiDescription(); |
| } |
| return null; |
| } |
| |
| /** |
| * Creates and returns a test baseline with the given id. Also adds it to |
| * the baseline manager |
| * |
| * @param id |
| * @return |
| */ |
| protected IApiBaseline getTestBaseline(String id) { |
| IApiBaseline baseline = ApiModelFactory.newApiBaseline(id); |
| fPMmanager.addApiBaseline(baseline); |
| return baseline; |
| } |
| |
| /** |
| * Tests trying to get the workspace baseline without the framework running |
| */ |
| @Test |
| public void testGetWorkspaceComponent() { |
| IApiBaseline baseline = getWorkspaceBaseline(); |
| assertNotNull("the workspace baseline must not be null", baseline); //$NON-NLS-1$ |
| } |
| |
| /** |
| * Tests that an API baseline can be added and retrieved successfully |
| */ |
| @Test |
| public void testAddBaseline() { |
| IApiBaseline baseline = getTestBaseline(ADDTEST); |
| assertNotNull("the test baseline must have been created", baseline); //$NON-NLS-1$ |
| assertTrue("the testadd baseline must be in the manager", fPMmanager.removeApiBaseline(ADDTEST)); //$NON-NLS-1$ |
| } |
| |
| /** |
| * Tests that an API baseline can be added/removed successfully |
| */ |
| @Test |
| public void testRemoveBaseline() { |
| IApiBaseline baseline = getTestBaseline("removetest"); //$NON-NLS-1$ |
| assertNotNull("the testremove baseline must exist", baseline); //$NON-NLS-1$ |
| baseline = fPMmanager.getApiBaseline("removetest"); //$NON-NLS-1$ |
| assertNotNull("the testremove baseline must be in the manager", baseline); //$NON-NLS-1$ |
| assertTrue("the testremove baseline should have been removed", fPMmanager.removeApiBaseline("removetest")); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| |
| /** |
| * Tests that the default baseline can be set/retrieved |
| */ |
| @Test |
| public void testSetDefaultBaseline() { |
| try { |
| IApiBaseline baseline = getTestBaseline(TESTDEFAULT); |
| assertNotNull("the testdefault baseline must exist", baseline); //$NON-NLS-1$ |
| fPMmanager.setDefaultApiBaseline(TESTDEFAULT); |
| baseline = fPMmanager.getDefaultApiBaseline(); |
| assertNotNull("the default baseline must be the testdefault baseline", baseline); //$NON-NLS-1$ |
| } finally { |
| fPMmanager.removeApiBaseline(TESTDEFAULT); |
| } |
| } |
| |
| /** |
| * Tests that all baselines added to the manager can be retrieved |
| */ |
| @Test |
| public void testGetAllBaselines() { |
| try { |
| fPMmanager.addApiBaseline(getTestBaseline(ADDTEST)); |
| fPMmanager.addApiBaseline(getTestBaseline(TESTDEFAULT)); |
| fPMmanager.addApiBaseline(getTestBaseline(THREE)); |
| IApiBaseline[] baselines = fPMmanager.getApiBaselines(); |
| assertEquals("there should be three baselines", 3, baselines.length); //$NON-NLS-1$ |
| } finally { |
| fPMmanager.removeApiBaseline(ADDTEST); |
| fPMmanager.removeApiBaseline(TESTDEFAULT); |
| fPMmanager.removeApiBaseline(THREE); |
| } |
| } |
| |
| /** |
| * Tests that all of the baselines have been removed |
| */ |
| @Test |
| public void testCleanUpMmanager() { |
| try { |
| fPMmanager.addApiBaseline(getTestBaseline(ADDTEST)); |
| fPMmanager.addApiBaseline(getTestBaseline(TESTDEFAULT)); |
| fPMmanager.addApiBaseline(getTestBaseline(THREE)); |
| IApiBaseline[] baselines = fPMmanager.getApiBaselines(); |
| assertEquals("there should be three baselines", 3, baselines.length); //$NON-NLS-1$ |
| assertTrue("the testadd baseline should have been removed", fPMmanager.removeApiBaseline(ADDTEST)); //$NON-NLS-1$ |
| assertTrue("the testdefault baseline should have been removed", fPMmanager.removeApiBaseline(TESTDEFAULT)); //$NON-NLS-1$ |
| assertTrue("the three baseline should have been removed", fPMmanager.removeApiBaseline(THREE)); //$NON-NLS-1$ |
| assertEquals("There sould be no more baselines", 0, fPMmanager.getApiBaselines().length); //$NON-NLS-1$ |
| } finally { |
| fPMmanager.removeApiBaseline(ADDTEST); |
| fPMmanager.removeApiBaseline(TESTDEFAULT); |
| fPMmanager.removeApiBaseline(THREE); |
| } |
| } |
| |
| /** |
| * Adds the given source to the given package in the given fragment root |
| * |
| * @param root the root to add the source to |
| * @param packagename the name of the package e.g. a.b.c |
| * @param sourcename the name of the source file without an extension e.g. |
| * TestClass1 |
| */ |
| public void assertTestSource(IPackageFragmentRoot root, String packagename, String sourcename) throws InvocationTargetException, IOException { |
| IPackageFragment fragment = root.getPackageFragment(packagename); |
| FileUtils.importFileFromDirectory(SRC_LOC.append(sourcename + ".java").toFile(), fragment.getPath(), new NullProgressMonitor()); //$NON-NLS-1$ |
| } |
| |
| /** |
| * Adds the package with the given name to the given package fragment root |
| * |
| * @param the project to add the package to |
| * @param srcroot the absolute path to the package fragment root to add the |
| * new package to |
| * @param packagename the name of the new package |
| * @return the new {@link IPackageFragment} or <code>null</code> |
| */ |
| public IPackageFragment assertTestPackage(IJavaProject project, IPath srcroot, String packagename) throws JavaModelException { |
| IPackageFragment fragment = null; |
| IPackageFragmentRoot root = project.findPackageFragmentRoot(srcroot); |
| assertNotNull("the 'src' package fragment root must exist", root); //$NON-NLS-1$ |
| fragment = root.createPackageFragment(packagename, true, new NullProgressMonitor()); |
| assertNotNull("the new package '" + packagename + "' should have been created", fragment); //$NON-NLS-1$ //$NON-NLS-2$ |
| return fragment; |
| } |
| |
| /** |
| * Adds a test library with the given name to the test projects' class path. |
| * The library is imported from the {@link #PLUGIN_LOC} location. |
| * |
| * @param project the project to add the library classpath entry to |
| * @param folderpath the path in the project where the library should be |
| * imported to |
| * @param libname the name of the library |
| */ |
| public IFolder assertTestLibrary(IJavaProject project, IPath folderpath, String libname) throws CoreException, InvocationTargetException, IOException { |
| IFolder folder = null; |
| // import library |
| folder = project.getProject().getFolder(folderpath); |
| if (!folder.exists()) { |
| folder.create(false, true, null); |
| } |
| FileUtils.importFileFromDirectory(PLUGIN_LOC.append(libname).toFile(), folder.getFullPath(), null); |
| IPath libPath = folder.getFullPath().append(libname); |
| |
| // add to manifest bundle classpath |
| ProjectUtils.addBundleClasspathEntry(project.getProject(), ProjectUtils.getBundleProjectService().newBundleClasspathEntry(null, null, libPath.removeFirstSegments(1))); |
| waitForAutoBuild(); |
| return folder; |
| } |
| |
| /** |
| * Asserts if the given restriction is on the specified source |
| * |
| * @param packagename |
| * @param sourcename |
| */ |
| public void assertSourceResctriction(String packagename, String sourcename, int restriction) throws CoreException { |
| IApiDescription desc = getTestProjectApiDescription(); |
| assertNotNull("the testing project api description must exist", desc); //$NON-NLS-1$ |
| IApiAnnotations annot = desc.resolveAnnotations(Factory.typeDescriptor(packagename + "." + sourcename)); //$NON-NLS-1$ |
| assertNotNull("the annotations for " + packagename + "." + sourcename + " cannot be null", annot); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
| assertEquals("there must be a noinstantiate setting for TestClass1", annot.getRestrictions(), restriction); //$NON-NLS-1$ |
| } |
| |
| /** |
| * Tests that closing an API aware project causes the workspace description |
| * to be updated |
| */ |
| @Test |
| public void testWPUpdateProjectClosed() throws Exception { |
| IJavaProject project = getTestingProject(); |
| assertNotNull("The testing project must exist", project); //$NON-NLS-1$ |
| assertNotNull("the workspace baseline must not be null", getWorkspaceBaseline()); //$NON-NLS-1$ |
| IApiComponent component = getWorkspaceBaseline().getApiComponent(TESTING_PLUGIN_PROJECT_NAME); |
| assertNotNull("the change project api component must exist in the workspace baseline", component); //$NON-NLS-1$ |
| project.getProject().close(new NullProgressMonitor()); |
| component = getWorkspaceBaseline().getApiComponent(TESTING_PLUGIN_PROJECT_NAME); |
| assertNull("the test project api component should no longer exist in the workspace baseline", component); //$NON-NLS-1$ |
| } |
| |
| /** |
| * Tests that opening an API aware project causes the workspace description |
| * to be updated |
| */ |
| @Test |
| public void testWPUpdateProjectOpen() throws Exception { |
| IJavaProject project = getTestingProject(); |
| assertNotNull("The testing project must exist", project); //$NON-NLS-1$ |
| if (project.getProject().isAccessible()) { |
| project.getProject().close(new NullProgressMonitor()); |
| } |
| project.getProject().open(new NullProgressMonitor()); |
| IApiBaseline baseline = getWorkspaceBaseline(); |
| assertNotNull("the workspace baseline must not be null", baseline); //$NON-NLS-1$ |
| IApiComponent component = baseline.getApiComponent(TESTING_PLUGIN_PROJECT_NAME); |
| assertNotNull("the test project api component must exist in the workspace baseline", component); //$NON-NLS-1$ |
| } |
| |
| /** |
| * Tests that adding a source file to an API aware project causes the |
| * workspace description to be updated This test adds |
| * <code>a.b.c.TestClass1</code> to the plug-in project |
| */ |
| @Test |
| public void testWPUpdateSourceAdded() throws Exception { |
| IJavaProject project = getTestingProject(); |
| assertNotNull("The testing project must exist", project); //$NON-NLS-1$ |
| IPackageFragmentRoot root = project.findPackageFragmentRoot(new Path(project.getElementName()).append(ProjectUtils.SRC_FOLDER).makeAbsolute().makeAbsolute()); |
| assertNotNull("the 'src' package fragment root must exist", root); //$NON-NLS-1$ |
| assertTestSource(root, TESTING_PACKAGE, "TestClass1"); //$NON-NLS-1$ |
| assertSourceResctriction(TESTING_PACKAGE, "TestClass1", RestrictionModifiers.NO_INSTANTIATE); //$NON-NLS-1$ |
| } |
| |
| /** |
| * Tests that removing a source file from an API aware project causes the |
| * workspace description to be updated |
| */ |
| @Test |
| public void testWPUpdateSourceRemoved() throws Exception { |
| IJavaProject project = getTestingProject(); |
| assertNotNull("The testing project must exist", project); //$NON-NLS-1$ |
| IPackageFragmentRoot root = project.findPackageFragmentRoot(new Path(project.getElementName()).append(ProjectUtils.SRC_FOLDER).makeAbsolute()); |
| assertNotNull("the 'src' package fragment root must exist", root); //$NON-NLS-1$ |
| assertTestSource(root, TESTING_PACKAGE, "TestClass1"); //$NON-NLS-1$ |
| IJavaElement element = project.findElement(new Path("a/b/c/TestClass1.java")); //$NON-NLS-1$ |
| assertNotNull("the class a.b.c.TestClass1 must exist in the project", element); //$NON-NLS-1$ |
| element.getResource().delete(true, new NullProgressMonitor()); |
| IApiDescription desc = getTestProjectApiDescription(); |
| assertNotNull("the testing project api description must exist", desc); //$NON-NLS-1$ |
| IApiAnnotations annot = desc.resolveAnnotations(Factory.typeDescriptor("a.b.c.TestClass1")); //$NON-NLS-1$ |
| assertNull("the annotations for a.b.c.TestClass1 should no longer be present", annot); //$NON-NLS-1$ |
| } |
| |
| /** |
| * Adds the specified tag to the source member defined by the member name |
| * and signature |
| * |
| * @param unit |
| * @param membername |
| * @param signature |
| * @param tagname |
| * @param remove |
| * @throws CoreException |
| * @throws MalformedTreeException |
| * @throws BadLocationException |
| */ |
| private void updateTagInSource(ICompilationUnit unit, String membername, String signature, String tagname, boolean remove) throws CoreException, MalformedTreeException, BadLocationException { |
| ASTParser parser = ASTParser.newParser(AST.JLS_Latest); |
| parser.setSource(unit); |
| CompilationUnit cunit = (CompilationUnit) parser.createAST(new NullProgressMonitor()); |
| assertNotNull("the ast compilation unit cannot be null", cunit); //$NON-NLS-1$ |
| cunit.recordModifications(); |
| ASTRewrite rewrite = ASTRewrite.create(cunit.getAST()); |
| cunit.accept(new SourceChangeVisitor(membername, signature, tagname, remove, rewrite)); |
| ITextFileBufferManager bm = FileBuffers.getTextFileBufferManager(); |
| IPath path = cunit.getJavaElement().getPath(); |
| try { |
| bm.connect(path, LocationKind.IFILE, null); |
| ITextFileBuffer tfb = bm.getTextFileBuffer(path, LocationKind.IFILE); |
| IDocument document = tfb.getDocument(); |
| TextEdit edits = rewrite.rewriteAST(document, null); |
| edits.apply(document); |
| tfb.commit(new NullProgressMonitor(), true); |
| } finally { |
| bm.disconnect(path, LocationKind.IFILE, null); |
| } |
| } |
| |
| /** |
| * Tests that making Javadoc changes to the source file TestClass2 cause the |
| * workspace baseline to be updated. |
| * |
| * This test adds a @noinstantiate tag to the source file TestClass2 |
| */ |
| @Test |
| public void testWPUpdateSourceTypeChanged() throws Exception { |
| IJavaProject project = getTestingProject(); |
| assertNotNull("The testing project must exist", project); //$NON-NLS-1$ |
| IPackageFragmentRoot root = project.findPackageFragmentRoot(new Path(project.getElementName()).append(ProjectUtils.SRC_FOLDER).makeAbsolute()); |
| assertNotNull("the 'src' package fragment root must exist", root); //$NON-NLS-1$ |
| NullProgressMonitor monitor = new NullProgressMonitor(); |
| IPackageFragment fragment = root.getPackageFragment("a.b.c"); //$NON-NLS-1$ |
| FileUtils.importFileFromDirectory(SRC_LOC.append("TestClass2.java").toFile(), fragment.getPath(), monitor); //$NON-NLS-1$ |
| ICompilationUnit element = (ICompilationUnit) project.findElement(new Path("a/b/c/TestClass2.java")); //$NON-NLS-1$ |
| assertNotNull("TestClass2 must exist in the test project", element); //$NON-NLS-1$ |
| updateTagInSource(element, "TestClass2", null, "@noinstantiate", false); //$NON-NLS-1$ //$NON-NLS-2$ |
| IApiDescription desc = getTestProjectApiDescription(); |
| assertNotNull("the testing project api description must exist", desc); //$NON-NLS-1$ |
| IApiAnnotations annot = desc.resolveAnnotations(Factory.typeDescriptor("a.b.c.TestClass2")); //$NON-NLS-1$ |
| assertNotNull("the annotations for a.b.c.TestClass2 cannot be null", annot); //$NON-NLS-1$ |
| assertTrue("there must be a noinstantiate setting for TestClass2", (annot.getRestrictions() & RestrictionModifiers.NO_INSTANTIATE) != 0); //$NON-NLS-1$ |
| assertTrue("there must be a noextend setting for TestClass2", (annot.getRestrictions() & RestrictionModifiers.NO_EXTEND) != 0); //$NON-NLS-1$ |
| } |
| |
| /** |
| * Tests that tags updated on an inner type are updated in the workspace |
| * description. |
| * |
| * This test adds a @noinstantiate tag to an inner class in TestClass3 |
| */ |
| @Test |
| public void testWPUpdateSourceInnerTypeChanged() throws Exception { |
| IJavaProject project = getTestingProject(); |
| assertNotNull("The testing project must exist", project); //$NON-NLS-1$ |
| IPackageFragmentRoot root = project.findPackageFragmentRoot(new Path(project.getElementName()).append(ProjectUtils.SRC_FOLDER).makeAbsolute()); |
| assertNotNull("the 'src' package fragment root must exist", root); //$NON-NLS-1$ |
| assertTestSource(root, TESTING_PACKAGE, "TestClass3"); //$NON-NLS-1$ |
| ICompilationUnit element = (ICompilationUnit) project.findElement(new Path("a/b/c/TestClass3.java")); //$NON-NLS-1$ |
| assertNotNull("TestClass3 must exist in the test project", element); //$NON-NLS-1$ |
| updateTagInSource(element, "InnerTestClass3", null, "@noinstantiate", false); //$NON-NLS-1$ //$NON-NLS-2$ |
| IApiDescription desc = getTestProjectApiDescription(); |
| assertNotNull("the testing project api description must exist", desc); //$NON-NLS-1$ |
| IApiAnnotations annot = desc.resolveAnnotations(Factory.typeDescriptor("a.b.c.TestClass3$InnerTestClass3")); //$NON-NLS-1$ |
| assertNotNull("the annotations for a.b.c.TestClass3$InnerTestClass3 cannot be null", annot); //$NON-NLS-1$ |
| assertFalse("there must not be a noinstantiate setting for TestClass3$InnerTestClass3", (annot.getRestrictions() & RestrictionModifiers.NO_INSTANTIATE) != 0); //$NON-NLS-1$ |
| assertFalse("there must not be a noextend setting for TestClass3$InnerTestClass3", (annot.getRestrictions() & RestrictionModifiers.NO_EXTEND) != 0); //$NON-NLS-1$ |
| } |
| |
| /** |
| * Tests that changing the javadoc for a method updates the workspace |
| * baseline |
| * |
| * This test adds a @noextend tag to the method foo() in TestClass1 |
| */ |
| @Test |
| public void testWPUpdateSourceMethodChanged() throws Exception { |
| IJavaProject project = getTestingProject(); |
| assertNotNull("The testing project must exist", project); //$NON-NLS-1$ |
| IPackageFragmentRoot root = project.findPackageFragmentRoot(new Path(project.getElementName()).append(ProjectUtils.SRC_FOLDER).makeAbsolute()); |
| assertNotNull("the 'src' package fragment root must exist", root); //$NON-NLS-1$ |
| assertTestSource(root, TESTING_PACKAGE, "TestClass1"); //$NON-NLS-1$ |
| ICompilationUnit element = (ICompilationUnit) project.findElement(new Path("a/b/c/TestClass1.java")); //$NON-NLS-1$ |
| assertNotNull("TestClass1 must exist in the test project", element); //$NON-NLS-1$ |
| updateTagInSource(element, "foo", "()V", "@nooverride", false); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
| IApiDescription desc = getTestProjectApiDescription(); |
| assertNotNull("the testing project api description must exist", desc); //$NON-NLS-1$ |
| IApiAnnotations annot = desc.resolveAnnotations(Factory.methodDescriptor("a.b.c.TestClass1", "foo", "()V")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
| assertNotNull("the annotations for foo() cannot be null", annot); //$NON-NLS-1$ |
| assertTrue("there must be a nooverride setting for foo()", (annot.getRestrictions() & RestrictionModifiers.NO_OVERRIDE) != 0); //$NON-NLS-1$ |
| } |
| |
| /** |
| * Tests that changing the javadoc for a field updates the workspace |
| * baseline |
| * |
| * This test adds a @noextend tag to the field 'field' in TestField9 |
| */ |
| @Test |
| public void testWPUpdateSourceFieldChanged() throws Exception { |
| IJavaProject project = getTestingProject(); |
| assertNotNull("The testing project must exist", project); //$NON-NLS-1$ |
| IPackageFragmentRoot root = project.findPackageFragmentRoot(new Path(project.getElementName()).append(ProjectUtils.SRC_FOLDER).makeAbsolute()); |
| assertNotNull("the 'src' package fragment root must exist", root); //$NON-NLS-1$ |
| assertTestSource(root, TESTING_PACKAGE, "TestField9"); //$NON-NLS-1$ |
| ICompilationUnit element = (ICompilationUnit) project.findElement(new Path("a/b/c/TestField9.java")); //$NON-NLS-1$ |
| assertNotNull("TestField9 must exist in the test project", element); //$NON-NLS-1$ |
| updateTagInSource(element, "field", null, "@noreference", false); //$NON-NLS-1$ //$NON-NLS-2$ |
| IApiDescription desc = getTestProjectApiDescription(); |
| assertNotNull("the testing project api description must exist", desc); //$NON-NLS-1$ |
| IApiAnnotations annot = desc.resolveAnnotations(Factory.fieldDescriptor("a.b.c.TestField9", "field")); //$NON-NLS-1$ //$NON-NLS-2$ |
| assertNotNull("the annotations for 'field' cannot be null", annot); //$NON-NLS-1$ |
| assertTrue("there must be a noreference setting for 'field'", (annot.getRestrictions() & RestrictionModifiers.NO_REFERENCE) != 0); //$NON-NLS-1$ |
| } |
| |
| /** |
| * Tests that removing a tag from a method updates the workspace baseline |
| * |
| * This test removes a @noextend tag to the method foo() in TestClass1 |
| */ |
| @Test |
| public void testWPUpdateSourceMethodRemoveTag() throws Exception { |
| IJavaProject project = getTestingProject(); |
| assertNotNull("The testing project must exist", project); //$NON-NLS-1$ |
| IPackageFragmentRoot root = project.findPackageFragmentRoot(new Path(project.getElementName()).append(ProjectUtils.SRC_FOLDER).makeAbsolute()); |
| assertNotNull("the 'src' package fragment root must exist", root); //$NON-NLS-1$ |
| assertTestSource(root, TESTING_PACKAGE, "TestClass1"); //$NON-NLS-1$ |
| ICompilationUnit element = (ICompilationUnit) project.findElement(new Path("a/b/c/TestClass1.java")); //$NON-NLS-1$ |
| assertNotNull("TestClass1 must exist in the test project", element); //$NON-NLS-1$ |
| updateTagInSource(element, "foo", "()V", "@nooverride", true); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
| IApiDescription desc = getTestProjectApiDescription(); |
| assertNotNull("the testing project api description must exist", desc); //$NON-NLS-1$ |
| IApiAnnotations annot = desc.resolveAnnotations(Factory.methodDescriptor("a.b.c.TestClass1", "foo", "()V")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
| assertNotNull("the annotations for foo() cannot be null", annot); //$NON-NLS-1$ |
| assertTrue("there must be no restrictions for foo()", annot.getRestrictions() == 0); //$NON-NLS-1$ |
| } |
| |
| /** |
| * Tests that removing a tag from a type updates the workspace baseline |
| * |
| * This test removes a @noinstantiate tag to an inner class in TestClass3 |
| */ |
| @Test |
| public void testWPUpdateSourceTypeRemoveTag() throws Exception { |
| IJavaProject project = getTestingProject(); |
| assertNotNull("The testing project must exist", project); //$NON-NLS-1$ |
| IPackageFragmentRoot root = project.findPackageFragmentRoot(new Path(project.getElementName()).append(ProjectUtils.SRC_FOLDER).makeAbsolute()); |
| assertNotNull("the 'src' package fragment root must exist", root); //$NON-NLS-1$ |
| assertTestSource(root, TESTING_PACKAGE, "TestClass3"); //$NON-NLS-1$ |
| ICompilationUnit element = (ICompilationUnit) project.findElement(new Path("a/b/c/TestClass3.java")); //$NON-NLS-1$ |
| assertNotNull("TestClass3 must exist in the test project", element); //$NON-NLS-1$ |
| updateTagInSource(element, "InnerTestClass3", null, "@noextend", true); //$NON-NLS-1$ //$NON-NLS-2$ |
| IApiDescription desc = getTestProjectApiDescription(); |
| assertNotNull("the testing project api description must exist", desc); //$NON-NLS-1$ |
| IApiAnnotations annot = desc.resolveAnnotations(Factory.typeDescriptor("a.b.c.TestClass3$InnerTestClass3")); //$NON-NLS-1$ |
| assertNotNull("the annotations for 'InnerTestClass3' cannot be null", annot); //$NON-NLS-1$ |
| assertTrue("there must be a no restrictions for 'InnerTestClass3'", (annot.getRestrictions() & RestrictionModifiers.NO_INSTANTIATE) == 0); //$NON-NLS-1$ |
| } |
| |
| /** |
| * Tests that removing a tag from a field updates the workspace baseline |
| * |
| * This test adds a @noextend tag to the field 'field' in TestField9 |
| */ |
| @Test |
| public void testWPUpdateSourceFieldRemoveTag() throws Exception { |
| IJavaProject project = getTestingProject(); |
| assertNotNull("The testing project must exist", project); //$NON-NLS-1$ |
| IPackageFragmentRoot root = project.findPackageFragmentRoot(new Path(project.getElementName()).append(ProjectUtils.SRC_FOLDER).makeAbsolute()); |
| assertNotNull("the 'src' package fragment root must exist", root); //$NON-NLS-1$ |
| assertTestSource(root, TESTING_PACKAGE, "TestField9"); //$NON-NLS-1$ |
| ICompilationUnit element = (ICompilationUnit) project.findElement(new Path("a/b/c/TestField9.java")); //$NON-NLS-1$ |
| assertNotNull("TestField9 must exist in the test project", element); //$NON-NLS-1$ |
| updateTagInSource(element, "field1", null, "@noreference", true); //$NON-NLS-1$ //$NON-NLS-2$ |
| IApiDescription desc = getTestProjectApiDescription(); |
| assertNotNull("the testing project api description must exist", desc); //$NON-NLS-1$ |
| IApiAnnotations annot = desc.resolveAnnotations(Factory.fieldDescriptor("a.b.c.TestField9", "field")); //$NON-NLS-1$ //$NON-NLS-2$ |
| assertNotNull("the annotations for 'field' cannot be null", annot); //$NON-NLS-1$ |
| assertTrue("there must be a no restrictions for 'field'", annot.getRestrictions() == 0); //$NON-NLS-1$ |
| } |
| |
| /** |
| * Tests that a library added to the build and bundle class path of a |
| * project causes the class file containers for the project to need to be |
| * recomputed |
| * |
| * @throws IOException |
| * @throws InvocationTargetException |
| * @throws CoreException |
| */ |
| @Test |
| public void testWPUpdateLibraryAddedToClasspath() throws Exception { |
| IFolder folder = null; |
| try { |
| IJavaProject project = getTestingProject(); |
| assertNotNull("The testing project must exist", project); //$NON-NLS-1$ |
| IApiComponent component = getWorkspaceBaseline().getApiComponent(project.getElementName()); |
| assertNotNull("the workspace component must exist", component); //$NON-NLS-1$ |
| int before = component.getApiTypeContainers().length; |
| |
| // add to classpath |
| folder = assertTestLibrary(project, new Path("libx"), "component.a_1.0.0.jar"); //$NON-NLS-1$ //$NON-NLS-2$ |
| assertNotNull("The new library path should not be null", folder); //$NON-NLS-1$ |
| |
| // re-retrieve updated component |
| component = getWorkspaceBaseline().getApiComponent(project.getElementName()); |
| assertTrue("there must be more containers after the addition", before < component.getApiTypeContainers().length); //$NON-NLS-1$ |
| } finally { |
| if (folder != null) { |
| FileUtils.delete(folder); |
| } |
| } |
| } |
| |
| /** |
| * Tests removing a library from the classpath of a project |
| */ |
| @Test |
| public void testWPUpdateLibraryRemovedFromClasspath() throws Exception { |
| IPath libPath = null; |
| try { |
| IJavaProject project = getTestingProject(); |
| assertNotNull("The testing project must exist", project); //$NON-NLS-1$ |
| |
| // add to classpath |
| IFolder folder = assertTestLibrary(project, new Path("libx"), "component.a_1.0.0.jar"); //$NON-NLS-1$ //$NON-NLS-2$ |
| IApiComponent component = getWorkspaceBaseline().getApiComponent(project.getElementName()); |
| assertNotNull("the workspace component must exist", component); //$NON-NLS-1$ |
| int before = component.getApiTypeContainers().length; |
| libPath = folder.getFullPath().append("component.a_1.0.0.jar"); //$NON-NLS-1$ |
| |
| // remove classpath entry |
| ProjectUtils.removeFromClasspath(project, JavaCore.newLibraryEntry(libPath, null, null)); |
| waitForAutoBuild(); |
| |
| // remove from bundle class path |
| IBundleProjectService service = ProjectUtils.getBundleProjectService(); |
| IBundleProjectDescription description = service.getDescription(project.getProject()); |
| description.setBundleClasspath(new IBundleClasspathEntry[] { service.newBundleClasspathEntry(new Path(ProjectUtils.SRC_FOLDER), null, null) }); |
| description.apply(null); |
| waitForAutoBuild(); |
| |
| // retrieve updated component |
| component = getWorkspaceBaseline().getApiComponent(project.getElementName()); |
| assertTrue("there must be less containers after the removal", before > component.getApiTypeContainers().length); //$NON-NLS-1$ |
| } finally { |
| if (libPath != null) { |
| FileUtils.delete(libPath.toOSString()); |
| } |
| } |
| } |
| |
| /** |
| * Tests that changing the output folder settings for a project cause the |
| * class file containers to be updated |
| */ |
| @Test |
| public void testWPUpdateDefaultOutputFolderChanged() throws Exception { |
| IJavaProject project = getTestingProject(); |
| assertNotNull("The testing project must exist", project); //$NON-NLS-1$ |
| IContainer container = ProjectUtils.addFolderToProject(project.getProject(), "bin2"); //$NON-NLS-1$ |
| assertNotNull("the new output folder cannot be null", container); //$NON-NLS-1$ |
| IApiComponent component = getWorkspaceBaseline().getApiComponent(project.getElementName()); |
| assertNotNull("the workspace component must exist", component); //$NON-NLS-1$ |
| int before = component.getApiTypeContainers().length; |
| project.setOutputLocation(container.getFullPath(), new NullProgressMonitor()); |
| waitForAutoBuild(); |
| assertTrue("there must be the same number of containers after the change", before == component.getApiTypeContainers().length); //$NON-NLS-1$ |
| assertTrue("the new output location should be 'bin2'", "bin2".equalsIgnoreCase(project.getOutputLocation().toFile().getName())); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| |
| /** |
| * Tests that the output folder settings for a source folder cause the class |
| * file containers to be updated |
| */ |
| @Test |
| public void testWPUpdateOutputFolderSrcFolderChanged() throws Exception { |
| IJavaProject project = getTestingProject(); |
| IApiComponent component = getWorkspaceBaseline().getApiComponent(project.getElementName()); |
| assertNotNull("the workspace component must exist", component); //$NON-NLS-1$ |
| int before = component.getApiTypeContainers().length; |
| |
| ProjectUtils.addFolderToProject(project.getProject(), "bin3"); //$NON-NLS-1$ |
| IContainer container = ProjectUtils.addFolderToProject(project.getProject(), "src2"); //$NON-NLS-1$ |
| // add to bundle class path |
| IBundleProjectService service = ProjectUtils.getBundleProjectService(); |
| IBundleClasspathEntry next = service.newBundleClasspathEntry(new Path("src2"), new Path("bin3"), new Path("next.jar")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
| ProjectUtils.addBundleClasspathEntry(project.getProject(), next); |
| waitForAutoBuild(); |
| |
| // retrieve updated component |
| component = getWorkspaceBaseline().getApiComponent(project.getElementName()); |
| assertTrue("there must be one more container after the change", before < component.getApiTypeContainers().length); //$NON-NLS-1$ |
| IPackageFragmentRoot root = project.getPackageFragmentRoot(container); |
| assertTrue("the class file container for src2 must be 'bin3'", "bin3".equals(root.getRawClasspathEntry().getOutputLocation().toFile().getName())); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| |
| /** |
| * Tests that adding a package does not update the workspace baseline |
| */ |
| @Test |
| public void testWPUpdatePackageAdded() throws Exception { |
| IJavaProject project = getTestingProject(); |
| assertNotNull("The testing project must exist", project); //$NON-NLS-1$ |
| |
| // add the package |
| assertTestPackage(project, new Path(project.getElementName()).append(ProjectUtils.SRC_FOLDER).makeAbsolute(), "a.test1.c.d"); //$NON-NLS-1$ |
| |
| IApiDescription desc = getTestProjectApiDescription(); |
| assertNotNull("the testing project api description must exist", desc); //$NON-NLS-1$ |
| IApiAnnotations annot = desc.resolveAnnotations(Factory.packageDescriptor("a.test1.c.d")); //$NON-NLS-1$ |
| assertNotNull("the annotations for package " + TESTING_PACKAGE + " should exist", annot); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| |
| /** |
| * Tests that removing a package updates the workspace baseline This test |
| * removes the a.b.c package being used in all tests thus far, and should be |
| * run last |
| */ |
| @Test |
| public void testWPUpdatePackageRemoved() throws Exception { |
| IJavaProject project = getTestingProject(); |
| assertNotNull("The testing project must exist", project); //$NON-NLS-1$ |
| |
| // add the package |
| IPath srcroot = new Path(project.getElementName()).append(ProjectUtils.SRC_FOLDER).makeAbsolute(); |
| IPackageFragment fragment = assertTestPackage(project, srcroot, "a.test2"); //$NON-NLS-1$ |
| assertNotNull("the package " + TESTING_PACKAGE + " must exist", fragment); //$NON-NLS-1$ //$NON-NLS-2$ |
| |
| // remove the package |
| fragment.delete(true, new NullProgressMonitor()); |
| |
| IApiDescription desc = getTestProjectApiDescription(); |
| assertNotNull("the testing project api description must exist", desc); //$NON-NLS-1$ |
| IApiAnnotations annot = desc.resolveAnnotations(Factory.packageDescriptor("a.test2")); //$NON-NLS-1$ |
| assertNull("the annotations for package " + TESTING_PACKAGE + " should not exist", annot); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| |
| /** |
| * Tests that an exported package addition in the PDE model is reflected in |
| * the workspace api baseline |
| */ |
| @Test |
| public void testWPUpdateExportPackageAdded() throws Exception { |
| IJavaProject project = getTestingProject(); |
| assertNotNull("The testing project must exist", project); //$NON-NLS-1$ |
| |
| // add package |
| assertTestPackage(project, new Path(project.getElementName()).append(ProjectUtils.SRC_FOLDER).makeAbsolute(), "export1"); //$NON-NLS-1$ |
| |
| // update |
| setPackageToApi(project, "export1"); //$NON-NLS-1$ |
| IApiAnnotations annot = getTestProjectApiDescription().resolveAnnotations(Factory.packageDescriptor("export1")); //$NON-NLS-1$ |
| assertNotNull("there must be an annotation for the new exported package", annot); //$NON-NLS-1$ |
| assertTrue("the newly exported package must be API visibility", annot.getVisibility() == VisibilityModifiers.API); //$NON-NLS-1$ |
| } |
| |
| /** |
| * Tests that changing a directive to x-internal on an exported package |
| * causes the workspace api baseline to be updated |
| */ |
| @Test |
| public void testWPUPdateExportPackageDirectiveChangedToInternal() throws Exception { |
| IJavaProject project = getTestingProject(); |
| assertNotNull("The testing project must exist", project); //$NON-NLS-1$ |
| |
| // add package |
| assertTestPackage(project, new Path(project.getElementName()).append(ProjectUtils.SRC_FOLDER).makeAbsolute(), "export1"); //$NON-NLS-1$ |
| |
| // export the package |
| ProjectUtils.addExportedPackage(project.getProject(), "export1", true, null); //$NON-NLS-1$ |
| |
| // check the description |
| IApiAnnotations annot = getTestProjectApiDescription().resolveAnnotations(Factory.packageDescriptor("export1")); //$NON-NLS-1$ |
| assertNotNull("there must be an annotation for the new exported package", annot); //$NON-NLS-1$ |
| assertTrue("the changed exported package must be PRIVATE visibility", annot.getVisibility() == VisibilityModifiers.PRIVATE); //$NON-NLS-1$ |
| } |
| |
| /** |
| * Tests that an exported package removal in the PDE model is reflected in |
| * the workspace api baseline |
| */ |
| @Test |
| public void testWPUpdateExportPackageRemoved() throws Exception { |
| IJavaProject project = getTestingProject(); |
| assertNotNull("The testing project must exist", project); //$NON-NLS-1$ |
| |
| // add package |
| assertTestPackage(project, new Path(project.getElementName()).append(ProjectUtils.SRC_FOLDER).makeAbsolute(), "export1"); //$NON-NLS-1$ |
| |
| setPackageToApi(project, "export1"); //$NON-NLS-1$ |
| IApiAnnotations annot = getTestProjectApiDescription().resolveAnnotations(Factory.packageDescriptor("export1")); //$NON-NLS-1$ |
| assertNotNull("there must be an annotation for the new exported package", annot); //$NON-NLS-1$ |
| assertTrue("the newly exported package must be API visibility", annot.getVisibility() == VisibilityModifiers.API); //$NON-NLS-1$ |
| |
| // remove exported packages |
| IBundleProjectService service = ProjectUtils.getBundleProjectService(); |
| IBundleProjectDescription description = service.getDescription(project.getProject()); |
| description.setPackageExports(null); |
| description.apply(null); |
| |
| // check the API description |
| annot = getTestProjectApiDescription().resolveAnnotations(Factory.packageDescriptor("export1")); //$NON-NLS-1$ |
| assertNotNull("should still be an annotation for the package", annot); //$NON-NLS-1$ |
| assertTrue("unexported package must be private", VisibilityModifiers.isPrivate(annot.getVisibility())); //$NON-NLS-1$ |
| } |
| |
| /** |
| * sets the given package name to be an Exported-Package |
| * |
| * @param name |
| */ |
| private void setPackageToApi(IJavaProject project, String name) throws CoreException { |
| ProjectUtils.addExportedPackage(project.getProject(), name, false, null); |
| } |
| |
| IJavaProject getTestingProject() { |
| return JavaCore.create(ResourcesPlugin.getWorkspace().getRoot().getProject(TESTING_PLUGIN_PROJECT_NAME)); |
| } |
| |
| @Before |
| public void setUp() throws Exception { |
| createProject(TESTING_PLUGIN_PROJECT_NAME, new String[] { TESTING_PACKAGE }); |
| setPackageToApi(getTestingProject(), TESTING_PACKAGE); |
| } |
| |
| @After |
| public void tearDown() throws Exception { |
| deleteProject(TESTING_PLUGIN_PROJECT_NAME); |
| getWorkspaceBaseline().dispose(); |
| } |
| } |