import PropTypes from '../../lib/ReactPropTypes'; import ReactTestUtils from "../../lib/ReactTestUtils"; import React from '../../src/May'; import { render, unmountComponentAtNode, findDOMNode } from '../../src/may-dom/MayDom'; import { shallowCompare } from '../../src/PureComponent'; var ReactDOM = { render: render, unmountComponentAtNode: unmountComponentAtNode, findDOMNode: findDOMNode } React.render = render; // import React from "../../dist/ReactANU"; // var ReactDOM = React; // var ReactTestUtils = { // renderIntoDocument: function (element) { // var div = document.createElement("div"); // return React.render(element, div); // } // }; //https://github.com/facebook/react/blob/master/src/isomorphic/children/__tests__/ReactChildren-test.js describe("ReactMultiChild", function () { // this.timeout(200000); it("should update children when possible", () => { var container = document.createElement("div"); var mockMount = jasmine.createSpy('mockMount'); var mockUpdate = jasmine.createSpy('mockUpdate'); var mockUnmount = jasmine.createSpy('mockUnmount'); class MockComponent extends React.Component { componentDidMount = mockMount; componentDidUpdate = mockUpdate; componentWillUnmount = mockUnmount; render() { return ; } } expect(mockMount.calls.count()).toBe(0); expect(mockUpdate.calls.count()).toBe(0); expect(mockUnmount.calls.count()).toBe(0); ReactDOM.render(
, container ); expect(mockMount.calls.count()).toBe(1); expect(mockUpdate.calls.count()).toBe(0); expect(mockUnmount.calls.count()).toBe(0); ReactDOM.render(
, container ); expect(mockMount.calls.count()).toBe(1); expect(mockUpdate.calls.count()).toBe(1); expect(mockUnmount.calls.count()).toBe(0); }); var LetterInner = class extends React.Component { render() { return
{this.props.char}
; } }; var Letter = class extends React.Component { render() { return ; } shouldComponentUpdate() { return false; } }; var Letters = class extends React.Component { render() { const letters = this.props.letters.split(""); return
{letters.map(c => )}
; } }; it("should replace children with different constructors", () => { var container = document.createElement("div"); var mockMount = jasmine.createSpy('mockMount'); var mockUnmount = jasmine.createSpy('mockUnmount'); class MockComponent extends React.Component { componentDidMount = mockMount; componentWillUnmount = mockUnmount; render() { return ; } } expect(mockMount.calls.count()).toBe(0); expect(mockUnmount.calls.count()).toBe(0); ReactDOM.render(
, container ); expect(mockMount.calls.count()).toBe(1); expect(mockUnmount.calls.count()).toBe(0); ReactDOM.render(
, container ); expect(mockMount.calls.count()).toBe(1); expect(mockUnmount.calls.count()).toBe(1); }); it("should NOT replace children with different owners", () => { var container = document.createElement("div"); var mockMount = jasmine.createSpy('mockMount'); var mockUnmount = jasmine.createSpy('mockUnmount'); class MockComponent extends React.Component { componentDidMount = mockMount; componentWillUnmount = mockUnmount; render() { return ; } } class WrapperComponent extends React.Component { render() { return this.props.children || ; } } expect(mockMount.calls.count()).toBe(0); expect(mockUnmount.calls.count()).toBe(0); ReactDOM.render(, container); expect(mockMount.calls.count()).toBe(1); expect(mockUnmount.calls.count()).toBe(0); ReactDOM.render( , container ); expect(mockMount.calls.count()).toBe(1); expect(mockUnmount.calls.count()).toBe(0); }); it("should replace children with different keys", () => { var container = document.createElement("div"); var mockMount = jasmine.createSpy('mockMount'); var mockUnmount = jasmine.createSpy('mockUnmount'); class MockComponent extends React.Component { componentDidMount = mockMount; componentWillUnmount = mockUnmount; render() { return ; } } expect(mockMount.calls.count()).toBe(0); expect(mockUnmount.calls.count()).toBe(0); ReactDOM.render(
, container ); expect(mockMount.calls.count()).toBe(1); expect(mockUnmount.calls.count()).toBe(0); ReactDOM.render(
, container ); expect(mockMount.calls.count()).toBe(2); expect(mockUnmount.calls.count()).toBe(1); }); it("should warn for duplicated array keys with component stack info", () => { class WrapperComponent extends React.Component { render() { return
{this.props.children}
; } } class Parent extends React.Component { render() { return (
{this.props.children}
); } } var instance = ReactTestUtils.renderIntoDocument({[
]}); var array = ReactTestUtils.scryRenderedDOMComponentsWithClass(instance, "child"); expect(array.length).toBe(1); var instance2 = ReactTestUtils.renderIntoDocument({[
,
]}); var array2 = ReactTestUtils.scryRenderedDOMComponentsWithClass(instance2, "aaa"); expect(array2.length).toBe(2); }); it("should warn for duplicated iterable keys with component stack info", () => { class WrapperComponent extends React.Component { render() { return
{this.props.children}
; } } class Parent extends React.Component { render() { return (
{this.props.children}
); } } function createIterable(array) { return { "@@iterator": function() { var i = 0; return { next() { const next = { value: i < array.length ? array[i] : undefined, done: i === array.length }; i++; return next; } }; } }; } var instance = ReactTestUtils.renderIntoDocument({createIterable([
])}); var array = ReactTestUtils.scryRenderedDOMComponentsWithClass(instance, "aaa"); expect(array.length).toBe(1); var instance = ReactTestUtils.renderIntoDocument({createIterable([
,
])}); var array = ReactTestUtils.scryRenderedDOMComponentsWithClass(instance, "aaa"); expect(array.length).toBe(2); }); //暂不处理 maps children // it("should warn for using maps as children with owner info", () => { // if (typeof Map === "function") { // class Parent extends React.Component { // render() { // return
{new Map([["foo", 0], ["bar", 1]])}
; // } // } // var container = document.createElement("div"); // ReactDOM.render(, container); // expect(container.innerText || container.textContent).toBe("01"); // } // }); it("should reorder bailed-out children", () => { var container = document.createElement("div"); // Two random strings -- some additions, some removals, some moves ReactDOM.render(, container); expect(container.textContent).toBe("XKwHomsNjIkBcQWFbiZU"); ReactDOM.render(, container); expect(container.textContent).toBe("EHCjpdTUuiybDvhRJwZt"); }); it("添加增删改", () => { var container = document.createElement("div"); // Two random strings -- some additions, some removals, some moves ReactDOM.render(, container); expect(container.textContent).toBe("8ABC4D5EFGH"); ReactDOM.render(, container); expect(container.textContent).toBe("GFE9DBACH"); }); //暂不处理 需要逐步diff /*it("prepares new children before unmounting old", () => { var list = []; class Spy extends React.Component { componentWillMount() { list.push(this.props.name + " componentWillMount"); } render() { list.push(this.props.name + " render"); return
; } componentDidMount() { list.push(this.props.name + " componentDidMount"); } componentWillUnmount() { list.push(this.props.name + " componentWillUnmount"); } } // These are reference-unequal so they will be swapped even if they have // matching keys var SpyA = props => ; var SpyB = props => ; var container = document.createElement("div"); ReactDOM.render(
, container ); ReactDOM.render(
, container ); expect(list).toEqual([ "oneA componentWillMount", "oneA render", "twoA componentWillMount", "twoA render", "oneA componentDidMount", "twoA componentDidMount", "oneA componentWillUnmount", "oneB componentWillMount", "oneB render", "twoA componentWillUnmount", "twoB componentWillMount", "twoB render", "oneB componentDidMount", "twoB componentDidMount" ]); }); */ });