| /******************************************************************************* |
| * Copyright (c) 2005, 2017 IBM Corporation and others. |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0. |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| *******************************************************************************/ |
| package org.eclipse.dltk.core.tests.model; |
| |
| import java.io.BufferedInputStream; |
| import java.io.BufferedOutputStream; |
| import java.io.File; |
| import java.io.FileOutputStream; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.OutputStream; |
| import java.net.URL; |
| |
| import org.eclipse.core.resources.IContainer; |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IFolder; |
| import org.eclipse.core.resources.IMarker; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IProjectDescription; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.IResourceDelta; |
| import org.eclipse.core.resources.IWorkspace; |
| import org.eclipse.core.resources.IWorkspaceRoot; |
| import org.eclipse.core.resources.IWorkspaceRunnable; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.FileLocator; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.dltk.compiler.problem.IProblem; |
| import org.eclipse.dltk.core.DLTKCore; |
| import org.eclipse.dltk.core.ElementChangedEvent; |
| import org.eclipse.dltk.core.IBuildpathAttribute; |
| import org.eclipse.dltk.core.IBuildpathEntry; |
| import org.eclipse.dltk.core.IElementChangedListener; |
| import org.eclipse.dltk.core.IModelElement; |
| import org.eclipse.dltk.core.IModelElementDelta; |
| import org.eclipse.dltk.core.IParent; |
| import org.eclipse.dltk.core.IProblemRequestor; |
| import org.eclipse.dltk.core.IProjectFragment; |
| import org.eclipse.dltk.core.IScriptFolder; |
| import org.eclipse.dltk.core.IScriptModel; |
| import org.eclipse.dltk.core.IScriptModelMarker; |
| import org.eclipse.dltk.core.IScriptProject; |
| import org.eclipse.dltk.core.ISourceModule; |
| import org.eclipse.dltk.core.ModelException; |
| import org.eclipse.dltk.core.WorkingCopyOwner; |
| import org.eclipse.dltk.core.tests.FileUtil; |
| import org.eclipse.dltk.core.tests.WorkspaceAutoBuild; |
| import org.eclipse.dltk.internal.core.BuildpathEntry; |
| import org.eclipse.dltk.internal.core.ModelElement; |
| import org.eclipse.dltk.internal.core.ModelManager; |
| import org.eclipse.dltk.internal.core.util.Util; |
| import org.eclipse.dltk.internal.core.util.Util.Comparer; |
| import org.eclipse.osgi.util.NLS; |
| import org.osgi.framework.Bundle; |
| |
| public abstract class AbstractModelTests extends SuiteOfTestCases { |
| protected boolean displayName = false; |
| protected String endChar = ","; |
| |
| // infos for invalid results |
| protected int tabs = 2; |
| |
| // working copies usage |
| protected ISourceModule[] workingCopies; |
| |
| protected WorkingCopyOwner wcOwner; |
| |
| protected boolean discard; |
| |
| protected String fTestProjectName = "org.eclipse.dltk.core.tests"; |
| |
| class DeltaListener implements IElementChangedListener { |
| IModelElementDelta[] deltas; |
| |
| @Override |
| public void elementChanged(ElementChangedEvent ev) { |
| IModelElementDelta[] copy = new IModelElementDelta[deltas.length + 1]; |
| System.arraycopy(deltas, 0, copy, 0, deltas.length); |
| copy[deltas.length] = ev.getDelta(); |
| deltas = copy; |
| } |
| |
| @Override |
| public String toString() { |
| StringBuffer buffer = new StringBuffer(); |
| for (int i = 0, length = this.deltas.length; i < length; i++) { |
| IModelElementDelta delta = this.deltas[i]; |
| IModelElementDelta[] children = delta.getAffectedChildren(); |
| int childrenLength = children.length; |
| IResourceDelta[] resourceDeltas = delta.getResourceDeltas(); |
| int resourceDeltasLength = resourceDeltas == null ? 0 : resourceDeltas.length; |
| if (childrenLength == 0 && resourceDeltasLength == 0) { |
| buffer.append(delta); |
| } else { |
| sortDeltas(children); |
| for (int j = 0; j < childrenLength; j++) { |
| buffer.append(children[j]); |
| if (j != childrenLength - 1) { |
| buffer.append("\n"); |
| } |
| } |
| for (int j = 0; j < resourceDeltasLength; j++) { |
| if (j == 0 && buffer.length() != 0) { |
| buffer.append("\n"); |
| } |
| buffer.append(resourceDeltas[j]); |
| if (j != resourceDeltasLength - 1) { |
| buffer.append("\n"); |
| } |
| } |
| } |
| if (i != length - 1) { |
| buffer.append("\n\n"); |
| |
| } |
| } |
| return buffer.toString(); |
| } |
| |
| protected void sortDeltas(IModelElementDelta[] elementDeltas) { |
| Comparer comparer = (a, b) -> { |
| IModelElementDelta deltaA = (IModelElementDelta) a; |
| IModelElementDelta deltaB = (IModelElementDelta) b; |
| return deltaA.getElement().getElementName().compareTo(deltaB.getElement().getElementName()); |
| }; |
| org.eclipse.dltk.internal.core.util.Util.sort(elementDeltas, comparer); |
| } |
| } |
| |
| protected DeltaListener deltaListener = new DeltaListener(); |
| |
| public AbstractModelTests(String name) { |
| super(name); |
| } |
| |
| public AbstractModelTests(String name, int tabs) { |
| super(name); |
| this.tabs = tabs; |
| } |
| |
| @Override |
| protected void setUp() throws Exception { |
| super.setUp(); |
| if (this.discard) { |
| this.workingCopies = null; |
| } |
| this.discard = true; |
| } |
| |
| @Override |
| protected void tearDown() throws Exception { |
| super.tearDown(); |
| if (this.discard && this.workingCopies != null) { |
| discardWorkingCopies(this.workingCopies); |
| this.wcOwner = null; |
| } |
| } |
| |
| public File getSourceWorkspacePath(String bundleName) { |
| return new File(getPluginDirectoryPath(bundleName), "workspace"); |
| } |
| |
| /** |
| * Returns the OS path to the directory that contains this plugin. |
| * |
| * @param bundleName |
| */ |
| protected File getPluginDirectoryPath(String bundleName) { |
| try { |
| final Bundle bundle = Platform.getBundle(bundleName); |
| if (bundle == null) { |
| throw new IllegalStateException(NLS.bind("Bundle \"{0}\" with test data not found", bundleName)); |
| } |
| URL platformURL = bundle.getEntry("/"); |
| return new File(FileLocator.toFileURL(platformURL).getFile()); |
| } catch (IOException e) { |
| e.printStackTrace(); |
| } |
| return null; |
| } |
| |
| /** |
| * Copy the given source directory (and all its contents) to the given target |
| * directory. |
| */ |
| protected void copyDirectory(File source, File target) throws IOException { |
| FileUtil.copyDirectory(source, target); |
| } |
| |
| /** |
| * Copy file from src (path to the original file) to dest (path to the |
| * destination file). |
| */ |
| public static void copy(File src, File dest) throws IOException { |
| FileUtil.copyFile(src, dest); |
| } |
| |
| public IProject setUpProject(final String projectName, String bundleName) throws CoreException, IOException { |
| return setUpProjectTo(projectName, projectName, bundleName); |
| } |
| |
| protected IScriptProject setUpScriptProjectTo(final String projectName, final String fromName, String bundleName) |
| throws CoreException, IOException { |
| final IProject project = setUpProjectTo(projectName, fromName, bundleName); |
| return DLTKCore.create(project); |
| } |
| |
| protected IProject setUpProjectTo(final String projectName, final String fromName, String bundleName) |
| throws CoreException, IOException { |
| // copy files in project from source workspace to target workspace |
| final File sourceWorkspacePath = getSourceWorkspacePath(bundleName); |
| final File targetWorkspacePath = getWorkspaceRoot().getLocation().toFile(); |
| |
| final File source = new File(sourceWorkspacePath, fromName); |
| if (!source.isDirectory()) { |
| throw new IllegalArgumentException(NLS.bind("Source directory \"{0}\" doesn't exist", source)); |
| } |
| copyDirectory(source, new File(targetWorkspacePath, projectName)); |
| |
| return createProject(projectName); |
| } |
| |
| protected IScriptProject setUpScriptProject(final String projectName, String bundleName) |
| throws CoreException, IOException { |
| final IProject project = setUpProject(projectName, bundleName); |
| return DLTKCore.create(project); |
| } |
| |
| /** |
| * Returns the specified source module in the given project, root, and folder or |
| * <code>null</code> if it does not exist. |
| */ |
| public ISourceModule getSourceModule(String projectName, String rootPath, IPath path) throws ModelException { |
| IScriptFolder folder = getScriptFolder(projectName, rootPath, path.removeLastSegments(1)); |
| if (folder == null) { |
| return null; |
| } |
| return folder.getSourceModule(path.lastSegment()); |
| } |
| |
| public ISourceModule getSourceModule(String projectName, String rootPath, String path) throws ModelException { |
| IScriptFolder folder = getScriptFolder(projectName, rootPath, new Path(path).removeLastSegments(1)); |
| if (folder == null) { |
| return null; |
| } |
| return folder.getSourceModule(new Path(path).lastSegment().toString()); |
| } |
| |
| /** |
| * Returns the specified script folder in the given project and fragment, or |
| * <code>null</code> if it does not exist. The rootPath must be specified as a |
| * project relative path. The empty path refers to the default package fragment. |
| */ |
| public IScriptFolder getScriptFolder(String projectName, String fragmentPath, IPath path) throws ModelException { |
| IProjectFragment root = getProjectFragment(projectName, fragmentPath); |
| if (root == null) { |
| return null; |
| } |
| return root.getScriptFolder(path); |
| } |
| |
| /** |
| * Returns the specified package fragment root in the given project, or |
| * <code>null</code> if it does not exist. If relative, the rootPath must be |
| * specified as a project relative path. The empty path refers to the package |
| * fragment root that is the project folder iteslf. If absolute, the rootPath |
| * refers to either an external zip, or a resource internal to the workspace |
| */ |
| public IProjectFragment getProjectFragment(String projectName, String fragmentPath) throws ModelException { |
| |
| IScriptProject project = getScriptProject(projectName); |
| if (project == null) { |
| return null; |
| } |
| IPath path = Path.fromPortableString(fragmentPath); |
| if (path.isAbsolute() && path.getDevice() == null) { |
| IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); |
| IResource resource = workspaceRoot.findMember(path); |
| IProjectFragment root; |
| // resource in the workspace |
| root = project.getProjectFragment(resource); |
| return root; |
| } else { |
| IProjectFragment[] roots = project.getProjectFragments(); |
| if (roots == null || roots.length == 0) { |
| return null; |
| } |
| for (int i = 0; i < roots.length; i++) { |
| IProjectFragment root = roots[i]; |
| IResource underlyingResource = root.getUnderlyingResource(); |
| if (underlyingResource != null && underlyingResource.getProjectRelativePath().equals(path)) { |
| return root; |
| } |
| if (root.getPath().equals(path)) { |
| return root; |
| } |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Returns the script Project with the given name in this test suite's model. |
| * This is a convenience method. |
| */ |
| public IScriptProject getScriptProject(String name) { |
| IProject project = getProject(name); |
| return DLTKCore.create(project); |
| } |
| |
| protected void discardWorkingCopies(ISourceModule[] units) throws ModelException { |
| if (units == null) |
| return; |
| for (int i = 0, length = units.length; i < length; i++) |
| if (units[i] != null) |
| units[i].discardWorkingCopy(); |
| } |
| |
| @Override |
| public void setUpSuite() throws Exception { |
| super.setUpSuite(); |
| |
| // ensure autobuilding is turned off |
| WorkspaceAutoBuild.disable(); |
| } |
| |
| protected ISourceModule getSourceModule(String path) { |
| return (ISourceModule) DLTKCore.create(getFile(path)); |
| } |
| |
| protected IFile getFile(String path) { |
| return getWorkspaceRoot().getFile(new Path(path)); |
| } |
| |
| protected IFolder getFolder(IPath path) { |
| return getWorkspaceRoot().getFolder(path); |
| } |
| |
| protected void deleteFolder(IPath folderPath) throws CoreException { |
| deleteResource(getFolder(folderPath)); |
| } |
| |
| /** |
| * Returns the IWorkspace this test suite is running on. |
| */ |
| public static IWorkspace getWorkspace() { |
| return ResourcesPlugin.getWorkspace(); |
| } |
| |
| public static IWorkspaceRoot getWorkspaceRoot() { |
| return getWorkspace().getRoot(); |
| } |
| |
| public static IProject getProject(String project) { |
| return getWorkspaceRoot().getProject(project); |
| } |
| |
| /* |
| * Create simple project. |
| */ |
| protected static IProject createProject(final String projectName) throws CoreException { |
| final IProject project = getProject(projectName); |
| IWorkspaceRunnable create = monitor -> { |
| project.create(null); |
| project.open(null); |
| }; |
| getWorkspace().run(create, null); |
| return project; |
| } |
| |
| /* |
| * Creates a script project with the given source folders an output location. |
| * Add those on the project's buildpath. |
| */ |
| protected static IScriptProject createScriptProject(String projectName, String[] natures, String[] sourceFolders) |
| throws CoreException { |
| return createScriptProject(projectName, natures, sourceFolders, null); |
| } |
| |
| protected static IScriptProject createScriptProject(final String projectName, final String[] natures, |
| final String[] sourceFolders, final String[] projects) throws CoreException { |
| return createScriptProject(projectName, natures, sourceFolders, projects, null); |
| } |
| |
| /* |
| * Creates a script project with the given source folders an output location. |
| * Add those on the project's buildpath. |
| */ |
| protected static IScriptProject createScriptProject(final String projectName, final String[] natures, |
| final String[] sourceFolders, final String[] projects, final String[] containers) throws CoreException { |
| final IScriptProject[] result = new IScriptProject[1]; |
| IWorkspaceRunnable create = monitor -> { |
| // create project |
| createProject(projectName); |
| |
| IProject project = getWorkspaceRoot().getProject(projectName); |
| |
| // add natures |
| IProjectDescription description = project.getDescription(); |
| description.setNatureIds(natures); |
| project.setDescription(description, null); |
| |
| // create buildpath entries |
| IPath projectPath = project.getFullPath(); |
| int sourceLength = sourceFolders == null ? 0 : sourceFolders.length; |
| int containersLength = containers == null ? 0 : containers.length; |
| int projectLength = projects == null ? 0 : projects.length; |
| IBuildpathEntry[] entries = new IBuildpathEntry[sourceLength + projectLength + containersLength]; |
| for (int i1 = 0; i1 < sourceLength; i1++) { |
| IPath sourcePath = new Path(sourceFolders[i1]); |
| int segmentCount = sourcePath.segmentCount(); |
| if (segmentCount > 0) { |
| // create folder and its parents |
| IContainer container = project; |
| for (int j = 0; j < segmentCount; j++) { |
| IFolder folder = container.getFolder(new Path(sourcePath.segment(j))); |
| if (!folder.exists()) { |
| folder.create(true, true, null); |
| } |
| container = folder; |
| } |
| } |
| // create source entry |
| entries[i1] = DLTKCore.newSourceEntry(projectPath.append(sourcePath)); |
| } |
| |
| for (int i2 = 0; i2 < projectLength; i2++) { |
| |
| // accessible files |
| IPath[] accessibleFiles; |
| accessibleFiles = new IPath[0]; |
| |
| // non accessible files |
| IPath[] nonAccessibleFiles; |
| nonAccessibleFiles = new IPath[0]; |
| |
| entries[sourceLength + i2] = DLTKCore.newProjectEntry(new Path(projects[i2]), |
| BuildpathEntry.getAccessRules(accessibleFiles, nonAccessibleFiles), true, |
| new IBuildpathAttribute[0], false); |
| } |
| |
| for (int i3 = 0; i3 < containersLength; i3++) { |
| entries[sourceLength + projectLength + i3] = DLTKCore.newContainerEntry(new Path(containers[i3])); |
| } |
| // set buildpath and output location |
| IScriptProject scriptProject = DLTKCore.create(project); |
| scriptProject.setRawBuildpath(entries, null); |
| |
| result[0] = scriptProject; |
| }; |
| getWorkspace().run(create, null); |
| return result[0]; |
| } |
| |
| /* |
| * Asserts that the given actual source (usually coming from a file content) is |
| * equal to the expected one. Note that 'expected' is assumed to have the '\n' |
| * line separator. The line separators in 'actual' are converted to '\n' before |
| * the comparison. |
| */ |
| protected void assertSourceEquals(String message, String expected, String actual) { |
| if (actual == null) { |
| assertEquals(message, expected, null); |
| return; |
| } |
| actual = org.eclipse.dltk.core.tests.util.Util.convertToIndependantLineDelimiter(actual); |
| if (!actual.equals(expected)) { |
| System.out.print(org.eclipse.dltk.core.tests.util.Util.displayString(actual.toString(), 2)); |
| System.out.println(this.endChar); |
| } |
| assertEquals(message, expected, actual); |
| } |
| |
| /** |
| * Delete this resource. |
| */ |
| public static void deleteResource(IResource resource) throws CoreException { |
| CoreException lastException = null; |
| try { |
| resource.delete(true, null); |
| } catch (CoreException e) { |
| lastException = e; |
| // just print for info |
| System.out.println(e.getMessage()); |
| } catch (IllegalArgumentException iae) { |
| // just print for info |
| System.out.println(iae.getMessage()); |
| } |
| int retryCount = 60; // wait 1 minute at most |
| while (resource.isAccessible() && --retryCount >= 0) { |
| try { |
| Thread.sleep(1000); |
| } catch (InterruptedException e) { |
| } |
| try { |
| resource.delete(true, null); |
| } catch (CoreException e) { |
| lastException = e; |
| // just print for info |
| System.out.println("Retry " + retryCount + ": " + e.getMessage()); |
| } catch (IllegalArgumentException iae) { |
| // just print for info |
| System.out.println("Retry " + retryCount + ": " + iae.getMessage()); |
| } |
| } |
| if (!resource.isAccessible()) |
| return; |
| System.err.println("Failed to delete " + resource.getFullPath()); |
| if (lastException != null) { |
| throw lastException; |
| } |
| } |
| |
| protected static IFolder createFolder(IPath path) throws CoreException { |
| final IFolder folder = getWorkspaceRoot().getFolder(path); |
| getWorkspace().run(monitor -> { |
| IContainer parent = folder.getParent(); |
| if (parent instanceof IFolder && !parent.exists()) { |
| createFolder(parent.getFullPath()); |
| } |
| folder.create(true, true, null); |
| }, null); |
| |
| return folder; |
| } |
| |
| public static void deleteProject(String projectName) throws CoreException { |
| IProject project = getProject(projectName); |
| if (project.exists() && !project.isOpen()) { // force opening so that |
| // project can be |
| // deleted without |
| // logging (see bug |
| // 23629) |
| project.open(null); |
| } |
| deleteResource(project); |
| } |
| |
| /** |
| * Batch deletion of projects |
| */ |
| protected void deleteProjects(final String... projectNames) throws CoreException { |
| ResourcesPlugin.getWorkspace().run(monitor -> { |
| if (projectNames != null) { |
| for (int i = 0, max = projectNames.length; i < max; i++) { |
| if (projectNames[i] != null) |
| deleteProject(projectNames[i]); |
| } |
| } |
| }, null); |
| } |
| |
| /** |
| * Starts listening to element deltas, and queues them in fgDeltas. |
| */ |
| public void startDeltas() { |
| clearDeltas(); |
| DLTKCore.addElementChangedListener(this.deltaListener); |
| } |
| |
| /** |
| * Stops listening to element deltas, and clears the current deltas. |
| */ |
| public void stopDeltas() { |
| DLTKCore.removeElementChangedListener(this.deltaListener); |
| clearDeltas(); |
| } |
| |
| /** |
| * Empties the current deltas. |
| */ |
| public void clearDeltas() { |
| this.deltaListener.deltas = new IModelElementDelta[0]; |
| } |
| |
| protected void sortElements(IModelElement[] elements) { |
| Comparer comparer = (a, b) -> { |
| ModelElement elementA = (ModelElement) a; |
| ModelElement elementB = (ModelElement) b; |
| // char[] tempJCLPath = "<externalJCLPath>".toCharArray(); |
| // String idA = new String(CharOperation.replace( |
| // elementA.toStringWithAncestors().toCharArray(), |
| // getExternalJCLPathString().toCharArray(), |
| // tempJCLPath)); |
| // String idB = new String(CharOperation.replace( |
| // elementB.toStringWithAncestors().toCharArray(), |
| // getExternalJCLPathString().toCharArray(), |
| // tempJCLPath)); |
| return elementA.toStringWithAncestors().compareTo(elementB.toStringWithAncestors().toString()); |
| // return idA.compareTo(idB); |
| }; |
| org.eclipse.dltk.internal.core.util.Util.sort(elements, comparer); |
| } |
| |
| protected void assertSortedElementsEqual(String message, String expected, IModelElement[] elements) { |
| sortElements(elements); |
| assertElementsEqual(message, expected, elements); |
| } |
| |
| protected void assertElementsEqual(String message, String expected, IModelElement[] elements) { |
| assertElementsEqual(message, expected, elements, false/* |
| * don't show key |
| */); |
| } |
| |
| protected void assertElementsEqual(String message, String expected, IModelElement[] elements, |
| boolean showResolvedInfo) { |
| StringBuffer buffer = new StringBuffer(); |
| if (elements != null) { |
| for (int i = 0, length = elements.length; i < length; i++) { |
| ModelElement element = (ModelElement) elements[i]; |
| if (element == null) { |
| buffer.append("<null>"); |
| } else { |
| buffer.append(element.toStringWithAncestors(showResolvedInfo)); |
| } |
| if (i != length - 1) |
| buffer.append("\n"); |
| } |
| } else { |
| buffer.append("<null>"); |
| } |
| String actual = buffer.toString(); |
| if (!expected.equals(actual)) { |
| if (this.displayName) |
| System.out.println(getName() + " actual result is:"); |
| System.out.println(org.eclipse.dltk.core.tests.util.Util.displayString(actual, this.tabs) + this.endChar); |
| } |
| assertEquals(message, expected, actual); |
| } |
| |
| protected void sortResources(Object[] resources) { |
| Util.Comparer comparer = (a, b) -> { |
| IResource resourceA = (IResource) a; |
| IResource resourceB = (IResource) b; |
| return resourceA.getFullPath().toString().compareTo(resourceB.getFullPath().toString()); |
| }; |
| Util.sort(resources, comparer); |
| } |
| |
| protected void assertResourceNamesEqual(String message, String expected, Object[] resources) { |
| sortResources(resources); |
| StringBuffer buffer = new StringBuffer(); |
| for (int i = 0, length = resources.length; i < length; i++) { |
| IResource resource = (IResource) resources[i]; |
| buffer.append(resource == null ? "<null>" : resource.getName()); |
| if (i != length - 1) |
| buffer.append("\n"); |
| } |
| if (!expected.equals(buffer.toString())) { |
| System.out.print(org.eclipse.dltk.core.tests.util.Util.displayString(buffer.toString(), 2)); |
| System.out.println(this.endChar); |
| } |
| assertEquals(message, expected, buffer.toString()); |
| } |
| |
| protected void assertDeltas(String message, String expected) { |
| String actual = this.deltaListener.toString(); |
| if (!expected.equals(actual)) { |
| System.out.println(actual); |
| } |
| assertEquals(message, expected, actual); |
| } |
| |
| protected void assertDeltas(String message, String expected, IModelElementDelta delta) { |
| String actual = delta == null ? "<null>" : delta.toString(); |
| if (!expected.equals(actual)) { |
| System.out.println(actual); |
| } |
| assertEquals(message, expected, actual); |
| } |
| |
| protected void assertMarkers(String message, String expectedMarkers, IScriptProject project) throws CoreException { |
| IMarker[] markers = project.getProject().findMarkers(IScriptModelMarker.BUILDPATH_PROBLEM_MARKER, false, |
| IResource.DEPTH_ZERO); |
| sortMarkers(markers); |
| assertMarkers(message, expectedMarkers, markers); |
| } |
| |
| protected void assertMarkers(String message, String expectedMarkers, IMarker[] markers) throws CoreException { |
| StringBuffer buffer = new StringBuffer(); |
| if (markers != null) { |
| for (int i = 0, length = markers.length; i < length; i++) { |
| IMarker marker = markers[i]; |
| buffer.append(marker.getAttribute(IMarker.MESSAGE)); |
| if (i != length - 1) { |
| buffer.append("\n"); |
| } |
| } |
| } |
| String actual = buffer.toString(); |
| if (!expectedMarkers.equals(actual)) { |
| System.out.println(org.eclipse.dltk.core.tests.util.Util.displayString(actual, 2)); |
| } |
| assertEquals(message, expectedMarkers, actual); |
| } |
| |
| protected void sortMarkers(IMarker[] markers) { |
| org.eclipse.dltk.internal.core.util.Util.Comparer comparer = (a, b) -> { |
| IMarker markerA = (IMarker) a; |
| IMarker markerB = (IMarker) b; |
| return markerA.getAttribute(IMarker.MESSAGE, "") //$NON-NLS-1$ |
| .compareTo(markerB.getAttribute(IMarker.MESSAGE, "")); //$NON-NLS-1$ |
| }; |
| org.eclipse.dltk.internal.core.util.Util.sort(markers, comparer); |
| } |
| |
| /** |
| * Sets the class path of the script project. |
| */ |
| public void setBuildpath(IScriptProject scriptProject, IBuildpathEntry[] buildpath) { |
| try { |
| scriptProject.setRawBuildpath(buildpath, null); |
| } catch (ModelException e) { |
| assertTrue("failed to set buildpath", false); |
| } |
| } |
| |
| /** |
| * Returns the last delta for the given element from the cached delta. |
| */ |
| protected IModelElementDelta getDeltaFor(IModelElement element) { |
| return getDeltaFor(element, false); |
| } |
| |
| /** |
| * Returns the delta for the given element from the cached delta. If the boolean |
| * is true returns the first delta found. |
| */ |
| protected IModelElementDelta getDeltaFor(IModelElement element, boolean returnFirst) { |
| IModelElementDelta[] deltas = this.deltaListener.deltas; |
| if (deltas == null) |
| return null; |
| IModelElementDelta result = null; |
| for (int i = 0; i < deltas.length; i++) { |
| IModelElementDelta delta = searchForDelta(element, this.deltaListener.deltas[i]); |
| if (delta != null) { |
| if (returnFirst) { |
| return delta; |
| } |
| result = delta; |
| } |
| } |
| return result; |
| } |
| |
| /** |
| * Returns a delta for the given element in the delta tree |
| */ |
| protected IModelElementDelta searchForDelta(IModelElement element, IModelElementDelta delta) { |
| |
| if (delta == null) { |
| return null; |
| } |
| if (delta.getElement().equals(element)) { |
| return delta; |
| } |
| for (int i = 0; i < delta.getAffectedChildren().length; i++) { |
| IModelElementDelta child = searchForDelta(element, delta.getAffectedChildren()[i]); |
| if (child != null) { |
| return child; |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Ensures the elements are present after creation. |
| */ |
| public void assertCreation(IModelElement[] newElements) { |
| for (int i = 0; i < newElements.length; i++) { |
| IModelElement newElement = newElements[i]; |
| assertTrue("Element should be present after creation", newElement.exists()); |
| } |
| } |
| |
| /** |
| * Ensures the element is present after creation. |
| */ |
| public void assertCreation(IModelElement newElement) { |
| assertCreation(new IModelElement[] { newElement }); |
| } |
| |
| /** |
| * Creates an operation to delete the given elements, asserts the operation is |
| * successful, and ensures the elements are no longer present in the model. |
| */ |
| public void assertDeletion(IModelElement[] elementsToDelete) throws ModelException { |
| IModelElement elementToDelete = null; |
| for (int i = 0; i < elementsToDelete.length; i++) { |
| elementToDelete = elementsToDelete[i]; |
| assertTrue("Element must be present to be deleted", elementToDelete.exists()); |
| } |
| |
| getScriptModel().delete(elementsToDelete, false, null); |
| |
| for (int i = 0; i < elementsToDelete.length; i++) { |
| elementToDelete = elementsToDelete[i]; |
| assertTrue("Element should not be present after deletion: " + elementToDelete, !elementToDelete.exists()); |
| } |
| } |
| |
| /** |
| * Returns the script Model this test suite is running on. |
| */ |
| public IScriptModel getScriptModel() { |
| return DLTKCore.create(getWorkspaceRoot()); |
| } |
| |
| /** |
| * Wait for autobuild notification to occur |
| */ |
| public static void waitForAutoBuild() { |
| WorkspaceAutoBuild.waitFor(); |
| } |
| |
| public void ensureCorrectPositioning(IParent container, IModelElement sibling, IModelElement positioned) |
| throws ModelException { |
| IModelElement[] children = container.getChildren(); |
| if (sibling != null) { |
| // find the sibling |
| boolean found = false; |
| for (int i = 0; i < children.length; i++) { |
| if (children[i].equals(sibling)) { |
| assertTrue("element should be before sibling", i > 0 && children[i - 1].equals(positioned)); |
| found = true; |
| break; |
| } |
| } |
| assertTrue("Did not find sibling", found); |
| } |
| } |
| |
| public ISourceModule getWorkingCopy(String path, boolean computeProblems) throws ModelException { |
| return getWorkingCopy(path, "", computeProblems); |
| } |
| |
| public ISourceModule getWorkingCopy(String path, String source) throws ModelException { |
| return getWorkingCopy(path, source, false); |
| } |
| |
| public ISourceModule getWorkingCopy(String path, String source, boolean computeProblems) throws ModelException { |
| if (this.wcOwner == null) |
| this.wcOwner = new WorkingCopyOwner() { |
| }; |
| return getWorkingCopy(path, source, this.wcOwner, computeProblems); |
| } |
| |
| public ISourceModule getWorkingCopy(String path, String source, WorkingCopyOwner owner, boolean computeProblems) |
| throws ModelException { |
| IProblemRequestor problemRequestor = computeProblems ? new IProblemRequestor() { |
| @Override |
| public void acceptProblem(IProblem problem) { |
| } |
| |
| @Override |
| public void beginReporting() { |
| } |
| |
| @Override |
| public void endReporting() { |
| } |
| |
| @Override |
| public boolean isActive() { |
| return true; |
| } |
| } : null; |
| return getWorkingCopy(path, source, owner, problemRequestor); |
| } |
| |
| public ISourceModule getWorkingCopy(String path, String source, WorkingCopyOwner owner, |
| IProblemRequestor problemRequestor) throws ModelException { |
| ISourceModule workingCopy = getSourceModule(path); |
| if (owner != null) |
| workingCopy = workingCopy.getWorkingCopy(/* owner, problemRequestor, */null/* |
| * no progress monitor |
| */); |
| else |
| workingCopy.becomeWorkingCopy(problemRequestor, null/* |
| * no progress monitor |
| */); |
| workingCopy.getBuffer().setContents(source); |
| // if (problemRequestor instanceof ProblemRequestor) |
| // ((ProblemRequestor) |
| // problemRequestor).initialize(source.toCharArray()); |
| workingCopy.makeConsistent(null/* no progress monitor */); |
| return workingCopy; |
| } |
| |
| public static void waitUntilIndexesReady() { |
| ModelManager.getModelManager().getIndexManager().waitUntilReady(); |
| } |
| |
| public static void storeFile(File dest, URL url) throws IOException { |
| try (InputStream input = new BufferedInputStream(url.openStream()); |
| OutputStream output = new BufferedOutputStream(new FileOutputStream(dest))) { |
| // Simple copy |
| int ch = -1; |
| while ((ch = input.read()) != -1) { |
| output.write(ch); |
| } |
| } |
| } |
| |
| public static File storeToMetadata(Bundle bundle, String name, String path) throws IOException { |
| File pathFile = DLTKCore.getDefault().getStateLocation().append(name).toFile(); |
| storeFile(pathFile, FileLocator.resolve(bundle.getEntry(path))); |
| return pathFile; |
| } |
| } |