Repository URL to install this package:
|
Version:
1.2.9 ▾
|
"use strict";
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
// @flow
const react_1 = __importStar(require("react"));
const enzyme_1 = require("enzyme");
const utils_1 = require("./utils");
const ThemeProvider_1 = __importDefault(require("../models/ThemeProvider"));
const withTheme_1 = __importDefault(require("../hoc/withTheme"));
let styled;
describe('theming', () => {
beforeEach(() => {
styled = utils_1.resetStyled();
});
it('should inject props.theme into a styled component', () => {
const Comp = styled.div `
color: ${props => props.theme.color};
`;
const theme = { color: 'black' };
enzyme_1.render(react_1.default.createElement(ThemeProvider_1.default, { theme: theme },
react_1.default.createElement(Comp, null)));
utils_1.expectCSSMatches(`.sc-a {} .b { color:${theme.color}; }`);
});
it('should inject props.theme into a styled component multiple levels deep', () => {
const Comp = styled.div `
color: ${props => props.theme.color};
`;
const theme = { color: 'black' };
enzyme_1.render(react_1.default.createElement(ThemeProvider_1.default, { theme: theme },
react_1.default.createElement("div", null,
react_1.default.createElement("div", null,
react_1.default.createElement(Comp, null)))));
utils_1.expectCSSMatches(`.sc-a {} .b { color:${theme.color}; }`);
});
it('should properly allow a component to fallback to its default props when a theme is not provided', () => {
const Comp1 = styled.div `
color: ${props => props.theme.test.color};
`;
Comp1.defaultProps = {
theme: {
test: {
color: 'purple',
},
},
};
enzyme_1.render(react_1.default.createElement("div", null,
react_1.default.createElement(Comp1, null)));
utils_1.expectCSSMatches(`.sc-a {} .b { color:purple; }`);
});
// https://github.com/styled-components/styled-components/issues/344
it('should use ThemeProvider theme instead of defaultProps theme', () => {
const Comp1 = styled.div `
color: ${props => props.theme.test.color};
`;
Comp1.defaultProps = {
theme: {
test: {
color: 'purple',
},
},
};
const theme = { test: { color: 'green' } };
enzyme_1.render(react_1.default.createElement(ThemeProvider_1.default, { theme: theme },
react_1.default.createElement(Comp1, null)));
utils_1.expectCSSMatches(`.sc-a {} .b { color:green; }`);
});
it('should properly allow a component to override the theme with a prop even if it is equal to defaultProps theme', () => {
const Comp1 = styled.div `
color: ${props => props.theme.test.color};
`;
Comp1.defaultProps = {
theme: {
test: {
color: 'purple',
},
},
};
const theme = { test: { color: 'green' } };
enzyme_1.render(react_1.default.createElement(ThemeProvider_1.default, { theme: theme },
react_1.default.createElement(Comp1, { theme: { test: { color: 'purple' } } })));
utils_1.expectCSSMatches(`.sc-a {} .b { color:purple; }`);
});
it('should properly allow a component to override the theme with a prop', () => {
const Comp = styled.div `
color: ${props => props.theme.color};
`;
const theme = {
color: 'purple',
};
enzyme_1.render(react_1.default.createElement("div", null,
react_1.default.createElement(ThemeProvider_1.default, { theme: theme },
react_1.default.createElement(Comp, { theme: { color: 'red' } }))));
utils_1.expectCSSMatches(`.sc-a {} .b { color:red; }`);
});
it('should properly set the theme with an empty object when no theme is provided and no defaults are set', () => {
const Comp1 = styled.div `
color: ${props => props.theme.color};
`;
enzyme_1.render(react_1.default.createElement("div", null,
react_1.default.createElement(Comp1, null)));
utils_1.expectCSSMatches(`.sc-a {}`);
});
it('should only inject props.theme into styled components within its child component tree', () => {
const Comp1 = styled.div `
color: ${props => props.theme.color};
`;
const Comp2 = styled.div `
background: ${props => props.theme.color};
`;
const theme = { color: 'black' };
enzyme_1.render(react_1.default.createElement("div", null,
react_1.default.createElement(ThemeProvider_1.default, { theme: theme },
react_1.default.createElement("div", null,
react_1.default.createElement(Comp1, null))),
react_1.default.createElement(Comp2, null)));
utils_1.expectCSSMatches(`.sc-a {} .c { color:${theme.color}; } .sc-b {}`);
});
it('should inject props.theme into all styled components within the child component tree', () => {
const Comp1 = styled.div `
color: ${props => props.theme.color};
`;
const Comp2 = styled.div `
background: ${props => props.theme.color};
`;
const theme = { color: 'black' };
enzyme_1.render(react_1.default.createElement(ThemeProvider_1.default, { theme: theme },
react_1.default.createElement("div", null,
react_1.default.createElement("div", null,
react_1.default.createElement(Comp1, null)),
react_1.default.createElement(Comp2, null))));
utils_1.expectCSSMatches(`.sc-a {} .c { color:${theme.color}; } .sc-b {} .d { background:${theme.color}; }`);
});
it('should inject new CSS when the theme changes', () => {
const Comp = styled.div `
color: ${props => props.theme.color};
`;
const originalTheme = { color: 'black' };
const newTheme = { color: 'blue' };
let theme = originalTheme;
// Force render the component
const renderComp = () => {
enzyme_1.render(react_1.default.createElement(ThemeProvider_1.default, { theme: theme },
react_1.default.createElement(Comp, null)));
};
renderComp();
const initialCSS = utils_1.expectCSSMatches(`.sc-a {} .b { color:${theme.color}; }`);
// Change the theme
theme = newTheme;
renderComp();
utils_1.expectCSSMatches(`${initialCSS} .c { color:${newTheme.color}; }`);
});
});
describe('theming', () => {
beforeEach(() => {
styled = utils_1.resetStyled();
});
it('should properly render with the same theme from default props on re-render', () => {
const Comp1 = styled.div `
color: ${props => props.theme.color};
`;
Comp1.defaultProps = {
theme: {
color: 'purple',
},
};
const wrapper = enzyme_1.mount(react_1.default.createElement(Comp1, null));
utils_1.expectCSSMatches(`.sc-a {} .b { color:purple; }`);
wrapper.update();
utils_1.expectCSSMatches(`.sc-a {} .b { color:purple; }`);
});
it('should properly update style if theme is changed', () => {
const Comp1 = styled.div `
color: ${props => props.theme.color};
`;
Comp1.defaultProps = {
theme: {
color: 'purple',
},
};
const wrapper = enzyme_1.mount(react_1.default.createElement(Comp1, null));
utils_1.expectCSSMatches(`.sc-a {} .b { color:purple; }`);
wrapper.setProps({ theme: { color: 'pink' } });
utils_1.expectCSSMatches(`.sc-a {} .b { color:purple; } .c { color:pink; }`);
});
it('should properly update style if props used in styles is changed', () => {
const Comp1 = styled.div `
color: ${props => props.theme.color};
z-index: ${props => props.zIndex}px;
`;
Comp1.defaultProps = {
theme: {
color: 'purple',
},
zIndex: 0,
};
const wrapper = enzyme_1.mount(react_1.default.createElement(Comp1, null));
let expectedStyles = `.sc-a {} .b { color:purple; z-index:0px; }`;
utils_1.expectCSSMatches(expectedStyles);
wrapper.setProps({ theme: { color: 'pink' } });
expectedStyles = `${expectedStyles} .c { color:pink; z-index:0px; }`;
utils_1.expectCSSMatches(expectedStyles);
wrapper.setProps({ zIndex: 1 });
utils_1.expectCSSMatches(`${expectedStyles} .d { color:pink; z-index:1px; }`);
});
it('should change the classnames when the theme changes', () => {
const Comp = styled.div `
color: ${props => props.theme.color};
`;
const originalTheme = { color: 'black' };
const newTheme = { color: 'blue' };
const Theme = ({ theme }) => (react_1.default.createElement(ThemeProvider_1.default, { theme: theme },
react_1.default.createElement(Comp, { someProps: theme })));
const wrapper = enzyme_1.mount(react_1.default.createElement(Theme, { theme: originalTheme }));
utils_1.expectCSSMatches(`.sc-a {} .b { color:${originalTheme.color}; }`);
expect(wrapper.find('div').prop('className')).toBe('sc-a b');
// Change theme
wrapper.setProps({ theme: newTheme });
utils_1.expectCSSMatches(`.sc-a {} .b { color:${originalTheme.color}; } .c { color:${newTheme.color}; }`);
expect(wrapper.find('div').prop('className')).toBe('sc-a c');
});
it('should inject props.theme into a component that uses withTheme hoc', () => {
const originalTheme = { color: 'black' };
const MyDiv = ({ theme }) => react_1.default.createElement("div", null, theme.color);
const MyDivWithTheme = withTheme_1.default(MyDiv);
const wrapper = enzyme_1.mount(react_1.default.createElement(ThemeProvider_1.default, { theme: originalTheme },
react_1.default.createElement(MyDivWithTheme, null)));
expect(wrapper.find('div').text()).toBe('black');
});
it('should properly update theme prop on hoc component when theme is changed', () => {
const MyDiv = ({ theme }) => react_1.default.createElement("div", null, theme.color);
const MyDivWithTheme = withTheme_1.default(MyDiv);
const originalTheme = { color: 'black' };
const newTheme = { color: 'blue' };
const Theme = ({ theme }) => (react_1.default.createElement(ThemeProvider_1.default, { theme: theme },
react_1.default.createElement(MyDivWithTheme, null)));
const wrapper = enzyme_1.mount(react_1.default.createElement(Theme, { theme: originalTheme }));
expect(wrapper.find('div').text()).toBe('black');
// Change theme
wrapper.setProps({ theme: newTheme });
expect(wrapper.find('div').text()).toBe('blue');
});
// https://github.com/styled-components/styled-components/issues/445
it('should use ThemeProvider theme instead of defaultProps theme after initial render', () => {
const Text = styled.div `
color: ${props => props.theme.color};
`;
Text.defaultProps = {
theme: {
color: 'purple',
},
};
const Theme = props => (react_1.default.createElement(ThemeProvider_1.default, { theme: { color: 'green' } },
react_1.default.createElement(Text, Object.assign({}, props))));
const wrapper = enzyme_1.mount(react_1.default.createElement(Theme, { prop: "foo" }));
utils_1.expectCSSMatches(`.sc-a { } .b { color:green; } `);
wrapper.setProps({ prop: 'bar' });
utils_1.expectCSSMatches(`.sc-a { } .b { color:green; } `);
});
// https://github.com/styled-components/styled-components/issues/596
it('should hoist static properties when using withTheme', () => {
class MyComponent extends react_1.Component {
}
MyComponent.myStaticProperty = true;
const MyComponentWithTheme = withTheme_1.default(MyComponent);
expect(MyComponentWithTheme.myStaticProperty).toBe(true);
});
it('should only pass the theme prop', () => {
class Comp extends react_1.Component {
render() {
return react_1.default.createElement("div", null);
}
}
const CompWithTheme = withTheme_1.default(Comp);
const wrapper = enzyme_1.mount(react_1.default.createElement(ThemeProvider_1.default, { theme: {} },
react_1.default.createElement(CompWithTheme, null)));
const inner = wrapper.find(Comp).first();
expect(Object.keys(inner.props()).length).toEqual(1);
expect(inner.props()).toEqual({ theme: {} });
});
it('should accept innerRef and pass it on as ref', () => {
class Comp extends react_1.Component {
render() {
return react_1.default.createElement("div", null);
}
}
const CompWithTheme = withTheme_1.default(Comp);
const ref = jest.fn();
const wrapper = enzyme_1.mount(react_1.default.createElement(ThemeProvider_1.default, { theme: {} },
react_1.default.createElement(CompWithTheme, { innerRef: ref })));
const inner = wrapper.find(Comp).first();
expect(ref).toHaveBeenCalledWith(inner.instance());
expect(inner.prop('innerRef')).toBe(undefined);
});
it('should accept innerRef and pass it on for stateless function components', () => {
const Comp = () => react_1.default.createElement("div", null);
const CompWithTheme = withTheme_1.default(Comp);
const ref = jest.fn();
const wrapper = enzyme_1.mount(react_1.default.createElement(ThemeProvider_1.default, { theme: {} },
react_1.default.createElement(CompWithTheme, { innerRef: ref })));
const inner = wrapper.find(Comp).first();
expect(ref).toHaveBeenCalledTimes(0);
expect(inner.prop('innerRef')).toBe(ref);
});
it('should accept innerRef and pass it on for styled components', () => {
const Comp = styled.div ``;
const CompWithTheme = withTheme_1.default(Comp);
const ref = jest.fn();
const wrapper = enzyme_1.mount(react_1.default.createElement(ThemeProvider_1.default, { theme: {} },
react_1.default.createElement(CompWithTheme, { innerRef: ref })));
const inner = wrapper.find(Comp).first();
expect(ref).toHaveBeenCalledWith(inner.getDOMNode());
expect(inner.prop('innerRef')).toBe(ref);
});
// https://github.com/styled-components/styled-components/issues/1130
it('should not break without a ThemeProvier if it has a defaultTheme', () => {
const MyDiv = ({ theme }) => react_1.default.createElement("div", null, theme.color);
const MyDivWithTheme = withTheme_1.default(MyDiv);
const theme = { color: 'red' };
const newTheme = { color: 'blue' };
MyDivWithTheme.defaultProps = { theme };
const wrapper = enzyme_1.mount(react_1.default.createElement(MyDivWithTheme, null));
expect(wrapper.find('div').text()).toBe('red');
// Change theme
wrapper.setProps({ theme: newTheme });
expect(wrapper.find('div').text()).toBe('blue');
});
// https://github.com/styled-components/styled-components/issues/1776
it('should allow module objects to be passed as themes', () => {
const theme = {
borderRadius: '2px',
palette: {
black: '#000',
white: '#fff',
// Flow has limited support for Symbols and computed properties;
// see <https://github.com/facebook/flow/issues/3258>.
// $FlowFixMe
[Symbol.toStringTag]: 'Module',
},
// Flow has limited support for Symbols and computed properties;
// see <https://github.com/facebook/flow/issues/3258>.
// $FlowFixMe
[Symbol.toStringTag]: 'Module',
};
const Comp1 = styled.div `
background-color: ${({ theme }) => theme.palette.white};
color: ${({ theme }) => theme.palette.black};
`;
let wrapper;
expect(() => {
wrapper = enzyme_1.mount(react_1.default.createElement(ThemeProvider_1.default, { theme: theme },
react_1.default.createElement(Comp1, null)));
}).not.toThrow('plain object');
utils_1.expectCSSMatches(`.sc-a {} .b {background-color:${theme.palette.white};color:${theme.palette.black};}`);
});
it('should allow other complex objects to be passed as themes', () => {
class Theme {
constructor(borderRadius) {
this.borderRadius = borderRadius;
}
}
const theme = new Theme('2px');
const Comp1 = styled.div `
border-radius: ${({ theme }) => theme.borderRadius};
`;
const wrapper = enzyme_1.mount(react_1.default.createElement(ThemeProvider_1.default, { theme: theme },
react_1.default.createElement(Comp1, null)));
utils_1.expectCSSMatches(`.sc-a {} .b {border-radius:${theme.borderRadius};}`);
});
it('should not allow the theme to be null', () => {
expect(() => {
enzyme_1.mount(
// $FlowInvalidInputTest
react_1.default.createElement(ThemeProvider_1.default, { theme: null },
react_1.default.createElement("div", null)));
}).toThrowErrorMatchingSnapshot();
});
it('should not allow the theme to be an array', () => {
expect(() => {
enzyme_1.mount(
// $FlowInvalidInputTest
react_1.default.createElement(ThemeProvider_1.default, { theme: ['a', 'b', 'c'] },
react_1.default.createElement("div", null)));
}).toThrowErrorMatchingSnapshot();
});
it('should not allow the theme to be a non-object', () => {
expect(() => {
enzyme_1.mount(
// $FlowInvalidInputTest
react_1.default.createElement(ThemeProvider_1.default, { theme: 42 },
react_1.default.createElement("div", null)));
}).toThrowErrorMatchingSnapshot();
});
});
//# sourceMappingURL=theme.test.js.map