Bug 1533418 - Support multiple workers as roots. r=jlast

http://dbg-workers.glitch.me

Updated tests in SourcesTree.spec.js to pass and
added test to ensure sources are added to the correct thread

Differential Revision: https://phabricator.services.mozilla.com/D29225

--HG--
extra : moz-landing-system : lando
This commit is contained in:
David Walsh 2019-05-08 07:14:44 +00:00
Родитель 7ccddfedc4
Коммит 0e8cd5dc37
50 изменённых файлов: 1198 добавлений и 984 удалений

Просмотреть файл

@ -46,5 +46,6 @@ DevToolsModules(
'stepOver.svg',
'tab.svg',
'whole-word-match.svg',
'window.svg',
'worker.svg',
)

Просмотреть файл

@ -0,0 +1,4 @@
<!-- 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/. -->
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill="context-fill" d="M13 1H3a3 3 0 0 0-3 3v8a3 3 0 0 0 3 3h11a2 2 0 0 0 2-2V4a3 3 0 0 0-3-3zm1 11a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V6h12zm0-7H2V4a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1z"></path></svg>

После

Ширина:  |  Высота:  |  Размер: 491 B

Просмотреть файл

@ -58,7 +58,7 @@ export function connect(url: string, actor: string, canRewind: boolean) {
dispatch(
({
type: "CONNECT",
mainThread: { url, actor, type: -1 },
mainThread: { url, actor, type: -1, name: "" },
canRewind
}: Action)
);

Просмотреть файл

@ -3,27 +3,12 @@
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
// @flow
import type { Action, FocusItem, ThunkArgs } from "./types";
import type { Context } from "../types";
import type { TreeNode } from "../utils/sources-tree/types";
export function setExpandedState(thread: string, expanded: Set<string>) {
return ({ dispatch, getState }: ThunkArgs) => {
dispatch(
({
type: "SET_EXPANDED_STATE",
thread,
expanded
}: Action)
);
};
export function setExpandedState(expanded: Set<string>) {
return { type: "SET_EXPANDED_STATE", expanded };
}
export function focusItem(cx: Context, item: FocusItem) {
return ({ dispatch, getState }: ThunkArgs) => {
dispatch({
type: "SET_FOCUSED_SOURCE_ITEM",
cx,
item
});
};
export function focusItem(item: TreeNode) {
return { type: "SET_FOCUSED_SOURCE_ITEM", item };
}

Просмотреть файл

@ -30,16 +30,10 @@ describe("blackbox", () => {
throw new Error("foo should exist");
}
const { thread } = selectors.getSourceActorsForSource(
getState(),
foo1Source.id
)[0];
const displayedSources = selectors.getDisplayedSourcesForThread(
getState(),
thread
const displayedSources = selectors.getDisplayedSources(getState());
expect(displayedSources.FakeThread[fooSource.id].isBlackBoxed).toEqual(
true
);
expect(displayedSources[fooSource.id].isBlackBoxed).toEqual(true);
expect(fooSource.isBlackBoxed).toEqual(true);
});
});

Просмотреть файл

@ -11,8 +11,6 @@ import {
makeSource
} from "../../utils/test-head";
import type { Source } from "../../types";
const { getProjectDirectoryRoot, getDisplayedSources } = selectors;
describe("setProjectDirectoryRoot", () => {
@ -54,14 +52,15 @@ describe("setProjectDirectoryRoot", () => {
dispatch(actions.setProjectDirectoryRoot(cx, "localhost:8000/examples/js"));
const filteredSourcesByThread = getDisplayedSources(getState());
const filteredSources = Object.values(filteredSourcesByThread)[0];
const firstSource: Source = (Object.values(filteredSources)[0]: any);
const filteredSources = (Object.values(
filteredSourcesByThread.FakeThread
): any)[0];
expect(firstSource.url).toEqual(
expect(filteredSources.url).toEqual(
"http://localhost:8000/examples/js/scopes.js"
);
expect(firstSource.relativeUrl).toEqual("scopes.js");
expect(filteredSources.relativeUrl).toEqual("scopes.js");
});
it("should update the child directory ", () => {

Просмотреть файл

@ -12,8 +12,8 @@ describe("source tree", () => {
const { dispatch, getState } = createStore();
const expandedState = new Set(["foo", "bar"]);
expect(getExpandedState(getState(), "FakeThread")).toEqual(undefined);
dispatch(actions.setExpandedState("FakeThread", expandedState));
expect(getExpandedState(getState(), "FakeThread")).toEqual(expandedState);
expect(getExpandedState(getState())).toEqual(new Set([]));
dispatch(actions.setExpandedState(expandedState));
expect(getExpandedState(getState())).toEqual(expandedState);
});
});

Просмотреть файл

@ -71,10 +71,7 @@ type NavigateAction =
| {| +type: "CONNECT", +mainThread: MainThread, +canRewind: boolean |}
| {| +type: "NAVIGATE", +mainThread: MainThread |};
export type FocusItem = {
thread: string,
item: TreeNode
};
export type FocusItem = TreeNode;
export type SourceTreeAction =
| {| +type: "SET_EXPANDED_STATE", +thread: string, +expanded: any |}

Просмотреть файл

@ -77,6 +77,7 @@ export function createWorker(actor: string, url: string) {
actor,
url,
// Ci.nsIWorkerDebugger.TYPE_DEDICATED
type: 0
type: 0,
name: ""
};
}

Просмотреть файл

@ -16,10 +16,8 @@ import {
getDebuggeeUrl,
getExpandedState,
getProjectDirectoryRoot,
getDisplayedSourcesForThread,
getDisplayedSources,
getFocusedSourceItem,
getWorkerByThread,
getWorkerCount,
getContext
} from "../../selectors";
@ -29,7 +27,6 @@ import { getGeneratedSourceByURL } from "../../reducers/sources";
import actions from "../../actions";
// Components
import AccessibleImage from "../shared/AccessibleImage";
import SourcesTreeItem from "./SourcesTreeItem";
import ManagedTree from "../shared/ManagedTree";
@ -42,25 +39,25 @@ import {
nodeHasChildren,
updateTree
} from "../../utils/sources-tree";
import { parse } from "../../utils/url";
import { getRawSourceURL } from "../../utils/source";
import { getDisplayName } from "../../utils/workers";
import { features } from "../../utils/prefs";
import type {
TreeNode,
TreeDirectory,
ParentMap
} from "../../utils/sources-tree/types";
import type { Worker, Source, Context } from "../../types";
import type { SourcesMap, State as AppState } from "../../reducers/types";
import type { Source, Context, Thread } from "../../types";
import type {
SourcesMapByThread,
State as AppState
} from "../../reducers/types";
import type { Item } from "../shared/ManagedTree";
type Props = {
cx: Context,
thread: string,
worker: Worker,
sources: SourcesMap,
threads: Thread[],
sources: SourcesMapByThread,
sourceCount: number,
shownSource?: Source,
selectedSource?: Source,
@ -70,8 +67,7 @@ type Props = {
selectSource: typeof actions.selectSource,
setExpandedState: typeof actions.setExpandedState,
focusItem: typeof actions.focusItem,
focused: TreeNode,
workerCount: number
focused: TreeNode
};
type State = {
@ -84,17 +80,24 @@ type State = {
type SetExpanded = (item: TreeNode, expanded: boolean, altKey: boolean) => void;
class SourcesTree extends Component<Props, State> {
mounted: boolean;
function shouldAutoExpand(depth, item, debuggeeUrl) {
if (depth !== 1) {
return false;
}
const { host } = parse(debuggeeUrl);
return item.name === host;
}
class SourcesTree extends Component<Props, State> {
constructor(props: Props) {
super(props);
const { debuggeeUrl, sources, projectRoot } = this.props;
const { debuggeeUrl, sources, threads } = this.props;
this.state = createTree({
projectRoot,
debuggeeUrl,
sources
sources,
threads
});
}
@ -104,21 +107,24 @@ class SourcesTree extends Component<Props, State> {
debuggeeUrl,
sources,
shownSource,
selectedSource
selectedSource,
threads
} = this.props;
const { uncollapsedTree, sourceTree } = this.state;
if (
projectRoot != nextProps.projectRoot ||
debuggeeUrl != nextProps.debuggeeUrl ||
threads != nextProps.threads ||
nextProps.sourceCount === 0
) {
// early recreate tree because of changes
// to project root, debugee url or lack of sources
// to project root, debuggee url or lack of sources
return this.setState(
createTree({
sources: nextProps.sources,
debuggeeUrl: nextProps.debuggeeUrl
debuggeeUrl: nextProps.debuggeeUrl,
threads: nextProps.threads
})
);
}
@ -145,6 +151,7 @@ class SourcesTree extends Component<Props, State> {
this.setState(
updateTree({
newSources: nextProps.sources,
threads: nextProps.threads,
prevSources: sources,
debuggeeUrl,
uncollapsedTree,
@ -161,7 +168,7 @@ class SourcesTree extends Component<Props, State> {
};
onFocus = (item: TreeNode) => {
this.props.focusItem(this.props.cx, { thread: this.props.thread, item });
this.props.focusItem(item);
};
onActivate = (item: TreeNode) => {
@ -170,16 +177,11 @@ class SourcesTree extends Component<Props, State> {
// NOTE: we get the source from sources because item.contents is cached
getSource(item: TreeNode): ?Source {
const source = getSourceFromNode(item);
if (source) {
return this.props.sources[source.id];
}
return null;
return getSourceFromNode(item);
}
getPath = (item: TreeNode): string => {
const path = `${item.path}/${item.name}`;
const { path } = item;
const source = this.getSource(item);
if (!source || isDirectory(item)) {
@ -187,15 +189,16 @@ class SourcesTree extends Component<Props, State> {
}
const blackBoxedPart = source.isBlackBoxed ? ":blackboxed" : "";
return `${path}/${source.id}/${blackBoxedPart}`;
};
onExpand = (item: Item, expandedState: Set<string>) => {
this.props.setExpandedState(this.props.thread, expandedState);
this.props.setExpandedState(expandedState);
};
onCollapse = (item: Item, expandedState: Set<string>) => {
this.props.setExpandedState(this.props.thread, expandedState);
this.props.setExpandedState(expandedState);
};
isEmpty() {
@ -230,6 +233,10 @@ class SourcesTree extends Component<Props, State> {
return sourceTree.contents;
};
getChildren = (item: $Shape<TreeDirectory>) => {
return nodeHasChildren(item) ? item.contents : [];
};
renderItem = (
item: TreeNode,
depth: number,
@ -238,13 +245,15 @@ class SourcesTree extends Component<Props, State> {
expanded: boolean,
{ setExpanded }: { setExpanded: SetExpanded }
) => {
const { debuggeeUrl, projectRoot } = this.props;
const { debuggeeUrl, projectRoot, threads } = this.props;
return (
<SourcesTreeItem
item={item}
threads={threads}
depth={depth}
focused={focused}
autoExpand={shouldAutoExpand(depth, item, debuggeeUrl)}
expanded={expanded}
focusItem={this.onFocus}
selectItem={this.selectItem}
@ -258,15 +267,15 @@ class SourcesTree extends Component<Props, State> {
renderTree() {
const { expanded, focused } = this.props;
const { highlightItems, listItems, parentMap } = this.state;
const treeProps = {
autoExpandAll: false,
autoExpandDepth: expanded ? 0 : 1,
autoExpandDepth: 1,
expanded,
focused,
getChildren: (item: $Shape<TreeDirectory>) =>
nodeHasChildren(item) ? item.contents : [],
getChildren: this.getChildren,
getParent: (item: $Shape<TreeNode>) => parentMap.get(item),
getPath: this.getPath,
getRoots: this.getRoots,
@ -286,14 +295,13 @@ class SourcesTree extends Component<Props, State> {
}
renderPane(...children) {
const { projectRoot, thread } = this.props;
const { projectRoot } = this.props;
return (
<div
key="pane"
className={classnames("sources-pane", {
"sources-list-custom-root": projectRoot,
thread
"sources-list-custom-root": projectRoot
})}
>
{children}
@ -301,39 +309,8 @@ class SourcesTree extends Component<Props, State> {
);
}
renderThreadHeader() {
const { worker, workerCount } = this.props;
if (!features.windowlessWorkers || workerCount == 0) {
return null;
}
if (worker) {
return (
<div className="node thread-header" key="thread-header">
<AccessibleImage className="worker" />
<span className="label">{getDisplayName(worker)}</span>
</div>
);
}
return (
<div className="node thread-header" key="thread-header">
<AccessibleImage className={"file"} />
<span className="label">{L10N.getStr("mainThread")}</span>
</div>
);
}
render() {
const { worker } = this.props;
if (!features.windowlessWorkers && worker) {
return null;
}
return this.renderPane(
this.renderThreadHeader(),
this.isEmpty() ? (
this.renderEmptyElement(L10N.getStr("noSourcesText"))
) : (
@ -347,15 +324,13 @@ class SourcesTree extends Component<Props, State> {
function getSourceForTree(
state: AppState,
displayedSources: SourcesMap,
source: ?Source,
thread
displayedSources: SourcesMapByThread,
source: ?Source
): ?Source {
if (!source) {
return null;
}
source = displayedSources[source.id];
if (!source || !source.isPrettyPrinted) {
return source;
}
@ -366,27 +341,19 @@ function getSourceForTree(
const mapStateToProps = (state, props) => {
const selectedSource = getSelectedSource(state);
const shownSource = getShownSource(state);
const focused = getFocusedSourceItem(state);
const thread = props.thread;
const displayedSources = getDisplayedSourcesForThread(state, thread);
const displayedSources = getDisplayedSources(state);
return {
threads: props.threads,
cx: getContext(state),
shownSource: getSourceForTree(state, displayedSources, shownSource, thread),
selectedSource: getSourceForTree(
state,
displayedSources,
selectedSource,
thread
),
shownSource: getSourceForTree(state, displayedSources, shownSource),
selectedSource: getSourceForTree(state, displayedSources, selectedSource),
debuggeeUrl: getDebuggeeUrl(state),
expanded: getExpandedState(state, props.thread),
focused: focused && focused.thread == props.thread ? focused.item : null,
expanded: getExpandedState(state),
focused: getFocusedSourceItem(state),
projectRoot: getProjectDirectoryRoot(state),
sources: displayedSources,
sourceCount: Object.values(displayedSources).length,
worker: getWorkerByThread(state, thread),
workerCount: getWorkerCount(state)
sourceCount: Object.values(displayedSources).length
};
};

Просмотреть файл

@ -11,12 +11,14 @@ import { showMenu } from "devtools-contextmenu";
import SourceIcon from "../shared/SourceIcon";
import AccessibleImage from "../shared/AccessibleImage";
import { getDisplayName, isWorker } from "../../utils/workers";
import {
getGeneratedSourceByURL,
getHasSiblingOfSameName,
hasPrettySource as checkHasPrettySource,
getContext
getContext,
getMainThread
} from "../../selectors";
import actions from "../../actions";
@ -31,9 +33,10 @@ import { copyToTheClipboard } from "../../utils/clipboard";
import { features } from "../../utils/prefs";
import type { TreeNode } from "../../utils/sources-tree/types";
import type { Source, Context } from "../../types";
import type { Source, Context, MainThread, Thread } from "../../types";
type Props = {
autoExpand: ?boolean,
cx: Context,
debuggeeUrl: string,
projectRoot: string,
@ -42,6 +45,8 @@ type Props = {
depth: number,
focused: boolean,
expanded: boolean,
threads: Thread[],
mainThread: MainThread,
hasMatchingGeneratedSource: boolean,
hasSiblingOfSameName: boolean,
hasPrettySource: boolean,
@ -65,47 +70,17 @@ type MenuOption = {
type ContextMenu = Array<MenuOption>;
class SourceTreeItem extends Component<Props, State> {
getIcon(item: TreeNode, depth: number) {
const { debuggeeUrl, projectRoot, source, hasPrettySource } = this.props;
if (item.path === "webpack://") {
return <AccessibleImage className="webpack" />;
} else if (item.path === "ng://") {
return <AccessibleImage className="angular" />;
} else if (isUrlExtension(item.path) && depth === 0) {
return <AccessibleImage className="extension" />;
componentDidMount() {
const { autoExpand, item } = this.props;
if (autoExpand) {
this.props.setExpanded(item, true, false);
}
if (depth === 0 && projectRoot === "") {
return (
<AccessibleImage
className={classnames("globe-small", {
debuggee: debuggeeUrl && debuggeeUrl.includes(item.name)
})}
/>
);
}
if (isDirectory(item)) {
return <AccessibleImage className="folder" />;
}
if (hasPrettySource) {
return <AccessibleImage className="prettyPrint" />;
}
if (source) {
return <SourceIcon source={source} />;
}
return null;
}
onClick = (e: MouseEvent) => {
const { item, focusItem, selectItem } = this.props;
focusItem(item);
if (!isDirectory(item)) {
selectItem(item);
}
@ -208,8 +183,69 @@ class SourceTreeItem extends Component<Props, State> {
);
}
renderItemName() {
const { item } = this.props;
renderIcon(item: TreeNode, depth: number) {
const {
debuggeeUrl,
projectRoot,
source,
hasPrettySource,
threads
} = this.props;
if (item.name === "webpack://") {
return <AccessibleImage className="webpack" />;
} else if (item.name === "ng://") {
return <AccessibleImage className="angular" />;
} else if (isUrlExtension(item.path) && depth === 1) {
return <AccessibleImage className="extension" />;
}
// Threads level
if (depth === 0 && projectRoot === "") {
const thread = threads.find(thrd => thrd.actor == item.name);
if (thread) {
const icon = thread === this.props.mainThread ? "window" : "worker";
return (
<AccessibleImage
className={classnames(icon, {
debuggee: debuggeeUrl && debuggeeUrl.includes(item.name)
})}
/>
);
}
}
if (isDirectory(item)) {
// Domain level
if (depth === 1) {
return <AccessibleImage className="globe-small" />;
}
return <AccessibleImage className="folder" />;
}
if (hasPrettySource) {
return <AccessibleImage className="prettyPrint" />;
}
if (source) {
return <SourceIcon source={source} />;
}
return null;
}
renderItemName(depth) {
const { item, threads } = this.props;
if (depth === 0) {
const thread = threads.find(({ actor }) => actor == item.name);
if (thread) {
return isWorker(thread)
? getDisplayName((thread: any))
: L10N.getStr("mainThread");
}
}
switch (item.name) {
case "ng://":
@ -253,10 +289,9 @@ class SourceTreeItem extends Component<Props, State> {
onContextMenu={e => this.onContextMenu(e, item)}
>
{this.renderItemArrow()}
{this.getIcon(item, depth)}
{this.renderIcon(item, depth)}
<span className="label">
{" "}
{this.renderItemName()}
{this.renderItemName(depth)}
{query} {suffix}
</span>
</div>
@ -276,6 +311,7 @@ const mapStateToProps = (state, props) => {
const { source } = props;
return {
cx: getContext(state),
mainThread: getMainThread(state),
hasMatchingGeneratedSource: getHasMatchingGeneratedSource(state, source),
hasSiblingOfSameName: getHasSiblingOfSameName(state, source),
hasPrettySource: source ? checkHasPrettySource(state, source.id) : false

Просмотреть файл

@ -127,9 +127,7 @@ class PrimaryPanes extends Component<Props, State> {
}
renderThreadSources() {
return this.props.threads.map(({ actor }) => (
<SourcesTree thread={actor} key={actor} />
));
return <SourcesTree threads={this.props.threads} />;
}
render() {

Просмотреть файл

@ -83,8 +83,10 @@ describe("SourcesTree", () => {
const newSource = createMockSource(
"server1.conn13.child1/43",
"http://mdn.com/four.js",
true
true,
""
);
const newThreadSources = {
...props.sources.FakeThread,
"server1.conn13.child1/43": newSource
@ -92,15 +94,12 @@ describe("SourcesTree", () => {
await component.setProps({
...props,
sources: {
...props.sources,
...newThreadSources
}
sources: newThreadSources
});
expect(
component.state("uncollapsedTree").contents[0].contents
).toHaveLength(6);
component.state("uncollapsedTree").contents[0].contents[0].contents
).toHaveLength(5);
});
it("updates sources if sources are emptied", async () => {
@ -120,15 +119,17 @@ describe("SourcesTree", () => {
it("recreates tree if projectRoot is changed", async () => {
const { component, props, defaultState } = render();
const sources = {
"server1.conn13.child1/41": createMockSource(
"server1.conn13.child1/41",
"http://mozilla.com/three.js"
)
FakeThread: {
"server1.conn13.child1/41": createMockSource(
"server1.conn13.child1/41",
"http://mozilla.com/three.js"
)
}
};
expect(defaultState.uncollapsedTree.contents[0].contents).toHaveLength(
5
);
expect(
defaultState.uncollapsedTree.contents[0].contents[0].contents
).toHaveLength(5);
await component.setProps({
...props,
@ -141,18 +142,22 @@ describe("SourcesTree", () => {
).toHaveLength(1);
});
it("recreates tree if debugeeUrl is changed", async () => {
it("recreates tree if debuggeeUrl is changed", async () => {
const { component, props, defaultState } = render();
const sources = {
"server1.conn13.child1/41": createMockSource(
"server1.conn13.child1/41",
"http://mdn.com/three.js"
)
FakeThread: {
"server1.conn13.child1/41": createMockSource(
"server1.conn13.child1/41",
"http://mdn.com/three.js",
true,
""
)
}
};
expect(defaultState.uncollapsedTree.contents[0].contents).toHaveLength(
5
);
expect(
defaultState.uncollapsedTree.contents[0].contents[0].contents
).toHaveLength(5);
await component.setProps({
...props,
@ -166,6 +171,56 @@ describe("SourcesTree", () => {
});
});
describe("updates threads", () => {
it("adds sources to the correct thread", async () => {
const { component, props } = render();
const newSource = createMockSource(
"server1.conn13.child1/43",
"http://mdn.com/four.js",
true,
""
);
const newThreadSources = {
FakeThread1: {
"server1.conn13.child1/43": newSource
}
};
expect(component.state("uncollapsedTree").contents[0].name).toEqual(
"FakeThread"
);
expect(
component.state("uncollapsedTree").contents[0].contents[0].contents
).toHaveLength(5);
expect(component.state("uncollapsedTree").contents[1]).toEqual(
undefined
);
await component.setProps({
...props,
sources: {
...props.sources,
...newThreadSources
}
});
expect(component.state("uncollapsedTree").contents[0].name).toEqual(
"FakeThread"
);
expect(
component.state("uncollapsedTree").contents[0].contents[0].contents
).toHaveLength(5);
expect(component.state("uncollapsedTree").contents[1].name).toEqual(
"FakeThread1"
);
expect(
component.state("uncollapsedTree").contents[1].contents[0].contents
).toHaveLength(1);
});
});
describe("updates highlighted items", () => {
it("updates highlightItems if selectedSource changes", async () => {
const { component, props } = render();
@ -173,8 +228,7 @@ describe("SourcesTree", () => {
"server1.conn13.child1/41",
"http://mdn.com/three.js",
false,
null,
"FakeThread"
null
);
await component.setProps({
...props,
@ -247,10 +301,7 @@ describe("SourcesTree", () => {
.find("ManagedTree")
.props()
.onExpand({}, expandedState);
expect(props.setExpandedState).toHaveBeenCalledWith(
"FakeThread",
expandedState
);
expect(props.setExpandedState).toHaveBeenCalledWith(expandedState);
});
it("onCollapse", async () => {
@ -260,10 +311,7 @@ describe("SourcesTree", () => {
.find("ManagedTree")
.props()
.onCollapse({}, expandedState);
expect(props.setExpandedState).toHaveBeenCalledWith(
"FakeThread",
expandedState
);
expect(props.setExpandedState).toHaveBeenCalledWith(expandedState);
});
it("getParent", async () => {
@ -274,8 +322,8 @@ describe("SourcesTree", () => {
.props()
.getParent(item);
expect(parent.path).toEqual("mdn.com");
expect(parent.contents).toHaveLength(5);
expect(parent.path).toEqual("FakeThread");
expect(parent.contents[0].contents).toHaveLength(5);
});
});
@ -283,31 +331,7 @@ describe("SourcesTree", () => {
it("should return path for item", async () => {
const { instance } = render();
const path = instance.getPath(createMockItem());
expect(path).toEqual(
"http://mdn.com/one.js/one.js/server1.conn13.child1/39/"
);
});
it("should return path for blackboxedboxed item", async () => {
const item = createMockItem(
"http://mdn.com/blackboxed.js",
"blackboxed.js",
{ id: "server1.conn13.child1/59" }
);
const sources = {
"server1.conn13.child1/59": createMockSource(
"server1.conn13.child1/59",
"http://mdn.com/blackboxed.js",
true
)
};
const { instance } = render({ sources });
const path = instance.getPath(item);
expect(path).toEqual(
"http://mdn.com/blackboxed.js/blackboxed.js/server1.conn13.child1/59/:blackboxed"
);
expect(path).toEqual("http://mdn.com/one.js/server1.conn13.child1/39/");
});
it("should return path for generated item", async () => {
@ -318,7 +342,7 @@ describe("SourcesTree", () => {
})
);
expect(pathOriginal).toEqual(
"http://mdn.com/four.js/four.js/server1.conn13.child1/42/originalSource-sha/"
"http://mdn.com/four.js/server1.conn13.child1/42/originalSource-sha/"
);
const pathGenerated = instance.getPath(
@ -327,7 +351,7 @@ describe("SourcesTree", () => {
})
);
expect(pathGenerated).toEqual(
"http://mdn.com/four.js/four.js/server1.conn13.child1/42/"
"http://mdn.com/four.js/server1.conn13.child1/42/"
);
});
});
@ -335,32 +359,42 @@ describe("SourcesTree", () => {
function generateDefaults(overrides: Object) {
const defaultSources = {
"server1.conn13.child1/39": createMockSource(
"server1.conn13.child1/39",
"http://mdn.com/one.js"
),
"server1.conn13.child1/40": createMockSource(
"server1.conn13.child1/40",
"http://mdn.com/two.js"
),
"server1.conn13.child1/41": createMockSource(
"server1.conn13.child1/41",
"http://mdn.com/three.js"
),
"server1.conn13.child1/42/originalSource-sha": createMockSource(
"server1.conn13.child1/42/originalSource-sha",
"http://mdn.com/four.js"
),
"server1.conn13.child1/42": createMockSource(
"server1.conn13.child1/42",
"http://mdn.com/four.js",
false,
"data:application/json?charset=utf?dsffewrsf"
)
FakeThread: {
"server1.conn13.child1/39": createMockSource(
"server1.conn13.child1/39",
"http://mdn.com/one.js",
false,
null
),
"server1.conn13.child1/40": createMockSource(
"server1.conn13.child1/40",
"http://mdn.com/two.js",
false,
null
),
"server1.conn13.child1/41": createMockSource(
"server1.conn13.child1/41",
"http://mdn.com/three.js",
false,
null
),
"server1.conn13.child1/42/originalSource-sha": createMockSource(
"server1.conn13.child1/42/originalSource-sha",
"http://mdn.com/four.js",
false,
null
),
"server1.conn13.child1/42": createMockSource(
"server1.conn13.child1/42",
"http://mdn.com/four.js",
false,
"data:application/json?charset=utf?dsffewrsf"
)
}
};
return {
cx: mockcx,
thread: "FakeThread",
autoExpandAll: true,
selectSource: jest.fn(),
setExpandedState: jest.fn(),
@ -370,6 +404,16 @@ function generateDefaults(overrides: Object) {
setProjectDirectoryRoot: jest.fn(),
focusItem: jest.fn(),
projectRoot: "",
threads: [
{
name: "FakeThread",
actor: "FakeThread"
},
{
name: "FakeThread1",
actor: "FakeThread1"
}
],
...overrides
};
}
@ -386,13 +430,7 @@ function render(overrides = {}) {
return { component, props, defaultState, instance };
}
function createMockSource(
id,
url,
isBlackBoxed = false,
sourceMapURL = null,
thread = ""
) {
function createMockSource(id, url, isBlackBoxed = false, sourceMapURL = null) {
return {
...makeMockSource(url, id),
isBlackBoxed,

Просмотреть файл

@ -375,6 +375,7 @@ function generateDefaults(overrides) {
selectItem: jest.fn(),
focusItem: jest.fn(),
setExpanded: jest.fn(),
threads: [{ name: "Main Thread" }],
...overrides
};
}
@ -389,7 +390,11 @@ function render(overrides = {}) {
return { component, props, defaultState, instance };
}
function createMockDirectory(path = "folder/", name = "folder", contents = []) {
function createMockDirectory(
path = "domain/subfolder",
name = "folder",
contents = []
) {
return {
type: "directory",
name,

Просмотреть файл

@ -57,6 +57,9 @@ exports[`PrimaryPanes with custom root renders custom root source list 1`] = `
</span>
</button>
</div>
<Connect(SourcesTree)
threads={Array []}
/>
</div>
<Connect(Outline)
alphabetizeOutline={false}
@ -123,6 +126,9 @@ exports[`PrimaryPanes with custom root renders empty custom root source list 1`]
</span>
</button>
</div>
<Connect(SourcesTree)
threads={Array []}
/>
</div>
<Connect(Outline)
alphabetizeOutline={false}

Просмотреть файл

@ -2,29 +2,16 @@
exports[`SourcesTree After changing expanded nodes Shows the tree with four.js, five.js and six.js expanded 1`] = `
<div
className="sources-pane thread"
className="sources-pane"
key="pane"
>
<div
className="node thread-header"
key="thread-header"
>
<AccessibleImage
className="file"
/>
<span
className="label"
>
Main Thread
</span>
</div>
<div
className="sources-list"
key="tree"
>
<ManagedTree
autoExpandAll={false}
autoExpandDepth={0}
autoExpandDepth={1}
expanded={
Array [
"four.js",
@ -51,22 +38,9 @@ exports[`SourcesTree After changing expanded nodes Shows the tree with four.js,
exports[`SourcesTree Should show a 'No Sources' message if there are no sources 1`] = `
<div
className="sources-pane thread"
className="sources-pane"
key="pane"
>
<div
className="node thread-header"
key="thread-header"
>
<AccessibleImage
className="file"
/>
<span
className="label"
>
Main Thread
</span>
</div>
<div
className="no-sources-message"
key="empty"
@ -78,22 +52,9 @@ exports[`SourcesTree Should show a 'No Sources' message if there are no sources
exports[`SourcesTree Should show the tree with nothing expanded 1`] = `
<div
className="sources-pane thread"
className="sources-pane"
key="pane"
>
<div
className="node thread-header"
key="thread-header"
>
<AccessibleImage
className="file"
/>
<span
className="label"
>
Main Thread
</span>
</div>
<div
className="sources-list"
key="tree"
@ -120,29 +81,16 @@ exports[`SourcesTree Should show the tree with nothing expanded 1`] = `
exports[`SourcesTree When loading initial source Shows the tree with one.js, two.js and three.js expanded 1`] = `
<div
className="sources-pane thread"
className="sources-pane"
key="pane"
>
<div
className="node thread-header"
key="thread-header"
>
<AccessibleImage
className="file"
/>
<span
className="label"
>
Main Thread
</span>
</div>
<div
className="sources-list"
key="tree"
>
<ManagedTree
autoExpandAll={false}
autoExpandDepth={0}
autoExpandDepth={1}
expanded={
Array [
"one.js",
@ -169,22 +117,9 @@ exports[`SourcesTree When loading initial source Shows the tree with one.js, two
exports[`SourcesTree on receiving new props updates highlighted items updates highlightItems if selectedSource changes 1`] = `
<div
className="sources-pane thread"
className="sources-pane"
key="pane"
>
<div
className="node thread-header"
key="thread-header"
>
<AccessibleImage
className="file"
/>
<span
className="label"
>
Main Thread
</span>
</div>
<div
className="sources-list"
key="tree"
@ -212,7 +147,7 @@ exports[`SourcesTree on receiving new props updates highlighted items updates hi
"url": "http://mdn.com/three.js",
},
"name": "three.js",
"path": "mdn.com/three.js",
"path": "FakeThread/mdn.com/three.js",
"type": "source",
},
Object {
@ -231,7 +166,7 @@ exports[`SourcesTree on receiving new props updates highlighted items updates hi
"url": "http://mdn.com/four.js",
},
"name": "four.js",
"path": "mdn.com/four.js",
"path": "FakeThread/mdn.com/four.js",
"type": "source",
},
Object {
@ -248,7 +183,7 @@ exports[`SourcesTree on receiving new props updates highlighted items updates hi
"url": "http://mdn.com/four.js",
},
"name": "four.js",
"path": "mdn.com/four.js",
"path": "FakeThread/mdn.com/four.js",
"type": "source",
},
Object {
@ -265,7 +200,7 @@ exports[`SourcesTree on receiving new props updates highlighted items updates hi
"url": "http://mdn.com/one.js",
},
"name": "one.js",
"path": "mdn.com/one.js",
"path": "FakeThread/mdn.com/one.js",
"type": "source",
},
Object {
@ -282,7 +217,7 @@ exports[`SourcesTree on receiving new props updates highlighted items updates hi
"url": "http://mdn.com/three.js",
},
"name": "three.js",
"path": "mdn.com/three.js",
"path": "FakeThread/mdn.com/three.js",
"type": "source",
},
Object {
@ -299,12 +234,111 @@ exports[`SourcesTree on receiving new props updates highlighted items updates hi
"url": "http://mdn.com/two.js",
},
"name": "two.js",
"path": "mdn.com/two.js",
"path": "FakeThread/mdn.com/two.js",
"type": "source",
},
],
"name": "mdn.com",
"path": "mdn.com",
"path": "FakeThread/mdn.com",
"type": "directory",
},
Object {
"contents": Array [
Object {
"contents": Array [
Object {
"contents": Object {
"id": "server1.conn13.child1/42",
"introductionType": undefined,
"introductionUrl": null,
"isBlackBoxed": false,
"isExtension": false,
"isPrettyPrinted": false,
"isWasm": false,
"relativeUrl": "http://mdn.com/four.js",
"sourceMapURL": "data:application/json?charset=utf?dsffewrsf",
"url": "http://mdn.com/four.js",
},
"name": "four.js",
"path": "FakeThread/mdn.com/four.js",
"type": "source",
},
Object {
"contents": Object {
"id": "server1.conn13.child1/42/originalSource-sha",
"introductionType": undefined,
"introductionUrl": null,
"isBlackBoxed": false,
"isExtension": false,
"isPrettyPrinted": false,
"isWasm": false,
"relativeUrl": "http://mdn.com/four.js",
"sourceMapURL": null,
"url": "http://mdn.com/four.js",
},
"name": "four.js",
"path": "FakeThread/mdn.com/four.js",
"type": "source",
},
Object {
"contents": Object {
"id": "server1.conn13.child1/39",
"introductionType": undefined,
"introductionUrl": null,
"isBlackBoxed": false,
"isExtension": false,
"isPrettyPrinted": false,
"isWasm": false,
"relativeUrl": "http://mdn.com/one.js",
"sourceMapURL": null,
"url": "http://mdn.com/one.js",
},
"name": "one.js",
"path": "FakeThread/mdn.com/one.js",
"type": "source",
},
Object {
"contents": Object {
"id": "server1.conn13.child1/41",
"introductionType": undefined,
"introductionUrl": null,
"isBlackBoxed": false,
"isExtension": false,
"isPrettyPrinted": false,
"isWasm": false,
"relativeUrl": "http://mdn.com/three.js",
"sourceMapURL": null,
"url": "http://mdn.com/three.js",
},
"name": "three.js",
"path": "FakeThread/mdn.com/three.js",
"type": "source",
},
Object {
"contents": Object {
"id": "server1.conn13.child1/40",
"introductionType": undefined,
"introductionUrl": null,
"isBlackBoxed": false,
"isExtension": false,
"isPrettyPrinted": false,
"isWasm": false,
"relativeUrl": "http://mdn.com/two.js",
"sourceMapURL": null,
"url": "http://mdn.com/two.js",
},
"name": "two.js",
"path": "FakeThread/mdn.com/two.js",
"type": "source",
},
],
"name": "mdn.com",
"path": "FakeThread/mdn.com",
"type": "directory",
},
],
"name": "FakeThread",
"path": "FakeThread",
"type": "directory",
},
]

Просмотреть файл

@ -75,6 +75,11 @@ Object {
"relativeUrl": "http://mdn.com/one.js",
"url": "http://mdn.com/one.js",
},
"threads": Array [
Object {
"name": "Main Thread",
},
],
"toggleBlackBox": [MockFunction],
},
"refs": Object {},
@ -122,6 +127,13 @@ Object {
"url": "http://mdn.com/one.js",
}
}
threads={
Array [
Object {
"name": "Main Thread",
},
]
}
toggleBlackBox={[MockFunction]}
/>,
"_forcedUpdate": false,
@ -198,6 +210,11 @@ Object {
"relativeUrl": "http://mdn.com/one.js",
"url": "http://mdn.com/one.js",
},
"threads": Array [
Object {
"name": "Main Thread",
},
],
"toggleBlackBox": [MockFunction],
},
}
@ -285,6 +302,11 @@ Object {
"relativeUrl": "http://mdn.com/one.js",
"url": "http://mdn.com/one.js",
},
"threads": Array [
Object {
"name": "Main Thread",
},
],
"toggleBlackBox": [MockFunction],
},
"refs": Object {},
@ -334,6 +356,13 @@ Object {
"url": "http://mdn.com/one.js",
}
}
threads={
Array [
Object {
"name": "Main Thread",
},
]
}
toggleBlackBox={[MockFunction]}
/>,
"_forcedUpdate": false,
@ -417,6 +446,11 @@ Object {
"relativeUrl": "http://mdn.com/one.js",
"url": "http://mdn.com/one.js",
},
"threads": Array [
Object {
"name": "Main Thread",
},
],
"toggleBlackBox": [MockFunction],
},
}
@ -433,8 +467,20 @@ Object {
<span
className="img no-arrow"
/>
<AccessibleImage
className="globe-small"
<Connect(SourceIcon)
source={
Object {
"id": "server1.conn13.child1/39",
"introductionType": undefined,
"introductionUrl": null,
"isBlackBoxed": false,
"isExtension": false,
"isPrettyPrinted": false,
"isWasm": false,
"relativeUrl": "http://mdn.com/one.js",
"url": "http://mdn.com/one.js",
}
}
/>
<span
className="label"
@ -487,6 +533,11 @@ Object {
"relativeUrl": "http://mdn.com/one.js",
"url": "http://mdn.com/one.js",
},
"threads": Array [
Object {
"name": "Main Thread",
},
],
"toggleBlackBox": [MockFunction],
},
"refs": Object {},
@ -536,6 +587,13 @@ Object {
"url": "http://mdn.com/one.js",
}
}
threads={
Array [
Object {
"name": "Main Thread",
},
]
}
toggleBlackBox={[MockFunction]}
/>,
"_forcedUpdate": false,
@ -549,8 +607,20 @@ Object {
<span
className="img no-arrow"
/>
<AccessibleImage
className="globe-small"
<Connect(SourceIcon)
source={
Object {
"id": "server1.conn13.child1/39",
"introductionType": undefined,
"introductionUrl": null,
"isBlackBoxed": false,
"isExtension": false,
"isPrettyPrinted": false,
"isWasm": false,
"relativeUrl": "http://mdn.com/one.js",
"url": "http://mdn.com/one.js",
}
}
/>
<span
className="label"
@ -602,6 +672,11 @@ Object {
"relativeUrl": "http://mdn.com/one.js",
"url": "http://mdn.com/one.js",
},
"threads": Array [
Object {
"name": "Main Thread",
},
],
"toggleBlackBox": [MockFunction],
},
}
@ -619,7 +694,7 @@ Object {
className="arrow"
/>
<AccessibleImage
className="globe-small debuggee"
className="folder"
/>
<span
className="label"
@ -662,6 +737,11 @@ Object {
"relativeUrl": "http://mdn.com/one.js",
"url": "http://mdn.com/one.js",
},
"threads": Array [
Object {
"name": "Main Thread",
},
],
"toggleBlackBox": [MockFunction],
},
"refs": Object {},
@ -701,6 +781,13 @@ Object {
"url": "http://mdn.com/one.js",
}
}
threads={
Array [
Object {
"name": "Main Thread",
},
]
}
toggleBlackBox={[MockFunction]}
/>,
"_forcedUpdate": false,
@ -715,7 +802,7 @@ Object {
className="arrow"
/>
<AccessibleImage
className="globe-small debuggee"
className="folder"
/>
<span
className="label"
@ -757,6 +844,11 @@ Object {
"relativeUrl": "http://mdn.com/one.js",
"url": "http://mdn.com/one.js",
},
"threads": Array [
Object {
"name": "Main Thread",
},
],
"toggleBlackBox": [MockFunction],
},
}
@ -774,7 +866,7 @@ Object {
className="arrow"
/>
<AccessibleImage
className="globe-small debuggee"
className="folder"
/>
<span
className="label"
@ -818,6 +910,11 @@ Object {
"relativeUrl": "http://mdn.com/one.js",
"url": "http://mdn.com/one.js",
},
"threads": Array [
Object {
"name": "Main Thread",
},
],
"toggleBlackBox": [MockFunction],
},
"refs": Object {},
@ -858,6 +955,13 @@ Object {
"url": "http://mdn.com/one.js",
}
}
threads={
Array [
Object {
"name": "Main Thread",
},
]
}
toggleBlackBox={[MockFunction]}
/>,
"_forcedUpdate": false,
@ -872,7 +976,7 @@ Object {
className="arrow"
/>
<AccessibleImage
className="globe-small debuggee"
className="folder"
/>
<span
className="label"
@ -915,6 +1019,11 @@ Object {
"relativeUrl": "http://mdn.com/one.js",
"url": "http://mdn.com/one.js",
},
"threads": Array [
Object {
"name": "Main Thread",
},
],
"toggleBlackBox": [MockFunction],
},
}
@ -924,7 +1033,7 @@ exports[`SourceTreeItem renderItem should show focused item for folder with expa
Object {
"component": <div
className="node focused"
key="folder/"
key="domain/subfolder"
onClick={[Function]}
onContextMenu={[Function]}
>
@ -932,7 +1041,7 @@ Object {
className="arrow expanded"
/>
<AccessibleImage
className="folder"
className="globe-small"
/>
<span
className="label"
@ -958,7 +1067,7 @@ Object {
"item": Object {
"contents": Array [],
"name": "folder",
"path": "folder/",
"path": "domain/subfolder",
"type": "directory",
},
"projectRoot": "",
@ -966,6 +1075,11 @@ Object {
"setExpanded": [MockFunction],
"setProjectDirectoryRoot": [MockFunction],
"source": null,
"threads": Array [
Object {
"name": "Main Thread",
},
],
"toggleBlackBox": [MockFunction],
},
"refs": Object {},
@ -985,7 +1099,7 @@ Object {
Object {
"contents": Array [],
"name": "folder",
"path": "folder/",
"path": "domain/subfolder",
"type": "directory",
}
}
@ -994,6 +1108,13 @@ Object {
setExpanded={[MockFunction]}
setProjectDirectoryRoot={[MockFunction]}
source={null}
threads={
Array [
Object {
"name": "Main Thread",
},
]
}
toggleBlackBox={[MockFunction]}
/>,
"_forcedUpdate": false,
@ -1008,7 +1129,7 @@ Object {
className="arrow expanded"
/>
<AccessibleImage
className="folder"
className="globe-small"
/>
<span
className="label"
@ -1033,7 +1154,7 @@ Object {
"item": Object {
"contents": Array [],
"name": "folder",
"path": "folder/",
"path": "domain/subfolder",
"type": "directory",
},
"projectRoot": "",
@ -1041,6 +1162,11 @@ Object {
"setExpanded": [MockFunction],
"setProjectDirectoryRoot": [MockFunction],
"source": null,
"threads": Array [
Object {
"name": "Main Thread",
},
],
"toggleBlackBox": [MockFunction],
},
}
@ -1100,6 +1226,11 @@ Object {
"relativeUrl": "http://mdn.com/one.js",
"url": "http://mdn.com/one.js",
},
"threads": Array [
Object {
"name": "Main Thread",
},
],
"toggleBlackBox": [MockFunction],
},
"refs": Object {},
@ -1138,6 +1269,13 @@ Object {
"url": "http://mdn.com/one.js",
}
}
threads={
Array [
Object {
"name": "Main Thread",
},
]
}
toggleBlackBox={[MockFunction]}
/>,
"_forcedUpdate": false,
@ -1193,6 +1331,11 @@ Object {
"relativeUrl": "http://mdn.com/one.js",
"url": "http://mdn.com/one.js",
},
"threads": Array [
Object {
"name": "Main Thread",
},
],
"toggleBlackBox": [MockFunction],
},
}
@ -1202,7 +1345,7 @@ exports[`SourceTreeItem renderItem should show icon for folder with arrow 1`] =
Object {
"component": <div
className="node"
key="folder/"
key="domain/subfolder"
onClick={[Function]}
onContextMenu={[Function]}
>
@ -1234,7 +1377,7 @@ Object {
"item": Object {
"contents": Array [],
"name": "folder",
"path": "folder/",
"path": "domain/subfolder",
"type": "directory",
},
"projectRoot": "",
@ -1242,6 +1385,11 @@ Object {
"setExpanded": [MockFunction],
"setProjectDirectoryRoot": [MockFunction],
"source": null,
"threads": Array [
Object {
"name": "Main Thread",
},
],
"toggleBlackBox": [MockFunction],
},
"refs": Object {},
@ -1259,7 +1407,7 @@ Object {
Object {
"contents": Array [],
"name": "folder",
"path": "folder/",
"path": "domain/subfolder",
"type": "directory",
}
}
@ -1268,6 +1416,13 @@ Object {
setExpanded={[MockFunction]}
setProjectDirectoryRoot={[MockFunction]}
source={null}
threads={
Array [
Object {
"name": "Main Thread",
},
]
}
toggleBlackBox={[MockFunction]}
/>,
"_forcedUpdate": false,
@ -1305,7 +1460,7 @@ Object {
"item": Object {
"contents": Array [],
"name": "folder",
"path": "folder/",
"path": "domain/subfolder",
"type": "directory",
},
"projectRoot": "",
@ -1313,6 +1468,11 @@ Object {
"setExpanded": [MockFunction],
"setProjectDirectoryRoot": [MockFunction],
"source": null,
"threads": Array [
Object {
"name": "Main Thread",
},
],
"toggleBlackBox": [MockFunction],
},
}
@ -1322,7 +1482,7 @@ exports[`SourceTreeItem renderItem should show icon for folder with expanded arr
Object {
"component": <div
className="node"
key="folder/"
key="domain/subfolder"
onClick={[Function]}
onContextMenu={[Function]}
>
@ -1330,7 +1490,7 @@ Object {
className="arrow expanded"
/>
<AccessibleImage
className="folder"
className="globe-small"
/>
<span
className="label"
@ -1356,7 +1516,7 @@ Object {
"item": Object {
"contents": Array [],
"name": "folder",
"path": "folder/",
"path": "domain/subfolder",
"type": "directory",
},
"projectRoot": "",
@ -1364,6 +1524,11 @@ Object {
"setExpanded": [MockFunction],
"setProjectDirectoryRoot": [MockFunction],
"source": null,
"threads": Array [
Object {
"name": "Main Thread",
},
],
"toggleBlackBox": [MockFunction],
},
"refs": Object {},
@ -1383,7 +1548,7 @@ Object {
Object {
"contents": Array [],
"name": "folder",
"path": "folder/",
"path": "domain/subfolder",
"type": "directory",
}
}
@ -1392,6 +1557,13 @@ Object {
setExpanded={[MockFunction]}
setProjectDirectoryRoot={[MockFunction]}
source={null}
threads={
Array [
Object {
"name": "Main Thread",
},
]
}
toggleBlackBox={[MockFunction]}
/>,
"_forcedUpdate": false,
@ -1406,7 +1578,7 @@ Object {
className="arrow expanded"
/>
<AccessibleImage
className="folder"
className="globe-small"
/>
<span
className="label"
@ -1431,7 +1603,7 @@ Object {
"item": Object {
"contents": Array [],
"name": "folder",
"path": "folder/",
"path": "domain/subfolder",
"type": "directory",
},
"projectRoot": "",
@ -1439,6 +1611,11 @@ Object {
"setExpanded": [MockFunction],
"setProjectDirectoryRoot": [MockFunction],
"source": null,
"threads": Array [
Object {
"name": "Main Thread",
},
],
"toggleBlackBox": [MockFunction],
},
}
@ -1456,7 +1633,7 @@ Object {
className="arrow"
/>
<AccessibleImage
className="extension"
className="folder"
/>
<span
className="label"
@ -1499,6 +1676,11 @@ Object {
"relativeUrl": "http://mdn.com/one.js",
"url": "http://mdn.com/one.js",
},
"threads": Array [
Object {
"name": "Main Thread",
},
],
"toggleBlackBox": [MockFunction],
},
"refs": Object {},
@ -1538,6 +1720,13 @@ Object {
"url": "http://mdn.com/one.js",
}
}
threads={
Array [
Object {
"name": "Main Thread",
},
]
}
toggleBlackBox={[MockFunction]}
/>,
"_forcedUpdate": false,
@ -1552,7 +1741,7 @@ Object {
className="arrow"
/>
<AccessibleImage
className="extension"
className="folder"
/>
<span
className="label"
@ -1594,6 +1783,11 @@ Object {
"relativeUrl": "http://mdn.com/one.js",
"url": "http://mdn.com/one.js",
},
"threads": Array [
Object {
"name": "Main Thread",
},
],
"toggleBlackBox": [MockFunction],
},
}
@ -1653,6 +1847,11 @@ Object {
"relativeUrl": "http://mdn.com/one.js",
"url": "http://mdn.com/one.js",
},
"threads": Array [
Object {
"name": "Main Thread",
},
],
"toggleBlackBox": [MockFunction],
},
"refs": Object {},
@ -1691,6 +1890,13 @@ Object {
"url": "http://mdn.com/one.js",
}
}
threads={
Array [
Object {
"name": "Main Thread",
},
]
}
toggleBlackBox={[MockFunction]}
/>,
"_forcedUpdate": false,
@ -1746,6 +1952,11 @@ Object {
"relativeUrl": "http://mdn.com/one.js",
"url": "http://mdn.com/one.js",
},
"threads": Array [
Object {
"name": "Main Thread",
},
],
"toggleBlackBox": [MockFunction],
},
}
@ -1827,6 +2038,11 @@ Object {
"relativeUrl": "http://mdn.com/one.js",
"url": "http://mdn.com/one.js",
},
"threads": Array [
Object {
"name": "Main Thread",
},
],
"toggleBlackBox": [MockFunction],
},
"refs": Object {},
@ -1875,6 +2091,13 @@ Object {
"url": "http://mdn.com/one.js",
}
}
threads={
Array [
Object {
"name": "Main Thread",
},
]
}
toggleBlackBox={[MockFunction]}
/>,
"_forcedUpdate": false,
@ -1952,6 +2175,11 @@ Object {
"relativeUrl": "http://mdn.com/one.js",
"url": "http://mdn.com/one.js",
},
"threads": Array [
Object {
"name": "Main Thread",
},
],
"toggleBlackBox": [MockFunction],
},
}
@ -2034,6 +2262,11 @@ Object {
"relativeUrl": "http://mdn.com/one.js",
"url": "http://mdn.com/one.js",
},
"threads": Array [
Object {
"name": "Main Thread",
},
],
"toggleBlackBox": [MockFunction],
},
"refs": Object {},
@ -2083,6 +2316,13 @@ Object {
"url": "http://mdn.com/one.js",
}
}
threads={
Array [
Object {
"name": "Main Thread",
},
]
}
toggleBlackBox={[MockFunction]}
/>,
"_forcedUpdate": false,
@ -2161,6 +2401,11 @@ Object {
"relativeUrl": "http://mdn.com/one.js",
"url": "http://mdn.com/one.js",
},
"threads": Array [
Object {
"name": "Main Thread",
},
],
"toggleBlackBox": [MockFunction],
},
}
@ -2242,6 +2487,11 @@ Object {
"relativeUrl": "http://mdn.com/one.js",
"url": "http://mdn.com/one.js",
},
"threads": Array [
Object {
"name": "Main Thread",
},
],
"toggleBlackBox": [MockFunction],
},
"refs": Object {},
@ -2290,6 +2540,13 @@ Object {
"url": "http://mdn.com/one.js",
}
}
threads={
Array [
Object {
"name": "Main Thread",
},
]
}
toggleBlackBox={[MockFunction]}
/>,
"_forcedUpdate": false,
@ -2367,6 +2624,11 @@ Object {
"relativeUrl": "http://mdn.com/one.js",
"url": "http://mdn.com/one.js",
},
"threads": Array [
Object {
"name": "Main Thread",
},
],
"toggleBlackBox": [MockFunction],
},
}

Просмотреть файл

@ -430,11 +430,12 @@ export class QuickOpenModal extends Component<Props, State> {
/* istanbul ignore next: ignoring testing of redux connection stuff */
function mapStateToProps(state) {
const selectedSource = getSelectedSource(state);
const displayedSources = getDisplayedSourcesList(state);
return {
cx: getContext(state),
enabled: getQuickOpenEnabled(state),
sources: formatSources(getDisplayedSourcesList(state), getTabs(state)),
sources: formatSources(displayedSources, getTabs(state)),
selectedSource,
selectedContentLoaded: selectedSource
? !!getSourceContent(state, selectedSource.id)

Просмотреть файл

@ -44,7 +44,7 @@ export class Worker extends Component<Props> {
onClick={this.onSelectThread}
>
<div className="icon">
<AccessibleImage className={worker ? "worker" : "file"} />
<AccessibleImage className={worker ? "worker" : "window"} />
</div>
<div className="label">{label}</div>
{isPaused ? (

Просмотреть файл

@ -80,6 +80,11 @@ html[dir="rtl"] .img.arrow {
mask-size: 12px 12px;
}
.img.window {
mask-image: url(resource://devtools/client/debugger/images/window.svg);
mask-size: 12px 12px;
}
.img.file {
mask-image: url(resource://devtools/client/debugger/images/file-small.svg);
mask-size: 12px 12px;

Просмотреть файл

@ -10,9 +10,12 @@
*/
import { sortBy } from "lodash";
import { createSelector } from "reselect";
import { getDisplayName } from "../utils/workers";
import type { MainThread, WorkerList } from "../types";
import type { Selector } from "./types";
import type { MainThread, WorkerList, Thread } from "../types";
import type { Action } from "../actions/types";
export type DebuggeeState = {
@ -21,7 +24,10 @@ export type DebuggeeState = {
};
export function initialDebuggeeState(): DebuggeeState {
return { workers: [], mainThread: { actor: "", url: "", type: -1 } };
return {
workers: [],
mainThread: { actor: "", url: "", type: -1, name: "" }
};
}
export default function debuggee(
@ -32,13 +38,10 @@ export default function debuggee(
case "CONNECT":
return {
...state,
mainThread: action.mainThread
mainThread: { ...action.mainThread, name: L10N.getStr("mainThread") }
};
case "INSERT_WORKERS":
return {
...state,
workers: [...state.workers, ...action.workers]
};
return insertWorkers(state, action.workers);
case "REMOVE_WORKERS":
const { workers } = action;
return {
@ -55,6 +58,18 @@ export default function debuggee(
}
}
function insertWorkers(state, workers) {
const formatedWorkers = workers.map(worker => ({
...worker,
name: getDisplayName(worker)
}));
return {
...state,
workers: [...state.workers, ...formatedWorkers]
};
}
export const getWorkers = (state: OuterState) => state.debuggee.workers;
export const getWorkerCount = (state: OuterState) => getWorkers(state).length;
@ -71,8 +86,10 @@ export function getDebuggeeUrl(state: OuterState): string {
return getMainThread(state).url;
}
export function getThreads(state: OuterState) {
return [getMainThread(state), ...sortBy(getWorkers(state), getDisplayName)];
}
export const getThreads: Selector<Thread[]> = createSelector(
getMainThread,
getWorkers,
(mainThread, workers) => [mainThread, ...sortBy(workers, getDisplayName)]
);
type OuterState = { debuggee: DebuggeeState };

Просмотреть файл

@ -9,15 +9,17 @@
* @module reducers/source-tree
*/
import type { SourceTreeAction } from "../actions/types";
import type { SourceTreeAction, FocusItem } from "../actions/types";
export type SourceTreeState = {
expanded: { [string]: Set<string> }
expanded: Set<string>,
focusedItem: ?FocusItem
};
export function InitialState(): SourceTreeState {
return {
expanded: {}
expanded: new Set(),
focusedItem: null
};
}
@ -28,6 +30,9 @@ export default function update(
switch (action.type) {
case "SET_EXPANDED_STATE":
return updateExpanded(state, action);
case "SET_FOCUSED_SOURCE_ITEM":
return { ...state, focusedItem: action.item };
}
return state;
@ -36,7 +41,7 @@ export default function update(
function updateExpanded(state, action) {
return {
...state,
expanded: { ...state.expanded, [action.thread]: new Set(action.expanded) }
expanded: new Set(action.expanded)
};
}
@ -44,6 +49,10 @@ type OuterState = {
sourceTree: SourceTreeState
};
export function getExpandedState(state: OuterState, thread: string) {
return state.sourceTree.expanded[thread];
export function getExpandedState(state: OuterState) {
return state.sourceTree.expanded;
}
export function getFocusedSourceItem(state: OuterState): ?FocusItem {
return state.sourceTree.focusedItem;
}

Просмотреть файл

@ -68,8 +68,9 @@ export type SourcesMap = { [SourceId]: Source };
type SourcesContentMap = {
[SourceId]: AsyncValue<SourceContent> | null
};
export type BreakpointPositionsMap = { [SourceId]: BreakpointPositions };
export type SourcesMapByThread = { [ThreadId]: SourcesMap };
export type BreakpointPositionsMap = { [SourceId]: BreakpointPositions };
type SourceActorMap = { [SourceId]: Array<SourceActorId> };
type UrlsMap = { [string]: SourceId[] };
@ -852,9 +853,10 @@ const getDisplayedSourceIDs: GetDisplayedSourceIDsSelector = createSelector(
return sourceIDsByThread;
}
);
type GetDisplayedSourcesSelector = (
OuterState & SourceActorOuterState
) => { [ThreadId]: { [SourceId]: Source } };
) => SourcesMapByThread;
export const getDisplayedSources: GetDisplayedSourcesSelector = createSelector(
state => state.sources.sources,
getDisplayedSourceIDs,
@ -874,17 +876,6 @@ export const getDisplayedSources: GetDisplayedSourcesSelector = createSelector(
}
);
export function getDisplayedSourcesForThread(
state: OuterState & SourceActorOuterState,
thread: string
): SourcesMap {
return getDisplayedSources(state)[thread] || {};
}
export function getFocusedSourceItem(state: OuterState): ?FocusItem {
return state.sources.focusedItem;
}
export function getSourceActorsForSource(
state: OuterState & SourceActorOuterState,
id: SourceId

Просмотреть файл

@ -81,7 +81,6 @@ describe("sources selectors", () => {
sources: update(state, {
type: "ADD_SOURCES",
cx: mockcx,
// coercing to a Source for the purpose of this test
sources: ((mockedSources: any): Source[])
}),
sourceActors: undefined
@ -94,9 +93,8 @@ describe("sources selectors", () => {
sources: update(state.sources, insertAction),
sourceActors: updateSourceActors(state.sourceActors, insertAction)
};
const selectedDisplayedSources = getDisplayedSources(state);
const threadSources = selectedDisplayedSources.foo;
expect(Object.values(threadSources)).toHaveLength(3);
const threadSources = getDisplayedSources(state);
expect(Object.values(threadSources.foo)).toHaveLength(3);
});
it("should omit all extensions when chrome preference enabled", () => {
@ -106,7 +104,6 @@ describe("sources selectors", () => {
sources: update(state, {
type: "ADD_SOURCES",
cx: mockcx,
// coercing to a Source for the purpose of this test
sources: ((mockedSources: any): Source[])
}),
sourceActors: undefined
@ -121,8 +118,7 @@ describe("sources selectors", () => {
sources: update(state.sources, insertAction),
sourceActors: updateSourceActors(state.sourceActors, insertAction)
};
const selectedDisplayedSources = getDisplayedSources(state);
const threadSources = selectedDisplayedSources.foo;
expect(Object.values(threadSources)).toHaveLength(1);
const threadSources = getDisplayedSources(state);
expect(Object.values(threadSources.foo)).toHaveLength(1);
});
});

Просмотреть файл

@ -447,13 +447,15 @@ export type Scope = {|
export type MainThread = {
+actor: ThreadId,
+url: string,
+type: number
+type: number,
+name: string
};
export type Worker = {
+actor: ThreadId,
+url: string,
+type: number
+type: number,
+name: string
};
export type Thread = MainThread & Worker;

Просмотреть файл

@ -491,7 +491,7 @@ export function getSourceQueryString(source: ?Source) {
}
export function isUrlExtension(url: string) {
return /^(chrome|moz)-extension:\//.test(url);
return /\/?(chrome|moz)-extension:\//.test(url);
}
export function getPlainUrl(url: string): string {

Просмотреть файл

@ -90,15 +90,25 @@ function traverseTree(
url: ParsedURL,
tree: TreeDirectory,
debuggeeHost: ?string,
source: Source
source: Source,
thread: string
): TreeNode {
const parts = url.path.split("/").filter(p => p !== "");
parts.unshift(url.group);
if (thread) {
parts.unshift(thread);
}
let path = "";
return parts.reduce((subTree, part, index) => {
path = path ? `${path}/${part}` : part;
const debuggeeHostIfRoot = index === 0 ? debuggeeHost : null;
if (index == 0 && thread) {
path = thread;
} else {
path = `${path}/${part}`;
}
const debuggeeHostIfRoot = index === 1 ? debuggeeHost : null;
return findOrCreateNode(
parts,
subTree,
@ -165,7 +175,8 @@ function addSourceToNode(
export function addToTree(
tree: TreeDirectory,
source: Source,
debuggeeHost: ?string
debuggeeHost: ?string,
thread: string
) {
const url = getURL(source, debuggeeHost);
@ -173,7 +184,7 @@ export function addToTree(
return;
}
const finalNode = traverseTree(url, tree, debuggeeHost, source);
const finalNode = traverseTree(url, tree, debuggeeHost, source, thread);
// $FlowIgnore
finalNode.contents = addSourceToNode(finalNode, url, source);

Просмотреть файл

@ -18,8 +18,9 @@ function _collapseTree(node: TreeNode, depth: number): TreeNode {
console.log(`Expected array at: ${node.path}`);
}
// Node is not a root/domain node, and only contains 1 item.
if (depth > 1 && node.contents.length === 1) {
// Node is not a (1) thread and (2) root/domain node,
// and only contains 1 item.
if (depth > 2 && node.contents.length === 1) {
const next = node.contents[0];
// Do not collapse if the next node is a leaf node.
if (next.type === "directory") {

Просмотреть файл

@ -1,36 +0,0 @@
/* 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 { addToTree } from "./addToTree";
import { collapseTree } from "./collapseTree";
import { createDirectoryNode, createParentMap } from "./utils";
import { getDomain } from "./treeOrder";
import type { SourcesMap } from "../../reducers/types";
import type { TreeDirectory } from "./types";
type Params = {
sources: SourcesMap,
debuggeeUrl: string
};
export function createTree({ sources, debuggeeUrl }: Params) {
const uncollapsedTree = createDirectoryNode("root", "", []);
const debuggeeHost = getDomain(debuggeeUrl);
for (const sourceId in sources) {
const source = sources[sourceId];
addToTree(uncollapsedTree, source, debuggeeHost);
}
const sourceTree = collapseTree((uncollapsedTree: TreeDirectory));
return {
uncollapsedTree,
sourceTree,
parentMap: createParentMap(sourceTree)
};
}

Просмотреть файл

@ -11,11 +11,10 @@
export { addToTree } from "./addToTree";
export { collapseTree } from "./collapseTree";
export { createTree } from "./createTree";
export { formatTree } from "./formatTree";
export { getDirectories } from "./getDirectories";
export { getFilenameFromPath, getURL } from "./getURL";
export { sortEntireTree, sortTree } from "./sortTree";
export { updateTree } from "./updateTree";
export { sortTree } from "./sortTree";
export { createTree, updateTree } from "./updateTree";
export * from "./utils";

Просмотреть файл

@ -10,7 +10,6 @@ DIRS += [
CompiledModules(
'addToTree.js',
'collapseTree.js',
'createTree.js',
'formatTree.js',
'getDirectories.js',
'getURL.js',

Просмотреть файл

@ -8,25 +8,6 @@ import { nodeHasChildren, isExactUrlMatch } from "./utils";
import type { TreeDirectory } from "./types";
/**
* Look at the nodes in the source tree, and determine the index of where to
* insert a new node. The ordering is index -> folder -> file.
* @memberof utils/sources-tree
* @static
*/
export function sortEntireTree(
tree: TreeDirectory,
debuggeeUrl: string = ""
): TreeDirectory {
if (nodeHasChildren(tree)) {
const contents = sortTree(tree, debuggeeUrl).map((subtree: any) =>
sortEntireTree(subtree)
);
return { ...tree, contents };
}
return tree;
}
/**
* Look at the nodes in the source tree, and determine the index of where to
* insert a new node. The ordering is index -> folder -> file.

Просмотреть файл

@ -2,77 +2,90 @@
exports[`sources-tree addToTree can add a file to an intermediate directory 1`] = `
" - root path=
- unpkg.com path=unpkg.com
- codemirror@5.1 path=unpkg.com/codemirror@5.1
- mode path=unpkg.com/codemirror@5.1/mode
- xml path=unpkg.com/codemirror@5.1/mode/xml
- xml.js path=unpkg.com/codemirror@5.1/mode/xml/xml.js source_id=server1.conn13.child1/39
- codemirror@5.1 path=unpkg.com/codemirror@5.1 source_id=server1.conn13.child1/37
- FakeThread path=FakeThread
- unpkg.com path=FakeThread/unpkg.com
- codemirror@5.1 path=FakeThread/unpkg.com/codemirror@5.1
- mode path=FakeThread/unpkg.com/codemirror@5.1/mode
- xml path=FakeThread/unpkg.com/codemirror@5.1/mode/xml
- xml.js path=FakeThread/unpkg.com/codemirror@5.1/mode/xml/xml.js source_id=server1.conn13.child1/39
- codemirror@5.1 path=FakeThread/unpkg.com/codemirror@5.1 source_id=server1.conn13.child1/37
"
`;
exports[`sources-tree addToTree correctly parses file sources 1`] = `
" - root path=
- file:// path=file://
- a path=file:///a
- b.js path=file:///a/b.js source_id=actor1
- FakeThread path=FakeThread
- file:// path=FakeThread/file://
- a path=FakeThread/file:///a
- b.js path=FakeThread/file:///a/b.js source_id=actor1
"
`;
exports[`sources-tree addToTree does not attempt to add two of the same directory 1`] = `
" - root path=
- davidwalsh.name path=davidwalsh.name
- (index) path=https://davidwalsh.name/ source_id=server1.conn13.child1/37
- wp-content path=davidwalsh.name/wp-content
- prism.js path=davidwalsh.name/wp-content/prism.js source_id=server1.conn13.child1/39
- FakeThread path=FakeThread
- davidwalsh.name path=FakeThread/davidwalsh.name
- (index) path=https://davidwalsh.name/ source_id=server1.conn13.child1/37
- wp-content path=FakeThread/davidwalsh.name/wp-content
- prism.js path=FakeThread/davidwalsh.name/wp-content/prism.js source_id=server1.conn13.child1/39
"
`;
exports[`sources-tree addToTree does not attempt to add two of the same file 1`] = `
" - root path=
- davidwalsh.name path=davidwalsh.name
- (index) path=https://davidwalsh.name/ source_id=server1.conn13.child1/37
- FakeThread path=FakeThread
- davidwalsh.name path=FakeThread/davidwalsh.name
- (index) path=https://davidwalsh.name/ source_id=server1.conn13.child1/39
- util.js path=FakeThread/davidwalsh.name/util.js source_id=server1.conn13.child1/37
- FakeThread2 path=FakeThread2
- davidwalsh.name path=FakeThread2/davidwalsh.name
- util.js path=FakeThread2/davidwalsh.name/util.js source_id=server1.conn13.child1/37
"
`;
exports[`sources-tree addToTree does not mangle encoded URLs 1`] = `
" - root path=
- example.com path=example.com
- foo path=example.com/foo
- B9724220.131821496;dc_ver=42.111;sz=468x60;u_sd=2;dc_adk=2020465299;ord=a53rpc;dc_rfl=1,https%3A%2F%2Fdavidwalsh.name%2F$0;xdt=1 path=example.com/foo/B9724220.131821496;dc_ver=42.111;sz=468x60;u_sd=2;dc_adk=2020465299;ord=a53rpc;dc_rfl=1,https%3A%2F%2Fdavidwalsh.name%2F$0;xdt=1 source_id=actor1
- FakeThread path=FakeThread
- example.com path=FakeThread/example.com
- foo path=FakeThread/example.com/foo
- B9724220.131821496;dc_ver=42.111;sz=468x60;u_sd=2;dc_adk=2020465299;ord=a53rpc;dc_rfl=1,https%3A%2F%2Fdavidwalsh.name%2F$0;xdt=1 path=FakeThread/example.com/foo/B9724220.131821496;dc_ver=42.111;sz=468x60;u_sd=2;dc_adk=2020465299;ord=a53rpc;dc_rfl=1,https%3A%2F%2Fdavidwalsh.name%2F$0;xdt=1 source_id=actor1
"
`;
exports[`sources-tree addToTree excludes javascript: URLs from the tree 1`] = `
" - root path=
- example.com path=example.com
- source1.js path=example.com/source1.js source_id=actor2
- FakeThread path=FakeThread
- example.com path=FakeThread/example.com
- source1.js path=FakeThread/example.com/source1.js source_id=actor2
"
`;
exports[`sources-tree addToTree name does not include query params 1`] = `
" - root path=
- example.com path=example.com
- foo path=example.com/foo
- name.js path=example.com/foo/name.js source_id=actor1
- FakeThread path=FakeThread
- example.com path=FakeThread/example.com
- foo path=FakeThread/example.com/foo
- name.js path=FakeThread/example.com/foo/name.js source_id=actor1
"
`;
exports[`sources-tree addToTree replaces a file with a directory 1`] = `
" - root path=
- unpkg.com path=unpkg.com
- codemirror@5.1 path=unpkg.com/codemirror@5.1
- mode path=unpkg.com/codemirror@5.1/mode
- xml path=unpkg.com/codemirror@5.1/mode/xml
- xml.js path=unpkg.com/codemirror@5.1/mode/xml/xml.js source_id=server1.conn13.child1/39
- codemirror@5.1 path=unpkg.com/codemirror@5.1 source_id=server1.conn13.child1/37
- FakeThread path=FakeThread
- unpkg.com path=FakeThread/unpkg.com
- codemirror@5.1 path=FakeThread/unpkg.com/codemirror@5.1
- mode path=FakeThread/unpkg.com/codemirror@5.1/mode
- xml path=FakeThread/unpkg.com/codemirror@5.1/mode/xml
- xml.js path=FakeThread/unpkg.com/codemirror@5.1/mode/xml/xml.js source_id=server1.conn13.child1/39
- codemirror@5.1 path=FakeThread/unpkg.com/codemirror@5.1 source_id=server1.conn13.child1/37
"
`;
exports[`sources-tree addToTree supports data URLs 1`] = `
" - root path=
- (no domain) path=(no domain)
- data:text/html,<script>console.log(123)</script> path=data:text/html,<script>console.log(123)</script> source_id=server1.conn13.child1/39
- FakeThread path=FakeThread
- (no domain) path=FakeThread/(no domain)
- data:text/html,<script>console.log(123)</script> path=data:text/html,<script>console.log(123)</script> source_id=server1.conn13.child1/39
"
`;

Просмотреть файл

@ -2,37 +2,41 @@
exports[`sources tree collapseTree can collapse a single source 1`] = `
" - root path=
- example.com path=example.com
- a/b path=example.com/a/b
- c.js path=example.com/a/b/c.js source_id=actor1
- Main Thread path=Main Thread
- example.com path=Main Thread/example.com
- a/b path=Main Thread/example.com/a/b
- c.js path=Main Thread/example.com/a/b/c.js source_id=actor1
"
`;
exports[`sources tree collapseTree correctly merges in a collapsed source with a deeper level 1`] = `
" - root path=
- example.com path=example.com
- a/b path=example.com/a/b
- c/d path=example.com/a/b/c/d
- e.js path=example.com/a/b/c/d/e.js source_id=actor2
- c.js path=example.com/a/b/c.js source_id=actor1
- Main Thread path=Main Thread
- example.com path=Main Thread/example.com
- a/b path=Main Thread/example.com/a/b
- c/d path=Main Thread/example.com/a/b/c/d
- e.js path=Main Thread/example.com/a/b/c/d/e.js source_id=actor2
- c.js path=Main Thread/example.com/a/b/c.js source_id=actor1
"
`;
exports[`sources tree collapseTree correctly merges in a collapsed source with a shallower level 1`] = `
" - root path=
- example.com path=example.com
- a/b path=example.com/a/b
- c.js path=example.com/a/b/c.js source_id=actor1
- x.js path=example.com/a/b/x.js source_id=actor3
- Main Thread path=Main Thread
- example.com path=Main Thread/example.com
- a/b path=Main Thread/example.com/a/b
- c.js path=Main Thread/example.com/a/b/c.js source_id=actor1
- x.js path=Main Thread/example.com/a/b/x.js source_id=actor3
"
`;
exports[`sources tree collapseTree correctly merges in a collapsed source with the same level 1`] = `
" - root path=
- example.com path=example.com
- a/b path=example.com/a/b
- c/d path=example.com/a/b/c/d
- e.js path=example.com/a/b/c/d/e.js source_id=actor2
- c.js path=example.com/a/b/c.js source_id=actor1
- Main Thread path=Main Thread
- example.com path=Main Thread/example.com
- a/b path=Main Thread/example.com/a/b
- c/d path=Main Thread/example.com/a/b/c/d
- e.js path=Main Thread/example.com/a/b/c/d/e.js source_id=actor2
- c.js path=Main Thread/example.com/a/b/c.js source_id=actor1
"
`;

Просмотреть файл

@ -1,73 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`sources-tree sortEntireTree alphabetically sorts children 1`] = `
" - root path=
- example.com path=example.com
- foo path=example.com/foo
- a_source3.js path=example.com/foo/a_source3.js source_id=actor3
- b_source2.js path=example.com/foo/b_source2.js source_id=actor2
- source1.js path=example.com/source1.js source_id=actor1
"
`;
exports[`sources-tree sortEntireTree puts folder at the top of the sort 1`] = `
" - root path=
- example.com path=example.com
- folder path=example.com/folder
- b path=example.com/folder/b
- b.js path=example.com/folder/b/b.js source_id=actor2
- c path=example.com/folder/c
- (index) path=http://example.com/folder/c/ source_id=actor3
- a.js path=example.com/folder/a.js source_id=actor1
"
`;
exports[`sources-tree sortEntireTree puts root debugee url at the top of the sort 1`] = `
" - root path=
- example.com path=example.com
- b.js path=example.com/b.js source_id=actor2
- api.example.com path=api.example.com
- a.js path=api.example.com/a.js source_id=actor1
- demo.com path=demo.com
- c.js path=demo.com/c.js source_id=actor3
"
`;
exports[`sources-tree sortEntireTree puts root debugee url at the top of the sort 2`] = `
" - root path=
- demo.com path=demo.com
- c.js path=demo.com/c.js source_id=actor3
- api.example.com path=api.example.com
- a.js path=api.example.com/a.js source_id=actor1
- example.com path=example.com
- b.js path=example.com/b.js source_id=actor2
"
`;
exports[`sources-tree sortEntireTree sorts folders first 1`] = `
" - root path=
- example.com path=example.com
- (index) path=http://example.com source_id=actor4
- b.js path=example.com/b.js
- b_source.js path=example.com/b.js/b_source.js source_id=actor2
- d path=example.com/d
- d_source.js path=example.com/d/d_source.js source_id=actor5
- a.js path=example.com/a.js source_id=actor1
- b2 path=example.com/b2 source_id=actor6
- c.js path=example.com/c.js source_id=actor3
"
`;
exports[`sources-tree sortEntireTree sorts folders first 2`] = `
" - root path=
- example.com path=example.com
- (index) path=http://example.com source_id=actor4
- b.js path=example.com/b.js
- b_source.js path=example.com/b.js/b_source.js source_id=actor2
- d path=example.com/d
- d_source.js path=example.com/d/d_source.js source_id=actor5
- a.js path=example.com/a.js source_id=actor1
- b2 path=example.com/b2 source_id=actor6
- c.js path=example.com/c.js source_id=actor3
"
`;

Просмотреть файл

@ -8,38 +8,45 @@ exports[`calls updateTree.js adds one source 1`] = `
\\"contents\\": [
{
\\"type\\": \\"directory\\",
\\"name\\": \\"davidwalsh.name\\",
\\"path\\": \\"davidwalsh.name\\",
\\"name\\": \\"FakeThread\\",
\\"path\\": \\"FakeThread\\",
\\"contents\\": [
{
\\"type\\": \\"source\\",
\\"name\\": \\"(index)\\",
\\"path\\": \\"https://davidwalsh.name/\\",
\\"contents\\": {
\\"id\\": \\"server1.conn13.child1/39\\",
\\"url\\": \\"https://davidwalsh.name/\\",
\\"isBlackBoxed\\": false,
\\"isPrettyPrinted\\": false,
\\"relativeUrl\\": \\"https://davidwalsh.name/\\",
\\"introductionUrl\\": null,
\\"isWasm\\": false,
\\"isExtension\\": false
}
},
{
\\"type\\": \\"source\\",
\\"name\\": \\"source1.js\\",
\\"path\\": \\"davidwalsh.name/source1.js\\",
\\"contents\\": {
\\"id\\": \\"server1.conn13.child1/37\\",
\\"url\\": \\"https://davidwalsh.name/source1.js\\",
\\"isBlackBoxed\\": false,
\\"isPrettyPrinted\\": false,
\\"relativeUrl\\": \\"https://davidwalsh.name/source1.js\\",
\\"introductionUrl\\": null,
\\"isWasm\\": false,
\\"isExtension\\": false
}
\\"type\\": \\"directory\\",
\\"name\\": \\"davidwalsh.name\\",
\\"path\\": \\"FakeThread/davidwalsh.name\\",
\\"contents\\": [
{
\\"type\\": \\"source\\",
\\"name\\": \\"(index)\\",
\\"path\\": \\"https://davidwalsh.name/\\",
\\"contents\\": {
\\"id\\": \\"server1.conn13.child1/39\\",
\\"url\\": \\"https://davidwalsh.name/\\",
\\"isBlackBoxed\\": false,
\\"isPrettyPrinted\\": false,
\\"relativeUrl\\": \\"https://davidwalsh.name/\\",
\\"introductionUrl\\": null,
\\"isWasm\\": false,
\\"isExtension\\": false
}
},
{
\\"type\\": \\"source\\",
\\"name\\": \\"source1.js\\",
\\"path\\": \\"FakeThread/davidwalsh.name/source1.js\\",
\\"contents\\": {
\\"id\\": \\"server1.conn13.child1/37\\",
\\"url\\": \\"https://davidwalsh.name/source1.js\\",
\\"isBlackBoxed\\": false,
\\"isPrettyPrinted\\": false,
\\"relativeUrl\\": \\"https://davidwalsh.name/source1.js\\",
\\"introductionUrl\\": null,
\\"isWasm\\": false,
\\"isExtension\\": false
}
}
]
}
]
}
@ -55,53 +62,60 @@ exports[`calls updateTree.js adds two sources 1`] = `
\\"contents\\": [
{
\\"type\\": \\"directory\\",
\\"name\\": \\"davidwalsh.name\\",
\\"path\\": \\"davidwalsh.name\\",
\\"name\\": \\"FakeThread\\",
\\"path\\": \\"FakeThread\\",
\\"contents\\": [
{
\\"type\\": \\"source\\",
\\"name\\": \\"(index)\\",
\\"path\\": \\"https://davidwalsh.name/\\",
\\"contents\\": {
\\"id\\": \\"server1.conn13.child1/39\\",
\\"url\\": \\"https://davidwalsh.name/\\",
\\"isBlackBoxed\\": false,
\\"isPrettyPrinted\\": false,
\\"relativeUrl\\": \\"https://davidwalsh.name/\\",
\\"introductionUrl\\": null,
\\"isWasm\\": false,
\\"isExtension\\": false
}
},
{
\\"type\\": \\"source\\",
\\"name\\": \\"source1.js\\",
\\"path\\": \\"davidwalsh.name/source1.js\\",
\\"contents\\": {
\\"id\\": \\"server1.conn13.child1/37\\",
\\"url\\": \\"https://davidwalsh.name/source1.js\\",
\\"isBlackBoxed\\": false,
\\"isPrettyPrinted\\": false,
\\"relativeUrl\\": \\"https://davidwalsh.name/source1.js\\",
\\"introductionUrl\\": null,
\\"isWasm\\": false,
\\"isExtension\\": false
}
},
{
\\"type\\": \\"source\\",
\\"name\\": \\"source2.js\\",
\\"path\\": \\"davidwalsh.name/source2.js\\",
\\"contents\\": {
\\"id\\": \\"server1.conn13.child1/40\\",
\\"url\\": \\"https://davidwalsh.name/source2.js\\",
\\"isBlackBoxed\\": false,
\\"isPrettyPrinted\\": false,
\\"relativeUrl\\": \\"https://davidwalsh.name/source2.js\\",
\\"introductionUrl\\": null,
\\"isWasm\\": false,
\\"isExtension\\": false
}
\\"type\\": \\"directory\\",
\\"name\\": \\"davidwalsh.name\\",
\\"path\\": \\"FakeThread/davidwalsh.name\\",
\\"contents\\": [
{
\\"type\\": \\"source\\",
\\"name\\": \\"(index)\\",
\\"path\\": \\"https://davidwalsh.name/\\",
\\"contents\\": {
\\"id\\": \\"server1.conn13.child1/39\\",
\\"url\\": \\"https://davidwalsh.name/\\",
\\"isBlackBoxed\\": false,
\\"isPrettyPrinted\\": false,
\\"relativeUrl\\": \\"https://davidwalsh.name/\\",
\\"introductionUrl\\": null,
\\"isWasm\\": false,
\\"isExtension\\": false
}
},
{
\\"type\\": \\"source\\",
\\"name\\": \\"source1.js\\",
\\"path\\": \\"FakeThread/davidwalsh.name/source1.js\\",
\\"contents\\": {
\\"id\\": \\"server1.conn13.child1/37\\",
\\"url\\": \\"https://davidwalsh.name/source1.js\\",
\\"isBlackBoxed\\": false,
\\"isPrettyPrinted\\": false,
\\"relativeUrl\\": \\"https://davidwalsh.name/source1.js\\",
\\"introductionUrl\\": null,
\\"isWasm\\": false,
\\"isExtension\\": false
}
},
{
\\"type\\": \\"source\\",
\\"name\\": \\"source2.js\\",
\\"path\\": \\"FakeThread/davidwalsh.name/source2.js\\",
\\"contents\\": {
\\"id\\": \\"server1.conn13.child1/40\\",
\\"url\\": \\"https://davidwalsh.name/source2.js\\",
\\"isBlackBoxed\\": false,
\\"isPrettyPrinted\\": false,
\\"relativeUrl\\": \\"https://davidwalsh.name/source2.js\\",
\\"introductionUrl\\": null,
\\"isWasm\\": false,
\\"isExtension\\": false
}
}
]
}
]
}
@ -117,38 +131,30 @@ exports[`calls updateTree.js shows all the sources 1`] = `
\\"contents\\": [
{
\\"type\\": \\"directory\\",
\\"name\\": \\"davidwalsh.name\\",
\\"path\\": \\"davidwalsh.name\\",
\\"name\\": \\"FakeThread\\",
\\"path\\": \\"FakeThread\\",
\\"contents\\": [
{
\\"type\\": \\"source\\",
\\"name\\": \\"(index)\\",
\\"path\\": \\"https://davidwalsh.name/\\",
\\"contents\\": {
\\"id\\": \\"server1.conn13.child1/39\\",
\\"url\\": \\"https://davidwalsh.name/\\",
\\"isBlackBoxed\\": false,
\\"isPrettyPrinted\\": false,
\\"relativeUrl\\": \\"https://davidwalsh.name/\\",
\\"introductionUrl\\": null,
\\"isWasm\\": false,
\\"isExtension\\": false
}
},
{
\\"type\\": \\"source\\",
\\"name\\": \\"source1.js\\",
\\"path\\": \\"davidwalsh.name/source1.js\\",
\\"contents\\": {
\\"id\\": \\"server1.conn13.child1/37\\",
\\"url\\": \\"https://davidwalsh.name/source1.js\\",
\\"isBlackBoxed\\": false,
\\"isPrettyPrinted\\": false,
\\"relativeUrl\\": \\"https://davidwalsh.name/source1.js\\",
\\"introductionUrl\\": null,
\\"isWasm\\": false,
\\"isExtension\\": false
}
\\"type\\": \\"directory\\",
\\"name\\": \\"davidwalsh.name\\",
\\"path\\": \\"FakeThread/davidwalsh.name\\",
\\"contents\\": [
{
\\"type\\": \\"source\\",
\\"name\\": \\"(index)\\",
\\"path\\": \\"https://davidwalsh.name/\\",
\\"contents\\": {
\\"id\\": \\"server1.conn13.child1/39\\",
\\"url\\": \\"https://davidwalsh.name/\\",
\\"isBlackBoxed\\": false,
\\"isPrettyPrinted\\": false,
\\"relativeUrl\\": \\"https://davidwalsh.name/\\",
\\"introductionUrl\\": null,
\\"isWasm\\": false,
\\"isExtension\\": false
}
}
]
}
]
}

Просмотреть файл

@ -17,7 +17,7 @@ import {
nodeHasChildren
} from "../index";
type RawSource = {| url: string, id: string |};
type RawSource = {| url: string, id: string, actors?: any |};
function createSourcesMap(sources: RawSource[]) {
const sourcesMap = sources.reduce((map, source) => {
@ -63,10 +63,10 @@ describe("sources-tree", () => {
);
const tree = createDirectoryNode("root", "", []);
addToTree(tree, source1, "http://example.com/");
addToTree(tree, source1, "http://example.com/", "FakeThread");
expect(tree.contents).toHaveLength(1);
const base = tree.contents[0];
const base = tree.contents[0].contents[0];
expect(base.name).toBe("example.com");
expect(base.contents).toHaveLength(1);
@ -89,8 +89,8 @@ describe("sources-tree", () => {
const tree = createDirectoryNode("root", "", []);
addToTree(tree, source1, "http://example.com/");
const childNode = getChildNode(tree, 0, 0, 0);
addToTree(tree, source1, "http://example.com/", "FakeThread");
const childNode = getChildNode(tree, 0, 0, 0, 0);
expect(childNode.name).toEqual(sourceName);
expect(formatTree(tree)).toMatchSnapshot();
});
@ -105,7 +105,7 @@ describe("sources-tree", () => {
const tree = createDirectoryNode("root", "", []);
addToTree(tree, source1, "http://example.com/");
addToTree(tree, source1, "http://example.com/", "FakeThread");
expect(formatTree(tree)).toMatchSnapshot();
});
@ -121,14 +121,22 @@ describe("sources-tree", () => {
}
];
const sourceMap = createSourcesMap(sources);
const sourceMap = { FakeThread: createSourcesMap(sources) };
const tree = createTree({
sources: sourceMap,
debuggeeUrl: "",
projectRoot: ""
threads: [
{
actor: "FakeThread",
name: "FakeThread",
url: "https://davidwalsh.name",
type: 1
}
]
}).sourceTree;
// expect(tree.contents).toHaveLength(1);
const subtree = tree.contents[0];
expect(tree.contents[0].contents).toHaveLength(1);
const subtree = tree.contents[0].contents[0];
expect(subtree.contents).toHaveLength(2);
expect(formatTree(tree)).toMatchSnapshot();
});
@ -141,11 +149,18 @@ describe("sources-tree", () => {
}
];
const sourceMap = createSourcesMap(sources);
const sourceMap = { FakeThread: createSourcesMap(sources) };
const tree = createTree({
sources: sourceMap,
debuggeeUrl: "",
projectRoot: ""
threads: [
{
actor: "FakeThread",
url: "https://davidwalsh.name",
type: 1,
name: "FakeThread"
}
]
}).sourceTree;
expect(formatTree(tree)).toMatchSnapshot();
});
@ -158,19 +173,39 @@ describe("sources-tree", () => {
},
{
id: "server1.conn13.child1/37",
url: "https://davidwalsh.name/"
url: "https://davidwalsh.name/util.js"
}
];
const sourceMap = createSourcesMap(sources);
const sourceMap = {
FakeThread: createSourcesMap(sources),
FakeThread2: createSourcesMap([sources[1]])
};
const tree = createTree({
sources: sourceMap,
debuggeeUrl: "",
projectRoot: ""
debuggeeUrl: "https://davidwalsh.name",
threads: [
{
actor: "FakeThread",
name: "FakeThread",
url: "https://davidwalsh.name",
type: 1
},
{
actor: "FakeThread2",
name: "FakeThread2",
url: "https://davidwalsh.name/WorkerA.js",
type: 2
}
]
}).sourceTree;
expect(tree.contents).toHaveLength(1);
const subtree = tree.contents[0];
expect(subtree.contents).toHaveLength(1);
expect(tree.contents[0].contents).toHaveLength(1);
const subtree = tree.contents[0].contents[0];
expect(subtree.contents).toHaveLength(2);
const subtree2 = tree.contents[1].contents[0];
expect(subtree2.contents).toHaveLength(1);
expect(formatTree(tree)).toMatchSnapshot();
});
@ -186,11 +221,11 @@ describe("sources-tree", () => {
);
const tree = createDirectoryNode("root", "", []);
addToTree(tree, source1, "http://example.com/");
addToTree(tree, source2, "http://example.com/");
addToTree(tree, source3, "http://example.com/");
addToTree(tree, source1, "http://example.com/", "FakeThread");
addToTree(tree, source2, "http://example.com/", "FakeThread");
addToTree(tree, source3, "http://example.com/", "FakeThread");
const base = tree.contents[0];
const base = tree.contents[0].contents[0];
expect(tree.contents).toHaveLength(1);
const source1Node = base.contents[0];
@ -202,10 +237,10 @@ describe("sources-tree", () => {
const source = makeMockSource("file:///a/b.js", "actor1");
const tree = createDirectoryNode("root", "", []);
addToTree(tree, source, "file:///a/index.html");
addToTree(tree, source, "file:///a/index.html", "FakeThread");
expect(tree.contents).toHaveLength(1);
const base = tree.contents[0];
const base = tree.contents[0].contents[0];
expect(base.name).toBe("file://");
expect(base.contents).toHaveLength(1);
@ -232,7 +267,9 @@ describe("sources-tree", () => {
const sources = createSourcesList(testData);
const tree = createDirectoryNode("root", "", []);
sources.forEach(source => addToTree(tree, source, "https://unpkg.com/"));
sources.forEach(source =>
addToTree(tree, source, "https://unpkg.com/", "FakeThread")
);
expect(formatTree(tree)).toMatchSnapshot();
});
@ -251,7 +288,9 @@ describe("sources-tree", () => {
const sources = createSourcesList(testData);
const tree = createDirectoryNode("root", "", []);
sources.forEach(source => addToTree(tree, source, "https://unpkg.com/"));
sources.forEach(source =>
addToTree(tree, source, "https://unpkg.com/", "FakeThread")
);
expect(formatTree(tree)).toMatchSnapshot();
});
@ -284,7 +323,7 @@ describe("sources-tree", () => {
const domain = "http://localhost:4242";
const sources = createSourcesList(testData);
const tree = createDirectoryNode("root", "", []);
sources.forEach(source => addToTree(tree, source, domain));
sources.forEach(source => addToTree(tree, source, domain, "FakeThread"));
expect(formatTree(tree)).toMatchSnapshot();
});
});

Просмотреть файл

@ -8,7 +8,6 @@ import { makeMockSource } from "../../../utils/test-mockup";
import {
collapseTree,
sortEntireTree,
formatTree,
addToTree,
createDirectoryNode
@ -22,11 +21,11 @@ describe("sources tree", () => {
describe("collapseTree", () => {
it("can collapse a single source", () => {
const fullTree = createDirectoryNode("root", "", []);
addToTree(fullTree, abcSource, "http://example.com/");
addToTree(fullTree, abcSource, "http://example.com/", "Main Thread");
expect(fullTree.contents).toHaveLength(1);
const tree = collapseTree(fullTree);
const host = tree.contents[0];
const host = tree.contents[0].contents[0];
expect(host.name).toBe("example.com");
expect(host.contents).toHaveLength(1);
@ -36,20 +35,17 @@ describe("sources tree", () => {
const abcNode = abFolder.contents[0];
expect(abcNode.name).toBe("c.js");
expect(abcNode.path).toBe("example.com/a/b/c.js");
expect(abcNode.path).toBe("Main Thread/example.com/a/b/c.js");
expect(formatTree(tree)).toMatchSnapshot();
});
it("correctly merges in a collapsed source with a deeper level", () => {
const fullTree = createDirectoryNode("root", "", []);
addToTree(fullTree, abcSource, "http://example.com/");
addToTree(fullTree, abcdeSource, "http://example.com/");
addToTree(fullTree, abcSource, "http://example.com/", "Main Thread");
addToTree(fullTree, abcdeSource, "http://example.com/", "Main Thread");
const tree = collapseTree(fullTree);
sortEntireTree(tree);
expect(tree.contents).toHaveLength(1);
const host = tree.contents[0];
const host = tree.contents[0].contents[0];
expect(host.name).toBe("example.com");
expect(host.contents).toHaveLength(1);
@ -59,24 +55,24 @@ describe("sources tree", () => {
const [cdFolder, abcNode] = abFolder.contents;
expect(abcNode.name).toBe("c.js");
expect(abcNode.path).toBe("example.com/a/b/c.js");
expect(abcNode.path).toBe("Main Thread/example.com/a/b/c.js");
expect(cdFolder.name).toBe("c/d");
const [abcdeNode] = cdFolder.contents;
expect(abcdeNode.name).toBe("e.js");
expect(abcdeNode.path).toBe("example.com/a/b/c/d/e.js");
expect(abcdeNode.path).toBe("Main Thread/example.com/a/b/c/d/e.js");
expect(formatTree(tree)).toMatchSnapshot();
});
it("correctly merges in a collapsed source with a shallower level", () => {
const fullTree = createDirectoryNode("root", "", []);
addToTree(fullTree, abcSource, "http://example.com/");
addToTree(fullTree, abxSource, "http://example.com/");
addToTree(fullTree, abcSource, "http://example.com/", "Main Thread");
addToTree(fullTree, abxSource, "http://example.com/", "Main Thread");
const tree = collapseTree(fullTree);
expect(tree.contents).toHaveLength(1);
const host = tree.contents[0];
const host = tree.contents[0].contents[0];
expect(host.name).toBe("example.com");
expect(host.contents).toHaveLength(1);
@ -86,21 +82,21 @@ describe("sources tree", () => {
const [abcNode, abxNode] = abFolder.contents;
expect(abcNode.name).toBe("c.js");
expect(abcNode.path).toBe("example.com/a/b/c.js");
expect(abcNode.path).toBe("Main Thread/example.com/a/b/c.js");
expect(abxNode.name).toBe("x.js");
expect(abxNode.path).toBe("example.com/a/b/x.js");
expect(abxNode.path).toBe("Main Thread/example.com/a/b/x.js");
expect(formatTree(tree)).toMatchSnapshot();
});
it("correctly merges in a collapsed source with the same level", () => {
const fullTree = createDirectoryNode("root", "", []);
addToTree(fullTree, abcdeSource, "http://example.com/");
addToTree(fullTree, abcSource, "http://example.com/");
addToTree(fullTree, abcdeSource, "http://example.com/", "Main Thread");
addToTree(fullTree, abcSource, "http://example.com/", "Main Thread");
const tree = collapseTree(fullTree);
expect(tree.contents).toHaveLength(1);
const host = tree.contents[0];
const host = tree.contents[0].contents[0];
expect(host.name).toBe("example.com");
expect(host.contents).toHaveLength(1);
@ -110,12 +106,12 @@ describe("sources tree", () => {
const [cdFolder, abcNode] = abFolder.contents;
expect(abcNode.name).toBe("c.js");
expect(abcNode.path).toBe("example.com/a/b/c.js");
expect(abcNode.path).toBe("Main Thread/example.com/a/b/c.js");
expect(cdFolder.name).toBe("c/d");
const [abcdeNode] = cdFolder.contents;
expect(abcdeNode.name).toBe("e.js");
expect(abcdeNode.path).toBe("example.com/a/b/c/d/e.js");
expect(abcdeNode.path).toBe("Main Thread/example.com/a/b/c/d/e.js");
expect(formatTree(tree)).toMatchSnapshot();
});
});

Просмотреть файл

@ -14,11 +14,13 @@ function formatDirectories(source, tree) {
}
function createSources(urls) {
return urls.reduce((sources, url, index) => {
const id = `a${index}`;
sources[id] = makeMockSource(url, id);
return sources;
}, {});
return {
FakeThread: urls.reduce((sources, url, index) => {
const id = `a${index}`;
sources[id] = makeMockSource(url, id);
return sources;
}, {})
};
}
describe("getDirectories", () => {
@ -29,14 +31,36 @@ describe("getDirectories", () => {
"http://b/c.js"
]);
const threads = [
{
actor: "FakeThread",
url: "http://a",
type: 1,
name: "FakeThread"
}
];
const debuggeeUrl = "http://a/";
const { sourceTree } = createTree({
sources,
debuggeeUrl,
projectRoot: ""
threads
});
expect(formatDirectories(sources.a0, sourceTree)).toEqual(["a/b.js", "a"]);
expect(formatDirectories(sources.a1, sourceTree)).toEqual(["a/c.js", "a"]);
expect(formatDirectories(sources.a2, sourceTree)).toEqual(["b/c.js", "b"]);
expect(formatDirectories(sources.FakeThread.a0, sourceTree)).toEqual([
"FakeThread/a/b.js",
"FakeThread/a",
"FakeThread"
]);
expect(formatDirectories(sources.FakeThread.a1, sourceTree)).toEqual([
"FakeThread/a/c.js",
"FakeThread/a",
"FakeThread"
]);
expect(formatDirectories(sources.FakeThread.a2, sourceTree)).toEqual([
"FakeThread/b/c.js",
"FakeThread/b",
"FakeThread"
]);
});
});

Просмотреть файл

@ -1,153 +0,0 @@
/* eslint max-nested-callbacks: ["error", 4]*/
/* 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 { makeMockSource } from "../../../utils/test-mockup";
import {
addToTree,
sortEntireTree,
createDirectoryNode,
formatTree
} from "../index";
describe("sources-tree", () => {
describe("sortEntireTree", () => {
it("alphabetically sorts children", () => {
const source1 = makeMockSource("http://example.com/source1.js", "actor1");
const source2 = makeMockSource(
"http://example.com/foo/b_source2.js",
"actor2"
);
const source3 = makeMockSource(
"http://example.com/foo/a_source3.js",
"actor3"
);
const _tree = createDirectoryNode("root", "", []);
addToTree(_tree, source1, "http://example.com/");
addToTree(_tree, source2, "http://example.com/");
addToTree(_tree, source3, "http://example.com/");
const tree = sortEntireTree(_tree);
const base = tree.contents[0];
const fooNode = base.contents[0];
expect(fooNode.name).toBe("foo");
expect(fooNode.contents).toHaveLength(2);
const source1Node = base.contents[1];
expect(source1Node.name).toBe("source1.js");
// source2 should be after source1 alphabetically
const source2Node = fooNode.contents[1];
const source3Node = fooNode.contents[0];
expect(source2Node.name).toBe("b_source2.js");
expect(source3Node.name).toBe("a_source3.js");
expect(formatTree(tree)).toMatchSnapshot();
});
it("sorts folders first", () => {
const sources = [
makeMockSource("http://example.com/a.js", "actor1"),
makeMockSource("http://example.com/b.js/b_source.js", "actor2"),
makeMockSource("http://example.com/c.js", "actor3"),
makeMockSource("http://example.com", "actor4"),
makeMockSource("http://example.com/d/d_source.js", "actor5"),
makeMockSource("http://example.com/b2", "actor6")
];
const _tree = createDirectoryNode("root", "", []);
sources.forEach(source =>
addToTree(_tree, source, "http://example.com/")
);
const tree = sortEntireTree(_tree);
const domain = tree.contents[0];
const [
indexNode,
bFolderNode,
dFolderNode,
aFileNode,
b2FileNode,
cFileNode
] = domain.contents;
expect(formatTree(tree)).toMatchSnapshot();
expect(indexNode.name).toBe("(index)");
expect(bFolderNode.name).toBe("b.js");
expect(bFolderNode.contents).toHaveLength(1);
expect(bFolderNode.contents[0].name).toBe("b_source.js");
expect(b2FileNode.name).toBe("b2");
expect(dFolderNode.name).toBe("d");
expect(dFolderNode.contents).toHaveLength(1);
expect(dFolderNode.contents[0].name).toBe("d_source.js");
expect(aFileNode.name).toBe("a.js");
expect(cFileNode.name).toBe("c.js");
expect(formatTree(tree)).toMatchSnapshot();
});
it("puts folder at the top of the sort", () => {
const sources = [
makeMockSource("http://example.com/folder/a.js", "actor1"),
makeMockSource("http://example.com/folder/b/b.js", "actor2"),
makeMockSource("http://example.com/folder/c/", "actor3")
];
const _tree = createDirectoryNode("root", "", []);
sources.forEach(source =>
addToTree(_tree, source, "http://example.com/")
);
const tree = sortEntireTree(_tree);
const [
bFolderNode,
cFolderNode,
aFileNode
] = tree.contents[0].contents[0].contents;
expect(bFolderNode.name).toBe("b");
expect(bFolderNode.contents).toHaveLength(1);
expect(bFolderNode.contents[0].name).toBe("b.js");
expect(cFolderNode.name).toBe("c");
expect(cFolderNode.contents).toHaveLength(1);
expect(cFolderNode.contents[0].name).toBe("(index)");
expect(aFileNode.name).toBe("a.js");
expect(formatTree(tree)).toMatchSnapshot();
});
it("puts root debugee url at the top of the sort", () => {
const sources = [
makeMockSource("http://api.example.com/a.js", "actor1"),
makeMockSource("http://example.com/b.js", "actor2"),
makeMockSource("http://demo.com/c.js", "actor3")
];
const rootA = "http://example.com/path/to/file.html";
const rootB = "https://www.demo.com/index.html";
const _treeA = createDirectoryNode("root", "", []);
const _treeB = createDirectoryNode("root", "", []);
sources.forEach(source => {
addToTree(_treeA, source, rootA);
addToTree(_treeB, source, rootB);
});
const treeA = sortEntireTree(_treeA, rootA);
const treeB = sortEntireTree(_treeB, rootB);
expect(treeA.contents[0].contents[0].name).toBe("b.js");
expect(treeA.contents[1].contents[0].name).toBe("a.js");
expect(treeB.contents[0].contents[0].name).toBe("c.js");
expect(treeB.contents[1].contents[0].name).toBe("a.js");
expect(formatTree(treeA)).toMatchSnapshot();
expect(formatTree(treeB)).toMatchSnapshot();
});
});
});

Просмотреть файл

@ -7,7 +7,7 @@
import { makeMockSource } from "../../../utils/test-mockup";
import { updateTree, createTree } from "../index";
type RawSource = {| url: string, id: string |};
type RawSource = {| url: string, id: string, actors?: any |};
function createSourcesMap(sources: RawSource[]) {
const sourcesMap = sources.reduce((map, source) => {
@ -15,7 +15,7 @@ function createSourcesMap(sources: RawSource[]) {
return map;
}, {});
return sourcesMap;
return { FakeThread: sourcesMap };
}
function formatTree(tree) {
@ -37,25 +37,32 @@ const sources = [
}
];
const threads = [
{
actor: "FakeThread",
url: "https://davidwalsh.name",
type: 1,
name: "FakeThread"
}
];
const debuggeeUrl = "blah";
describe("calls updateTree.js", () => {
it("adds one source", () => {
const prevSources = createSourcesMap([sources[0]]);
const { sourceTree, uncollapsedTree } = createTree({
debuggeeUrl,
sources: prevSources,
projectRoot: ""
threads
});
const newTree = updateTree({
debuggeeUrl,
prevSources,
newSources: createSourcesMap([sources[0], sources[1]]),
uncollapsedTree,
sourceTree,
projectRoot: ""
threads
});
expect(formatTree(newTree)).toMatchSnapshot();
@ -67,7 +74,7 @@ describe("calls updateTree.js", () => {
const { sourceTree, uncollapsedTree } = createTree({
debuggeeUrl,
sources: prevSources,
projectRoot: ""
threads
});
const newTree = updateTree({
@ -76,7 +83,8 @@ describe("calls updateTree.js", () => {
newSources: createSourcesMap([sources[0], sources[1], sources[2]]),
uncollapsedTree,
sourceTree,
projectRoot: ""
projectRoot: "",
threads
});
expect(formatTree(newTree)).toMatchSnapshot();
@ -90,7 +98,7 @@ describe("calls updateTree.js", () => {
const { sourceTree, uncollapsedTree } = createTree({
debuggeeUrl,
sources: prevSources,
projectRoot: ""
threads
});
const newTree = updateTree({
@ -99,7 +107,8 @@ describe("calls updateTree.js", () => {
newSources: createSourcesMap([sources[1]]),
uncollapsedTree,
sourceTree,
projectRoot: ""
projectRoot: "",
threads
});
expect(formatTree(newTree)).toMatchSnapshot();

Просмотреть файл

@ -13,7 +13,6 @@ import {
isExactUrlMatch,
isDirectory,
addToTree,
sortEntireTree,
isNotJavaScript
} from "../index";
@ -47,9 +46,10 @@ describe("sources tree", () => {
];
const tree = createDirectoryNode("root", "", []);
sources.forEach(source => addToTree(tree, source, "http://example.com/"));
sortEntireTree(tree);
const [bFolderNode, aFileNode] = tree.contents[0].contents;
sources.forEach(source =>
addToTree(tree, source, "http://example.com/", "Main Thread")
);
const [bFolderNode, aFileNode] = tree.contents[0].contents[0].contents;
const [cFolderNode] = bFolderNode.contents;
const [dFileNode] = cFolderNode.contents;

Просмотреть файл

@ -6,42 +6,82 @@
import { addToTree } from "./addToTree";
import { collapseTree } from "./collapseTree";
import { createParentMap } from "./utils";
import { difference } from "lodash";
import { createDirectoryNode, createParentMap } from "./utils";
import { getDomain } from "./treeOrder";
import type { SourcesMap } from "../../reducers/types";
import type { SourcesMapByThread } from "../../reducers/types";
import type { Thread, Source } from "../../types";
import type { TreeDirectory } from "./types";
function newSourcesSet(newSources, prevSources) {
const newSourceIds = difference(
Object.keys(newSources),
Object.keys(prevSources)
);
const uniqSources = newSourceIds.map(id => newSources[id]);
return uniqSources;
function getSourcesToAdd(newSources, prevSources): Source[] {
const sourcesToAdd = [];
for (const sourceId in newSources) {
const newSource = newSources[sourceId];
const prevSource = prevSources ? prevSources[sourceId] : null;
if (!prevSource) {
sourcesToAdd.push(newSource);
}
}
return sourcesToAdd;
}
type Params = {
newSources: SourcesMap,
prevSources: SourcesMap,
type UpdateTreeParams = {
newSources: SourcesMapByThread,
prevSources: SourcesMapByThread,
uncollapsedTree: TreeDirectory,
sourceTree: TreeDirectory,
debuggeeUrl: string
debuggeeUrl: string,
threads: Thread[]
};
type CreateTreeParams = {
sources: SourcesMapByThread,
debuggeeUrl: string,
threads: Thread[]
};
export function createTree({
debuggeeUrl,
sources,
threads
}: CreateTreeParams) {
const uncollapsedTree = createDirectoryNode("root", "", []);
return updateTree({
debuggeeUrl,
newSources: sources,
prevSources: {},
threads,
uncollapsedTree
});
}
export function updateTree({
newSources,
prevSources,
debuggeeUrl,
uncollapsedTree,
sourceTree
}: Params) {
const newSet = newSourcesSet(newSources, prevSources);
threads
}: UpdateTreeParams) {
const debuggeeHost = getDomain(debuggeeUrl);
const contexts = (Object.keys(newSources): any);
for (const source of newSet) {
addToTree(uncollapsedTree, source, debuggeeHost);
}
contexts.forEach(context => {
const thread = threads.find(t => t.actor === context);
if (!thread) {
return;
}
const sourcesToAdd = getSourcesToAdd(
(Object.values(newSources[context]): any),
prevSources[context] ? (Object.values(prevSources[context]): any) : null
);
for (const source of sourcesToAdd) {
addToTree(uncollapsedTree, source, debuggeeHost, thread.actor);
}
});
const newSourceTree = collapseTree(uncollapsedTree);

Просмотреть файл

@ -13,7 +13,7 @@ import { getURL } from "./getURL";
const IGNORED_URLS = ["debugger eval code", "XStringBundle"];
export function nodeHasChildren(item: TreeNode): boolean {
return Array.isArray(item.contents) && item.type === "directory";
return Array.isArray(item.contents) && item.type == "directory";
}
export function isExactUrlMatch(pathPart: string, debuggeeUrl: string) {

Просмотреть файл

@ -10,7 +10,7 @@ add_task(async function() {
await waitForSources(dbg, "doc-asm.html", "asm.js");
// Make sure sources appear.
is(findAllElements(dbg, "sourceNodes").length, 2);
is(findAllElements(dbg, "sourceNodes").length, 3);
await selectSource(dbg, "asm.js");

Просмотреть файл

@ -49,6 +49,9 @@ add_task(async function() {
const extension = await installAndStartExtension();
let dbg = await initDebugger("doc-content-script-sources.html");
await clickElement(dbg, "sourceDirectoryLabel", 2);
await selectContentScriptSources(dbg);
await closeTab(dbg, "content_script.js");
@ -57,6 +60,9 @@ add_task(async function() {
await dbg.toolbox.destroy();
const toolbox = await openToolboxForTab(gBrowser.selectedTab, "jsdebugger");
dbg = createDebuggerContext(toolbox);
await clickElement(dbg, "sourceDirectoryLabel", 2);
await selectContentScriptSources(dbg);
await addBreakpoint(dbg, "content_script.js", 2);

Просмотреть файл

@ -66,8 +66,8 @@ add_task(async function() {
const bundleSrc = findSource(dbg, "bundle.js");
// Check that the original sources appear in the source tree
await clickElement(dbg, "sourceDirectoryLabel", 3);
await assertSourceCount(dbg, 8);
await clickElement(dbg, "sourceDirectoryLabel", 4);
await assertSourceCount(dbg, 9);
await selectSource(dbg, bundleSrc);

Просмотреть файл

@ -5,8 +5,8 @@
add_task(async function() {
const dbg = await initDebugger("doc-sources.html", "simple1", "simple2", "nested-source", "long.js");
await clickElement(dbg, "sourceDirectoryLabel", 2);
await assertSourceCount(dbg, 7);
await clickElement(dbg, "sourceDirectoryLabel", 3);
await assertSourceCount(dbg, 8);
// Right key on open dir
await pressKey(dbg, "Right");
@ -15,12 +15,12 @@ add_task(async function() {
// Right key on closed dir
await pressKey(dbg, "Right");
await assertSourceCount(dbg, 8);
await assertNodeIsFocused(dbg, 3);
await assertNodeIsFocused(dbg, 4);
// Left key on a open dir
await pressKey(dbg, "Left");
await assertSourceCount(dbg, 7);
await assertNodeIsFocused(dbg, 3);
await assertSourceCount(dbg, 8);
await assertNodeIsFocused(dbg, 4);
// Down key on a closed dir
await pressKey(dbg, "Down");
@ -28,32 +28,33 @@ add_task(async function() {
// Right key on a source
await pressKey(dbg, "Right");
await assertNodeIsFocused(dbg, 5);
await assertNodeIsFocused(dbg, 4);
// Down key on a source
await waitForSourceCount(dbg, 9);
await pressKey(dbg, "Down");
await assertNodeIsFocused(dbg, 6);
await assertNodeIsFocused(dbg, 5);
// Go to bottom of tree and press down key
await pressKey(dbg, "Down");
await pressKey(dbg, "Down");
await assertNodeIsFocused(dbg, 7);
await assertNodeIsFocused(dbg, 6);
// Up key on a source
await pressKey(dbg, "Up");
await assertNodeIsFocused(dbg, 6);
await assertNodeIsFocused(dbg, 5);
// Left key on a source
await pressKey(dbg, "Left");
await assertNodeIsFocused(dbg, 2);
await assertNodeIsFocused(dbg, 4);
// Left key on a closed dir
await pressKey(dbg, "Left");
await assertSourceCount(dbg, 2);
await assertSourceCount(dbg, 8);
await pressKey(dbg, "Left");
await assertNodeIsFocused(dbg, 1);
await assertNodeIsFocused(dbg, 3);
// Up Key at the top of the source tree
await pressKey(dbg, "Up");
await assertNodeIsFocused(dbg, 1);
await assertNodeIsFocused(dbg, 2);
});

Просмотреть файл

@ -18,15 +18,15 @@ add_task(async function() {
} = dbg;
// Expand nodes and make sure more sources appear.
await assertSourceCount(dbg, 2);
await clickElement(dbg, "sourceDirectoryLabel", 2);
await assertSourceCount(dbg, 7);
await assertSourceCount(dbg, 3);
await clickElement(dbg, "sourceDirectoryLabel", 3);
await assertSourceCount(dbg, 8);
await clickElement(dbg, "sourceDirectoryLabel", 4);
await assertSourceCount(dbg, 9);
const selected = waitForDispatch(dbg, "SET_SELECTED_LOCATION");
await clickElement(dbg, "sourceNode", 4);
await clickElement(dbg, "sourceNode", 5);
await selected;
await waitForSelectedSource(dbg);
@ -34,12 +34,12 @@ add_task(async function() {
await waitForElementWithSelector(dbg, ".sources-list .focused");
const focusedNode = findElementWithSelector(dbg, ".sources-list .focused");
const fourthNode = findElement(dbg, "sourceNode", 4);
const fourthNode = findElement(dbg, "sourceNode", 5);
const selectedSource = getSelectedSource().url;
ok(fourthNode.classList.contains("focused"), "4th node is focused");
ok(selectedSource.includes("nested-source.js"), "nested-source is selected");
await assertNodeIsFocused(dbg, 4);
await assertNodeIsFocused(dbg, 5);
await waitForSelectedSource(dbg, "nested-source");
// Make sure new sources appear in the list.
@ -49,10 +49,10 @@ add_task(async function() {
content.document.body.appendChild(script);
});
await waitForSourceCount(dbg, 9);
await assertNodeIsFocused(dbg, 4);
await waitForSourceCount(dbg, 10);
await assertNodeIsFocused(dbg, 5);
is(
getSourceNodeLabel(dbg, 7),
getSourceNodeLabel(dbg, 8),
"math.min.js",
"math.min.js - The dynamic script exists"
);

Просмотреть файл

@ -15,12 +15,11 @@ info(`START: ${new Error().lineNumber}`);
const document = window.document;
await waitForSources(dbg, testUrl);
// yield waitForSourceCount(dbg, 6);
info("Loaded, selecting the test script to debug");
// First expand the domain
const domain = [...document.querySelectorAll(".tree-node")].find(node => {
return node.textContent.trim() == "mozilla.org";
return node.querySelector(".label").textContent.trim() == "mozilla.org";
});
const arrow = domain.querySelector(".arrow");
arrow.click();