Repository URL to install this package:
Version:
1.2.13 ▾
|
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const react_1 = __importDefault(require("react"));
const enzyme_1 = require("enzyme");
const utils_1 = require("./utils");
const injectGlobal_1 = __importDefault(require("../constructors/injectGlobal"));
const stringifyRules_1 = __importDefault(require("../utils/stringifyRules"));
const css_1 = __importDefault(require("../constructors/css"));
const keyframes_1 = __importDefault(require("../constructors/keyframes"));
const StyleSheet_1 = __importDefault(require("../models/StyleSheet"));
const constants_1 = require("../constants");
const keyframes = keyframes_1.default(hash => `keyframe_${hash % 1000}`, stringifyRules_1.default, css_1.default);
const injectGlobal = injectGlobal_1.default(stringifyRules_1.default, css_1.default);
const getStyleTags = () => Array.from(document.querySelectorAll('style')).map(el => ({
css: el.innerHTML.trim().replace(/\s+/gm, ' '),
}));
let styled;
describe('rehydration', () => {
/**
* Make sure the setup is the same for every test
*/
beforeEach(() => {
styled = utils_1.resetStyled();
});
describe('with existing styled components', () => {
beforeEach(() => {
document.head.innerHTML = `
<style ${constants_1.SC_ATTR}="b">
/* sc-component-id: TWO */
.TWO {}
.b { color: red; }
</style>
`;
StyleSheet_1.default.reset();
});
it('should preserve the styles', () => {
utils_1.expectCSSMatches('.TWO {} .b { color: red; }');
});
it('should append a new component like normal', () => {
const Comp = styled.div.withConfig({ componentId: 'ONE' }) `
color: blue;
`;
enzyme_1.shallow(react_1.default.createElement(Comp, null));
utils_1.expectCSSMatches('.b { color: red; } .ONE { } .a { color:blue; }');
});
it('should reuse a componentId', () => {
const A = styled.div.withConfig({ componentId: 'ONE' }) `
color: blue;
`;
enzyme_1.shallow(react_1.default.createElement(A, null));
const B = styled.div.withConfig({ componentId: 'TWO' }) ``;
enzyme_1.shallow(react_1.default.createElement(B, null));
utils_1.expectCSSMatches('.b { color: red; } .ONE { } .a { color:blue; }');
});
it('should reuse a componentId and generated class', () => {
const A = styled.div.withConfig({ componentId: 'ONE' }) `
color: blue;
`;
enzyme_1.shallow(react_1.default.createElement(A, null));
const B = styled.div.withConfig({ componentId: 'TWO' }) `
color: red;
`;
enzyme_1.shallow(react_1.default.createElement(B, null));
utils_1.expectCSSMatches('.b { color: red; } .ONE { } .a { color:blue; }');
});
it('should reuse a componentId and inject new classes', () => {
const A = styled.div.withConfig({ componentId: 'ONE' }) `
color: blue;
`;
enzyme_1.shallow(react_1.default.createElement(A, null));
const B = styled.div.withConfig({ componentId: 'TWO' }) `
color: red;
`;
enzyme_1.shallow(react_1.default.createElement(B, null));
const C = styled.div.withConfig({ componentId: 'TWO' }) `
color: green;
`;
enzyme_1.shallow(react_1.default.createElement(C, null));
utils_1.expectCSSMatches('.b{ color: red; } .c{ color:green; } .ONE { } .a{ color:blue; }');
});
});
describe('with styled components with props', () => {
beforeEach(() => {
/* Hash 1323611362 is based on name TWO and contents color: red.
* Change either and this will break. */
document.head.innerHTML = `
<style ${constants_1.SC_ATTR}='a b'>
/* sc-component-id: ONE */
.ONE {}
.a { color: blue; }
/* sc-component-id: TWO */
.TWO {}
.b { color: red; }
</style>
`;
StyleSheet_1.default.reset();
});
it('should preserve the styles', () => {
utils_1.expectCSSMatches(`
.ONE { } .a { color: blue; }
.TWO { } .b { color: red; }
`);
});
it('should not inject new styles for a component already rendered', () => {
const Comp = styled.div.withConfig({ componentId: 'ONE' }) `
color: ${props => props.color};
`;
enzyme_1.shallow(react_1.default.createElement(Comp, { color: "blue" }));
utils_1.expectCSSMatches(`
.ONE { } .a { color: blue; }
.TWO { } .b { color: red; }
`);
});
it('should inject new styles for a new computed style of a component', () => {
utils_1.seedNextClassnames(['x']);
const Comp = styled.div.withConfig({ componentId: 'ONE' }) `
color: ${props => props.color};
`;
enzyme_1.shallow(react_1.default.createElement(Comp, { color: "green" }));
utils_1.expectCSSMatches(`
.a { color: blue; } .x { color:green; }
.b { color: red; }
`);
});
});
describe('with inline styles that werent rendered by us', () => {
beforeEach(() => {
/* Same css as before, but without the data attributes we ignore it */
document.head.innerHTML = `
<style>
/* sc-component-id: TWO */
.TWO {}
.b { color: red; }
</style>
`;
StyleSheet_1.default.reset();
});
it('should leave the existing styles there', () => {
utils_1.expectCSSMatches('.TWO {} .b { color: red; }');
});
it('should generate new classes, even if they have the same name', () => {
const A = styled.div.withConfig({ componentId: 'ONE' }) `
color: blue;
`;
enzyme_1.shallow(react_1.default.createElement(A, null));
const B = styled.div.withConfig({ componentId: 'TWO' }) `
color: red;
`;
enzyme_1.shallow(react_1.default.createElement(B, null));
utils_1.expectCSSMatches('.TWO {} .b { color: red; } .ONE { } .a { color:blue; } .TWO {} .b { color:red; } ');
});
});
describe('with global styles', () => {
beforeEach(() => {
/* Adding a non-local stylesheet with a hash 557410406 which is
* derived from "body { background: papayawhip; }" so be careful
* changing it. */
document.head.innerHTML = `
<style ${constants_1.SC_ATTR}>
/* sc-component-id: sc-global-557410406 */
body { background: papayawhip; }
</style>
<style ${constants_1.SC_ATTR}='b'>
/* sc-component-id: TWO */
.TWO {}
.b { color: red; }
</style>
`;
StyleSheet_1.default.reset();
});
it('should leave the existing styles there', () => {
utils_1.expectCSSMatches('body { background: papayawhip; } .TWO {} .b { color: red; }');
});
it('should inject new global styles at the end', () => {
injectGlobal `
body { color: tomato; }
`;
utils_1.expectCSSMatches('body { background: papayawhip; } .b { color: red; } body { color:tomato; }');
});
it('should interleave global and local styles', () => {
injectGlobal `
body { color: tomato; }
`;
const A = styled.div.withConfig({ componentId: 'ONE' }) `
color: blue;
`;
enzyme_1.shallow(react_1.default.createElement(A, null));
utils_1.expectCSSMatches('body { background: papayawhip; } .b { color: red; } body { color:tomato; } .ONE { } .a { color:blue; }');
expect(getStyleTags()).toEqual([
{
css: '/* sc-component-id: sc-global-557410406 */ body{background:papayawhip;} ',
},
{ css: '/* sc-component-id: TWO */ .b{color:red;} ' },
{
css: '/* sc-component-id: sc-global-2299393384 */ body{color:tomato;} ',
},
{ css: '/* sc-component-id: ONE */ .ONE {} .a{color:blue;}' },
].reduce((acc, { css }) => {
acc[0].css += css;
return acc;
}, [{ css: '' }]));
});
});
describe('with all styles already rendered', () => {
let styleTags;
beforeEach(() => {
document.head.innerHTML = `
<style ${constants_1.SC_ATTR}>
/* sc-component-id: sc-global-1455077013 */
html { font-size: 16px; }
/* sc-component-id: sc-global-557410406 */
body { background: papayawhip; }
</style>
<style ${constants_1.SC_ATTR}='a b'>
/* sc-component-id: ONE */
.ONE {}
.a { color: blue; }
/* sc-component-id: TWO */
.TWO {}
.b { color: red; }
</style>
`;
styleTags = Array.from(document.querySelectorAll('style'));
StyleSheet_1.default.reset();
});
it('should not touch existing styles', () => {
utils_1.expectCSSMatches(`
html { font-size: 16px; }
body { background: papayawhip; }
.ONE { } .a { color: blue; }
.TWO { } .b { color: red; }
`);
});
it('should replace stylesheets on-demand', () => {
const tagsAfterReset = Array.from(document.querySelectorAll('style'));
expect(tagsAfterReset[0]).toBe(styleTags[0]);
expect(tagsAfterReset[1]).toBe(styleTags[1]);
/* Rerendering existing tags doesn't touch the DOM */
const A = styled.div.withConfig({ componentId: 'ONE' }) `
color: blue;
`;
enzyme_1.shallow(react_1.default.createElement(A, null));
const B = styled.div.withConfig({ componentId: 'TWO' }) `
color: red;
`;
enzyme_1.shallow(react_1.default.createElement(B, null));
const styleTagsAfterRehydration = Array.from(document.querySelectorAll('style'));
expect(styleTagsAfterRehydration[0]).toEqual(styleTags[0]);
/* Only when new components are introduced (or a previous component
* generates a new hash) does the style tag get replaced. */
const C = styled.div.withConfig({ componentId: 'THREE' }) `
color: green;
`;
enzyme_1.shallow(react_1.default.createElement(C, null));
/* the order stays correct and the styles are unharmed
* NOTE: during rehydration the empty rules are stripped out however */
utils_1.expectCSSMatches(`
html { font-size:16px; }
body { background:papayawhip; }
.a { color:blue; }
.b { color:red; }
.THREE { } .c { color:green; }
`);
});
it('should not change styles if rendered in the same order they were created with', () => {
injectGlobal `
html { font-size: 16px; }
`;
injectGlobal `
body { background: papayawhip; }
`;
const A = styled.div.withConfig({ componentId: 'ONE' }) `
color: blue;
`;
enzyme_1.shallow(react_1.default.createElement(A, null));
const B = styled.div.withConfig({ componentId: 'TWO' }) `
color: red;
`;
enzyme_1.shallow(react_1.default.createElement(B, null));
utils_1.expectCSSMatches(`
html { font-size: 16px; }
body { background: papayawhip; }
.ONE { } .a { color: blue; }
.TWO { } .b { color: red; }
`);
});
it('should still not change styles if rendered in a different order', () => {
const B = styled.div.withConfig({ componentId: 'TWO' }) `
color: red;
`;
enzyme_1.shallow(react_1.default.createElement(B, null));
injectGlobal `
body { background: papayawhip; }
`;
const A = styled.div.withConfig({ componentId: 'ONE' }) `
color: blue;
`;
enzyme_1.shallow(react_1.default.createElement(A, null));
injectGlobal `
html { font-size: 16px; }
`;
utils_1.expectCSSMatches(`
html { font-size: 16px; }
body { background: papayawhip; }
.ONE { } .a { color: blue; }
.TWO { } .b { color: red; }
`);
});
});
describe('with keyframes', () => {
beforeEach(() => {
document.head.innerHTML = `
<style ${constants_1.SC_ATTR}='keyframe_880'>
/* sc-component-id: sc-keyframes-keyframe_880 */
@-webkit-keyframes keyframe_880 {from {opacity: 0;}}@keyframes keyframe_880 {from {opacity: 0;}}
</style>
`;
StyleSheet_1.default.reset();
});
it('should not touch existing styles', () => {
utils_1.expectCSSMatches(`
@-webkit-keyframes keyframe_880 {from {opacity: 0;}}@keyframes keyframe_880 {from {opacity: 0;}}
`);
});
it('should not regenerate keyframes', () => {
keyframes `
from { opacity: 0; }
`;
utils_1.expectCSSMatches(`
@-webkit-keyframes keyframe_880 {from {opacity: 0;}}@keyframes keyframe_880 {from {opacity: 0;}}
`);
});
it('should still inject new keyframes', () => {
keyframes `
from { opacity: 1; }
`;
utils_1.expectCSSMatches(`
@-webkit-keyframes keyframe_880 {from {opacity: 0;}}@keyframes keyframe_880 {from {opacity: 0;}}
@-webkit-keyframes keyframe_144 {from {opacity:1;}}@keyframes keyframe_144 {from {opacity:1;}}
`);
});
it('should pass the keyframes name along as well', () => {
const fadeIn = keyframes `
from { opacity: 0; }
`;
const A = styled.div `
animation: ${fadeIn} 1s both;
`;
const fadeOut = keyframes `
from { opacity: 1; }
`;
const B = styled.div `
animation: ${fadeOut} 1s both;
`;
/* Purposely rendering out of order to make sure the output looks right */
enzyme_1.shallow(react_1.default.createElement(B, null));
enzyme_1.shallow(react_1.default.createElement(A, null));
utils_1.expectCSSMatches(`
@-webkit-keyframes keyframe_880 {from {opacity: 0;}}@keyframes keyframe_880 {from {opacity: 0;}}
.sc-a { } .d { -webkit-animation:keyframe_880 1s both; animation:keyframe_880 1s both; }
@-webkit-keyframes keyframe_144 {from {opacity:1;}}@keyframes keyframe_144 {from {opacity:1;}}
.sc-b { } .c { -webkit-animation:keyframe_144 1s both; animation:keyframe_144 1s both; }
`);
});
});
});
//# sourceMappingURL=rehydration.test.js.map