material-ui
Version:
Material Design UI components built with React
281 lines (228 loc) • 7.59 kB
JavaScript
import React from 'react/addons';
import ContextPure from 'mixins/context-pure';
import ThemeManager from 'styles/theme-manager';
import DefaultRawTheme from 'styles/raw-themes/light-raw-theme';
const TestUtils = React.addons.TestUtils;
const update = React.addons.update;
const GrandChildComponent = React.createClass({
mixins: [ContextPure],
contextTypes: {
muiTheme: React.PropTypes.object,
},
statics: {
getRelevantContextKeys(muiTheme) {
return {
grandChildThemeProp: muiTheme.grandChildThemeProp,
}
},
},
renderCount: 0,
render() {
this.renderCount++;
return <div />;
},
getRenderCount() {
return this.renderCount;
},
});
const ChildComponent = React.createClass({
mixins: [ContextPure],
contextTypes: {
muiTheme: React.PropTypes.object,
},
getInitialState: function() {
return {
childState: 0,
};
},
statics: {
getRelevantContextKeys(muiTheme) {
return {
childThemeProp: muiTheme.childThemeProp,
}
},
getChildrenClasses() {
return [
GrandChildComponent,
];
},
},
renderCount: 0,
render() {
this.renderCount++;
return <GrandChildComponent ref="grandChild" />;
},
getGrandChildRenderCount() {
return this.refs.grandChild.getRenderCount();
},
getRenderCount() {
return this.renderCount;
},
updateState(childState) {
this.setState({childState});
},
});
const ParentComponent = React.createClass({
childContextTypes: {
muiTheme: React.PropTypes.object,
},
propTypes: {
staticTheme: React.PropTypes.bool,
},
renderCount: 0,
getDefaultProps: function() {
return {
staticTheme: true,
};
},
getChildContext() {
return {
muiTheme: this.theme,
};
},
getInitialState() {
return {
childProp: 0,
};
},
componentWillMount() {
this.theme = ThemeManager.getMuiTheme(DefaultRawTheme);
this.theme.static = this.props.staticTheme;
this.theme.childThemeProp = 0;
this.theme.grandChildThemeProp = 0;
},
render() {
this.renderCount++;
return <ChildComponent ref="child" testProp={this.state.childProp} />;
},
getChildRenderCount() {
return this.refs.child.getRenderCount();
},
getGrandChildRenderCount() {
return this.refs.child.getGrandChildRenderCount();
},
getRenderCount() {
return this.renderCount;
},
updateChildState(childState) {
this.refs.child.updateState(childState);
},
updateChildContextKey(childThemeProp) {
this.theme = update(this.theme, {
childThemeProp: { $set: childThemeProp },
});
this.forceUpdate();
},
updateGrandChildContextKey(grandChildThemeProp) {
this.theme = update(this.theme, {
grandChildThemeProp: { $set: grandChildThemeProp },
});
this.forceUpdate();
},
updateChildProp(childProp) {
this.setState({childProp});
},
});
describe('Mixin-ContextPure', () => {
let parentElement;
describe('when muiTheme.static is false', () => {
beforeEach(() => {
parentElement = TestUtils.renderIntoDocument(
<ParentComponent
staticTheme={false} />
);
});
it('should not render when context is updated but did not change', () => {
parentElement.updateChildContextKey(0);
parentElement.getRenderCount().should.equal(2);
parentElement.getChildRenderCount().should.equal(1);
parentElement.getGrandChildRenderCount().should.equal(1);
});
it('should not render when prop is updated but did not change', () => {
parentElement.updateChildProp(0);
parentElement.getRenderCount().should.equal(2);
parentElement.getChildRenderCount().should.equal(1);
parentElement.getGrandChildRenderCount().should.equal(1);
});
it('should not render when state is updated but did not change', () => {
parentElement.updateChildState(0);
parentElement.getRenderCount().should.equal(1);
parentElement.getChildRenderCount().should.equal(1);
parentElement.getGrandChildRenderCount().should.equal(1);
});
it('should render when context props change', () => {
parentElement.updateChildContextKey(1);
parentElement.getRenderCount().should.equal(2);
parentElement.getChildRenderCount().should.equal(2);
parentElement.getGrandChildRenderCount().should.equal(1);
});
it('should render when props change', () => {
parentElement.updateChildProp(1);
parentElement.getRenderCount().should.equal(2);
parentElement.getChildRenderCount().should.equal(2);
parentElement.getGrandChildRenderCount().should.equal(1);
});
it('should render when state change', () => {
parentElement.updateChildState(1);
parentElement.getRenderCount().should.equal(1);
parentElement.getChildRenderCount().should.equal(2);
parentElement.getGrandChildRenderCount().should.equal(1);
});
it('should render grandchild when grandchild context props change', () => {
parentElement.updateGrandChildContextKey(1);
parentElement.getRenderCount().should.equal(2);
parentElement.getChildRenderCount().should.equal(2);
parentElement.getGrandChildRenderCount().should.equal(2);
});
});
describe('when muiTheme.static is true', () => {
beforeEach(() => {
parentElement = TestUtils.renderIntoDocument(
<ParentComponent
staticTheme={true} />
);
});
it('should not render when context is updated but did not change', () => {
parentElement.updateChildContextKey(1);
parentElement.getRenderCount().should.equal(2);
parentElement.getChildRenderCount().should.equal(1);
parentElement.getGrandChildRenderCount().should.equal(1);
});
it('should not render when prop is updated but did not change', () => {
parentElement.updateChildProp(0);
parentElement.getRenderCount().should.equal(2);
parentElement.getChildRenderCount().should.equal(1);
parentElement.getGrandChildRenderCount().should.equal(1);
});
it('should not render when state is updated but did not change', () => {
parentElement.updateChildState(0);
parentElement.getRenderCount().should.equal(1);
parentElement.getChildRenderCount().should.equal(1);
parentElement.getGrandChildRenderCount().should.equal(1);
});
it('should not render when context props change', () => {
parentElement.updateChildContextKey(1);
parentElement.getRenderCount().should.equal(2);
parentElement.getChildRenderCount().should.equal(1);
parentElement.getGrandChildRenderCount().should.equal(1);
});
it('should not render grandchild when grandchild context props change', () => {
parentElement.updateGrandChildContextKey(1);
parentElement.getRenderCount().should.equal(2);
parentElement.getChildRenderCount().should.equal(1);
parentElement.getGrandChildRenderCount().should.equal(1);
});
it('should render when props change', () => {
parentElement.updateChildProp(1);
parentElement.getRenderCount().should.equal(2);
parentElement.getChildRenderCount().should.equal(2);
parentElement.getGrandChildRenderCount().should.equal(1);
});
it('should render when state change', () => {
parentElement.updateChildState(1);
parentElement.getRenderCount().should.equal(1);
parentElement.getChildRenderCount().should.equal(2);
parentElement.getGrandChildRenderCount().should.equal(1);
});
});
});