summaryrefslogtreecommitdiffstats
path: root/devtools/client/debugger/src/actions/breakpoints/tests/breakpoints.spec.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/client/debugger/src/actions/breakpoints/tests/breakpoints.spec.js')
-rw-r--r--devtools/client/debugger/src/actions/breakpoints/tests/breakpoints.spec.js487
1 files changed, 487 insertions, 0 deletions
diff --git a/devtools/client/debugger/src/actions/breakpoints/tests/breakpoints.spec.js b/devtools/client/debugger/src/actions/breakpoints/tests/breakpoints.spec.js
new file mode 100644
index 0000000000..4a1e68a0bd
--- /dev/null
+++ b/devtools/client/debugger/src/actions/breakpoints/tests/breakpoints.spec.js
@@ -0,0 +1,487 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
+
+// @flow
+
+import {
+ createStore,
+ selectors,
+ actions,
+ makeSource,
+ getTelemetryEvents,
+} from "../../../utils/test-head";
+
+import { mockCommandClient } from "../../tests/helpers/mockCommandClient";
+import { mockPendingBreakpoint } from "../../tests/helpers/breakpoints.js";
+import { makePendingLocationId } from "../../../utils/breakpoint";
+
+function mockClient(positionsResponse = {}) {
+ return {
+ ...mockCommandClient,
+ getSourceActorBreakpointPositions: async () => positionsResponse,
+ getSourceActorBreakableLines: async () => [],
+ };
+}
+
+describe("breakpoints", () => {
+ it("should add a breakpoint", async () => {
+ const { dispatch, getState, cx } = createStore(mockClient({ "2": [1] }));
+ const loc1 = {
+ sourceId: "a",
+ line: 2,
+ column: 1,
+ sourceUrl: "http://localhost:8000/examples/a",
+ };
+
+ const source = await dispatch(actions.newGeneratedSource(makeSource("a")));
+ await dispatch(actions.loadSourceText({ cx, source }));
+ await dispatch(
+ actions.setSelectedLocation(cx, source, {
+ line: 1,
+ column: 1,
+ sourceId: source.id,
+ })
+ );
+
+ await dispatch(actions.addBreakpoint(cx, loc1));
+
+ expect(selectors.getBreakpointCount(getState())).toEqual(1);
+ const bp = selectors.getBreakpoint(getState(), loc1);
+ expect(bp && bp.location).toEqual(loc1);
+ expect(getTelemetryEvents("add_breakpoint")).toHaveLength(1);
+
+ const bpSources = selectors.getBreakpointSources(getState());
+ expect(bpSources).toMatchSnapshot();
+ });
+
+ it("should not show a breakpoint that does not have text", async () => {
+ const { dispatch, getState, cx } = createStore(mockClient({ "5": [1] }));
+ const loc1 = {
+ sourceId: "a",
+ line: 5,
+ column: 1,
+ sourceUrl: "http://localhost:8000/examples/a",
+ };
+ const source = await dispatch(actions.newGeneratedSource(makeSource("a")));
+ await dispatch(actions.loadSourceText({ cx, source }));
+ await dispatch(
+ actions.setSelectedLocation(cx, source, {
+ line: 1,
+ column: 1,
+ sourceId: source.id,
+ })
+ );
+
+ await dispatch(actions.addBreakpoint(cx, loc1));
+
+ expect(selectors.getBreakpointCount(getState())).toEqual(1);
+ const bp = selectors.getBreakpoint(getState(), loc1);
+ expect(bp && bp.location).toEqual(loc1);
+ expect(selectors.getBreakpointSources(getState())).toMatchSnapshot();
+ });
+
+ it("should show a disabled breakpoint that does not have text", async () => {
+ const { dispatch, getState, cx } = createStore(mockClient({ "5": [1] }));
+ const loc1 = {
+ sourceId: "a",
+ line: 5,
+ column: 1,
+ sourceUrl: "http://localhost:8000/examples/a",
+ };
+ const source = await dispatch(actions.newGeneratedSource(makeSource("a")));
+ await dispatch(actions.loadSourceText({ cx, source }));
+ await dispatch(
+ actions.setSelectedLocation(cx, source, {
+ line: 1,
+ column: 1,
+ sourceId: source.id,
+ })
+ );
+
+ await dispatch(actions.addBreakpoint(cx, loc1));
+ const breakpoint = selectors.getBreakpoint(getState(), loc1);
+ if (!breakpoint) {
+ throw new Error("no breakpoint");
+ }
+
+ await dispatch(actions.disableBreakpoint(cx, breakpoint));
+
+ expect(selectors.getBreakpointCount(getState())).toEqual(1);
+ const bp = selectors.getBreakpoint(getState(), loc1);
+ expect(bp && bp.location).toEqual(loc1);
+ expect(selectors.getBreakpointSources(getState())).toMatchSnapshot();
+ });
+
+ it("should not re-add a breakpoint", async () => {
+ const { dispatch, getState, cx } = createStore(mockClient({ "5": [1] }));
+ const loc1 = {
+ sourceId: "a",
+ line: 5,
+ column: 1,
+ sourceUrl: "http://localhost:8000/examples/a",
+ };
+
+ const source = await dispatch(actions.newGeneratedSource(makeSource("a")));
+ await dispatch(actions.loadSourceText({ cx, source }));
+ await dispatch(
+ actions.setSelectedLocation(cx, source, {
+ line: 1,
+ column: 1,
+ sourceId: source.id,
+ })
+ );
+
+ await dispatch(actions.addBreakpoint(cx, loc1));
+ expect(selectors.getBreakpointCount(getState())).toEqual(1);
+ const bp = selectors.getBreakpoint(getState(), loc1);
+ expect(bp && bp.location).toEqual(loc1);
+
+ await dispatch(actions.addBreakpoint(cx, loc1));
+ expect(selectors.getBreakpointCount(getState())).toEqual(1);
+ });
+
+ it("should remove a breakpoint", async () => {
+ const { dispatch, getState, cx } = createStore(
+ mockClient({ "5": [1], "6": [2] })
+ );
+
+ const loc1 = {
+ sourceId: "a",
+ line: 5,
+ column: 1,
+ sourceUrl: "http://localhost:8000/examples/a",
+ };
+
+ const loc2 = {
+ sourceId: "b",
+ line: 6,
+ column: 2,
+ sourceUrl: "http://localhost:8000/examples/b",
+ };
+
+ const aSource = await dispatch(actions.newGeneratedSource(makeSource("a")));
+ await dispatch(actions.loadSourceText({ cx, source: aSource }));
+
+ const bSource = await dispatch(actions.newGeneratedSource(makeSource("b")));
+ await dispatch(actions.loadSourceText({ cx, source: bSource }));
+
+ await dispatch(
+ actions.setSelectedLocation(cx, aSource, {
+ line: 1,
+ column: 1,
+ sourceId: aSource.id,
+ })
+ );
+
+ await dispatch(actions.addBreakpoint(cx, loc1));
+ await dispatch(actions.addBreakpoint(cx, loc2));
+
+ const bp = selectors.getBreakpoint(getState(), loc1);
+ if (!bp) {
+ throw new Error("no bp");
+ }
+ await dispatch(actions.removeBreakpoint(cx, bp));
+
+ expect(selectors.getBreakpointCount(getState())).toEqual(1);
+ });
+
+ it("should disable a breakpoint", async () => {
+ const { dispatch, getState, cx } = createStore(
+ mockClient({ "5": [1], "6": [2] })
+ );
+
+ const loc1 = {
+ sourceId: "a",
+ line: 5,
+ column: 1,
+ sourceUrl: "http://localhost:8000/examples/a",
+ };
+
+ const loc2 = {
+ sourceId: "b",
+ line: 6,
+ column: 2,
+ sourceUrl: "http://localhost:8000/examples/b",
+ };
+
+ const aSource = await dispatch(actions.newGeneratedSource(makeSource("a")));
+ await dispatch(actions.loadSourceText({ cx, source: aSource }));
+
+ const bSource = await dispatch(actions.newGeneratedSource(makeSource("b")));
+ await dispatch(actions.loadSourceText({ cx, source: bSource }));
+
+ await dispatch(actions.addBreakpoint(cx, loc1));
+ await dispatch(actions.addBreakpoint(cx, loc2));
+
+ const breakpoint = selectors.getBreakpoint(getState(), loc1);
+ if (!breakpoint) {
+ throw new Error("no breakpoint");
+ }
+
+ await dispatch(actions.disableBreakpoint(cx, breakpoint));
+
+ const bp = selectors.getBreakpoint(getState(), loc1);
+ expect(bp && bp.disabled).toBe(true);
+ });
+
+ it("should enable breakpoint", async () => {
+ const { dispatch, getState, cx } = createStore(
+ mockClient({ "5": [1], "6": [2] })
+ );
+ const loc = {
+ sourceId: "a",
+ line: 5,
+ column: 1,
+ sourceUrl: "http://localhost:8000/examples/a",
+ };
+
+ const aSource = await dispatch(actions.newGeneratedSource(makeSource("a")));
+ await dispatch(actions.loadSourceText({ cx, source: aSource }));
+
+ await dispatch(actions.addBreakpoint(cx, loc));
+ let bp = selectors.getBreakpoint(getState(), loc);
+ if (!bp) {
+ throw new Error("no breakpoint");
+ }
+
+ await dispatch(actions.disableBreakpoint(cx, bp));
+
+ bp = selectors.getBreakpoint(getState(), loc);
+ if (!bp) {
+ throw new Error("no breakpoint");
+ }
+
+ expect(bp && bp.disabled).toBe(true);
+
+ await dispatch(actions.enableBreakpoint(cx, bp));
+
+ bp = selectors.getBreakpoint(getState(), loc);
+ expect(bp && !bp.disabled).toBe(true);
+ });
+
+ it("should toggle all the breakpoints", async () => {
+ const { dispatch, getState, cx } = createStore(
+ mockClient({ "5": [1], "6": [2] })
+ );
+
+ const loc1 = {
+ sourceId: "a",
+ line: 5,
+ column: 1,
+ sourceUrl: "http://localhost:8000/examples/a",
+ };
+
+ const loc2 = {
+ sourceId: "b",
+ line: 6,
+ column: 2,
+ sourceUrl: "http://localhost:8000/examples/b",
+ };
+
+ const aSource = await dispatch(actions.newGeneratedSource(makeSource("a")));
+ await dispatch(actions.loadSourceText({ cx, source: aSource }));
+
+ const bSource = await dispatch(actions.newGeneratedSource(makeSource("b")));
+ await dispatch(actions.loadSourceText({ cx, source: bSource }));
+
+ await dispatch(actions.addBreakpoint(cx, loc1));
+ await dispatch(actions.addBreakpoint(cx, loc2));
+
+ await dispatch(actions.toggleAllBreakpoints(cx, true));
+
+ let bp1 = selectors.getBreakpoint(getState(), loc1);
+ let bp2 = selectors.getBreakpoint(getState(), loc2);
+
+ expect(bp1 && bp1.disabled).toBe(true);
+ expect(bp2 && bp2.disabled).toBe(true);
+
+ await dispatch(actions.toggleAllBreakpoints(cx, false));
+
+ bp1 = selectors.getBreakpoint(getState(), loc1);
+ bp2 = selectors.getBreakpoint(getState(), loc2);
+ expect(bp1 && bp1.disabled).toBe(false);
+ expect(bp2 && bp2.disabled).toBe(false);
+ });
+
+ it("should remove all the breakpoints", async () => {
+ const mockedPendingBreakpoint = mockPendingBreakpoint({ column: 2 });
+ const id = makePendingLocationId(mockedPendingBreakpoint.location);
+ const pendingBreakpoints = { [id]: mockedPendingBreakpoint };
+
+ const { dispatch, getState, cx } = createStore(
+ mockClient({ "5": [1], "6": [2] }),
+ { pendingBreakpoints }
+ );
+
+ const loc1 = {
+ sourceId: "a",
+ line: 5,
+ column: 1,
+ sourceUrl: "http://localhost:8000/examples/a",
+ };
+
+ const loc2 = {
+ sourceId: "b",
+ line: 6,
+ column: 2,
+ sourceUrl: "http://localhost:8000/examples/b",
+ };
+
+ const aSource = await dispatch(actions.newGeneratedSource(makeSource("a")));
+ await dispatch(actions.loadSourceText({ cx, source: aSource }));
+
+ const bSource = await dispatch(actions.newGeneratedSource(makeSource("b")));
+ await dispatch(actions.loadSourceText({ cx, source: bSource }));
+
+ await dispatch(actions.addBreakpoint(cx, loc1));
+ await dispatch(actions.addBreakpoint(cx, loc2));
+
+ await dispatch(actions.removeAllBreakpoints(cx));
+
+ const bps = selectors.getBreakpointsList(getState());
+ const pendingBps = selectors.getPendingBreakpointList(getState());
+
+ expect(bps).toHaveLength(0);
+ expect(pendingBps).toHaveLength(0);
+ });
+
+ it("should toggle a breakpoint at a location", async () => {
+ const loc = { sourceId: "foo1", line: 5, column: 1 };
+ const getBp = () => selectors.getBreakpoint(getState(), loc);
+
+ const { dispatch, getState, cx } = createStore(mockClient({ "5": [1] }));
+
+ const source = await dispatch(
+ actions.newGeneratedSource(makeSource("foo1"))
+ );
+ await dispatch(actions.loadSourceText({ cx, source }));
+
+ await dispatch(actions.selectLocation(cx, loc));
+
+ await dispatch(actions.toggleBreakpointAtLine(cx, 5));
+ const bp = getBp();
+ expect(bp && !bp.disabled).toBe(true);
+
+ await dispatch(actions.toggleBreakpointAtLine(cx, 5));
+ expect(getBp()).toBe(undefined);
+ });
+
+ it("should disable/enable a breakpoint at a location", async () => {
+ const location = { sourceId: "foo1", line: 5, column: 1 };
+ const getBp = () => selectors.getBreakpoint(getState(), location);
+
+ const { dispatch, getState, cx } = createStore(mockClient({ "5": [1] }));
+
+ const source = await dispatch(
+ actions.newGeneratedSource(makeSource("foo1"))
+ );
+ await dispatch(actions.loadSourceText({ cx, source }));
+
+ await dispatch(actions.selectLocation(cx, { sourceId: "foo1", line: 1 }));
+
+ await dispatch(actions.toggleBreakpointAtLine(cx, 5));
+ let bp = getBp();
+ expect(bp && !bp.disabled).toBe(true);
+ bp = getBp();
+ if (!bp) {
+ throw new Error("no bp");
+ }
+ await dispatch(actions.toggleDisabledBreakpoint(cx, bp));
+ bp = getBp();
+ expect(bp && bp.disabled).toBe(true);
+ });
+
+ it("should set the breakpoint condition", async () => {
+ const { dispatch, getState, cx } = createStore(mockClient({ "5": [1] }));
+
+ const loc = {
+ sourceId: "a",
+ line: 5,
+ column: 1,
+ sourceUrl: "http://localhost:8000/examples/a",
+ };
+
+ const source = await dispatch(actions.newGeneratedSource(makeSource("a")));
+ await dispatch(actions.loadSourceText({ cx, source }));
+
+ await dispatch(actions.addBreakpoint(cx, loc));
+
+ let bp = selectors.getBreakpoint(getState(), loc);
+ expect(bp && bp.options.condition).toBe(undefined);
+
+ await dispatch(
+ actions.setBreakpointOptions(cx, loc, {
+ condition: "const foo = 0",
+ getTextForLine: () => {},
+ })
+ );
+
+ bp = selectors.getBreakpoint(getState(), loc);
+ expect(bp && bp.options.condition).toBe("const foo = 0");
+ });
+
+ it("should set the condition and enable a breakpoint", async () => {
+ const { dispatch, getState, cx } = createStore(mockClient({ "5": [1] }));
+
+ const loc = {
+ sourceId: "a",
+ line: 5,
+ column: 1,
+ sourceUrl: "http://localhost:8000/examples/a",
+ };
+
+ const source = await dispatch(actions.newGeneratedSource(makeSource("a")));
+ await dispatch(actions.loadSourceText({ cx, source }));
+
+ await dispatch(actions.addBreakpoint(cx, loc));
+ let bp = selectors.getBreakpoint(getState(), loc);
+ if (!bp) {
+ throw new Error("no breakpoint");
+ }
+
+ await dispatch(actions.disableBreakpoint(cx, bp));
+
+ bp = selectors.getBreakpoint(getState(), loc);
+ expect(bp && bp.options.condition).toBe(undefined);
+
+ await dispatch(
+ actions.setBreakpointOptions(cx, loc, {
+ condition: "const foo = 0",
+ getTextForLine: () => {},
+ })
+ );
+ const newBreakpoint = selectors.getBreakpoint(getState(), loc);
+ expect(newBreakpoint && !newBreakpoint.disabled).toBe(true);
+ expect(newBreakpoint && newBreakpoint.options.condition).toBe(
+ "const foo = 0"
+ );
+ });
+
+ it("should remap breakpoints on pretty print", async () => {
+ const { dispatch, getState, cx } = createStore(mockClient({ "1": [0] }));
+
+ const loc = {
+ sourceId: "a.js",
+ line: 1,
+ column: 0,
+ sourceUrl: "http://localhost:8000/examples/a.js",
+ };
+
+ const source = await dispatch(
+ actions.newGeneratedSource(makeSource("a.js"))
+ );
+ await dispatch(actions.loadSourceText({ cx, source }));
+
+ await dispatch(actions.addBreakpoint(cx, loc));
+ await dispatch(actions.togglePrettyPrint(cx, "a.js"));
+
+ const breakpoint = selectors.getBreakpointsList(getState())[0];
+
+ expect(
+ breakpoint.location.sourceUrl &&
+ breakpoint.location.sourceUrl.includes("formatted")
+ ).toBe(true);
+ expect(breakpoint).toMatchSnapshot();
+ });
+});