blob: e3940c76754c34fbf148cbf10031768e1cba412a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.wst.debug.core.tests;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.eclipse.core.resources.IMarkerDelta;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IBreakpointListener;
import org.eclipse.debug.core.IBreakpointManager;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.ui.actions.ToggleBreakpointAction;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.source.IVerticalRulerInfo;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.progress.WorkbenchJob;
import org.eclipse.wst.jsdt.core.IJavaScriptElement;
import org.eclipse.wst.jsdt.core.IJavaScriptUnit;
import org.eclipse.wst.jsdt.core.JavaScriptCore;
import org.eclipse.wst.jsdt.debug.core.breakpoints.IJavaScriptFunctionBreakpoint;
import org.eclipse.wst.jsdt.debug.core.breakpoints.IJavaScriptLineBreakpoint;
import org.eclipse.wst.jsdt.debug.core.breakpoints.IJavaScriptLoadBreakpoint;
import org.eclipse.wst.jsdt.debug.core.model.JavaScriptDebugModel;
/**
* Abstract test that has delegate methods to create various kinds of breakpoints with the ability
* to auto remove them after tests complete
*
* @since 1.0
*/
public abstract class AbstractBreakpointTest extends AbstractDebugTest {
/**
* Test project name for testing breakpoints
*/
protected static final String BP_PROJECT = "BpProject"; //$NON-NLS-1$
private ArrayList breakpoints = new ArrayList();
/**
* Constructor
* @param name
*/
public AbstractBreakpointTest(String name) {
super(name);
}
/* (non-Javadoc)
* @see junit.framework.TestCase#tearDown()
*/
protected void tearDown() throws Exception {
try {
if(breakpoints.size() > 0) {
getBreakpointManager().removeBreakpoints((IBreakpoint[]) breakpoints.toArray(new IBreakpoint[breakpoints.size()]), true);
breakpoints.clear();
}
}
finally {
super.tearDown();
}
}
/* (non-Javadoc)
* @see junit.framework.TestCase#setUp()
*/
protected void setUp() throws Exception {
super.setUp();
assertTestProject(AbstractBreakpointTest.BP_PROJECT);
}
/**
* Creates a line breakpoint in the given script at the given line number.
*
* @param scriptpath the absolute path to the script to create the breakpoint in
* @param line line number to install the breakpoint at
* @param condition the optional condition for the breakpoint
* @return line breakpoint
* @throws Exception
*/
protected IJavaScriptLineBreakpoint createLineBreakpoint(String scriptpath, int line, String condition) throws Exception {
assertNotNull("script path cannot be null creating a line breakpoint", scriptpath); //$NON-NLS-1$
assertTrue("the line number must be greater than -1 to create a line breakpoint", line > -1); //$NON-NLS-1$
IResource res = getBreakpointResource(scriptpath);
assertNotNull("failed creating line breakpoint: the breakpoint resource could not be found for ["+scriptpath+"]", res); //$NON-NLS-1$ //$NON-NLS-2$
IJavaScriptUnit element = (IJavaScriptUnit) JavaScriptCore.create(res);
assertNotNull("failed creating line breakpoint: the javascript element could not be computed for ["+scriptpath+"]", element); //$NON-NLS-1$ //$NON-NLS-2$
Document doc = new Document(element.getSource());
IRegion region = doc.getLineInformation(line);
HashMap attr = new HashMap();
int offset = region.getOffset();
IJavaScriptLineBreakpoint bp = JavaScriptDebugModel.createLineBreakpoint(res, line, offset, offset+region.getLength(), attr, true);
bp.setCondition(condition);
breakpoints.add(bp);
forceDeltas(res.getProject());
return bp;
}
/**
* Creates JavaScript line breakpoints on the given array of lines
* @param resource
* @param lines
* @return the list of created breakpoints
* @throws Exception
*/
protected List createLineBreakpoints(String path, int[] lines) throws Exception {
List bps = new ArrayList(lines.length);
for (int i = 0; i < lines.length; i++) {
IBreakpoint bp = createLineBreakpoint(path, lines[i], null);
bps.add(bp);
breakpoints.add(bp);
}
return bps;
}
/**
* Creates a new function breakpoint
*
* @param scriptpath the full absolute workspace path to the script to create a function breakpoint for
* @param fname function name
* @param sig function signature
* @param condition the optional condition for the breakpoint
* @param entry whether to break on entry
* @param exit whether to break on exit
*/
protected IJavaScriptFunctionBreakpoint createFunctionBreakpoint(String scriptpath, String fname, String sig, String condition, boolean entry, boolean exit) throws Exception {
assertNotNull("script path cannot be null creating a function breakpoint", scriptpath); //$NON-NLS-1$
assertNotNull("function name cannot be null creating a function breakpoint", fname); //$NON-NLS-1$
assertNotNull("function signature cannot be null creating a function breakpoint", sig); //$NON-NLS-1$
IResource res = getBreakpointResource(scriptpath);
assertNotNull("failed creating function breakpoint: the breakpoint resource could not be found for ["+scriptpath+"]", res); //$NON-NLS-1$ //$NON-NLS-2$
IJavaScriptElement element = JavaScriptCore.create(res);
assertNotNull("failed creating line breakpoint: the javascript element could not be computed for ["+scriptpath+"]", element); //$NON-NLS-1$ //$NON-NLS-2$
//TODO find the function
HashMap attr = new HashMap();
IJavaScriptFunctionBreakpoint bp = JavaScriptDebugModel.createFunctionBreakpoint(res, fname, sig, -1, -1, attr, false);
bp.setEntry(entry);
bp.setExit(exit);
bp.setCondition(condition);
breakpoints.add(bp);
forceDeltas(res.getProject());
return bp;
}
/**
* Creates a script load breakpoint for the given script path
*
* @param scriptpath the full absolute workspace path to the script to create a load breakpoint for
*
* @return class prepare breakpoint
* @throws Exception
*/
protected IJavaScriptLoadBreakpoint createScriptloadBreakpoint(String scriptpath) throws Exception {
assertNotNull("script path cannot be null creating a script load breakpoint", scriptpath); //$NON-NLS-1$
IResource res = getBreakpointResource(scriptpath);
assertNotNull("failed creating script load breakpoint: the breakpoint resource could not be found for ["+scriptpath+"]", res); //$NON-NLS-1$ //$NON-NLS-2$
IJavaScriptElement element = JavaScriptCore.create(res);
assertNotNull("failed creating line breakpoint: the javascript element could not be computed for ["+scriptpath+"]", element); //$NON-NLS-1$ //$NON-NLS-2$
HashMap attr = new HashMap();
IJavaScriptLoadBreakpoint bp = JavaScriptDebugModel.createScriptLoadBreakpoint(res, -1, -1, attr, false);
breakpoints.add(bp);
forceDeltas(res.getProject());
return bp;
}
/**
* Returns the workspace resource for the given script path or <code>null</code>
* @param scriptpath the absolute workspace path
*
* @return the {@link IResource} backing the path or <code>null</code>
*/
protected IResource getBreakpointResource(String scriptpath) {
return ResourcesPlugin.getWorkspace().getRoot().findMember(new Path(scriptpath));
}
/**
* Deletes all existing breakpoints
*
* @throws Exception
*/
protected void removeAllBreakpoints() throws Exception {
IBreakpoint[] bps = getBreakpointManager().getBreakpoints();
if(bps.length > 0) {
getBreakpointManager().removeBreakpoints(bps, true);
}
}
/**
* Toggles a breakpoint in the editor at the given line number returning the breakpoint
* or <code>null</code> if none.
*
* @param editor
* @param lineNumber
* @return returns the created breakpoint or <code>null</code> if none.
* @throws InterruptedException
*/
protected IBreakpoint toggleBreakpoint(final IEditorPart editor, int lineNumber) throws InterruptedException {
final IVerticalRulerInfo info = new VerticalRulerInfoStub(lineNumber-1); // sub 1, as the doc lines start at 0
WorkbenchJob job = new WorkbenchJob("toggle javascript breakpoint") { //$NON-NLS-1$
public IStatus runInUIThread(IProgressMonitor monitor) {
ToggleBreakpointAction action = new ToggleBreakpointAction(editor, null, info);
action.run();
return Status.OK_STATUS;
}
};
final Object lock = new Object();
final IBreakpoint[] bps = new IBreakpoint[1];
IBreakpointListener listener = new IBreakpointListener() {
public void breakpointRemoved(IBreakpoint breakpoint, IMarkerDelta delta) {
synchronized (lock) {
lock.notifyAll();
}
}
public void breakpointChanged(IBreakpoint breakpoint, IMarkerDelta delta) {
}
public void breakpointAdded(IBreakpoint breakpoint) {
synchronized (lock) {
bps[0] = breakpoint;
lock.notifyAll();
}
}
};
IBreakpointManager manager = DebugPlugin.getDefault().getBreakpointManager();
manager.addBreakpointListener(listener);
synchronized (lock) {
job.setPriority(Job.INTERACTIVE);
job.schedule();
lock.wait(10000);
}
manager.removeBreakpointListener(listener);
if(bps[0] != null) {
breakpoints.add(bps[0]);
}
return bps[0];
}
}