/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
var { BrowserLoader } = ChromeUtils.importESModule(
"resource://devtools/shared/loader/browser-loader.sys.mjs"
);
var { require } = BrowserLoader({
baseURI:
"resource://devtools/client/memory/",
window,
});
var {
Assert } = ChromeUtils.importESModule(
"resource://testing-common/Assert.sys.mjs"
);
var EXPECTED_DTU_ASSERT_FAILURE_COUNT =
0;
SimpleTest.registerCleanupFunction(
function () {
if (
DevToolsUtils.assertionFailureCount !== EXPECTED_DTU_ASSERT_FAILURE_COUNT
) {
ok(
false,
"Should have had the expected number of DevToolsUtils.assert() failures." +
"Expected " +
EXPECTED_DTU_ASSERT_FAILURE_COUNT +
", got " +
DevToolsUtils.assertionFailureCount
);
}
});
var DevToolsUtils = require(
"resource://devtools/shared/DevToolsUtils.js");
var { immutableUpdate } = DevToolsUtils;
var constants = require(
"resource://devtools/client/memory/constants.js");
var {
censusDisplays,
diffingState,
labelDisplays,
dominatorTreeState,
snapshotState,
viewState,
censusState,
} = constants;
const { L10N } = require(
"resource://devtools/client/memory/utils.js");
var models = require(
"resource://devtools/client/memory/models.js");
var Immutable = require(
"resource://devtools/client/shared/vendor/immutable.js");
var React = require(
"resource://devtools/client/shared/vendor/react.js");
const dom = require(
"resource://devtools/client/shared/vendor/react-dom-factories.js");
var ReactDOM = require(
"resource://devtools/client/shared/vendor/react-dom.js");
var { createFactory } = React;
var Heap = createFactory(
require(
"resource://devtools/client/memory/components/Heap.js")
);
var CensusTreeItem = createFactory(
require(
"resource://devtools/client/memory/components/CensusTreeItem.js")
);
var DominatorTreeComponent = createFactory(
require(
"resource://devtools/client/memory/components/DominatorTree.js")
);
var DominatorTreeItem = createFactory(
require(
"resource://devtools/client/memory/components/DominatorTreeItem.js")
);
var ShortestPaths = createFactory(
require(
"resource://devtools/client/memory/components/ShortestPaths.js")
);
var TreeMap = createFactory(
require(
"resource://devtools/client/memory/components/TreeMap.js")
);
var SnapshotListItem = createFactory(
require(
"resource://devtools/client/memory/components/SnapshotListItem.js")
);
var List = createFactory(
require(
"resource://devtools/client/memory/components/List.js")
);
var Toolbar = createFactory(
require(
"resource://devtools/client/memory/components/Toolbar.js")
);
// All tests are asynchronous.
SimpleTest.waitForExplicitFinish();
var noop = () => {};
var TEST_CENSUS_TREE_ITEM_PROPS = Object.freeze({
item: Object.freeze({
bytes:
10,
count:
1,
totalBytes:
10,
totalCount:
1,
name:
"foo",
children: [
Object.freeze({
bytes:
10,
count:
1,
totalBytes:
10,
totalCount:
1,
name:
"bar",
}),
],
}),
depth:
0,
arrow:
">",
focused:
true,
getPercentBytes: () =>
50,
getPercentCount: () =>
50,
showSign:
false,
onViewSourceInDebugger: noop,
inverted:
false,
});
// Counter for mock DominatorTreeNode ids.
var TEST_NODE_ID_COUNTER =
0;
/**
* Create a mock DominatorTreeNode for testing, with sane defaults. Override any
* property by providing it on `opts`. Optionally pass child nodes as well.
*
* @param {Object} opts
* @param {Array<DominatorTreeNode>?} children
*
* @returns {DominatorTreeNode}
*/
function makeTestDominatorTreeNode(opts, children) {
const nodeId = TEST_NODE_ID_COUNTER++;
const node = Object.assign(
{
nodeId,
label: [
"other",
"SomeType"],
shallowSize:
1,
retainedSize: (children || []).reduce(
(size, c) => size + c.retainedSize,
1
),
parentId: undefined,
children,
moreChildrenAvailable:
true,
},
opts
);
if (children && children.length) {
children.map(c => {
c.parentId = node.nodeId;
});
}
return node;
}
var TEST_DOMINATOR_TREE = Object.freeze({
dominatorTreeId:
666,
root: (
function makeTree(depth =
0) {
let children;
if (depth <=
3) {
children = [
makeTree(depth +
1),
makeTree(depth +
1),
makeTree(depth +
1),
];
}
return makeTestDominatorTreeNode({}, children);
})(),
expanded:
new Set(),
focused:
null,
error:
null,
display: labelDisplays.coarseType,
activeFetchRequestCount:
null,
state: dominatorTreeState.LOADED,
});
var TEST_DOMINATOR_TREE_PROPS = Object.freeze({
dominatorTree: TEST_DOMINATOR_TREE,
onLoadMoreSiblings: noop,
onViewSourceInDebugger: noop,
onExpand: noop,
onCollapse: noop,
});
var TEST_SHORTEST_PATHS_PROPS = Object.freeze({
graph: Object.freeze({
nodes: [
{ id:
1, label: [
"other",
"SomeType"] },
{ id:
2, label: [
"other",
"SomeType"] },
{ id:
3, label: [
"other",
"SomeType"] },
],
edges: [
{ from:
1, to:
2, name:
"1->2" },
{ from:
1, to:
3, name:
"1->3" },
{ from:
2, to:
3, name:
"2->3" },
],
}),
});
var TEST_SNAPSHOT = Object.freeze({
id:
1337,
selected:
true,
path:
"/fake/path/to/snapshot",
census: Object.freeze({
report: Object.freeze({
objects: Object.freeze({ count:
4, bytes:
400 }),
scripts: Object.freeze({ count:
3, bytes:
300 }),
strings: Object.freeze({ count:
2, bytes:
200 }),
other: Object.freeze({ count:
1, bytes:
100 }),
}),
display: Object.freeze({
displayName:
"Test Display",
tooltip:
"Test display tooltup",
inverted:
false,
breakdown: Object.freeze({
by:
"coarseType",
objects: Object.freeze({ by:
"count", count:
true, bytes:
true }),
scripts: Object.freeze({ by:
"count", count:
true, bytes:
true }),
strings: Object.freeze({ by:
"count", count:
true, bytes:
true }),
other: Object.freeze({ by:
"count", count:
true, bytes:
true }),
}),
}),
state: censusState.SAVED,
inverted:
false,
filter:
null,
expanded:
new Set(),
focused:
null,
parentMap: Object.freeze(Object.create(
null)),
}),
dominatorTree: TEST_DOMINATOR_TREE,
error:
null,
imported:
false,
creationTime:
0,
state: snapshotState.READ,
});
var TEST_HEAP_PROPS = Object.freeze({
onSnapshotClick: noop,
onLoadMoreSiblings: noop,
onCensusExpand: noop,
onCensusCollapse: noop,
onDominatorTreeExpand: noop,
onDominatorTreeCollapse: noop,
onCensusFocus: noop,
onDominatorTreeFocus: noop,
onViewSourceInDebugger: noop,
diffing:
null,
view: { state: viewState.CENSUS },
snapshot: TEST_SNAPSHOT,
sizes: Object.freeze({ shortestPathsSize:
0.
5 }),
onShortestPathsResize: noop,
});
var TEST_TOOLBAR_PROPS = Object.freeze({
censusDisplays: [
censusDisplays.coarseType,
censusDisplays.allocationStack,
censusDisplays.invertedAllocationStack,
],
censusDisplay: censusDisplays.coarseType,
onTakeSnapshotClick: noop,
onImportClick: noop,
onCensusDisplayChange: noop,
onToggleRecordAllocationStacks: noop,
allocations: models.allocations,
onToggleInverted: noop,
inverted:
false,
filterString:
null,
setFilterString: noop,
diffing:
null,
onToggleDiffing: noop,
view: { state: viewState.CENSUS },
onViewChange: noop,
labelDisplays: [labelDisplays.coarseType, labelDisplays.allocationStack],
labelDisplay: labelDisplays.coarseType,
onLabelDisplayChange: noop,
snapshots: [],
});
function makeTestCensusNode() {
return {
name:
"Function",
bytes:
100,
totalBytes:
100,
count:
100,
totalCount:
100,
children: [],
};
}
var TEST_TREE_MAP_PROPS = Object.freeze({
treeMap: Object.freeze({
report: {
name:
null,
bytes:
0,
totalBytes:
400,
count:
0,
totalCount:
400,
children: [
{
name:
"objects",
bytes:
0,
totalBytes:
200,
count:
0,
totalCount:
200,
children: [makeTestCensusNode(), makeTestCensusNode()],
},
{
name:
"other",
bytes:
0,
totalBytes:
200,
count:
0,
totalCount:
200,
children: [makeTestCensusNode(), makeTestCensusNode()],
},
],
},
}),
});
var TEST_SNAPSHOT_LIST_ITEM_PROPS = Object.freeze({
onClick: noop,
onSave: noop,
onDelete: noop,
item: TEST_SNAPSHOT,
index:
1234,
});
function onNextAnimationFrame(fn) {
return () => requestAnimationFrame(() => requestAnimationFrame(fn));
}
/**
* Render the provided ReactElement in the provided HTML container.
* Returns a Promise that will resolve the rendered element as a React
* component.
*/
function renderComponent(element, container) {
return new Promise(resolve => {
const component = ReactDOM.render(
element,
container,
onNextAnimationFrame(() => {
dumpn(
"Rendered = " + container.innerHTML);
resolve(component);
})
);
});
}
function dumpn(msg) {
dump(`MEMORY-TEST: ${msg}\n`);
}