Skip to content

Fixed bug where line breakpoint would use incorrectly character #490

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Jan 19, 2022
17 changes: 11 additions & 6 deletions src/actions/SetBreakpoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
Breakpoint,
} from "vscode";
import displayPendingEditDecorations from "../util/editDisplayUtils";
import { isLineSelectionType } from "../util/selectionType";

function getBreakpoints(uri: Uri, range: Range) {
return debug.breakpoints.filter(
Expand Down Expand Up @@ -46,16 +47,20 @@ export default class SetBreakpoint implements Action {
const toRemove: Breakpoint[] = [];

targets.forEach((target) => {
let range: Range = target.selection.selection;
// The action preference give us line content but line breakpoints are registered on character 0
if (isLineSelectionType(target.selectionType)) {
range = range.with(range.start.with(undefined, 0), undefined);
}
const uri = target.selection.editor.document.uri;
const existing = getBreakpoints(uri, target.selection.selection);
const existing = getBreakpoints(uri, range);
if (existing.length > 0) {
toRemove.push(...existing);
} else {
toAdd.push(
new SourceBreakpoint(
new Location(uri, target.selection.selection.start)
)
);
if (isLineSelectionType(target.selectionType)) {
range = range.with(undefined, range.end.with(undefined, 0));
}
toAdd.push(new SourceBreakpoint(new Location(uri, range)));
}
});

Expand Down
160 changes: 160 additions & 0 deletions src/test/suite/breakpoints.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
import * as assert from "assert";
import * as vscode from "vscode";
import * as sinon from "sinon";
import { getCursorlessApi } from "../../util/getExtensionApi";
import { openNewEditor } from "../openNewEditor";

suite("breakpoints", async function () {
this.timeout("100s");
this.retries(3);

setup(() => {
removeBreakpoints();
});

teardown(() => {
sinon.restore();
});

suiteTeardown(() => {
removeBreakpoints();
});

test("breakpoint harp add", breakpointHarpAdd);
test("breakpoint token harp add", breakpointTokenHarpAdd);
test("breakpoint harp remove", breakpointHarpRemove);
test("breakpoint token harp remove", breakpointTokenHarpRemove);
});

async function breakpointHarpAdd() {
const graph = (await getCursorlessApi()).graph!;
await openNewEditor(" hello");
await graph.hatTokenMap.addDecorations();

await vscode.commands.executeCommand(
"cursorless.command",
"breakpoint harp",
"setBreakpoint",
[
{
type: "primitive",
mark: {
type: "decoratedSymbol",
symbolColor: "default",
character: "h",
},
},
]
);

const breakpoints = vscode.debug.breakpoints;
assert.deepStrictEqual(breakpoints.length, 1);
assert.ok(breakpoints[0] instanceof vscode.SourceBreakpoint);
const breakpoint = <vscode.SourceBreakpoint>breakpoints[0];
assert.ok(breakpoint.location.range.isEqual(new vscode.Range(0, 0, 0, 0)));
}

async function breakpointTokenHarpAdd() {
const graph = (await getCursorlessApi()).graph!;
await openNewEditor(" hello");
await graph.hatTokenMap.addDecorations();

await vscode.commands.executeCommand(
"cursorless.command",
"breakpoint token harp",
"setBreakpoint",
[
{
type: "primitive",
selectionType: "token",
mark: {
type: "decoratedSymbol",
symbolColor: "default",
character: "h",
},
},
]
);

const breakpoints = vscode.debug.breakpoints;
assert.deepStrictEqual(breakpoints.length, 1);
assert.ok(breakpoints[0] instanceof vscode.SourceBreakpoint);
const breakpoint = <vscode.SourceBreakpoint>breakpoints[0];
assert.ok(breakpoint.location.range.isEqual(new vscode.Range(0, 2, 0, 7)));
}

async function breakpointHarpRemove() {
const graph = (await getCursorlessApi()).graph!;
const editor = await openNewEditor(" hello");
await graph.hatTokenMap.addDecorations();

vscode.debug.addBreakpoints([
new vscode.SourceBreakpoint(
new vscode.Location(editor.document.uri, new vscode.Range(0, 0, 0, 0))
),
]);

assert.deepStrictEqual(vscode.debug.breakpoints.length, 1);

await vscode.commands.executeCommand(
"cursorless.command",
"breakpoint harp",
"setBreakpoint",
[
{
type: "primitive",
mark: {
type: "decoratedSymbol",
symbolColor: "default",
character: "h",
},
},
]
);

assert.deepStrictEqual(vscode.debug.breakpoints.length, 0);
}

async function breakpointTokenHarpRemove() {
const graph = (await getCursorlessApi()).graph!;
const editor = await openNewEditor(" hello");
await graph.hatTokenMap.addDecorations();

vscode.debug.addBreakpoints([
new vscode.SourceBreakpoint(
new vscode.Location(editor.document.uri, new vscode.Range(0, 0, 0, 0))
),
new vscode.SourceBreakpoint(
new vscode.Location(editor.document.uri, new vscode.Range(0, 2, 0, 7))
),
]);

assert.deepStrictEqual(vscode.debug.breakpoints.length, 2);

await vscode.commands.executeCommand(
"cursorless.command",
"breakpoint token harp",
"setBreakpoint",
[
{
type: "primitive",
selectionType: "token",
mark: {
type: "decoratedSymbol",
symbolColor: "default",
character: "h",
},
},
]
);

const breakpoints = vscode.debug.breakpoints;
assert.deepStrictEqual(breakpoints.length, 1);
assert.ok(breakpoints[0] instanceof vscode.SourceBreakpoint);
const breakpoint = <vscode.SourceBreakpoint>breakpoints[0];
assert.ok(breakpoint.location.range.isEqual(new vscode.Range(0, 0, 0, 0)));
}

function removeBreakpoints() {
vscode.debug.removeBreakpoints(vscode.debug.breakpoints);
}