2015-10-16 07:09:57 +08:00
|
|
|
/**
|
2017-09-25 04:48:13 +08:00
|
|
|
* Copyright (c) 2015-present, Facebook, Inc.
|
2015-10-16 07:09:57 +08:00
|
|
|
*
|
2017-09-25 04:48:13 +08:00
|
|
|
* This source code is licensed under the MIT license found in the
|
|
|
|
|
* LICENSE file in the root directory of this source tree.
|
2015-10-16 07:09:57 +08:00
|
|
|
*
|
|
|
|
|
* @emails react-core
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
'use strict';
|
|
|
|
|
|
2016-09-07 06:18:42 +08:00
|
|
|
describe('ReactDOMComponentTree', () => {
|
2015-10-16 07:09:57 +08:00
|
|
|
var React;
|
|
|
|
|
var ReactDOM;
|
2015-10-16 12:29:22 +08:00
|
|
|
var ReactDOMComponentTree;
|
2015-10-16 07:09:57 +08:00
|
|
|
var ReactDOMServer;
|
|
|
|
|
|
|
|
|
|
function renderMarkupIntoDocument(elt) {
|
|
|
|
|
var container = document.createElement('div');
|
|
|
|
|
// Force server-rendering path:
|
|
|
|
|
container.innerHTML = ReactDOMServer.renderToString(elt);
|
2017-09-28 00:14:27 +08:00
|
|
|
return ReactDOM.hydrate(elt, container);
|
2015-10-16 07:09:57 +08:00
|
|
|
}
|
|
|
|
|
|
2016-11-16 23:42:39 +08:00
|
|
|
function getTypeOf(instance) {
|
|
|
|
|
if (typeof instance.tag === 'number') {
|
|
|
|
|
return instance.type;
|
|
|
|
|
}
|
|
|
|
|
return instance._currentElement.type;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getTextOf(instance) {
|
|
|
|
|
if (typeof instance.tag === 'number') {
|
|
|
|
|
return instance.memoizedProps;
|
|
|
|
|
}
|
|
|
|
|
return instance._stringText;
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-07 06:18:42 +08:00
|
|
|
beforeEach(() => {
|
2017-03-01 10:42:52 +08:00
|
|
|
React = require('react');
|
|
|
|
|
ReactDOM = require('react-dom');
|
2017-06-14 07:58:35 +08:00
|
|
|
// TODO: can we express this test with only public API?
|
2015-10-16 12:29:22 +08:00
|
|
|
ReactDOMComponentTree = require('ReactDOMComponentTree');
|
2017-03-01 10:42:52 +08:00
|
|
|
ReactDOMServer = require('react-dom/server');
|
2015-10-16 07:09:57 +08:00
|
|
|
});
|
|
|
|
|
|
2016-09-07 06:18:42 +08:00
|
|
|
it('finds nodes for instances', () => {
|
2015-10-16 07:09:57 +08:00
|
|
|
// This is a little hard to test directly. But refs rely on it -- so we
|
|
|
|
|
// check that we can find a ref at arbitrary points in the tree, even if
|
|
|
|
|
// other nodes don't have a ref.
|
2016-07-21 15:23:42 +08:00
|
|
|
class Component extends React.Component {
|
|
|
|
|
render() {
|
2015-10-16 07:09:57 +08:00
|
|
|
var toRef = this.props.toRef;
|
|
|
|
|
return (
|
|
|
|
|
<div ref={toRef === 'div' ? 'target' : null}>
|
|
|
|
|
<h1 ref={toRef === 'h1' ? 'target' : null}>hello</h1>
|
|
|
|
|
<p ref={toRef === 'p' ? 'target' : null}>
|
|
|
|
|
<input ref={toRef === 'input' ? 'target' : null} />
|
|
|
|
|
</p>
|
|
|
|
|
goodbye.
|
|
|
|
|
</div>
|
|
|
|
|
);
|
2016-07-21 15:23:42 +08:00
|
|
|
}
|
|
|
|
|
}
|
2015-10-16 07:09:57 +08:00
|
|
|
|
|
|
|
|
function renderAndGetRef(toRef) {
|
|
|
|
|
var inst = renderMarkupIntoDocument(<Component toRef={toRef} />);
|
|
|
|
|
return inst.refs.target.nodeName;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
expect(renderAndGetRef('div')).toBe('DIV');
|
|
|
|
|
expect(renderAndGetRef('h1')).toBe('H1');
|
|
|
|
|
expect(renderAndGetRef('p')).toBe('P');
|
|
|
|
|
expect(renderAndGetRef('input')).toBe('INPUT');
|
|
|
|
|
});
|
|
|
|
|
|
2016-09-07 06:18:42 +08:00
|
|
|
it('finds instances for nodes', () => {
|
2016-07-21 15:23:42 +08:00
|
|
|
class Component extends React.Component {
|
|
|
|
|
render() {
|
2015-10-16 12:29:22 +08:00
|
|
|
return (
|
|
|
|
|
<div>
|
|
|
|
|
<h1>hello</h1>
|
|
|
|
|
<p>
|
|
|
|
|
<input />
|
|
|
|
|
</p>
|
|
|
|
|
goodbye.
|
|
|
|
|
<main dangerouslySetInnerHTML={{__html: '<b><img></b>'}} />
|
|
|
|
|
</div>
|
|
|
|
|
);
|
2016-07-21 15:23:42 +08:00
|
|
|
}
|
|
|
|
|
}
|
2015-10-16 12:29:22 +08:00
|
|
|
|
|
|
|
|
function renderAndQuery(sel) {
|
|
|
|
|
var root = renderMarkupIntoDocument(<section><Component /></section>);
|
|
|
|
|
return sel ? root.querySelector(sel) : root;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function renderAndGetInstance(sel) {
|
|
|
|
|
return ReactDOMComponentTree.getInstanceFromNode(renderAndQuery(sel));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function renderAndGetClosest(sel) {
|
|
|
|
|
return ReactDOMComponentTree.getClosestInstanceFromNode(
|
2017-03-14 08:05:18 +08:00
|
|
|
renderAndQuery(sel),
|
2015-10-16 12:29:22 +08:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-16 23:42:39 +08:00
|
|
|
expect(getTypeOf(renderAndGetInstance(null))).toBe('section');
|
|
|
|
|
expect(getTypeOf(renderAndGetInstance('div'))).toBe('div');
|
|
|
|
|
expect(getTypeOf(renderAndGetInstance('h1'))).toBe('h1');
|
|
|
|
|
expect(getTypeOf(renderAndGetInstance('p'))).toBe('p');
|
|
|
|
|
expect(getTypeOf(renderAndGetInstance('input'))).toBe('input');
|
|
|
|
|
expect(getTypeOf(renderAndGetInstance('main'))).toBe('main');
|
2015-10-16 12:29:22 +08:00
|
|
|
|
|
|
|
|
// This one's a text component!
|
2015-12-30 16:01:04 +08:00
|
|
|
var root = renderAndQuery(null);
|
2017-03-14 08:05:18 +08:00
|
|
|
var inst = ReactDOMComponentTree.getInstanceFromNode(
|
|
|
|
|
root.children[0].childNodes[2],
|
|
|
|
|
);
|
2016-11-16 23:42:39 +08:00
|
|
|
expect(getTextOf(inst)).toBe('goodbye.');
|
2015-10-16 12:29:22 +08:00
|
|
|
|
2016-11-16 23:42:39 +08:00
|
|
|
expect(getTypeOf(renderAndGetClosest('b'))).toBe('main');
|
|
|
|
|
expect(getTypeOf(renderAndGetClosest('img'))).toBe('main');
|
2015-10-16 12:29:22 +08:00
|
|
|
});
|
2015-10-16 07:09:57 +08:00
|
|
|
});
|