summaryrefslogtreecommitdiffstats
path: root/devtools/client/debugger/src/actions/tests/expressions.spec.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/client/debugger/src/actions/tests/expressions.spec.js')
-rw-r--r--devtools/client/debugger/src/actions/tests/expressions.spec.js184
1 files changed, 184 insertions, 0 deletions
diff --git a/devtools/client/debugger/src/actions/tests/expressions.spec.js b/devtools/client/debugger/src/actions/tests/expressions.spec.js
new file mode 100644
index 0000000000..48b06ebd1a
--- /dev/null
+++ b/devtools/client/debugger/src/actions/tests/expressions.spec.js
@@ -0,0 +1,184 @@
+/* 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/>. */
+
+import {
+ actions,
+ selectors,
+ createStore,
+ makeSource,
+} from "../../utils/test-head";
+
+import { makeMockFrame } from "../../utils/test-mockup";
+
+const mockThreadFront = {
+ evaluate: (script, { frameId }) =>
+ new Promise((resolve, reject) => {
+ if (!frameId) {
+ resolve("bla");
+ } else {
+ resolve("boo");
+ }
+ }),
+ evaluateExpressions: (inputs, { frameId }) =>
+ Promise.all(
+ inputs.map(
+ input =>
+ new Promise((resolve, reject) => {
+ if (!frameId) {
+ resolve("bla");
+ } else {
+ resolve("boo");
+ }
+ })
+ )
+ ),
+ getFrameScopes: async () => {},
+ getFrames: async () => [],
+ sourceContents: () => ({ source: "", contentType: "text/javascript" }),
+ getSourceActorBreakpointPositions: async () => ({}),
+ getSourceActorBreakableLines: async () => [],
+ autocomplete: () => {
+ return new Promise(resolve => {
+ resolve({
+ from: "foo",
+ matches: ["toLocaleString", "toSource", "toString", "toolbar", "top"],
+ matchProp: "to",
+ });
+ });
+ },
+};
+
+describe("expressions", () => {
+ it("should add an expression", async () => {
+ const { dispatch, getState, cx } = createStore(mockThreadFront);
+
+ await dispatch(actions.addExpression(cx, "foo"));
+ expect(selectors.getExpressions(getState())).toHaveLength(1);
+ });
+
+ it("should not add empty expressions", () => {
+ const { dispatch, getState, cx } = createStore(mockThreadFront);
+
+ dispatch(actions.addExpression(cx, undefined));
+ dispatch(actions.addExpression(cx, ""));
+ expect(selectors.getExpressions(getState())).toHaveLength(0);
+ });
+
+ it("should not add invalid expressions", async () => {
+ const { dispatch, getState, cx } = createStore(mockThreadFront);
+ await dispatch(actions.addExpression(cx, "foo#"));
+ const state = getState();
+ expect(selectors.getExpressions(state)).toHaveLength(0);
+ expect(selectors.getExpressionError(state)).toBe(true);
+ });
+
+ it("should update an expression", async () => {
+ const { dispatch, getState, cx } = createStore(mockThreadFront);
+
+ await dispatch(actions.addExpression(cx, "foo"));
+ const expression = selectors.getExpression(getState(), "foo");
+ if (!expression) {
+ throw new Error("expression must exist");
+ }
+
+ await dispatch(actions.updateExpression(cx, "bar", expression));
+ const bar = selectors.getExpression(getState(), "bar");
+
+ expect(bar && bar.input).toBe("bar");
+ });
+
+ it("should not update an expression w/ invalid code", async () => {
+ const { dispatch, getState, cx } = createStore(mockThreadFront);
+
+ await dispatch(actions.addExpression(cx, "foo"));
+ const expression = selectors.getExpression(getState(), "foo");
+ if (!expression) {
+ throw new Error("expression must exist");
+ }
+ await dispatch(actions.updateExpression(cx, "#bar", expression));
+ expect(selectors.getExpression(getState(), "bar")).toBeUndefined();
+ });
+
+ it("should delete an expression", async () => {
+ const { dispatch, getState, cx } = createStore(mockThreadFront);
+
+ await dispatch(actions.addExpression(cx, "foo"));
+ await dispatch(actions.addExpression(cx, "bar"));
+ expect(selectors.getExpressions(getState())).toHaveLength(2);
+
+ const expression = selectors.getExpression(getState(), "foo");
+
+ if (!expression) {
+ throw new Error("expression must exist");
+ }
+
+ const bar = selectors.getExpression(getState(), "bar");
+ dispatch(actions.deleteExpression(expression));
+ expect(selectors.getExpressions(getState())).toHaveLength(1);
+ expect(bar && bar.input).toBe("bar");
+ });
+
+ it("should evaluate expressions global scope", async () => {
+ const { dispatch, getState, cx } = createStore(mockThreadFront);
+ await dispatch(actions.addExpression(cx, "foo"));
+ await dispatch(actions.addExpression(cx, "bar"));
+
+ let foo = selectors.getExpression(getState(), "foo");
+ let bar = selectors.getExpression(getState(), "bar");
+ expect(foo && foo.value).toBe("bla");
+ expect(bar && bar.value).toBe("bla");
+
+ await dispatch(actions.evaluateExpressions(cx));
+ foo = selectors.getExpression(getState(), "foo");
+ bar = selectors.getExpression(getState(), "bar");
+ expect(foo && foo.value).toBe("bla");
+ expect(bar && bar.value).toBe("bla");
+ });
+
+ it("should evaluate expressions in specific scope", async () => {
+ const { dispatch, getState } = createStore(mockThreadFront);
+ await createFrames(getState, dispatch);
+
+ const cx = selectors.getThreadContext(getState());
+ await dispatch(actions.newGeneratedSource(makeSource("source")));
+ await dispatch(actions.addExpression(cx, "foo"));
+ await dispatch(actions.addExpression(cx, "bar"));
+
+ let foo = selectors.getExpression(getState(), "foo");
+ let bar = selectors.getExpression(getState(), "bar");
+ expect(foo && foo.value).toBe("boo");
+ expect(bar && bar.value).toBe("boo");
+
+ await dispatch(actions.evaluateExpressions(cx));
+ foo = selectors.getExpression(getState(), "foo");
+ bar = selectors.getExpression(getState(), "bar");
+ expect(foo && foo.value).toBe("boo");
+ expect(bar && bar.value).toBe("boo");
+ });
+
+ it("should get the autocomplete matches for the input", async () => {
+ const { cx, dispatch, getState } = createStore(mockThreadFront);
+ await dispatch(actions.autocomplete(cx, "to", 2));
+ expect(selectors.getAutocompleteMatchset(getState())).toMatchSnapshot();
+ });
+});
+
+async function createFrames(getState, dispatch) {
+ const frame = makeMockFrame();
+ await dispatch(actions.newGeneratedSource(makeSource("example.js")));
+ await dispatch(actions.newGeneratedSource(makeSource("source")));
+
+ await dispatch(
+ actions.paused({
+ thread: "FakeThread",
+ frame,
+ frames: [frame],
+ why: { type: "just because" },
+ })
+ );
+
+ await dispatch(
+ actions.selectFrame(selectors.getThreadContext(getState()), frame)
+ );
+}