// @flow
/* eslint-disable react/no-multi-comp */
import React from 'react'
import PropTypes from 'prop-types'
import { renderToString } from 'react-dom/server'
import { render } from 'react-dom'
import { shallow, mount } from 'enzyme'
import StyleSheetManager from '../StyleSheetManager'
import StyleSheet from '../StyleSheet'
import ServerStyleSheet from '../ServerStyleSheet'
import { resetStyled, expectCSSMatches } from '../../test/utils'
import Frame from 'react-frame-component'
let styled
describe('StyleSheetManager', () => {
beforeEach(() => {
// $FlowFixMe
document.body.innerHTML = ''
// $FlowFixMe
document.head.innerHTML = ''
styled = resetStyled(true)
})
it('should use given stylesheet instance', () => {
const sheet = new ServerStyleSheet()
const Title = styled.h1`color: palevioletred;`
renderToString(
)
expect(sheet.getStyleTags().includes(`palevioletred`)).toEqual(true)
})
it('should render its child', () => {
const target = document.head
const Title = styled.h1`color: palevioletred;`
const child =
const renderedComp = shallow(
{child}
)
expect(renderedComp.contains(child)).toEqual(true)
})
it('should append style to given target', () => {
const target = document.body
const Title = styled.h1`color: palevioletred;`
class Child extends React.Component {
componentDidMount() {
// $FlowFixMe
const styles = target.querySelector('style').textContent
expect(styles.includes(`palevioletred`)).toEqual(true)
}
render() { return }
}
mount(
)
})
it('should append style to given target in iframe', () => {
const iframe = document.createElement('iframe')
const app = document.createElement('div')
// $FlowFixMe
document.body.appendChild(iframe)
// $FlowFixMe
iframe.contentDocument.body.appendChild(app)
const target = iframe.contentDocument.head
const Title = styled.h1`color: palevioletred;`
class Child extends React.Component {
componentDidMount() {
// $FlowFixMe
const styles = target.querySelector('style').textContent
expect(styles.includes(`palevioletred`)).toEqual(true)
}
render() { return }
}
mount(
,
{ attachTo: app }
)
})
it('should apply styles to appropriate targets for nested StyleSheetManagers', () => {
const ONE = styled.h1`
color: red;
`
const TWO = styled.h2`
color: blue;
`
const THREE = styled.h3`
color: green;
`
mount(
)
// $FlowFixMe
expect(document.head.innerHTML).toMatchSnapshot()
// $FlowFixMe
expect(document.body.innerHTML).toMatchSnapshot()
})
// https://github.com/styled-components/styled-components/issues/1634
it('should inject styles into two parallel contexts', async () => {
const Title = styled.h1`
color: palevioletred;
`
// Injects the stylesheet into the document available via context
const SheetInjector = ({ children }, { document }) => (
{children}
)
SheetInjector.contextTypes = {
document: PropTypes.any,
}
class Child extends React.Component {
static contextTypes = {
document: PropTypes.any,
}
componentDidMount() {
// $FlowFixMe
const styles = this.context.document.querySelector('style').textContent
expect(styles.includes(`palevioletred`)).toEqual(true)
this.props.resolve()
}
render() {
return
}
}
const div = document.body.appendChild(document.createElement('div'))
let promiseA, promiseB
promiseA = new Promise((resolveA, reject) => {
promiseB = new Promise((resolveB, reject) => {
try {
// Render two iframes. each iframe should have the styles for the child injected into their head
render(
,
div
)
} catch (e) {
reject(e)
div.parentElement.removeChild(div)
}
})
})
await Promise.all([promiseA, promiseB])
div.parentElement.removeChild(div)
})
describe('ssr', () => {
it('should extract CSS outside the nested StyleSheetManager', () => {
const sheet = new ServerStyleSheet()
const ONE = styled.h1`
color: red;
`
const TWO = styled.h2`
color: blue;
`
class Wrapper extends React.Component {
state = {
targetRef: null
}
render() {
return (
{ this.setState({ targetRef: el }) }}>
{this.state.targetRef &&
}
)
}
}
const html = renderToString(
)
const css = sheet.getStyleTags()
expect(html).toMatchSnapshot()
expect(css).toMatchSnapshot()
})
})
})