UNPKG

arkit

Version:

Visualises JavaScript, TypeScript and Flow codebases as meaningful and committable architecture diagrams

293 lines (257 loc) 8.27 kB
/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @emails react-core */ 'use strict'; const ReactDOMServerIntegrationUtils = require('./utils/ReactDOMServerIntegrationTestUtils'); let PropTypes; let React; let ReactDOM; let ReactDOMServer; function initModules() { // Reset warning cache. jest.resetModuleRegistry(); PropTypes = require('prop-types'); React = require('react'); ReactDOM = require('react-dom'); ReactDOMServer = require('react-dom/server'); // Make them available to the helpers. return { ReactDOM, ReactDOMServer, }; } const { resetModules, itRenders, itThrowsWhenRendering, } = ReactDOMServerIntegrationUtils(initModules); describe('ReactDOMServerIntegration', () => { beforeEach(() => { resetModules(); }); describe('legacy context', function() { let PurpleContext, RedContext; beforeEach(() => { class Parent extends React.Component { getChildContext() { return {text: this.props.text}; } render() { return this.props.children; } } Parent.childContextTypes = {text: PropTypes.string}; PurpleContext = props => <Parent text="purple">{props.children}</Parent>; RedContext = props => <Parent text="red">{props.children}</Parent>; }); itRenders('class child with context', async render => { class ClassChildWithContext extends React.Component { render() { return <div>{this.context.text}</div>; } } ClassChildWithContext.contextTypes = {text: PropTypes.string}; const e = await render( <PurpleContext> <ClassChildWithContext /> </PurpleContext>, ); expect(e.textContent).toBe('purple'); }); itRenders('stateless child with context', async render => { function FunctionChildWithContext(props, context) { return <div>{context.text}</div>; } FunctionChildWithContext.contextTypes = {text: PropTypes.string}; const e = await render( <PurpleContext> <FunctionChildWithContext /> </PurpleContext>, ); expect(e.textContent).toBe('purple'); }); itRenders('class child without context', async render => { class ClassChildWithoutContext extends React.Component { render() { // this should render blank; context isn't passed to this component. return <div>{this.context.text}</div>; } } const e = await render( <PurpleContext> <ClassChildWithoutContext /> </PurpleContext>, ); expect(e.textContent).toBe(''); }); itRenders('stateless child without context', async render => { function FunctionChildWithoutContext(props, context) { // this should render blank; context isn't passed to this component. return <div>{context.text}</div>; } const e = await render( <PurpleContext> <FunctionChildWithoutContext /> </PurpleContext>, ); expect(e.textContent).toBe(''); }); itRenders('class child with wrong context', async render => { class ClassChildWithWrongContext extends React.Component { render() { // this should render blank; context.text isn't passed to this component. return <div id="classWrongChild">{this.context.text}</div>; } } ClassChildWithWrongContext.contextTypes = {foo: PropTypes.string}; const e = await render( <PurpleContext> <ClassChildWithWrongContext /> </PurpleContext>, ); expect(e.textContent).toBe(''); }); itRenders('stateless child with wrong context', async render => { function FunctionChildWithWrongContext(props, context) { // this should render blank; context.text isn't passed to this component. return <div id="statelessWrongChild">{context.text}</div>; } FunctionChildWithWrongContext.contextTypes = { foo: PropTypes.string, }; const e = await render( <PurpleContext> <FunctionChildWithWrongContext /> </PurpleContext>, ); expect(e.textContent).toBe(''); }); itRenders('with context passed through to a grandchild', async render => { function Grandchild(props, context) { return <div>{context.text}</div>; } Grandchild.contextTypes = {text: PropTypes.string}; const Child = props => <Grandchild />; const e = await render( <PurpleContext> <Child /> </PurpleContext>, ); expect(e.textContent).toBe('purple'); }); itRenders('a child context overriding a parent context', async render => { const Grandchild = (props, context) => { return <div>{context.text}</div>; }; Grandchild.contextTypes = {text: PropTypes.string}; const e = await render( <PurpleContext> <RedContext> <Grandchild /> </RedContext> </PurpleContext>, ); expect(e.textContent).toBe('red'); }); itRenders('a child context merged with a parent context', async render => { class Parent extends React.Component { getChildContext() { return {text1: 'purple'}; } render() { return <Child />; } } Parent.childContextTypes = {text1: PropTypes.string}; class Child extends React.Component { getChildContext() { return {text2: 'red'}; } render() { return <Grandchild />; } } Child.childContextTypes = {text2: PropTypes.string}; const Grandchild = (props, context) => { return ( <div> <div id="first">{context.text1}</div> <div id="second">{context.text2}</div> </div> ); }; Grandchild.contextTypes = { text1: PropTypes.string, text2: PropTypes.string, }; const e = await render(<Parent />); expect(e.querySelector('#first').textContent).toBe('purple'); expect(e.querySelector('#second').textContent).toBe('red'); }); itRenders( 'with a call to componentWillMount before getChildContext', async render => { class WillMountContext extends React.Component { getChildContext() { return {text: this.state.text}; } UNSAFE_componentWillMount() { this.setState({text: 'foo'}); } render() { return <Child />; } } WillMountContext.childContextTypes = {text: PropTypes.string}; const Child = (props, context) => { return <div>{context.text}</div>; }; Child.contextTypes = {text: PropTypes.string}; const e = await render(<WillMountContext />); expect(e.textContent).toBe('foo'); }, ); itRenders( 'if getChildContext exists but childContextTypes is missing with a warning', async render => { function HopefulChild(props, context) { return context.foo || 'nope'; } HopefulChild.contextTypes = { foo: PropTypes.string, }; class ForgetfulParent extends React.Component { render() { return <HopefulChild />; } getChildContext() { return {foo: 'bar'}; } } const e = await render(<ForgetfulParent />, 1); expect(e.textContent).toBe('nope'); }, ); itThrowsWhenRendering( 'if getChildContext returns a value not in childContextTypes', render => { class MyComponent extends React.Component { render() { return <div />; } getChildContext() { return {value1: 'foo', value2: 'bar'}; } } MyComponent.childContextTypes = {value1: PropTypes.string}; return render(<MyComponent />); }, 'MyComponent.getChildContext(): key "value2" is not defined in childContextTypes.', ); }); });