diff options
Diffstat (limited to 'devtools/client/debugger/src/components/Editor/tests')
7 files changed, 1053 insertions, 0 deletions
diff --git a/devtools/client/debugger/src/components/Editor/tests/Breakpoints.spec.js b/devtools/client/debugger/src/components/Editor/tests/Breakpoints.spec.js new file mode 100644 index 0000000000..915b812dff --- /dev/null +++ b/devtools/client/debugger/src/components/Editor/tests/Breakpoints.spec.js @@ -0,0 +1,54 @@ +/* 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 React from "react"; +import { shallow } from "enzyme"; +import Breakpoints from "../Breakpoints"; + +const BreakpointsComponent = Breakpoints.WrappedComponent; + +function generateDefaults(overrides) { + const sourceId = "server1.conn1.child1/source1"; + const matchingBreakpoints = [{ location: { source: { id: sourceId } } }]; + + return { + selectedSource: { sourceId, get: () => false }, + editor: { + codeMirror: { + setGutterMarker: jest.fn(), + }, + }, + blackboxedRanges: {}, + cx: {}, + breakpointActions: {}, + editorActions: {}, + breakpoints: matchingBreakpoints, + ...overrides, + }; +} + +function render(overrides = {}) { + const props = generateDefaults(overrides); + const component = shallow(<BreakpointsComponent {...props} />); + return { component, props }; +} + +describe("Breakpoints Component", () => { + it("should render breakpoints without columns", async () => { + const sourceId = "server1.conn1.child1/source1"; + const breakpoints = [{ location: { source: { id: sourceId } } }]; + + const { component, props } = render({ breakpoints }); + expect(component.find("Breakpoint")).toHaveLength(props.breakpoints.length); + }); + + it("should render breakpoints with columns", async () => { + const sourceId = "server1.conn1.child1/source1"; + const breakpoints = [{ location: { column: 2, source: { id: sourceId } } }]; + + const { component, props } = render({ breakpoints }); + expect(component.find("Breakpoint")).toHaveLength(props.breakpoints.length); + expect(component).toMatchSnapshot(); + }); +}); diff --git a/devtools/client/debugger/src/components/Editor/tests/ConditionalPanel.spec.js b/devtools/client/debugger/src/components/Editor/tests/ConditionalPanel.spec.js new file mode 100644 index 0000000000..05e4dcb727 --- /dev/null +++ b/devtools/client/debugger/src/components/Editor/tests/ConditionalPanel.spec.js @@ -0,0 +1,77 @@ +/* eslint max-nested-callbacks: ["error", 7] */ +/* 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 React from "react"; +import { mount } from "enzyme"; +import { ConditionalPanel } from "../ConditionalPanel"; +import * as mocks from "../../../utils/test-mockup"; + +const source = mocks.makeMockSource(); + +function generateDefaults(overrides, log, line, column, condition, logValue) { + const breakpoint = mocks.makeMockBreakpoint(source, line, column); + breakpoint.options.condition = condition; + breakpoint.options.logValue = logValue; + + return { + editor: { + CodeMirror: { + fromTextArea: jest.fn(() => { + return { + on: jest.fn(), + getWrapperElement: jest.fn(() => { + return { + addEventListener: jest.fn(), + }; + }), + focus: jest.fn(), + setCursor: jest.fn(), + lineCount: jest.fn(), + }; + }), + }, + codeMirror: { + addLineWidget: jest.fn(), + }, + }, + location: breakpoint.location, + source, + breakpoint, + log, + getDefaultValue: jest.fn(), + openConditionalPanel: jest.fn(), + closeConditionalPanel: jest.fn(), + ...overrides, + }; +} + +function render(log, line, column, condition, logValue, overrides = {}) { + const defaults = generateDefaults( + overrides, + log, + line, + column, + condition, + logValue + ); + const props = { ...defaults, ...overrides }; + const wrapper = mount(<ConditionalPanel {...props} />); + return { wrapper, props }; +} + +describe("ConditionalPanel", () => { + it("it should render at location of selected breakpoint", () => { + const { wrapper } = render(false, 2, 2); + expect(wrapper).toMatchSnapshot(); + }); + it("it should render with condition at selected breakpoint location", () => { + const { wrapper } = render(false, 3, 3, "I'm a condition", "not a log"); + expect(wrapper).toMatchSnapshot(); + }); + it("it should render with logpoint at selected breakpoint location", () => { + const { wrapper } = render(true, 4, 4, "not a condition", "I'm a log"); + expect(wrapper).toMatchSnapshot(); + }); +}); diff --git a/devtools/client/debugger/src/components/Editor/tests/DebugLine.spec.js b/devtools/client/debugger/src/components/Editor/tests/DebugLine.spec.js new file mode 100644 index 0000000000..a7fcb53a2d --- /dev/null +++ b/devtools/client/debugger/src/components/Editor/tests/DebugLine.spec.js @@ -0,0 +1,85 @@ +/* eslint max-nested-callbacks: ["error", 7] */ +/* 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 React from "react"; +import { shallow } from "enzyme"; + +import DebugLine from "../DebugLine"; + +import { setDocument } from "../../../utils/editor"; + +function createMockDocument(clear) { + const doc = { + addLineClass: jest.fn(), + removeLineClass: jest.fn(), + markText: jest.fn(() => ({ clear })), + getLine: line => "", + }; + + return doc; +} + +function generateDefaults(editor, overrides) { + return { + editor, + pauseInfo: { + why: { type: "breakpoint" }, + }, + frame: null, + sourceTextContent: null, + ...overrides, + }; +} + +function createLocation(line) { + return { + source: { + id: "foo", + }, + sourceId: "foo", + line, + column: 2, + }; +} + +function render(overrides = {}) { + const clear = jest.fn(); + const editor = { codeMirror: {} }; + const props = generateDefaults(editor, overrides); + + const doc = createMockDocument(clear); + setDocument("foo", doc); + + const component = shallow(<DebugLine.WrappedComponent {...props} />, { + lifecycleExperimental: true, + }); + return { component, props, clear, editor, doc }; +} + +describe("DebugLine Component", () => { + describe("pausing at the first location", () => { + describe("when there is no selected frame", () => { + it("should not set the debug line", () => { + const { component, props, doc } = render({ frame: null }); + const line = 2; + const location = createLocation(line); + + component.setProps({ ...props, location }); + expect(doc.removeLineClass).not.toHaveBeenCalled(); + }); + }); + + describe("when there is a different source", () => { + it("should not set the debug line", async () => { + const { component, doc } = render(); + const newSelectedFrame = { location: { sourceId: "bar" } }; + expect(doc.removeLineClass).not.toHaveBeenCalled(); + + component.setProps({ frame: newSelectedFrame }); + expect(doc.removeLineClass).not.toHaveBeenCalled(); + }); + }); + }); +}); diff --git a/devtools/client/debugger/src/components/Editor/tests/Footer.spec.js b/devtools/client/debugger/src/components/Editor/tests/Footer.spec.js new file mode 100644 index 0000000000..b58ba45cb3 --- /dev/null +++ b/devtools/client/debugger/src/components/Editor/tests/Footer.spec.js @@ -0,0 +1,67 @@ +/* eslint max-nested-callbacks: ["error", 7] */ +/* 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 React from "react"; +import { shallow } from "enzyme"; + +import SourceFooter from "../Footer"; +import { createSourceObject } from "../../../utils/test-head"; +import { setDocument } from "../../../utils/editor"; + +function createMockDocument(clear, position) { + const doc = { + getCursor: jest.fn(() => position), + }; + return doc; +} + +function generateDefaults(overrides) { + return { + editor: { + codeMirror: { + doc: {}, + cursorActivity: jest.fn(), + on: jest.fn(), + }, + }, + endPanelCollapsed: false, + selectedSource: { + ...createSourceObject("foo"), + content: null, + }, + ...overrides, + }; +} + +function render(overrides = {}, position = { line: 0, column: 0 }) { + const clear = jest.fn(); + const props = generateDefaults(overrides); + + const doc = createMockDocument(clear, position); + setDocument(props.selectedSource.id, doc); + + const component = shallow(<SourceFooter.WrappedComponent {...props} />, { + lifecycleExperimental: true, + }); + return { component, props, clear, doc }; +} + +describe("SourceFooter Component", () => { + describe("default case", () => { + it("should render", () => { + const { component } = render(); + expect(component).toMatchSnapshot(); + }); + }); + + describe("move cursor", () => { + it("should render new cursor position", () => { + const { component } = render(); + component.setState({ cursorPosition: { line: 5, column: 10 } }); + + expect(component).toMatchSnapshot(); + }); + }); +}); diff --git a/devtools/client/debugger/src/components/Editor/tests/__snapshots__/Breakpoints.spec.js.snap b/devtools/client/debugger/src/components/Editor/tests/__snapshots__/Breakpoints.spec.js.snap new file mode 100644 index 0000000000..48cda915a4 --- /dev/null +++ b/devtools/client/debugger/src/components/Editor/tests/__snapshots__/Breakpoints.spec.js.snap @@ -0,0 +1,35 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Breakpoints Component should render breakpoints with columns 1`] = ` +<div> + <Breakpoint + breakpoint={ + Object { + "location": Object { + "column": 2, + "source": Object { + "id": "server1.conn1.child1/source1", + }, + }, + } + } + breakpointActions={Object {}} + cx={Object {}} + editor={ + Object { + "codeMirror": Object { + "setGutterMarker": [MockFunction], + }, + } + } + editorActions={Object {}} + key="undefined:undefined:2" + selectedSource={ + Object { + "get": [Function], + "sourceId": "server1.conn1.child1/source1", + } + } + /> +</div> +`; diff --git a/devtools/client/debugger/src/components/Editor/tests/__snapshots__/ConditionalPanel.spec.js.snap b/devtools/client/debugger/src/components/Editor/tests/__snapshots__/ConditionalPanel.spec.js.snap new file mode 100644 index 0000000000..d2f52bb6e3 --- /dev/null +++ b/devtools/client/debugger/src/components/Editor/tests/__snapshots__/ConditionalPanel.spec.js.snap @@ -0,0 +1,630 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`ConditionalPanel it should render at location of selected breakpoint 1`] = ` +<ConditionalPanel + breakpoint={ + Object { + "disabled": false, + "generatedLocation": Object { + "column": 2, + "line": 2, + "source": Object { + "id": "source", + }, + "sourceId": "source", + }, + "id": "breakpoint", + "location": Object { + "column": 2, + "line": 2, + "source": Object { + "id": "source", + }, + "sourceId": "source", + }, + "options": Object { + "condition": undefined, + "logValue": undefined, + }, + "originalText": "text", + "text": "text", + } + } + closeConditionalPanel={[MockFunction]} + editor={ + Object { + "CodeMirror": Object { + "fromTextArea": [MockFunction] { + "calls": Array [ + Array [ + <textarea />, + Object { + "cursorBlinkRate": 530, + "mode": "javascript", + "placeholder": "Breakpoint condition, e.g. items.length > 0", + "theme": "mozilla", + }, + ], + ], + "results": Array [ + Object { + "type": "return", + "value": Object { + "focus": [MockFunction] { + "calls": Array [ + Array [], + ], + "results": Array [ + Object { + "type": "return", + "value": undefined, + }, + ], + }, + "getWrapperElement": [MockFunction] { + "calls": Array [ + Array [], + ], + "results": Array [ + Object { + "type": "return", + "value": Object { + "addEventListener": [MockFunction] { + "calls": Array [ + Array [ + "keydown", + [Function], + ], + ], + "results": Array [ + Object { + "type": "return", + "value": undefined, + }, + ], + }, + }, + }, + ], + }, + "lineCount": [MockFunction] { + "calls": Array [ + Array [], + ], + "results": Array [ + Object { + "type": "return", + "value": undefined, + }, + ], + }, + "on": [MockFunction] { + "calls": Array [ + Array [ + "keydown", + [Function], + ], + Array [ + "blur", + [Function], + ], + ], + "results": Array [ + Object { + "type": "return", + "value": undefined, + }, + Object { + "type": "return", + "value": undefined, + }, + ], + }, + "setCursor": [MockFunction] { + "calls": Array [ + Array [ + undefined, + 0, + ], + ], + "results": Array [ + Object { + "type": "return", + "value": undefined, + }, + ], + }, + }, + }, + ], + }, + }, + "codeMirror": Object { + "addLineWidget": [MockFunction] { + "calls": Array [ + Array [ + 1, + <div> + <div + class="conditional-breakpoint-panel" + > + <div + class="prompt" + > + » + </div> + <textarea /> + </div> + </div>, + Object { + "coverGutter": true, + "noHScroll": true, + }, + ], + ], + "results": Array [ + Object { + "type": "return", + "value": undefined, + }, + ], + }, + }, + } + } + getDefaultValue={[MockFunction]} + location={ + Object { + "column": 2, + "line": 2, + "source": Object { + "id": "source", + }, + "sourceId": "source", + } + } + log={false} + openConditionalPanel={[MockFunction]} + source={ + Object { + "displayURL": Object { + "fileExtension": "", + "filename": "url", + "group": "", + "path": "url", + "search": "", + }, + "extensionName": null, + "id": "source", + "isExtension": false, + "isOriginal": false, + "isPrettyPrinted": false, + "isWasm": false, + "thread": "FakeThread", + "url": "url", + } + } +/> +`; + +exports[`ConditionalPanel it should render with condition at selected breakpoint location 1`] = ` +<ConditionalPanel + breakpoint={ + Object { + "disabled": false, + "generatedLocation": Object { + "column": 3, + "line": 3, + "source": Object { + "id": "source", + }, + "sourceId": "source", + }, + "id": "breakpoint", + "location": Object { + "column": 3, + "line": 3, + "source": Object { + "id": "source", + }, + "sourceId": "source", + }, + "options": Object { + "condition": "I'm a condition", + "logValue": "not a log", + }, + "originalText": "text", + "text": "text", + } + } + closeConditionalPanel={[MockFunction]} + editor={ + Object { + "CodeMirror": Object { + "fromTextArea": [MockFunction] { + "calls": Array [ + Array [ + <textarea> + I'm a condition + </textarea>, + Object { + "cursorBlinkRate": 530, + "mode": "javascript", + "placeholder": "Breakpoint condition, e.g. items.length > 0", + "theme": "mozilla", + }, + ], + ], + "results": Array [ + Object { + "type": "return", + "value": Object { + "focus": [MockFunction] { + "calls": Array [ + Array [], + ], + "results": Array [ + Object { + "type": "return", + "value": undefined, + }, + ], + }, + "getWrapperElement": [MockFunction] { + "calls": Array [ + Array [], + ], + "results": Array [ + Object { + "type": "return", + "value": Object { + "addEventListener": [MockFunction] { + "calls": Array [ + Array [ + "keydown", + [Function], + ], + ], + "results": Array [ + Object { + "type": "return", + "value": undefined, + }, + ], + }, + }, + }, + ], + }, + "lineCount": [MockFunction] { + "calls": Array [ + Array [], + ], + "results": Array [ + Object { + "type": "return", + "value": undefined, + }, + ], + }, + "on": [MockFunction] { + "calls": Array [ + Array [ + "keydown", + [Function], + ], + Array [ + "blur", + [Function], + ], + ], + "results": Array [ + Object { + "type": "return", + "value": undefined, + }, + Object { + "type": "return", + "value": undefined, + }, + ], + }, + "setCursor": [MockFunction] { + "calls": Array [ + Array [ + undefined, + 0, + ], + ], + "results": Array [ + Object { + "type": "return", + "value": undefined, + }, + ], + }, + }, + }, + ], + }, + }, + "codeMirror": Object { + "addLineWidget": [MockFunction] { + "calls": Array [ + Array [ + 2, + <div> + <div + class="conditional-breakpoint-panel" + > + <div + class="prompt" + > + » + </div> + <textarea> + I'm a condition + </textarea> + </div> + </div>, + Object { + "coverGutter": true, + "noHScroll": true, + }, + ], + ], + "results": Array [ + Object { + "type": "return", + "value": undefined, + }, + ], + }, + }, + } + } + getDefaultValue={[MockFunction]} + location={ + Object { + "column": 3, + "line": 3, + "source": Object { + "id": "source", + }, + "sourceId": "source", + } + } + log={false} + openConditionalPanel={[MockFunction]} + source={ + Object { + "displayURL": Object { + "fileExtension": "", + "filename": "url", + "group": "", + "path": "url", + "search": "", + }, + "extensionName": null, + "id": "source", + "isExtension": false, + "isOriginal": false, + "isPrettyPrinted": false, + "isWasm": false, + "thread": "FakeThread", + "url": "url", + } + } +/> +`; + +exports[`ConditionalPanel it should render with logpoint at selected breakpoint location 1`] = ` +<ConditionalPanel + breakpoint={ + Object { + "disabled": false, + "generatedLocation": Object { + "column": 4, + "line": 4, + "source": Object { + "id": "source", + }, + "sourceId": "source", + }, + "id": "breakpoint", + "location": Object { + "column": 4, + "line": 4, + "source": Object { + "id": "source", + }, + "sourceId": "source", + }, + "options": Object { + "condition": "not a condition", + "logValue": "I'm a log", + }, + "originalText": "text", + "text": "text", + } + } + closeConditionalPanel={[MockFunction]} + editor={ + Object { + "CodeMirror": Object { + "fromTextArea": [MockFunction] { + "calls": Array [ + Array [ + <textarea> + I'm a log + </textarea>, + Object { + "cursorBlinkRate": 530, + "mode": "javascript", + "placeholder": "Log message, e.g. displayName", + "theme": "mozilla", + }, + ], + ], + "results": Array [ + Object { + "type": "return", + "value": Object { + "focus": [MockFunction] { + "calls": Array [ + Array [], + ], + "results": Array [ + Object { + "type": "return", + "value": undefined, + }, + ], + }, + "getWrapperElement": [MockFunction] { + "calls": Array [ + Array [], + ], + "results": Array [ + Object { + "type": "return", + "value": Object { + "addEventListener": [MockFunction] { + "calls": Array [ + Array [ + "keydown", + [Function], + ], + ], + "results": Array [ + Object { + "type": "return", + "value": undefined, + }, + ], + }, + }, + }, + ], + }, + "lineCount": [MockFunction] { + "calls": Array [ + Array [], + ], + "results": Array [ + Object { + "type": "return", + "value": undefined, + }, + ], + }, + "on": [MockFunction] { + "calls": Array [ + Array [ + "keydown", + [Function], + ], + Array [ + "blur", + [Function], + ], + ], + "results": Array [ + Object { + "type": "return", + "value": undefined, + }, + Object { + "type": "return", + "value": undefined, + }, + ], + }, + "setCursor": [MockFunction] { + "calls": Array [ + Array [ + undefined, + 0, + ], + ], + "results": Array [ + Object { + "type": "return", + "value": undefined, + }, + ], + }, + }, + }, + ], + }, + }, + "codeMirror": Object { + "addLineWidget": [MockFunction] { + "calls": Array [ + Array [ + 3, + <div> + <div + class="conditional-breakpoint-panel log-point" + > + <div + class="prompt" + > + » + </div> + <textarea> + I'm a log + </textarea> + </div> + </div>, + Object { + "coverGutter": true, + "noHScroll": true, + }, + ], + ], + "results": Array [ + Object { + "type": "return", + "value": undefined, + }, + ], + }, + }, + } + } + getDefaultValue={[MockFunction]} + location={ + Object { + "column": 4, + "line": 4, + "source": Object { + "id": "source", + }, + "sourceId": "source", + } + } + log={true} + openConditionalPanel={[MockFunction]} + source={ + Object { + "displayURL": Object { + "fileExtension": "", + "filename": "url", + "group": "", + "path": "url", + "search": "", + }, + "extensionName": null, + "id": "source", + "isExtension": false, + "isOriginal": false, + "isPrettyPrinted": false, + "isWasm": false, + "thread": "FakeThread", + "url": "url", + } + } +/> +`; diff --git a/devtools/client/debugger/src/components/Editor/tests/__snapshots__/Footer.spec.js.snap b/devtools/client/debugger/src/components/Editor/tests/__snapshots__/Footer.spec.js.snap new file mode 100644 index 0000000000..d6123d4c67 --- /dev/null +++ b/devtools/client/debugger/src/components/Editor/tests/__snapshots__/Footer.spec.js.snap @@ -0,0 +1,105 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`SourceFooter Component default case should render 1`] = ` +<div + className="source-footer" +> + <div + className="source-footer-start" + > + <div + className="commands" + > + <button + aria-label="Ignore source" + className="action black-box" + key="black-box" + onClick={[Function]} + title="Ignore source" + > + <AccessibleImage + className="blackBox" + /> + </button> + <button + className="action prettyPrint" + disabled={true} + key="prettyPrint" + onClick={[Function]} + > + <AccessibleImage + className="prettyPrint" + /> + </button> + </div> + </div> + <div + className="source-footer-end" + > + <div + className="cursor-position" + title="(Line 1, column 1)" + > + (1, 1) + </div> + <PaneToggleButton + collapsed={false} + horizontal={false} + key="toggle" + position="end" + /> + </div> +</div> +`; + +exports[`SourceFooter Component move cursor should render new cursor position 1`] = ` +<div + className="source-footer" +> + <div + className="source-footer-start" + > + <div + className="commands" + > + <button + aria-label="Ignore source" + className="action black-box" + key="black-box" + onClick={[Function]} + title="Ignore source" + > + <AccessibleImage + className="blackBox" + /> + </button> + <button + className="action prettyPrint" + disabled={true} + key="prettyPrint" + onClick={[Function]} + > + <AccessibleImage + className="prettyPrint" + /> + </button> + </div> + </div> + <div + className="source-footer-end" + > + <div + className="cursor-position" + title="(Line 6, column 11)" + > + (6, 11) + </div> + <PaneToggleButton + collapsed={false} + horizontal={false} + key="toggle" + position="end" + /> + </div> +</div> +`; |