Files
2018-02-02 04:16:08 -05:00

218 lines
6.0 KiB
JavaScript

/* 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/. */
/* eslint no-unused-vars: [2, {"vars": "local"}] */
"use strict";
var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
var { require } = Cu.import("resource://devtools/shared/Loader.jsm", {});
var { Assert } = require("resource://testing-common/Assert.jsm");
var { gDevTools } = require("devtools/client/framework/devtools");
var { BrowserLoader } = Cu.import("resource://devtools/client/shared/browser-loader.js", {});
var promise = require("promise");
var defer = require("devtools/shared/defer");
var Services = require("Services");
var { DebuggerServer } = require("devtools/server/main");
var { DebuggerClient } = require("devtools/shared/client/main");
var DevToolsUtils = require("devtools/shared/DevToolsUtils");
var flags = require("devtools/shared/flags");
var { Task } = require("devtools/shared/task");
var { TargetFactory } = require("devtools/client/framework/target");
var { Toolbox } = require("devtools/client/framework/toolbox");
flags.testing = true;
var { require: browserRequire } = BrowserLoader({
baseURI: "resource://devtools/client/shared/",
window
});
let ReactDOM = browserRequire("devtools/client/shared/vendor/react-dom");
let React = browserRequire("devtools/client/shared/vendor/react");
var TestUtils = React.addons.TestUtils;
var EXAMPLE_URL = "http://example.com/browser/browser/devtools/shared/test/";
function forceRender(comp) {
return setState(comp, {})
.then(() => setState(comp, {}));
}
// All tests are asynchronous.
SimpleTest.waitForExplicitFinish();
function onNextAnimationFrame(fn) {
return () =>
requestAnimationFrame(() =>
requestAnimationFrame(fn));
}
function setState(component, newState) {
return new Promise(resolve => {
component.setState(newState, onNextAnimationFrame(resolve));
});
}
function setProps(component, newProps) {
return new Promise(resolve => {
component.setProps(newProps, onNextAnimationFrame(resolve));
});
}
function dumpn(msg) {
dump(`SHARED-COMPONENTS-TEST: ${msg}\n`);
}
/**
* Tree
*/
var TEST_TREE_INTERFACE = {
getParent: x => TEST_TREE.parent[x],
getChildren: x => TEST_TREE.children[x],
renderItem: (x, depth, focused) => "-".repeat(depth) + x + ":" + focused + "\n",
getRoots: () => ["A", "M"],
getKey: x => "key-" + x,
itemHeight: 1,
onExpand: x => TEST_TREE.expanded.add(x),
onCollapse: x => TEST_TREE.expanded.delete(x),
isExpanded: x => TEST_TREE.expanded.has(x),
};
function isRenderedTree(actual, expectedDescription, msg) {
const expected = expectedDescription.map(x => x + "\n").join("");
dumpn(`Expected tree:\n${expected}`);
dumpn(`Actual tree:\n${actual}`);
is(actual, expected, msg);
}
// Encoding of the following tree/forest:
//
// A
// |-- B
// | |-- E
// | | |-- K
// | | `-- L
// | |-- F
// | `-- G
// |-- C
// | |-- H
// | `-- I
// `-- D
// `-- J
// M
// `-- N
// `-- O
var TEST_TREE = {
children: {
A: ["B", "C", "D"],
B: ["E", "F", "G"],
C: ["H", "I"],
D: ["J"],
E: ["K", "L"],
F: [],
G: [],
H: [],
I: [],
J: [],
K: [],
L: [],
M: ["N"],
N: ["O"],
O: []
},
parent: {
A: null,
B: "A",
C: "A",
D: "A",
E: "B",
F: "B",
G: "B",
H: "C",
I: "C",
J: "D",
K: "E",
L: "E",
M: null,
N: "M",
O: "N"
},
expanded: new Set(),
};
/**
* Frame
*/
function checkFrameString({
el, file, line, column, source, functionName, shouldLink, tooltip
}) {
let $ = selector => el.querySelector(selector);
let $func = $(".frame-link-function-display-name");
let $source = $(".frame-link-source");
let $sourceInner = $(".frame-link-source-inner");
let $filename = $(".frame-link-filename");
let $line = $(".frame-link-line");
is($filename.textContent, file, "Correct filename");
is(el.getAttribute("data-line"), line ? `${line}` : null, "Expected `data-line` found");
is(el.getAttribute("data-column"),
column ? `${column}` : null, "Expected `data-column` found");
is($sourceInner.getAttribute("title"), tooltip, "Correct tooltip");
is($source.tagName, shouldLink ? "A" : "SPAN", "Correct linkable status");
if (shouldLink) {
is($source.getAttribute("href"), source, "Correct source");
}
if (line != null) {
let lineText = `:${line}`;
if (column != null) {
lineText += `:${column}`;
}
is($line.textContent, lineText, "Correct line number");
} else {
ok(!$line, "Should not have an element for `line`");
}
if (functionName != null) {
is($func.textContent, functionName, "Correct function name");
} else {
ok(!$func, "Should not have an element for `functionName`");
}
}
function renderComponent(component, props) {
const el = React.createElement(component, props, {});
// By default, renderIntoDocument() won't work for stateless components, but
// it will work if the stateless component is wrapped in a stateful one.
// See https://github.com/facebook/react/issues/4839
const wrappedEl = React.DOM.span({}, [el]);
const renderedComponent = TestUtils.renderIntoDocument(wrappedEl);
return ReactDOM.findDOMNode(renderedComponent).children[0];
}
function shallowRenderComponent(component, props) {
const el = React.createElement(component, props);
const renderer = TestUtils.createRenderer();
renderer.render(el, {});
return renderer.getRenderOutput();
}
/**
* Test that a rep renders correctly across different modes.
*/
function testRepRenderModes(modeTests, testName, componentUnderTest, gripStub) {
modeTests.forEach(({mode, expectedOutput, message}) => {
const modeString = typeof mode === "undefined" ? "no mode" : mode;
if (!message) {
message = `${testName}: ${modeString} renders correctly.`;
}
const rendered = renderComponent(componentUnderTest.rep, { object: gripStub, mode });
is(rendered.textContent, expectedOutput, message);
});
}