Skip to content
This repository was archived by the owner on Jan 11, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions circle.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
machine:
node:
version: 7.0
version: 7.7.2
services:
- docker
environment:
Expand All @@ -20,7 +20,7 @@ test:
- mkdir -p $CIRCLE_TEST_REPORTS/mocha
- mkdir -p $CIRCLE_TEST_REPORTS/flow-coverage
- mkdir -p $CIRCLE_TEST_REPORTS/jest-coverage
- node ./node_modules/.bin/jest --testResultsProcessor jest-junit-reporter --coverage --coverageDirectory=$CIRCLE_TEST_REPORTS/jest-coverage
- jest -i --testResultsProcessor jest-junit-reporter --coverage --coverageDirectory=$CIRCLE_TEST_REPORTS/jest-coverage
- yarn license-check
- yarn lint-css
- yarn lint-js
Expand Down
14 changes: 14 additions & 0 deletions flow-typed/debugger-html.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,20 @@ declare module "debugger-html" {
actualLocation: Location
};

/**
* PendingBreakpoint
*
* @memberof types
* @static
*/
declare type PendingBreakpoint = {
location: Location,
loading: boolean,
disabled: boolean,
text: string,
condition: ?string
};

/**
* Frame ID
*
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@
],
"testPathIgnorePatterns": [
"/node_modules/",
"/helpers/",
"<rootDir>/test/",
"<rootDir>/utils/tests/fixtures/"
],
Expand Down
3 changes: 1 addition & 2 deletions src/actions/breakpoints.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ export function addBreakpoint(
if (!text) {
text = getTextForLine ? getTextForLine(actualLocation.line) : "";
}

return { id, actualLocation, text, hitCount };
})()
});
Expand All @@ -110,7 +109,7 @@ export function removeBreakpoint(location: Location) {
return _removeOrDisableBreakpoint(location);
}

function _removeOrDisableBreakpoint(location, isDisabled) {
function _removeOrDisableBreakpoint(location, isDisabled = false) {
return ({ dispatch, getState, client }: ThunkArgs) => {
let bp = getBreakpoint(getState(), location);
if (!bp) {
Expand Down
73 changes: 43 additions & 30 deletions src/actions/sources.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,29 +46,38 @@ function checkSelectedSource(state, dispatch, source) {
}
}

function checkPendingBreakpoints(state, dispatch, source) {
const pendingBreakpoints = getPendingBreakpoints(state);

if (pendingBreakpoints) {
pendingBreakpoints.forEach(pendingBreakpoint => {
const {
location: { line, sourceUrl, column },
condition
} = pendingBreakpoint;
const sameSource = sourceUrl && sourceUrl == source.url;

const location = { sourceId: source.id, sourceUrl, line, column };
async function checkPendingBreakpoint(
state,
dispatch,
pendingBreakpoint,
source
) {
const {
location: { line, sourceUrl, column },
condition
} = pendingBreakpoint;
const sameSource = sourceUrl && sourceUrl === source.url;
const location = { sourceId: source.id, sourceUrl, line, column };
const bp = getBreakpoint(state, location);

if (sameSource && !bp) {
if (location.column && isEnabled("columnBreakpoints")) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned earlier, this block probably needs to be refactored. The if statements do not make sense, as in all cases we will call await dispatch(addBreakpoint(location, { condition }));. Instead we probably want to use an early return if !isEnabled("columnBreakpoints").

await dispatch(addBreakpoint(location, { condition }));
} else {
await dispatch(addBreakpoint(location, { condition }));
}
}
}

const bp = getBreakpoint(state, location);
async function checkPendingBreakpoints(state, dispatch, source) {
const pendingBreakpoints = getPendingBreakpoints(state);
if (!pendingBreakpoints) {
return;
}

if (sameSource && !bp) {
if (location.column && isEnabled("columnBreakpoints")) {
dispatch(addBreakpoint(location, { condition }));
} else {
dispatch(addBreakpoint(location, { condition }));
}
}
});
const pendingBreakpointsArray = pendingBreakpoints.valueSeq().toJS();
for (let pendingBreakpoint of pendingBreakpointsArray) {
await checkPendingBreakpoint(state, dispatch, pendingBreakpoint, source);
}
}

Expand All @@ -78,23 +87,27 @@ function checkPendingBreakpoints(state, dispatch, source) {
* @static
*/
export function newSource(source: Source) {
return ({ dispatch, getState }: ThunkArgs) => {
return async ({ dispatch, getState }: ThunkArgs) => {
dispatch({ type: constants.ADD_SOURCE, source });

if (prefs.clientSourceMapsEnabled) {
dispatch(loadSourceMap(source));
await dispatch(loadSourceMap(source));
}

dispatch({ type: constants.ADD_SOURCE, source });

checkSelectedSource(getState(), dispatch, source);
checkPendingBreakpoints(getState(), dispatch, source);
await checkPendingBreakpoints(getState(), dispatch, source);
};
}

export function newSources(sources: Source[]) {
return ({ dispatch, getState }: ThunkArgs) => {
sources
.filter(source => !getSource(getState(), source.id))
.forEach(source => dispatch(newSource(source)));
return async ({ dispatch, getState }: ThunkArgs) => {
const filteredSources = sources.filter(
source => !getSource(getState(), source.id)
);

for (let source of filteredSources) {
await dispatch(newSource(source));
}
};
}

Expand Down
66 changes: 43 additions & 23 deletions src/actions/tests/breakpoints.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,54 @@
import { createStore, selectors, actions } from "../../utils/test-head";
import expect from "expect.js";

const simpleMockThreadClient = {
setBreakpoint: (location, condition) => {
return new Promise((resolve, reject) => {
resolve({ id: "hi", actualLocation: location });
});
},

removeBreakpoint: id => {
return new Promise((resolve, reject) => {
resolve({ status: "done" });
});
},

setBreakpointCondition: (id, location, condition, noSliding) => {
return new Promise((resolve, reject) => {
resolve({ sourceId: "a", line: 5 });
});
}
};
import { createStore, selectors, actions } from "../../utils/test-head";
import {
simulateCorrectThreadClient,
simpleMockThreadClient
} from "./helpers/breakpoints.js";

describe("breakpoints", () => {
it("should add a breakpoint", async () => {
const { dispatch, getState } = createStore(simpleMockThreadClient);
const loc1 = { sourceId: "a", line: 5 };

await dispatch(actions.addBreakpoint({ sourceId: "a", line: 5 }));
await dispatch(actions.addBreakpoint({ sourceId: "b", line: 6 }));
await dispatch(actions.addBreakpoint(loc1));
const bps = selectors.getBreakpoints(getState());
const bp = selectors.getBreakpoint(getState(), loc1);
expect(bps.size).to.be(1);
expect(bp.location).to.eql(loc1);
});

expect(selectors.getBreakpoints(getState()).size).to.be(2);
it("should not re-add a breakpoint", async () => {
const { dispatch, getState } = createStore(simpleMockThreadClient);
const loc1 = { sourceId: "a", line: 5 };

await dispatch(actions.addBreakpoint(loc1));
let bps = selectors.getBreakpoints(getState());
const bp = selectors.getBreakpoint(getState(), loc1);
expect(bps.size).to.be(1);
expect(bp.location).to.eql(loc1);

await dispatch(actions.addBreakpoint(loc1));
bps = selectors.getBreakpoints(getState());
expect(bps.size).to.be(1);
});

describe("adding a breakpoint to an invalid location", async () => {
it("adds only one breakpoint with a corrected location", async () => {
const invalidLocation = { sourceId: "a", line: 5 };
const {
correctedThreadClient,
correctedLocation
} = simulateCorrectThreadClient(2, invalidLocation);
const { dispatch, getState } = createStore(correctedThreadClient);

await dispatch(actions.addBreakpoint(invalidLocation));
const state = getState();
const bps = selectors.getBreakpoints(state);
const bp = selectors.getBreakpoint(state, correctedLocation);
expect(bps.size).to.be(1);
expect(bp.location).to.eql(correctedLocation);
});
});

it("should remove a breakpoint", async () => {
Expand Down
79 changes: 79 additions & 0 deletions src/actions/tests/helpers/breakpoints.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { makeLocationId } from "../../../reducers/breakpoints";

export const theMockedPendingBreakpoint = {
location: {
sourceUrl: "http://localhost:8000/examples/bar.js",
line: 5,
column: undefined
},
condition: "3",
disabled: false
};

export function generateCorrectedBreakpoint(breakpoint, correctedLocation) {
return Object.assign({}, breakpoint, { location: correctedLocation });
}

function generateCorrectingThreadClient(offset = 0) {
return {
setBreakpoint: (location, condition) => {
const actualLocation = Object.assign({}, location, {
line: location.line + offset
});

return Promise.resolve({
id: makeLocationId(location),
actualLocation,
condition
});
}
};
}

/* in some cases, a breakpoint may be added, but the source will respond
* with a different breakpoint location. This is due to the breakpoint being
* added between functions, or somewhere that doesnt make sense. This function
* simulates that behavior.
* */
export function simulateCorrectThreadClient(offset, location) {
const correctedThreadClient = generateCorrectingThreadClient(offset);
const offsetLine = { line: location.line + offset };
const correctedLocation = Object.assign({}, location, offsetLine);
return { correctedThreadClient, correctedLocation };
}

export function generateBreakpoint(filename) {
return {
location: {
sourceUrl: `http://localhost:8000/examples/${filename}`,
sourceId: filename,
line: 5
},
condition: null,
disabled: false
};
}

export function generatePendingBreakpoint(breakpoint) {
const {
location: { sourceUrl, line, column },
condition,
disabled
} = breakpoint;

return {
location: { sourceUrl, line, column },
condition,
disabled
};
}

export const simpleMockThreadClient = {
setBreakpoint: (location, _condition) =>
Promise.resolve({ id: "hi", actualLocation: location }),

removeBreakpoint: _id => Promise.resolve({ status: "done" }),

setBreakpointCondition: (_id, _location, _condition, _noSliding) =>
Promise.resolve({ sourceId: "a", line: 5 })
};
Loading